diff --git a/GAMS/IntExtOpt.gms b/GAMS/IntExtOpt.gms index 1b94ca729dcb3c8f2de84b53078fbea3df5f6bf5..b6cd76f213b41e6827fac3c23c0b231872a292ac 100644 --- a/GAMS/IntExtOpt.gms +++ b/GAMS/IntExtOpt.gms @@ -12,6 +12,7 @@ SET land_cover / cropland, pasture, timberForest, carbonForest, otherNatural /; SET wood_producing / timberForest, carbonForest, otherNatural /; ALIAS (land_cover, land_cover_before); + ALIAS (land_cover, land_cover_after); SET location; PARAMETER suitableLandArea(location) areas of land in Mha; diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java index 99f61ca67c679fbfcbcd48ea3360fbaea8cde049..859fc7e0f1caedb95fc34a9e0f2918e6ed27ed9c 100755 --- a/src/ac/ed/lurg/ModelConfig.java +++ b/src/ac/ed/lurg/ModelConfig.java @@ -417,4 +417,9 @@ public class ModelConfig { public static final int DIET_CHANGE_START_YEAR = getIntProperty("DIET_CHANGE_START_YEAR", 2020); public static final int DIET_CHANGE_END_YEAR = getIntProperty("DIET_CHANGE_END_YEAR", 2040); public static final String TARGET_DIET_FILE = getProperty("TARGET_DIET_FILE", DATA_DIR + File.separator + "TargetDiet.txt"); + + // Forestry parameters + public static final double CARBON_PRICE = getDoubleProperty("CARBON_PRICE", 20.0); + public static final double WOOD_PRICE = getDoubleProperty("WOOD_PRICE", 0.175); + } diff --git a/src/ac/ed/lurg/ModelMain.java b/src/ac/ed/lurg/ModelMain.java index 8525acd2ffb21e01d43c73cd32045965696c7619..e8d6d12d0805f86337dc54f3cdeb09846dd314a1 100644 --- a/src/ac/ed/lurg/ModelMain.java +++ b/src/ac/ed/lurg/ModelMain.java @@ -48,6 +48,7 @@ import ac.ed.lurg.output.LandUseOutputer; import ac.ed.lurg.output.LpjgOutputer; import ac.ed.lurg.types.CommodityType; import ac.ed.lurg.types.CropType; +import ac.ed.lurg.types.GamsLandCoverType; import ac.ed.lurg.types.LandCoverType; import ac.ed.lurg.utils.FileWriterHelper; import ac.ed.lurg.utils.LogWriter; @@ -606,6 +607,15 @@ public class ModelMain { for (Map.Entry<RasterKey, LandCoverItem> entry : initialLC.entrySet()) landUseRaster.put(entry.getKey(), new LandUseItem(entry.getValue())); + + // Set initial GAMS land covers + for (LandUseItem item : landUseRaster.values()) { + item.setGamsLandCoverArea(GamsLandCoverType.CROPLAND, item.getLandCoverArea(LandCoverType.CROPLAND)); + item.setGamsLandCoverArea(GamsLandCoverType.PASTURE, item.getLandCoverArea(LandCoverType.PASTURE)); + item.setGamsLandCoverArea(GamsLandCoverType.TIMBER_FOREST, item.getLandCoverArea(LandCoverType.MANAGED_FOREST)); + item.setGamsLandCoverArea(GamsLandCoverType.CARBON_FOREST, 0.0); + item.setGamsLandCoverArea(GamsLandCoverType.OTHER_NATURAL, item.getLandCoverArea(LandCoverType.OTHER_NATURAL) + item.getLandCoverArea(LandCoverType.UNMANAGED_FOREST)); + } return landUseRaster; } diff --git a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java index 302260ccc836a5e38207bc3833dac362096a77eb..c13a265d968e52ea6a3bf838405e020121acc6d6 100644 --- a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java +++ b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java @@ -23,13 +23,14 @@ import com.gams.api.GAMSWorkspaceInfo; import ac.ed.lurg.ModelConfig; import ac.ed.lurg.country.CountryPrice; import ac.ed.lurg.country.TradeConstraint; +import ac.ed.lurg.landuse.CarbonFluxItem; import ac.ed.lurg.landuse.CropUsageData; import ac.ed.lurg.landuse.Intensity; import ac.ed.lurg.landuse.IrrigationItem; import ac.ed.lurg.landuse.LandUseItem; +import ac.ed.lurg.landuse.WoodYieldItem; import ac.ed.lurg.types.CommodityType; import ac.ed.lurg.types.CropType; -import ac.ed.lurg.types.ForestType; import ac.ed.lurg.types.GamsLandCoverType; import ac.ed.lurg.types.LandCoverType; import ac.ed.lurg.types.Parameter; @@ -166,37 +167,16 @@ public class GamsLocationOptimiser { } - /* - // Add forest land cover - for (ForestType ft : ForestType.values()) { - Vector<String> v = new Vector<String>(); - v.add(ft.getName()); - v.add(locString); - setGamsParamValue(prevLandCoverP.addRecord(v), landUseItem.getForestArea(ft), 2); - } - - // Add non-forest land cover. Need to do it like this because mapping is not 1:1 for natural and not all LandCoverTypes included. - Vector<String> v = new Vector<String>(); - - v.add("cropland"); - v.add(locString); - setGamsParamValue(prevLandCoverP.addRecord(v), landUseItem.getLandCoverArea(LandCoverType.CROPLAND), 2); - - v.set(0, "pasture"); - setGamsParamValue(prevLandCoverP.addRecord(v), landUseItem.getLandCoverArea(LandCoverType.PASTURE), 2); - - v.set(0, "otherNatural"); - setGamsParamValue(prevLandCoverP.addRecord(v), landUseItem.getLandCoverArea(LandCoverType.OTHER_NATURAL) + landUseItem.getLandCoverArea(LandCoverType.UNMANAGED_FOREST), 2); - */ - + // Previous land covers for (GamsLandCoverType lc : GamsLandCoverType.values()) { Vector<String> v = new Vector<String>(); v.add(lc.getName()); v.add(locString); - setGamsParamValue(prevLandCoverP.addRecord(v), landUseItem.getGamsLandCoverArea(lc), 2); + setGamsParamValue(prevLandCoverP.addRecord(v), landUseItem.getGamsLandCoverArea(lc), 3); } } + if (DEBUG) LogWriter.println(String.format(" Total agricultural %.1f,\t suitable %.1f", totalAgriLand, totalSuitable)); if (DEBUG) LogWriter.println("\nIrrigation data (cost, constraint)"); @@ -356,6 +336,50 @@ public class GamsLocationOptimiser { maxExpansion = ModelConfig.MAX_CHINA_LAND_EXPANSION_RATE; } addScalar(inDB, "maxLandExpansionRate", maxExpansion, 3); + + addScalar(inDB, "carbonPrice", ModelConfig.CARBON_PRICE, 3); + addScalar(inDB, "woodPrice", ModelConfig.WOOD_PRICE, 3); + + // Carbon fluxes + GAMSParameter cFluxRateP = inDB.addParameter("carbonFluxRate", 3); + + for (Entry<Integer, ? extends CarbonFluxItem> entry : inputData.getCarbonFluxes().entrySet()) { + Integer locationId = entry.getKey(); + String locString = Integer.toString(locationId); + CarbonFluxItem cFlux = entry.getValue(); + + for (GamsLandCoverType prevLC : GamsLandCoverType.values()) { + for (GamsLandCoverType newLC : GamsLandCoverType.values()) { + Vector<String> v = new Vector<String>(); + v.add(prevLC.getName()); + v.add(newLC.getName()); + v.add(locString); + setGamsParamValue(cFluxRateP.addRecord(v), cFlux.getCarbonFlux(prevLC, newLC), 3); + } + } + + } + + // Wood yields + GAMSParameter woodYieldP = inDB.addParameter("woodYield", 3); + + for (Entry<Integer, ? extends WoodYieldItem> entry : inputData.getWoodYields().entrySet()) { + Integer locationId = entry.getKey(); + String locString = Integer.toString(locationId); + WoodYieldItem wYield = entry.getValue(); + + for (GamsLandCoverType prevLC : GamsLandCoverType.values()) { + for (GamsLandCoverType newLC : GamsLandCoverType.values()) { + Vector<String> v = new Vector<String>(); + v.add(prevLC.getName()); + v.add(newLC.getName()); + v.add(locString); + setGamsParamValue(woodYieldP.addRecord(v), wYield.getWoodYield(prevLC, newLC), 3); + } + } + + } + } private void addScalar(GAMSDatabase gamsDb, String recordName, double val, int places) { @@ -404,13 +428,11 @@ public class GamsLocationOptimiser { GAMSParameter parmProdCost = outDB.getParameter("totalProdCost"); GAMSParameter parmCroplandArea = outDB.getParameter("totalCropland"); GAMSParameter parmTotalArea = outDB.getParameter("totalArea"); - GAMSParameter parmProdShock = outDB.getParameter("productionShock"); - GAMSVariable varLandCoverArea = outDB.getVariable("landCoverArea"); + GAMSParameter parmProdShock = outDB.getParameter("productionShock"); double totalCropArea = 0; double totalPastureArea = 0; - double area, fertIntensity, irrigIntensity, otherIntensity = Double.NaN, ruminantFeed, monogastricFeed, netImport, netImportCost, yield, unitCost, prod, prodCost; - double landCoverArea; + double area, fertIntensity, irrigIntensity, otherIntensity = Double.NaN, ruminantFeed, monogastricFeed, netImport, netImportCost, yield, unitCost, prod, prodCost; final LazyHashMap<Integer, LandUseItem> landUses = new LazyHashMap<Integer, LandUseItem>() { protected LandUseItem createValue() { return new LandUseItem(); } @@ -448,7 +470,7 @@ public class GamsLocationOptimiser { } - LandUseItem landUseItem = landUses.lazyGet(locId); + LandUseItem landUseItem = landUses.lazyGet(locId); // returns landUseItem for location. If does not exist, creates new one if (area > 0) { @@ -471,37 +493,6 @@ public class GamsLocationOptimiser { landUseItem.setCropFraction(cropType, croplandArea > 0 ? area/croplandArea : 0); } - /* - for (GAMSVariableRecord rec : varLandCoverArea) { - String lc = rec.getKeys()[0]; - String locationName = rec.getKeys()[1]; - int locId = Integer.parseInt(locationName); - landCoverArea = rec.getLevel(); - LandUseItem landUseItem = landUses.lazyGet(locId); - - switch(lc) { - case "forestT": - landUseItem.setForestArea(ForestType.TIMBER_FOREST, landCoverArea); - break; - case "forestC": - landUseItem.setForestArea(ForestType.CARBON_FOREST, landCoverArea); - } - - } - */ - for (GAMSVariableRecord rec : varLandCoverArea) { - String lc = rec.getKeys()[0]; - String locationName = rec.getKeys()[1]; - int locId = Integer.parseInt(locationName); - - landCoverArea = rec.getLevel(); - - LandUseItem landUseItem = landUses.lazyGet(locId); - - landUseItem.setGamsLandCoverArea(GamsLandCoverType.getForName(lc), landCoverArea); - - } - for (CropType meatTypes : CropType.getMeatTypes()) { netImport = getParmValue(parmNetImports, meatTypes.getGamsName()); @@ -515,6 +506,24 @@ public class GamsLocationOptimiser { LogWriter.println(String.format("\n%s %s: Total area= %.1f (crop=%.1f, pasture %.1f)", inputData.getCountryInput().getCountry(), inputData.getTimestep().getYear(), totalCropArea+totalPastureArea, totalCropArea, totalPastureArea)); + + + // Land cover areas + GAMSVariable varLandCoverArea = outDB.getVariable("landCoverArea"); + double landCoverArea; + + for (GAMSVariableRecord rec : varLandCoverArea) { + String lc = rec.getKeys()[0]; + String locationName = rec.getKeys()[1]; + int locId = Integer.parseInt(locationName); + + landCoverArea = rec.getLevel(); + + LandUseItem landUseItem = landUses.lazyGet(locId); + + landUseItem.setGamsLandCoverArea(GamsLandCoverType.getForName(lc), landCoverArea); + + } GamsLocationOutput results = new GamsLocationOutput(modelStatus, landUses, cropUsageData); return results; diff --git a/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java b/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java index 4511ed939e2d9adbdb8d4c0a3fb4c3ee34c48309..23511eec9008d441632e20f371bad387550831b8 100644 --- a/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java +++ b/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java @@ -245,7 +245,44 @@ public class GamsRasterOptimiser { return newLandUseRaster; } +/* + private void allocGamsLandCovers(RasterSet<LandUseItem> newLandUseRaster, Set<RasterKey> keys, GamsLandCoverType toLC, GamsLandCoverType fromLC, double change) { + GamsLandCoverType toType = toLC; + GamsLandCoverType fromType = fromLC; + // reverse direction if negative + if (change < 0) { + change = -change; + toType = fromLC; + fromType = toLC; + } + + double totalShortfall = 0; + Set<RasterKey> keysWithSpace = new HashSet<RasterKey>(); + double totalUnprotectedLC = 0; + + for (RasterKey key : keys) { + LandUseItem newLandUseItem = newLandUseRaster.get(key); + totalUnprotectedLC += newLandUseItem.getUnprotectedLandCoverArea(fromType); + } + + for (RasterKey key : keys) { + //if (DEBUG) LogWriter.println(" Processing raster key " + key); + LandUseItem newLandUseItem = newLandUseRaster.get(key); + + if (newLandUseItem!=null) { + double cellChange = (fromType.isProtectable() && totalUnprotectedLC > 0) ? change * newLandUseItem.getUnprotectedLandCoverArea(fromType)/totalUnprotectedLC : change / keys.size(); + double shortfall = newLandUseItem.moveAreas(toType, fromType, cellChange); + if (shortfall == 0) + keysWithSpace.add(key); + else + totalShortfall += shortfall; + } + } + + + } +*/ private void allocAllLandCropsTop(RasterSet<LandUseItem> newLandUseRaster, Set<RasterKey> keys, LandCoverType toLC, LandCoverType fromLC, double change, Integer locId) { LandCoverType toType = toLC; @@ -422,13 +459,13 @@ public class GamsRasterOptimiser { } // Aggregate carbon fluxes and wood yields - for (GamsLandCoverType lc_previous : GamsLandCoverType.values()) { - for (GamsLandCoverType lc_new : GamsLandCoverType.values()) { - aggCFlux.setCarbonFlux(lc_previous, lc_new, aggregateMean(aggCFlux.getCarbonFlux(lc_previous, lc_new), suitableAreaSoFar, - carbonFluxItem.getCarbonFlux(lc_previous, lc_new), suitableAreaThisTime)); + for (GamsLandCoverType prevLC : GamsLandCoverType.values()) { + for (GamsLandCoverType newLC : GamsLandCoverType.values()) { + aggCFlux.setCarbonFlux(prevLC, newLC, aggregateMean(aggCFlux.getCarbonFlux(prevLC, newLC), suitableAreaSoFar, + carbonFluxItem.getCarbonFlux(prevLC, newLC), suitableAreaThisTime)); - aggWYield.setWoodYield(lc_previous, lc_new, aggregateMean(aggWYield.getWoodYield(lc_previous, lc_new), suitableAreaSoFar, - woodYieldItem.getWoodYield(lc_previous, lc_new), suitableAreaThisTime)); + aggWYield.setWoodYield(prevLC, newLC, aggregateMean(aggWYield.getWoodYield(prevLC, newLC), suitableAreaSoFar, + woodYieldItem.getWoodYield(prevLC, newLC), suitableAreaThisTime)); } } @@ -494,6 +531,13 @@ public class GamsRasterOptimiser { double areaSoFar = aggLandUse.getLandCoverArea(landType); aggLandUse.setLandCoverArea(landType, areaSoFar + areaThisTime); } + + // Gams land cover areas + for (GamsLandCoverType landType : GamsLandCoverType.values()) { + double areaThisTime = landUseItem.getGamsLandCoverArea(landType); + double areaSoFar = aggLandUse.getGamsLandCoverArea(landType); + aggLandUse.setGamsLandCoverArea(landType, areaSoFar + areaThisTime); + } } } diff --git a/src/ac/ed/lurg/landuse/CarbonFluxRasterSet.java b/src/ac/ed/lurg/landuse/CarbonFluxRasterSet.java index 059bfac408f18137f9dc093dba67bdf47d708667..986bea65a2feab9b8482f100fc7c44ef9057cf20 100644 --- a/src/ac/ed/lurg/landuse/CarbonFluxRasterSet.java +++ b/src/ac/ed/lurg/landuse/CarbonFluxRasterSet.java @@ -18,7 +18,6 @@ public class CarbonFluxRasterSet extends RasterSet<CarbonFluxItem> { return new CarbonFluxItem(); } - // not very efficient, we could keep the mapping of country to area somewhere. @Override public CarbonFluxRasterSet createSubsetForKeys(Collection<RasterKey> keys) { CarbonFluxRasterSet subsetCarbonFluxRaster = new CarbonFluxRasterSet(getHeaderDetails()); diff --git a/src/ac/ed/lurg/landuse/CarbonFluxReader.java b/src/ac/ed/lurg/landuse/CarbonFluxReader.java index bac2e81417bb51b6d092f6b1d874a06f52263eda..d5d1087d1e3d067888d4f6bb3e0ef68233644745 100644 --- a/src/ac/ed/lurg/landuse/CarbonFluxReader.java +++ b/src/ac/ed/lurg/landuse/CarbonFluxReader.java @@ -11,36 +11,36 @@ public class CarbonFluxReader extends AbstractTabularRasterReader<CarbonFluxItem private static final int MIN_COLS = 18; - public CarbonFluxReader(RasterSet<CarbonFluxItem> carbonFlux) { - super("[ |\t]+", MIN_COLS, carbonFlux); + public CarbonFluxReader(RasterSet<CarbonFluxItem> carbonFluxes) { + super("[ |\t]+", MIN_COLS, carbonFluxes); } @Override protected void setData(RasterKey key, CarbonFluxItem item, Map<String, Double> rowValues) { - item.setCarbonFlux(GamsLandCoverType.CROPLAND, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "c2n")); - item.setCarbonFlux(GamsLandCoverType.CROPLAND, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "c2f")); - item.setCarbonFlux(GamsLandCoverType.CROPLAND, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "c2x")); - item.setCarbonFlux(GamsLandCoverType.CROPLAND, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "c2p")); + item.setCarbonFlux(GamsLandCoverType.CROPLAND, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "crop_to_ntrl")); + item.setCarbonFlux(GamsLandCoverType.CROPLAND, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "crop_to_forT")); + item.setCarbonFlux(GamsLandCoverType.CROPLAND, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "crop_to_forC")); + item.setCarbonFlux(GamsLandCoverType.CROPLAND, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "crop_to_past")); - item.setCarbonFlux(GamsLandCoverType.PASTURE, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "p2n")); - item.setCarbonFlux(GamsLandCoverType.PASTURE, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "p2f")); - item.setCarbonFlux(GamsLandCoverType.PASTURE, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "p2x")); - item.setCarbonFlux(GamsLandCoverType.PASTURE, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "p2c")); + item.setCarbonFlux(GamsLandCoverType.PASTURE, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "past_to_ntrl")); + item.setCarbonFlux(GamsLandCoverType.PASTURE, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "past_to_forT")); + item.setCarbonFlux(GamsLandCoverType.PASTURE, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "past_to_forC")); + item.setCarbonFlux(GamsLandCoverType.PASTURE, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "past_to_crop")); - item.setCarbonFlux(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "n2p")); - item.setCarbonFlux(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "n2f")); - item.setCarbonFlux(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "n2x")); - item.setCarbonFlux(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "n2p")); + item.setCarbonFlux(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "ntrl_to_past")); + item.setCarbonFlux(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "ntrl_to_forT")); + item.setCarbonFlux(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "ntrl_to_forC")); + item.setCarbonFlux(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "ntrl_to_crop")); - item.setCarbonFlux(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "f2p")); - item.setCarbonFlux(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "f2n")); - item.setCarbonFlux(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "f2x")); - item.setCarbonFlux(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "f2c")); + item.setCarbonFlux(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "forT_to_past")); + item.setCarbonFlux(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "forT_to_ntrl")); + item.setCarbonFlux(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "forT_to_forC")); + item.setCarbonFlux(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "forT_to_crop")); - item.setCarbonFlux(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "x2p")); - item.setCarbonFlux(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "x2n")); - item.setCarbonFlux(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "x2f")); - item.setCarbonFlux(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "x2c")); + item.setCarbonFlux(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "forC_to_past")); + item.setCarbonFlux(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "forC_to_ntrl")); + item.setCarbonFlux(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "forC_to_forT")); + item.setCarbonFlux(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "forC_to_crop")); } diff --git a/src/ac/ed/lurg/landuse/LandUseItem.java b/src/ac/ed/lurg/landuse/LandUseItem.java index 1729969e7d7847ec8359c11450f4dba733e3d7bc..a01d32a4da168546c64ef4a1ea0b8958dc70db57 100644 --- a/src/ac/ed/lurg/landuse/LandUseItem.java +++ b/src/ac/ed/lurg/landuse/LandUseItem.java @@ -8,7 +8,6 @@ import java.util.Map; import ac.ed.lurg.ModelConfig; import ac.ed.lurg.types.CropToDouble; import ac.ed.lurg.types.CropType; -import ac.ed.lurg.types.ForestType; import ac.ed.lurg.types.GamsLandCoverType; import ac.ed.lurg.types.LandCoverType; import ac.ed.lurg.utils.Interpolator; @@ -21,7 +20,6 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial private Map<CropType, Double> cropFractions = new HashMap<CropType, Double>(); private Map<LandCoverType, Double> landCoverAreas = new HashMap<LandCoverType, Double>(); private Map<LandCoverType, Double> unprotectedAreas = new HashMap<LandCoverType, Double>(); - private Map<ForestType, Double> forestAreas = new HashMap<ForestType, Double>(); private Map<GamsLandCoverType, Double> gamsLandCoverAreas = new HashMap<GamsLandCoverType, Double>(); private double protectedArea; //protected area in Mha private double unavailableArea; //area unavailable due to altitude etc @@ -430,18 +428,6 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial return total; } - public double getForestArea(ForestType forestType) { - return forestAreas.get(forestType); - } - - public void setForestArea(ForestType c, double d) { - if (Double.isNaN(d) || Double.isInfinite(d)) - throw new RuntimeException("AreasItem for " + c + " is " + d); - - double landCover = (d < 0.0) ? 0.0 : d; - - forestAreas.put(c, landCover); - } public double getGamsLandCoverArea(GamsLandCoverType landCoverType) { return gamsLandCoverAreas.get(landCoverType); @@ -455,6 +441,17 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial gamsLandCoverAreas.put(c, landCover); } + + /** move areas from one land cover to another, return any residual not possible */ + public void moveGamsAreas(GamsLandCoverType toType, GamsLandCoverType fromType, double changeReq) { + + double prevTo = getGamsLandCoverArea(toType); + double prevFrom = getGamsLandCoverArea(fromType); + + setGamsLandCoverArea(toType, prevTo + changeReq); + setGamsLandCoverArea(fromType, prevFrom - changeReq); + + } @Override public String toString() { diff --git a/src/ac/ed/lurg/landuse/WoodYieldRasterSet.java b/src/ac/ed/lurg/landuse/WoodYieldRasterSet.java index e330aefa0710a24b27b7acd2e67360c8e7ac91ea..ae8ca043a567751708f36a6a0a708bdd7bcee8c3 100644 --- a/src/ac/ed/lurg/landuse/WoodYieldRasterSet.java +++ b/src/ac/ed/lurg/landuse/WoodYieldRasterSet.java @@ -18,7 +18,6 @@ public class WoodYieldRasterSet extends RasterSet<WoodYieldItem> { return new WoodYieldItem(); } - // not very efficient, we could keep the mapping of country to area somewhere. @Override public WoodYieldRasterSet createSubsetForKeys(Collection<RasterKey> keys) { WoodYieldRasterSet subsetWoodYieldRaster = new WoodYieldRasterSet(getHeaderDetails()); diff --git a/src/ac/ed/lurg/landuse/WoodYieldReader.java b/src/ac/ed/lurg/landuse/WoodYieldReader.java index d74880d1b0d527c11c68f44babc1c5ac245ac686..b8b5a99f8b8102bd42308c5a8159f27b64ef0b2b 100644 --- a/src/ac/ed/lurg/landuse/WoodYieldReader.java +++ b/src/ac/ed/lurg/landuse/WoodYieldReader.java @@ -16,30 +16,30 @@ public class WoodYieldReader extends AbstractTabularRasterReader<WoodYieldItem> } protected void setData(RasterKey key, WoodYieldItem item, Map<String, Double> rowValues) { - item.setWoodYield(GamsLandCoverType.CROPLAND, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "c2n")); - item.setWoodYield(GamsLandCoverType.CROPLAND, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "c2f")); - item.setWoodYield(GamsLandCoverType.CROPLAND, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "c2x")); - item.setWoodYield(GamsLandCoverType.CROPLAND, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "c2p")); + item.setWoodYield(GamsLandCoverType.CROPLAND, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "crop_to_ntrl")); + item.setWoodYield(GamsLandCoverType.CROPLAND, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "crop_to_forT")); + item.setWoodYield(GamsLandCoverType.CROPLAND, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "crop_to_forC")); + item.setWoodYield(GamsLandCoverType.CROPLAND, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "crop_to_past")); - item.setWoodYield(GamsLandCoverType.PASTURE, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "p2n")); - item.setWoodYield(GamsLandCoverType.PASTURE, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "p2f")); - item.setWoodYield(GamsLandCoverType.PASTURE, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "p2x")); - item.setWoodYield(GamsLandCoverType.PASTURE, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "p2c")); + item.setWoodYield(GamsLandCoverType.PASTURE, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "past_to_ntrl")); + item.setWoodYield(GamsLandCoverType.PASTURE, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "past_to_forT")); + item.setWoodYield(GamsLandCoverType.PASTURE, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "past_to_forC")); + item.setWoodYield(GamsLandCoverType.PASTURE, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "past_to_crop")); - item.setWoodYield(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "n2p")); - item.setWoodYield(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "n2f")); - item.setWoodYield(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "n2x")); - item.setWoodYield(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "n2p")); + item.setWoodYield(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "ntrl_to_past")); + item.setWoodYield(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "ntrl_to_forT")); + item.setWoodYield(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "ntrl_to_forC")); + item.setWoodYield(GamsLandCoverType.OTHER_NATURAL, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "ntrl_to_crop")); - item.setWoodYield(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "f2p")); - item.setWoodYield(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "f2n")); - item.setWoodYield(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "f2x")); - item.setWoodYield(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "f2c")); + item.setWoodYield(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "forT_to_past")); + item.setWoodYield(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "forT_to_ntrl")); + item.setWoodYield(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.CARBON_FOREST, getValueForCol(rowValues, "forT_to_forC")); + item.setWoodYield(GamsLandCoverType.TIMBER_FOREST, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "forT_to_crop")); - item.setWoodYield(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "x2p")); - item.setWoodYield(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "x2n")); - item.setWoodYield(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "x2f")); - item.setWoodYield(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "x2c")); + item.setWoodYield(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.PASTURE, getValueForCol(rowValues, "forC_to_past")); + item.setWoodYield(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.OTHER_NATURAL, getValueForCol(rowValues, "forC_to_ntrl")); + item.setWoodYield(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.TIMBER_FOREST, getValueForCol(rowValues, "forC_to_forT")); + item.setWoodYield(GamsLandCoverType.CARBON_FOREST, GamsLandCoverType.CROPLAND, getValueForCol(rowValues, "forC_to_crop")); } }