Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules. Face-thickness for the vdiff implicit operator.
When use_harmonic = .false. (default): arithmetic mean
0.5 · (h_a + h_b). Standard MOM6 / ROMS behaviour.
When use_harmonic = .true.: harmonic mean
2 · h_a · h_b / max(h_a + h_b, eps). Better-conditioned
when one of h_a, h_b is small — arithmetic mean is
dominated by the thicker neighbour, generating stiff
tridiagonal coefficients at thin/vanishing layers.
Equivalent to arithmetic when h_a = h_b.
Marked pure + !$acc routine seq so NVHPC can inline the
body into the do concurrent callers without descriptor
marshalling.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | h_a | |||
| real(kind=wp), | intent(in) | :: | h_b | |||
| logical, | intent(in) | :: | use_harmonic |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| real(kind=wp), | private, | parameter | :: | EPS | = | 1.0e-30_wp | |
| real(kind=wp), | private | :: | sum_h |
pure function face_thick(h_a, h_b, use_harmonic) result(dz) !! Public only for the unit-test suite (no production module imports it); !! ignore when developing production code in other modules. !! Face-thickness for the vdiff implicit operator. !! !! When `use_harmonic = .false.` (default): arithmetic mean !! `0.5 · (h_a + h_b)`. Standard MOM6 / ROMS behaviour. !! !! When `use_harmonic = .true.`: harmonic mean !! `2 · h_a · h_b / max(h_a + h_b, eps)`. Better-conditioned !! when one of `h_a`, `h_b` is small — arithmetic mean is !! dominated by the thicker neighbour, generating stiff !! tridiagonal coefficients at thin/vanishing layers. !! Equivalent to arithmetic when `h_a = h_b`. !! !! Marked `pure` + `!$acc routine seq` so NVHPC can inline the !! body into the `do concurrent` callers without descriptor !! marshalling. !$acc routine seq real(wp), intent(in) :: h_a, h_b logical, intent(in) :: use_harmonic real(wp) :: dz real(wp), parameter :: EPS = 1.0e-30_wp real(wp) :: sum_h if (use_harmonic) then sum_h = h_a + h_b if (sum_h > EPS) then dz = 2.0_wp*h_a*h_b/sum_h else dz = 0.5_wp*sum_h end if else dz = 0.5_wp*(h_a + h_b) end if end function face_thick