portedportable, not yet portedexecuted, not portableexecutable, not hit by this run
| 1 | ! This file is part of MOM6, the Modular Ocean Model version 6. | |
| 2 | ! See the LICENSE file for licensing information. | |
| 3 | ! SPDX-License-Identifier: Apache-2.0 | |
| 4 | ||
| 5 | !> Interface to CVMix interior shear schemes | |
| 6 | module MOM_CVMix_shear | |
| 7 | ||
| 8 | !> \author Brandon Reichl | |
| 9 | ||
| 10 | use MOM_diag_mediator, only : post_data, register_diag_field, safe_alloc_ptr | |
| 11 | use MOM_diag_mediator, only : diag_ctrl, time_type | |
| 12 | use MOM_error_handler, only : MOM_error, is_root_pe, FATAL, WARNING, NOTE | |
| 13 | use MOM_file_parser, only : get_param, log_version, param_file_type | |
| 14 | use MOM_grid, only : ocean_grid_type | |
| 15 | use MOM_interface_heights, only : thickness_to_dz | |
| 16 | use MOM_unit_scaling, only : unit_scale_type | |
| 17 | use MOM_variables, only : thermo_var_ptrs | |
| 18 | use MOM_verticalGrid, only : verticalGrid_type | |
| 19 | use MOM_EOS, only : calculate_density | |
| 20 | use CVMix_shear, only : CVMix_init_shear, CVMix_coeffs_shear | |
| 21 | use MOM_kappa_shear, only : kappa_shear_is_used | |
| 22 | implicit none ; private | |
| 23 | ||
| 24 | #include <MOM_memory.h> | |
| 25 | ||
| 26 | public calculate_CVMix_shear, CVMix_shear_init, CVMix_shear_is_used, CVMix_shear_end | |
| 27 | ||
| 28 | ! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional | |
| 29 | ! consistency testing. These are noted in comments with units like Z, H, L, and T, along with | |
| 30 | ! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units | |
| 31 | ! vary with the Boussinesq approximation, the Boussinesq variant is given first. | |
| 32 | ||
| 33 | !> Control structure including parameters for CVMix interior shear schemes. | |
| 34 | type, public :: CVMix_shear_cs ; private | |
| 35 | logical :: use_LMD94 !< Flags to use the LMD94 scheme | |
| 36 | logical :: use_PP81 !< Flags to use Pacanowski and Philander (JPO 1981) | |
| 37 | integer :: n_smooth_ri !< Number of times to smooth Ri using a 1-2-1 filter | |
| 38 | real :: Ri_zero !< LMD94 critical Richardson number [nondim] | |
| 39 | real :: Nu_zero !< LMD94 maximum interior diffusivity [Z2 T-1 ~> m2 s-1] | |
| 40 | real :: KPP_exp !< Exponent of unitless factor of diffusivities | |
| 41 | !! for KPP internal shear mixing scheme [nondim] | |
| 42 | real, allocatable, dimension(:,:,:) :: N2 !< Squared Brunt-Vaisala frequency [T-2 ~> s-2] | |
| 43 | real, allocatable, dimension(:,:,:) :: S2 !< Squared shear frequency [T-2 ~> s-2] | |
| 44 | real, allocatable, dimension(:,:,:) :: ri_grad !< Gradient Richardson number [nondim] | |
| 45 | real, allocatable, dimension(:,:,:) :: ri_grad_orig !< Gradient Richardson number | |
| 46 | !! after smoothing [nondim] | |
| 47 | character(10) :: Mix_Scheme !< Mixing scheme name (string) | |
| 48 | ||
| 49 | type(diag_ctrl), pointer :: diag => NULL() !< Pointer to the diagnostics control structure | |
| 50 | !>@{ Diagnostic handles | |
| 51 | integer :: id_N2 = -1, id_S2 = -1, id_ri_grad = -1, id_kv = -1, id_kd = -1 | |
| 52 | integer :: id_ri_grad_orig = -1 | |
| 53 | !>@} | |
| 54 | ||
| 55 | end type CVMix_shear_cs | |
| 56 | ||
| 57 | character(len=40) :: mdl = "MOM_CVMix_shear" !< This module's name. | |
| 58 | ||
| 59 | contains | |
| 60 | ||
| 61 | !> Subroutine for calculating (internal) vertical diffusivities/viscosities | |
| 62 | 0 | subroutine calculate_CVMix_shear(u_H, v_H, h, tv, kd, kv, G, GV, US, CS ) |
| 63 | type(ocean_grid_type), intent(in) :: G !< Grid structure. | |
| 64 | type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure. | |
| 65 | type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type | |
| 66 | real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: u_H !< Initial zonal velocity on T points [L T-1 ~> m s-1] | |
| 67 | real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: v_H !< Initial meridional velocity on T | |
| 68 | !! points [L T-1 ~> m s-1] | |
| 69 | real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. | |
| 70 | type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamics structure. | |
| 71 | real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(out) :: kd !< The vertical diffusivity at each interface | |
| 72 | !! (not layer!) [H Z T-1 ~> m2 s-1 or kg m-1 s-1] | |
| 73 | real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(out) :: kv !< The vertical viscosity at each interface | |
| 74 | !! (not layer!) [H Z T-1 ~> m2 s-1 or Pa s] | |
| 75 | type(CVMix_shear_cs), pointer :: CS !< The control structure returned by a previous | |
| 76 | !! call to CVMix_shear_init. | |
| 77 | ! Local variables | |
| 78 | integer :: i, j, k, kk, km1, s | |
| 79 | real :: GoRho ! Gravitational acceleration divided by density [Z T-2 R-1 ~> m4 s-2 kg-1] | |
| 80 | real :: pref ! Interface pressures [R L2 T-2 ~> Pa] | |
| 81 | real :: DU, DV ! Velocity differences [L T-1 ~> m s-1] | |
| 82 | real :: dz_int ! Grid spacing around an interface [Z ~> m] | |
| 83 | real :: N2 ! Buoyancy frequency at an interface [T-2 ~> s-2] | |
| 84 | real :: S2 ! Shear squared at an interface [T-2 ~> s-2] | |
| 85 | real :: dummy ! A dummy variable [nondim] | |
| 86 | real :: dRho ! Buoyancy differences [Z T-2 ~> m s-2] | |
| 87 | 0 | real, dimension(SZI_(G),SZK_(GV)) :: dz ! Height change across layers [Z ~> m] |
| 88 | 0 | real, dimension(2*(GV%ke)) :: pres_1d ! A column of interface pressures [R L2 T-2 ~> Pa] |
| 89 | 0 | real, dimension(2*(GV%ke)) :: temp_1d ! A column of temperatures [C ~> degC] |
| 90 | 0 | real, dimension(2*(GV%ke)) :: salt_1d ! A column of salinities [S ~> ppt] |
| 91 | 0 | real, dimension(2*(GV%ke)) :: rho_1d ! A column of densities at interface pressures [R ~> kg m-3] |
| 92 | 0 | real, dimension(GV%ke+1) :: Ri_Grad !< Gradient Richardson number [nondim] |
| 93 | 0 | real, dimension(GV%ke+1) :: Ri_Grad_prev !< Gradient Richardson number before s.th smoothing iteration [nondim] |
| 94 | 0 | real, dimension(GV%ke+1) :: Kvisc !< Vertical viscosity at interfaces [m2 s-1] |
| 95 | 0 | real, dimension(GV%ke+1) :: Kdiff !< Diapycnal diffusivity at interfaces [m2 s-1] |
| 96 | real :: epsln !< Threshold to identify vanished layers [H ~> m or kg m-2] | |
| 97 | ||
| 98 | ! some constants | |
| 99 | 0 | GoRho = GV%g_Earth_Z_T2 / GV%Rho0 |
| 100 | 0 | epsln = 1.e-10 * GV%m_to_H |
| 101 | ||
| 102 | 0 | do j = G%jsc, G%jec |
| 103 | ||
| 104 | ! Find the vertical distances across layers. | |
| 105 | 0 | call thickness_to_dz(h, tv, dz, j, G, GV) |
| 106 | ||
| 107 | 0 | do i = G%isc, G%iec |
| 108 | ||
| 109 | ! skip calling for land points | |
| 110 | 0 | if (G%mask2dT(i,j)==0.) cycle |
| 111 | ||
| 112 | ! Richardson number computed for each cell in a column. | |
| 113 | 0 | pRef = 0. ; if (associated(tv%p_surf)) pRef = tv%p_surf(i,j) |
| 114 | 0 | Ri_Grad(:)=1.e8 !Initialize w/ large Richardson value |
| 115 | 0 | do k=1,GV%ke |
| 116 | ! pressure, temp, and saln for EOS | |
| 117 | ! kk+1 = k fields | |
| 118 | ! kk+2 = km1 fields | |
| 119 | 0 | km1 = max(1, k-1) |
| 120 | 0 | kk = 2*(k-1) |
| 121 | 0 | pres_1D(kk+1) = pRef |
| 122 | 0 | pres_1D(kk+2) = pRef |
| 123 | 0 | Temp_1D(kk+1) = tv%T(i,j,k) |
| 124 | 0 | Temp_1D(kk+2) = tv%T(i,j,km1) |
| 125 | 0 | Salt_1D(kk+1) = tv%S(i,j,k) |
| 126 | 0 | Salt_1D(kk+2) = tv%S(i,j,km1) |
| 127 | ||
| 128 | ! pRef is pressure at interface between k and km1. | |
| 129 | ! iterate pRef for next pass through k-loop. | |
| 130 | 0 | pRef = pRef + (GV%g_Earth * GV%H_to_RZ) * h(i,j,k) |
| 131 | ||
| 132 | enddo ! k-loop finishes | |
| 133 | ||
| 134 | ! compute in-situ density [R ~> kg m-3] | |
| 135 | 0 | call calculate_density(Temp_1D, Salt_1D, pres_1D, rho_1D, tv%eqn_of_state) |
| 136 | ||
| 137 | ! N2 (can be negative) on interface | |
| 138 | 0 | do k = 1, GV%ke |
| 139 | 0 | km1 = max(1, k-1) |
| 140 | 0 | kk = 2*(k-1) |
| 141 | 0 | DU = u_h(i,j,k) - u_h(i,j,km1) |
| 142 | 0 | DV = v_h(i,j,k) - v_h(i,j,km1) |
| 143 | 0 | if (GV%Boussinesq .or. GV%semi_Boussinesq) then |
| 144 | 0 | dRho = GoRho * (rho_1D(kk+1) - rho_1D(kk+2)) |
| 145 | else | |
| 146 | 0 | dRho = GV%g_Earth_Z_T2 * (rho_1D(kk+1) - rho_1D(kk+2)) / (0.5*(rho_1D(kk+1) + rho_1D(kk+2))) |
| 147 | endif | |
| 148 | 0 | dz_int = 0.5*(dz(i,km1) + dz(i,k)) + GV%dZ_subroundoff |
| 149 | 0 | N2 = DRHO / dz_int |
| 150 | 0 | S2 = US%L_to_Z**2*((DU*DU) + (DV*DV)) / (dz_int*dz_int) |
| 151 | 0 | Ri_Grad(k) = max(0., N2) / max(S2, 1.e-10*US%T_to_s**2) |
| 152 | ||
| 153 | ! fill 3d arrays, if user asks for diagnostics | |
| 154 | 0 | if (CS%id_N2 > 0) CS%N2(i,j,k) = N2 |
| 155 | 0 | if (CS%id_S2 > 0) CS%S2(i,j,k) = S2 |
| 156 | ||
| 157 | enddo | |
| 158 | ||
| 159 | 0 | Ri_grad(GV%ke+1) = Ri_grad(GV%ke) |
| 160 | ||
| 161 | 0 | if (CS%n_smooth_ri > 0) then |
| 162 | ||
| 163 | 0 | if (CS%id_ri_grad_orig > 0) CS%ri_grad_orig(i,j,:) = Ri_Grad(:) |
| 164 | ||
| 165 | ! 1) fill Ri_grad in vanished layers with adjacent value | |
| 166 | 0 | do k = 2, GV%ke |
| 167 | 0 | if (h(i,j,k) <= epsln) Ri_grad(k) = Ri_grad(k-1) |
| 168 | enddo | |
| 169 | ||
| 170 | 0 | Ri_grad(GV%ke+1) = Ri_grad(GV%ke) |
| 171 | ||
| 172 | 0 | do s=1,CS%n_smooth_ri |
| 173 | ||
| 174 | 0 | Ri_Grad_prev(:) = Ri_Grad(:) |
| 175 | ||
| 176 | ! 2) vertically smooth Ri with 1-2-1 filter | |
| 177 | 0 | dummy = 0.25 * Ri_grad_prev(2) |
| 178 | 0 | do k = 3, GV%ke |
| 179 | 0 | Ri_Grad(k) = dummy + 0.5 * Ri_Grad_prev(k) + 0.25 * Ri_grad_prev(k+1) |
| 180 | 0 | dummy = 0.25 * Ri_grad(k) |
| 181 | enddo | |
| 182 | enddo | |
| 183 | ||
| 184 | 0 | Ri_grad(GV%ke+1) = Ri_grad(GV%ke) |
| 185 | ||
| 186 | endif | |
| 187 | ||
| 188 | 0 | if (CS%id_ri_grad > 0) CS%ri_grad(i,j,:) = Ri_Grad(:) |
| 189 | ||
| 190 | 0 | do K=1,GV%ke+1 |
| 191 | 0 | Kvisc(K) = GV%HZ_T_to_m2_s * kv(i,j,K) |
| 192 | 0 | Kdiff(K) = GV%HZ_T_to_m2_s * kd(i,j,K) |
| 193 | enddo | |
| 194 | ||
| 195 | ! Call to CVMix wrapper for computing interior mixing coefficients. | |
| 196 | call CVMix_coeffs_shear(Mdiff_out=Kvisc(:), & | |
| 197 | Tdiff_out=Kdiff(:), & | |
| 198 | RICH=Ri_Grad(:), & | |
| 199 | nlev=GV%ke, & | |
| 200 | 0 | max_nlev=GV%ke) |
| 201 | 0 | do K=1,GV%ke+1 |
| 202 | 0 | kv(i,j,K) = GV%m2_s_to_HZ_T * Kvisc(K) |
| 203 | 0 | kd(i,j,K) = GV%m2_s_to_HZ_T * Kdiff(K) |
| 204 | enddo | |
| 205 | enddo | |
| 206 | enddo | |
| 207 | ||
| 208 | ! write diagnostics | |
| 209 | 0 | if (CS%id_kd > 0) call post_data(CS%id_kd, kd, CS%diag) |
| 210 | 0 | if (CS%id_kv > 0) call post_data(CS%id_kv, kv, CS%diag) |
| 211 | 0 | if (CS%id_N2 > 0) call post_data(CS%id_N2, CS%N2, CS%diag) |
| 212 | 0 | if (CS%id_S2 > 0) call post_data(CS%id_S2, CS%S2, CS%diag) |
| 213 | 0 | if (CS%id_ri_grad > 0) call post_data(CS%id_ri_grad, CS%ri_grad, CS%diag) |
| 214 | 0 | if (CS%id_ri_grad_orig > 0) call post_data(CS%id_ri_grad_orig ,CS%ri_grad_orig, CS%diag) |
| 215 | ||
| 216 | 0 | end subroutine calculate_CVMix_shear |
| 217 | ||
| 218 | ||
| 219 | !> Initialized the CVMix internal shear mixing routine. | |
| 220 | !! \todo Does this note require emphasis? | |
| 221 | !! \note *This is where we test to make sure multiple internal shear | |
| 222 | !! mixing routines (including JHL) are not enabled at the same time.* | |
| 223 | !! (returns) CVMix_shear_init - True if module is to be used, False otherwise | |
| 224 | 1 | logical function CVMix_shear_init(Time, G, GV, US, param_file, diag, CS) |
| 225 | type(time_type), intent(in) :: Time !< The current time. | |
| 226 | type(ocean_grid_type), intent(in) :: G !< Grid structure. | |
| 227 | type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure. | |
| 228 | type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type | |
| 229 | type(param_file_type), intent(in) :: param_file !< Run-time parameter file handle | |
| 230 | type(diag_ctrl), target, intent(inout) :: diag !< Diagnostics control structure. | |
| 231 | type(CVMix_shear_cs), pointer :: CS !< This module's control structure. | |
| 232 | ! Local variables | |
| 233 | integer :: NumberTrue=0 | |
| 234 | logical :: use_JHL | |
| 235 | logical :: use_LMD94 | |
| 236 | logical :: use_PP81 | |
| 237 | ||
| 238 | ! This include declares and sets the variable "version". | |
| 239 | #include "version_variable.h" | |
| 240 | ||
| 241 | 1 | if (associated(CS)) then |
| 242 | call MOM_error(WARNING, "CVMix_shear_init called with an associated "// & | |
| 243 | 0 | "control structure.") |
| 244 | 0 | return |
| 245 | endif | |
| 246 | ||
| 247 | ! Set default, read and log parameters | |
| 248 | 1 | call get_param(param_file, mdl, "USE_LMD94", use_LMD94, default=.false., do_not_log=.true.) |
| 249 | 1 | call get_param(param_file, mdl, "USE_PP81", use_PP81, default=.false., do_not_log=.true.) |
| 250 | call log_version(param_file, mdl, version, & | |
| 251 | "Parameterization of shear-driven turbulence via CVMix (various options)", & | |
| 252 | 1 | all_default=.not.(use_PP81.or.use_LMD94)) |
| 253 | call get_param(param_file, mdl, "USE_LMD94", use_LMD94, & | |
| 254 | "If true, use the Large-McWilliams-Doney (JGR 1994) "//& | |
| 255 | 1 | "shear mixing parameterization.", default=.false.) |
| 256 | 1 | if (use_LMD94) & |
| 257 | 0 | NumberTrue=NumberTrue + 1 |
| 258 | call get_param(param_file, mdl, "USE_PP81", use_PP81, & | |
| 259 | "If true, use the Pacanowski and Philander (JPO 1981) "//& | |
| 260 | 1 | "shear mixing parameterization.", default=.false.) |
| 261 | 1 | if (use_PP81) & |
| 262 | 0 | NumberTrue = NumberTrue + 1 |
| 263 | 1 | use_JHL=kappa_shear_is_used(param_file) |
| 264 | 1 | if (use_JHL) NumberTrue = NumberTrue + 1 |
| 265 | ! After testing for interior schemes, make sure only 0 or 1 are enabled. | |
| 266 | ! Otherwise, warn user and kill job. | |
| 267 | 1 | if ((NumberTrue) > 1) then |
| 268 | call MOM_error(FATAL, 'MOM_CVMix_shear_init: '// & | |
| 269 | 'Multiple shear driven internal mixing schemes selected, '//& | |
| 270 | 0 | 'please disable all but one scheme to proceed.') |
| 271 | endif | |
| 272 | ||
| 273 | 1 | CVMix_shear_init = use_PP81 .or. use_LMD94 |
| 274 | ||
| 275 | ! Forego remainder of initialization if not using this scheme | |
| 276 | 1 | if (.not. CVMix_shear_init) return |
| 277 | ||
| 278 | 0 | allocate(CS) |
| 279 | 0 | CS%use_LMD94 = use_LMD94 |
| 280 | 0 | CS%use_PP81 = use_PP81 |
| 281 | 0 | if (use_LMD94) & |
| 282 | 0 | CS%Mix_Scheme = 'KPP' |
| 283 | 0 | if (use_PP81) & |
| 284 | 0 | CS%Mix_Scheme = 'PP' |
| 285 | ||
| 286 | call get_param(param_file, mdl, "NU_ZERO", CS%Nu_Zero, & | |
| 287 | "Leading coefficient in KPP shear mixing.", & | |
| 288 | 0 | units="m2 s-1", default=5.e-3, scale=US%m2_s_to_Z2_T) |
| 289 | call get_param(param_file, mdl, "RI_ZERO", CS%Ri_Zero, & | |
| 290 | "Critical Richardson for KPP shear mixing, "// & | |
| 291 | "NOTE this the internal mixing and this is "// & | |
| 292 | "not for setting the boundary layer depth.", & | |
| 293 | 0 | units="nondim", default=0.8) |
| 294 | call get_param(param_file, mdl, "KPP_EXP", CS%KPP_exp, & | |
| 295 | "Exponent of unitless factor of diffusivities, "// & | |
| 296 | "for KPP internal shear mixing scheme.", & | |
| 297 | 0 | units="nondim", default=3.0) |
| 298 | call get_param(param_file, mdl, "N_SMOOTH_RI", CS%n_smooth_ri, & | |
| 299 | "If > 0, vertically smooth the Richardson "// & | |
| 300 | "number by applying a 1-2-1 filter N_SMOOTH_RI times.", & | |
| 301 | 0 | default=0) |
| 302 | call cvmix_init_shear(mix_scheme=CS%Mix_Scheme, & | |
| 303 | KPP_nu_zero=US%Z2_T_to_m2_s*CS%Nu_Zero, & | |
| 304 | KPP_Ri_zero=CS%Ri_zero, & | |
| 305 | 0 | KPP_exp=CS%KPP_exp) |
| 306 | ||
| 307 | ! Register diagnostics; allocation and initialization | |
| 308 | 0 | CS%diag => diag |
| 309 | ||
| 310 | CS%id_N2 = register_diag_field('ocean_model', 'N2_shear', diag%axesTi, Time, & | |
| 311 | 0 | 'Square of Brunt-Vaisala frequency used by MOM_CVMix_shear module', '1/s2', conversion=US%s_to_T**2) |
| 312 | 0 | if (CS%id_N2 > 0) then |
| 313 | 0 | allocate( CS%N2( SZI_(G), SZJ_(G), SZK_(GV)+1 ), source=0. ) |
| 314 | endif | |
| 315 | ||
| 316 | CS%id_S2 = register_diag_field('ocean_model', 'S2_shear', diag%axesTi, Time, & | |
| 317 | 0 | 'Square of vertical shear used by MOM_CVMix_shear module','1/s2', conversion=US%s_to_T**2) |
| 318 | 0 | if (CS%id_S2 > 0) then |
| 319 | 0 | allocate( CS%S2( SZI_(G), SZJ_(G), SZK_(GV)+1 ), source=0. ) |
| 320 | endif | |
| 321 | ||
| 322 | CS%id_ri_grad = register_diag_field('ocean_model', 'ri_grad_shear', diag%axesTi, Time, & | |
| 323 | 0 | 'Gradient Richarson number used by MOM_CVMix_shear module','nondim') |
| 324 | 0 | if (CS%id_ri_grad > 0) then !Initialize w/ large Richardson value |
| 325 | 0 | allocate( CS%ri_grad( SZI_(G), SZJ_(G), SZK_(GV)+1 ), source=1.e8 ) |
| 326 | endif | |
| 327 | ||
| 328 | 0 | if (CS%n_smooth_ri > 0) then |
| 329 | CS%id_ri_grad_orig = register_diag_field('ocean_model', 'ri_grad_shear_orig', & | |
| 330 | diag%axesTi, Time, & | |
| 331 | 'Original gradient Richarson number, before smoothing was applied. This is '//& | |
| 332 | 0 | 'part of the MOM_CVMix_shear module and only available when N_SMOOTH_RI > 0','nondim') |
| 333 | endif | |
| 334 | 0 | if (CS%id_ri_grad_orig > 0 .or. CS%n_smooth_ri > 0) then !Initialize w/ large Richardson value |
| 335 | 0 | allocate( CS%ri_grad_orig( SZI_(G), SZJ_(G), SZK_(GV)+1 ), source=1.e8 ) |
| 336 | endif | |
| 337 | ||
| 338 | CS%id_kd = register_diag_field('ocean_model', 'kd_shear_CVMix', diag%axesTi, Time, & | |
| 339 | 0 | 'Vertical diffusivity added by MOM_CVMix_shear module', 'm2/s', conversion=GV%HZ_T_to_m2_s) |
| 340 | CS%id_kv = register_diag_field('ocean_model', 'kv_shear_CVMix', diag%axesTi, Time, & | |
| 341 | 0 | 'Vertical viscosity added by MOM_CVMix_shear module', 'm2/s', conversion=GV%HZ_T_to_m2_s) |
| 342 | ||
| 343 | 0 | end function CVMix_shear_init |
| 344 | ||
| 345 | !> Reads the parameters "USE_LMD94" and "USE_PP81" and returns true if either is true. | |
| 346 | !! This function allows other modules to know whether this parameterization will | |
| 347 | !! be used without needing to duplicate the log entry. | |
| 348 | 2 | logical function CVMix_shear_is_used(param_file) |
| 349 | type(param_file_type), intent(in) :: param_file !< Run-time parameter files handle. | |
| 350 | ! Local variables | |
| 351 | logical :: LMD94, PP81 | |
| 352 | call get_param(param_file, mdl, "USE_LMD94", LMD94, & | |
| 353 | 2 | default=.false., do_not_log=.true.) |
| 354 | call get_param(param_file, mdl, "USE_PP81", PP81, & | |
| 355 | 2 | default=.false., do_not_log=.true.) |
| 356 | 2 | CVMix_shear_is_used = (LMD94 .or. PP81) |
| 357 | 2 | end function CVMix_shear_is_used |
| 358 | ||
| 359 | !> Clear pointers and deallocate memory | |
| 360 | 0 | subroutine CVMix_shear_end(CS) |
| 361 | type(CVMix_shear_cs), intent(inout) :: CS !< Control structure for this module that | |
| 362 | !! will be deallocated in this subroutine | |
| 363 | 0 | if (CS%id_N2 > 0) deallocate(CS%N2) |
| 364 | 0 | if (CS%id_S2 > 0) deallocate(CS%S2) |
| 365 | 0 | if (CS%id_ri_grad > 0) deallocate(CS%ri_grad) |
| 366 | 0 | end subroutine CVMix_shear_end |
| 367 | ||
| 368 | 0 | end module MOM_CVMix_shear |