MOM6
SCM_CVmix_tests.F90
Go to the documentation of this file.
1 !> Initial conditions and forcing for the single column model (SCM) CVmix
2 !! test set.
4 
5 ! This file is part of MOM6. See LICENSE.md for the license.
6 
7 use mom_error_handler, only : mom_error, fatal
10 use mom_grid, only : ocean_grid_type
13 use mom_time_manager, only : time_type, operator(+), operator(/), get_time,&
14  time_type_to_real
16 implicit none ; private
17 
18 #include <MOM_memory.h>
19 
24 public scm_cvmix_tests_cs
25 
26 !> Container for surface forcing parameters
28 private
29  logical :: usewindstress !< True to use wind stress
30  logical :: useheatflux !< True to use heat flux
31  logical :: useevaporation !< True to use evaporation
32  logical :: usediurnalsw !< True to use diurnal sw radiation
33  real :: tau_x !< (Constant) Wind stress, X (Pa)
34  real :: tau_y !< (Constant) Wind stress, Y (Pa)
35  real :: surf_hf !< (Constant) Heat flux (m K s^{-1})
36  real :: surf_evap !< (Constant) Evaporation rate (m/s)
37  real :: max_sw !< maximum of diurnal sw radiation (m K s^{-1})
38  real,public :: rho0 !< reference density copied for easy passing
39 end type
40 
41 ! This include declares and sets the variable "version".
42 #include "version_variable.h"
43 
44 character(len=40) :: mdl = "SCM_CVmix_tests" ! This module's name.
45 
46 contains
47 
48 !> Initializes temperature and salinity for the SCM CVmix test example
49 subroutine scm_cvmix_tests_ts_init(T, S, h, G, GV, param_file, just_read_params)
50  real, dimension(NIMEM_,NJMEM_, NKMEM_), intent(out) :: T !< Potential temperature (degC)
51  real, dimension(NIMEM_,NJMEM_, NKMEM_), intent(out) :: S !< Salinity (psu)
52  real, dimension(NIMEM_,NJMEM_, NKMEM_), intent(in) :: h !< Layer thickness (m or Pa)
53  type(ocean_grid_type), intent(in) :: G !< Grid structure
54  type(verticalgrid_type), intent(in) :: GV!< Vertical grid structure
55  type(param_file_type), intent(in) :: param_file !< Input parameter structure
56  logical, optional, intent(in) :: just_read_params !< If present and true, this call will
57  !! only read parameters without changing h.
58  ! Local variables
59  real :: eta(szk_(g)+1) ! The 1-d nominal positions of the interfaces.
60  real :: UpperLayerTempMLD !< Upper layer Temp MLD thickness (m)
61  real :: UpperLayerSaltMLD !< Upper layer Salt MLD thickness (m)
62  real :: UpperLayerTemp !< Upper layer temperature (SST if thickness 0) (deg C)
63  real :: UpperLayerSalt !< Upper layer salinity (SSS if thickness 0) (PPT)
64  real :: LowerLayerTemp !< Temp at top of lower layer (deg C)
65  real :: LowerLayerSalt !< Salt at top of lower layer (PPT)
66  real :: LowerLayerdTdz !< Temp gradient in lower layer (deg C m^{-1})
67  real :: LowerLayerdSdz !< Salt gradient in lower layer (PPT m^{-1})
68  real :: zC, DZ
69  logical :: just_read ! If true, just read parameters but set nothing.
70  integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz
71 
72  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
73  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
74 
75 
76  just_read = .false. ; if (present(just_read_params)) just_read = just_read_params
77 
78  if (.not.just_read) call log_version(param_file, mdl, version)
79  call get_param(param_file, mdl,"SCM_TEMP_MLD",upperlayertempmld, &
80  'Initial temp mixed layer depth', units='m',default=0.0, do_not_log=just_read)
81  call get_param(param_file, mdl,"SCM_SALT_MLD",upperlayersaltmld, &
82  'Initial salt mixed layer depth', units='m',default=0.0, do_not_log=just_read)
83  call get_param(param_file, mdl,"SCM_L1_SALT",upperlayersalt, &
84  'Layer 2 surface salinity', units='1e-3',default=35.0, do_not_log=just_read)
85  call get_param(param_file, mdl,"SCM_L1_TEMP",upperlayertemp, &
86  'Layer 1 surface temperature', units='C', default=20.0, do_not_log=just_read)
87  call get_param(param_file, mdl,"SCM_L2_SALT",lowerlayersalt, &
88  'Layer 2 surface salinity', units='1e-3',default=35.0, do_not_log=just_read)
89  call get_param(param_file, mdl,"SCM_L2_TEMP",lowerlayertemp, &
90  'Layer 2 surface temperature', units='C', default=20.0, do_not_log=just_read)
91  call get_param(param_file, mdl,"SCM_L2_DTDZ",lowerlayerdtdz, &
92  'Initial temperature stratification in layer 2', &
93  units='C/m', default=0.00, do_not_log=just_read)
94  call get_param(param_file, mdl,"SCM_L2_DSDZ",lowerlayerdsdz, &
95  'Initial salinity stratification in layer 2', &
96  units='PPT/m', default=0.00, do_not_log=just_read)
97 
98  if (just_read) return ! All run-time parameters have been read, so return.
99 
100  do j=js,je ; do i=is,ie
101  eta(1) = 0. ! Reference to surface
102  do k=1,nz
103  eta(k+1) = eta(k) - h(i,j,k)*gv%H_to_m ! Interface below layer (in m)
104  zc = 0.5*( eta(k) + eta(k+1) ) ! Z of middle of layer (in m)
105  dz = min(0., zc+upperlayertempmld)
106  if (dz.ge.0.0) then ! in Layer 1
107  t(i,j,k) = upperlayertemp
108  else ! in Layer 2
109  t(i,j,k) = lowerlayertemp + lowerlayerdtdz * dz
110  endif
111  dz = min(0., zc+upperlayersaltmld)
112  if (dz.ge.0.0) then ! in Layer 1
113  s(i,j,k) = upperlayersalt
114  else ! in Layer 2
115  s(i,j,k) = lowerlayersalt + lowerlayerdsdz * dz
116  endif
117  enddo ! k
118  enddo ; enddo
119 
120 end subroutine scm_cvmix_tests_ts_init
121 
122 !> Initializes surface forcing for the CVmix test case suite
123 subroutine scm_cvmix_tests_surface_forcing_init(Time, G, param_file, CS)
124  type(time_type), intent(in) :: Time !< Time
125  type(ocean_grid_type), intent(in) :: G !< Grid structure
126  type(param_file_type), intent(in) :: param_file !< Input parameter structure
127  type(scm_cvmix_tests_cs), pointer :: CS !< Parameter container
128 
129 ! This include declares and sets the variable "version".
130 #include "version_variable.h"
131 
132  if (associated(cs)) then
133  call mom_error(fatal, "SCM_CVmix_tests_surface_forcing_init called with an associated "// &
134  "control structure.")
135  return
136  endif
137  allocate(cs)
138 
139  ! Read all relevant parameters and write them to the model log.
140  call log_version(param_file, mdl, version, "")
141  call get_param(param_file, mdl, "SCM_USE_WIND_STRESS", &
142  cs%UseWindStress, "Wind Stress switch "// &
143  "used in the SCM CVmix surface forcing.", &
144  units='', default=.false.)
145  call get_param(param_file, mdl, "SCM_USE_HEAT_FLUX", &
146  cs%UseHeatFlux, "Heat flux switch "// &
147  "used in the SCM CVmix test surface forcing.", &
148  units='', default=.false.)
149  call get_param(param_file, mdl, "SCM_USE_EVAPORATION", &
150  cs%UseEvaporation, "Evaporation switch "// &
151  "used in the SCM CVmix test surface forcing.", &
152  units='', default=.false.)
153  call get_param(param_file, mdl, "SCM_USE_DIURNAL_SW", &
154  cs%UseDiurnalSW, "Diurnal sw radation switch "// &
155  "used in the SCM CVmix test surface forcing.", &
156  units='', default=.false.)
157  if (cs%UseWindStress) then
158  call get_param(param_file, mdl, "SCM_TAU_X", &
159  cs%tau_x, "Constant X-dir wind stress "// &
160  "used in the SCM CVmix test surface forcing.", &
161  units='N/m2', fail_if_missing=.true.)
162  call get_param(param_file, mdl, "SCM_TAU_Y", &
163  cs%tau_y, "Constant y-dir wind stress "// &
164  "used in the SCM CVmix test surface forcing.", &
165  units='N/m2', fail_if_missing=.true.)
166  endif
167  if (cs%UseHeatFlux) then
168  call get_param(param_file, mdl, "SCM_HEAT_FLUX", &
169  cs%surf_HF, "Constant surface heat flux "// &
170  "used in the SCM CVmix test surface forcing.", &
171  units='m K/s', fail_if_missing=.true.)
172  endif
173  if (cs%UseEvaporation) then
174  call get_param(param_file, mdl, "SCM_EVAPORATION", &
175  cs%surf_evap, "Constant surface evaporation "// &
176  "used in the SCM CVmix test surface forcing.", &
177  units='m/s', fail_if_missing=.true.)
178  endif
179  if (cs%UseDiurnalSW) then
180  call get_param(param_file, mdl, "SCM_DIURNAL_SW_MAX", &
181  cs%Max_sw, "Maximum diurnal sw radiation "// &
182  "used in the SCM CVmix test surface forcing.", &
183  units='m K/s', fail_if_missing=.true.)
184  endif
185 
187 
188 subroutine scm_cvmix_tests_wind_forcing(state, fluxes, day, G, CS)
189  type(surface), intent(in) :: state !< Surface state structure
190  type(forcing), intent(inout) :: fluxes !< Surface fluxes structure
191  type(time_type), intent(in) :: day !< Time in days
192  type(ocean_grid_type), intent(inout) :: G !< Grid structure
193  type(scm_cvmix_tests_cs), pointer :: CS !< Container for SCM parameters
194  ! Local variables
195  integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq
196  integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
197  real :: mag_tau
198  ! Bounds for loops and memory allocation
199  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
200  isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
201  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
202  isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
203 
204  ! Allocate the forcing arrays, if necessary.
205  call allocate_forcing_type(g, fluxes, stress=.true., ustar=.true. )
206 
207  do j=js,je ; do i=isq,ieq
208  fluxes%taux(i,j) = cs%tau_x
209  enddo ; enddo
210  do j=jsq,jeq ; do i=is,ie
211  fluxes%tauy(i,j) = cs%tau_y
212  enddo ; enddo
213  mag_tau = sqrt(cs%tau_x*cs%tau_x + cs%tau_y*cs%tau_y)
214  if (associated(fluxes%ustar)) then ; do j=js,je ; do i=is,ie
215  fluxes%ustar(i,j) = sqrt( mag_tau / cs%Rho0 )
216  enddo ; enddo ; endif
217 
218 end subroutine scm_cvmix_tests_wind_forcing
219 
220 
221 subroutine scm_cvmix_tests_buoyancy_forcing(state, fluxes, day, G, CS)
222  type(surface), intent(in) :: state !< Surface state structure
223  type(forcing), intent(inout) :: fluxes !< Surface fluxes structure
224  type(time_type), intent(in) :: day !< Time in days (seconds?)
225  type(ocean_grid_type), intent(inout) :: G !< Grid structure
226  type(scm_cvmix_tests_cs), pointer :: CS !< Container for SCM parameters
227 
228  ! Local variables
229  integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq
230  integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
231  real :: PI
232 
233  pi = 4.0*atan(1.0)
234 
235  ! Bounds for loops and memory allocation
236  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
237  isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
238  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
239  isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
240 
241  ! Allocate the forcing arrays, if necessary.
242  call allocate_forcing_type(g, fluxes, water=.true., heat=.true. )
243 
244  if (cs%UseHeatFlux) then
245  ! Note CVmix test inputs give Heat flux in [m K/s]
246  ! therefore must convert to W/m2 by multiplying
247  ! by Rho0*Cp
248  do j=jsq,jeq ; do i=is,ie
249  fluxes%sens(i,j) = cs%surf_HF * cs%Rho0 * fluxes%C_p
250  enddo; enddo
251  endif
252 
253  if (cs%UseEvaporation) then
254  do j=jsq,jeq ; do i=is,ie
255  ! Note CVmix test inputs give evaporation in m/s
256  ! This therefore must be converted to mass flux
257  ! by multiplying by density
258  fluxes%evap(i,j) = cs%surf_evap * cs%Rho0
259  enddo; enddo
260  endif
261 
262  if (cs%UseDiurnalSW) then
263  do j=jsq,jeq ; do i=is,ie
264  ! Note CVmix test inputs give max sw rad in [m K/s]
265  ! therefore must convert to W/m2 by multiplying
266  ! by Rho0*Cp
267  ! Note diurnal cycle peaks at Noon.
268  fluxes%sw(i,j) = cs%Max_sw * max(0.0,cos(2*pi* &
269  (time_type_to_real(day)/86400.-0.5))) * cs%RHO0 * fluxes%C_p
270  enddo; enddo
271  endif
272 
274 
275 end module scm_cvmix_tests
The following structure contains pointers to various fields which may be used describe the surface st...
This module implements boundary forcing for MOM6.
subroutine, public scm_cvmix_tests_ts_init(T, S, h, G, GV, param_file, just_read_params)
Initializes temperature and salinity for the SCM CVmix test example.
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
subroutine, public scm_cvmix_tests_wind_forcing(state, fluxes, day, G, CS)
Provides the ocean grid type.
Definition: MOM_grid.F90:2
subroutine, public allocate_forcing_type(G, fluxes, stress, ustar, water, heat, shelf, press, iceberg)
Conditionally allocate fields within the forcing type.
subroutine, public scm_cvmix_tests_surface_forcing_init(Time, G, param_file, CS)
Initializes surface forcing for the CVmix test case suite.
subroutine, public scm_cvmix_tests_buoyancy_forcing(state, fluxes, day, G, CS)
Structure that contains pointers to the boundary forcing used to drive the liquid ocean simulated by ...
The thermo_var_ptrs structure contains pointers to an assortment of thermodynamic fields that may be ...
Initial conditions and forcing for the single column model (SCM) CVmix test set.
character(len=40) mdl
subroutine, public mom_error(level, message, all_print)
Container for surface forcing parameters.