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

{WIP} LPJ-GUESS SDA Couplers #2660

Draft
wants to merge 68 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
84f3c25
started new read state function
istfer Jun 8, 2019
1c96f7d
add helper function that locates function
istfer Jun 8, 2019
2747330
add helper function that finds closing paranthesis
istfer Jun 8, 2019
0518d2c
add function that finds stream
istfer Jun 10, 2019
c8fc996
start reading
istfer Jun 13, 2019
4ac6530
first read
istfer Jun 13, 2019
6e92048
extract typedef enums
istfer Jun 13, 2019
6d2bac5
read typedef enum
istfer Jun 13, 2019
4221e09
read Historic
istfer Jun 13, 2019
d477ca7
read vector
istfer Jun 13, 2019
b1bf79e
read vector with const int
istfer Jun 14, 2019
7faffa8
read in parameters header too
istfer Jun 14, 2019
3921cc3
case fo seed
istfer Jun 14, 2019
2f8bbda
ready to loop over stands
istfer Jun 15, 2019
b3b0025
start looping over patches
istfer Jun 15, 2019
45970e5
reading individual class
istfer Jun 15, 2019
d6ef1ec
first pass at read individual
istfer Jun 16, 2019
d58848d
finish individual
istfer Jun 17, 2019
3ab63d9
few more flexibility
istfer Jun 17, 2019
83b996b
read matrix
istfer Jun 17, 2019
f66c54a
getting ready to read sompool
istfer Jun 17, 2019
4a6ea5a
catch one more case
istfer Jun 18, 2019
1bb8b87
finished soil
istfer Jun 18, 2019
d84f80f
adding more hardcoded constants for now
istfer Jun 18, 2019
f9899dd
getting ready to read fluxes
istfer Jun 18, 2019
af59c40
finished patch
istfer Jun 18, 2019
4e42c6c
finished reading all - first pass
istfer Jun 18, 2019
94d304c
Added allometry and allocation functions from LPJ-GUESS. Also summin…
MagicForrest Jun 18, 2019
cc3cceb
read meta.bin
istfer Jun 19, 2019
b88b529
allocation() function now correctly included
MagicForrest Jun 19, 2019
64fbdeb
k_latosa is sapwood_ratio in pecan
istfer Jun 19, 2019
bbb97a6
Merge branch 'develop' of github.com:PecanProject/pecan into LPJGUESS…
istfer Jun 19, 2019
58709a6
small rearrangement for compilation
istfer Jun 19, 2019
c27d10f
add new par minmoist_est
istfer Jun 19, 2019
645bb7d
Allocation of biomass now also works. It seems to fail when scaling…
MagicForrest Jun 19, 2019
50170e2
using phenology and leafphysiognomy
istfer Jun 20, 2019
e479b8d
Added allometry() call. Gives the target results for a biomass chang…
MagicForrest Jun 20, 2019
05dcadb
Factorised the adjustDensity and adjustBiomass code.
MagicForrest Jun 20, 2019
a601256
few modifications for PalEON model version
istfer Jun 21, 2019
0c6f624
parsing files some more
istfer Jun 21, 2019
3293a0d
Also scale and adjust N pools.
MagicForrest Jun 21, 2019
aae14e6
Mostly code tidying/documentation ahead of merging.
MagicForrest Jun 21, 2019
2b4e6b9
Merge branch 'LPJGUESS_SDA' into LPJGUESS_SDA
istfer Jun 21, 2019
09ea06e
Merge pull request #2 from MagicForrest/LPJGUESS_SDA
istfer Jun 21, 2019
6fdb02b
modifying function for PalEON version
istfer Jun 21, 2019
e34ea19
Merge branch 'LPJGUESS_SDA' of https://github.com/istfer/pecan into L…
istfer Jun 21, 2019
c86b1a3
read new PhotosynthesisResults
istfer Jun 22, 2019
ecc6faf
updates for the new model version, first pass finished
istfer Jun 24, 2019
cb206bf
Documented adjustBiomass() and cleaned the fucntion a little.
MagicForrest Jun 24, 2019
3df3ec0
start read_restart.LPJGUESS
istfer Jun 24, 2019
a0d938e
LPJGUESS uses exact days and will require split inputs function
istfer Jun 24, 2019
9f8e777
backbone of read_restart
istfer Jun 24, 2019
aa3acf5
Added HEIGHT_MAX as an argument to over-ride the LPJ-GUESS 150m max h…
MagicForrest Jun 24, 2019
85c4a1f
Merge branch 'LPJGUESS_SDA' of github.com:MagicForrest/pecan into LPJ…
MagicForrest Jun 24, 2019
49085a5
start split inputs for LPJGUESS
istfer Jun 25, 2019
90c4c07
number of individuals are back
istfer Jun 26, 2019
a0572c0
Just coding style
MagicForrest Jun 27, 2019
fa628db
Merge branch 'LPJGUESS_SDA' into LPJGUESS_SDA
istfer Jun 27, 2019
4f60bce
Merge pull request #3 from MagicForrest/LPJGUESS_SDA
istfer Jun 27, 2019
3adac8e
define state year
istfer Jun 27, 2019
94da6de
Merge branch 'LPJGUESS_SDA' of https://github.com/istfer/pecan into L…
istfer Jun 27, 2019
14d05f6
add doc tags
istfer Jun 28, 2019
47a7c05
LPJGUESS package build
istfer Jun 28, 2019
e6d5138
no need for single quote
istfer Jun 28, 2019
2273bbd
Merge branch 'develop' of github.com:PecanProject/pecan into LPJGUESS…
istfer Jun 28, 2019
0f94f65
Merge branch 'develop' of github.com:PecanProject/pecan into LPJGUESS…
istfer Jul 17, 2020
4c5530a
Merge branch 'develop' into LPJGUESS_SDA
infotroph May 4, 2023
82dd326
Merge branch 'develop' into LPJGUESS_SDA
mdietze Nov 8, 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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ PEcAnRTM_*.*tar.gz
**/vignettes/pecan
cache
# Files generated by Rstudio
# MF - ignore C++ compiled files
*.o
*.so
*.Rproj*
book_source/**/*.html
# files generated by fia2ed script
Expand Down
1 change: 1 addition & 0 deletions models/lpjguess/DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Imports:
PEcAn.utils,
lubridate (>= 1.6.0),
ncdf4 (>= 1.15),
Rcpp (>= 1.0.1),
tibble
Suggests:
testthat (>= 1.0.2)
Expand Down
5 changes: 5 additions & 0 deletions models/lpjguess/NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
# Generated by roxygen2: do not edit by hand

