Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
379e017
Merge pull request #6 from NCAR/develop
cenlinhe May 27, 2021
6b7f45d
Merge branch 'NCAR:develop' into develop
cenlinhe Apr 12, 2023
9165400
Merge branch 'NCAR:develop' into develop
cenlinhe Jun 6, 2023
dfb99b6
bug fix for FVEG scaling of canopy heat storage
cenlinhe Jun 6, 2023
20887f5
fix format issue
cenlinhe Jun 7, 2023
09b765a
Merge pull request #88 from cenlinhe/canhs_bugfix_v5
cenlinhe Jun 7, 2023
3cd2bcd
Merge pull request #89 from NCAR/develop
cenlinhe Jun 7, 2023
45f6521
bug fix for initialization to work with BEP,BEM urban physics call
cenlinhe Jun 10, 2023
ba9f679
Merge pull request #94 from NCAR/develop
cenlinhe Jun 10, 2023
48329b3
Update README.md
cenlinhe Sep 8, 2023
0d7ba21
Update README.md
cenlinhe Sep 8, 2023
0cb07b5
Update README.md
cenlinhe Sep 8, 2023
32231c2
Update README.md
cenlinhe Sep 8, 2023
151daf8
Update README.md
cenlinhe Sep 8, 2023
2459ba8
Update README.md
cenlinhe Sep 8, 2023
e0d2064
bug fix for snow layer combine
cenlinhe Sep 19, 2023
a7dd399
bug fix for VegFrac scaling, issue #91-92
cenlinhe Sep 19, 2023
43b82b8
Merge branch 'master' into develop
cenlinhe Sep 19, 2023
107215a
Merge pull request #98 from NCAR/develop
cenlinhe Sep 19, 2023
814c129
use consistent common undefined value for initialization
cenlinhe Nov 30, 2023
6c9717b
Merge pull request #101 from NCAR/develop
cenlinhe Nov 30, 2023
ad2826b
bug fix for undefined albedo value
cenlinhe Jan 5, 2024
843a742
bug fix for leaf mass initialization for urban pixel
cenlinhe Jan 5, 2024
1a853a5
Merge pull request #107 from NCAR/develop
cenlinhe Jan 5, 2024
e9b85a0
merge
tslin2 Jan 18, 2024
074a66e
negative theta_1500 in PedoTransferSR2006Mod.F90
tslin2 Jan 18, 2024
53767f4
update
tslin2 Jan 18, 2024
75cd9a4
update theta
tslin2 Jan 18, 2024
2ba002a
update for value
tslin2 Jan 18, 2024
8a9543a
Merge pull request #111 from tslin2/develop
cenlinhe Jan 18, 2024
c27b868
Add files via upload
RAbolafiaRosenzweig Feb 1, 2024
8569cc6
Add files via upload
RAbolafiaRosenzweig Feb 1, 2024
7e302f6
Add files via upload
RAbolafiaRosenzweig Feb 1, 2024
50c3657
Add files via upload
RAbolafiaRosenzweig Feb 1, 2024
8138618
Add files via upload
RAbolafiaRosenzweig Feb 2, 2024
c7a04d8
Merge pull request #112 from RAbolafiaRosenzweig/develop
cenlinhe Feb 2, 2024
929fd87
Merge branch 'snicar_lin' into develop
cenlinhe Mar 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
![image](https://user-images.githubusercontent.com/43385564/236596277-45d492e7-79fd-4006-83e2-3044106afd94.png)
![noahmp_logo_update](https://github.com/NCAR/noahmp/assets/43385564/1fb47fc2-99bd-4360-9ed0-6d5656c29626)


[![DOI](https://zenodo.org/badge/236657733.svg)](https://zenodo.org/badge/latestdoi/236657733)


# Noah-MP Community Model Repository
# Noah-MP<sup>®</sup> Community Model Repository


Noah-MP is a widely-used state-of-the-art land surface model used in many research and operational weather/climate models (e.g., HRLDAS, WRF, MPAS, WRF-Hydro/NWM, NOAA/UFS, NASA/LIS, etc.).
Noah-MP<sup>®</sup> is a widely-used state-of-the-art land surface model used in many research and operational weather/climate models (e.g., HRLDAS, WRF, MPAS, WRF-Hydro/NWM, NOAA/UFS, NASA/LIS, etc.).

This is the official Noah-MP land surface model unified repository for code downloading and contribution. Noah-MP is a community open-source model developed with the contributions from the entire scientific community. For development, maintenance, and release of the community Noah-MP GitHub code, please contact: Cenlin He (cenlinhe@ucar.edu) and Fei Chen (feichen@ucar.edu).

Expand All @@ -27,7 +26,7 @@ Technical documentation freely available at http://dx.doi.org/10.5065/ew8g-yr95

**Original Noah-MP model description paper**: Niu, G. Y., Yang, Z. L., Mitchell, K. E., Chen, F., Ek, M. B., Barlage, M., ... & Xia, Y. (2011). The community Noah land surface model with multiparameterization options (Noah‐MP): 1. Model description and evaluation with local‐scale measurements. Journal of Geophysical Research: Atmospheres, 116(D12).

**Noah-MP version 5.0 model description paper**: He, C., Valayamkunnath, P., Barlage, M., Chen, F., Gochis, D., Cabell, R., Schneider, T., Rasmussen, R., Niu, G.-Y., Yang, Z.-L., Niyogi, D., and Ek, M.: Modernizing the open-source community Noah-MP land surface model (version 5.0) with enhanced modularity, interoperability, and applicability, EGUsphere [preprint], https://doi.org/10.5194/egusphere-2023-675, 2023.
**Noah-MP version 5.0 model description paper**: He, C., Valayamkunnath, P., Barlage, M., Chen, F., Gochis, D., Cabell, R., Schneider, T., Rasmussen, R., Niu, G.-Y., Yang, Z.-L., Niyogi, D., and Ek, M.: Modernizing the open-source community Noah with multi-parameterization options (Noah-MP) land surface model (version 5.0) with enhanced modularity, interoperability, and applicability, Geosci. Model Dev., 16, 5131–5151, https://doi.org/10.5194/gmd-16-5131-2023, 2023.


## Noah-MP GitHub structure
Expand Down
9 changes: 5 additions & 4 deletions drivers/hrldas/ConfigVarInTransferMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,12 @@ subroutine ConfigVarInTransfer(noahmp, NoahmpIO)

! treatment for urban point
if ( (NoahmpIO%IVGTYP(I,J) == NoahmpIO%ISURBAN_TABLE) .or. (NoahmpIO%IVGTYP(I,J) > NoahmpIO%URBTYPE_beg) ) then
noahmp%config%domain%FlagUrban = .true.
if(NoahmpIO%SF_URBAN_PHYSICS == 0 ) then
noahmp%config%domain%VegType = NoahmpIO%ISURBAN_TABLE
if ( NoahmpIO%SF_URBAN_PHYSICS == 0 ) then
noahmp%config%domain%VegType = NoahmpIO%ISURBAN_TABLE ! treat as bulk urban point
noahmp%config%domain%FlagUrban = .true.
else
noahmp%config%domain%VegType = NoahmpIO%NATURAL_TABLE ! set urban vegetation type based on table natural
noahmp%config%domain%VegType = NoahmpIO%NATURAL_TABLE ! set rural vegetation type based on table natural
! urban is handled by explicit urban scheme outside Noah-MP
NoahmpIO%GVFMAX(I,J) = 0.96 * 100.0 ! unit: %
endif
endif
Expand Down
4 changes: 1 addition & 3 deletions drivers/hrldas/EnergyVarOutTransferMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,11 @@ subroutine EnergyVarOutTransfer(noahmp, NoahmpIO)
NoahmpIO%CHB2XY (I,J) = noahmp%energy%state%ExchCoeffSh2mBare
NoahmpIO%Q2MVXY (I,J) = noahmp%energy%state%SpecHumidity2mVeg /(1.0-noahmp%energy%state%SpecHumidity2mVeg) ! spec humidity to mixing ratio
NoahmpIO%Q2MBXY (I,J) = noahmp%energy%state%SpecHumidity2mBare/(1.0-noahmp%energy%state%SpecHumidity2mBare)
NoahmpIO%ALBEDO (I,J) = noahmp%energy%state%AlbedoSfc
NoahmpIO%IRRSPLH (I,J) = NoahmpIO%IRRSPLH(I,J) + &
(noahmp%energy%flux%HeatLatentIrriEvap * noahmp%config%domain%MainTimeStep)
NoahmpIO%TSLB (I,1:NumSoilLayer,J) = noahmp%energy%state%TemperatureSoilSnow(1:NumSoilLayer)
NoahmpIO%TSNOXY (I,-NumSnowLayerMax+1:0,J) = noahmp%energy%state%TemperatureSoilSnow(-NumSnowLayerMax+1:0)
if ( noahmp%energy%state%AlbedoSfc > -999 ) then
NoahmpIO%ALBEDO(I,J) = noahmp%energy%state%AlbedoSfc
endif

!SNICAR
if (noahmp%config%nmlist%OptSnowAlbedo == 3 )then
Expand Down
9 changes: 7 additions & 2 deletions drivers/hrldas/NoahmpInitMainMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,13 @@ subroutine NoahmpInitMain(NoahmpIO)
NoahmpIO%LAI(I,J) = 0.0
NoahmpIO%LAI(I,J) = max(NoahmpIO%LAI(I,J), 0.05) ! at least start with 0.05 for arbitrary initialization (v3.7)
NoahmpIO%XSAIXY(I,J) = max(0.1*NoahmpIO%LAI(I,J), 0.05) ! MB: arbitrarily initialize SAI using input LAI (v3.7)
NoahmpIO%LFMASSXY(I,J) = NoahmpIO%LAI(I,J) * 1000.0 / &
max(NoahmpIO%SLA_TABLE(NoahmpIO%IVGTYP(I,J)),1.0) ! use LAI to initialize (v3.7)
if ( urbanpt_flag .eqv. .true. ) then
NoahmpIO%LFMASSXY(I,J) = NoahmpIO%LAI(I,J) * 1000.0 / &
max(NoahmpIO%SLA_TABLE(NoahmpIO%NATURAL_TABLE),1.0)! use LAI to initialize (v3.7)
else
NoahmpIO%LFMASSXY(I,J) = NoahmpIO%LAI(I,J) * 1000.0 / &
max(NoahmpIO%SLA_TABLE(NoahmpIO%IVGTYP(I,J)),1.0) ! use LAI to initialize (v3.7)
endif
NoahmpIO%STMASSXY(I,J) = NoahmpIO%XSAIXY(I,J) * 1000.0 / 3.0 ! use SAI to initialize (v3.7)
NoahmpIO%RTMASSXY(I,J) = 500.0 ! these are all arbitrary and probably should be
NoahmpIO%WOODXY(I,J) = 500.0 ! in the table or read from initialization
Expand Down
3 changes: 3 additions & 0 deletions drivers/hrldas/PedoTransferSR2006Mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ subroutine PedoTransferSR2006(NoahmpIO, noahmp, Sand, Clay, Orgm)
+ sr2006_psi_e_b*psi_et &
+ sr2006_psi_e_c

theta_33 = max(10.0**-3.0,theta_33) ! For numerical stability
theta_1500 = max(10.0**-5.0,theta_1500) ! For numerical stability

! assign property values
smcwlt = theta_1500
smcref = theta_33
Expand Down
4 changes: 2 additions & 2 deletions parameters/NoahmpTable.TBL
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
ISCROP = 2 ! crop land type in USGS
EBLFOREST = 13 ! evergreen broadleaf forest land type in USGS
NATURAL = 5 ! natural vegation type in urban pixel in USGS
URBTYPE_beg = 40 ! land type number above which are urban (e.g., LCZ)
URBTYPE_beg = 50 ! land type number above which are urban (e.g., LCZ)
LCZ_1 = 51 ! urban local climate zone (LCZ) type 1: compact highrise
LCZ_2 = 52 ! urban local climate zone (LCZ) type 2: compact midrise
LCZ_3 = 53 ! urban local climate zone (LCZ) type 3: compact lowrise
Expand Down Expand Up @@ -243,7 +243,7 @@
ISCROP = 12 ! crop land type in MODIS
EBLFOREST = 2 ! evergreen broadleaf forest land type in MODIS
NATURAL = 14 ! natural vegation type in urban pixel in MODIS
URBTYPE_beg = 40 ! land type number above which are urban (e.g., LCZ)
URBTYPE_beg = 50 ! land type number above which are urban (e.g., LCZ)
LCZ_1 = 51 ! urban local climate zone (LCZ) type 1: compact highrise
LCZ_2 = 52 ! urban local climate zone (LCZ) type 2: compact midrise
LCZ_3 = 53 ! urban local climate zone (LCZ) type 3: compact lowrise
Expand Down
33 changes: 19 additions & 14 deletions src/AtmosForcingMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -166,21 +166,26 @@ subroutine ProcessAtmosForcing(noahmp)
endif
endif

! wet-bulb scheme (Wang et al., 2019 GRL), C.He, 12/18/2020
! wet-bulb scheme (Wang et al., 2019 GRL), C.He, 12/18/2020, R. Abolafia-Rosnezweig, 02/01/2024
if ( OptRainSnowPartition == 5 ) then
TemperatureDegC = min( 50.0, max(-50.0,(TemperatureAirRefHeight-ConstFreezePoint)) ) ! Kelvin to degree Celsius with limit -50 to +50
if ( TemperatureAirRefHeight > ConstFreezePoint ) then
LatHeatVap = ConstLatHeatEvap
else
LatHeatVap = ConstLatHeatSublim
endif
PsychConst = ConstHeatCapacAir * PressureAirRefHeight / (0.622 * LatHeatVap)
TemperatureWetBulb = TemperatureDegC - 5.0 ! first guess wetbulb temperature
do LoopInd = 1, LoopNum
VapPresSat = 610.8 * exp( (17.27*TemperatureWetBulb) / (237.3+TemperatureWetBulb) )
TemperatureWetBulb = TemperatureWetBulb - (VapPresSat - PressureVaporRefHeight) / PsychConst ! Wang et al., 2019 GRL Eq.2
enddo
FrozenPrecipFrac = 1.0 / (1.0 + 6.99e-5 * exp(2.0*(TemperatureWetBulb+3.97))) ! Wang et al., 2019 GRL Eq. 1

if ( TemperatureAirRefHeight >= (ConstFreezePoint+10) ) then !avoid numerical errors when temperature is high
FrozenPrecipFrac = 0.0
else
TemperatureDegC = min( 50.0, max(-50.0,(TemperatureAirRefHeight-ConstFreezePoint)) ) ! Kelvin to degree Celsius with limit -50 to +50
if ( TemperatureAirRefHeight > ConstFreezePoint ) then
LatHeatVap = ConstLatHeatEvap
else
LatHeatVap = ConstLatHeatSublim
endif
PsychConst = ConstHeatCapacAir * PressureAirRefHeight / (0.622 * LatHeatVap)
TemperatureWetBulb = TemperatureDegC - 5.0 ! first guess wetbulb temperature
do LoopInd = 1, LoopNum
VapPresSat = 610.8 * exp( (17.27*TemperatureWetBulb) / (237.3+TemperatureWetBulb) )
TemperatureWetBulb = TemperatureWetBulb - (VapPresSat - PressureVaporRefHeight) / PsychConst ! Wang et al., 2019 GRL Eq.2
enddo
FrozenPrecipFrac = 1.0 / (1.0 + 6.99e-5 * exp(2.0*(TemperatureWetBulb+3.97))) ! Wang et al., 2019 GRL Eq. 1
endif
endif

! rain-snow partitioning
Expand Down
3 changes: 2 additions & 1 deletion src/CanopyHydrologyMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ subroutine CanopyHydrology(noahmp)
LeafAreaIndEff => noahmp%energy%state%LeafAreaIndEff ,& ! in, leaf area index, after burying by snow
StemAreaIndEff => noahmp%energy%state%StemAreaIndEff ,& ! in, stem area index, after burying by snow
FlagFrozenCanopy => noahmp%energy%state%FlagFrozenCanopy ,& ! in, used to define latent heat pathway
VegFrac => noahmp%energy%state%VegFrac ,& ! in, greeness vegetation fraction
SnowfallDensity => noahmp%water%state%SnowfallDensity ,& ! in, bulk density of snowfall [kg/m3]
CanopyLiqHoldCap => noahmp%water%param%CanopyLiqHoldCap ,& ! in, maximum intercepted liquid water per unit veg area index [mm]
VegFrac => noahmp%energy%state%VegFrac ,& ! in, greeness vegetation fraction
Expand Down Expand Up @@ -68,7 +69,7 @@ subroutine CanopyHydrology(noahmp)

! canopy liquid water
! maximum canopy intercepted water
CanopyLiqWaterMax = VegFrac * CanopyLiqHoldCap * (LeafAreaIndEff + StemAreaIndEff)
CanopyLiqWaterMax = VegFrac * CanopyLiqHoldCap * (LeafAreaIndEff + StemAreaIndEff)

! canopy evaporation, transpiration, and dew
if ( FlagFrozenCanopy .eqv. .false. ) then ! Barlage: change to FlagFrozenCanopy
Expand Down
2 changes: 1 addition & 1 deletion src/EnergyMainGlacierMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ subroutine EnergyMainGlacier(noahmp)
if ( RadSwDownRefHeight > 0.0 ) then
AlbedoSfc = RadSwReflSfc / RadSwDownRefHeight
else
AlbedoSfc = -999.9
AlbedoSfc = undefined_real
endif

end associate
Expand Down
2 changes: 1 addition & 1 deletion src/EnergyMainMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ subroutine EnergyMain(noahmp)
if ( RadSwDownRefHeight > 0.0 ) then
AlbedoSfc = RadSwReflSfc / RadSwDownRefHeight
else
AlbedoSfc = -999.9
AlbedoSfc = undefined_real
endif
end associate

Expand Down
3 changes: 2 additions & 1 deletion src/ResistanceCanopyStomataBallBerryMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ subroutine ResistanceCanopyStomataBallBerry(noahmp, IndexShade)
PressureAtmosO2 => noahmp%energy%state%PressureAtmosO2 ,& ! in, atmospheric o2 pressure [Pa]
PressureAtmosCO2 => noahmp%energy%state%PressureAtmosCO2 ,& ! in, atmospheric co2 pressure [Pa]
ResistanceLeafBoundary => noahmp%energy%state%ResistanceLeafBoundary ,& ! in, leaf boundary layer resistance [s/m]
VegFrac => noahmp%energy%state%VegFrac ,& ! in, greeness vegetation fraction
RadPhotoActAbsSunlit => noahmp%energy%flux%RadPhotoActAbsSunlit ,& ! in, average absorbed par for sunlit leaves [W/m2]
RadPhotoActAbsShade => noahmp%energy%flux%RadPhotoActAbsShade ,& ! in, average absorbed par for shaded leaves [W/m2]
ResistanceStomataSunlit => noahmp%energy%state%ResistanceStomataSunlit ,& ! out, sunlit leaf stomatal resistance [s/m]
Expand All @@ -101,7 +102,7 @@ subroutine ResistanceCanopyStomataBallBerry(noahmp, IndexShade)
ResistanceStomataTmp = 1.0 / ConductanceLeafMin * CF
PhotosynLeafTmp = 0.0
if ( IndexShade == 0 ) RadPhotoActAbsTmp = RadPhotoActAbsSunlit / max(VegFrac,1.0e-6) ! Sunlit case
if ( IndexShade == 1 ) RadPhotoActAbsTmp = RadPhotoActAbsShade / max(VegFrac,1.0e-6) ! Shaded case
if ( IndexShade == 1 ) RadPhotoActAbsTmp = RadPhotoActAbsShade / max(VegFrac,1.0e-6) ! Shaded case

! only compute when there is radiation absorption
if ( RadPhotoActAbsTmp > 0.0 ) then
Expand Down
5 changes: 3 additions & 2 deletions src/ResistanceCanopyStomataJarvisMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ subroutine ResistanceCanopyStomataJarvis(noahmp, IndexShade)
ResistanceTemp = 0.0
ResistanceVapDef = 0.0
ResistanceStomataTmp = 0.0
if ( IndexShade == 0 ) RadPhotoActAbsTmp = RadPhotoActAbsSunlit / max(VegFrac,1.0e-6) ! Sunlit case
if ( IndexShade == 1 ) RadPhotoActAbsTmp = RadPhotoActAbsShade / max(VegFrac,1.0e-6) ! Shaded case
if ( IndexShade == 0 ) RadPhotoActAbsTmp = RadPhotoActAbsSunlit / max(VegFrac,1.0e-6) ! Sunlit case
if ( IndexShade == 1 ) RadPhotoActAbsTmp = RadPhotoActAbsShade / max(VegFrac,1.0e-6) ! Shaded case


! compute MixingRatioTmp and MixingRatioSat
SpecHumidityTmp = 0.622 * PressureVaporCanAir / (PressureAirRefHeight - 0.378*PressureVaporCanAir) ! specific humidity
Expand Down
2 changes: 1 addition & 1 deletion src/SnowLayerCombineMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ subroutine SnowLayerCombine(noahmp)
endif

else
if ( NumSnowLayerNeg < -1 ) then ! MB/KM: change to NumSnowLayerNeg
! if ( NumSnowLayerOld < -1 ) then ! MB/KM: change to NumSnowLayerNeg !samlin
if ( NumSnowLayerNeg < -1 ) then ! MB/KM: change to NumSnowLayerNeg !samlin
SnowLiqWater(J-1) = SnowLiqWater(J-1) + SnowLiqWater(J)
SnowIce(J-1) = SnowIce(J-1) + SnowIce(J)
ThicknessSnowSoilLayer(J-1) = ThicknessSnowSoilLayer(J-1) + ThicknessSnowSoilLayer(J)
Expand Down
8 changes: 4 additions & 4 deletions utility/Machine.F90
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ module Machine
integer, public, parameter :: kind_noahmp = 4 ! single precision
#endif

integer, public, parameter :: undefined_int = huge(1) ! undefined integer for variable initialization
real(kind=kind_noahmp), public, parameter :: undefined_real = huge(1.0) ! undefined real for variable initializatin
integer, public, parameter :: undefined_int_neg = -999 ! undefined integer negative for variable initialization
real(kind=kind_noahmp), public, parameter :: undefined_real_neg = -999.0 ! undefined real negative for variable initializatin
integer, public, parameter :: undefined_int = -9999 ! undefined integer for variable initialization
real(kind=kind_noahmp), public, parameter :: undefined_real = -9999.0 ! undefined real for variable initializatin
integer, public, parameter :: undefined_int_neg = -9999 ! undefined integer negative for variable initialization
real(kind=kind_noahmp), public, parameter :: undefined_real_neg = -9999.0 ! undefined real negative for variable initializatin

end module Machine