From d32c19ed21321654e9ce6137688d07bc2d6bf82b Mon Sep 17 00:00:00 2001 From: R0slyn <roslyn.henry.08@aberdeen.ac.uk> Date: Thu, 15 Nov 2018 10:27:21 +0000 Subject: [PATCH] fix to incorporate seed and waste losses into production passed from GAMS to Java, incl change to fbs method. Outputting demand for Frances and hacky code for Trump stuff. --- GAMS/IntExtOpt.gms | 6 ++-- GAMS/LUOpt.gms | 6 ++-- data/subsidyrates.csv | 2 +- src/ac/ed/lurg/InternationalMarket.java | 6 ++-- src/ac/ed/lurg/ModelConfig.java | 1 + src/ac/ed/lurg/ModelMain.java | 35 +++++++++++++++++-- src/ac/ed/lurg/country/CountryAgent.java | 16 +++++---- .../country/gams/GamsLocationOptimiser.java | 7 ++++ src/ac/ed/lurg/landuse/CropUsageData.java | 2 +- 9 files changed, 62 insertions(+), 19 deletions(-) diff --git a/GAMS/IntExtOpt.gms b/GAMS/IntExtOpt.gms index c02f4ed5..6f0b2ac4 100644 --- a/GAMS/IntExtOpt.gms +++ b/GAMS/IntExtOpt.gms @@ -243,9 +243,9 @@ $gdxin parameter feedCostRate(feed_crop); * Production quantities based on smaller area (before unhandledCropArea adjustment applied) - totalProd(crop) = sum(location, area.l(crop, location) * yield.l(crop, location)); - totalProd('ruminants') = meatEfficency*sum(feed_crop, ruminantFeed.l(feed_crop) * cropDM(feed_crop)); - totalProd('monogastrics') = meatEfficency*sum(feed_crop, monogastricFeed.l(feed_crop) * cropDM(feed_crop)); + totalProd(crop) = sum(location, area.l(crop, location) * yield.l(crop, location))* (1 - seedAndWasteRate(crop)); + totalProd('ruminants') = meatEfficency*(sum(feed_crop, ruminantFeed.l(feed_crop) * cropDM(feed_crop)) + ruminantOtherFeed) * (1 - seedAndWasteRate('ruminants')); + totalProd('monogastrics') = meatEfficency*(sum(feed_crop, monogastricFeed.l(feed_crop) * cropDM(feed_crop)) + monogastricOtherFeed)* (1 - seedAndWasteRate('monogastrics')); * Cost based on adjusted area area.l(crop_less_pasture, location) = area.l(crop_less_pasture, location) / (1.0 - unhandledCropRate); diff --git a/GAMS/LUOpt.gms b/GAMS/LUOpt.gms index ad188039..dfaf456a 100644 --- a/GAMS/LUOpt.gms +++ b/GAMS/LUOpt.gms @@ -19,6 +19,7 @@ PARAMETER previousRuminantFeed(crop); PARAMETER previousMonogastricFeed(crop); PARAMETER previousImportAmount(all_types) we still need imports and for feed that we is not grown domestically; + PARAMETER previousExportAmount(all_types) PARAMETER yieldNone(crop, location) yield in t per ha; PARAMETER yieldFertOnly(crop, location) yield in t per ha; PARAMETER yieldIrrigOnly(crop, location) yield in t per ha; @@ -56,7 +57,7 @@ *$gdxin "/Users/peteralexander/Documents/R_Workspace/UNPLUM/output/GamsTmp/China2010.gdx" $gdxin %gdxincname% $load location, suitableLandArea, demand, agriExpansionCost, cropIncCost, pastureIncCost, cropDecCost, pastureDecCost -$load previousArea, previousFertIntensity, previousIrrigIntensity, previousOtherIntensity, previousRuminantFeed, previousMonogastricFeed, previousImportAmount +$load previousArea, previousFertIntensity, previousIrrigIntensity, previousOtherIntensity, previousRuminantFeed, previousMonogastricFeed, previousImportAmount, previousExportAmount $load yieldNone, yieldFertOnly, yieldIrrigOnly, yieldBoth $load fertParam, irrigParam, otherIParam, exportPrices, importPrices, maxProduction, minProduction, unhandledCropRate, setAsideRate, maxLandExpansionRate, subsidyRate $load meatEfficency, otherICost, irrigCost, irrigMaxRate, irrigConstraint, fertiliserUnitCost, domesticPriceMarkup, minDemandPerCereal, seedAndWasteRate, animalFeedFromOtherSources @@ -235,6 +236,7 @@ $gdxin ruminantFeed.L(feed_crop) = previousRuminantFeed(feed_crop); monogastricFeed.L(feed_crop) = previousMonogastricFeed(feed_crop); importForFeed.L(all_types) = 0; + export.L(traded_commodity) = previousExportAmount(traded_commodity); SOLVE LAND_USE USING NLP MAXIMIZING totalProfit; @@ -252,7 +254,7 @@ $gdxin parameter netImportCost(all_types); * Need to copy to parameter for backward compatibility - totalProd(all_types) = production.l(all_types); + totalProd(all_types) = production.l(all_types) * (1 - seedAndWasteRate(all_types)); * Cost based on adjusted area area.l(crop_less_pasture, location) = area.l(crop_less_pasture, location) / (1.0 - unhandledCropRate); diff --git a/data/subsidyrates.csv b/data/subsidyrates.csv index 40012d0a..56ebb516 100644 --- a/data/subsidyrates.csv +++ b/data/subsidyrates.csv @@ -1 +1 @@ -country,crop,rate +country,crop,rate diff --git a/src/ac/ed/lurg/InternationalMarket.java b/src/ac/ed/lurg/InternationalMarket.java index cd7b9b11..de86cf01 100644 --- a/src/ac/ed/lurg/InternationalMarket.java +++ b/src/ac/ed/lurg/InternationalMarket.java @@ -58,12 +58,14 @@ public class InternationalMarket { for (Entry<CropType, CropUsageData> entry : cropUsage.entrySet()) { CropType c = entry.getKey(); double countryNetImports = entry.getValue().getNetImports(); - + if (countryNetImports > 0) totalImportCommodities.incrementValue(c, countryNetImports); else totalExportCommodities.incrementValue(c, -countryNetImports); } + + } // energycrops are a special case where demand in global and exogenously specified @@ -71,10 +73,10 @@ public class InternationalMarket { // Look at trade balance and adjust appropriately for (CropType crop : CropType.getImportedTypes()) { + GlobalPrice prevPrice = worldPrices.get(crop); double imports = totalImportCommodities.containsKey(crop) ? totalImportCommodities.get(crop) : 0.0; double exportsBeforeTransportLosses = totalExportCommodities.containsKey(crop) ? totalExportCommodities.get(crop) : 0.0; - double previousStockLevel = stockLevel.get(crop); GlobalPrice adjustedPrice = prevPrice.createWithUpdatedMarketPrices(imports, exportsBeforeTransportLosses, exportsBeforeTransportLosses * ModelConfig.TRANSPORT_LOSSES, (ModelConfig.MARKET_ADJ_PRICE), timestep); LogWriter.println( String.format("Price for %s updated from %s (imports amount %.0f, exports amount %.0f) to %s ", diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java index a69e23a3..92fdc5d1 100644 --- a/src/ac/ed/lurg/ModelConfig.java +++ b/src/ac/ed/lurg/ModelConfig.java @@ -222,6 +222,7 @@ public class ModelConfig { public static final String PRICES_OUTPUT_FILE = OUTPUT_DIR + File.separator + "prices.txt"; public static final String DEMAND_OUTPUT_FILE = OUTPUT_DIR + File.separator + "demand.txt"; public static final String DOMESTIC_OUTPUT_FILE = OUTPUT_DIR + File.separator + "domestic.txt"; + public static final String COUNTRY_DEMAND_FILE = OUTPUT_DIR + File.separator + "countryDemand.txt"; public static final String FOOD_BALANCE_SHEET_FILE = OUTPUT_DIR + File.separator + "fbs.txt"; public static final boolean OUTPUT_FOR_LPJG = getBooleanProperty("OUTPUT_FOR_LPJG", true); diff --git a/src/ac/ed/lurg/ModelMain.java b/src/ac/ed/lurg/ModelMain.java index 72a82e06..d18e7251 100644 --- a/src/ac/ed/lurg/ModelMain.java +++ b/src/ac/ed/lurg/ModelMain.java @@ -259,9 +259,9 @@ public class ModelMain { } } - double seedAndWaste = prod * crop.getSeedAndWasteRate(); + double seedAndWaste = (prod * (1/(1-crop.getSeedAndWasteRate())))-prod; double netSupply = prod - exportsBeforeTL + imports; - double foodAnd1stGen = netSupply - feedMonogastrics - feedRuminants - seedAndWaste; + double foodAnd1stGen = netSupply - feedMonogastrics - feedRuminants; if (!crop.equals(CropType.SETASIDE)) prodArea *= (1-ModelConfig.UNHANDLED_CROP_RATE); // remove unhandled crop area @@ -351,7 +351,7 @@ private void writeDomesticProductionFile(Timestep timestep) { StringBuffer sbData = new StringBuffer(); sbData.append(String.format("%d,%s,%s", timestep.getYear(), country.getCountry(), crop.getGamsName())); - sbData.append(String.format(",%.3f,%.3f,%.3f,%.10f,%.10f,%.3f,%.3f,%.3f", area, prod, prodCosts, importPrice, exportPrice, netImports, rumFeedAmount, monFeedAmount)); + sbData.append(String.format(",%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f", area, prod, prodCosts, importPrice, exportPrice, netImports, rumFeedAmount, monFeedAmount)); outputFile.write(sbData.toString()); outputFile.newLine(); @@ -364,12 +364,41 @@ private void writeDomesticProductionFile(Timestep timestep) { } } + private void writeCountryDemandFile(Timestep timestep){ + + try { + StringBuffer sbHeadings = new StringBuffer("Year, Country, Commodity, Demand"); + BufferedWriter outputFile = getFileWriter(timestep, ModelConfig.COUNTRY_DEMAND_FILE, sbHeadings.toString()); + + for (CountryAgent country : countryAgents) { + for (CommodityType commodity : CommodityType.getAllItems()) { + + double demand = country.getCurrentProjectedDemand().get(commodity); + + StringBuffer sbData = new StringBuffer(); + sbData.append(String.format("%d,%s,%s", timestep.getYear(), country.getCountry(), commodity.getGamsName())); + sbData.append(String.format(",%.3f", demand)); + + outputFile.write(sbData.toString()); + outputFile.newLine(); + } + } + outputFile.close(); + + } catch (IOException e) { + LogWriter.print(e); + } + + } + + private void outputTimestepResults(Timestep timestep, RasterSet<LandUseItem> landUseRaster) { writeLandCoverFile(timestep, landUseRaster); writeGlobalMarketFile(timestep); writeDemandFile(timestep); writeDomesticProductionFile(timestep); + writeCountryDemandFile(timestep); writeGlobalFoodBalanceSheet(timestep, landUseRaster); if (ModelConfig.OUTPUT_FOR_LPJG) { diff --git a/src/ac/ed/lurg/country/CountryAgent.java b/src/ac/ed/lurg/country/CountryAgent.java index 142c5eb1..cb6926d2 100644 --- a/src/ac/ed/lurg/country/CountryAgent.java +++ b/src/ac/ed/lurg/country/CountryAgent.java @@ -174,24 +174,26 @@ public class CountryAgent { else totalExcessProd += netImportsFromMinDemand; } - double additionalNetImportsRequired = demand - totalProd - totalmportFromMD; - for (CropType crop : commodity.getCropTypes()) { double netImportsMD = netImportsFromMinDemands.get(crop); double netImports=0; if (additionalNetImportsRequired > 0) { // overall importing if (minCerealFracts.containsKey(crop)) - netImports = netImportsMD + minCerealFracts.get(crop) * additionalNetImportsRequired; // divide required imports by minCerealFracts + netImports = netImportsMD + minCerealFracts.get(crop) * additionalNetImportsRequired; // divide required imports by minCerealFracts } else { // overall exporting if (netImportsMD > 0) netImports = netImportsMD; // still import what we need for minimum fraction - else + else{ + if(netImportsMD != 0) netImports = netImportsMD / totalExcessProd * additionalNetImportsRequired; // divide exports by production in excess of minimum demand - } + else + netImports = 0; + } + } - CropUsageData cropUsage = cropUsages.get(crop); + CropUsageData cropUsage = cropUsages.get(crop); LogWriter.println("Updating cereal " + crop + " to " + netImports); cropUsage.updateNetImports(netImports); } @@ -245,6 +247,7 @@ public class CountryAgent { changeDown = changeUp = allowedImportChange * maxOfProdOrSupply; + } if (CropType.ENERGY_CROPS.equals(crop)) { double croplandArea = LandUseItem.getTotalLandCover(previousGamsRasterOutput.getLandUses().values(), LandCoverType.CROPLAND); @@ -262,7 +265,6 @@ public class CountryAgent { baseTradeOrProd=0; } - importConstraints.put(crop, new TradeOrProductionConstraint(baseTradeOrProd - changeDown, baseTradeOrProd + changeUp, ModelConfig.ORIG_LEAST_COST_MIN)); } diff --git a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java index a90988a3..270c1181 100644 --- a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java +++ b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java @@ -261,6 +261,7 @@ public class GamsLocationOptimiser { GAMSParameter exportPriceP = inDB.addParameter("exportPrices", 1); for (CropType crop : CropType.getImportedTypes()) { + TradeOrProductionConstraint iec = countryInput.getTradeOrProductionConstraints().get(crop); CountryPrice gp = countryInput.getCountryPrices().get(crop); double minTradeOrProd = iec.getMinConstraint(); @@ -268,6 +269,12 @@ public class GamsLocationOptimiser { double importPrice = gp.getImportPrice(); double exportPrice = gp.getExportPrice(); +/* if(ModelConfig.US_EXPORT_TARRIFF != 1.0 & inputData.getTimestep().getYear() >= 2018 & crop == CropType.OILCROPS & + countryInput.getCountry().getName().equals("United States of America")){ + exportPrice = gp.getExportPrice()* ModelConfig.US_EXPORT_TARRIFF; + } + else exportPrice = gp.getExportPrice();*/ + CropUsageData cu = countryInput.getPreviousCropUsageData().get(crop); double netImports = cu.getNetImports(); double imports = netImports>0 ? netImports : 0; diff --git a/src/ac/ed/lurg/landuse/CropUsageData.java b/src/ac/ed/lurg/landuse/CropUsageData.java index 828a710d..dfe97349 100644 --- a/src/ac/ed/lurg/landuse/CropUsageData.java +++ b/src/ac/ed/lurg/landuse/CropUsageData.java @@ -39,7 +39,7 @@ public class CropUsageData { public double getNetProduction() { return prod - ruminantFeed - monogastricFeed; } - + public double getProdCost() { return prodCost; } -- GitLab