export(calculateGridcellVariablePerPFT)
export(met2model.LPJGUESS)
export(model2netcdf.LPJGUESS)
export(pecan2lpjguess)
export(readStateBinary)
export(split_inputs.LPJGUESS)
export(update.state.LPJGUESS)
export(write.config.LPJGUESS)
export(write.insfile.LPJGUESS)
importFrom(Rcpp,sourceCpp)
importFrom(ncdf4,nc_close)
importFrom(ncdf4,ncatt_get)
importFrom(ncdf4,ncatt_put)
importFrom(ncdf4,ncdim_def)
importFrom(ncdf4,ncvar_def)
importFrom(ncdf4,ncvar_get)
useDynLib(PEcAn.LPJGUESS)
7 changes: 7 additions & 0 deletions models/lpjguess/R/RcppExports.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Generated by using Rcpp::compileAttributes() -> do not edit by hand
# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393

allocation <- function(bminc, cmass_leaf, cmass_root, cmass_sap, cmass_debt, cmass_heart, ltor, height, sla, wooddens, lifeform, k_latosa, k_allom2, k_allom3, cmass_leaf_inc, cmass_root_inc, cmass_sap_inc, cmass_debt_inc, cmass_heart_inc, litter_leaf_inc, litter_root_inc, exceeds_cmass) {
.Call('_PEcAn_LPJGUESS_allocation', PACKAGE = 'PEcAn.LPJGUESS', bminc, cmass_leaf, cmass_root, cmass_sap, cmass_debt, cmass_heart, ltor, height, sla, wooddens, lifeform, k_latosa, k_allom2, k_allom3, cmass_leaf_inc, cmass_root_inc, cmass_sap_inc, cmass_debt_inc, cmass_heart_inc, litter_leaf_inc, litter_root_inc, exceeds_cmass)
}

145 changes: 145 additions & 0 deletions models/lpjguess/R/adjust.biomass.LPJGUESS.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#-------------------------------------------------------------------------------
# Copyright (c) 2012 University of Illinois, NCSA.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the
# University of Illinois/NCSA Open Source License
# which accompanies this distribution, and is available at
# http://opensource.ncsa.illinois.edu/license.html
#-------------------------------------------------------------------------------

