diff --git a/GAMS/IntExtOpt.gms b/GAMS/IntExtOpt.gms
index e73089b8ae08d81d3b73fd8c876029ecd6cdebae..56a3f4b935609c82453d518d057c4b40f0e4f867 100644
--- a/GAMS/IntExtOpt.gms
+++ b/GAMS/IntExtOpt.gms
@@ -11,6 +11,7 @@
 
  SET land_cover / cropland, pasture, timberForest, carbonForest, natural, naturalNew /;
  SET forested(land_cover) / timberForest, carbonForest, natural /;
+ SET managed_forest(land_cover) / timberForest, carbonForest /;
  SET natural_forest(land_cover) / carbonForest, natural /;
  SET non_timber_forest(land_cover) / cropland, pasture, carbonForest, natural, naturalNew /;
  SET exc_natural(land_cover) / cropland, pasture, timberForest, naturalNew /;
@@ -72,7 +73,6 @@
  SCALAR forestRotationPeriod;
  SCALAR timberMaxNetImport;
  SCALAR timberMinNetImport;
- SCALAR loggingCost;
 
 *$gdxin "C:\Users\Bart\Documents\PhD\GAMS testing area\_gams_java_gdb1.gdx"
 $gdxin %gdxincname%
@@ -82,7 +82,7 @@ $load yieldNone, yieldFertOnly, yieldIrrigOnly, yieldBoth, yieldShock
 $load fertParam, irrigParam, otherIParam, exportPrices, importPrices, maxNetImport, minNetImport, unhandledCropRate, setAsideRate, maxLandExpansionRate, subsidyRate
 $load meatEfficency, otherICost, irrigCost, irrigMaxRate, irrigConstraint, fertiliserUnitCost, domesticPriceMarkup, minDemandPerCereal, minDemandPerOilcrop, seedAndWasteRate
 $load previousLandCoverArea, carbonFluxRate, woodYieldLuc, carbonPrice, woodPrice
-$load conversionCost, timberForestYield, woodYieldRota, infrastructureCost, netPresentValueFactor, forestRotationPeriod, timberMaxNetImport, timberMinNetImport, loggingCost
+$load conversionCost, timberForestYield, woodYieldRota, infrastructureCost, netPresentValueFactor, forestRotationPeriod, timberMaxNetImport, timberMinNetImport
 $gdxin
 
  SCALAR delta "use to smooth power function see 7.5 www.gams.com/dd/docs/solversconopt.pdf" / 0.00000000001 /;
@@ -121,11 +121,12 @@ $gdxin
  baseCost('pasture') = 0.04;
  otherIntCost('pasture') = 0.8 + otherICost;
 
- SCALAR forestExpansionMaxRate / 0.0175 /;
+ SCALAR naturalDecreaseMaxRate / 1 /;
+ SCALAR naturalWoodHarvestMaxRate / 0.02 /;
  woodYieldLuc('carbonForest', 'naturalNew', location) = woodYieldLuc('carbonForest', 'pasture', location);
  woodYieldLuc('natural', 'naturalNew', location) = woodYieldLuc('natural', 'pasture', location);
  conversionCost(land_cover, 'naturalNew') = conversionCost(land_cover, 'natural');
- conversionCost('natural', 'naturalNew') =  conversionCost('carbonForest', 'naturalNew');
+ conversionCost('natural', 'naturalNew') =  0;
 
  woodYieldLuc('carbonForest', land_cover, location) = 0;
 
@@ -134,6 +135,10 @@ $gdxin
  carbonFluxRate('pasture', 'naturalNew', location) = carbonFluxRate('pasture', 'natural', location);
  carbonFluxRate('cropland', 'naturalNew', location) = carbonFluxRate('cropland', 'natural', location);
 
