CCPP SciDoc v7.0.0  v7.0.0
Common Community Physics Package Developed at DTC
 
Loading...
Searching...
No Matches
sflx.f
1
3
5 module sflx
6 contains
116 subroutine gfssflx &! --- inputs:
117 & ( nsoil, couple, icein, ffrozp, dt, zlvl, sldpth, &
118 & swdn, swnet, lwdn, sfcems, sfcprs, sfctmp, &
119 & sfcspd, prcp, q2, q2sat, dqsdt2, th2, ivegsrc, &
120 & vegtyp, soiltyp, slopetyp, shdmin, alb, snoalb, &
121 & rhonewsn, exticeden, &
122 & bexpp, xlaip, & ! sfc-perts, mgehne
123 & lheatstrg, &! --- input/outputs:
124 & tbot, cmc, t1, stc, smc, sh2o, sneqv, ch, cm,z0, &! --- outputs:
125 & nroot, shdfac, snowh, albedo, eta, sheat, ec, &
126 & edir, et, ett, esnow, drip, dew, beta, etp, ssoil, &
127 & flx1, flx2, flx3, runoff1, runoff2, runoff3, &
128 & snomlt, sncovr, rc, pc, rsmin, xlai, rcs, rct, rcq, &
129 & rcsoil, soilw, soilm, smcwlt, smcdry, smcref, smcmax, &
130 & errmsg, errflg )
131
132! ===================================================================== !
133! description: !
134! !
135! subroutine sflx - version 2.7: !
136! sub-driver for "noah/osu lsm" family of physics subroutines for a !
137! soil/veg/snowpack land-surface model to update soil moisture, soil !
138! ice, soil temperature, skin temperature, snowpack water content, !
139! snowdepth, and all terms of the surface energy balance and surface !
140! water balance (excluding input atmospheric forcings of downward !
141! radiation and precip) !
142! !
143! usage: !
144! !
145! call sflx !
146! --- inputs: !
147! ( nsoil, couple, icein, ffrozp, dt, zlvl, sldpth, !
148! swdn, swnet, lwdn, sfcems, sfcprs, sfctmp, !
149! sfcspd, prcp, q2, q2sat, dqsdt2, th2,ivegsrc, !
150! vegtyp, soiltyp, slopetyp, shdmin, alb, snoalb, !
151! --- input/outputs: !
152! tbot, cmc, t1, stc, smc, sh2o, sneqv, ch, cm, !
153! --- outputs: !
154! nroot, shdfac, snowh, albedo, eta, sheat, ec, !
155! edir, et, ett, esnow, drip, dew, beta, etp, ssoil, !
156! flx1, flx2, flx3, runoff1, runoff2, runoff3, !
157! snomlt, sncovr, rc, pc, rsmin, xlai, rcs, rct, rcq, !
158! rcsoil, soilw, soilm, smcwlt, smcdry, smcref, smcmax ) !
159! !
160! !
161! subprograms called: redprm, snow_new, csnow, snfrac, alcalc, !
162! tdfcnd, snowz0, sfcdif, penman, canres, nopac, snopac. !
163! !
164! !
165! program history log: !
166! jun 2003 -- k. mitchell et. al -- created version 2.7 !
167! 200x -- sarah lu modified the code including: !
168! added passing argument, couple; replaced soldn !
169! and solnet by radflx; call sfcdif if couple=0; !
170! apply time filter to stc and tskin; and the !
171! way of namelist inport. !
172! feb 2004 -- m. ek noah v2.7.1 non-linear weighting of snow vs !
173! non-snow covered portions of gridbox !
174! apr 2009 -- y.-t. hou added lw surface emissivity effect, !
175! streamlined and reformatted the code, and !
176! consolidated constents/parameters by using !
177! module physcons, and added program documentation!
178! sep 2009 -- s. moorthi minor fixes !
179! !
180! ==================== defination of variables ==================== !
181! !
182! inputs: size !
183! nsoil - integer, number of soil layers (>=2 but <=nsold) 1 !
184! couple - integer, =0:uncoupled (land model only) 1 !
185! =1:coupled with parent atmos model !
186! icein - integer, sea-ice flag (=1: sea-ice, =0: land) 1 !
187! ffrozp - real, fractional snow/rain 1 !
188! dt - real, time step (<3600 sec) 1 !
189! zlvl - real, height abv atmos ground forcing vars (m) 1 !
190! sldpth - real, thickness of each soil layer (m) nsoil !
191! swdn - real, downward sw radiation flux (w/m**2) 1 !
192! swnet - real, downward sw net (dn-up) flux (w/m**2) 1 !
193! lwdn - real, downward lw radiation flux (w/m**2) 1 !
194! sfcems - real, sfc lw emissivity (fractional) 1 !
195! sfcprs - real, pressure at height zlvl abv ground(pascals) 1 !
196! sfctmp - real, air temp at height zlvl abv ground (k) 1 !
197! sfcspd - real, wind speed at height zlvl abv ground (m/s) 1 !
198! prcp - real, precip rate (kg m-2 s-1) 1 !
199! q2 - real, mixing ratio at hght zlvl abv grnd (kg/kg) 1 !
200! q2sat - real, sat mixing ratio at zlvl abv grnd (kg/kg) 1 !
201! dqsdt2 - real, slope of sat specific humidity curve at 1 !
202! t=sfctmp (kg kg-1 k-1) !
203! th2 - real, air potential temp at zlvl abv grnd (k) 1 !
204! ivegsrc - integer, sfc veg type data source umd or igbp !
205! vegtyp - integer, vegetation type (integer index) 1 !
206! soiltyp - integer, soil type (integer index) 1 !
207! slopetyp - integer, class of sfc slope (integer index) 1 !
208! shdmin - real, min areal coverage of green veg (fraction) 1 !
209! alb - real, bkground snow-free sfc albedo (fraction) 1 !
210! snoalb - real, max albedo over deep snow (fraction) 1 !
211! lheatstrg- logical, flag for canopy heat storage 1 !
212! parameterization !
213! !
214! input/outputs: !
215! tbot - real, bottom soil temp (k) 1 !
216! (local yearly-mean sfc air temp) !
217! cmc - real, canopy moisture content (m) 1 !
218! t1 - real, ground/canopy/snowpack eff skin temp (k) 1 !
219! stc - real, soil temp (k) nsoil !
220! smc - real, total soil moisture (vol fraction) nsoil !
221! sh2o - real, unfrozen soil moisture (vol fraction) nsoil !
222! note: frozen part = smc-sh2o !
223! sneqv - real, water-equivalent snow depth (m) 1 !
224! note: snow density = snwqv/snowh !
225! ch - real, sfc exchange coeff for heat & moisture (m/s)1 !
226! note: conductance since it's been mult by wind !
227! cm - real, sfc exchange coeff for momentum (m/s) 1 !
228! note: conductance since it's been mult by wind !
229! !
230! outputs: !
231! nroot - integer, number of root layers 1 !
232! shdfac - real, aeral coverage of green veg (fraction) 1 !
233! snowh - real, snow depth (m) 1 !
234! albedo - real, sfc albedo incl snow effect (fraction) 1 !
235! eta - real, downward latent heat flux (w/m2) 1 !
236! sheat - real, downward sensible heat flux (w/m2) 1 !
237! ec - real, canopy water evaporation (w/m2) 1 !
238! edir - real, direct soil evaporation (w/m2) 1 !
239! et - real, plant transpiration (w/m2) nsoil !
240! ett - real, total plant transpiration (w/m2) 1 !
241! esnow - real, sublimation from snowpack (w/m2) 1 !
242! drip - real, through-fall of precip and/or dew in excess 1 !
243! of canopy water-holding capacity (m) !
244! dew - real, dewfall (or frostfall for t<273.15) (m) 1 !
245! beta - real, ratio of actual/potential evap 1 !
246! etp - real, potential evaporation (w/m2) 1 !
247! ssoil - real, upward soil heat flux (w/m2) 1 !
248! flx1 - real, precip-snow sfc flux (w/m2) 1 !
249! flx2 - real, freezing rain latent heat flux (w/m2) 1 !
250! flx3 - real, phase-change heat flux from snowmelt (w/m2) 1 !
251! snomlt - real, snow melt (m) (water equivalent) 1 !
252! sncovr - real, fractional snow cover 1 !
253! runoff1 - real, surface runoff (m/s) not infiltrating sfc 1 !
254! runoff2 - real, sub sfc runoff (m/s) (baseflow) 1 !
255! runoff3 - real, excess of porosity for a given soil layer 1 !
256! rc - real, canopy resistance (s/m) 1 !
257! pc - real, plant coeff (fraction) where pc*etp=transpi 1 !
258! rsmin - real, minimum canopy resistance (s/m) 1 !
259! xlai - real, leaf area index (dimensionless) 1 !
260! rcs - real, incoming solar rc factor (dimensionless) 1 !
261! rct - real, air temp rc factor (dimensionless) 1 !
262! rcq - real, atoms vapor press deficit rc factor 1 !
263! rcsoil - real, soil moisture rc factor (dimensionless) 1 !
264! soilw - real, available soil mois in root zone 1 !
265! soilm - real, total soil column mois (frozen+unfrozen) (m)1 !
266! smcwlt - real, wilting point (volumetric) 1 !
267! smcdry - real, dry soil mois threshold (volumetric) 1 !
268! smcref - real, soil mois threshold (volumetric) 1 !
269! smcmax - real, porosity (sat val of soil mois) 1 !
270! !
271! ==================== end of description ===================== !
272!
273 use machine , only : kind_phys
274!
275 use physcons, only : con_cp, con_rd, con_t0c, con_g, con_pi, &
276 & con_cliq, con_csol, con_hvap, con_hfus, &
277 & con_sbc
278!
279 implicit none
280
281! --- constant parameters:
282! *** note: some of the constants are different in subprograms and need to
283! be consolidated with the standard def in module physcons at sometime
284! at the present time, those diverse values are kept temperately to
285! provide the same result as the original codes. -- y.t.h. may09
286
287 integer, parameter :: nsold = 4
288
289! real (kind=kind_phys), parameter :: gs = con_g !< con_g =9.80665
290 real (kind=kind_phys), parameter :: gs1 = 9.8
291 real (kind=kind_phys), parameter :: gs2 = 9.81
292 real (kind=kind_phys), parameter :: tfreez = con_t0c
293 real (kind=kind_phys), parameter :: lsubc = 2.501e+6
294 real (kind=kind_phys), parameter :: lsubf = 3.335e5
295 real (kind=kind_phys), parameter :: lsubs = 2.83e+6 ! ? in sflx, snopac
296 real (kind=kind_phys), parameter :: elcp = 2.4888e+3 ! ? in penman
297! real (kind=kind_phys), parameter :: rd = con_rd ! con_rd =287.05
298 real (kind=kind_phys), parameter :: rd1 = 287.04 ! con_rd in sflx, penman, canres
299 real (kind=kind_phys), parameter :: cp = con_cp ! con_cp =1004.6
300 real (kind=kind_phys), parameter :: cp1 = 1004.5 ! con_cp in sflx, canres
301 real (kind=kind_phys), parameter :: cp2 = 1004.0 ! con_cp in htr
302! real (kind=kind_phys), parameter :: cph2o = con_cliq ! con_cliq=4.1855e+3
303 real (kind=kind_phys), parameter :: cph2o1 = 4.218e+3 ! con_cliq in penman, snopac
304 real (kind=kind_phys), parameter :: cph2o2 = 4.2e6 ! con_cliq in hrt *unit diff!
305 real (kind=kind_phys), parameter :: cpice = con_csol ! con_csol=2.106e+3
306 real (kind=kind_phys), parameter :: cpice1 = 2.106e6 ! con_csol in hrt *unit diff!
307! real (kind=kind_phys), parameter :: sigma = con_sbc ! con_sbc=5.6704e-8
308 real (kind=kind_phys), parameter :: sigma1 = 5.67e-8 ! con_sbc in penman, nopac, snopac
309
310! --- inputs:
311 integer, intent(in) :: nsoil, couple, icein, vegtyp, soiltyp, &
312 & slopetyp, ivegsrc
313
314 real (kind=kind_phys), intent(in) :: ffrozp, dt, zlvl, lwdn, &
315 & sldpth(nsoil), swdn, swnet, sfcems, sfcprs, sfctmp, &
316 & sfcspd, prcp, q2, q2sat, dqsdt2, th2, shdmin, alb, snoalb, &
317 & bexpp, xlaip, rhonewsn & !sfc-perts, mgehne
318
319 logical, intent(in) :: lheatstrg, exticeden
320
321! --- input/outputs:
322 real (kind=kind_phys), intent(inout) :: tbot, cmc, t1, sneqv, &
323 & stc(nsoil), smc(nsoil), sh2o(nsoil), ch, cm
324
325! --- outputs:
326 integer, intent(out) :: nroot
327
328 real (kind=kind_phys), intent(out) :: shdfac, snowh, albedo, &
329 & eta, sheat, ec, edir, et(nsoil), ett, esnow, drip, dew, &
330 & beta, etp, ssoil, flx1, flx2, flx3, snomlt, sncovr, &
331 & runoff1, runoff2, runoff3, rc, pc, rsmin, xlai, rcs, &
332 & rct, rcq, rcsoil, soilw, soilm, smcwlt, smcdry, smcref, &
333 & smcmax
334 character(len=*), intent(out) :: errmsg
335 integer, intent(out) :: errflg
336
337! --- locals:
338! real (kind=kind_phys) :: df1h,
339 real (kind=kind_phys) :: bexp, cfactr, cmcmax, csoil, czil, &
340 & df1, df1a, dksat, dwsat, dsoil, dtot, frcsno, &
341 & frcsoi, epsca, fdown, f1, fxexp, frzx, hs, kdt, prcp1, &
342 & psisat, quartz, rch, refkdt, rr, rgl, rsmax, sndens, &
343 & sncond, sbeta, sn_new, slope, snup, salp, soilwm, soilww, &
344 & t1v, t24, t2v, th2v, topt, tsnow, zbot, z0
345
346 real (kind=kind_phys) :: shdfac0
347 real (kind=kind_phys), dimension(nsold) :: rtdis, zsoil
348
349 logical :: frzgra, snowng
350
351 integer :: ice, k, kz
352!
353!===> ... begin here
354!
355! Initialize CCPP error-handling
356 errflg = 0
357 errmsg = ''
358
359! --- ... initialization
360
361 runoff1 = 0.0
362 runoff2 = 0.0
363 runoff3 = 0.0
364 snomlt = 0.0
365 rc = 0.0
366
367! --- ... define local variable ice to achieve:
368! sea-ice case, ice = 1
369! non-glacial land, ice = 0
370! glacial-ice land, ice = -1
371! if vegtype=15 (glacial-ice), re-set ice flag = -1 (glacial-ice)
372! note - for open-sea, sflx should *not* have been called. set green
373! vegetation fraction (shdfac) = 0.
374
376 shdfac0 = shdfac
377 ice = icein
378
379 if(ivegsrc == 2) then
380 if (vegtyp == 13) then
381 ice = -1
382 shdfac = 0.0
383 endif
384 endif
385
386 if(ivegsrc == 1) then
387 if (vegtyp == 15) then
388 ice = -1
389 shdfac = 0.0
390 endif
391 endif
392
394 if (ice == 1) then
395
396 shdfac = 0.0
397
400
401 do kz = 1, nsoil
402 zsoil(kz) = -3.0 * float(kz) / float(nsoil)
403 enddo
404
405 else
406
409! note - sign of zsoil is negative (denoting below ground)
410
411 zsoil(1) = -sldpth(1)
412 do kz = 2, nsoil
413 zsoil(kz) = -sldpth(kz) + zsoil(kz-1)
414 end do
415
416 endif ! end if_ice_block
417
418! --- ... next is crucial call to set the land-surface parameters,
419! including soil-type and veg-type dependent parameters.
420! set shdfac=0.0 for bare soil surfaces
421
424 call redprm(errmsg, errflg)
425 if(ivegsrc == 1) then
426!only igbp type has urban
427!urban
428 if(vegtyp == 13)then
429! shdfac=0.05
430! rsmin=400.0
431! smcmax = 0.45
432! smcref = 0.42
433! smcwlt = 0.40
434! smcdry = 0.40
435 rsmin=400.0*(1-shdfac0)+40.0*shdfac0 ! gvf
436 shdfac=shdfac0 ! gvf
437 smcmax = 0.45*(1-shdfac0)+smcmax*shdfac0
438 smcref = 0.42*(1-shdfac0)+smcref*shdfac0
439 smcwlt = 0.40*(1-shdfac0)+smcwlt*shdfac0
440 smcdry = 0.40*(1-shdfac0)+smcdry*shdfac0
441 endif
442 endif
443
444! --- inputs: !
445! ( nsoil, vegtyp, soiltyp, slopetyp, sldpth, zsoil, !
446! --- outputs: !
447! cfactr, cmcmax, rsmin, rsmax, topt, refkdt, kdt, !
448! sbeta, shdfac, rgl, hs, zbot, frzx, psisat, slope, !
449! snup, salp, bexp, dksat, dwsat, smcmax, smcwlt, !
450! smcref, smcdry, f1, quartz, fxexp, rtdis, nroot, !
451! z0, czil, xlai, csoil ) !
452
453! --- ... bexp sfc-perts, mgehne
463
464 if( bexpp < 0.) then
465 bexp = bexp * max(1.+bexpp, 0.)
466 endif
467 if( bexpp >= 0.) then
468 bexp = bexp * min(1.+bexpp, 2.)
469 endif
470! --- ... lai sfc-perts, mgehne
472 xlai = xlai * (1.+xlaip)
473 xlai = max(xlai, .75)
474
476
477 snowng = .false.
478 frzgra = .false.
479
484! note - runoff2 is then a negative value (as a flag) over sea-ice or
485! glacial-ice, in order to achieve water balance.
486
487 if (ice == 1) then
488
489 if (sneqv < 0.01) then
490 sneqv = 0.01
491 snowh = 0.10
492! snowh = sneqv / sndens
493 endif
494
495 elseif (ice == -1) then
496
497 if (sneqv < 0.10) then
498! sndens = sneqv / snowh
499! runoff2 = -(0.10 - sneqv) / dt
500 sneqv = 0.10
501 snowh = 1.00
502! snowh = sneqv / sndens
503 endif
504
505 endif ! end if_ice_block
506
509
510 if (ice /= 0) then
511 do kz = 1, nsoil
512 smc(kz) = 1.0
513 sh2o(kz) = 1.0
514 enddo
515 endif
516
519! (note that csnow is a function subroutine)
520
521 if (sneqv .eq. 0.0) then
522 sndens = 0.0
523 snowh = 0.0
524 sncond = 1.0
525 else
526 sndens = sneqv / snowh
527 sndens = max( 0.0, min( 1.0, sndens )) ! added by moorthi
528
529 call csnow
530! --- inputs: !
531! ( sndens, !
532! --- outputs: !
533! sncond ) !
534
535 endif
536
542
543 if (prcp > 0.0) then
544 if (ffrozp > 0.) then
545 snowng = .true.
546 else
547 if (t1 <= tfreez) frzgra = .true.
548 endif
549 endif
550
552! determine new snowfall (converting precipitation rate from
553! \f$kg m^{-2} s^{-1}\f$ to a liquid equiv snow depth in meters)
554! and add it to the existing snowpack.
557
558 if (snowng .or. frzgra) then
559
560! snowfall
561 if (snowng) then
562 sn_new = ffrozp*prcp * dt * 0.001
563 sneqv = sneqv + sn_new
564 prcp1 = (1.-ffrozp)*prcp
565 endif
566! freezing rain
567 if (frzgra) then
568 sn_new = prcp * dt * 0.001
569 sneqv = sneqv + sn_new
570 prcp1 = 0.0
571 endif
572
575 call snow_new
576! --- inputs: !
577! ( sfctmp, sn_new, rhonewsn, exticeden, !
578! --- input/outputs: !
579! snowh, sndens ) !
580
582 call csnow
583! --- inputs: !
584! ( sndens, !
585! --- outputs: !
586! sncond ) !
587
588 else
589
593
594 prcp1 = prcp
595
596 endif ! end if_snowng_block
597
600
601 if (ice /= 0) then
602
603! --- ... snow cover, albedo over sea-ice, glacial-ice
604
605 sncovr = 1.0
606 albedo = 0.65
607
608 else
609
610! --- ... non-glacial land
611! if snow depth=0, set snowcover fraction=0, albedo=snow free albedo.
612
613 if (sneqv == 0.0) then
614
615 sncovr = 0.0
616 albedo = alb
617
618 else
619
620! --- ... determine snow fraction cover.
621! determine surface albedo modification due to snowdepth state.
623 call snfrac
624! --- inputs: !
625! ( sneqv, snup, salp, snowh, !
626! --- outputs: !
627! sncovr ) !
628
631 call alcalc
632! --- inputs: !
633! ( alb, snoalb, shdfac, shdmin, sncovr, tsnow, !
634! --- outputs: !
635! albedo ) !
636
637 endif ! end if_sneqv_block
638
639 endif ! end if_ice_block
640
641! --- ... thermal conductivity for sea-ice case, glacial-ice case
644
645 if (ice /= 0) then
646
647 df1 = 2.2
648
649 else
652
653! --- ... next calculate the subsurface heat flux, which first requires
654! calculation of the thermal diffusivity. treatment of the
655! latter follows that on pages 148-149 from "heat transfer in
656! cold climates", by v. j. lunardini (published in 1981
657! by van nostrand reinhold co.) i.e. treatment of two contiguous
658! "plane parallel" mediums (namely here the first soil layer
659! and the snowpack layer, if any). this diffusivity treatment
660! behaves well for both zero and nonzero snowpack, including the
661! limit of very thin snowpack. this treatment also eliminates
662! the need to impose an arbitrary upper bound on subsurface
663! heat flux when the snowpack becomes extremely thin.
664
665! --- ... first calculate thermal diffusivity of top soil layer, using
666! both the frozen and liquid soil moisture, following the
667! soil thermal diffusivity function of peters-lidard et al.
668! (1998,jas, vol 55, 1209-1224), which requires the specifying
669! the quartz content of the given soil class (see routine redprm)
670
671 call tdfcnd &
672! --- inputs:
673 & ( smc(1), quartz, smcmax, sh2o(1), &
674! --- outputs:
675 & df1 &
676 & )
677! if(ivegsrc == 1) then
678!only igbp type has urban
679!urban
680! if ( vegtyp == 13 ) df1=3.24
681! endif
682
686!wz only urban for igbp type
687!
688!jhan urban canopy heat storage effect is included in pbl scheme
689!
690 if((.not.lheatstrg) .and. &
691 & (ivegsrc == 1 .and. vegtyp == 13)) then
692 df1 = 3.24*(1.-shdfac) + shdfac*df1*exp(sbeta*shdfac)
693 else
694 df1 = df1 * exp( sbeta*shdfac )
695 endif
696
697 endif ! end if_ice_block
698
699! --- ... finally "plane parallel" snowpack effect following
700! v.j. linardini reference cited above. note that dtot is
701! combined depth of snowdepth and thickness of first soil layer
702
703 dsoil = -0.5 * zsoil(1)
704
705 if (sneqv == 0.0) then
706
707 ssoil = df1 * (t1 - stc(1)) / dsoil
708
709 else
710
711 dtot = snowh + dsoil
712 frcsno = snowh / dtot
713 frcsoi = dsoil / dtot
714
715! --- ... 1. harmonic mean (series flow)
716
717! df1 = (sncond*df1) / (frcsoi*sncond + frcsno*df1)
718! df1h = (sncond*df1) / (frcsoi*sncond + frcsno*df1)
719
720! --- ... 2. arithmetic mean (parallel flow)
721
722! df1 = frcsno*sncond + frcsoi*df1
723 df1a = frcsno*sncond + frcsoi*df1
724
725! --- ... 3. geometric mean (intermediate between harmonic and arithmetic mean)
726
727! df1 = (sncond**frcsno) * (df1**frcsoi)
728! df1 = df1h*sncovr + df1a*(1.0-sncovr)
729! df1 = df1h*sncovr + df1 *(1.0-sncovr)
730 df1 = df1a*sncovr + df1 *(1.0-sncovr)
731
735
736 ssoil = df1 * (t1 - stc(1)) / dtot
737
738 endif ! end if_sneqv_block
739
742
743! if (couple == 0) then ! uncoupled mode
744 if (sncovr > 0.0) then
745
746 call snowz0
747! --- inputs: !
748! ( sncovr, !
749! --- input/outputs: !
750! z0 ) !
751
752 endif
753! endif
754
757
758 t2v = sfctmp * (1.0 + 0.61*q2)
759
760! --- ... next call routine sfcdif to calculate the sfc exchange coef (ch)
761! for heat and moisture.
762! note - comment out call sfcdif, if sfcdif already called in calling
763! program (such as in coupled atmospheric model).
764! - do not call sfcdif until after above call to redprm, in case
765! alternative values of roughness length (z0) and zilintinkevich
766! coef (czil) are set there via namelist i/o.
767! - routine sfcdif returns a ch that represents the wind spd times
768! the "original" nondimensional "ch" typical in literature. hence
769! the ch returned from sfcdif has units of m/s. the important
770! companion coefficient of ch, carried here as "rch", is the ch
771! from sfcdif times air density and parameter "cp". "rch" is
772! computed in "call penman". rch rather than ch is the coeff
773! usually invoked later in eqns.
774! - sfcdif also returns the surface exchange coefficient for momentum,
775! cm, also known as the surface drage coefficient, but cm is not
776! used here.
777
778! --- ... key required radiation term is the total downward radiation
779! (fdown) = net solar (swnet) + downward longwave (lwdn),
780! for use in penman ep calculation (penman) and other surface
781! energy budget calcuations. also need downward solar (swdn)
782! for canopy resistance routine (canres).
783! note - fdown, swdn are derived differently in the uncoupled and
784! coupled modes.
785
789
790 if (couple == 0) then !......uncoupled mode
791
792! --- ... uncoupled mode:
793! compute surface exchange coefficients
794
795 t1v = t1 * (1.0 + 0.61 * q2)
796 th2v = th2 * (1.0 + 0.61 * q2)
797
798 call sfcdif
799! --- inputs: !
800! ( zlvl, z0, t1v, th2v, sfcspd, czil, !
801! --- input/outputs: !
802! cm, ch ) !
803
804! swnet = net solar radiation into the ground (w/m2; dn-up) from input
805! fdown = net solar + downward lw flux at sfc (w/m2)
806
807 fdown = swnet + lwdn
808
809 else !......coupled mode
810
811! --- ... coupled mode (couple .ne. 0):
812! surface exchange coefficients computed externally and passed in,
813! hence subroutine sfcdif not called.
814
815! swnet = net solar radiation into the ground (w/m2; dn-up) from input
816! fdown = net solar + downward lw flux at sfc (w/m2)
817
818 fdown = swnet + lwdn
819
820 endif ! end if_couple_block
821
825
826 call penman
827! --- inputs: !
828! ( sfctmp, sfcprs, sfcems, ch, t2v, th2, prcp, fdown, !
829! ssoil, q2, q2sat, dqsdt2, snowng, frzgra, !
830! --- outputs: !
831! t24, etp, rch, epsca, rr, flx2 ) !
832
835
836 if (shdfac > 0.) then
837
838! --- ... frozen ground extension: total soil water "smc" was replaced
839! by unfrozen soil water "sh2o" in call to canres below
840
841 call canres
842! --- inputs: !
843! ( nsoil, nroot, swdn, ch, q2, q2sat, dqsdt2, sfctmp, !
844! sfcprs, sfcems, sh2o, smcwlt, smcref, zsoil, rsmin, !
845! rsmax, topt, rgl, hs, xlai, !
846! --- outputs: !
847! rc, pc, rcs, rct, rcq, rcsoil ) !
848
849 endif
850
853
854 esnow = 0.0
855
856 if (sneqv .eq. 0.0) then
860 call nopac
861! --- inputs: !
862! ( nsoil, nroot, etp, prcp, smcmax, smcwlt, smcref, !
863! smcdry, cmcmax, dt, shdfac, sbeta, sfctmp, sfcems, !
864! t24, th2, fdown, epsca, bexp, pc, rch, rr, cfactr, !
865! slope, kdt, frzx, psisat, zsoil, dksat, dwsat, !
866! zbot, ice, rtdis, quartz, fxexp, csoil, lheatstrg, !
867! --- input/outputs: !
868! cmc, t1, stc, sh2o, tbot, !
869! --- outputs: !
870! eta, smc, ssoil, runoff1, runoff2, runoff3, edir, !
871! ec, et, ett, beta, drip, dew, flx1, flx3 ) !
872
873 else
874
876 call snopac
877! --- inputs: !
878! ( nsoil, nroot, etp, prcp, smcmax, smcwlt, smcref, smcdry, !
879! cmcmax, dt, df1, sfcems, sfctmp, t24, th2, fdown, epsca, !
880! bexp, pc, rch, rr, cfactr, slope, kdt, frzx, psisat, !
881! zsoil, dwsat, dksat, zbot, shdfac, ice, rtdis, quartz, !
882! fxexp, csoil, flx2, snowng, lheatstrg, !
883! --- input/outputs: !
884! prcp1, cmc, t1, stc, sncovr, sneqv, sndens, snowh, !
885! sh2o, tbot, beta, !
886! --- outputs: !
887! smc, ssoil, runoff1, runoff2, runoff3, edir, ec, et, !
888! ett, snomlt, drip, dew, flx1, flx3, esnow ) !
889
890! run-total accumulated snow based on snowfall and snowmelt in [m]
891
892 endif
893
894
897
898 sheat = -(ch*cp1*sfcprs) / (rd1*t2v) * (th2 - t1)
899
902! convert eta from kg m-2 s-1 to w m-2
903! eta = eta * lsubc
904! etp = etp * lsubc
905
906 edir = edir * lsubc
907 ec = ec * lsubc
908
909 do k = 1, 4
910 et(k) = et(k) * lsubc
911 enddo
912
913 ett = ett * lsubc
914 esnow = esnow * lsubs
915 etp = etp * ((1.0 - sncovr)*lsubc + sncovr*lsubs)
916
917 if (etp > 0.) then
918 eta = edir + ec + ett + esnow
919 else
920 eta = etp
921 endif
922
923 if (etp == 0.0) then
924 beta = 0.0
925 else
926 beta = eta/etp
927 endif
928
932
933 ssoil = -1.0 * ssoil
934
935 if (ice == 0) then
936
941
942 runoff3 = runoff3 / dt
943 runoff2 = runoff2 + runoff3
944
945 else
946
951
952 runoff1 = snomlt / dt
953 endif
954
957
958 soilm = -1.0 * smc(1) * zsoil(1)
959 do k = 2, nsoil
960 soilm = soilm + smc(k)*(zsoil(k-1) - zsoil(k))
961 enddo
962
963 soilwm = -1.0 * (smcmax - smcwlt) * zsoil(1)
964 soilww = -1.0 * (smc(1) - smcwlt) * zsoil(1)
965 do k = 2, nroot
966 soilwm = soilwm + (smcmax - smcwlt) * (zsoil(k-1) - zsoil(k))
967 soilww = soilww + (smc(k) - smcwlt) * (zsoil(k-1) - zsoil(k))
968 enddo
969
970 soilw = soilww / soilwm
971!
972 return
973
974
975! =================
976 contains
977! =================
978
979!*************************************!
980! section-1 1st level subprograms !
981!*************************************!
982
983!-----------------------------------
986 subroutine alcalc
987!...................................
988! --- inputs:
989! & ( alb, snoalb, shdfac, shdmin, sncovr, tsnow, &
990! --- outputs:
991! & albedo &
992! & )
993
994! ===================================================================== !
995! description: !
996! !
997! subroutine alcalc calculates albedo including snow effect (0 -> 1) !
998! !
999! subprogram called: none !
1000! !
1001! !
1002! ==================== defination of variables ==================== !
1003! !
1004! inputs from calling program: size !
1005! alb - real, snowfree albedo 1 !
1006! snoalb - real, maximum (deep) snow albedo 1 !
1007! shdfac - real, areal fractional coverage of green veg. 1 !
1008! shdmin - real, minimum areal coverage of green veg. 1 !
1009! sncovr - real, fractional snow cover 1 !
1010! tsnow - real, snow surface temperature (k) 1 !
1011! !
1012! outputs to calling program: !
1013! albedo - real, surface albedo including snow effect 1 !
1014! !
1015! ==================== end of description ===================== !
1016!
1017! --- inputs:
1018! real (kind=kind_phys), intent(in) :: alb, snoalb, shdfac, &
1019! & shdmin, sncovr, tsnow
1020
1021! --- outputs:
1022! real (kind=kind_phys), intent(out) :: albedo
1023
1024! --- locals: (none)
1025
1026!
1027!===> ... begin here
1028!
1029! --- ... snoalb is argument representing maximum albedo over deep snow,
1030! as passed into sflx, and adapted from the satellite-based
1031! maximum snow albedo fields provided by d. robinson and g. kukla
1032! (1985, jcam, vol 24, 402-411)
1033
1034! albedo = alb + (1.0-(shdfac-shdmin))*sncovr*(snoalb-alb)
1035 albedo = alb + sncovr*(snoalb - alb)
1036
1037 if (albedo > snoalb) albedo = snoalb
1038
1039! --- ... base formulation (dickinson et al., 1986, cogley et al., 1990)
1040
1041! if (tsnow <= 263.16) then
1042! albedo = snoalb
1043! else
1044! if (tsnow < 273.16) then
1045! tm = 0.1 * (tsnow - 263.16)
1046! albedo = 0.5 * ((0.9 - 0.2*(tm**3)) + (0.8 - 0.16*(tm**3)))
1047! else
1048! albedo = 0.67
1049! endif
1050! endif
1051
1052! --- ... isba formulation (verseghy, 1991; baker et al., 1990)
1053
1054! if (tsnow < 273.16) then
1055! albedo = snoalb - 0.008*dt/86400
1056! else
1057! albedo = (snoalb - 0.5) * exp( -0.24*dt/86400 ) + 0.5
1058! endif
1059
1060!
1061 return
1062!...................................
1063 end subroutine alcalc
1064!-----------------------------------
1065
1066
1067!-----------------------------------
1073 subroutine canres
1074! --- inputs:
1075! & ( nsoil, nroot, swdn, ch, q2, q2sat, dqsdt2, sfctmp, &
1076! & sfcprs, sfcems, sh2o, smcwlt, smcref, zsoil, rsmin, &
1077! & rsmax, topt, rgl, hs, xlai, &
1078! --- outputs:
1079! & rc, pc, rcs, rct, rcq, rcsoil &
1080! & )
1081
1082! ===================================================================== !
1083! description: !
1084! !
1085! subroutine canres calculates canopy resistance which depends on !
1086! incoming solar radiation, air temperature, atmospheric water vapor !
1087! pressure deficit at the lowest model level, and soil moisture !
1088! (preferably unfrozen soil moisture rather than total) !
1089! !
1090! source: jarvis (1976), noilhan and planton (1989, mwr), jacquemin !
1091! and noilhan (1990, blm) !
1092! see also: chen et al (1996, jgr, vol 101(d3), 7251-7268), eqns !
1093! 12-14 and table 2 of sec. 3.1.2 !
1094! !
1095! subprogram called: none !
1096! !
1097! !
1098! ==================== defination of variables ==================== !
1099! !
1100! inputs from calling program: size !
1101! nsoil - integer, no. of soil layers 1 !
1102! nroot - integer, no. of soil layers in root zone (<nsoil) 1 !
1103! swdn - real, incoming solar radiation 1 !
1104! ch - real, sfc exchange coeff for heat and moisture 1 !
1105! q2 - real, air humidity at 1st level above ground 1 !
1106! q2sat - real, sat. air humidity at 1st level abv ground 1 !
1107! dqsdt2 - real, slope of sat. humidity function wrt temp 1 !
1108! sfctmp - real, sfc temperature at 1st level above ground 1 !
1109! sfcprs - real, sfc pressure 1 !
1110! sfcems - real, sfc emissivity for lw radiation 1 !
1111! sh2o - real, volumetric soil moisture nsoil !
1112! smcwlt - real, wilting point 1 !
1113! smcref - real, reference soil moisture 1 !
1114! zsoil - real, soil depth (negative sign, as below grd) nsoil !
1115! rsmin - real, mimimum stomatal resistance 1 !
1116! rsmax - real, maximum stomatal resistance 1 !
1117! topt - real, optimum transpiration air temperature 1 !
1118! rgl - real, canopy resistance func (in solar rad term) 1 !
1119! hs - real, canopy resistance func (vapor deficit term) 1 !
1120! xlai - real, leaf area index 1 !
1121! !
1122! outputs to calling program: !
1123! rc - real, canopy resistance 1 !
1124! pc - real, plant coefficient 1 !
1125! rcs - real, incoming solar rc factor 1 !
1126! rct - real, air temp rc factor 1 !
1127! rcq - real, atoms vapor press deficit rc factor 1 !
1128! rcsoil - real, soil moisture rc factor 1 !
1129! !
1130! ==================== end of description ===================== !
1131!
1132! --- inputs:
1133! integer, intent(in) :: nsoil, nroot
1134
1135! real (kind=kind_phys), intent(in) :: swdn, ch, q2, q2sat, &
1136! & dqsdt2, sfctmp, sfcprs, sfcems, smcwlt, smcref, rsmin, &
1137! & rsmax, topt, rgl, hs, xlai, sh2o(nsoil), zsoil(nsoil)
1138
1139! --- outputs:
1140! real (kind=kind_phys), intent(out) :: rc, pc, rcs, rct, rcq, &
1141! & rcsoil
1142
1143! --- locals:
1144 real (kind=kind_phys) :: delta, ff, gx, rr, part(nsold)
1145
1146 integer :: k
1147
1148!
1149!===> ... begin here
1150!
1151! --- ... initialize canopy resistance multiplier terms.
1152
1153 rcs = 0.0
1154 rct = 0.0
1155 rcq = 0.0
1156 rcsoil = 0.0
1157 rc = 0.0
1158
1159! --- ... contribution due to incoming solar radiation
1160
1161 ff = 0.55 * 2.0 * swdn / (rgl*xlai)
1162 rcs = (ff + rsmin/rsmax) / (1.0 + ff)
1163 rcs = max( rcs, 0.0001 )
1164
1165! --- ... contribution due to air temperature at first model level above ground
1166! rct expression from noilhan and planton (1989, mwr).
1167
1168 rct = 1.0 - 0.0016 * (topt - sfctmp)**2.0
1169 rct = max( rct, 0.0001 )
1170
1171! --- ... contribution due to vapor pressure deficit at first model level.
1172! rcq expression from ssib
1173
1174 rcq = 1.0 / (1.0 + hs*(q2sat-q2))
1175 rcq = max( rcq, 0.01 )
1176
1177! --- ... contribution due to soil moisture availability.
1178! determine contribution from each soil layer, then add them up.
1179
1180 gx = (sh2o(1) - smcwlt) / (smcref - smcwlt)
1181 gx = max( 0.0, min( 1.0, gx ) )
1182
1183! --- ... use soil depth as weighting factor
1184 part(1) = (zsoil(1)/zsoil(nroot)) * gx
1185
1186! --- ... use root distribution as weighting factor
1187! part(1) = rtdis(1) * gx
1188
1189 do k = 2, nroot
1190
1191 gx = (sh2o(k) - smcwlt) / (smcref - smcwlt)
1192 gx = max( 0.0, min( 1.0, gx ) )
1193
1194! --- ... use soil depth as weighting factor
1195 part(k) = ((zsoil(k) - zsoil(k-1)) / zsoil(nroot)) * gx
1196
1197! --- ... use root distribution as weighting factor
1198! part(k) = rtdis(k) * gx
1199
1200 enddo
1201
1202 do k = 1, nroot
1203 rcsoil = rcsoil + part(k)
1204 enddo
1205 rcsoil = max( rcsoil, 0.0001 )
1206
1207! --- ... determine canopy resistance due to all factors. convert canopy
1208! resistance (rc) to plant coefficient (pc) to be used with
1209! potential evap in determining actual evap. pc is determined by:
1210! pc * linerized penman potential evap = penman-monteith actual
1211! evaporation (containing rc term).
1212
1213 rc = rsmin / (xlai*rcs*rct*rcq*rcsoil)
1214 rr = (4.0*sfcems*sigma1*rd1/cp1) * (sfctmp**4.0)/(sfcprs*ch) + 1.0
1215 delta = (lsubc/cp1) * dqsdt2
1216
1217 pc = (rr + delta) / (rr*(1.0 + rc*ch) + delta)
1218!
1219 return
1220!...................................
1221 end subroutine canres
1222!-----------------------------------
1223
1224
1225!-----------------------------------
1228 subroutine csnow
1229!...................................
1230! --- inputs:
1231! & ( sndens, &
1232! --- outputs:
1233! & sncond &
1234! & )
1235
1236! ===================================================================== !
1237! description: !
1238! !
1239! subroutine csnow calculates snow termal conductivity !
1240! !
1241! subprogram called: none !
1242! !
1243! ==================== defination of variables ==================== !
1244! !
1245! inputs from the calling program: size !
1246! sndens - real, snow density 1 !
1247! !
1248! outputs to the calling program: !
1249! sncond - real, snow termal conductivity 1 !
1250! !
1251! ==================== end of description ===================== !
1252!
1253! --- constant parameters:
1254 real (kind=kind_phys), parameter :: unit = 0.11631
1255
1256! --- inputs:
1257! real (kind=kind_phys), intent(in) :: sndens
1258
1259! --- outputs:
1260! real (kind=kind_phys), intent(out) :: sncond
1261
1262! --- locals:
1263 real (kind=kind_phys) :: c
1264
1265!
1266!===> ... begin here
1267!
1268! --- ... sncond in units of cal/(cm*hr*c), returned in w/(m*c)
1269! basic version is dyachkova equation (1960), for range 0.1-0.4
1270
1271 c = 0.328 * 10**(2.25*sndens)
1272 sncond = unit * c
1273
1274! --- ... de vaux equation (1933), in range 0.1-0.6
1275
1276! sncond = 0.0293 * (1.0 + 100.0*sndens**2)
1277
1278! --- ... e. andersen from flerchinger
1279
1280! sncond = 0.021 + 2.51 * sndens**2
1281!
1282 return
1283!...................................
1284 end subroutine csnow
1285!-----------------------------------
1286
1287
1288!-----------------------------------
1293 subroutine nopac
1294!...................................
1295! --- inputs:
1296! & ( nsoil, nroot, etp, prcp, smcmax, smcwlt, smcref, &
1297! & smcdry, cmcmax, dt, shdfac, sbeta, sfctmp, sfcems, &
1298! & t24, th2, fdown, epsca, bexp, pc, rch, rr, cfactr, &
1299! & slope, kdt, frzx, psisat, zsoil, dksat, dwsat, &
1300! & zbot, ice, rtdis, quartz, fxexp, csoil, lheatstrg, &
1301! --- input/outputs:
1302! & cmc, t1, stc, sh2o, tbot, &
1303! --- outputs:
1304! & eta, smc, ssoil, runoff1, runoff2, runoff3, edir, &
1305! & ec, et, ett, beta, drip, dew, flx1, flx3 &
1306! & )
1307
1308! ===================================================================== !
1309! description: !
1310! !
1311! subroutine nopac calculates soil moisture and heat flux values and !
1312! update soil moisture content and soil heat content values for the !
1313! case when no snow pack is present. !
1314! !
1315! !
1316! subprograms called: evapo, smflx, tdfcnd, shflx !
1317! !
1318! ==================== defination of variables ==================== !
1319! !
1320! inputs from calling program: size !
1321! nsoil - integer, number of soil layers 1 !
1322! nroot - integer, number of root layers 1 !
1323! etp - real, potential evaporation 1 !
1324! prcp - real, precip rate 1 !
1325! smcmax - real, porosity (sat val of soil mois) 1 !
1326! smcwlt - real, wilting point 1 !
1327! smcref - real, soil mois threshold 1 !
1328! smcdry - real, dry soil mois threshold 1 !
1329! cmcmax - real, maximum canopy water parameters 1 !
1330! dt - real, time step 1 !
1331! shdfac - real, aeral coverage of green veg 1 !
1332! sbeta - real, param to cal veg effect on soil heat flux 1 !
1333! sfctmp - real, air temp at height zlvl abv ground 1 !
1334! sfcems - real, sfc lw emissivity 1 !
1335! t24 - real, sfctmp**4 1 !
1336! th2 - real, air potential temp at zlvl abv grnd 1 !
1337! fdown - real, net solar + downward lw flux at sfc 1 !
1338! epsca - real, 1 !
1339! bexp - real, soil type "b" parameter 1 !
1340! pc - real, plant coeff 1 !
1341! rch - real, companion coefficient of ch 1 !
1342! rr - real, 1 !
1343! cfactr - real, canopy water parameters 1 !
1344! slope - real, linear reservoir coefficient 1 !
1345! kdt - real, 1 !
1346! frzx - real, frozen ground parameter 1 !
1347! psisat - real, saturated soil potential 1 !
1348! zsoil - real, soil layer depth below ground (negative) nsoil !
1349! dksat - real, saturated soil hydraulic conductivity 1 !
1350! dwsat - real, saturated soil diffusivity 1 !
1351! zbot - real, specify depth of lower bd soil 1 !
1352! ice - integer, sea-ice flag (=1: sea-ice, =0: land) 1 !
1353! rtdis - real, root distribution nsoil !
1354! quartz - real, soil quartz content 1 !
1355! fxexp - real, bare soil evaporation exponent 1 !
1356! csoil - real, soil heat capacity 1 !
1357! lheatstrg- logical, flag for canopy heat storage 1 !
1358! parameterization !
1359! !
1360! input/outputs from and to the calling program: !
1361! cmc - real, canopy moisture content 1 !
1362! t1 - real, ground/canopy/snowpack eff skin temp 1 !
1363! stc - real, soil temp nsoil !
1364! sh2o - real, unfrozen soil moisture nsoil !
1365! tbot - real, bottom soil temp 1 !
1366! !
1367! outputs to the calling program: !
1368! eta - real, downward latent heat flux 1 !
1369! smc - real, total soil moisture nsoil !
1370! ssoil - real, upward soil heat flux 1 !
1371! runoff1 - real, surface runoff not infiltrating sfc 1 !
1372! runoff2 - real, sub surface runoff (baseflow) 1 !
1373! runoff3 - real, excess of porosity 1 !
1374! edir - real, direct soil evaporation 1 !
1375! ec - real, canopy water evaporation 1 !
1376! et - real, plant transpiration nsoil !
1377! ett - real, total plant transpiration 1 !
1378! beta - real, ratio of actual/potential evap 1 !
1379! drip - real, through-fall of precip and/or dew 1 !
1380! dew - real, dewfall (or frostfall) 1 !
1381! flx1 - real, precip-snow sfc flux 1 !
1382! flx3 - real, phase-change heat flux from snowmelt 1 !
1383! !
1384! ==================== end of description ===================== !
1385!
1386! --- inputs:
1387! integer, intent(in) :: nsoil, nroot, ice
1388
1389! real (kind=kind_phys), intent(in) :: etp, prcp, smcmax, &
1390! & smcwlt, smcref, smcdry, cmcmax, dt, shdfac, sbeta, &
1391! & sfctmp, sfcems, t24, th2, fdown, epsca, bexp, pc, &
1392! & rch, rr, cfactr, slope, kdt, frzx, psisat, &
1393! & zsoil(nsoil), dksat, dwsat, zbot, rtdis(nsoil), &
1394! & quartz, fxexp, csoil
1395
1396! logical, intent(in) :: lheatstrg
1397
1398! --- input/outputs:
1399! real (kind=kind_phys), intent(inout) :: cmc, t1, stc(nsoil), &
1400! & sh2o(nsoil), tbot
1401
1402! --- outputs:
1403! real (kind=kind_phys), intent(out) :: eta, smc(nsoil), ssoil, &
1404! & runoff1, runoff2, runoff3, edir, ec, et(nsoil), ett, &
1405! & beta, drip, dew, flx1, flx3
1406
1407! --- locals:
1408 real (kind=kind_phys) :: df1, eta1, etp1, prcp1, yy, yynum, &
1409 & zz1, ec1, edir1, et1(nsoil), ett1
1410
1411 integer :: k
1412
1413!
1414!===> ... begin here
1415!
1416! --- ... convert etp from kg m-2 s-1 to ms-1 and initialize dew.
1417
1418 prcp1= prcp * 0.001
1419 etp1 = etp * 0.001
1420 dew = 0.0
1421 edir = 0.0
1422 edir1= 0.0
1423 ec = 0.0
1424 ec1 = 0.0
1425
1426 do k = 1, nsoil
1427 et(k) = 0.0
1428 et1(k) = 0.0
1429 enddo
1430
1431 ett = 0.0
1432 ett1 = 0.0
1433
1434 if (etp > 0.0) then
1435
1436! --- ... convert prcp from 'kg m-2 s-1' to 'm s-1'.
1437
1438 call evapo &
1439! --- inputs:
1440 & ( nsoil, nroot, cmc, cmcmax, etp1, dt, zsoil, &
1441 & sh2o, smcmax, smcwlt, smcref, smcdry, pc, &
1442 & shdfac, cfactr, rtdis, fxexp, &
1443! --- outputs:
1444 & eta1, edir1, ec1, et1, ett1 &
1445 & )
1446
1447 call smflx &
1448! --- inputs:
1449 & ( nsoil, dt, kdt, smcmax, smcwlt, cmcmax, prcp1, &
1450 & zsoil, slope, frzx, bexp, dksat, dwsat, shdfac, &
1451 & edir1, ec1, et1, &
1452! --- input/outputs:
1453 & cmc, sh2o, smc, &
1454! --- outputs:
1455 & runoff1, runoff2, runoff3, drip &
1456 & )
1457
1458 else
1459
1460! --- ... if etp < 0, assume dew forms (transform etp1 into dew and
1461! reinitialize etp1 to zero).
1462
1463 eta1 = 0.0
1464 dew = -etp1
1465
1466! --- ... convert prcp from 'kg m-2 s-1' to 'm s-1' and add dew amount.
1467
1468 prcp1 = prcp1 + dew
1469
1470 call smflx &
1471! --- inputs:
1472 & ( nsoil, dt, kdt, smcmax, smcwlt, cmcmax, prcp1, &
1473 & zsoil, slope, frzx, bexp, dksat, dwsat, shdfac, &
1474 & edir1, ec1, et1, &
1475! --- input/outputs:
1476 & cmc, sh2o, smc, &
1477! --- outputs:
1478 & runoff1, runoff2, runoff3, drip &
1479 & )
1480
1481 endif ! end if_etp_block
1482
1483! --- ... convert modeled evapotranspiration fm m s-1 to kg m-2 s-1
1484
1485 eta = eta1 * 1000.0
1486 edir = edir1 * 1000.0
1487 ec = ec1 * 1000.0
1488
1489 do k = 1, nsoil
1490 et(k) = et1(k) * 1000.0
1491 enddo
1492
1493 ett = ett1 * 1000.0
1494
1495! --- ... based on etp and e values, determine beta
1496
1497 if ( etp <= 0.0 ) then
1498 beta = 0.0
1499 if ( etp < 0.0 ) then
1500 beta = 1.0
1501 endif
1502 else
1503 beta = eta / etp
1504 endif
1505
1506! --- ... get soil thermal diffuxivity/conductivity for top soil lyr,
1507! calc. adjusted top lyr soil temp and adjusted soil flux, then
1508! call shflx to compute/update soil heat flux and soil temps.
1509
1510 call tdfcnd &
1511! --- inputs:
1512 & ( smc(1), quartz, smcmax, sh2o(1), &
1513! --- outputs:
1514 & df1 &
1515 & )
1516! if(ivegsrc == 1) then
1517!urban
1518! if ( vegtyp == 13 ) df1=3.24
1519! endif
1520
1521! --- ... vegetation greenness fraction reduction in subsurface heat
1522! flux via reduction factor, which is convenient to apply here
1523! to thermal diffusivity that is later used in hrt to compute
1524! sub sfc heat flux (see additional comments on veg effect
1525! sub-sfc heat flx in routine sflx)
1526!wz only urban for igbp type
1527!
1528!jhan urban canopy heat storage effect is included in pbl scheme
1529!
1530 if((.not.lheatstrg) .and. &
1531 & (ivegsrc == 1 .and. vegtyp == 13)) then
1532 df1 = 3.24*(1.-shdfac) + shdfac*df1*exp(sbeta*shdfac)
1533 else
1534 df1 = df1 * exp( sbeta*shdfac )
1535 endif
1536
1537! --- ... compute intermediate terms passed to routine hrt (via routine
1538! shflx below) for use in computing subsurface heat flux in hrt
1539
1540 yynum = fdown - sfcems*sigma1*t24
1541 yy = sfctmp + (yynum/rch + th2 - sfctmp - beta*epsca)/rr
1542 zz1 = df1/(-0.5*zsoil(1)*rch*rr) + 1.0
1543
1544 call shflx &
1545! --- inputs:
1546 & ( nsoil, smc, smcmax, dt, yy, zz1, zsoil, zbot, &
1547 & psisat, bexp, df1, ice, quartz, csoil, vegtyp, &
1548 & shdfac, lheatstrg, &
1549! --- input/outputs:
1550 & stc, t1, tbot, sh2o, &
1551! --- outputs:
1552 & ssoil &
1553 & )
1554
1555! --- ... set flx1 and flx3 (snopack phase change heat fluxes) to zero since
1556! they are not used here in snopac. flx2 (freezing rain heat flux)
1557! was similarly initialized in the penman routine.
1558
1559 flx1 = 0.0
1560 flx3 = 0.0
1561!
1562 return
1563!...................................
1564 end subroutine nopac
1565!-----------------------------------
1566
1567
1568!-----------------------------------
1573 subroutine penman
1574!...................................
1575! --- inputs:
1576! & ( sfctmp, sfcprs, sfcems, ch, t2v, th2, prcp, fdown, &
1577! & ssoil, q2, q2sat, dqsdt2, snowng, frzgra, &
1578! --- outputs:
1579! & t24, etp, rch, epsca, rr, flx2 &
1580! & )
1581
1582! ===================================================================== !
1583! description: !
1584! !
1585! subroutine penman calculates potential evaporation for the current !
1586! point. various partial sums/products are also calculated and passed !
1587! back to the calling routine for later use. !
1588! !
1589! !
1590! subprogram called: none !
1591! !
1592! ==================== defination of variables ==================== !
1593! !
1594! inputs: size !
1595! sfctmp - real, sfc temperature at 1st level above ground 1 !
1596! sfcprs - real, sfc pressure 1 !
1597! sfcems - real, sfc emissivity for lw radiation 1 !
1598! ch - real, sfc exchange coeff for heat & moisture 1 !
1599! t2v - real, sfc virtual temperature 1 !
1600! th2 - real, air potential temp at zlvl abv grnd 1 !
1601! prcp - real, precip rate 1 !
1602! fdown - real, net solar + downward lw flux at sfc 1 !
1603! ssoil - real, upward soil heat flux 1 !
1604! q2 - real, mixing ratio at hght zlvl abv ground 1 !
1605! q2sat - real, sat mixing ratio at zlvl abv ground 1 !
1606! dqsdt2 - real, slope of sat specific humidity curve 1 !
1607! snowng - logical, snow flag 1 !
1608! frzgra - logical, freezing rain flag 1 !
1609! !
1610! outputs: !
1611! t24 - real, sfctmp**4 1 !
1612! etp - real, potential evaporation 1 !
1613! rch - real, companion coefficient of ch 1 !
1614! epsca - real, 1 !
1615! rr - real, 1 !
1616! flx2 - real, freezing rain latent heat flux 1 !
1617! !
1618! ==================== end of description ===================== !
1619!
1620! --- inputs:
1621! real (kind=kind_phys), intent(in) :: sfctmp, sfcprs, sfcems, &
1622! & ch, t2v, th2, prcp, fdown, ssoil, q2, q2sat, dqsdt2
1623
1624! logical, intent(in) :: snowng, frzgra
1625
1626! --- outputs:
1627! real (kind=kind_phys), intent(out) :: t24, etp, rch, epsca, &
1628! & rr, flx2
1629
1630! --- locals:
1631 real (kind=kind_phys) :: a, delta, fnet, rad, rho
1632
1633!
1634!===> ... begin here
1635!
1636 flx2 = 0.0
1637
1638! --- ... prepare partial quantities for penman equation.
1639
1640 delta = elcp * dqsdt2
1641 t24 = sfctmp * sfctmp * sfctmp * sfctmp
1642 rr = t24 * 6.48e-8 / (sfcprs*ch) + 1.0
1643 rho = sfcprs / (rd1*t2v)
1644 rch = rho * cp * ch
1645
1646! --- ... adjust the partial sums / products with the latent heat
1647! effects caused by falling precipitation.
1648
1649 if (.not. snowng) then
1650 if (prcp > 0.0) rr = rr + cph2o1*prcp/rch
1651 else
1652! ---- ... fractional snowfall/rainfall
1653 rr = rr + (cpice*ffrozp+cph2o1*(1.-ffrozp)) &
1654 & *prcp/rch
1655 endif
1656
1657 fnet = fdown - sfcems*sigma1*t24 - ssoil
1658
1659! --- ... include the latent heat effects of frzng rain converting to ice
1660! on impact in the calculation of flx2 and fnet.
1661
1662 if (frzgra) then
1663 flx2 = -lsubf * prcp
1664 fnet = fnet - flx2
1665 endif
1666
1667! --- ... finish penman equation calculations.
1668
1669 rad = fnet/rch + th2 - sfctmp
1670 a = elcp * (q2sat - q2)
1671 epsca = (a*rr + rad*delta) / (delta + rr)
1672 etp = epsca * rch / lsubc
1673!
1674 return
1675!...................................
1676 end subroutine penman
1677!-----------------------------------
1678
1679
1680!-----------------------------------
1685 subroutine redprm(errmsg, errflg)
1686!...................................
1687! --- inputs:
1688! & ( nsoil, vegtyp, soiltyp, slopetyp, sldpth, zsoil, &
1689! --- outputs:
1690! & cfactr, cmcmax, rsmin, rsmax, topt, refkdt, kdt, &
1691! & sbeta, shdfac, rgl, hs, zbot, frzx, psisat, slope, &
1692! & snup, salp, bexp, dksat, dwsat, smcmax, smcwlt, &
1693! & smcref, smcdry, f1, quartz, fxexp, rtdis, nroot, &
1694! & z0, czil, xlai, csoil &
1695! & )
1696
1697! ===================================================================== !
1698! description: !
1699! !
1700! subroutine redprm internally sets(default valuess), or optionally !
1701! read-in via namelist i/o, all soil and vegetation parameters !
1702! required for the execusion of the noah lsm. !
1703! !
1704! optional non-default parameters can be read in, accommodating up to !
1705! 30 soil, veg, or slope classes, if the default max number of soil, !
1706! veg, and/or slope types is reset. !
1707! !
1708! future upgrades of routine redprm must expand to incorporate some !
1709! of the empirical parameters of the frozen soil and snowpack physics !
1710! (such as in routines frh2o, snowpack, and snow_new) not yet set in !
1711! this redprm routine, but rather set in lower level subroutines. !
1712! !
1713! all soil, veg, slope, and universal parameters values are defined !
1714! externally (in subroutine "set_soilveg.f") and then accessed via !
1715! "use namelist_soilveg" (below) and then set here. !
1716! !
1717! soil types zobler (1986) cosby et al (1984) (quartz cont.(1)) !
1718! 1 coarse loamy sand (0.82) !
1719! 2 medium silty clay loam (0.10) !
1720! 3 fine light clay (0.25) !
1721! 4 coarse-medium sandy loam (0.60) !
1722! 5 coarse-fine sandy clay (0.52) !
1723! 6 medium-fine clay loam (0.35) !
1724! 7 coarse-med-fine sandy clay loam (0.60) !
1725! 8 organic loam (0.40) !
1726! 9 glacial land ice loamy sand (na using 0.82)!
1727! 13: <old>- glacial land ice -<old> !
1728! 13: glacial-ice (no longer use these parameters), now !
1729! treated as ice-only surface and sub-surface !
1730! (in subroutine hrtice) !
1731! upgraded to statsgo (19-type)
1732! 1: sand
1733! 2: loamy sand
1734! 3: sandy loam
1735! 4: silt loam
1736! 5: silt
1737! 6:loam
1738! 7:sandy clay loam
1739! 8:silty clay loam
1740! 9:clay loam
1741! 10:sandy clay
1742! 11: silty clay
1743! 12: clay
1744! 13: organic material
1745! 14: water
1746! 15: bedrock
1747! 16: other (land-ice)
1748! 17: playa
1749! 18: lava
1750! 19: white sand
1751! !
1752! ssib vegetation types (dorman and sellers, 1989; jam) !
1753! 1: broadleaf-evergreen trees (tropical forest) !
1754! 2: broadleaf-deciduous trees !
1755! 3: broadleaf and needleleaf trees (mixed forest) !
1756! 4: needleleaf-evergreen trees !
1757! 5: needleleaf-deciduous trees (larch) !
1758! 6: broadleaf trees with groundcover (savanna) !
1759! 7: groundcover only (perennial) !
1760! 8: broadleaf shrubs with perennial groundcover !
1761! 9: broadleaf shrubs with bare soil !
1762! 10: dwarf trees and shrubs with groundcover (tundra) !
1763! 11: bare soil !
1764! 12: cultivations (the same parameters as for type 7) !
1765! 13: <old>- glacial (the same parameters as for type 11) -<old> !
1766! 13: glacial-ice (no longer use these parameters), now treated as !
1767! ice-only surface and sub-surface (in subroutine hrtice) !
1768! upgraded to IGBP (20-type)
1769! 1:Evergreen Needleleaf Forest
1770! 2:Evergreen Broadleaf Forest
1771! 3:Deciduous Needleleaf Forest
1772! 4:Deciduous Broadleaf Forest
1773! 5:Mixed Forests
1774! 6:Closed Shrublands
1775! 7:Open Shrublands
1776! 8:Woody Savannas
1777! 9:Savannas
1778! 10:Grasslands
1779! 11:Permanent wetlands
1780! 12:Croplands
1781! 13:Urban and Built-Up
1782! 14:Cropland/natural vegetation mosaic
1783! 15:Snow and Ice
1784! 16:Barren or Sparsely Vegetated
1785! 17:Water
1786! 18:Wooded Tundra
1787! 19:Mixed Tundra
1788! 20:Bare Ground Tundra
1789! !
1790! slopetyp is to estimate linear reservoir coefficient slope to the !
1791! baseflow runoff out of the bottom layer. lowest class (slopetyp=0) !
1792! means highest slope parameter = 1. !
1793! !
1794! slope class percent slope !
1795! 1 0-8 !
1796! 2 8-30 !
1797! 3 > 30 !
1798! 4 0-30 !
1799! 5 0-8 & > 30 !
1800! 6 8-30 & > 30 !
1801! 7 0-8, 8-30, > 30 !
1802! 9 glacial ice !
1803! blank ocean/sea !
1804! !
1805! note: class 9 from zobler file should be replaced by 8 and 'blank' 9 !
1806! !
1807! !
1808! subprogram called: none !
1809! !
1810! ==================== defination of variables ==================== !
1811! !
1812! inputs from calling program: size !
1813! nsoil - integer, number of soil layers 1 !
1814! vegtyp - integer, vegetation type (integer index) 1 !
1815! soiltyp - integer, soil type (integer index) 1 !
1816! slopetyp - integer, class of sfc slope (integer index) 1 !
1817! sldpth - integer, thickness of each soil layer (m) nsoil !
1818! zsoil - integer, soil depth (negative sign) (m) nsoil !
1819! !
1820! outputs to the calling program: !
1821! cfactr - real, canopy water parameters 1 !
1822! cmcmax - real, maximum canopy water parameters 1 !
1823! rsmin - real, mimimum stomatal resistance 1 !
1824! rsmax - real, maximum stomatal resistance 1 !
1825! topt - real, optimum transpiration air temperature 1 !
1826! refkdt - real, =2.e-6 the sat. dk. val for soil type 2 1 !
1827! kdt - real, 1 !
1828! sbeta - real, param to cal veg effect on soil heat flux 1 !
1829! shdfac - real, vegetation greenness fraction 1 !
1830! rgl - real, canopy resistance func (in solar rad term) 1 !
1831! hs - real, canopy resistance func (vapor deficit term) 1 !
1832! zbot - real, specify depth of lower bd soil temp (m) 1 !
1833! frzx - real, frozen ground parameter, ice content 1 !
1834! threshold above which frozen soil is impermeable !
1835! psisat - real, saturated soil potential 1 !
1836! slope - real, linear reservoir coefficient 1 !
1837! snup - real, threshold snow depth (water equi m) 1 !
1838! salp - real, snow cover shape parameter 1 !
1839! from anderson's hydro-17 best fit salp = 2.6 !
1840! bexp - real, the 'b' parameter 1 !
1841! dksat - real, saturated soil hydraulic conductivity 1 !
1842! dwsat - real, saturated soil diffusivity 1 !
1843! smcmax - real, max soil moisture content (porosity) 1 !
1844! smcwlt - real, wilting pt soil moisture contents 1 !
1845! smcref - real, reference soil moisture (onset stress) 1 !
1846! smcdry - real, air dry soil moist content limits 1 !
1847! f1 - real, used to comp soil diffusivity/conductivity 1 !
1848! quartz - real, soil quartz content 1 !
1849! fxexp - real, bare soil evaporation exponent 1 !
1850! rtdis - real, root distribution nsoil !
1851! nroot - integer, number of root layers 1 !
1852! z0 - real, roughness length (m) 1 !
1853! czil - real, param to cal roughness length of heat 1 !
1854! xlai - real, leaf area index 1 !
1855! csoil - real, soil heat capacity (j m-3 k-1) 1 !
1856! !
1857! ==================== end of description ===================== !
1858!
1860
1861! --- input:
1862! integer, intent(in) :: nsoil, vegtyp, soiltyp, slopetyp
1863
1864! real (kind=kind_phys), intent(in) :: sldpth(nsoil), zsoil(nsoil)
1865
1866! --- outputs:
1867! real (kind=kind_phys), intent(out) :: cfactr, cmcmax, rsmin, &
1868! & rsmax, topt, refkdt, kdt, sbeta, shdfac, rgl, hs, zbot, &
1869! & frzx, psisat, slope, snup, salp, bexp, dksat, dwsat, &
1870! & smcmax, smcwlt, smcref, smcdry, f1, quartz, fxexp, z0, &
1871! & czil, xlai, csoil, rtdis(nsoil)
1872 character(len=*), intent(out) :: errmsg
1873 integer, intent(out) :: errflg
1874! integer, intent(out) :: nroot
1875
1876! --- locals:
1877 real (kind=kind_phys) :: frzfact, frzk, refdk
1878
1879 integer :: i
1880
1881!
1882!===> ... begin here
1883!
1884! Initialize CCPP error-handling
1885 errflg = 0
1886 errmsg = ''
1887
1888 if (soiltyp > defined_soil) then
1889 write(*,*) 'warning: too many soil types,soiltyp=',soiltyp, &
1890 & 'defined_soil=',defined_soil
1891 errflg = 1
1892 errmsg = 'ERROR(sflx.f): too many soil types'
1893 return
1894 endif
1895
1896 if (vegtyp > defined_veg) then
1897 write(*,*) 'warning: too many veg types'
1898 errflg = 1
1899 errmsg = 'ERROR(sflx.f): too many veg types'
1900 return
1901 endif
1902
1903 if (slopetyp > defined_slope) then
1904 write(*,*) 'warning: too many slope types'
1905 errflg = 1
1906 errmsg = 'ERROR(sflx.f): too many slope types'
1907 return
1908 endif
1909
1910! --- ... set-up universal parameters (not dependent on soiltyp, vegtyp
1911! or slopetyp)
1912
1913 zbot = zbot_data
1914 salp = salp_data
1915 cfactr = cfactr_data
1916 cmcmax = cmcmax_data
1917 sbeta = sbeta_data
1918 rsmax = rsmax_data
1919 topt = topt_data
1920 refdk = refdk_data
1921 frzk = frzk_data
1922 fxexp = fxexp_data
1923 refkdt = refkdt_data
1924 czil = czil_data
1925 csoil = csoil_data
1926
1927! --- ... set-up soil parameters
1928
1929 bexp = bb(soiltyp)
1930 dksat = satdk(soiltyp)
1931 dwsat = satdw(soiltyp)
1932 f1 = f11(soiltyp)
1933 kdt = refkdt * dksat / refdk
1934
1935 psisat = satpsi(soiltyp)
1936 quartz = qtz(soiltyp)
1937 smcdry = drysmc(soiltyp)
1938 smcmax = maxsmc(soiltyp)
1939 smcref = refsmc(soiltyp)
1940 smcwlt = wltsmc(soiltyp)
1941
1942 frzfact = (smcmax / smcref) * (0.412 / 0.468)
1943
1944! --- ... to adjust frzk parameter to actual soil type: frzk * frzfact
1945
1946 frzx = frzk * frzfact
1947
1948! --- ... set-up vegetation parameters
1949
1950 nroot = nroot_data(vegtyp)
1951 snup = snupx(vegtyp)
1952 rsmin = rsmtbl(vegtyp)
1953
1954 rgl = rgltbl(vegtyp)
1955 hs = hstbl(vegtyp)
1956! roughness lengthe is defined in sfcsub
1957! z0 = z0_data(vegtyp)
1958 xlai= lai_data(vegtyp)
1959
1960 if (vegtyp == bare) shdfac = 0.0
1961
1962 if (nroot > nsoil) then
1963 write(*,*) 'warning: too many root layers'
1964 errflg = 1
1965 errmsg = 'ERROR(sflx.f): too many root layers'
1966 return
1967 endif
1968
1969! --- ... calculate root distribution. present version assumes uniform
1970! distribution based on soil layer depths.
1971
1972 do i = 1, nroot
1973 rtdis(i) = -sldpth(i) / zsoil(nroot)
1974 enddo
1975
1976! --- ... set-up slope parameter
1977
1978 slope = slope_data(slopetyp)
1979!
1980 return
1981!...................................
1982 end subroutine redprm
1983!-----------------------------------
1984
1985
1986!-----------------------------------
1990 subroutine sfcdif
1991!...................................
1992! --- inputs:
1993! & ( zlvl, z0, t1v, th2v, sfcspd, czil, &
1994! --- input/outputs:
1995! & cm, ch &
1996! & )
1997
1998! ===================================================================== !
1999! description: !
2000! !
2001! subroutine sfcdif calculates surface layer exchange coefficients !
2002! via iterative process. see chen et al (1997, blm) !
2003! !
2004! subprogram called: none !
2005! !
2006! !
2007! ==================== defination of variables ==================== !
2008! !
2009! inputs from the calling program: size !
2010! zlvl - real, height abv atmos ground forcing vars (m) 1 !
2011! z0 - real, roughness length (m) 1 !
2012! t1v - real, surface exchange coefficient 1 !
2013! th2v - real, surface exchange coefficient 1 !
2014! sfcspd - real, wind speed at height zlvl abv ground (m/s) 1 !
2015! czil - real, param to cal roughness length of heat 1 !
2016! !
2017! input/outputs from and to the calling program: !
2018! cm - real, sfc exchange coeff for momentum (m/s) 1 !
2019! ch - real, sfc exchange coeff for heat & moisture (m/s)1 !
2020! !
2021! ==================== end of description ===================== !
2022!
2023! --- constant parameters:
2024 integer, parameter :: itrmx = 5
2025 real (kind=kind_phys), parameter :: wwst = 1.2
2026 real (kind=kind_phys), parameter :: wwst2 = wwst*wwst
2027 real (kind=kind_phys), parameter :: vkrm = 0.40
2028 real (kind=kind_phys), parameter :: excm = 0.001
2029 real (kind=kind_phys), parameter :: beta = 1.0/270.0
2030 real (kind=kind_phys), parameter :: btg = beta*gs1
2031 real (kind=kind_phys), parameter :: elfc = vkrm*btg
2032 real (kind=kind_phys), parameter :: wold = 0.15
2033 real (kind=kind_phys), parameter :: wnew = 1.0-wold
2034 real (kind=kind_phys), parameter :: pihf = 3.14159265/2.0 ! con_pi/2.0
2035
2036 real (kind=kind_phys), parameter :: epsu2 = 1.e-4
2037 real (kind=kind_phys), parameter :: epsust = 0.07
2038 real (kind=kind_phys), parameter :: ztmin = -5.0
2039 real (kind=kind_phys), parameter :: ztmax = 1.0
2040 real (kind=kind_phys), parameter :: hpbl = 1000.0
2041 real (kind=kind_phys), parameter :: sqvisc = 258.2
2042
2043 real (kind=kind_phys), parameter :: ric = 0.183
2044 real (kind=kind_phys), parameter :: rric = 1.0/ric
2045 real (kind=kind_phys), parameter :: fhneu = 0.8
2046 real (kind=kind_phys), parameter :: rfc = 0.191
2047 real (kind=kind_phys), parameter :: rfac = ric/(fhneu*rfc*rfc)
2048
2049! --- inputs:
2050! real (kind=kind_phys), intent(in) :: zlvl, z0, t1v, th2v, &
2051! & sfcspd, czil
2052
2053! --- input/outputs:
2054! real (kind=kind_phys), intent(inout) :: cm, ch
2055
2056! --- locals:
2057 real (kind=kind_phys) :: zilfc, zu, zt, rdz, cxch, dthv, du2, &
2058 & btgh, wstar2, ustar, zslu, zslt, rlogu, rlogt, rlmo, &
2059 & zetalt, zetalu, zetau, zetat, xlu4, xlt4, xu4, xt4, &
2060 & xlu, xlt, xu, xt, psmz, simm, pshz, simh, ustark, &
2061 & rlmn, rlma
2062
2063 integer :: ilech, itr
2064
2065! --- define local in-line functions:
2066
2067 real (kind=kind_phys) :: pslmu, pslms, pslhu, pslhs, zz
2068 real (kind=kind_phys) :: pspmu, pspms, psphu, psphs, xx, yy
2069
2070! ... 1) lech's surface functions
2071
2072 pslmu( zz ) = -0.96 * log( 1.0-4.5*zz )
2073 pslms( zz ) = zz*rric - 2.076*(1.0 - 1.0/(zz + 1.0))
2074 pslhu( zz ) = -0.96 * log( 1.0-4.5*zz )
2075 pslhs( zz ) = zz*rfac - 2.076*(1.0 - 1.0/(zz + 1.0))
2076
2077! ... 2) paulson's surface functions
2078
2079 pspmu( xx ) = -2.0 * log( (xx + 1.0)*0.5 ) &
2080 & - log( (xx*xx + 1.0)*0.5 ) + 2.0*atan(xx) - pihf
2081 pspms( yy ) = 5.0 * yy
2082 psphu( xx ) = -2.0 * log( (xx*xx + 1.0)*0.5 )
2083 psphs( yy ) = 5.0 * yy
2084
2085!
2086!===> ... begin here
2087!
2088! --- ... this routine sfcdif can handle both over open water (sea, ocean) and
2089! over solid surface (land, sea-ice).
2090
2091 ilech = 0
2092
2093! --- ... ztfc: ratio of zoh/zom less or equal than 1
2094! czil: constant c in zilitinkevich, s. s.1995,:note about zt
2095
2096 zilfc = -czil * vkrm * sqvisc
2097
2098 zu = z0
2099
2100 rdz = 1.0 / zlvl
2101 cxch = excm * rdz
2102 dthv = th2v - t1v
2103 du2 = max( sfcspd*sfcspd, epsu2 )
2104
2105! --- ... beljars correction of ustar
2106
2107 btgh = btg * hpbl
2108
2109! --- ... if statements to avoid tangent linear problems near zero
2110 if (btgh*ch*dthv /= 0.0) then
2111 wstar2 = wwst2 * abs( btgh*ch*dthv )**(2.0/3.0)
2112 else
2113 wstar2 = 0.0
2114 endif
2115
2116 ustar = max( sqrt( cm*sqrt( du2+wstar2 ) ), epsust )
2117
2118! --- ... zilitinkevitch approach for zt
2119
2120 zt = exp( zilfc*sqrt( ustar*z0 ) ) * z0
2121
2122 zslu = zlvl + zu
2123 zslt = zlvl + zt
2124
2125! print*,'zslt=',zslt
2126! print*,'zlvl=',zvll
2127! print*,'zt=',zt
2128
2129 rlogu = log( zslu/zu )
2130 rlogt = log( zslt/zt )
2131
2132 rlmo = elfc*ch*dthv / ustar**3
2133
2134! print*,'rlmo=',rlmo
2135! print*,'elfc=',elfc
2136! print*,'ch=',ch
2137! print*,'dthv=',dthv
2138! print*,'ustar=',ustar
2139
2140 do itr = 1, itrmx
2141
2142! --- ... 1./ monin-obukkhov length-scale
2143
2144 zetalt = max( zslt*rlmo, ztmin )
2145 rlmo = zetalt / zslt
2146 zetalu = zslu * rlmo
2147 zetau = zu * rlmo
2148 zetat = zt * rlmo
2149
2150 if (ilech == 0) then
2151
2152 if (rlmo < 0.0) then
2153 xlu4 = 1.0 - 16.0 * zetalu
2154 xlt4 = 1.0 - 16.0 * zetalt
2155 xu4 = 1.0 - 16.0 * zetau
2156 xt4 = 1.0 - 16.0* zetat
2157
2158 xlu = sqrt( sqrt( xlu4 ) )
2159 xlt = sqrt( sqrt( xlt4 ) )
2160 xu = sqrt( sqrt( xu4 ) )
2161 xt = sqrt( sqrt( xt4 ) )
2162
2163 psmz = pspmu(xu)
2164
2165! print*,'-----------1------------'
2166! print*,'psmz=',psmz
2167! print*,'pspmu(zetau)=',pspmu( zetau )
2168! print*,'xu=',xu
2169! print*,'------------------------'
2170
2171 simm = pspmu( xlu ) - psmz + rlogu
2172 pshz = psphu( xt )
2173 simh = psphu( xlt ) - pshz + rlogt
2174 else
2175 zetalu = min( zetalu, ztmax )
2176 zetalt = min( zetalt, ztmax )
2177 psmz = pspms( zetau )
2178
2179! print*,'-----------2------------'
2180! print*,'psmz=',psmz
2181! print*,'pspms(zetau)=',pspms( zetau )
2182! print*,'zetau=',zetau
2183! print*,'------------------------'
2184
2185 simm = pspms( zetalu ) - psmz + rlogu
2186 pshz = psphs( zetat )
2187 simh = psphs( zetalt ) - pshz + rlogt
2188 endif ! end if_rlmo_block
2189
2190 else
2191
2192! --- ... lech's functions
2193
2194 if (rlmo < 0.0) then
2195 psmz = pslmu( zetau )
2196
2197! print*,'-----------3------------'
2198! print*,'psmz=',psmz
2199! print*,'pslmu(zetau)=',pslmu( zetau )
2200! print*,'zetau=',zetau
2201! print*,'------------------------'
2202
2203 simm = pslmu( zetalu ) - psmz + rlogu
2204 pshz = pslhu( zetat )
2205 simh = pslhu( zetalt ) - pshz + rlogt
2206 else
2207 zetalu = min( zetalu, ztmax )
2208 zetalt = min( zetalt, ztmax )
2209
2210 psmz = pslms( zetau )
2211
2212! print*,'-----------4------------'
2213! print*,'psmz=',psmz
2214! print*,'pslms(zetau)=',pslms( zetau )
2215! print*,'zetau=',zetau
2216! print*,'------------------------'
2217
2218 simm = pslms( zetalu ) - psmz + rlogu
2219 pshz = pslhs( zetat )
2220 simh = pslhs( zetalt ) - pshz + rlogt
2221 endif ! end if_rlmo_block
2222
2223 endif ! end if_ilech_block
2224
2225! --- ... beljaars correction for ustar
2226
2227 ustar = max( sqrt( cm*sqrt( du2+wstar2 ) ), epsust )
2228
2229! --- ... zilitinkevitch fix for zt
2230
2231 zt = exp( zilfc*sqrt( ustar*z0 ) ) * z0
2232
2233 zslt = zlvl + zt
2234 rlogt = log( zslt/zt )
2235
2236 ustark = ustar * vkrm
2237 cm = max( ustark/simm, cxch )
2238 ch = max( ustark/simh, cxch )
2239
2240! --- ... if statements to avoid tangent linear problems near zero
2241
2242 if (btgh*ch*dthv /= 0.0) then
2243 wstar2 = wwst2 * abs(btgh*ch*dthv) ** (2.0/3.0)
2244 else
2245 wstar2 = 0.0
2246 endif
2247
2248 rlmn = elfc*ch*dthv / ustar**3
2249 rlma = rlmo*wold + rlmn*wnew
2250
2251 rlmo = rlma
2252
2253 enddo ! end do_itr_loop
2254
2255! print*,'----------------------------'
2256! print*,'sfcdif output ! ! ! ! ! ! ! ! ! ! ! !'
2257!
2258! print*,'zlvl=',zlvl
2259! print*,'z0=',z0
2260! print*,'t1v=',t1v
2261! print*,'th2v=',th2v
2262! print*,'sfcspd=',sfcspd
2263! print*,'czil=',czil
2264! print*,'cm=',cm
2265! print*,'ch=',ch
2266! print*,'----------------------------'
2267!
2268 return
2269!...................................
2270 end subroutine sfcdif
2271!-----------------------------------
2272
2273
2274!-----------------------------------
2277 subroutine snfrac
2278!...................................
2279! --- inputs:
2280! & ( sneqv, snup, salp, snowh, &
2281! --- outputs:
2282! & sncovr &
2283! & )
2284
2285! ===================================================================== !
2286! description: !
2287! !
2288! subroutine snfrac calculatexsnow fraction (0 -> 1) !
2289! !
2290! subprogram called: none !
2291! !
2292! !
2293! ==================== defination of variables ==================== !
2294! !
2295! inputs from the calling program: size !
2296! sneqv - real, snow water equivalent (m) 1 !
2297! snup - real, threshold sneqv depth above which sncovr=1 1 !
2298! salp - real, tuning parameter 1 !
2299! snowh - real, snow depth (m) 1 !
2300! !
2301! outputs to the calling program: !
2302! sncovr - real, fractional snow cover 1 !
2303! !
2304! ==================== end of description ===================== !
2305!
2306! --- inputs:
2307! real (kind=kind_phys), intent(in) :: sneqv, snup, salp, snowh
2308
2309! --- outputs:
2310! real (kind=kind_phys), intent(out) :: sncovr
2311
2312! --- locals:
2313 real (kind=kind_phys) :: rsnow, z0n
2314
2315!
2316!===> ... begin here
2317!
2318! --- ... snup is veg-class dependent snowdepth threshhold (set in routine
2319! redprm) above which snocvr=1.
2320
2321 if (sneqv < snup) then
2322 rsnow = sneqv / snup
2323 sncovr = 1.0 - (exp(-salp*rsnow) - rsnow*exp(-salp))
2324 else
2325 sncovr = 1.0
2326 endif
2327
2328 z0n = 0.035
2329
2330! --- ... formulation of dickinson et al. 1986
2331
2332! sncovr = snowh / (snowh + 5.0*z0n)
2333
2334! --- ... formulation of marshall et al. 1994
2335
2336! sncovr = sneqv / (sneqv + 2.0*z0n)
2337
2338!
2339 return
2340!...................................
2341 end subroutine snfrac
2342!-----------------------------------
2343
2344
2345!-----------------------------------
2350 subroutine snopac
2351!...................................
2352! --- inputs:
2353! & ( nsoil, nroot, etp, prcp, smcmax, smcwlt, smcref, smcdry, &
2354! & cmcmax, dt, df1, sfcems, sfctmp, t24, th2, fdown, epsca, &
2355! & bexp, pc, rch, rr, cfactr, slope, kdt, frzx, psisat, &
2356! & zsoil, dwsat, dksat, zbot, shdfac, ice, rtdis, quartz, &
2357! & fxexp, csoil, flx2, snowng, lheatstrg, &
2358! --- input/outputs:
2359! & prcp1, cmc, t1, stc, sncovr, sneqv, sndens, snowh, &
2360! & sh2o, tbot, beta, &
2361! --- outputs:
2362! & smc, ssoil, runoff1, runoff2, runoff3, edir, ec, et, &
2363! & ett, snomlt, drip, dew, flx1, flx3, esnow &
2364! & )
2365
2366! ===================================================================== !
2367! description: !
2368! !
2369! subroutine snopac calculates soil moisture and heat flux values and !
2370! update soil moisture content and soil heat content values for the !
2371! case when a snow pack is present. !
2372! !
2373! !
2374! subprograms called: evapo, smflx, shflx, snowpack
2375! !
2376! ==================== defination of variables ==================== !
2377! !
2378! inputs from the calling program: size !
2379! nsoil - integer, number of soil layers 1 !
2380! nroot - integer, number of root layers 1 !
2381! etp - real, potential evaporation 1 !
2382! prcp - real, precip rate 1 !
2383! smcmax - real, porosity 1 !
2384! smcwlt - real, wilting point 1 !
2385! smcref - real, soil mois threshold 1 !
2386! smcdry - real, dry soil mois threshold 1 !
2387! cmcmax - real, maximum canopy water parameters 1 !
2388! dt - real, time step 1 !
2389! df1 - real, thermal diffusivity m !
2390! sfcems - real, lw surface emissivity 1 !
2391! sfctmp - real, sfc temperature 1 !
2392! t24 - real, sfctmp**4 1 !
2393! th2 - real, sfc air potential temperature 1 !
2394! fdown - real, net solar + downward lw flux at sfc 1 !
2395! epsca - real, 1 !
2396! bexp - real, soil type "b" parameter 1 !
2397! pc - real, plant coeff 1 !
2398! rch - real, companion coefficient of ch 1 !
2399! rr - real, 1 !
2400! cfactr - real, canopy water parameters 1 !
2401! slope - real, linear reservoir coefficient 1 !
2402! kdt - real, 1 !
2403! frzx - real, frozen ground parameter 1 !
2404! psisat - real, saturated soil potential 1 !
2405! zsoil - real, soil layer depth below ground (negative) nsoil !
2406! dwsat - real, saturated soil diffusivity 1 !
2407! dksat - real, saturated soil hydraulic conductivity 1 !
2408! zbot - real, specify depth of lower bd soil 1 !
2409! shdfac - real, aeral coverage of green vegetation 1 !
2410! ice - integer, sea-ice flag (=1: sea-ice, =0: land) 1 !
2411! rtdis - real, root distribution nsoil !
2412! quartz - real, soil quartz content 1 !
2413! fxexp - real, bare soil evaporation exponent 1 !
2414! csoil - real, soil heat capacity 1 !
2415! flx2 - real, freezing rain latent heat flux 1 !
2416! snowng - logical, snow flag 1 !
2417! lheatstrg- logical, flag for canopy heat storage 1 !
2418! parameterization !
2419! !
2420! input/outputs from and to the calling program: !
2421! prcp1 - real, effective precip 1 !
2422! cmc - real, canopy moisture content 1 !
2423! t1 - real, ground/canopy/snowpack eff skin temp 1 !
2424! stc - real, soil temperature nsoil !
2425! sncovr - real, snow cover 1 !
2426! sneqv - real, water-equivalent snow depth 1 !
2427! sndens - real, snow density 1 !
2428! snowh - real, snow depth 1 !
2429! sh2o - real, unfrozen soil moisture nsoil !
2430! tbot - real, bottom soil temperature 1 !
2431! beta - real, ratio of actual/potential evap 1 !
2432! !
2433! outputs to the calling program: !
2434! smc - real, total soil moisture nsoil !
2435! ssoil - real, upward soil heat flux 1 !
2436! runoff1 - real, surface runoff not infiltrating sfc 1 !
2437! runoff2 - real, sub surface runoff 1 !
2438! runoff3 - real, excess of porosity for a given soil layer 1 !
2439! edir - real, direct soil evaporation 1 !
2440! ec - real, canopy water evaporation 1 !
2441! et - real, plant transpiration nsoil !
2442! ett - real, total plant transpiration 1 !
2443! snomlt - real, snow melt water equivalent 1 !
2444! drip - real, through-fall of precip 1 !
2445! dew - real, dewfall (or frostfall) 1 !
2446! flx1 - real, precip-snow sfc flux 1 !
2447! flx3 - real, phase-change heat flux from snowmelt 1 !
2448! esnow - real, sublimation from snowpack 1 !
2449! !
2450! ==================== end of description ===================== !
2451!
2452! --- constant parameters:
2453 real, parameter :: esdmin = 1.e-6
2454
2455! --- inputs:
2456! integer, intent(in) :: nsoil, nroot, ice
2457
2458! real (kind=kind_phys), intent(in) :: etp, prcp, smcmax, smcref, &
2459! & smcwlt, smcdry, cmcmax, dt, df1, sfcems, sfctmp, t24, &
2460! & th2, fdown, epsca, bexp, pc, rch, rr, cfactr, slope, kdt, &
2461! & frzx, psisat, dwsat, dksat, zbot, shdfac, quartz, &
2462! & csoil, fxexp, flx2, zsoil(nsoil), rtdis(nsoil)
2463
2464! logical, intent(in) :: snowng
2465!
2466! logical, intent(in) :: lheatstrg
2467!
2468
2469! --- input/outputs:
2470! real (kind=kind_phys), intent(inout) :: prcp1, t1, sncovr, sneqv, &
2471! & sndens, snowh, cmc, tbot, beta, sh2o(nsoil), stc(nsoil)
2472
2473! --- outputs:
2474! real (kind=kind_phys), intent(out) :: ssoil, runoff1, runoff2, &
2475! & runoff3, edir, ec, et(nsoil), ett, snomlt, drip, dew, &
2476! & flx1, flx3, esnow, smc(nsoil)
2477
2478! --- locals:
2479 real (kind=kind_phys):: denom, dsoil, dtot, etp1, ssoil1, &
2480 & snoexp, ex, t11, t12, t12a, t12b, yy, zz1, seh, t14, &
2481 & ec1, edir1, ett1, etns, etns1, esnow1, esnow2, etanrg, &
2482 & et1(nsoil)
2483
2484 integer k
2485
2486! data snoexp /1.0/ !!! <----- for noah v2.7
2487 data snoexp /2.0/ !!! <----- for noah v2.7.1
2488
2489! --- ... convert potential evap (etp) from kg m-2 s-1 to m s-1 and then to an
2490! amount (m) given timestep (dt) and call it an effective snowpack
2491! reduction amount, esnow2 (m) for a snowcover fraction = 1.0. this is
2492! the amount the snowpack would be reduced due to sublimation from the
2493! snow sfc during the timestep. sublimation will proceed at the
2494! potential rate unless the snow depth is less than the expected
2495! snowpack reduction. for snowcover fraction = 1.0, 0=edir=et=ec, and
2496! hence total evap = esnow = sublimation (potential evap rate)
2497
2498! --- ... if sea-ice (ice=1) or glacial-ice (ice=-1), snowcover fraction = 1.0,
2499! and sublimation is at the potential rate.
2500! for non-glacial land (ice=0), if snowcover fraction < 1.0, total
2501! evaporation < potential due to non-potential contribution from
2502! non-snow covered fraction.
2503
2504 prcp1 = prcp1 * 0.001
2505
2506 edir = 0.0
2507 edir1 = 0.0
2508
2509 ec = 0.0
2510 ec1 = 0.0
2511
2512 do k = 1, nsoil
2513 et(k) = 0.0
2514 et1(k) = 0.0
2515 enddo
2516
2517 ett = 0.0
2518 ett1 = 0.0
2519 etns = 0.0
2520 etns1 = 0.0
2521 esnow = 0.0
2522 esnow1= 0.0
2523 esnow2= 0.0
2524
2525 dew = 0.0
2526 etp1 = etp * 0.001
2527
2528 if (etp < 0.0) then
2529
2530! --- ... if etp<0 (downward) then dewfall (=frostfall in this case).
2531
2532 dew = -etp1
2533 esnow2 = etp1 * dt
2534 etanrg = etp * ((1.0-sncovr)*lsubc + sncovr*lsubs)
2535
2536 else
2537
2538! --- ... etp >= 0, upward moisture flux
2539
2540 if (ice /= 0) then ! for sea-ice and glacial-ice case
2541
2542 esnow = etp
2543 esnow1 = esnow * 0.001
2544 esnow2 = esnow1 * dt
2545 etanrg = esnow * lsubs
2546
2547 else ! for non-glacial land case
2548
2549 if (sncovr < 1.0) then
2550
2551 call evapo &
2552! --- inputs:
2553 & ( nsoil, nroot, cmc, cmcmax, etp1, dt, zsoil, &
2554 & sh2o, smcmax, smcwlt, smcref, smcdry, pc, &
2555 & shdfac, cfactr, rtdis, fxexp, &
2556! --- outputs:
2557 & etns1, edir1, ec1, et1, ett1 &
2558 & )
2559
2560 edir1 = edir1 * (1.0 - sncovr)
2561 ec1 = ec1 * (1.0 - sncovr)
2562
2563 do k = 1, nsoil
2564 et1(k) = et1(k) * (1.0 - sncovr)
2565 enddo
2566
2567 ett1 = ett1 * (1.0 - sncovr)
2568 etns1 = etns1 * (1.0 - sncovr)
2569
2570 edir = edir1 * 1000.0
2571 ec = ec1 * 1000.0
2572
2573 do k = 1, nsoil
2574 et(k) = et1(k) * 1000.0
2575 enddo
2576
2577 ett = ett1 * 1000.0
2578 etns = etns1 * 1000.0
2579
2580 endif ! end if_sncovr_block
2581
2582 esnow = etp * sncovr
2583! esnow1 = etp * 0.001
2584 esnow1 = esnow * 0.001
2585 esnow2 = esnow1 * dt
2586 etanrg = esnow*lsubs + etns*lsubc
2587
2588 endif ! end if_ice_block
2589
2590 endif ! end if_etp_block
2591
2592! --- ... if precip is falling, calculate heat flux from snow sfc to newly
2593! accumulating precip. note that this reflects the flux appropriate for
2594! the not-yet-updated skin temperature (t1). assumes temperature of the
2595! snowfall striking the gound is =sfctmp (lowest model level air temp).
2596
2597 flx1 = 0.0
2598 if ( snowng ) then
2599! --- ... fractional snowfall/rainfall
2600 flx1 = (cpice* ffrozp + cph2o1*(1.-ffrozp)) &
2601 & * prcp * (t1 - sfctmp)
2602 else
2603 if (prcp > 0.0) flx1 = cph2o1 * prcp * (t1 - sfctmp)
2604 endif
2605
2606! --- ... calculate an 'effective snow-grnd sfc temp' (t12) based on heat
2607! fluxes between the snow pack and the soil and on net radiation.
2608! include flx1 (precip-snow sfc) and flx2 (freezing rain latent
2609! heat) fluxes.
2610! flx2 reflects freezing rain latent heat flux using t1 calculated
2611! in penman.
2612
2613 dsoil = -0.5 * zsoil(1)
2614 dtot = snowh + dsoil
2615 denom = 1.0 + df1 / (dtot * rr * rch)
2616
2617! t12a = ( (fdown - flx1 - flx2 - sigma1*t24) / rch &
2618! & + th2 - sfctmp - beta*epsca ) / rr
2619 t12a = ( (fdown - flx1 - flx2 - sfcems*sigma1*t24) / rch &
2620 & + th2 - sfctmp - etanrg/rch ) / rr
2621
2622 t12b = df1 * stc(1) / (dtot * rr * rch)
2623 t12 = (sfctmp + t12a + t12b) / denom
2624
2625! --- ... if the 'effective snow-grnd sfc temp' is at or below freezing, no snow
2626! melt will occur. set the skin temp to this effective temp. reduce
2627! (by sublimination ) or increase (by frost) the depth of the snowpack,
2628! depending on sign of etp.
2629! update soil heat flux (ssoil) using new skin temperature (t1)
2630! since no snowmelt, set accumulated snowmelt to zero, set 'effective'
2631! precip from snowmelt to zero, set phase-change heat flux from snowmelt
2632! to zero.
2633
2634 if (t12 <= tfreez) then
2635
2636 t1 = t12
2637 ssoil = df1 * (t1 - stc(1)) / dtot
2638!wz ssoil = (t1 - stc (1)) * max(7.0, df1/dtot)
2639 sneqv = max(0.0, sneqv-esnow2)
2640 flx3 = 0.0
2641 ex = 0.0
2642 snomlt = 0.0
2643
2644 else
2645
2646! --- ... if the 'effective snow-grnd sfc temp' is above freezing, snow melt
2647! will occur. call the snow melt rate,ex and amt, snomlt. revise the
2648! effective snow depth. revise the skin temp because it would have chgd
2649! due to the latent heat released by the melting. calc the latent heat
2650! released, flx3. set the effective precip, prcp1 to the snow melt rate,
2651! ex for use in smflx. adjustment to t1 to account for snow patches.
2652! calculate qsat valid at freezing point. note that esat (saturation
2653! vapor pressure) value of 6.11e+2 used here is that valid at frzzing
2654! point. note that etp from call penman in sflx is ignored here in
2655! favor of bulk etp over 'open water' at freezing temp.
2656! update soil heat flux (s) using new skin temperature (t1)
2657
2658! --- ... noah v2.7.1 mek feb2004
2659! non-linear weighting of snow vs non-snow covered portions of gridbox
2660! so with snoexp = 2.0 (>1), surface skin temperature is higher than
2661! for the linear case (snoexp = 1).
2662
2663! t1 = tfreez * sncovr**snoexp + t12 * (1.0 - sncovr**snoexp)
2664 t1 = tfreez * max(0.01,sncovr**snoexp) + &
2665 & t12 * (1.0 - max(0.01,sncovr**snoexp))
2666
2667 beta = 1.0
2668 ssoil = df1 * (t1 - stc(1)) / dtot
2669
2670! --- ... if potential evap (sublimation) greater than depth of snowpack.
2671! beta<1
2672! snowpack has sublimated away, set depth to zero.
2673
2674 if (sneqv-esnow2 <= esdmin) then
2675
2676 sneqv = 0.0
2677 ex = 0.0
2678 snomlt = 0.0
2679 flx3 = 0.0
2680
2681 else
2682
2683! --- ... potential evap (sublimation) less than depth of snowpack, retain
2684! beta=1.
2685
2686 sneqv = sneqv - esnow2
2687 seh = rch * (t1 - th2)
2688
2689 t14 = t1 * t1
2690 t14 = t14 * t14
2691
2692 flx3 = fdown - flx1 - flx2 - sfcems*sigma1*t14 &
2693 & - ssoil - seh - etanrg
2694 if (flx3 <= 0.0) flx3 = 0.0
2695
2696 ex = flx3 * 0.001 / lsubf
2697
2698! --- ... snowmelt reduction depending on snow cover
2699! if snow cover less than 5% no snowmelt reduction
2700! note: does 'if' below fail to match the melt water with the melt
2701! energy?
2702
2703! if (sncovr > 0.05) ex = ex * sncovr
2704 snomlt = ex * dt
2705
2706! --- ... esdmin represents a snowpack depth threshold value below which we
2707! choose not to retain any snowpack, and instead include it in snowmelt.
2708
2709 if (sneqv-snomlt >= esdmin) then
2710
2711 sneqv = sneqv - snomlt
2712
2713 else
2714
2715! --- ... snowmelt exceeds snow depth
2716
2717 ex = sneqv / dt
2718 flx3 = ex * 1000.0 * lsubf
2719 snomlt = sneqv
2720 sneqv = 0.0
2721
2722 endif ! end if_sneqv-snomlt_block
2723
2724 endif ! end if_sneqv-esnow2_block
2725
2726! prcp1 = prcp1 + ex
2727
2728! --- ... if non-glacial land, add snowmelt rate (ex) to precip rate to be used
2729! in subroutine smflx (soil moisture evolution) via infiltration.
2730
2731! --- ... for sea-ice and glacial-ice, the snowmelt will be added to subsurface
2732! runoff/baseflow later near the end of sflx (after return from call to
2733! subroutine snopac)
2734
2735 if (ice == 0) prcp1 = prcp1 + ex
2736
2737 endif ! end if_t12<=tfreez_block
2738
2739! --- ... final beta now in hand, so compute evaporation. evap equals etp
2740! unless beta<1.
2741
2742! eta = beta * etp
2743
2744! --- ... smflx returns updated soil moisture values for non-glacial land.
2745! if sea-ice (ice=1) or glacial-ice (ice=-1), skip call to smflx, since
2746! no soil medium for sea-ice or glacial-ice
2747
2748 if (ice == 0) then
2749
2750 call smflx &
2751! --- inputs:
2752 & ( nsoil, dt, kdt, smcmax, smcwlt, cmcmax, prcp1, &
2753 & zsoil, slope, frzx, bexp, dksat, dwsat, shdfac, &
2754 & edir1, ec1, et1, &
2755! --- input/outputs:
2756 & cmc, sh2o, smc, &
2757! --- outputs:
2758 & runoff1, runoff2, runoff3, drip &
2759 & )
2760
2761 endif
2762
2763! --- ... before call shflx in this snowpack case, set zz1 and yy arguments to
2764! special values that ensure that ground heat flux calculated in shflx
2765! matches that already computed for below the snowpack, thus the sfc
2766! heat flux to be computed in shflx will effectively be the flux at the
2767! snow top surface. t11 is a dummy arguement so we will not use the
2768! skin temp value as revised by shflx.
2769
2770 zz1 = 1.0
2771 yy = stc(1) - 0.5*ssoil*zsoil(1)*zz1 / df1
2772 t11 = t1
2773
2774! --- ... shflx will calc/update the soil temps. note: the sub-sfc heat flux
2775! (ssoil1) and the skin temp (t11) output from this shflx call are not
2776! used in any subsequent calculations. rather, they are dummy variables
2777! here in the snopac case, since the skin temp and sub-sfc heat flux are
2778! updated instead near the beginning of the call to snopac.
2779
2780 call shflx &
2781! --- inputs:
2782 & ( nsoil, smc, smcmax, dt, yy, zz1, zsoil, zbot, &
2783 & psisat, bexp, df1, ice, quartz, csoil, vegtyp, &
2784 & shdfac, lheatstrg, &
2785! --- input/outputs:
2786 & stc, t11, tbot, sh2o, &
2787! --- outputs:
2788 & ssoil1 &
2789 & )
2790
2791! --- ... snow depth and density adjustment based on snow compaction. yy is
2792! assumed to be the soil temperture at the top of the soil column.
2793
2794 if (ice == 0) then ! for non-glacial land
2795
2796 if (sneqv > 0.0) then
2797
2798 call snowpack &
2799! --- inputs:
2800 & ( sneqv, dt, t1, yy, &
2801! --- input/outputs:
2802 & snowh, sndens &
2803 & )
2804
2805 else
2806
2807 sneqv = 0.0
2808 snowh = 0.0
2809 sndens = 0.0
2810! sncond = 1.0
2811 sncovr = 0.0
2812
2813 endif ! end if_sneqv_block
2814
2815! --- ... over sea-ice or glacial-ice, if s.w.e. (sneqv) below threshold lower
2816! bound (0.01 m for sea-ice, 0.10 m for glacial-ice), then set at
2817! lower bound and store the source increment in subsurface runoff/
2818! baseflow (runoff2). note: runoff2 is then a negative value (as
2819! a flag) over sea-ice or glacial-ice, in order to achieve water balance.
2820
2821 elseif (ice == 1) then ! for sea-ice
2822
2823 if (sneqv >= 0.01) then
2824
2825 call snowpack &
2826! --- inputs:
2827 & ( sneqv, dt, t1, yy, &
2828! --- input/outputs:
2829 & snowh, sndens &
2830 & )
2831
2832 else
2833
2834! sndens = sneqv / snowh
2835! runoff2 = -(0.01 - sneqv) / dt
2836 sneqv = 0.01
2837 snowh = 0.05
2838 sncovr = 1.0
2839! snowh = sneqv / sndens
2840
2841 endif ! end if_sneqv_block
2842
2843 else ! for glacial-ice
2844
2845 if (sneqv >= 0.10) then
2846
2847 call snowpack &
2848! --- inputs:
2849 & ( sneqv, dt, t1, yy, &
2850! --- input/outputs:
2851 & snowh, sndens &
2852 & )
2853
2854 else
2855
2856! sndens = sneqv / snowh
2857! runoff2 = -(0.10 - sneqv) / dt
2858 sneqv = 0.10
2859 snowh = 0.50
2860 sncovr = 1.0
2861! snowh = sneqv / sndens
2862
2863 endif ! end if_sneqv_block
2864
2865 endif ! end if_ice_block
2866
2867!
2868 return
2869!...................................
2870 end subroutine snopac
2871!-----------------------------------
2872
2873
2874!-----------------------------------
2878 subroutine snow_new
2879!...................................
2880! --- inputs:
2881! & ( sfctmp, sn_new, rhonewsn, exticeden, &
2882! --- input/outputs:
2883! & snowh, sndens &
2884! & )
2885
2886! ===================================================================== !
2887! description: !
2888! !
2889! subroutine snow_new calculates snow depth and densitity to account !
2890! for the new snowfall. new values of snow depth & density returned. !
2891! !
2892! subprogram called: none !
2893! !
2894! ==================== defination of variables ==================== !
2895! !
2896! inputs from the calling program: size !
2897! sfctmp - real, surface air temperature (k) 1 !
2898! sn_new - real, new snowfall (m) 1 !
2899! !
2900! input/outputs from and to the calling program: !
2901! snowh - real, snow depth (m) 1 !
2902! sndens - real, snow density 1 !
2903! (g/cm3=dimensionless fraction of h2o density) !
2904! !
2905! ==================== end of description ===================== !
2906!
2907! --- inputs:
2908! real(kind=kind_phys), intent(in) :: sfctmp, sn_new
2909
2910! --- input/outputs:
2911! real(kind=kind_phys), intent(inout) :: snowh, sndens
2912
2913! --- locals:
2914 real(kind=kind_phys) :: dsnew, snowhc, hnewc, newsnc, tempc
2915
2916!
2917!===> ... begin here
2918!
2919! --- ... conversion into simulation units
2920
2921 snowhc = snowh * 100.0
2922 newsnc = sn_new * 100.0
2923 tempc = sfctmp - tfreez
2924
2925! --- ... calculating new snowfall density depending on temperature
2926! equation from gottlib l. 'a general runoff model for
2927! snowcovered and glacierized basin', 6th nordic hydrological
2928! conference, vemadolen, sweden, 1980, 172-177pp.
2929
2930 if(.not. exticeden) then
2931 if (tempc <= -15.0) then
2932 dsnew = 0.05
2933 else
2934 dsnew = 0.05 + 0.0017*(tempc + 15.0)**1.5
2935 endif
2936 else
2937 dsnew = rhonewsn*0.001
2938 endif
2939
2940! --- ... adjustment of snow density depending on new snowfall
2941
2942 hnewc = newsnc / dsnew
2943 sndens = (snowhc*sndens + hnewc*dsnew) / (snowhc + hnewc)
2944 snowhc = snowhc + hnewc
2945 snowh = snowhc * 0.01
2946!
2947 return
2948!...................................
2949 end subroutine snow_new
2950!-----------------------------------
2951
2952
2953!-----------------------------------
2956 subroutine snowz0
2957!...................................
2958! --- inputs:
2959! & ( sncovr, &
2960! --- input/outputs:
2961! & z0 &
2962! & )
2963
2964! ===================================================================== !
2965! description: !
2966! !
2967! subroutine snowz0 calculates total roughness length over snow !
2968! !
2969! subprogram called: none !
2970! !
2971! ==================== defination of variables ==================== !
2972! !
2973! inputs from the calling program: size !
2974! sncovr - real, fractional snow cover 1 !
2975! !
2976! input/outputs from and to the calling program: !
2977! z0 - real, roughness length (m) 1 !
2978! !
2979! ==================== end of description ===================== !
2980!
2981! --- inputs:
2982! real(kind=kind_phys), intent(in) :: sncovr
2983
2984! --- input/outputs:
2985! real(kind=kind_phys), intent(inout) :: z0
2986
2987! --- locals:
2988 real(kind=kind_phys) :: z0s
2989!
2990!===> ... begin here
2991!
2992! z0s = 0.001 ! snow roughness length:=0.001 (m)
2993! --- ... current noah lsm condition - mbek, 09-oct-2001
2994 z0s = z0
2995
2996 z0 = (1.0 - sncovr)*z0 + sncovr*z0s
2997
2998!
2999 return
3000!...................................
3001 end subroutine snowz0
3002!-----------------------------------
3003
3004
3005!-----------------------------------
3009 subroutine tdfcnd &
3010! --- inputs:
3011 & ( smc, qz, smcmax, sh2o, &
3012! --- outputs:
3013 & df &
3014 & )
3015
3016! ===================================================================== !
3017! description: !
3018! !
3019! subroutine tdfcnd calculates thermal diffusivity and conductivity !
3020! of the soil for a given point and time. !
3021! !
3022! peters-lidard approach (peters-lidard et al., 1998) !
3023! june 2001 changes: frozen soil condition. !
3024! !
3025! subprogram called: none !
3026! !
3027! use as in peters-lidard, 1998 (modif. from johansen, 1975). !
3028! pablo grunmann, 08/17/98 !
3029! refs.: !
3030! farouki, o.t.,1986: thermal properties of soils. series on rock !
3031! and soil mechanics, vol. 11, trans tech, 136 pp. !
3032! johansen, o., 1975: thermal conductivity of soils. ph.d. thesis, !
3033! university of trondheim, !
3034! peters-lidard, c. d., et al., 1998: the effect of soil thermal !
3035! conductivity parameterization on surface energy fluxes !
3036! and temperatures. journal of the atmospheric sciences, !
3037! vol. 55, pp. 1209-1224. !
3038! !
3039! ==================== defination of variables ==================== !
3040! !
3041! inputs: size !
3042! smc - real, top layer total soil moisture 1 !
3043! qz - real, quartz content (soil type dependent) 1 !
3044! smcmax - real, porosity 1 !
3045! sh2o - real, top layer unfrozen soil moisture 1 !
3046! !
3047! outputs: !
3048! df - real, soil thermal diffusivity and conductivity 1 !
3049! !
3050! locals: !
3051! thkw - water thermal conductivity 1 !
3052! thkqtz - thermal conductivity for quartz 1 !
3053! thko - thermal conductivity for other soil components 1 !
3054! thkqtz - thermal conductivity for the solids combined 1 !
3055! thkice - ice thermal conductivity 1 !
3056! !
3057! !
3058! ==================== end of description ===================== !
3059!
3060! --- input:
3061 real (kind=kind_phys), intent(in) :: smc, qz, smcmax, sh2o
3062
3063! --- output:
3064 real (kind=kind_phys), intent(out) :: df
3065
3066! --- locals:
3067 real (kind=kind_phys) :: gammd, thkdry, ake, thkice, thko, &
3068 & thkqtz, thksat, thks, thkw, satratio, xu, xunfroz
3069!
3070!===> ... begin here
3071!
3072! --- ... if the soil has any moisture content compute a partial sum/product
3073! otherwise use a constant value which works well with most soils
3074
3075! --- ... saturation ratio:
3076
3077 satratio = smc / smcmax
3078
3079! --- ... parameters w/(m.k)
3080 thkice = 2.2
3081 thkw = 0.57
3082 thko = 2.0
3083! if (qz <= 0.2) thko = 3.0
3084 thkqtz = 7.7
3085
3086! --- ... solids' conductivity
3087
3088 thks = (thkqtz**qz) * (thko**(1.0-qz))
3089
3090! --- ... unfrozen fraction (from 1., i.e., 100%liquid, to 0. (100% frozen))
3091
3092 xunfroz = (sh2o + 1.e-9) / (smc + 1.e-9)
3093
3094! --- ... unfrozen volume for saturation (porosity*xunfroz)
3095
3096 xu=xunfroz*smcmax
3097
3098! --- ... saturated thermal conductivity
3099
3100 thksat = thks**(1.-smcmax) * thkice**(smcmax-xu) * thkw**(xu)
3101
3102! --- ... dry density in kg/m3
3103
3104 gammd = (1.0 - smcmax) * 2700.0
3105
3106! --- ... dry thermal conductivity in w.m-1.k-1
3107
3108 thkdry = (0.135*gammd + 64.7) / (2700.0 - 0.947*gammd)
3109
3110 if ( sh2o+0.0005 < smc ) then ! frozen
3111
3112 ake = satratio
3113
3114 else ! unfrozen
3115
3116! --- ... range of validity for the kersten number (ake)
3117 if ( satratio > 0.1 ) then
3118
3119! --- ... kersten number (using "fine" formula, valid for soils containing
3120! at least 5% of particles with diameter less than 2.e-6 meters.)
3121! (for "coarse" formula, see peters-lidard et al., 1998).
3122
3123 ake = log10( satratio ) + 1.0
3124
3125 else
3126
3127! --- ... use k = kdry
3128 ake = 0.0
3129
3130 endif ! end if_satratio_block
3131
3132 endif ! end if_sh2o+0.0005_block
3133
3134! --- ... thermal conductivity
3135
3136 df = ake * (thksat - thkdry) + thkdry
3137!
3138 return
3139!...................................
3140 end subroutine tdfcnd
3141!-----------------------------------
3142
3143
3144!*********************************************!
3145! section-2 2nd level subprograms !
3146!*********************************************!
3147
3148
3149!-----------------------------------
3156 subroutine evapo &
3157! --- inputs:
3158 & ( nsoil, nroot, cmc, cmcmax, etp1, dt, zsoil, &
3159 & sh2o, smcmax, smcwlt, smcref, smcdry, pc, &
3160 & shdfac, cfactr, rtdis, fxexp, &
3161! --- outputs:
3162 & eta1, edir1, ec1, et1, ett1 &
3163 & )
3164
3165! ===================================================================== !
3166! description: !
3167! !
3168! subroutine evapo calculates soil moisture flux. the soil moisture !
3169! content (smc - a per unit volume measurement) is a dependent variable!
3170! that is updated with prognostic eqns. the canopy moisture content !
3171! (cmc) is also updated. frozen ground version: new states added: !
3172! sh2o, and frozen ground correction factor, frzfact and parameter !
3173! slope. !
3174! !
3175! !
3176! subprogram called: devap, transp !
3177! !
3178! ==================== defination of variables ==================== !
3179! !
3180! inputs from calling program: size !
3181! nsoil - integer, number of soil layers 1 !
3182! nroot - integer, number of root layers 1 !
3183! cmc - real, canopy moisture content 1 !
3184! cmcmax - real, maximum canopy water parameters 1 !
3185! etp1 - real, potential evaporation 1 !
3186! dt - real, time step 1 !
3187! zsoil - real, soil layer depth below ground nsoil !
3188! sh2o - real, unfrozen soil moisture nsoil !
3189! smcmax - real, porosity 1 !
3190! smcwlt - real, wilting point 1 !
3191! smcref - real, soil mois threshold 1 !
3192! smcdry - real, dry soil mois threshold 1 !
3193! pc - real, plant coeff 1 !
3194! cfactr - real, canopy water parameters 1 !
3195! rtdis - real, root distribution nsoil !
3196! fxexp - real, bare soil evaporation exponent 1 !
3197! !
3198! outputs to calling program: !
3199! eta1 - real, latent heat flux 1 !
3200! edir1 - real, direct soil evaporation 1 !
3201! ec1 - real, canopy water evaporation 1 !
3202! et1 - real, plant transpiration nsoil !
3203! ett1 - real, total plant transpiration 1 !
3204! !
3205! ==================== end of description ===================== !
3206!
3207! --- inputs:
3208 integer, intent(in) :: nsoil, nroot
3209
3210 real (kind=kind_phys), intent(in) :: cmc, cmcmax, etp1, dt, pc, &
3211 & smcmax, smcwlt, smcref, smcdry, shdfac, cfactr, fxexp, &
3212 & zsoil(nsoil), sh2o(nsoil), rtdis(nsoil)
3213
3214! --- outputs:
3215 real (kind=kind_phys), intent(out) :: eta1, edir1, ec1, ett1, &
3216 & et1(nsoil)
3217
3218! --- locals:
3219 real (kind=kind_phys) :: cmc2ms
3220
3221 integer :: i, k
3222
3223!
3224!===> ... begin here
3225!
3226! --- ... executable code begins here if the potential evapotranspiration
3227! is greater than zero.
3228
3229 edir1 = 0.0
3230 ec1 = 0.0
3231
3232 do k = 1, nsoil
3233 et1(k) = 0.0
3234 enddo
3235 ett1 = 0.0
3236
3237 if (etp1 > 0.0) then
3238
3239! --- ... retrieve direct evaporation from soil surface. call this function
3240! only if veg cover not complete.
3241! frozen ground version: sh2o states replace smc states.
3242
3243 if (shdfac < 1.0) then
3244
3245 call devap &
3246! --- inputs:
3247 & ( etp1, sh2o(1), shdfac, smcmax, smcdry, fxexp, &
3248! --- outputs:
3249 & edir1 &
3250 & )
3251
3252 endif
3253
3254! --- ... initialize plant total transpiration, retrieve plant transpiration,
3255! and accumulate it for all soil layers.
3256
3257 if (shdfac > 0.0) then
3258
3259 call transp &
3260! --- inputs:
3261 & ( nsoil, nroot, etp1, sh2o, smcwlt, smcref, &
3262 & cmc, cmcmax, zsoil, shdfac, pc, cfactr, rtdis, &
3263! --- outputs:
3264 & et1 &
3265 & )
3266
3267 do k = 1, nsoil
3268 ett1 = ett1 + et1(k)
3269 enddo
3270
3271! --- ... calculate canopy evaporation.
3272! if statements to avoid tangent linear problems near cmc=0.0.
3273
3274 if (cmc > 0.0) then
3275 ec1 = shdfac * ( (cmc/cmcmax)**cfactr ) * etp1
3276 else
3277 ec1 = 0.0
3278 endif
3279
3280! --- ... ec should be limited by the total amount of available water
3281! on the canopy. -f.chen, 18-oct-1994
3282
3283 cmc2ms = cmc / dt
3284 ec1 = min( cmc2ms, ec1 )
3285 endif
3286
3287 endif ! end if_etp1_block
3288
3289! --- ... total up evap and transp types to obtain actual evapotransp
3290
3291 eta1 = edir1 + ett1 + ec1
3292
3293!
3294 return
3295!...................................
3296 end subroutine evapo
3297!-----------------------------------
3298
3299
3300!-----------------------------------
3305 subroutine shflx &
3306! --- inputs:
3307 & ( nsoil, smc, smcmax, dt, yy, zz1, zsoil, zbot, &
3308 & psisat, bexp, df1, ice, quartz, csoil, vegtyp, &
3309 & shdfac, lheatstrg, &
3310! --- input/outputs:
3311 & stc, t1, tbot, sh2o, &
3312! --- outputs:
3313 & ssoil &
3314 & )
3315
3316! ===================================================================== !
3317! description: !
3318! !
3319! subroutine shflx updates the temperature state of the soil column !
3320! based on the thermal diffusion equation and update the frozen soil !
3321! moisture content based on the temperature. !
3322! !
3323! subprogram called: hstep, hrtice, hrt !
3324! !
3325! !
3326! ==================== defination of variables ==================== !
3327! !
3328! inputs: size !
3329! nsoil - integer, number of soil layers 1 !
3330! smc - real, total soil moisture nsoil !
3331! smcmax - real, porosity (sat val of soil mois) 1 !
3332! dt - real, time step 1 !
3333! yy - real, soil temperature at the top of column 1 !
3334! zz1 - real, 1 !
3335! zsoil - real, soil layer depth below ground (negative) nsoil !
3336! zbot - real, specify depth of lower bd soil 1 !
3337! psisat - real, saturated soil potential 1 !
3338! bexp - real, soil type "b" parameter 1 !
3339! df1 - real, thermal diffusivity and conductivity 1 !
3340! ice - integer, sea-ice flag (=1: sea-ice, =0: land) 1 !
3341! quartz - real, soil quartz content 1 !
3342! csoil - real, soil heat capacity 1 !
3343! vegtyp - integer, vegtation type 1 !
3344! shdfac - real, aeral coverage of green vegetation 1 !
3345! lheatstrg- logical, flag for canopy heat storage 1 !
3346! parameterization !
3347! !
3348! input/outputs: !
3349! stc - real, soil temp nsoil !
3350! t1 - real, ground/canopy/snowpack eff skin temp 1 !
3351! tbot - real, bottom soil temp 1 !
3352! sh2o - real, unfrozen soil moisture nsoil !
3353! !
3354! outputs: !
3355! ssoil - real, upward soil heat flux 1 !
3356! !
3357! ==================== end of description ===================== !
3358!
3359! --- parameter constants:
3360 real (kind=kind_phys), parameter :: ctfil1 = 0.5
3361 real (kind=kind_phys), parameter :: ctfil2 = 1.0 - ctfil1
3362
3363! --- inputs:
3364 integer, intent(in) :: nsoil, ice, vegtyp
3365
3366 real (kind=kind_phys), intent(in) :: smc(nsoil), smcmax, dt, yy, &
3367 & zz1, zsoil(nsoil), zbot, psisat, bexp, df1, quartz, csoil, &
3368 & shdfac
3369
3370 logical, intent(in) :: lheatstrg
3371
3372! --- input/outputs:
3373 real (kind=kind_phys), intent(inout) :: stc(nsoil), t1, tbot, &
3374 & sh2o(nsoil)
3375
3376! --- outputs:
3377 real (kind=kind_phys), intent(out) :: ssoil
3378
3379! --- locals:
3380 real (kind=kind_phys) :: ai(nsold), bi(nsold), ci(nsold), oldt1, &
3381 & rhsts(nsold), stcf(nsold), stsoil(nsoil)
3382
3383 integer :: i
3384
3385!
3386!===> ... begin here
3387!
3388 oldt1 = t1
3389 do i = 1, nsoil
3390 stsoil(i) = stc(i)
3391 enddo
3392
3393! --- ... hrt routine calcs the right hand side of the soil temp dif eqn
3394
3395 if (ice /= 0) then
3396
3397! --- ... sea-ice case, glacial-ice case
3398
3399 call hrtice &
3400! --- inputs:
3401 & ( nsoil, stc, zsoil, yy, zz1, df1, ice, &
3402! --- input/outputs:
3403 & tbot, &
3404! --- outputs:
3405 & rhsts, ai, bi, ci &
3406 & )
3407
3408 call hstep &
3409! --- inputs:
3410 & ( nsoil, stc, dt, &
3411! --- input/outputs:
3412 & rhsts, ai, bi, ci, &
3413! --- outputs:
3414 & stcf &
3415 & )
3416
3417 else
3418
3419! --- ... land-mass case
3420
3421 call hrt &
3422! --- inputs:
3423 & ( nsoil, stc, smc, smcmax, zsoil, yy, zz1, tbot, &
3424 & zbot, psisat, dt, bexp, df1, quartz, csoil,vegtyp, &
3425 & shdfac, lheatstrg, &
3426! --- input/outputs:
3427 & sh2o, &
3428! --- outputs:
3429 & rhsts, ai, bi, ci &
3430 & )
3431
3432 call hstep &
3433! --- inputs:
3434 & ( nsoil, stc, dt, &
3435! --- input/outputs:
3436 & rhsts, ai, bi, ci, &
3437! --- outputs:
3438 & stcf &
3439 & )
3440
3441 endif
3442
3443 do i = 1, nsoil
3444 stc(i) = stcf(i)
3445 enddo
3446
3447! --- ... in the no snowpack case (via routine nopac branch,) update the grnd
3448! (skin) temperature here in response to the updated soil temperature
3449! profile above. (note: inspection of routine snopac shows that t1
3450! below is a dummy variable only, as skin temperature is updated
3451! differently in routine snopac)
3452
3453 t1 = (yy + (zz1 - 1.0)*stc(1)) / zz1
3454 t1 = ctfil1*t1 + ctfil2*oldt1
3455
3456 do i = 1, nsoil
3457 stc(i) = ctfil1*stc(i) + ctfil2*stsoil(i)
3458 enddo
3459
3460! --- ... calculate surface soil heat flux
3461
3462 ssoil = df1*(stc(1) - t1) / (0.5*zsoil(1))
3463
3464!
3465 return
3466!...................................
3467 end subroutine shflx
3468!-----------------------------------
3469
3470
3471
3472!-----------------------------------
3479 subroutine smflx &
3480! --- inputs:
3481 & ( nsoil, dt, kdt, smcmax, smcwlt, cmcmax, prcp1, &
3482 & zsoil, slope, frzx, bexp, dksat, dwsat, shdfac, &
3483 & edir1, ec1, et1, &
3484! --- input/outputs:
3485 & cmc, sh2o, smc, &
3486! --- outputs:
3487 & runoff1, runoff2, runoff3, drip &
3488 & )
3489
3490! ===================================================================== !
3491! description: !
3492! !
3493! subroutine smflx calculates soil moisture flux. the soil moisture !
3494! content (smc - a per unit volume measurement) is a dependent variable!
3495! that is updated with prognostic eqns. the canopy moisture content !
3496! (cmc) is also updated. frozen ground version: new states added: sh2o!
3497! and frozen ground correction factor, frzx and parameter slope. !
3498! !
3499! !
3500! subprogram called: srt, sstep !
3501! !
3502! ==================== defination of variables ==================== !
3503! !
3504! inputs: size !
3505! nsoil - integer, number of soil layers 1 !
3506! dt - real, time step 1 !
3507! kdt - real, 1 !
3508! smcmax - real, porosity 1 !
3509! smcwlt - real, wilting point 1 !
3510! cmcmax - real, maximum canopy water parameters 1 !
3511! prcp1 - real, effective precip 1 !
3512! zsoil - real, soil layer depth below ground (negative) nsoil !
3513! slope - real, linear reservoir coefficient 1 !
3514! frzx - real, frozen ground parameter 1 !
3515! bexp - real, soil type "b" parameter 1 !
3516! dksat - real, saturated soil hydraulic conductivity 1 !
3517! dwsat - real, saturated soil diffusivity 1 !
3518! shdfac - real, aeral coverage of green veg 1 !
3519! edir1 - real, direct soil evaporation 1 !
3520! ec1 - real, canopy water evaporation 1 !
3521! et1 - real, plant transpiration nsoil !
3522! !
3523! input/outputs: !
3524! cmc - real, canopy moisture content 1 !
3525! sh2o - real, unfrozen soil moisture nsoil !
3526! smc - real, total soil moisture nsoil !
3527! !
3528! outputs: !
3529! runoff1 - real, surface runoff not infiltrating sfc 1 !
3530! runoff2 - real, sub surface runoff (baseflow) 1 !
3531! runoff3 - real, excess of porosity 1 !
3532! drip - real, through-fall of precip and/or dew 1 !
3533! !
3534! ==================== end of description ===================== !
3535!
3536! --- inputs:
3537 integer, intent(in) :: nsoil
3538
3539 real (kind=kind_phys), intent(in) :: dt, kdt, smcmax, smcwlt, &
3540 & cmcmax, prcp1, slope, frzx, bexp, dksat, dwsat, shdfac, &
3541 & edir1, ec1, et1(nsoil), zsoil(nsoil)
3542
3543! --- input/outputs:
3544 real (kind=kind_phys), intent(inout) :: cmc, sh2o(nsoil), &
3545 & smc(nsoil)
3546
3547! --- outputs:
3548 real (kind=kind_phys), intent(out) :: runoff1, runoff2, &
3549 & runoff3, drip
3550
3551! --- locals:
3552 real (kind=kind_phys) :: dummy, excess, pcpdrp, rhsct, trhsct, &
3553 & rhstt(nsold), sice(nsold), sh2oa(nsold), sh2ofg(nsold), &
3554 & ai(nsold), bi(nsold), ci(nsold)
3555
3556 integer :: i, k
3557!
3558!===> ... begin here
3559!
3560! --- ... executable code begins here.
3561
3562 dummy = 0.0
3563
3564! --- ... compute the right hand side of the canopy eqn term ( rhsct )
3565
3566 rhsct = shdfac*prcp1 - ec1
3567
3568! --- ... convert rhsct (a rate) to trhsct (an amount) and add it to
3569! existing cmc. if resulting amt exceeds max capacity, it becomes
3570! drip and will fall to the grnd.
3571
3572 drip = 0.0
3573 trhsct = dt * rhsct
3574 excess = cmc + trhsct
3575
3576 if (excess > cmcmax) drip = excess - cmcmax
3577
3578! --- ... pcpdrp is the combined prcp1 and drip (from cmc) that goes into
3579! the soil
3580
3581 pcpdrp = (1.0 - shdfac)*prcp1 + drip/dt
3582
3583! --- ... store ice content at each soil layer before calling srt & sstep
3584
3585 do i = 1, nsoil
3586 sice(i) = smc(i) - sh2o(i)
3587 enddo
3588
3589! --- ... call subroutines srt and sstep to solve the soil moisture
3590! tendency equations.
3591
3592! --- if the infiltrating precip rate is nontrivial,
3593! (we consider nontrivial to be a precip total over the time step
3594! exceeding one one-thousandth of the water holding capacity of
3595! the first soil layer)
3596! then call the srt/sstep subroutine pair twice in the manner of
3597! time scheme "f" (implicit state, averaged coefficient)
3598! of section 2 of kalnay and kanamitsu (1988, mwr, vol 116,
3599! pages 1945-1958)to minimize 2-delta-t oscillations in the
3600! soil moisture value of the top soil layer that can arise because
3601! of the extreme nonlinear dependence of the soil hydraulic
3602! diffusivity coefficient and the hydraulic conductivity on the
3603! soil moisture state
3604! otherwise call the srt/sstep subroutine pair once in the manner of
3605! time scheme "d" (implicit state, explicit coefficient)
3606! of section 2 of kalnay and kanamitsu
3607! pcpdrp is units of kg/m**2/s or mm/s, zsoil is negative depth in m
3608
3609! if ( pcpdrp .gt. 0.0 ) then
3610 if ( (pcpdrp*dt) > (0.001*1000.0*(-zsoil(1))*smcmax) ) then
3611
3612! --- ... frozen ground version:
3613! smc states replaced by sh2o states in srt subr. sh2o & sice states
3614! included in sstep subr. frozen ground correction factor, frzx
3615! added. all water balance calculations using unfrozen water
3616
3617 call srt &
3618! --- inputs:
3619 & ( nsoil, edir1, et1, sh2o, sh2o, pcpdrp, zsoil, dwsat, &
3620 & dksat, smcmax, bexp, dt, smcwlt, slope, kdt, frzx, sice, &
3621! --- outputs:
3622 & rhstt, runoff1, runoff2, ai, bi, ci &
3623 & )
3624
3625 call sstep &
3626! --- inputs:
3627 & ( nsoil, sh2o, rhsct, dt, smcmax, cmcmax, zsoil, sice, &
3628! --- input/outputs:
3629 & dummy, rhstt, ai, bi, ci, &
3630! --- outputs:
3631 & sh2ofg, runoff3, smc &
3632 & )
3633
3634 do k = 1, nsoil
3635 sh2oa(k) = (sh2o(k) + sh2ofg(k)) * 0.5
3636 enddo
3637
3638 call srt &
3639! --- inputs:
3640 & ( nsoil, edir1, et1, sh2o, sh2oa, pcpdrp, zsoil, dwsat, &
3641 & dksat, smcmax, bexp, dt, smcwlt, slope, kdt, frzx, sice, &
3642! --- outputs:
3643 & rhstt, runoff1, runoff2, ai, bi, ci &
3644 & )
3645
3646 call sstep &
3647! --- inputs:
3648 & ( nsoil, sh2o, rhsct, dt, smcmax, cmcmax, zsoil, sice, &
3649! --- input/outputs:
3650 & cmc, rhstt, ai, bi, ci, &
3651! --- outputs:
3652 & sh2o, runoff3, smc &
3653 & )
3654
3655 else
3656
3657 call srt &
3658! --- inputs:
3659 & ( nsoil, edir1, et1, sh2o, sh2o, pcpdrp, zsoil, dwsat, &
3660 & dksat, smcmax, bexp, dt, smcwlt, slope, kdt, frzx, sice, &
3661! --- outputs:
3662 & rhstt, runoff1, runoff2, ai, bi, ci &
3663 & )
3664
3665 call sstep &
3666! --- inputs:
3667 & ( nsoil, sh2o, rhsct, dt, smcmax, cmcmax, zsoil, sice, &
3668! --- input/outputs:
3669 & cmc, rhstt, ai, bi, ci, &
3670! --- outputs:
3671 & sh2o, runoff3, smc &
3672 & )
3673
3674 endif
3675
3676! runof = runoff
3677!
3678 return
3679!...................................
3680 end subroutine smflx
3681!-----------------------------------
3682
3683
3684!-----------------------------------
3691 subroutine snowpack &
3692! --- inputs:
3693 & ( esd, dtsec, tsnow, tsoil, &
3694! --- input/outputs:
3695 & snowh, sndens &
3696 & )
3697
3698! ===================================================================== !
3699! description: !
3700! !
3701! subroutine snowpack calculates compaction of snowpack under !
3702! conditions of increasing snow density, as obtained from an !
3703! approximate solution of e. anderson's differential equation (3.29),!
3704! noaa technical report nws 19, by victor koren, 03/25/95. !
3705! subroutine will return new values of snowh and sndens !
3706! !
3707! !
3708! subprogram called: none !
3709! !
3710! !
3711! ==================== defination of variables ==================== !
3712! !
3713! inputs: size !
3714! esd - real, water equivalent of snow (m) 1 !
3715! dtsec - real, time step (sec) 1 !
3716! tsnow - real, snow surface temperature (k) 1 !
3717! tsoil - real, soil surface temperature (k) 1 !
3718! !
3719! input/outputs: !
3720! snowh - real, snow depth (m) 1 !
3721! sndens - real, snow density 1 !
3722! (g/cm3=dimensionless fraction of h2o density) !
3723! !
3724! ==================== end of description ===================== !
3725!
3726! --- parameter constants:
3727 real (kind=kind_phys), parameter :: c1 = 0.01
3728 real (kind=kind_phys), parameter :: c2 = 21.0
3729
3730! --- inputs:
3731 real (kind=kind_phys), intent(in) :: esd, dtsec, tsnow, tsoil
3732
3733! --- input/outputs:
3734 real (kind=kind_phys), intent(inout) :: snowh, sndens
3735
3736! --- locals:
3737 real (kind=kind_phys) :: bfac, dsx, dthr, dw, snowhc, pexp, &
3738 & tavgc, tsnowc, tsoilc, esdc, esdcx
3739
3740 integer :: ipol, j
3741!
3742!===> ... begin here
3743!
3744! --- ... conversion into simulation units
3745
3746 snowhc = snowh * 100.0
3747 esdc = esd * 100.0
3748 dthr = dtsec / 3600.0
3749 tsnowc = tsnow - tfreez
3750 tsoilc = tsoil - tfreez
3751
3752! --- ... calculating of average temperature of snow pack
3753
3754 tavgc = 0.5 * (tsnowc + tsoilc)
3755
3756! --- ... calculating of snow depth and density as a result of compaction
3757! sndens=ds0*(exp(bfac*esd)-1.)/(bfac*esd)
3758! bfac=dthr*c1*exp(0.08*tavgc-c2*ds0)
3759! note: bfac*esd in sndens eqn above has to be carefully treated
3760! numerically below:
3761! c1 is the fractional increase in density (1/(cm*hr))
3762! c2 is a constant (cm3/g) kojima estimated as 21 cms/g
3763
3764 if (esdc > 1.e-2) then
3765 esdcx = esdc
3766 else
3767 esdcx = 1.e-2
3768 endif
3769
3770 bfac = dthr*c1 * exp(0.08*tavgc - c2*sndens)
3771
3772! dsx = sndens * ((dexp(bfac*esdc)-1.0) / (bfac*esdc))
3773
3774! --- ... the function of the form (e**x-1)/x imbedded in above expression
3775! for dsx was causing numerical difficulties when the denominator "x"
3776! (i.e. bfac*esdc) became zero or approached zero (despite the fact
3777! that the analytical function (e**x-1)/x has a well defined limit
3778! as "x" approaches zero), hence below we replace the (e**x-1)/x
3779! expression with an equivalent, numerically well-behaved
3780! polynomial expansion.
3781
3782! --- ... number of terms of polynomial expansion, and hence its accuracy,
3783! is governed by iteration limit "ipol".
3784! ipol greater than 9 only makes a difference on double
3785! precision (relative errors given in percent %).
3786! ipol=9, for rel.error <~ 1.6 e-6 % (8 significant digits)
3787! ipol=8, for rel.error <~ 1.8 e-5 % (7 significant digits)
3788! ipol=7, for rel.error <~ 1.8 e-4 % ...
3789
3790 ipol = 4
3791 pexp = 0.0
3792
3793 do j = ipol, 1, -1
3794! pexp = (1.0 + pexp)*bfac*esdc /real(j+1)
3795 pexp = (1.0 + pexp)*bfac*esdcx/real(j+1)
3796 enddo
3797 pexp = pexp + 1.
3798
3799 dsx = sndens * pexp
3800
3801! --- ... above line ends polynomial substitution
3802! end of koren formulation
3803
3804!! --- ... base formulation (cogley et al., 1990)
3805! convert density from g/cm3 to kg/m3
3806
3807!! dsm = sndens * 1000.0
3808
3809!! dsx = dsm + dtsec*0.5*dsm*gs2*esd / &
3810!! & (1.e7*exp(-0.02*dsm + kn/(tavgc+273.16)-14.643))
3811
3812!! --- ... convert density from kg/m3 to g/cm3
3813
3814!! dsx = dsx / 1000.0
3815
3816!! --- ... end of cogley et al. formulation
3817
3818! --- ... set upper/lower limit on snow density
3819
3820 dsx = max( min( dsx, 0.40 ), 0.05 )
3821 sndens = dsx
3822
3823! --- ... update of snow depth and density depending on liquid water
3824! during snowmelt. assumed that 13% of liquid water can be
3825! stored in snow per day during snowmelt till snow density 0.40.
3826
3827 if (tsnowc >= 0.0) then
3828 dw = 0.13 * dthr / 24.0
3829 sndens = sndens*(1.0 - dw) + dw
3830 if (sndens > 0.40) sndens = 0.40
3831 endif
3832
3833! --- ... calculate snow depth (cm) from snow water equivalent and snow
3834! density. change snow depth units to meters
3835
3836 snowhc = esdc / sndens
3837 snowh = snowhc * 0.01
3838
3839!
3840 return
3841!...................................
3842 end subroutine snowpack
3843!-----------------------------------
3844
3845
3846!*********************************************!
3847! section-3 3rd or lower level subprograms !
3848!*********************************************!
3849
3850
3851!-----------------------------------
3854 subroutine devap &
3855! --- inputs:
3856 & ( etp1, smc, shdfac, smcmax, smcdry, fxexp, &
3857! --- outputs:
3858 & edir1 &
3859 & )
3860
3861! ===================================================================== !
3862! description: !
3863! !
3864! subroutine devap calculates direct soil evaporation !
3865! !
3866! !
3867! subprogram called: none !
3868! !
3869! !
3870! ==================== defination of variables ==================== !
3871! !
3872! inputs: size !
3873! etp1 - real, potential evaporation 1 !
3874! smc - real, unfrozen soil moisture 1 !
3875! shdfac - real, aeral coverage of green vegetation 1 !
3876! smcmax - real, porosity (sat val of soil mois) 1 !
3877! smcdry - real, dry soil mois threshold 1 !
3878! fxexp - real, bare soil evaporation exponent 1 !
3879! !
3880! outputs: !
3881! edir1 - real, direct soil evaporation 1 !
3882! !
3883! ==================== end of description ===================== !
3884!
3885! --- inputs:
3886 real (kind=kind_phys), intent(in) :: etp1, smc, shdfac, smcmax, &
3887 & smcdry, fxexp
3888
3889! --- outputs:
3890 real (kind=kind_phys), intent(out) :: edir1
3891
3892! --- locals:
3893 real (kind=kind_phys) :: fx, sratio
3894!
3895!===> ... begin here
3896!
3897! --- ... direct evap a function of relative soil moisture availability,
3898! linear when fxexp=1.
3899! fx > 1 represents demand control
3900! fx < 1 represents flux control
3901
3902 sratio = (smc - smcdry) / (smcmax - smcdry)
3903
3904 if (sratio > 0.0) then
3905 fx = sratio**fxexp
3906 fx = max( min( fx, 1.0 ), 0.0 )
3907 else
3908 fx = 0.0
3909 endif
3910
3911! --- ... allow for the direct-evap-reducing effect of shade
3912
3913 edir1 = fx * ( 1.0 - shdfac ) * etp1
3914!
3915 return
3916!...................................
3917 end subroutine devap
3918!-----------------------------------
3919
3920
3921!-----------------------------------
3934 subroutine frh2o &
3935! --- inputs:
3936 & ( tkelv, smc, sh2o, smcmax, bexp, psis, &
3937! --- outputs:
3938 & liqwat &
3939 & )
3940
3941! ===================================================================== !
3942! description: !
3943! !
3944! subroutine frh2o calculates amount of supercooled liquid soil water !
3945! content if temperature is below 273.15k (t0). requires newton-type !
3946! iteration to solve the nonlinear implicit equation given in eqn 17 !
3947! of koren et al (1999, jgr, vol 104(d16), 19569-19585). !
3948! !
3949! new version (june 2001): much faster and more accurate newton !
3950! iteration achieved by first taking log of eqn cited above -- less !
3951! than 4 (typically 1 or 2) iterations achieves convergence. also, !
3952! explicit 1-step solution option for special case of parameter ck=0, !
3953! which reduces the original implicit equation to a simpler explicit !
3954! form, known as the "flerchinger eqn". improved handling of solution !
3955! in the limit of freezing point temperature t0. !
3956! !
3957! subprogram called: none !
3958! !
3959! !
3960! ==================== defination of variables ==================== !
3961! !
3962! inputs: size !
3963! tkelv - real, temperature (k) 1 !
3964! smc - real, total soil moisture content (volumetric) 1 !
3965! sh2o - real, liquid soil moisture content (volumetric) 1 !
3966! smcmax - real, saturation soil moisture content 1 !
3967! bexp - real, soil type "b" parameter 1 !
3968! psis - real, saturated soil matric potential 1 !
3969! !
3970! outputs: !
3971! liqwat - real, supercooled liquid water content 1 !
3972! !
3973! ==================== end of description ===================== !
3974!
3975! --- constant parameters:
3976 real (kind=kind_phys), parameter :: ck = 8.0
3977! real (kind=kind_phys), parameter :: ck = 0.0
3978 real (kind=kind_phys), parameter :: blim = 5.5
3979 real (kind=kind_phys), parameter :: error = 0.005
3980
3981! --- inputs:
3982 real (kind=kind_phys), intent(in) :: tkelv, smc, sh2o, smcmax, &
3983 & bexp, psis
3984
3985! --- outputs:
3986 real (kind=kind_phys), intent(out) :: liqwat
3987
3988! --- locals:
3989 real (kind=kind_phys) :: bx, denom, df, dswl, fk, swl, swlk
3990
3991 integer :: nlog, kcount
3992!
3993!===> ... begin here
3994!
3995! --- ... limits on parameter b: b < 5.5 (use parameter blim)
3996! simulations showed if b > 5.5 unfrozen water content is
3997! non-realistically high at very low temperatures.
3998
3999 bx = bexp
4000 if (bexp > blim) bx = blim
4001
4002! --- ... initializing iterations counter and iterative solution flag.
4003
4004 nlog = 0
4005 kcount= 0
4006
4007! --- ... if temperature not significantly below freezing (t0), sh2o = smc
4008
4009 if (tkelv > (tfreez-1.e-3)) then
4010
4011 liqwat = smc
4012
4013 else
4014
4015 if (ck /= 0.0) then
4016
4017! --- ... option 1: iterated solution for nonzero ck
4018! in koren et al, jgr, 1999, eqn 17
4019
4020! --- ... initial guess for swl (frozen content)
4021
4022 swl = smc - sh2o
4023
4024! --- ... keep within bounds.
4025
4026 swl = max( min( swl, smc-0.02 ), 0.0 )
4027
4028! --- ... start of iterations
4029
4030 do while ( (nlog < 10) .and. (kcount == 0) )
4031 nlog = nlog + 1
4032
4033 df = log( (psis*gs2/lsubf) * ( (1.0 + ck*swl)**2.0 ) &
4034 & * (smcmax/(smc-swl))**bx ) - log(-(tkelv-tfreez)/tkelv)
4035
4036 denom = 2.0*ck/(1.0 + ck*swl) + bx/(smc - swl)
4037 swlk = swl - df/denom
4038
4039! --- ... bounds useful for mathematical solution.
4040
4041 swlk = max( min( swlk, smc-0.02 ), 0.0 )
4042
4043! --- ... mathematical solution bounds applied.
4044
4045 dswl = abs(swlk - swl)
4046 swl = swlk
4047
4048! --- ... if more than 10 iterations, use explicit method (ck=0 approx.)
4049! when dswl less or eq. error, no more iterations required.
4050
4051 if ( dswl <= error ) then
4052 kcount = kcount + 1
4053 endif
4054 enddo ! end do_while_loop
4055
4056! --- ... bounds applied within do-block are valid for physical solution.
4057
4058 liqwat = smc - swl
4059
4060 endif ! end if_ck_block
4061
4062! --- ... option 2: explicit solution for flerchinger eq. i.e. ck=0
4063! in koren et al., jgr, 1999, eqn 17
4064! apply physical bounds to flerchinger solution
4065
4066 if (kcount == 0) then
4067 fk = ( ( (lsubf/(gs2*(-psis))) &
4068 & * ((tkelv-tfreez)/tkelv) )**(-1/bx) ) * smcmax
4069
4070 fk = max( fk, 0.02 )
4071
4072 liqwat = min( fk, smc )
4073 endif
4074
4075 endif ! end if_tkelv_block
4076!
4077 return
4078!...................................
4079 end subroutine frh2o
4080!-----------------------------------
4081
4082
4083!-----------------------------------
4089 subroutine hrt &
4090! --- inputs:
4091 & ( nsoil, stc, smc, smcmax, zsoil, yy, zz1, tbot, &
4092 & zbot, psisat, dt, bexp, df1, quartz, csoil, vegtyp, &
4093 & shdfac, lheatstrg, &
4094! --- input/outputs:
4095 & sh2o, &
4096! --- outputs:
4097 & rhsts, ai, bi, ci &
4098 & )
4099
4100! ===================================================================== !
4101! description: !
4102! !
4103! subroutine hrt calculates the right hand side of the time tendency !
4104! term of the soil thermal diffusion equation. also to compute !
4105! (prepare) the matrix coefficients for the tri-diagonal matrix of !
4106! the implicit time scheme. !
4107! !
4108! subprogram called: tbnd, snksrc, tmpavg !
4109! !
4110! !
4111! ==================== defination of variables ==================== !
4112! !
4113! inputs: size !
4114! nsoil - integer, number of soil layers 1 !
4115! stc - real, soil temperature nsoil !
4116! smc - real, total soil moisture nsoil !
4117! smcmax - real, porosity 1 !
4118! zsoil - real, soil layer depth below ground (negative) nsoil !
4119! yy - real, 1 !
4120! zz1 - real, soil temperture at the top soil column 1 !
4121! tbot - real, bottom soil temp 1 !
4122! zbot - real, specify depth of lower bd soil 1 !
4123! psisat - real, saturated soil potential 1 !
4124! dt - real, time step 1 !
4125! bexp - real, soil type "b" parameter 1 !
4126! df1 - real, thermal diffusivity 1 !
4127! quartz - real, soil quartz content 1 !
4128! csoil - real, soil heat capacity 1 !
4129! vegtyp - integer, vegetation type 1 !
4130! shdfac - real, aeral coverage of green vegetation 1 !
4131! lheatstrg- logical, flag for canopy heat storage 1 !
4132! parameterization !
4133! !
4134! input/outputs: !
4135! sh2o - real, unfrozen soil moisture nsoil !
4136! !
4137! outputs: !
4138! rhsts - real, time tendency of soil thermal diffusion nsoil !
4139! ai - real, matrix coefficients nsold !
4140! bi - real, matrix coefficients nsold !
4141! ci - real, matrix coefficients nsold !
4142! !
4143! ==================== end of description ===================== !
4144!
4145! --- inputs:
4146 integer, intent(in) :: nsoil, vegtyp
4147
4148 real (kind=kind_phys), intent(in) :: stc(nsoil), smc(nsoil), &
4149 & smcmax, zsoil(nsoil), yy, zz1, tbot, zbot, psisat, dt, &
4150 & bexp, df1, quartz, csoil, shdfac
4151
4152 logical, intent(in) :: lheatstrg
4153
4154! --- input/outputs:
4155 real (kind=kind_phys), intent(inout) :: sh2o(nsoil)
4156
4157! --- outputs:
4158 real (kind=kind_phys), intent(out) :: rhsts(nsoil), ai(nsold), &
4159 & bi(nsold), ci(nsold)
4160
4161! --- locals:
4162 real (kind=kind_phys) :: ddz, ddz2, denom, df1n, df1k, dtsdz, &
4163 & dtsdz2, hcpct, qtot, ssoil, sice, tavg, tbk, tbk1, &
4164 & tsnsr, tsurf, csoil_loc
4165
4166 integer :: i, k
4167
4168 logical :: itavg
4169
4170!
4171!===> ... begin here
4172!
4173 csoil_loc=csoil
4174
4175 if (.not.lheatstrg .and. ivegsrc == 1)then
4176!urban
4177!
4178!jhan urban canopy heat storage effect is included in pbl scheme
4179!
4180 if( vegtyp == 13 ) then
4181! csoil_loc=3.0e6
4182 csoil_loc=3.0e6*(1.-shdfac)+csoil*shdfac ! gvf
4183 endif
4184 endif
4185
4186! --- ... initialize logical for soil layer temperature averaging.
4187
4188 itavg = .true.
4189! itavg = .false.
4190
4191! === begin section for top soil layer
4192
4193! --- ... calc the heat capacity of the top soil layer
4194
4195 hcpct = sh2o(1)*cph2o2 + (1.0 - smcmax)*csoil_loc &
4196 & + (smcmax - smc(1))*cp2 + (smc(1) - sh2o(1))*cpice1
4197
4198! --- ... calc the matrix coefficients ai, bi, and ci for the top layer
4199
4200 ddz = 1.0 / ( -0.5*zsoil(2) )
4201 ai(1) = 0.0
4202 ci(1) = (df1*ddz) / ( zsoil(1)*hcpct )
4203 bi(1) = -ci(1) + df1 / ( 0.5*zsoil(1)*zsoil(1)*hcpct*zz1 )
4204
4205! --- ... calculate the vertical soil temp gradient btwn the 1st and 2nd soil
4206! layers. then calculate the subsurface heat flux. use the temp
4207! gradient and subsfc heat flux to calc "right-hand side tendency
4208! terms", or "rhsts", for top soil layer.
4209
4210 dtsdz = (stc(1) - stc(2)) / (-0.5*zsoil(2))
4211 ssoil = df1 * (stc(1) - yy) / (0.5*zsoil(1)*zz1)
4212 rhsts(1) = (df1*dtsdz - ssoil) / (zsoil(1)*hcpct)
4213
4214! --- ... next capture the vertical difference of the heat flux at top and
4215! bottom of first soil layer for use in heat flux constraint applied to
4216! potential soil freezing/thawing in routine snksrc.
4217
4218 qtot = ssoil - df1*dtsdz
4219
4220! --- ... if temperature averaging invoked (itavg=true; else skip):
4221! set temp "tsurf" at top of soil column (for use in freezing soil
4222! physics later in subroutine snksrc). if snowpack content is
4223! zero, then tsurf expression below gives tsurf = skin temp. if
4224! snowpack is nonzero (hence argument zz1=1), then tsurf expression
4225! below yields soil column top temperature under snowpack. then
4226! calculate temperature at bottom interface of 1st soil layer for use
4227! later in subroutine snksrc
4228
4229 if (itavg) then
4230
4231 tsurf = (yy + (zz1-1)*stc(1)) / zz1
4232
4233 call tbnd &
4234! --- inputs:
4235 & ( stc(1), stc(2), zsoil, zbot, 1, nsoil, &
4236! --- outputs:
4237 & tbk &
4238 & )
4239
4240 endif
4241
4242! --- ... calculate frozen water content in 1st soil layer.
4243
4244 sice = smc(1) - sh2o(1)
4245
4246! --- ... if frozen water present or any of layer-1 mid-point or bounding
4247! interface temperatures below freezing, then call snksrc to
4248! compute heat source/sink (and change in frozen water content)
4249! due to possible soil water phase change
4250
4251 if ( (sice > 0.0) .or. (tsurf < tfreez) .or. &
4252 & (stc(1) < tfreez) .or. (tbk < tfreez) ) then
4253
4254 if (itavg) then
4255
4256 call tmpavg &
4257! --- inputs:
4258 & ( tsurf, stc(1), tbk, zsoil, nsoil, 1, &
4259! --- outputs:
4260 & tavg &
4261 & )
4262
4263 else
4264
4265 tavg = stc(1)
4266
4267 endif ! end if_itavg_block
4268
4269 call snksrc &
4270! --- inputs:
4271 & ( nsoil, 1, tavg, smc(1), smcmax, psisat, bexp, dt, &
4272 & qtot, zsoil, &
4273! --- input/outputs:
4274 & sh2o(1), &
4275! --- outputs:
4276 & tsnsr &
4277 & )
4278
4279
4280 rhsts(1) = rhsts(1) - tsnsr / ( zsoil(1)*hcpct )
4281
4282 endif ! end if_sice_block
4283
4284! === this ends section for top soil layer.
4285
4286! --- ... initialize ddz2
4287
4288 ddz2 = 0.0
4289
4290! --- ... loop thru the remaining soil layers, repeating the above process
4291! (except subsfc or "ground" heat flux not repeated in lower layers)
4292
4293 df1k = df1
4294
4295 do k = 2, nsoil
4296
4297! --- ... calculate heat capacity for this soil layer.
4298
4299 hcpct = sh2o(k)*cph2o2 + (1.0 - smcmax)*csoil_loc &
4300 & + (smcmax - smc(k))*cp2 + (smc(k) - sh2o(k))*cpice1
4301
4302 if (k /= nsoil) then
4303
4304! --- ... this section for layer 2 or greater, but not last layer.
4305! calculate thermal diffusivity for this layer.
4306
4307 call tdfcnd &
4308! --- inputs:
4309 & ( smc(k), quartz, smcmax, sh2o(k), &
4310! --- outputs:
4311 & df1n &
4312 & )
4313!urban
4314! if (ivegsrc == 1)then
4315! if ( vegtyp == 13 ) df1n = 3.24
4316! endif
4317!wz only urban for igbp type
4318!
4319!jhan urban canopy heat storage effect is included in pbl scheme
4320!
4321 if((.not.lheatstrg) .and.
4322 & (ivegsrc == 1 .and. vegtyp == 13)) then
4323 df1n = 3.24*(1.-shdfac) + shdfac*df1n
4324 endif
4325
4326! --- ... calc the vertical soil temp gradient thru this layer
4327
4328 denom = 0.5 * (zsoil(k-1) - zsoil(k+1))
4329 dtsdz2 = (stc(k) - stc(k+1)) / denom
4330
4331! --- ... calc the matrix coef, ci, after calc'ng its partial product
4332
4333 ddz2 = 2.0 / (zsoil(k-1) - zsoil(k+1))
4334 ci(k) = -df1n*ddz2 / ((zsoil(k-1) - zsoil(k)) * hcpct)
4335
4336! --- ... if temperature averaging invoked (itavg=true; else skip):
4337! calculate temp at bottom of layer.
4338
4339 if (itavg) then
4340
4341 call tbnd &
4342! --- inputs:
4343 & ( stc(k), stc(k+1), zsoil, zbot, k, nsoil, &
4344! --- outputs:
4345 & tbk1 &
4346 & )
4347
4348 endif
4349
4350 else
4351
4352! --- ... special case of bottom soil layer: calculate thermal diffusivity
4353! for bottom layer.
4354
4355 call tdfcnd &
4356! --- inputs:
4357 & ( smc(k), quartz, smcmax, sh2o(k), &
4358! --- outputs:
4359 & df1n &
4360 & )
4361!urban
4362! if (ivegsrc == 1)then
4363! if ( vegtyp == 13 ) df1n = 3.24
4364! endif
4365!wz only urban for igbp type
4366!
4367!jhan urban canopy heat storage effect is included in pbl scheme
4368!
4369 if((.not.lheatstrg) .and.
4370 & (ivegsrc == 1 .and. vegtyp == 13)) then
4371 df1n = 3.24*(1.-shdfac) + shdfac*df1n
4372 endif
4373
4374! --- ... calc the vertical soil temp gradient thru bottom layer.
4375
4376 denom = 0.5 * (zsoil(k-1) + zsoil(k)) - zbot
4377 dtsdz2 = (stc(k) - tbot) / denom
4378
4379! --- ... set matrix coef, ci to zero if bottom layer.
4380
4381 ci(k) = 0.0
4382
4383! --- ... if temperature averaging invoked (itavg=true; else skip):
4384! calculate temp at bottom of last layer.
4385
4386 if (itavg) then
4387
4388 call tbnd &
4389! --- inputs:
4390 & ( stc(k), tbot, zsoil, zbot, k, nsoil, &
4391! --- outputs:
4392 & tbk1 &
4393 & )
4394
4395 endif
4396
4397 endif ! end if_k_block
4398
4399! --- ... calculate rhsts for this layer after calc'ng a partial product.
4400
4401 denom = (zsoil(k) - zsoil(k-1)) * hcpct
4402 rhsts(k) = ( df1n*dtsdz2 - df1k*dtsdz ) / denom
4403
4404 qtot = -1.0 * denom * rhsts(k)
4405 sice = smc(k) - sh2o(k)
4406
4407 if ( (sice > 0.0) .or. (tbk < tfreez) .or. &
4408 & (stc(k) < tfreez) .or. (tbk1 < tfreez) ) then
4409
4410 if (itavg) then
4411
4412 call tmpavg &
4413! --- inputs:
4414 & ( tbk, stc(k), tbk1, zsoil, nsoil, k, &
4415! --- outputs:
4416 & tavg &
4417 & )
4418
4419 else
4420 tavg = stc(k)
4421 endif
4422
4423 call snksrc &
4424! --- inputs:
4425 & ( nsoil, k, tavg, smc(k), smcmax, psisat, bexp, dt, &
4426 & qtot, zsoil, &
4427! --- input/outputs:
4428 & sh2o(k), &
4429! --- outputs:
4430 & tsnsr &
4431 & )
4432
4433 rhsts(k) = rhsts(k) - tsnsr/denom
4434 endif
4435
4436! --- ... calc matrix coefs, ai, and bi for this layer.
4437
4438 ai(k) = - df1 * ddz / ((zsoil(k-1) - zsoil(k)) * hcpct)
4439 bi(k) = -(ai(k) + ci(k))
4440
4441! --- ... reset values of df1, dtsdz, ddz, and tbk for loop to next soil layer.
4442
4443 tbk = tbk1
4444 df1k = df1n
4445 dtsdz = dtsdz2
4446 ddz = ddz2
4447
4448 enddo ! end do_k_loop
4449
4450!
4451 return
4452!...................................
4453 end subroutine hrt
4454!-----------------------------------
4455
4456
4457!-----------------------------------
4462 subroutine hrtice &
4463! --- inputs:
4464 & ( nsoil, stc, zsoil, yy, zz1, df1, ice, &
4465! --- input/outputs:
4466 & tbot, &
4467! --- outputs:
4468 & rhsts, ai, bi, ci &
4469 & )
4470
4471! ===================================================================== !
4472! description: !
4473! !
4474! subroutine hrtice calculates the right hand side of the time tendency!
4475! term of the soil thermal diffusion equation for sea-ice (ice = 1) or !
4476! glacial-ice (ice). compute (prepare) the matrix coefficients for the !
4477! tri-diagonal matrix of the implicit time scheme. !
4478! (note: this subroutine only called for sea-ice or glacial ice, but !
4479! not for non-glacial land (ice = 0). !
4480! !
4481! subprogram called: none !
4482! !
4483! !
4484! ==================== defination of variables ==================== !
4485! !
4486! inputs: size !
4487! nsoil - integer, number of soil layers 1 !
4488! stc - real, soil temperature nsoil !
4489! zsoil - real, soil depth (negative sign, as below grd) nsoil !
4490! yy - real, soil temperature at the top of column 1 !
4491! zz1 - real, 1 !
4492! df1 - real, thermal diffusivity and conductivity 1 !
4493! ice - integer, sea-ice flag (=1: sea-ice, =0: land) 1 !
4494! !
4495! input/outputs: !
4496! tbot - real, bottom soil temperature 1 !
4497! !
4498! outputs: !
4499! rhsts - real, time tendency of soil thermal diffusion nsoil !
4500! ai - real, matrix coefficients nsold !
4501! bi - real, matrix coefficients nsold !
4502! ci - real, matrix coefficients nsold !
4503! !
4504! ==================== end of description ===================== !
4505!
4506! --- inputs:
4507 integer, intent(in) :: nsoil, ice
4508
4509 real (kind=kind_phys), intent(in) :: stc(nsoil), zsoil(nsoil), &
4510 & yy, zz1, df1
4511
4512! --- input/outputs:
4513 real (kind=kind_phys), intent(inout) :: tbot
4514
4515! --- outputs:
4516 real (kind=kind_phys), intent(out) :: rhsts(nsoil), ai(nsold), &
4517 & bi(nsold), ci(nsold)
4518
4519! --- locals:
4520 real (kind=kind_phys) :: ddz, ddz2, denom, dtsdz, dtsdz2, &
4521 & hcpct, ssoil, zbot
4522
4523 integer :: k
4524
4525!
4526!===> ... begin here
4527!
4528! --- ... set a nominal universal value of the sea-ice specific heat capacity,
4529! hcpct = 1880.0*917.0 = 1.72396e+6 (source: fei chen, 1995)
4530! set bottom of sea-ice pack temperature: tbot = 271.16
4531! set a nominal universal value of glacial-ice specific heat capacity,
4532! hcpct = 2100.0*900.0 = 1.89000e+6 (source: bob grumbine, 2005)
4533! tbot passed in as argument, value from global data set
4534
4535 if (ice == 1) then
4536! --- ... sea-ice
4537 hcpct = 1.72396e+6
4538 tbot = 271.16
4539 else
4540! --- ... glacial-ice
4541 hcpct = 1.89000e+6
4542 endif
4543
4544! --- ... the input argument df1 is a universally constant value of sea-ice
4545! and glacial-ice thermal diffusivity, set in sflx as df1 = 2.2.
4546
4547! --- ... set ice pack depth. use tbot as ice pack lower boundary temperature
4548! (that of unfrozen sea water at bottom of sea ice pack). assume ice
4549! pack is of n=nsoil layers spanning a uniform constant ice pack
4550! thickness as defined by zsoil(nsoil) in routine sflx.
4551! if glacial-ice, set zbot = -25 meters
4552
4553 if (ice == 1) then
4554! --- ... sea-ice
4555 zbot = zsoil(nsoil)
4556 else
4557! --- ... glacial-ice
4558 zbot = -25.0
4559 endif
4560
4561! --- ... calc the matrix coefficients ai, bi, and ci for the top layer
4562
4563 ddz = 1.0 / (-0.5*zsoil(2))
4564 ai(1) = 0.0
4565 ci(1) = (df1*ddz) / (zsoil(1)*hcpct)
4566 bi(1) = -ci(1) + df1 / (0.5*zsoil(1)*zsoil(1)*hcpct*zz1)
4567
4568! --- ... calc the vertical soil temp gradient btwn the top and 2nd soil
4569! layers. recalc/adjust the soil heat flux. use the gradient and
4570! flux to calc rhsts for the top soil layer.
4571
4572 dtsdz = (stc(1) - stc(2)) / (-0.5*zsoil(2))
4573 ssoil = df1 * (stc(1) - yy) / (0.5*zsoil(1)*zz1)
4574 rhsts(1) = (df1*dtsdz - ssoil) / (zsoil(1)*hcpct)
4575
4576! --- ... initialize ddz2
4577
4578 ddz2 = 0.0
4579
4580! --- ... loop thru the remaining soil layers, repeating the above process
4581
4582 do k = 2, nsoil
4583
4584 if (k /= nsoil) then
4585
4586! --- ... calc the vertical soil temp gradient thru this layer.
4587
4588 denom = 0.5 * (zsoil(k-1) - zsoil(k+1))
4589 dtsdz2 = (stc(k) - stc(k+1)) / denom
4590
4591! --- ... calc the matrix coef, ci, after calc'ng its partial product.
4592
4593 ddz2 = 2.0 / (zsoil(k-1) - zsoil(k+1))
4594 ci(k) = -df1*ddz2 / ((zsoil(k-1) - zsoil(k))*hcpct)
4595
4596 else
4597
4598! --- ... calc the vertical soil temp gradient thru the lowest layer.
4599
4600 dtsdz2 = (stc(k) - tbot) &
4601 & / (0.5*(zsoil(k-1) + zsoil(k)) - zbot)
4602
4603! --- ... set matrix coef, ci to zero.
4604
4605 ci(k) = 0.0
4606
4607 endif ! end if_k_block
4608
4609! --- ... calc rhsts for this layer after calc'ng a partial product.
4610
4611 denom = (zsoil(k) - zsoil(k-1)) * hcpct
4612 rhsts(k) = (df1*dtsdz2 - df1*dtsdz) / denom
4613
4614! --- ... calc matrix coefs, ai, and bi for this layer.
4615
4616 ai(k) = - df1*ddz / ((zsoil(k-1) - zsoil(k)) * hcpct)
4617 bi(k) = -(ai(k) + ci(k))
4618
4619! --- ... reset values of dtsdz and ddz for loop to next soil lyr.
4620
4621 dtsdz = dtsdz2
4622 ddz = ddz2
4623
4624 enddo ! end do_k_loop
4625!
4626 return
4627!...................................
4628 end subroutine hrtice
4629!-----------------------------------
4630
4631
4632!-----------------------------------
4635 subroutine hstep &
4636! --- inputs:
4637 & ( nsoil, stcin, dt, &
4638! --- input/outputs:
4639 & rhsts, ai, bi, ci, &
4640! --- outputs:
4641 & stcout &
4642 & )
4643
4644! ===================================================================== !
4645! description: !
4646! !
4647! subroutine hstep calculates/updates the soil temperature field. !
4648! !
4649! subprogram called: rosr12 !
4650! !
4651! !
4652! ==================== defination of variables ==================== !
4653! !
4654! inputs: size !
4655! nsoil - integer, number of soil layers 1 !
4656! stcin - real, soil temperature nsoil !
4657! dt - real, time step 1 !
4658! !
4659! input/outputs: !
4660! rhsts - real, time tendency of soil thermal diffusion nsoil !
4661! ai - real, matrix coefficients nsold !
4662! bi - real, matrix coefficients nsold !
4663! ci - real, matrix coefficients nsold !
4664! !
4665! outputs: !
4666! stcout - real, updated soil temperature nsoil !
4667! !
4668! ==================== end of description ===================== !
4669!
4670! --- inputs:
4671 integer, intent(in) :: nsoil
4672
4673 real (kind=kind_phys), intent(in) :: stcin(nsoil), dt
4674
4675! --- input/outputs:
4676 real (kind=kind_phys), intent(inout) :: rhsts(nsoil), &
4677 & ai(nsold), bi(nsold), ci(nsold)
4678
4679! --- outputs:
4680 real (kind=kind_phys), intent(out) :: stcout(nsoil)
4681
4682! --- locals:
4683 integer :: k
4684
4685 real (kind=kind_phys) :: ciin(nsold), rhstsin(nsoil)
4686
4687!
4688!===> ... begin here
4689!
4690! --- ... create finite difference values for use in rosr12 routine
4691
4692 do k = 1, nsoil
4693 rhsts(k) = rhsts(k) * dt
4694 ai(k) = ai(k) * dt
4695 bi(k) = 1.0 + bi(k)*dt
4696 ci(k) = ci(k) * dt
4697 enddo
4698
4699! --- ... copy values for input variables before call to rosr12
4700
4701 do k = 1, nsoil
4702 rhstsin(k) = rhsts(k)
4703 enddo
4704
4705 do k = 1, nsold
4706 ciin(k) = ci(k)
4707 enddo
4708
4709! --- ... solve the tri-diagonal matrix equation
4710
4711 call rosr12 &
4712! --- inputs:
4713 & ( nsoil, ai, bi, rhstsin, &
4714! --- input/outputs:
4715 & ciin, &
4716! --- outputs:
4717 & ci, rhsts &
4718 & )
4719
4720! --- ... calc/update the soil temps using matrix solution
4721
4722 do k = 1, nsoil
4723 stcout(k) = stcin(k) + ci(k)
4724 enddo
4725!
4726 return
4727!...................................
4728 end subroutine hstep
4729!-----------------------------------
4730
4731
4732!-----------------------------------
4735 subroutine rosr12 &
4736! --- inputs:
4737 & ( nsoil, a, b, d, &
4738! --- input/outputs:
4739 & c, &
4740! --- outputs:
4741 & p, delta &
4742 & )
4743
4744! ===================================================================== !
4745! description: !
4746! !
4747! subroutine rosr12 inverts (solve) the tri-diagonal matrix problem !
4748! shown below: !
4749! !
4750! ### ### ### ### ### ###!
4751! #b(1), c(1), 0 , 0 , 0 , . . . , 0 # # # # #!
4752! #a(2), b(2), c(2), 0 , 0 , . . . , 0 # # # # #!
4753! # 0 , a(3), b(3), c(3), 0 , . . . , 0 # # # # d(3) #!
4754! # 0 , 0 , a(4), b(4), c(4), . . . , 0 # # p(4) # # d(4) #!
4755! # 0 , 0 , 0 , a(5), b(5), . . . , 0 # # p(5) # # d(5) #!
4756! # . . # # . # = # . #!
4757! # . . # # . # # . #!
4758! # . . # # . # # . #!
4759! # 0 , . . . , 0 , a(m-2), b(m-2), c(m-2), 0 # #p(m-2)# #d(m-2)#!
4760! # 0 , . . . , 0 , 0 , a(m-1), b(m-1), c(m-1)# #p(m-1)# #d(m-1)#!
4761! # 0 , . . . , 0 , 0 , 0 , a(m) , b(m) # # p(m) # # d(m) #!
4762! ### ### ### ### ### ###!
4763! !
4764! subprogram called: none !
4765! !
4766! !
4767! ==================== defination of variables ==================== !
4768! !
4769! inputs: size !
4770! nsoil - integer, number of soil layers 1 !
4771! a - real, matrix coefficients nsoil !
4772! b - real, matrix coefficients nsoil !
4773! d - real, soil water time tendency nsoil !
4774! !
4775! input/outputs: !
4776! c - real, matrix coefficients nsoil !
4777! !
4778! outputs: !
4779! p - real, nsoil !
4780! delta - real, nsoil !
4781! !
4782! ==================== end of description ===================== !
4783!
4784! --- inputs:
4785 integer, intent(in) :: nsoil
4786
4787 real (kind=kind_phys), dimension(nsoil), intent(in) :: a, b, d
4788
4789! --- input/outputs:
4790 real (kind=kind_phys), dimension(nsoil), intent(inout) :: c
4791
4792! --- outputs:
4793 real (kind=kind_phys), dimension(nsoil), intent(out) :: p, delta
4794
4795! --- locals:
4796 integer :: k, kk
4797
4798!
4799!===> ... begin here
4800!
4801! --- ... initialize eqn coef c for the lowest soil layer
4802
4803 c(nsoil) = 0.0
4804
4805! --- ... solve the coefs for the 1st soil layer
4806
4807 p(1) = -c(1) / b(1)
4808 delta(1) = d(1) / b(1)
4809
4810! --- ... solve the coefs for soil layers 2 thru nsoil
4811
4812 do k = 2, nsoil
4813 p(k) = -c(k) * ( 1.0 / (b(k) + a(k)*p(k-1)) )
4814 delta(k) = (d(k) - a(k)*delta(k-1)) &
4815 & * ( 1.0 / (b(k) + a(k)*p(k-1)) )
4816 enddo
4817
4818! --- ... set p to delta for lowest soil layer
4819
4820 p(nsoil) = delta(nsoil)
4821
4822! --- ... adjust p for soil layers 2 thru nsoil
4823
4824 do k = 2, nsoil
4825 kk = nsoil - k + 1
4826 p(kk) = p(kk)*p(kk+1) + delta(kk)
4827 enddo
4828!
4829 return
4830!...................................
4831 end subroutine rosr12
4832!-----------------------------------
4833
4834
4835!-----------------------------------
4838 subroutine snksrc &
4839! --- inputs:
4840 & ( nsoil, k, tavg, smc, smcmax, psisat, bexp, dt, &
4841 & qtot, zsoil, &
4842! --- input/outputs:
4843 & sh2o, &
4844! --- outputs:
4845 & tsrc &
4846 & )
4847
4848! ===================================================================== !
4849! description: !
4850! !
4851! subroutine snksrc calculates sink/source term of the termal !
4852! diffusion equation. !
4853! !
4854! subprograms called: frh2o !
4855! !
4856! !
4857! ==================== defination of variables ==================== !
4858! !
4859! inputs: size !
4860! nsoil - integer, number of soil layers 1 !
4861! k - integer, index of soil layers 1 !
4862! tavg - real, soil layer average temperature 1 !
4863! smc - real, total soil moisture 1 !
4864! smcmax - real, porosity 1 !
4865! psisat - real, saturated soil potential 1 !
4866! bexp - real, soil type "b" parameter 1 !
4867! dt - real, time step 1 !
4868! qtot - real, tot vertical diff of heat flux 1 !
4869! zsoil - real, soil layer depth below ground (negative) nsoil !
4870! !
4871! input/outputs: !
4872! sh2o - real, available liqued water 1 !
4873! !
4874! outputs: !
4875! tsrc - real, heat source/sink 1 !
4876! !
4877! ==================== end of description ===================== !
4878!
4879! --- parameter constants:
4880 real (kind=kind_phys), parameter :: dh2o = 1.0000e3
4881
4882! --- inputs:
4883 integer, intent(in) :: nsoil, k
4884
4885 real (kind=kind_phys), intent(in) :: tavg, smc, smcmax, psisat, &
4886 & bexp, dt, qtot, zsoil(nsoil)
4887
4888! --- input/outputs:
4889 real (kind=kind_phys), intent(inout) :: sh2o
4890
4891! --- outputs:
4892 real (kind=kind_phys), intent(out) :: tsrc
4893
4894! --- locals:
4895 real (kind=kind_phys) :: dz, free, xh2o
4896
4897! --- external functions:
4898! real (kind=kind_phys) :: frh2o
4899!
4900!===> ... begin here
4901!
4902 if (k == 1) then
4903 dz = -zsoil(1)
4904 else
4905 dz = zsoil(k-1) - zsoil(k)
4906 endif
4907
4908! --- ... via function frh2o, compute potential or 'equilibrium' unfrozen
4909! supercooled free water for given soil type and soil layer temperature.
4910! function frh20 invokes eqn (17) from v. koren et al (1999, jgr, vol.
4911! 104, pg 19573). (aside: latter eqn in journal in centigrade units.
4912! routine frh2o use form of eqn in kelvin units.)
4913
4914! free = frh2o( tavg,smc,sh2o,smcmax,bexp,psisat )
4915
4916 call frh2o &
4917! --- inputs:
4918 & ( tavg, smc, sh2o, smcmax, bexp, psisat, &
4919! --- outputs:
4920 & free &
4921 & )
4922
4923
4924! --- ... in next block of code, invoke eqn 18 of v. koren et al (1999, jgr,
4925! vol. 104, pg 19573.) that is, first estimate the new amountof liquid
4926! water, 'xh2o', implied by the sum of (1) the liquid water at the begin
4927! of current time step, and (2) the freeze of thaw change in liquid
4928! water implied by the heat flux 'qtot' passed in from routine hrt.
4929! second, determine if xh2o needs to be bounded by 'free' (equil amt) or
4930! if 'free' needs to be bounded by xh2o.
4931
4932 xh2o = sh2o + qtot*dt / (dh2o*lsubf*dz)
4933
4934! --- ... first, if freezing and remaining liquid less than lower bound, then
4935! reduce extent of freezing, thereby letting some or all of heat flux
4936! qtot cool the soil temp later in routine hrt.
4937
4938 if ( xh2o < sh2o .and. xh2o < free) then
4939 if ( free > sh2o ) then
4940 xh2o = sh2o
4941 else
4942 xh2o = free
4943 endif
4944 endif
4945
4946! --- ... second, if thawing and the increase in liquid water greater than
4947! upper bound, then reduce extent of thaw, thereby letting some or
4948! all of heat flux qtot warm the soil temp later in routine hrt.
4949
4950 if ( xh2o > sh2o .and. xh2o > free ) then
4951 if ( free < sh2o ) then
4952 xh2o = sh2o
4953 else
4954 xh2o = free
4955 endif
4956 endif
4957
4958 xh2o = max( min( xh2o, smc ), 0.0 )
4959
4960! --- ... calculate phase-change heat source/sink term for use in routine hrt
4961! and update liquid water to reflcet final freeze/thaw increment.
4962
4963 tsrc = -dh2o * lsubf * dz * (xh2o - sh2o) / dt
4964 sh2o = xh2o
4965!
4966 return
4967!...................................
4968 end subroutine snksrc
4969!-----------------------------------
4970
4971
4972!-----------------------------------
4978 subroutine srt &
4979! --- inputs:
4980 & ( nsoil, edir, et, sh2o, sh2oa, pcpdrp, zsoil, dwsat, &
4981 & dksat, smcmax, bexp, dt, smcwlt, slope, kdt, frzx, sice, &
4982! --- outputs:
4983 & rhstt, runoff1, runoff2, ai, bi, ci &
4984 & )
4985
4986! ===================================================================== !
4987! description: !
4988! subroutine srt calculates the right hand side of the time tendency !
4989! term of the soil water diffusion equation. also to compute !
4990! ( prepare ) the matrix coefficients for the tri-diagonal matrix !
4991! of the implicit time scheme. !
4992! !
4993! subprogram called: wdfcnd !
4994! !
4995! !
4996! ==================== defination of variables ==================== !
4997! !
4998! inputs: size !
4999! nsoil - integer, number of soil layers 1 !
5000! edir - real, direct soil evaporation 1 !
5001! et - real, plant transpiration nsoil !
5002! sh2o - real, unfrozen soil moisture nsoil !
5003! sh2oa - real, nsoil !
5004! pcpdrp - real, combined prcp and drip 1 !
5005! zsoil - real, soil layer depth below ground nsoil !
5006! dwsat - real, saturated soil diffusivity 1 !
5007! dksat - real, saturated soil hydraulic conductivity 1 !
5008! smcmax - real, porosity 1 !
5009! bexp - real, soil type "b" parameter 1 !
5010! dt - real, time step 1 !
5011! smcwlt - real, wilting point 1 !
5012! slope - real, linear reservoir coefficient 1 !
5013! kdt - real, 1 !
5014! frzx - real, frozen ground parameter 1 !
5015! sice - real, ice content at each soil layer nsoil !
5016! !
5017! outputs: !
5018! rhstt - real, soil water time tendency nsoil !
5019! runoff1 - real, surface runoff not infiltrating sfc 1 !
5020! runoff2 - real, sub surface runoff (baseflow) 1 !
5021! ai - real, matrix coefficients nsold !
5022! bi - real, matrix coefficients nsold !
5023! ci - real, matrix coefficients nsold !
5024! !
5025! ==================== end of description ===================== !
5026!
5027! --- inputs:
5028 integer, intent(in) :: nsoil
5029
5030 real (kind=kind_phys), dimension(nsoil), intent(in) :: et, &
5031 & sh2o, sh2oa, zsoil, sice
5032
5033 real (kind=kind_phys), intent(in) :: edir, pcpdrp, dwsat, dksat, &
5034 & smcmax, smcwlt, bexp, dt, slope, kdt, frzx
5035
5036! --- outputs:
5037 real (kind=kind_phys), intent(out) :: runoff1, runoff2, &
5038 & rhstt(nsoil), ai(nsold), bi(nsold), ci(nsold)
5039
5040
5041! --- locals:
5042 real (kind=kind_phys) :: acrt, dd, ddt, ddz, ddz2, denom, denom2, &
5043 & dice, dsmdz, dsmdz2, dt1, fcr, infmax, mxsmc, mxsmc2, px, &
5044 & numer, pddum, sicemax, slopx, smcav, sstt, sum, val, wcnd, &
5045 & wcnd2, wdf, wdf2, dmax(nsold)
5046
5047 integer :: cvfrz, ialp1, iohinf, j, jj, k, ks
5048!
5049!===> ... begin here
5050!
5051! --- ... frozen ground version:
5052! reference frozen ground parameter, cvfrz, is a shape parameter
5053! of areal distribution function of soil ice content which equals
5054! 1/cv. cv is a coefficient of spatial variation of soil ice content.
5055! based on field data cv depends on areal mean of frozen depth, and
5056! it close to constant = 0.6 if areal mean frozen depth is above 20 cm.
5057! that is why parameter cvfrz = 3 (int{1/0.6*0.6}). current logic
5058! doesn't allow cvfrz be bigger than 3
5059
5060 parameter(cvfrz = 3)
5061
5062c ----------------------------------------------------------------------
5063! --- ... determine rainfall infiltration rate and runoff. include
5064! the infiltration formule from schaake and koren model.
5065! modified by q duan
5066
5067 iohinf = 1
5068
5069! --- ... let sicemax be the greatest, if any, frozen water content within
5070! soil layers.
5071
5072 sicemax = 0.0
5073 do ks = 1, nsoil
5074 if (sice(ks) > sicemax) sicemax = sice(ks)
5075 enddo
5076
5077! --- ... determine rainfall infiltration rate and runoff
5078
5079 pddum = pcpdrp
5080 runoff1 = 0.0
5081
5082 if (pcpdrp /= 0.0) then
5083
5084! --- ... modified by q. duan, 5/16/94
5085
5086 dt1 = dt/86400.
5087 smcav = smcmax - smcwlt
5088 dmax(1) = -zsoil(1) * smcav
5089
5090! --- ... frozen ground version:
5091
5092 dice = -zsoil(1) * sice(1)
5093
5094 dmax(1) = dmax(1)*(1.0 - (sh2oa(1)+sice(1)-smcwlt)/smcav)
5095 dd = dmax(1)
5096
5097 do ks = 2, nsoil
5098
5099! --- ... frozen ground version:
5100
5101 dice = dice + ( zsoil(ks-1) - zsoil(ks) ) * sice(ks)
5102
5103 dmax(ks) = (zsoil(ks-1)-zsoil(ks))*smcav
5104 dmax(ks) = dmax(ks)*(1.0 - (sh2oa(ks)+sice(ks)-smcwlt)/smcav)
5105 dd = dd + dmax(ks)
5106 enddo
5107
5108! --- ... val = (1.-exp(-kdt*sqrt(dt1)))
5109! in below, remove the sqrt in above
5110
5111 val = 1.0 - exp(-kdt*dt1)
5112 ddt = dd * val
5113
5114 px = pcpdrp * dt
5115 if (px < 0.0) px = 0.0
5116
5117 infmax = (px*(ddt/(px+ddt)))/dt
5118
5119! --- ... frozen ground version:
5120! reduction of infiltration based on frozen ground parameters
5121
5122 fcr = 1.
5123
5124 if (dice > 1.e-2) then
5125 acrt = cvfrz * frzx / dice
5126 sum = 1.
5127
5128 ialp1 = cvfrz - 1
5129 do j = 1, ialp1
5130 k = 1
5131
5132 do jj = j+1,ialp1
5133 k = k * jj
5134 enddo
5135
5136 sum = sum + (acrt**( cvfrz-j)) / float(k)
5137 enddo
5138
5139 fcr = 1.0 - exp(-acrt) * sum
5140 endif
5141
5142 infmax = infmax * fcr
5143
5144! --- ... correction of infiltration limitation:
5145! if infmax .le. hydrolic conductivity assign infmax the value
5146! of hydrolic conductivity
5147
5148! mxsmc = max ( sh2oa(1), sh2oa(2) )
5149 mxsmc = sh2oa(1)
5150
5151 call wdfcnd &
5152! --- inputs:
5153 & ( mxsmc, smcmax, bexp, dksat, dwsat, sicemax, &
5154! --- outputs:
5155 & wdf, wcnd &
5156 & )
5157
5158 infmax = max( infmax, wcnd )
5159 infmax = min( infmax, px )
5160
5161 if (pcpdrp > infmax) then
5162 runoff1 = pcpdrp - infmax
5163 pddum = infmax
5164 endif
5165
5166 endif ! end if_pcpdrp_block
5167
5168! --- ... to avoid spurious drainage behavior, 'upstream differencing'
5169! in line below replaced with new approach in 2nd line:
5170! 'mxsmc = max(sh2oa(1), sh2oa(2))'
5171
5172 mxsmc = sh2oa(1)
5173
5174 call wdfcnd &
5175! --- inputs:
5176 & ( mxsmc, smcmax, bexp, dksat, dwsat, sicemax, &
5177! --- outputs:
5178 & wdf, wcnd &
5179 & )
5180
5181! --- ... calc the matrix coefficients ai, bi, and ci for the top layer
5182
5183 ddz = 1.0 / ( -.5*zsoil(2) )
5184 ai(1) = 0.0
5185 bi(1) = wdf * ddz / ( -zsoil(1) )
5186 ci(1) = -bi(1)
5187
5188! --- ... calc rhstt for the top layer after calc'ng the vertical soil
5189! moisture gradient btwn the top and next to top layers.
5190
5191 dsmdz = ( sh2o(1) - sh2o(2) ) / ( -.5*zsoil(2) )
5192 rhstt(1) = (wdf*dsmdz + wcnd - pddum + edir + et(1)) / zsoil(1)
5193 sstt = wdf * dsmdz + wcnd + edir + et(1)
5194
5195! --- ... initialize ddz2
5196
5197 ddz2 = 0.0
5198
5199! --- ... loop thru the remaining soil layers, repeating the abv process
5200
5201 do k = 2, nsoil
5202 denom2 = (zsoil(k-1) - zsoil(k))
5203
5204 if (k /= nsoil) then
5205 slopx = 1.0
5206
5207! --- ... again, to avoid spurious drainage behavior, 'upstream differencing'
5208! in line below replaced with new approach in 2nd line:
5209! 'mxsmc2 = max (sh2oa(k), sh2oa(k+1))'
5210
5211 mxsmc2 = sh2oa(k)
5212
5213 call wdfcnd &
5214! --- inputs:
5215 & ( mxsmc2, smcmax, bexp, dksat, dwsat, sicemax, &
5216! --- outputs:
5217 & wdf2, wcnd2 &
5218 & )
5219
5220! --- ... calc some partial products for later use in calc'ng rhstt
5221
5222 denom = (zsoil(k-1) - zsoil(k+1))
5223 dsmdz2 = (sh2o(k) - sh2o(k+1)) / (denom * 0.5)
5224
5225! --- ... calc the matrix coef, ci, after calc'ng its partial product
5226
5227 ddz2 = 2.0 / denom
5228 ci(k) = -wdf2 * ddz2 / denom2
5229
5230 else ! if_k_block
5231
5232! --- ... slope of bottom layer is introduced
5233
5234 slopx = slope
5235
5236! --- ... retrieve the soil water diffusivity and hydraulic conductivity
5237! for this layer
5238
5239 call wdfcnd &
5240! --- inputs:
5241 & ( sh2oa(nsoil), smcmax, bexp, dksat, dwsat, sicemax, &
5242! --- outputs:
5243 & wdf2, wcnd2 &
5244 & )
5245
5246! --- ... calc a partial product for later use in calc'ng rhstt
5247 dsmdz2 = 0.0
5248
5249! --- ... set matrix coef ci to zero
5250
5251 ci(k) = 0.0
5252
5253 endif ! end if_k_block
5254
5255! --- ... calc rhstt for this layer after calc'ng its numerator
5256
5257 numer = wdf2*dsmdz2 + slopx*wcnd2 - wdf*dsmdz - wcnd + et(k)
5258 rhstt(k) = numer / (-denom2)
5259
5260! --- ... calc matrix coefs, ai, and bi for this layer
5261
5262 ai(k) = -wdf * ddz / denom2
5263 bi(k) = -( ai(k) + ci(k) )
5264
5265! --- ... reset values of wdf, wcnd, dsmdz, and ddz for loop to next lyr
5266! runoff2: sub-surface or baseflow runoff
5267
5268 if (k == nsoil) then
5269 runoff2 = slopx * wcnd2
5270 endif
5271
5272 if (k /= nsoil) then
5273 wdf = wdf2
5274 wcnd = wcnd2
5275 dsmdz= dsmdz2
5276 ddz = ddz2
5277 endif
5278 enddo ! end do_k_loop
5279!
5280 return
5281!...................................
5282 end subroutine srt
5283!-----------------------------------
5284
5285
5286!-----------------------------------
5290 subroutine sstep &
5291! --- inputs:
5292 & ( nsoil, sh2oin, rhsct, dt, smcmax, cmcmax, zsoil, sice, &
5293! --- input/outputs:
5294 & cmc, rhstt, ai, bi, ci, &
5295! --- outputs:
5296 & sh2oout, runoff3, smc &
5297 & )
5298
5299! ===================================================================== !
5300! description: !
5301! subroutine sstep calculates/updates soil moisture content values !
5302! and canopy moisture content values. !
5303! !
5304! subprogram called: rosr12 !
5305! !
5306! !
5307! ==================== defination of variables ==================== !
5308! !
5309! inputs: size !
5310! nsoil - integer, number of soil layers 1 !
5311! sh2oin - real, unfrozen soil moisture nsoil !
5312! rhsct - real, 1 !
5313! dt - real, time step 1 !
5314! smcmax - real, porosity 1 !
5315! cmcmax - real, maximum canopy water parameters 1 !
5316! zsoil - real, soil layer depth below ground nsoil !
5317! sice - real, ice content at each soil layer nsoil !
5318! !
5319! input/outputs: !
5320! cmc - real, canopy moisture content 1 !
5321! rhstt - real, soil water time tendency nsoil !
5322! ai - real, matrix coefficients nsold !
5323! bi - real, matrix coefficients nsold !
5324! ci - real, matrix coefficients nsold !
5325! !
5326! outputs: !
5327! sh2oout - real, updated soil moisture content nsoil !
5328! runoff3 - real, excess of porosity 1 !
5329! smc - real, total soil moisture nsoil !
5330! !
5331! ==================== end of description ===================== !
5332!
5333! --- input:
5334 integer, intent(in) :: nsoil
5335
5336 real (kind=kind_phys), dimension(nsoil), intent(in) :: sh2oin, &
5337 & zsoil, sice
5338
5339 real (kind=kind_phys), intent(in) :: rhsct, dt, smcmax, cmcmax
5340
5341! --- inout/outputs:
5342 real (kind=kind_phys), intent(inout) :: cmc, rhstt(nsoil), &
5343 & ai(nsold), bi(nsold), ci(nsold)
5344
5345! --- outputs:
5346 real (kind=kind_phys), intent(out) :: sh2oout(nsoil), runoff3, &
5347 & smc(nsoil)
5348
5349! --- locals:
5350 real (kind=kind_phys) :: ciin(nsold), rhsttin(nsoil), ddz, stot, &
5351 & wplus
5352
5353 integer :: i, k, kk11
5354!
5355!===> ... begin here
5356!
5357! --- ... create 'amount' values of variables to be input to the
5358! tri-diagonal matrix routine.
5359
5360 do k = 1, nsoil
5361 rhstt(k) = rhstt(k) * dt
5362 ai(k) = ai(k) * dt
5363 bi(k) = 1. + bi(k) * dt
5364 ci(k) = ci(k) * dt
5365 enddo
5366
5367! --- ... copy values for input variables before call to rosr12
5368
5369 do k = 1, nsoil
5370 rhsttin(k) = rhstt(k)
5371 enddo
5372
5373 do k = 1, nsold
5374 ciin(k) = ci(k)
5375 enddo
5376
5377! --- ... call rosr12 to solve the tri-diagonal matrix
5378
5379 call rosr12 &
5380! --- inputs:
5381 & ( nsoil, ai, bi, rhsttin, &
5382! --- input/outputs:
5383 & ciin, &
5384! --- outputs:
5385 & ci, rhstt &
5386 & )
5387
5388! --- ... sum the previous smc value and the matrix solution to get
5389! a new value. min allowable value of smc will be 0.02.
5390! runoff3: runoff within soil layers
5391
5392 wplus = 0.0
5393 runoff3 = 0.0
5394 ddz = -zsoil(1)
5395
5396 do k = 1, nsoil
5397 if (k /= 1) ddz = zsoil(k - 1) - zsoil(k)
5398
5399 sh2oout(k) = sh2oin(k) + ci(k) + wplus/ddz
5400
5401 stot = sh2oout(k) + sice(k)
5402 if (stot > smcmax) then
5403 if (k == 1) then
5404 ddz = -zsoil(1)
5405 else
5406 kk11 = k - 1
5407 ddz = -zsoil(k) + zsoil(kk11)
5408 endif
5409
5410 wplus = (stot - smcmax) * ddz
5411 else
5412 wplus = 0.0
5413 endif
5414
5415 smc(k) = max( min( stot, smcmax ), 0.02 )
5416 sh2oout(k) = max( smc(k)-sice(k), 0.0 )
5417 enddo
5418
5419 runoff3 = wplus
5420
5421! --- ... update canopy water content/interception (cmc). convert rhsct to
5422! an 'amount' value and add to previous cmc value to get new cmc.
5423
5424 cmc = cmc + dt*rhsct
5425 if (cmc < 1.e-20) cmc = 0.0
5426 cmc = min( cmc, cmcmax )
5427!
5428 return
5429!...................................
5430 end subroutine sstep
5431!-----------------------------------
5432
5433
5434!-----------------------------------
5438 subroutine tbnd &
5439! --- inputs:
5440 & ( tu, tb, zsoil, zbot, k, nsoil, &
5441! --- outputs:
5442 & tbnd1 &
5443 & )
5444
5445! ===================================================================== !
5446! description: !
5447! !
5448! subroutine tbnd calculates temperature on the boundary of the !
5449! layer by interpolation of the middle layer temperatures !
5450! !
5451! subprogram called: none !
5452! !
5453! ==================== defination of variables ==================== !
5454! !
5455! inputs: size !
5456! tu - real, soil temperature 1 !
5457! tb - real, bottom soil temp 1 !
5458! zsoil - real, soil layer depth nsoil !
5459! zbot - real, specify depth of lower bd soil 1 !
5460! k - integer, soil layer index 1 !
5461! nsoil - integer, number of soil layers 1 !
5462! !
5463! outputs: !
5464! tbnd1 - real, temperature at bottom interface of the lyr 1 !
5465! !
5466! ==================== end of description ===================== !
5467!
5468! --- input:
5469 integer, intent(in) :: k, nsoil
5470
5471 real (kind=kind_phys), intent(in) :: tu, tb, zbot, zsoil(nsoil)
5472
5473! --- output:
5474 real (kind=kind_phys), intent(out) :: tbnd1
5475
5476! --- locals:
5477 real (kind=kind_phys) :: zb, zup
5478
5479! --- ... use surface temperature on the top of the first layer
5480
5481 if (k == 1) then
5482 zup = 0.0
5483 else
5484 zup = zsoil(k-1)
5485 endif
5486
5487! --- ... use depth of the constant bottom temperature when interpolate
5488! temperature into the last layer boundary
5489
5490 if (k == nsoil) then
5491 zb = 2.0*zbot - zsoil(k)
5492 else
5493 zb = zsoil(k+1)
5494 endif
5495
5496! --- ... linear interpolation between the average layer temperatures
5497
5498 tbnd1 = tu + (tb-tu)*(zup-zsoil(k))/(zup-zb)
5499!
5500 return
5501!...................................
5502 end subroutine tbnd
5503!-----------------------------------
5504
5505
5506!-----------------------------------
5513 subroutine tmpavg &
5514! --- inputs:
5515 & ( tup, tm, tdn, zsoil, nsoil, k, &
5516! --- outputs:
5517 & tavg &
5518 & )
5519
5520! ===================================================================== !
5521! description: !
5522! subroutine tmpavg calculates soil layer average temperature (tavg) !
5523! in freezing/thawing layer using up, down, and middle layer !
5524! temperatures (tup, tdn, tm), where tup is at top boundary of !
5525! layer, tdn is at bottom boundary of layer. tm is layer prognostic !
5526! state temperature. !
5527! !
5528! !
5529! subprogram called: none !
5530! !
5531!
5532! ==================== defination of variables ==================== !
5533! !
5534! inputs: size !
5535! tup - real, temperature ar top boundary of layer 1 !
5536! tm - real, layer prognostic state temperature 1 !
5537! tdn - real, temperature ar bottom boundary of layer 1 !
5538! zsoil - real, soil layer depth nsoil !
5539! nsoil - integer, number of soil layers 1 !
5540! k - integer, layer index 1 !
5541! outputs: !
5542! tavg - real, soil layer average temperature 1 !
5543! !
5544! ==================== end of description ===================== !
5545!
5546! --- input:
5547 integer, intent(in) :: nsoil, k
5548
5549 real (kind=kind_phys), intent(in) :: tup, tm, tdn, zsoil(nsoil)
5550
5551! --- output:
5552 real (kind=kind_phys), intent(out) :: tavg
5553
5554! --- locals:
5555 real (kind=kind_phys) :: dz, dzh, x0, xdn, xup
5556!
5557!===> ... begin here
5558!
5559 if (k == 1) then
5560 dz = -zsoil(1)
5561 else
5562 dz = zsoil(k-1) - zsoil(k)
5563 endif
5564
5565 dzh = dz * 0.5
5566
5567 if (tup < tfreez) then
5568
5569 if (tm < tfreez) then
5570 if (tdn < tfreez) then ! tup, tm, tdn < t0
5571 tavg = (tup + 2.0*tm + tdn) / 4.0
5572 else ! tup & tm < t0, tdn >= t0
5573 x0 = (tfreez - tm) * dzh / (tdn - tm)
5574 tavg = 0.5*(tup*dzh + tm*(dzh+x0)+tfreez*(2.*dzh-x0)) / dz
5575 endif
5576 else
5577 if (tdn < tfreez) then ! tup < t0, tm >= t0, tdn < t0
5578 xup = (tfreez-tup) * dzh / (tm-tup)
5579 xdn = dzh - (tfreez-tm) * dzh / (tdn-tm)
5580 tavg = 0.5*(tup*xup + tfreez*(2.*dz-xup-xdn)+tdn*xdn) / dz
5581 else ! tup < t0, tm >= t0, tdn >= t0
5582 xup = (tfreez-tup) * dzh / (tm-tup)
5583 tavg = 0.5*(tup*xup + tfreez*(2.*dz-xup)) / dz
5584 endif
5585 endif
5586
5587 else ! if_tup_block
5588
5589 if (tm < tfreez) then
5590 if (tdn < tfreez) then ! tup >= t0, tm < t0, tdn < t0
5591 xup = dzh - (tfreez-tup) * dzh / (tm-tup)
5592 tavg = 0.5*(tfreez*(dz-xup) + tm*(dzh+xup)+tdn*dzh) / dz
5593 else ! tup >= t0, tm < t0, tdn >= t0
5594 xup = dzh - (tfreez-tup) * dzh / (tm-tup)
5595 xdn = (tfreez-tm) * dzh / (tdn-tm)
5596 tavg = 0.5 * (tfreez*(2.*dz-xup-xdn) + tm*(xup+xdn)) / dz
5597 endif
5598 else
5599 if (tdn < tfreez) then ! tup >= t0, tm >= t0, tdn < t0
5600 xdn = dzh - (tfreez-tm) * dzh / (tdn-tm)
5601 tavg = (tfreez*(dz-xdn) + 0.5*(tfreez+tdn)*xdn) / dz
5602 else ! tup >= t0, tm >= t0, tdn >= t0
5603 tavg = (tup + 2.0*tm + tdn) / 4.0
5604 endif
5605 endif
5606
5607 endif ! end if_tup_block
5608!
5609 return
5610!...................................
5611 end subroutine tmpavg
5612!-----------------------------------
5613
5614
5615!-----------------------------------
5618 subroutine transp &
5619! --- inputs:
5620 & ( nsoil, nroot, etp1, smc, smcwlt, smcref, &
5621 & cmc, cmcmax, zsoil, shdfac, pc, cfactr, rtdis, &
5622! --- outputs:
5623 & et1 &
5624 & )
5625
5626! ===================================================================== !
5627! description: !
5628! subroutine transp calculates transpiration for the veg class. !
5629! !
5630! subprogram called: none !
5631! !
5632! !
5633! ==================== defination of variables ==================== !
5634! !
5635! inputs: size !
5636! nsoil - integer, number of soil layers 1 !
5637! nroot - integer, number of root layers 1 !
5638! etp1 - real, potential evaporation 1 !
5639! smc - real, unfrozen soil moisture nsoil !
5640! smcwlt - real, wilting point 1 !
5641! smcref - real, soil mois threshold 1 !
5642! cmc - real, canopy moisture content 1 !
5643! cmcmax - real, maximum canopy water parameters 1 !
5644! zsoil - real, soil layer depth below ground nsoil !
5645! shdfac - real, aeral coverage of green vegetation 1 !
5646! pc - real, plant coeff 1 !
5647! cfactr - real, canopy water parameters 1 !
5648! rtdis - real, root distribution nsoil !
5649! !
5650! outputs: !
5651! et1 - real, plant transpiration nsoil !
5652! !
5653! ==================== end of description ===================== !
5654!
5655! --- input:
5656 integer, intent(in) :: nsoil, nroot
5657
5658 real (kind=kind_phys), intent(in) :: etp1, smcwlt, smcref, &
5659 & cmc, cmcmax, shdfac, pc, cfactr
5660
5661 real (kind=kind_phys), dimension(nsoil), intent(in) :: smc, &
5662 & zsoil, rtdis
5663
5664! --- output:
5665 real (kind=kind_phys), dimension(nsoil), intent(out) :: et1
5666
5667! --- locals:
5668 real (kind=kind_phys) :: denom, etp1a, rtx, sgx, gx(7)
5669
5670 integer :: i, k
5671!
5672!===> ... begin here
5673!
5674! --- ... initialize plant transp to zero for all soil layers.
5675
5676 do k = 1, nsoil
5677 et1(k) = 0.0
5678 enddo
5679
5680! --- ... calculate an 'adjusted' potential transpiration
5681! if statement below to avoid tangent linear problems near zero
5682! note: gx and other terms below redistribute transpiration by layer,
5683! et(k), as a function of soil moisture availability, while preserving
5684! total etp1a.
5685
5686 if (cmc /= 0.0) then
5687 etp1a = shdfac * pc * etp1 * (1.0 - (cmc /cmcmax) ** cfactr)
5688 else
5689 etp1a = shdfac * pc * etp1
5690 endif
5691
5692 sgx = 0.0
5693 do i = 1, nroot
5694 gx(i) = ( smc(i) - smcwlt ) / ( smcref - smcwlt )
5695 gx(i) = max( min( gx(i), 1.0 ), 0.0 )
5696 sgx = sgx + gx(i)
5697 enddo
5698 sgx = sgx / nroot
5699
5700 denom = 0.0
5701 do i = 1, nroot
5702 rtx = rtdis(i) + gx(i) - sgx
5703 gx(i) = gx(i) * max( rtx, 0.0 )
5704 denom = denom + gx(i)
5705 enddo
5706 if (denom <= 0.0) denom = 1.0
5707
5708 do i = 1, nroot
5709 et1(i) = etp1a * gx(i) / denom
5710 enddo
5711
5712! --- ... above code assumes a vertically uniform root distribution
5713! code below tests a variable root distribution
5714
5715! et(1) = ( zsoil(1) / zsoil(nroot) ) * gx * etp1a
5716! et(1) = ( zsoil(1) / zsoil(nroot) ) * etp1a
5717
5718! --- ... using root distribution as weighting factor
5719
5720! et(1) = rtdis(1) * etp1a
5721! et(1) = etp1a * part(1)
5722
5723! --- ... loop down thru the soil layers repeating the operation above,
5724! but using the thickness of the soil layer (rather than the
5725! absolute depth of each layer) in the final calculation.
5726
5727! do k = 2, nroot
5728! gx = ( smc(k) - smcwlt ) / ( smcref - smcwlt )
5729! gx = max ( min ( gx, 1.0 ), 0.0 )
5730! --- ... test canopy resistance
5731! gx = 1.0
5732! et(k) = ((zsoil(k)-zsoil(k-1))/zsoil(nroot))*gx*etp1a
5733! et(k) = ((zsoil(k)-zsoil(k-1))/zsoil(nroot))*etp1a
5734
5735! --- ... using root distribution as weighting factor
5736
5737! et(k) = rtdis(k) * etp1a
5738! et(k) = etp1a*part(k)
5739! enddo
5740
5741!
5742 return
5743!...................................
5744 end subroutine transp
5745!-----------------------------------
5746
5747
5748!-----------------------------------
5752 subroutine wdfcnd &
5753! --- inputs:
5754 & ( smc, smcmax, bexp, dksat, dwsat, sicemax, &
5755! --- outputs:
5756 & wdf, wcnd &
5757 & )
5758
5759! ===================================================================== !
5760! description: !
5761! subroutine wdfcnd calculates soil water diffusivity and soil !
5762! hydraulic conductivity. !
5763! !
5764! subprogram called: none !
5765! !
5766! !
5767! ==================== defination of variables ==================== !
5768! !
5769! inputs: size !
5770! smc - real, layer total soil moisture 1 !
5771! smcmax - real, porosity 1 !
5772! bexp - real, soil type "b" parameter 1 !
5773! dksat - real, saturated soil hydraulic conductivity 1 !
5774! dwsat - real, saturated soil diffusivity 1 !
5775! sicemax - real, max frozen water content in soil layer 1 !
5776! !
5777! outputs: !
5778! wdf - real, soil water diffusivity 1 !
5779! wcnd - real, soil hydraulic conductivity 1 !
5780! !
5781! ==================== end of description ===================== !
5782!
5783! --- input:
5784 real (kind=kind_phys), intent(in) :: smc, smcmax, bexp, dksat, &
5785 & dwsat, sicemax
5786
5787! --- output:
5788 real (kind=kind_phys), intent(out) :: wdf, wcnd
5789
5790! --- locals:
5791 real (kind=kind_phys) :: expon, factr1, factr2, vkwgt
5792!
5793!===> ... begin here
5794!
5795! --- ... calc the ratio of the actual to the max psbl soil h2o content
5796
5797 factr1 = min(1.0, max(0.0, 0.2/smcmax))
5798 factr2 = min(1.0, max(0.0, smc/smcmax))
5799
5800! --- ... prep an expntl coef and calc the soil water diffusivity
5801
5802 expon = bexp + 2.0
5803 wdf = dwsat * factr2 ** expon
5804
5805! --- ... frozen soil hydraulic diffusivity. very sensitive to the vertical
5806! gradient of unfrozen water. the latter gradient can become very
5807! extreme in freezing/thawing situations, and given the relatively
5808! few and thick soil layers, this gradient sufferes serious
5809! trunction errors yielding erroneously high vertical transports of
5810! unfrozen water in both directions from huge hydraulic diffusivity.
5811! therefore, we found we had to arbitrarily constrain wdf
5812!
5813! version d_10cm: ....... factr1 = 0.2/smcmax
5814! weighted approach....... pablo grunmann, 28_sep_1999.
5815
5816 if (sicemax > 0.0) then
5817 vkwgt = 1.0 / (1.0 + (500.0*sicemax)**3.0)
5818 wdf = vkwgt*wdf + (1.0- vkwgt)*dwsat*factr1**expon
5819 endif
5820
5821! --- ... reset the expntl coef and calc the hydraulic conductivity
5822
5823 expon = (2.0 * bexp) + 3.0
5824 wcnd = dksat * factr2 ** expon
5825!
5826 return
5827!...................................
5828 end subroutine wdfcnd
5829!-----------------------------------
5830
5831! =========================== !
5832! end contain programs !
5833! =========================== !
5834
5835!...................................
5836 end subroutine gfssflx
5837!-----------------------------------
5838 end module sflx
subroutine csnow
This subroutine calculates snow termal conductivity.
Definition sflx.f:1229
subroutine alcalc
This subroutine calculates albedo including snow effect (0 -> 1).
Definition sflx.f:987
subroutine snksrc(nsoil, k, tavg, smc, smcmax, psisat, bexp, dt, qtot, zsoil, sh2o, tsrc)
This subroutine calculates sink/source term of the termal diffusion equation.
Definition sflx.f:4847
subroutine redprm(errmsg, errflg)
This subroutine internally sets default values or optionally read-in via namelist i/o,...
Definition sflx.f:1686
subroutine sstep(nsoil, sh2oin, rhsct, dt, smcmax, cmcmax, zsoil, sice, cmc, rhstt, ai, bi, ci, sh2oout, runoff3, smc)
This subroutine calculates/updates soil moisture content values and canopy moisture content values.
Definition sflx.f:5298
subroutine penman
This subroutine calculates potential evaporation for the current point. various partial sums/products...
Definition sflx.f:1574
subroutine hrtice(nsoil, stc, zsoil, yy, zz1, df1, ice, tbot, rhsts, ai, bi, ci)
This subroutine calculates the right hand side of the time tendency term of the soil thermal diffusio...
Definition sflx.f:4470
subroutine gfssflx(nsoil, couple, icein, ffrozp, dt, zlvl, sldpth, swdn, swnet, lwdn, sfcems, sfcprs, sfctmp, sfcspd, prcp, q2, q2sat, dqsdt2, th2, ivegsrc, vegtyp, soiltyp, slopetyp, shdmin, alb, snoalb, rhonewsn, exticeden, bexpp, xlaip, lheatstrg, tbot, cmc, t1, stc, smc, sh2o, sneqv, ch, cm, z0, nroot, shdfac, snowh, albedo, eta, sheat, ec, edir, et, ett, esnow, drip, dew, beta, etp, ssoil, flx1, flx2, flx3, runoff1, runoff2, runoff3, snomlt, sncovr, rc, pc, rsmin, xlai, rcs, rct, rcq, rcsoil, soilw, soilm, smcwlt, smcdry, smcref, smcmax, errmsg, errflg)
This is the entity of GFS Noah LSM model of physics subroutines. It is a soil/veg/snowpack land-surfa...
Definition sflx.f:131
subroutine rosr12(nsoil, a, b, d, c, p, delta)
This subroutine inverts (solve) the tri-diagonal matrix problem.
Definition sflx.f:4743
subroutine evapo(nsoil, nroot, cmc, cmcmax, etp1, dt, zsoil, sh2o, smcmax, smcwlt, smcref, smcdry, pc, shdfac, cfactr, rtdis, fxexp, eta1, edir1, ec1, et1, ett1)
This subroutine calculates soil moisture flux. The soil moisture content (smc - a per unit volume mea...
Definition sflx.f:3164
subroutine transp(nsoil, nroot, etp1, smc, smcwlt, smcref, cmc, cmcmax, zsoil, shdfac, pc, cfactr, rtdis, et1)
This subroutine calculates transpiration for the veg class.
Definition sflx.f:5625
subroutine frh2o(tkelv, smc, sh2o, smcmax, bexp, psis, liqwat)
This subroutine calculates amount of supercooled liquid soil water content if temperature is below 27...
Definition sflx.f:3940
subroutine tdfcnd(smc, qz, smcmax, sh2o, df)
This subroutine calculates thermal diffusivity and conductivity of the soil for a given point and tim...
Definition sflx.f:3015
subroutine tbnd(tu, tb, zsoil, zbot, k, nsoil, tbnd1)
This subroutine calculates temperature on the boundary of the layer by interpolation of the middle la...
Definition sflx.f:5444
subroutine nopac
This subroutine calculates soil moisture and heat flux values and update soil moisture content and so...
Definition sflx.f:1294
subroutine snowz0
This subroutine calculates total roughness length over snow.
Definition sflx.f:2957
subroutine shflx(nsoil, smc, smcmax, dt, yy, zz1, zsoil, zbot, psisat, bexp, df1, ice, quartz, csoil, vegtyp, shdfac, lheatstrg, stc, t1, tbot, sh2o, ssoil)
This subroutine updates the temperature state of the soil column based on the thermal diffusion equat...
Definition sflx.f:3315
subroutine canres
This subroutine calculates canopy resistance which depends on incoming solar radiation,...
Definition sflx.f:1074
subroutine snowpack(esd, dtsec, tsnow, tsoil, snowh, sndens)
This subroutine calculates compaction of a snowpack under conditions of increasing snow density,...
Definition sflx.f:3697
subroutine snow_new
This subroutine calculates snow depth and densitity to account for the new snowfall....
Definition sflx.f:2879
subroutine hrt(nsoil, stc, smc, smcmax, zsoil, yy, zz1, tbot, zbot, psisat, dt, bexp, df1, quartz, csoil, vegtyp, shdfac, lheatstrg, sh2o, rhsts, ai, bi, ci)
This subroutine calculates the right hand side of the time tendency term of the soil thermal diffusio...
Definition sflx.f:4099
subroutine devap(etp1, smc, shdfac, smcmax, smcdry, fxexp, edir1)
This subrtouine calculates direct soil evaporation.
Definition sflx.f:3860
subroutine wdfcnd(smc, smcmax, bexp, dksat, dwsat, sicemax, wdf, wcnd)
This subroutine calculates soil water diffusivity and soil hydraulic conductivity.
Definition sflx.f:5758
subroutine hstep(nsoil, stcin, dt, rhsts, ai, bi, ci, stcout)
This subroutine calculates/updates the soil temperature field.
Definition sflx.f:4643
subroutine snopac
This subroutine calculates soil moisture and heat flux values and update soil moisture content and so...
Definition sflx.f:2351
subroutine tmpavg(tup, tm, tdn, zsoil, nsoil, k, tavg)
This subroutine calculates soil layer average temperature (tavg) in freezing/thawing layer using up,...
Definition sflx.f:5519
subroutine srt(nsoil, edir, et, sh2o, sh2oa, pcpdrp, zsoil, dwsat, dksat, smcmax, bexp, dt, smcwlt, slope, kdt, frzx, sice, rhstt, runoff1, runoff2, ai, bi, ci)
This subroutine calculates the right hand side of the time tendency term of the soil water diffusion ...
Definition sflx.f:4985
subroutine smflx(nsoil, dt, kdt, smcmax, smcwlt, cmcmax, prcp1, zsoil, slope, frzx, bexp, dksat, dwsat, shdfac, edir1, ec1, et1, cmc, sh2o, smc, runoff1, runoff2, runoff3, drip)
This subroutine calculates soil moisture flux. The soil moisture content (smc - a per unit vulume mea...
Definition sflx.f:3489
subroutine snfrac
This subroutine calculates snow fraction (0->1).
Definition sflx.f:2278
subroutine sfcdif
This subroutine calculates surface layer exchange coefficients via iterative process(see Chen et al....
Definition sflx.f:1991
subroutine albedo(parameters, vegtyp, ist, ice, nsoil, dt, cosz, fage, elai, esai, tg, tv, snowh, fsno, fwet, smc, sneqvo, sneqv, qsnow, fveg, iloc, jloc, albold, tauss, albgrd, albgri, albd, albi, fabd, fabi, ftdd, ftid, ftii, fsun, frevi, frevd, fregd, fregi, bgap, wgap, albsnd, albsni)
surface albedos. also fluxes (per unit incoming direct and diffuse radiation) reflected,...
subroutine error(parameters, swdown,fsa,fsr,fira,fsh,fcev, fgev,fctr,ssoil,beg_wb,canliq,canice, sneqv,wa,smc,dzsnso,prcp,ecan, etran,edir,runsrf,runsub,dt,nsoil, nsnow,ist,errwat, iloc,jloc,fveg, sav,sag,fsrv,fsrg,zwt,pah, ifdef ccpp
check surface energy balance and water balance.
This module contains namelist options for Noah LSM.
This module contains the entity of GFS Noah LSM Model(Version 2.7).
Definition sflx.f:5