CCPP SciDoc v7.0.x  v7.0.0
Common Community Physics Package Developed at DTC
 
Loading...
Searching...
No Matches
ugwpv1_gsldrag.F90
1
2
39
40 use machine, only: kind_phys
41
42 use cires_ugwpv1_triggers, only: slat_geos5_2020, slat_geos5_tamp_v1
43 use cires_ugwpv1_module, only: cires_ugwpv1_init, ngwflux_update, calendar_ugwp
44 use cires_ugwpv1_module, only: knob_ugwp_version, cires_ugwp_dealloc, tamp_mpa
45 use cires_ugwpv1_solv2, only: cires_ugwpv1_ngw_solv2
46! use cires_ugwpv1_solv2, only: cires_ugwpv1_ngw_solv2, ecmwf_ngw
47 use ecmwf_ngw, only: ecmwf_ngw_emc
48
49 use cires_ugwpv1_oro, only: orogw_v1
50
51 use drag_suite, only: drag_suite_run, drag_suite_psl
52
53 implicit none
54
55 private
56
57 public ugwpv1_gsldrag_init, ugwpv1_gsldrag_run, ugwpv1_gsldrag_finalize
58
59 logical :: is_initialized = .false.
60
61contains
62
63! ------------------------------------------------------------------------
64! CCPP entry points for CIRES Unified Gravity Wave Physics (UGWP) scheme v0
65! ------------------------------------------------------------------------
70 subroutine ugwpv1_gsldrag_init ( &
71 me, master, nlunit, input_nml_file, logunit, &
72 fn_nml2, jdat, lonr, levs, ak, bk, dtp, &
73 con_pi, con_rerth, con_p0, &
74 con_g, con_omega, con_cp, con_rd, con_rv,con_fvirt, &
75 do_ugwp,do_ugwp_v0, do_ugwp_v0_orog_only, do_gsl_drag_ls_bl, &
76 do_gsl_drag_ss, do_gsl_drag_tofd, do_ngw_ec, do_ugwp_v1, &
77!! do_gsl_drag_ss, do_gsl_drag_tofd, do_ugwp_v1, &
78 do_ugwp_v1_orog_only, do_ugwp_v1_w_gsldrag, errmsg, errflg)
79
80 use ugwp_common
81
82!---- initialization of unified_ugwp
83 implicit none
84
85 integer, intent (in) :: me
86 integer, intent (in) :: master
87 integer, intent (in) :: nlunit
88 character(len=*), intent (in) :: input_nml_file(:)
89 integer, intent (in) :: logunit
90 integer, intent (in) :: jdat(:)
91 integer, intent (in) :: lonr
92 integer, intent (in) :: levs
93 real(kind=kind_phys), intent (in) :: ak(:), bk(:)
94 real(kind=kind_phys), intent (in) :: dtp
95
96 real(kind=kind_phys), intent (in) :: con_p0, con_pi, con_rerth
97 real(kind=kind_phys), intent (in) :: con_g, con_cp, con_rd, con_rv, con_omega, con_fvirt
98 logical, intent (in) :: do_ugwp
99
100 logical, intent (in) :: do_ugwp_v0, do_ugwp_v0_orog_only, &
101 do_gsl_drag_ls_bl, do_gsl_drag_ss, &
102!! do_gsl_drag_tofd, do_ugwp_v1, &
103 do_gsl_drag_tofd, do_ugwp_v1, do_ngw_ec, &
104 do_ugwp_v1_orog_only,do_ugwp_v1_w_gsldrag
105
106 character(len=*), intent (in) :: fn_nml2
107 !character(len=*), parameter :: fn_nml='input.nml'
108
109 character(len=*), intent(out) :: errmsg
110 integer, intent(out) :: errflg
111
112 ! Initialize CCPP error handling variables
113 errmsg = ''
114 errflg = 0
115!============================================================================
116!
117! gwd_opt => "1 and 2, 3, 22, 33' see previous GSL-commits
118! related to GSL-oro drag suite
119! for use of the new-GSL/old-GFS/EMC inputs for sub-grid orography
120! see details inside /ufs-weather-model/FV3/io/FV3GFS_io.F90
121! FV3GFS_io.F90: if (Model%gwd_opt==3 .or. Model%gwd_opt==33 .or. &
122! FV3GFS_io.F90: Model%gwd_opt==2 .or. Model%gwd_opt==22 ) then
123! FV3GFS_io.F90: if ( (Model%gwd_opt==3 .or. Model%gwd_opt==33) .or. &
124! FV3GFS_io.F90: ( (Model%gwd_opt==2 .or. Model%gwd_opt==22) .and. &
125!
126! gwd_opt=1 -current 14-element GFS-EMC subgrid-oro input
127! gwd_opt=2 and 3 24-element -current 14-element GFS-EMC subgrid-oro input
128! GSL uses the gwd_opt flag to control "extra" diagnostics (22 and 33)
129! CCPP may use gwd_opt to determine 14 or 24 variables for the input
130! but at present you work with "nmtvr"
131! GFS_GWD_generic.F90: integer, intent(in) :: im, levs, nmtvr
132!GFS_GWD_generic.F90: real(kind=kind_phys), intent(in) :: mntvar(im,nmtvr)
133!GFS_GWD_generic.F90: if (nmtvr == 14) then ! gwd_opt=1 current operational - as of 2014
134!GFS_GWD_generic.F90: elseif (nmtvr == 10) then ????
135!GFS_GWD_generic.F90: elseif (nmtvr == 6) then ????
136!GFS_GWD_generic.F90: elseif (nmtvr == 24) then ! GSD_drag_suite and unified_ugwp gwd_opt=2,3
137!
138! 1) gsldrag: do_gsl_drag_ls_bl, do_gsl_drag_ss, do_gsl_drag_tofd, do_ugwp_v1
139! 2) CIRES-v1: do_ugwp_v1, do_ugwp_v1_orog_only, do_tofd, ldiag_ugwp
140!==============================================================================
141 ! Test to make sure that at most only one large-scale/blocking
142 ! orographic drag scheme is chosen
143 if ( (do_ugwp_v0.and.(do_ugwp_v0_orog_only.or.do_gsl_drag_ls_bl.or. &
144 do_ugwp_v1.or.do_ugwp_v1_orog_only)) .or. &
145 (do_ugwp_v0_orog_only.and.(do_gsl_drag_ls_bl.or.do_ugwp_v1.or. &
146 do_ugwp_v1_orog_only)) .or. &
147 (do_gsl_drag_ls_bl.and.do_ugwp_v1_orog_only) ) then
148
149 write(errmsg,'(*(a))') "Logic error: Only one large-scale&
150 &/blocking scheme (do_ugwp_v0,do_ugwp_v0_orog_only,&
151 &do_gsl_drag_ls_bl,do_ugwp_v1 or &
152 &do_ugwp_v1_orog_only) can be chosen"
153 errflg = 1
154 return
155
156 end if
157
158 if ( do_ugwp_v0_orog_only .or. do_ugwp_v0) then
159 print *, ' ccpp do_ugwp_v0 active ', do_ugwp_v0
160 print *, ' ccpp do_ugwp_v1_orog_only active ', do_ugwp_v0_orog_only
161 write(errmsg,'(*(a))') " the CIRES <ugwpv1_gsldrag> CCPP-suite does not &
162 support <ugwp_v0> schemes "
163 errflg = 1
164 return
165 endif
166
167 if (do_ugwp_v1_w_gsldrag .and. do_ugwp_v1_orog_only ) then
168
169 print *, ' do_ugwp_v1_w_gsldrag ', do_ugwp_v1_w_gsldrag
170 print *, ' do_ugwp_v1_orog_only ', do_ugwp_v1_orog_only
171 print *, ' do_gsl_drag_ls_bl ',do_gsl_drag_ls_bl
172 write(errmsg,'(*(a))') " the CIRES <ugwpv1_gsldrag> CCPP-suite intend to &
173 support <ugwp_v1> with <gsldrag> but has Logic error"
174 errflg = 1
175 return
176 endif
177!==========================
178!
179! initialize ugwp_common
180! con_pi, con_rerth, con_p0, con_g, con_omega, con_cp, con_rd, con_rv,con_fvirt
181!
182!==========================
183
184 pi = con_pi
185 arad = con_rerth
186 p0s = con_p0
187 grav = con_g
188 omega1= con_omega
189 cpd = con_cp
190 rd = con_rd
191 rv = con_rv
192 fv = con_fvirt
193
194 grav2 = grav + grav; rgrav = 1.0/grav ; rgrav2 = rgrav*rgrav
195 rdi = 1.0 / rd ; rcpd = 1./cpd; rcpd2 = 0.5/cpd
196 gor = grav/rd
197 gr2 = grav*gor
198 grcp = grav*rcpd
199 gocp = grcp
200 rcpdl = cpd*rgrav
201 grav2cpd = grav*grcp
202
203 pi2 = 2.*pi ; pih = .5*pi
204 rad_to_deg=180.0/pi
205 deg_to_rad=pi/180.0
206
207 bnv2min = (pi2/1800.)*(pi2/1800.)
208 bnv2max = (pi2/30.)*(pi2/30.)
209 dw2min = 1.0
210 velmin = sqrt(dw2min)
211 minvel = 0.5
212
213 omega2 = 2.*omega1
214 omega3 = 3.*omega1
215
216 hpscale = 7000. ; hpskm = hpscale*1.e-3
217 rhp = 1./hpscale
218 rhp2 = 0.5*rhp; rh4 = 0.25*rhp
219 rhp4 = rhp2 * rhp2
220 khp = rhp* rd/cpd
221 mkzmin = pi2/80.0e3
222 mkz2min = mkzmin*mkzmin
223 mkzmax = pi2/500.
224 mkz2max = mkzmax*mkzmax
225 cdmin = 2.e-2/mkzmax
226
227 rcpdt = rcpd/dtp
228
229 if ( do_ugwp_v1 ) then
230 call cires_ugwpv1_init (me, master, nlunit, logunit, jdat, con_pi, &
231 con_rerth, fn_nml2, input_nml_file, lonr, &
232 levs, ak, bk, con_p0, dtp, errmsg, errflg)
233 if (errflg/=0) return
234 end if
235
236 if (me == master) then
237 print *, ' ccpp: ugwpv1_gsldrag_init '
238
239 print *, ' ccpp do_ugwp_v1 flag ', do_ugwp_v1
240 print *, ' ccpp do_gsl_drag_ls_bl flag ', do_gsl_drag_ls_bl
241 print *, ' ccpp do_gsl_drag_ss flag ' , do_gsl_drag_ss
242 print *, ' ccpp do_gsl_drag_tofd flag ', do_gsl_drag_tofd
243
244 print *, ' ccpp: ugwpv1_gsldrag_init '
245 endif
246
247 is_initialized = .true.
248
249 end subroutine ugwpv1_gsldrag_init
250
251! -----------------------------------------------------------------------
252! finalize of ugwpv1_gsldrag (_finalize)
253! -----------------------------------------------------------------------
254
256
260 subroutine ugwpv1_gsldrag_finalize(errmsg, errflg)
261
262 implicit none
263
264 character(len=*), intent(out) :: errmsg
265 integer, intent(out) :: errflg
266
267! Initialize CCPP error handling variables
268 errmsg = ''
269 errflg = 0
270
271 if (.not.is_initialized) return
272
273 call cires_ugwp_dealloc
274
275 is_initialized = .false.
276
277 end subroutine ugwpv1_gsldrag_finalize
278
279! -----------------------------------------------------------------------
280! originally from ugwp_driver_v0.f
281! driver of cires_ugwp (_driver)
282! -----------------------------------------------------------------------
283! driver is called after pbl & before chem-parameterizations
284! -----------------------------------------------------------------------
285! order = dry-adj=>conv=mp-aero=>radiation -sfc/land- chem -> vertdiff-> [rf-gws]=> ion-re
286! -----------------------------------------------------------------------
295 subroutine ugwpv1_gsldrag_run(me, master, im, levs, ak, bk, ntrac, lonr, dtp, &
296 kdt, ldiag3d, lssav, flag_for_gwd_generic_tend, do_gsl_drag_ls_bl, &
297 do_gsl_drag_ss, do_gsl_drag_tofd, &
298 do_gwd_opt_psl, psl_gwd_dx_factor, &
299 do_ngw_ec, do_ugwp_v1, do_ugwp_v1_orog_only, &
300 do_ugwp_v1_w_gsldrag, gwd_opt, do_tofd, ldiag_ugwp, ugwp_seq_update, &
301 cdmbgwd, alpha_fd, jdat, nmtvr, hprime, oc, theta, sigma, gamma, &
302 elvmax, clx, oa4, varss,oc1ss,oa4ss,ol4ss, dx, xlat, xlat_d, sinlat, coslat, &
303 area, rain, br1, hpbl,vtype, kpbl, slmsk, &
304 ugrs, vgrs, tgrs, q1, prsi, prsl, prslk, phii, phil, del, tau_amf, &
305 dudt_ogw, dvdt_ogw, du_ogwcol, dv_ogwcol, &
306 dudt_obl, dvdt_obl, du_oblcol, dv_oblcol, &
307 dudt_oss, dvdt_oss, du_osscol, dv_osscol, &
308 dudt_ofd, dvdt_ofd, du_ofdcol, dv_ofdcol, &
309 dudt_ngw, dvdt_ngw, dtdt_ngw, kdis_ngw, dudt_gw, dvdt_gw, dtdt_gw, kdis_gw, &
310 tau_ogw, tau_ngw, tau_oss, &
311 zogw, zlwb, zobl, zngw, dusfcg, dvsfcg, dudt, dvdt, dtdt, rdxzb, &
312 dtend, dtidx, index_of_x_wind, index_of_y_wind, index_of_temperature, &
313 index_of_process_orographic_gwd, index_of_process_nonorographic_gwd, &
314 lprnt, ipr, spp_wts_gwd, spp_gwd, errmsg, errflg)
315
316!
317!########################################################################
318! Attention New Arrays and Names must be ADDED inside
319!
320! a) /FV3/gfsphysics/GFS_layer/GFS_typedefs.meta
321! b) /FV3/gfsphysics/GFS_layer/GFS_typedefs.F90
322! c) /FV3/gfsphysics/GFS_layer/GFS_diagnostics.F90 "diag-cs is not tested"
323!########################################################################
324
325 use ugwp_common, only : con_pi => pi, con_g => grav, con_rd => rd, &
326 con_rv => rv, con_cp => cpd, con_fv => fv, &
327 con_rerth => arad, con_omega => omega1, rgrav
328
329 implicit none
330
331! Preference use (im,levs) rather than (:,:) to avoid memory-leaks
332! that found in Nov-Dec 2020
333! order array-description control-logical
334! other in-variables
335! out-variables
336! local-variables
337!
338! unified GSL and CIRES diagnostics inside CCPP and GFS_typedefs.F90/GFS_diagnostics.F90
339!
340! interface variables
341 logical, intent(in) :: ldiag3d, lssav
342 logical, intent(in) :: flag_for_gwd_generic_tend
343 logical, intent(in) :: lprnt
344
345 integer, intent(in) :: ipr
346
347! flags for choosing combination of GW drag schemes to run
348
349 logical, intent (in) :: do_gsl_drag_ls_bl, do_gsl_drag_ss, do_gsl_drag_tofd
350 logical, intent (in) :: do_ugwp_v1, do_ngw_ec, do_ugwp_v1_orog_only, do_tofd
351 logical, intent (in) :: ldiag_ugwp, ugwp_seq_update
352 logical, intent (in) :: do_ugwp_v1_w_gsldrag ! combination of ORO and NGW schemes
353
354 integer, intent(in) :: me, master, im, levs, ntrac,lonr
355 real(kind=kind_phys), intent(in) :: dtp
356 real(kind=kind_phys), intent(in) :: ak(:), bk(:)
357 integer, intent(in) :: kdt, jdat(:)
358! option for psl gwd
359 logical, intent(in) :: do_gwd_opt_psl ! option for psl gravity wave drag
360 real(kind=kind_phys), intent(in) :: psl_gwd_dx_factor !
361! SSO parameters and variables
362 integer, intent(in) :: gwd_opt !gwd_opt and nmtvr are "redundant" controls
363 integer, intent(in) :: nmtvr
364 real(kind=kind_phys), intent(in) :: cdmbgwd(:), alpha_fd ! for gsl_drag
365
366 real(kind=kind_phys), intent(in), dimension(:) :: hprime, oc, theta, sigma, gamma
367
368 real(kind=kind_phys), intent(in), dimension(:) :: elvmax
369 real(kind=kind_phys), intent(in), dimension(:,:) :: clx, oa4
370
371 real(kind=kind_phys), intent(in), dimension(:) :: dx
372 real(kind=kind_phys), intent(in), dimension(:) :: varss,oc1ss
373 real(kind=kind_phys), intent(in), dimension(:,:) :: oa4ss,ol4ss
374
375!=====
376!ccpp-style passing constants, I prefer to take them out from the "call-subr" list
377!=====
378! real(kind=kind_phys), intent(in) :: con_g, con_omega, con_pi, con_cp, con_rd, &
379! con_rv, con_rerth, con_fvirt
380! grids
381
382 real(kind=kind_phys), intent(in), dimension(:) :: xlat, xlat_d, sinlat, coslat, area
383
384! State vars + PBL/slmsk +rain
385
386 real(kind=kind_phys), intent(in), dimension(:,:) :: del, ugrs, vgrs, tgrs, prsl, prslk, phil
387 real(kind=kind_phys), intent(in), dimension(:,:) :: prsi, phii
388 real(kind=kind_phys), intent(in), dimension(:,:) :: q1
389 integer, intent(in), dimension(:) :: kpbl
390 integer, intent(in), dimension(:) :: vtype
391
392 real(kind=kind_phys), intent(in), dimension(:) :: rain
393 real(kind=kind_phys), intent(in), dimension(:) :: br1, hpbl, slmsk
394!
395! moved to GFS_phys_time_vary
396! real(kind=kind_phys), intent(in), dimension(:) :: ddy_j1tau, ddy_j2tau
397! integer, intent(in), dimension(:) :: jindx1_tau, jindx2_tau
398 real(kind=kind_phys), intent(in), dimension(:) :: tau_amf
399
400!Output (optional):
401
402 real(kind=kind_phys), intent(out), dimension(:) :: &
403 du_ogwcol, dv_ogwcol, du_oblcol, dv_oblcol, &
404 du_osscol, dv_osscol, du_ofdcol, dv_ofdcol
405!
406! we may add later but due to launch in the upper layes ~ mPa comparing to ORO Pa*(0.1)
407! du_ngwcol, dv_ngwcol
408
409 real(kind=kind_phys), intent(out), dimension(:) :: dusfcg, dvsfcg
410 real(kind=kind_phys), intent(out), dimension(:) :: tau_ogw, tau_ngw, tau_oss
411
412 real(kind=kind_phys), intent(out) , dimension(:,:) :: &
413 dudt_ogw, dvdt_ogw, dudt_obl, dvdt_obl, &
414 dudt_oss, dvdt_oss, dudt_ofd, dvdt_ofd
415
416 real(kind=kind_phys), intent(out) , dimension(:,:) :: dudt_ngw, dvdt_ngw, kdis_ngw, dtdt_ngw
417 real(kind=kind_phys), intent(out) , dimension(:,:) :: dudt_gw, dvdt_gw, dtdt_gw, kdis_gw
418
419 real(kind=kind_phys), intent(out) , dimension(:) :: zogw, zlwb, zobl, zngw
420
421 real(kind=kind_phys), intent(inout), dimension(:,:) :: dudt, dvdt, dtdt
422
423 real(kind=kind_phys), intent(inout), optional :: dtend(:,:,:)
424 integer, intent(in) :: dtidx(:,:)
425 integer, intent(in) :: &
426 index_of_x_wind, index_of_y_wind, index_of_temperature, &
427 index_of_process_orographic_gwd, index_of_process_nonorographic_gwd
428
429 real(kind=kind_phys), intent(out), dimension(:) :: rdxzb ! for stoch phys. mtb-level
430
431 real(kind=kind_phys), intent(in), optional :: spp_wts_gwd(:,:)
432 integer, intent(in) :: spp_gwd
433
434 character(len=*), intent(out) :: errmsg
435 integer, intent(out) :: errflg
436
437! local variables
438 integer :: i, k
439 real(kind=kind_phys), dimension(im) :: sgh30
440 real(kind=kind_phys), dimension(im, levs) :: pdvdt, pdudt
441 real(kind=kind_phys), dimension(im, levs) :: pdtdt, pkdis
442!------------
443!
444! from ugwp_driver_v0.f -> cires_ugwp_initialize.F90 -> module ugwp_wmsdis_init
445! now in the namelist of cires_ugwp "knob_ugwp_tauamp" controls tamp_mpa
446!
447! tamp_mpa =knob_ugwp_tauamp !amplitude for GEOS-5/MERRA-2
448!------------
449! real(kind=kind_phys), parameter :: tamp_mpa_v0=30.e-3 ! large flux to help "GFS-ensembles" in July 2019
450
451! switches that activate impact of OGWs and NGWs
452
453! integer :: nmtvr_temp
454
455 real(kind=kind_phys), dimension(im, levs) :: zmet ! geopotential height at model Layer centers
456 real(kind=kind_phys), dimension(im, levs+1) :: zmeti ! geopotential height at model layer interfaces
457
458! ugwp_v1 local variables
459
460 integer :: y4, month, day, ddd_ugwp, curdate, curday, idtend
461
462! ugwp_v1 temporary (local) diagnostic variables from cires_ugwp_solv2_v1
463! diagnostics for wind and temp rms to compare with space-borne data and metrics
464! in the Middle atmosphere: 20-110 km ( not active in CCPP-style, oct 2020)
465! real(kind=kind_phys) :: tauabs(im,levs), wrms(im,levs), trms(im,levs)
466
467 ! Initialize CCPP error handling variables
468
469 errmsg = ''
470 errflg = 0
471
472! 1) ORO stationary GWs
473! ------------------
474!
475! for all oro-suites can uze geo-meters having "hpbl"
476!
477! All GW-schemes operate with Zmet =phil*inv_g, passing Zmet/Zmeti can be more robust
478! + rho*dz = =delp * inv_g can be also pre-comp for all "GW-schemes"
479!
480 zmeti = phii* rgrav
481 zmet = phil* rgrav
482
483!===============================================================
484! ORO-diag
485
486 if (do_ugwp_v1 .or. ldiag_ugwp) then
487 dudt_ogw(:,:)= 0.; dvdt_ogw(:,:)=0.; dudt_obl(:,:)=0.; dvdt_obl(:,:)=0.
488 dudt_oss(:,:)= 0.; dvdt_oss(:,:)=0.; dudt_ofd(:,:)=0.; dvdt_ofd(:,:)=0.
489 du_ogwcol(:)=0. ; dv_ogwcol(:)=0. ; du_oblcol(:)=0. ; dv_oblcol(:)=0.
490 du_osscol(:)=0. ; dv_osscol(:)=0. ;du_ofdcol(:)=0. ; dv_ofdcol(:)=0.
491 dudt_ngw(:,:)=0.; dvdt_ngw(:,:)=0.; dtdt_ngw(:,:)=0.; kdis_ngw(:,:)=0.
492 else
493 dudt_ogw(:,:) = 0.
494 end if
495
496 dusfcg(:) = 0. ; dvsfcg(:) =0.
497
498! ngw+ogw - diag
499
500 dudt_gw(:,:)=0. ; dvdt_gw(:,:)=0. ; dtdt_gw(:,:)=0. ; kdis_gw(:,:)=0.
501! source fluxes
502
503 tau_ogw(:)=0. ; tau_ngw(:)=0. ; tau_oss(:)=0.
504
505! launch layers
506
507 zlwb(:)= 0. ; zogw(:)=0. ; zobl(:)=0. ; zngw(:)=0.
508!===============================================================
509! diag tendencies due to all-SSO schemes (ORO-physics)
510! ogw + obl + oss + ofd ..... no explicit "lee wave trapping"
511!===============================================================
512 do k=1,levs
513 do i=1,im
514 pdvdt(i,k) = 0.0
515 pdudt(i,k) = 0.0
516 pdtdt(i,k) = 0.0
517 pkdis(i,k) = 0.0
518 enddo
519 enddo
520
521 ! Run the appropriate large-scale (large-scale GWD + blocking) scheme
522 ! Note: In case of GSL drag_suite, this includes ss and tofd
523
524 if ( do_gsl_drag_ls_bl.or.do_gsl_drag_ss.or.do_gsl_drag_tofd) then
525!
526! to do: the zero diag and tendency values assigned inside "drag_suite_run" can be skipped :
527!
528! dudt_ogw, dvdt_ogw, dudt_obl, dvdt_obl,dudt_oss, dvdt_oss, dudt_ofd, dvdt_ofd
529! du_ogwcol, dv_ogwcol, du_oblcol, dv_oblcol, du_osscol, dv_osscol, du_ofdcol dv_ofdcol
530! dusfcg, dvsfcg
531!
532 if (do_gwd_opt_psl) then
533 call drag_suite_psl(im, levs, pdvdt, pdudt, pdtdt, &
534 ugrs,vgrs,tgrs,q1, &
535 kpbl,prsi,del,prsl,prslk,phii,phil,dtp, &
536 kdt,hprime,oc,oa4,clx,varss,oc1ss,oa4ss, &
537 ol4ss,theta,sigma,gamma,elvmax, &
538 dudt_ogw, dvdt_ogw, dudt_obl, dvdt_obl, &
539 dudt_oss, dvdt_oss, dudt_ofd, dvdt_ofd, &
540 dusfcg, dvsfcg, &
541 du_ogwcol, dv_ogwcol, du_oblcol, dv_oblcol, &
542 du_osscol, dv_osscol, du_ofdcol, dv_ofdcol, &
543 slmsk,br1,hpbl,vtype,con_g,con_cp,con_rd,con_rv, &
544 con_fv, con_pi, lonr, &
545 cdmbgwd(1:2),alpha_fd,me,master, &
546 lprnt,ipr,rdxzb,dx,gwd_opt, &
547 do_gsl_drag_ls_bl,do_gsl_drag_ss,do_gsl_drag_tofd, &
548 psl_gwd_dx_factor, &
549 dtend, dtidx, index_of_process_orographic_gwd, &
550 index_of_temperature, index_of_x_wind, &
551 index_of_y_wind, ldiag3d, ldiag_ugwp, &
552 ugwp_seq_update, spp_wts_gwd, spp_gwd, errmsg, errflg)
553 else
554 call drag_suite_run(im, levs, pdvdt, pdudt, pdtdt, &
555 ugrs,vgrs,tgrs,q1, &
556 kpbl,prsi,del,prsl,prslk,phii,phil,dtp, &
557 kdt,hprime,oc,oa4,clx,varss,oc1ss,oa4ss, &
558 ol4ss,theta,sigma,gamma,elvmax, &
559 dudt_ogw, dvdt_ogw, dudt_obl, dvdt_obl, &
560 dudt_oss, dvdt_oss, dudt_ofd, dvdt_ofd, &
561 dusfcg, dvsfcg, &
562 du_ogwcol, dv_ogwcol, du_oblcol, dv_oblcol, &
563 du_osscol, dv_osscol, du_ofdcol, dv_ofdcol, &
564 slmsk,br1,hpbl,con_g,con_cp,con_rd,con_rv, &
565 con_fv, con_pi, lonr, &
566 cdmbgwd(1:2),alpha_fd,me,master, &
567 lprnt,ipr,rdxzb,dx,gwd_opt, &
568 do_gsl_drag_ls_bl,do_gsl_drag_ss,do_gsl_drag_tofd, &
569 dtend, dtidx, index_of_process_orographic_gwd, &
570 index_of_temperature, index_of_x_wind, &
571 index_of_y_wind, ldiag3d, ldiag_ugwp, &
572 ugwp_seq_update, spp_wts_gwd, spp_gwd, errmsg, errflg)
573 endif
574 if(errflg/=0) return
575
576!
577! dusfcg = du_ogwcol + du_oblcol + du_osscol + du_ofdcol
578!
579! if (kdt <= 2 .and. me == master) then
580! print *, ' unified drag_suite_run ', kdt
581! print *, ' GSL drag du/dt ', maxval(Pdudt)*86400, minval(Pdudt)*86400
582! print *, ' GSL drag dv/dt ', maxval(Pdvdt)*86400, minval(Pdvdt)*86400
583!
584! zero print *, ' unified drag_GSL dT/dt ', maxval(Pdtdt)*86400, minval(Pdtdt)*86400
585!
586! if (gwd_opt == 22 .or. gwd_opt == 33) then
587! print *, ' unified drag_GSL dUBL/dt ', maxval(dudt_obl)*86400, minval(dudt_obl)*86400
588! print *, ' unified drag_GSL dVBL/dt ', maxval(dvdt_obl)*86400, minval(dvdt_obl)*86400
589! print *, ' unified drag_GSL dUOGW/dt ', maxval(dudt_ogw)*86400, minval(dudt_ogw)*86400
590! print *, ' unified drag_GSL dVOGW/dt ', maxval(dvdt_ogw)*86400, minval(dvdt_ogw)*86400
591! print *, ' unified drag_GSL dUOss/dt ', maxval(dudt_oss)*86400, minval(dudt_oss)*86400
592! print *, ' unified drag_GSL dVOSS/dt ', maxval(dvdt_oss)*86400, minval(dvdt_oss)*86400
593! print *, ' unified drag_GSL dUOfd/dt ', maxval(dudt_ofd)*86400, minval(dudt_ofd)*86400
594! print *, ' unified drag_GSL dVOfd/dt ', maxval(dvdt_ofd)*86400, minval(dvdt_ofd)*86400
595! endif
596! endif
597
598 endif
599!
600! not gsldrag large-scale oro-scheme for example "do_ugwp_v1_orog_only"
601!
602
603 if ( do_ugwp_v1_orog_only ) then
604!
605! for TOFD we use now "varss" of GSL-drag /not sgh30=abs(oro-oro_f)/
606! only sum of integrated ORO+GW effects (dusfcg and dvsfcg) = sum(ogw + obl + oss*0 + ofd + ngw)
607!
608! OROGW_V1 introduce "orchestration" between OGW-effects and Mountain Blocking
609! it starts to examines options for the Scale-Aware (SA)formulation of SSO-effects
610! if ( me == master .and. kdt == 1) print *, ' bf orogw_v1 nmtvr=', nmtvr, ' do_tofd=', do_tofd
611
612 if (gwd_opt ==1 )sgh30 = 0.15*hprime ! portion of the mesoscale SSO (~[oro_unfilt -oro_filt)
613 if (gwd_opt >1 ) sgh30 = varss ! as in gsldrag: see drag_suite_run
614
615 call orogw_v1 (im, levs, lonr, me, master,dtp, kdt, do_tofd, &
616 xlat_d, sinlat, coslat, area, &
617 cdmbgwd(1:2), hprime, oc, oa4, clx, theta, &
618 sigma, gamma, elvmax, sgh30, kpbl, ugrs, &
619 vgrs, tgrs, q1, prsi,del,prsl,prslk, zmeti, zmet, &
620 pdvdt, pdudt, pdtdt, pkdis, dusfcg, dvsfcg,rdxzb, &
621 zobl, zlwb, zogw, tau_ogw, dudt_ogw, dvdt_ogw, &
622 dudt_obl, dvdt_obl,dudt_ofd, dvdt_ofd, &
623 du_ogwcol, dv_ogwcol, du_oblcol, dv_oblcol, &
624 du_ofdcol, dv_ofdcol, errmsg,errflg )
625 if(errflg/=0) return
626
627!
628! orogw_v1: dusfcg = du_ogwcol + du_oblcol + du_ofdcol only 3 terms
629!
630! if (kdt <= 2 .and. me == master) then
631!
632! print *, ' unified_ugwp orogw_v1 ', kdt, me, nmtvr
633! print *, ' unified_ugwp orogw_v1 du/dt ', maxval(Pdudt)*86400, minval(Pdudt)*86400
634! print *, ' unified_ugwp orogw_v1 dv/dt ', maxval(Pdvdt)*86400, minval(Pdvdt)*86400
635! print *, ' unified_ugwp orogw_v1 dT/dt ', maxval(Pdtdt)*86400, minval(Pdtdt)*86400
636! print *, ' unified_ugwp orogw_v1 dUBL/dt ', maxval(dudt_obl)*86400, minval(dudt_obl)*86400
637! print *, ' unified_ugwp orogw_v1 dVBL/dt ', maxval(dvdt_obl)*86400, minval(dvdt_obl)*86400
638! endif
639
640 end if
641!
642! for old-fashioned GFS-style diag-cs like dt3dt(:.:, 1:14) collections
643!
644 if(ldiag3d .and. lssav .and. .not. flag_for_gwd_generic_tend) then
645 idtend = dtidx(index_of_x_wind,index_of_process_orographic_gwd)
646 if(idtend>=1) then
647 dtend(:,:,idtend) = dtend(:,:,idtend) + pdudt*dtp
648 endif
649 idtend = dtidx(index_of_y_wind,index_of_process_orographic_gwd)
650 if(idtend>=1) then
651 dtend(:,:,idtend) = dtend(:,:,idtend) + pdvdt*dtp
652 endif
653 idtend = dtidx(index_of_temperature,index_of_process_orographic_gwd)
654 if(idtend>=1) then
655 dtend(:,:,idtend) = dtend(:,:,idtend) + pdtdt*dtp
656 endif
657 endif
658!
659!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
660! Begin non-stationary GW schemes
661! ugwp_v1
662!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
663
664 if (do_ugwp_v1) then
665
666!==================================================================
667! call slat_geos5_tamp_v1(im, tamp_mpa, xlat_d, tau_ngw)
668!
669! 2020 updates of MERRA/GEOS tau_ngw for the C96-QBO FV3GFS-127L runs
670!==================================================================
671
672 call slat_geos5_2020(im, tamp_mpa, xlat_d, tau_ngw)
673
674 y4 = jdat(1); month = jdat(2); day = jdat(3)
675!
676! hour = jdat(5)
677! fhour = float(hour)+float(jdat(6))/60. + float(jdat(7))/3600.
678! fhour = (kdt-1)*dtp/3600.
679! fhrday = fhour/24. - nint(fhour/24.)
680
681 call calendar_ugwp(y4, month, day, ddd_ugwp)
682 curdate = y4*1000 + ddd_ugwp
683
684 call ngwflux_update(me, master, im, levs, kdt, ddd_ugwp,curdate, &
685 tau_amf, xlat_d, sinlat,coslat, rain, tau_ngw)
686
687 if (do_ngw_ec) then
688
689 call ecmwf_ngw_emc(me, master, im, levs, kdt, dtp, dx, &
690 tau_ngw, tgrs, ugrs, vgrs, q1, prsl, prsi, &
691 zmet, zmeti,prslk, xlat_d, sinlat, coslat, &
692 dudt_ngw, dvdt_ngw, dtdt_ngw, kdis_ngw, zngw)
693 else
694
695 call cires_ugwpv1_ngw_solv2(me, master, im, levs, kdt, dtp, &
696 tau_ngw, tgrs, ugrs, vgrs, q1, prsl, prsi, &
697 zmet, zmeti,prslk, xlat_d, sinlat, coslat, &
698 dudt_ngw, dvdt_ngw, dtdt_ngw, kdis_ngw, zngw)
699
700 endif
701
702!
703! => con_g, con_cp, con_rd, con_rv, con_omega, con_pi, con_fvirt
704!
705! if (me == master .and. kdt <= 2) then
706! print *
707! write(6,*)'FV3GFS finished fv3_ugwp_solv2_v1 '
708! write(6,*) ' non-stationary GWs with GMAO/MERRA GW-forcing '
709! print *
710!
711! print *, ' ugwp_v1 ', kdt
712! print *, ' ugwp_v1 du/dt ', maxval(dudt_ngw)*86400, minval(dudt_ngw)*86400
713! print *, ' ugwp_v1 dv/dt ', maxval(dvdt_ngw)*86400, minval(dvdt_ngw)*86400
714! print *, ' ugwp_v1 dT/dt ', maxval(dtdt_ngw)*86400, minval(dtdt_ngw)*86400
715! endif
716
717 end if ! do_ugwp_v1
718
719 if(ldiag3d .and. lssav .and. .not. flag_for_gwd_generic_tend) then
720 idtend = dtidx(index_of_x_wind,index_of_process_nonorographic_gwd)
721 if(idtend>=1) then
722 dtend(:,:,idtend) = dtend(:,:,idtend) + dudt_ngw(i,k)*dtp
723 endif
724 idtend = dtidx(index_of_y_wind,index_of_process_nonorographic_gwd)
725 if(idtend>=1) then
726 dtend(:,:,idtend) = dtend(:,:,idtend) + dvdt_ngw(i,k)*dtp
727 endif
728 idtend = dtidx(index_of_temperature,index_of_process_nonorographic_gwd)
729 if(idtend>=1) then
730 dtend(:,:,idtend) = dtend(:,:,idtend) + dtdt_ngw(i,k)*dtp
731 endif
732 endif
733
734!
735! get total sso-OGW + NGW
736!
737 if (do_ugwp_v1) then
738 dudt_gw = pdudt + dudt_ngw
739 dvdt_gw = pdvdt + dvdt_ngw
740 dtdt_gw = pdtdt + dtdt_ngw
741 kdis_gw = pkdis + kdis_ngw
742 else
743 dudt_gw = pdudt
744 dvdt_gw = pdvdt
745 dtdt_gw = pdtdt
746 kdis_gw = pkdis
747 end if
748!
749! accumulate "tendencies" as in the GFS-ipd (pbl + ugwp + zero-RF)
750!
751 dudt = dudt + dudt_gw
752 dvdt = dvdt + dvdt_gw
753 dtdt = dtdt + dtdt_gw
754
755 end subroutine ugwpv1_gsldrag_run
756end module ugwpv1_gsldrag
This module contains the orographic drag scheme.
Definition drag_suite.F90:6
This module introduces two gravity wave drag schemes: UGWPv1 and orographic drag scheme.