@@ -38,6 +38,7 @@ module FATESPlantRespPhotosynthMod
3838 use FatesInterfaceTypesMod, only : hlm_parteh_mode
3939 use FatesInterfaceTypesMod, only : numpft
4040 use FatesInterfaceTypesMod, only : nleafage
41+ use FatesUtilsMod, only : QuadraticRoots = > QuadraticRootsSridharachary
4142 use EDParamsMod, only : maxpft
4243 use EDParamsMod, only : nlevleaf
4344 use EDParamsMod, only : nclmax
@@ -1379,7 +1380,7 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in
13791380 aquad = theta_psii
13801381 bquad = - (qabs + jmax)
13811382 cquad = qabs * jmax
1382- call quadratic_f (aquad, bquad, cquad, r1, r2)
1383+ call QuadraticRoots (aquad, bquad, cquad, r1, r2)
13831384 je = min (r1,r2)
13841385
13851386 ! Initialize intercellular co2
@@ -1409,7 +1410,7 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in
14091410 aquad = theta_cj_c3
14101411 bquad = - (ac + aj)
14111412 cquad = ac * aj
1412- call quadratic_f (aquad, bquad, cquad, r1, r2)
1413+ call QuadraticRoots (aquad, bquad, cquad, r1, r2)
14131414 agross = min (r1,r2)
14141415
14151416 else
@@ -1440,13 +1441,13 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in
14401441 aquad = theta_cj_c4
14411442 bquad = - (ac + aj)
14421443 cquad = ac * aj
1443- call quadratic_f (aquad, bquad, cquad, r1, r2)
1444+ call QuadraticRoots (aquad, bquad, cquad, r1, r2)
14441445 ai = min (r1,r2)
14451446
14461447 aquad = theta_ip
14471448 bquad = - (ai + ap)
14481449 cquad = ai * ap
1449- call quadratic_f (aquad, bquad, cquad, r1, r2)
1450+ call QuadraticRoots (aquad, bquad, cquad, r1, r2)
14501451 agross = min (r1,r2)
14511452
14521453 end if
@@ -1485,7 +1486,7 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in
14851486 (2.0 * stomatal_intercept_btran + term * &
14861487 (1.0 - medlyn_slope(ft)* medlyn_slope(ft) / vpd)) * term
14871488
1488- call quadratic_f (aquad, bquad, cquad, r1, r2)
1489+ call QuadraticRoots (aquad, bquad, cquad, r1, r2)
14891490 gs_mol = max (r1,r2)
14901491
14911492 else if ( stomatal_model == ballberry_model ) then ! stomatal conductance calculated from Ball et al. (1987)
@@ -1494,7 +1495,7 @@ subroutine LeafLayerPhotosynthesis(f_sun_lsl, & ! in
14941495 cquad = - gb_mol* (leaf_co2_ppress* stomatal_intercept_btran + &
14951496 bb_slope(ft)* anet* can_press * ceair/ veg_esat )
14961497
1497- call quadratic_f (aquad, bquad, cquad, r1, r2)
1498+ call QuadraticRoots (aquad, bquad, cquad, r1, r2)
14981499 gs_mol = max (r1,r2)
14991500 end if
15001501
@@ -1922,145 +1923,6 @@ end function fth25_f
19221923
19231924 ! =====================================================================================
19241925
1925- subroutine quadratic_f (a , b , c , r1 , r2 )
1926- !
1927- ! !DESCRIPTION:
1928- ! ==============================================================================!
1929- !- ---------------- Solve quadratic equation for its two roots -----------------!
1930- ! ==============================================================================!
1931- ! This solution is mostly derived from:
1932- ! Press WH, Teukolsky SA, Vetterling WT, Flannery BP. 1992. Numerical Recipes
1933- ! in Fortran77: The Art of Scientific Computing. 2nd edn. Cambridge
1934- ! University Press, Cambridge UK, ISBN 0-521-43064-X.
1935- ! Available at: http://numerical.recipes/oldverswitcher.html, section 5.6.
1936- !
1937- ! !REVISION HISTORY:
1938- ! 4/5/10: Adapted from /home/bonan/ecm/psn/An_gs_iterative.f90 by Keith Oleson
1939- ! 7/23/16: Copied over from CLM by Ryan Knox
1940- ! 12/30/23: Instead of issuing errors when a=0, solve the trivial cases too.
1941- ! Check determinant sign, and stop the run when it is negative.
1942- !
1943- ! !USES:
1944- !
1945- ! !ARGUMENTS:
1946- real (r8 ), intent (in ) :: a,b,c ! Terms for quadratic equation
1947- real (r8 ), intent (out ) :: r1,r2 ! Roots of quadratic equation
1948- !
1949- ! !LOCAL VARIABLES:
1950- real (r8 ) :: discriminant ! Discriminant
1951- real (r8 ) :: q ! Temporary term for quadratic solution
1952- logical :: a_offzero ! Is a close to zero?
1953- logical :: b_offzero ! Is b close to zero?
1954- logical :: c_offzero ! Is c close to zero?
1955- ! ! Local constants:
1956- real (r8 ), parameter :: discard = 1.e36_r8 ! Large number for discarding answer
1957- !- -----------------------------------------------------------------------------
1958-
1959- ! Save logical tests.
1960- a_offzero = abs (a) > nearzero
1961- b_offzero = abs (b) > nearzero
1962- c_offzero = abs (c) > nearzero
1963-
1964- if (a_offzero .and. ( b_offzero .or. c_offzero ) ) then
1965- ! Quadratic equation with two non-zero solutions (but may be complex solutions)
1966- discriminant = b* b - 4._r8 * a * c
1967-
1968- ! Proceed only when the discriminant is non-negative or only tiny negative
1969- if (discriminant >= - nearzero) then
1970- ! Coerce discriminant to non-negative
1971- discriminant = max (0._r8 ,discriminant)
1972-
1973- ! Find q as in the numerical recipes. If b or c are non-zero, q cannot
1974- ! be zero, no need for additional checks.
1975- q = - 0.5_r8 * (b + sign (sqrt (discriminant),b))
1976- r1 = q / a
1977- r2 = c / q
1978- else
1979- ! Negative discriminant, stop the run.
1980- write (fates_log(),' (a)' ) ' ---~---'
1981- write (fates_log(),' (a)' ) ' Fatal error!'
1982- write (fates_log(),' (a)' ) ' Quadratic equation discriminant is negative.'
1983- write (fates_log(),' (a)' ) ' ---~---'
1984- write (fates_log(),' (a,1x,es12.5)' ) ' a = ' ,a
1985- write (fates_log(),' (a,1x,es12.5)' ) ' b = ' ,b
1986- write (fates_log(),' (a,1x,es12.5)' ) ' c = ' ,c
1987- write (fates_log(),' (a,1x,es12.5)' ) ' discriminant = ' ,discriminant
1988- call endrun(msg= errMsg(sourcefile, __LINE__))
1989- end if
1990- else if (a_offzero) then
1991- ! b and c are nearly zero. Both roots must be zero.
1992- r1 = 0._r8
1993- r2 = 0._r8
1994- else if (b_offzero) then
1995- ! "a" is not zero, not a true quadratic equation. Single root.
1996- r1 = - c / b
1997- r2 = discard
1998- else
1999- ! Both a and b are zero, this really doesn't make any sense and should never
2000- ! happen. If it does, issue an error and stop the run.
2001- write (fates_log(),' (a)' ) ' ---~---'
2002- write (fates_log(),' (a)' ) ' Fatal error!'
2003- write (fates_log(),' (a)' ) ' This solver expects '' a'' and/or '' b'' to be non-zero.'
2004- write (fates_log(),' (a)' ) ' ---~---'
2005- write (fates_log(),' (a,1x,es12.5)' ) ' a = ' ,a
2006- write (fates_log(),' (a,1x,es12.5)' ) ' b = ' ,b
2007- write (fates_log(),' (a,1x,es12.5)' ) ' c = ' ,c
2008- write (fates_log(),' (a)' ) ' ---~---'
2009- call endrun(msg= errMsg(sourcefile, __LINE__))
2010- end if
2011-
2012- return
2013- end subroutine quadratic_f
2014-
2015- ! ====================================================================================
2016-
2017- subroutine quadratic_fast (a , b , c , r1 , r2 )
2018- !
2019- ! !DESCRIPTION:
2020- ! ==============================================================================!
2021- !- ---------------- Solve quadratic equation for its two roots -----------------!
2022- ! THIS METHOD SIMPLY REMOVES THE DIV0 CHECK AND ERROR REPORTING !
2023- ! ==============================================================================!
2024- ! Solution from Press et al (1986) Numerical Recipes: The Art of Scientific
2025- ! Computing (Cambridge University Press, Cambridge), pp. 145.
2026- !
2027- ! !REVISION HISTORY:
2028- ! 4/5/10: Adapted from /home/bonan/ecm/psn/An_gs_iterative.f90 by Keith Oleson
2029- ! 7/23/16: Copied over from CLM by Ryan Knox
2030- !
2031- ! !USES:
2032- !
2033- ! !ARGUMENTS:
2034- real (r8 ), intent (in ) :: a,b,c ! Terms for quadratic equation
2035- real (r8 ), intent (out ) :: r1,r2 ! Roots of quadratic equation
2036- !
2037- ! !LOCAL VARIABLES:
2038- real (r8 ) :: q ! Temporary term for quadratic solution
2039- !- -----------------------------------------------------------------------------
2040-
2041- ! if (a == 0._r8) then
2042- ! write (fates_log(),*) 'Quadratic solution error: a = ',a
2043- ! call endrun(msg=errMsg(sourcefile, __LINE__))
2044- ! end if
2045-
2046- if (b >= 0._r8 ) then
2047- q = - 0.5_r8 * (b + sqrt (b* b - 4._r8 * a* c))
2048- else
2049- q = - 0.5_r8 * (b - sqrt (b* b - 4._r8 * a* c))
2050- end if
2051-
2052- r1 = q / a
2053- ! if (q /= 0._r8) then
2054- r2 = c / q
2055- ! else
2056- ! r2 = 1.e36_r8
2057- ! end if
2058-
2059- end subroutine quadratic_fast
2060-
2061-
2062- ! ====================================================================================
2063-
20641926 subroutine UpdateCanopyNCanNRadPresent (currentPatch )
20651927
20661928 ! ---------------------------------------------------------------------------------
0 commit comments