+ SCALAR forestRotationCost;
+ forestRotationCost = 0.1;
+ SCALAR woodHarvestParam / 1.897 /;
+
  VARIABLES
        cropArea(crop, location)           total area for crops - Mha
        fertI(crop, location)              fertilizer intensity for each crop - factor between 0 and 1
@@ -152,9 +157,10 @@ $gdxin
        totalConversionCost(location)      land cover conversion cost - $1000 per ha
        woodHarvestLuc(location)           wood harvested due to land cover change - Mt C-eq
        woodHarvestRota(location)          wood harvested from timber forest rotation - Mt C-eq
-       totalWoodHarvest                   total wood harvested from all activities - Mt C-eq
+       totalWoodHarvest(location)                   total wood harvested from all activities - Mt C-eq
        woodExported                       total wood sold - Mt C-eq
        carbonFlux(location)               total carbon flux  - Mt C
+       loggingCost(location)              cost of logging forest
 *       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;
 
@@ -190,20 +196,20 @@ $gdxin
        LAND_COVER_CHANGE_CALC(land_cover, location)     calc land cover change
        LAND_COVER_CHANGE_CONSTRAINT(land_cover, location) conservation of land area
        NATURAL_CONVERSION_CONSTRAINT(exc_natural, location) can't create primary natural area
-*       FOREST_EXPANSION_CONSTRAINT(forested, location)    constraint on forest expansion
-*       FOREST_CONTRACTION_CONSTRAINT(forested, location)  constraint on forest contraction
        NATURAL_CONTRACTION_CONSTRAINT(location)
        CONVERSION_COST(location)                          cost of land cover conversion
 
        WOOD_HARVEST_LUC_CALC(location)                    calc wood harvested from LUC
        WOOD_HARVEST_ROTA_CALC(location)                   calc wood harvested from timber forest rotation
-       TOTAL_WOOD_HARVEST_CALC                            total wood harvested
-*       WOOD_MIN_EXPORT_CONSTRAINT                         constraint on minimum wood export
+       TOTAL_WOOD_HARVEST_CALC(location)                            total wood harvested
+       NATURAL_WOOD_HARVEST_CONSTRAINT(location)
        WOOD_MAX_EXPORT_CONSTRAINT                         constraint on maximum wood export
-*       WOOD_MAX_TRADE_CONSTRAINT
+       WOOD_MIN_TRADE_CONSTRAINT                          constraint on minimum wood export
+       WOOD_MAX_TRADE_CONSTRAINT
        WOOD_ROTA_EXPORT_CONSTRAINT                        must export all wood produced from timber forest rotation
-*       WOOD_ROTA_TO_LUC_CONSTRAINT
 
+*       WOOD_ROTA_TO_LUC_CONSTRAINT
+       LOGGING_COST_CALC(location)
        CARBON_FLUX_CALC(location)                         calc carbon flux
        COST_EQ                                        total cost objective function;
 
@@ -263,35 +269,39 @@ $gdxin
 
  NATURAL_CONVERSION_CONSTRAINT(exc_natural, location) .. landCoverChange(exc_natural, 'natural', location) =E= 0;
 
-* FOREST_EXPANSION_CONSTRAINT(forested, location) .. landCoverArea(forested, location) =L= previousLandCoverArea(forested, location) + suitableLandArea(location) * forestExpansionMaxRate;
-* FOREST_CONTRACTION_CONSTRAINT(forested, location) .. landCoverArea(forested, location) =G= previousLandCoverArea(forested, location) - suitableLandArea(location) * forestExpansionMaxRate;
-
- NATURAL_CONTRACTION_CONSTRAINT(location) .. landCoverArea('natural', location) =G= previousLandCoverArea('natural', location) * (1 - forestExpansionMaxRate);
+ NATURAL_CONTRACTION_CONSTRAINT(location) .. landCoverArea('natural', location) =G= previousLandCoverArea('natural', location) * (1 - naturalDecreaseMaxRate);
 
  CONVERSION_COST(location) .. totalConversionCost(location) =E= sum((land_cover_before, land_cover_after), landCoverChange(land_cover_before, land_cover_after, location) * conversionCost(land_cover_before, land_cover_after)) +
                                                                  sum(exc_natural, landCoverChange('natural', exc_natural, location) * infrastructureCost(location));
 
 * Wood from land cover change
- WOOD_HARVEST_LUC_CALC(location) .. woodHarvestLuc(location) =E= sum((land_cover_before, land_cover_after), landCoverChange(land_cover_before, land_cover_after, location) * woodYieldLuc(land_cover_before, land_cover_after, location));
+* WOOD_HARVEST_LUC_CALC(location) .. woodHarvestLuc(location) =E= sum((land_cover_before, land_cover_after), landCoverChange(land_cover_before, land_cover_after, location) * woodYieldLuc(land_cover_before, land_cover_after, location));
+
+ WOOD_HARVEST_LUC_CALC(location) .. woodHarvestLuc(location) =E= woodYieldLuc('natural', 'naturalNew', location) * landCoverChange('natural', 'naturalNew', location);
 
 * Wood from timberForest rotation  = harvest from new forest + existing forest
  WOOD_HARVEST_ROTA_CALC(location) .. woodHarvestRota(location) =E= [ sum(non_timber_forest, landCoverChange(non_timber_forest, 'timberForest', location) * woodYieldRota(non_timber_forest, 'timberForest', location)) +
                                                                      landCoverChange('timberForest', 'timberForest', location) * timberForestYield(location)
                                                                    ] / forestRotationPeriod;
 
- TOTAL_WOOD_HARVEST_CALC .. totalWoodHarvest =E= sum(location, woodHarvestLuc(location) + woodHarvestRota(location));
+ TOTAL_WOOD_HARVEST_CALC(location) .. totalWoodHarvest(location) =E= woodHarvestLuc(location) + woodHarvestRota(location);
+
+ NATURAL_WOOD_HARVEST_CONSTRAINT(location) .. woodHarvestLuc(location) =L= previousLandCoverArea('natural', location) * woodYieldLuc('natural', 'naturalNew', location) * naturalWoodHarvestMaxRate;
 
-* WOOD_MIN_EXPORT_CONSTRAINT .. 0 - woodExported =L= timberMaxNetImport;
+ WOOD_MAX_EXPORT_CONSTRAINT .. woodExported =L= sum(location, totalWoodHarvest(location));
 
- WOOD_MAX_EXPORT_CONSTRAINT .. woodExported =L= totalWoodHarvest;
+ WOOD_MIN_TRADE_CONSTRAINT .. 0 - woodExported =L= timberMaxNetImport;
 
-* WOOD_MAX_TRADE_CONSTRAINT .. 0 - woodExported =G= timberMinNetImport;
+ WOOD_MAX_TRADE_CONSTRAINT .. 0 - woodExported =G= timberMinNetImport;
 
 * Must sell timber producted in timberForest
  WOOD_ROTA_EXPORT_CONSTRAINT .. woodExported =G= sum(location, woodHarvestRota(location));
 
 * WOOD_ROTA_TO_LUC_CONSTRAINT .. sum(location, woodHarvestLuc(location)) =L= sum(location, woodHarvestRota(location)) * 2;
 
+ LOGGING_COST_CALC(location) .. loggingCost(location) =E= 0.04 + 0.06 * landCoverChange('natural', 'naturalNew', location) / [previousLandCoverArea('natural', location) + delta] *
+                                                          landCoverChange('natural', 'naturalNew', location) * woodYieldLuc('natural', 'naturalNew', location);
+
  CARBON_FLUX_CALC(location) .. carbonFlux(location) =E= sum((land_cover_before, land_cover_after), landCoverChange(land_cover_before, land_cover_after, location) * carbonFluxRate(land_cover_before, land_cover_after, location));
 
 
