@@ -52,6 +52,14 @@ module MOM_lateral_mixing_coeffs
52
52
! ! as the vertical structure of thickness diffusivity.
53
53
logical :: kdgl90_use_ebt_struct ! < If true, uses the equivalent barotropic structure
54
54
! ! as the vertical structure of diffusivity in the GL90 scheme.
55
+ logical :: kdgl90_use_sqg_struct ! < If true, uses the surface quasigeostrophic structure
56
+ ! ! as the vertical structure of diffusivity in the GL90 scheme.
57
+ logical :: khth_use_sqg_struct ! < If true, uses the surface quasigeostrophic structure
58
+ ! ! as the vertical structure of thickness diffusivity.
59
+ logical :: khtr_use_ebt_struct ! < If true, uses the equivalent barotropic structure
60
+ ! ! as the vertical structure of tracer diffusivity.
61
+ logical :: khtr_use_sqg_struct ! < If true, uses the surface quasigeostrophic structure
62
+ ! ! as the vertical structure of tracer diffusivity.
55
63
logical :: calculate_cg1 ! < If true, calls wave_speed() to calculate the first
56
64
! ! baroclinic wave speed and populate CS%cg1.
57
65
! ! This parameter is set depending on other parameters.
@@ -117,6 +125,9 @@ module MOM_lateral_mixing_coeffs
117
125
real , allocatable :: ebt_struct(:,:,:) ! < EBT vertical structure to scale diffusivities with [nondim]
118
126
real , allocatable :: sqg_struct(:,:,:) ! < SQG vertical structure to scale diffusivities with [nondim]
119
127
real , allocatable :: BS_struct(:,:,:) ! < Vertical structure function used in backscatter [nondim]
128
+ real , allocatable :: khth_struct(:,:,:) ! < Vertical structure function used in thickness diffusivity [nondim]
129
+ real , allocatable :: khtr_struct(:,:,:) ! < Vertical structure function used in tracer diffusivity [nondim]
130
+ real , allocatable :: kdgl90_struct(:,:,:) ! < Vertical structure function used in GL90 diffusivity [nondim]
120
131
real :: BS_EBT_power ! < Power to raise EBT vertical structure to. Default 0.0.
121
132
real :: sqg_expo ! < Exponent for SQG vertical structure [nondim]. Default 0.0
122
133
logical :: BS_use_sqg ! < If true, use sqg_stuct for backscatter vertical structure.
@@ -168,7 +179,8 @@ module MOM_lateral_mixing_coeffs
168
179
integer :: id_N2_u=- 1 , id_N2_v=- 1 , id_S2_u=- 1 , id_S2_v=- 1
169
180
integer :: id_dzu=- 1 , id_dzv=- 1 , id_dzSxN=- 1 , id_dzSyN=- 1
170
181
integer :: id_Rd_dx=- 1 , id_KH_u_QG = - 1 , id_KH_v_QG = - 1
171
- integer :: id_sqg_struct=- 1 , id_BS_struct=- 1
182
+ integer :: id_sqg_struct=- 1 , id_BS_struct=- 1 , id_khth_struct=- 1 , id_khtr_struct=- 1
183
+ integer :: id_kdgl90_struct=- 1
172
184
type (diag_ctrl), pointer :: diag ! < A structure that is used to regulate the
173
185
! ! timing of diagnostic output.
174
186
! >@}
@@ -220,14 +232,15 @@ subroutine calc_depth_function(G, CS)
220
232
end subroutine calc_depth_function
221
233
222
234
! > Calculates and stores the non-dimensional resolution functions
223
- subroutine calc_resoln_function (h , tv , G , GV , US , CS , MEKE )
235
+ subroutine calc_resoln_function (h , tv , G , GV , US , CS , MEKE , dt )
224
236
type (ocean_grid_type), intent (inout ) :: G ! < Ocean grid structure
225
237
type (verticalGrid_type), intent (in ) :: GV ! < Vertical grid structure
226
238
real , dimension (SZI_(G),SZJ_(G),SZK_(GV)), intent (in ) :: h ! < Layer thickness [H ~> m or kg m-2]
227
239
type (thermo_var_ptrs), intent (in ) :: tv ! < Thermodynamic variables
228
240
type (unit_scale_type), intent (in ) :: US ! < A dimensional unit scaling type
229
241
type (VarMix_CS), intent (inout ) :: CS ! < Variable mixing control structure
230
242
type (MEKE_type), intent (in ) :: MEKE ! < MEKE struct
243
+ real , intent (in ) :: dt ! < Time increment [T ~> s]
231
244
232
245
! Local variables
233
246
! Depending on the power-function being used, dimensional rescaling may be limited, so some
@@ -237,7 +250,6 @@ subroutine calc_resoln_function(h, tv, G, GV, US, CS, MEKE)
237
250
real :: cg1_v ! The gravity wave speed interpolated to v points [L T-1 ~> m s-1] or [m s-1].
238
251
real :: dx_term ! A term in the denominator [L2 T-2 ~> m2 s-2] or [m2 s-2]
239
252
integer :: power_2
240
- real :: dt ! < Time increment [T ~> s]
241
253
integer :: is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz
242
254
integer :: i, j, k
243
255
is = G% isc ; ie = G% iec ; js = G% jsc ; je = G% jec ; nz = GV% ke
@@ -249,7 +261,8 @@ subroutine calc_resoln_function(h, tv, G, GV, US, CS, MEKE)
249
261
if (CS% calculate_cg1) then
250
262
if (.not. allocated (CS% cg1)) call MOM_error(FATAL, &
251
263
" calc_resoln_function: %cg1 is not associated with Resoln_scaled_Kh." )
252
- if (CS% khth_use_ebt_struct .or. CS% kdgl90_use_ebt_struct .or. CS% BS_EBT_power> 0 .) then
264
+ if (CS% khth_use_ebt_struct .or. CS% kdgl90_use_ebt_struct &
265
+ .or. CS% khtr_use_ebt_struct .or. CS% BS_EBT_power> 0 .) then
253
266
if (.not. allocated (CS% ebt_struct)) call MOM_error(FATAL, &
254
267
" calc_resoln_function: %ebt_struct is not associated with RESOLN_USE_EBT." )
255
268
if (CS% Resoln_use_ebt) then
@@ -269,12 +282,17 @@ subroutine calc_resoln_function(h, tv, G, GV, US, CS, MEKE)
269
282
call create_group_pass(CS% pass_cg1, CS% cg1, G% Domain)
270
283
call do_group_pass(CS% pass_cg1, G% Domain)
271
284
endif
272
- if (CS% sqg_expo> 0.0 ) then
285
+ if (CS% BS_use_sqg .or. CS% khth_use_sqg_struct .or. CS% khtr_use_sqg_struct &
286
+ .or. CS% kdgl90_use_sqg_struct .or. CS% id_sqg_struct> 0 ) then
273
287
call calc_sqg_struct(h, tv, G, GV, US, CS, dt, MEKE)
274
288
call pass_var(CS% sqg_struct, G% Domain)
275
289
endif
276
290
277
- if (CS% BS_EBT_power> 0 .) then
291
+ if (CS% BS_EBT_power> 0 . .and. CS% BS_use_sqg) then
292
+ call MOM_error(FATAL, &
293
+ " calc_resoln_function: BS_EBT_POWER>0. &
294
+ and BS_USE_SQG=True cannot be set together" )
295
+ elseif (CS% BS_EBT_power> 0 .) then
278
296
do k= 1 ,nz ; do j= G% jsd,G% jed ; do i= G% isd,G% ied
279
297
CS% BS_struct(i,j,k) = CS% ebt_struct(i,j,k)** CS% BS_EBT_power
280
298
enddo ; enddo ; enddo
@@ -284,6 +302,48 @@ subroutine calc_resoln_function(h, tv, G, GV, US, CS, MEKE)
284
302
enddo ; enddo ; enddo
285
303
endif
286
304
305
+ if (CS% khth_use_ebt_struct .and. CS% khth_use_sqg_struct) then
306
+ call MOM_error(FATAL, &
307
+ " calc_resoln_function: Only one of KHTH_USE_EBT_STRUCT &
308
+ and KHTH_USE_SQG_STRUCT can be true" )
309
+ elseif (CS% khth_use_ebt_struct) then
310
+ do k= 1 ,nz ; do j= G% jsd,G% jed ; do i= G% isd,G% ied
311
+ CS% khth_struct(i,j,k) = CS% ebt_struct(i,j,k)
312
+ enddo ; enddo ; enddo
313
+ elseif (CS% khth_use_sqg_struct) then
314
+ do k= 1 ,nz ; do j= G% jsd,G% jed ; do i= G% isd,G% ied
315
+ CS% khth_struct(i,j,k) = CS% sqg_struct(i,j,k)
316
+ enddo ; enddo ; enddo
317
+ endif
318
+
319
+ if (CS% khtr_use_ebt_struct .and. CS% khtr_use_sqg_struct) then
320
+ call MOM_error(FATAL, &
321
+ " calc_resoln_function: Only one of KHTR_USE_EBT_STRUCT &
322
+ and KHTR_USE_SQG_STRUCT can be true" )
323
+ elseif (CS% khtr_use_ebt_struct) then
324
+ do k= 1 ,nz ; do j= G% jsd,G% jed ; do i= G% isd,G% ied
325
+ CS% khtr_struct(i,j,k) = CS% ebt_struct(i,j,k)
326
+ enddo ; enddo ; enddo
327
+ elseif (CS% khtr_use_sqg_struct) then
328
+ do k= 1 ,nz ; do j= G% jsd,G% jed ; do i= G% isd,G% ied
329
+ CS% khtr_struct(i,j,k) = CS% sqg_struct(i,j,k)
330
+ enddo ; enddo ; enddo
331
+ endif
332
+
333
+ if (CS% kdgl90_use_ebt_struct .and. CS% kdgl90_use_sqg_struct) then
334
+ call MOM_error(FATAL, &
335
+ " calc_resoln_function: Only one of KD_GL90_USE_EBT_STRUCT &
336
+ and KD_GL90_USE_SQG_STRUCT can be true" )
337
+ elseif (CS% kdgl90_use_ebt_struct) then
338
+ do k= 1 ,nz ; do j= G% jsd,G% jed ; do i= G% isd,G% ied
339
+ CS% kdgl90_struct(i,j,k) = CS% ebt_struct(i,j,k)
340
+ enddo ; enddo ; enddo
341
+ elseif (CS% kdgl90_use_sqg_struct) then
342
+ do k= 1 ,nz ; do j= G% jsd,G% jed ; do i= G% isd,G% ied
343
+ CS% kdgl90_struct(i,j,k) = CS% sqg_struct(i,j,k)
344
+ enddo ; enddo ; enddo
345
+ endif
346
+
287
347
! Calculate and store the ratio between deformation radius and grid-spacing
288
348
! at h-points [nondim].
289
349
if (CS% calculate_rd_dx) then
@@ -478,6 +538,9 @@ subroutine calc_resoln_function(h, tv, G, GV, US, CS, MEKE)
478
538
if (query_averaging_enabled(CS% diag)) then
479
539
if (CS% id_Res_fn > 0 ) call post_data(CS% id_Res_fn, CS% Res_fn_h, CS% diag)
480
540
if (CS% id_BS_struct > 0 ) call post_data(CS% id_BS_struct, CS% BS_struct, CS% diag)
541
+ if (CS% id_khth_struct > 0 ) call post_data(CS% id_khth_struct, CS% khth_struct, CS% diag)
542
+ if (CS% id_khtr_struct > 0 ) call post_data(CS% id_khtr_struct, CS% khtr_struct, CS% diag)
543
+ if (CS% id_kdgl90_struct > 0 ) call post_data(CS% id_kdgl90_struct, CS% kdgl90_struct, CS% diag)
481
544
endif
482
545
483
546
if (CS% debug) then
@@ -534,18 +597,24 @@ subroutine calc_sqg_struct(h, tv, G, GV, US, CS, dt, MEKE)
534
597
do j= js,je ; do i= is,ie
535
598
Le(i,j) = MEKE% Le(i,j)
536
599
f(i,j) = max (0.25 * abs (G% CoriolisBu(I,J) + G% CoriolisBu(I-1 ,J-1 ) + &
537
- G% CoriolisBu(I-1 ,J) + G% CoriolisBu(I,J-1 )), 1.0e-8 )
600
+ G% CoriolisBu(I-1 ,J) + G% CoriolisBu(I,J-1 )), 1.0e-8 / US % T_to_s )
538
601
enddo ; enddo
539
602
else
540
603
do j= js,je ; do i= is,ie
541
604
Le(i,j) = sqrt (G% areaT(i,j))
542
605
f(i,j) = max (0.25 * abs (G% CoriolisBu(I,J) + G% CoriolisBu(I-1 ,J-1 ) + &
543
- G% CoriolisBu(I-1 ,J) + G% CoriolisBu(I,J-1 )), 1.0e-8 )
606
+ G% CoriolisBu(I-1 ,J) + G% CoriolisBu(I,J-1 )), 1.0e-8 * US % T_to_s )
544
607
enddo ; enddo
545
608
endif
609
+ if (CS% debug) then
610
+ call hchksum(Le, ' SQG length scale' , G% HI, unscale= US% L_to_m)
611
+ call hchksum(f, ' Coriolis at h point' , G% HI, unscale= US% s_to_T)
612
+ call uvchksum( ' MEKE LmixScale' , dzu, dzv, G% HI, unscale= US% Z_to_m, scalar_pair= .true. )
613
+ endif
546
614
do k= 2 ,nz ; do j= js,je ; do i= is,ie
547
615
N2 = max (0.25 * (N2_u(I-1 ,j,k) + N2_u(I,j,k) + N2_v(i,J-1 ,k) + N2_v(i,J,k)),0.0 )
548
- dzc = 0.25 * (dzu(I-1 ,j,k) + dzu(I,j,k) + dzv(i,J-1 ,k) + dzv(i,J,k))* N2** 0.5 / f(i,j)
616
+ dzc = 0.25 * (dzu(I-1 ,j,k) + dzu(I,j,k) + dzv(i,J-1 ,k) + dzv(i,J,k)) * &
617
+ N2** 0.5 / f(i,j)* US% Z_to_L
549
618
! dzs = -N2**0.5/f(i,j)*dzc
550
619
CS% sqg_struct(i,j,k) = CS% sqg_struct(i,j,k-1 )* exp (- CS% sqg_expo* dzc/ Le(i,j))
551
620
enddo ; enddo ; enddo
@@ -1353,19 +1422,33 @@ subroutine VarMix_init(Time, G, GV, US, param_file, diag, CS)
1353
1422
" If true, the SQG vertical structure is used for backscatter " // &
1354
1423
" on the condition that BS_EBT_power=0" , &
1355
1424
default= .false. )
1356
- if (CS% BS_EBT_power> 0 .) CS% BS_use_sqg = .false.
1357
1425
call get_param(param_file, mdl, " SQG_EXPO" , CS% sqg_expo, &
1358
1426
" Nondimensional exponent coeffecient of the SQG mode " // &
1359
- " that is used for the vertical struture of diffusivities." , units= " nondim" , default= 0.0 )
1360
- if (CS% sqg_expo== 0 .) CS% BS_use_sqg = .false.
1427
+ " that is used for the vertical struture of diffusivities." , units= " nondim" , default= 1.0 )
1361
1428
call get_param(param_file, mdl, " KHTH_USE_EBT_STRUCT" , CS% khth_use_ebt_struct, &
1362
1429
" If true, uses the equivalent barotropic structure " // &
1363
1430
" as the vertical structure of thickness diffusivity." ,&
1364
1431
default= .false. )
1432
+ call get_param(param_file, mdl, " KHTH_USE_SQG_STRUCT" , CS% khth_use_sqg_struct, &
1433
+ " If true, uses the surface quasigeostrophic structure " // &
1434
+ " as the vertical structure of thickness diffusivity." ,&
1435
+ default= .false. )
1436
+ call get_param(param_file, mdl, " KHTR_USE_EBT_STRUCT" , CS% khtr_use_ebt_struct, &
1437
+ " If true, uses the equivalent barotropic structure " // &
1438
+ " as the vertical structure of tracer diffusivity." ,&
1439
+ default= .false. )
1440
+ call get_param(param_file, mdl, " KHTR_USE_SQG_STRUCT" , CS% khtr_use_sqg_struct, &
1441
+ " If true, uses the surface quasigeostrophic structure " // &
1442
+ " as the vertical structure of tracer diffusivity." ,&
1443
+ default= .false. )
1365
1444
call get_param(param_file, mdl, " KD_GL90_USE_EBT_STRUCT" , CS% kdgl90_use_ebt_struct, &
1366
1445
" If true, uses the equivalent barotropic structure " // &
1367
1446
" as the vertical structure of diffusivity in the GL90 scheme." ,&
1368
1447
default= .false. )
1448
+ call get_param(param_file, mdl, " KD_GL90_USE_SQG_STRUCT" , CS% kdgl90_use_sqg_struct, &
1449
+ " If true, uses the equivalent barotropic structure " // &
1450
+ " as the vertical structure of diffusivity in the GL90 scheme." ,&
1451
+ default= .false. )
1369
1452
call get_param(param_file, mdl, " KHTH_SLOPE_CFF" , KhTh_Slope_Cff, &
1370
1453
" The nondimensional coefficient in the Visbeck formula " // &
1371
1454
" for the interface depth diffusivity" , units= " nondim" , default= 0.0 )
@@ -1409,7 +1492,7 @@ subroutine VarMix_init(Time, G, GV, US, param_file, diag, CS)
1409
1492
endif
1410
1493
1411
1494
if (CS% Resoln_use_ebt .or. CS% khth_use_ebt_struct .or. CS% kdgl90_use_ebt_struct &
1412
- .or. CS% BS_EBT_power> 0 .) then
1495
+ .or. CS% BS_EBT_power> 0 . .or. CS % khtr_use_ebt_struct ) then
1413
1496
in_use = .true.
1414
1497
call get_param(param_file, mdl, " RESOLN_N2_FILTER_DEPTH" , N2_filter_depth, &
1415
1498
" The depth below which N2 is monotonized to avoid stratification " // &
@@ -1418,13 +1501,23 @@ subroutine VarMix_init(Time, G, GV, US, param_file, diag, CS)
1418
1501
units= " m" , default=- 1.0 , scale= GV% m_to_H)
1419
1502
allocate (CS% ebt_struct(isd:ied,jsd:jed,GV% ke), source= 0.0 )
1420
1503
endif
1421
- if (CS% sqg_expo> 0.0 ) then
1422
- allocate (CS% sqg_struct(isd:ied,jsd:jed,GV% ke), source= 0.0 )
1423
- endif
1504
+
1424
1505
1425
1506
allocate (CS% BS_struct(isd:ied,jsd:jed,GV% ke), source= 0.0 )
1426
1507
CS% BS_struct(:,:,:) = 1.0
1427
1508
1509
+ if (CS% khth_use_ebt_struct .or. CS% khth_use_sqg_struct) then
1510
+ allocate (CS% khth_struct(isd:ied, jsd:jed, gv% ke), source= 0.0 )
1511
+ endif
1512
+
1513
+ if (CS% khtr_use_ebt_struct .or. CS% khtr_use_sqg_struct) then
1514
+ allocate (CS% khtr_struct(isd:ied, jsd:jed, gv% ke), source= 0.0 )
1515
+ endif
1516
+
1517
+ if (CS% kdgl90_use_ebt_struct .or. CS% kdgl90_use_sqg_struct) then
1518
+ allocate (CS% kdgl90_struct(isd:ied, jsd:jed, gv% ke), source= 0.0 )
1519
+ endif
1520
+
1428
1521
if (CS% use_stored_slopes) then
1429
1522
if (KhTr_Slope_Cff> 0 . .or. KhTh_Slope_Cff> 0 .) then
1430
1523
call get_param(param_file, mdl, " VISBECK_MAX_SLOPE" , CS% Visbeck_S_max, &
@@ -1520,15 +1613,29 @@ subroutine VarMix_init(Time, G, GV, US, param_file, diag, CS)
1520
1613
' m2' , conversion= US% L_to_m** 2 )
1521
1614
endif
1522
1615
1523
- if (CS% sqg_expo> 0.0 ) then
1524
- CS% id_sqg_struct = register_diag_field(' ocean_model' , ' sqg_struct' , diag% axesTl, Time, &
1616
+ CS% id_sqg_struct = register_diag_field(' ocean_model' , ' sqg_struct' , diag% axesTl, Time, &
1525
1617
' Vertical structure of SQG mode' , ' nondim' )
1618
+ if (CS% BS_use_sqg .or. CS% khth_use_sqg_struct .or. CS% khtr_use_sqg_struct &
1619
+ .or. CS% kdgl90_use_sqg_struct .or. CS% id_sqg_struct> 0 ) then
1620
+ allocate (CS% sqg_struct(isd:ied,jsd:jed,GV% ke), source= 0.0 )
1526
1621
endif
1527
1622
1528
1623
CS% id_BS_struct = register_diag_field(' ocean_model' , ' BS_struct' , diag% axesTl, Time, &
1529
1624
' Vertical structure of backscatter' , ' nondim' )
1625
+ if (CS% khth_use_ebt_struct .or. CS% khth_use_sqg_struct) then
1626
+ CS% id_khth_struct = register_diag_field(' ocean_model' , ' khth_struct' , diag% axesTl, Time, &
1627
+ ' Vertical structure of thickness diffusivity' , ' nondim' )
1628
+ endif
1629
+ if (CS% khtr_use_ebt_struct .or. CS% khtr_use_sqg_struct) then
1630
+ CS% id_khtr_struct = register_diag_field(' ocean_model' , ' khtr_struct' , diag% axesTl, Time, &
1631
+ ' Vertical structure of tracer diffusivity' , ' nondim' )
1632
+ endif
1633
+ if (CS% kdgl90_use_ebt_struct .or. CS% kdgl90_use_sqg_struct) then
1634
+ CS% id_kdgl90_struct = register_diag_field(' ocean_model' , ' kdgl90_struct' , diag% axesTl, Time, &
1635
+ ' Vertical structure of GL90 diffusivity' , ' nondim' )
1636
+ endif
1530
1637
1531
- if ((CS% calculate_Eady_growth_rate .and. CS% use_stored_slopes) .or. (CS % sqg_expo > 0.0 ) ) then
1638
+ if ((CS% calculate_Eady_growth_rate .and. CS% use_stored_slopes) ) then
1532
1639
CS% id_N2_u = register_diag_field(' ocean_model' , ' N2_u' , diag% axesCui, Time, &
1533
1640
' Square of Brunt-Vaisala frequency, N^2, at u-points, as used in Visbeck et al.' , &
1534
1641
' s-2' , conversion= (US% L_to_Z* US% s_to_T)** 2 )
@@ -1780,10 +1887,13 @@ end subroutine VarMix_init
1780
1887
subroutine VarMix_end (CS )
1781
1888
type (VarMix_CS), intent (inout ) :: CS
1782
1889
1783
- if (CS% Resoln_use_ebt .or. CS% khth_use_ebt_struct .or. CS% kdgl90_use_ebt_struct .or. CS % BS_EBT_power > 0 .) &
1784
- deallocate (CS% ebt_struct)
1785
- if (CS% sqg_expo > 0.0 ) deallocate (CS% sqg_struct)
1890
+ if (CS% Resoln_use_ebt .or. CS% khth_use_ebt_struct .or. CS% kdgl90_use_ebt_struct &
1891
+ .or. CS % BS_EBT_power > 0 . .or. CS % khtr_use_ebt_struct) deallocate (CS% ebt_struct)
1892
+ if (allocated ( CS% sqg_struct) ) deallocate (CS% sqg_struct)
1786
1893
if (allocated (CS% BS_struct)) deallocate (CS% BS_struct)
1894
+ if (CS% khth_use_ebt_struct .or. CS% khth_use_sqg_struct) deallocate (CS% khth_struct)
1895
+ if (CS% khtr_use_ebt_struct .or. CS% khtr_use_sqg_struct) deallocate (CS% khtr_struct)
1896
+ if (CS% kdgl90_use_ebt_struct .or. CS% kdgl90_use_sqg_struct) deallocate (CS% kdgl90_struct)
1787
1897
1788
1898
if (CS% use_stored_slopes .or. CS% sqg_expo> 0.0 ) then
1789
1899
deallocate (CS% slope_x)
0 commit comments