Пример #1
0
        //---------------------------------------------------------------------------
        public PhotosynthesisModel()
        {
            envModel       = new EnvironmentModel();
            canopy         = new LeafCanopy();
            canopy.nLayers = 1;
            sunlit         = new SunlitCanopy();
            shaded         = new ShadedCanopy();

            canopy.notifyChanged += runDaily;
            photoPathwayChanged  += canopy.photoPathwayChanged;

            envModel.notify      += runDaily;
            parameters            = new List <string>();
            variables             = new List <string>();
            sunlitShadedVariables = new List <string>();
            canopyVariables       = new List <string>();

            canopy.layerNumberChanged += sunlit.initArrays;
            canopy.layerNumberChanged += shaded.initArrays;
        }
Пример #2
0
        public override void Run(bool sendNotification, double swAvail = 0, double maxHourlyT = -1, double sunlitFraction = 0, double shadedFraction = 0)
        {
            if (!Initialised)
            {
                return;
            }

            if (sendNotification && NotifyStart != null)
            {
                NotifyStart(false);
            }

            EnvModel.Run(this.Time);
            Canopy.CalcCanopyStructure(this.EnvModel.SunAngle.Rad);

            SunlitAC1 = new SunlitCanopy(Canopy.NLayers, SSType.AC1);
            SunlitAJ  = new SunlitCanopy(Canopy.NLayers, SSType.AJ);
            ShadedAC1 = new ShadedCanopy(Canopy.NLayers, SSType.AC1);
            ShadedAJ  = new ShadedCanopy(Canopy.NLayers, SSType.AJ);

            double temp = EnvModel.GetTemp(Time);

            if (temp > Canopy.CPath.JTMax || temp < Canopy.CPath.JTMin || temp > Canopy.CPath.GmTMax || temp < Canopy.CPath.GmTMin)
            {
                ZeroVariables();
                return;
            }

            if (EnvModel.Ios.Value(this.Time) <= (0 + double.Epsilon))
            {
                ZeroVariables();
                return;
            }


            SunlitAC1.CalcLAI(this.Canopy, ShadedAC1);
            SunlitAJ.CalcLAI(this.Canopy, ShadedAJ);
            ShadedAC1.CalcLAI(this.Canopy, SunlitAC1);
            ShadedAJ.CalcLAI(this.Canopy, SunlitAJ);

            Canopy.Run(this, EnvModel);

            SunlitAC1.Run(Canopy.NLayers, this, ShadedAC1);
            SunlitAJ.Run(Canopy.NLayers, this, ShadedAJ);
            ShadedAC1.Run(Canopy.NLayers, this, SunlitAC1);
            ShadedAJ.Run(Canopy.NLayers, this, SunlitAJ);

            TranspirationMode mode = TranspirationMode.unlimited;

            if (maxHourlyT != -1)
            {
                mode = TranspirationMode.limited;
            }

            bool useAirTemp = false;

            List <bool> results = new List <bool>();

            results.Add(SunlitAC1.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), mode, maxHourlyT, sunlitFraction));
            results.Add(SunlitAJ.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), mode, maxHourlyT, sunlitFraction));
            results.Add(ShadedAC1.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), mode, maxHourlyT, shadedFraction));
            results.Add(ShadedAJ.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), mode, maxHourlyT, shadedFraction));

            Count = 1;

            bool caughtError = false;

            while (results.Contains(false) && !caughtError)
            {
                results.Clear();
                results.Add(SunlitAC1.CalcPhotosynthesis(this, useAirTemp, 0, SunlitAC1.LeafTemp[0], mode, maxHourlyT, sunlitFraction));
                results.Add(SunlitAJ.CalcPhotosynthesis(this, useAirTemp, 0, SunlitAJ.LeafTemp[0], mode, maxHourlyT, sunlitFraction));
                results.Add(ShadedAC1.CalcPhotosynthesis(this, useAirTemp, 0, ShadedAC1.LeafTemp[0], mode, maxHourlyT, shadedFraction));
                results.Add(ShadedAJ.CalcPhotosynthesis(this, useAirTemp, 0, ShadedAJ.LeafTemp[0], mode, maxHourlyT, shadedFraction));

                Count++;

                if (Count > 50 && !caughtError)
                {
                    ZeroVariables();

                    //writeScenario(swAvail);
                    caughtError = true;

                    return;
                }
            }

            // canopy.calcCanopyBiomassAccumulation(this);

            if (sendNotification && NotifyFinish != null)
            {
                NotifyFinish();
            }
            // writeScenario(swAvail);
        }
