Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NGEE Arctic IM1 - Polygonal tundra #10

Open
wants to merge 40 commits into
base: thorntonpe/lnd/IM1
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
f686b54
Add maxalt across overall simulation.
rfiorella Sep 26, 2024
ca1f497
Add excess ground ice as a column variable
rfiorella Sep 26, 2024
eb043af
Change excess ground ice units to unitless
rfiorella Apr 16, 2024
104a746
Update excess_ice from single column value to depth varying
rfiorella Sep 26, 2024
b185bf2
defined new ice wedge polygon land unit types and microtopographic pa…
chuckaustin Mar 28, 2024
dd206a9
Added routine to calculate surface inundated fraction in polygonal tu…
chuckaustin Apr 4, 2024
e27bdd9
Remove ispolygon from landunit_varcon import
rfiorella May 9, 2024
7789d5e
New routine to calculate surface runoff in polygonal tundra and some …
chuckaustin May 15, 2024
6e47601
add meangradz to lun_pp
chuckaustin May 15, 2024
720f19e
Add ground subsidence variable to SoilHydrologyMod
rfiorella Sep 26, 2024
c450a0d
Add variable calculation of microtopographic parameters
rfiorella May 15, 2024
0b9256a
Track MAXALT in 1989
rfiorella Sep 26, 2024
3080cd9
Add use_polygonal_tundra flag to CanopyStateType
rfiorella Jun 10, 2024
c5a6187
Add missing polygon types to SoilHydrologyMod
rfiorella Jun 10, 2024
3542e86
Add missing allocation of wt_polygon matrix
rfiorella Sep 26, 2024
d812674
Remove melted excess ice and set initiation for subsidence
rfiorella Jun 12, 2024
76ec5b9
Read gradz from surfdata file when polygonal tundra is turned on.
rfiorella Sep 26, 2024
265c68c
Prevent errors in wt_polygon calculations
rfiorella Jul 11, 2024
84ace73
Ensure EXCESS_ICE only hist/rest files if use_polygonal_tundra
rfiorella Jul 14, 2024
681b6bd
Add calls to add columns/patches/landunits for polygonal tundra
rfiorella Jul 18, 2024
1934370
Major updates to landunits idx accounting for polygonal tundra
rfiorella Sep 26, 2024
30a7acc
fix divide by zero issue in canopyhydrologymod
rfiorella Jul 25, 2024
a503e49
Fix microtopo parameter calcs
rfiorella Jul 25, 2024
ea9e427
Add Arctic initialization option
rfiorella Sep 26, 2024
7301079
Move column microtopo to col_ws from col_pp
rfiorella Aug 12, 2024
7d910e3
IWP runoff and subsidence bug fixes
rfiorella Aug 15, 2024
5f81f36
Fix wt_lunit and wt_polygon arrays when feature is off
rfiorella Sep 9, 2024
e4f78f4
add ERS test for polygonal tundra
rfiorella Sep 9, 2024
4fddcd6
add polygon test to tests.py
rfiorella Sep 9, 2024
4c89721
Various changes for adding, passing new test
rfiorella Sep 9, 2024
524b563
change length of wt_lunit to only be larger when use_polygonal_tundra
rfiorella Sep 12, 2024
b0c415f
Allow variable specification of the length of the landunit_names array
rfiorella Sep 13, 2024
e247b47
make length of max_lunit depend on use_polygonal_tundra
rfiorella Sep 15, 2024
0c9653e
Update test to also test use_arctic_init
rfiorella Sep 15, 2024
59d1a69
make arctic init temperature vary with latitude
rfiorella Sep 26, 2024
d402398
bug fix roundup
rfiorella Sep 17, 2024
d5780e3
Cleanup prior to merge testing
rfiorella Sep 20, 2024
2d780f9
iwp_subsidence bug fixes
rfiorella Sep 25, 2024
aeb0bfe
protect additional variables with use_polygonal_tundra
rfiorella Oct 1, 2024
5d18e7e
cleanup no longer needed write statements
rfiorella Oct 1, 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
5 changes: 3 additions & 2 deletions cime_config/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
"ERS.f19_g16.I20TRGSWCNPECACNTBC.elm-eca_f19_g16_I20TRGSWCNPECACNTBC",
"ERS.f19_g16.I20TRGSWCNPRDCTCBC.elm-ctc_f19_g16_I20TRGSWCNPRDCTCBC",
"ERS.r05_r05.ICNPRDCTCBC.elm-cbudget",
"ERS.ELM_USRDAT.I1850CNPRDCTCBC.elm-usrpft_default_I1850CNPRDCTCBC",
"ERS.ELM_USRDAT.I1850CNPRDCTCBC.elm-usrpft_codetest_I1850CNPRDCTCBC",
"ERS.ELM_USRDAT.I1850CNPRDCTCBC.elm-polygonal_tundra"
)
},

