public override double[] RunApsim(int DOY, double latitude, double maxT, double minT, double radn, double lai, double SLN, double soilWaterAvail, double RootShootRatio, double MaxHourlyTRate = 100) { EnvModel.Initialised = false; EnvModel.LatitudeD = latitude; EnvModel.DOY = DOY; EnvModel.MaxT = maxT; EnvModel.MinT = minT; EnvModel.Radn = radn; // Check that this changes ratio Canopy.LAI = lai; Canopy.CPath.SLNAv = SLN; EnvModel.Initialised = true; EnvModel.Run(); Initialised = true; List <double> sunlitWaterDemands = new List <double>(); List <double> shadedWaterDemands = new List <double>(); List <double> hourlyWaterDemandsmm = new List <double>(); List <double> hourlyWaterSuppliesmm = new List <double>(); List <double> sunlitAssimilations = new List <double>(); List <double> shadedAssimilations = new List <double>(); List <double> interceptedRadn = new List <double>(); int startHour = 6; int endHour = 18; // Calculate the potential photosynthesis and water demand for (int time = startHour; time <= endHour; time++) { double rads = EnvModel.Ios.Value(time); if (double.IsNaN(rads) || rads <= 0) { interceptedRadn.Add(0); sunlitWaterDemands.Add(0); shadedWaterDemands.Add(0); hourlyWaterDemandsmm.Add(0); hourlyWaterSuppliesmm.Add(0); sunlitAssimilations.Add(0); shadedAssimilations.Add(0); } else { // Run the model Run(time, soilWaterAvail); // Calculate radiation double propIntRadn = Canopy.PropnInterceptedRadns.Sum(); double radiation = EnvModel.TotalIncidentRadiation * propIntRadn * 3600; interceptedRadn.Add(radiation); // Retrieve water demand double sunlitWaterDemand = Math.Min(Math.Min(SunlitAc1.WaterUse[0], SunlitAc2.WaterUse[0]), SunlitAj.WaterUse[0]); double shadedWaterDemand = Math.Min(Math.Min(ShadedAc1.WaterUse[0], ShadedAc2.WaterUse[0]), ShadedAj.WaterUse[0]); // Retrieve assimilations double sunlitAssimilation = Math.Min(Math.Min(SunlitAc1.A[0], SunlitAc2.A[0]), SunlitAj.A[0]); double shadedAssimilation = Math.Min(Math.Min(ShadedAc1.A[0], ShadedAc2.A[0]), ShadedAj.A[0]); // Note: Values are explicitly defined to be 0 or Sensible inside the Run() method sunlitWaterDemands.Add(sunlitWaterDemand); shadedWaterDemands.Add(shadedWaterDemand); hourlyWaterDemandsmm.Add((sunlitWaterDemands.Last() + shadedWaterDemands.Last())); hourlyWaterSuppliesmm.Add(hourlyWaterDemandsmm.Last()); sunlitAssimilations.Add(sunlitAssimilation); shadedAssimilations.Add(shadedAssimilation); } } potentialAssimilation = sunlitAssimilations.Sum() + shadedAssimilations.Sum(); // Setting water supply to water available from Apsim double maxHourlyT = Math.Min(hourlyWaterSuppliesmm.Max(), MaxHourlyTRate); for (int i = 0; i < hourlyWaterSuppliesmm.Count; i++) { if (hourlyWaterSuppliesmm[i] > maxHourlyT) { hourlyWaterSuppliesmm[i] = maxHourlyT; } } if (soilWaterAvail > 0.0001) { if (hourlyWaterDemandsmm.Sum() > soilWaterAvail) { double tolerance = 0.000001; double highTestValue = maxHourlyT; double lowTestValue = 0; double trialTestValue = 0; double supplyTrial = hourlyWaterSuppliesmm.Sum(); double supplyHighTest = 0; double supplyLowTest = 0; while ((soilWaterAvail + tolerance) < supplyTrial || (soilWaterAvail - tolerance) > supplyTrial) { supplyHighTest = CalcTestSoilWater(hourlyWaterSuppliesmm, highTestValue); supplyLowTest = CalcTestSoilWater(hourlyWaterSuppliesmm, lowTestValue); trialTestValue = (highTestValue + lowTestValue) / 2; supplyTrial = CalcTestSoilWater(hourlyWaterSuppliesmm, trialTestValue); if (supplyHighTest > soilWaterAvail && supplyTrial < soilWaterAvail) { lowTestValue = trialTestValue; } else if (supplyTrial > soilWaterAvail && lowTestValue < soilWaterAvail) { highTestValue = trialTestValue; } } for (int i = 0; i < hourlyWaterSuppliesmm.Count; i++) { if (hourlyWaterSuppliesmm[i] > trialTestValue) { hourlyWaterSuppliesmm[i] = trialTestValue; } } } } else { for (int i = 0; i < hourlyWaterSuppliesmm.Count; i++) { hourlyWaterSuppliesmm[i] = 0; } } // Calculate the water limited photosynthesis (if necesssary) if (soilWaterAvail < hourlyWaterDemandsmm.Sum()) { sunlitAssimilations.Clear(); shadedAssimilations.Clear(); //Now that we have our hourly supplies we can calculate again for (int time = startHour; time <= endHour; time++) { double sunlitWaterDemand = sunlitWaterDemands[time - startHour]; double shadedWaterDemand = shadedWaterDemands[time - startHour]; double totalWaterDemand = sunlitWaterDemand + shadedWaterDemand; if (interceptedRadn[time - 6] > 0) { Run(time, soilWaterAvail, hourlyWaterSuppliesmm[time - startHour], sunlitWaterDemand / totalWaterDemand, shadedWaterDemand / totalWaterDemand); double sunlitAssimilation = Math.Min(Math.Min(SunlitAc1.A[0], SunlitAc2.A[0]), SunlitAj.A[0]); double shadedAssimilation = Math.Min(Math.Min(ShadedAc1.A[0], ShadedAc2.A[0]), ShadedAj.A[0]); sunlitAssimilations.Add(sunlitAssimilation); shadedAssimilations.Add(shadedAssimilation); } else { sunlitAssimilations.Add(0); shadedAssimilations.Add(0); } } } double[] results = new double[5]; for (int i = 0; i < sunlitAssimilations.Count; i++) { if (double.IsNaN(sunlitAssimilations[i])) { sunlitAssimilations[i] = 0; } if (double.IsNaN(shadedAssimilations[i])) { shadedAssimilations[i] = 0; } if (double.IsNaN(hourlyWaterDemandsmm[i])) { hourlyWaterDemandsmm[i] = 0; } if (double.IsNaN(hourlyWaterSuppliesmm[i])) { hourlyWaterSuppliesmm[i] = 0; } if (double.IsNaN(interceptedRadn[i])) { interceptedRadn[i] = 0; } } results[0] = (sunlitAssimilations.Sum() + shadedAssimilations.Sum()) * 3600 / 1000000 * 44 * B * 100 / ((1 + RootShootRatio) * 100); results[1] = hourlyWaterDemandsmm.Sum(); results[2] = hourlyWaterSuppliesmm.Sum(); results[3] = interceptedRadn.Sum(); results[4] = potentialAssimilation * 3600 / 1000000 * 44 * B * 100 / ((1 + RootShootRatio) * 100); return(results); }
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); 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); // 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); 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); // Run the canopy model 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); // Set the transpiration 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; double defaultCm = Canopy.Ca * Canopy.CPath.CiCaRatio; var results = new bool[6]; // Initial calculation results[0] = (SunlitAc1.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), defaultCm, mode, maxHourlyT, sunlitFraction)); results[1] = (SunlitAc2.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), defaultCm, mode, maxHourlyT, sunlitFraction)); results[2] = (SunlitAj.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), defaultCm, mode, maxHourlyT, sunlitFraction)); results[3] = (ShadedAc1.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), defaultCm, mode, maxHourlyT, shadedFraction)); results[4] = (ShadedAc2.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), defaultCm, mode, maxHourlyT, shadedFraction)); results[5] = (ShadedAj.CalcPhotosynthesis(this, useAirTemp, 0, EnvModel.GetTemp(Time), defaultCm, mode, maxHourlyT, shadedFraction)); // After initialisation we use new leaf temperature useAirTemp = false; // SUNLIT CALCULATIONS double defaultAC1A = 0.0; double defaultAC1Water = 0.0; double defaultAC2A = 0.0; double defaultAC2Water = 0.0; double defaultAJA = 0.0; double defaultAJWater = 0.0; // If the initial calculation fails, set values to 0 if (results[0] || results[1] || results[2]) { SunlitAc1.A[0] = 0.0; SunlitAc1.WaterUse[0] = 0.0; SunlitAc2.A[0] = 0.0; SunlitAc2.WaterUse[0] = 0.0; SunlitAj.A[0] = 0.0; SunlitAj.WaterUse[0] = 0.0; } else { defaultAC1A = SunlitAc1.A[0]; defaultAC1Water = SunlitAc1.WaterUse[0]; defaultAC2A = SunlitAc2.A[0]; defaultAC2Water = SunlitAc2.WaterUse[0]; defaultAJA = SunlitAj.A[0]; defaultAJWater = SunlitAj.WaterUse[0]; } // If there is sufficient photosynthetic rate if (SunlitAc1.A[0] > 0.5 && SunlitAc2.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], SunlitAc1.Cm[0], mode, maxHourlyT, sunlitFraction)); results[1] = (SunlitAc2.CalcPhotosynthesis(this, useAirTemp, 0, SunlitAc2.LeafTemp[0], SunlitAc2.Cm[0], mode, maxHourlyT, sunlitFraction)); results[2] = (SunlitAj.CalcPhotosynthesis(this, useAirTemp, 0, SunlitAj.LeafTemp[0], SunlitAj.Cm[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] || results[2]) { SunlitAc1.A[0] = defaultAC1A; SunlitAc1.WaterUse[0] = defaultAC1Water; SunlitAc2.A[0] = defaultAC2A; SunlitAc2.WaterUse[0] = defaultAC2Water; SunlitAj.A[0] = defaultAJA; SunlitAj.WaterUse[0] = defaultAC1Water; break; } } } // SHADED CALCULATIONS // If the initial calculation fails, set values to 0 if (results[3] || results[4] || results[5]) { ShadedAc1.A[0] = 0.0; ShadedAc1.WaterUse[0] = 0.0; ShadedAc2.A[0] = 0.0; ShadedAc2.WaterUse[0] = 0.0; ShadedAj.A[0] = 0.0; ShadedAj.WaterUse[0] = 0.0; } else { defaultAC1A = ShadedAc1.A[0]; defaultAC1Water = ShadedAc1.WaterUse[0]; defaultAC2A = ShadedAc2.A[0]; defaultAC2Water = ShadedAc2.WaterUse[0]; defaultAJA = ShadedAj.A[0]; defaultAJWater = ShadedAj.WaterUse[0]; } // If there is sufficient photosynthetic rate if (ShadedAc1.A[0] > 0.5 && ShadedAc2.A[0] > 0.5 && ShadedAj.A[0] > 0.5) { for (int n = 0; n < 3; n++) { results[3] = (ShadedAc1.CalcPhotosynthesis(this, useAirTemp, 0, ShadedAc1.LeafTemp[0], ShadedAc1.Cm[0], mode, maxHourlyT, shadedFraction)); results[4] = (ShadedAc2.CalcPhotosynthesis(this, useAirTemp, 0, ShadedAc2.LeafTemp[0], ShadedAc2.Cm[0], mode, maxHourlyT, shadedFraction)); results[5] = (ShadedAj.CalcPhotosynthesis(this, useAirTemp, 0, ShadedAj.LeafTemp[0], ShadedAj.Cm[0], mode, maxHourlyT, shadedFraction)); // If any of the above is < 0, set both values zero (for each type of leaf separately). if (results[3] || results[4] || results[5]) { ShadedAc1.A[0] = defaultAC1A; ShadedAc1.WaterUse[0] = defaultAC1Water; ShadedAc2.A[0] = defaultAC2A; ShadedAc2.WaterUse[0] = defaultAC2Water; ShadedAj.A[0] = defaultAJA; ShadedAj.WaterUse[0] = defaultAJWater; } } } if (sendNotification && NotifyFinish != null) { NotifyFinish(); } }
public ConsulKVHelper(ConsulClient client) { this.envModel = EnvHelper.GetEnv(); this.client = client; this.keyPrefix = $"apps/{envModel.APP_BUILD_NAME}/{envModel.ASPNETCORE_ENVIRONMENT}/"; }
//--------------------------------------------------------------------------- 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(); } }
public override double[] RunApsim(int DOY, double latitude, double maxT, double minT, double radn, double lai, double SLN, double soilWaterAvail, double RootShootRatio) { // PM = new LayerCanopyPhotosynthesis.PhotosynthesisModelC4(); EnvModel.Initialised = false; EnvModel.LatitudeD = latitude; EnvModel.DOY = (int)DOY; EnvModel.MaxT = maxT; EnvModel.MinT = minT; EnvModel.Radn = radn; // Check that this changes ratio Canopy.LAI = lai; Canopy.CPath.SLNAv = SLN; EnvModel.Initialised = true; EnvModel.Run(); Initialised = true; List <double> sunlitWaterDemands = new List <double>(); List <double> shadedWaterDemands = new List <double>(); List <double> hourlyWaterDemandsmm = new List <double>(); List <double> hourlyWaterSuppliesmm = new List <double>(); List <double> sunlitAssimilations = new List <double>(); List <double> shadedAssimilations = new List <double>(); List <double> interceptedRadn = new List <double>(); double d = Canopy.CPath.CiCaRatio; for (int time = 6; time <= 18; time++) { //This run is to get potential water use if (time > EnvModel.Sunrise && time < EnvModel.Sunset) { Run(time, soilWaterAvail); //sunlitWaterDemands.Add(Math.Min(Math.Min(SunlitAC1.Elambda_[0], sunlitAC2.Elambda_[0]), SunlitAJ.Elambda_[0])); //shadedWaterDemands.Add(Math.Min(Math.Min(ShadedAC1.Elambda_[0], shadedAC2.Elambda_[0]), ShadedAJ.Elambda_[0])); sunlitWaterDemands.Add(Math.Min(Math.Min(SunlitAC1.WaterUse[0], sunlitAC2.WaterUse[0]), SunlitAJ.WaterUse[0])); shadedWaterDemands.Add(Math.Min(Math.Min(ShadedAC1.WaterUse[0], shadedAC2.WaterUse[0]), ShadedAJ.WaterUse[0])); sunlitWaterDemands[sunlitWaterDemands.Count - 1] = Math.Max(sunlitWaterDemands.Last(), 0); shadedWaterDemands[shadedWaterDemands.Count - 1] = Math.Max(shadedWaterDemands.Last(), 0); hourlyWaterDemandsmm.Add((sunlitWaterDemands.Last() + shadedWaterDemands.Last())); //hourlyWaterDemandsmm.Add((sunlitWaterDemands.Last() + shadedWaterDemands.Last()) / Canopy.Lambda * 1000 * 0.001 * 3600); hourlyWaterSuppliesmm.Add(hourlyWaterDemandsmm.Last()); } else { sunlitWaterDemands.Add(0); shadedWaterDemands.Add(0); hourlyWaterDemandsmm.Add(0); hourlyWaterSuppliesmm.Add(0); } sunlitAssimilations.Add(0); shadedAssimilations.Add(0); } double maxHourlyT = hourlyWaterSuppliesmm.Max(); while (hourlyWaterSuppliesmm.Sum() > soilWaterAvail) { maxHourlyT *= 0.99; for (int i = 0; i < hourlyWaterSuppliesmm.Count; i++) { if (hourlyWaterSuppliesmm[i] > maxHourlyT) { hourlyWaterSuppliesmm[i] = maxHourlyT; } } } sunlitAssimilations.Clear(); shadedAssimilations.Clear(); //Now that we have our hourly supplies we can calculate again for (int time = 6; time <= 18; time++) { double TSupply = hourlyWaterSuppliesmm[time - 6]; double sunlitWaterDemand = sunlitWaterDemands[time - 6]; double shadedWaterDemand = shadedWaterDemands[time - 6]; double totalWaterDemand = sunlitWaterDemand + shadedWaterDemand; if (time > EnvModel.Sunrise && time < EnvModel.Sunset) { Run(time, soilWaterAvail, hourlyWaterSuppliesmm[time - 6], sunlitWaterDemand / totalWaterDemand, shadedWaterDemand / totalWaterDemand); sunlitAssimilations.Add(Math.Min(Math.Min(SunlitAC1.A[0], sunlitAC2.A[0]), SunlitAJ.A[0])); shadedAssimilations.Add(Math.Min(Math.Min(ShadedAC1.A[0], shadedAC2.A[0]), ShadedAJ.A[0])); sunlitAssimilations[sunlitAssimilations.Count - 1] = Math.Max(sunlitAssimilations.Last(), 0); shadedAssimilations[shadedAssimilations.Count - 1] = Math.Max(shadedAssimilations.Last(), 0); double propIntRadn = Canopy.PropnInterceptedRadns.Sum(); interceptedRadn.Add(EnvModel.TotalIncidentRadiation * propIntRadn * 3600); interceptedRadn[interceptedRadn.Count - 1] = Math.Max(interceptedRadn.Last(), 0); } else { sunlitAssimilations.Add(0); shadedAssimilations.Add(0); interceptedRadn.Add(0); } } double[] results = new double[4]; results[0] = (sunlitAssimilations.Sum() + shadedAssimilations.Sum()) * 3600 / 1000000 * 44 * B * 100 / ((1 + RootShootRatio) * 100); results[1] = hourlyWaterDemandsmm.Sum(); results[2] = hourlyWaterSuppliesmm.Sum(); results[3] = interceptedRadn.Sum(); return(results); }
/// <summary> /// 使用 系统启动可以自动注册以及关闭时候反注册服务 /// </summary> /// <param name="app"></param> /// <param name="lifetime"></param> /// <returns></returns> public static IApplicationBuilder UseMicroService(this IApplicationBuilder app, IApplicationLifetime lifetime) { // 从管道中获取 环境变量配置 EnvModel envModel = app.ApplicationServices.GetService <EnvModel>(); // 从管道中获取 Consul客户端 var consulClient = app.ApplicationServices.GetService <ConsulClient>(); // 从管道中获取 获取 微服务配置 AgentServiceOption _agentServiceOption = app.ApplicationServices.GetService <AgentServiceOption>(); // 从管道中获取 获取服务注册的服务实例 IAgentServiceHelper _AgentServiceBuilder = app.ApplicationServices.GetService <IAgentServiceHelper>(); IConsulKVHelper _ConsulKVHelper = app.ApplicationServices.GetService <IConsulKVHelper>(); // 中间件1 : 健康检查 app.UseHealthChecks(_agentServiceOption.Service_HealthCheck_Route, new HealthCheckOptions() { ResultStatusCodes = { [MsHealthStatus.Healthy] = StatusCodes.Status200OK, [MsHealthStatus.Degraded] = StatusCodes.Status200OK, [MsHealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable }, AllowCachingResponses = false, ResponseWriter = WriteResponse }); #region 务注册 // 构建 服务注册 信息 AgentServiceRegistration serviceRegistration = _AgentServiceBuilder.BuildMicroServiceRegisterInfo(_agentServiceOption); // 取消注册(使用生命周期) lifetime.ApplicationStopping.Register(() => { consulClient.Agent.ServiceDeregister(serviceRegistration.ID).Wait(); Console.WriteLine("--------------------------------------------------------------------------------"); Console.WriteLine($"---------- [{DateTime.Now}] 服务[{serviceRegistration.ID}]:反注册成功"); Console.WriteLine("--------------------------------------------------------------------------------"); Console.WriteLine(); }); // 添加 注册(先反注册再注册) consulClient.Agent.ServiceRegister(serviceRegistration).Wait(); Console.WriteLine("--------------------------------------------------------------------------------"); Console.WriteLine($"---------- [{DateTime.Now}] 服务[{serviceRegistration.ID}]:注册成功"); Console.WriteLine("--------------------------------------------------------------------------------"); Console.WriteLine(); // 添加健康检查 管道 app.UseMiddleware <HealthCheckMiddleware>(); Console.WriteLine("--------------------------------------------------------------------------------"); Console.WriteLine($"---------- [{DateTime.Now}] 注册:健康检查中间件启动"); Console.WriteLine("--------------------------------------------------------------------------------"); Console.WriteLine(); #endregion #region 添加HangFire组件 SchedulerOption schedulerOption = app.ApplicationServices.GetService <SchedulerOption>(); if (schedulerOption.IsEnable) { Console.WriteLine("--------------------------------------------------------------------------------"); Console.WriteLine($"---------- [{DateTime.Now}] 启动调度器服务 ----------"); app.UseHangfireServer(options: schedulerOption.BackgroundJobServerOptions);//启动Hangfire服务 if (schedulerOption.UseDashboard) { Console.WriteLine($"---------- [{DateTime.Now}] 启动调度器管理页面 ----------"); app.UseHangfireDashboard(); } Console.WriteLine("--------------------------------------------------------------------------------"); } #endregion return(app); }