Пример #3
0
        public override void Run(bool sendNotification, double swAvail = 0, double maxHourlyT = -1, double sunlitFraction = 0, double shadedFraction = 0)
        {
            if (!Initialised)
            {
                return;
            }

            if (sendNotification && NotifyStart != null)
            {
                NotifyStart(false);
            }

            // Sets the environment
            EnvModel.Run(this.Time);
            Canopy.CalcCanopyStructure(this.EnvModel.SunAngle.Rad);

            // Sets the canopy status
            SunlitAc1 = new SunlitCanopy(Canopy.NLayers, SSType.Ac1);
            SunlitAj  = new SunlitCanopy(Canopy.NLayers, SSType.Aj);
            ShadedAc1 = new ShadedCanopy(Canopy.NLayers, SSType.Ac1);
            ShadedAj  = new ShadedCanopy(Canopy.NLayers, SSType.Aj);

            double temp = EnvModel.GetTemp(Time);

            // Don't perform photosynthesis beyond temperature boundaries
            if (temp > Canopy.CPath.JTMax || temp < Canopy.CPath.JTMin || temp > Canopy.CPath.GmTMax || temp < Canopy.CPath.GmTMin)
            {
                ZeroVariables();
                return;
            }

            // Don't perform photosynthesis if the sun isn't up
            if (EnvModel.Ios.Value(this.Time) <= (0 + double.Epsilon))
            {
                ZeroVariables();
                return;
            }

            // Calculate the leaf area index
            SunlitAc1.CalcLAI(this.Canopy, ShadedAc1);
            SunlitAj.CalcLAI(this.Canopy, ShadedAj);
            ShadedAc1.CalcLAI(this.Canopy, SunlitAc1);
            ShadedAj.CalcLAI(this.Canopy, SunlitAj);

            // Run the canopy model
            Canopy.Run(this, EnvModel);
            SunlitAc1.Run(Canopy.NLayers, this, ShadedAc1);
            SunlitAj.Run(Canopy.NLayers, this, ShadedAj);
            ShadedAc1.Run(Canopy.NLayers, this, SunlitAc1);
            ShadedAj.Run(Canopy.NLayers, this, SunlitAj);

            // Set the transpirtation mode
            TranspirationMode mode = TranspirationMode.unlimited;

            if (maxHourlyT != -1)
            {
                mode = TranspirationMode.limited;
            }

            // For the initial photosynthesis calculation each hour we use air temperature
            bool useAirTemp = true;

            var results = new bool[4];

            // Initial calculation
            results[0] = (SunlitAc1.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), mode, maxHourlyT, sunlitFraction));
            results[1] = (SunlitAj.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), mode, maxHourlyT, sunlitFraction));
            results[2] = (ShadedAc1.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), mode, maxHourlyT, shadedFraction));
            results[3] = (ShadedAj.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), mode, maxHourlyT, shadedFraction));

            // After initialisation we use new leaf temperature
            useAirTemp = false;

            // SUNLIT CALCULATIONS
            double defaultAC1A     = 0.0;
            double defaultAC1Water = 0.0;
            double defaultAJA      = 0.0;
            double defaultAJWater  = 0.0;

            // If the initial calculation fails, set values to 0
            if (results[0] || results[1])
            {
                SunlitAc1.A[0]        = 0.0;
                SunlitAc1.WaterUse[0] = 0.0;
                SunlitAj.A[0]         = 0.0;
                SunlitAj.WaterUse[0]  = 0.0;
            }
            else
            {
                defaultAC1A     = SunlitAc1.A[0];
                defaultAC1Water = SunlitAc1.WaterUse[0];
                defaultAJA      = SunlitAj.A[0];
                defaultAJWater  = SunlitAj.WaterUse[0];
            }

            // Ben Ababaei (2019.10.14): If NONE of the As is > 0.5, don't get inside the following loop.
            // If there is sufficient photosynthetic rate
            if (SunlitAc1.A[0] > 0.5 && SunlitAj.A[0] > 0.5)
            {
                for (int n = 0; n < 3; n++)
                {
                    results[0] = SunlitAc1.CalcPhotosynthesis(this, useAirTemp, 0, SunlitAc1.LeafTemp[0], mode, maxHourlyT, sunlitFraction);
                    results[1] = SunlitAj.CalcPhotosynthesis(this, useAirTemp, 0, SunlitAj.LeafTemp[0], mode, maxHourlyT, sunlitFraction);

                    // If any of the above is < 0, set both values zero (for each type of leaf separately).
                    if (results[0] || results[1])
                    {
                        SunlitAc1.A[0]        = defaultAC1A;
                        SunlitAc1.WaterUse[0] = defaultAC1Water;
                        SunlitAj.A[0]         = defaultAJA;
                        SunlitAj.WaterUse[0]  = defaultAC1Water;

                        break;
                    }
                }
            }

            // SHADED CALCULATIONS
            if (results[2] || results[3])
            {
                ShadedAc1.A[0]        = 0.0;
                ShadedAc1.WaterUse[0] = 0.0;
                ShadedAj.A[0]         = 0.0;
                ShadedAj.WaterUse[0]  = 0.0;
            }
            else
            {
                defaultAC1A     = ShadedAc1.A[0];
                defaultAC1Water = ShadedAc1.WaterUse[0];
                defaultAJA      = ShadedAj.A[0];
                defaultAJWater  = ShadedAj.WaterUse[0];
            }

            // If there is sufficient photosynthetic rate
            if (ShadedAc1.A[0] > 0.5 && ShadedAj.A[0] > 0.5)
            {
                for (int n = 0; n < 3; n++)
                {
                    results[2] = ShadedAc1.CalcPhotosynthesis(this, useAirTemp, 0, ShadedAc1.LeafTemp[0], mode, maxHourlyT, shadedFraction);
                    results[3] = ShadedAj.CalcPhotosynthesis(this, useAirTemp, 0, ShadedAj.LeafTemp[0], mode, maxHourlyT, shadedFraction);

                    // If any of the above is < 0, set both values zero (for each type of leaf separately).
                    if (results[2] || results[3])
                    {
                        ShadedAc1.A[0]        = defaultAC1A;
                        ShadedAc1.WaterUse[0] = defaultAC1Water;
                        ShadedAj.A[0]         = defaultAJA;
                        ShadedAj.WaterUse[0]  = defaultAJWater;
                    }
                }
            }

            if (sendNotification && NotifyFinish != null)
            {
                NotifyFinish();
            }
        }
