From fcfefffa7492e1852899132bfe89baef7e0b1990 Mon Sep 17 00:00:00 2001 From: Bart Arendarczyk <s1924442@ed.ac.uk> Date: Sat, 1 Apr 2023 14:50:06 +0100 Subject: [PATCH] Improved handling of trade constraints and price adjustment. --- GAMS/IntExtOpt.gms | 32 +- data/price_caps.csv | 26 +- data/wood_demand_adj.csv | 363 ++++++++++++++++++ src/ac/ed/lurg/ModelConfig.java | 21 +- src/ac/ed/lurg/country/CountryAgent.java | 38 +- src/ac/ed/lurg/country/GlobalPrice.java | 62 +-- src/ac/ed/lurg/country/TradeConstraint.java | 10 + .../country/gams/GamsLocationOptimiser.java | 10 +- src/ac/ed/lurg/landuse/WoodUsageData.java | 4 + src/ac/ed/lurg/types/CropType.java | 20 +- src/ac/ed/lurg/yield/YieldResponsesItem.java | 2 +- 11 files changed, 465 insertions(+), 123 deletions(-) create mode 100644 data/wood_demand_adj.csv diff --git a/GAMS/IntExtOpt.gms b/GAMS/IntExtOpt.gms index f487da0a..0b41b15f 100644 --- a/GAMS/IntExtOpt.gms +++ b/GAMS/IntExtOpt.gms @@ -70,7 +70,7 @@ SCALAR maxGrossLccRate max rate of gross land cover change; SCALAR maxFertChange max increase in total fertilizer use; SCALAR maxIrrigChange max increase in total irrigation use; - SCALAR tradeAdjustmentCostRate + SCALAR tradeAdjustmentCostRate; SCALAR forestManagementCost cost $1000 per ha; SCALAR vegClearingCostRate cost of clearing vegetation $1000 per tC; @@ -122,9 +122,12 @@ $gdxin baseCost('pasture') = 0.04; otherIntCost('pasture') = 0.8 + otherICost; - PARAMETER animalProdCost(animal); - animalProdCost('ruminants') = 0.28; - animalProdCost('monogastrics') = 0.24; + PARAMETER animalProdCost(animal) + / ruminants 0.20 + monogastrics 0.14 /; + + PARAMETER previousNetImport(import_types); + previousNetImport(import_types) = previousImportAmount(import_types) - previousExportAmount(import_types); VARIABLES @@ -140,6 +143,7 @@ $gdxin importAmount(all_types) imports of crops and meat - Mt exportAmount(all_types) exports of crops and meat - Mt animalProd(animal) animal production + netImportAmount(import_types) tradeAdjustmentCost(import_types) totalFeedDM total feed dry matter @@ -153,7 +157,6 @@ $gdxin forestryCost(location) total cost in 1000$ carbonCredits(location) - totalLandValue * A "artificial variable for debugging https://www.gams.com/blog/2017/07/misbehaving-model-infeasible/" total_cost total cost of domestic supply including net imports; @@ -184,6 +187,7 @@ $gdxin RUM_PROD_CALC ruminants production MON_PROD_CALC monogastrics production + NET_IMPORT_CALC(import_types) MAX_NET_IMPORT_CONSTRAINT(import_types) constraint on max net imports MIN_NET_IMPORT_CONSTRAINT(import_types) constraint on min net imports PASTURE_IMPORT_CONSTRAINT constraint to not import pasture @@ -284,7 +288,7 @@ $gdxin landCoverChange(land_cover_before, land_cover_after, location) * conversionCost(land_cover_before, land_cover_after, location)); * MIN_LAND_COVER_AREA_CONSTRAINT(land_cover, location) .. landCoverArea(land_cover, location) =G= minLandCoverArea(land_cover, location); - + ************* Forestry *********************************** WOOD_YIELD_CALC(location) .. woodYieldRota(location) =E= woodYieldMax(location) * (1 - exp(-woodYieldParam(location) / rotationIntensity(location))); @@ -302,8 +306,8 @@ $gdxin FORESTRY_COST_CALC(location) .. forestryCost(location) =E= sum(managed_forest, landCoverArea(managed_forest, location) * forestBaseCost(managed_forest)) + forestManagementCost * rotationIntensity(location) * landCoverArea('timberForest', location) - + sum(land_cover$[not sameAs(land_cover, 'carbonForest')], landCoverChange(land_cover, 'carbonForest', location) * forestManagementCost); -* + sum(wood_type, 0.005 * (exp((exportAmount(wood_type) - previousExportAmount(wood_type))) - 1) * exportAmount(wood_type)); + + sum(land_cover$[not sameAs(land_cover, 'carbonForest')], landCoverChange(land_cover, 'carbonForest', location) * forestManagementCost) + + woodSupply(location) * vegClearingCostRate; *********** Carbon *********************************** @@ -315,13 +319,15 @@ $gdxin *************** Trade ******************************* - MAX_NET_IMPORT_CONSTRAINT(import_types) .. importAmount(import_types) - exportAmount(import_types) =L= maxNetImport(import_types); - MIN_NET_IMPORT_CONSTRAINT(import_types) .. importAmount(import_types) - exportAmount(import_types) =G= minNetImport(import_types); + NET_IMPORT_CALC(import_types) .. netImportAmount(import_types) =E= importAmount(import_types) - exportAmount(import_types); + + MAX_NET_IMPORT_CONSTRAINT(import_types) .. netImportAmount(import_types) =L= maxNetImport(import_types); + MIN_NET_IMPORT_CONSTRAINT(import_types) .. netImportAmount(import_types) =G= minNetImport(import_types); PASTURE_IMPORT_CONSTRAINT .. importAmount('pasture') =E= 0; PASTURE_EXPORT_CONSTRAINT .. exportAmount('pasture') =E= 0; - - TRADE_ADJUSTMENT_COST_CALC(import_types) .. tradeAdjustmentCost(import_types) =E= tradeAdjustmentCostRate * power((importAmount(import_types) - exportAmount(import_types)) - (previousImportAmount(import_types) - previousExportAmount(import_types)), 2); + + TRADE_ADJUSTMENT_COST_CALC(import_types) .. tradeAdjustmentCost(import_types) =E= power(netImportAmount(import_types) - previousNetImport(import_types), 2) * tradeAdjustmentCostRate; ************ Total cost ****************************** @@ -367,7 +373,6 @@ $gdxin parameter totalProdCost(all_types); parameter totalArea(crop); parameter totalCropland(location); - parameter netImportAmount(all_types); parameter netImportCost(all_types); parameter feedCostRate(feed_crop); parameter productionShock(all_types); @@ -392,7 +397,6 @@ $gdxin totalProdCost('ruminants') = sum(feed_crop, ruminantFeed.l(feed_crop) * feedCostRate(feed_crop)) + animalProd.l('ruminants') * animalProdCost('ruminants'); totalProdCost('monogastrics') = sum(feed_crop, monogastricFeed.l(feed_crop) * feedCostRate(feed_crop)) + animalProd.l('monogastrics') * animalProdCost('monogastrics'); - netImportAmount(import_types) = importAmount.l(import_types) - exportAmount.l(import_types); netImportCost(import_types) = importAmount.l(import_types) * importPrices(import_types) - exportAmount.l(import_types) * exportPrices(import_types); netCarbonCredits = SUM(location, carbonCredits.L(location)); diff --git a/data/price_caps.csv b/data/price_caps.csv index af8165a7..7bc18965 100644 --- a/data/price_caps.csv +++ b/data/price_caps.csv @@ -1,14 +1,14 @@ Category,Item,MinPrice,MaxPrice -crop,monogastrics,0.005,1 -crop,ruminants,0.005,1 -crop,wheat,0.005,1 -crop,maize,0.005,1 -crop,rice,0.005,1 -crop,oilcrops,0.005,1 -crop,pulses,0.005,1 -crop,starchyRoots,0.005,1 -crop,fruitveg,0.005,1 -crop,sugar,0.005,1 -crop,energycrops,0.005,1 -wood,wood,0.005,1 -carbon,carbon,0.005,1 +crop,monogastrics,0.0001,5 +crop,ruminants,0.0001,5 +crop,wheat,0.0001,5 +crop,maize,0.0001,5 +crop,rice,0.0001,5 +crop,oilcrops,0.0001,5 +crop,pulses,0.0001,5 +crop,starchyRoots,0.0001,5 +crop,fruitveg,0.0001,5 +crop,sugar,0.0001,5 +crop,energycrops,0.0001,5 +wood,wood,0.0001,5 +carbon,carbon,0.0001,5 \ No newline at end of file diff --git a/data/wood_demand_adj.csv b/data/wood_demand_adj.csv new file mode 100644 index 00000000..20b2d76d --- /dev/null +++ b/data/wood_demand_adj.csv @@ -0,0 +1,363 @@ +Iso3,Type,Production,Demand,NetImports +AFG,roundwood,1.76,1.760609667,0.000609667 +AFG,fuelwood,1.890300667,1.890468667,0.000168 +ALB,roundwood,0.097208333,0.108182667,0.010974333 +ALB,fuelwood,1.028746667,1.017354,-0.011392667 +DZA,roundwood,0.1386,0.178031,0.039431 +DZA,fuelwood,8.686460667,8.686460667,0 +AGO,roundwood,1.25,1.164618333,-0.085381667 +AGO,fuelwood,4.773993,4.773993,0 +ARG,roundwood,13.20259867,13.09079467,-0.111804 +ARG,fuelwood,4.076543667,4.076453667,-9.00E-05 +ARM,roundwood,0.001693667,0.002870333,0.001176667 +ARM,fuelwood,1.546,1.546014,1.40E-05 +AUS,roundwood,32.97932033,28.00568233,-4.973638 +AUS,fuelwood,4.108786,4.033908667,-0.074877333 +AUT,roundwood,13.33730833,22.27463967,8.937331333 +AUT,fuelwood,5.243656,5.679198667,0.435542667 +AZE,roundwood,0.0033,0.004935333,0.001635333 +AZE,fuelwood,0.422,0.422001,1.00E-06 +BHS,roundwood,0.017,0.029723667,0.012723667 +BHS,fuelwood,0.033818667,0.033819,3.33E-07 +BHR,roundwood,0,0.003009667,0.003009667 +BHR,fuelwood,0.007253667,0.007605,0.000351333 +BGD,roundwood,0.217071668,0.302692335,0.085620667 +BGD,fuelwood,13.84515643,13.84502676,-0.000129667 +BRB,roundwood,0.006,0.00703,0.00103 +BRB,fuelwood,0.004742333,0.004742333,0 +BLR,roundwood,15.43957167,14.73271733,-0.706854333 +BLR,fuelwood,11.02323333,10.96296667,-0.060266667 +BEL,roundwood,3.782298866,5.8310872,2.048788333 +BEL,fuelwood,0.769859482,0.885607815,0.115748333 +BLZ,roundwood,0.041,0.047361,0.006361 +BLZ,fuelwood,0.126,0.126,0 +BEN,roundwood,0.384656,0.337515667,-0.047140333 +BEN,fuelwood,6.600257667,6.600257667,0 +BTN,roundwood,0.125168,0.125172,4.00E-06 +BTN,fuelwood,5.236146333,5.236146333,0 +BOL,roundwood,1.315666667,1.303423,-0.012243667 +BOL,fuelwood,2.479089667,2.479089667,0 +BIH,roundwood,2.950468667,2.978938667,0.02847 +BIH,fuelwood,1.531766667,0.73802,-0.793746667 +BWA,roundwood,0.105,0.152695333,0.047695333 +BWA,fuelwood,0.699385667,0.699448333,6.27E-05 +BRA,roundwood,150.6666667,150.1932567,-0.47341 +BRA,fuelwood,122.5866667,122.5699563,-0.016710333 +BRN,roundwood,0.077776667,0.077798667,2.20E-05 +BRN,fuelwood,0.011643667,0.011650667,7.00E-06 +BGR,roundwood,3.516785667,3.284521667,-0.232264 +BGR,fuelwood,2.849241667,2.665237667,-0.184004 +BFA,roundwood,1.171,1.171388,0.000388 +BFA,fuelwood,14.19381233,14.19381233,0 +BDI,roundwood,0.440082908,0.440155241,7.23E-05 +BDI,fuelwood,4.224091784,4.224091784,0 +CPV,roundwood,0,0.000853,0.000853 +CPV,fuelwood,0.186,0.186,0 +KHM,roundwood,0.322,0.292383,-0.029617 +KHM,fuelwood,7.369578667,7.369372,-0.000206667 +CMR,roundwood,3.831865,2.615151333,-1.216713667 +CMR,fuelwood,10.57166567,10.57166567,0 +CAN,roundwood,150.2097817,147.11891,-3.090871667 +CAN,fuelwood,1.486046333,1.411855667,-0.074190667 +CAF,roundwood,0.844713,0.640019667,-0.204693333 +CAF,fuelwood,2,2,0 +TCD,roundwood,0.761,0.760977333,-2.27E-05 +TCD,fuelwood,7.982273,7.982273,0 +CHL,roundwood,46.29762967,46.05308333,-0.244546333 +CHL,fuelwood,16.121789,16.12179167,2.67E-06 +CHN,roundwood,175.5271153,234.379758,58.85264267 +CHN,fuelwood,163.0260283,163.0286893,0.002661 +COL,roundwood,2.666166333,2.589068667,-0.077097667 +COL,fuelwood,6.519973333,6.519968667,-4.67E-06 +COM,roundwood,0.02465,0.024810667,0.000160667 +COM,fuelwood,0.321685667,0.32183,0.000144333 +COG,roundwood,2.369456333,1.468768,-0.900688333 +COG,fuelwood,1.507886667,1.507886667,0 +CRI,roundwood,1.286713667,1.137161333,-0.149552333 +CRI,fuelwood,3.272391667,3.272399667,8.00E-06 +CIV,roundwood,2.4,2.387988333,-0.012011667 +CIV,fuelwood,9.226079,9.226069333,-9.67E-06 +HRV,roundwood,3.131572667,3.009152667,-0.12242 +HRV,fuelwood,2.256533333,1.690524333,-0.566009 +CUB,roundwood,0.611,0.618024,0.007024 +CUB,fuelwood,1.141,1.141,0 +CYP,roundwood,0.002001,0.00609,0.004089 +CYP,fuelwood,0.009947667,0.011530667,0.001583 +CZE,roundwood,12.05542176,3.933860764,-8.121561 +CZE,fuelwood,2.322295074,2.142197407,-0.180097667 +PRK,roundwood,1.5,1.483337,-0.016663 +PRK,fuelwood,6.235740333,6.235727,-1.33E-05 +COD,roundwood,4.611013,4.558086,-0.052927 +COD,fuelwood,85.63231767,85.63231567,-2.00E-06 +DNK,roundwood,1.781,1.698104,-0.082896 +DNK,fuelwood,2.0611,2.135235667,0.074135667 +DJI,roundwood,0,0.000183667,0.000183667 +DJI,fuelwood,0.399619,0.399619,0 +DOM,roundwood,0.078003333,0.122837,0.044833667 +DOM,fuelwood,0.967961333,0.967961333,0 +ECU,roundwood,2.44,2.169531667,-0.270468333 +ECU,fuelwood,5.037486333,5.0375,1.37E-05 +EGY,roundwood,0,0.137141784,0.137141784 +EGY,fuelwood,0,1.524929143,1.524929143 +SLV,roundwood,0.682,0.670865,-0.011135 +SLV,fuelwood,4.133777333,4.133777333,0 +GNQ,roundwood,1.266666667,0.265714,-1.000952667 +GNQ,fuelwood,0.447,0.447,0 +ERI,roundwood,0.022495,0.0225,5.00E-06 +ERI,fuelwood,1.000536,1.000536,0 +EST,roundwood,6.127567537,3.768639203,-2.358928333 +EST,fuelwood,3.899880828,3.646980828,-0.2529 +SWZ,roundwood,0.521415582,0.496981249,-0.024434333 +SWZ,fuelwood,1.025868038,0.456938038,-0.56893 +ETH,roundwood,2.935,2.934981,-1.90E-05 +ETH,fuelwood,111.8815183,111.8815183,0 +FJI,roundwood,0.8,0.798907333,-0.001092667 +FJI,fuelwood,0.037,0.036942,-5.80E-05 +FIN,roundwood,29.48393523,34.23556223,4.751627 +FIN,fuelwood,4.077734732,4.026342065,-0.051392667 +FRA,roundwood,25.50871967,22.70654333,-2.802176333 +FRA,fuelwood,24.41010167,24.06707067,-0.343031 +PYF,roundwood,0.001,0.002688667,0.001688667 +PYF,fuelwood,0.004644,0.004645,1.00E-06 +GAB,roundwood,2.157666667,2.117734667,-0.039932 +GAB,fuelwood,1.07,1.07,0 +GMB,roundwood,0.154166667,0.042185333,-0.111981333 +GMB,fuelwood,0.765960667,0.765960667,0 +GEO,roundwood,0.169483,0.198123333,0.028640333 +GEO,fuelwood,0.405099333,0.397191667,-0.007907667 +DEU,roundwood,46.16455765,48.32213698,2.157579333 +DEU,fuelwood,21.01938124,21.27516358,0.255782333 +GHA,roundwood,2.430555667,2.078253,-0.352302667 +GHA,fuelwood,47.22927,47.226388,-0.002882 +GRC,roundwood,0.479673333,0.495795667,0.016122333 +GRC,fuelwood,1.003137333,1.159827333,0.15669 +GRD,roundwood,0,0.000642667,0.000642667 +GRD,fuelwood,0,0,0 +GTM,roundwood,0.653804,0.626832333,-0.026971667 +GTM,fuelwood,20.908489,20.90847133,-1.77E-05 +GIN,roundwood,0.651,0.642553,-0.008447 +GIN,fuelwood,12.34088267,12.34088267,0 +GNB,roundwood,0.13191,0.125225667,-0.006684333 +GNB,fuelwood,2.882234333,2.882234333,0 +GUY,roundwood,0.311762333,0.187762667,-0.123999667 +GUY,fuelwood,0.823948,0.818361,-0.005587 +HTI,roundwood,0.239,0.240356667,0.001356667 +HTI,fuelwood,2.119133667,2.119133667,0 +HND,roundwood,0.981062,0.972730667,-0.008331333 +HND,fuelwood,8.23591,8.232712667,-0.003197333 +HUN,roundwood,2.930692667,2.613198333,-0.317494333 +HUN,fuelwood,2.776239667,2.751587,-0.024652667 +ISL,roundwood,0.001666667,0.004139,0.002472333 +ISL,fuelwood,0.001333333,0.001227667,-0.000105667 +IND,roundwood,49.517,53.794734,4.277734 +IND,fuelwood,303.339636,303.3447007,0.005064667 +IDN,roundwood,79.38933333,80.205874,0.816540667 +IDN,fuelwood,42.30000967,42.29690033,-0.003109333 +IRN,roundwood,0.416,0.435980667,0.019980667 +IRN,fuelwood,0.03,0.030063667,6.37E-05 +IRQ,roundwood,0.059,0.088999667,0.029999667 +IRQ,fuelwood,0.118,0.118009667,9.67E-06 +IRL,roundwood,3.589333333,3.871886,0.282552667 +IRL,fuelwood,0.212666667,0.223793,0.011126333 +ISR,roundwood,0.025,0.039261667,0.014261667 +ISR,fuelwood,0.002,0.014996,0.012996 +ITA,roundwood,3.982316,6.963112667,2.980796667 +ITA,fuelwood,10.839,11.85788733,1.018887333 +JAM,roundwood,0.152349333,0.156162667,0.003813333 +JAM,fuelwood,0.509008667,0.509008667,0 +JPN,roundwood,23.07933333,25.19033467,2.111001333 +JPN,fuelwood,6.405666667,6.411855,0.006188333 +JOR,roundwood,0.004,0.004826667,0.000826667 +JOR,fuelwood,0.364387,0.364993667,0.000606667 +KAZ,roundwood,0.148333333,0.230896333,0.082563 +KAZ,fuelwood,0.228333333,0.231526667,0.003193333 +KEN,roundwood,1.032,1.02962,-0.00238 +KEN,fuelwood,26.4,26.40000967,9.67E-06 +KWT,roundwood,0,0.007041667,0.007041667 +KWT,fuelwood,0.020447667,0.021229,0.000781333 +KGZ,roundwood,0.00932,0.051386667,0.042066667 +KGZ,fuelwood,0.0366,0.036567,-3.30E-05 +LAO,roundwood,1.432,1.325165,-0.106835 +LAO,fuelwood,5.770353667,5.769886333,-0.000467333 +LVA,roundwood,10.1991231,8.515890435,-1.683232667 +LVA,fuelwood,2.10455698,1.830953647,-0.273603333 +LBN,roundwood,0.00715,0.011868667,0.004718667 +LBN,fuelwood,0.018609,0.019169,0.00056 +LSO,roundwood,0.012666667,0.049391,0.036724333 +LSO,fuelwood,2.139851,2.140261333,0.000410333 +LBR,roundwood,0.46343,0.331720333,-0.131709667 +LBR,fuelwood,9.169455667,9.169455667,0 +LBY,roundwood,0.116,0.130988,0.014988 +LBY,fuelwood,1.041532,1.041601,6.90E-05 +LTU,roundwood,4.95,3.358847667,-1.591152333 +LTU,fuelwood,1.871666667,1.694826667,-0.17684 +LUX,roundwood,0.28300617,0.57429617,0.29129 +LUX,fuelwood,0.063332796,0.076008796,0.012676 +MDG,roundwood,0.17393,0.175286333,0.001356333 +MDG,fuelwood,14.68201467,14.681773,-0.000241667 +MWI,roundwood,1.43,1.433014333,0.003014333 +MWI,fuelwood,5.913169,5.913169,0 +MYS,roundwood,14.49014967,12.75565533,-1.734494333 +MYS,fuelwood,2.455313,2.448034667,-0.007278333 +MDV,roundwood,0,0.003682667,0.003682667 +MDV,fuelwood,0.016437667,0.017669333,0.001231667 +MLI,roundwood,0.817,0.763762,-0.053238 +MLI,fuelwood,5.783094333,5.783094333,0 +MLT,roundwood,0,5.63E-05,5.63E-05 +MLT,fuelwood,0,0.001238,0.001238 +MRT,roundwood,0.032,0.037719333,0.005719333 +MRT,fuelwood,2.168979333,2.168955333,-2.40E-05 +MUS,roundwood,0.000521425,0.026659425,0.026138 +MUS,fuelwood,0.002021237,0.002197237,0.000176 +MEX,roundwood,7.752333333,7.754599667,0.002266333 +MEX,fuelwood,38.605443,38.586746,-0.018697 +MNG,roundwood,0.162,0.164886333,0.002886333 +MNG,fuelwood,0.6,0.600109667,0.000109667 +MNE,roundwood,0.751338333,0.751781333,0.000443 +MNE,fuelwood,0.35662,0.354181333,-0.002438667 +MAR,roundwood,0.298333333,0.424320667,0.125987333 +MAR,fuelwood,6.616582333,6.616612667,3.03E-05 +MOZ,roundwood,1.984,1.282292,-0.701708 +MOZ,fuelwood,16.724,16.72406167,6.17E-05 +MMR,roundwood,4.36,4.326867,-0.033133 +MMR,fuelwood,38.28655733,38.28659667,3.93E-05 +NAM,roundwood,0,0.01365,0.01365 +NAM,fuelwood,1.632811667,1.627289333,-0.005522333 +NPL,roundwood,1.3,1.302659667,0.002659667 +NPL,fuelwood,11.87636667,11.876367,3.33E-07 +NLD,roundwood,0.775764,0.541152,-0.234612 +NLD,fuelwood,2.345233333,2.047625333,-0.297608 +NCL,roundwood,0.0147,0.015176333,0.000476333 +NCL,fuelwood,0.012855333,0.012855333,0 +NZL,roundwood,35.45066667,14.720892,-20.72977467 +NZL,fuelwood,0,8.50E-05,8.50E-05 +NIC,roundwood,0.130104667,0.129353667,-0.000751 +NIC,fuelwood,6.168661667,6.168661667,0 +NER,roundwood,0.701,0.700366333,-0.000633667 +NER,fuelwood,11.65273467,11.65273467,0 +NGA,roundwood,10.022,9.581148333,-0.440851667 +NGA,fuelwood,66.213834,66.21224467,-0.001589333 +MKD,roundwood,0.117,0.158541,0.041541 +MKD,fuelwood,0.672333333,0.687934333,0.015601 +NOR,roundwood,10.78854,7.667534333,-3.121005667 +NOR,fuelwood,1.639671333,1.759432333,0.119761 +OMN,roundwood,0,0.019557667,0.019557667 +OMN,fuelwood,0.048892,0.049096,0.000204 +PAK,roundwood,2.417459011,2.582250678,0.164791667 +PAK,fuelwood,17.5851381,17.58464043,-0.000497667 +PAN,roundwood,0.397696667,0.257536333,-0.140160333 +PAN,fuelwood,1.005105667,1.005105667,0 +PNG,roundwood,4.072,0.501659667,-3.570340333 +PNG,fuelwood,5.533,5.533,0 +PRY,roundwood,4.044,4.029523,-0.014477 +PRY,fuelwood,7.469185,7.469063333,-0.000121667 +PER,roundwood,1.125863333,1.155319,0.029455667 +PER,fuelwood,7.240179,7.240167,-1.20E-05 +PHL,roundwood,3.890466,3.949002667,0.058536667 +PHL,fuelwood,11.489433,11.48549767,-0.003935333 +POL,roundwood,39.87205667,37.152746,-2.719310667 +POL,fuelwood,5.225207,5.079971,-0.145236 +PRT,roundwood,6.470583864,8.02512153,1.554537667 +PRT,fuelwood,0.628597354,0.614416021,-0.014181333 +QAT,roundwood,0,0.001529,0.001529 +QAT,fuelwood,0.005116,0.011,0.005884 +KOR,roundwood,4.272666667,9.583414333,5.310747667 +KOR,fuelwood,0.292333333,0.292653667,0.000320333 +MDA,roundwood,0.045,0.045315333,0.000315333 +MDA,fuelwood,1.219978333,1.219981,2.67E-06 +ROU,roundwood,10.06658567,11.204917,1.138331333 +ROU,fuelwood,5.369443,5.591606333,0.222163333 +RUS,roundwood,206.791394,188.6343767,-18.15701733 +RUS,fuelwood,15.47527233,15.33109267,-0.144179667 +RWA,roundwood,1.013574141,1.016177475,0.002603333 +RWA,fuelwood,4.181663341,4.181663341,0 +LCA,roundwood,0,0.000368667,0.000368667 +LCA,fuelwood,0.009492,0.009492,0 +VCT,roundwood,0,0.000595333,0.000595333 +VCT,fuelwood,0.007106,0.007106,0 +WSM,roundwood,0.0057,0.006466667,0.000766667 +WSM,fuelwood,0.07,0.07,0 +STP,roundwood,0.0272,0.027245,4.50E-05 +STP,fuelwood,0.113544,0.113544,0 +SAU,roundwood,0,0.024284333,0.024284333 +SAU,fuelwood,0.301267667,0.313421667,0.012154 +SEN,roundwood,0.816,0.824499,0.008499 +SEN,fuelwood,5.598048333,5.595732,-0.002316333 +SRB,roundwood,1.514,1.511333333,-0.002666667 +SRB,fuelwood,6.439666667,6.409666667,-0.03 +SLE,roundwood,0.257866667,0.139872667,-0.117994 +SLE,fuelwood,5.927444667,5.927403667,-4.10E-05 +SGP,roundwood,0,0.031815,0.031815 +SGP,fuelwood,0.028732333,0.027356,-0.001376333 +SVK,roundwood,8.735620333,8.021461,-0.714159333 +SVK,fuelwood,0.571453,0.644598667,0.073145667 +SVN,roundwood,3.630870667,1.927916,-1.702954667 +SVN,fuelwood,1.091295333,0.903115667,-0.188179667 +SLB,roundwood,3.202,0.252728333,-2.949271667 +SLB,fuelwood,0.134754,0.134754,0 +SOM,roundwood,0.11,0.110926667,0.000926667 +SOM,fuelwood,15.60759267,15.60759267,0 +ZAF,roundwood,14.99697567,14.45323533,-0.543740333 +ZAF,fuelwood,12.02560733,12.61095567,0.585348333 +SSD,roundwood,0,0,-0.010986 +SSD,fuelwood,4.716333333,4.716333333,0 +ESP,roundwood,15.16807033,14.154257,-1.013813333 +ESP,fuelwood,2.908704333,2.863029667,-0.045674667 +LKA,roundwood,0.7028,0.704197333,0.001397333 +LKA,fuelwood,4.60367,4.60367,0 +SDN,roundwood,1.157,1.142306667,-0.014693333 +SDN,fuelwood,15.50879767,15.50879767,0 +SUR,roundwood,1.006862667,0.518723667,-0.488139 +SUR,fuelwood,0.088,0.088019333,1.93E-05 +SWE,roundwood,46.19464132,53.65073666,7.456095333 +SWE,fuelwood,3.943455967,4.024326967,0.080871 +CHE,roundwood,2.910666667,2.414162333,-0.496504333 +CHE,fuelwood,1.708176667,1.715751,0.007574333 +SYR,roundwood,0.0398,0.048706,0.008906 +SYR,fuelwood,0.034790667,0.034790667,0 +TWN,roundwood,1.459448667,1.900008333,0.440559667 +TWN,fuelwood,0.005495667,0.007134,0.001638333 +TJK,roundwood,0,0.011085667,0.011085667 +TJK,fuelwood,3.674,3.673969333,-3.07E-05 +THA,roundwood,14.6,14.61619333,0.016193333 +THA,fuelwood,18.518049,18.523733,0.005684 +TLS,roundwood,0,0,-1.17E-05 +TLS,fuelwood,0.085032,0.085032,0 +TGO,roundwood,0.206003,0.172215333,-0.033787667 +TGO,fuelwood,4.424,4.423988,-1.20E-05 +TTO,roundwood,0.1668,0.166106333,-0.000693667 +TTO,fuelwood,0.030460667,0.030461,3.33E-07 +TUN,roundwood,0.084519823,0.096815823,0.012296 +TUN,fuelwood,1.003672897,1.003591231,-8.17E-05 +TUR,roundwood,21.54266667,21.58823333,0.045566667 +TUR,fuelwood,5.593666667,5.620589333,0.026922667 +TKM,roundwood,0,0.004609667,0.004609667 +TKM,fuelwood,0.006666667,0.032,0.025333333 +UGA,roundwood,5.33,5.310808333,-0.019191667 +UGA,fuelwood,43.73351467,43.73351467,0 +UKR,roundwood,8.525466667,8.532739,0.007272333 +UKR,fuelwood,10.30696667,9.117434333,-1.189532333 +ARE,roundwood,0,0.081065,0.081065 +ARE,fuelwood,0.018847,0.024242,0.005395 +GBR,roundwood,8.600561,9.039714333,0.439153333 +GBR,fuelwood,2.350933333,2.495227667,0.144294333 +TZA,roundwood,2.838079,2.835825667,-0.002253333 +TZA,fuelwood,24.820354,24.81902333,-0.001330667 +USA,roundwood,385.542306,376.036402,-9.505904 +USA,fuelwood,69.13516433,68.992805,-0.142359333 +URY,roundwood,7.506575953,6.029059619,-1.477516333 +URY,fuelwood,1.415608914,1.415610914,2.00E-06 +UZB,roundwood,0.0092,0.257660333,0.248460333 +UZB,fuelwood,0.020166667,0.020120333,-4.63E-05 +VUT,roundwood,0.038,0.034559667,-0.003440333 +VUT,fuelwood,0.091,0.091,0 +VEN,roundwood,1.317,1.310759333,-0.006240667 +VEN,fuelwood,4.304446,4.304446,0 +VNM,roundwood,36.16875333,38.70161033,2.532857 +VNM,fuelwood,20,19.98639467,-0.013605333 +YEM,roundwood,0.002556667,0.003327,0.000770333 +YEM,fuelwood,0.574145667,0.574783,0.000637333 +ZMB,roundwood,2.674666667,2.629792,-0.044874667 +ZMB,fuelwood,23.033,23.03300133,1.33E-06 +ZWE,roundwood,0.60448,0.585449667,-0.019030333 +ZWE,fuelwood,9.296991667,9.296991667,0 \ No newline at end of file diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java index 35e5760c..51f8d80c 100755 --- a/src/ac/ed/lurg/ModelConfig.java +++ b/src/ac/ed/lurg/ModelConfig.java @@ -228,7 +228,7 @@ public class ModelConfig { public static final double INITAL_PRICE_MAIZE = getDoubleProperty("INITAL_PRICE_MAIZE", 0.132 * ModelConfig.INITIAL_PRICE_SHIFT); public static final double INITAL_PRICE_RICE = getDoubleProperty("INITAL_PRICE_RICE", 0.142 * ModelConfig.INITIAL_PRICE_SHIFT); public static final double INITAL_PRICE_OILCROPS = getDoubleProperty("INITAL_PRICE_OILCROPS", 0.13 * ModelConfig.INITIAL_PRICE_SHIFT); - public static final double INITAL_PRICE_PULSES = getDoubleProperty("INITAL_PRICE_PULSES", 0.3 * ModelConfig.INITIAL_PRICE_SHIFT); + public static final double INITAL_PRICE_PULSES = getDoubleProperty("INITAL_PRICE_PULSES", 0.40 * ModelConfig.INITIAL_PRICE_SHIFT); public static final double INITAL_PRICE_STARCHYROOTS = getDoubleProperty("INITAL_PRICE_STARCHYROOTS", 0.07 * ModelConfig.INITIAL_PRICE_SHIFT); public static final double INITAL_PRICE_MONOGASTRICS = getDoubleProperty("INITAL_PRICE_MONOGASTRICS", 0.27 * ModelConfig.INITIAL_PRICE_SHIFT); // value from calibration public static final double INITAL_PRICE_RUMINANTS = getDoubleProperty("INITAL_PRICE_RUMINANTS", 0.25 * ModelConfig.INITIAL_PRICE_SHIFT); // value from calibration @@ -363,10 +363,9 @@ public class ModelConfig { public static final int BASE_YEAR = getIntProperty("BASE_YEAR", 2019); // Import export limits - public static final double ANNUAL_MAX_IMPORT_CHANGE = getDoubleProperty("ANNUAL_MAX_IMPORT_CHANGE", 0.05); + public static final double ANNUAL_MAX_IMPORT_CHANGE = getDoubleProperty("ANNUAL_MAX_IMPORT_CHANGE", 0.5); public static final double MAX_IMPORT_CHANGE = getDoubleProperty("MAX_IMPORT_CHANGE", ANNUAL_MAX_IMPORT_CHANGE*TIMESTEP_SIZE); - public static final double IMPORT_CHANGE_ELASTICITY = getDoubleProperty("IMPORT_CHANGE_ELASTICITY", 3.0); // higher value = steeper trade imbalance adjustment - public static final double TRADE_ADJUSTMENT_COST_RATE = getDoubleProperty("TRADE_ADJUSTMENT_COST_RATE", 0.05); + public static final double TRADE_ADJUSTMENT_COST_RATE = getDoubleProperty("TRADE_ADJUSTMENT_COST_RATE", 0.02); // Price caps public static final String PRICE_CAP_FILE = DATA_DIR + File.separator + "price_caps.csv"; @@ -426,14 +425,14 @@ public class ModelConfig { public static final boolean RESET_ENERGYCROP_PRICE = getBooleanProperty("RESET_ENERGYCROP_PRICE", true); // Resets price after calibration to avoid problems due to low initial demand // public static final double BIOENERGY_HEATING_VALUE_GJ_PER_T = getDoubleProperty("BIOENERGY_HEATING_VALUE_GJ_PER_T", 17.5); // GJ per t DM - public static final double MARKET_LAMBDA = getDoubleProperty("MARKET_LAMBDA", 0.04); // controls international market price adjustment rate - public static final double MARKET_DAMPING = getDoubleProperty("MARKET_DAMPING", 1.0); // controls international market price adjustment rate + public static final double MARKET_BETA = getDoubleProperty("MARKET_BETA", 0.015); // controls international market price adjustment rate + public static final double MARKET_LAMBDA = getDoubleProperty("MARKET_LAMBDA", 0.4); // controls international market price adjustment rate public static final String PRICE_UPDATE_METHOD = getProperty("PRICE_UPDATE_METHOD", "StockUseRatio"); // Options: StockUseRatio, MarketImbalance, StockChange public static final double MAX_PRICE_INCREASE = getDoubleProperty("MAX_PRICE_INCREASE", 1.5); public static final double MAX_PRICE_DECREASE = getDoubleProperty("MAX_PRICE_DECREASE", .75); - public static final int DEMAND_RECALC_MAX_ITERATIONS = IS_CALIBRATION_RUN ? 0 : getIntProperty("DEMAND_RECALC_MAX_ITERATIONS", 1); // 0 is original behaviour - public static final boolean DEMAND_RECALC_ON_NEGATIVE_STOCK = IS_CALIBRATION_RUN ? false : getBooleanProperty("DEMAND_RECALC_ON_NEGATIVE_STOCK", false); + public static final int DEMAND_RECALC_MAX_ITERATIONS = IS_CALIBRATION_RUN ? 0 : getIntProperty("DEMAND_RECALC_MAX_ITERATIONS", 0); // 0 is original behaviour + public static final boolean DEMAND_RECALC_ON_NEGATIVE_STOCK = IS_CALIBRATION_RUN ? false : getBooleanProperty("DEMAND_RECALC_ON_NEGATIVE_STOCK", false); public static final double POPULATION_AGGREG_LIMIT = getDoubleProperty("POPULATION_AGGREG_LIMIT", 30.0); // in millions, smaller countries are aggregated on a regional basis public static final boolean PREDEFINED_COUNTRY_GROUPING = getBooleanProperty("PREDEFINED_COUNTRY_GROUPING", true); @@ -451,7 +450,7 @@ public class ModelConfig { public static final double IRRIG_COST_SCALE_FACTOR = getDoubleProperty("IRRIG_COST_SCALE_FACTOR", 0.00035); public static final double IRRIG_COST_MULTIPLIER = getDoubleProperty("IRRIG_COST_MULTIPLIER", 1.0); - public static final double FERTILISER_COST_PER_T = getDoubleProperty("FERTILISER_COST_PER_T", 1.6); // $500/t, 18% N/t + public static final double FERTILISER_COST_PER_T = getDoubleProperty("FERTILISER_COST_PER_T", 1.4); // $500/t, 18% N/t public static final double FERTILISER_MAX_COST = FERTILISER_COST_PER_T * MAX_FERT_AMOUNT/1000; public static final double DOMESTIC_PRICE_MARKUP = getDoubleProperty("DOMESTIC_PRICE_MARKUP", 1.0); @@ -482,7 +481,7 @@ public class ModelConfig { public static final double PASTURE_MAX_IRRIGATION_RATE = getDoubleProperty("DEFAULT_MAX_IRRIGATION_RATE", 50.0); // shouldn't need this but some areas crops don't have a value, but was causing them to be selected public static final int LPJG_TIMESTEP_SIZE = getIntProperty("LPJG_TIMESTEP_SIZE", 5); - public static final int LPJ_YEAR_OFFSET = getIntProperty("LPJ_YEAR_OFFSET", -1);; + public static final int LPJ_YEAR_OFFSET = getIntProperty("LPJ_YEAR_OFFSET", -1); public static final int NUM_YIELD_CLUSTERS = getIntProperty("NUM_YIELD_CLUSTERS", 5000); public static final long RANDOM_SEED = getIntProperty("RANDOM_SEED", 1974329); // any number will do @@ -526,7 +525,7 @@ public class ModelConfig { public static final double VEGETATION_CLEARING_COST = getDoubleProperty("VEGETATION_CLEARING_COST", 0.08); //$1000/tC public static final double FOREST_MANAGEMENT_COST = IS_FORESTRY_ON ? getDoubleProperty("FOREST_MANAGEMENT_COST", 2.5) : 0.0; // establishment, management etc. $1000/ha public static final double FOREST_BASE_COST = getDoubleProperty("FOREST_BASE_COST", 0.3); // $1000/ha - public static final double WOOD_TRADE_BARRIER = getDoubleProperty("WOOD_TRADE_BARRIER", 0.2); //$1000/tC + public static final double WOOD_TRADE_BARRIER = getDoubleProperty("WOOD_TRADE_BARRIER", 0.3); //$1000/tC public static final double INIT_ROUNDWOOD_PRICE = IS_FORESTRY_ON ? getDoubleProperty("INIT_ROUNDWOOD_PRICE", 0.1) : 0.0; // $1000/tC-eq public static final double INIT_FUELWOOD_PRICE = IS_FORESTRY_ON ? getDoubleProperty("INIT_FUELWOOD_PRICE", 0.08) : 0.0; // $1000/tC-eq public static final int CARBON_WOOD_MAX_TIME = getIntProperty("CARBON_WOOD_MAX_TIME", 160); // upper data limit, years diff --git a/src/ac/ed/lurg/country/CountryAgent.java b/src/ac/ed/lurg/country/CountryAgent.java index 2f66cef1..f870f431 100644 --- a/src/ac/ed/lurg/country/CountryAgent.java +++ b/src/ac/ed/lurg/country/CountryAgent.java @@ -169,30 +169,13 @@ public class CountryAgent extends AbstractCountryAgent { double changeDown = 0; // max of supply overall, needed for when imports are supplying feed and change is zero to allow for production to replace imports - double maxOfProdOrSupply = cropUsage.getProductionExpected() + Math.max(baseTrade, 0); //max of supply for food - double production = cropUsage.getProductionExpected(); - double netSupply = getCropUsageData().get(crop).getNetSupply(); - GlobalPrice cropPrice = currentWorldPrices.get(crop); + // minimum 1 so trade balance can still change when supply is 0 + double maxOfProdOrSupply = Math.max(cropUsage.getProductionExpected() + Math.max(baseTrade, 0), 1); if (ModelConfig.IS_CALIBRATION_RUN && currentTimestep.getTimestep() <= ModelConfig.END_FIRST_STAGE_CALIBRATION) { changeUp = changeDown = 0; } else { - if (crop.isImportedCrop()) { - // exporter or not fully reliant on exports. Avoid forcing import reliant countries to reduce imports - if (baseTrade < 0 || production > baseTrade) { - double tradeImbalanceFract = cropPrice.getTradeImbalanceFraction(); - // If in danger of stocks becoming negative, shift towards more exports - if (cropPrice.isStockCritical()) { - baseTrade = baseTrade - Math.abs(baseTrade) * tradeImbalanceFract * 1.1; - changeUp = 0; - } else { - changeUp = maxOfProdOrSupply * ModelConfig.MAX_IMPORT_CHANGE; - } - } else { - changeUp = maxOfProdOrSupply * ModelConfig.MAX_IMPORT_CHANGE; - } - changeDown = maxOfProdOrSupply * ModelConfig.MAX_IMPORT_CHANGE; - } + changeDown = changeUp = maxOfProdOrSupply * ModelConfig.MAX_IMPORT_CHANGE; } if (CropType.ENERGY_CROPS.equals(crop) && baseTrade == 0) { // could apply this logic for all crops? @@ -212,8 +195,11 @@ public class CountryAgent extends AbstractCountryAgent { minLimit = minMaxLimits.get(MinMaxNetImportManager.LimitType.MIN_LIMIT_TYPE).get(crop); maxLimit = minMaxLimits.get(MinMaxNetImportManager.LimitType.MAX_LIMIT_TYPE).get(crop); } + LogWriter.print(crop.toString(), 3); - importConstraints.put(crop, new TradeConstraint(baseTrade - changeDown, baseTrade + changeUp, restiction, minLimit, maxLimit)); + TradeConstraint tradeConstraint = new TradeConstraint(baseTrade - changeDown, baseTrade + changeUp, restiction, minLimit, maxLimit); + + importConstraints.put(crop, tradeConstraint); } TradeConstraint carbonTradeConstraint; @@ -226,10 +212,9 @@ public class CountryAgent extends AbstractCountryAgent { if (Math.abs(baseTrade) < 1e-3) { // to set initial trade when starting from zero changeUp = changeDown = getCurrentCarbonDemand(); } else { - double maxOfProdOrSupply = carbonUsageData.getCarbonCredits() + Math.max(baseTrade, 0); + double maxOfProdOrSupply = Math.max(carbonUsageData.getCarbonCredits() + Math.max(baseTrade, 0), 1); // double change otherwise we run into issues as not all countries can meet demand with domestic production - changeUp = maxOfProdOrSupply * globalCarbonPrice.getMaxImportChange() * 2; - changeDown = maxOfProdOrSupply * globalCarbonPrice.getMaxExportChange() * 2; + changeUp = changeDown = maxOfProdOrSupply * ModelConfig.MAX_IMPORT_CHANGE; } carbonTradeConstraint = new TradeConstraint(baseTrade - changeDown, baseTrade + changeUp); @@ -253,15 +238,12 @@ public class CountryAgent extends AbstractCountryAgent { double changeUp; double changeDown; - double demand = currentWoodDemand.get(woodType); - double maxOfProdOrSupply = woodUsage.getProduction() + Math.max(baseTrade, 0); - //double baseTrade = demand * woodUsage.getBaseImportDemandRatio(); + double maxOfProdOrSupply = Math.max(woodUsage.getProduction() + Math.max(baseTrade, 0), 1); if (ModelConfig.IS_CALIBRATION_RUN && currentTimestep.getTimestep() <= ModelConfig.END_FIRST_STAGE_CALIBRATION) { changeUp = changeDown = 0.0; } else { changeUp = changeDown = maxOfProdOrSupply * ModelConfig.MAX_IMPORT_CHANGE; - //changeUp = changeDown = demand * 0.04; } woodTradeConstraints.put(woodType, new TradeConstraint(baseTrade - changeDown, baseTrade + changeUp)); diff --git a/src/ac/ed/lurg/country/GlobalPrice.java b/src/ac/ed/lurg/country/GlobalPrice.java index dd5174b6..fa1ea9f5 100644 --- a/src/ac/ed/lurg/country/GlobalPrice.java +++ b/src/ac/ed/lurg/country/GlobalPrice.java @@ -18,9 +18,10 @@ public class GlobalPrice implements Serializable { private double stockLevel; private double stockUseRatio; private double referencePrice; + private double prevStockChange; private GlobalPrice(Timestep timestep, double exportPrice, double stockLevel, double importAmount, double exportAmountBeforeLoss, - double transportLosses, double referencePrice, double stockUseRatio) { + double transportLosses, double referencePrice, double stockUseRatio, double prevStockChange) { this.timestep = timestep; this.exportPrice = exportPrice; this.stockLevel = stockLevel; @@ -29,12 +30,13 @@ public class GlobalPrice implements Serializable { this.exportAmountBeforeLoss = exportAmountBeforeLoss; this.transportLosses = transportLosses; this.referencePrice = referencePrice; + this.prevStockChange = prevStockChange; LogWriter.println("Created " + this, 3); } public static GlobalPrice createInitial(double exportPrice, double intitalStock) { return new GlobalPrice(new Timestep(ModelConfig.START_TIMESTEP-1), exportPrice, intitalStock, Double.NaN, - Double.NaN, Double.NaN, Double.NaN, Double.NaN); + Double.NaN, Double.NaN, Double.NaN, Double.NaN, 0.0); } public double getExportPrice(){ @@ -99,9 +101,20 @@ public class GlobalPrice implements Serializable { adjustment = 1; } else if (ModelConfig.PRICE_UPDATE_METHOD.equals("StockUseRatio")) { - // MARKET_LAMBDA controls how strongly prices adjust to stock imbalance - // MARKET_DAMPING controls how quickly prices reach equilibrium - adjustment = 1 - (ModelConfig.MARKET_LAMBDA * (updatedStock - targetStock) + ModelConfig.MARKET_DAMPING * stockChange) / production; + // MARKET_BETA controls how strongly prices adjust to stock imbalance + // MARKET_LAMBDA controls how quickly prices reach equilibrium + //adjustment = 1 - (ModelConfig.MARKET_BETA * (updatedStock - targetStock) + ModelConfig.MARKET_LAMBDA * stockChange) / production; + // Sum of target stock and trade flow volume. Trying to avoid large swings in prices when stocks low + double stockAndFlow = stockLevel + Math.max(newImports, newExportAmountBeforeLoss); + adjustment = 1 - (ModelConfig.MARKET_LAMBDA * stockChange / stockAndFlow + + ModelConfig.MARKET_LAMBDA * (stockChange - prevStockChange) / stockAndFlow + + ModelConfig.MARKET_BETA * (updatedStock - targetStock) / targetStock ); + + // Maximum price increase if projected stock below zero + if (updatedStock + stockChange + (stockChange - prevStockChange) <= 0) { + adjustment = ModelConfig.MAX_PRICE_INCREASE; + } + } else if (ModelConfig.PRICE_UPDATE_METHOD.equals("MarketImbalance")) { double ratio = stockChange/(production-stockChange); @@ -131,9 +144,9 @@ public class GlobalPrice implements Serializable { double newPrice = exportPrice * adjustment; double refPrice = ModelConfig.IS_CALIBRATION_RUN ? exportPrice : referencePrice; // during calibration reference price isn't fixed, but it is after that - + return new GlobalPrice(thisTimeStep, newPrice, updatedStock, newImports, newExportAmountBeforeLoss, - newTransportLosses, refPrice, updatedStockUseRatio); + newTransportLosses, refPrice, updatedStockUseRatio, stockChange); } else { LogWriter.printlnWarning(String.format("Price for not updated (still %s), as no imports and no exports for it", exportPrice)); @@ -157,45 +170,12 @@ public class GlobalPrice implements Serializable { public GlobalPrice createPriceAdjustedByFactor(double factor) { return new GlobalPrice(timestep, exportPrice * factor, stockLevel, importAmount, exportAmountBeforeLoss, - transportLosses, referencePrice, stockUseRatio); + transportLosses, referencePrice, stockUseRatio, prevStockChange); } public void resetStock(Double stock) { this.stockLevel = stock; } - - public double calcTradeMaxChange(double ratio) { - if (Double.isNaN(ratio)) { - return ModelConfig.MAX_IMPORT_CHANGE; - } else { - // allowed change decreases as trade imbalance increases - double change = Math.exp(-(ratio - 1) * ModelConfig.IMPORT_CHANGE_ELASTICITY) * ModelConfig.MAX_IMPORT_CHANGE; - return Math.min(change, ModelConfig.MAX_IMPORT_CHANGE); // cap at max change - } - } - - public double getMaxImportChange() { - //return calcTradeMaxChange(importAmount / exportAmountBeforeLoss); - return stockLevel > importAmount ? Math.min(stockLevel / importAmount - 1, ModelConfig.MAX_IMPORT_CHANGE) : 0; - } - - public double getMaxExportChange() { - //return calcTradeMaxChange(exportAmountBeforeLoss/ importAmount); - return (exportAmountBeforeLoss > 1.2 * importAmount) ? 0 : ModelConfig.MAX_IMPORT_CHANGE; - } - - public boolean isStockCritical() { - return (stockLevel < importAmount && exportAmountBeforeLoss < importAmount * 1.2) || stockLevel < 0; - } - public double getTradeImbalanceFraction() { - double netImports = importAmount - exportAmountBeforeLoss; - double tradeVolume = importAmount + exportAmountBeforeLoss; - return netImports / tradeVolume; - } - - public double getImportToExportRatio() { - return exportAmountBeforeLoss > 0 ? importAmount / exportAmountBeforeLoss : 0; - } } \ No newline at end of file diff --git a/src/ac/ed/lurg/country/TradeConstraint.java b/src/ac/ed/lurg/country/TradeConstraint.java index e90e2ce5..ffa912c0 100644 --- a/src/ac/ed/lurg/country/TradeConstraint.java +++ b/src/ac/ed/lurg/country/TradeConstraint.java @@ -1,10 +1,12 @@ package ac.ed.lurg.country; +import ac.ed.lurg.ModelConfig; import ac.ed.lurg.utils.LogWriter; public class TradeConstraint { private double minValue; private double maxValue; + private double tradeAdjustmentCost = ModelConfig.TRADE_ADJUSTMENT_COST_RATE; public TradeConstraint(double min, double max) { minValue = min; @@ -47,6 +49,14 @@ public class TradeConstraint { return maxValue; } + public void setTradeAdjustmentCost(double cost) { + tradeAdjustmentCost = cost; + } + + public double getTradeAdjustmentCost() { + return tradeAdjustmentCost; + } + @Override public String toString() { return "TradeConstraint [minValue=" + minValue + ", maxValue=" + maxValue + "]"; diff --git a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java index 24311649..99f5c442 100644 --- a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java +++ b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java @@ -520,7 +520,7 @@ public class GamsLocationOptimiser { GAMSVariable varOtherIntensities = outDB.getVariable("otherIntensity"); GAMSVariable varRuminantFeed = outDB.getVariable("ruminantFeed"); GAMSVariable varMonogastricFeed = outDB.getVariable("monogastricFeed"); - GAMSParameter parmNetImports = outDB.getParameter("netImportAmount"); + GAMSVariable varNetImports = outDB.getVariable("netImportAmount"); GAMSParameter parmNetImportCost = outDB.getParameter("netImportCost"); GAMSVariable varYields = outDB.getVariable("yield"); GAMSVariable varUnitEnergies = outDB.getVariable("unitCost"); @@ -558,7 +558,7 @@ public class GamsLocationOptimiser { if (!cropUsageData.containsKey(cropType)) { // then we must not have seen this crop type before, so need to do all non location specific stuff ruminantFeed = varRuminantFeed.findRecord(itemName).getLevel(); monogastricFeed = varMonogastricFeed.findRecord(itemName).getLevel(); - netImport = cropType.isImportedCrop() ? getParmValue(parmNetImports, itemName) : 0; + netImport = cropType.isImportedCrop() ? varNetImports.findRecord(itemName).getLevel() : 0; netImportCost = cropType.isImportedCrop() ? getParmValue(parmNetImportCost, itemName) : 0; prod = getParmValue(parmProd, itemName); prodCost = getParmValue(parmProdCost, itemName); @@ -587,7 +587,7 @@ public class GamsLocationOptimiser { } for (CropType meatTypes : CropType.getMeatTypes()) { - netImport = getParmValue(parmNetImports, meatTypes.getGamsName()); + netImport = varNetImports.findRecord(meatTypes.getGamsName()).getLevel(); netImportCost= getParmValue(parmNetImportCost, meatTypes.getGamsName()); prod = getParmValue(parmProd, meatTypes.getGamsName()); prodCost = getParmValue(parmProdCost, meatTypes.getGamsName()); @@ -634,7 +634,7 @@ public class GamsLocationOptimiser { */ GAMSParameter woodSupplyP = outDB.getParameter("woodSupplyP"); for (WoodType wType : WoodType.values()) { - double netImports = getParmValue(parmNetImports, wType.getName()); + double netImports = varNetImports.findRecord(wType.getName()).getLevel(); double supply = getParmValue(woodSupplyP, wType.getName()); WoodUsageData woodUsageData = inputData.getCountryInput().getPreviousWoodUsageData().get(wType); woodUsageData.setProduction(supply); @@ -653,7 +653,7 @@ public class GamsLocationOptimiser { // Carbon double carbonSequestered = outDB.getParameter("netCarbonCredits").getFirstRecord().getValue(); - double netCarbonImport = getParmValue(parmNetImports, "carbonCredits"); + double netCarbonImport = varNetImports.findRecord("carbonCredits").getLevel(); CarbonUsageData carbonUsageData = new CarbonUsageData(carbonSequestered, netCarbonImport, 0.0); return new GamsLocationOutput(modelStatus, landUses, cropUsageData, landCoverChanges, carbonUsageData, diff --git a/src/ac/ed/lurg/landuse/WoodUsageData.java b/src/ac/ed/lurg/landuse/WoodUsageData.java index 3771e670..4d803430 100644 --- a/src/ac/ed/lurg/landuse/WoodUsageData.java +++ b/src/ac/ed/lurg/landuse/WoodUsageData.java @@ -41,4 +41,8 @@ public class WoodUsageData implements Serializable { public double getBaseImportDemandRatio() { return baseImportDemandRatio; } + + public double getNetSupply() { + return expectedProduction + netImport; + } } diff --git a/src/ac/ed/lurg/types/CropType.java b/src/ac/ed/lurg/types/CropType.java index 06457535..47a13ab1 100644 --- a/src/ac/ed/lurg/types/CropType.java +++ b/src/ac/ed/lurg/types/CropType.java @@ -11,18 +11,18 @@ import ac.ed.lurg.utils.LogWriter; public enum CropType { - WHEAT("WheatBarleyOats", "wheat", true, false, 9.5, ModelConfig.INITAL_PRICE_WHEAT, 0.4), - MAIZE("MaizeMilletSorghum", "maize", true, false, 5.1, ModelConfig.INITAL_PRICE_MAIZE, 0.4), - RICE("Rice (Paddy Equivalent)", "rice", true, false, 8.3, ModelConfig.INITAL_PRICE_RICE, 0.4), - OILCROPS("Oilcrops", "oilcrops", true, false, 4.4, ModelConfig.INITAL_PRICE_OILCROPS, 0.3), - PULSES("Pulses", "pulses", true, false, 10.8, ModelConfig.INITAL_PRICE_PULSES, 0.5), - STARCHY_ROOTS("Starchy Roots", "starchyRoots", true, false, 14.3, ModelConfig.INITAL_PRICE_STARCHYROOTS, 0.2), + WHEAT("WheatBarleyOats", "wheat", true, false, 9.5, ModelConfig.INITAL_PRICE_WHEAT, 0.45), + MAIZE("MaizeMilletSorghum", "maize", true, false, 5.1, ModelConfig.INITAL_PRICE_MAIZE, 0.35), + RICE("Rice (Paddy Equivalent)", "rice", true, false, 8.3, ModelConfig.INITAL_PRICE_RICE, 0.50), + OILCROPS("Oilcrops", "oilcrops", true, false, 4.4, ModelConfig.INITAL_PRICE_OILCROPS, 0.25), + PULSES("Pulses", "pulses", true, false, 10.8, ModelConfig.INITAL_PRICE_PULSES, 0.45), + STARCHY_ROOTS("Starchy Roots", "starchyRoots", true, false, 14.3, ModelConfig.INITAL_PRICE_STARCHYROOTS, 0.10), ENERGY_CROPS("Energy crops", "energycrops", true, false, 5, ModelConfig.INITAL_PRICE_ENERGYCROPS, 0.2), SETASIDE("setaside", "setaside", false, false, 0, 0, 0), - MONOGASTRICS("Monogastrics", "monogastrics", true, true, 3.1, ModelConfig.INITAL_PRICE_MONOGASTRICS, 0.2), - RUMINANTS("Ruminants", "ruminants", true, true, 2.2, ModelConfig.INITAL_PRICE_RUMINANTS, 0.2), - FRUITVEG("FruitVeg", "fruitveg", true, false, 8.9, ModelConfig.INITAL_PRICE_FRUITVEG, 0.2), - SUGAR("Sugar", "sugar", true, false, 0.1, ModelConfig.INITAL_PRICE_SUGAR, 0.5), + MONOGASTRICS("Monogastrics", "monogastrics", true, true, 3.1, ModelConfig.INITAL_PRICE_MONOGASTRICS, 0.35), + RUMINANTS("Ruminants", "ruminants", true, true, 2.2, ModelConfig.INITAL_PRICE_RUMINANTS, 0.10), + FRUITVEG("FruitVeg", "fruitveg", true, false, 8.9, ModelConfig.INITAL_PRICE_FRUITVEG, 0.10), + SUGAR("Sugar", "sugar", true, false, 0.1, ModelConfig.INITAL_PRICE_SUGAR, 0.40), PASTURE("pasture", "pasture", false, false, 0, 0, 0); // confusing having a land cover and a crop type. Needed here for yields (but not used for cropland area fractions). private String faoName; diff --git a/src/ac/ed/lurg/yield/YieldResponsesItem.java b/src/ac/ed/lurg/yield/YieldResponsesItem.java index 95aece9d..f36251d7 100644 --- a/src/ac/ed/lurg/yield/YieldResponsesItem.java +++ b/src/ac/ed/lurg/yield/YieldResponsesItem.java @@ -54,7 +54,7 @@ public class YieldResponsesItem implements RasterItem { YieldResponsesItem item = new YieldResponsesItem(); for (CropType crop : CropType.values()) { for (YieldType yieldType : YieldType.values()) { - item.setYield(yieldType, crop, 0.0); + item.setYield(yieldType, crop, 0.001); // Needs to be non-zero otherwise GAMS will fail } } return item; -- GitLab