MOM6
Idealized_Hurricane.F90
1 !> Forcing for the idealized hurricane and SCM_idealized_hurricane examples.
3 
4 ! This file is part of MOM6. See LICENSE.md for the license.
5 
6 ! History
7 !--------
8 ! November 2014: Origination.
9 ! October 2018: Renamed module from SCM_idealized_hurricane to idealized_hurricane
10 ! This module is no longer exclusively for use in SCM mode.
11 ! Legacy code that can be deleted is at the bottom (currently maintained
12 ! only to preserve exact answers in SCM mode).
13 ! The T/S initializations have been removed since they are redundant
14 ! w/ T/S initializations in CVMix_tests (which should be moved
15 ! into the main state_initialization to their utility
16 ! for multiple example cases)..
17 ! To do
18 ! 1. Remove the legacy SCM_idealized_hurricane_wind_forcing code
19 ! 2. Make the hurricane-to-background wind transition a runtime parameter
20 !
21 
22 use mom_error_handler, only : mom_error, fatal
25 use mom_forcing_type, only : allocate_forcing_type, allocate_mech_forcing
26 use mom_grid, only : ocean_grid_type
28 use mom_time_manager, only : time_type, operator(+), operator(/), time_type_to_real
32 
33 implicit none ; private
34 
35 #include <MOM_memory.h>
36 
37 public idealized_hurricane_wind_init !Public interface to initialize the idealized
38  ! hurricane wind profile.
39 public idealized_hurricane_wind_forcing !Public interface to update the idealized
40  ! hurricane wind profile.
41 public scm_idealized_hurricane_wind_forcing !Public interface to the legacy idealized
42  ! hurricane wind profile for SCM.
43 
44 !> Container for parameters describing idealized wind structure
45 type, public :: idealized_hurricane_cs ; private
46 
47  ! Parameters used to compute Holland radial wind profile
48  real :: rho_a !< Mean air density [kg m-3]
49  real :: pressure_ambient !< Pressure at surface of ambient air [Pa]
50  real :: pressure_central !< Pressure at surface at hurricane center [Pa]
51  real :: rad_max_wind !< Radius of maximum winds [m]
52  real :: max_windspeed !< Maximum wind speeds [m s-1]
53  real :: hurr_translation_spd !< Hurricane translation speed [m s-1]
54  real :: hurr_translation_dir !< Hurricane translation speed [m s-1]
55  real :: gustiness !< Gustiness (optional, used in u*) [m s-1]
56  real :: rho0 !< A reference ocean density [kg m-3]
57  real :: hurr_cen_y0 !< The initial y position of the hurricane
58  !! This experiment is conducted in a Cartesian
59  !! grid and this is assumed to be in meters [m]
60  real :: hurr_cen_x0 !< The initial x position of the hurricane
61  !! This experiment is conducted in a Cartesian
62  !! grid and this is assumed to be in meters [m]
63  real :: holland_a !< Parameter 'A' from the Holland formula
64  real :: holland_b !< Parameter 'B' from the Holland formula
65  real :: holland_axbxdp !< 'A' x 'B' x (Pressure Ambient-Pressure central)
66  !! for the Holland prorfile calculation
67  logical :: relative_tau !< A logical to take difference between wind
68  !! and surface currents to compute the stress
69 
70 
71  ! Parameters used if in SCM (single column model) mode
72  logical :: scm_mode !< If true this being used in Single Column Model mode
73  logical :: br_bench !< A "benchmark" configuration (which is meant to
74  !! provide identical wind to reproduce a previous
75  !! experiment, where that wind formula contained
76  !! an error)
77  real :: dy_from_center !< (Fixed) distance in y from storm center path [m]
78 
79  ! Par
80  real :: pi !< Mathematical constant
81  real :: deg2rad !< Mathematical constant
82 
83 end type
84 
85 ! This include declares and sets the variable "version".
86 #include "version_variable.h"
87 
88 character(len=40) :: mdl = "idealized_hurricane" !< This module's name.
89 
90 contains
91 
92 !> Initializes wind profile for the SCM idealized hurricane example
93 subroutine idealized_hurricane_wind_init(Time, G, param_file, CS)
94  type(time_type), &
95  intent(in) :: time !< Model time
96  type(ocean_grid_type), &
97  intent(in) :: g !< Grid structure
98  type(param_file_type), &
99  intent(in) :: param_file !< Input parameter structure
100  type(idealized_hurricane_cs), &
101  pointer :: cs !< Parameter container
102 
103  real :: dp, c
104 
105 ! This include declares and sets the variable "version".
106 #include "version_variable.h"
107 
108  if (associated(cs)) then
109  call mom_error(fatal, "idealized_hurricane_wind_init called "// &
110  "with an associated control structure.")
111  return
112  endif
113 
114  allocate(cs)
115 
116  cs%pi = 4.0*atan(1.0)
117  cs%Deg2Rad = cs%pi/180.
118 
119  ! Read all relevant parameters and write them to the model log.
120  call log_version(param_file, mdl, version, "")
121 
122  ! Parameters for computing a wind profile
123  call get_param(param_file, mdl, "IDL_HURR_RHO_AIR", cs%rho_a, &
124  "Air density used to compute the idealized hurricane "//&
125  "wind profile.", units='kg/m3', default=1.2)
126  call get_param(param_file, mdl, "IDL_HURR_AMBIENT_PRESSURE", &
127  cs%pressure_ambient, "Ambient pressure used in the "//&
128  "idealized hurricane wind profile.", units='Pa', &
129  default=101200.)
130  call get_param(param_file, mdl, "IDL_HURR_CENTRAL_PRESSURE", &
131  cs%pressure_central, "Central pressure used in the "//&
132  "idealized hurricane wind profile.", units='Pa', &
133  default=96800.)
134  call get_param(param_file, mdl, "IDL_HURR_RAD_MAX_WIND", &
135  cs%rad_max_wind, "Radius of maximum winds used in the "//&
136  "idealized hurricane wind profile.", units='m', &
137  default=50.e3)
138  call get_param(param_file, mdl, "IDL_HURR_MAX_WIND", cs%max_windspeed, &
139  "Maximum wind speed used in the idealized hurricane"// &
140  "wind profile.", units='m/s', default=65.)
141  call get_param(param_file, mdl, "IDL_HURR_TRAN_SPEED", cs%hurr_translation_spd, &
142  "Translation speed of hurricane used in the idealized "//&
143  "hurricane wind profile.", units='m/s', default=5.0)
144  call get_param(param_file, mdl, "IDL_HURR_TRAN_DIR", cs%hurr_translation_dir, &
145  "Translation direction (towards) of hurricane used in the "//&
146  "idealized hurricane wind profile.", units='degrees', &
147  default=180.0)
148  cs%hurr_translation_dir = cs%hurr_translation_dir * cs%Deg2Rad
149  call get_param(param_file, mdl, "IDL_HURR_X0", cs%Hurr_cen_X0, &
150  "Idealized Hurricane initial X position", &
151  units='m', default=0.)
152  call get_param(param_file, mdl, "IDL_HURR_Y0", cs%Hurr_cen_Y0, &
153  "Idealized Hurricane initial Y position", &
154  units='m', default=0.)
155  call get_param(param_file, mdl, "IDL_HURR_TAU_CURR_REL", cs%relative_tau, &
156  "Current relative stress switch "//&
157  "used in the idealized hurricane wind profile.", &
158  units='', default=.false.)
159 
160  ! Parameters for SCM mode
161  call get_param(param_file, mdl, "IDL_HURR_SCM_BR_BENCH", cs%BR_BENCH, &
162  "Single column mode benchmark case switch, which is "// &
163  "invoking a modification (bug) in the wind profile meant to "//&
164  "reproduce a previous implementation.", units='', default=.false.)
165  call get_param(param_file, mdl, "IDL_HURR_SCM", cs%SCM_MODE, &
166  "Single Column mode switch "//&
167  "used in the SCM idealized hurricane wind profile.", &
168  units='', default=.false.)
169  call get_param(param_file, mdl, "IDL_HURR_SCM_LOCY", cs%DY_from_center, &
170  "Y distance of station used in the SCM idealized hurricane "//&
171  "wind profile.", units='m', default=50.e3)
172 
173  ! The following parameters are model run-time parameters which are used
174  ! and logged elsewhere and so should not be logged here. The default
175  ! value should be consistent with the rest of the model.
176  call get_param(param_file, mdl, "RHO_0", cs%Rho0, &
177  "The mean ocean density used with BOUSSINESQ true to "//&
178  "calculate accelerations and the mass for conservation "//&
179  "properties, or with BOUSSINSEQ false to convert some "//&
180  "parameters from vertical units of m to kg m-2.", &
181  units="kg m-3", default=1035.0, do_not_log=.true.)
182  call get_param(param_file, mdl, "GUST_CONST", cs%gustiness, &
183  "The background gustiness in the winds.", units="Pa", &
184  default=0.00, do_not_log=.true.)
185 
186 
187  if (cs%BR_BENCH) then
188  cs%rho_a = 1.2
189  endif
190  dp = cs%pressure_ambient - cs%pressure_central
191  c = cs%max_windspeed / sqrt( dp )
192  cs%Holland_B = c**2 * cs%rho_a * exp(1.0)
193  cs%Holland_A = (cs%rad_max_wind)**cs%Holland_B
194  cs%Holland_AxBxDP = cs%Holland_A*cs%Holland_B*dp
195 
196  return
197 end subroutine idealized_hurricane_wind_init
198 
199 !> Computes the surface wind for the idealized hurricane test cases
200 subroutine idealized_hurricane_wind_forcing(state, forces, day, G, US, CS)
201  type(surface), intent(in) :: state !< Surface state structure
202  type(mech_forcing), intent(inout) :: forces !< A structure with the driving mechanical forces
203  type(time_type), intent(in) :: day !< Time in days
204  type(ocean_grid_type), intent(inout) :: g !< Grid structure
205  type(unit_scale_type), intent(in) :: us !< A dimensional unit scaling type
206  type(idealized_hurricane_cs), pointer :: cs !< Container for idealized hurricane parameters
207 
208  ! Local variables
209  integer :: i, j, is, ie, js, je, isq, ieq, jsq, jeq
210  integer :: isd, ied, jsd, jed, isdb, iedb, jsdb, jedb
211 
212  real :: tx,ty !< wind stress
213  real :: uocn, vocn !< Surface ocean velocity components
214  real :: lat, lon !< Grid location
215  real :: yy, xx !< storm relative position
216  real :: xc, yc !< Storm center location
217  real :: f !< Coriolis
218  real :: fbench !< The benchmark 'f' value
219  real :: fbench_fac !< A factor that is set to 0 to use the
220  !! benchmark 'f' value
221  real :: rel_tau_fac !< A factor that is set to 0 to disable
222  !! current relative stress calculation
223 
224  ! Bounds for loops and memory allocation
225  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
226  isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
227  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
228  isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
229 
230  ! Allocate the forcing arrays, if necessary.
231  call allocate_mech_forcing(g, forces, stress=.true., ustar=.true.)
232 
233  if (cs%relative_tau) then
234  rel_tau_fac = 1.
235  else
236  rel_tau_fac = 0. !Multiplied to 0 surface current
237  endif
238 
239  !> Compute storm center location
240  xc = cs%Hurr_cen_X0 + (time_type_to_real(day)*cs%hurr_translation_spd*&
241  cos(cs%hurr_translation_dir))
242  yc = cs%Hurr_cen_Y0 + (time_type_to_real(day)*cs%hurr_translation_spd*&
243  sin(cs%hurr_translation_dir))
244 
245 
246  if (cs%BR_Bench) then
247  ! f reset to value used in generated wind for benchmark test
248  fbench = 5.5659e-05
249  fbench_fac = 0.0
250  else
251  fbench = 0.0
252  fbench_fac = 1.0
253  endif
254 
255  !> Computes taux
256  do j=js,je
257  do i=is-1,ieq
258  uocn = state%u(i,j)*rel_tau_fac
259  vocn = 0.25*(state%v(i,j)+state%v(i+1,j-1)&
260  +state%v(i+1,j)+state%v(i,j-1))*rel_tau_fac
261  f = abs(0.5*us%s_to_T*(g%CoriolisBu(i,j)+g%CoriolisBu(i,j-1)))*fbench_fac + fbench
262  ! Calculate position as a function of time.
263  if (cs%SCM_mode) then
264  yy = yc + cs%dy_from_center
265  xx = xc
266  else
267  lat = g%geoLatCu(i,j)*1000. ! Convert Lat from km to m.
268  lon = g%geoLonCu(i,j)*1000. ! Convert Lon from km to m.
269  yy = lat - yc
270  xx = lon - xc
271  endif
272  call idealized_hurricane_wind_profile(&
273  cs,f,yy,xx,uocn,vocn,tx,ty)
274  forces%taux(i,j) = g%mask2dCu(i,j) * tx
275  enddo
276  enddo
277  !> Computes tauy
278  do j=js-1,jeq
279  do i=is,ie
280  uocn = 0.25*(state%u(i,j)+state%u(i-1,j+1)&
281  +state%u(i-1,j)+state%u(i,j+1))*rel_tau_fac
282  vocn = state%v(i,j)*rel_tau_fac
283  f = abs(0.5*us%s_to_T*(g%CoriolisBu(i-1,j)+g%CoriolisBu(i,j)))*fbench_fac + fbench
284  ! Calculate position as a function of time.
285  if (cs%SCM_mode) then
286  yy = yc + cs%dy_from_center
287  xx = xc
288  else
289  lat = g%geoLatCv(i,j)*1000. ! Convert Lat from km to m.
290  lon = g%geoLonCv(i,j)*1000. ! Convert Lon from km to m.
291  yy = lat - yc
292  xx = lon - xc
293  endif
294  call idealized_hurricane_wind_profile(cs, f, yy, xx, uocn, vocn, tx, ty)
295  forces%tauy(i,j) = g%mask2dCv(i,j) * ty
296  enddo
297  enddo
298 
299  !> Get Ustar
300  do j=js,je
301  do i=is,ie
302  ! This expression can be changed if desired, but need not be.
303  forces%ustar(i,j) = us%m_to_Z*us%T_to_s * g%mask2dT(i,j) * sqrt(cs%gustiness/cs%Rho0 + &
304  sqrt(0.5*(forces%taux(i-1,j)**2 + forces%taux(i,j)**2) + &
305  0.5*(forces%tauy(i,j-1)**2 + forces%tauy(i,j)**2))/cs%Rho0)
306  enddo
307  enddo
308 
309  return
310 end subroutine idealized_hurricane_wind_forcing
311 
312 !> Calculate the wind speed at a location as a function of time.
313 subroutine idealized_hurricane_wind_profile(CS, absf, YY, XX, UOCN, VOCN, Tx, Ty)
314  ! Author: Brandon Reichl
315  ! Date: Nov-20-2014
316  ! Aug-14-2018 Generalized for non-SCM configuration
317 
318  ! Input parameters
319  type(idealized_hurricane_cs), &
320  pointer :: CS !< Container for SCM parameters
321  real, intent(in) :: absf !<Input coriolis magnitude
322  real, intent(in) :: YY !< Location in m relative to center y
323  real, intent(in) :: XX !< Location in m relative to center x
324  real, intent(in) :: UOCN !< X surface current
325  real, intent(in) :: VOCN !< Y surface current
326  real, intent(out) :: Tx !< X stress
327  real, intent(out) :: Ty !< Y stress
328 
329  ! Local variables
330 
331  ! Wind profile terms
332  real :: U10
333  real :: radius
334  real :: radius10
335  real :: radius_km
336  real :: radiusB
337  real :: fcor
338  real :: du10
339  real :: du
340  real :: dv
341  real :: CD
342 
343  !Wind angle variables
344  real :: Alph !< The resulting inflow angle (positive outward)
345  real :: Rstr
346  real :: A0
347  real :: A1
348  real :: P1
349  real :: Adir
350  real :: V_TS
351  real :: U_TS
352 
353  ! Implementing Holland (1980) parameteric wind profile
354 
355  radius = sqrt(xx**2 + yy**2)
356 
357  !/ BGR
358  ! rkm - r converted to km for Holland prof.
359  ! used in km due to error, correct implementation should
360  ! not need rkm, but to match winds w/ experiment this must
361  ! be maintained. Causes winds far from storm center to be a
362  ! couple of m/s higher than the correct Holland prof.
363  if (cs%BR_Bench) then
364  radius_km = radius/1000.
365  else
366  ! if not comparing to benchmark, then use correct Holland prof.
367  radius_km = radius
368  endif
369  radiusb = (radius)**cs%Holland_B
370 
371  !/
372  ! Calculate U10 in the interior (inside of 10x radius of maximum wind),
373  ! while adjusting U10 to 0 outside of 12x radius of maximum wind.
374  if ( (radius/cs%rad_max_wind .gt. 0.001) .and. &
375  (radius/cs%rad_max_wind .lt. 10.) ) then
376  u10 = sqrt(cs%Holland_AxBxDP*exp(-cs%Holland_A/radiusb)/(cs%rho_A*radiusb)&
377  +0.25*(radius_km*absf)**2) - 0.5*radius_km*absf
378  elseif ( (radius/cs%rad_max_wind .gt. 10.) .and. &
379  (radius/cs%rad_max_wind .lt. 15.) ) then
380 
381  radius10 = cs%rad_max_wind*10.
382 
383  if (cs%BR_Bench) then
384  radius_km = radius10/1000.
385  else
386  radius_km = radius10
387  endif
388  radiusb=radius10**cs%Holland_B
389 
390  u10 = (sqrt(cs%Holland_AxBxDp*exp(-cs%Holland_A/radiusb)/(cs%rho_A*radiusb)&
391  +0.25*(radius_km*absf)**2)-0.5*radius_km*absf) &
392  * (15.-radius/cs%rad_max_wind)/5.
393  else
394  u10 = 0.
395  endif
396  adir = atan2(yy,xx)
397  !\
398 
399  ! Wind angle model following Zhang and Ulhorn (2012)
400  ! ALPH is inflow angle positive outward.
401  rstr = min(10.,radius / cs%rad_max_wind)
402  a0 = -0.9*rstr - 0.09*cs%max_windspeed - 14.33
403  a1 = -a0*(0.04*rstr + 0.05*cs%Hurr_translation_spd + 0.14)
404  p1 = (6.88*rstr - 9.60*cs%Hurr_translation_spd + 85.31) * cs%Deg2Rad
405  alph = a0 - a1*cos(cs%hurr_translation_dir-adir-p1)
406  if ( (radius/cs%rad_max_wind.gt.10.) .and.&
407  (radius/cs%rad_max_wind.lt.15.) ) then
408  alph = alph*(15.0-radius/cs%rad_max_wind)/5.
409  elseif (radius/cs%rad_max_wind.gt.15.) then
410  alph = 0.0
411  endif
412  alph = alph * cs%Deg2Rad
413 
414  ! Calculate translation speed components
415  u_ts = cs%hurr_translation_spd/2.*cos(cs%hurr_translation_dir)
416  v_ts = cs%hurr_translation_spd/2.*sin(cs%hurr_translation_dir)
417 
418  ! Set output (relative) winds
419  du = u10*sin(adir-cs%Pi-alph) - uocn + u_ts
420  dv = u10*cos(adir-alph) - vocn + v_ts
421 
422  ! Use a simple drag coefficient as a function of U10 (from Sullivan et al., 2010)
423  du10 = sqrt(du**2+dv**2)
424  if (du10.lt.11.) then
425  cd = 1.2e-3
426  elseif (du10.lt.20.0) then
427  cd = (0.49 + 0.065*u10)*1.e-3
428  else
429  cd = 1.8e-3
430  endif
431 
432  ! Compute stress vector
433  tx = cs%rho_A * cd * sqrt(du**2 + dv**2) * du
434  ty = cs%rho_A * cd * sqrt(du**2 + dv**2) * dv
435 
436  return
437 end subroutine idealized_hurricane_wind_profile
438 
439 !> This subroutine is primarily needed as a legacy for reproducing answers.
440 !! It is included as an additional subroutine rather than padded into the previous
441 !! routine with flags to ease its eventual removal. Its functionality is replaced
442 !! with the new routines and it can be deleted when answer changes are acceptable.
443 subroutine scm_idealized_hurricane_wind_forcing(state, forces, day, G, US, CS)
444  type(surface), intent(in) :: state !< Surface state structure
445  type(mech_forcing), intent(inout) :: forces !< A structure with the driving mechanical forces
446  type(time_type), intent(in) :: day !< Time in days
447  type(ocean_grid_type), intent(inout) :: g !< Grid structure
448  type(unit_scale_type), intent(in) :: us !< A dimensional unit scaling type
449  type(idealized_hurricane_cs), pointer :: cs !< Container for SCM parameters
450  ! Local variables
451  integer :: i, j, is, ie, js, je, isq, ieq, jsq, jeq
452  integer :: isd, ied, jsd, jed, isdb, iedb, jsdb, jedb
453  real :: pie, deg2rad
454  real :: u10, a, b, c, r, f, du10, rkm ! For wind profile expression
455  real :: xx, t0 !for location
456  real :: dp, rb
457  real :: cd ! Air-sea drag coefficient
458  real :: uocn, vocn ! Surface ocean velocity components
459  real :: du, dv ! Air-sea differential motion
460  !Wind angle variables
461  real :: alph,rstr, a0, a1, p1, adir, transdir, v_ts, u_ts
462  logical :: br_bench
463  ! Bounds for loops and memory allocation
464  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
465  isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
466  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
467  isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
468 
469  ! Allocate the forcing arrays, if necessary.
470 
471  call allocate_mech_forcing(g, forces, stress=.true., ustar=.true.)
472  pie = 4.0*atan(1.0) ; deg2rad = pie/180.
473  !/ BR
474  ! Implementing Holland (1980) parameteric wind profile
475  !------------------------------------------------------|
476  br_bench = .true. !true if comparing to LES runs |
477  t0 = 129600. !TC 'eye' crosses (0,0) at 36 hours|
478  transdir = pie !translation direction (-x) |
479  !------------------------------------------------------|
480  dp = cs%pressure_ambient - cs%pressure_central
481  c = cs%max_windspeed / sqrt( dp )
482  b = c**2 * cs%rho_a * exp(1.0)
483  if (br_bench) then
484  ! rho_a reset to value used in generated wind for benchmark test
485  b = c**2 * 1.2 * exp(1.0)
486  endif
487  a = (cs%rad_max_wind/1000.)**b
488  f = us%s_to_T*g%CoriolisBu(is,js) ! f=f(x,y) but in the SCM is constant
489  if (br_bench) then
490  ! f reset to value used in generated wind for benchmark test
491  f = 5.5659e-05 !### A constant value in s-1.
492  endif
493  !/ BR
494  ! Calculate x position as a function of time.
495  xx = ( t0 - time_type_to_real(day)) * cs%hurr_translation_spd * cos(transdir)
496  r = sqrt(xx**2 + cs%DY_from_center**2)
497  !/ BR
498  ! rkm - r converted to km for Holland prof.
499  ! used in km due to error, correct implementation should
500  ! not need rkm, but to match winds w/ experiment this must
501  ! be maintained. Causes winds far from storm center to be a
502  ! couple of m/s higher than the correct Holland prof.
503  if (br_bench) then
504  rkm = r/1000.
505  rb = (rkm)**b
506  else
507  ! if not comparing to benchmark, then use correct Holland prof.
508  rkm = r
509  rb = r**b
510  endif
511  !/ BR
512  ! Calculate U10 in the interior (inside of 10x radius of maximum wind),
513  ! while adjusting U10 to 0 outside of 12x radius of maximum wind.
514  ! Note that rho_a is set to 1.2 following generated wind for experiment
515  if (r/cs%rad_max_wind > 0.001 .AND. r/cs%rad_max_wind < 10.) then
516  u10 = sqrt( a*b*dp*exp(-a/rb)/(1.2*rb) + 0.25*(rkm*f)**2 ) - 0.5*rkm*f
517  elseif (r/cs%rad_max_wind > 10. .AND. r/cs%rad_max_wind < 12.) then
518  r=cs%rad_max_wind*10.
519  if (br_bench) then
520  rkm = r/1000.
521  rb=rkm**b
522  else
523  rkm = r
524  rb = r**b
525  endif
526  u10 = ( sqrt( a*b*dp*exp(-a/rb)/(1.2*rb) + 0.25*(rkm*f)**2 ) - 0.5*rkm*f) &
527  * (12. - r/cs%rad_max_wind)/2.
528  else
529  u10 = 0.
530  endif
531  adir = atan2(cs%DY_from_center,xx)
532 
533  !/ BR
534  ! Wind angle model following Zhang and Ulhorn (2012)
535  ! ALPH is inflow angle positive outward.
536  rstr = min(10.,r / cs%rad_max_wind)
537  a0 = -0.9*rstr -0.09*cs%max_windspeed - 14.33
538  a1 = -a0 *(0.04*rstr +0.05*cs%hurr_translation_spd+0.14)
539  p1 = (6.88*rstr -9.60*cs%hurr_translation_spd+85.31)*pie/180.
540  alph = a0 - a1*cos( (transdir - adir ) - p1)
541  if (r/cs%rad_max_wind > 10. .AND. r/cs%rad_max_wind < 12.) then
542  alph = alph* (12. - r/cs%rad_max_wind)/2.
543  elseif (r/cs%rad_max_wind > 12.) then
544  alph = 0.0
545  endif
546  alph = alph * deg2rad
547  !/BR
548  ! Prepare for wind calculation
549  ! X_TS is component of translation speed added to wind vector
550  ! due to background steering wind.
551  u_ts = cs%hurr_translation_spd/2.*cos(transdir)
552  v_ts = cs%hurr_translation_spd/2.*sin(transdir)
553 
554  ! Set the surface wind stresses, in [Pa]. A positive taux
555  ! accelerates the ocean to the (pseudo-)east.
556  ! The i-loop extends to is-1 so that taux can be used later in the
557  ! calculation of ustar - otherwise the lower bound would be Isq.
558  do j=js,je ; do i=is-1,ieq
559  !/BR
560  ! Turn off surface current for stress calculation to be
561  ! consistent with test case.
562  uocn = 0.!state%u(I,j)
563  vocn = 0.!0.25*( (state%v(i,J) + state%v(i+1,J-1)) &
564  ! +(state%v(i+1,J) + state%v(i,J-1)) )
565  !/BR
566  ! Wind vector calculated from location/direction (sin/cos flipped b/c
567  ! cyclonic wind is 90 deg. phase shifted from position angle).
568  du = u10*sin(adir-pie-alph) - uocn + u_ts
569  dv = u10*cos(adir-alph) - vocn + v_ts
570  !/----------------------------------------------------|
571  !BR
572  ! Add a simple drag coefficient as a function of U10 |
573  !/----------------------------------------------------|
574  du10=sqrt(du**2+dv**2)
575  if (du10 < 11.) then
576  cd = 1.2e-3
577  elseif (du10 < 20.) then
578  cd = (0.49 + 0.065 * u10 )*0.001
579  else
580  cd = 0.0018
581  endif
582  forces%taux(i,j) = cs%rho_a * g%mask2dCu(i,j) * cd*sqrt(du**2+dv**2)*du
583  enddo ; enddo
584  !/BR
585  ! See notes above
586  do j=js-1,jeq ; do i=is,ie
587  uocn = 0.!0.25*( (state%u(I,j) + state%u(I-1,j+1)) &
588  ! +(state%u(I-1,j) + state%u(I,j+1)) )
589  vocn = 0.!state%v(i,J)
590  du = u10*sin(adir-pie-alph) - uocn + u_ts
591  dv = u10*cos(adir-alph) - vocn + v_ts
592  du10=sqrt(du**2+dv**2)
593  if (du10 < 11.) then
594  cd = 1.2e-3
595  elseif (du10 < 20.) then
596  cd = (0.49 + 0.065 * u10 )*0.001
597  else
598  cd = 0.0018
599  endif
600  forces%tauy(i,j) = cs%rho_a * g%mask2dCv(i,j) * cd*du10*dv
601  enddo ; enddo
602  ! Set the surface friction velocity [m s-1]. ustar is always positive.
603  do j=js,je ; do i=is,ie
604  ! This expression can be changed if desired, but need not be.
605  forces%ustar(i,j) = us%m_to_Z*us%T_to_s * g%mask2dT(i,j) * sqrt(cs%gustiness/cs%Rho0 + &
606  sqrt(0.5*(forces%taux(i-1,j)**2 + forces%taux(i,j)**2) + &
607  0.5*(forces%tauy(i,j-1)**2 + forces%tauy(i,j)**2))/cs%Rho0)
608  enddo ; enddo
609  return
610 end subroutine scm_idealized_hurricane_wind_forcing
611 
612 end module idealized_hurricane
mom_time_manager
Wraps the FMS time manager functions.
Definition: MOM_time_manager.F90:2
mom_forcing_type::mech_forcing
Structure that contains pointers to the mechanical forcing at the surface used to drive the liquid oc...
Definition: MOM_forcing_type.F90:185
mom_variables::surface
Pointers to various fields which may be used describe the surface state of MOM, and which will be ret...
Definition: MOM_variables.F90:38
mom_safe_alloc
Convenience functions for safely allocating memory without accidentally reallocating pointer and caus...
Definition: MOM_safe_alloc.F90:3
mom_verticalgrid
Provides a transparent vertical ocean grid type and supporting routines.
Definition: MOM_verticalGrid.F90:2
mom_file_parser::log_version
An overloaded interface to log version information about modules.
Definition: MOM_file_parser.F90:109
mom_variables::thermo_var_ptrs
Pointers to an assortment of thermodynamic fields that may be available, including potential temperat...
Definition: MOM_variables.F90:82
mom_file_parser::param_file_type
A structure that can be parsed to read and document run-time parameters.
Definition: MOM_file_parser.F90:54
mom_file_parser::get_param
An overloaded interface to read and log the values of various types of parameters.
Definition: MOM_file_parser.F90:102
mom_unit_scaling::unit_scale_type
Describes various unit conversion factors.
Definition: MOM_unit_scaling.F90:14
mom_forcing_type
This module implements boundary forcing for MOM6.
Definition: MOM_forcing_type.F90:2
mom_verticalgrid::verticalgrid_type
Describes the vertical ocean grid, including unit conversion factors.
Definition: MOM_verticalGrid.F90:24
mom_variables
Provides transparent structures with groups of MOM6 variables and supporting routines.
Definition: MOM_variables.F90:2
mom_file_parser
The MOM6 facility to parse input files for runtime parameters.
Definition: MOM_file_parser.F90:2
idealized_hurricane
Forcing for the idealized hurricane and SCM_idealized_hurricane examples.
Definition: Idealized_Hurricane.F90:2
mom_grid
Provides the ocean grid type.
Definition: MOM_grid.F90:2
mom_unit_scaling
Provides a transparent unit rescaling type to facilitate dimensional consistency testing.
Definition: MOM_unit_scaling.F90:2
mom_forcing_type::forcing
Structure that contains pointers to the boundary forcing used to drive the liquid ocean simulated by ...
Definition: MOM_forcing_type.F90:49
idealized_hurricane::idealized_hurricane_cs
Container for parameters describing idealized wind structure.
Definition: Idealized_Hurricane.F90:45
mom_safe_alloc::safe_alloc_ptr
Allocate a pointer to a 1-d, 2-d or 3-d array.
Definition: MOM_safe_alloc.F90:12
mom_error_handler
Routines for error handling and I/O management.
Definition: MOM_error_handler.F90:2
mom_grid::ocean_grid_type
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:25