Skip to content

Commit e7d5e80

Browse files
committed
Merge pull request #60 from mnlevy1981/feature/more_efficient_tidal
Refactor cvmix_tidal to only compute vert_dep once
2 parents dc5038a + 7edab82 commit e7d5e80

File tree

6 files changed

+228
-83
lines changed

6 files changed

+228
-83
lines changed

reg_tests/tidal-Simmons/Simmons-test.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,4 @@ build
3636
run
3737

3838
# (2) Look at output
39-
ncdump -v Tdiff single_col.nc
39+
ncdump -v Mdiff,Tdiff single_col.nc

src/drivers/cvmix_tidal_Simmons.F90

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Subroutine cvmix_tidal_driver()
1919
cvmix_global_params_type
2020
use cvmix_tidal, only : cvmix_init_tidal, &
2121
cvmix_coeffs_tidal, &
22+
cvmix_compute_Simmons_invariant, &
2223
cvmix_tidal_params_type, &
2324
cvmix_get_tidal_str, &
2425
cvmix_get_tidal_real
@@ -42,7 +43,7 @@ Subroutine cvmix_tidal_driver()
4243
type(cvmix_global_params_type) :: CVmix_params
4344
type(cvmix_tidal_params_type) :: CVmix_Simmons_params
4445

45-
real(cvmix_r8), dimension(:,:,:), allocatable, target :: Tdiff
46+
real(cvmix_r8), dimension(:,:,:), allocatable, target :: Mdiff, Tdiff
4647

4748
! file index
4849
integer :: fid
@@ -118,9 +119,11 @@ Subroutine cvmix_tidal_driver()
118119
buoy(:,:,1) = cvmix_zero
119120

120121
! Allocate memory to store diffusivity values
122+
allocate(Mdiff(nlon, nlat, max_nlev+1))
121123
allocate(Tdiff(nlon, nlat, max_nlev+1))
122124
! Set diffusivity to _FillValue
123125
FillVal = 1e5_cvmix_r8
126+
Mdiff = FillVal
124127
Tdiff = FillVal
125128

126129
! Read in global data from grid file, physics file, and energy flux file
@@ -181,13 +184,18 @@ Subroutine cvmix_tidal_driver()
181184
call cvmix_put(CVmix_vars(i,j), 'lat', lat(i,j))
182185
call cvmix_put(CVmix_vars(i,j), 'lon', lon(i,j))
183186

184-
call cvmix_put(CVmix_params, 'max_nlev', max_nlev)
187+
call cvmix_put(CVmix_params, 'max_nlev', max_nlev)
188+
call cvmix_put(CVmix_params, 'Prandtl', 10._cvmix_r8)
185189
call cvmix_put(CVmix_params, 'fw_rho', 1e3_cvmix_r8)
190+
call cvmix_compute_Simmons_invariant(CVmix_vars(i,j), CVmix_params, &
191+
energy_flux(i,j), &
192+
CVmix_Simmons_params)
186193
! Point CVmix_vars values to memory allocated above
194+
CVmix_vars(i,j)%Mdiff_iface => Mdiff(i,j,1:nlev+1)
187195
CVmix_vars(i,j)%Tdiff_iface => Tdiff(i,j,1:nlev+1)
188196

189197
call cvmix_coeffs_tidal(CVmix_vars(i,j), CVmix_params, &
190-
energy_flux(i,j), CVmix_Simmons_params)
198+
CVmix_Simmons_params)
191199

192200
end if
193201
end do
@@ -205,7 +213,7 @@ Subroutine cvmix_tidal_driver()
205213
this_lat = CVmix_vars(lon_out, lat_out)%lat
206214
call cvmix_io_open(fid, "single_col.nc", "nc")
207215
call cvmix_output_write(fid, CVmix_vars(lon_out, lat_out), &
208-
(/"zw_iface", "Tdiff "/))
216+
(/"zw_iface", "Mdiff ", "Tdiff "/))
209217
if (this_lon.ge.0) then
210218
write(lonstr,"(F6.2,1X,A)") this_lon, "E"
211219
else
@@ -221,6 +229,9 @@ Subroutine cvmix_tidal_driver()
221229
call cvmix_output_write_att(fid, "column_lat", latstr)
222230

223231
! Variable Attributes
232+
call cvmix_output_write_att(fid, "long_name", "momentum diffusivity", &
233+
var_name="Mdiff")
234+
call cvmix_output_write_att(fid, "units", "m^2/s", var_name="Mdiff")
224235
call cvmix_output_write_att(fid, "long_name", "tracer diffusivity", &
225236
var_name="Tdiff")
226237
call cvmix_output_write_att(fid, "units", "m^2/s", var_name="Tdiff")
@@ -235,7 +246,15 @@ Subroutine cvmix_tidal_driver()
235246
end if
236247

