From 479ee663715b0ff6829ff7c68785d5ccaa8d43ec Mon Sep 17 00:00:00 2001
From: Peter Alexander <peter@blackhillock.co.uk>
Date: Mon, 4 Jul 2016 16:10:10 +0100
Subject: [PATCH] Remove hardcode parameters from GAMS code

---
 GAMS/IntExtOpt.gms                            | 21 +++++++++-----
 src/ac/ed/lurg/ModelConfig.java               |  9 +++++-
 .../country/gams/GamsLocationOptimiser.java   | 29 +++++++++----------
 3 files changed, 34 insertions(+), 25 deletions(-)

diff --git a/GAMS/IntExtOpt.gms b/GAMS/IntExtOpt.gms
index fe074b39..9ba87c32 100644
--- a/GAMS/IntExtOpt.gms
+++ b/GAMS/IntExtOpt.gms
@@ -32,20 +32,22 @@
  SCALAR landChangeEnergy                     energy required to add ha of agricultural land;
  SCALAR minFeedRate                          minimum rate of feed for producing animal products (why is this needed?);
  SCALAR fertiliserUnitCost                   fert cost at max fert rate;
+ SCALAR otherIParam                          yield response to other intensity;
+ SCALAR otherICost                           cost of other intensity;
+ SCALAR unhandledCropArea                    includes fruit veg forage crops set aside and failed crop;
 
 *$gdxin "/Users/peteralexander/Documents/R_Workspace/temp/GamsTest/_gams_java_1091455539.gdx"
 $gdxin %gdxincname% 
 $load location, suitableLandArea, previousArea, demand, landChangeEnergy
 $load yieldNone, yieldFertOnly, yieldIrrigOnly, yieldBoth
-$load fertParam, irrigParam, worldExportPrices, worldImportPrices, maxNetImport, minNetImport
-$load meatEfficency, minFeedRate, irrigCost, irrigMaxRate, irrigConstraint, cropAdj, fertiliserUnitCost
+$load fertParam, irrigParam, otherIParam, worldExportPrices, worldImportPrices, maxNetImport, minNetImport, unhandledCropArea
+$load meatEfficency, minFeedRate, otherICost, irrigCost, irrigMaxRate, irrigConstraint, cropAdj, fertiliserUnitCost
 $gdxin    
  
  SCALAR delta use to smooth power function see 7.5 www.gams.com dd docs solversconopt.pdf / 0.00000000001 /  
      
  SCALAR minDemandPerCereal / 0.1 /;
  
- SCALAR unhandledCropArea includes fruit veg forage crops set aside and failed crop / 0.4 /;
  previousArea(crop_less_pasture, location) = previousArea(crop_less_pasture, location) * (1.0 - unhandledCropArea);
  
  PARAMETER cropDM(crop)  kg DM per kg of feed the conversion from feed to meat is done in the R animal product index
@@ -116,7 +118,7 @@ $gdxin
  UNIT_ENERGY_EQ(crop, location) .. unitEnergy(crop, location) =E=  ( baseCost(crop) +              
                                                                      fertiliserUnitCost * fertI(crop, location) + 
                                                                      irrigCost(location) * irrigMaxRate(crop, location) * irrigI(crop, location) +
-                                                                     otherIntensity(crop, location)
+                                                                     otherICost * otherIntensity(crop, location)
                                                                      ) ;
  
  YIELD_EQ(crop, location) .. yield(crop, location) =E= (
@@ -131,7 +133,7 @@ $gdxin
                (yieldBoth(crop, location) + yieldNone(crop, location) - yieldFertOnly(crop, location) - yieldIrrigOnly(crop, location)) *
                                       (1 - exp(-fertParam(crop, location)*fertI(crop, location))) * (1 - exp(-irrigParam(crop, location)*irrigI(crop, location)))
 
-            ) * cropAdj(crop) * (1 - exp(-otherIntensity(crop, location)*4));
+            ) * cropAdj(crop) * (1 - exp(-otherIntensity(crop, location)*otherIParam));
    
  NET_SUPPLY_EQ(crop) .. net_supply(crop) =E= (sum(location, area(crop, location) * yield(crop, location)) - feedAmount(crop)) / cropDM(crop) + importAmount(crop) - exportAmount(crop);
   
@@ -193,11 +195,10 @@ $gdxin
  area.L(crop, location) = previousArea(crop, location)
  SOLVE LAND_USE USING NLP MINIMIZING energy;
       
+* display agriLandExpansion.l, previousArea, area.l, net_supply.l, demand, feedAmount.l, yield.l, importAmount.l, exportAmount.l;
 
- display agriLandExpansion.l, previousArea, area.l, net_supply.l, demand, feedAmount.l, yield.l, importAmount.l, exportAmount.l;
 
- area.l(crop_less_pasture, location) = area.l(crop_less_pasture, location) / (1.0 - unhandledCropArea);
- 
+* Calculate summary information used in Java process 
  parameter totalProd(all_types);
  parameter totalProdCost(all_types);
  parameter totalCropland(location);
@@ -205,8 +206,12 @@ $gdxin
  parameter netImportEnergy(all_types);
  parameter feedEnergy(all_types);
  
+* Production quantities based on smaller area (before unhandledCropArea adjustment applied)
  totalProd(crop) = sum(location, area.l(crop, location) * yield.l(crop, location));
  totalProd('meat') = meatEfficency*sum(feed_crop, feedAmount.l(feed_crop));
+  
+* Cost based on adjusted area
+ area.l(crop_less_pasture, location) = area.l(crop_less_pasture, location) / (1.0 - unhandledCropArea);
  totalProdCost(crop) = sum(location, unitEnergy.l(crop, location) * area.l(crop, location));
  totalCropland(location) = sum(crop_less_pasture, area.l(crop_less_pasture, location));
  
diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java
index 7bd58e23..12d53d9e 100644
--- a/src/ac/ed/lurg/ModelConfig.java
+++ b/src/ac/ed/lurg/ModelConfig.java
@@ -148,11 +148,18 @@ public class ModelConfig {
 	public static final double MARKET_LAMBA = getDoubleProperty("MARKET_LAMBA", 0.3); // controls international market price adjustment rate
 	public static final double POPULATION_AGGREG_LIMIT = getDoubleProperty("POPULATION_AGGREG_LIMIT", 40.0);  // in millions, smaller countries are aggregated on a regional basis
 	
+	public static final double UNHANDLED_CROP_AREA = getDoubleProperty("UNHANDLED_CROP_AREA", 0.4);
+
+	public static final double OTHER_INTENSITY_COST = getDoubleProperty("OTHER_INTENSITY_COST", 0.5);
+	public static final double OTHER_INTENSITY_PARAM = getDoubleProperty("OTHER_INTENSITY_PARAM", 5.0);
+
 	public static final double IRRIG_COST_SCALE_FACTOR = getDoubleProperty("IRRIG_COST_SCALE_FACTOR", 0.01);
 	public static final double FERTILISER_COST_PER_T = getDoubleProperty("FERTILISER_COST_PER_T", 0.87 * 1.4 * 2); // £900/t N *  1.4$/£ * 2NPK/N
 	public static final double FERTILISER_MAX_COST = FERTILISER_COST_PER_T * MAX_FERT_AMOUNT/1000;
+	
+	public static final double DOMESTIC_LOSSES = getDoubleProperty("DOMESTIC_LOSSES", 0.1);  // in international trade
 	public static final double TRANSPORT_LOSSES = getDoubleProperty("TRANSPORT_LOSSES", 0.15);  // in international trade
-	public static final double TRADE_BARRIER_FACTOR = getDoubleProperty("TRADE_BARRIER_FACTOR", 1.3);  // price factor in international trade, transport cost and real trade barriers
+	public static final double TRADE_BARRIER_FACTOR = getDoubleProperty("TRADE_BARRIER_FACTOR", 1.5);  // price factor in international trade, transport cost and real trade barriers
 
 	public static final int NUM_CEREAL_CATEGORIES = getIntProperty("NUM_CEREAL_CATEGORIES", 5);
 	public static final int NUM_PASTURE_CATEGORIES = getIntProperty("NUM_PASTURE_CATEGORIES", 1);
diff --git a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
index f2049682..85f26bb3 100644
--- a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
+++ b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
@@ -188,23 +188,24 @@ public class GamsLocationOptimiser {
 		addItemMapParm(inDB.addParameter("worldImportPrices", 1), countryInput.getWorldImportPrices(), false);
 		addItemMapParm(inDB.addParameter("worldExportPrices", 1), countryInput.getWorldExportPrices(), false);
 
-		addScalar(inDB.addParameter("meatEfficency", 0), countryInput.getMeatEfficiency());
-		if (DEBUG) LogWriter.println("\nMeatEfficiency: " + countryInput.getMeatEfficiency());
+		addScalar(inDB, "meatEfficency", countryInput.getMeatEfficiency());		
+		addScalar(inDB, "fertiliserUnitCost", ModelConfig.FERTILISER_MAX_COST);
+		addScalar(inDB, "otherICost",ModelConfig.OTHER_INTENSITY_COST);
+		addScalar(inDB, "otherIParam", ModelConfig.OTHER_INTENSITY_PARAM);
+		addScalar(inDB, "landChangeEnergy", countryInput.getLandChangeEnergy());
+		addScalar(inDB, "minFeedRate", countryInput.getMinFeedRate());
+		addScalar(inDB, "unhandledCropArea", ModelConfig.UNHANDLED_CROP_AREA);
 		
-		addScalar(inDB.addParameter("fertiliserUnitCost", 0), ModelConfig.FERTILISER_MAX_COST);
-		if (DEBUG) LogWriter.println("\nFertiliserUnitCost: " + ModelConfig.FERTILISER_MAX_COST);
-		
-		
-		addScalar(inDB.addParameter("landChangeEnergy", 0), countryInput.getLandChangeEnergy());
-		if (DEBUG) LogWriter.println("\nLandChangeEnergy: " + countryInput.getLandChangeEnergy());
-
-		addScalar(inDB.addParameter("minFeedRate", 0), countryInput.getMinFeedRate());
-		if (DEBUG) LogWriter.println("\nMinFeedRate: " + countryInput.getMinFeedRate());
-
 		if (DEBUG) LogWriter.println("\ncropAdj");
 		addItemMapParm(inDB.addParameter("cropAdj", 1), countryInput.getCropAdjustments(), DEBUG);
 	}
 
+	private void addScalar(GAMSDatabase gamsDb, String recordName, double val) {
+		GAMSParameter param = gamsDb.addParameter(recordName, 0);
+		param.addRecord().setValue(val);
+		if (DEBUG) LogWriter.println("\n" + recordName + ": " + val);
+	}
+	
 	private void setPreviousArea(GAMSParameter prevCropP, String locString, String cropTypeString, double d) {
 		Vector<String> v = new Vector<String>();
 		v.add(cropTypeString);
@@ -318,10 +319,6 @@ public class GamsLocationOptimiser {
 		}
 	}
 
-	private void addScalar(GAMSParameter param, double val) {
-		param.addRecord().setValue(val);
-	}
-
 	private void addItemMapParm(GAMSParameter parm, Map<CropType, Double> itemMap, boolean printOutput) {
 		for (Map.Entry<CropType, Double> entry : itemMap.entrySet()) {
 			double d = entry.getValue();
-- 
GitLab