diff --git a/GAMS/IntExtOpt.gms b/GAMS/IntExtOpt.gms index 5464729ce5d700be6198d655f076c71a75dc7fc0..dea860ebf7e881f0a8c14aced84e4949736eb748 100644 --- a/GAMS/IntExtOpt.gms +++ b/GAMS/IntExtOpt.gms @@ -13,6 +13,7 @@ SET land_cover / cropland, pasture, timberForest, carbonForest, natural /; SET managed_forest(land_cover) / timberForest, carbonForest /; + SET agriculture(land_cover) / cropland, pasture /; ALIAS (land_cover, land_cover_before); ALIAS (land_cover, land_cover_after); @@ -61,8 +62,9 @@ SCALAR unhandledCropRate rate of fruit veg and other crops not modelled; SCALAR setAsideRate rate of set aside and failed crop; SCALAR domesticPriceMarkup factor price increased from cost of production; - SCALAR maxLandExpansionRate max rate of country land expansion; - SCALAR energycropsMaxProportion maximum proportion of croplands for energycriops; + SCALAR maxGrossLccRate max rate of gross land cover change; + SCALAR maxFertChange max increase in total fertilizer use; + SCALAR maxIrrigChange max increase in total irrigation use; SCALAR forestManagementCost cost $1000 per ha; SCALAR vegClearingCostRate cost of clearing vegetation $1000 per tC; @@ -75,10 +77,10 @@ $gdxin %gdxincname% $load location, suitableLandArea, demand $load previousCropArea, previousFertIntensity, previousIrrigIntensity, previousOtherIntensity, previousRuminantFeed, previousMonogastricFeed, previousImportAmount, previousExportAmount $load yieldNone, yieldFertOnly, yieldIrrigOnly, yieldBoth, yieldShock -$load fertParam, irrigParam, otherIParam, exportPrices, importPrices, maxNetImport, minNetImport, unhandledCropRate, setAsideRate, maxLandExpansionRate, subsidyRate +$load fertParam, irrigParam, otherIParam, exportPrices, importPrices, maxNetImport, minNetImport, unhandledCropRate, setAsideRate, maxGrossLccRate, subsidyRate $load meatEfficency, otherICost, irrigCost, irrigMaxRate, irrigConstraint, fertiliserUnitCost, domesticPriceMarkup, minDemandPerCereal, minDemandPerOilcrop, seedAndWasteRate $load previousLandCoverArea, carbonFluxRate, carbonCreditRate, woodYieldRota, woodYieldLUC, forestRotationPeriod, conversionCost -$load forestManagementCost, vegClearingCostRate, carbonHorizon, energycropsMaxProportion, carbonForestMaxProportion +$load forestManagementCost, vegClearingCostRate, carbonHorizon, carbonForestMaxProportion, maxFertChange, maxIrrigChange $gdxin SCALAR delta "use to smooth power function see 7.5 www.gams.com dd docs solversconopt.pdf" / 0.00000000001 /; @@ -152,7 +154,7 @@ $gdxin total_cost total cost of domestic supply including net imports; POSITIVE VARIABLE cropArea, fertI, irrigI, otherIntensity, ruminantFeed, monogastricFeed, importAmount, exportAmount, totalFeedDM, - landCoverArea, landCoverChange, totalConversionCost, woodSupplyRota, woodSupplyLUC; + landCoverArea, landCoverChange, totalConversionCost, woodSupplyRota, woodSupplyLUC, animalProd; * POSITIVE VARIABLE A; @@ -164,6 +166,8 @@ $gdxin MAX_IRRIG_INTENSITY_CONSTRAINT(crop, location) constraint on maximum irrigation intensity MAX_OTHER_INTENSITY_CONSTRAINT(crop, location) IRRIGATION_CONSTRAINT(location) constraint on water usage + FERT_RATE_INCREASE_CONSTRAINT + IRRIG_RATE_INCREASE_CONSTRAINT NET_SUPPLY_EQ(crop) calc net supply for crops CROP_DEMAND_CONSTRAINT(crop) satisfy demand for individual crops @@ -223,11 +227,19 @@ $gdxin MAX_IRRIG_INTENSITY_CONSTRAINT(crop, location) .. irrigI(crop, location) =L= 1; MAX_OTHER_INTENSITY_CONSTRAINT(crop, location) .. otherIntensity(crop, location) =L= 1; - IRRIGATION_CONSTRAINT(location) .. irrigConstraint(location) * suitableLandArea(location) * (1.0 - unhandledCropRate) =G= sum(crop, irrigMaxRate(crop, location) * irrigI(crop, location) * cropArea(crop, location)); + IRRIGATION_CONSTRAINT(location) .. irrigConstraint(location) * suitableLandArea(location) * (1.0 - unhandledCropRate) =G= + sum(crop, irrigMaxRate(crop, location) * irrigI(crop, location) * cropArea(crop, location)); + + FERT_RATE_INCREASE_CONSTRAINT .. sum((crop, location), fertI(crop, location) * cropArea(crop, location)) =L= + sum((crop, location), previousFertIntensity(crop, location) * previousCropArea(crop, location)) * (1 + maxFertChange); + + IRRIG_RATE_INCREASE_CONSTRAINT .. sum((crop, location), irrigI(crop, location) * irrigMaxRate(crop, location) * cropArea(crop, location)) =L= + sum((crop, location), previousIrrigIntensity(crop, location) * irrigMaxRate(crop, location) * previousCropArea(crop, location)) * (1 + maxIrrigChange); *************** Crop supply ************************* - NET_SUPPLY_EQ(crop) .. netSupply(crop) =E= sum(location, cropArea(crop, location) * yield(crop, location)) * (1 - seedAndWasteRate(crop)) - ruminantFeed(crop) - monogastricFeed(crop) + importAmount(crop) - exportAmount(crop); + NET_SUPPLY_EQ(crop) .. netSupply(crop) =E= sum(location, cropArea(crop, location) * yield(crop, location)) * + (1 - seedAndWasteRate(crop)) - ruminantFeed(crop) - monogastricFeed(crop) + importAmount(crop) - exportAmount(crop); CROP_DEMAND_CONSTRAINT(crop) .. netSupply(crop) =G= demand(crop); @@ -244,6 +256,7 @@ $gdxin MONOGASTRICS_DEMAND_CONSTRAINT .. animalProd('monogastrics') =G= (demand('monogastrics') - importAmount('monogastrics') + exportAmount('monogastrics')); TOTAL_NON_PASTURE_FEED_DM_CALC .. totalFeedDM =E= sum(feed_crop_less_pasture, (ruminantFeed(feed_crop_less_pasture) + monogastricFeed(feed_crop_less_pasture)) * cropDM(feed_crop_less_pasture)); + FEED_MIX_CONSTRAINT(feed_crop_less_pasture) .. (ruminantFeed(feed_crop_less_pasture) + monogastricFeed(feed_crop_less_pasture)) * cropDM(feed_crop_less_pasture) =L= totalFeedDM * 0.7; ************** Land Cover ***************************** @@ -261,8 +274,8 @@ $gdxin LAND_COVER_CHANGE_CONSTRAINT(land_cover, location) .. sum(land_cover_after, landCoverChange(land_cover, land_cover_after, location)) =E= previousLandCoverArea(land_cover, location); - CONVERSION_COST_CALC(location) .. totalConversionCost(location) =E= sum((land_cover_before, land_cover_after), landCoverChange(land_cover_before, land_cover_after, location) * conversionCost(land_cover_before, land_cover_after, location)); - + CONVERSION_COST_CALC(location) .. totalConversionCost(location) =E= sum((land_cover_before, land_cover_after), + landCoverChange(land_cover_before, land_cover_after, location) * conversionCost(land_cover_before, land_cover_after, location)); ************* Forestry *********************************** WOOD_SUPPLY_ROTA_CALC .. woodSupplyRota =E= sum(location, landCoverArea('timberForest', location) * woodYieldRota(location)); diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java index ef086d4821dbe2ead5d084addfcd1895b1761bfb..250da78ece152b47cf9cba71e43031b0932e24c2 100755 --- a/src/ac/ed/lurg/ModelConfig.java +++ b/src/ac/ed/lurg/ModelConfig.java @@ -391,19 +391,13 @@ public class ModelConfig { public static final double OTHER_WATER_USE_FACTOR = getDoubleProperty("OTHER_WATER_USE_FACTOR", 1.0); public static final boolean USE_BLUE_WATER_FILE_IRRIG_CONSTRAINT = getBooleanProperty("USE_BLUE_WATER_FILE_IRRIG_CONSTRAINT", false);; - public static final boolean CONVERSION_COSTS_FROM_FILE = getBooleanProperty("CONVERSION_COSTS_FROM_FILE", true); + public static final boolean CONVERSION_COSTS_FROM_FILE = getBooleanProperty("CONVERSION_COSTS_FROM_FILE", false); public static final String CONVERSION_COST_FILE = getProperty("CONVERSION_COST_FILE", DATA_DIR + File.separator + "conversion_costs.csv"); // cost of converting from one land cover to another, $1000/ha - public static final double LAND_CHANGE_COST = getDoubleProperty("LAND_CHANGE_COST", 0.2); - public static final double CROP_TO_PASTURE_COST_FACTOR = getDoubleProperty("CROP_TO_PASTURE_COST_FACTOR", 1.0); - public static final double AGRI_LAND_EXPANSION_COST_FACTOR = getDoubleProperty("AGRI_LAND_EXPANSION_COST_FACTOR", 1.0); - - public static final double CROP_INCREASE_COST = getDoubleProperty("CROP_INCREASE_COST", 0.05 * LAND_CHANGE_COST * AGRI_LAND_EXPANSION_COST_FACTOR); - public static final double CROP_DECREASE_COST = getDoubleProperty("CROP_DECREASE_COST", 1.65 * LAND_CHANGE_COST); - public static final double PASTURE_INCREASE_COST = getDoubleProperty("PASTURE_INCREASE_COST", 0.35 * LAND_CHANGE_COST * CROP_TO_PASTURE_COST_FACTOR * AGRI_LAND_EXPANSION_COST_FACTOR); - public static final double PASTURE_DECREASE_COST = getDoubleProperty("PASTURE_DECREASE_COST", LAND_CHANGE_COST); - public static final double MANAGED_FOREST_INCREASE_COST = getDoubleProperty("MANAGED_FOREST_INCREASE_COST", LAND_CHANGE_COST); // $1000/ha - public static final double MANAGED_FOREST_DECREASE_COST = getDoubleProperty("MANAGED_FOREST_DECREASE_COST", LAND_CHANGE_COST); // $1000/ha - + public static final double LAND_CONVERSION_COST_FACTOR = getDoubleProperty("NATURAL_CONVERSION_COST", 1.0); // for monte carlo + public static final double CROPLAND_CONVERSION_COST = getDoubleProperty("CROPLAND_CONVERSION_COST", 0.4 * LAND_CONVERSION_COST_FACTOR); + public static final double PASTURE_CONVERSION_COST = getDoubleProperty("PASTURE_CONVERSION_COST", 0.22 * LAND_CONVERSION_COST_FACTOR); + public static final double FOREST_CONVERSION_COST = getDoubleProperty("FOREST_CONVERSION_COST", 0.2 * LAND_CONVERSION_COST_FACTOR); + public static final double NATURAL_CONVERSION_COST = getDoubleProperty("NATURAL_CONVERSION_COST", 0.03 * LAND_CONVERSION_COST_FACTOR); public static final double TECHNOLOGY_CHANGE_ANNUAL_RATE = getDoubleProperty("TECHNOLOGY_CHANGE_ANNUAL_RATE", 0.002); public static final int TECHNOLOGY_CHANGE_START_STEP = getIntProperty("TECHNOLOGY_CHANGE_START_STEP", 0); @@ -461,7 +455,9 @@ public class ModelConfig { public static final boolean PROTECTED_AREAS_ENABLED = getBooleanProperty("PROTECTED_AREAS_ENABLED", true); public static final double MIN_NATURAL_RATE = getDoubleProperty("MIN_NATURAL_RATE", 0.05); - public static final double MAX_CHINA_LAND_EXPANSION_RATE = getDoubleProperty("MAX_CHINA_LAND_EXPANSION_RATE", 0.011*0.4); // 1.1% max forest change 40% of natural land is forest + public static final double MAX_GROSS_LCC_RATE = getDoubleProperty("MAX_GROSS_LCC_RATE", 0.01); // 1% gross change + public static final double MAX_FERT_CHANGE = getDoubleProperty("MAX_FERT_CHANGE", 0.08); // 8% from FAO data 95th percentile + public static final double MAX_IRRIG_CHANGE = getDoubleProperty("MAX_IRRIG_CHANGE", 0.03); // 3% from FAO data 95th percentile public static final boolean DEBUG_JUST_DEMAND_OUTPUT = getBooleanProperty("DEBUG_JUST_DEMAND_OUTPUT", false); public static final int DEBUG_LOG_LEVEL = getIntProperty("DEBUG_LEVEL", 2); // Print only events below this level. Errors & Warnings always printed (0); Solve status (1); Global events (2); Country events (3) @@ -515,7 +511,7 @@ public class ModelConfig { public static final double VEGETATION_CLEARING_COST = getDoubleProperty("VEGETATION_CLEARING_COST", 0.001); //$1000/tC public static final double FOREST_MANAGEMENT_COST = IS_FORESTRY_ON ? getDoubleProperty("FOREST_ESTABLISHMENT_COST", 5.0) : 0.0; // establishment, management etc. $1000/ha public static final double WOOD_TRADE_BARRIER = getDoubleProperty("WOOD_TRADE_BARRIER", 0.2); //$1000/tC - public static final double INIT_WOOD_PRICE = IS_FORESTRY_ON ? getDoubleProperty("INIT_WOOD_PRICE", 0.38) : 0.0; // $1000/tC-eq + public static final double INIT_WOOD_PRICE = IS_FORESTRY_ON ? getDoubleProperty("INIT_WOOD_PRICE", 0.22) : 0.0; // $1000/tC-eq public static final boolean ENABLE_VEGETATION_CLEARANCE_COST = getBooleanProperty("ENABLE_VEGETATION_CLEARANCE_COST", false); // calculates cost of clearing vegetation even if forestry off public static final int MIN_FOREST_ROTATION_PERIOD = getIntProperty("MIN_FOREST_ROTATION_PERIOD", 5); // Minimum forest rotation period; Bauhus et al., 2010. Ecosystem goods and services from plantation forests. diff --git a/src/ac/ed/lurg/country/AbstractCountryAgent.java b/src/ac/ed/lurg/country/AbstractCountryAgent.java index d2584ccd0bba9b7af074a3c005f627fa684b062c..dbe33c52f0984f7bd3f29d13ec1502de1ebde6f0 100644 --- a/src/ac/ed/lurg/country/AbstractCountryAgent.java +++ b/src/ac/ed/lurg/country/AbstractCountryAgent.java @@ -174,7 +174,7 @@ public abstract class AbstractCountryAgent { } protected void updateNetImportsFromProdAndDemand(Map<CommodityType, Double> demands, Map<CommodityType, Map<CropType, Double>> minDemandFracts, Map<CropType, CropUsageData> cropUsages) { - LogWriter.println("AbstractCountryAgent: updateNetImportsFromProdAndDemand for " + country); + LogWriter.println("AbstractCountryAgent: updateNetImportsFromProdAndDemand for " + country, 3); for (CommodityType commodity : CommodityType.getAllFoodItems()) { @@ -200,7 +200,7 @@ public abstract class AbstractCountryAgent { totalExcessProd += netImportsFromMinDemand; } double additionalNetImportsRequired = demand - totalProd - totalmportFromMD; - LogWriter.println("additionalNetImportsRequired is " + additionalNetImportsRequired); + LogWriter.println("additionalNetImportsRequired is " + additionalNetImportsRequired, 3); for (CropType crop : commodity.getCropTypes()) { double netImportsMD = netImportsFromMinDemands.get(crop); @@ -217,7 +217,7 @@ public abstract class AbstractCountryAgent { } CropUsageData cropUsage = cropUsages.get(crop); - LogWriter.println("Updating " + commodity + " net imports " + crop + " to " + netImports); + LogWriter.println("Updating " + commodity + " net imports " + crop + " to " + netImports, 3); cropUsage.updateNetImports(netImports); } } @@ -227,7 +227,7 @@ public abstract class AbstractCountryAgent { CropUsageData cropUsage = cropUsages.get(crop); double prod = cropUsage.getProductionExpected() *(1-crop.getSeedAndWasteRate()) - cropUsage.getMonogastricFeed() - cropUsage.getRuminantFeed(); double netImports = demand - prod; - LogWriter.println("Updating net imports " + crop + " to " + netImports); + LogWriter.println("Updating net imports " + crop + " to " + netImports, 3); cropUsage.updateNetImports(netImports); } } diff --git a/src/ac/ed/lurg/country/gams/GamsDemandOptimiser.java b/src/ac/ed/lurg/country/gams/GamsDemandOptimiser.java index 8990d4bc4b7cb11c687d1a947a871bf09d47b4eb..061cd4fa37cb0feeb96365b3e5f91f468c3c92c2 100755 --- a/src/ac/ed/lurg/country/gams/GamsDemandOptimiser.java +++ b/src/ac/ed/lurg/country/gams/GamsDemandOptimiser.java @@ -2,9 +2,11 @@ package ac.ed.lurg.country.gams; import java.io.File; import java.io.IOException; +import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; @@ -31,9 +33,11 @@ public class GamsDemandOptimiser { private GamsDemandInput inputData; private static final boolean DEBUG = false; + private boolean saveGamsGdxFiles; public GamsDemandOptimiser(GamsDemandInput inputData) { this.inputData = inputData; + saveGamsGdxFiles = (ModelConfig.GAMS_COUNTRY_TO_SAVE != null && inputData.getCountry().getCountryName().equals(ModelConfig.GAMS_COUNTRY_TO_SAVE)); } public GamsDemandOutput getDemandPc() { @@ -62,7 +66,7 @@ public class GamsDemandOptimiser { opt.defines("gdx_prices_and_gdp", inDB.getName()); if (ModelConfig.ADJUST_DIET_PREFS) { - LogWriter.println("Adusting diet params"); + LogWriter.println("Adjusting diet params", 3); GAMSDatabase originalParamDb = ws.addDatabaseFromGDX(new File(ModelConfig.DEMAND_PARAM_FILE).getAbsolutePath()); GAMSDatabase adjustedParamDb = ws.addDatabase(originalParamDb); adjustDietParams(adjustedParamDb); @@ -79,6 +83,9 @@ public class GamsDemandOptimiser { LogWriter.println("Took " + (System.currentTimeMillis() - startTime) + " ms to run", 3); + if (saveGamsGdxFiles) + saveGDXFile("demand", workingDirectory.toFile()); + if (ModelConfig.CLEANUP_GAMS_DIR) { gamsJob.OutDB().dispose(); deleteDirectory(workingDirectory.toFile()); @@ -226,4 +233,22 @@ public class GamsDemandOptimiser { } return dir.delete(); } + + private void saveGDXFile(String ext, File tempDir) { + // some hacky code for debug purposes that keeps each gams gdx file + String country = inputData.getCountry().getCountryName().replaceAll("\\s+",""); + int year = inputData.getYear(); + try { + Files.copy( + FileSystems.getDefault().getPath(tempDir + File.separator + "_gams_java_gdb1.gdx"), + FileSystems.getDefault().getPath(ModelConfig.TEMP_DIR + File.separator + country + year + ext + ".gdx"), + StandardCopyOption.REPLACE_EXISTING); + Files.copy( + FileSystems.getDefault().getPath(tempDir + File.separator + "_gams_java_gjo1.lst"), + FileSystems.getDefault().getPath(ModelConfig.TEMP_DIR + File.separator + country + year + ext + "Listing" + ".lst"), + StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + LogWriter.print(e); + } + } } diff --git a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java index af511068752166083e3c9bfb72553b5d24f4d499..507a195e8b8f2d004aa2ea5b73f6c2f824a64953 100644 --- a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java +++ b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java @@ -351,12 +351,9 @@ public class GamsLocationOptimiser { addScalar(inDB, "unhandledCropRate", ModelConfig.UNHANDLED_CROP_RATE, 3); addScalar(inDB, "setAsideRate", ModelConfig.SETASIDE_RATE, 5); addScalar(inDB, "domesticPriceMarkup", ModelConfig.DOMESTIC_PRICE_MARKUP, 3); - double maxExpansion = 1.0; - if (!ModelConfig.IS_CALIBRATION_RUN && countryInput.getCountry().getName().equals("China")) { - maxExpansion = ModelConfig.MAX_CHINA_LAND_EXPANSION_RATE; - } - addScalar(inDB, "maxLandExpansionRate", maxExpansion, 3); - addScalar(inDB, "energycropsMaxProportion", ModelConfig.ENERGYCROPS_MAX_PROPORTION, 5); + addScalar(inDB, "maxGrossLccRate", ModelConfig.MAX_GROSS_LCC_RATE, 5); + addScalar(inDB, "maxFertChange", ModelConfig.MAX_FERT_CHANGE, 5); + addScalar(inDB, "maxIrrigChange", ModelConfig.MAX_IRRIG_CHANGE, 5); // Forestry Map<WoodType, Double> woodDemandMap = countryInput.getWoodDemand(); diff --git a/src/ac/ed/lurg/demand/AbstractDemandManager.java b/src/ac/ed/lurg/demand/AbstractDemandManager.java index b60384ec79b89132c6e60182c84e11c47e7871ca..127c3066470ee92d389b975029c823c3553fd835 100644 --- a/src/ac/ed/lurg/demand/AbstractDemandManager.java +++ b/src/ac/ed/lurg/demand/AbstractDemandManager.java @@ -1,5 +1,6 @@ package ac.ed.lurg.demand; +import java.io.Serializable; import java.util.HashMap; import java.util.Map; @@ -12,16 +13,21 @@ import ac.ed.lurg.types.CropType; import ac.ed.lurg.types.WoodType; import ac.ed.lurg.utils.LogWriter; -public abstract class AbstractDemandManager { +public abstract class AbstractDemandManager implements Serializable { - protected CompositeCountryManager compositeCountryManager; - protected CalorieManager calorieManager; - protected BioenergyDemandManager bioenergyDemandManager; - protected CerealFractionsManager cerealFractionsManager; + private static final long serialVersionUID = 8622023691732185744L; + protected transient CompositeCountryManager compositeCountryManager; + protected transient CalorieManager calorieManager; + protected transient BioenergyDemandManager bioenergyDemandManager; + protected transient CerealFractionsManager cerealFractionsManager; protected CarbonDemandManager carbonDemandManager; protected WoodDemandManager woodDemandManager; public AbstractDemandManager(CompositeCountryManager compositeCountryManager, CalorieManager calorieManager) { + setup(compositeCountryManager, calorieManager); + } + + protected void setup(CompositeCountryManager compositeCountryManager, CalorieManager calorieManager) { this.compositeCountryManager = compositeCountryManager; this.calorieManager = calorieManager; bioenergyDemandManager = new BioenergyDemandManager(); @@ -40,7 +46,13 @@ public abstract class AbstractDemandManager { for (SingleCountry c : compositeCountryManager.getAllForCompositeCountry(cc)) { + try { foodDemandMap = getFoodDemand(c, year, prices, outputGamsDemand); + } catch (Exception e) { + LogWriter.printlnError("Error: AbstractDemandManager not including " + c + " due to exception"); + LogWriter.print(e); + continue; + } for (CommodityType commodity : CommodityType.getAllFoodItems()) { diff --git a/src/ac/ed/lurg/demand/AbstractSSPDemandManager.java b/src/ac/ed/lurg/demand/AbstractSSPDemandManager.java index beccd91852b98c99c0e5f218a0e24caf194081f9..153d194fa13db7d8eb7d064c4218186362c77268 100644 --- a/src/ac/ed/lurg/demand/AbstractSSPDemandManager.java +++ b/src/ac/ed/lurg/demand/AbstractSSPDemandManager.java @@ -15,29 +15,37 @@ import ac.ed.lurg.utils.LogWriter; public abstract class AbstractSSPDemandManager extends AbstractDemandManager { - protected SspManager sspManager; - protected String ssp_scenario; - protected BaseConsumpManager baseConsumpManager; - protected CalorieManager calorieManager; - private SingleCountry usa; - private AgriculturalGDPManager agriculturalGDPManager; + private static final long serialVersionUID = 1169375638148027645L; + protected transient SspManager sspManager; + protected transient String ssp_scenario; + protected transient BaseConsumpManager baseConsumpManager; + private transient SingleCountry usa; + private transient AgriculturalGDPManager agriculturalGDPManager; public AbstractSSPDemandManager(String ssp_scenario, BaseConsumpManager baseConsumpManager,CalorieManager calorieManager, CompositeCountryManager compositeCountryManager) { super(compositeCountryManager, calorieManager); + setup(ssp_scenario, baseConsumpManager); + } + + public void setup(String ssp_scenario, BaseConsumpManager baseConsumpManager) { this.ssp_scenario = ssp_scenario; this.baseConsumpManager = baseConsumpManager; - this.calorieManager = calorieManager; sspManager = new SspManager(); usa = CountryManager.getForName("United States of America"); agriculturalGDPManager = new AgriculturalGDPManager(); } + protected void setup(String ssp_scenario, BaseConsumpManager baseConsumpManager, CalorieManager calorieManager, CompositeCountryManager compositeCountryManager) { + super.setup(compositeCountryManager, calorieManager); + setup(ssp_scenario, baseConsumpManager); + } + @Override public void updateGdpLossesFromShock(CompositeCountry cc, int year, double shockMagnitude) { for (SingleCountry c : compositeCountryManager.getAllForCompositeCountry(cc)) { SspData sd = sspManager.get(ssp_scenario, year, c); - LogWriter.println("sd data " + sd); + LogWriter.println("sd data " + sd, 3); if(sd != null) { double gdp = sd.getGdp(); double agriculturalGDPProportion = agriculturalGDPManager.getProportion(c); diff --git a/src/ac/ed/lurg/demand/DemandManagerFromFile.java b/src/ac/ed/lurg/demand/DemandManagerFromFile.java index a01eb0907d09c71362e690125b1d19fa1829a910..a4c63b6e44708387acc70ff4bc3798d95a64de47 100644 --- a/src/ac/ed/lurg/demand/DemandManagerFromFile.java +++ b/src/ac/ed/lurg/demand/DemandManagerFromFile.java @@ -14,6 +14,7 @@ import ac.ed.lurg.utils.StringTabularReader; public class DemandManagerFromFile extends AbstractDemandManager { + private static final long serialVersionUID = -3296655986819599788L; private StringTabularReader historicalConsumptionReader; private StringTabularReader histWoodConsumpReader; diff --git a/src/ac/ed/lurg/demand/DemandManagerSSP.java b/src/ac/ed/lurg/demand/DemandManagerSSP.java index 833695c185481f0cedbb99678bb2665be44507c0..67c37e4168521eb491749221d6d4a838a9597b8a 100644 --- a/src/ac/ed/lurg/demand/DemandManagerSSP.java +++ b/src/ac/ed/lurg/demand/DemandManagerSSP.java @@ -12,6 +12,7 @@ import ac.ed.lurg.types.WoodType; public class DemandManagerSSP extends AbstractSSPDemandManager { + private static final long serialVersionUID = 6500619362109439516L; private DemandCurveManager demandCurveManager; public DemandManagerSSP(String ssp_scenario, BaseConsumpManager baseConsumpManager, CalorieManager calorieManager, CompositeCountryManager compositeCountryManager) { diff --git a/src/ac/ed/lurg/demand/ElasticDemandManager.java b/src/ac/ed/lurg/demand/ElasticDemandManager.java index 0e7537966ad5255f186aa40207036980ce6fcfe1..7d53594ab0bf779fc5366ce7207a8571cc194dd9 100755 --- a/src/ac/ed/lurg/demand/ElasticDemandManager.java +++ b/src/ac/ed/lurg/demand/ElasticDemandManager.java @@ -19,15 +19,27 @@ import ac.ed.lurg.utils.LogWriter; public class ElasticDemandManager extends AbstractSSPDemandManager { - private Map<SingleCountry, Map<CommodityType, Double>> baseCpcCache = new HashMap<SingleCountry, Map<CommodityType, Double>>(); - private Map<SingleCountry, GamsDemandOutput> previousGamsDemands = new HashMap<SingleCountry, GamsDemandOutput>(); - private BufferedWriter outputFile; + private static final long serialVersionUID = -8605798315853420916L; + private Map<SingleCountry, Map<CommodityType, Double>> baseCpcCache; + private transient Map<SingleCountry, GamsDemandOutput> previousGamsDemands; + private transient BufferedWriter outputFile; private PriceMarkUps priceMarkups; + private int baseYearToRebaseConsumption; + /** Constructor used in calibration only */ public ElasticDemandManager(String ssp_scenario, BaseConsumpManager baseConsumpManager, CalorieManager calorieManager, CompositeCountryManager compositeCountryManager) { super(ssp_scenario, baseConsumpManager, calorieManager, compositeCountryManager); - priceMarkups = new PriceMarkUps(); + this.priceMarkups = new PriceMarkUps(); + baseCpcCache = new HashMap<SingleCountry, Map<CommodityType, Double>>(); + baseYearToRebaseConsumption = ModelConfig.BASE_YEAR; + + setup(); + } + + protected void setup() { + previousGamsDemands = new HashMap<SingleCountry, GamsDemandOutput>(); + try { outputFile = FileWriterHelper.getFileWriter(true, true, ModelConfig.DEMAND_OPTIMISATION_OUTPUT_FILE, getDamsDemandOutputsHeader()); } catch (IOException e) { @@ -35,6 +47,11 @@ public class ElasticDemandManager extends AbstractSSPDemandManager { } } + public void setup(String ssp_scenario, BaseConsumpManager baseConsumpManager, CalorieManager calorieManager, CompositeCountryManager compositeCountryManager) { + super.setup(ssp_scenario, baseConsumpManager, calorieManager, compositeCountryManager); + setup(); + } + @Override Map<CommodityType, Double> getFoodDemandMap(SingleCountry c, int year, double gdpPc, double population, Map<CommodityType, Double> producerPrices, double usaGdpPc, boolean outputGamsDemand) { Map<CommodityType, Double> consumerPrices = new HashMap<CommodityType, Double>(); @@ -50,10 +67,7 @@ public class ElasticDemandManager extends AbstractSSPDemandManager { double producerPrice = producerPricePlum * (1000/kcalPerT.get(commodity) * 2000 *365); //price per person per year commodity x per year assuming 2000 kcal a day double consumerPrice = priceMarkups.markedupPrice(c, commodity, producerPrice); - consumerPrices.put(commodity, consumerPrice); - LogWriter.println("Consumer price for " + commodity.getGamsName() + " is " + consumerPrice, 3); - } GamsDemandInput inputData = new GamsDemandInput(c, year, gdpPc, consumerPrices,kcalPerT, usaGdpPc, previousGamsDemands.get(c)); @@ -66,7 +80,7 @@ public class ElasticDemandManager extends AbstractSSPDemandManager { Map<CommodityType, Double> foodPc = gamsOutput.getPlumDemands(); Map<CommodityType, Double> foodDemands = new HashMap<CommodityType, Double>(); - SspData baseSspData = sspManager.get(ssp_scenario, ModelConfig.BASE_YEAR, c); + SspData baseSspData = sspManager.get(ssp_scenario, baseYearToRebaseConsumption, c); double baseGdpPc = baseSspData.getGdpPc(); Map<CommodityType, Double> baseExpCpcMap = baseCpcCache.get(c); @@ -142,6 +156,10 @@ public class ElasticDemandManager extends AbstractSSPDemandManager { } } + public PriceMarkUps getPriceMarkups() { + return priceMarkups; + } + @Override public Map<WoodType, Double> getWoodDemandMap(SingleCountry country, double gdpPc, double baseGdpPc, double population, double basePopulation) { Map<WoodType, Double> demandMap = new HashMap<WoodType, Double>(); diff --git a/src/ac/ed/lurg/landuse/ConversionCostReader.java b/src/ac/ed/lurg/landuse/ConversionCostReader.java index cde141cb02eebef4a0f33b751732772bafd3433e..5b18af6bba3d4c13bfd111dbd46d16aa8d3ef323 100644 --- a/src/ac/ed/lurg/landuse/ConversionCostReader.java +++ b/src/ac/ed/lurg/landuse/ConversionCostReader.java @@ -62,31 +62,34 @@ public class ConversionCostReader { LogWriter.println("Processed " + filename, 2); } - public void calcFromConfig() { - conversionCosts.put(new LccKey(LandCoverType.CROPLAND, LandCoverType.PASTURE), ModelConfig.CROP_DECREASE_COST + ModelConfig.PASTURE_INCREASE_COST); - conversionCosts.put(new LccKey(LandCoverType.CROPLAND, LandCoverType.NATURAL), ModelConfig.CROP_DECREASE_COST); - conversionCosts.put(new LccKey(LandCoverType.CROPLAND, LandCoverType.TIMBER_FOREST), ModelConfig.CROP_DECREASE_COST + ModelConfig.MANAGED_FOREST_INCREASE_COST); - conversionCosts.put(new LccKey(LandCoverType.CROPLAND, LandCoverType.CARBON_FOREST), ModelConfig.CROP_DECREASE_COST + ModelConfig.MANAGED_FOREST_INCREASE_COST); - - conversionCosts.put(new LccKey(LandCoverType.PASTURE, LandCoverType.CROPLAND), ModelConfig.PASTURE_DECREASE_COST + ModelConfig.CROP_INCREASE_COST); - conversionCosts.put(new LccKey(LandCoverType.PASTURE, LandCoverType.NATURAL), ModelConfig.PASTURE_DECREASE_COST); - conversionCosts.put(new LccKey(LandCoverType.PASTURE, LandCoverType.TIMBER_FOREST), ModelConfig.PASTURE_DECREASE_COST + ModelConfig.MANAGED_FOREST_INCREASE_COST); - conversionCosts.put(new LccKey(LandCoverType.PASTURE, LandCoverType.CARBON_FOREST), ModelConfig.PASTURE_DECREASE_COST + ModelConfig.MANAGED_FOREST_INCREASE_COST); - - conversionCosts.put(new LccKey(LandCoverType.NATURAL, LandCoverType.CROPLAND), ModelConfig.CROP_INCREASE_COST); - conversionCosts.put(new LccKey(LandCoverType.NATURAL, LandCoverType.PASTURE), ModelConfig.PASTURE_INCREASE_COST); - conversionCosts.put(new LccKey(LandCoverType.NATURAL, LandCoverType.TIMBER_FOREST), ModelConfig.MANAGED_FOREST_INCREASE_COST); - conversionCosts.put(new LccKey(LandCoverType.NATURAL, LandCoverType.CARBON_FOREST), ModelConfig.MANAGED_FOREST_INCREASE_COST); - - conversionCosts.put(new LccKey(LandCoverType.TIMBER_FOREST, LandCoverType.CROPLAND), ModelConfig.MANAGED_FOREST_DECREASE_COST + ModelConfig.CROP_INCREASE_COST); - conversionCosts.put(new LccKey(LandCoverType.TIMBER_FOREST, LandCoverType.PASTURE), ModelConfig.MANAGED_FOREST_DECREASE_COST + ModelConfig.PASTURE_INCREASE_COST); - conversionCosts.put(new LccKey(LandCoverType.TIMBER_FOREST, LandCoverType.NATURAL), ModelConfig.MANAGED_FOREST_DECREASE_COST); - conversionCosts.put(new LccKey(LandCoverType.TIMBER_FOREST, LandCoverType.CARBON_FOREST), ModelConfig.MANAGED_FOREST_INCREASE_COST + ModelConfig.MANAGED_FOREST_DECREASE_COST); - - conversionCosts.put(new LccKey(LandCoverType.CARBON_FOREST, LandCoverType.CROPLAND), ModelConfig.MANAGED_FOREST_DECREASE_COST + ModelConfig.CROP_INCREASE_COST); - conversionCosts.put(new LccKey(LandCoverType.CARBON_FOREST, LandCoverType.PASTURE), ModelConfig.MANAGED_FOREST_DECREASE_COST + ModelConfig.PASTURE_INCREASE_COST); - conversionCosts.put(new LccKey(LandCoverType.CARBON_FOREST, LandCoverType.NATURAL), ModelConfig.MANAGED_FOREST_DECREASE_COST); - conversionCosts.put(new LccKey(LandCoverType.CARBON_FOREST, LandCoverType.TIMBER_FOREST), ModelConfig.MANAGED_FOREST_INCREASE_COST + ModelConfig.MANAGED_FOREST_DECREASE_COST); + public void calcFromConfig() { + for (LandCoverType fromLc : LandCoverType.getConvertibleTypes()) { + for (LandCoverType toLc : LandCoverType.getConvertibleTypes()) { + if (fromLc.equals(toLc)) { // skip + continue; + } + switch(fromLc) { + case CROPLAND: + conversionCosts.put(new LccKey(fromLc, toLc), ModelConfig.CROPLAND_CONVERSION_COST); + break; + case PASTURE: + conversionCosts.put(new LccKey(fromLc, toLc), ModelConfig.PASTURE_CONVERSION_COST); + break; + case TIMBER_FOREST: + conversionCosts.put(new LccKey(fromLc, toLc), ModelConfig.FOREST_CONVERSION_COST); + break; + case CARBON_FOREST: + conversionCosts.put(new LccKey(fromLc, toLc), ModelConfig.FOREST_CONVERSION_COST); + break; + case NATURAL: + conversionCosts.put(new LccKey(fromLc, toLc), ModelConfig.NATURAL_CONVERSION_COST); + break; + default: + conversionCosts.put(new LccKey(fromLc, toLc), 0.0); + break; + } + } + } } public void calcForSecondStageCalib() { diff --git a/src/ac/ed/lurg/landuse/IrrigationRasterSet.java b/src/ac/ed/lurg/landuse/IrrigationRasterSet.java index c63d57f9cf33afceb5170181cdd15b8f3f319670..df2d8b9fac50296c78e8220ae94b03fd1ef00185 100644 --- a/src/ac/ed/lurg/landuse/IrrigationRasterSet.java +++ b/src/ac/ed/lurg/landuse/IrrigationRasterSet.java @@ -25,7 +25,8 @@ public class IrrigationRasterSet extends RasterSet<IrrigationItem> { } public void updateIrrigConstraints(Timestep timestep) { - Map<RasterKey, Double> lpjIrrigConstraints = getIrrigFromLpjRunoff(timestep.getYear(), false); + int currentYear = ModelConfig.IS_CALIBRATION_RUN ? ModelConfig.BASE_YEAR : timestep.getYear(); + Map<RasterKey, Double> lpjIrrigConstraints = getIrrigFromLpjRunoff(currentYear, false); for (Map.Entry<RasterKey, IrrigationItem> entry : entrySet()) { IrrigationItem irrigItem = entry.getValue();