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);
            }
        }
示例#2
0
        public static List <IEcoregionPnETVariables> GetClimateRegionData(IEcoregionPnET ecoregion, DateTime start, DateTime end, Climate.Phase spinupOrfuture)
        {
            // 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);

            var oldYear = -1;

            while (end.Ticks > date.Ticks)
            {
                if (!all_values[ecoregion].ContainsKey(date))
                {
                    if (date.Year != oldYear)
                    {
                        //PlugIn.ModelCore.UI.WriteLine($"Retrieving Climate Library for year {date.Year}.");

                        if (spinupOrfuture == Climate.Phase.Future_Climate)
                        {
                            if (Climate.Future_MonthlyData.ContainsKey(date.Year))
                            {
                                ClimateRegionData.AnnualWeather[ecoregion] = Climate.Future_MonthlyData[date.Year][ecoregion.Index];
                            }
                        }
                        else
                        {
                            if (Climate.Spinup_MonthlyData.ContainsKey(date.Year))
                            {
                                ClimateRegionData.AnnualWeather[ecoregion] = Climate.Spinup_MonthlyData[date.Year][ecoregion.Index];
                            }
                        }

                        oldYear = date.Year;
                    }

                    var monthlyData = new MonthlyClimateRecord(ecoregion, date);

                    List <ISpeciesPNET> species = PlugIn.SpeciesPnET.AllSpecies.ToList();

                    IEcoregionPnETVariables ecoregion_variables = new ClimateRegionPnETVariables(monthlyData, 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);
        }
        private SpeciesPnETVariables GetSpeciesVariables(MonthlyClimateRecord monthlyClimateRecord, 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 - 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 * (monthlyClimateRecord.Tmin + 273)))));

            speciespnetvars.JH2O = JH2O;

            // NETPSN net 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   = (float)(AmaxB_slope * monthlyClimateRecord.CO2 + AmaxB_int);

            speciespnetvars.AmaxB_CO2 = AmaxB_CO2;

            //-------------------FTempPSN (public for output file)
            if (dTemp)
            {
                speciespnetvars.FTempPSN = DTempResponse(Tday, spc.PsnTOpt, spc.PsnTMin, spc.PsnTMax);
            }
            else
            {
                //speciespnetvars.FTempPSN = EcoregionPnETVariables.LinearPsnTempResponse(Tday, spc.PsnTOpt, spc.PsnTMin); // Original PnET-Succession
                speciespnetvars.FTempPSN = CurvelinearPsnTempResponse(Tday, spc.PsnTOpt, spc.PsnTMin); // 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 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);
        }