##' Adjust LPJ-GUESS individual's biomass
##'
##' This function adjusts an LPJ-GUESS individual by calling the LPJ-GUESS allocation function (compiled C++)
##' with a given biomass change. It updates the individual biomass pools directly, and also returns, in a list further
##' adjustments to the litter pools.
##'
##' @param individual A nested list which encapsulates an LPJ-GUESS 'Individual' as read from a binary state file
##' @param rel.change A numeric by which to scale the density and C and N pools
##' @param sla The SLA (specific leaf area) (per PFT parameter)
##' @param k_latosa The leaf area to sapwood area ratio (per PFT parameter)
##' @param k_allom2,k_allom3, Allometry coefficients (per PFT parameters)
##' @param wooddens Wood density (kgC/m^2) (per PFT parameter)
##' @param crownarea_max Maximum allowed crown area (m^2) (per PFT parameter)
##' @param lifeform An integer code for the lifeform of this individual (cohort): 1 = Tree, 2 = Grass
##'
##' The changes in C pools are determined by the allocation. The changes in the N pools are designed to
##' maintain the pre-exisiing C:N ratios, so N is just scaled using the updated C with the initial C:N ratio.
##' The N storage pools (nstore_longterm and nstore_labile) don't have pre-existing C:N ratios, so they are
##' just scaled by the overall biomass change (the 'rel.change' argument to the function).
##'
##' Note that after this function is called the function \code{allometry} should be used to update the individual
##' and to check that the newly updated individual has a 'valid' allometry. The litter pools should also be updated.
##' This is implemented in the \code{updateState} function following the call to this \code{adjustBiomass} function.
##'
##'
##' @keywords internal
##' @return the scaled 'individual' (the initial nested list with update values)
##' @author Matthew Forrest
adjust.biomass.LPJGUESS <- function(individual, rel.change, sla, wooddens, lifeform, k_latosa, k_allom2, k_allom3){

# dummy input values to the allocation function below
# note that they are not actually updated by the function, the updated values are in the returned list
cmass_leaf_inc <- 0
cmass_root_inc <- 0
cmass_sap_inc <- 0
cmass_debt_inc <- 0
cmass_heart_inc <- 0
litter_leaf_inc <- 0
litter_root_inc <- 0
exceeds_cmass <- 0

# calculate the total biomass and the absolute change based on this
biomass.total <- individual$cmass_leaf+individual$cmass_root+individual$cmass_heart+individual$cmass_sap-individual$cmass_debt
biomass.inc <- (biomass.total * rel.change) - biomass.total


updated.pools <- allocation(
# vegetation state
bminc = as.numeric(biomass.inc/individual$densindiv),
cmass_leaf = as.numeric(individual$cmass_leaf/individual$densindiv),
cmass_root = as.numeric(individual$cmass_root/individual$densindiv),
cmass_sap = as.numeric(individual$cmass_sap/individual$densindiv),
cmass_debt = as.numeric(individual$cmass_debt/individual$densindiv),
cmass_heart = as.numeric(individual$cmass_heart/individual$densindiv),
ltor = as.numeric(individual$ltor),
height = as.numeric(individual$height),
# PFT parameters
sla = as.numeric(sla),
wooddens = as.numeric(wooddens),
lifeform = as.integer(lifeform),
k_latosa = as.numeric(k_latosa),
k_allom2 = as.numeric(k_allom2),
k_allom3 = as.numeric(k_allom3),
# calculated increments (not actually used, the updated values returned in the updated.pools list)
cmass_leaf_inc = as.numeric(cmass_leaf_inc),
cmass_root_inc = as.numeric(cmass_root_inc),
cmass_sap_inc = as.numeric(cmass_sap_inc),
cmass_debt_inc = as.numeric(cmass_debt_inc),
cmass_heart_inc = as.numeric(cmass_heart_inc),
litter_leaf_inc = as.numeric(litter_leaf_inc),
litter_root_inc = as.numeric(litter_root_inc),
exceeds_cmass = as.numeric(exceeds_cmass))


# adjust the various associated C (and N) pools based on the results of the allocation call

# leaf
original.cmass_leaf <- individual$cmass_leaf
new.cmass_leaf <- individual$cmass_leaf + (updated.pools[["cmass_leaf_inc"]] * individual$densindiv)
leaf.scaling <- new.cmass_leaf / original.cmass_leaf
individual$cmass_leaf <- new.cmass_leaf
individual$nmass_leaf <- individual$nmass_leaf * leaf.scaling

# root
original.cmass_root <- individual$cmass_root
new.cmass_root <- individual$cmass_root + (updated.pools[["cmass_root_inc"]] * individual$densindiv)
root.scaling <- new.cmass_root / original.cmass_root
individual$cmass_root <- new.cmass_root
individual$nmass_root <- individual$nmass_root * root.scaling


# sap, heart and debt only for trees
if(lifeform == 1) {

# sap
original.cmass_sap <- individual$cmass_sap
new.cmass_sap <- individual$cmass_sap + (updated.pools[["cmass_sap_inc"]] * individual$densindiv)
sap.scaling <- new.cmass_sap / original.cmass_sap
individual$cmass_sap <- new.cmass_sap
individual$nmass_sap <- individual$nmass_sap * sap.scaling


# heart
original.cmass_heart <- individual$cmass_heart
new.cmass_heart <- individual$cmass_heart + (updated.pools[["cmass_heart_inc"]] * individual$densindiv)
heart.scaling <- new.cmass_heart / original.cmass_heart
individual$cmass_heart <- new.cmass_heart
individual$nmass_heart <- individual$nmass_heart * heart.scaling

# debt - note no equivalant N debt
original.cmass_debt <- individual$cmass_debt
new.cmass_debt <- individual$cmass_debt + (updated.pools[["cmass_debt_inc"]] * individual$densindiv)
individual$cmass_debt <- new.cmass_debt

}


# N labile and long term storage - note no equivalant C pools and they are not determined by allocation upgrade,
# so simply scale by the overall biomass change
individual$nstore_labile <- individual$nstore_labile * rel.change
individual$nstore_longterm <- individual$nstore_longterm * rel.change


# TODO (potentially): MF - for simulations involving managed forestry and harvest the variable 'cmass_wood_inc_5'
# should also be updated. This is a vector, and I am not sure if the increment should go at the start or the end of it.
# But also, how to deal simultaneously with harvesting and nudging will probably require some thought, and maybe
# it is not necessary or appropriate to update this variable
#print(individual$cmass_wood_inc_5)

return(list(individual = individual,
litter_leaf_inc = updated.pools[["litter_leaf_inc"]],
litter_root_inc = updated.pools[["litter_root_inc"]],
exceeds_cmass = updated.pools[["exceeds_cmass"]]
))

}
43 changes: 43 additions & 0 deletions models/lpjguess/R/adjust.density.LPJGUESS.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#-------------------------------------------------------------------------------
# Copyright (c) 2012 University of Illinois, NCSA.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the
# University of Illinois/NCSA Open Source License
# which accompanies this distribution, and is available at
# http://opensource.ncsa.illinois.edu/license.html
#-------------------------------------------------------------------------------

