From 0239a3784e8f03e478ff9ba919f57bae6a9bfadb Mon Sep 17 00:00:00 2001
From: Peter Alexander <peter@blackhillock.co.uk>
Date: Wed, 17 Dec 2014 12:02:15 +0000
Subject: [PATCH] no message

---
 GAMS/IntExtOpt.gms                            |  6 +--
 src/ac/ed/lurg/ModelMain.java                 | 51 ++++++++++++-------
 src/ac/ed/lurg/country/CountryAgent.java      |  3 +-
 .../country/gams/GamsLocationOptimiser.java   |  9 +++-
 src/ac/ed/lurg/landuse/IntensitiesItem.java   |  2 +-
 src/ac/ed/lurg/landuse/Intensity.java         | 14 ++++-
 src/ac/ed/lurg/types/CropToDoubleMap.java     | 35 +++++++++++++
 7 files changed, 94 insertions(+), 26 deletions(-)
 create mode 100644 src/ac/ed/lurg/types/CropToDoubleMap.java

diff --git a/GAMS/IntExtOpt.gms b/GAMS/IntExtOpt.gms
index 013b3b9c..da6e1984 100644
--- a/GAMS/IntExtOpt.gms
+++ b/GAMS/IntExtOpt.gms
@@ -50,7 +50,7 @@ $gdxin
        feedAmount(crop)                   amount of feed for each crop - t
        netImportAmount(crop)              export of crop - t
        yield(crop, location)              yield per area for each crop - t per ha
-       unit_energy(crop, location)        energy per area for each crop - energy
+       unitEnergy(crop, location)        energy per area for each crop - energy
        energy                             total input energy - energy;
  
  POSITIVE VARIABLE area, fertI, irrigI, otherIntensity, feedAmount;
@@ -73,7 +73,7 @@ $gdxin
        MIN_FEED_CONSTRAINT                              constraint on min feed rate
        ENERGY_EQ                                        total energy objective function;
  
- UNIT_ENERGY_EQ(crop, location) .. unit_energy(crop, location) =E= power((1+ fertI(crop, location)+irrigI(crop, location)+otherIntensity(crop, location)), 2);
+ UNIT_ENERGY_EQ(crop, location) .. unitEnergy(crop, location) =E= power((1+ fertI(crop, location)+irrigI(crop, location)+otherIntensity(crop, location)), 2);
  
  YIELD_EQ(crop, location) .. yield(crop, location) =E= (
                yieldNone(crop, location) + 
@@ -118,7 +118,7 @@ $gdxin
  
  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, location), area(crop, location) * unit_energy(crop, location))
+ ENERGY_EQ .. energy =E= (SUM((crop, location), area(crop, location) * unitEnergy(crop, location))
             + sum(location, sum(crop, area(crop, location)) - sum(crop, previous_area(crop, location)) * landChangeEnergy)
             + sum(crop, (netImportAmount(crop) * tradeBarrier) * world_input_energy(crop))) / 1000000;
  
diff --git a/src/ac/ed/lurg/ModelMain.java b/src/ac/ed/lurg/ModelMain.java
index bdaa29e8..ae08cb72 100644
--- a/src/ac/ed/lurg/ModelMain.java
+++ b/src/ac/ed/lurg/ModelMain.java
@@ -12,10 +12,15 @@ import ac.ed.lurg.country.Country;
 import ac.ed.lurg.country.CountryAgent;
 import ac.ed.lurg.country.CountryBoundaryItem;
 import ac.ed.lurg.country.CountryBoundaryReader;
+import ac.ed.lurg.country.gams.GamsRasterOutput;
 import ac.ed.lurg.demand.DemandManager;
+import ac.ed.lurg.landuse.AreasItem;
 import ac.ed.lurg.landuse.CommodityData;
+import ac.ed.lurg.landuse.IntensitiesItem;
+import ac.ed.lurg.landuse.Intensity;
 import ac.ed.lurg.landuse.LandCoverItem;
 import ac.ed.lurg.landuse.LandCoverReader;
+import ac.ed.lurg.types.CropToDoubleMap;
 import ac.ed.lurg.types.CropType;
 import ac.ed.lurg.types.LandDataType;
 import ac.ed.lurg.types.ModelFitType;