237248
! Write diffusivity field to netcdf
238-
call cvmix_io_open(fid, "diff.nc", "nc")
249+
call cvmix_io_open(fid, "Mdiff.nc", "nc")
250+
call cvmix_output_write(fid, "Mdiff", (/"nlon ", "nlat ", "niface"/), &
251+
Mdiff, FillVal=FillVal)
252+
call cvmix_output_write_att(fid, "long_name", "momentum diffusivity", &
253+
var_name="Mdiff")
254+
call cvmix_output_write_att(fid, "units", "m^2/s", var_name="Mdiff")
255+
call cvmix_io_close(fid)
256+
257+
call cvmix_io_open(fid, "Tdiff.nc", "nc")
239258
call cvmix_output_write(fid, "Tdiff", (/"nlon ", "nlat ", "niface"/), &
240259
Tdiff, FillVal=FillVal)
241260
call cvmix_output_write_att(fid, "long_name", "tracer diffusivity", &

src/shared/cvmix_kinds_and_types.F90

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ module cvmix_kinds_and_types
101101
! Surface Stokes drift magnitude
102102
real(cvmix_r8) :: SurfaceStokesDrift
103103
! units: m/s
104+
! A time-invariant coefficient needed for Simmons, et al. tidal mixing
105+
real(cvmix_r8) :: SimmonsCoeff
104106

105107
! Values on interfaces (dimsize = nlev+1)
106108
! --------------------
@@ -125,9 +127,12 @@ module cvmix_kinds_and_types
125127
real(cvmix_r8), dimension(:), pointer :: ShearRichardson_iface => NULL()
126128
! units: unitless
127129

128-
! For tidal mixing, we need the squared buoyancy frequency
130+
! For tidal mixing, we need the squared buoyancy frequency and vertical
131+
! deposition function
129132
real(cvmix_r8), dimension(:), pointer :: SqrBuoyancyFreq_iface => NULL()
130133
! units: s^-2
134+
real(cvmix_r8), dimension(:), pointer :: VertDep_iface => NULL()
135+
! units: unitless
131136

132137
! For KPP, need to store non-local transport term
133138
real(cvmix_r8), dimension(:), pointer :: kpp_Tnonlocal_iface => NULL()

src/shared/cvmix_put_get.F90

Lines changed: 51 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module cvmix_put_get
44
!\newpage
55
! !MODULE: cvmix_put_get
66
!
7-
! !AUTHOR:
7+
! !AUTHOR:
88
! Michael N. Levy, NCAR ([email protected])
99
!
1010
! !DESCRIPTION:
@@ -57,7 +57,7 @@ subroutine cvmix_put_int(CVmix_vars, varname, val, nlev_in)
5757
!\\
5858
5959
! !USES:
60-
! Only those used by entire module.
60+
! Only those used by entire module.
6161

6262
! !INPUT PARAMETERS:
6363
character(len=*), intent(in) :: varname
@@ -72,7 +72,7 @@ subroutine cvmix_put_int(CVmix_vars, varname, val, nlev_in)
7272

7373
! Local variables
7474
integer :: nlev
75-
75+
7676
if (present(nlev_in)) then
7777
nlev = nlev_in
7878
else
@@ -85,7 +85,7 @@ subroutine cvmix_put_int(CVmix_vars, varname, val, nlev_in)
8585
print*, "You tried to set ", trim(varname)
8686
stop 1
8787
end if
88-
88+
8989
select case (trim(cvmix_att_name(varname)))
9090
case ('nlev')
9191
CVmix_vars%nlev = val
@@ -118,7 +118,7 @@ subroutine cvmix_put_real(CVmix_vars, varname, val, nlev_in)
118118
!\\
119119
120120
! !USES:
121-
! Only those used by entire module.
121+
! Only those used by entire module.
122122

123123
! !INPUT PARAMETERS:
124124
character(len=*), intent(in) :: varname
@@ -132,7 +132,7 @@ subroutine cvmix_put_real(CVmix_vars, varname, val, nlev_in)
132132

133133
! Local variables
134134
integer :: nlev
135-
135+
136136
if (present(nlev_in)) then
137137
nlev = nlev_in
138138
else
@@ -145,7 +145,7 @@ subroutine cvmix_put_real(CVmix_vars, varname, val, nlev_in)
145145
print*, "You tried to set ", trim(varname)
146146
stop 1
147147
end if
148-
148+
149149
select case (trim(cvmix_att_name(varname)))
150150
case ('OceanDepth')
151151
CVmix_vars%OceanDepth = val
@@ -170,10 +170,12 @@ subroutine cvmix_put_real(CVmix_vars, varname, val, nlev_in)
170170
CVmix_vars%LangmuirEnhancementFactor = val
171171
case ("SurfaceStokesDrift")
172172
CVmix_vars%SurfaceStokesDrift = val
173+
case ('SimmonsCoeff')
174+
CVmix_vars%SimmonsCoeff = val
173175

174176
case ("dzw")
175-
print*, "WARNING: you are setting the cell midpoint to midpoint", &
176-
"distance in all levels to a constant value"
177+
! print*, "WARNING: you are setting the cell midpoint to midpoint ", &
178+
! "distance in all levels to a constant value"
177179
if (.not.associated(CVmix_vars%dzw)) then
178180
allocate(CVmix_vars%dzw(nlev+1))
179181
end if
@@ -194,15 +196,15 @@ subroutine cvmix_put_real(CVmix_vars, varname, val, nlev_in)
194196
end if
195197
CVmix_vars%Sdiff_iface(:) = val
196198
case ("ShearRichardson_iface")
197-
print*, "WARNING: you are setting the Richardson number in all", &
198-
"levels to a constant value"
199+
! print*, "WARNING: you are setting the Richardson number in all ", &
200+
! "levels to a constant value"
199201
if (.not.associated(CVmix_vars%ShearRichardson_iface)) then
200202
allocate(CVmix_vars%ShearRichardson_iface(nlev+1))
201203
end if
202204
CVmix_vars%ShearRichardson_iface(:) = val
203205
case ("SqrBuoyancyFreq_iface")
204-
print*, "WARNING: you are setting the buoyancy in all levels to a", &
205-
"constant value"
206+
! print*, "WARNING: you are setting the buoyancy in all levels to a ", &
207+
! "constant value"
206208
if (.not.associated(CVmix_vars%SqrBuoyancyFreq_iface)) then
207209
allocate(CVmix_vars%SqrBuoyancyFreq_iface(nlev+1))
208210
end if
@@ -228,52 +230,57 @@ subroutine cvmix_put_real(CVmix_vars, varname, val, nlev_in)
228230
CVmix_vars%kpp_Snonlocal_iface(:) = val
229231

230232
case ("dzt")
231-
print*, "WARNING: you are setting the cell thickness in all levels", &
232-
"to a constant value"
233+
! print*, "WARNING: you are setting the cell thickness in all levels ", &
234+
! "to a constant value"
233235
if (.not.associated(CVmix_vars%dzt)) then
234236
allocate(CVmix_vars%dzt(nlev))
235237
end if
236238
CVmix_vars%dzt(:) = val
237239
case ("WaterDensity_cntr")
238-
print*, "WARNING: you are setting the density in all levels to a", &
239-
"constant value"
240+
! print*, "WARNING: you are setting the density in all levels to a ", &
241+
! "constant value"
240242
if (.not.associated(CVmix_vars%WaterDensity_cntr)) then
241243
allocate(CVmix_vars%WaterDensity_cntr(nlev))
242244
end if
243245
CVmix_vars%WaterDensity_cntr(:) = val
244246
case ("AdiabWaterDensity_cntr")
245-
print*, "WARNING: you are setting the adiabatic density in all", &
246-
"levels to a constant value"
247+
! print*, "WARNING: you are setting the adiabatic density in all ", &
248+
! "levels to a constant value"
247249
if (.not.associated(CVmix_vars%AdiabWaterDensity_cntr)) then
248250
allocate(CVmix_vars%AdiabWaterDensity_cntr(nlev))
249251
end if
250252
CVmix_vars%AdiabWaterDensity_cntr(:) = val
251253
case ("BulkRichardson_cntr")
252-
print*, "WARNING: you are setting the bulk Richardson number in all", &
253-
"levels to a constant value"
254+
! print*, "WARNING: you are setting the bulk Richardson number in all", &
255+
! " levels to a constant value"
254256
if (.not.associated(CVmix_vars%BulkRichardson_cntr)) then
255257
allocate(CVmix_vars%BulkRichardson_cntr(nlev))
256258
end if
257259
CVmix_vars%BulkRichardson_cntr(:) = val
258260
case ('strat_param_num')
259-
print*, "WARNING: you are setting the numerator of the", &
260-
"stratification parameter in all levels to a constant value"
261+
! print*, "WARNING: you are setting the numerator of the ", &
262+
! "stratification parameter in all levels to a constant value"
261263
if (.not.associated(CVmix_vars%strat_param_num)) then
262264
allocate(CVmix_vars%strat_param_num(nlev))
263265
end if
264266
CVmix_vars%strat_param_num(:) = val
265267
case ('strat_param_denom')
266-
print*, "WARNING: you are setting the denominator of the", &
267-
"stratification parameter in all levels to a constant value"
268+
! print*, "WARNING: you are setting the denominator of the ", &
269+
! "stratification parameter in all levels to a constant value"
268270
if (.not.associated(CVmix_vars%strat_param_denom)) then
269271
allocate(CVmix_vars%strat_param_denom(nlev))
270272
end if
271273
CVmix_vars%strat_param_denom(:) = val
274+
case ("VertDep_iface")
275+
if (.not.associated(CVmix_vars%VertDep_iface)) then
276+
allocate(CVmix_vars%VertDep_iface(nlev+1))
277+
end if
278+
CVmix_vars%VertDep_iface(:) = val
272279

273280
case default
274-
print*, "ERROR: ", trim(varname), " not a valid choice!"
281+
print*, "ERROR: ", trim(varname), " not a valid choice for cvmix_put!"
275282
stop 1
276-
283+
277284
end select
278285
!EOC
279286

@@ -292,7 +299,7 @@ subroutine cvmix_put_real_1D(CVmix_vars, varname, val, nlev_in)
292299
!\\
293300
294301
! !USES:
295-
! Only those used by entire module.
302+
! Only those used by entire module.
296303

297304
! !INPUT PARAMETERS:
298305
character(len=*), intent(in) :: varname
@@ -306,7 +313,7 @@ subroutine cvmix_put_real_1D(CVmix_vars, varname, val, nlev_in)
306313

307314
! Local variables
308315
integer :: nlev
309-
316+
310317
if (present(nlev_in)) then
311318
nlev = nlev_in
312319
else
@@ -319,7 +326,7 @@ subroutine cvmix_put_real_1D(CVmix_vars, varname, val, nlev_in)
319326
print*, "You tried to set ", trim(varname)
320327
stop 1
321328
end if
322-
329+
323330
select case (trim(cvmix_att_name(varname)))
324331
case ("zw_iface")
325332
if (.not.associated(CVmix_vars%zw_iface)) then
@@ -375,7 +382,11 @@ subroutine cvmix_put_real_1D(CVmix_vars, varname, val, nlev_in)
375382
allocate(CVmix_vars%kpp_Snonlocal_iface(nlev+1))
376383
end if
377384
CVmix_vars%kpp_Snonlocal_iface(:) = val
378-
385+
case ("VertDep_iface")
386+
if (.not.associated(CVmix_vars%VertDep_iface)) then
387+
allocate(CVmix_vars%VertDep_iface(nlev+1))
388+
end if
389+
CVmix_vars%VertDep_iface(:) = val
379390
case ("zt_cntr")
380391
if (.not.associated(CVmix_vars%zt_cntr)) then
381392
allocate(CVmix_vars%zt_cntr(nlev))
@@ -423,9 +434,9 @@ subroutine cvmix_put_real_1D(CVmix_vars, varname, val, nlev_in)
423434
CVmix_vars%Vy_cntr(:) = val
424435

425436
case default
426-
print*, "ERROR: ", trim(varname), " not a valid choice!"
437+
print*, "ERROR: ", trim(varname), " not a valid choice for cvmix_put!"
427438
stop 1
428-
439+
429440
end select
430441

431442
!EOC
@@ -445,7 +456,7 @@ subroutine cvmix_put_global_params_int(CVmix_params, varname, val)
445456
!\\
446457
447458
! !USES:
448-
! Only those used by entire module.
459+
! Only those used by entire module.
449460

450461
! !INPUT PARAMETERS:
451462
character(len=*), intent(in) :: varname
@@ -459,11 +470,11 @@ subroutine cvmix_put_global_params_int(CVmix_params, varname, val)
459470
select case (trim(varname))
460471
case ('max_nlev')
461472
CVmix_params%max_nlev = val
462-
473+
463474
case default
464475
print*, "ERROR: ", trim(varname), " not a valid choice!"
465476
stop 1
466-
477+
467478
end select
468479
!EOC
469480

@@ -482,7 +493,7 @@ subroutine cvmix_put_global_params_real(CVmix_params, varname, val)
482493
!\\
483494
484495
! !USES:
485-
! Only those used by entire module.
496+
! Only those used by entire module.
486497

487498
! !INPUT PARAMETERS:
488499
character(len=*), intent(in) :: varname
@@ -494,17 +505,17 @@ subroutine cvmix_put_global_params_real(CVmix_params, varname, val)
494505
!BOC
495506

496507
select case (trim(varname))
497-
case ('prandtl')
508+
case ('prandtl','Prandtl')
498509
CVmix_params%prandtl = val
499510
case ('fw_rho','FreshWaterDensity')
500511
CVmix_params%FreshWaterDensity = val
501512
case ('sw_rho','SaltWaterDensity')
502513
CVmix_params%SaltWaterDensity= val
503-
514+
504515
case default
505516
print*, "ERROR: ", trim(varname), " not a valid choice!"
506517
stop 1
507-
518+
508519
end select
509520
!EOC
510521

0 commit comments

Comments
 (0)