58 & ps,t1,q1,z1,garea,wind, &
59 & prsl1,prslki,prsik1,prslk1, &
60 & sigmaf,vegtype,shdmax,ivegsrc, &
63 & flag_lakefreeze,lakefrac,fice, &
64 & u10m,v10m,sfc_z0_type, &
65 & u1,v1,usfco,vsfco,use_oceanuv, &
68 & tskin_wat, tskin_lnd, tskin_ice, &
69 & tsurf_wat, tsurf_lnd, tsurf_ice, &
70 & z0rl_wat, z0rl_lnd, z0rl_ice, &
72 & ustar_wat, ustar_lnd, ustar_ice, &
73 & cm_wat, cm_lnd, cm_ice, &
74 & ch_wat, ch_lnd, ch_ice, &
75 & rb_wat, rb_lnd, rb_ice, &
76 & stress_wat,stress_lnd,stress_ice, &
77 & fm_wat, fm_lnd, fm_ice, &
78 & fh_wat, fh_lnd, fh_ice, &
79 & fm10_wat, fm10_lnd, fm10_ice, &
80 & fh2_wat, fh2_lnd, fh2_ice, &
81 & ztmax_wat, ztmax_lnd, ztmax_ice, &
87 integer,
parameter :: kp = kind_phys
88 integer,
intent(in) :: im, ivegsrc
89 integer,
intent(in) :: sfc_z0_type
90 logical,
intent(in) :: use_oceanuv
92 integer,
dimension(:),
intent(in) :: vegtype
94 logical,
intent(in) :: redrag
95 logical,
dimension(:),
intent(in) :: flag_iter, dry, icy
96 logical,
dimension(:),
intent(in) :: flag_lakefreeze
97 logical,
dimension(:),
intent(inout) :: wet
99 logical,
intent(in) :: thsfc_loc
101 real(kind=kind_phys),
dimension(:),
intent(in) :: u10m,v10m
102 real(kind=kind_phys),
dimension(:),
intent(in) :: u1,v1
103 real(kind=kind_phys),
dimension(:),
intent(in) :: usfco,vsfco
104 real(kind=kind_phys),
intent(in) :: rvrdm1, eps, epsm1, grav
105 real(kind=kind_phys),
dimension(:),
intent(in) :: &
106 & ps,t1,q1,z1,garea,prsl1,prslki,prsik1,prslk1, &
107 & wind,sigmaf,shdmax, &
109 real(kind=kind_phys),
dimension(:),
intent(in) :: lakefrac
110 real(kind=kind_phys),
dimension(:),
intent(in) :: fice
111 real(kind=kind_phys),
dimension(:),
intent(in) :: &
112 & tskin_wat, tskin_lnd, tskin_ice, &
113 & tsurf_wat, tsurf_lnd, tsurf_ice
115 real(kind=kind_phys),
dimension(:),
intent(in) :: z0rl_wav
116 real(kind=kind_phys),
dimension(:),
intent(inout) :: &
117 & z0rl_wat, z0rl_lnd, z0rl_ice, &
118 & ustar_wat, ustar_lnd, ustar_ice, &
119 & cm_wat, cm_lnd, cm_ice, &
120 & ch_wat, ch_lnd, ch_ice, &
121 & rb_wat, rb_lnd, rb_ice, &
122 & stress_wat,stress_lnd,stress_ice, &
123 & fm_wat, fm_lnd, fm_ice, &
124 & fh_wat, fh_lnd, fh_ice, &
125 & fm10_wat, fm10_lnd, fm10_ice, &
126 & fh2_wat, fh2_lnd, fh2_ice, &
127 & ztmax_wat, ztmax_lnd, ztmax_ice
128 real(kind=kind_phys),
dimension(:),
intent(out) :: zvfun
130 character(len=*),
intent(out) :: errmsg
131 integer,
intent(out) :: errflg
136 real(kind=kind_phys) :: windrel
138 real(kind=kind_phys) :: rat, tv1, thv1, restar, wind10m,
139 & czilc, tem1, tem2, virtfac
142 real(kind=kind_phys) :: tvs, z0, z0max, ztmax, gdx
144 real(kind=kind_phys),
parameter :: z0lo=0.1, z0up=1.0
146 real(kind=kind_phys),
parameter ::
147 & one=1.0_kp, zero=0.0_kp, half=0.5_kp, qmin=1.0e-8_kp
148 &, charnock=.018_kp, z0s_max=.317e-2_kp &
150 &, vis=1.4e-5_kp, rnu=1.51e-5_kp, visi=one/vis &
151 &, log01=log(0.01_kp), log05=log(0.05_kp), log07=log(0.07_kp)
180 if(flag_iter(i) .or. flag_lakefreeze(i))
then
187 virtfac = one + rvrdm1 * max(q1(i),qmin)
189 tv1 = t1(i) * virtfac
191 thv1 = t1(i) * prslki(i) * virtfac
193 thv1 = t1(i) / prslk1(i) * virtfac
205 tvs = half * (tsurf_lnd(i)+tskin_lnd(i)) * virtfac
207 tvs = half * (tsurf_lnd(i)+tskin_lnd(i))/prsik1(i)
211 z0max = max(zmin, min(0.01_kp * z0rl_lnd(i), z1(i)))
213 tem1 = one - shdmax(i)
217 if( ivegsrc == 1 )
then
219 if (vegtype(i) == 10)
then
220 z0max = exp( tem2*log01 + tem1*log07 )
221 elseif (vegtype(i) == 6)
then
222 z0max = exp( tem2*log01 + tem1*log05 )
223 elseif (vegtype(i) == 7)
then
226 elseif (vegtype(i) == 16)
then
230 z0max = exp( tem2*log01 + tem1*log(z0max) )
233 elseif (ivegsrc == 2 )
then
235 if (vegtype(i) == 7)
then
236 z0max = exp( tem2*log01 + tem1*log07 )
237 elseif (vegtype(i) == 8)
then
238 z0max = exp( tem2*log01 + tem1*log05 )
239 elseif (vegtype(i) == 9)
then
242 elseif (vegtype(i) == 11)
then
246 z0max = exp( tem2*log01 + tem1*log(z0max) )
251 if (z0pert(i) /= zero )
then
252 z0max = z0max * (10.0_kp**z0pert(i))
255 z0max = max(z0max, zmin)
264 czilc = 10.0_kp ** (- 4.0_kp * z0max)
265 czilc = max(min(czilc, 0.8_kp), 0.08_kp)
266 tem1 = 1.0_kp - sigmaf(i)
267 czilc = czilc * tem1 * tem1
268 ztmax_lnd(i) = z0max * exp( - czilc * ca
269 & * 258.2_kp * sqrt(ustar_lnd(i)*z0max) )
272 if (ztpert(i) /= zero)
then
273 ztmax_lnd(i) = ztmax_lnd(i) * (10.0_kp**ztpert(i))
275 ztmax_lnd(i) = max(ztmax_lnd(i), zmin)
279 tem1 = (z0max - z0lo) / (z0up - z0lo)
280 tem1 = min(max(tem1, zero), 1.0_kp)
281 tem2 = max(sigmaf(i), 0.1_kp)
282 zvfun(i) = sqrt(tem1 * tem2)
286 & (z1(i), zvfun(i), gdx, tv1, thv1, wind(i),
287 & z0max, ztmax_lnd(i), tvs, grav, thsfc_loc,
289 & rb_lnd(i), fm_lnd(i), fh_lnd(i), fm10_lnd(i), fh2_lnd(i),
290 & cm_lnd(i), ch_lnd(i), stress_lnd(i), ustar_lnd(i))
298 tvs = half * (tsurf_ice(i)+tskin_ice(i)) * virtfac
300 tvs = half * (tsurf_ice(i)+tskin_ice(i))/prsik1(i)
304 z0max = max(zmin, min(0.01_kp * z0rl_ice(i), z1(i)))
306 tem1 = one - shdmax(i)
319 z0max = max(z0max, zmin)
329 czilc = 10.0_kp ** (- 4.0_kp * z0max)
330 czilc = max(min(czilc, 0.8_kp), 0.08_kp)
331 tem1 = 1.0_kp - sigmaf(i)
332 czilc = czilc * tem1 * tem1
333 ztmax_ice(i) = z0max * exp( - czilc * ca
334 & * 258.2_kp * sqrt(ustar_ice(i)*z0max) )
336 ztmax_ice(i) = max(ztmax_ice(i), 1.0e-6)
340 & (z1(i), zvfun(i), gdx, tv1, thv1, wind(i),
341 & z0max, ztmax_ice(i), tvs, grav, thsfc_loc,
343 & rb_ice(i), fm_ice(i), fh_ice(i), fm10_ice(i), fh2_ice(i),
344 & cm_ice(i), ch_ice(i), stress_ice(i), ustar_ice(i))
355 tvs = half * (tsurf_wat(i)+tskin_wat(i)) * virtfac
357 tvs = half * (tsurf_wat(i)+tskin_wat(i))/prsik1(i)
361 if (use_oceanuv)
then
362 wind10m=sqrt((u10m(i)-usfco(i))**2+(v10m(i)-vsfco(i))**2)
363 windrel=sqrt((u1(i)-usfco(i))**2+(v1(i)-vsfco(i))**2)
365 wind10m=sqrt(u10m(i)*u10m(i)+v10m(i)*v10m(i))
369 z0 = 0.01_kp * z0rl_wat(i)
370 z0max = max(zmin, min(z0,z1(i)))
376 restar = max(ustar_wat(i)*z0max*visi, 0.000001_kp)
385 rat = min(7.0_kp, 2.67_kp * sqrt(sqrt(restar)) - 2.57_kp)
386 ztmax_wat(i) = max(z0max * exp(-rat), zmin)
388 if (sfc_z0_type == 6)
then
390 else if (sfc_z0_type == 7)
then
392 else if (sfc_z0_type > 0)
then
393 write(0,*)
'no option for sfc_z0_type=',sfc_z0_type
395 errmsg =
'ERROR(sfc_diff_run): no option for sfc_z0_type'
401 & (z1(i), zvfun(i), gdx, tv1, thv1, windrel,
402 & z0max, ztmax_wat(i), tvs, grav, thsfc_loc,
404 & rb_wat(i), fm_wat(i), fh_wat(i), fm10_wat(i), fh2_wat(i),
405 & cm_wat(i), ch_wat(i), stress_wat(i), ustar_wat(i))
409 if ((sfc_z0_type == -1) .and.
410 & (lakefrac(i) == 0.0 .and. fice(i) == 0.0) .and.
411 & (z0rl_wav(i)>1.0e-7_kp .and. z0rl_wav(i)<0.1_kp))
then
413 tem1 = 0.11 * vis / ustar_wat(i)
414 z0 = tem1 + 0.01_kp * z0rl_wav(i)
417 z0rl_wat(i) = 100.0_kp * max(min(z0,z0s_max),1.0e-7_kp)
419 z0rl_wat(i) = 100.0_kp * max(min(z0,0.1_kp), 1.e-7_kp)
422 elseif ((sfc_z0_type == 0) .or.
423 & ((sfc_z0_type == -1) .and.
424 & (z0rl_wav(i)<=1.0e-7_kp .or. z0rl_wav(i)>=0.1_kp)))
then
426 tem1 = 0.11 * vis / ustar_wat(i)
427 z0 = tem1 + (charnock/grav)*ustar_wat(i)*ustar_wat(i)
439 z0rl_wat(i) = 100.0_kp * max(min(z0,z0s_max),1.0e-7_kp)
441 z0rl_wat(i) = 100.0_kp * max(min(z0,0.1_kp), 1.e-7_kp)
444 elseif (sfc_z0_type == 6)
then
446 z0rl_wat(i) = 100.0_kp * z0
447 elseif (sfc_z0_type == 7)
then
449 z0rl_wat(i) = 100.0_kp * z0
451 z0rl_wat(i) = 1.0e-4_kp
465 & ( z1, zvfun, gdx, tv1, thv1, wind, z0max, ztmax, tvs, grav, &
468 & rb, fm, fh, fm10, fh2, cm, ch, stress, ustar)
471 integer,
parameter :: kp = kind_phys
473 real(kind=kind_phys),
intent(in) :: &
474 & z1, zvfun, gdx, tv1, thv1, wind, z0max, ztmax, tvs, grav
475 logical,
intent(in) :: thsfc_loc
478 real(kind=kind_phys),
intent(out) :: &
479 & rb, fm, fh, fm10, fh2, cm, ch, stress, ustar
482 real(kind=kind_phys),
parameter :: alpha=5.0_kp, a0=-3.975_kp &
483 &, a1=12.32_kp, alpha4=4.0_kp*alpha &
484 &, b1=-7.755_kp, b2=6.041_kp &
485 &, xkrefsqr=0.3_kp, xkmin=0.05_kp &
487 &, a0p=-7.941_kp, a1p=24.75_kp, b1p=-8.705_kp, b2p=7.899_kp&
488 &, zolmin=-10.0_kp, zero=0.0_kp, one=1.0_kp
490 real(kind=kind_phys) aa, aa0, bb, bb0, dtv, adtv,
491 & hl1, hl12, pm, ph, pm10, ph2,
493 & fms, fhs, hl0, hl0inf, hlinf,
494 & hl110, hlt, hltinf, olinf,
497 real(kind=kind_phys) xkzo
506 if(gdx >= xkgdx)
then
515 xkzo = min(max(tem2, xkmin), xkzo)
518 zolmax = xkrefsqr / sqrt(xkzo)
523 adtv = max(abs(dtv),0.001_kp)
524 dtv = sign(1.0_kp,dtv) * adtv
527 rb = max(-5000.0_kp, (grav+grav) * dtv * z1
528 & / ((thv1 + tvs) * wind * wind))
530 rb = max(-5000.0_kp, grav * dtv * z1
531 & / (tv1 * wind * wind))
536 fm = log((z0max+z1) * tem1)
537 fh = log((ztmax+z1) * tem2)
538 fm10 = log((z0max+10.0_kp) * tem1)
539 fh2 = log((ztmax+2.0_kp) * tem2)
540 hlinf = rb * fm * fm / fh
541 hlinf = min(max(hlinf,zolmin),zolmax)
545 if (dtv >= zero)
then
547 if(hlinf > 0.25_kp)
then
549 hl0inf = z0max * tem1
550 hltinf = ztmax * tem1
551 aa = sqrt(one + alpha4 * hlinf)
552 aa0 = sqrt(one + alpha4 * hl0inf)
554 bb0 = sqrt(one + alpha4 * hltinf)
555 pm = aa0 - aa + log( (aa + one)/(aa0 + one) )
556 ph = bb0 - bb + log( (bb + one)/(bb0 + one) )
559 hl1 = fms * fms * rb / fhs
560 hl1 = min(hl1, zolmax)
568 aa = sqrt(one + alpha4 * hl1)
569 aa0 = sqrt(one + alpha4 * hl0)
571 bb0 = sqrt(one + alpha4 * hlt)
572 pm = aa0 - aa + log( (one+aa)/(one+aa0) )
573 ph = bb0 - bb + log( (one+bb)/(one+bb0) )
574 hl110 = hl1 * 10.0_kp * z1i
575 aa = sqrt(one + alpha4 * hl110)
576 pm10 = aa0 - aa + log( (one+aa)/(one+aa0) )
577 hl12 = (hl1+hl1) * z1i
579 bb = sqrt(one + alpha4 * hl12)
580 ph2 = bb0 - bb + log( (one+bb)/(one+bb0) )
586 tem1 = 50.0_kp * z0max
587 if(abs(olinf) <= tem1)
then
589 hlinf = max(hlinf, zolmin)
594 if (hlinf >= -0.5_kp)
then
596 pm = (a0 + a1*hl1) * hl1 / (one+ (b1+b2*hl1) *hl1)
597 ph = (a0p + a1p*hl1) * hl1 / (one+ (b1p+b2p*hl1)*hl1)
598 hl110 = hl1 * 10.0_kp * z1i
599 pm10 = (a0 + a1*hl110) * hl110/(one+(b1+b2*hl110)*hl110)
600 hl12 = (hl1+hl1) * z1i
601 ph2 = (a0p + a1p*hl12) * hl12/(one+(b1p+b2p*hl12)*hl12)
604 tem1 = one / sqrt(hl1)
605 pm = log(hl1) + 2.0_kp * sqrt(tem1) - .8776_kp
606 ph = log(hl1) + 0.5_kp * tem1 + 1.386_kp
609 hl110 = hl1 * 10.0_kp * z1i
610 pm10 = log(hl110) + 2.0_kp/sqrt(sqrt(hl110)) - 0.8776_kp
612 hl12 = (hl1+hl1) * z1i
613 ph2 = log(hl12) + 0.5_kp / sqrt(hl12) + 1.386_kp
625 cm = ca * ca / (fm * fm)
626 ch = ca * ca / (fm * fh)
630 stress = cm * wind * wind
695 use machine ,
only : kind_phys
700 REAL(kind=kind_phys),
INTENT(IN) :: uref
701 REAL(kind=kind_phys),
INTENT(OUT):: znott
702 real(kind=kind_phys),
parameter :: p00 = 1.100000000000000e-04,
703 & p15 = -9.144581627678278e-10, p14 = 7.020346616456421e-08,
704 & p13 = -2.155602086883837e-06, p12 = 3.333848806567684e-05,
705 & p11 = -2.628501274963990e-04, p10 = 8.634221567969181e-04,
707 & p25 = -8.654513012535990e-12, p24 = 1.232380050058077e-09,
708 & p23 = -6.837922749505057e-08, p22 = 1.871407733439947e-06,
709 & p21 = -2.552246987137160e-05, p20 = 1.428968311457630e-04,
711 & p35 = 3.207515102100162e-12, p34 = -2.945761895342535e-10,
712 & p33 = 8.788972147364181e-09, p32 = -3.814457439412957e-08,
713 & p31 = -2.448983648874671e-06, p30 = 3.436721779020359e-05,
715 & p45 = -3.530687797132211e-11, p44 = 3.939867958963747e-09,
716 & p43 = -1.227668406985956e-08, p42 = -1.367469811838390e-05,
717 & p41 = 5.988240863928883e-04, p40 = -7.746288511324971e-03,
719 & p56 = -1.187982453329086e-13, p55 = 4.801984186231693e-11,
720 & p54 = -8.049200462388188e-09, p53 = 7.169872601310186e-07,
721 & p52 = -3.581694433758150e-05, p51 = 9.503919224192534e-04,
722 & p50 = -1.036679430885215e-02,
724 & p60 = 4.751256171799112e-05
726 if (uref >= 0.0 .and. uref < 5.9 )
then
728 elseif (uref >= 5.9 .and. uref <= 15.4)
then
729 znott = p10 + uref * (p11 + uref * (p12 + uref * (p13
730 & + uref * (p14 + uref * p15))))
731 elseif (uref > 15.4 .and. uref <= 21.6)
then
732 znott = p20 + uref * (p21 + uref * (p22 + uref * (p23
733 & + uref * (p24 + uref * p25))))
734 elseif (uref > 21.6 .and. uref <= 42.2)
then
735 znott = p30 + uref * (p31 + uref * (p32 + uref * (p33
736 & + uref * (p34 + uref * p35))))
737 elseif ( uref > 42.2 .and. uref <= 53.3)
then
738 znott = p40 + uref * (p41 + uref * (p42 + uref * (p43
739 & + uref * (p44 + uref * p45))))
740 elseif ( uref > 53.3 .and. uref <= 80.0)
then
741 znott = p50 + uref * (p51 + uref * (p52 + uref * (p53
742 & + uref * (p54 + uref * (p55 + uref * p56)))))
743 elseif ( uref > 80.0)
then
746 print*,
'Wrong input uref value:',uref
810 use machine ,
only : kind_phys
815 REAL(kind=kind_phys),
INTENT(IN) :: uref
816 REAL(kind=kind_phys),
INTENT(OUT):: znott
818 real(kind=kind_phys),
parameter :: p00 = 1.100000000000000e-04,
820 & p15 = -9.193764479895316e-10, p14 = 7.052217518653943e-08,
821 & p13 = -2.163419217747114e-06, p12 = 3.342963077911962e-05,
822 & p11 = -2.633566691328004e-04, p10 = 8.644979973037803e-04,
824 & p25 = -9.402722450219142e-12, p24 = 1.325396583616614e-09,
825 & p23 = -7.299148051141852e-08, p22 = 1.982901461144764e-06,
826 & p21 = -2.680293455916390e-05, p20 = 1.484341646128200e-04,
828 & p35 = 7.921446674311864e-12, p34 = -1.019028029546602e-09,
829 & p33 = 5.251986927351103e-08, p32 = -1.337841892062716e-06,
830 & p31 = 1.659454106237737e-05, p30 = -7.558911792344770e-05,
832 & p45 = -2.694370426850801e-10, p44 = 5.817362913967911e-08,
833 & p43 = -5.000813324746342e-06, p42 = 2.143803523428029e-04,
834 & p41 = -4.588070983722060e-03, p40 = 3.924356617245624e-02,
836 & p56 = -1.663918773476178e-13, p55 = 6.724854483077447e-11,
837 & p54 = -1.127030176632823e-08, p53 = 1.003683177025925e-06,
838 & p52 = -5.012618091180904e-05, p51 = 1.329762020689302e-03,
839 & p50 = -1.450062148367566e-02, p60 = 6.840803042788488e-05
841 if (uref >= 0.0 .and. uref < 5.9 )
then
843 elseif (uref >= 5.9 .and. uref <= 15.4)
then
844 znott = p10 + uref * (p11 + uref * (p12 + uref * (p13
845 & + uref * (p14 + uref * p15))))
846 elseif (uref > 15.4 .and. uref <= 21.6)
then
847 znott = p20 + uref * (p21 + uref * (p22 + uref * (p23
848 & + uref * (p24 + uref * p25))))
849 elseif (uref > 21.6 .and. uref <= 42.6)
then
850 znott = p30 + uref * (p31 + uref * (p32 + uref * (p33
851 & + uref * (p34 + uref * p35))))
852 elseif ( uref > 42.6 .and. uref <= 53.0)
then
853 znott = p40 + uref * (p41 + uref * (p42 + uref * (p43
854 & + uref * (p44 + uref * p45))))
855 elseif ( uref > 53.0 .and. uref <= 80.0)
then
856 znott = p50 + uref * (p51 + uref * (p52 + uref * (p53
857 & + uref * (p54 + uref * (p55 + uref * p56)))))
858 elseif ( uref > 80.0)
then
861 print*,
'Wrong input uref value:',uref
subroutine, public sfc_diff_run(im, rvrdm1, eps, epsm1, grav, ps, t1, q1, z1, garea, wind, prsl1, prslki, prsik1, prslk1, sigmaf, vegtype, shdmax, ivegsrc, z0pert, ztpert, flag_iter, redrag, flag_lakefreeze, lakefrac, fice, u10m, v10m, sfc_z0_type, u1, v1, usfco, vsfco, use_oceanuv, wet, dry, icy, thsfc_loc, tskin_wat, tskin_lnd, tskin_ice, tsurf_wat, tsurf_lnd, tsurf_ice, z0rl_wat, z0rl_lnd, z0rl_ice, z0rl_wav, ustar_wat, ustar_lnd, ustar_ice, cm_wat, cm_lnd, cm_ice, ch_wat, ch_lnd, ch_ice, rb_wat, rb_lnd, rb_ice, stress_wat, stress_lnd, stress_ice, fm_wat, fm_lnd, fm_ice, fh_wat, fh_lnd, fh_ice, fm10_wat, fm10_lnd, fm10_ice, fh2_wat, fh2_lnd, fh2_ice, ztmax_wat, ztmax_lnd, ztmax_ice, zvfun, errmsg, errflg)