From 00d88d286e7b395d6f9ffb50fa30a886c2a7ab04 Mon Sep 17 00:00:00 2001 From: Robert Hallberg Date: Wed, 14 Feb 2024 18:32:24 -0500 Subject: [PATCH] Document remapping function variable units Added or amended comments to document the mostly arbitrary units of about 108 variables in 5 low-level remapping modules. Only comments are changed and all answers are bitwise identical. --- src/ALE/P1M_functions.F90 | 10 +-- src/ALE/PCM_functions.F90 | 6 +- src/ALE/PLM_functions.F90 | 122 +++++++++++++++++++------------------ src/ALE/PPM_functions.F90 | 32 +++++----- src/ALE/regrid_solvers.F90 | 70 +++++++++++---------- 5 files changed, 128 insertions(+), 112 deletions(-) diff --git a/src/ALE/P1M_functions.F90 b/src/ALE/P1M_functions.F90 index b17b35c85c..7889966135 100644 --- a/src/ALE/P1M_functions.F90 +++ b/src/ALE/P1M_functions.F90 @@ -36,7 +36,7 @@ subroutine P1M_interpolation( N, h, u, edge_values, ppoly_coef, h_neglect, answe ! Local variables integer :: k ! loop index - real :: u0_l, u0_r ! edge values (left and right) + real :: u0_l, u0_r ! edge values (left and right) [A] ! Bound edge values (routine found in 'edge_values.F90') call bound_edge_values( N, h, u, edge_values, h_neglect, answer_date=answer_date ) @@ -74,10 +74,10 @@ subroutine P1M_boundary_extrapolation( N, h, u, edge_values, ppoly_coef ) real, dimension(:,:), intent(inout) :: ppoly_coef !< coefficients of piecewise polynomials, mainly [A] ! Local variables - real :: u0, u1 ! cell averages - real :: h0, h1 ! corresponding cell widths - real :: slope ! retained PLM slope - real :: u0_l, u0_r ! edge values + real :: u0, u1 ! cell averages [A] + real :: h0, h1 ! corresponding cell widths [H] + real :: slope ! retained PLM slope [A] + real :: u0_l, u0_r ! edge values [A] ! ----------------------------------------- ! Left edge value in the left boundary cell diff --git a/src/ALE/PCM_functions.F90 b/src/ALE/PCM_functions.F90 index 4f64e4a96d..f5899339e4 100644 --- a/src/ALE/PCM_functions.F90 +++ b/src/ALE/PCM_functions.F90 @@ -17,11 +17,11 @@ module PCM_functions !! defining 'grid' and 'ppoly'. No consistency check is performed. subroutine PCM_reconstruction( N, u, edge_values, ppoly_coef ) integer, intent(in) :: N !< Number of cells - real, dimension(:), intent(in) :: u !< cell averages + real, dimension(:), intent(in) :: u !< cell averages in arbitrary units [A] real, dimension(:,:), intent(inout) :: edge_values !< Edge value of polynomial, - !! with the same units as u. + !! with the same units as u [A]. real, dimension(:,:), intent(inout) :: ppoly_coef !< Coefficients of polynomial, - !! with the same units as u. + !! with the same units as u [A]. ! Local variables integer :: k diff --git a/src/ALE/PLM_functions.F90 b/src/ALE/PLM_functions.F90 index bc7f100a04..c0c4516fe2 100644 --- a/src/ALE/PLM_functions.F90 +++ b/src/ALE/PLM_functions.F90 @@ -16,20 +16,21 @@ module PLM_functions contains -!> Returns a limited PLM slope following White and Adcroft, 2008. [units of u] +!> Returns a limited PLM slope following White and Adcroft, 2008, in the same arbitrary +!! units [A] as the input values. !! Note that this is not the same as the Colella and Woodward method. real elemental pure function PLM_slope_wa(h_l, h_c, h_r, h_neglect, u_l, u_c, u_r) - real, intent(in) :: h_l !< Thickness of left cell [units of grid thickness] - real, intent(in) :: h_c !< Thickness of center cell [units of grid thickness] - real, intent(in) :: h_r !< Thickness of right cell [units of grid thickness] - real, intent(in) :: h_neglect !< A negligible thickness [units of grid thickness] - real, intent(in) :: u_l !< Value of left cell [units of u] - real, intent(in) :: u_c !< Value of center cell [units of u] - real, intent(in) :: u_r !< Value of right cell [units of u] + real, intent(in) :: h_l !< Thickness of left cell in arbitrary grid thickness units [H] + real, intent(in) :: h_c !< Thickness of center cell in arbitrary grid thickness units [H] + real, intent(in) :: h_r !< Thickness of right cell in arbitrary grid thickness units [H] + real, intent(in) :: h_neglect !< A negligible thickness [H] + real, intent(in) :: u_l !< Value of left cell in arbitrary units [A] + real, intent(in) :: u_c !< Value of center cell in arbitrary units [A] + real, intent(in) :: u_r !< Value of right cell in arbitrary units [A] ! Local variables real :: sigma_l, sigma_c, sigma_r ! Left, central and right slope estimates as - ! differences across the cell [units of u] - real :: u_min, u_max ! Minimum and maximum value across cell [units of u] + ! differences across the cell [A] + real :: u_min, u_max ! Minimum and maximum value across cell [A] ! Side differences sigma_r = u_r - u_c @@ -63,20 +64,21 @@ real elemental pure function PLM_slope_wa(h_l, h_c, h_r, h_neglect, u_l, u_c, u_ end function PLM_slope_wa -!> Returns a limited PLM slope following Colella and Woodward 1984. +!> Returns a limited PLM slope following Colella and Woodward 1984, in the same +!! arbitrary units as the input values [A]. real elemental pure function PLM_slope_cw(h_l, h_c, h_r, h_neglect, u_l, u_c, u_r) - real, intent(in) :: h_l !< Thickness of left cell [units of grid thickness] - real, intent(in) :: h_c !< Thickness of center cell [units of grid thickness] - real, intent(in) :: h_r !< Thickness of right cell [units of grid thickness] - real, intent(in) :: h_neglect !< A negligible thickness [units of grid thickness] - real, intent(in) :: u_l !< Value of left cell [units of u] - real, intent(in) :: u_c !< Value of center cell [units of u] - real, intent(in) :: u_r !< Value of right cell [units of u] + real, intent(in) :: h_l !< Thickness of left cell in arbitrary grid thickness units [H] + real, intent(in) :: h_c !< Thickness of center cell in arbitrary grid thickness units [H] + real, intent(in) :: h_r !< Thickness of right cell in arbitrary grid thickness units [H] + real, intent(in) :: h_neglect !< A negligible thickness [H] + real, intent(in) :: u_l !< Value of left cell in arbitrary units [A] + real, intent(in) :: u_c !< Value of center cell in arbitrary units [A] + real, intent(in) :: u_r !< Value of right cell in arbitrary units [A] ! Local variables real :: sigma_l, sigma_c, sigma_r ! Left, central and right slope estimates as - ! differences across the cell [units of u] - real :: u_min, u_max ! Minimum and maximum value across cell [units of u] - real :: h_cn ! Thickness of center cell [units of grid thickness] + ! differences across the cell [A] + real :: u_min, u_max ! Minimum and maximum value across cell [A] + real :: h_cn ! Thickness of center cell [H] h_cn = h_c + h_neglect @@ -117,18 +119,19 @@ real elemental pure function PLM_slope_cw(h_l, h_c, h_r, h_neglect, u_l, u_c, u_ end function PLM_slope_cw -!> Returns a limited PLM slope following Colella and Woodward 1984. +!> Returns a limited PLM slope following Colella and Woodward 1984, in the same +!! arbitrary units as the input values [A]. real elemental pure function PLM_monotonized_slope(u_l, u_c, u_r, s_l, s_c, s_r) - real, intent(in) :: u_l !< Value of left cell [units of u] - real, intent(in) :: u_c !< Value of center cell [units of u] - real, intent(in) :: u_r !< Value of right cell [units of u] - real, intent(in) :: s_l !< PLM slope of left cell [units of u] - real, intent(in) :: s_c !< PLM slope of center cell [units of u] - real, intent(in) :: s_r !< PLM slope of right cell [units of u] + real, intent(in) :: u_l !< Value of left cell in arbitrary units [A] + real, intent(in) :: u_c !< Value of center cell in arbitrary units [A] + real, intent(in) :: u_r !< Value of right cell in arbitrary units [A] + real, intent(in) :: s_l !< PLM slope of left cell [A] + real, intent(in) :: s_c !< PLM slope of center cell [A] + real, intent(in) :: s_r !< PLM slope of right cell [A] ! Local variables - real :: e_r, e_l, edge ! Right, left and temporary edge values [units of u] - real :: almost_two ! The number 2, almost. - real :: slp ! Magnitude of PLM central slope [units of u] + real :: e_r, e_l, edge ! Right, left and temporary edge values [A] + real :: almost_two ! The number 2, almost [nondim] + real :: slp ! Magnitude of PLM central slope [A] almost_two = 2. * ( 1. - epsilon(s_c) ) @@ -155,17 +158,18 @@ real elemental pure function PLM_monotonized_slope(u_l, u_c, u_r, s_l, s_c, s_r) end function PLM_monotonized_slope -!> Returns a PLM slope using h2 extrapolation from a cell to the left. +!> Returns a PLM slope using h2 extrapolation from a cell to the left, in the same +!! arbitrary units as the input values [A]. !! Use the negative to extrapolate from the cell to the right. real elemental pure function PLM_extrapolate_slope(h_l, h_c, h_neglect, u_l, u_c) - real, intent(in) :: h_l !< Thickness of left cell [units of grid thickness] - real, intent(in) :: h_c !< Thickness of center cell [units of grid thickness] - real, intent(in) :: h_neglect !< A negligible thickness [units of grid thickness] - real, intent(in) :: u_l !< Value of left cell [units of u] - real, intent(in) :: u_c !< Value of center cell [units of u] + real, intent(in) :: h_l !< Thickness of left cell in arbitrary grid thickness units [H] + real, intent(in) :: h_c !< Thickness of center cell in arbitrary grid thickness units [H] + real, intent(in) :: h_neglect !< A negligible thickness [H] + real, intent(in) :: u_l !< Value of left cell in arbitrary units [A] + real, intent(in) :: u_c !< Value of center cell in arbitrary units [A] ! Local variables - real :: left_edge ! Left edge value [units of u] - real :: hl, hc ! Left and central cell thicknesses [units of grid thickness] + real :: left_edge ! Left edge value [A] + real :: hl, hc ! Left and central cell thicknesses [H] ! Avoid division by zero for vanished cells hl = h_l + h_neglect @@ -185,24 +189,26 @@ end function PLM_extrapolate_slope !! defining 'grid' and 'ppoly'. No consistency check is performed here. subroutine PLM_reconstruction( N, h, u, edge_values, ppoly_coef, h_neglect ) integer, intent(in) :: N !< Number of cells - real, dimension(:), intent(in) :: h !< cell widths (size N) - real, dimension(:), intent(in) :: u !< cell averages (size N) + real, dimension(:), intent(in) :: h !< cell widths (size N) [H] + real, dimension(:), intent(in) :: u !< cell averages (size N) in arbitrary units [A] real, dimension(:,:), intent(inout) :: edge_values !< edge values of piecewise polynomials, - !! with the same units as u. + !! with the same units as u [A]. real, dimension(:,:), intent(inout) :: ppoly_coef !< coefficients of piecewise polynomials, mainly - !! with the same units as u. + !! with the same units as u [A]. real, optional, intent(in) :: h_neglect !< A negligibly small width for !! the purpose of cell reconstructions - !! in the same units as h + !! in the same units as h [H] ! Local variables - integer :: k ! loop index - real :: u_l, u_r ! left and right cell averages - real :: slope ! retained PLM slope - real :: e_r, edge - real :: almost_one - real, dimension(N) :: slp, mslp - real :: hNeglect + integer :: k ! loop index + real :: u_l, u_r ! left and right cell averages [A] + real :: slope ! retained PLM slope for a normalized cell width [A] + real :: e_r ! The edge value in the neighboring cell [A] + real :: edge ! The projected edge value in the cell [A] + real :: almost_one ! A value that is slightly smaller than 1 [nondim] + real, dimension(N) :: slp ! The first guess at the normalized tracer slopes [A] + real, dimension(N) :: mslp ! The monotonized normalized tracer slopes [A] + real :: hNeglect ! A negligibly small width used in cell reconstructions [H] hNeglect = hNeglect_dflt ; if (present(h_neglect)) hNeglect = h_neglect @@ -265,18 +271,18 @@ end subroutine PLM_reconstruction !! defining 'grid' and 'ppoly'. No consistency check is performed here. subroutine PLM_boundary_extrapolation( N, h, u, edge_values, ppoly_coef, h_neglect ) integer, intent(in) :: N !< Number of cells - real, dimension(:), intent(in) :: h !< cell widths (size N) - real, dimension(:), intent(in) :: u !< cell averages (size N) + real, dimension(:), intent(in) :: h !< cell widths (size N) [H] + real, dimension(:), intent(in) :: u !< cell averages (size N) in arbitrary units [A] real, dimension(:,:), intent(inout) :: edge_values !< edge values of piecewise polynomials, - !! with the same units as u. + !! with the same units as u [A]. real, dimension(:,:), intent(inout) :: ppoly_coef !< coefficients of piecewise polynomials, mainly - !! with the same units as u. + !! with the same units as u [A]. real, optional, intent(in) :: h_neglect !< A negligibly small width for !! the purpose of cell reconstructions - !! in the same units as h + !! in the same units as h [H] ! Local variables - real :: slope ! retained PLM slope - real :: hNeglect + real :: slope ! retained PLM slope for a normalized cell width [A] + real :: hNeglect ! A negligibly small width used in cell reconstructions [H] hNeglect = hNeglect_dflt ; if (present(h_neglect)) hNeglect = h_neglect diff --git a/src/ALE/PPM_functions.F90 b/src/ALE/PPM_functions.F90 index 805a70d502..ef6841f635 100644 --- a/src/ALE/PPM_functions.F90 +++ b/src/ALE/PPM_functions.F90 @@ -28,7 +28,7 @@ module PPM_functions subroutine PPM_reconstruction( N, h, u, edge_values, ppoly_coef, h_neglect, answer_date) integer, intent(in) :: N !< Number of cells real, dimension(N), intent(in) :: h !< Cell widths [H] - real, dimension(N), intent(in) :: u !< Cell averages [A] + real, dimension(N), intent(in) :: u !< Cell averages in arbitrary coordinates [A] real, dimension(N,2), intent(inout) :: edge_values !< Edge values [A] real, dimension(N,3), intent(inout) :: ppoly_coef !< Polynomial coefficients, mainly [A] real, optional, intent(in) :: h_neglect !< A negligibly small width [H] @@ -36,7 +36,7 @@ subroutine PPM_reconstruction( N, h, u, edge_values, ppoly_coef, h_neglect, answ ! Local variables integer :: k ! Loop index - real :: edge_l, edge_r ! Edge values (left and right) + real :: edge_l, edge_r ! Edge values (left and right) [A] ! PPM limiter call PPM_limiter_standard( N, h, u, edge_values, h_neglect, answer_date=answer_date ) @@ -69,9 +69,9 @@ subroutine PPM_limiter_standard( N, h, u, edge_values, h_neglect, answer_date ) ! Local variables integer :: k ! Loop index - real :: u_l, u_c, u_r ! Cell averages (left, center and right) - real :: edge_l, edge_r ! Edge values (left and right) - real :: expr1, expr2 + real :: u_l, u_c, u_r ! Cell averages (left, center and right) [A] + real :: edge_l, edge_r ! Edge values (left and right) [A] + real :: expr1, expr2 ! Temporary expressions [A2] ! Bound edge values call bound_edge_values( N, h, u, edge_values, h_neglect, answer_date=answer_date ) @@ -135,8 +135,8 @@ subroutine PPM_monotonicity( N, u, edge_values ) real, dimension(:,:), intent(inout) :: edge_values !< Potentially modified edge values [A] ! Local variables - integer :: k ! Loop index - real :: a6,da ! scalar temporaries + integer :: k ! Loop index + real :: a6, da ! Normalized scalar curvature and slope [A] ! Loop on interior cells to impose monotonicity ! Eq. 1.10 of (Colella & Woodward, JCP 84) @@ -195,14 +195,16 @@ subroutine PPM_boundary_extrapolation( N, h, u, edge_values, ppoly_coef, h_negle ! Local variables integer :: i0, i1 - real :: u0, u1 - real :: h0, h1 - real :: a, b, c - real :: u0_l, u0_r - real :: u1_l, u1_r - real :: slope - real :: exp1, exp2 - real :: hNeglect + real :: u0, u1 ! Average concentrations in the two neighboring cells [A] + real :: h0, h1 ! Thicknesses of the two neighboring cells [H] + real :: a, b, c ! An edge value, normalized slope and normalized curvature + ! of a reconstructed distribution [A] + real :: u0_l, u0_r ! Edge values of a neighboring cell [A] + real :: u1_l, u1_r ! Neighboring cell slopes renormalized by the thickness of + ! the cell being worked on [A] + real :: slope ! The normalized slope [A] + real :: exp1, exp2 ! Temporary expressions [A2] + real :: hNeglect ! A negligibly small width used in cell reconstructions [H] hNeglect = hNeglect_dflt ; if (present(h_neglect)) hNeglect = h_neglect diff --git a/src/ALE/regrid_solvers.F90 b/src/ALE/regrid_solvers.F90 index 0655d31062..6e5b3a0cb0 100644 --- a/src/ALE/regrid_solvers.F90 +++ b/src/ALE/regrid_solvers.F90 @@ -18,15 +18,19 @@ module regrid_solvers !! The matrix A must be square, with the first index varing down the column. subroutine solve_linear_system( A, R, X, N, answer_date ) integer, intent(in) :: N !< The size of the system - real, dimension(N,N), intent(inout) :: A !< The matrix being inverted [nondim] - real, dimension(N), intent(inout) :: R !< system right-hand side [A] - real, dimension(N), intent(inout) :: X !< solution vector [A] + real, dimension(N,N), intent(inout) :: A !< The matrix being inverted in arbitrary units [A] on + !! input, but internally modified to become nondimensional + !! during the solver. + real, dimension(N), intent(inout) :: R !< system right-hand side in arbitrary units [A B] on + !! input, but internally modified to have units of [B] + !! during the solver + real, dimension(N), intent(inout) :: X !< solution vector in arbitrary units [B] integer, optional, intent(in) :: answer_date !< The vintage of the expressions to use ! Local variables - real, parameter :: eps = 0.0 ! Minimum pivot magnitude allowed - real :: factor ! The factor that eliminates the leading nonzero element in a row. - real :: pivot, I_pivot ! The pivot value and its reciprocal [nondim] - real :: swap_a, swap_b + real, parameter :: eps = 0.0 ! Minimum pivot magnitude allowed [A] + real :: factor ! The factor that eliminates the leading nonzero element in a row [A-1] + real :: pivot, I_pivot ! The pivot value and its reciprocal, in [A] and [A-1] + real :: swap_a, swap_b ! Swap space in various units [various] logical :: found_pivot ! If true, a pivot has been found logical :: old_answers ! If true, use expressions that give the original (2008 through 2018) MOM6 answers integer :: i, j, k @@ -110,15 +114,18 @@ end subroutine solve_linear_system !! The matrix A must be square, with the first index varing along the row. subroutine linear_solver( N, A, R, X ) integer, intent(in) :: N !< The size of the system - real, dimension(N,N), intent(inout) :: A !< The matrix being inverted [nondim] - real, dimension(N), intent(inout) :: R !< system right-hand side [A] - real, dimension(N), intent(inout) :: X !< solution vector [A] + real, dimension(N,N), intent(inout) :: A !< The matrix being inverted in arbitrary units [A] on + !! input, but internally modified to become nondimensional + !! during the solver. + real, dimension(N), intent(inout) :: R !< system right-hand side in [A B] on input, but internally + !! modified to have units of [B] during the solver + real, dimension(N), intent(inout) :: X !< solution vector [B] ! Local variables - real, parameter :: eps = 0.0 ! Minimum pivot magnitude allowed - real :: factor ! The factor that eliminates the leading nonzero element in a row. - real :: I_pivot ! The reciprocal of the pivot value [inverse of the input units of a row of A] - real :: swap + real, parameter :: eps = 0.0 ! Minimum pivot magnitude allowed [A] + real :: factor ! The factor that eliminates the leading nonzero element in a row [A-1]. + real :: I_pivot ! The reciprocal of the pivot value [A-1] + real :: swap ! Swap space used in various units [various] integer :: i, j, k ! Loop on rows to transform the problem into multiplication by an upper-right matrix. @@ -175,16 +182,17 @@ end subroutine linear_solver !! (A is made up of lower, middle and upper diagonals) subroutine solve_tridiagonal_system( Al, Ad, Au, R, X, N, answer_date ) integer, intent(in) :: N !< The size of the system - real, dimension(N), intent(in) :: Ad !< Matrix center diagonal - real, dimension(N), intent(in) :: Al !< Matrix lower diagonal - real, dimension(N), intent(in) :: Au !< Matrix upper diagonal - real, dimension(N), intent(in) :: R !< system right-hand side - real, dimension(N), intent(out) :: X !< solution vector + real, dimension(N), intent(in) :: Ad !< Matrix center diagonal in arbitrary units [A] + real, dimension(N), intent(in) :: Al !< Matrix lower diagonal [A] + real, dimension(N), intent(in) :: Au !< Matrix upper diagonal [A] + real, dimension(N), intent(in) :: R !< system right-hand side in arbitrary units [A B] + real, dimension(N), intent(out) :: X !< solution vector in arbitrary units [B] integer, optional, intent(in) :: answer_date !< The vintage of the expressions to use ! Local variables - real, dimension(N) :: pivot, Al_piv - real, dimension(N) :: c1 ! Au / pivot for the backward sweep - real :: I_pivot ! The inverse of the most recent pivot + real, dimension(N) :: pivot ! The pivot value [A] + real, dimension(N) :: Al_piv ! The lower diagonal divided by the pivot value [nondim] + real, dimension(N) :: c1 ! Au / pivot for the backward sweep [nondim] + real :: I_pivot ! The inverse of the most recent pivot [A-1] integer :: k ! Loop index logical :: old_answers ! If true, use expressions that give the original (2008 through 2018) MOM6 answers @@ -237,16 +245,16 @@ end subroutine solve_tridiagonal_system !! roundoff compared with (Al+Au), the answers are prone to inaccuracy. subroutine solve_diag_dominant_tridiag( Al, Ac, Au, R, X, N ) integer, intent(in) :: N !< The size of the system - real, dimension(N), intent(in) :: Ac !< Matrix center diagonal offset from Al + Au - real, dimension(N), intent(in) :: Al !< Matrix lower diagonal - real, dimension(N), intent(in) :: Au !< Matrix upper diagonal - real, dimension(N), intent(in) :: R !< system right-hand side - real, dimension(N), intent(out) :: X !< solution vector + real, dimension(N), intent(in) :: Ac !< Matrix center diagonal offset from Al + Au in arbitrary units [A] + real, dimension(N), intent(in) :: Al !< Matrix lower diagonal [A] + real, dimension(N), intent(in) :: Au !< Matrix upper diagonal [A] + real, dimension(N), intent(in) :: R !< system right-hand side in arbitrary units [A B] + real, dimension(N), intent(out) :: X !< solution vector in arbitrary units [B] ! Local variables - real, dimension(N) :: c1 ! Au / pivot for the backward sweep - real :: d1 ! The next value of 1.0 - c1 - real :: I_pivot ! The inverse of the most recent pivot - real :: denom_t1 ! The first term in the denominator of the inverse of the pivot. + real, dimension(N) :: c1 ! Au / pivot for the backward sweep [nondim] + real :: d1 ! The next value of 1.0 - c1 [nondim] + real :: I_pivot ! The inverse of the most recent pivot [A-1] + real :: denom_t1 ! The first term in the denominator of the inverse of the pivot [A] integer :: k ! Loop index ! Factorization and forward sweep, in a form that will never give a division by a