From 50906f96647d03f656ea037942fad1f1963b45e2 Mon Sep 17 00:00:00 2001 From: s1924442 <b.arendarczyk@sms.ed.ac.uk> Date: Wed, 31 Mar 2021 14:49:38 +0100 Subject: [PATCH] Added carbon demand from external file. --- src/ac/ed/lurg/ModelConfig.java | 4 +- src/ac/ed/lurg/ModelMain.java | 7 +- src/ac/ed/lurg/country/CountryAgent.java | 2 +- .../ed/lurg/country/CountryAgentManager.java | 2 +- .../country/crafty/CraftyCountryAgent.java | 8 ++- .../country/crafty/CraftyProdManager.java | 4 +- .../ed/lurg/demand/AbstractDemandManager.java | 6 ++ .../ed/lurg/demand/CarbonDemandManager.java | 64 +++++++++++++++++++ 8 files changed, 86 insertions(+), 11 deletions(-) create mode 100644 src/ac/ed/lurg/demand/CarbonDemandManager.java diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java index 77dddcf6..583b7be0 100755 --- a/src/ac/ed/lurg/ModelConfig.java +++ b/src/ac/ed/lurg/ModelConfig.java @@ -424,8 +424,10 @@ public class ModelConfig { public static final String TARGET_DIET_FILE = getProperty("TARGET_DIET_FILE", DATA_DIR + File.separator + "TargetDiet.txt"); // Forestry parameters - public static final String CONVERSION_COST_FILE = DATA_DIR + File.separator + "conversion_costs.csv"; + public static final String CONVERSION_COST_FILE = DATA_DIR + File.separator + "conversion_costs.csv"; // cost of converting from one land cover to another, $1000/ha public static final String SERIALIZED_CARBON_MARKET_FILE = CALIB_DIR + File.separator + "CarbonMarket.ser"; + public static final String CARBON_DEMAND_FILENAME = getProperty("CARBON_DEMAND_FILENAME", "carbon_demand.csv"); + public static final String CARBON_DEMAND_FILE = getProperty("CARBON_DEMAND_FILE", DATA_DIR + File.separator + CARBON_DEMAND_FILENAME); public static final double CARBON_PRICE = getDoubleProperty("CARBON_PRICE", 0.02); // $1000/tC-eq public static final double WOOD_PRICE = getDoubleProperty("WOOD_PRICE", 0.05); // $1000/tC-eq public static final int FOREST_LOCKIN_PERIOD = getIntProperty("FOREST_LOCKIN_PERIOD", 30); // cannot convert forest after planting for this many years diff --git a/src/ac/ed/lurg/ModelMain.java b/src/ac/ed/lurg/ModelMain.java index 6d8d436f..91402619 100644 --- a/src/ac/ed/lurg/ModelMain.java +++ b/src/ac/ed/lurg/ModelMain.java @@ -143,13 +143,12 @@ public class ModelMain { double previousGen2EcDDemand = (timestep.isInitialTimestep() || ModelConfig.IS_CALIBRATION_RUN ) ? 0: demandManager.getSecondGenBioenergyDemand(timestep.getPreviousTimestep()); double gen2EcDDemand = demandManager.getSecondGenBioenergyDemand(ModelConfig.IS_CALIBRATION_RUN ? new Timestep(1) : timestep); double gen2Increase = (gen2EcDDemand>previousGen2EcDDemand) ? gen2EcDDemand - previousGen2EcDDemand : 0.0; - double previousCarbonDemand = (timestep.isInitialTimestep() || ModelConfig.IS_CALIBRATION_RUN ) ? 0: 0.0; - double carbonDemand = 1000; //TODO read from file - double carbonDemandIncrease = (carbonDemand > previousCarbonDemand) ? carbonDemand - previousCarbonDemand: 0; + double previousCarbonDemand = (timestep.isInitialTimestep() || ModelConfig.IS_CALIBRATION_RUN ) ? 0: demandManager.getCarbonDemand(timestep.getPreviousTimestep()); + double carbonDemand = demandManager.getCarbonDemand(ModelConfig.IS_CALIBRATION_RUN ? new Timestep(1) : timestep); + double carbonDemandIncrease = (carbonDemand > previousCarbonDemand) ? carbonDemand - previousCarbonDemand: 0; CarbonFluxRasterSet currentCarbonFluxData = getCarbonFluxData(timestep); - WoodYieldRasterSet currentWoodYieldData = getWoodYieldData(timestep); DoubleMap<LandCoverType, LandCoverType, Double> conversionCosts = new ConversionCostReader().read(); diff --git a/src/ac/ed/lurg/country/CountryAgent.java b/src/ac/ed/lurg/country/CountryAgent.java index 8478526c..d1308e99 100644 --- a/src/ac/ed/lurg/country/CountryAgent.java +++ b/src/ac/ed/lurg/country/CountryAgent.java @@ -219,7 +219,7 @@ public class CountryAgent extends AbstractCountryAgent { importConstraints.put(crop, new TradeConstraint(baseTrade - changeDown, baseTrade + changeUp)); } - // Carbon import/export constraints + // Carbon import/export constraints TODO not used double baseTrade = getNetCarbonFlux(); double countryArea = LandUseItem.getTotalLandArea(previousGamsRasterOutput.getLandUses().values()); double changeUp = 0.0; diff --git a/src/ac/ed/lurg/country/CountryAgentManager.java b/src/ac/ed/lurg/country/CountryAgentManager.java index 1012723d..3ca85261 100644 --- a/src/ac/ed/lurg/country/CountryAgentManager.java +++ b/src/ac/ed/lurg/country/CountryAgentManager.java @@ -137,7 +137,7 @@ public class CountryAgentManager { } if (craftyCountryAgents.size() > 0) { - craftyManager.updateWithCraftyData(craftyCountryAgents, timestep, internationalMarket.getWorldPrices()); // this will wait for the marker file from CRAFTY + craftyManager.updateWithCraftyData(craftyCountryAgents, timestep, internationalMarket.getWorldPrices(), internationalMarket.getCarbonPrice()); // this will wait for the marker file from CRAFTY } } diff --git a/src/ac/ed/lurg/country/crafty/CraftyCountryAgent.java b/src/ac/ed/lurg/country/crafty/CraftyCountryAgent.java index af0145d6..8879fd0d 100644 --- a/src/ac/ed/lurg/country/crafty/CraftyCountryAgent.java +++ b/src/ac/ed/lurg/country/crafty/CraftyCountryAgent.java @@ -28,8 +28,8 @@ public class CraftyCountryAgent extends AbstractCountryAgent { return cropUsageData; } - public void updateProduction(Map<CropType, Double> cropProduction, Map<CropType, GlobalPrice> worldPrices) { - calculateCountryPricesAndDemand(worldPrices, false); + public void updateProduction(Map<CropType, Double> cropProduction, Map<CropType, GlobalPrice> worldPrices, GlobalPrice carbonPrice) { + calculateCountryPricesAndDemand(worldPrices, carbonPrice, false); cropUsageData = new HashMap<CropType, CropUsageData>(); for (Entry<CropType, Double> entry : cropProduction.entrySet()) { @@ -50,4 +50,8 @@ public class CraftyCountryAgent extends AbstractCountryAgent { } return commPricePlum; } + + public double getNetCarbonFlux() { + return 0; + } } \ No newline at end of file diff --git a/src/ac/ed/lurg/country/crafty/CraftyProdManager.java b/src/ac/ed/lurg/country/crafty/CraftyProdManager.java index 1a4414bc..7b67dccf 100644 --- a/src/ac/ed/lurg/country/crafty/CraftyProdManager.java +++ b/src/ac/ed/lurg/country/crafty/CraftyProdManager.java @@ -32,7 +32,7 @@ public class CraftyProdManager { return craftyCountries; } - public void updateWithCraftyData(Collection<CraftyCountryAgent> craftyCountryAgents, Timestep timestep, Map<CropType, GlobalPrice> worldPrices) { + public void updateWithCraftyData(Collection<CraftyCountryAgent> craftyCountryAgents, Timestep timestep, Map<CropType, GlobalPrice> worldPrices, GlobalPrice carbonPrice) { String rootDir = ModelConfig.CRAFTY_PRODUCTION_DIR + File.separator + timestep.getYear(); long startTime = System.currentTimeMillis(); @@ -66,7 +66,7 @@ public class CraftyProdManager { if (cropProduction.size() < CropType.getImportedTypes().size()) { // Don't need setaside or pasture, which aren't imported either LogWriter.printlnError("Not all crops present in Crafty production for country: " + cca.getCountry() + " only " + cropProduction.size()); } - cca.updateProduction(cropProduction, worldPrices); + cca.updateProduction(cropProduction, worldPrices, carbonPrice); } catch (Exception e) { LogWriter.println("Problem getting Crafty data for: " + cca.getCountry()); diff --git a/src/ac/ed/lurg/demand/AbstractDemandManager.java b/src/ac/ed/lurg/demand/AbstractDemandManager.java index 81808f06..f97074d4 100644 --- a/src/ac/ed/lurg/demand/AbstractDemandManager.java +++ b/src/ac/ed/lurg/demand/AbstractDemandManager.java @@ -19,12 +19,14 @@ public abstract class AbstractDemandManager { protected CalorieManager calorieManager; protected BioenergyDemandManager bioenergyDemandManager; protected CerealFractionsManager cerealFractionsManager; + protected CarbonDemandManager carbonDemandManager; public AbstractDemandManager(CompositeCountryManager compositeCountryManager, CalorieManager calorieManager) { this.compositeCountryManager = compositeCountryManager; this.calorieManager = calorieManager; bioenergyDemandManager = new BioenergyDemandManager(); cerealFractionsManager = new CerealFractionsManager(compositeCountryManager); + carbonDemandManager = new CarbonDemandManager(); } public Map<CommodityType, Double> getDemand(CompositeCountry cc, int year, Map<CommodityType, Double> prices, boolean outputGamsDemand) { @@ -130,5 +132,9 @@ public abstract class AbstractDemandManager { // LogWriter.println("updated map " + updatedFoodDemandMap); return updatedFoodDemandMap; } + + public double getCarbonDemand(Timestep timestep) { + return carbonDemandManager.getGlobalCarbonDemand(timestep.getYear()); + } } diff --git a/src/ac/ed/lurg/demand/CarbonDemandManager.java b/src/ac/ed/lurg/demand/CarbonDemandManager.java new file mode 100644 index 00000000..dc9bf1a0 --- /dev/null +++ b/src/ac/ed/lurg/demand/CarbonDemandManager.java @@ -0,0 +1,64 @@ +package ac.ed.lurg.demand; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import ac.ed.lurg.ModelConfig; +import ac.ed.lurg.utils.Interpolator; +import ac.ed.lurg.utils.LogWriter; + +public class CarbonDemandManager { + private Map<Integer, Double> globalCarbonDemand; // global demand for carbon sequestration + private static final int YEAR_COL = 0; + private static final int DEMAND_COL = 1; + + public CarbonDemandManager() { + readCarbonDemandData(); + } + + public void readCarbonDemandData() { + + Map<Integer, Double> data = new HashMap<Integer, Double>(); + + String filename = ModelConfig.CARBON_DEMAND_FILE; + try { + BufferedReader reader = new BufferedReader(new FileReader(filename)); + String line; + Integer year; + Double demand; + reader.readLine(); // read header + + while ((line=reader.readLine()) != null) { + String[] tokens = line.split(","); + + if (tokens.length < 2) + LogWriter.printlnError("Too few columns in " + filename + ", " + line); + + year = Integer.valueOf(tokens[YEAR_COL]); + demand = Double.valueOf(tokens[DEMAND_COL]); + + data.put(year, demand); + } + reader.close(); + + } catch (IOException e) { + LogWriter.printlnError("Failed in reading carbon demand data"); + LogWriter.print(e); + } + globalCarbonDemand = data; + LogWriter.println("Processed " + filename); + } + + public double getGlobalCarbonDemand(int year) { + int downYear = (year/5) * 5; + int upYear = downYear + 5; + Double lowerD = globalCarbonDemand.get(downYear); + Double upperD = globalCarbonDemand.get(upYear); + double factor = ((double)(year - downYear)) / (upYear - downYear); + Double d = Interpolator.interpolate(lowerD, upperD, factor); + return d; + } +} -- GitLab