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

Have different import and export prices

parent ebccf28e
No related branches found
No related tags found
No related merge requests found
......@@ -147,8 +147,9 @@ public class ModelConfig {
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 IRRIG_COST_SCALE_FACTOR = getDoubleProperty("IRRIG_COST_SCALE_FACTOR", 2.0);
public static final double TRANSPORT_LOSSES = getDoubleProperty("TRANSPORT_LOSSES", 0.2); // 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.2); // 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);
......
......@@ -15,6 +15,7 @@ import ac.ed.lurg.country.CompositeCountryManager;
import ac.ed.lurg.country.CountryAgent;
import ac.ed.lurg.country.CountryBoundaryRaster;
import ac.ed.lurg.country.CountryBoundaryReader;
import ac.ed.lurg.country.GlobalPrice;
import ac.ed.lurg.country.gams.GamsRasterOutput;
import ac.ed.lurg.demand.BaseConsumpManager;
import ac.ed.lurg.demand.DemandManager;
......@@ -51,7 +52,7 @@ public class ModelMain {
private CompositeCountryManager compositeCountryManager;
private RasterHeaderDetails desiredProjection;
private Map<CropType, Double> prevWorldPrices;
private Map<CropType, GlobalPrice> prevWorldPrices;
private RasterSet<LandUseItem> prevLandUseRaster;
public static void main(String[] args) {
......@@ -72,11 +73,11 @@ public class ModelMain {
countryAgents = createCountryAgents(compositeCountryManager.getAll());
// in first timestep we don't have this info, but ok as constrained to import/export specified amount
prevWorldPrices = new HashMap<CropType, Double>();
prevWorldPrices = new HashMap<CropType, GlobalPrice>();
for (CropType c : CropType.getImportedTypes())
prevWorldPrices.put(c, 0.3);
prevWorldPrices.put(c, GlobalPrice.createInitial(0.3));
prevWorldPrices.put(CropType.STARCHY_ROOTS, 1.4);
prevWorldPrices.put(CropType.STARCHY_ROOTS, GlobalPrice.createInitial(1.2));
}
/* run the model */
......@@ -123,7 +124,6 @@ public class ModelMain {
catch (Exception e) {
LogWriter.printlnError("Exception processing " + ca.getCountry() + " will continue with other countries");
LogWriter.print(e);
System.exit(1);
}
if (result == null) {
......@@ -151,17 +151,17 @@ public class ModelMain {
// Look at trade balance and adjust appropriately
for (CropType crop : CropType.getImportedTypes()) {
double prevPrice = prevWorldPrices.get(crop);
GlobalPrice prevPrice = prevWorldPrices.get(crop);
if (!totalImportCommodities.containsKey(crop) || !totalExportCommodities.containsKey(crop)) {
LogWriter.printlnError(String.format("Price for %s not updated (still %.3f), as no imports or no exports for it", crop.getGamsName(), prevPrice));
LogWriter.printlnError(String.format("Price for %s not updated (still %s), as no imports or no exports for it", crop.getGamsName(), prevPrice));
continue;
}
double imports = totalImportCommodities.get(crop);
double exports = totalExportCommodities.get(crop) * (1.0-ModelConfig.TRANSPORT_LOSSES);
double adjustedPrice = updateMarketPrices(prevPrice, imports, exports);
LogWriter.println(String.format("Price for %s updated from %.3f (imports %.0f, exports %.0f) to %.3f ", crop.getGamsName(), prevPrice, imports, exports, adjustedPrice));
GlobalPrice adjustedPrice = prevPrice.updateMarketPrices(imports, exports);
LogWriter.println(String.format("Price for %s updated from %s (imports amount %.0f, exports amount %.0f) to %s ", crop.getGamsName(), prevPrice, imports, exports, adjustedPrice));
prevWorldPrices.put(crop, adjustedPrice);
}
......@@ -173,22 +173,6 @@ public class ModelMain {
prevLandUseRaster = globalLandUseRaster;
}
public double updateMarketPrices(double previousPrice, double demand, double supply) {
if (demand > 0 || supply > 0) {
double ratio;
if (demand > supply)
ratio = (demand-supply)/demand;
else
ratio = (demand-supply)/supply;
double adjustment = Math.exp(ratio * ModelConfig.MARKET_LAMBA);
return previousPrice * adjustment;
}
else {
return previousPrice;
}
}
private BufferedWriter getFileWriter(Timestep timestep, String file, String columnHeadings) throws IOException {
if (timestep.isInitialTimestep()) {
......
......@@ -62,7 +62,7 @@ public class CountryAgent {
return country;
}
public GamsRasterOutput determineProduction(Timestep timestep, YieldRaster countryYieldSurfaces, Map<CropType, Double> worldInputPrices) {
public GamsRasterOutput determineProduction(Timestep timestep, YieldRaster countryYieldSurfaces, Map<CropType, GlobalPrice> worldPrices) {
currentTimestep = timestep;
this.countryYieldSurfaces = countryYieldSurfaces;
......@@ -77,7 +77,7 @@ public class CountryAgent {
}
else {
// optimize areas and intensity
GamsRasterInput input = getGamsRasterInput(projectedDemand, worldInputPrices);
GamsRasterInput input = getGamsRasterInput(projectedDemand, worldPrices);
GamsRasterOptimiser opti = new GamsRasterOptimiser(input);
LogWriter.println("Running " + country.getName() + ", currentTimestep " + currentTimestep);
......@@ -89,7 +89,7 @@ public class CountryAgent {
return null;
}
private GamsRasterInput getGamsRasterInput(Map<CommodityType, Double> projectedDemand, Map<CropType, Double> worldInputPrices) {
private GamsRasterInput getGamsRasterInput(Map<CommodityType, Double> projectedDemand, Map<CropType, GlobalPrice> worldPrices) {
GamsRasterOutput prevOutput;
Map<CropType, Double> cropAdjs;
......@@ -116,7 +116,7 @@ public class CountryAgent {
maxOfProdOrSupply.put(entry.getKey(), cropUsage.getProduction() + Math.max(netImports, 0));
}
GamsCountryInput countryLevelInputs = GamsCountryInput.createInput(country, projectedDemand, worldInputPrices, baseNetImport, maxOfProdOrSupply, cropAdjs, calibrate);
GamsCountryInput countryLevelInputs = GamsCountryInput.createInput(country, projectedDemand, worldPrices, baseNetImport, maxOfProdOrSupply, cropAdjs, calibrate);
GamsRasterInput input = new GamsRasterInput(currentTimestep, countryYieldSurfaces, prevOutput.getLandUses(), irrigationCostRaster, countryLevelInputs);
return input;
......
package ac.ed.lurg.country;
import ac.ed.lurg.ModelConfig;
public class GlobalPrice {
double importPrice;
double exportPrice;
public GlobalPrice(double importPrice, double exportPrice) {
this.importPrice = importPrice;
this.exportPrice = exportPrice;
}
public static GlobalPrice createInitial(double exportPrice) {
return new GlobalPrice(exportPrice * ModelConfig.TRADE_BARRIER_FACTOR / (1-ModelConfig.TRANSPORT_LOSSES), exportPrice);
}
public double getImportPrice() {
return importPrice;
}
public double getExportPrice() {
return exportPrice;
}
public GlobalPrice updateMarketPrices(double demand, double supply) {
if (demand > 0 || supply > 0) {
double ratio;
if (demand > supply)
ratio = (demand-supply)/demand;
else
ratio = (demand-supply)/supply;
double adjustment = Math.exp(ratio * ModelConfig.MARKET_LAMBA);
return new GlobalPrice(importPrice * adjustment, exportPrice * adjustment);
}
else {
return this;
}
}
@Override
public String toString() {
return String.format("import=%.3f export=%.3f", importPrice, exportPrice);
}
}
package ac.ed.lurg.country;
public class ImportExportConstraint {
double minNetImport;
double maxNetImport;
public ImportExportConstraint(double minNetImport, double maxNetImport) {
this.minNetImport = minNetImport;
this.maxNetImport = maxNetImport;
}
public double getMinNetImport() {
return minNetImport;
}
public double getMaxNetImport() {
return maxNetImport;
}
}
......@@ -5,6 +5,8 @@ import java.util.Map;
import ac.ed.lurg.ModelConfig;
import ac.ed.lurg.country.CompositeCountry;
import ac.ed.lurg.country.GlobalPrice;
import ac.ed.lurg.country.ImportExportConstraint;
import ac.ed.lurg.types.CommodityType;
import ac.ed.lurg.types.CropType;
......@@ -12,13 +14,10 @@ public class GamsCountryInput {
private CompositeCountry country; // not really required but useful for debugging
private Map<CommodityType, Double> projectedDemand;
private Map<CropType, Double> worldInputPrices;
private Map<CropType, Double> maxNetImport;
private Map<CropType, Double> minNetImport;
private Map<CropType, GlobalPrice> worldPrices;
private Map<CropType, ImportExportConstraint> importConstraints;
private Map<CropType, Double> cropAdjustments;
private boolean calibrateToObserved;
// limits to areas for each location and crop
/* private double maxLandUseChange;
private double meatEfficiency;
......@@ -27,52 +26,34 @@ public class GamsCountryInput {
private double landChangeEnergy;*/
private GamsCountryInput(CompositeCountry country, Map<CommodityType, Double> projectedDemand, Map<CropType, Double> worldInputPrices,
Map<CropType, Double> maxNetImport, Map<CropType, Double> minNetImport, Map<CropType, Double> cropAdjustments, boolean calibrateToObserved) {
private GamsCountryInput(CompositeCountry country, Map<CommodityType, Double> projectedDemand, Map<CropType, GlobalPrice> worldPrices,
Map<CropType, ImportExportConstraint> importConstraints, Map<CropType, Double> cropAdjustments, boolean calibrateToObserved) {
super();
this.country = country;
this.projectedDemand = projectedDemand;
this.worldInputPrices = worldInputPrices;
this.maxNetImport = maxNetImport;
this.minNetImport = minNetImport;
this.worldPrices = worldPrices;
this.importConstraints = importConstraints;
this.cropAdjustments = cropAdjustments;
this.calibrateToObserved = calibrateToObserved;
}
public GamsCountryInput(GamsCountryInput gamsInput, Map<CropType, Double> cropAdjs) {
this(gamsInput.country, gamsInput.projectedDemand, gamsInput.worldInputPrices, gamsInput.maxNetImport, gamsInput.minNetImport, cropAdjs, false);
this(gamsInput.country, gamsInput.projectedDemand, gamsInput.worldPrices, gamsInput.importConstraints, cropAdjs, false);
}
public static GamsCountryInput createInput(CompositeCountry country, Map<CommodityType, Double> projectedDemand, Map<CropType, Double> worldInputPrices,
public static GamsCountryInput createInput(CompositeCountry country, Map<CommodityType, Double> projectedDemand, Map<CropType, GlobalPrice> worldPrices,
Map<CropType, Double> baseNetImport, Map<CropType, Double> maxOfProdOrSupply, Map<CropType, Double> cropAdjustments, boolean calibrateToObserved) {
Map<CropType, Double> maxNetImport;
Map<CropType, Double> minNetImport;
if (calibrateToObserved) { // this condition is no required as calibration now done from GasmRasterOptimiser rather than in GAMS script
maxNetImport = baseNetImport;
minNetImport = baseNetImport;
cropAdjustments = new HashMap<CropType, Double>(); // recreate, but might have been null is this case anyway
for (CropType c : CropType.getNonMeatTypes()) {
cropAdjustments.put(c, 1.0);
}
}
else {
double allowedImportChange = ModelConfig.MAX_IMPORT_CHANGE;
maxNetImport = new HashMap<CropType, Double>();
minNetImport = new HashMap<CropType, Double>();
for (Map.Entry<CropType, Double> entry : baseNetImport.entrySet()) {
CropType c = entry.getKey();
double change = allowedImportChange * maxOfProdOrSupply.get(c);
maxNetImport.put(c, entry.getValue() + change);
minNetImport.put(c, entry.getValue() - change);
}
double allowedImportChange = ModelConfig.MAX_IMPORT_CHANGE;
Map<CropType, ImportExportConstraint> importConstraints = new HashMap<CropType, ImportExportConstraint>();
for (Map.Entry<CropType, Double> entry : baseNetImport.entrySet()) {
CropType c = entry.getKey();
double change = allowedImportChange * maxOfProdOrSupply.get(c);
importConstraints.put(c, new ImportExportConstraint(entry.getValue() - change, entry.getValue() + change));
}
return new GamsCountryInput(country, projectedDemand, worldInputPrices, maxNetImport, minNetImport, cropAdjustments, calibrateToObserved);
return new GamsCountryInput(country, projectedDemand, worldPrices, importConstraints, cropAdjustments, calibrateToObserved);
}
......@@ -84,16 +65,12 @@ public class GamsCountryInput {
return projectedDemand;
}
public Map<CropType, Double> getWorldInputPrices() {
return worldInputPrices;
public Map<CropType, GlobalPrice> getWorldPrices() {
return worldPrices;
}
public Map<CropType, Double> getMaxNetImport() {
return maxNetImport;
}
public Map<CropType, Double> getMinNetImport() {
return minNetImport;
public Map<CropType, ImportExportConstraint> getImportConstraints() {
return importConstraints;
}
// public Map<CropType, Double> getMinFeedAmount() {
......@@ -119,4 +96,36 @@ public class GamsCountryInput {
public boolean isCalibrateToObserved() {
return calibrateToObserved;
}
public Map<CropType, Double> getMinNetImport() {
Map<CropType, Double> netImport = new HashMap<CropType, Double>();
for (Map.Entry<CropType, ImportExportConstraint> entry : importConstraints.entrySet()) {
netImport.put(entry.getKey(), entry.getValue().getMinNetImport());
}
return netImport;
}
public Map<CropType, Double> getMaxNetImport() {
Map<CropType, Double> netImport = new HashMap<CropType, Double>();
for (Map.Entry<CropType, ImportExportConstraint> entry : importConstraints.entrySet()) {
netImport.put(entry.getKey(), entry.getValue().getMaxNetImport());
}
return netImport;
}
public Map<CropType, Double> getWorldImportPrices() {
Map<CropType, Double> prices = new HashMap<CropType, Double>();
for (Map.Entry<CropType, GlobalPrice> entry : worldPrices.entrySet()) {
prices.put(entry.getKey(), entry.getValue().getImportPrice());
}
return prices;
}
public Map<CropType, Double> getWorldExportPrices() {
Map<CropType, Double> prices = new HashMap<CropType, Double>();
for (Map.Entry<CropType, GlobalPrice> entry : worldPrices.entrySet()) {
prices.put(entry.getKey(), entry.getValue().getExportPrice());
}
return prices;
}
}
......@@ -7,10 +7,12 @@ import java.util.Map.Entry;
import java.util.Vector;
import ac.ed.lurg.ModelConfig;
import ac.ed.lurg.country.GlobalPrice;
import ac.ed.lurg.country.ImportExportConstraint;
import ac.ed.lurg.landuse.CropUsageData;
import ac.ed.lurg.landuse.LandUseItem;
import ac.ed.lurg.landuse.Intensity;
import ac.ed.lurg.landuse.IrrigationItem;
import ac.ed.lurg.landuse.LandUseItem;
import ac.ed.lurg.types.CommodityType;
import ac.ed.lurg.types.CropType;
import ac.ed.lurg.types.LandCoverType;
......@@ -167,16 +169,18 @@ public class GamsLocationOptimiser {
if (DEBUG) {
LogWriter.println("\nImport-export, min net imports, max net imports, import price, export price");
for (CropType crop : CropType.getImportedTypes()) {
ImportExportConstraint iec = countryInput.getImportConstraints().get(crop);
GlobalPrice gp = countryInput.getWorldPrices().get(crop);
LogWriter.println(String.format(" %15s, \t %5.1f, \t %5.1f, \t %5.3f, \t %5.3f",
crop.getGamsName(), countryInput.getMinNetImport().get(crop), countryInput.getMaxNetImport().get(crop),
countryInput.getWorldInputPrices().get(crop), countryInput.getWorldInputPrices().get(crop)));
crop.getGamsName(), iec.getMinNetImport(), iec.getMaxNetImport(), gp.getImportPrice(), gp.getExportPrice()));
}
}
addItemMapParm(inDB.addParameter("minNetImport", 1), countryInput.getMinNetImport(), false);
addItemMapParm(inDB.addParameter("maxNetImport", 1), countryInput.getMaxNetImport(), false);
addItemMapParm(inDB.addParameter("worldImportPrices", 1), countryInput.getWorldInputPrices(), false);
addItemMapParm(inDB.addParameter("worldExportPrices", 1), countryInput.getWorldInputPrices(), false);
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());
......
......@@ -22,7 +22,7 @@ public class GamsLocationTest {
}
private void run() {
GamsCountryInput countryLevelInputs = GamsCountryInput.createInput(new CompositeCountry("Test"), getProjectedDemand(), getWorldInputEnergy(), getBaseNetImport(), null, null, true);
GamsCountryInput countryLevelInputs = GamsCountryInput.createInput(new CompositeCountry("Test"), getProjectedDemand(), null, null, null, null, true);
GamsLocationInput gamsInput = new GamsLocationInput(new Timestep(0), getYields(), getPreviousArea(), getIrrigationCosts(), countryLevelInputs);
GamsLocationOptimiser opti = new GamsLocationOptimiser(gamsInput);
......
......@@ -18,7 +18,7 @@ public class GamsRasterTest extends GamsLocationTest {
}
private void run() {
GamsCountryInput countryLevelInputs = GamsCountryInput.createInput(new CompositeCountry("Test"), getProjectedDemand(), getWorldInputEnergy(), getBaseNetImport(), null, null, true);
GamsCountryInput countryLevelInputs = GamsCountryInput.createInput(new CompositeCountry("Test"), getProjectedDemand(), null, null, null, null, true);
GamsRasterInput input = new GamsRasterInput(new Timestep(0), getYieldRaster(), getPreviousAreaRaster(), getIrrigationCost(), countryLevelInputs);
GamsRasterOptimiser opti = new GamsRasterOptimiser(input);
......
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