@@ -31,6 +36,8 @@ public class ModelMain {
 	private Collection<CountryAgent> countryAgents;
 	private Map<Country, List<RasterKey>> countryToKeysMap;
 	private DemandManager demandManager;
+	private Map<CropType, Double> prevWorldInputEnergy;
+
 
 	public static void main(String[] args)  {
 		ModelMain theModel = new ModelMain();
@@ -42,8 +49,9 @@ public class ModelMain {
 	private void setup() {
 		countryToKeysMap = createCountryToKeysMap();
 		demandManager = new DemandManager(ModelFitType.LOGISTIC, ModelConfig.SSP_SCENARIO);
-
 		countryAgents = createCountryAgents();
+		
+		prevWorldInputEnergy = new HashMap<CropType, Double>();  // in first timestep we don't have this info, but ok as constrained to import/export specified amount
 	}
 
 	/* run the model */
@@ -55,29 +63,36 @@ public class ModelMain {
 	private void doTimestep(int timestep) {
 		YieldRaster yieldSurfaces = getYieldSurfaces(timestep);
 		LogWriter.println("Timestep " + timestep);
+		
+		CropToDoubleMap totalArea = new CropToDoubleMap();
+		CropToDoubleMap totalWorldInputEnergy = new CropToDoubleMap();
 
 		for (CountryAgent ca : countryAgents) {
 			LogWriter.println("Country " + ca.getCountry());
 			Collection<RasterKey> countryKeys = countryToKeysMap.get(ca.getCountry());
 
 			YieldRaster countryYieldSurfaces = yieldSurfaces.getSubsetRasterForKeys(countryKeys);
-			ca.determineProduction(timestep, countryYieldSurfaces, getWorldInputEnergy());
+			GamsRasterOutput result = ca.determineProduction(timestep, countryYieldSurfaces, prevWorldInputEnergy);
+			
+			RasterSet<AreasItem> cropAreaR =  result.getCropAreaRaster();
+			RasterSet<IntensitiesItem> intensityR = result.getIntensityRaster();
+			
+			for (Map.Entry<RasterKey, IntensitiesItem> entry : intensityR.entrySet()) {
+				RasterKey key = entry.getKey();
+				AreasItem areas = cropAreaR.get(key);
+				IntensitiesItem intensities= entry.getValue();
+
+				for (CropType crop : CropType.values()) {
+					Double area = areas.getCropArea(crop);
+					Intensity intensity = intensities.getIntensity(crop);
+					
+					totalArea.incrementValue(crop, area);
+					totalWorldInputEnergy.incrementValue(crop, area * intensity.getUnitEnergy());
+				}
+			}
 		}
-
-		// examine global trade balance
-	}
-
-	public Map<CropType, Double> getWorldInputEnergy() {
-		Map<CropType, Double> dummyMap = new HashMap<CropType, Double>();
-		dummyMap.put(CropType.CEREALS, 9.0);
-		dummyMap.put(CropType.FRUIT, 5.0);
-		dummyMap.put(CropType.OILCROPS, 10.0);
-		dummyMap.put(CropType.STARCHY_ROOTS, 5.0);
-		dummyMap.put(CropType.PULSES, 20.0);
-		dummyMap.put(CropType.VEGETABLES, 20.0);
-		dummyMap.put(CropType.MEAT_OR_PASTURE, 80.0);
-		dummyMap.put(CropType.TREENUTS, 5.0);
-		return dummyMap;
+		
+		prevWorldInputEnergy = totalWorldInputEnergy.divideBy(totalArea);
 	}
 
 	public Map<Country, List<RasterKey>> createCountryToKeysMap() {
@@ -145,4 +160,4 @@ public class ModelMain {
 
 		return yieldSurfaces;
 	}
-}
+}
\ No newline at end of file
diff --git a/src/ac/ed/lurg/country/CountryAgent.java b/src/ac/ed/lurg/country/CountryAgent.java
index 87cdf5a5..f2c95fa5 100644
--- a/src/ac/ed/lurg/country/CountryAgent.java
+++ b/src/ac/ed/lurg/country/CountryAgent.java
@@ -67,7 +67,7 @@ public class CountryAgent {
 		return country;
 	}
 
-	public void determineProduction(int timestep, YieldRaster countryYieldSurfaces, Map<CropType, Double> worldInputEnergy) {
+	public GamsRasterOutput determineProduction(int timestep, YieldRaster countryYieldSurfaces, Map<CropType, Double> worldInputEnergy) {
 		currentTimestep = timestep;
 		this.countryYieldSurfaces = countryYieldSurfaces;
 		
@@ -82,6 +82,7 @@ public class CountryAgent {
 		
 		GamsRasterOutput result = opti.run();
 		resultsTimeseries.put(timestep, result);
+		return result;
 	}
 
 	private Map<CropType, Double> getProjectedDemand() {
diff --git a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
index 1c5a2cad..71cf0eb9 100644
--- a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
+++ b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
@@ -135,9 +135,11 @@ public class GamsLocationOptimiser {
 		GAMSVariable varOtherIntensities = outDB.getVariable("otherIntensity");
 		GAMSVariable varFeedAmount = outDB.getVariable("feedAmount");
 		GAMSVariable varNetImports = outDB.getVariable("netImportAmount");
+		GAMSVariable varYields = outDB.getVariable("yield");
+		GAMSVariable varUnitEnergies = outDB.getVariable("unitEnergy");
 
 		double totalArea = 0;
-		double area, fertIntensity, irrigIntensity, otherIntensity, feedAmount, netImport;
+		double area, fertIntensity, irrigIntensity, otherIntensity, feedAmount, netImport, yield, unitEnergy;
 
 		Map<Integer, IntensitiesItem> intensities = new HashMap<Integer, IntensitiesItem>();
 		Map<Integer, AreasItem> cropAreas = new HashMap<Integer, AreasItem>();
@@ -151,6 +153,9 @@ public class GamsLocationOptimiser {
 			fertIntensity = varFertIntensities.findRecord(itemName, locationName).getLevel();
 			irrigIntensity = varIrrigIntensities.findRecord(itemName, locationName).getLevel();
 			otherIntensity = varOtherIntensities.findRecord(itemName, locationName).getLevel();
+			yield = varYields.findRecord(itemName, locationName).getLevel();
+			unitEnergy = varUnitEnergies.findRecord(itemName, locationName).getLevel();
+			
 			int locId = Integer.parseInt(locationName);
 			CropType cropType = CropType.getForGamsName(itemName);
 			
@@ -171,7 +176,7 @@ public class GamsLocationOptimiser {
 					intensityItem = new IntensitiesItem();
 					intensities.put(locId, intensityItem);
 				}
-				intensityItem.setIntensity(cropType, new Intensity(fertIntensity, irrigIntensity, otherIntensity));
+				intensityItem.setIntensity(cropType, new Intensity(fertIntensity, irrigIntensity, otherIntensity, yield, unitEnergy));
 
 				AreasItem areaItem = cropAreas.get(locId);
 				if (areaItem == null) {
diff --git a/src/ac/ed/lurg/landuse/IntensitiesItem.java b/src/ac/ed/lurg/landuse/IntensitiesItem.java
index c7006850..90c21543 100644
--- a/src/ac/ed/lurg/landuse/IntensitiesItem.java
+++ b/src/ac/ed/lurg/landuse/IntensitiesItem.java
@@ -10,7 +10,7 @@ public class IntensitiesItem implements RasterItem {
 
 	Map<CropType, Intensity> intensityMap = new HashMap<CropType, Intensity>();
 	
-	public Intensity getLandUses(CropType crop) {
+	public Intensity getIntensity(CropType crop) {
 		return intensityMap.get(crop);
 	}
 	
diff --git a/src/ac/ed/lurg/landuse/Intensity.java b/src/ac/ed/lurg/landuse/Intensity.java
index daa20a8a..6844daaf 100644
--- a/src/ac/ed/lurg/landuse/Intensity.java
+++ b/src/ac/ed/lurg/landuse/Intensity.java
@@ -4,12 +4,16 @@ public class Intensity {
 	double fertiliserIntensity;
 	double irrigationIntensity;
 	double otherIntensity;
+	double yield;
+	double unitEnergy;
 	
-	public Intensity(double fertiliserIntensity, double irrigationIntensity, double otherIntensity) {
+	public Intensity(double fertiliserIntensity, double irrigationIntensity, double otherIntensity, double yield, double unitEnergy) {
 		super();
 		this.fertiliserIntensity = fertiliserIntensity;
 		this.irrigationIntensity = irrigationIntensity;
 		this.otherIntensity = otherIntensity;
+		this.yield = yield;
+		this.unitEnergy = unitEnergy;
 	}
 
 	public double getFertiliserIntensity() {
@@ -23,4 +27,12 @@ public class Intensity {
 	public double getOtherIntensity() {
 		return otherIntensity;
 	}
+
+	public double getYield() {
+		return yield;
+	}
+
+	public double getUnitEnergy() {
+		return unitEnergy;
+	}
 }
diff --git a/src/ac/ed/lurg/types/CropToDoubleMap.java b/src/ac/ed/lurg/types/CropToDoubleMap.java
new file mode 100644
index 00000000..857d57e9
--- /dev/null
+++ b/src/ac/ed/lurg/types/CropToDoubleMap.java
@@ -0,0 +1,35 @@
+package ac.ed.lurg.types;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class CropToDoubleMap extends HashMap<CropType, Double> {
+
+	private static final long serialVersionUID = -4347578627666847612L;
+
+	public void incrementValue(CropType crop, double inc) {
+		if (containsKey(crop)) {
+			double currentValue = get(crop);
+			put(crop, currentValue + inc);
+		}
+		else {
+			put(crop, inc);
+		}
+	}
+	
+	/** parameter map must have all the keys in instance*/
+	public CropToDoubleMap divideBy(HashMap<CropType, Double> valuesToDivideBy) {
+		CropToDoubleMap result = new CropToDoubleMap();
+		
+		for (Map.Entry<CropType, Double> entry : entrySet()) {
+			CropType crop = entry.getKey();
+			Double divideBy = valuesToDivideBy.get(crop);
+			if (divideBy == null)
+				throw new RuntimeException("CropToDoubleMap.divideBy parameter has no value for " + crop);
+			
+			result.put(crop, entry.getValue()/divideBy);
+		}
+		return result;
+	}
+
+}
-- 
GitLab