//--------------------------------------------------------------------- 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 ClimateRegionPnETVariables(MonthlyClimateRecord monthlyClimateRecord, DateTime date, bool wythers, bool dTemp, List <ISpeciesPNET> Species, float latitude) { _monthlyClimateRecord = monthlyClimateRecord; _date = date; speciesVariables = new Dictionary <string, SpeciesPnETVariables>(); _tave = (float)(0.5 * (monthlyClimateRecord.Tmin + monthlyClimateRecord.Tmax)); _dayspan = Calculate_DaySpan(date.Month); float hr = Calculate_hr(date.DayOfYear, latitude); _daylength = Calculate_DayLength(hr); float nightlength = Calculate_NightLength(hr); _tday = (float)(0.5 * (monthlyClimateRecord.Tmax + _tave)); _vpd = Calculate_VPD(Tday, (float)monthlyClimateRecord.Tmin); foreach (ISpeciesPNET spc in Species) { SpeciesPnETVariables speciespnetvars = GetSpeciesVariables(monthlyClimateRecord, wythers, dTemp, Daylength, nightlength, spc); speciesVariables.Add(spc.Name, 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. 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; }