/// <summary> /// /// </summary> public void CalculateRootGrowth() { try { RootDepth = RootDepth + InputModel.DailyRootGrowth; RootDepth = MathTools.CheckConstraints(RootDepth, InputModel.MaxRootDepth, 0); } catch (Exception ex) { throw ErrorLogger.CreateException(ex); } }
/// <summary> /// This subroutine calculates growth stress factors for todays_temp /// and water /// </summary> public void CalculateGrowthStressFactors() { try { // ****************************** // * Temperature stress index * // ****************************** // [Equation 2.235] from EPIC double ratio; if (!MathTools.DoublesAreEqual(InputModel.OptTemp, InputModel.BaseTemp)) { ratio = (Engine.ClimateModule.Temperature - InputModel.BaseTemp) / (InputModel.OptTemp - InputModel.BaseTemp); } else { ratio = 1; //dont log error for this one } TempStressIndex = Math.Sin(0.5 * Math.PI * ratio); TempStressIndex = Math.Max(TempStressIndex, 0.0); TempStressIndex = Math.Min(TempStressIndex, 1.0); // ************************ // * Water stress index * // ************************ WaterStressIndex = 1.0; if (PotTranspiration > 0.0) { WaterStressIndex = TotalTranspiration / PotTranspiration; } WaterStressIndex = Math.Max(WaterStressIndex, 0.0); WaterStressIndex = Math.Min(WaterStressIndex, 1.0); // ************************************* // * calculate minimum stress factor * // ************************************* GrowthRegulator = 1; GrowthRegulator = Math.Min(GrowthRegulator, TempStressIndex); GrowthRegulator = Math.Min(GrowthRegulator, WaterStressIndex); GrowthRegulator = MathTools.CheckConstraints(GrowthRegulator, 1.0, 0); } catch (Exception ex) { throw ErrorLogger.CreateException(ex); } }
/// <summary> /// /// </summary> public void CalculateTranspiration() { for (int i = 0; i < sim.in_LayerCount; ++i) { sim.layer_transpiration[i] = 0; } out_PotTranspiration_mm = CalculatePotentialTranspiration(); if (out_PotTranspiration_mm > 0) { double psup; // std::vector<double>density; // std::vector<double>supply; // std::vector<double>root_penetration; double[] density = new double[10]; double[] supply = new double[10]; double[] root_penetration = new double[10]; // total_transpiration=1;//REMOVE THIS // return ;//REMOVE THIS // density.resize(sim.in_LayerCount); // supply.resize(sim.in_LayerCount); // root_penetration.resize(sim.in_LayerCount); // initialize transpiration array for (int i = 0; i < sim.in_LayerCount; ++i) { sim.layer_transpiration[i] = 0; } // Calculate soil water supply index for (int i = 0; i < sim.in_LayerCount; ++i) { double denom = sim.DrainUpperLimit_rel_wp[i]; if (MathTools.DoublesAreEqual(denom, 0)) { sim.mcfc[i] = MathTools.CheckConstraints(sim.SoilWater_rel_wp[i] / denom, 1.0, 0.0); } else { sim.mcfc[i] = 0; //LogDivideByZeroError("CalculateTranspiration","sim.DrainUpperLimit_rel_wp[i]","sim.mcfc[i]"); } if (sim.mcfc[i] >= 0.3) { supply[i] = 1.0; } else { supply[i] = sim.mcfc[i] / 0.3; } } // Calculate root penetration per layer (root_penetration) // Calculate root density per layer (density) root_penetration[0] = 1.0; density[0] = 1.0; for (int i = 1; i < sim.in_LayerCount; ++i) { if (sim.depth[i + 1] - sim.depth[i] > 0) { root_penetration[i] = Math.Min(1.0, Math.Max(out_RootDepth_mm - sim.depth[i], 0) / (sim.depth[i + 1] - sim.depth[i])); if (sim.depth[i + 1] > 300) { if (MathTools.DoublesAreEqual(MaximumRootDepth, 300)) { density[i] = Math.Max(0.0, (1.0 - 0.50 * Math.Min(1.0, (sim.depth[i + 1] - 300.0) / (MaximumRootDepth - 300.0)))); } else { density[i] = 0.5; //dont log this error } } else { density[i] = 1.0; } } else { root_penetration[i] = 0; density[i] = 1.0; //string text1="sim.depth["+string(i+1)+"]-sim.depth["+string(i)+"] ("+FormatFloat("0.#",sim.depth[i+1])+"-"+FormatFloat("0.#",sim.depth[i])+")"; //LogDivideByZeroError("CalculateTranspiration",text1,"root_penetration["+String(i)+"]"); } } // Calculate transpiration from each layer psup = 0; for (int i = 0; i < sim.in_LayerCount; ++i) { if (root_penetration[i] < 1.0 && sim.mcfc[i] <= (1.0 - root_penetration[i])) { sim.layer_transpiration[i] = 0.0; } else { sim.layer_transpiration[i] = density[i] * supply[i] * out_PotTranspiration_mm; } if (sim.layer_transpiration[i] > sim.SoilWater_rel_wp[i]) { sim.layer_transpiration[i] = Math.Max(0.0, sim.SoilWater_rel_wp[i]); } psup = psup + sim.layer_transpiration[i]; } // reduce transpiration if more than potential transpiration if (!MathTools.DoublesAreEqual(psup, 0) && psup > out_PotTranspiration_mm) { for (int i = 0; i < sim.in_LayerCount; ++i) { sim.layer_transpiration[i] *= out_PotTranspiration_mm / psup; } } total_transpiration = 0; for (int i = 0; i < sim.in_LayerCount; ++i) { total_transpiration += sim.layer_transpiration[i]; // sim.layer_transpiration[i]=layer_transpiration[i]; } } else { for (int i = 0; i < sim.in_LayerCount; ++i) { sim.layer_transpiration[i] = 0; } total_transpiration = 0; } accumulated_transpiration += total_transpiration; }
public void CalculateTranspiration() { for (int i = 0; i < Engine.SoilModule.LayerCount; ++i) { Engine.SoilModule.LayerTranspiration[i] = 0; } PotTranspiration = CalculatePotentialTranspiration(); if (PotTranspiration > 0) { double psup; double[] density = new double[10]; double[] supply = new double[10]; double[] rootPenetration = new double[10]; // initialize transpiration array //Didn't we just do this ! //for (int i = 0; i < Sim.SoilController.LayerCount; ++i) //{ // Sim.SoilController.LayerTranspiration[i] = 0; //} // Calculate soil water supply index for (int i = 0; i < Engine.SoilModule.LayerCount; ++i) { double denom = Engine.SoilModule.DrainUpperLimitRelWP[i]; if (!MathTools.DoublesAreEqual(denom, 0)) { Engine.SoilModule.MCFC[i] = MathTools.CheckConstraints(Engine.SoilModule.SoilWaterRelWP[i] / denom, 1.0, 0.0); } else { Engine.SoilModule.MCFC[i] = 0; //LogDivideByZeroError("CalculateTranspiration","sim.DrainUpperLimit_rel_wp[i]","sim.mcfc[i]"); } //TODO: the 0.3 here is the SWPropForNoStress variable - need to implement if (Engine.SoilModule.MCFC[i] >= 0.3) { supply[i] = 1.0; } else { supply[i] = Engine.SoilModule.MCFC[i] / 0.3; } } // Calculate root penetration per layer (root_penetration) // Calculate root density per layer (density) rootPenetration[0] = 1.0; density[0] = 1.0; for (int i = 1; i < Engine.SoilModule.LayerCount; ++i) { if (Engine.SoilModule.Depth[i + 1] - Engine.SoilModule.Depth[i] > 0) { rootPenetration[i] = Math.Min(1.0, Math.Max(RootDepth - Engine.SoilModule.Depth[i], 0) / (Engine.SoilModule.Depth[i + 1] - Engine.SoilModule.Depth[i])); if (Engine.SoilModule.Depth[i + 1] > 300) { if (!MathTools.DoublesAreEqual(MaximumRootDepth, 300)) { //density[i] = Math.Max(0.0, (1.0 - 0.50 * Math.Min(1.0, (Sim.SoilController.Depth[i + 1] - 300.0) / (MaximumRootDepth - 300.0)))); density[i] = Math.Max(0.0, (1.0 - 0.50 * Math.Min(1.0, (Engine.SoilModule.Depth[i + 1] - 300.0) / (RootDepth - 300.0)))); } else { density[i] = 0.5; //dont log this error } } else { density[i] = 1.0; } } else { rootPenetration[i] = 0; density[i] = 1.0; //string text1="sim.depth["+string(i+1)+"]-sim.depth["+string(i)+"] ("+FormatFloat("0.#",sim.depth[i+1])+"-"+FormatFloat("0.#",sim.depth[i])+")"; //LogDivideByZeroError("CalculateTranspiration",text1,"root_penetration["+String(i)+"]"); } } // Calculate transpiration from each layer psup = 0; for (int i = 0; i < Engine.SoilModule.LayerCount; ++i) { if (rootPenetration[i] < 1.0 && Engine.SoilModule.MCFC[i] <= (1.0 - rootPenetration[i])) { Engine.SoilModule.LayerTranspiration[i] = 0.0; } else { Engine.SoilModule.LayerTranspiration[i] = density[i] * supply[i] * PotTranspiration; } if (Engine.SoilModule.LayerTranspiration[i] > Engine.SoilModule.SoilWaterRelWP[i]) { Engine.SoilModule.LayerTranspiration[i] = Math.Max(0.0, Engine.SoilModule.SoilWaterRelWP[i]); } psup = psup + Engine.SoilModule.LayerTranspiration[i]; } // reduce transpiration if more than potential transpiration if (!MathTools.DoublesAreEqual(psup, 0) && psup > PotTranspiration) { for (int i = 0; i < Engine.SoilModule.LayerCount; ++i) { Engine.SoilModule.LayerTranspiration[i] *= PotTranspiration / psup; } } TotalTranspiration = 0; for (int i = 0; i < Engine.SoilModule.LayerCount; ++i) { TotalTranspiration += Engine.SoilModule.LayerTranspiration[i]; } } else { for (int i = 0; i < Engine.SoilModule.LayerCount; ++i) { Engine.SoilModule.LayerTranspiration[i] = 0; } TotalTranspiration = 0; } AccumulatedTranspiration += TotalTranspiration; CropTranspiration = TotalTranspiration; CropEvapoTranspiration = CropTranspiration + Engine.SoilModule.SoilEvap; Engine.SoilModule.EvapoTransp += CropTranspiration; Engine.SoilModule.Transpiration = CropTranspiration; }
/// <summary> /// /// </summary> public void CalculateRootGrowth() { RootDepth = RootDepth + InputModel.DailyRootGrowth; RootDepth = MathTools.CheckConstraints(RootDepth, MaximumRootDepth, 0); }