CCPP SciDoc v7.0.0  v7.0.0
Common Community Physics Package Developed at DTC
 
Loading...
Searching...
No Matches
gwdps.f
1
4
7 module gwdps
8
9 contains
10
194 subroutine gwdps_run( &
195 & IM,KM,A,B,C,U1,V1,T1,Q1,KPBL, &
196 & PRSI,DEL,PRSL,PRSLK,PHII, PHIL,DELTIM,KDT, &
197 & HPRIME,OC,OA4,CLX4,THETA,SIGMA,GAMMA,ELVMAX, &
198 & DUSFC,DVSFC,dtaux2d_ms,dtauy2d_ms,dtaux2d_bl, &
199 & dtauy2d_bl,dusfc_ms,dvsfc_ms,dusfc_bl,dvsfc_bl, &
200 & G, CP, RD, RV, IMX, &
201 & nmtvr, cdmbgwd, me, lprnt, ipr, rdxzb, ldiag_ugwp, &
202 & errmsg, errflg)
203
204!
205! ********************************************************************
206! -----> I M P L E M E N T A T I O N V E R S I O N <----------
207!
208! --- Not in this code -- History of GWDP at NCEP----
209! ---------------- -----------------------
210! VERSION 3 MODIFIED FOR GRAVITY WAVES, LOCATION: .FR30(V3GWD) *J*
211!--- 3.1 INCLUDES VARIABLE SATURATION FLUX PROFILE CF ISIGST
212!--- 3.G INCLUDES PS COMBINED W/ PH (GLAS AND GFDL)
213!----- ALSO INCLUDED IS RI SMOOTH OVER A THICK LOWER LAYER
214!----- ALSO INCLUDED IS DECREASE IN DE-ACC AT TOP BY 1/2
215!----- THE NMC GWD INCORPORATING BOTH GLAS(P&S) AND GFDL(MIGWD)
216!----- MOUNTAIN INDUCED GRAVITY WAVE DRAG
217!----- CODE FROM .FR30(V3MONNX) FOR MONIN3
218!----- THIS VERSION (06 MAR 1987)
219!----- THIS VERSION (26 APR 1987) 3.G
220!----- THIS VERSION (01 MAY 1987) 3.9
221!----- CHANGE TO FORTRAN 77 (FEB 1989) --- HANN-MING HENRY JUANG
222!----- 20070601 ELVMAX bug fix (*j*)
223!
224! VERSION 4
225! ----- This code -----
226!
227!----- MODIFIED TO IMPLEMENT THE ENHANCED LOW TROPOSPHERIC GRAVITY
228!----- WAVE DRAG DEVELOPED BY KIM AND ARAKAWA(JAS, 1995).
229! Orographic Std Dev (hprime), Convexity (OC), Asymmetry (OA4)
230! and Lx (CLX4) are input topographic statistics needed.
231!
232!----- PROGRAMMED AND DEBUGGED BY HONG, ALPERT AND KIM --- JAN 1996.
233!----- debugged again - moorthi and iredell --- may 1998.
234!-----
235! Further Cleanup, optimization and modification
236! - S. Moorthi May 98, March 99.
237!----- modified for usgs orography data (ncep office note 424)
238! and with several bugs fixed - moorthi and hong --- july 1999.
239!
240!----- Modified & implemented into NRL NOGAPS
241! - Young-Joon Kim, July 2000
242!-----
243! VERSION lm MB (6): oz fix 8/2003
244! ----- This code -----
245!
246!------ Changed to include the Lott and Miller Mtn Blocking
247! with some modifications by (*j*) 4/02
248! From a Principal Coordinate calculation using the
249! Hi Res 8 minute orography, the Angle of the
250! mtn with that to the East (x) axis is THETA, the slope
251! parameter SIGMA. The anisotropy is in GAMMA - all are input
252! topographic statistics needed. These are calculated off-line
253! as a function of model resolution in the fortran code ml01rg2.f,
254! with script mlb2.sh. (*j*)
255!----- gwdps_mb.f version (following lmi) elvmax < hncrit (*j*)
256! MB3a expt to enhance elvmax mtn hgt see sigfac & hncrit
257! gwdps_GWDFIX_v6.f FIXGWD GF6.0 20070608 sigfac=4.
258!-----
259!----------------------------------------------------------------------C
260! USE
261! ROUTINE IS CALLED FROM GBPHYS (AFTER CALL TO MONNIN)
262!
263! PURPOSE
264! USING THE GWD PARAMETERIZATIONS OF PS-GLAS AND PH-
265! GFDL TECHNIQUE. THE TIME TENDENCIES OF U V
266! ARE ALTERED TO INCLUDE THE EFFECT OF MOUNTAIN INDUCED
267! GRAVITY WAVE DRAG FROM SUB-GRID SCALE OROGRAPHY INCLUDING
268! CONVECTIVE BREAKING, SHEAR BREAKING AND THE PRESENCE OF
269! CRITICAL LEVELS
270!
271! INPUT
272! A(IM,KM) NON-LIN TENDENCY FOR V WIND COMPONENT
273! B(IM,KM) NON-LIN TENDENCY FOR U WIND COMPONENT
274! C(IM,KM) NON-LIN TENDENCY FOR TEMPERATURE
275! U1(IM,KM) ZONAL WIND M/SEC AT T0-DT
276! V1(IM,KM) MERIDIONAL WIND M/SEC AT T0-DT
277! T1(IM,KM) TEMPERATURE DEG K AT T0-DT
278! Q1(IM,KM) SPECIFIC HUMIDITY AT T0-DT
279!
280! DELTIM TIME STEP SECS
281! SI(N) P/PSFC AT BASE OF LAYER N
282! SL(N) P/PSFC AT MIDDLE OF LAYER N
283! DEL(N) POSITIVE INCREMENT OF P/PSFC ACROSS LAYER N
284! KPBL(IM) is the index of the top layer of the PBL
285! ipr & lprnt for diagnostics
286!
287! OUTPUT
288! A, B AS AUGMENTED BY TENDENCY DUE TO GWDPS
289! OTHER INPUT VARIABLES UNMODIFIED.
290! revision log:
291! May 2013 J. Wang change cleff back to opn setting
292! Jan 2014 J. Wang merge Henry and Fangin's dissipation heat in gfs to nems
293!
294!
295! ********************************************************************
296 USE machine , ONLY : kind_phys
297 implicit none
298!
299 ! Interface variables
300 integer, intent(in) :: im, km, imx, kdt, ipr, me
301 integer, intent(in) :: KPBL(:) ! Index for the PBL top layer!
302 real(kind=kind_phys), intent(in) :: &
303 & deltim, g, cp, rd, rv, cdmbgwd(:)
304 real(kind=kind_phys), intent(inout) :: &
305 & a(:,:), b(:,:), c(:,:)
306 real(kind=kind_phys), intent(in) :: &
307 & u1(:,:), v1(:,:), t1(:,:), &
308 & q1(:,:), prsi(:,:), del(:,:), &
309 & prsl(:,:), prslk(:,:), phil(:,:), &
310 & phii(:,:)
311 real(kind=kind_phys), intent(in) :: &
312 & oc(:), oa4(:,:), clx4(:,:), hprime(:)
313 real(kind=kind_phys), intent(inout) :: elvmax(:)
314 real(kind=kind_phys), intent(in) :: &
315 & theta(:), sigma(:), gamma(:)
316 real(kind=kind_phys), intent(inout) :: dusfc(:), dvsfc(:), &
317 & rdxzb(:)
318 real(kind=kind_phys), intent(inout), optional :: dtaux2d_ms(:,:), &
319 & dtauy2d_ms(:,:), dtaux2d_bl(:,:), &
320 & dtauy2d_bl(:,:)
321 real(kind=kind_phys), intent(inout), optional :: dusfc_ms(:), &
322 & dvsfc_ms(:), dusfc_bl(:), dvsfc_bl(:)
323 integer, intent(in) :: nmtvr
324 logical, intent(in) :: lprnt
325 logical, intent(in) :: ldiag_ugwp
326 character(len=*), intent(out) :: errmsg
327 integer, intent(out) :: errflg
328!
329 ! Local variables
330! for lm mtn blocking
331 real(kind=kind_phys) wk(im)
332 real(kind=kind_phys) bnv2lm(im,km),pe(im),ek(im),zbk(im),up(im)
333 real(kind=kind_phys) db(im,km),ang(im,km),uds(im,km)
334 real(kind=kind_phys) zlen, rtrm, phiang, cdmb, dbim, zr, cdmbo4
335 real(kind=kind_phys) eng0, eng1
336!
337! Some constants
338!
339 real(kind=kind_phys) pi, dw2min, rimin, ric, bnv2min, efmin
340 &, efmax,hpmax,hpmin, rad_to_deg, deg_to_rad
341 parameter(pi=3.1415926535897931)
342 parameter(rad_to_deg=180.0/pi, deg_to_rad=pi/180.0)
343 parameter(dw2min=1., rimin=-100., ric=0.25, bnv2min=1.0e-5)
344! PARAMETER (EFMIN=0.0, EFMAX=10.0, hpmax=200.0)
345 parameter(efmin=0.0, efmax=10.0, hpmax=2400.0, hpmin=1.0)
346!
347 real(kind=kind_phys) frc, ce, ceofrc, frmax, cg, gmax
348 &, veleps, factop, rlolev, rdi
349! &, CRITAC, VELEPS, FACTOP, RLOLEV, RDI
350 parameter(frc=1.0, ce=0.8, ceofrc=ce/frc, frmax=100., cg=0.5)
351 parameter(gmax=1.0, veleps=1.0, factop=0.5)
352! parameter (GMAX=1.0, CRITAC=5.0E-4, VELEPS=1.0, FACTOP=0.5)
353 parameter(rlolev=50000.0)
354! parameter (RLOLEV=500.0)
355! parameter (RLOLEV=0.5)
356!
357 real(kind=kind_phys) dpmin,hminmt,hncrit,minwnd,sigfac
358! --- for lm mtn blocking
359! parameter (cdmb = 1.0) !< non-dim sub grid mtn drag Amp (*j*)
360 parameter(hncrit=8000.)
361! hncrit set to 8000m and sigfac added to enhance elvmax mtn hgt
362 parameter(sigfac=4.0)
363 parameter(hminmt=50.)
364 parameter(minwnd=0.1)
365
366! parameter (dpmin=00.0) !< Minimum thickness of the reference layer
367!! parameter (dpmin=05.0) !< Minimum thickness of the reference layer
368! parameter (dpmin=20.0) !< Minimum thickness of the reference layer
369
370 parameter(dpmin=5000.0)
372!
373 real(kind=kind_phys) fdir
374 integer mdir
375 parameter(mdir=8, fdir=mdir/(pi+pi))
376 integer nwdir(mdir)
377 data nwdir/6,7,5,8,2,3,1,4/
378 save nwdir
379!
380 LOGICAL ICRILV(IM)
381!
382!---- MOUNTAIN INDUCED GRAVITY WAVE DRAG
383!
384 real(kind=kind_phys) taub(im), xn(im), yn(im), ubar(im) &
385 &, vbar(im), ulow(im), oa(im), clx(im) &
386 &, roll(im), uloi(im) &
387 &, dtfac(im), xlinv(im), delks(im)
388! &, DTFAC(IM), XLINV(IM), DELKS(IM), DELKS1(IM)
389!
390 real(kind=kind_phys) bnv2(im,km), taup(im,km+1), ri_n(im,km) &
391 &, taud(im,km), ro(im,km), vtk(im,km) &
392 &, vtj(im,km), scor(im), velco(im,km-1) &
393 &, bnv2bar(im), cdsigohp(im)
394!
395! real(kind=kind_phys) VELKO(KM-1)
396 integer kref(IM), kint(im), iwk(im), ipt(im)
397! for lm mtn blocking
398 integer iwklm(im)
399! integer kreflm(IM), iwklm(im)
400 integer idxzb(im), ktrial, klevm1
401!
402 real(kind=kind_phys) gor, gocp, fv, gr2, bnv, fr &
403 &, brvf, cleff, tem, tem1, tem2, temc, temv&
404 &, wdir, ti, rdz, dw2, shr2, bvf2 &
405 &, rdelks, efact, coefm, gfobnv, onebg &
406 &, scork, rscor, hd, fro, rim, sira &
407 &, dtaux, dtauy, pkp1log, pklog &
408 &, cosang, sinang, cos2a, sin2a, oneocpdt
409!
410 integer kmm1, kmm2, lcap, lcapp1, kbps, kbpsp1,kbpsm1 &
411 &, kmps, idir, nwd, i, j, k, klcap, kp1, kmpbl, npt, npr, kmll
412! &, kmll,kmds,ihit,jhit
413!
414 ! Initialize CCPP error handling variables
415 errmsg = ''
416 errflg = 0
417!
418! parameter (cdmb = 1.0) ! non-dim sub grid mtn drag Amp (*j*)
419! non-dim sub grid mtn drag Amp (*j*)
420! cdmb = 1.0/float(IMX/192)
421! cdmb = 192.0/float(IMX)
422 cdmb = 4.0 * 192.0/float(imx)
423 if (cdmbgwd(1) >= 0.0) cdmb = cdmb * cdmbgwd(1)
424 cdmbo4 = 0.25 * cdmb
425!
426 npr = 0
427!
428 DO k = 1, km
429 DO i = 1, im
430 db(i,k) = 0.
431 ang(i,k) = 0.
432 uds(i,k) = 0.
433 ENDDO
434 ENDDO
435!
436 rdi = 1.0 / rd
437 onebg = 1.0 / g
438 gor = g/rd
439 gr2 = g*gor
440 gocp = g/cp
441 fv = rv/rd - 1
442 oneocpdt = 1.0 / (cp*deltim)
443!
444! NCNT = 0
445 kmm1 = km - 1
446 kmm2 = km - 2
447 lcap = km
448 lcapp1 = lcap + 1
449!
450 rdxzb(:) = 0
451!
452 IF ( nmtvr == 14) then
453! ---- for lm and gwd calculation points
454 ipt = 0
455 npt = 0
456 DO i = 1,im
457 IF (elvmax(i) > hminmt .and. hprime(i) > hpmin) then
458 npt = npt + 1
459 ipt(npt) = i
460! if (lprnt .and. ipr == i) npr = npt
461 ENDIF
462 ENDDO
463 IF (npt == 0) RETURN ! No gwd/mb calculation done!
464!
465! if (lprnt) print *,' npt=',npt,' npr=',npr,' ipr=',ipr,' im=',im
466! &,' ipt(npt)=',ipt(npt)
467!
468! --- iwklm is the level above the height of the of the mountain.
469! --- idxzb is the level of the dividing streamline.
470! INITIALIZE DIVIDING STREAMLINE (DS) CONTROL VECTOR
471!
472 do i=1,npt
473 iwklm(i) = 2
474 idxzb(i) = 0
475! kreflm(i) = 0
476 enddo
477! if (lprnt)
478! & print *,' in gwdps_lm.f npt,IM,IY,km,me=',npt,IM,IY,km,me
479!
480!
482!
483!..............................
484!..............................
485!
486! (*j*) 11/03: test upper limit on KMLL=km - 1
487! then do not need hncrit -- test with large hncrit first.
488! KMLL = km / 2 ! maximum mtnlm height : # of vertical levels / 2
489
490 kmll = kmm1
491
492! --- No mtn should be as high as KMLL (so we do not have to start at
493! --- the top of the model but could do calc for all levels).
494!
495 DO i = 1, npt
496 j = ipt(i)
497 elvmax(j) = min(elvmax(j) + sigfac * hprime(j), hncrit)
498 cdsigohp(i) = cdmbo4 * sigma(j) / hprime(j)
499 ENDDO
500!
501 DO k = 1,kmll
502 DO i = 1, npt
503 j = ipt(i)
504! --- interpolate to max mtn height for index, iwklm(I) wk[gz]
505! --- ELVMAX is limited to hncrit because to hi res topo30 orog.
506 pkp1log = phil(j,k+1) * onebg
507 pklog = phil(j,k) * onebg
508!!!------- ELVMAX(J) = min (ELVMAX(J) + sigfac * hprime(j), hncrit)
509
510 if (elvmax(j) <= pkp1log .and. elvmax(j) >= pklog) THEN
511
512! print *,' in gwdps_lm.f 1 =',k,ELVMAX(j),pklog,pkp1log,me
513! --- wk for diags but can be saved and reused.
514 wk(i) = g * elvmax(j) / (phil(j,k+1) - phil(j,k))
515 iwklm(i) = max(iwklm(i), k+1)
516! print *,' in gwdps_lm.f 2 npt=',npt,i,j,wk(i),iwklm(i),me
517 endif
518!
519! --- find at prsl levels large scale environment variables
520! --- these cover all possible mtn max heights
521 vtj(i,k) = t1(j,k) * (1.0+fv*q1(j,k))
522 vtk(i,k) = vtj(i,k) / prslk(j,k)
523 ro(i,k) = rdi * prsl(j,k) / vtj(i,k) ! DENSITY Kg/M**3
524 ENDDO
525 ENDDO
526!
527! testing for highest model level of mountain top
528!
529! ihit = 2
530! jhit = 0
531! do i = 1, npt
532! j=ipt(i)
533! if ( iwklm(i) .gt. ihit ) then
534! ihit = iwklm(i)
535! jhit = j
536! endif
537! enddo
538! print *, ' mb: kdt,max(iwklm),jhit,phil,me=',
539! & kdt,ihit,jhit,phil(jhit,ihit),me
540
541 klevm1 = kmll - 1
542 DO k = 1, klevm1
543 kp1 = k + 1
544 DO i = 1, npt
545 j = ipt(i)
546 rdz = g / (phil(j,kp1) - phil(j,k))
547! --- Brunt-Vaisala Frequency
549 bnv2lm(i,k) = (g+g) * rdz * (vtk(i,kp1) - vtk(i,k))
550 & / (vtk(i,kp1) + vtk(i,k))
551 bnv2lm(i,k) = max( bnv2lm(i,k), bnv2min )
552 ENDDO
553 ENDDO
554! print *,' in gwdps_lm.f 3 npt=',npt,j,RDZ,me
555!
556 DO i = 1, npt
557 j = ipt(i)
558 delks(i) = 1.0 / (prsi(j,1) - prsi(j,iwklm(i)))
559! DELKS1(I) = 1.0 / (PRSI(J,1) - PRSL(J,iwklm(i)))
560 ubar(i) = 0.0
561 vbar(i) = 0.0
562 roll(i) = 0.0
563 pe(i) = 0.0
564 ek(i) = 0.0
565 bnv2bar(i) = (prsi(j,1)-prsl(j,1)) * delks(i) * bnv2lm(i,1)
566 ENDDO
567
568! --- find the dividing stream line height
569! --- starting from the level above the max mtn downward
570! --- iwklm(i) is the k-index of mtn elvmax elevation
573! DO Ktrial = KMLL, 1, -1
574! DO I = 1, npt
575! IF ( Ktrial < iwklm(I) .and. kreflm(I) == 0 ) then
576! kreflm(I) = Ktrial
577! ENDIF
578! ENDDO
579! ENDDO
580! print *,' in gwdps_lm.f 4 npt=',npt,kreflm(npt),me
581!
582! --- in the layer kreflm(I) to 1 find PE (which needs N, ELVMAX)
583! --- make averages, guess dividing stream (DS) line layer.
584! --- This is not used in the first cut except for testing and
585! --- is the vert ave of quantities from the surface to mtn top.
586!
587 DO i = 1, npt
588 DO k = 1, iwklm(i)-1
589 j = ipt(i)
590 rdelks = del(j,k) * delks(i)
591 ubar(i) = ubar(i) + rdelks * u1(j,k) ! trial Mean U below
592 vbar(i) = vbar(i) + rdelks * v1(j,k) ! trial Mean V below
593 roll(i) = roll(i) + rdelks * ro(i,k) ! trial Mean RO below
594 if (k < iwklm(i)-1) then
595 rdelks = (prsl(j,k)-prsl(j,k+1)) * delks(i)
596 else
597 rdelks = (prsl(j,k)-prsi(j,k+1)) * delks(i)
598 endif
599 bnv2bar(i) = bnv2bar(i) + bnv2lm(i,k) * rdelks
600! --- these vert ave are for diags, testing and GWD to follow (*j*).
601 ENDDO
602 ENDDO
603! print *,' in gwdps_lm.f 5 =',i,kreflm(npt),BNV2bar(npt),me
604!
605! --- integrate to get PE in the trial layer.
606! --- Need the first layer where PE>EK - as soon as
607! --- IDXZB is not 0 we have a hit and Zb is found.
608!
609 DO i = 1, npt
610 j = ipt(i)
611 DO k = iwklm(i), 1, -1
612 phiang = atan2(v1(j,k),u1(j,k))*rad_to_deg
613 ang(i,k) = ( theta(j) - phiang )
614 if ( ang(i,k) > 90. ) ang(i,k) = ang(i,k) - 180.
615 if ( ang(i,k) < -90. ) ang(i,k) = ang(i,k) + 180.
616 ang(i,k) = ang(i,k) * deg_to_rad
617!
624
625 uds(i,k) =
626 & max(sqrt(u1(j,k)*u1(j,k) + v1(j,k)*v1(j,k)), minwnd)
627! --- Test to see if we found Zb previously
628 IF (idxzb(i) == 0 ) then
629 pe(i) = pe(i) + bnv2lm(i,k) * (g*elvmax(j) - phil(j,k))
630 & * (phii(j,k+1) - phii(j,k))
631 & * (onebg*onebg)
632! --- KE
633! --- Wind projected on the line perpendicular to mtn range, U(Zb(K)).
634! --- kenetic energy is at the layer Zb
635! --- THETA ranges from -+90deg |_ to the mtn "largest topo variations"
636 up(i) = uds(i,k) * cos(ang(i,k))
637 ek(i) = 0.5 * up(i) * up(i)
638
639! --- Dividing Stream lime is found when PE =exceeds EK.
640 IF (pe(i) >= ek(i)) THEN
641 idxzb(i) = k
642 rdxzb(j) = real(k,kind=kind_phys)
643 ENDIF
644! --- Then mtn blocked flow is between Zb=k(IDXZB(I)) and surface
645!
659 ENDIF
660 ENDDO
661 ENDDO
662!
663! print *,' in gwdps_lm.f 6 =',phiang,THETA(ipt(npt)),me
664! print *,' in gwdps_lm.f 7 =',IDXZB(npt),PE(npt)
665!
666! if (lprnt .and. npr .gt. 0) then
667! print *,' BNV2bar,BNV2lm=',bnv2bar(npr),BNV2lm(npr,1:klevm1)
668! print *,' npr,IDXZB,UDS=',npr,IDXZB(npr),UDS(npr,:)
669! print *,' PE,UP,EK=',PE(npr),UP(npr),EK(npr)
670! endif
671!
672 DO i = 1, npt
673 j = ipt(i)
674! --- Calc if N constant in layers (Zb guess) - a diagnostic only.
675 zbk(i) = elvmax(j)
676 & - sqrt(ubar(i)*ubar(i) + vbar(i)*vbar(i))/bnv2bar(i)
677 ENDDO
678!
679! if (lprnt .and. npr .gt. 0) then
680! print *,' iwklm,ZBK=',iwklm(npr),ZBK(npr),IDXZB(npr)
681! print *,' Zb=',PHIL(ipr),IDXZB(npr))/G
682! print *,' in gwdps_lm.f 8 npt =',npt,ZBK(npt),UP(npt),me
683! endif
684!
685! --- The drag for mtn blocked flow
686!
687 DO i = 1, npt
688 j = ipt(i)
689 zlen = 0.
690! print *,' in gwdps_lm.f 9 =',i,j,IDXZB(i),me
691 IF (idxzb(i) > 0) then
692 DO k = idxzb(i), 1, -1
693 IF (phil(j,idxzb(i)) > phil(j,k)) then
694
702 zlen = sqrt( (phil(j,idxzb(i)) - phil(j,k))
703 & / (phil(j,k ) + g*hprime(j)) )
704! --- lm eq 14:
714
715 cosang = cos(ang(i,k))
716 sinang = sin(ang(i,k))
717 cos2a = cosang * cosang
718 sin2a = sinang * sinang
719 tem = cos2a + gamma(j)*sin2a
720 ! Here Rtrm is 1.0/R
721 ! --------------------
722 if (abs(tem) > 1.e-06) then
723 rtrm = (gamma(j)*cos2a + sin2a) / tem
724 elseif (tem > 0.0) then
725 rtrm = (gamma(j)*cos2a + sin2a) * 1.0e6
726 else
727 rtrm = - (gamma(j)*cos2a + sin2a) * 1.0e6
728 endif
729 zr = max( 2.0 - rtrm, 0. )
730
731! --- (negitive of DB -- see sign at tendency)
741
742 db(i,k) = cdsigohp(i) * zr * ro(i,k) * zlen
743 & * max(cosang, gamma(j)*sinang) * uds(i,k)
744!
745! if(lprnt .and. i .eq. npr) then
746! print *,' in gwdps_lmi.f 10 npt=',npt,i,j,idxzb(i)
747! &, DBTMP,R' ang=',ang(i,k),' gamma=',gamma(j),' K=',K
748! print *,' in gwdps_lmi.f 11 K=',k,ZLEN,cos(ANG(I,K))
749! print *,' in gwdps_lmi.f 12 DB=',DB(i,k),sin(ANG(I,K))
750! endif
751 endif
752 ENDDO
753! if(lprnt) print *,' @K=1,ZLEN,DBTMP=',K,ZLEN,DBTMP
754 endif
755 ENDDO
756!
757!.............................
758!.............................
759! end mtn blocking section
760!
761 ELSEIF ( nmtvr /= 14) then
762! ---- for mb not present and gwd (nmtvr .ne .14)
763 ipt = 0
764 npt = 0
765 DO i = 1,im
766 IF ( hprime(i) > hpmin ) then
767 npt = npt + 1
768 ipt(npt) = i
769 if (ipr == i) npr = npt
770 ENDIF
771 ENDDO
772 IF (npt == 0) RETURN ! No gwd/mb calculation done!
773!
774! if (lprnt) print *,' NPR=',npr,' npt=',npt,' IPR=',IPR
775! &,' ipt(npt)=',ipt(npt)
776!
777 do i=1,npt
778 idxzb(i) = 0
779 enddo
780 ENDIF
781!
782!.............................
783!.............................
784!
786 kmpbl = km / 2 ! maximum pbl height : # of vertical levels / 2
787!
788! Scale cleff between IM=384*2 and 192*2 for T126/T170 and T62
789!
790 if (imx > 0) then
791! cleff = 1.0E-5 * SQRT(FLOAT(IMX)/384.0) ! this is inverse of CLEFF!
792! cleff = 1.0E-5 * SQRT(FLOAT(IMX)/192.0) ! this is inverse of CLEFF!
793! cleff = 0.5E-5 * SQRT(FLOAT(IMX)/192.0) ! this is inverse of CLEFF!
794! cleff = 1.0E-5 * SQRT(FLOAT(IMX)/192)/float(IMX/192)
795! cleff = 1.0E-5 / SQRT(FLOAT(IMX)/192.0) ! this is inverse of CLEFF!
796 cleff = 0.5e-5 / sqrt(float(imx)/192.0) ! this is inverse of CLEFF!
797! hmhj for ndsl
798! jw cleff = 0.1E-5 / SQRT(FLOAT(IMX)/192.0) ! this is inverse of CLEFF!
799! cleff = 2.0E-5 * SQRT(FLOAT(IMX)/192.0) ! this is inverse of CLEFF!
800! cleff = 2.5E-5 * SQRT(FLOAT(IMX)/192.0) ! this is inverse of CLEFF!
801 endif
802 if (cdmbgwd(2) >= 0.0) cleff = cleff * cdmbgwd(2)
803!
804 DO k = 1,km
805 DO i =1,npt
806 j = ipt(i)
807 vtj(i,k) = t1(j,k) * (1.0+fv*q1(j,k))
808 vtk(i,k) = vtj(i,k) / prslk(j,k)
809 ro(i,k) = rdi * prsl(j,k) / vtj(i,k) ! DENSITY TONS/M**3
810 taup(i,k) = 0.0
811 ENDDO
812 ENDDO
813 DO k = 1,kmm1
814 kp1 = k + 1
815 DO i =1,npt
816 j = ipt(i)
817 ti = 2.0 / (t1(j,k)+t1(j,kp1))
818 tem = ti / (prsl(j,k)-prsl(j,kp1))
819 rdz = g / (phil(j,kp1) - phil(j,k))
820 tem1 = u1(j,k) - u1(j,kp1)
821 tem2 = v1(j,k) - v1(j,kp1)
822 dw2 = tem1*tem1 + tem2*tem2
823 shr2 = max(dw2,dw2min) * rdz * rdz
824 bvf2 = g*(gocp+rdz*(vtj(i,kp1)-vtj(i,k))) * ti
825 ri_n(i,k) = max(bvf2/shr2,rimin) ! Richardson number
826! Brunt-Vaisala Frequency
827! TEM = GR2 * (PRSL(J,K)+PRSL(J,K+1)) * TEM
828! BNV2(I,K) = TEM * (VTK(I,K+1)-VTK(I,K))/(VTK(I,K+1)+VTK(I,K))
829 bnv2(i,k) = (g+g) * rdz * (vtk(i,kp1)-vtk(i,k))
830 & / (vtk(i,kp1)+vtk(i,k))
831 bnv2(i,k) = max( bnv2(i,k), bnv2min )
832 ENDDO
833 ENDDO
834! print *,' in gwdps_lm.f GWD:14 =',npt,kmm1,bnv2(npt,kmm1)
835!
836! Apply 3 point smoothing on BNV2
837!
838! do k=1,km
839! do i=1,im
840! vtk(i,k) = bnv2(i,k)
841! enddo
842! enddo
843! do k=2,kmm1
844! do i=1,im
845! bnv2(i,k) = 0.25*(vtk(i,k-1)+vtk(i,k+1)) + 0.5*vtk(i,k)
846! enddo
847! enddo
848!
849! Finding the first interface index above 50 hPa level
850!
851 do i=1,npt
852 iwk(i) = 2
853 enddo
854 DO k=3,kmpbl
855 DO i=1,npt
856 j = ipt(i)
857 tem = (prsi(j,1) - prsi(j,k))
858 if (tem < dpmin) iwk(i) = k
859 enddo
860 enddo
861!
864 kbps = 1
865 kmps = km
866 DO i=1,npt
867 j = ipt(i)
868 kref(i) = max(iwk(i), kpbl(j)+1 ) ! reference level
869 delks(i) = 1.0 / (prsi(j,1) - prsi(j,kref(i)))
870! DELKS1(I) = 1.0 / (PRSI(J,1) - PRSL(J,kref(I)))
871 ubar(i) = 0.0
872 vbar(i) = 0.0
873 roll(i) = 0.0
874 kbps = max(kbps, kref(i))
875 kmps = min(kmps, kref(i))
876!
877 bnv2bar(i) = (prsi(j,1)-prsl(j,1)) * delks(i) * bnv2(i,1)
878 ENDDO
879! print *,' in gwdps_lm.f GWD:15 =',KBPS,KMPS
880 kbpsp1 = kbps + 1
881 kbpsm1 = kbps - 1
882 DO k = 1,kbps
883 DO i = 1,npt
884 IF (k < kref(i)) THEN
885 j = ipt(i)
886 rdelks = del(j,k) * delks(i)
887 ubar(i) = ubar(i) + rdelks * u1(j,k) ! Mean U below kref
888 vbar(i) = vbar(i) + rdelks * v1(j,k) ! Mean V below kref
889!
890 roll(i) = roll(i) + rdelks * ro(i,k) ! Mean RO below kref
891 if (k < kref(i)-1) then
892 rdelks = (prsl(j,k)-prsl(j,k+1)) * delks(i)
893 else
894 rdelks = (prsl(j,k)-prsi(j,k+1)) * delks(i)
895 endif
896 bnv2bar(i) = bnv2bar(i) + bnv2(i,k) * rdelks
897 ENDIF
898 ENDDO
899 ENDDO
900! print *,' in gwdps_lm.f GWD:15B =',bnv2bar(npt)
901!
902! FIGURE OUT LOW-LEVEL HORIZONTAL WIND DIRECTION AND FIND 'OA'
903!
904! NWD 1 2 3 4 5 6 7 8
905! WD W S SW NW E N NE SE
906!
909 DO i = 1,npt
910 j = ipt(i)
911 wdir = atan2(ubar(i),vbar(i)) + pi
912 idir = mod(nint(fdir*wdir),mdir) + 1
913 nwd = nwdir(idir)
914 oa(i) = (1-2*int( (nwd-1)/4 )) * oa4(j,mod(nwd-1,4)+1)
915 clx(i) = clx4(j,mod(nwd-1,4)+1)
916 ENDDO
917!
918!-----XN,YN "LOW-LEVEL" WIND PROJECTIONS IN ZONAL
919! & MERIDIONAL DIRECTIONS
920!-----ULOW "LOW-LEVEL" WIND MAGNITUDE - (= U)
921!-----BNV2 BNV2 = N**2
922!-----TAUB BASE MOMENTUM FLUX
923!-----= -(RO * U**3/(N*XL)*GF(FR) FOR N**2 > 0
924!-----= 0. FOR N**2 < 0
925!-----FR FROUDE = N*HPRIME / U
926!-----G GMAX*FR**2/(FR**2+CG/OC)
927!
928!-----INITIALIZE SOME ARRAYS
929!
930 DO i = 1,npt
931 xn(i) = 0.0
932 yn(i) = 0.0
933 taub(i) = 0.0
934 ulow(i) = 0.0
935 dtfac(i) = 1.0
936 icrilv(i) = .false. ! INITIALIZE CRITICAL LEVEL CONTROL VECTOR
937
938!
939!----COMPUTE THE "LOW LEVEL" WIND MAGNITUDE (M/S)
940!
941 ulow(i) = max(sqrt(ubar(i)*ubar(i) + vbar(i)*vbar(i)), 1.0)
942 uloi(i) = 1.0 / ulow(i)
943 ENDDO
944!
945 DO k = 1,kmm1
946 kp1 = k + 1
947 DO i = 1,npt
948 j = ipt(i)
949 velco(i,k) = 0.5 * ((u1(j,k)+u1(j,kp1))*ubar(i)
950 & + (v1(j,k)+v1(j,kp1))*vbar(i))
951 velco(i,k) = velco(i,k) * uloi(i)
952! IF ((VELCO(I,K).LT.VELEPS) .AND. (VELCO(I,K).GT.0.)) THEN
953! VELCO(I,K) = VELEPS
954! ENDIF
955 ENDDO
956 ENDDO
957!
958!
959! find the interface level of the projected wind where
960! low levels & upper levels meet above pbl
961!
962! do i=1,npt
963! kint(i) = km
964! enddo
965! do k = 1,kmm1
966! do i = 1,npt
967! IF (K .GT. kref(I)) THEN
968! if(velco(i,k) .lt. veleps .and. kint(i) .eq. km) then
969! kint(i) = k+1
970! endif
971! endif
972! enddo
973! enddo
974! WARNING KINT = KREF !!!!!!!!!
975 do i=1,npt
976 kint(i) = kref(i)
977 enddo
978!
979! if(lprnt) print *,' ubar=',ubar
980! &,' vbar=',vbar,' ulow=',ulow,' veleps=',veleps
981!
982 DO i = 1,npt
983 j = ipt(i)
984 bnv = sqrt( bnv2bar(i) )
985 fr = bnv * uloi(i) * min(hprime(j),hpmax)
986 fr = min(fr, frmax)
987 xn(i) = ubar(i) * uloi(i)
988 yn(i) = vbar(i) * uloi(i)
989!
990! Compute the base level stress and store it in TAUB
991! CALCULATE ENHANCEMENT FACTOR, NUMBER OF MOUNTAINS & ASPECT
992! RATIO CONST. USE SIMPLIFIED RELATIONSHIP BETWEEN STANDARD
993! DEVIATION & CRITICAL HGT
994!
1023
1032
1033 efact = (oa(i) + 2.) ** (ceofrc*fr)
1034 efact = min( max(efact,efmin), efmax )
1035!
1036 coefm = (1. + clx(i)) ** (oa(i)+1.)
1037!
1038 xlinv(i) = coefm * cleff
1039!
1040 tem = fr * fr * oc(j)
1041 gfobnv = gmax * tem / ((tem + cg)*bnv) ! G/N0
1042!
1043 taub(i) = xlinv(i) * roll(i) * ulow(i) * ulow(i)
1044 & * ulow(i) * gfobnv * efact ! BASE FLUX Tau0
1045!
1046! tem = min(HPRIME(I),hpmax)
1047! TAUB(I) = XLINV(I) * ROLL(I) * ULOW(I) * BNV * tem * tem
1048!
1049 k = max(1, kref(i)-1)
1050 tem = max(velco(i,k)*velco(i,k), 0.1)
1051 scor(i) = bnv2(i,k) / tem ! Scorer parameter below ref level
1052 ENDDO
1053! if(lprnt) print *,' taub=',taub
1054!
1055!----SET UP BOTTOM VALUES OF STRESS
1056!
1057 DO k = 1, kbps
1058 DO i = 1,npt
1059 IF (k <= kref(i)) taup(i,k) = taub(i)
1060 ENDDO
1061 ENDDO
1062!
1063! Now compute vertical structure of the stress.
1064!
1065 DO k = kmps, kmm1 ! Vertical Level K Loop!
1066 kp1 = k + 1
1067 DO i = 1, npt
1068!
1069!-----UNSTABLE LAYER IF RI < RIC
1070!-----UNSTABLE LAYER IF UPPER AIR VEL COMP ALONG SURF VEL <=0 (CRIT LAY)
1071!---- AT (U-C)=0. CRIT LAYER EXISTS AND BIT VECTOR SHOULD BE SET (.LE.)
1072!
1073 IF (k >= kref(i)) THEN
1074 icrilv(i) = icrilv(i) .OR. ( ri_n(i,k) < ric)
1075 & .OR. (velco(i,k) <= 0.0)
1076 ENDIF
1077 ENDDO
1078!
1091 DO i = 1,npt
1092 IF (k >= kref(i)) THEN
1093 IF (.NOT.icrilv(i) .AND. taup(i,k) > 0.0 ) THEN
1094 temv = 1.0 / max(velco(i,k), 0.01)
1095! IF (OA(I) .GT. 0. .AND. PRSI(ipt(i),KP1).GT.RLOLEV) THEN
1096 IF (oa(i) > 0. .AND. kp1 < kint(i)) THEN
1097 scork = bnv2(i,k) * temv * temv
1098 rscor = min(1.0, scork / scor(i))
1099 scor(i) = scork
1100 ELSE
1101 rscor = 1.
1102 ENDIF
1103!
1115
1116 brvf = sqrt(bnv2(i,k)) ! Brunt-Vaisala Frequency
1117! TEM1 = XLINV(I)*(RO(I,KP1)+RO(I,K))*BRVF*VELCO(I,K)*0.5
1118 tem1 = xlinv(i)*(ro(i,kp1)+ro(i,k))*brvf*0.5
1119 & * max(velco(i,k),0.01)
1120 hd = sqrt(taup(i,k) / tem1)
1121 fro = brvf * hd * temv
1122!
1123! RIM is the MINIMUM-RICHARDSON NUMBER BY SHUTTS (1985)
1124!
1133
1134 tem2 = sqrt(ri_n(i,k))
1135 tem = 1. + tem2 * fro
1136 rim = ri_n(i,k) * (1.-fro) / (tem * tem)
1137!
1138! CHECK STABILITY TO EMPLOY THE 'SATURATION HYPOTHESIS'
1139! OF LINDZEN (1981) EXCEPT AT TROPOSPHERIC DOWNSTREAM REGIONS
1140!
1156! ----------------------
1157 IF (rim <= ric .AND.
1158! & (OA(I) .LE. 0. .OR. PRSI(ipt(I),KP1).LE.RLOLEV )) THEN
1159 & (oa(i) <= 0. .OR. kp1 >= kint(i) )) THEN
1160 temc = 2.0 + 1.0 / tem2
1161 hd = velco(i,k) * (2.*sqrt(temc)-temc) / brvf
1162 taup(i,kp1) = tem1 * hd * hd
1163 ELSE
1164 taup(i,kp1) = taup(i,k) * rscor
1165 ENDIF
1166 taup(i,kp1) = min(taup(i,kp1), taup(i,k))
1167 ENDIF
1168 ENDIF
1169 ENDDO
1170 ENDDO
1171!
1172! DO I=1,IM
1173! taup(i,km+1) = taup(i,km)
1174! ENDDO
1175!
1176 IF(lcap <= km) THEN
1177 DO klcap = lcapp1, km+1
1178 DO i = 1,npt
1179 sira = prsi(ipt(i),klcap) / prsi(ipt(i),lcap)
1180 taup(i,klcap) = sira * taup(i,lcap)
1181 ENDDO
1182 ENDDO
1183 ENDIF
1184!
1185! Calculate - (g/p*)*d(tau)/d(sigma) and Decel terms DTAUX, DTAUY
1186!
1187 DO k = 1,km
1188 DO i = 1,npt
1189 taud(i,k) = g * (taup(i,k+1) - taup(i,k)) / del(ipt(i),k)
1190 ENDDO
1191 ENDDO
1192!
1193!------LIMIT DE-ACCELERATION (MOMENTUM DEPOSITION ) AT TOP TO 1/2 VALUE
1194!------THE IDEA IS SOME STUFF MUST GO OUT THE 'TOP'
1195!
1196 DO klcap = lcap, km
1197 DO i = 1,npt
1198 taud(i,klcap) = taud(i,klcap) * factop
1199 ENDDO
1200 ENDDO
1201!
1202!------IF THE GRAVITY WAVE DRAG WOULD FORCE A CRITICAL LINE IN THE
1203!------LAYERS BELOW SIGMA=RLOLEV DURING THE NEXT DELTIM TIMESTEP,
1204!------THEN ONLY APPLY DRAG UNTIL THAT CRITICAL LINE IS REACHED.
1205!
1206 DO k = 1,kmm1
1207 DO i = 1,npt
1208 IF (k > kref(i) .and. prsi(ipt(i),k) >= rlolev) THEN
1209 IF(taud(i,k) /= 0.) THEN
1210 tem = deltim * taud(i,k)
1211 dtfac(i) = min(dtfac(i),abs(velco(i,k)/tem))
1212 ENDIF
1213 ENDIF
1214 ENDDO
1215 ENDDO
1216!
1217! if(lprnt .and. npr > 0) then
1218! print *,' before A=',A(npr,:)
1219! print *,' before B=',B(npr,:)
1220! endif
1221
1226
1227 DO k = 1,km
1228 DO i = 1,npt
1229 j = ipt(i)
1230 taud(i,k) = taud(i,k) * dtfac(i)
1231 dtaux = taud(i,k) * xn(i)
1232 dtauy = taud(i,k) * yn(i)
1233 eng0 = 0.5*(u1(j,k)*u1(j,k)+v1(j,k)*v1(j,k))
1234
1235 if (k < idxzb(i)) then ! --- lm mb (*j*) changes overwrite GWD
1236 ! ---------------------------------------
1237 dbim = db(i,k) / (1.+db(i,k)*deltim)
1238 a(j,k) = - dbim * v1(j,k) + a(j,k)
1239 b(j,k) = - dbim * u1(j,k) + b(j,k)
1240 eng1 = eng0*(1.0-dbim*deltim)*(1.0-dbim*deltim)
1241
1242! if ( ABS(DBIM * U1(J,K)) > .01 )
1243! & print *,' in gwdps_lmi.f KDT=',KDT,I,K,DB(I,K),
1244! & dbim,idxzb(I),U1(J,K),V1(J,K),me
1245
1246 tem1 = dbim * del(j,k)
1247 dusfc(j) = dusfc(j) + onebg * tem1 * u1(j,k)
1248 dvsfc(j) = dvsfc(j) + onebg * tem1 * v1(j,k)
1249 ! Output blocking tendencies if ldiag_ugwp=.true.
1250 if (ldiag_ugwp) then
1251 dtaux2d_bl(j,k) = - dbim * u1(j,k)
1252 dtauy2d_bl(j,k) = - dbim * v1(j,k)
1253 dusfc_bl(j) = dusfc_bl(j) + dtaux2d_bl(j,k) * del(j,k)
1254 dvsfc_bl(j) = dvsfc_bl(j) + dtauy2d_bl(j,k) * del(j,k)
1255 end if
1256 else ! orographic GWD applied
1257 ! ----------------------
1258 a(j,k) = dtauy + a(j,k)
1259 b(j,k) = dtaux + b(j,k)
1260 tem1 = u1(j,k) + dtaux*deltim
1261 tem2 = v1(j,k) + dtauy*deltim
1262 eng1 = 0.5 * (tem1*tem1+tem2*tem2)
1263 dusfc(j) = dusfc(j) - onebg * dtaux * del(j,k)
1264 dvsfc(j) = dvsfc(j) - onebg * dtauy * del(j,k)
1265 ! Output mesoscale GWD tendencies if ldiag_ugwp=.ture.
1266 if (ldiag_ugwp) then
1267 dtaux2d_ms(j,k) = dtaux
1268 dtauy2d_ms(j,k) = dtauy
1269 dusfc_ms(j) = dusfc_ms(j) + dtaux * del(j,k)
1270 dvsfc_ms(j) = dvsfc_ms(j) + dtauy * del(j,k)
1271 end if
1272 endif
1273 c(j,k) = c(j,k) + max(eng0-eng1,0.) * oneocpdt
1274 ENDDO
1275 ENDDO
1276
1277! if (lprnt) then
1278! print *,' in gwdps_lm.f after A=',A(ipr,:)
1279! print *,' in gwdps_lm.f after B=',B(ipr,:)
1280! print *,' DB=',DB(ipr,:)
1281! endif
1282
1283 if (ldiag_ugwp) then
1284 ! Finalize dusfc and dvsfc diagnostics
1285 DO i = 1,npt
1286 j = ipt(i)
1287 dusfc_ms(j) = - onebg * dusfc_ms(j)
1288 dvsfc_ms(j) = - onebg * dvsfc_ms(j)
1289 dusfc_bl(j) = - onebg * dusfc_bl(j)
1290 dvsfc_bl(j) = - onebg * dvsfc_bl(j)
1291 ENDDO
1292 end if
1293!
1294! MONITOR FOR EXCESSIVE GRAVITY WAVE DRAG TENDENCIES IF NCNT>0
1295!
1296! IF(NCNT.GT.0) THEN
1297! IF(LAT.GE.38.AND.LAT.LE.42) THEN
1298!CMIC$ GUARD 37
1299! DO 92 I = 1,IM
1300! IF(IKOUNT.GT.NCNT) GO TO 92
1301! IF(I.LT.319.OR.I.GT.320) GO TO 92
1302! DO 91 K = 1,KM
1303! IF(ABS(TAUD(I,K)) .GT. CRITAC) THEN
1304! IF(I.LE.IM) THEN
1305! IKOUNT = IKOUNT+1
1306! PRINT 123,I,LAT,KDT
1307! PRINT 124,TAUB(I),BNV(I),ULOW(I),
1308! 1 GF(I),FR(I),ROLL(I),HPRIME(I),XN(I),YN(I)
1309! PRINT 124,(TAUD(I,KK),KK = 1,KM)
1310! PRINT 124,(TAUP(I,KK),KK = 1,KM+1)
1311! PRINT 124,(ri_n(I,KK),KK = 1,KM)
1312! DO 93 KK = 1,KMM1
1313! VELKO(KK) =
1314! 1 0.5*((U1(I,KK)+U1(I,KK+1))*UBAR(I)+
1315! 2 (V1(I,KK)+V1(I,KK+1))*VBAR(I))*ULOI(I)
1316!93 CONTINUE
1317! PRINT 124,(VELKO(KK),KK = 1,KMM1)
1318! PRINT 124,(A (I,KK),KK = 1,KM)
1319! PRINT 124,(DTAUY(I,KK),KK = 1,KM)
1320! PRINT 124,(B (I,KK),KK = 1,KM)
1321! PRINT 124,(DTAUX(I,KK),KK = 1,KM)
1322! GO TO 92
1323! ENDIF
1324! ENDIF
1325!91 CONTINUE
1326!92 CONTINUE
1327!CMIC$ END GUARD 37
1328!123 FORMAT(' *** MIGWD PRINT *** I=',I3,' LAT=',I3,' KDT=',I3)
1329!124 FORMAT(2X, 10E13.6)
1330! ENDIF
1331! ENDIF
1332!
1333! print *,' in gwdps_lm.f 18 =',A(ipt(1),idxzb(1))
1334! &, B(ipt(1),idxzb(1)),me
1335 RETURN
1336 end subroutine gwdps_run
1338 end module gwdps
subroutine gwdps_run(im, km, a, b, c, u1, v1, t1, q1, kpbl, prsi, del, prsl, prslk, phii, phil, deltim, kdt, hprime, oc, oa4, clx4, theta, sigma, gamma, elvmax, dusfc, dvsfc, dtaux2d_ms, dtauy2d_ms, dtaux2d_bl, dtauy2d_bl, dusfc_ms, dvsfc_ms, dusfc_bl, dvsfc_bl, g, cp, rd, rv, imx, nmtvr, cdmbgwd, me, lprnt, ipr, rdxzb, ldiag_ugwp, errmsg, errflg)
Definition gwdps.f:203
This module contains the CCPP-compliant orographic gravity wave dray scheme. This version of gwdps is...
Definition gwdps.f:7