58 & ps,t1,q1,z1,garea,wind, &
59 & prsl1,prslki,prsik1,prslk1, &
60 & sigmaf,vegtype,shdmax,ivegsrc, &
64 & u10m,v10m,sfc_z0_type, &
65 & u1,v1,usfco,vsfco,icplocn2atm, &
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 integer,
intent(in) :: icplocn2atm
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) :: &
110 & tskin_wat, tskin_lnd, tskin_ice, &
111 & tsurf_wat, tsurf_lnd, tsurf_ice
113 real(kind=kind_phys),
dimension(:),
intent(in) :: z0rl_wav
114 real(kind=kind_phys),
dimension(:),
intent(inout) :: &
115 & z0rl_wat, z0rl_lnd, z0rl_ice, &
116 & ustar_wat, ustar_lnd, ustar_ice, &
117 & cm_wat, cm_lnd, cm_ice, &
118 & ch_wat, ch_lnd, ch_ice, &
119 & rb_wat, rb_lnd, rb_ice, &
120 & stress_wat,stress_lnd,stress_ice, &
121 & fm_wat, fm_lnd, fm_ice, &
122 & fh_wat, fh_lnd, fh_ice, &
123 & fm10_wat, fm10_lnd, fm10_ice, &
124 & fh2_wat, fh2_lnd, fh2_ice, &
125 & ztmax_wat, ztmax_lnd, ztmax_ice
126 real(kind=kind_phys),
dimension(:),
intent(out) :: zvfun
128 character(len=*),
intent(out) :: errmsg
129 integer,
intent(out) :: errflg
134 real(kind=kind_phys) :: windrel
136 real(kind=kind_phys) :: rat, tv1, thv1, restar, wind10m,
137 & czilc, tem1, tem2, virtfac
140 real(kind=kind_phys) :: tvs, z0, z0max, ztmax, gdx
142 real(kind=kind_phys),
parameter :: z0lo=0.1, z0up=1.0
144 real(kind=kind_phys),
parameter ::
145 & one=1.0_kp, zero=0.0_kp, half=0.5_kp, qmin=1.0e-8_kp
146 &, charnock=.018_kp, z0s_max=.317e-2_kp &
148 &, vis=1.4e-5_kp, rnu=1.51e-5_kp, visi=one/vis &
149 &, log01=log(0.01_kp), log05=log(0.05_kp), log07=log(0.07_kp)
178 if(flag_iter(i) .or. flag_lakefreeze(i))
then
185 virtfac = one + rvrdm1 * max(q1(i),qmin)
187 tv1 = t1(i) * virtfac
189 thv1 = t1(i) * prslki(i) * virtfac
191 thv1 = t1(i) / prslk1(i) * virtfac
203 tvs = half * (tsurf_lnd(i)+tskin_lnd(i)) * virtfac
205 tvs = half * (tsurf_lnd(i)+tskin_lnd(i))/prsik1(i)
209 z0max = max(zmin, min(0.01_kp * z0rl_lnd(i), z1(i)))
211 tem1 = one - shdmax(i)
215 if( ivegsrc == 1 )
then
217 if (vegtype(i) == 10)
then
218 z0max = exp( tem2*log01 + tem1*log07 )
219 elseif (vegtype(i) == 6)
then
220 z0max = exp( tem2*log01 + tem1*log05 )
221 elseif (vegtype(i) == 7)
then
224 elseif (vegtype(i) == 16)
then
228 z0max = exp( tem2*log01 + tem1*log(z0max) )
231 elseif (ivegsrc == 2 )
then
233 if (vegtype(i) == 7)
then
234 z0max = exp( tem2*log01 + tem1*log07 )
235 elseif (vegtype(i) == 8)
then
236 z0max = exp( tem2*log01 + tem1*log05 )
237 elseif (vegtype(i) == 9)
then
240 elseif (vegtype(i) == 11)
then
244 z0max = exp( tem2*log01 + tem1*log(z0max) )
249 if (z0pert(i) /= zero )
then
250 z0max = z0max * (10.0_kp**z0pert(i))
253 z0max = max(z0max, zmin)
262 czilc = 10.0_kp ** (- 4.0_kp * z0max)
263 czilc = max(min(czilc, 0.8_kp), 0.08_kp)
264 tem1 = 1.0_kp - sigmaf(i)
265 czilc = czilc * tem1 * tem1
266 ztmax_lnd(i) = z0max * exp( - czilc * ca
267 & * 258.2_kp * sqrt(ustar_lnd(i)*z0max) )
270 if (ztpert(i) /= zero)
then
271 ztmax_lnd(i) = ztmax_lnd(i) * (10.0_kp**ztpert(i))
273 ztmax_lnd(i) = max(ztmax_lnd(i), zmin)
277 tem1 = (z0max - z0lo) / (z0up - z0lo)
278 tem1 = min(max(tem1, zero), 1.0_kp)
279 tem2 = max(sigmaf(i), 0.1_kp)
280 zvfun(i) = sqrt(tem1 * tem2)
284 & (z1(i), zvfun(i), gdx, tv1, thv1, wind(i),
285 & z0max, ztmax_lnd(i), tvs, grav, thsfc_loc,
287 & rb_lnd(i), fm_lnd(i), fh_lnd(i), fm10_lnd(i), fh2_lnd(i),
288 & cm_lnd(i), ch_lnd(i), stress_lnd(i), ustar_lnd(i))
296 tvs = half * (tsurf_ice(i)+tskin_ice(i)) * virtfac
298 tvs = half * (tsurf_ice(i)+tskin_ice(i))/prsik1(i)
302 z0max = max(zmin, min(0.01_kp * z0rl_ice(i), z1(i)))
304 tem1 = one - shdmax(i)
317 z0max = max(z0max, zmin)
327 czilc = 10.0_kp ** (- 4.0_kp * z0max)
328 czilc = max(min(czilc, 0.8_kp), 0.08_kp)
329 tem1 = 1.0_kp - sigmaf(i)
330 czilc = czilc * tem1 * tem1
331 ztmax_ice(i) = z0max * exp( - czilc * ca
332 & * 258.2_kp * sqrt(ustar_ice(i)*z0max) )
334 ztmax_ice(i) = max(ztmax_ice(i), 1.0e-6)
338 & (z1(i), zvfun(i), gdx, tv1, thv1, wind(i),
339 & z0max, ztmax_ice(i), tvs, grav, thsfc_loc,
341 & rb_ice(i), fm_ice(i), fh_ice(i), fm10_ice(i), fh2_ice(i),
342 & cm_ice(i), ch_ice(i), stress_ice(i), ustar_ice(i))
353 tvs = half * (tsurf_wat(i)+tskin_wat(i)) * virtfac
355 tvs = half * (tsurf_wat(i)+tskin_wat(i))/prsik1(i)
359 if (icplocn2atm == 0)
then
360 wind10m=sqrt(u10m(i)*u10m(i)+v10m(i)*v10m(i))
362 else if (icplocn2atm ==1)
then
363 wind10m=sqrt((u10m(i)-usfco(i))**2+(v10m(i)-vsfco(i))**2)
364 windrel=sqrt((u1(i)-usfco(i))**2+(v1(i)-vsfco(i))**2)
367 if (sfc_z0_type == -1)
then
368 tem1 = 0.11 * vis / ustar_wat(i)
369 z0 = tem1 + 0.01_kp * z0rl_wav(i)
372 z0max = max(min(z0, z0s_max),1.0e-7_kp)
374 z0max = max(min(z0,0.1_kp), 1.0e-7_kp)
376 z0rl_wat(i) = 100.0_kp * z0max
378 z0 = 0.01_kp * z0rl_wat(i)
379 z0max = max(zmin, min(z0,z1(i)))
386 restar = max(ustar_wat(i)*z0max*visi, 0.000001_kp)
395 rat = min(7.0_kp, 2.67_kp * sqrt(sqrt(restar)) - 2.57_kp)
396 ztmax_wat(i) = max(z0max * exp(-rat), zmin)
398 if (sfc_z0_type == 6)
then
400 else if (sfc_z0_type == 7)
then
402 else if (sfc_z0_type > 0)
then
403 write(0,*)
'no option for sfc_z0_type=',sfc_z0_type
405 errmsg =
'ERROR(sfc_diff_run): no option for sfc_z0_type'
411 & (z1(i), zvfun(i), gdx, tv1, thv1, windrel,
412 & z0max, ztmax_wat(i), tvs, grav, thsfc_loc,
414 & rb_wat(i), fm_wat(i), fh_wat(i), fm10_wat(i), fh2_wat(i),
415 & cm_wat(i), ch_wat(i), stress_wat(i), ustar_wat(i))
419 if (sfc_z0_type >= 0)
then
420 if (sfc_z0_type == 0)
then
422 tem1 = 0.11 * vis / ustar_wat(i)
423 z0 = tem1 + (charnock/grav)*ustar_wat(i)*ustar_wat(i)
435 z0rl_wat(i) = 100.0_kp * max(min(z0, z0s_max), &
438 z0rl_wat(i) = 100.0_kp * max(min(z0,0.1_kp), 1.e-7_kp)
441 elseif (sfc_z0_type == 6)
then
443 z0rl_wat(i) = 100.0_kp * z0
444 elseif (sfc_z0_type == 7)
then
446 z0rl_wat(i) = 100.0_kp * z0
448 z0rl_wat(i) = 1.0e-4_kp
451 elseif (z0rl_wav(i) <= 1.0e-7_kp .or.
452 & z0rl_wav(i) > 1.0_kp)
then
454 tem1 = 0.11 * vis / ustar_wat(i)
455 z0 = tem1 + (charnock/grav)*ustar_wat(i)*ustar_wat(i)
458 z0rl_wat(i) = 100.0_kp * max(min(z0, z0s_max),1.0e-7_kp)
460 z0rl_wat(i) = 100.0_kp * max(min(z0,0.1_kp), 1.0e-7_kp)
477 & ( z1, zvfun, gdx, tv1, thv1, wind, z0max, ztmax, tvs, grav, &
480 & rb, fm, fh, fm10, fh2, cm, ch, stress, ustar)
483 integer,
parameter :: kp = kind_phys
485 real(kind=kind_phys),
intent(in) :: &
486 & z1, zvfun, gdx, tv1, thv1, wind, z0max, ztmax, tvs, grav
487 logical,
intent(in) :: thsfc_loc
490 real(kind=kind_phys),
intent(out) :: &
491 & rb, fm, fh, fm10, fh2, cm, ch, stress, ustar
494 real(kind=kind_phys),
parameter :: alpha=5.0_kp, a0=-3.975_kp &
495 &, a1=12.32_kp, alpha4=4.0_kp*alpha &
496 &, b1=-7.755_kp, b2=6.041_kp &
497 &, xkrefsqr=0.3_kp, xkmin=0.05_kp &
499 &, a0p=-7.941_kp, a1p=24.75_kp, b1p=-8.705_kp, b2p=7.899_kp&
500 &, zolmin=-10.0_kp, zero=0.0_kp, one=1.0_kp
502 real(kind=kind_phys) aa, aa0, bb, bb0, dtv, adtv,
503 & hl1, hl12, pm, ph, pm10, ph2,
505 & fms, fhs, hl0, hl0inf, hlinf,
506 & hl110, hlt, hltinf, olinf,
509 real(kind=kind_phys) xkzo
518 if(gdx >= xkgdx)
then
527 xkzo = min(max(tem2, xkmin), xkzo)
530 zolmax = xkrefsqr / sqrt(xkzo)
535 adtv = max(abs(dtv),0.001_kp)
536 dtv = sign(1.0_kp,dtv) * adtv
539 rb = max(-5000.0_kp, (grav+grav) * dtv * z1
540 & / ((thv1 + tvs) * wind * wind))
542 rb = max(-5000.0_kp, grav * dtv * z1
543 & / (tv1 * wind * wind))
548 fm = log((z0max+z1) * tem1)
549 fh = log((ztmax+z1) * tem2)
550 fm10 = log((z0max+10.0_kp) * tem1)
551 fh2 = log((ztmax+2.0_kp) * tem2)
552 hlinf = rb * fm * fm / fh
553 hlinf = min(max(hlinf,zolmin),zolmax)
557 if (dtv >= zero)
then
559 if(hlinf > 0.25_kp)
then
561 hl0inf = z0max * tem1
562 hltinf = ztmax * tem1
563 aa = sqrt(one + alpha4 * hlinf)
564 aa0 = sqrt(one + alpha4 * hl0inf)
566 bb0 = sqrt(one + alpha4 * hltinf)
567 pm = aa0 - aa + log( (aa + one)/(aa0 + one) )
568 ph = bb0 - bb + log( (bb + one)/(bb0 + one) )
571 hl1 = fms * fms * rb / fhs
572 hl1 = min(hl1, zolmax)
580 aa = sqrt(one + alpha4 * hl1)
581 aa0 = sqrt(one + alpha4 * hl0)
583 bb0 = sqrt(one + alpha4 * hlt)
584 pm = aa0 - aa + log( (one+aa)/(one+aa0) )
585 ph = bb0 - bb + log( (one+bb)/(one+bb0) )
586 hl110 = hl1 * 10.0_kp * z1i
587 aa = sqrt(one + alpha4 * hl110)
588 pm10 = aa0 - aa + log( (one+aa)/(one+aa0) )
589 hl12 = (hl1+hl1) * z1i
591 bb = sqrt(one + alpha4 * hl12)
592 ph2 = bb0 - bb + log( (one+bb)/(one+bb0) )
598 tem1 = 50.0_kp * z0max
599 if(abs(olinf) <= tem1)
then
601 hlinf = max(hlinf, zolmin)
606 if (hlinf >= -0.5_kp)
then
608 pm = (a0 + a1*hl1) * hl1 / (one+ (b1+b2*hl1) *hl1)
609 ph = (a0p + a1p*hl1) * hl1 / (one+ (b1p+b2p*hl1)*hl1)
610 hl110 = hl1 * 10.0_kp * z1i
611 pm10 = (a0 + a1*hl110) * hl110/(one+(b1+b2*hl110)*hl110)
612 hl12 = (hl1+hl1) * z1i
613 ph2 = (a0p + a1p*hl12) * hl12/(one+(b1p+b2p*hl12)*hl12)
616 tem1 = one / sqrt(hl1)
617 pm = log(hl1) + 2.0_kp * sqrt(tem1) - .8776_kp
618 ph = log(hl1) + 0.5_kp * tem1 + 1.386_kp
621 hl110 = hl1 * 10.0_kp * z1i
622 pm10 = log(hl110) + 2.0_kp/sqrt(sqrt(hl110)) - 0.8776_kp
624 hl12 = (hl1+hl1) * z1i
625 ph2 = log(hl12) + 0.5_kp / sqrt(hl12) + 1.386_kp
637 cm = ca * ca / (fm * fm)
638 ch = ca * ca / (fm * fh)
642 stress = cm * wind * wind
708 use machine ,
only : kind_phys
713 REAL(kind=kind_phys),
INTENT(IN) :: uref
714 REAL(kind=kind_phys),
INTENT(OUT):: znott
715 real(kind=kind_phys),
parameter :: p00 = 1.100000000000000e-04,
716 & p15 = -9.144581627678278e-10, p14 = 7.020346616456421e-08,
717 & p13 = -2.155602086883837e-06, p12 = 3.333848806567684e-05,
718 & p11 = -2.628501274963990e-04, p10 = 8.634221567969181e-04,
720 & p25 = -8.654513012535990e-12, p24 = 1.232380050058077e-09,
721 & p23 = -6.837922749505057e-08, p22 = 1.871407733439947e-06,
722 & p21 = -2.552246987137160e-05, p20 = 1.428968311457630e-04,
724 & p35 = 3.207515102100162e-12, p34 = -2.945761895342535e-10,
725 & p33 = 8.788972147364181e-09, p32 = -3.814457439412957e-08,
726 & p31 = -2.448983648874671e-06, p30 = 3.436721779020359e-05,
728 & p45 = -3.530687797132211e-11, p44 = 3.939867958963747e-09,
729 & p43 = -1.227668406985956e-08, p42 = -1.367469811838390e-05,
730 & p41 = 5.988240863928883e-04, p40 = -7.746288511324971e-03,
732 & p56 = -1.187982453329086e-13, p55 = 4.801984186231693e-11,
733 & p54 = -8.049200462388188e-09, p53 = 7.169872601310186e-07,
734 & p52 = -3.581694433758150e-05, p51 = 9.503919224192534e-04,
735 & p50 = -1.036679430885215e-02,
737 & p60 = 4.751256171799112e-05
739 if (uref >= 0.0 .and. uref < 5.9 )
then
741 elseif (uref >= 5.9 .and. uref <= 15.4)
then
742 znott = p10 + uref * (p11 + uref * (p12 + uref * (p13
743 & + uref * (p14 + uref * p15))))
744 elseif (uref > 15.4 .and. uref <= 21.6)
then
745 znott = p20 + uref * (p21 + uref * (p22 + uref * (p23
746 & + uref * (p24 + uref * p25))))
747 elseif (uref > 21.6 .and. uref <= 42.2)
then
748 znott = p30 + uref * (p31 + uref * (p32 + uref * (p33
749 & + uref * (p34 + uref * p35))))
750 elseif ( uref > 42.2 .and. uref <= 53.3)
then
751 znott = p40 + uref * (p41 + uref * (p42 + uref * (p43
752 & + uref * (p44 + uref * p45))))
753 elseif ( uref > 53.3 .and. uref <= 80.0)
then
754 znott = p50 + uref * (p51 + uref * (p52 + uref * (p53
755 & + uref * (p54 + uref * (p55 + uref * p56)))))
756 elseif ( uref > 80.0)
then
759 print*,
'Wrong input uref value:',uref
823 use machine ,
only : kind_phys
828 REAL(kind=kind_phys),
INTENT(IN) :: uref
829 REAL(kind=kind_phys),
INTENT(OUT):: znott
831 real(kind=kind_phys),
parameter :: p00 = 1.100000000000000e-04,
833 & p15 = -9.193764479895316e-10, p14 = 7.052217518653943e-08,
834 & p13 = -2.163419217747114e-06, p12 = 3.342963077911962e-05,
835 & p11 = -2.633566691328004e-04, p10 = 8.644979973037803e-04,
837 & p25 = -9.402722450219142e-12, p24 = 1.325396583616614e-09,
838 & p23 = -7.299148051141852e-08, p22 = 1.982901461144764e-06,
839 & p21 = -2.680293455916390e-05, p20 = 1.484341646128200e-04,
841 & p35 = 7.921446674311864e-12, p34 = -1.019028029546602e-09,
842 & p33 = 5.251986927351103e-08, p32 = -1.337841892062716e-06,
843 & p31 = 1.659454106237737e-05, p30 = -7.558911792344770e-05,
845 & p45 = -2.694370426850801e-10, p44 = 5.817362913967911e-08,
846 & p43 = -5.000813324746342e-06, p42 = 2.143803523428029e-04,
847 & p41 = -4.588070983722060e-03, p40 = 3.924356617245624e-02,
849 & p56 = -1.663918773476178e-13, p55 = 6.724854483077447e-11,
850 & p54 = -1.127030176632823e-08, p53 = 1.003683177025925e-06,
851 & p52 = -5.012618091180904e-05, p51 = 1.329762020689302e-03,
852 & p50 = -1.450062148367566e-02, p60 = 6.840803042788488e-05
854 if (uref >= 0.0 .and. uref < 5.9 )
then
856 elseif (uref >= 5.9 .and. uref <= 15.4)
then
857 znott = p10 + uref * (p11 + uref * (p12 + uref * (p13
858 & + uref * (p14 + uref * p15))))
859 elseif (uref > 15.4 .and. uref <= 21.6)
then
860 znott = p20 + uref * (p21 + uref * (p22 + uref * (p23
861 & + uref * (p24 + uref * p25))))
862 elseif (uref > 21.6 .and. uref <= 42.6)
then
863 znott = p30 + uref * (p31 + uref * (p32 + uref * (p33
864 & + uref * (p34 + uref * p35))))
865 elseif ( uref > 42.6 .and. uref <= 53.0)
then
866 znott = p40 + uref * (p41 + uref * (p42 + uref * (p43
867 & + uref * (p44 + uref * p45))))
868 elseif ( uref > 53.0 .and. uref <= 80.0)
then
869 znott = p50 + uref * (p51 + uref * (p52 + uref * (p53
870 & + uref * (p54 + uref * (p55 + uref * p56)))))
871 elseif ( uref > 80.0)
then
874 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, u10m, v10m, sfc_z0_type, u1, v1, usfco, vsfco, icplocn2atm, 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)