94de8518 by Nathan Lighthart

Add CO2 effects to Potential Crop Growth

- Add input variable co2
- Add routine to calculate biomass using co2
1 parent 2aaf8ad9
......@@ -184,6 +184,10 @@ public class PotentialCropGrowthAdapter extends AnnotatedAdapter {
@Optional
@Input @Output public double BioYield;
@Description("the daily atmospheric level of CO2")
@Units("ppm")
@Input public double co2;
@Description("Amount N Added to Residue Pool After Harvesting")
@Units("kgN/ha")
@Output public double Addresidue_pooln;
......@@ -210,6 +214,9 @@ public class PotentialCropGrowthAdapter extends AnnotatedAdapter {
@Description("DLAI (Senescence)")
@Output public double dlai;
@Description("Co2Effect")
@Output public double co2effect;
private Map<HRU, PotentialCropGrowthSWAT> swatComponentMap = new ConcurrentHashMap<>();
@Override
......@@ -230,7 +237,9 @@ public class PotentialCropGrowthAdapter extends AnnotatedAdapter {
private void executeSWAT() {
PotentialCropGrowthSWAT component = swatComponentMap.get(hru);
if (component == null) {
//component = new PotentialCropGrowthSWAT();
component = new PotentialCropGrowthSWAT();
swatComponentMap.put(hru, component);
}
......@@ -288,6 +297,9 @@ public class PotentialCropGrowthAdapter extends AnnotatedAdapter {
component.FPHUact = FPHUact;
component.nfert = nfert;
// co2
component.co2 = co2;
component.execute();
plantStateReset = component.plantStateReset;
......@@ -316,6 +328,7 @@ public class PotentialCropGrowthAdapter extends AnnotatedAdapter {
topt = component.topt;
fr3N = component.fr3N;
dlai = component.dlai;
co2effect = component.co2eff;
}
private void executeUPGM() {
......
......@@ -21,6 +21,9 @@
package crop;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;
public class PotentialCropGrowthSWAT {
......@@ -88,6 +91,20 @@ public class PotentialCropGrowthSWAT {
public double fracharvestn;
private double LAI_delta;
private static final boolean DO_CO2_BIOMASS = false;
// For co2 response.
public double co2;
public double co2eff;
// Assuming hardcoded values for initial testing will be ok. Eventually this could be user input.
// c4 crops
private static final List<Double> CO2_X_C4CROPS = Arrays.asList(0.0, 220.0, 280.0, 330.0, 400.0, 490.0, 570.0, 750.0, 990.0, 9999.0);
private static final List<Double> CO2_Y_C4CROPS = Arrays.asList(0.00, 0.85, 0.95, 1.00, 1.02, 1.04, 1.05, 1.06, 1.07, 1.08);
// c5 crops
private static final List<Double> CO2_X_C3CROPS = Arrays.asList(0.0, 220.0, 330.0, 440.0, 550.0, 660.0, 770.0, 880.0, 990.0, 9999.0);
private static final List<Double> CO2_Y_C3CROPS = Arrays.asList(0.00, 0.71, 1.00, 1.08, 1.17, 1.25, 1.32, 1.38, 1.43, 1.50);
public void execute() {
BioYield = 0;
......@@ -103,7 +120,12 @@ public class PotentialCropGrowthSWAT {
calc_phu();
calc_lai();
calc_biomass();
if (DO_CO2_BIOMASS) {
calc_co2_biomass();
} else {
co2eff = 1.0;
calc_biomass();
}
CanHeightAct = calc_canopy();
calc_root();
calc_nuptake();
......@@ -207,6 +229,43 @@ public class PotentialCropGrowthSWAT {
BioOpt_delta = (dormancy) ? 0 : BioOpt_delta;
}
private void calc_co2_biomass() {
co2eff = 1.0; // default = no impact.
int indexLess = 0;
int indexPlusOne = 0;
if (idc == 4) {
// c4 crops (?maybe?)
// either exact position of co2 value, or pos - 1 in array.
int indx = Collections.binarySearch(CO2_X_C4CROPS, co2);
if (indx < 0) {
indexLess = Math.abs(indx) - 2;
indexPlusOne = Math.abs(indx) - 1;
} else {
indexLess = indx;
indexPlusOne = Math.abs(indx) + 1;
}
co2eff = (co2 - CO2_X_C4CROPS.get(indexLess)) * (CO2_Y_C4CROPS.get(indexPlusOne) - CO2_Y_C4CROPS.get(indexLess))
/ (CO2_X_C4CROPS.get(indexPlusOne) - CO2_X_C4CROPS.get(indexLess)) + CO2_Y_C4CROPS.get(indexLess);
} else {
// either exact position of co2 value, or pos - 1 in array.
int indx = Collections.binarySearch(CO2_X_C3CROPS, co2);
if (indx < 0) {
indexLess = Math.abs(indx) - 2;
indexPlusOne = Math.abs(indx) - 1;
} else {
indexLess = indx;
indexPlusOne = Math.abs(indx) + 1;
}
co2eff = (co2 - CO2_X_C3CROPS.get(indexLess)) * (CO2_Y_C3CROPS.get(indexPlusOne) - CO2_Y_C3CROPS.get(indexLess))
/ (CO2_X_C3CROPS.get(indexPlusOne) - CO2_X_C3CROPS.get(indexLess)) + CO2_Y_C3CROPS.get(indexLess);
}
double Hphosyn = 0.5 * solRad * (1 - Math.exp(LExCoef * LAI)) * co2eff; // intercepted photosynthetically active radiation (MJ/m^2)
BioOpt_delta = rue * Hphosyn;
BioOpt_delta = (dormancy) ? 0 : BioOpt_delta;
}
// canopy cover
// canopy cover is expressed as a function of LAI
private double calc_canopy() {
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!