diff --git a/test/divergence_operator_1D_test_m.F90 b/test/divergence_operator_1D_test_m.F90 index 87adb5a..155825f 100644 --- a/test/divergence_operator_1D_test_m.F90 +++ b/test/divergence_operator_1D_test_m.F90 @@ -65,6 +65,27 @@ pure function parabola(x) result(y) y = (x**2)/2 end function + ! PURPOSE: Tests that the 2nd-order discrete divergence of the gradient operator correctly computes + ! div(grad(f)) for a parabolic function (x^2/2), which should yield a constant value of + ! 1.0 everywhere, and reports a passing or failing test diagnosis based on whether the + ! computed values approximate the expected result within a tight tolerance. + ! KEYWORDS: divergence, gradient, div-grad, laplacian-equivalence, finite-difference, + ! defined operation, unit-test, scalar_1D, parabola, 2nd-order, structured-grid, staggered-grid, + ! test-diagnosis, differential-operator, verification, compound-operator + ! CONTEXT: This function is part of the operator test suite in the formal library, which provides + ! defined operations (.grad., .div., .laplacian., etc.) for staggered-grid + ! scalar fields. It tests the compound expression .div. (.grad. f), which should be + ! mathematically equivalent to the Laplacian but is computed by composing the gradient and + ! divergence operators separately rather than using the dedicated .laplacian. operator. The + ! scalar field is initialized as a parabola (x^2/2) on a 16-cell 1D domain [0, 5] at + ! 2nd-order accuracy, and the expected div(grad) value is the constant 1.0. This + ! complements the direct Laplacian tests by verifying that the discrete gradient and + ! divergence operators compose correctly. A tight_tolerance is used, reflecting that the + ! parabola is within the polynomial exactness range of the 2nd-order stencils. The + ! conditional compilation directives handle differences between gfortran and other compilers + ! regarding associate-block support for user-defined operator results. The test result is + ! accumulated using the .also. and .approximates. defined operations and the + ! passing_test()/test_diagnosis_t testing infrastructure. function check_2nd_order_div_grad_parabola() result(test_diagnosis) type(test_diagnosis_t) test_diagnosis procedure(scalar_1D_initializer_i), pointer :: scalar_1D_initializer => parabola @@ -84,7 +105,30 @@ function check_2nd_order_div_grad_parabola() result(test_diagnosis) end associate #endif end function + ! END CODE CHUNK + ! PURPOSE: Tests that the 4th-order discrete divergence of the gradient operator correctly computes + ! div(grad(f)) for a parabolic function (x^2/2), which should yield a constant value of + ! 1.0 everywhere, and reports a passing or failing test diagnosis based on whether the + ! computed values approximate the expected result within a tight tolerance. + ! KEYWORDS: divergence, gradient, div-grad, laplacian-equivalence, finite-difference, + ! defined operation, unit-test, scalar_1D, parabola, 4th-order, structured-grid, staggered-grid, + ! test-diagnosis, differential-operator, verification, compound-operator, + ! higher-order-accuracy + ! CONTEXT: This function is part of the operator test suite in the formal library, which provides + ! defined operations (.grad., .div., .laplacian., etc.) for staggered-grid + ! scalar fields. It tests the compound expression .div. (.grad. f), which should be + ! mathematically equivalent to the Laplacian but is computed by composing the gradient and + ! divergence operators separately rather than using the dedicated .laplacian. operator. The + ! scalar field is initialized as a parabola (x^2/2) on a 16-cell 1D domain [0, 9] at + ! 4th-order accuracy, and the expected div(grad) value is the constant 1.0. Compared to the + ! 2nd-order variant, this test uses a wider domain [0, 9] vs [0, 5], which tests the + ! higher-order stencil on a coarser effective resolution. A tight_tolerance is still used, + ! as the parabola is well within the polynomial exactness range of the 4th-order stencils. + ! The conditional compilation directives handle differences between gfortran and other + ! compilers regarding associate-block support for user-defined operator results. The test + ! result is accumulated using the .also. and .approximates. defined operations and the + ! passing_test()/test_diagnosis_t testing infrastructure. function check_4th_order_div_grad_parabola() result(test_diagnosis) type(test_diagnosis_t) test_diagnosis procedure(scalar_1D_initializer_i), pointer :: scalar_1D_initializer => parabola @@ -104,6 +148,7 @@ function check_4th_order_div_grad_parabola() result(test_diagnosis) end associate #endif end function + ! END CODE CHUNK pure function sinusoid(x) result(y) double precision, intent(in) :: x(:) @@ -111,6 +156,28 @@ pure function sinusoid(x) result(y) y = sin(x) + cos(x) end function + ! PURPOSE: Tests that the 2nd-order discrete divergence operator converges at the expected rate by + ! comparing coarse-grid (100 cells) and fine-grid (101 cells) solutions of the divergence + ! of the vector field [sin(x) + cos(x)] against the analytical divergence cos(x) - sin(x). + ! It verifies that both grids approximate the expected divergence within a rough tolerance + ! and that the observed convergence rate matches 2nd-order accuracy. + ! KEYWORDS: divergence, finite-difference, convergence-rate, 2nd-order, defined operation, + ! unit-test, vector_1D, sinusoid, structured-grid, staggered-grid, test-diagnosis, differential-operator, + ! verification, grid-refinement, order-of-accuracy + ! CONTEXT: This function is part of the divergence operator test suite in the formal library, which + ! provides defined operations (.div., .grad., .laplacian., etc.) for + ! staggered-grid scalar and vector fields. It constructs two vector_1D_t objects + ! initialized with a sinusoidal function on the domain [0, 2*pi] at 2nd-order accuracy + ! with coarse (100) and fine (101) cell counts, applies the .div. operator to both, and + ! compares the results against the analytical divergence cos(x) - sin(x). This test mirrors + ! the structure of the gradient convergence tests but exercises the divergence operator on + ! a vector field rather than the gradient operator on a scalar field. The observed + ! convergence rate is computed via log(coarse_error/fine_error)/log(fine_cells/coarse_cells) + ! and checked against the desired 2nd order. A rough_tolerance is used for all checks. The + ! conditional compilation directives handle differences between gfortran and other compilers + ! regarding associate-block support for user-defined operator results. The test result is + ! accumulated using the .also. and .approximates. defined operations and the + ! passing_test()/test_diagnosis_t testing infrastructure. function check_2nd_order_div_sinusoid_convergence() result(test_diagnosis) type(test_diagnosis_t) test_diagnosis procedure(vector_1D_initializer_i), pointer :: vector_1D_initializer => sinusoid @@ -155,7 +222,32 @@ function check_2nd_order_div_sinusoid_convergence() result(test_diagnosis) end associate #endif end function + ! END CODE CHUNK + ! PURPOSE: Tests that the 4th-order discrete divergence operator converges at the expected rate by + ! comparing coarse-grid (500 cells) and fine-grid (501 cells) solutions of the divergence + ! of the vector field [sin(x) + cos(x)] against the analytical divergence cos(x) - sin(x). + ! It verifies that both grids approximate the expected divergence within a loose tolerance + ! and that the observed convergence rate matches 4th-order accuracy. + ! KEYWORDS: divergence, finite-difference, convergence-rate, 4th-order, defined operation, + ! unit-test, vector_1D, sinusoid, structured-grid, staggered-grid, test-diagnosis, differential-operator, + ! verification, grid-refinement, order-of-accuracy, higher-order-accuracy + ! CONTEXT: This function is part of the divergence operator test suite in the formal library, which + ! provides defined operations (.div., .grad., .laplacian., etc.) for + ! staggered-grid scalar and vector fields. It constructs two vector_1D_t objects + ! initialized with a sinusoidal function on the domain [0, 2*pi] at 4th-order accuracy + ! with coarse (500) and fine (501) cell counts, applies the .div. operator to both, and + ! compares the results against the analytical divergence cos(x) - sin(x). Compared to the + ! 2nd-order divergence convergence test, this test uses significantly more cells (500/501 + ! vs 100/101) to ensure stable convergence rate estimation at higher order. The point-wise + ! accuracy checks use loose_tolerance rather than rough_tolerance, reflecting the tighter + ! errors achievable with the 4th-order stencil on finer grids, while the convergence rate + ! check uses crude_tolerance. The observed convergence rate is computed via + ! log(coarse_error/fine_error)/log(fine_cells/coarse_cells) and checked against the desired + ! 4th order. The conditional compilation directives handle differences between gfortran and + ! other compilers regarding associate-block support for user-defined operator results. The + ! test result is accumulated using the .also. and .approximates. defined operations and + ! the passing_test()/test_diagnosis_t testing infrastructure. function check_4th_order_div_sinusoid_convergence() result(test_diagnosis) type(test_diagnosis_t) test_diagnosis procedure(vector_1D_initializer_i), pointer :: vector_1D_initializer => sinusoid @@ -203,5 +295,6 @@ function check_4th_order_div_sinusoid_convergence() result(test_diagnosis) end associate #endif end function + ! END CODE CHUNK -end module divergence_operator_1D_test_m \ No newline at end of file +end module divergence_operator_1D_test_m diff --git a/test/gradient_operator_1D_test_m.F90 b/test/gradient_operator_1D_test_m.F90 index e61710a..bdc4904 100644 --- a/test/gradient_operator_1D_test_m.F90 +++ b/test/gradient_operator_1D_test_m.F90 @@ -63,7 +63,23 @@ pure function const(x) result(y) y = [(5D0, i=1,size(x))] end function - + ! PURPOSE: Tests that the discrete gradient operator correctly computes the gradient of a constant + ! function, which should yield zero everywhere, at both 2nd-order and 4th-order accuracy + ! on 16-cell 1D domains, and reports a passing or failing test diagnosis based on whether + ! the computed values approximate zero within a loose tolerance. + ! KEYWORDS: gradient, finite-difference, defined operation, unit-test, scalar_1D, constant-function, + ! 2nd-order, 4th-order, structured-grid, staggered-grid, test-diagnosis, differential-operator, verification + ! CONTEXT: This function is part of the gradient operator test suite in the formal library, which + ! provides defined operations (.grad., .laplacian., etc.) for staggered-grid + ! scalar fields. It constructs a scalar_1D_t object initialized with a constant function and + ! applies the .grad. operator twice: first at 2nd-order on the domain [0, 4], then at + ! 4th-order on the domain [0, 8]. In both cases the analytically expected gradient is zero, + ! so this test verifies that the finite-difference stencils do not introduce spurious + ! non-zero gradients for a trivial input. A loose_tolerance is used for both checks. The + ! conditional compilation directives handle differences between gfortran and other compilers + ! regarding associate-block support for user-defined operator results. The test result is + ! accumulated across both order checks using the .also. and .approximates. defined + ! operations and the passing_test()/test_diagnosis_t testing infrastructure. function check_grad_const() result(test_diagnosis) type(test_diagnosis_t) test_diagnosis double precision, parameter :: grad_expected = 0. @@ -98,6 +114,7 @@ function check_grad_const() result(test_diagnosis) end associate #endif end function + ! END CODE CHUNK pure function line(x) result(y) double precision, intent(in) :: x(:) @@ -105,6 +122,27 @@ pure function line(x) result(y) y = 14*x + 3 end function + ! PURPOSE: Tests that the discrete gradient operator correctly computes the gradient of a linear + ! function (14*x + 3), which should yield a constant value of 14 everywhere, at both + ! 2nd-order and 4th-order accuracy on 16-cell 1D domains, and reports a passing or failing + ! test diagnosis based on whether the computed values approximate the expected constant + ! gradient within a loose tolerance. + ! KEYWORDS: gradient, finite-difference, defined operation, unit-test, scalar_1D, linear-function, + ! 2nd-order, 4th-order, structured-grid, staggered-grid, test-diagnosis, differential-operator, verification + ! CONTEXT: This function is part of the gradient operator test suite in the formal library, which + ! provides defined operations (.grad., .laplacian., etc.) for staggered-grid + ! scalar fields. It constructs a scalar_1D_t object initialized with a linear function and + ! applies the .grad. operator twice: first at 2nd-order on the domain [0, 4], then at + ! 4th-order on the domain [0, 8]. In both cases the analytically expected gradient is the + ! constant 14, so this test verifies that finite-difference stencils of different orders + ! exactly reproduce the gradient of a linear function, which is within the polynomial + ! exactness range of both stencil orders. This complements the constant-function gradient + ! test by exercising a non-trivial but still analytically simple input. A loose_tolerance + ! is used for both checks. The conditional compilation directives handle differences between + ! gfortran and other compilers regarding associate-block support for user-defined operator + ! results. The test result is accumulated across both order checks using the .also. and + ! .approximates. defined operations and the passing_test()/test_diagnosis_t testing + ! infrastructure. function check_grad_line() result(test_diagnosis) type(test_diagnosis_t) test_diagnosis double precision, parameter :: grad_expected = 14D0 @@ -138,6 +176,7 @@ function check_grad_line() result(test_diagnosis) end associate #endif end function + ! END CODE CHUNK pure function parabola(x) result(y) double precision, intent(in) :: x(:) @@ -145,7 +184,28 @@ pure function parabola(x) result(y) y = 7*x**2 + 3*x + 5 end function - + ! PURPOSE: Tests that the discrete gradient operator correctly computes the gradient of a parabolic + ! function (7*x^2 + 3*x + 5), which should yield the spatially-varying result 14*x + 3 + ! at each grid point, at both 2nd-order and 4th-order accuracy on 16-cell 1D domains, and + ! reports a passing or failing test diagnosis based on whether the computed values + ! approximate the expected gradient within a loose tolerance. + ! KEYWORDS: gradient, finite-difference, defined operation, unit-test, scalar_1D, parabola, + ! 2nd-order, 4th-order, structured-grid, staggered-grid, test-diagnosis, differential-operator, + ! verification, spatially-varying + ! CONTEXT: This function is part of the gradient operator test suite in the formal library, which + ! provides defined operations (.grad., .laplacian., etc.) for staggered-grid + ! scalar fields. It constructs a scalar_1D_t object initialized with a parabolic function + ! and applies the .grad. operator twice: first at 2nd-order on the domain [0, 4], then at + ! 4th-order on the domain [0, 8]. Unlike the constant and linear gradient tests, the + ! expected gradient here is spatially varying (14*x + 3), so the test retrieves the grid + ! coordinates via grad%grid() and constructs the expected values at each grid point using + ! nested associate blocks. The parabola is within the polynomial exactness range of both + ! the 2nd-order and 4th-order stencils, so both should reproduce the analytical gradient. + ! A loose_tolerance is used for both checks. The conditional compilation directives handle + ! differences between gfortran and other compilers regarding associate-block support for + ! user-defined operator results. The test result is accumulated across both order checks + ! using the .also. and .approximates. defined operations and the passing_test()/ + ! test_diagnosis_t testing infrastructure. function check_grad_parabola() result(test_diagnosis) type(test_diagnosis_t) test_diagnosis procedure(scalar_1D_initializer_i), pointer :: scalar_1D_initializer => parabola @@ -187,6 +247,7 @@ function check_grad_parabola() result(test_diagnosis) end associate #endif end function + ! END CODE CHUNK pure function sinusoid(x) result(y) double precision, intent(in) :: x(:) @@ -194,7 +255,29 @@ pure function sinusoid(x) result(y) y = sin(x) + cos(x) end function - + ! PURPOSE: Tests that the 2nd-order discrete gradient operator converges at the expected rate by + ! comparing coarse-grid (200 cells) and fine-grid (201 cells) solutions of the gradient + ! of sin(x) + cos(x) against the analytical derivative cos(x) - sin(x). It verifies that + ! both grids approximate the expected gradient within a rough tolerance and that the + ! observed convergence rate matches 2nd-order accuracy. + ! KEYWORDS: gradient, finite-difference, convergence-rate, 2nd-order, defined operation, + ! unit-test, scalar_1D, sinusoid, structured-grid, staggered-grid, test-diagnosis, differential-operator, + ! verification, grid-refinement, order-of-accuracy + ! CONTEXT: This function is part of the gradient operator test suite in the formal library, which + ! provides defined operations (.grad., .laplacian., etc.) for staggered-grid + ! scalar fields. It constructs two scalar_1D_t objects initialized with a sinusoidal + ! function on the domain [0, 2*pi] at 2nd-order accuracy with coarse (200) and fine (201) + ! cell counts, applies the .grad. operator to both, and compares the results against the + ! analytical derivative cos(x) - sin(x). Unlike the polynomial gradient tests (constant, + ! linear, parabola) that verify exact reproduction within stencil polynomial exactness, + ! this test uses a transcendental function to measure the actual convergence rate via + ! log(coarse_error/fine_error)/log(fine_cells/coarse_cells) and checks that it matches the + ! desired 2nd order. Unlike the Laplacian convergence test, this test does not separately + ! check interior and boundary convergence rates. A rough_tolerance is used for all checks. + ! The conditional compilation directives handle differences between gfortran and other + ! compilers regarding associate-block support for user-defined operator results. The test + ! result is accumulated using the .also. and .approximates. defined operations and the + ! passing_test()/test_diagnosis_t testing infrastructure. function check_2nd_order_grad_convergence() result(test_diagnosis) type(test_diagnosis_t) test_diagnosis procedure(scalar_1D_initializer_i), pointer :: scalar_1D_initializer => sinusoid @@ -241,7 +324,32 @@ function check_2nd_order_grad_convergence() result(test_diagnosis) end associate #endif end function - + ! END CODE CHUNK + + ! PURPOSE: Tests that the 4th-order discrete gradient operator converges at the expected rate by + ! comparing coarse-grid and fine-grid solutions of the gradient of sin(x) + cos(x) against + ! the analytical derivative cos(x) - sin(x). It verifies that both grids approximate the + ! expected gradient within a rough tolerance and that the observed convergence rate matches + ! 4th-order accuracy. + ! KEYWORDS: gradient, finite-difference, convergence-rate, 4th-order, defined operation, + ! unit-test, scalar_1D, sinusoid, structured-grid, staggered-grid, test-diagnosis, differential-operator, + ! verification, grid-refinement, order-of-accuracy, higher-order-accuracy + ! CONTEXT: This function is part of the gradient operator test suite in the formal library, which + ! provides defined operations (.grad., .laplacian., etc.) for staggered-grid + ! scalar fields. It constructs two scalar_1D_t objects initialized with a sinusoidal + ! function on the domain [0, 2*pi] at 4th-order accuracy, applies the .grad. operator to + ! both, and compares the results against the analytical derivative cos(x) - sin(x). The + ! coarse and fine cell counts differ between compilers: gfortran uses 300/301 while other + ! compilers use 400/401, reflecting compiler-specific numerical behavior at higher order. + ! Like the 2nd-order gradient convergence test, this test computes the observed convergence + ! rate via log(coarse_error/fine_error)/log(fine_cells/coarse_cells) and checks that it + ! matches the desired 4th order. It does not separately check interior and boundary + ! convergence rates as the Laplacian convergence test does. A rough_tolerance is used for + ! all checks. The conditional compilation directives handle both the differing cell counts + ! and the differences between gfortran and other compilers regarding associate-block support + ! for user-defined operator results. The test result is accumulated using the .also. and + ! .approximates. defined operations and the passing_test()/test_diagnosis_t testing + ! infrastructure. function check_4th_order_grad_convergence() result(test_diagnosis) type(test_diagnosis_t) test_diagnosis procedure(scalar_1D_initializer_i), pointer :: scalar_1D_initializer => sinusoid @@ -289,5 +397,6 @@ function check_4th_order_grad_convergence() result(test_diagnosis) end associate #endif end function + ! END CODE CHUNK -end module \ No newline at end of file +end module diff --git a/test/integration_operators_1D_test_m.F90 b/test/integration_operators_1D_test_m.F90 index 2f32c3e..da8423e 100644 --- a/test/integration_operators_1D_test_m.F90 +++ b/test/integration_operators_1D_test_m.F90 @@ -81,6 +81,30 @@ pure function SSS_f_div_v(x) result(integral) integral = (x**3)/6 end function + ! PURPOSE: Tests that the volume integral of v dot grad(f) converges at the expected rate and + ! produces sufficiently accurate results for both 2nd-order and 4th-order discretizations. + ! It computes the integral .SSS. (v .dot. .grad. f) * dV on two grids (500 and 501 cells) + ! for each order, compares the high-resolution result against a known analytical integral, + ! and verifies that the observed convergence rate matches the expected order of accuracy. + ! KEYWORDS: volume-integral, gradient, dot-product, finite-difference, convergence-rate, + ! defined operation, unit-test, scalar_1D, vector_1D, parabola, linear-function, + ! 2nd-order, 4th-order, structured-grid, staggered-grid, test-diagnosis, verification, grid-refinement, + ! order-of-accuracy, integral-operator + ! CONTEXT: This function is part of the operator test suite in the formal library, which provides + ! defined operations (.grad., .SSS., .dot., etc.) for staggered-grid scalar + ! and vector fields. It exercises a compound expression combining the gradient operator, + ! vector dot product, volume element, and volume integration operator in a single test. The + ! scalar field f is initialized as a parabola and the vector field v as a linear function, + ! yielding an analytically known volume integral via the antiderivative SSS_v_dot_grad_f + ! evaluated at the domain boundaries [0, 1]. The test loops over 2nd-order and 4th-order + ! discretizations, using order-specific expected convergence rates and solution tolerances + ! stored in parameter arrays indexed by order. For each order, it constructs low-resolution + ! (500 cells) and high-resolution (501 cells) scalar and vector fields, computes the volume + ! integral on each, checks the high-resolution absolute error against a tight solution + ! tolerance, and verifies the convergence rate via log(lo_res/hi_res)/log(cells_/cells) + ! against the expected order within a percentage tolerance. The test result is accumulated + ! using the .also., .isAtMost., .approximates., and .withinPercentage. defined operations + ! and the passing_test()/test_diagnosis_t testing infrastructure. function check_volume_integral_of_v_dot_grad_f() result(test_diagnosis) type(test_diagnosis_t) test_diagnosis procedure(scalar_1D_initializer_i), pointer :: scalar_1D_initializer @@ -127,7 +151,37 @@ function check_volume_integral_of_v_dot_grad_f() result(test_diagnosis) end do end function - + ! END CODE CHUNK + + ! PURPOSE: Tests that the volume integral of f times div(v) converges at the expected rate and + ! produces sufficiently accurate results for both 2nd-order and 4th-order discretizations. + ! It computes the integral .SSS. (f * .div. v) * dV on two grids (500 and 501 cells) for + ! each order, compares the high-resolution result against a known analytical integral, and + ! verifies that the observed convergence rate matches the expected order of accuracy. + ! KEYWORDS: volume-integral, divergence, scalar-multiplication, finite-difference, convergence-rate, + ! defined operation, unit-test, scalar_1D, vector_1D, parabola, linear-function, + ! 2nd-order, 4th-order, structured-grid, staggered-grid, test-diagnosis, verification, grid-refinement, + ! order-of-accuracy, integral-operator + ! CONTEXT: This function is part of the operator test suite in the formal library, which provides + ! defined operations (.grad., .div., .SSS., etc.) for staggered-grid scalar + ! and vector fields. It exercises a compound expression combining the divergence operator, + ! scalar-field multiplication, volume element, and volume integration operator in a single + ! test. The scalar field f is initialized as a parabola and the vector field v as a linear + ! function, yielding an analytically known volume integral via the antiderivative + ! SSS_f_div_v evaluated at the domain boundaries [0, 1]. This test complements the + ! check_volume_integral_of_v_dot_grad_f test, as f*div(v) and v dot grad(f) are related + ! through integration by parts. The test loops over 2nd-order and 4th-order + ! discretizations, using order-specific expected convergence rates and solution tolerances + ! stored in parameter arrays indexed by order. The 4th-order case uses a slightly larger + ! percentage tolerance (2%) compared to the v_dot_grad_f test (1%), reflecting differences + ! in how the divergence and gradient discretizations accumulate numerical error. For each + ! order, it constructs low-resolution (500 cells) and high-resolution (501 cells) scalar + ! and vector fields, computes the volume integral on each, checks the high-resolution + ! absolute error against a tight solution tolerance, and verifies the convergence rate via + ! log(lo_res/hi_res)/log(cells_/cells) against the expected order within a percentage + ! tolerance. The test result is accumulated using the .also., .isAtMost., .approximates., + ! and .withinPercentage. defined operations and the passing_test()/test_diagnosis_t + ! testing infrastructure. function check_volume_integral_of_f_div_v() result(test_diagnosis) type(test_diagnosis_t) test_diagnosis procedure(scalar_1D_initializer_i), pointer :: scalar_1D_initializer @@ -174,7 +228,39 @@ function check_volume_integral_of_f_div_v() result(test_diagnosis) end do end function - + ! END CODE CHUNK + + ! PURPOSE: Tests that the surface integral of the product f times (v dot dA) converges at the + ! expected rate and produces sufficiently accurate results for both 2nd-order and 4th-order + ! discretizations. It computes the integral .SS. (f .x. (v .dot. dA)) on two grids for + ! each order, compares the high-resolution result against a known analytical surface + ! integral, and verifies that the observed convergence rate matches the expected order of + ! accuracy. + ! KEYWORDS: surface-integral, dot-product, scalar-multiplication, finite-difference, convergence-rate, + ! defined operation, unit-test, scalar_1D, vector_1D, parabola, linear-function, + ! 2nd-order, 4th-order, structured-grid, staggered-grid, test-diagnosis, verification, grid-refinement, + ! order-of-accuracy, integral-operator, surface-area-element + ! CONTEXT: This function is part of the operator test suite in the formal library, which provides + ! defined operations (.grad., .div., .SS., .dot., .x., etc.) for + ! staggered-grid scalar and vector fields. It exercises a compound expression combining + ! scalar-vector multiplication, the vector dot product with the surface area element dA, + ! and the surface integration operator .SS. in a single test. The scalar field f is + ! initialized as a parabola and the vector field v as a linear function, yielding an + ! analytically known surface integral computed as parabola(x_max)*line(x_max) minus + ! parabola(x_min)*line(x_min) on the domain [0, 1]. This test complements the volume + ! integral tests by verifying surface flux computations, which are related through the + ! divergence theorem. The test includes compiler-specific conditional compilation: the + ! Intel compiler uses fewer cells (400/401 vs 500/501) and a looser percentage tolerance + ! for the 4th-order convergence rate (5% vs 4%), reflecting compiler-specific numerical + ! differences. The test loops over 2nd-order and 4th-order discretizations, using + ! order-specific expected convergence rates and solution tolerances stored in parameter + ! arrays indexed by order. For each order, it constructs low-resolution and high-resolution + ! scalar and vector fields, computes the surface integral on each, checks the + ! high-resolution absolute error against a tight solution tolerance, and verifies the + ! convergence rate via log(lo_res/hi_res)/log(cells_/cells) against the expected order + ! within a percentage tolerance. The test result is accumulated using the .also., + ! .isAtMost., .approximates., and .withinPercentage. defined operations and the + ! passing_test()/test_diagnosis_t testing infrastructure. function check_surface_integral_of_vf() result(test_diagnosis) type(test_diagnosis_t) test_diagnosis procedure(scalar_1D_initializer_i), pointer :: scalar_1D_initializer @@ -226,6 +312,7 @@ function check_surface_integral_of_vf() result(test_diagnosis) end do end function + ! END CODE CHUNK pure function quartic(x) result(f) double precision, intent(in) :: x(:) @@ -239,6 +326,30 @@ pure function exponential(x) result(v) v = exp(x) end function + ! PURPOSE: Tests that the extended Gauss divergence theorem holds discretely by verifying that the + ! residual of the identity .SSS. (v dot grad f) dV + .SSS. (f div v) dV - .SS. (f v dot dA) + ! is near zero for both 2nd-order and 4th-order discretizations on a 20-cell 1D domain. + ! KEYWORDS: gauss-divergence-theorem, volume-integral, surface-integral, gradient, divergence, + ! dot-product, finite-difference, defined operation, unit-test, scalar_1D, vector_1D, + ! quartic, exponential, 2nd-order, 4th-order, structured-grid, staggered-grid, test-diagnosis, + ! verification, integral-identity, conservation + ! CONTEXT: This function is part of the operator test suite in the formal library, which provides + ! defined operations (.grad., .div., .SSS., .SS., .dot., .x., etc.) for + ! staggered-grid scalar and vector fields. It serves as a capstone verification test that + ! ties together the volume integral of v dot grad(f), the volume integral of f times div(v), + ! and the surface integral of f times (v dot dA) through the extended Gauss divergence + ! theorem identity. Unlike the individual volume and surface integral convergence tests + ! that compare each integral against an analytical result, this test checks that the three + ! discrete integrals satisfy the theorem's algebraic relationship with a residual below + ! residual_tolerance, regardless of how closely each individual integral matches its + ! analytical value. The scalar field f is initialized as a quartic function and the vector + ! field v as an exponential function, providing a non-trivial test case where neither field + ! is within the polynomial exactness range of the stencils. A relatively coarse grid of 20 + ! cells is used, emphasizing that the discrete identity should hold even on under-resolved + ! grids. The test loops over 2nd-order and 4th-order discretizations, computing the + ! residual for each and checking its absolute value against residual_tolerance. The test + ! result is accumulated using the .also. and .isAtMost. defined operations and the + ! passing_test()/test_diagnosis_t testing infrastructure. function check_gauss_divergence_theorem() result(test_diagnosis) type(test_diagnosis_t) test_diagnosis procedure(scalar_1D_initializer_i), pointer :: scalar_1D_initializer @@ -270,5 +381,6 @@ function check_gauss_divergence_theorem() result(test_diagnosis) end do end function + ! END CODE CHUNK end module integration_operators_1D_test_m diff --git a/test/laplacian_operator_1D_test_m.F90 b/test/laplacian_operator_1D_test_m.F90 index ccd5486..bc41d02 100644 --- a/test/laplacian_operator_1D_test_m.F90 +++ b/test/laplacian_operator_1D_test_m.F90 @@ -64,6 +64,20 @@ pure function parabola(x) result(y) y = (x**2)/2 end function + ! PURPOSE: Tests that the 2nd-order discrete Laplacian operator correctly computes the Laplacian of + ! a parabolic function (x^2/2), which should yield a constant value of 1.0 everywhere, and + ! reports a passing or failing test diagnosis based on whether the computed values approximate + ! the expected analytical result within a tight tolerance. + ! KEYWORDS: laplacian, finite-difference, defined operation, unit-test, scalar_1D, parabola, 2nd-order, + ! structured-grid, staggered-grid, test-diagnosis, differential-operator, verification + ! CONTEXT: This function is part of the Laplacian operator test suite in the formal library, which provides + ! defined operations (.laplacian., .gradient., etc.) for staggered-grid scalar fields. + ! It constructs a scalar_1D_t object initialized with a parabola function on a 16-cell 1D domain [0, 5], + ! applies the .laplacian. operator, and checks that all resulting values match the analytically expected + ! constant Laplacian of 1.0. The conditional compilation directives handle differences between gfortran + ! and other compilers regarding associate-block support for user-defined operator results. The test result + ! is accumulated using the .also. and .approximates. defined operations and the + ! passing_test()/test_diagnosis_t testing infrastructure. function check_2nd_order_laplacian_parabola() result(test_diagnosis) type(test_diagnosis_t) test_diagnosis procedure(scalar_1D_initializer_i), pointer :: scalar_1D_initializer => parabola @@ -83,6 +97,7 @@ function check_2nd_order_laplacian_parabola() result(test_diagnosis) end associate #endif end function + ! END CODE CHUNK pure function quartic(x) result(y) double precision, intent(in) :: x(:) @@ -90,6 +105,23 @@ pure function quartic(x) result(y) y = (x**4)/12 end function + ! PURPOSE: Tests that the 4th-order discrete Laplacian operator correctly computes the Laplacian + ! of a quartic function (x^4/24), which should yield x^2 at each grid point, and reports a passing or + ! failing test diagnosis based on whether the computed values approximate the expected spatially-varying + ! analytical result within a loose tolerance. + ! KEYWORDS: laplacian, finite-difference, defined operation, unit-test, scalar_1D, quartic, 4th-order, + ! structured-grid, staggered-grid, test-diagnosis, differential-operator, verification, higher-order-accuracy + ! CONTEXT: This function is part of the Laplacian operator test suite in the formal library, which provides + ! defined operations (.laplacian., .gradient., etc.) for staggered-grid scalar fields. + ! It constructs a scalar_1D_t object initialized with a quartic function on a 16-cell 1D domain [0, 40], + ! applies the .laplacian. operator at 4th-order accuracy, and checks that all resulting values match the + ! analytically expected spatially-varying Laplacian of x^2. Unlike the 2nd-order parabola test, this test + ! exercises a higher-order stencil and validates against a non-constant expected result by retrieving the + ! grid coordinates via laplacian_quartic%grid(). A loose_tolerance is used instead of tight_tolerance, + ! reflecting the greater numerical challenge of the higher-order polynomial on a coarse grid. The + ! conditional compilation directives handle differences between gfortran and other compilers regarding + ! associate-block support for user-defined operator results. The test result is accumulated using + ! the .also. and .approximates. defined operations and the passing_test()/test_diagnosis_t testing infrastructure. function check_4th_order_laplacian_of_quartic() result(test_diagnosis) type(test_diagnosis_t) test_diagnosis procedure(scalar_1D_initializer_i), pointer :: scalar_1D_initializer => quartic @@ -111,6 +143,7 @@ function check_4th_order_laplacian_of_quartic() result(test_diagnosis) end associate #endif end function + ! END CODE CHUNK pure function f(x) double precision, intent(in) :: x(:) @@ -124,16 +157,68 @@ pure function d2f_dx2(x) d2f_dx2 = -sin(x) end function + ! PURPOSE: Wrapper test that invokes the Laplacian convergence check for 2nd-order accuracy + ! using a coarse grid of 400 cells and a fine grid of 401 cells, returning the + ! resulting test diagnosis. + ! KEYWORDS: laplacian, finite-difference, convergence-rate, 2nd-order, unit-test, wrapper, + ! grid-refinement, verification, test-diagnosis + ! CONTEXT: This function is a thin wrapper in the Laplacian operator test suite of the formal + ! library. It delegates to check_laplacian_convergence, supplying 2nd-order accuracy + ! and specific coarse/fine cell counts (400 and 401). The nearly identical cell counts + ! yield a small refinement ratio, which is sufficient for estimating the convergence + ! rate of the 2nd-order Laplacian stencil applied to sin(x) on [0, 2*pi]. By + ! isolating the parameter choices in a dedicated function, the test suite can register + ! this case as a standalone test while reusing the shared convergence-checking logic + ! in check_laplacian_convergence. function check_2nd_order_laplacian_convergence() result(test_diagnosis) type(test_diagnosis_t) test_diagnosis test_diagnosis = check_laplacian_convergence(order_desired=2, coarse_cells=400, fine_cells=401) end function + ! END CODE CHUNK + ! PURPOSE: Wrapper test that invokes the Laplacian convergence check for 4th-order accuracy + ! using a coarse grid of 150 cells and a fine grid of 151 cells, returning the + ! resulting test diagnosis. + ! KEYWORDS: laplacian, finite-difference, convergence-rate, 4th-order, unit-test, wrapper, + ! grid-refinement, verification, test-diagnosis, higher-order-accuracy + ! CONTEXT: This function is a thin wrapper in the Laplacian operator test suite of the formal + ! library. It delegates to check_laplacian_convergence, supplying 4th-order accuracy + ! and specific coarse/fine cell counts (150 and 151). Compared to the 2nd-order + ! convergence wrapper, this test uses fewer cells because the higher-order stencil + ! achieves smaller errors on coarser grids, making convergence detectable with fewer + ! degrees of freedom. By isolating the parameter choices in a dedicated function, the + ! test suite can register this case as a standalone test while reusing the shared + ! convergence-checking logic in check_laplacian_convergence. function check_4th_order_laplacian_convergence() result(test_diagnosis) type(test_diagnosis_t) test_diagnosis test_diagnosis = check_laplacian_convergence(order_desired = 4, coarse_cells=150, fine_cells=151) end function + ! END CODE CHUNK + ! PURPOSE: Tests that the discrete Laplacian operator converges at the expected order of accuracy by + ! comparing coarse-grid and fine-grid solutions of the Laplacian of sin(x) against the + ! analytical second derivative. It verifies that both grids approximate the expected Laplacian + ! within a crude tolerance, that the interior convergence rate matches the desired order, and + ! that the boundary convergence rate matches one order lower than the desired order. + ! KEYWORDS: laplacian, finite-difference, convergence-rate, defined operation, unit-test, scalar_1D, + ! structured-grid, staggered-grid, test-diagnosis, differential-operator, verification, grid-refinement, + ! boundary-accuracy, interior-accuracy, order-of-accuracy, sin-function + ! CONTEXT: This function is part of the Laplacian operator test suite in the formal library, which + ! provides defined operations (.laplacian., .gradient., etc.) for staggered-grid + ! scalar fields. Unlike the parabola and quartic tests that verify correctness against known + ! analytical results on a single grid, this test performs a grid-refinement convergence study + ! using a trigonometric function f(x)=sin(x) on the domain [0, 2*pi]. It constructs two + ! scalar_1D_t objects at the caller-specified order and cell counts (coarse and fine), applies + ! the .laplacian. operator to both, and computes the maximum absolute error in both the + ! interior and boundary regions separately. The interior region excludes boundary points up to + ! a depth returned by reduced_order_boundary_depth(), reflecting that boundary stencils are + ! one order less accurate than interior stencils. The observed convergence rate is computed as + ! log(coarse_error/fine_error)/log(fine_cells/coarse_cells) and checked against the desired + ! order for the interior and desired order minus one for the boundary. The conditional + ! compilation directives handle differences between gfortran and other compilers regarding + ! associate-block support for user-defined operator results. The test result is accumulated + ! using the .also. and .approximates. defined operations and the passing_test()/test_diagnosis_t + ! testing infrastructure. function check_laplacian_convergence(order_desired, coarse_cells, fine_cells) result(test_diagnosis) type(test_diagnosis_t) test_diagnosis procedure(scalar_1D_initializer_i), pointer :: scalar_1D_initializer => f @@ -208,5 +293,6 @@ function check_laplacian_convergence(order_desired, coarse_cells, fine_cells) re end associate #endif end function + ! END CODE CHUNK -end module \ No newline at end of file +end module