Expand Down Expand Up @@ -94,8 +97,6 @@
"SMS.r05_r05.IELM.elm-topounit",
"ERS.ELM_USRDAT.I1850ELM.elm-usrdat",
"ERS.r05_r05.IELM.elm-lnd_rof_2way",
"ERS.ELM_USRDAT.I1850CNPRDCTCBC.elm-usrpft_default_I1850CNPRDCTCBC",
"ERS.ELM_USRDAT.I1850CNPRDCTCBC.elm-usrpft_codetest_I1850CNPRDCTCBC",
"ERS.r05_r05.IELM.elm-V2_ELM_MOSART_features",
"ERS.ELM_USRDAT.IELM.elm-surface_water_dynamics"
)
Expand Down
4 changes: 4 additions & 0 deletions components/elm/bld/namelist_files/namelist_defaults.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2228,4 +2228,8 @@ this mask will have smb calculated over the entire global land surface
<use_fan use_fates=".true." >.false.</use_fan>
<use_fan fan_mode='disable'>.false.</use_fan>

<!-- NGEE Arctic Options -->
<use_polygonal_tundra>.false.</use_polygonal_tundra>;
<use_arctic_init>.false.</use_arctic_init>;

</namelist_defaults>
20 changes: 20 additions & 0 deletions components/elm/bld/namelist_files/namelist_definition.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2160,6 +2160,16 @@ written only if do_budgets variable is .true.,
default: 0
</entry>

<!-- ======================================================================================== -->
<!-- NGEE Arctic Options -->
<!-- ======================================================================================== -->

<entry id="use_arctic_init" type="logical" category="default_settings"
group="elm_inparm" value=".false.">
Cold-start initialization conditions in tundra start saturated and frozen.
<default>Default: .false.</default>
</entry>

<!-- ======================================================================================== -->
<!-- Namelist options for soil erosion model -->
<!-- ======================================================================================== -->
Expand Down Expand Up @@ -2222,4 +2232,14 @@ not be called.
<default>Default: 0</default>
</entry>

<!-- ======================================================================================== -->
<!-- NGEE Arctic Options -->
<!-- ======================================================================================== -->

<entry id="use_polygonal_tundra" type="logical" category="default_settings"
group="elm_inparm" value=".false.">
Use polygonal tundra parameterizations for ice wedge polygon microtopography and inindation fraction
<default>Default: .false.</default>
</entry>

