public static List <IEcoregionPnETVariables> GetData(IEcoregionPnET ecoregion, DateTime start, DateTime end) { // Monthly simulation data untill but not including end List <IEcoregionPnETVariables> data = new List <IEcoregionPnETVariables>(); // Date: the last date in the collection of running data DateTime date = new DateTime(start.Ticks); while (end.Ticks > date.Ticks) { if (all_values[ecoregion].ContainsKey(date) == false) { IObservedClimate observedClimate = ObservedClimate.GetData(ecoregion, date); List <ISpeciesPNET> species = PlugIn.SpeciesPnET.AllSpecies.ToList(); IEcoregionPnETVariables ecoregion_variables = new EcoregionPnETVariables(observedClimate, date, wythers, dtemp, species, ecoregion.Latitude); all_values[ecoregion].Add(date, ecoregion_variables); } data.Add(all_values[ecoregion][date]); date = date.AddMonths(1); } return(data); }
//--------------------------------------------------------------------- public EcoregionPnETVariables(IObservedClimate climate_dataset, DateTime Date, bool Wythers, bool DTemp, List <ISpeciesPNET> Species, float Latitude) { this._date = Date; this.obs_clim = climate_dataset; speciesVariables = new Dictionary <string, SpeciesPnETVariables>(); _tave = (float)0.5 * (climate_dataset.Tmin + climate_dataset.Tmax); _dayspan = EcoregionPnETVariables.Calculate_DaySpan(Date.Month); float hr = Calculate_hr(Date.DayOfYear, Latitude); //hours of daylight _daylength = Calculate_DayLength(hr); float nightlength = Calculate_NightLength(hr); _tday = (float)0.5 * (climate_dataset.Tmax + _tave); _vpd = EcoregionPnETVariables.Calculate_VPD(Tday, climate_dataset.Tmin); foreach (ISpeciesPNET spc in Species) { SpeciesPnETVariables speciespnetvars = GetSpeciesVariables(ref climate_dataset, Wythers, DTemp, Daylength, nightlength, spc); speciesVariables.Add(spc.Name, speciespnetvars); } }
public EcoregionPnETVariables(IObservedClimate climate_dataset, DateTime Date, bool Wythers, bool DTemp, List<ISpeciesPNET> Species) { this._date = Date; this.obs_clim = climate_dataset; speciesVariables = new Dictionary<string, SpeciesPnETVariables>(); _tave = (float)0.5 * (climate_dataset.Tmin + climate_dataset.Tmax); _dayspan = EcoregionPnETVariables.Calculate_DaySpan(Date.Month); float hr = Calculate_hr(Date.DayOfYear, PlugIn.Latitude); _daylength = Calculate_DayLength(hr); float nightlength = Calculate_NightLength(hr); _tday = (float)0.5 * (climate_dataset.Tmax + _tave); _vpd = EcoregionPnETVariables.Calculate_VPD(Tday, climate_dataset.Tmin); foreach (ISpeciesPNET spc in Species ) { SpeciesPnETVariables speciespnetvars = GetSpeciesVariables(ref climate_dataset, Wythers, DTemp, Daylength, nightlength, spc); speciesVariables.Add(spc.Name, speciespnetvars); } }
public static ObservedClimate GetData(IEcoregion ecoregion, DateTime date) { // get the appropriate values as read in from a climate txt file IObservedClimate observed_climate = GetClimateData(ecoregion); try { return(GetData(observed_climate, date)); } catch { throw new System.Exception("Can't get climate data for ecoregion " + ecoregion.Name + " and date " + date.ToString()); } }
public static ObservedClimate GetData(IObservedClimate observed_climate, DateTime date) { foreach (ObservedClimate d in observed_climate) { if (d.Year.Length == 4) { if (int.Parse(d.Month) == date.Month && date.Year == int.Parse(d.Year)) { return(d); } } else { string[] yearExtremes = d.Year.Split('-'); if (int.Parse(d.Month) == date.Month && int.Parse(yearExtremes[0]) <= date.Year && date.Year <= int.Parse(yearExtremes[1])) { return(d); } } } throw new System.Exception("No climate entry for ecoregion date " + date); }
//--------------------------------------------------------------------- private SpeciesPnETVariables GetSpeciesVariables(ref IObservedClimate climate_dataset, bool Wythers, bool DTemp, float daylength, float nightlength, ISpeciesPNET spc) { // Class that contains species specific PnET variables for a certain month SpeciesPnETVariables speciespnetvars = new SpeciesPnETVariables(); // Gradient of effect of vapour pressure deficit on growth. speciespnetvars.DVPD = Math.Max(0, 1.0f - spc.DVPD1 * (float)Math.Pow(VPD, spc.DVPD2)); // ** CO2 effect on growth ** // M. Kubiske method for wue calculation: Improved methods for calculating WUE and Transpiration in PnET. float JH2O = (float)(0.239 * ((VPD / (8314.47 * (climate_dataset.Tmin + 273f))))); speciespnetvars.JH2O = JH2O; // GROSSPSN gross photosynthesis // Modify AmaxB based on CO2 level // Equations solved from 2 known points: (350, AmaxB) and (550, AmaxB * CO2AmaxBEff) float AmaxB_slope = (float)(((spc.CO2AMaxBEff - 1.0) * spc.AmaxB) / 200.0); // Derived from m = [(AmaxB*CO2AMaxBEff) - AmaxB]/[550 - 350] float AmaxB_int = (float)(-1.0 * (((spc.CO2AMaxBEff - 1.0) * 1.75) - 1.0) * spc.AmaxB); // Derived from b = AmaxB - (AmaxB_slope * 350) float AmaxB_CO2 = AmaxB_slope * climate_dataset.CO2 + AmaxB_int; speciespnetvars.AmaxB_CO2 = AmaxB_CO2; //-------------------FTempPSN (public for output file) if (DTemp) { speciespnetvars.FTempPSN = EcoregionPnETVariables.DTempResponse(Tday, spc.PsnTOpt, spc.PsnTMin, spc.PsnTMax); } else { //speciespnetvars.FTempPSN = EcoregionPnETVariables.LinearPsnTempResponse(Tday, spc.PsnTOpt, spc.PsnTMin); // Original PnET-Succession speciespnetvars.FTempPSN = EcoregionPnETVariables.CurvelinearPsnTempResponse(Tday, spc.PsnTOpt, spc.PsnTMin, spc.PsnTMax); // Modified 051216(BRM) } // Dday maintenance respiration factor (scaling factor of actual vs potential respiration applied to daily temperature) float fTempRespDay = CalcQ10Factor(spc.Q10, Tday, spc.PsnTOpt); // Night maintenance respiration factor (scaling factor of actual vs potential respiration applied to night temperature) float fTempRespNight = CalcQ10Factor(spc.Q10, Tmin, spc.PsnTOpt); // Unitless respiration adjustment: public for output file only float FTempRespWeightedDayAndNight = (float)Math.Min(1.0, (fTempRespDay * daylength + fTempRespNight * nightlength) / ((float)daylength + (float)nightlength)); speciespnetvars.FTempRespWeightedDayAndNight = FTempRespWeightedDayAndNight; // Scaling factor of respiration given day and night temperature and day and night length speciespnetvars.MaintRespFTempResp = spc.MaintResp * FTempRespWeightedDayAndNight; // Respiration gC/timestep (RespTempResponses[0] = day respiration factor) // Respiration acclimation subroutine From: Tjoelker, M.G., Oleksyn, J., Reich, P.B. 1999. // Acclimation of respiration to temperature and C02 in seedlings of boreal tree species // in relation to plant size and relative growth rate. Global Change Biology. 49:679-691, // and Tjoelker, M.G., Oleksyn, J., Reich, P.B. 2001. Modeling respiration of vegetation: // evidence for a general temperature-dependent Q10. Global Change Biology. 7:223-230. // This set of algorithms resets the veg parameter "BaseFolRespFrac" from // the static vegetation parameter, then recalculates BaseFolResp based on the adjusted // BaseFolRespFrac // Base foliage respiration float BaseFolRespFrac; // Base parameter in Q10 temperature dependency calculation float Q10base; if (Wythers == true) { //Computed Base foliar respiration based on temp; this is species-level BaseFolRespFrac = (0.138071F - 0.0024519F * Tave); //Midpoint between Tave and Optimal Temp; this is also species-level float Tmidpoint = (Tave + spc.PsnTOpt) / 2F; // Base parameter in Q10 temperature dependency calculation in current temperature Q10base = (3.22F - 0.046F * Tmidpoint); } else { // The default PnET setting BaseFolRespFrac = spc.BFolResp; Q10base = spc.Q10; } speciespnetvars.BaseFolRespFrac = BaseFolRespFrac; // Respiration Q10 factor speciespnetvars.Q10Factor = CalcQ10Factor(Q10base, Tave, spc.PsnTOpt); return(speciespnetvars); }
private SpeciesPnETVariables GetSpeciesVariables(ref IObservedClimate climate_dataset, bool Wythers, bool DTemp, float daylength, float nightlength, ISpeciesPNET spc) { // Class that contains species specific PnET variables for a certain month SpeciesPnETVariables speciespnetvars = new SpeciesPnETVariables(); // Gradient of effect of vapour pressure deficit on growth. float DVPD = Math.Max(0, 1 - spc.DVPD1 * (float)Math.Pow(VPD, spc.DVPD2)); // Co2 ratio internal to the leave versus external float cicaRatio = (-0.075f * spc.FolN) + 0.875f; // Reference co2 ratio float ci350 = 350 * cicaRatio; // Elevated co2 effect float Arel350 = 1.22f * ((ci350 - 68) / (ci350 + 136)); // Elevated leaf internal co2 concentration float ciElev = climate_dataset.CO2 * cicaRatio; float ArelElev = 1.22f * ((ciElev - 68) / (ciElev + 136)); // CO2 effect on growth float delamax = 1 + ((ArelElev - Arel350) / Arel350); speciespnetvars.DelAmax = delamax; // CO2 effect on photosynthesis // Calculate CO2 effect on conductance and set slope and intercept for A-gs relationship //float Ci = climate_dataset.CO2 * (1 - cicaRatio); //float Delgs = delamax / ((Ci / (350.0f - ci350))); // denominator -> CO2 conductance effect float Delgs = delamax / ((climate_dataset.CO2 - climate_dataset.CO2 * cicaRatio) / (350.0f - ci350)); //_gsSlope = (float)((-1.1309 * delamax) + 1.9762); // used to determine ozone uptake //_gsInt = (float)((0.4656 * delamax) - 0.9701); //DWUE determined from CO2 effects on conductance float wue = (spc.WUEcnst / VPD) * (1 + 1 - Delgs); speciespnetvars.WUE = wue; // water use efficiency in a co2 enriched atmosphere //speciespnetvars.WUE_CO2_corr = wue / delamax; //speciespnetvars.WUE_CO2_corr = (climate_dataset.CO2 - Ci) / 1.6f; // NETPSN net photosynthesis speciespnetvars.Amax = speciespnetvars.DelAmax * (spc.AmaxA + spc.AmaxB * spc.FolN); //Reference net Psn (lab conditions) in gC/m2 leaf area/timestep float RefNetPsn = _dayspan * (speciespnetvars.Amax * DVPD * daylength * Constants.MC) / Constants.billion; //-------------------FTempPSN (public for output file) if (DTemp) { speciespnetvars.FTempPSN = EcoregionPnETVariables.DTempResponse(Tday, spc.PsnTOpt, spc.PsnTMin); } else { //speciespnetvars.FTempPSN = EcoregionPnETVariables.LinearPsnTempResponse(Tday, spc.PsnTOpt, spc.PsnTMin); // Original PnET-Succession speciespnetvars.FTempPSN = EcoregionPnETVariables.CurvelinearPsnTempResponse(Tday, spc.PsnTOpt, spc.PsnTMin); // Modified 051216(BRM) } // PSN (gC/m2 leaf area/tstep) reference net psn in a given temperature speciespnetvars.FTempPSNRefNetPsn = speciespnetvars.FTempPSN * RefNetPsn; //EcoregionPnETVariables.RespTempResponse(spc, Tday, climate_dataset.Tmin, daylength, nightlength); // Dday maintenance respiration factor (scaling factor of actual vs potential respiration applied to daily temperature) float fTempRespDay = CalcQ10Factor(spc.Q10, Tday, spc.PsnTOpt); // Night maintenance respiration factor (scaling factor of actual vs potential respiration applied to night temperature) float fTempRespNight = CalcQ10Factor(spc.Q10, Tmin , spc.PsnTOpt); // Unitless respiration adjustment: public for output file only speciespnetvars.FTempRespWeightedDayAndNight = (float)Math.Min(1.0, (fTempRespDay * daylength + fTempRespNight * nightlength) / ((float)daylength + (float)nightlength)); ; // Scaling factor of respiration given day and night temperature and day and night length speciespnetvars.MaintRespFTempResp = spc.MaintResp * speciespnetvars.FTempRespWeightedDayAndNight; // Respiration gC/timestep (RespTempResponses[0] = day respiration factor) // Respiration acclimation subroutine From: Tjoelker, M.G., Oleksyn, J., Reich, P.B. 1999. // Acclimation of respiration to temperature and C02 in seedlings of boreal tree species // in relation to plant size and relative growth rate. Global Change Biology. 49:679-691, // and Tjoelker, M.G., Oleksyn, J., Reich, P.B. 2001. Modeling respiration of vegetation: // evidence for a general temperature-dependent Q10. Global Change Biology. 7:223-230. // This set of algorithms resets the veg parameter "BaseFolRespFrac" from // the static vegetation parameter, then recalculates BaseFolResp based on the adjusted // BaseFolRespFrac // Base foliage respiration float BaseFolResp; // Base parameter in Q10 temperature dependency calculation float Q10base; if (Wythers == true) { //Computed Base foliar respiration based on temp; this is species-level, so you can compute outside this IF block and use for all cohorts of a species BaseFolResp = (0.138071F - 0.0024519F * Tave); //Midpoint between Tave and Optimal Temp; this is also species-level float Tmidpoint=(Tave+ spc.PsnTOpt)/2F; // Base parameter in Q10 temperature dependency calculation in current temperature Q10base = (3.22F - 0.046F * Tmidpoint); } else { // The default PnET setting is that these BaseFolResp = spc.BFolResp; Q10base = spc.Q10; } // Growth respiration factor speciespnetvars.FTempRespDay = BaseFolResp * CalcQ10Factor(Q10base, Tave, spc.PsnTOpt); return speciespnetvars; }
public void CompareWythersWithEarlier() { string ClimateFileName = @"C:\Users\debruijna\Desktop\PnET-Succession\EricCalibration\Oconto_weather_Temp0_Prec0_PAR0.txt"; IObservedClimate observed = new ObservedClimate(ClimateFileName); //PnETSpeciesParameters FolN SLWmax SLWDel TOfol AmaxA AmaxB HalfSat H3 H4 PsnAgeRed PsnTMin PsnTOpt k //tsugcana 1.2 190 0 0.3333 5.3 21.5 230 114 235 5 1 19 0.5 //PnETSpeciesParameters WUEcnst MaintResp DNSC FracBelowG EstMoist EstRad FracFol FrActWd //tsugcana 6 0.0005 0.05 0.33 1 1 0.13 0.00005 <<tsugcan /* * LandisData PnETGenericParameters * PnETGenericParameters Value * BFolResp 0.1 * TOroot 0.02 * TOwood 0.01 * MaxCanopyLayers 2 * IMAX 70 * >>DNSC 0.05 <<target NSCfraction * >>MaintResp 0.0025 * PreventEstablishment true * wythers true */ Landis.Core.PostFireRegeneration postfireregen = Landis.Core.PostFireRegeneration.Resprout; float wuecnst = 6; float dnsc = 0.05F; float cfracbiomass = 0.45F; float kwdlit = 0.1F; float fracbelowg = 0.33F; float fracfol = 0.13F; float fractWd = 0.00005F; float psnagered = 5; ushort h2 = 0; ushort h3 = 114; ushort h4 = 235; float slwdel = 0; float slwmax = 190; float tofol = 0.3333F; float toroot = 0.02F; float halfsat = 230F; float initialnsc = 7; float k = 0.5F; float towood = 0.01F; float estrad = 1; float estmoist = 1; float follignin = 0.2F; bool preventestablishment = false; float psntopt = 19F; float q10 = 2F; float psntmin = 1F; float dvpd1 = 0.05F; float dvpd2 = 2F; float foln = 1.2F; float amaxa = 5.3F; float amaxb = 21.5F; float maintresp = 0.0005F; float bfolresp = 0.1F; int Index = 0; string name = "tsugcana"; int maxSproutAge = 0; int minSproutAge = 0; int maxSeedDist = 100; int effectiveSeedDist = 30; float vegReprodProb = 0; byte fireTolerance = 3; byte shadeTolerance = 5; int maturity = 60; int longevity = 450; ISpeciesPNET species = new SpeciesPnET(Landis.Core.PostFireRegeneration.Resprout, wuecnst, dnsc, cfracbiomass, kwdlit, fracbelowg, fracfol, fractWd, psnagered, h2, h3, h4, slwdel, slwmax, tofol , toroot, halfsat, initialnsc, k, towood, estrad, estmoist, follignin, preventestablishment, psntopt, q10, psntmin, dvpd1 , dvpd2, foln, amaxa, amaxb, maintresp, bfolresp, Index, name, maxSproutAge, minSproutAge, maxSeedDist, effectiveSeedDist, vegReprodProb , fireTolerance, shadeTolerance, maturity, longevity); DateTime date = new DateTime(1910, 1, 1); string fn = @"C:\Users\debruijna\Desktop\FTempRespDayRefResp.txt"; System.IO.StreamWriter sw = new System.IO.StreamWriter(fn); sw.WriteLine("date" + "\t" + "FTempRespDayRefRespWythers" + "\t" + "FTempRespDayRefRespNoWythers"); while (date < new DateTime(1950, 1, 1)) { IObservedClimate climate = ObservedClimate.GetData(observed, date); float FTempRespDayRefRespWythers = new EcoregionPnETVariables(climate, date, true, new System.Collections.Generic.List <ISpeciesPNET>() { species })[species.Name].FTempRespDayRefResp; float FTempRespDayRefRespNoWythers = new EcoregionPnETVariables(climate, date, false, new System.Collections.Generic.List <ISpeciesPNET>() { species })[species.Name].FTempRespDayRefResp; sw.WriteLine(date + "\t" + FTempRespDayRefRespWythers + "\t" + FTempRespDayRefRespNoWythers); date = date.AddMonths(1); } sw.Close(); }