diff --git a/GAMS/IntExtOpt.gms b/GAMS/IntExtOpt.gms index 1bc06716b7c6563842f31ed27e3d79926ca24e50..bc63b2457c4329b0ff0c018f5ea3f501f41b4ef1 100644 --- a/GAMS/IntExtOpt.gms +++ b/GAMS/IntExtOpt.gms @@ -70,8 +70,6 @@ PARAMETER otherIParam(crop, location) yield response to other intensity; PARAMETER prodCost(crop) cost per ha before intensity values not including fertiliser or irrigation i.e. seed spray and other. In 1000 $ per ha; PARAMETER animalProdCost(animal) cost per unit produced; - PARAMETER feedCostCalib(feed_crop) additional feed cost for feed mix calibration; - PARAMETER costCalibFactor(all_types); PARAMETER previousProduction(all_types); SCALAR meatEfficency efficiency of converting feed and pasture into animal products; @@ -95,7 +93,7 @@ SCALAR discountRate; SCALAR energyPrice; -*$gdxin "~/Documents/PLUM_Output/calib_forest/GamsTmp/China2020landuse.gdx" +*$gdxin "/Users/bart/Documents/PLUM_Output/calib/GamsTmp/Brazil2020landuse.gdx" $gdxin %gdxincname% $load location, suitableLandArea, demand $load previousCropArea, previousFertIntensity, previousIrrigIntensity, previousOtherIntensity, previousRuminantFeed, previousMonogastricFeed, previousImportAmount, previousExportAmount @@ -105,11 +103,11 @@ $load meatEfficency, otherICost, irrigCost, irrigConstraint, irrigMaxRate, ferti $load previousLandCoverArea, carbonCreditRate, conversionCost, woodYieldMaxParam, woodYieldSlopeParam, woodYieldShapeParam, tradeAdjustmentCostRate $load forestManagementCost, carbonForestMaxProportion, previousRotationIntensity, maxLandCoverChange, maxLandCoverArea $load fertLimRestricted, irrigLimRestricted, otherLimRestricted, fertLimConventional, irrigLimConventional, otherLimConventional -$load solarEnergyDensity, agrivoltaicsYieldFactor, prodCost, animalProdCost, feedCostCalib, solarNpvRate -$load discountRate, energyPrice, monoculturePenalty, agrivoltaicsCropCostFactor, costCalibFactor, previousProduction, pastureIntensityPenalty +$load solarEnergyDensity, agrivoltaicsYieldFactor, prodCost, animalProdCost, solarNpvRate +$load discountRate, energyPrice, monoculturePenalty, agrivoltaicsCropCostFactor, previousProduction, pastureIntensityPenalty $gdxin - SCALAR delta "use to smooth power function see 7.5 www.gams.com dd docs solversconopt.pdf" / 0.00000000001 /; + SCALAR delta / 1e-6 /; PARAMETER cropDM(crop) kg DM per kg of feed the conversion from feed to meat is done in the R animal product index. Pasture is in DM terms already / wheat 0.87 @@ -137,8 +135,8 @@ $gdxin previousFeedAmount('monogastrics', feed_crop) = previousMonogastricFeed(feed_crop); PARAMETER feedDiversityCost(animal) - / monogastrics = 0.03 - ruminants = 0.06 /; + / monogastrics = 0.04 + ruminants = 0.05 /; VARIABLES unitCost(crop, farming_type, location) cost per area for each crop - cost @@ -158,6 +156,7 @@ $gdxin netImportIncrease(import_types) netImportDecrease(import_types) excessImports(import_types) + importFraction(all_types) landCoverArea(land_cover, protection, location) land cover area in Mha landCoverChange(land_cover_before, land_cover_after, protection, location) land cover change in Mha @@ -167,7 +166,6 @@ $gdxin rotationIntensity(location) equivalent to 1 divided by rotation period woodSupply total wood supply - million m3 forestryNPV(location) NPV of wood production - woodPriceFactor(location) carbonCredits(location) carbon credits generated - Mt C @@ -176,7 +174,7 @@ $gdxin ; - POSITIVE VARIABLE cropArea, fertI, irrigI, otherIntensity, yield, feedAmount, importAmount, exportAmount, woodPriceFactor, cropProduction, excessImports, + POSITIVE VARIABLE cropArea, fertI, irrigI, otherIntensity, yield, feedAmount, importAmount, exportAmount, cropProduction, excessImports, importFraction, landCoverArea, landCoverChange, woodYieldRota, rotationIntensity, woodSupply, totalProduction, netImportIncrease, netImportDecrease; @@ -197,6 +195,7 @@ $gdxin MIN_NET_IMPORT_CONSTRAINT(import_types) MAX_NET_IMPORT_CONSTRAINT(import_types) NET_IMPORTS_CHANGE_CALC(import_types) + IMPORT_FRACTION_CALC(all_types) fraction of supply that is imported SETASIDE_AREA_CALC(farming_type, location) setaside area constraint CROPLAND_LAND_COVER_CALC(protection, farming_type, location) cropland area equals sum of all crop areas @@ -210,8 +209,7 @@ $gdxin WOOD_YIELD_CALC(location) wood yield at rotation - tC per ha WOOD_SUPPLY_CALC wood supply calculation WOOD_DEMAND_CONSTRAINT wood demand constraint - FORESTRY_NPV_CALC(location) net present value of wood production (Faustmann's formula) - WOOD_PRICE_FACTOR_CALC(location) price multiplier based on tree age (older trees more valuable) + FORESTRY_NPV_CALC(location) net present value of wood production (Faustmann's formula) PV_ENERGY_DEMAND_CONSTRAINT energy produced from photovoltaics AV_ENERGY_DEMAND_CONSTRAINT energy produced from agrivoltaics @@ -324,10 +322,7 @@ $gdxin WOOD_DEMAND_CONSTRAINT .. woodSupply =E= demand('wood') + exportAmount('wood') - importAmount('wood'); -* Mature trees more valuable. Encourages longer rotation periods. - WOOD_PRICE_FACTOR_CALC(location) .. woodPriceFactor(location) =E= 1 - exp(-0.023 / rotationIntensity(location)); - - FORESTRY_NPV_CALC(location) .. forestryNPV(location) =E= (woodPriceFactor(location) * exportPrices('wood') * woodYieldRota(location) - forestManagementCost) * rotationIntensity(location); + FORESTRY_NPV_CALC(location) .. forestryNPV(location) =E= (exportPrices('wood') * woodYieldRota(location) - forestManagementCost) * rotationIntensity(location); *********** Carbon *********************************** @@ -353,6 +348,8 @@ $gdxin NET_IMPORTS_CHANGE_CALC(import_types) .. netImportIncrease(import_types) - netImportDecrease(import_types) =E= netImportAmount(import_types) - previousNetImport(import_types); + IMPORT_FRACTION_CALC(all_types) .. importFraction(all_types) =E= importAmount(all_types) / (importAmount(all_types) + totalProduction(all_types) + delta); + * No imports or exports of pasture allowed importAmount.FX('pasture') = 0; exportAmount.FX('pasture') = 0; @@ -360,18 +357,20 @@ $gdxin * Allow solar energy import in case cannot produce enough domestically. maxNetImport('energyPV') = demand('energyPV'); maxNetImport('energyAV') = demand('energyAV'); + importPrices('energyPV') = 1000; + importPrices('energyAV') = 1000; ************ Total Net Present Value ****************************** NPV_CALC .. total_npv =E= -* Value of crop and animal production minus feed used - sum(agri_types, totalProduction(agri_types) * exportPrices(agri_types)) +* Value of crop and animal production minus domestically produced feed used + sum(agri_types, exportPrices(agri_types) * (totalProduction(agri_types) - sum(animal, feedAmount(animal, agri_types)) * (1 - importFraction(agri_types)))) * Cost of crop production - sum((crop, farming_type, location), cropArea(crop, farming_type, location) * unitCost(crop, farming_type, location) * (1 - subsidyRate(crop))) * Cost of animal production - sum(animal, animalProdCost(animal) * totalProduction(animal) * (1 - subsidyRate(animal))) -* Cost of feed - - sum((animal, feed_crop_less_pasture), feedAmount(animal, feed_crop_less_pasture) * importPrices(feed_crop_less_pasture)) +* Cost of feed imports + - sum((animal, import_types), importPrices(import_types) * feedAmount(animal, import_types) * importFraction(import_types)) * NPV of wood production + sum(location, forestryNPV(location) * landCoverArea('timberForest', 'unprotected', location)) * NPV of solar energy @@ -385,17 +384,15 @@ $gdxin * Crop monoculture penalty. Derived from Simpson's diversity index, weighted by production - sum(location, monoculturePenalty * sum(crop_less_pasture_setaside, sqr(cropProduction(crop_less_pasture_setaside, location))) / (sum(crop_less_pasture_setaside, cropProduction(crop_less_pasture_setaside, location)) + 0.01)) * Pasture intensity penalty. Controls how spread out pasture production is. - - sum(location, pastureIntensityPenalty * sqr(cropProduction('pasture', location))) / (sum(location, cropProduction('pasture', location)) + 0.01) + - sum(location, pastureIntensityPenalty * sqr(cropProduction('pasture', location))) / (sum(location, cropProduction('pasture', location)) + delta) * Small reward for increasing natural area to allow land abandonment + sum((land_cover, protection, location)$(not sameAs(land_cover, 'natural')), 0.00001 * landCoverChange(land_cover, 'natural', protection, location)) * Feed diversity penalty - - sum(animal, feedDiversityCost(animal) * sum(feed_crop, sqr(feedAmount(animal, feed_crop) * cropDM(feed_crop))) / (sum(feed_crop, feedAmount(animal, feed_crop) * cropDM(feed_crop)) + 0.01)) + - sum(animal, feedDiversityCost(animal) * sum(feed_crop, sqr(feedAmount(animal, feed_crop) * cropDM(feed_crop))) / (sum(feed_crop, feedAmount(animal, feed_crop) * cropDM(feed_crop)) + delta)) * Net import change cost - sum(import_types, tradeAdjustmentCostRate(import_types) * (netImportIncrease(import_types) + netImportDecrease(import_types))) * Allow import constraint to be relaxed at a high cost if needed to avoid solution failture - sum(import_types, 1000 * excessImports(import_types)) -* Allow energy imports if cannot produce domestically - - 1000 * (importAmount('energyPV') + importAmount('energyAV')) ; MODEL LAND_USE / ALL / ; @@ -435,7 +432,7 @@ $gdxin parameter totalProdCost(all_types); parameter totalCropArea(crop); parameter netImportCost(all_types); - parameter importFraction(all_types); +* parameter importFraction(all_types); parameter prodCostRate(crop); parameter productionShock(all_types); parameter woodProdCost; @@ -448,12 +445,12 @@ $gdxin netImportCost(import_types) = importAmount.L(import_types) * importPrices(import_types) - exportAmount.l(import_types) * exportPrices(import_types); - importFraction(import_types) $ (importAmount.l(import_types) > 0) = importAmount.l(import_types) / (totalProduction.l(import_types) + importAmount.l(import_types)); +* importFraction(import_types) $ (importAmount.l(import_types) > 0) = importAmount.l(import_types) / (totalProduction.l(import_types) + importAmount.l(import_types)); prodCostRate(crop)$[totalProduction.l(crop) <> 0] = totalProdCost(crop) / totalProduction.l(crop); - totalProdCost(animal) = sum(feed_crop, importFraction(feed_crop) * feedAmount.l(animal, feed_crop) * importPrices(feed_crop) - + (1 - importFraction(feed_crop)) * prodCostRate(feed_crop)) + totalProduction.l(animal) * animalProdCost(animal); + totalProdCost(animal) = sum(feed_crop, importFraction.l(feed_crop) * feedAmount.l(animal, feed_crop) * importPrices(feed_crop) + + (1 - importFraction.l(feed_crop)) * prodCostRate(feed_crop)) + totalProduction.l(animal) * animalProdCost(animal); If(woodSupply.L > 0, woodProdCost = sum(location, forestManagementCost * rotationIntensity.L(location) * landCoverArea.L('timberForest', 'unprotected', location)); diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java index 707278726b1dd14f0d61bd3c8208e996754adab6..e432aa5690fa57c6ae77798d40474946369553ed 100755 --- a/src/ac/ed/lurg/ModelConfig.java +++ b/src/ac/ed/lurg/ModelConfig.java @@ -280,19 +280,19 @@ public class ModelConfig { public static final double INITIAL_PRICE_FRUITVEG = getDoubleProperty("INITIAL_PRICE_FRUITVEG", 0.176); public static final double INITIAL_PRICE_SUGAR = getDoubleProperty("INITIAL_PRICE_SUGAR", 0.046); - public static final double PROD_COST_WHEAT = getDoubleProperty("PROD_COST_WHEAT", 0.25); + public static final double PROD_COST_WHEAT = getDoubleProperty("PROD_COST_WHEAT", 0.3); public static final double PROD_COST_MAIZE = getDoubleProperty("PROD_COST_MAIZE", 0.3); public static final double PROD_COST_RICE = getDoubleProperty("PROD_COST_RICE", 0.8); public static final double PROD_COST_OILCROPS_NFIX = getDoubleProperty("PROD_COST_OILCROPS_NFIX", 0.4); - public static final double PROD_COST_OILCROPS_OTHER = getDoubleProperty("PROD_COST_OILCROPS_OTHER", 0.4); + public static final double PROD_COST_OILCROPS_OTHER = getDoubleProperty("PROD_COST_OILCROPS_OTHER", 0.6); public static final double PROD_COST_PULSES = getDoubleProperty("PROD_COST_PULSES", 0.6); - public static final double PROD_COST_STARCHYROOTS = getDoubleProperty("PROD_COST_STARCHYROOTS", 2.5); + public static final double PROD_COST_STARCHYROOTS = getDoubleProperty("PROD_COST_STARCHYROOTS", 3.0); public static final double PROD_COST_MONOGASTRICS = getDoubleProperty("PROD_COST_MONOGASTRICS", 0.03); public static final double PROD_COST_RUMINANTS = getDoubleProperty("PROD_COST_RUMINANTS", 0.05); public static final double PROD_COST_PASTURE = getDoubleProperty("PROD_COST_PASTURE", 0.1); public static final double PROD_COST_ENERGYCROPS = getDoubleProperty("PROD_COST_ENERGYCROPS", 0.3); public static final double PROD_COST_FRUITVEG = getDoubleProperty("PROD_COST_FRUITVEG", 8.0); - public static final double PROD_COST_SUGAR = getDoubleProperty("PROD_COST_SUGAR", 4.0); + public static final double PROD_COST_SUGAR = getDoubleProperty("PROD_COST_SUGAR", 3.0); // These are initial demand system prices in 2000 kcal terms @@ -449,7 +449,7 @@ public class ModelConfig { public static final double SOLAR_CONVERSION_COST = getDoubleProperty("SOLAR_CONVERSION_COST", 10.0); public static final double NATURAL_CONVERSION_COST = getDoubleProperty("NATURAL_CONVERSION_COST", 0.12); // controls additional cost of natural conversion. Higher cost if higher proportion of land is natural - public static final double INFRASTRUCTURE_COST_FACTOR = getDoubleProperty("INFRASTRUCTURE_COST_FACTOR", 0.4); + public static final double INFRASTRUCTURE_COST_FACTOR = getDoubleProperty("INFRASTRUCTURE_COST_FACTOR", 0.6); public static final double TECHNOLOGY_CHANGE_ANNUAL_RATE = getDoubleProperty("TECHNOLOGY_CHANGE_ANNUAL_RATE", 0.002); @@ -560,14 +560,14 @@ public class ModelConfig { public static final String MIN_MAX_TRADE_FILE = getProperty("MIN_MAX_TRADE_FILE", OUTPUT_DIR + File.separator + "minMaxNetImport.csv"); // Forestry - public static final boolean IS_FORESTRY_ON = getBooleanProperty("IS_FORESTRY_ON", false); + public static final boolean IS_FORESTRY_ON = getBooleanProperty("IS_FORESTRY_ON", true); public static final String WOOD_DEMAND_FILENAME = getProperty("WOOD_DEMAND_FILENAME", "wood_base_demand.csv"); public static final String WOOD_DEMAND_FILE = getProperty("WOOD_DEMAND_FILE", DATA_DIR + File.separator + WOOD_DEMAND_FILENAME); public static final double INIT_WOOD_STOCK = getDoubleProperty("INIT_WOOD_STOCK", 1200.0); // million m3 public static final double WOOD_BIOMASS_CONVERSION_FACTOR = getDoubleProperty("WOOD_BIOMASS_CONVERSION_FACTOR", 0.3); // m3 to tC-eq p.16 [https://doi.org/10.5194/gmd-13-5425-2020] public static final double FOREST_MANAGEMENT_COST = IS_FORESTRY_ON ? getDoubleProperty("FOREST_MANAGEMENT_COST", 2.0) : 0.0; // establishment, management etc. $1000/ha public static final double WOOD_TRADE_BARRIER = getDoubleProperty("WOOD_TRADE_BARRIER", 0.1); //$1000/m3 - public static final double INIT_WOOD_PRICE = IS_FORESTRY_ON ? getDoubleProperty("INIT_ROUNDWOOD_PRICE", 0.05) : 0.0; // $1000/m3 + public static final double INIT_WOOD_PRICE = IS_FORESTRY_ON ? getDoubleProperty("INIT_WOOD_PRICE", 0.07) : 0.0; // $1000/m3 public static final int CARBON_WOOD_MAX_TIME = getIntProperty("CARBON_WOOD_MAX_TIME", 160); // upper data limit, years // Carbon diff --git a/src/ac/ed/lurg/country/CountryAgent.java b/src/ac/ed/lurg/country/CountryAgent.java index 5de56df63221f93014b82165f16f0ce34796bc68..8df574a90dda18b0b884afcdb9615cb8f152618f 100644 --- a/src/ac/ed/lurg/country/CountryAgent.java +++ b/src/ac/ed/lurg/country/CountryAgent.java @@ -178,10 +178,12 @@ public class CountryAgent extends AbstractCountryAgent { double baseTrade = cropUsage.getNetImportsExpected(); double maxOfProdOrSupply = cropUsage.getProductionExpected() + Math.max(baseTrade, 0); + double currentDemand = totalDemand.get(crop); double prevDemand = cropUsage.getNetSupply() - cropUsage.getMonogastricFeed() - cropUsage.getRuminantFeed(); - double minNetImport = totalDemand.get(crop) < baseTrade ? totalDemand.get(crop) * 0.99 : baseTrade - ModelConfig.MAX_IMPORT_CHANGE * maxOfProdOrSupply; - double maxNetImport = Math.max(baseTrade + ModelConfig.MAX_IMPORT_CHANGE * maxOfProdOrSupply, baseTrade + totalDemand.get(crop) - prevDemand); + double change = Math.max(ModelConfig.MAX_IMPORT_CHANGE * maxOfProdOrSupply, 1); // max of 1 otherwise if only importing then can never export + double minNetImport = currentDemand < baseTrade ? currentDemand * 0.95 : baseTrade - change; // min imports can't be lower than demand + double maxNetImport = Math.max(baseTrade + change, baseTrade + currentDemand - prevDemand); // increase in demand can be imported double restiction = 0; if (currentExportRestrictions != null) { @@ -210,9 +212,12 @@ public class CountryAgent extends AbstractCountryAgent { if (ModelConfig.IS_CARBON_ON) { double baseTrade = carbonUsageData.getNetCarbonImport(); double maxOfProdOrSupply = carbonUsageData.getCarbonCredits() + Math.max(0, carbonUsageData.getNetCarbonImport()); + double currentDemand = getCurrentCarbonDemand(); double prevDemand = carbonUsageData.getCarbonCredits() + carbonUsageData.getNetCarbonImport(); - double minNetImport = getTotalWoodDemand() < baseTrade ? getCurrentCarbonDemand() * 0.99 : baseTrade - ModelConfig.MAX_IMPORT_CHANGE * maxOfProdOrSupply; - double maxNetImport = Math.max(baseTrade + ModelConfig.MAX_IMPORT_CHANGE * maxOfProdOrSupply, baseTrade + getTotalWoodDemand() - prevDemand) ; + + double change = Math.max(ModelConfig.MAX_IMPORT_CHANGE * maxOfProdOrSupply, 1); // max of 1 otherwise if only importing then can never export + double minNetImport = currentDemand < baseTrade ? currentDemand * 0.95 : baseTrade - change; // min imports can't be lower than demand + double maxNetImport = Math.max(baseTrade + change, baseTrade + currentDemand - prevDemand); // increase in demand can be imported carbonTradeConstraint = new TradeConstraint(minNetImport, maxNetImport); @@ -225,11 +230,13 @@ public class CountryAgent extends AbstractCountryAgent { if (ModelConfig.IS_FORESTRY_ON) { WoodUsageData woodUsageData = previousGamsRasterOutput.getWoodUsageData(); double baseTrade = woodUsageData.getNetImport(); + double maxOfProdOrSupply = woodUsageData.getProduction() + Math.max(baseTrade, 0); + double currentDemand = getTotalWoodDemand(); double prevDemand = woodUsageData.getNetImport() + woodUsageData.getProduction(); - double maxOfProdOrSupply = woodUsageData.getProduction() + Math.max(baseTrade, 0); - double minNetImport = getTotalWoodDemand() < baseTrade ? getTotalWoodDemand() * 0.99 : baseTrade - ModelConfig.MAX_IMPORT_CHANGE * maxOfProdOrSupply; - double maxNetImport = Math.max(baseTrade + ModelConfig.MAX_IMPORT_CHANGE * maxOfProdOrSupply, baseTrade + getTotalWoodDemand() - prevDemand) ; + double change = Math.max(ModelConfig.MAX_IMPORT_CHANGE * maxOfProdOrSupply, 1); // max of 1 otherwise if only importing then can never export + double minNetImport = currentDemand < baseTrade ? currentDemand * 0.95 : baseTrade - change; // min imports can't be lower than demand + double maxNetImport = Math.max(baseTrade + change, baseTrade + currentDemand - prevDemand); // increase in demand can be imported woodTradeConstraint = new TradeConstraint(minNetImport, maxNetImport); } else { diff --git a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java index d51024cbc320f6118e277c5cc9525505c129f974..035bd79832335652b42589d5a3d99d2f07b8d0c7 100644 --- a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java +++ b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java @@ -311,15 +311,6 @@ public class GamsLocationOptimiser { } } - // Calibrated feed costs - GAMSParameter feedCostP = inDB.addParameter("feedCostCalib", 1); - Map<CropType, Double> feedCosts = calibrationItem.getFeedCosts(); - for (CropType crop : feedCosts.keySet()) { - Vector<String> v = new Vector<>(); - v.add(crop.getGamsName()); - setGamsParamValue(feedCostP.addRecord(v), feedCosts.get(crop), -1); - } - if (DEBUG) LogWriter.println("\nCrop, subsidy rate"); GAMSParameter subsideRateP = inDB.addParameter("subsidyRate", 1); for (CropType crop : CropType.getImportedTypes()) { @@ -342,8 +333,8 @@ public class GamsLocationOptimiser { CountryPrice gp = countryInput.getCountryPrices().get(crop); double minTrade = iec.getMinConstraint(); double maxTrade = iec.getMaxConstraint(); - double importPrice = gp.getImportPrice() * calibrationItem.getSubsidyRate(crop); - double exportPrice = gp.getProducerNetExportPrice() * calibrationItem.getSubsidyRate(crop); + double importPrice = gp.getImportPrice(); + double exportPrice = gp.getProducerNetExportPrice(); CropUsageData cu = countryInput.getPreviousCropUsageData().get(crop); double netImports = cu.getNetImportsExpected(); @@ -367,7 +358,6 @@ public class GamsLocationOptimiser { setGamsParamValue(previousRuminantFeedP.addRecord(crop.getGamsName()), ruminantFeed, -1); setGamsParamValue(previousMonogastricFeedP.addRecord(crop.getGamsName()), monogastricFeed, -1); setGamsParamValue(seedAndWasteRateP.addRecord(crop.getGamsName()), seedAndWasteRate, -1); - setGamsParamValue(costCalibP.addRecord(crop.getGamsName()), calibrationItem.getSubsidyRate(crop), -1); setGamsParamValue(previousProdP.addRecord(crop.getGamsName()), prevProd, -1); } diff --git a/src/ac/ed/lurg/landuse/ConversionCostManager.java b/src/ac/ed/lurg/landuse/ConversionCostManager.java index 987d2ec3c2a15534c0c46546d974d298dc2f93a4..ef5e5f5f159905ea5e2247209bbeabf0f832c5eb 100644 --- a/src/ac/ed/lurg/landuse/ConversionCostManager.java +++ b/src/ac/ed/lurg/landuse/ConversionCostManager.java @@ -118,6 +118,7 @@ public class ConversionCostManager { conversionCosts.put(key, baseCost * ModelConfig.getAdjParam("AGRI_LAND_EXPANSION_COST_FACTOR")); } + // Additional cost of managed forest establishment if (toLc.equals(LandCoverType.TIMBER_FOREST)) { double baseCost = conversionCosts.get(key); conversionCosts.put(key, baseCost + ModelConfig.getAdjParam("TIMBER_FOREST_ESTABLISHMENT_COST")); diff --git a/src/ac/ed/lurg/utils/calib/CalibrationItem.java b/src/ac/ed/lurg/utils/calib/CalibrationItem.java index 5bde036ace4d972b0b40b5e7f578b8ffca0ea003..1c83a13f0cc6f560fa2e413c08b72469172f434a 100644 --- a/src/ac/ed/lurg/utils/calib/CalibrationItem.java +++ b/src/ac/ed/lurg/utils/calib/CalibrationItem.java @@ -1,7 +1,6 @@ package ac.ed.lurg.utils.calib; import ac.ed.lurg.types.CropType; -import ac.ed.lurg.types.WoodType; import java.io.Serializable; import java.util.HashMap; @@ -10,34 +9,18 @@ import java.util.Map; public class CalibrationItem implements Serializable { private static final long serialVersionUID = 7012118381657442621L; private Map<CropType, Double> cropProdCosts = new HashMap<>(); - private Map<CropType, Double> feedCosts = new HashMap<>(); private double irrigationCostFactor; private double irrigationEfficiency; private double forestryCostFactor; - private Map<CropType, Double> subsidyRates = new HashMap<>(); - double error; public CalibrationItem() {} public CalibrationItem(CalibrationItem itemToCopy) { super(); this.cropProdCosts.putAll(itemToCopy.cropProdCosts); - this.feedCosts.putAll(itemToCopy.feedCosts); this.irrigationCostFactor = itemToCopy.irrigationCostFactor; this.irrigationEfficiency = itemToCopy.irrigationEfficiency; this.forestryCostFactor = itemToCopy.forestryCostFactor; - this.subsidyRates.putAll(itemToCopy.subsidyRates); - this.error = itemToCopy.error; - } - - public void copyParameters(CalibrationItem itemToCopy) { - this.cropProdCosts.putAll(itemToCopy.cropProdCosts); - this.feedCosts.putAll(itemToCopy.feedCosts); - this.irrigationCostFactor = itemToCopy.irrigationCostFactor; - this.irrigationEfficiency = itemToCopy.irrigationEfficiency; - this.forestryCostFactor = itemToCopy.forestryCostFactor; - this.subsidyRates.putAll(itemToCopy.subsidyRates); - this.error = itemToCopy.error; } public double getIrrigationCostFactor() { @@ -68,18 +51,6 @@ public class CalibrationItem implements Serializable { return cropProdCosts; } - public void setFeedCosts(Map<CropType, Double> feedCosts) { - this.feedCosts = feedCosts; - } - - public void setFeedCost(CropType crop, Double cost) { - feedCosts.put(crop, cost); - } - - public Map<CropType, Double> getFeedCosts() { - return feedCosts; - } - public void setForestryCostFactor(double forestryCostFactor) { this.forestryCostFactor = forestryCostFactor; } @@ -88,19 +59,4 @@ public class CalibrationItem implements Serializable { return forestryCostFactor; } - public void setSubsidyRate(CropType crop, double subsidyRate) { - subsidyRates.put(crop, subsidyRate); - } - - public double getSubsidyRate(CropType crop) { - return subsidyRates.get(crop); - } - - public double getError() { - return error; - } - - public void setError(double error) { - this.error = error; - } } diff --git a/src/ac/ed/lurg/utils/calib/CalibrationManager.java b/src/ac/ed/lurg/utils/calib/CalibrationManager.java index 379e8cf5ca4b9c332daa0eab9b3484f583e6b64b..05c58891e2c6e49d3dd8431f6fdf70dfed5f1e71 100644 --- a/src/ac/ed/lurg/utils/calib/CalibrationManager.java +++ b/src/ac/ed/lurg/utils/calib/CalibrationManager.java @@ -66,22 +66,11 @@ public class CalibrationManager implements Serializable { // Production costs Map<CropType, Double> initProdCosts = new HashMap<>(defaultProductionCosts); - // Feed costs - Map<CropType, Double> initFeedCosts = new HashMap<>(); - for (CropType crop : CropType.getNonMeatTypes()) { - initFeedCosts.put(crop, 0.01); - } - CalibrationItem calibrationItem = new CalibrationItem(); calibrationItem.setIrrigationEfficiency(irrigationEfficiency.get(cc)); calibrationItem.setIrrigationCostFactor(1); calibrationItem.setCropProdCosts(initProdCosts); - calibrationItem.setFeedCosts(initFeedCosts); calibrationItem.setForestryCostFactor(1); - for (CropType crop : CropType.getImportedTypes()) { - calibrationItem.setSubsidyRate(crop, 1); - } - //calibrationItem.setError(Double.POSITIVE_INFINITY); parameters.put(cc, calibrationItem); prevParams.put(cc, new CalibrationItem(calibrationItem)); @@ -107,7 +96,7 @@ public class CalibrationManager implements Serializable { { double adj; double ratio = countryIrrig / baseCountryIrrig; - if ((ratio > 0.5 && ratio < 2) || Math.abs(countryIrrig - baseCountryIrrig) < 1) { + if ((ratio > 0.5 && ratio < 1.5) || Math.abs(countryIrrig - baseCountryIrrig) < 1) { adj = 1; } else { adj = 1 + 0.5 * lambda * ((countryIrrig - baseCountryIrrig) / (countryIrrig + baseCountryIrrig)); @@ -130,7 +119,7 @@ public class CalibrationManager implements Serializable { double prod = cropUsage.get(crop).getProductionExpected(); double adj; double ratio = prod / baselineProd; - if (prod + baselineProd < 1 || (ratio > 0.5 && ratio < 2)) { + if (prod + baselineProd < 1 || (ratio > 0.5 && ratio < 1.25)) { adj = 1; } else { adj = 1 + 0.5 * lambda * ((prod - baselineProd) / (baselineProd + prod)); @@ -142,6 +131,23 @@ public class CalibrationManager implements Serializable { calibrationItem.setCropProdCost(crop, newCost); } + // Forestry costs + if (ModelConfig.IS_FORESTRY_ON) { + double prod = woodUsage.getProduction(); + double baselineProd = baselineWoodUsage.get(compositeCountry).getProduction(); + double adj; + double ratio = prod / baselineProd; + if (prod + baselineProd < 1 || (ratio > 0.5 && ratio < 1.25)) { + adj = 1; + } else { + adj = 1 + 0.5 * lambda * ((prod - baselineProd) / (baselineProd + prod)); + } + + double newCost = calibrationItem.getForestryCostFactor() * adj; + newCost = Math.min(Math.max(newCost, 0.5), 3); + calibrationItem.setForestryCostFactor(newCost); + } + }