Skip to content
Snippets Groups Projects
Commit f089362a authored by Peter Alexander's avatar Peter Alexander
Browse files

Multiple locations per country

parent 1d228865
No related branches found
No related tags found
No related merge requests found
...@@ -3,13 +3,14 @@ ...@@ -3,13 +3,14 @@
SET crop_less_pasture(crop) arable crops types includes treenuts but not pasture / cereals, fruits, oilcrops, starchyRoots, treenuts, vegetables, pulses /; SET crop_less_pasture(crop) arable crops types includes treenuts but not pasture / cereals, fruits, oilcrops, starchyRoots, treenuts, vegetables, pulses /;
SET feed_crop(crop) / cereals, oilcrops /; SET feed_crop(crop) / cereals, oilcrops /;
SET not_feed_crops(crop) / fruits, starchyRoots, treenuts, vegetables, pulses, pasture_or_meat /; SET not_feed_crops(crop) / fruits, starchyRoots, treenuts, vegetables, pulses, pasture_or_meat /;
SET location / 1*2 /;
PARAMETER previous_area(crop) areas for previous timestep in ha; PARAMETER previous_area(crop, location) areas for previous timestep in ha;
PARAMETER demand(crop) yield in t per ha; PARAMETER yield00(crop, location) yield in t per ha;
PARAMETER yield00(crop) yield in t per ha; PARAMETER yield10(crop, location) yield in t per ha;
PARAMETER yield10(crop) yield in t per ha; PARAMETER yield01(crop, location) yield in t per ha;
PARAMETER yield01(crop) yield in t per ha; PARAMETER yield11(crop, location) yield in t per ha;
PARAMETER yield11(crop) yield in t per ha; PARAMETER demand(crop) in t;
PARAMETER world_input_energy(crop) average input energy from world exports used to determine if we should import or export; PARAMETER world_input_energy(crop) average input energy from world exports used to determine if we should import or export;
PARAMETER maxNetImport(crop) maximum net import for each crop based on world market; PARAMETER maxNetImport(crop) maximum net import for each crop based on world market;
PARAMETER minNetImport(crop) minimum net import for each crop based on world market; PARAMETER minNetImport(crop) minimum net import for each crop based on world market;
...@@ -23,9 +24,9 @@ ...@@ -23,9 +24,9 @@
$gdxin %gdxincname% $gdxin %gdxincname%
$load previous_area, demand, yield00, yield10, yield01, yield11, world_input_energy, maxNetImport, minNetImport, meatEfficency, maxLandUseChange, tradeBarrier, landChangeEnergy, minFeedRate $load previous_area, demand, yield00, yield10, yield01, yield11, world_input_energy, maxNetImport, minNetImport, meatEfficency, maxLandUseChange, tradeBarrier, landChangeEnergy, minFeedRate
$gdxin $gdxin
DISPLAY landChangeEnergy DISPLAY yield00, yield10, yield01, yield11
PARAMETER feedEnergy(crop) energy from feed in MJ per t PARAMETER feedEnergy(crop) energy from feed in MJ per t
/ cereals 13.7 / cereals 13.7
oilcrops 18.6 oilcrops 18.6
...@@ -37,58 +38,59 @@ $gdxin ...@@ -37,58 +38,59 @@ $gdxin
pasture_or_meat 1.0 / ; pasture_or_meat 1.0 / ;
VARIABLES VARIABLES
area(crop) total area for each crop - ha area(crop, location) total area for each crop - ha
fertI(crop, location) fertilizer intensity for each crop - factor between 0 and 1
irrigI(crop, location) irrigation intensity for each crop - factor between 0 and 1
otherIntensity(crop, location) other intensity for each crop - unit less
feedAmount(crop) amount of feed for each crop - t feedAmount(crop) amount of feed for each crop - t
fertI(crop) fertilizer intensity for each crop - factor between 0 and 1
irrigI(crop) irrigation intensity for each crop - factor between 0 and 1
otherIntensity(crop) other intensity for each crop - unit less
netImportAmount(crop) export of crop - t netImportAmount(crop) export of crop - t
yield(crop) yield per area for each crop - t per ha yield(crop, location) yield per area for each crop - t per ha
unit_energy(crop) energy per area for each crop - energy unit_energy(crop, location) energy per area for each crop - energy
energy total input energy - energy; energy total input energy - energy;
POSITIVE VARIABLE area, fertI, irrigI, otherI, feedAmount; POSITIVE VARIABLE area, fertI, irrigI, otherI, feedAmount;
EQUATIONS EQUATIONS
UNIT_ENERGY_EQ(crop) energy per area UNIT_ENERGY_EQ(crop, location) energy per area
YIELD_EQ(crop) yield given chosen intensity YIELD_EQ(crop, location) yield given chosen intensity
CROP_DEMAND_CONSTRAINT(crop_less_pasture) satisfy demand for crop CROP_DEMAND_CONSTRAINT(crop_less_pasture) satisfy demand for crop
MEAT_DEMAND_CONSTRAINT satisfy demand for crop MEAT_DEMAND_CONSTRAINT satisfy demand for crop
MAX_FERT_INTENSITY_CONSTRAINT(crop) constraint on maximum fertilizer intensity MAX_FERT_INTENSITY_CONSTRAINT(crop, location) constraint on maximum fertilizer intensity
MAX_IRRIG_INTENSITY_CONSTRAINT(crop) constraint on maximum irrigation intensity MAX_IRRIG_INTENSITY_CONSTRAINT(crop, location) constraint on maximum irrigation intensity
CROPLAND_CHANGE_CONSTRAINT constraint on the rate of land use change CROPLAND_CHANGE_CONSTRAINT(location) constraint on the rate of land use change
PASTURE_CHANGE_CONSTRAINT constraint on the rate of land use change PASTURE_CHANGE_CONSTRAINT(location) constraint on the rate of land use change
AGRI_LAND_CHANGE_CONSTRAINT constraint expansion of agricultural land AGRI_LAND_CHANGE_CONSTRAINT(location) constraint expansion of agricultural land
NON_FEED_CROP_CONSTRAINT(not_feed_crops) constraint to set non feed crop feed usage to zero NON_FEED_CROP_CONSTRAINT(not_feed_crops) constraint to set non feed crop feed usage to zero
MAX_NET_IMPORT_CONSTRAINT(crop) constraint on max net imports MAX_NET_IMPORT_CONSTRAINT(crop) constraint on max net imports
MIN_NET_IMPORT_CONSTRAINT(crop) constraint on min net imports MIN_NET_IMPORT_CONSTRAINT(crop) constraint on min net imports
MIN_FEED_CONSTRAINT constraint on min feed rate MIN_FEED_CONSTRAINT constraint on min feed rate
ENERGY_EQ total energy objective function; ENERGY_EQ total energy objective function;
UNIT_ENERGY_EQ(crop) .. unit_energy(crop) =E= (fertI(crop)+irrigI(crop)+otherIntensity(crop)) + sqr(fertI(crop)+irrigI(crop)+otherIntensity(crop)) / 8; UNIT_ENERGY_EQ(crop, location) .. unit_energy(crop, location) =E= fertI(crop, location)+irrigI(crop, location)+otherIntensity(crop, location) +
sqr(fertI(crop, location)+irrigI(crop, location)+otherIntensity(crop, location)) / 2;
YIELD_EQ(crop) .. yield(crop) =E= ( YIELD_EQ(crop, location) .. yield(crop, location) =E= (
yield00(crop)*(1-fertI(crop))*(1-irrigI(crop)) + yield00(crop, location)*(1-fertI(crop, location))*(1-irrigI(crop, location)) +
yield10(crop)*fertI(crop)*(1-irrigI(crop)) + yield10(crop, location)*fertI(crop, location)*(1-irrigI(crop, location)) +
yield01(crop)*(1-fertI(crop))*irrigI(crop) + yield01(crop, location)*(1-fertI(crop, location))*irrigI(crop, location) +
yield11(crop)*fertI(crop)*irrigI(crop) yield11(crop, location)*fertI(crop, location)*irrigI(crop, location)
) * otherIntensity(crop); ) * otherIntensity(crop, location);
CROP_DEMAND_CONSTRAINT(crop_less_pasture) .. area(crop_less_pasture) * yield(crop_less_pasture) - feedAmount(crop_less_pasture) =G= CROP_DEMAND_CONSTRAINT(crop_less_pasture) .. sum(location, area(crop_less_pasture, location) * yield(crop_less_pasture, location)) - feedAmount(crop_less_pasture) =G=
demand(crop_less_pasture) - netImportAmount(crop_less_pasture); demand(crop_less_pasture) - netImportAmount(crop_less_pasture);
MEAT_DEMAND_CONSTRAINT .. meatEfficency*sum(feed_crop, feedDM(feed_crop) * feedAmount(feed_crop)) + feedDM('pasture_or_meat') * area('pasture_or_meat') * yield('pasture_or_meat') =G= MEAT_DEMAND_CONSTRAINT .. meatEfficency*sum(feed_crop, feedDM(feed_crop) * feedAmount(feed_crop)) + feedDM('pasture_or_meat') * sum(location, area('pasture_or_meat', location) * yield('pasture_or_meat', location)) =G=
demand('pasture_or_meat') - netImportAmount('pasture_or_meat'); demand('pasture_or_meat') - netImportAmount('pasture_or_meat');
MAX_FERT_INTENSITY_CONSTRAINT(crop) .. fertI(crop) =L= 1; MAX_FERT_INTENSITY_CONSTRAINT(crop, location) .. fertI(crop, location) =L= 1;
MAX_IRRIG_INTENSITY_CONSTRAINT(crop) .. irrigI(crop) =L= 1; MAX_IRRIG_INTENSITY_CONSTRAINT(crop, location) .. irrigI(crop, location) =L= 1;
CROPLAND_CHANGE_CONSTRAINT .. 1 - sum(crop_less_pasture, area(crop_less_pasture))/sum(crop_less_pasture, previous_area(crop_less_pasture)) =L= maxLandUseChange; CROPLAND_CHANGE_CONSTRAINT(location) .. 1 - sum(crop_less_pasture, area(crop_less_pasture, location))/sum(crop_less_pasture, previous_area(crop_less_pasture, location)) =L= maxLandUseChange;
PASTURE_CHANGE_CONSTRAINT .. 1 - area('pasture_or_meat')/previous_area('pasture_or_meat') =L= maxLandUseChange; PASTURE_CHANGE_CONSTRAINT(location) .. 1 - area('pasture_or_meat', location)/previous_area('pasture_or_meat', location) =L= maxLandUseChange;
AGRI_LAND_CHANGE_CONSTRAINT .. abs(sum(crop, area(crop)) / sum(crop, previous_area(crop)) - 1) =L= maxLandUseChange; AGRI_LAND_CHANGE_CONSTRAINT(location) .. abs(sum(crop, area(crop, location)) / sum(crop, previous_area(crop, location)) - 1) =L= maxLandUseChange;
NON_FEED_CROP_CONSTRAINT(not_feed_crops) .. feedAmount(not_feed_crops) =E= 0; NON_FEED_CROP_CONSTRAINT(not_feed_crops) .. feedAmount(not_feed_crops) =E= 0;
...@@ -98,13 +100,15 @@ $gdxin ...@@ -98,13 +100,15 @@ $gdxin
MIN_FEED_CONSTRAINT .. sum(feed_crop, feedDM(feed_crop) * feedAmount(feed_crop)) =G= minFeedRate * (demand('pasture_or_meat') - netImportAmount('pasture_or_meat')); MIN_FEED_CONSTRAINT .. sum(feed_crop, feedDM(feed_crop) * feedAmount(feed_crop)) =G= minFeedRate * (demand('pasture_or_meat') - netImportAmount('pasture_or_meat'));
ENERGY_EQ .. energy =E= SUM(crop, area(crop)*unit_energy(crop)) ENERGY_EQ .. energy =E= SUM((crop, location), area(crop, location)*unit_energy(crop, location))
+ (sum(crop, area(crop)) - sum(crop, previous_area(crop))) * landChangeEnergy + sum(location, sum(crop, area(crop, location)) - sum(crop, previous_area(crop, location)) * landChangeEnergy)
+ sum(crop, (netImportAmount(crop) * tradeBarrier) * world_input_energy(crop)); + sum(crop, (netImportAmount(crop) * tradeBarrier) * world_input_energy(crop));
MODEL LAND_USE /ALL/ ; MODEL LAND_USE /ALL/ ;
SOLVE LAND_USE USING DNLP MINIMIZING energy; SOLVE LAND_USE USING DNLP MINIMIZING energy;
DISPLAY yield00, yield10, yield01, yield11
Scalar ms 'model status', ss 'solve status'; Scalar ms 'model status', ss 'solve status';
ms=LAND_USE.modelstat; ms=LAND_USE.modelstat;
ss=LAND_USE.solvestat; ss=LAND_USE.solvestat;
...@@ -2,6 +2,7 @@ package ac.ed.lurg.country.gams; ...@@ -2,6 +2,7 @@ package ac.ed.lurg.country.gams;
import java.io.File; import java.io.File;
import java.util.Map; import java.util.Map;
import java.util.Vector;
import ac.ed.lurg.ModelConfig; import ac.ed.lurg.ModelConfig;
import ac.ed.lurg.country.CropAreas; import ac.ed.lurg.country.CropAreas;
...@@ -39,28 +40,33 @@ public class GamsLandUseOptimiser { ...@@ -39,28 +40,33 @@ public class GamsLandUseOptimiser {
GAMSDatabase db = ws.addDatabase(); GAMSDatabase db = ws.addDatabase();
LogWriter.println("\nPrevious areas"); LogWriter.println("\nPrevious areas");
GAMSParameter parm = db.addParameter("previous_area", 1, "the previous area for each land use"); GAMSParameter parm = db.addParameter("previous_area", 2, "the previous area for each land use");
addItemMapParm(parm, inputData.getPreviousCropArea()); addLocationMapParm(parm, inputData.getPreviousCropArea(), "1");
addLocationMapParm(parm, inputData.getPreviousCropArea(), "2");
LogWriter.println("\nDemand"); LogWriter.println("\nDemand");
parm = db.addParameter("demand", 1, "demand for crop"); parm = db.addParameter("demand", 1, "demand for crop");
addItemMapParm(parm, inputData.getProjectedDemand()); addItemMapParm(parm, inputData.getProjectedDemand());
LogWriter.println("\nYield"); LogWriter.println("\nYield");
parm = db.addParameter("yield00", 1, "ref yield t per ha"); parm = db.addParameter("yield00", 2, "ref yield t per ha");
addItemMapParm(parm, inputData.getRefYield()); addLocationMapParm(parm, inputData.getRefYield(), "1");
addLocationMapParm(parm, inputData.getRefYield(), "2");
LogWriter.println("\nYield"); LogWriter.println("\nYield");
parm = db.addParameter("yield10", 1, "ref yield t per ha"); parm = db.addParameter("yield10", 2, "ref yield t per ha");
addItemMapParm(parm, inputData.getRefYield()); addLocationMapParm(parm, inputData.getRefYield(), "1");
addLocationMapParm(parm, inputData.getRefYield(), "2");
LogWriter.println("\nYield"); LogWriter.println("\nYield");
parm = db.addParameter("yield01", 1, "ref yield t per ha"); parm = db.addParameter("yield01", 2, "ref yield t per ha");
addItemMapParm(parm, inputData.getRefYield()); addLocationMapParm(parm, inputData.getRefYield(), "1");
addLocationMapParm(parm, inputData.getRefYield(), "2");
LogWriter.println("\nYield"); LogWriter.println("\nYield");
parm = db.addParameter("yield11", 1, "ref yield t per ha"); parm = db.addParameter("yield11", 2, "ref yield t per ha");
addItemMapParm(parm, inputData.getRefYield()); addLocationMapParm(parm, inputData.getRefYield(), "1");
addLocationMapParm(parm, inputData.getRefYield(), "2");
LogWriter.println("\nWorld input energy"); LogWriter.println("\nWorld input energy");
parm = db.addParameter("world_input_energy", 1, "average input energy from world exports used to determine if we should import or export energy per t"); parm = db.addParameter("world_input_energy", 1, "average input energy from world exports used to determine if we should import or export energy per t");
...@@ -102,16 +108,17 @@ public class GamsLandUseOptimiser { ...@@ -102,16 +108,17 @@ public class GamsLandUseOptimiser {
for (GAMSVariableRecord rec : varAreas) { for (GAMSVariableRecord rec : varAreas) {
String itemName = rec.getKeys()[0]; String itemName = rec.getKeys()[0];
String locationName = rec.getKeys()[1];
area = rec.getLevel(); area = rec.getLevel();
fertIntensity = varFertIntensities.findRecord(itemName).getLevel(); fertIntensity = varFertIntensities.findRecord(itemName, locationName).getLevel();
irrigIntensity = varIrrigIntensities.findRecord(itemName).getLevel(); irrigIntensity = varIrrigIntensities.findRecord(itemName, locationName).getLevel();
otherIntensity = varOtherIntensities.findRecord(itemName).getLevel(); otherIntensity = varOtherIntensities.findRecord(itemName, locationName).getLevel();
feedAmount = varFeedAmount.findRecord(itemName).getLevel(); feedAmount = varFeedAmount.findRecord(itemName).getLevel();
netImports = varNetImports.findRecord(itemName).getLevel(); netImports = varNetImports.findRecord(itemName).getLevel();
totalArea += rec.getLevel(); totalArea += rec.getLevel();
LogWriter.println(String.format("%15s:\tarea= %.1f,\tfert= %.3f,\tirrg= %.3f,\tintensity= %.3f,\tfeedAmount= %.0f,\tnetImports= %.0f", LogWriter.println(String.format("%15s, l%s:\tarea= %.1f,\tfert= %.3f,\tirrg= %.3f,\tintensity= %.3f,\tfeedAmount= %.0f,\tnetImports= %.0f",
itemName, area, fertIntensity, irrigIntensity, otherIntensity, feedAmount, netImports)); itemName, locationName, area, fertIntensity, irrigIntensity, otherIntensity, feedAmount, netImports));
output.addCropArea(CropType.getForGamsName(itemName), area, otherIntensity, feedAmount, netImports); output.addCropArea(CropType.getForGamsName(itemName), area, otherIntensity, feedAmount, netImports);
} }
...@@ -132,6 +139,20 @@ public class GamsLandUseOptimiser { ...@@ -132,6 +139,20 @@ public class GamsLandUseOptimiser {
} }
} }
private void addLocationMapParm(GAMSParameter parm, Map<CropType, Double> itemMap, String locationId) {
for (Map.Entry<CropType, Double> entry : itemMap.entrySet()) {
LogWriter.println(String.format(" %15s,\t %.1f", entry.getKey().getGamsName(), entry.getValue()));
Vector<String> v = new Vector<String>();
v.add(entry.getKey().getGamsName());
v.add(locationId);
if (locationId.equals("2") & entry.getKey().getGamsName().equals("cereals"))
parm.addRecord(v).setValue(0.99);
else
parm.addRecord(v).setValue(entry.getValue());
}
}
@SuppressWarnings("unused") @SuppressWarnings("unused")
private void cleanup(String directory) { private void cleanup(String directory) {
File directoryToDelete = new File(directory); File directoryToDelete = new File(directory);
......
...@@ -23,13 +23,13 @@ public class GamsTest implements GamsInputData { ...@@ -23,13 +23,13 @@ public class GamsTest implements GamsInputData {
@Override @Override
public Map<CropType, Double> getProjectedDemand() { public Map<CropType, Double> getProjectedDemand() {
Map<CropType, Double> dummyMap = new HashMap<CropType, Double>(); Map<CropType, Double> dummyMap = new HashMap<CropType, Double>();
dummyMap.put(CropType.CEREALS, 390.0); dummyMap.put(CropType.CEREALS, 290.0);
dummyMap.put(CropType.FRUIT, 50.0); dummyMap.put(CropType.FRUIT, 50.0);
dummyMap.put(CropType.OILCROPS, 100.0); dummyMap.put(CropType.OILCROPS, 100.0);
dummyMap.put(CropType.STARCHY_ROOTS, 50.0); dummyMap.put(CropType.STARCHY_ROOTS, 50.0);
dummyMap.put(CropType.PULSES, 60.0); dummyMap.put(CropType.PULSES, 60.0);
dummyMap.put(CropType.VEGETABLES, 20.0); dummyMap.put(CropType.VEGETABLES, 20.0);
dummyMap.put(CropType.MEAT_OR_PASTURE, 800.0); dummyMap.put(CropType.MEAT_OR_PASTURE, 80.0);
dummyMap.put(CropType.TREENUTS, 5.0); dummyMap.put(CropType.TREENUTS, 5.0);
return dummyMap; return dummyMap;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment