//--------------------------------------------------------------------- // Generates new climate parameters at an annual time step. // public static void GenerateNewClimate(int year, int years) { //PlugIn.ModelCore.Log.WriteLine(" Generating new climate for simulation year {0}.", year); AnnualClimateArray = new Ecoregions.AuxParm<AnnualClimate[]>(PlugIn.ModelCore.Ecoregions); // Issues with this approach: Each ecoregion will have unique variability associated with // temperature and precipitation. In reality, we expect some regional synchronicity. An // easy-ish solution would be to use the same random number in combination with standard // deviations for all ecoregions. The converse problem is over synchronization of climate, but // that would certainly be preferrable over smaller regions. foreach(IEcoregion ecoregion in PlugIn.ModelCore.Ecoregions) { if(ActiveSiteCount[ecoregion] > 0) { AnnualClimate[] tempClimate = new AnnualClimate[years]; for (int y = 0; y < years; y++) { int actualYear = year + y; if(Climate.AllData.ContainsKey(actualYear)) { Climate.TimestepData = Climate.AllData[actualYear]; //PlugIn.ModelCore.Log.WriteLine(" Changing TimestepData: Yr={0}, Eco={1}.", actualYear, ecoregion.Name); //PlugIn.ModelCore.Log.WriteLine(" Changing TimestepData: AllData Jan Ppt = {0:0.00}.", Climate.AllData[actualYear][ecoregion.Index,0].AvgPpt); //PlugIn.ModelCore.Log.WriteLine(" Changing TimestepData: Timestep Jan Ppt = {0:0.00}.", Climate.TimestepData[ecoregion.Index,0].AvgPpt); } tempClimate[y] = new AnnualClimate(ecoregion.Index, actualYear, Latitude[ecoregion]); } AnnualClimateArray[ecoregion] = tempClimate; } } }
//--------------------------------------------------------------------- // Generates new climate parameters at an annual time step. // public static void GenerateNewClimate(int year, int years) { //PlugIn.ModelCore.UI.WriteLine(" Generating new climate for simulation year {0}.", year); AnnualClimateArray = new Ecoregions.AuxParm<AnnualClimate[]>(PlugIn.ModelCore.Ecoregions); foreach(IEcoregion ecoregion in PlugIn.ModelCore.Ecoregions) { if(ecoregion.Active) { AnnualClimate[] tempClimate = new AnnualClimate[years]; for (int y = 0; y < years; y++) { int actualYear = year + y; if(Climate.AllData.ContainsKey(actualYear)) { Climate.TimestepData = Climate.AllData[actualYear]; //PlugIn.ModelCore.UI.WriteLine(" Changing TimestepData: Yr={0}, Eco={1}.", actualYear, ecoregion.Name); //PlugIn.ModelCore.UI.WriteLine(" Changing TimestepData: AllData Jan Ppt = {0:0.00}.", Climate.AllData[actualYear][ecoregion.Index,0].AvgPpt); //PlugIn.ModelCore.UI.WriteLine(" Changing TimestepData: Timestep Jan Ppt = {0:0.00}.", Climate.TimestepData[ecoregion.Index,0].AvgPpt); } AnnualClimate.AnnualClimateInitialize(); // Synchronizes temperature and precipitation deviation across ecoregions. tempClimate[y] = new AnnualClimate(ecoregion, actualYear, Latitude[ecoregion]); } AnnualClimateArray[ecoregion] = tempClimate; } } }
//--------------------------------------------------------------------------- public static double CalculateAnnualActualEvapotranspiration(AnnualClimate annualClimate, double fieldCapacity) { // field capacity input as cm // variable with xVariableName indicate conversion to mm double xFieldCap = fieldCapacity * 10.0; double waterAvail = 0.0; double actualET = 0.0; double oldWaterAvail = 0.0; double accPotWaterLoss = 0.0; for(int month = 0; month < 12; month++) { double monthlyRain = annualClimate.MonthlyPrecip[month]; double potentialET = annualClimate.MonthlyPET[month]; //Calc potential water loss this month double potWaterLoss = monthlyRain - potentialET; //If monthlyRain doesn't satisfy potentialET, add this month's potential //water loss to accumulated water loss from soil if (potWaterLoss < 0.0) { accPotWaterLoss += potWaterLoss; double xAccPotWaterLoss = accPotWaterLoss * 10.0; //Calc water retained in soil given so much accumulated potential //water loss Pastor and Post. 1984. Can. J. For. Res. 14:466:467. waterAvail = fieldCapacity * System.Math.Exp((.000461 - 1.10559 / xFieldCap) * (-1.0 * xAccPotWaterLoss)); if (waterAvail < 0.0) waterAvail = 0.0; //changeSoilMoisture - during this month double changeSoilMoisture = waterAvail - oldWaterAvail; //Calc actual evapotranspiration (AET) if soil water is drawn down actualET += (monthlyRain - changeSoilMoisture); } //If monthlyRain satisfies potentialET, don't draw down soil water else { waterAvail = oldWaterAvail + potWaterLoss; if (waterAvail >= fieldCapacity) waterAvail = fieldCapacity; double changeSoilMoisture = waterAvail - oldWaterAvail; //If soil partially recharged, reduce accumulated potential //water loss accordingly accPotWaterLoss += changeSoilMoisture; //If soil completely recharged, reset accumulated potential //water loss to zero if (waterAvail >= fieldCapacity) accPotWaterLoss = 0.0; //If soil water is not drawn upon, add potentialET to AET actualET += potentialET; } oldWaterAvail = waterAvail; } return actualET; }
//--------------------------------------------------------------------------- public static double CalculateAnnualActualEvapotranspiration(AnnualClimate annualClimate, double fieldCapacity) { // field capacity input as cm // variable with xVariableName indicate conversion to mm double xFieldCap = fieldCapacity * 10.0; double waterAvail = 0.0; double actualET = 0.0; double oldWaterAvail = 0.0; double accPotWaterLoss = 0.0; for (int month = 0; month < 12; month++) { double monthlyRain = annualClimate.MonthlyPrecip[month]; double potentialET = annualClimate.MonthlyPET[month]; //Calc potential water loss this month double potWaterLoss = monthlyRain - potentialET; //If monthlyRain doesn't satisfy potentialET, add this month's potential //water loss to accumulated water loss from soil if (potWaterLoss < 0.0) { accPotWaterLoss += potWaterLoss; double xAccPotWaterLoss = accPotWaterLoss * 10.0; //Calc water retained in soil given so much accumulated potential //water loss Pastor and Post. 1984. Can. J. For. Res. 14:466:467. waterAvail = fieldCapacity * System.Math.Exp((.000461 - 1.10559 / xFieldCap) * (-1.0 * xAccPotWaterLoss)); if (waterAvail < 0.0) { waterAvail = 0.0; } //changeSoilMoisture - during this month double changeSoilMoisture = waterAvail - oldWaterAvail; //Calc actual evapotranspiration (AET) if soil water is drawn down actualET += (monthlyRain - changeSoilMoisture); } //If monthlyRain satisfies potentialET, don't draw down soil water else { waterAvail = oldWaterAvail + potWaterLoss; if (waterAvail >= fieldCapacity) { waterAvail = fieldCapacity; } double changeSoilMoisture = waterAvail - oldWaterAvail; //If soil partially recharged, reduce accumulated potential //water loss accordingly accPotWaterLoss += changeSoilMoisture; //If soil completely recharged, reset accumulated potential //water loss to zero if (waterAvail >= fieldCapacity) { accPotWaterLoss = 0.0; } //If soil water is not drawn upon, add potentialET to AET actualET += potentialET; } oldWaterAvail = waterAvail; } return(actualET); }