</namelist_definition>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
./xmlchange LND_DOMAIN_FILE=domain.lnd.1x1pt_icycape_c240909.nc
./xmlchange ATM_DOMAIN_FILE=domain.lnd.1x1pt_icycape_c240909.nc
./xmlchange LND_DOMAIN_PATH="\$DIN_LOC_ROOT/share/domains/domain.clm"
./xmlchange ATM_DOMAIN_PATH="\$DIN_LOC_ROOT/share/domains/domain.clm"
./xmlchange DATM_MODE=CLMGSWP3v1
./xmlchange DATM_CLMNCEP_YR_START=2000
./xmlchange DATM_CLMNCEP_YR_END=2000
./xmlchange NTASKS=1
./xmlchange NTHRDS=1
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
use_polygonal_tundra = .true.
use_arctic_init = .true.
fsurdat = '$DIN_LOC_ROOT/lnd/clm2/surfdata_map/surfdata_1x1pt_IcyCape_polygons_c240909.nc'
161 changes: 137 additions & 24 deletions components/elm/src/biogeophys/ActiveLayerMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ module ActiveLayerMod
! !USES:
use shr_kind_mod , only : r8 => shr_kind_r8
use shr_const_mod , only : SHR_CONST_TKFRZ
use elm_varctl , only : iulog
use elm_varctl , only : iulog, spinup_state, use_polygonal_tundra
use TemperatureType , only : temperature_type
use CanopyStateType , only : canopystate_type
use GridcellType , only : grc_pp
use ColumnType , only : col_pp
use ColumnDataType , only : col_es
use ColumnDataType , only : col_es, col_ws
use LandunitType , only : lun_pp
use landunit_varcon , only : ilowcenpoly, iflatcenpoly, ihighcenpoly
!
implicit none
save
Expand Down Expand Up @@ -47,7 +49,7 @@ subroutine alt_calc(num_soilc, filter_soilc, &
use elm_varpar , only : nlevgrnd
use elm_time_manager , only : get_curr_date, get_step_size
use elm_varctl , only : iulog
use elm_varcon , only : zsoi
use elm_varcon , only : zsoi, dzsoi, zisoi
!
! !ARGUMENTS:
integer , intent(in) :: num_soilc ! number of soil columns in filter
Expand All @@ -56,27 +58,41 @@ subroutine alt_calc(num_soilc, filter_soilc, &
type(canopystate_type) , intent(inout) :: canopystate_vars
!
! !LOCAL VARIABLES:
integer :: c, j, fc, g ! counters
integer :: alt_ind ! index of base of activel layer
integer :: year ! year (0, ...) for nstep+1
integer :: mon ! month (1, ..., 12) for nstep+1
integer :: day ! day of month (1, ..., 31) for nstep+1
integer :: sec ! seconds into current date for nstep+1
integer :: dtime ! time step length in seconds
integer :: k_frz ! index of first nonfrozen soil layer
logical :: found_thawlayer ! used to break loop when first unfrozen layer reached
real(r8) :: t1, t2, z1, z2 ! temporary variables
integer :: c, j, fc, g ! counters
integer :: alt_ind ! index of base of active layer
integer :: year ! year (0, ...) for nstep+1
integer :: mon ! month (1, ..., 12) for nstep+1
integer :: day ! day of month (1, ..., 31) for nstep+1
integer :: sec ! seconds into current date for nstep+1
integer :: dtime ! time step length in seconds
integer :: k_frz ! index of first nonfrozen soil layer
logical :: found_thawlayer ! used to break loop when first unfrozen layer reached
real(r8) :: t1, t2, z1, z2, orig_excess, old_mfrac ! temporary variables
real(r8), dimension(nlevgrnd) :: melt_profile ! profile of melted excess ice
!-----------------------------------------------------------------------

associate( &
t_soisno => col_es%t_soisno , & ! Input: [real(r8) (:,:) ] soil temperature (Kelvin) (-nlevsno+1:nlevgrnd)

alt => canopystate_vars%alt_col , & ! Output: [real(r8) (:) ] current depth of thaw
altmax => canopystate_vars%altmax_col , & ! Output: [real(r8) (:) ] maximum annual depth of thaw
altmax_lastyear => canopystate_vars%altmax_lastyear_col , & ! Output: [real(r8) (:) ] prior year maximum annual depth of thaw
alt_indx => canopystate_vars%alt_indx_col , & ! Output: [integer (:) ] current depth of thaw
altmax_indx => canopystate_vars%altmax_indx_col , & ! Output: [integer (:) ] maximum annual depth of thaw
altmax_lastyear_indx => canopystate_vars%altmax_lastyear_indx_col & ! Output: [integer (:) ] prior year maximum annual depth of thaw
! RF NOTE: use of 1989 ALT in these parameterizations is somewhat of a placeholder used to compare against
! ATS runs for NGEE Arctic Phase 3. It should ultimately be replaced by a more physically based threshold
! later on.
associate( &
t_soisno => col_es%t_soisno , & ! Input: [real(r8) (:,:) ] soil temperature (Kelvin) (-nlevsno+1:nlevgrnd)

alt => canopystate_vars%alt_col , & ! Output: [real(r8) (:) ] current depth of thaw
altmax => canopystate_vars%altmax_col , & ! Output: [real(r8) (:) ] maximum annual depth of thaw
altmax_lastyear => canopystate_vars%altmax_lastyear_col , & ! Output: [real(r8) (:) ] prior year maximum annual depth of thaw
altmax_1989 => canopystate_vars%altmax_1989_col , & ! Output: [real(r8) (:) ] maximum ALT in 1989
altmax_ever => canopystate_vars%altmax_ever_col , & ! Output: [real(r8) (:) ] maximum thaw depth since initialization
alt_indx => canopystate_vars%alt_indx_col , & ! Output: [integer (:) ] current depth of thaw
altmax_indx => canopystate_vars%altmax_indx_col , & ! Output: [integer (:) ] maximum annual depth of thaw
altmax_lastyear_indx => canopystate_vars%altmax_lastyear_indx_col , & ! Output: [integer (:) ] prior year maximum annual depth of thaw
altmax_1989_indx => canopystate_vars%altmax_1989_indx_col, & ! Output: [integer (:) ] index of maximum ALT in 1989
altmax_ever_indx => canopystate_vars%altmax_ever_indx_col, & ! Output: [integer (:) ] maximum thaw depth since initialization
excess_ice => col_ws%excess_ice , & ! Input/output:[real(r8) (:,:)] depth variable excess ice content in soil column (-)
rmax => col_ws%iwp_microrel , & ! Output: [real(r8) (:) ] ice wedge polygon microtopographic relief (m)
vexc => col_ws%iwp_exclvol , & ! Output: [real(r8) (:) ] ice wedge polygon excluded volume (m)
ddep => col_ws%iwp_ddep , & ! Output: [real(r8) (:) ] ice wedge polygon depression depth (m)
subsidence => col_ws%iwp_subsidence , & ! Input/output:[real(r8)(:)] ice wedge polygon subsidence (m)
frac_melted => col_ws%frac_melted & ! Input/output:[real(r8)(:)] fraction of layer that has ever melted (-)
)

! on a set annual timestep, update annual maxima
Expand Down Expand Up @@ -144,14 +160,111 @@ subroutine alt_calc(num_soilc, filter_soilc, &
endif
endif


! if appropriate, update maximum annual active layer thickness
if (alt(c) > altmax(c)) then
altmax(c) = alt(c)
altmax_indx(c) = alt_indx(c)
endif
if (alt(c) > altmax_ever(c)) then
if (spinup_state .eq. 0) then
altmax_ever(c) = alt(c)
altmax_ever_indx(c) = alt_indx(c)
else !overwrite if in spinup
altmax_ever(c) = 0._r8
altmax_ever_indx(c) = 0
endif
endif

! special loop for if year = 1989, see above note regarding
! replacing with more physically based mechanism.
if (year .eq. 1989) then
altmax_1989(c) = altmax(c)
altmax_1989_indx(c) = altmax_indx(c)
endif

end do
if (use_polygonal_tundra) then
! update subsidence based on change in ALT
! melt_profile stores the amount of excess_ice
! melted in this timestep.
! note that this may cause some unexpected results
! for taliks

! initialize melt_profile as zero
melt_profile(:) = 0._r8

do j = nlevgrnd,1,-1 ! note, this will go from bottom to top
if (j .gt. k_frz + 1) then ! all layers below k_frz + 1 remain frozen
melt_profile(j) = 0.0_r8
else if (j .eq. k_frz + 1) then ! first layer below the 'thawed' layer
! need to check to see if the active layer thickness is is actually
! in this layer (and not between the midpoint of j_frz and bottom interface
! or else inferred melt will be negative
! also note: only have ice to melt if alt has never been this deep, otherwise
! ice will continue to be removed each time step the alt remains in this layer
if ((alt(c)-zisoi(j-1)) .ge. 0._r8 .and. (alt(c) .eq. altmax_ever(c)) .and. (frac_melted(c,j) .lt. 1._r8)) then
orig_excess = (1._r8/(1._r8-frac_melted(c,j))) * excess_ice(c,j)
old_mfrac = frac_melted(c,j)
! update frac melted
frac_melted(c,j) = min(max(frac_melted(c,j), (alt(c)-zisoi(j-1))/dzsoi(j)),1._r8)
melt_profile(j) = orig_excess*(frac_melted(c,j) - old_mfrac)
excess_ice(c,j) = excess_ice(c,j) - melt_profile(j)
else
melt_profile(j) = 0._r8 ! no melt
end if
else if (j .eq. k_frz) then
if (alt(c) .eq. altmax_ever(c) .and. (frac_melted(c,j) .lt. 1._r8)) then
orig_excess = (1._r8/(1._r8 - frac_melted(c,j))) * excess_ice(c,j)
old_mfrac = frac_melted(c,j)
! update frac_melted:
frac_melted(c,j) = min(max(frac_melted(c,j), (alt(c)-zsoi(j-1))/dzsoi(j)),1._r8)
! remove ice, only if alt has never been this deep before:
melt_profile(j) = orig_excess*(frac_melted(c,j) - old_mfrac)
excess_ice(c,j) = excess_ice(c,j) - melt_profile(j)
else
melt_profile(j) = 0._r8
end if
else !
melt_profile(j) = excess_ice(c,j)
! remove melted excess ice
excess_ice(c,j) = 0._r8
end if
! calculate subsidence at this layer:
melt_profile(j) = melt_profile(j) * dzsoi(j)
end do

! subsidence is integral of melt profile:
if ((year .ge. 1989) .and. (altmax_ever(c) .ge. altmax_1989(c))) then
subsidence(c) = subsidence(c) + sum(melt_profile)
end if

! limit subsidence to 0.4 m
subsidence(c) = min(0.4_r8, subsidence(c))

! update ice wedge polygon microtopographic parameters if in polygonal ground
!rpf - min/max logic may be redunant w/ subsidence limiter above
!rpf - TODO: many of these (particularly the invariant ones) should be
! moved to data_types/ColumnDataType.F90 to avoid the highcenpoly elseif condition
! each time step.
if (lun_pp%ispolygon(col_pp%landunit(c))) then
if (lun_pp%polygontype(col_pp%landunit(c)) .eq. ilowcenpoly) then
rmax(c) = 0.4_r8
vexc(c) = 0.2_r8
ddep(c) = max(0.05_r8, 0.15_r8 - 0.25_r8*subsidence(c))
elseif (lun_pp%polygontype(col_pp%landunit(c)) .eq. iflatcenpoly) then
rmax(c) = min(0.4_r8, 0.1_r8 + 0.75_r8*subsidence(c))
vexc(c) = min(0.2_r8, 0.05_r8 + 0.375_r8*subsidence(c))
ddep(c) = min(0.05_r8, 0.01_r8 + 0.1_r8*subsidence(c))
elseif (lun_pp%polygontype(col_pp%landunit(c)) .eq. ihighcenpoly) then
rmax(c) = 0.4_r8
vexc(c) = 0.2_r8
ddep(c) = 0.05_r8
else
!call endrun !<- TODO: needed? Potential way to prevent unintended updating of microtopography
! if polygonal ground is misspecified on surface file.
endif
endif
endif
end do

end associate

Expand Down
Loading