MOM6
SCM_idealized_hurricane.F90
Go to the documentation of this file.
1 !> Initial conditions and forcing for the single column model (SCM) idealized
2 !! hurricane example.
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
12 use mom_time_manager, only : time_type, operator(+), operator(/), get_time,&
13  time_type_to_real
16 
17 implicit none ; private
18 
19 #include <MOM_memory.h>
20 
25 
26 !> Container for parameters describing idealized wind structure
28  real :: rho_a !< Air density
29  real :: p_n !< Ambient pressure
30  real :: p_c !< Central pressure
31  real :: r_max !< Radius of maximum winds
32  real :: u_max !< Maximum wind speeds
33  real :: yy !< Distance (positive north) of storm center
34  real :: tran_speed !< Hurricane translation speed
35  real :: gust_const !< Gustiness (used in u*)
36  real :: rho0 !< A reference ocean density in kg/m3
37 end type
38 
39 ! This include declares and sets the variable "version".
40 #include "version_variable.h"
41 
42 character(len=40) :: mdl = "SCM_idealized_hurricane" ! This module's name.
43 
44 contains
45 
46 !> Initializes temperature and salinity for the SCM idealized hurricane example
47 subroutine scm_idealized_hurricane_ts_init(T, S, h, G, GV, param_file, just_read_params)
48  type(ocean_grid_type), intent(in) :: G !< Grid structure
49  type(verticalgrid_type), intent(in) :: GV !< Vertical grid structure
50  real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: T !< Potential temperature (degC)
51  real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: S !< Salinity (psu)
52  real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< Layer thickness (m or Pa)
53  type(param_file_type), intent(in) :: param_file !< Input parameter structure
54  logical, optional, intent(in) :: just_read_params !< If present and true, this call will
55  !! only read parameters without changing h.
56  ! Local variables
57  real :: eta(szk_(g)+1) ! The 1-d nominal positions of the interfaces.
58  real :: S_ref, SST_ref, dTdZ, MLD
59  real :: zC
60  logical :: just_read ! If true, just read parameters but set nothing.
61  integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz
62 
63  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
64  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
65 
66  just_read = .false. ; if (present(just_read_params)) just_read = just_read_params
67 
68  if (.not.just_read) call log_version(param_file, mdl, version)
69  call get_param(param_file, mdl,"SCM_S_REF",s_ref, &
70  'Reference salinity', units='1e-3',default=35.0, do_not_log=just_read)
71  call get_param(param_file, mdl,"SCM_SST_REF",sst_ref, &
72  'Reference surface temperature', units='C', &
73  fail_if_missing=.not.just_read, do_not_log=just_read)
74  call get_param(param_file, mdl,"SCM_DTDZ",dtdz, &
75  'Initial temperature stratification below mixed layer', &
76  units='C/m', fail_if_missing=.not.just_read, do_not_log=just_read)
77  call get_param(param_file, mdl,"SCM_MLD",mld, &
78  'Initial mixed layer depth', units='m', &
79  fail_if_missing=.not.just_read, do_not_log=just_read)
80 
81  if (just_read) return ! All run-time parameters have been read, so return.
82 
83  do j=js,je ; do i=is,ie
84  eta(1) = 0. ! Reference to surface
85  do k=1,nz
86  eta(k+1) = eta(k) - h(i,j,k)*gv%H_to_m ! Interface below layer (in m)
87  zc = 0.5*( eta(k) + eta(k+1) ) ! Z of middle of layer (in m)
88  t(i,j,k) = sst_ref + dtdz*min(0., zc+mld)
89  s(i,j,k) = s_ref
90  enddo ! k
91  enddo ; enddo
92 
94 
95 !> Initializes wind profile for the SCM idealized hurricane example
96 subroutine scm_idealized_hurricane_wind_init(Time, G, param_file, CS)
97  type(time_type), intent(in) :: Time !< Time
98  type(ocean_grid_type), intent(in) :: G !< Grid structure
99  type(param_file_type), intent(in) :: param_file !< Input parameter structure
100  type(scm_idealized_hurricane_cs), pointer :: CS !< Parameter container
101 
102 ! This include declares and sets the variable "version".
103 #include "version_variable.h"
104 
105  if (associated(cs)) then
106  call mom_error(fatal, "SCM_idealized_hurricane_wind_init called with an associated "// &
107  "control structure.")
108  return
109  endif
110  allocate(cs)
111 
112  ! Read all relevant parameters and write them to the model log.
113  call log_version(param_file, mdl, version, "")
114  call get_param(param_file, mdl, "SCM_RHO_AIR", cs%rho_a, &
115  "Air density "// &
116  "used in the SCM idealized hurricane wind profile.", &
117  units='kg/m3', default=1.2)
118  call get_param(param_file, mdl, "SCM_AMBIENT_PRESSURE", cs%p_n, &
119  "Ambient pressure "// &
120  "used in the SCM idealized hurricane wind profile.", &
121  units='Pa', default=101200.)
122  call get_param(param_file, mdl, "SCM_CENTRAL_PRESSURE", cs%p_c, &
123  "Central pressure "// &
124  "used in the SCM idealized hurricane wind profile.", &
125  units='Pa', default=96800.)
126  call get_param(param_file, mdl, "SCM_RADIUS_MAX_WINDS", cs%r_max, &
127  "Radius of maximum winds "// &
128  "used in the SCM idealized hurricane wind profile.", &
129  units='m', default=50.e3)
130  call get_param(param_file, mdl, "SCM_MAX_WIND_SPEED", cs%U_max, &
131  "Maximum wind speed "// &
132  "used in the SCM idealized hurricane wind profile.", &
133  units='m/s', default=65.)
134  call get_param(param_file, mdl, "SCM_YY", cs%YY, &
135  "Y distance of station "// &
136  "used in the SCM idealized hurricane wind profile.", &
137  units='m', default=50.e3)
138  call get_param(param_file, mdl, "SCM_TRAN_SPEED", cs%TRAN_SPEED, &
139  "Translation speed of hurricane"// &
140  "used in the SCM idealized hurricane wind profile.", &
141  units='m/s', default=5.0)
142  call get_param(param_file, mdl, "RHO_0", cs%Rho0, &
143  "The mean ocean density used with BOUSSINESQ true to \n"//&
144  "calculate accelerations and the mass for conservation \n"//&
145  "properties, or with BOUSSINSEQ false to convert some \n"//&
146  "parameters from vertical units of m to kg m-2.", &
147  units="kg m-3", default=1035.0)
148  ! The following parameter is a model run-time parameter which is used
149  ! and logged elsewhere and so should not be logged here. The default
150  ! value should be consistent with the rest of the model.
151  call get_param(param_file, mdl, "GUST_CONST", cs%gust_const, &
152  "The background gustiness in the winds.", units="Pa", &
153  default=0.00, do_not_log=.true.)
154 
155 
157 
158 subroutine scm_idealized_hurricane_wind_forcing(state, fluxes, day, G, CS)
159  type(surface), intent(in) :: state !< Surface state structure
160  type(forcing), intent(inout) :: fluxes !< Surface fluxes structure
161  type(time_type), intent(in) :: day !< Time in days
162  type(ocean_grid_type), intent(inout) :: G !< Grid structure
163  type(scm_idealized_hurricane_cs), pointer :: CS !< Container for SCM parameters
164  ! Local variables
165  integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq
166  integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
167  real :: pie, Deg2Rad
168  real :: U10, A, B, C, r, f,du10,rkm ! For wind profile expression
169  real :: xx, t0 !for location
170  real :: dp, rB
171  real :: Cd ! Air-sea drag coefficient
172  real :: Uocn, Vocn ! Surface ocean velocity components
173  real :: dU, dV ! Air-sea differential motion
174  !Wind angle variables
175  real :: Alph,Rstr, A0, A1, P1, Adir, transdir, V_TS, U_TS
176  logical :: BR_Bench
177  ! Bounds for loops and memory allocation
178  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
179  isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
180  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
181  isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
182 
183  ! Allocate the forcing arrays, if necessary.
184  call allocate_forcing_type(g, fluxes, stress=.true., ustar=.true.)
185 
186  pie = 4.0*atan(1.0) ; deg2rad = pie/180.
187 
188  !/ BR
189  ! Implementing Holland (1980) parameteric wind profile
190  !------------------------------------------------------|
191  br_bench = .true. !true if comparing to LES runs |
192  t0 = 129600. !TC 'eye' crosses (0,0) at 36 hours|
193  transdir = pie !translation direction (-x) |
194  !------------------------------------------------------|
195  dp = cs%p_n - cs%p_c
196  c = cs%U_max / sqrt( dp )
197  b = c**2 * cs%rho_a * exp(1.0)
198  if (br_bench) then
199  ! rho_a reset to value used in generated wind for benchmark test
200  b = c**2 * 1.2 * exp(1.0)
201  endif
202  a = (cs%r_max/1000.)**b
203  f =g%CoriolisBu(is,js) ! f=f(x,y) but in the SCM is constant
204  if (br_bench) then
205  ! f reset to value used in generated wind for benchmark test
206  f = 5.5659e-05
207  endif
208  !/ BR
209  ! Calculate x position as a function of time.
210  xx = ( t0 - time_type_to_real(day)) * cs%tran_speed * cos(transdir)
211  r = sqrt(xx**2.+cs%YY**2.)
212  !/ BR
213  ! rkm - r converted to km for Holland prof.
214  ! used in km due to error, correct implementation should
215  ! not need rkm, but to match winds w/ experiment this must
216  ! be maintained. Causes winds far from storm center to be a
217  ! couple of m/s higher than the correct Holland prof.
218  if (br_bench) then
219  rkm = r/1000.
220  rb = (rkm)**b
221  else
222  ! if not comparing to benchmark, then use correct Holland prof.
223  rkm = r
224  rb = r**b
225  endif
226  !/ BR
227  ! Calculate U10 in the interior (inside of 10x radius of maximum wind),
228  ! while adjusting U10 to 0 outside of 12x radius of maximum wind.
229  ! Note that rho_a is set to 1.2 following generated wind for experiment
230  if (r/cs%r_max.gt.0.001 .AND. r/cs%r_max.lt.10.) then
231  u10 = sqrt( a*b*dp*exp(-a/rb)/(1.2*rb) + 0.25*(rkm*f)**2 ) - 0.5*rkm*f
232  elseif (r/cs%r_max.gt.10. .AND. r/cs%r_max.lt.12.) then
233  r=cs%r_max*10.
234  if (br_bench) then
235  rkm = r/1000.
236  rb=rkm**b
237  else
238  rkm = r
239  rb = r**b
240  endif
241  u10 = ( sqrt( a*b*dp*exp(-a/rb)/(1.2*rb) + 0.25*(rkm*f)**2 ) - 0.5*rkm*f) &
242  * (12. - r/cs%r_max)/2.
243  else
244  u10 = 0.
245  end if
246  adir = atan2(cs%YY,xx)
247 
248  !/ BR
249  ! Wind angle model following Zhang and Ulhorn (2012)
250  ! ALPH is inflow angle positive outward.
251  rstr = min(10.,r / cs%r_max)
252  a0 = -0.9*rstr -0.09*cs%U_max -14.33
253  a1 = -a0 *(0.04*rstr +0.05*cs%tran_speed+0.14)
254  p1 = (6.88*rstr -9.60*cs%tran_speed+85.31)*pie/180.
255  alph = a0 - a1*cos( (transdir - adir ) - p1)
256  if (r/cs%r_max.gt.10. .AND. r/cs%r_max.lt.12.) then
257  alph = alph* (12. - r/cs%r_max)/2.
258  elseif (r/cs%r_max.gt.12.) then
259  alph = 0.0
260  endif
261  alph = alph * deg2rad
262 
263  !/BR
264  ! Prepare for wind calculation
265  ! X_TS is component of translation speed added to wind vector
266  ! due to background steering wind.
267  u_ts = cs%tran_speed/2.*cos(transdir)
268  v_ts = cs%tran_speed/2.*sin(transdir)
269 
270  ! Set the surface wind stresses, in units of Pa. A positive taux
271  ! accelerates the ocean to the (pseudo-)east.
272  ! The i-loop extends to is-1 so that taux can be used later in the
273  ! calculation of ustar - otherwise the lower bound would be Isq.
274  do j=js,je ; do i=is-1,ieq
275  !/BR
276  ! Turn off surface current for stress calculation to be
277  ! consistent with test case.
278  uocn = 0.!state%u(I,j)
279  vocn = 0.!0.25*( (state%v(i,J) + state%v(i+1,J-1)) &
280  ! +(state%v(i+1,J) + state%v(i,J-1)) )
281  !/BR
282  ! Wind vector calculated from location/direction (sin/cos flipped b/c
283  ! cyclonic wind is 90 deg. phase shifted from position angle).
284  du = u10*sin(adir-pie-alph) - uocn + u_ts
285  dv = u10*cos(adir-alph) - vocn + v_ts
286  !/----------------------------------------------------|
287  !BR
288  ! Add a simple drag coefficient as a function of U10 |
289  !/----------------------------------------------------|
290  du10=sqrt(du**2+dv**2)
291  if (du10.LT.11.) then
292  cd = 1.2e-3
293  elseif (du10.LT.20.) then
294  cd = (0.49 + 0.065 * u10 )*0.001
295  else
296  cd = 0.0018
297  endif
298  fluxes%taux(i,j) = cs%rho_a * g%mask2dCu(i,j) * cd*sqrt(du**2+dv**2)*du
299  enddo ; enddo
300  !/BR
301  ! See notes above
302  do j=js-1,jeq ; do i=is,ie
303  uocn = 0.!0.25*( (state%u(I,j) + state%u(I-1,j+1)) &
304  ! +(state%u(I-1,j) + state%u(I,j+1)) )
305  vocn = 0.!state%v(i,J)
306  du = u10*sin(adir-pie-alph) - uocn + u_ts
307  dv = u10*cos(adir-alph) - vocn + v_ts
308  du10=sqrt(du**2+dv**2)
309  if (du10.LT.11.) then
310  cd = 1.2e-3
311  elseif (du10.LT.20.) then
312  cd = (0.49 + 0.065 * u10 )*0.001
313  else
314  cd = 0.0018
315  endif
316  fluxes%tauy(i,j) = cs%rho_a * g%mask2dCv(i,j) * cd*du10*dv
317  enddo ; enddo
318  ! Set the surface friction velocity, in units of m s-1. ustar is always positive.
319  do j=js,je ; do i=is,ie
320  ! This expression can be changed if desired, but need not be.
321  fluxes%ustar(i,j) = g%mask2dT(i,j) * sqrt(cs%gust_const/cs%Rho0 + &
322  sqrt(0.5*(fluxes%taux(i-1,j)**2 + fluxes%taux(i,j)**2) + &
323  0.5*(fluxes%tauy(i,j-1)**2 + fluxes%tauy(i,j)**2))/cs%Rho0)
324  enddo ; enddo
325 
327 
328 end module scm_idealized_hurricane
The following structure contains pointers to various fields which may be used describe the surface st...
subroutine, public scm_idealized_hurricane_wind_init(Time, G, param_file, CS)
Initializes wind profile for the SCM idealized hurricane example.
This module implements boundary forcing for MOM6.
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Provides the ocean grid type.
Definition: MOM_grid.F90:2
Container for parameters describing idealized wind structure.
subroutine, public allocate_forcing_type(G, fluxes, stress, ustar, water, heat, shelf, press, iceberg)
Conditionally allocate fields within the forcing type.
subroutine, public scm_idealized_hurricane_ts_init(T, S, h, G, GV, param_file, just_read_params)
Initializes temperature and salinity for the SCM idealized hurricane example.
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 ...
subroutine, public scm_idealized_hurricane_wind_forcing(state, fluxes, day, G, CS)
subroutine, public mom_error(level, message, all_print)
Initial conditions and forcing for the single column model (SCM) idealized hurricane example...