##' Adjust LPJ-GUESS individual's density
##'
##' Very simple function that just scales the density of individuals and the associated C and N pools
##' by a relative amount
##'
##' @param individual A nested list which encapsulates an LPJ-GUESS 'Individual' as read from a binary state file
##' @param rel.change A numeric by which to scale the density and C and N pools
##'
##'
##' @keywords internal
##' @return the scaled 'individual' (the initial nested list with update values)
##' @author Matthew Forrest
adjust.density.LPJGUESS <- function(individual, rel.change) {

# the density
individual$densindiv <- individual$densindiv * rel.change
#the coupled C and N pools
individual$cmass_leaf <- individual$cmass_leaf * rel.change
individual$nmass_leaf <- individual$nmass_leaf * rel.change
individual$cmass_root <- individual$cmass_root * rel.change
individual$nmass_root <- individual$nmass_root * rel.change
individual$cmass_sap <- individual$cmass_sap * rel.change
individual$nmass_sap <- individual$nmass_sap * rel.change
individual$cmass_heart <- individual$cmass_heart * rel.change
individual$nmass_heart <- individual$nmass_heart * rel.change
# the carbon debt ('retrocative storage' with no N couterpart)
individual$cmass_debt <- individual$cmass_debt * rel.change
# labile and long term N storage with no C counterparts
individual$nstore_longterm <- individual$nstore_longterm * rel.change
individual$nstore_labile <- individual$nstore_labile * rel.change

return(individual)

}
6 changes: 6 additions & 0 deletions models/lpjguess/R/allocation.LPJGUESS.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
##' @useDynLib PEcAn.LPJGUESS
##' @importFrom Rcpp sourceCpp
NULL

# compile the LPJ-GUESS allocation function using Rcpp
sourceCpp("src/allocation.LPJGUESS.cpp")
Loading
Loading