Пример #4
0
        //---------------------------------------------------------------------------
        public override void Run(bool sendNotification, double swAvail = 0, double maxHourlyT = -1, double sunlitFraction = 0, double shadedFraction = 0)
        {
            if (!Initialised)
            {
                return;
            }

            if (sendNotification && NotifyStart != null)
            {
                NotifyStart(false);
            }

            EnvModel.Run(this.Time);
            Canopy.CalcCanopyStructure(this.EnvModel.SunAngle.Rad);

            SunlitAC1 = new SunlitCanopy(Canopy.NLayers, SSType.AC1);
            sunlitAC2 = new SunlitCanopy(Canopy.NLayers, SSType.AC2);
            SunlitAJ  = new SunlitCanopy(Canopy.NLayers, SSType.AJ);
            ShadedAC1 = new ShadedCanopy(Canopy.NLayers, SSType.AC1);
            shadedAC2 = new ShadedCanopy(Canopy.NLayers, SSType.AC2);
            ShadedAJ  = new ShadedCanopy(Canopy.NLayers, SSType.AJ);

            double temp = EnvModel.GetTemp(Time);

            if (temp > Canopy.CPath.JTMax || temp < Canopy.CPath.JTMin || temp > Canopy.CPath.GmTMax || temp < Canopy.CPath.GmTMin)
            {
                ZeroVariables();
                return;
            }

            if (EnvModel.Ios.Value(this.Time) <= (0 + double.Epsilon))
            {
                ZeroVariables();
                return;
            }

            SunlitAC1.CalcLAI(this.Canopy, ShadedAC1);
            sunlitAC2.CalcLAI(this.Canopy, shadedAC2);
            SunlitAJ.CalcLAI(this.Canopy, ShadedAJ);
            ShadedAC1.CalcLAI(this.Canopy, SunlitAC1);
            shadedAC2.CalcLAI(this.Canopy, sunlitAC2);
            ShadedAJ.CalcLAI(this.Canopy, SunlitAJ);

            Canopy.Run(this, EnvModel);

            SunlitAC1.Run(Canopy.NLayers, this, ShadedAC1);
            sunlitAC2.Run(Canopy.NLayers, this, shadedAC2);
            SunlitAJ.Run(Canopy.NLayers, this, ShadedAJ);
            ShadedAC1.Run(Canopy.NLayers, this, SunlitAC1);
            shadedAC2.Run(Canopy.NLayers, this, sunlitAC2);
            ShadedAJ.Run(Canopy.NLayers, this, SunlitAJ);

            TranspirationMode mode = TranspirationMode.unlimited;

            if (maxHourlyT != -1)
            {
                mode = TranspirationMode.limited;
            }

            bool useAirTemp = false;

            double defaultCm = 160;

            List <bool> results = new List <bool>();

            results.Add(SunlitAC1.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), defaultCm, mode, maxHourlyT, sunlitFraction));
            results.Add(sunlitAC2.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), defaultCm, mode, maxHourlyT, sunlitFraction));
            results.Add(SunlitAJ.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), defaultCm, mode, maxHourlyT, sunlitFraction));
            results.Add(ShadedAC1.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), defaultCm, mode, maxHourlyT, shadedFraction));
            results.Add(shadedAC2.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), defaultCm, mode, maxHourlyT, shadedFraction));
            results.Add(ShadedAJ.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), defaultCm, mode, maxHourlyT, shadedFraction));

            Count = 1;

            bool caughtError = false;

            while (results.Contains(false) && !caughtError)
            {
                results.Clear();
                results.Add(SunlitAC1.CalcPhotosynthesis(this, useAirTemp, 0, SunlitAC1.LeafTemp[0], SunlitAC1.Cm[0], mode, maxHourlyT, sunlitFraction));
                results.Add(sunlitAC2.CalcPhotosynthesis(this, useAirTemp, 0, sunlitAC2.LeafTemp[0], sunlitAC2.Cm[0], mode, maxHourlyT, sunlitFraction));
                results.Add(SunlitAJ.CalcPhotosynthesis(this, useAirTemp, 0, SunlitAJ.LeafTemp[0], SunlitAJ.Cm[0], mode, maxHourlyT, sunlitFraction));
                results.Add(ShadedAC1.CalcPhotosynthesis(this, useAirTemp, 0, ShadedAC1.LeafTemp[0], ShadedAC1.Cm[0], mode, maxHourlyT, shadedFraction));
                results.Add(shadedAC2.CalcPhotosynthesis(this, useAirTemp, 0, shadedAC2.LeafTemp[0], shadedAC2.Cm[0], mode, maxHourlyT, shadedFraction));
                results.Add(ShadedAJ.CalcPhotosynthesis(this, useAirTemp, 0, ShadedAJ.LeafTemp[0], ShadedAJ.Cm[0], mode, maxHourlyT, shadedFraction));

                if (double.IsNaN(SunlitAC1.Cm[0]) ||
                    double.IsNaN(sunlitAC2.Cm[0]) ||
                    double.IsNaN(SunlitAJ.Cm[0]) ||
                    double.IsNaN(ShadedAC1.Cm[0]) ||
                    double.IsNaN(shadedAC2.Cm[0]) ||
                    double.IsNaN(ShadedAJ.Cm[0]) ||
                    Count == 30)
                {
                    SunlitAC1.Cm[0] = defaultCm;
                    sunlitAC2.Cm[0] = defaultCm;
                    SunlitAJ.Cm[0]  = defaultCm;
                    ShadedAC1.Cm[0] = defaultCm;
                    shadedAC2.Cm[0] = defaultCm;
                    ShadedAJ.Cm[0]  = defaultCm;

                    useAirTemp = true;
                }

                if (Count > 100)
                {
                    ZeroVariables();

                    return;
                }

                Count++;

                if (Count > 100 && !caughtError)
                {
                    StreamWriter sr = new StreamWriter("scenario.csv");

                    sr.WriteLine("Lat," + EnvModel.LatitudeD);
                    sr.WriteLine("DOY," + EnvModel.DOY);
                    sr.WriteLine("Maxt," + EnvModel.MaxT);
                    sr.WriteLine("AvailableWater," + swAvail);
                    sr.WriteLine("Mint," + EnvModel.MinT);
                    sr.WriteLine("Radn," + EnvModel.Radn);
                    sr.WriteLine("Ratio," + EnvModel.AtmTransmissionRatio);
                    sr.WriteLine("LAI," + Canopy.LAI);
                    sr.WriteLine("SLN," + Canopy.CPath.SLNAv);

                    List <double> temps = new List <double>();

                    for (int i = 0; i <= 12; i++)
                    {
                        temps.Add(EnvModel.GetTemp(i + 5));
                    }

                    sr.WriteLine("Temps," + String.Join(",", temps.ToArray()));

                    sr.Flush();

                    sr.Close();

                    caughtError = true;
                }
            }

            if (sendNotification && NotifyFinish != null)
            {
                NotifyFinish();
            }
        }