diff --git a/GAMS/IntExtOpt.gms b/GAMS/IntExtOpt.gms index fa8a5eff4e543aae211ff84287956a388c2b096c..a076089a76d876346b497ffefdc149531045f95a 100644 --- a/GAMS/IntExtOpt.gms +++ b/GAMS/IntExtOpt.gms @@ -91,8 +91,6 @@ $gdxin demand(cereal_crop) = demand('cereals') * minDemandPerCereal(cereal_crop); demand(oilpulse_crop) = demand('oilcropspulses') * minDemandPerOilcrop(oilpulse_crop); - previousCropArea(crop_less_pasture, location) = previousCropArea(crop_less_pasture, location) * (1.0 - unhandledCropRate); - PARAMETER cropDM(crop) kg DM per kg of feed the conversion from feed to meat is done in the R animal product index. Pasture is in DM terms already / wheat 0.87 maize 0.86 @@ -111,8 +109,8 @@ $gdxin oilcrops 0.2 pulses 0.31 starchyRoots 3.14 - fruitveg 4.0 - sugar 3.0 + fruitveg 4.5 + sugar 3.8 energyCrops 0.34 / ; PARAMETER baseCost(crop); @@ -166,8 +164,8 @@ $gdxin MAX_IRRIG_INTENSITY_CONSTRAINT(crop, location) constraint on maximum irrigation intensity MAX_OTHER_INTENSITY_CONSTRAINT(crop, location) IRRIGATION_CONSTRAINT(location) constraint on water usage - FERT_RATE_INCREASE_CONSTRAINT - IRRIG_RATE_INCREASE_CONSTRAINT +* FERT_RATE_INCREASE_CONSTRAINT +* IRRIG_RATE_INCREASE_CONSTRAINT NET_SUPPLY_EQ(crop) calc net supply for crops CROP_DEMAND_CONSTRAINT(crop) satisfy demand for individual crops @@ -227,14 +225,14 @@ $gdxin MAX_IRRIG_INTENSITY_CONSTRAINT(crop, location) .. irrigI(crop, location) =L= 1; MAX_OTHER_INTENSITY_CONSTRAINT(crop, location) .. otherIntensity(crop, location) =L= 1; - IRRIGATION_CONSTRAINT(location) .. irrigConstraint(location) * suitableLandArea(location) * (1.0 - unhandledCropRate) =G= + IRRIGATION_CONSTRAINT(location) .. irrigConstraint(location) * suitableLandArea(location) =G= sum(crop, irrigMaxRate(crop, location) * irrigI(crop, location) * cropArea(crop, location)); - FERT_RATE_INCREASE_CONSTRAINT .. sum((crop, location), fertI(crop, location) * cropArea(crop, location)) =L= - sum((crop, location), previousFertIntensity(crop, location) * previousCropArea(crop, location)) * (1 + maxFertChange); +* FERT_RATE_INCREASE_CONSTRAINT .. sum((crop, location), fertI(crop, location) * cropArea(crop, location)) =L= +* sum((crop, location), previousFertIntensity(crop, location) * previousCropArea(crop, location)) * (1 + maxFertChange); - IRRIG_RATE_INCREASE_CONSTRAINT .. sum((crop, location), irrigI(crop, location) * irrigMaxRate(crop, location) * cropArea(crop, location)) =L= - sum((crop, location), previousIrrigIntensity(crop, location) * irrigMaxRate(crop, location) * previousCropArea(crop, location)) * (1 + maxIrrigChange); +* IRRIG_RATE_INCREASE_CONSTRAINT .. sum((crop, location), irrigI(crop, location) * irrigMaxRate(crop, location) * cropArea(crop, location)) =L= +* sum((crop, location), previousIrrigIntensity(crop, location) * irrigMaxRate(crop, location) * previousCropArea(crop, location)) * (1 + maxIrrigChange); *************** Crop supply ************************* @@ -261,9 +259,9 @@ $gdxin ************** Land Cover ***************************** - SETASIDE_AREA_CALC(location) .. cropArea('setaside', location) =E= sum(crop_less_pasture_setaside, cropArea(crop_less_pasture_setaside, location)) * setAsideRate; + SETASIDE_AREA_CALC(location) .. cropArea('setaside', location) =E= sum(crop_less_pasture_setaside, cropArea(crop_less_pasture_setaside, location)) * (setAsideRate + unhandledCropRate); - CROPLAND_LAND_COVER_CALC(location) .. landCoverArea('cropland', location) =E= sum(crop_less_pasture, cropArea(crop_less_pasture, location)) / (1.0 - unhandledCropRate); + CROPLAND_LAND_COVER_CALC(location) .. landCoverArea('cropland', location) =E= sum(crop_less_pasture, cropArea(crop_less_pasture, location)); PASTURE_LAND_COVER_CALC(location) .. landCoverArea('pasture', location) =E= cropArea('pasture', location); @@ -363,7 +361,7 @@ $gdxin totalProd('monogastrics') = meatEfficency*(sum(feed_crop, monogastricFeed.l(feed_crop) * cropDM(feed_crop))); * Cost based on adjusted area - cropArea.l(crop_less_pasture, location) = cropArea.l(crop_less_pasture, location) / (1.0 - unhandledCropRate); + cropArea.l(crop_less_pasture, location) = cropArea.l(crop_less_pasture, location); totalProdCost(crop) = sum(location, unitCost.l(crop, location) * cropArea.l(crop, location)); totalCropland(location) = sum(crop_less_pasture, cropArea.l(crop_less_pasture, location)); totalArea(crop) = sum(location, cropArea.l(crop, location)); diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java index 797bb299fa35f3dc5cdb5baf6da15e1a4090e3a6..6fe441a2a455d715f664f4b4f75281871dceab83 100755 --- a/src/ac/ed/lurg/ModelConfig.java +++ b/src/ac/ed/lurg/ModelConfig.java @@ -200,15 +200,15 @@ public class ModelConfig { public static final String YIELD_FILENAME = getProperty("YIELD_FILENAME", "yield.out"); public static final boolean PASTURE_FERT_RESPONSE_FROM_LPJ = getBooleanProperty("PASTURE_FERT_RESPONSE_FROM_LPJ", false);; - public static final double CALIB_FACTOR_CEREAL_C3 = getDoubleProperty("CALIB_FACTOR_CEREAL_C3", 1.11); - public static final double CALIB_FACTOR_CEREAL_C4 = getDoubleProperty("CALIB_FACTOR_CEREAL_C4", 0.679); - public static final double CALIB_FACTOR_MISCANTHUS = getDoubleProperty("CALIB_FACTOR_MISCANTHUS", 2.148); - public static final double CALIB_FACTOR_RICE = getDoubleProperty("CALIB_FACTOR_RICE", 0.918); - public static final double CALIB_FACTOR_OILCROPS = getDoubleProperty("CALIB_FACTOR_OILCROPS", 1.53); - public static final double CALIB_FACTOR_PULSES = getDoubleProperty("CALIB_FACTOR_PULSES", 1.16); - public static final double CALIB_FACTOR_STARCHY_ROOTS = getDoubleProperty("CALIB_FACTOR_STARCHY_ROOTS",5.14); - public static final double CALIB_FACTOR_FRUITVEG = getDoubleProperty("CALIB_FACTOR_FRUITVEG",4.03); - public static final double CALIB_FACTOR_SUGAR = getDoubleProperty("CALIB_FACTOR_SUGAR", 1.02); + public static final double CALIB_FACTOR_CEREAL_C3 = getDoubleProperty("CALIB_FACTOR_CEREAL_C3", 0.904); + public static final double CALIB_FACTOR_CEREAL_C4 = getDoubleProperty("CALIB_FACTOR_CEREAL_C4", 0.504); + public static final double CALIB_FACTOR_MISCANTHUS = getDoubleProperty("CALIB_FACTOR_MISCANTHUS", 2.047); + public static final double CALIB_FACTOR_RICE = getDoubleProperty("CALIB_FACTOR_RICE", 0.978); + public static final double CALIB_FACTOR_OILCROPS = getDoubleProperty("CALIB_FACTOR_OILCROPS", 1.0); + public static final double CALIB_FACTOR_PULSES = getDoubleProperty("CALIB_FACTOR_PULSES", 0.347); + public static final double CALIB_FACTOR_STARCHY_ROOTS = getDoubleProperty("CALIB_FACTOR_STARCHY_ROOTS",4.679); + public static final double CALIB_FACTOR_FRUITVEG = getDoubleProperty("CALIB_FACTOR_FRUITVEG",3.377); + public static final double CALIB_FACTOR_SUGAR = getDoubleProperty("CALIB_FACTOR_SUGAR", 1.0); public static final double CALIB_FACTOR_PASTURE = getDoubleProperty("CALIB_FACTOR_PASTURE", 1.0); public static final String C3_CEREALS_COLUMN = getProperty("C3_CEREALS_COLUMN", "CerealsC3"); @@ -217,19 +217,19 @@ public class ModelConfig { public static final String PULSES_COLUMN = getProperty("PULSES_COLUMN", "Pulses"); public static final String OILCROPS_COLUMN = getProperty("OILCROPS_COLUMN", "Oilcrops"); public static final String STARCHY_ROOTS_COLUMN = getProperty("STARCHY_ROOTS_COLUMN", "StarchyRoots"); - public static final String FRUITVEG_COLUMN = getProperty("FRUITVEG_COLUMN", "Oilcrops"); - public static final String SUGAR_COLUMN = getProperty("SUGAR_COLUMN", "Oilcrops"); - public static final String PASTURE_C3_COLUMN = getProperty("PASTURE_C3_COLUMN", "PC3G"); - public static final String PASTURE_C4_COLUMN = getProperty("PASTURE_C4_COLUMN", "PC4G"); + public static final String FRUITVEG_COLUMN = getProperty("FRUITVEG_COLUMN", "FruitAndVeg"); + public static final String SUGAR_COLUMN = getProperty("SUGAR_COLUMN", "Sugar"); + public static final String PASTURE_C3_COLUMN = getProperty("PASTURE_C3_COLUMN", "C3G_pas"); + public static final String PASTURE_C4_COLUMN = getProperty("PASTURE_C4_COLUMN", "C4G_pas"); // These are production prices in PLUM style feed equivalent terms public static final double INITIAL_PRICE_SHIFT = getDoubleProperty("INITIAL_PRICE_SHIFT", 1.0); - public static final double INITAL_PRICE_WHEAT = getDoubleProperty("INITAL_PRICE_WHEAT", 0.157 * ModelConfig.INITIAL_PRICE_SHIFT); - public static final double INITAL_PRICE_MAIZE = getDoubleProperty("INITAL_PRICE_MAIZE", 0.152 * ModelConfig.INITIAL_PRICE_SHIFT); - public static final double INITAL_PRICE_RICE = getDoubleProperty("INITAL_PRICE_RICE", 0.182 * ModelConfig.INITIAL_PRICE_SHIFT); - public static final double INITAL_PRICE_OILCROPS = getDoubleProperty("INITAL_PRICE_OILCROPS", (0.820 * .4 + 0.314 * .6) * 0.3 * ModelConfig.INITIAL_PRICE_SHIFT); - public static final double INITAL_PRICE_PULSES = getDoubleProperty("INITAL_PRICE_PULSES", 0.2 * ModelConfig.INITIAL_PRICE_SHIFT); - public static final double INITAL_PRICE_STARCHYROOTS = getDoubleProperty("INITAL_PRICE_STARCHYROOTS", 0.1 * ModelConfig.INITIAL_PRICE_SHIFT); + public static final double INITAL_PRICE_WHEAT = getDoubleProperty("INITAL_PRICE_WHEAT", 0.113 * ModelConfig.INITIAL_PRICE_SHIFT); + 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_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 public static final double INITAL_PRICE_ENERGYCROPS = getDoubleProperty("INITAL_PRICE_ENERGYCROPS", 0.04 * ModelConfig.INITIAL_PRICE_SHIFT); @@ -358,7 +358,7 @@ public class ModelConfig { // Temporal configuration public static final int START_TIMESTEP = getIntProperty("START_TIMESTEP", 0); - public static final int END_TIMESTEP = getIntProperty("END_TIMESTEP", 80); + public static final int END_TIMESTEP = getIntProperty("END_TIMESTEP", 81); public static final int TIMESTEP_SIZE = getIntProperty("TIMESTEP_SIZE", 1); public static final int BASE_YEAR = getIntProperty("BASE_YEAR", 2019); @@ -394,7 +394,7 @@ public class ModelConfig { public static final double PASTURE_HARVEST_FRACTION = getDoubleProperty("PASTURE_HARVEST_FRACTION", 0.5); public static final double MEAT_EFFICIENCY = getDoubleProperty("MEAT_EFFICIENCY", 1.0); // 'meat' is includes feed conversion ratio already, this is tech. change or similar - public static final double IRRIGIATION_EFFICIENCY = getDoubleProperty("IRRIGIATION_EFFICIENCY", 0.5); + public static final double IRRIGIATION_EFFICIENCY = getDoubleProperty("IRRIGIATION_EFFICIENCY", 0.6); public static final int ELLIOTT_BASEYEAR = 2010; public static final double ENVIRONMENTAL_WATER_CONSTRAINT = getDoubleProperty("ENVIRONMENTAL_WATER_CONSTRAINT", 0.5); // change with care, as due to normalisation it might not have the impact you first imagine public static final double OTHER_WATER_USE_FACTOR = getDoubleProperty("OTHER_WATER_USE_FACTOR", 1.0); @@ -404,10 +404,10 @@ public class ModelConfig { public static final String CONVERSION_COST_FILE = getProperty("CONVERSION_COST_FILE", DATA_DIR + File.separator + "conversion_costs.csv"); // cost of converting from one land cover to another, $1000/ha public static final double LAND_CONVERSION_COST_FACTOR = getDoubleProperty("LAND_CONVERSION_COST_FACTOR", 1.0); // for monte carlo public static final double AGRI_LAND_EXPANSION_COST_FACTOR = getDoubleProperty("AGRI_LAND_EXPANSION_COST_FACTOR", 1.0); // for monte carlo - public static final double CROPLAND_CONVERSION_COST = getDoubleProperty("CROPLAND_CONVERSION_COST", 0.33 * LAND_CONVERSION_COST_FACTOR); - public static final double PASTURE_CONVERSION_COST = getDoubleProperty("PASTURE_CONVERSION_COST", 0.2 * LAND_CONVERSION_COST_FACTOR); - public static final double FOREST_CONVERSION_COST = getDoubleProperty("FOREST_CONVERSION_COST", 0.116 * LAND_CONVERSION_COST_FACTOR); - public static final double NATURAL_CONVERSION_COST = getDoubleProperty("NATURAL_CONVERSION_COST", 0.016 * LAND_CONVERSION_COST_FACTOR); + public static final double CROPLAND_CONVERSION_COST = getDoubleProperty("CROPLAND_CONVERSION_COST", 0.11 * LAND_CONVERSION_COST_FACTOR); + public static final double PASTURE_CONVERSION_COST = getDoubleProperty("PASTURE_CONVERSION_COST", 0.08 * LAND_CONVERSION_COST_FACTOR); + public static final double FOREST_CONVERSION_COST = getDoubleProperty("FOREST_CONVERSION_COST", 0.1 * LAND_CONVERSION_COST_FACTOR); + public static final double NATURAL_CONVERSION_COST = getDoubleProperty("NATURAL_CONVERSION_COST", 0.015 * LAND_CONVERSION_COST_FACTOR); public static final double TECHNOLOGY_CHANGE_ANNUAL_RATE = getDoubleProperty("TECHNOLOGY_CHANGE_ANNUAL_RATE", 0.002); public static final int TECHNOLOGY_CHANGE_START_STEP = getIntProperty("TECHNOLOGY_CHANGE_START_STEP", 0); @@ -442,15 +442,15 @@ public class ModelConfig { // 1105.6 Mha is harvested in crops we represent. crop_prod[Country =="World" & Item %in% itemGroupMapping$cropProdItem & Year == 2011, sum(area)] // extract values by running AltLURead.R and common.R // So we do not represent crops covering (1341.911-1239.03)/1547.464=6.65% of cropland. Additionally 10.3% of cropland is set aside, fallow or failed crops, - public static final double UNHANDLED_CROP_RATE = getDoubleProperty("UNHANDLED_CROP_RATE", 0.0665); // mostly forage crops + public static final double UNHANDLED_CROP_RATE = getDoubleProperty("UNHANDLED_CROP_RATE", 0.0498); // mostly forage crops public static final double SETASIDE_RATE = getDoubleProperty("SETASIDE_RATE", 0.103); // includes aside, fallow and failed cropland areas - public static final double OTHER_INTENSITY_COST = getDoubleProperty("OTHER_INTENSITY_COST", 0.8); + public static final double OTHER_INTENSITY_COST = getDoubleProperty("OTHER_INTENSITY_COST", 0.6); public static final double OTHER_INTENSITY_PARAM = getDoubleProperty("OTHER_INTENSITY_PARAM", 3.22); - public static final double IRRIG_COST_SCALE_FACTOR = getDoubleProperty("IRRIG_COST_SCALE_FACTOR", 0.0003); + public static final double IRRIG_COST_SCALE_FACTOR = getDoubleProperty("IRRIG_COST_SCALE_FACTOR", 0.0002); 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.4); // $500/t, 18% N/t + 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_MAX_COST = FERTILISER_COST_PER_T * MAX_FERT_AMOUNT/1000; public static final double DOMESTIC_PRICE_MARKUP = getDoubleProperty("DOMESTIC_PRICE_MARKUP", 1.0); @@ -458,12 +458,13 @@ public class ModelConfig { public static final double TRANSPORT_COST = getDoubleProperty("TRANSPORT_COST", 0.1); // 10% transport cost public static final double TRADE_BARRIER_FACTOR_DEFAULT = getDoubleProperty("TRADE_BARRIER_FACTOR_DEFAULT", 0.2); // price factor in international trade, transport cost and real trade barriers public static final double TRADE_BARRIER_MULTIPLIER = getDoubleProperty("TRADE_BARRIER_MULTIPLIER", 1.0); - public static final double TRADE_BARRIER_OFFSET_RUMINANTS = getDoubleProperty("TRADE_BARRIER_OFFSET_RUMINANTS", 0.0); // additional trade barrier for ruminants (e.g. 0.1 = 10 percentage points) public static final boolean ACTIVE_TRADE_BARRIERS = getBooleanProperty("ACTIVE_TRADE_BARRIERS", true); // if set to true read in barrier information from file, otherwise use default as above public static final double TRADE_BARRIER_ENERGY_CROPS = getDoubleProperty("TRADE_BARRIER_ENERGY_CROPS", 0.01); // price factor in international trade, transport cost and real trade barriers public static final boolean SHOCKS_POSSIBLE = getBooleanProperty("SHOCKS_POSSIBLE", false); public static final double YIELD_SHOCK_MAGNIFIER = getDoubleProperty("YIELD_SHOCK_MAGNIFIER", 1.0); + public static final boolean ENABLE_SUBSIDIES = getBooleanProperty("ENABLE_SUBSIDIES", false); // currently disabled by default as causes issues. + public static final boolean PROTECTED_AREAS_ENABLED = getBooleanProperty("PROTECTED_AREAS_ENABLED", true); public static final double MIN_NATURAL_RATE = getDoubleProperty("MIN_NATURAL_RATE", 0.05); public static final double MAX_GROSS_LCC_RATE = getDoubleProperty("MAX_GROSS_LCC_RATE", 0.01); // 1% gross change @@ -480,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", 0);; + 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 diff --git a/src/ac/ed/lurg/country/SubsidyRateManager.java b/src/ac/ed/lurg/country/SubsidyRateManager.java index 2c5cae60db240f89c47141c507e69fb5769bfe6e..e0167ed6dc55580872b7af38a258728a244f5973 100644 --- a/src/ac/ed/lurg/country/SubsidyRateManager.java +++ b/src/ac/ed/lurg/country/SubsidyRateManager.java @@ -43,6 +43,13 @@ public class SubsidyRateManager { private Map<CropType, Double> getSubsidyRates(SingleCountry c) { Map<CropType, Double> rates = new HashMap<CropType, Double>(); + if (!ModelConfig.ENABLE_SUBSIDIES) { + for (CropType crop : CropType.getAllItems()) { + rates.put(crop, 0.0); + } + return rates; + } + for (CropType crop : CropType.getAllItems()) { Map<String, String> queryMap = new HashMap<String, String>(); queryMap.put("Iso3", c.getCountryCode()); diff --git a/src/ac/ed/lurg/country/TradeManager.java b/src/ac/ed/lurg/country/TradeManager.java index 0cc3242fc8a0cffedd6d63dfb54ec9720f9c597e..632eda45c3289f6251107361bfecc48684a266de 100644 --- a/src/ac/ed/lurg/country/TradeManager.java +++ b/src/ac/ed/lurg/country/TradeManager.java @@ -42,8 +42,6 @@ public class TradeManager { tradeMap.get(cc).put(CropType.ENERGY_CROPS, ModelConfig.TRADE_BARRIER_ENERGY_CROPS); } - tradeMap.get(cc).incrementValue(CropType.RUMINANTS, ModelConfig.TRADE_BARRIER_OFFSET_RUMINANTS); - return tradeMap.get(cc); } diff --git a/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java b/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java index 7b26c2294832860fd2d5254f630b4e9928118f83..235ab9c03dbd80a2695fa2d879cd343ff7702d96 100644 --- a/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java +++ b/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java @@ -170,10 +170,14 @@ public class GamsRasterOptimiser { LandCoverType fromLc = item.getFromLandCover(); LandCoverType toLc = item.getToLandCover(); double totalChangeArea = item.getArea(); + if (totalChangeArea < 1e-6) + continue; + double totalArea = 0; for (RasterKey key : keys) { totalArea += luRaster.get(key).getLandCoverArea(fromLc, LandProtectionType.CONVERTIBLE); } + for (RasterKey key : keys) { double area = luRaster.get(key).getLandCoverArea(fromLc, LandProtectionType.CONVERTIBLE); double fraction = area / totalArea;