//--------------------------------------------------------------------------- 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; }
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); }
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(); } }
//--------------------------------------------------------------------------- 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(); } }