diff --git a/GAMS/IntExtOpt.gms b/GAMS/IntExtOpt.gms index d20564f6df0649777126c12084ccaf41b56e4c11..0ac433f0baa40f170d978c1bc4db30b19063c6e3 100644 --- a/GAMS/IntExtOpt.gms +++ b/GAMS/IntExtOpt.gms @@ -23,6 +23,8 @@ PARAMETER maxNetImport(import_crop) maximum net import for each crop based on world market; PARAMETER minNetImport(import_crop) minimum net import for each crop based on world market; PARAMETER irrigCost(location) irrigation cost; + PARAMETER irrigMaxRate(crop, location) max water application rate irrigation in mm; + PARAMETER irrigConstraint(location) max water available for irrigation in mm; PARAMETER cropAdj(crop) this is the fudge factor that allows the model to fit the observed data SCALAR meatEfficency efficiency of converting feed and pasture into animal products; @@ -36,7 +38,7 @@ $gdxin %gdxincname% $load location, suitableLandArea, previousArea, demand, landChangeEnergy $load yieldNone, yieldFertOnly, yieldIrrigOnly, yieldBoth $load fertParam, irrigParam, worldInputPrices, maxNetImport, minNetImport -$load meatEfficency, minFeedRate, irrigCost +$load meatEfficency, minFeedRate, irrigCost, irrigMaxRate, irrigConstraint $load cropAdj, fitToPreviousAreas $gdxin @@ -100,6 +102,7 @@ $gdxin MIN_NET_IMPORT_CONSTRAINT(import_crop) constraint on min net imports PASTURE_IMPORT_CONSTRAINT constraint to not import pasture MIN_FEED_CONSTRAINT constraint on min feed rate + IRRIGATION_CONSTRAINT(location) constraint no water usage NET_SUPPLY_EQ(crop) calc net supply for crops AGRI_LAND_EXPANSION_CALC(location) calc agriLandExpansion CROP_INCREASE_CALC(location) @@ -146,6 +149,8 @@ $gdxin MIN_FEED_CONSTRAINT .. sum(feed_crop_less_pasture, feedDM(feed_crop_less_pasture) * feedAmount(feed_crop_less_pasture)) =G= minFeedRate * (demand('meat') - netImportAmount('meat')); + IRRIGATION_CONSTRAINT(location) .. irrigConstraint(location) =G= sum(crop, irrigMaxRate(crop, location) * irrigI(crop, location) * area(crop, location)); + AGRI_LAND_EXPANSION_CALC(location) .. agriLandExpansion(location) =G= sum(crop, area(crop, location) - previousArea(crop, location)); CROP_INCREASE_CALC(location) .. cropIncrease(location) =G= sum(crop_less_pasture, area(crop_less_pasture, location) - previousArea(crop_less_pasture, location)); diff --git a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java index c56267a0b374b82ecd9fbdaf6a2fecef4df408b3..3f28357ffb1b9f497b0fb824e5218f1162c165ad 100644 --- a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java +++ b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java @@ -32,12 +32,6 @@ import com.gams.api.GAMSWorkspaceInfo; public class GamsLocationOptimiser { - // DM kg / kg - // cereals 0.86 - // oilcrops 0.90 - // soy 0.89 - // potatoes 0.21 - private static final boolean DEBUG = true; private GamsLocationInput inputData; @@ -89,7 +83,7 @@ public class GamsLocationOptimiser { if (DEBUG) LogWriter.println("\nPrevious crop and land areas"); GAMSParameter prevCropP = inDB.addParameter("previousArea", 2); GAMSParameter landP = inDB.addParameter("suitableLandArea", 1); - + double totalAgriLand = 0; for (Map.Entry<Integer, ? extends LandUseItem> entry : inputData.getPreviousLandUse().entrySet()) { @@ -115,36 +109,46 @@ public class GamsLocationOptimiser { } if (DEBUG) LogWriter.println(String.format(" Total agricultural\t %.1f", totalAgriLand)); - if (DEBUG) LogWriter.println("\nIrrigation cost"); - GAMSParameter irrigCostP = inDB.addParameter("irrigCost", 1); - for (Entry<Integer, ? extends IrrigationItem> entry : inputData.getIrrigationCosts().entrySet()) { + if (DEBUG) LogWriter.println("\nIrrigation data (cost, constraint)"); + GAMSParameter irrigCostP = inDB.addParameter("irrigCost", 1); + GAMSParameter irrigConstraintP = inDB.addParameter("irrigConstraint", 1); + Map<Integer, ? extends IrrigationItem> irrigationData = inputData.getIrrigationCosts(); + + for (Entry<Integer, ? extends IrrigationItem> entry : irrigationData.entrySet()) { Integer locationId = entry.getKey(); IrrigationItem irrigCostItem = entry.getValue(); double irrigCost = irrigCostItem.getIrrigCost(); - if (DEBUG) LogWriter.println(String.format(" %d %15s,\t %.1f", locationId, "irrigCost", irrigCost)); + double irrigConstraint = irrigCostItem.getIrrigConstraint(); + if (DEBUG) LogWriter.println(String.format(" %d \t %.1f,\t %.1f", locationId, irrigCost, irrigConstraint)); irrigCostP.addRecord(Integer.toString(locationId)).setValue(irrigCost); + irrigConstraintP.addRecord(Integer.toString(locationId)).setValue(irrigCost); } if (DEBUG) LogWriter.println("\nDemand"); GamsCountryInput countryInput = inputData.getCountryInput(); addCommodityMapParm(inDB.addParameter("demand", 1), countryInput.getProjectedDemand()); - if (DEBUG) LogWriter.println("\nYield (fert/irrig) None/None, Max/None, None/Max, Max/Max,\t [fert p],\t [irrig p]"); + if (DEBUG) LogWriter.println("\nYield (fert/irrig) None/None, Max/None, None/Max, Max/Max,\t [fert p],\t [irrig p],\t {max irrig}"); GAMSParameter yNoneP = inDB.addParameter("yieldNone", 2); GAMSParameter y_fert = inDB.addParameter("yieldFertOnly", 2); GAMSParameter y_irrig = inDB.addParameter("yieldIrrigOnly", 2); GAMSParameter y_both = inDB.addParameter("yieldBoth", 2); GAMSParameter fert_p = inDB.addParameter("fertParam", 2); GAMSParameter irrig_p = inDB.addParameter("irrigParam", 2); + GAMSParameter irrigMaxP = inDB.addParameter("irrigMaxRate", 2); for (Entry<Integer, ? extends YieldResponsesItem> entry : inputData.getYields().entrySet()) { Integer locationId = entry.getKey(); String locString = Integer.toString(locationId); YieldResponsesItem yresp = entry.getValue(); + IrrigationItem irrigationItem = irrigationData.get(locationId); for (CropType crop : CropType.getNonMeatTypes()) { - if (DEBUG) LogWriter.println(String.format("%d %15s,\t %.1f,\t %.1f, \t %.1f,\t %.1f,\t\t [%.2f],\t [%.2f]", - locationId, crop.getGamsName(), yresp.getYieldNone(crop), yresp.getYieldFertOnly(crop), yresp.getYieldIrrigOnly(crop), yresp.getYieldMax(crop), yresp.getFertParam(crop), yresp.getIrrigParam(crop))); + double maxIrrig = irrigationItem.getMaxIrrigAmount(crop); + + if (DEBUG) LogWriter.println(String.format("%d %15s,\t %.1f,\t %.1f, \t %.1f,\t %.1f,\t\t [%.2f],\t [%.2f],\t {%.1f}", + locationId, crop.getGamsName(), yresp.getYieldNone(crop), yresp.getYieldFertOnly(crop), yresp.getYieldIrrigOnly(crop), yresp.getYieldMax(crop), + yresp.getFertParam(crop), yresp.getIrrigParam(crop), maxIrrig)); Vector<String> v = new Vector<String>(); v.add(crop.getGamsName()); @@ -156,6 +160,7 @@ public class GamsLocationOptimiser { y_both.addRecord(v).setValue(yresp.getYieldMax(crop)); fert_p.addRecord(v).setValue(yresp.getFertParam(crop)); irrig_p.addRecord(v).setValue(yresp.getIrrigParam(crop)); + irrigMaxP.addRecord(v).setValue(maxIrrig); } } diff --git a/src/ac/ed/lurg/landuse/IrrigationItem.java b/src/ac/ed/lurg/landuse/IrrigationItem.java index 5ebcfb9d72892124e28c812b32b35b9915cfd508..1a2d873e14756cfec7eebfd5f0ec91ae3e0013d5 100644 --- a/src/ac/ed/lurg/landuse/IrrigationItem.java +++ b/src/ac/ed/lurg/landuse/IrrigationItem.java @@ -25,7 +25,7 @@ public class IrrigationItem implements RasterItem { public double getMaxIrrigAmount(CropType crop) { Double d = maxIrrigAmounts.get(crop); - return d==null ? Double.NaN : d.doubleValue(); + return d==null ? 0.0 : d.doubleValue(); } public void setMaxIrrigAmount(CropType crop, double maxIrrig) {