@@ -301,9 +311,9 @@ $gdxin
 
                SUM(import_crop, importAmount(import_crop) * importPrices(import_crop) - exportAmount(import_crop) * exportPrices(import_crop)) +
 
-               SUM(location, totalConversionCost(location)) -
+               SUM(location, totalConversionCost(location)) +
 
-               woodExported * woodPrice +
+               [SUM((managed_forest, location), landCoverArea(managed_forest, location) * forestRotationCost) - woodExported * woodPrice] + SUM(location, loggingCost(location)) +
 
                SUM(location, carbonFlux(location)) * carbonPrice
          );
@@ -320,7 +330,6 @@ $gdxin
  importAmount.L(all_types) = previousImportAmount(all_types);
  exportAmount.L(all_types) = previousExportAmount(all_types);
  woodHarvestRota.L(location) = previousLandCoverArea('timberForest', location) * timberForestYield(location) / forestRotationPeriod;
- totalWoodHarvest.L = sum(location, woodHarvestRota.L(location));
  totalConversionCost.L(location) = previousLandCoverArea('timberForest', location) * conversionCost('timberForest', 'timberForest');
 
  LAND_USE.OptFile = 1;
diff --git a/data/conversion_costs.csv b/data/conversion_costs.csv
index 5e44b81153f28bdba389d806679d0e72198b80f4..353b1a7b8a3dd375f7b6058f1df5cbf9dff3cd0e 100644
--- a/data/conversion_costs.csv
+++ b/data/conversion_costs.csv
@@ -1,26 +1,21 @@
 fromLC,toLC,Cost
-pasture,cropland,0.21
-pasture,pasture,0
+pasture,cropland,0.3
 pasture,timberForest,0.2
 pasture,carbonForest,0.2
 pasture,natural,0.2
-cropland,cropland,0
 cropland,pasture,0.4
 cropland,timberForest,0.33
 cropland,carbonForest,0.33
 cropland,natural,0.33
-timberForest,cropland,0.01
-timberForest,pasture,0.07
-timberForest,timberForest,0
-timberForest,carbonForest,0
-timberForest,natural,0
-carbonForest,cropland,0.01
-carbonForest,pasture,0.07
-carbonForest,timberForest,0
-carbonForest,carbonForest,0
-carbonForest,natural,0
-natural,cropland,0.01
-natural,pasture,0.07
-natural,timberForest,0
-natural,carbonForest,0
-natural,natural,0
+timberForest,cropland,0.206
+timberForest,pasture,0.176
+timberForest,carbonForest,0.05
+timberForest,natural,0.07
+carbonForest,cropland,0.206
+carbonForest,pasture,0.176
+carbonForest,timberForest,0.05
+carbonForest,natural,0.07
+natural,cropland,0.106
+natural,pasture,0.076
+natural,timberForest,0.07
+natural,carbonForest,0.07
diff --git a/src/ac/ed/lurg/InternationalMarket.java b/src/ac/ed/lurg/InternationalMarket.java
index cbd77efa7541fb3b9ff706e1d78bd81ac6730f90..2ebc7bf393d5b3818b77f50c7dadf2d87163f6cb 100644
--- a/src/ac/ed/lurg/InternationalMarket.java
+++ b/src/ac/ed/lurg/InternationalMarket.java
@@ -41,8 +41,8 @@ public class InternationalMarket {
 				worldPrices.put(crop, GlobalPrice.createInitial(crop.getInitialPrice(), initialStock));
 			}
 			
-			carbonPrice = GlobalPrice.createInitial(ModelConfig.CARBON_PRICE, 0);
-			timberPrice = GlobalPrice.createInitial(ModelConfig.WOOD_PRICE, 1000);
+			carbonPrice = GlobalPrice.createInitial(ModelConfig.INIT_CARBON_PRICE, 0);
+			timberPrice = GlobalPrice.createInitial(ModelConfig.INIT_WOOD_PRICE, ModelConfig.INIT_WOOD_STOCK);
 		}
 		else {
 			List<Object> deserializedPrices = deserializeGlobalPrice();
diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java
index 9788115077d73f5ca277192ebc42d8f920f2d578..8997c16f5ac2ba108634a2138c22f30657ff855c 100755
--- a/src/ac/ed/lurg/ModelConfig.java
+++ b/src/ac/ed/lurg/ModelConfig.java
@@ -422,18 +422,21 @@ public class ModelConfig {
 	public static final int DIET_CHANGE_END_YEAR = getIntProperty("DIET_CHANGE_END_YEAR", 2040);
 	public static final String TARGET_DIET_FILE = getProperty("TARGET_DIET_FILE", DATA_DIR + File.separator + "TargetDiet.txt");
 	
-	// Forestry parameters
+	// Forestry and carbon market parameters
 	public static final String CONVERSION_COST_FILE = DATA_DIR + File.separator + "conversion_costs.csv"; // cost of converting from one land cover to another, $1000/ha
 	public static final String SERIALIZED_CARBON_MARKET_FILE = CALIB_DIR + File.separator +  "CarbonMarket.ser";
 	public static final String CARBON_DEMAND_FILENAME = getProperty("CARBON_DEMAND_FILENAME", "carbon_demand.csv");
 	public static final String CARBON_DEMAND_FILE = getProperty("CARBON_DEMAND_FILE", DATA_DIR + File.separator + CARBON_DEMAND_FILENAME);
-	public static final double CARBON_PRICE = getDoubleProperty("CARBON_PRICE", 0.02); // $1000/tC-eq
+	public static final double INIT_CARBON_PRICE = getDoubleProperty("INIT_CARBON_PRICE", 0.02); // $1000/tC-eq
 	public static final String TIMBER_DEMAND_FILENAME = getProperty("TIMBER_DEMAND_FILENAME", "timber_demand.csv");
 	public static final String TIMBER_DEMAND_FILE = getProperty("TIMBER_DEMAND_FILE", DATA_DIR + File.separator + TIMBER_DEMAND_FILENAME);
-	public static final double WOOD_PRICE = getDoubleProperty("WOOD_PRICE", 0.05); // $1000/tC-eq
-	public static final int FOREST_ROTATION_PERIOD = getIntProperty("FOREST_LOCKIN_PERIOD", 20); // cannot convert forest after planting for this many years
+	public static final double INIT_WOOD_PRICE = getDoubleProperty("INIT_WOOD_PRICE", 0.05); // $1000/tC-eq
+	public static final double INIT_WOOD_STOCK = getDoubleProperty("INIT_WOOD_STOCK", 0.0); // $1000/tC-eq
+	public static final int FOREST_ROTATION_PERIOD = getIntProperty("FOREST_ROTATION_PERIOD", 30); // cannot convert forest after planting for this many years
 	public static final int NATURAL_REGROWTH_TIME = getIntProperty("NATURAL_REGROWTH_TIME", 50); // years
+	public static final double NATURAL_REGROWTH_PARAM_P = getDoubleProperty("NATURAL_REGROWTH_PARAM_P", 1.0); // Chapman-Richards paramater. Controls gradient of growth curve
+	public static final double NATURAL_REGROWTH_PARAM_K = -Math.log(1 - Math.pow(0.95, (1 / NATURAL_REGROWTH_PARAM_P))) / NATURAL_REGROWTH_TIME; // Calc Chapman-Richards paramater. 95% yield reached at NATURAL_REGROWTH_TIME
 	public static final double DISCOUNT_RATE = getDoubleProperty("DISCOUNT_RATE", 0.05);
-	public static final double TREE_PLANTING_COST = getDoubleProperty("TREE_PLANTING_COST", 1.0); // $1000/ha
+	public static final double TREE_PLANTING_COST = getDoubleProperty("TREE_PLANTING_COST", 1.2); // $1000/ha
 	public static final double TREE_LOGGING_COST = getDoubleProperty("TREE_LOGGING_COST", 0.02); // $1000/tC-eq
 }
diff --git a/src/ac/ed/lurg/country/CountryAgent.java b/src/ac/ed/lurg/country/CountryAgent.java
index 277042c354a645afe95e5f4a3170797293fec20c..6ed73fec233ba2a9f9079a326828838f24580d29 100644
--- a/src/ac/ed/lurg/country/CountryAgent.java
+++ b/src/ac/ed/lurg/country/CountryAgent.java
@@ -233,14 +233,7 @@ public class CountryAgent extends AbstractCountryAgent {
 		// Timber import/export constraints
 		TradeConstraint timberTradeConstraint;
 		{
-			double baseTrade;
-			if (ModelConfig.IS_CALIBRATION_RUN && currentTimestep.isInitialTimestep()) {
-				double forestedAndNaturalArea = LandUseItem.getTotalLandCover(previousGamsRasterOutput.getLandUses().values(), LandCoverType.NATURAL) +
-						LandUseItem.getTotalLandCover(previousGamsRasterOutput.getLandUses().values(), LandCoverType.TIMBER_FOREST);
-				baseTrade = -timberDemandIncrease * forestedAndNaturalArea / 4000;
-			} else {
-				baseTrade = -getTimberProduction(); // net imports negative as all exported
-			}
+			double baseTrade = -getTimberProduction(); // net imports negative as all exported
 			double countryArea = LandUseItem.getTotalLandArea(previousGamsRasterOutput.getLandUses().values());
 			double changeUp = 0.0;
 			double changeDown = 0.0;
@@ -249,7 +242,14 @@ public class CountryAgent extends AbstractCountryAgent {
 				changeUp = baseTrade * allowedImportChange;
 			}
 			// TODO add initial timber production
-			changeDown = Math.min(baseTrade * allowedImportChange, -(timberDemandIncrease * countryArea / 15000 * 2));
+			if (ModelConfig.IS_CALIBRATION_RUN && currentTimestep.isInitialTimestep()) {
+				double forestedAndNaturalArea = LandUseItem.getTotalLandCover(previousGamsRasterOutput.getLandUses().values(), LandCoverType.NATURAL) +
+						LandUseItem.getTotalLandCover(previousGamsRasterOutput.getLandUses().values(), LandCoverType.TIMBER_FOREST);
+				changeDown = -timberDemandIncrease * forestedAndNaturalArea / 4000;
+				if (ModelConfig.DEBUG_LIMIT_COUNTRIES) {changeDown = -timberDemandIncrease;}
+			} else {
+				changeDown = Math.min(baseTrade * allowedImportChange, -(timberDemandIncrease * countryArea / 15000 * 2));
+			}
 			changeUp = baseTrade * allowedImportChange;
 
 			timberTradeConstraint = new TradeConstraint(baseTrade + changeDown, baseTrade - changeUp);
diff --git a/src/ac/ed/lurg/country/ForestManager.java b/src/ac/ed/lurg/country/ForestManager.java
index 5d8b4bf296252e5e0e4bc39197d4f1135f7e031e..1e582d7c1da5c6e9d48a231098b81f66841e29ff 100644
--- a/src/ac/ed/lurg/country/ForestManager.java
+++ b/src/ac/ed/lurg/country/ForestManager.java
@@ -72,11 +72,6 @@ public class ForestManager {
 				otherNaturalArea.put(clusterId, otherNaturalAreaSoFar + luItem.getUnprotectedLandCoverArea(LandCoverType.NATURAL) * (1 - naturalForestFraction)); // Natural is other natural + unmanaged forest so need to subtract the latter
 				managedForestArea.put(clusterId, timberForestAreaSoFar + luItem.getUnprotectedLandCoverArea(LandCoverType.TIMBER_FOREST));
 				timberYieldTimesArea.put(clusterId, timberYieldSoFar + luItem.getUnprotectedLandCoverArea(LandCoverType.TIMBER_FOREST) * timberYieldThisTime);
-				
-				/*
-				if (clusterId == 3) {
-					LogWriter.println(""+timberYieldThisTime+","+timberYieldSoFar+","+luItem.getLandCoverArea(LandCoverType.TIMBER_FOREST)+","+timberForestAreaSoFar);
-				}*/
 
 			} catch (Exception e) {
 				LogWriter.print(e);
@@ -120,7 +115,9 @@ public class ForestManager {
 	
 	// Calculates wood yield factor for natural areas based on age
 	private double naturalWoodYieldFunction(double age) {
-		return Math.min(age, ModelConfig.NATURAL_REGROWTH_TIME) / ModelConfig.NATURAL_REGROWTH_TIME;
+		//return Math.min(age, ModelConfig.NATURAL_REGROWTH_TIME) / ModelConfig.NATURAL_REGROWTH_TIME;
+		// Chapman-Richards function
+		return Math.pow((1 - Math.exp(-ModelConfig.NATURAL_REGROWTH_PARAM_K * age)), ModelConfig.NATURAL_REGROWTH_PARAM_P);
 	}
 	
 	public Map<Integer, Double> getNaturalYieldFactorForTimestep(Timestep timestep) {
@@ -143,13 +140,15 @@ public class ForestManager {
 	
 	public void updateForestHistory(ArrayList<LandCoverChangeItem> gamsLandCoverChanges, Map<Integer, Double> baseTimberYield) {
 		
-		// Update timber forest yield
-		for (Integer locId : timberForestYield.keySet()) {
-			double area = timberForestArea.get(locId);
-			double currentYield = timberForestYield.get(locId);
-			double baseYield = baseTimberYield.get(locId);
-			double updatedYield = updateTimberForestYield(area, currentYield, baseYield);
-			timberForestYield.put(locId, updatedYield);
+		if (!ModelConfig.IS_CALIBRATION_RUN) {
+			// Update timber forest yield - the yield effect of previous land use gradually decreases
+			for (Integer locId : timberForestYield.keySet()) {
+				double area = timberForestArea.get(locId);
+				double currentYield = timberForestYield.get(locId);
+				double baseYield = baseTimberYield.get(locId);
+				double updatedYield = updateTimberForestYield(area, currentYield, baseYield);
+				timberForestYield.put(locId, updatedYield);
+			}
 		}
 		
 		// Removed timber forest
@@ -161,6 +160,7 @@ public class ForestManager {
 				timberForestArea.put(locId, currentArea - removedArea);
 			}
 		}
+		
 		// New timber forest
 		for (LandCoverChangeItem item : gamsLandCoverChanges) {		
 			if (item.getToLandCover().equals(LandCoverType.TIMBER_FOREST.getName()) && !item.getFromLandCover().equals(LandCoverType.TIMBER_FOREST.getName())) {
@@ -182,6 +182,10 @@ public class ForestManager {
 		// Safety check
 		timberForestArea.forEach((k, v) -> {if (v < 0) LogWriter.printlnError("ForestManager.updateForestHistory(): timberForestArea < 0");});
 		
+		// Don't update natural areas during calibration run
+		if (ModelConfig.IS_CALIBRATION_RUN)
+			return;
+		
 		// Update natural areas
 		Map<Integer, Double> newNaturalArea = new HashMap<Integer, Double>();
 		Map<Integer, Double> clearedNaturalArea = new HashMap<Integer, Double>();
@@ -193,10 +197,6 @@ public class ForestManager {
 			String toLC = item.getToLandCover();
 			double area = item.getArea();
 			
-			if (locId == 13) {
-				int foo = 1;
-			}
-			
 			// new natural area
 			if (!fromLC.equals("natural") && toLC.equals("naturalNew")) {
 				double areaSoFar = (newNaturalArea.containsKey(locId)) ? newNaturalArea.get(locId) : 0;
diff --git a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
index 0d44762fd7144c34bcb3c4598dc5a56ea20888bb..b5c5e20309dd64d6e952406be88a41e3e9b93906 100644
--- a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
+++ b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
@@ -180,7 +180,7 @@ public class GamsLocationOptimiser {
 			}
 			
 			// Infrastructure cost
-			double infrastructureCost = landUseItem.getLandCoverFract(LandCoverType.NATURAL) * 0.09 + 0.01;
+			double infrastructureCost = landUseItem.getLandCoverFract(LandCoverType.NATURAL) * 0.1;
 			setGamsParamValue(infrastructureCostP.addRecord(locString), infrastructureCost, 5);
 				
 		}
@@ -431,7 +431,7 @@ public class GamsLocationOptimiser {
 		
 		// Land cover conversion cost
 		GAMSParameter conversionCostP = inDB.addParameter("conversionCost", 2);
-		/*
+		
 		DoubleMap<LandCoverType, LandCoverType, Double> conversionCosts = inputData.getConversionCosts();
 		
 		for (Entry<LandCoverType, Map<LandCoverType, Double>> fromMap : conversionCosts.getMap().entrySet()) {
@@ -445,7 +445,7 @@ public class GamsLocationOptimiser {
 				setGamsParamValue(conversionCostP.addRecord(v), cost, 5);
 			}
 		}
-		*/
+		/*
 		for (LandCoverType fromLc : LandCoverType.getConvertibleTypes()) {
 			for (LandCoverType toLc : LandCoverType.getConvertibleTypes()) {
 				double cost = 0;
@@ -477,7 +477,7 @@ public class GamsLocationOptimiser {
 					cost += ModelConfig.CROP_INCREASE_COST;
 					break;
 				case TIMBER_FOREST:
-					cost += ModelConfig.TREE_PLANTING_COST / ModelConfig.FOREST_ROTATION_PERIOD;
+					cost += ModelConfig.TREE_PLANTING_COST;
 					break;
 				case CARBON_FOREST:
 					cost += ModelConfig.TREE_PLANTING_COST / ModelConfig.FOREST_ROTATION_PERIOD;
@@ -490,13 +490,22 @@ public class GamsLocationOptimiser {
 				
 				if (toLc.equals(fromLc))
 					cost = 0;
-				
+	
+				if (toLc.equals(LandCoverType.NATURAL) && fromLc.isManagedForest())
+					cost = 0;
+					
 				// Forest rotation cost
 				if (toLc.isManagedForest() && fromLc.isManagedForest() & toLc.equals(fromLc))
 					cost += ModelConfig.TREE_PLANTING_COST / ModelConfig.FOREST_ROTATION_PERIOD;
 				
-				if (!toLc.isNatural() && fromLc.isNatural())
-					cost += ModelConfig.AGRI_EXPANSION_COST_BASE;
+				if (toLc.equals(LandCoverType.NATURAL) && fromLc.equals(LandCoverType.TIMBER_FOREST))
+					cost += ModelConfig.TREE_PLANTING_COST / ModelConfig.FOREST_ROTATION_PERIOD * 0.9;
+				
+				//if (toLc.equals(LandCoverType.TIMBER_FOREST))
+				//	cost = cost / ModelConfig.FOREST_ROTATION_PERIOD;
+				
+				
+				cost = 0;
 				
 				Vector<String> v = new Vector<String>();
 				v.add(fromLc.getName());
@@ -504,7 +513,7 @@ public class GamsLocationOptimiser {
 				setGamsParamValue(conversionCostP.addRecord(v), cost, 5);
 			}
 		}
-		
+		*/
 		// Net present value factor for timber i.e. multiply by value of potential timber harvest to get the future discounted value over the forest rotation period		
 		double npvFactor = 0;