//--------------------------------------------------------------------------------------------------------- public double calcLeafTemperature(PhotosynthesisModel PM, int layer, double _leafTemp) { EnvironmentModel EM = PM.envModel; LeafCanopy canopy = PM.canopy; double airTemp = EM.getTemp(PM.time); s[layer] = (es[layer] - canopy.es_Ta) / (leafTemp[layer] - EM.maxT); gs[layer] = gs_CO2[layer] / canopy.ra; rs_H2O[layer] = (1 / gs[layer] - 1.3 * canopy.rb_H_LAIs[layer] - canopy.rts[layer]) / 1.6; Sn[layer] = canopy.energyConvRatio * absorbedIrradiance[layer]; R_[layer] = canopy.Bz * Math.Pow((leafTemp[layer] + 273), 4) * canopy.fvap * canopy.fclear * LAIS[layer] / canopy.LAIs.Sum(); Rn[layer] = Sn[layer] - R_[layer]; lE[layer] = (s[layer] * Rn[layer] + canopy.airDensity * canopy.cp * VPD[layer] / (canopy.rb_H_LAIs[layer] + canopy.rts[layer])) / (s[layer] + canopy.g * ((canopy.rb_H2O_LAIs[layer] + canopy.rts[layer] + rs_H2O[layer]) / (canopy.rb_H_LAIs[layer] + canopy.rts[layer]))); double calcLeafTemp = airTemp + (canopy.rb_H_LAIs[layer] + canopy.rts[layer]) * (Rn[layer] - lE[layer]) / (canopy.airDensity * canopy.cp); //return Math.Pow(1 - _leafTemp / calcLeafTemp, 2); return(Math.Pow(_leafTemp - calcLeafTemp, 2)); }
void CalcConductanceResistance(PhotosynthesisModel PM) { for (int i = 0; i < _nLayers; i++) { //Intercepted radiation //Saturated vapour pressure ES = PM.EnvModel.CalcSVP(PM.EnvModel.GetTemp(PM.Time)); ES1 = PM.EnvModel.CalcSVP(PM.EnvModel.GetTemp(PM.Time) + 1); S = (ES1 - ES) / ((PM.EnvModel.GetTemp(PM.Time) + 1) - PM.EnvModel.GetTemp(PM.Time)); //Wind speed //us[i] = u0 * Math.Exp(-ku * (i + 1)); Us[i] = U0; Rair = PM.EnvModel.ATM * 100000 / (287 * (PM.EnvModel.GetTemp(PM.Time) + 273)) * 1000 / 28.966; Gbh[i] = 0.01 * Math.Pow((Us[i] / LeafWidth), 0.5) * (1 - Math.Exp(-0.5 * Ku * LAI)) / (0.5 * Ku); //Boundary layer //rb_Hs[i] = 100 * Math.Pow((leafWidths[i] / us[i]), 0.5); //rb_H2Os[i] = 0.93 * rb_Hs[i]; //rb_CO2s[i] = 1.37 * rb_H2Os[i]; //rts[i] = 0.74 * Math.Pow(Math.Log(2 - 0.7 * Height) / (0.1 * Height), 2) / (0.16 * us[i]) / LAIs[i]; //rb_H_LAIs[i] = rb_Hs[i] / LAIs[i]; //rb_H2O_LAIs[i] = rb_H2Os[i] / LAIs[i]; } }
//---------------------------------------------------------------------- public void CalcRdActivity25(LeafCanopy canopy, SunlitShadedCanopy sunlit, PhotosynthesisModel PM) { for (int i = 0; i < _nLayers; i++) { Rd25[i] = canopy.Rd25[i] - sunlit.Rd25[i]; } }
//--------------------------------------------------------------------------------------------------------- public void CalcPRate25(LeafCanopy canopy, SunlitShadedCanopy sunlit, PhotosynthesisModel PM) { for (int i = 0; i < _nLayers; i++) { VpMax25[i] = canopy.VpMax25[i] - sunlit.VpMax25[i]; } }
//--------------------------------------------------------------------------------------------------------- public virtual void run(int nlayers, PhotosynthesisModel PM, SunlitShadedCanopy counterpart) { _nLayers = nlayers; initArrays(_nLayers); calcIncidentRadiation(PM.envModel, PM.canopy, counterpart); calcAbsorbedRadiation(PM.envModel, PM.canopy, counterpart); calcMaxRates(PM.canopy, counterpart, PM); }
//----------------------------------------------------------------------- public void run(PhotosynthesisModel PM, EnvironmentModel EM) { calcAbsorbedRadiation(EM); calcLeafNitrogenDistribution(PM); calcConductanceResistance(); calcLeafTemperature(PM, EM); calcTotalLeafNitrogen(PM); }
//----------------------------------------------------------------------- void CalcLeafNitrogenDistribution(PhotosynthesisModel PM) { //-------------This is only when coupled with Apsim---------------------------------------- //-------------Otherwise use parameters---------------------------------------------------- if (PM.nitrogenModel == PhotosynthesisModel.NitrogenModel.APSIM) { SLNTop = PM.Canopy.CPath.SLNAv * PM.Canopy.CPath.SLNRatioTop; LeafNTopCanopy = SLNTop * 1000 / 14; NcAv = PM.Canopy.CPath.SLNAv * 1000 / 14; NAllocationCoeff = -1 * Math.Log((NcAv - PM.Canopy.CPath.StructuralN) / (LeafNTopCanopy - PM.Canopy.CPath.StructuralN)) * 2; } //-------------This is only when coupled with Apsim---------------------------------------- else { SLNTop = LeafNTopCanopy / 1000 * 14; NcAv = (LeafNTopCanopy - PM.Canopy.CPath.StructuralN) * Math.Exp(-0.5 * NAllocationCoeff) + PM.Canopy.CPath.StructuralN; PM.Canopy.CPath.SLNAv = NcAv / 1000 * 14; PM.Canopy.CPath.SLNRatioTop = SLNTop / PM.Canopy.CPath.SLNAv; } for (int i = 0; i < _nLayers; i++) { LeafNs[i] = CalcSLN(LAIAccums[i], PM.Canopy.CPath.StructuralN); VcMax25[i] = LAI * CPath.PsiVc * (LeafNTopCanopy - PM.Canopy.CPath.StructuralN) * ( (i == 0 ? 1 : Math.Exp(-NAllocationCoeff * LAIAccums[i - 1] / LAI)) - Math.Exp(-NAllocationCoeff * LAIAccums[i] / LAI)) / NAllocationCoeff; //J2Max25[i] = LAI * CPath.PsiJ2 * (LeafNTopCanopy - PM.Canopy.CPath.StructuralN) * ( // (i == 0 ? 1 : Math.Exp(-NAllocationCoeff * LAIAccums[i - 1] / LAI)) - // Math.Exp(-NAllocationCoeff * LAIAccums[i] / LAI)) / NAllocationCoeff; JMax25[i] = LAI * CPath.PsiJ * (LeafNTopCanopy - PM.Canopy.CPath.StructuralN) * ( (i == 0 ? 1 : Math.Exp(-NAllocationCoeff * LAIAccums[i - 1] / LAI)) - Math.Exp(-NAllocationCoeff * LAIAccums[i] / LAI)) / NAllocationCoeff; Rd25[i] = LAI * CPath.PsiRd * (LeafNTopCanopy - PM.Canopy.CPath.StructuralN) * ( (i == 0 ? 1 : Math.Exp(-NAllocationCoeff * LAIAccums[i - 1] / LAI)) - Math.Exp(-NAllocationCoeff * LAIAccums[i] / LAI)) / NAllocationCoeff; VpMax25[i] = LAI * CPath.PsiVp * (LeafNTopCanopy - PM.Canopy.CPath.StructuralN) * ( (i == 0 ? 1 : Math.Exp(-NAllocationCoeff * LAIAccums[i - 1] / LAI)) - Math.Exp(-NAllocationCoeff * LAIAccums[i] / LAI)) / NAllocationCoeff; //Gm25[i] = CPath.PsiGm * (NcAv - PM.Canopy.CPath.StructuralN) + CPath.CGm; Gm25[i] = LAI * CPath.PsiGm * (LeafNTopCanopy - PM.Canopy.CPath.StructuralN) * ( (i == 0 ? 1 : Math.Exp(-NAllocationCoeff * LAIAccums[i - 1] / LAI)) - Math.Exp(-NAllocationCoeff * LAIAccums[i] / LAI)) / NAllocationCoeff; } }
//--------------------------------------------------------------------------------------------------------- public void calcPRate25(LeafCanopy canopy, SunlitShadedCanopy shaded, PhotosynthesisModel PM) { for (int i = 0; i < _nLayers; i++) { VpMax25[i] = canopy.LAI * canopy.CPath.psiVp * (canopy.leafNTopCanopy - canopy.CPath.structuralN) * ((i == 0 ? 1 : Math.Exp(-(canopy.beamExtCoeffs[i] + canopy.NAllocationCoeff / canopy.LAI) * canopy.LAIAccums[i - 1])) - Math.Exp(-(canopy.beamExtCoeffs[i] + canopy.NAllocationCoeff / canopy.LAI) * canopy.LAIAccums[i])) / (canopy.NAllocationCoeff + canopy.beamExtCoeffs[i] * canopy.LAI); } }
public void Run(PhotosynthesisModel PM, EnvironmentModel EM) { //calcCanopyStructure(EM.sunAngle.rad); CalcAbsorbedRadiation(EM); CalcLeafNitrogenDistribution(PM); CalcConductanceResistance(PM); CalcLeafTemperature(PM, EM); CalcTotalLeafNitrogen(PM); }
//---------------------------------------------------------------------- public void CalcRdActivity25(LeafCanopy canopy, SunlitShadedCanopy shaded, PhotosynthesisModel PM) { for (int i = 0; i < _nLayers; i++) { Rd25[i] = canopy.LAI * canopy.CPath.PsiRd * (canopy.LeafNTopCanopy - canopy.CPath.StructuralN) * ((i == 0 ? 1 : Math.Exp(-(canopy.BeamExtCoeffs[i] + canopy.NAllocationCoeff / canopy.LAI) * canopy.LAIAccums[i - 1])) - Math.Exp(-(canopy.BeamExtCoeffs[i] + canopy.NAllocationCoeff / canopy.LAI) * canopy.LAIAccums[i])) / (canopy.NAllocationCoeff + canopy.BeamExtCoeffs[i] * canopy.LAI); } }
//--------------------------------------------------------------------------------------------------------- public override void CalcConductanceResistance(PhotosynthesisModel PM, LeafCanopy canopy) { for (int i = 0; i < canopy.NLayers; i++) { Gbh[i] = 0.01 * Math.Pow((canopy.Us[i] / canopy.LeafWidth), 0.5) * (1 - Math.Exp(-1 * (0.5 * canopy.Ku + canopy.Kb) * canopy.LAI)) / (0.5 * canopy.Ku + canopy.Kb); } base.CalcConductanceResistance(PM, canopy); }
//--------------------------------------------------------------------------------------------------------- public void calcPhotosynthesis(PhotosynthesisModel PM, int layer) { LeafCanopy canopy = PM.canopy; leafTemp[layer] = PM.envModel.getTemp(PM.time); double vpd = PM.envModel.getVPD(PM.time); canopy.CPath.CiCaRatio = canopy.CPath.CiCaRatioSlope * vpd + canopy.CPath.CiCaRatioIntercept; VcMaxT[layer] = TempFunctionExp.val(leafTemp[layer], VcMax25[layer], canopy.CPath.VcMax_c, canopy.CPath.VcMax_b); RdT[layer] = TempFunctionExp.val(leafTemp[layer], Rd25[layer], canopy.CPath.Rd_c, canopy.CPath.Rd_b); JMaxT[layer] = TempFunction.val(leafTemp[layer], JMax25[layer], canopy.CPath.JMax_TOpt, canopy.CPath.JMax_Omega); VpMaxT[layer] = TempFunctionExp.val(leafTemp[layer], VpMax25[layer], canopy.CPath.VpMax_c, canopy.CPath.VpMax_b); Vpr[layer] = canopy.Vpr_l * LAIS[layer]; //TODO: I2 = canopy.ja * absorbedIrradiance[layer] canopy.ja = (1 - canopy.f) / 2; J[layer] = (canopy.ja * absorbedIrradiance[layer] + JMaxT[layer] - Math.Pow(Math.Pow(canopy.ja * absorbedIrradiance[layer] + JMaxT[layer], 2) - 4 * canopy.θ * JMaxT[layer] * canopy.ja * absorbedIrradiance[layer], 0.5)) / (2 * canopy.θ); Kc[layer] = TempFunctionExp.val(leafTemp[layer], canopy.CPath.Kc_P25, canopy.CPath.Kc_c, canopy.CPath.Kc_b); Ko[layer] = TempFunctionExp.val(leafTemp[layer], canopy.CPath.Ko_P25, canopy.CPath.Ko_c, canopy.CPath.Ko_b); VcVo[layer] = TempFunctionExp.val(leafTemp[layer], canopy.CPath.VcMax_VoMax_P25, canopy.CPath.VcMax_VoMax_c, canopy.CPath.VcMax_VoMax_b); ScO[layer] = Ko[layer] / Kc[layer] * VcVo[layer]; g_[layer] = 0.5 / ScO[layer]; canopy.Sco = ScO[layer]; //For reporting ??? K_[layer] = Kc[layer] * (1 + canopy.oxygenPartialPressure / Ko[layer]); es[layer] = 5.637E-7 * Math.Pow(leafTemp[layer], 4) + 1.728E-5 * Math.Pow(leafTemp[layer], 3) + 1.534E-3 * Math.Pow(leafTemp[layer], 2) + 4.424E-2 * leafTemp[layer] + 6.095E-1; canopy.airDensity = 1.295 * Math.Exp(-3.6E-3 * PM.envModel.getTemp(PM.time)); canopy.ra = canopy.airDensity * 1000.0 / 28.966; VPD[layer] = PM.envModel.getVPD(PM.time); fVPD[layer] = canopy.a / (1 + VPD[layer] / canopy.Do); gs[layer] = fVPD[layer]; gm_CO2T[layer] = LAIS[layer] * TempFunction.val(leafTemp[layer], canopy.CPath.gm_P25, canopy.CPath.gm_TOpt, canopy.CPath.gm_Omega); gb_CO2[layer] = 1 / canopy.rb_CO2s[layer] * LAIS[layer] * canopy.ra; }
public void CalcLeafTemperature(PhotosynthesisModel PM, EnvironmentModel EM) { //double airTemp = EM.getTemp(PM.time); //fvap = 0.56 - 0.079 * Math.Pow(10 * Vair, 0.5); //fclear = 0.1 + 0.9 * Math.Max(0, Math.Min(1, (EM.atmTransmissionRatio - 0.2) / 0.5)); //g = (cp * Math.Pow(10, -6)) * p / (l * mwRatio); //es_Ta = 5.637E-7 * Math.Pow(airTemp, 4) + 1.728E-5 * Math.Pow(airTemp, 3) + 1.534E-3 * // Math.Pow(airTemp, 2) + 4.424E-2 * airTemp + 6.095E-1; //a2 = CPath.F2 * (1 - CPath.fcyc) / (CPath.F2 / CPath.F1 + (1 - CPath.fcyc)); }
public void CalcCanopyBiomassAccumulation(PhotosynthesisModel PM) { //for (int i = 0; i < nLayers; i++) //{ // //TODO -- Rename / refactor variables to reflect units and time // //TODO -- calculate biomass using B after daily A has ben summed (ie 1 calculation per day) // //TODO -- check that we are only calculating between dawn and dusk // //TODO -- use floor and cieling on dusk and dawn to calculate assimilation times // Ac[i] = (PM.sunlit.A[i] + PM.shaded.A[i]) * 3600; // Rename (Acan, hour) (umolCo2/m2/s) // // Acgross[i] = Ac[i] * Math.Pow(10, -6) * 44; // (gCo2/m2/s) // biomassC[i] = Ac[i] * 44 * B * Math.Pow(10, -6); // Hourly Biomass //} //totalBiomassC = biomassC.Sum(); }
////--------------------------------------------------------------------------------------------------------- /// <summary> /// /// </summary> /// <param name="PM"></param> /// <param name="canopy"></param> public virtual void CalcConductanceResistance(PhotosynthesisModel PM, LeafCanopy canopy) { for (int i = 0; i < canopy.NLayers; i++) { //gbh[i] = 0.01 * Math.Pow((canopy.us[i] / canopy.leafWidth), 0.5) * // (1 - Math.Exp(-1 * (0.5 * canopy.ku + canopy.kb) * canopy.LAI)) / (0.5 * canopy.ku + canopy.kb); Gbw[i] = Gbh[i] / 0.92; //This 0.92 changed from 0.93 29/06 Rbh[i] = 1 / Gbh[i]; Rbw[i] = 1 / Gbw[i]; Gbw_m[i] = PM.EnvModel.ATM * PM.Canopy.Rair * Gbw[i]; GbCO2[i] = Gbw_m[i] / 1.37; } }
//-------------------------------------------------------------- public PhotoLayerSolverC3(PhotosynthesisModel PM, int layer) : base(PM, layer) { }
//--------------------------------------------------------------------------------------------------------- public void CalcElectronTransportRate25(LeafCanopy canopy, SunlitShadedCanopy sunlit, PhotosynthesisModel PM) { for (int i = 0; i < _nLayers; i++) { //J2Max25[i] = canopy.J2Max25[i] - sunlit.J2Max25[i]; JMax25[i] = canopy.JMax25[i] - sunlit.JMax25[i]; } }
//--------------------------------------------------------------------------------------------------------- public override void CalcMaxRates(LeafCanopy canopy, SunlitShadedCanopy counterpart, PhotosynthesisModel PM) { CalcRubiscoActivity25(canopy, counterpart, PM); CalcElectronTransportRate25(canopy, counterpart, PM); CalcRdActivity25(canopy, counterpart, PM); CalcPRate25(canopy, counterpart, PM); CalcGmRate25(canopy, counterpart, PM); }
public abstract double calcPhotosynthesis(PhotosynthesisModel PM, SunlitShadedCanopy s, int layer, double _Cc);
//--------------------------------------------------------------------------------------------------------- /// <summary> /// /// </summary> /// <param name="PM"></param> /// <param name="canopy"></param> public virtual void DoWaterInteraction(PhotosynthesisModel PM, LeafCanopy canopy, TranspirationMode mode) { for (int i = 0; i < canopy.NLayers; i++) { Rn[i] = AbsorbedIrradiancePAR[i] + AbsorbedIrradianceNIR[i]; double BnUp = 8 * canopy.Sigma * Math.Pow((PM.EnvModel.GetTemp(PM.Time) + PM.EnvModel.AbsoluteTemperature), 3) * (LeafTemp__[i] - PM.EnvModel.GetTemp(PM.Time)); //This should be: HEnergyBalance - * (LeafTemp__[i]-PM.EnvModel.GetTemp(PM.Time)); double VPTLeaf = 0.61365 * Math.Exp(17.502 * LeafTemp__[i] / (240.97 + LeafTemp__[i])); double VPTAir = 0.61365 * Math.Exp(17.502 * PM.EnvModel.GetTemp(PM.Time) / (240.97 + PM.EnvModel.GetTemp(PM.Time))); double VPTAir_1 = 0.61365 * Math.Exp(17.502 * (PM.EnvModel.GetTemp(PM.Time) + 1) / (240.97 + (PM.EnvModel.GetTemp(PM.Time) + 1))); double VPTMin = 0.61365 * Math.Exp(17.502 * PM.EnvModel.MinT / (240.97 + PM.EnvModel.MinT)); double s = VPTAir_1 - VPTAir; VPD_la[i] = VPTLeaf - VPTMin; double Wl = VPTLeaf / (PM.EnvModel.ATM * 100) * 1000; double Wa = VPTMin / (PM.EnvModel.ATM * 100) * 1000; if (mode == TranspirationMode.unlimited) { double a_var_gsCO2 = 1 / GbCO2[i]; double d_var_gsCO2 = (Wl - Wa) / (1000 - (Wl + Wa) / 2) * (canopy.Ca + Ci[i]) / 2; double e_var_gsCO2 = A[i]; double f_var_gsCO2 = canopy.Ca - Ci[i]; double m_var_gsCO2 = 1.37; //Constant double n_var_gsCO2 = 1.6; //Constant double a_lump_gsCO2 = e_var_gsCO2 * a_var_gsCO2 * m_var_gsCO2 + e_var_gsCO2 * a_var_gsCO2 * n_var_gsCO2 + d_var_gsCO2 * m_var_gsCO2 * n_var_gsCO2 - f_var_gsCO2 * m_var_gsCO2; double b_lump_gsCO2 = e_var_gsCO2 * m_var_gsCO2 * (e_var_gsCO2 * Math.Pow(a_var_gsCO2, 2) * n_var_gsCO2 + a_var_gsCO2 * d_var_gsCO2 * m_var_gsCO2 * n_var_gsCO2 - a_var_gsCO2 * f_var_gsCO2 * n_var_gsCO2); double c_lump_gsCO2 = -a_lump_gsCO2; double d_lump_gsCO2 = m_var_gsCO2 * A[i]; GsCO2[i] = 2 * d_lump_gsCO2 / (Math.Pow((Math.Pow(a_lump_gsCO2, 2) - 4 * b_lump_gsCO2), 0.5) - a_lump_gsCO2); double Gtw = 1 / (1 / (1.37 * GbCO2[i]) + 1 / (1.6 * GsCO2[i])); //Are these the same constansts shown above double GtCO2 = 1 / (1 / GbCO2[i] + 1 / GsCO2[i]); //DO NOT DELETE - FILLED ARE OF SPREADSHEET //double EMolsPerSecond = Gtw * (Wl - Wa) / (1000 - (Wl + Wa) / 2); //double EMmPerHour = EMolsPerSecond * 18 / 1000 * 3600; //double LambdaEEnergyBalance = 44100 * EMolsPerSecond; //44100 should be a parameter..discuss with AW //double HEnergyBalance = 8 * canopy.Sigma * Math.Pow((PM.EnvModel.GetTemp(PM.Time) + PM.EnvModel.AbsoluteTemperature), 3); //TDelta[i] = (Rn[i] - LambdaEEnergyBalance) / (HEnergyBalance + canopy.Rcp / Rbh[i]); double rtw = canopy.Rair / Gtw * PM.EnvModel.ATM; double a_lump_lambdaE = s * (Rn[i] - BnUp) + VPD_la[i] * canopy.Rcp / Rbh[i]; double b_lump_lambdaE = s + canopy.G * (rtw) / Rbh[i]; double lambdaE = a_lump_lambdaE / b_lump_lambdaE; double EKgPerSecond = lambdaE / canopy.Lambda; WaterUseMolsSecond[i] = EKgPerSecond / 18 * 1000; WaterUse[i] = EKgPerSecond * 3600; double a_lump_deltaT = canopy.G * (Rn[i] - BnUp) * rtw / canopy.Rcp - VPD_la[i]; double d_lump_deltaT = s + canopy.G * rtw / Rbh[i]; TDelta[i] = a_lump_deltaT / d_lump_deltaT; VPD_la[i] = 0.61365 * Math.Exp(17.502 * LeafTemp__[i] / (240.97 + LeafTemp__[i])) - 0.61365 * Math.Exp(17.502 * PM.EnvModel.MinT / (240.97 + PM.EnvModel.MinT)); LeafTemp[i] = PM.EnvModel.GetTemp(PM.Time) + TDelta[i]; } else { WaterUseMolsSecond[i] = WaterUse[i] / 18 * 1000 / 3600; double EKgPerSecond = WaterUseMolsSecond[i] * 18 / 1000; double rtw = (s * (Rn[i] - BnUp) + VPD_la[i] * canopy.Rcp / Rbh[i] - canopy.Lambda * EKgPerSecond * s) * Rbh[i] / (canopy.Lambda * EKgPerSecond * canopy.G); Rsw[i] = rtw - Rbw[i]; GsCO2[i] = canopy.Rair * PM.EnvModel.ATM / Rsw[i] / 1.6; double GtCO2 = 1 / (1 / GbCO2[i] + 1 / GsCO2[i]); double a_lump_deltaT = canopy.G * (Rn[i] - BnUp) * rtw / canopy.Rcp - VPD_la[i]; double d_lump_deltaT = s + canopy.G * rtw / Rbh[i]; TDelta[i] = a_lump_deltaT / d_lump_deltaT; //DO NOT DELETE - FILLED ARE OF SPREADSHEET //double LambdaEEnergyBalance = 44100 * EMolsPerSecond; //44100 should be a parameter..discuss with AW //double HEnergyBalance = 8 * canopy.Sigma * Math.Pow((PM.EnvModel.GetTemp(PM.Time) + PM.EnvModel.AbsoluteTemperature), 3); //double Tdelta = (Rn[i] - LambdaEEnergyBalance) / (HEnergyBalance + canopy.Rcp / Rbh[i]); //This is not used anywhere //double Gtw = EMolsPerSecond * (1000 - (Wl + Wa) / 2) / (Wl - Wa); //GsCO2[i] = 1 / ((1 / Gtw - 1 / (1.37 * GbCO2[i])) * 1.6); //GtCO2 = 1 / (1 / GbCO2[i] + 1 / GsCO2[i]); LeafTemp[i] = PM.EnvModel.GetTemp(PM.Time) + TDelta[i]; } } }
//--------------------------------------------------------------------------------------------------------- public void CalcElectronTransportRate25(LeafCanopy canopy, SunlitShadedCanopy shaded, PhotosynthesisModel PM) { for (int i = 0; i < _nLayers; i++) { //J2Max25[i] = canopy.LAI * canopy.CPath.PsiJ2 * (canopy.LeafNTopCanopy - canopy.CPath.StructuralN) * // ((i == 0 ? 1 : Math.Exp(-(canopy.BeamExtCoeffs[i] + canopy.NAllocationCoeff / canopy.LAI) * canopy.LAIAccums[i - 1])) - // Math.Exp(-(canopy.BeamExtCoeffs[i] + canopy.NAllocationCoeff / canopy.LAI) * canopy.LAIAccums[i])) / // (canopy.NAllocationCoeff + canopy.BeamExtCoeffs[i] * canopy.LAI); JMax25[i] = canopy.LAI * canopy.CPath.PsiJ * (canopy.LeafNTopCanopy - canopy.CPath.StructuralN) * ((i == 0 ? 1 : Math.Exp(-(canopy.BeamExtCoeffs[i] + canopy.NAllocationCoeff / canopy.LAI) * canopy.LAIAccums[i - 1])) - Math.Exp(-(canopy.BeamExtCoeffs[i] + canopy.NAllocationCoeff / canopy.LAI) * canopy.LAIAccums[i])) / (canopy.NAllocationCoeff + canopy.BeamExtCoeffs[i] * canopy.LAI); } }
public void CalcTotalLeafNitrogen(PhotosynthesisModel PM) { TotalLeafNitrogen = LAI * ((LeafNTopCanopy - PM.Canopy.CPath.StructuralN) * (1 - Math.Exp(-NAllocationCoeff)) / NAllocationCoeff + PM.Canopy.CPath.StructuralN); }
//--------------------------------------------------------------------------- public void runDaily() { if (!initialised) { return; } if (notifyStart != null) { notifyStart(true); } double modelTime = this.time; instants = new List <double>(); ass = new List <double>(); Ios = new List <double>(); Idiffs = new List <double>(); Idirs = new List <double>(); SunlitACs = new List <double>(); SunlitAJs = new List <double>(); ShadedACs = new List <double>(); ShadedAJs = new List <double>(); dailyBiomass = 0; interceptedRadn = 0; AShadedMax = 0; ASunlitMax = 0; envModel.run(); for (double time = minTime; time <= maxTime; time += timeStep) { this.time = time; instants.Add(canopy.Ac.Sum()); ass.Add(canopy.biomassC.Sum() * timeStep); Idiffs.Add(envModel.diffuseRadiationPAR); Idirs.Add(envModel.directRadiationPAR); Ios.Add(envModel.diffuseRadiationPAR + envModel.directRadiationPAR); dailyBiomass += canopy.totalBiomassC; double propIntRadn = canopy.propnInterceptedRadns.Sum(); double interceptedRadnTimestep = envModel.totalIncidentRadiation * propIntRadn * timeStep * 3600; interceptedRadn += interceptedRadnTimestep; double RUEtimeStep = canopy.biomassC[0] / interceptedRadnTimestep; PhotosynthesisModel PM = this; if (ASunlitMax < sunlit.A.Max()) { ASunlitMax = sunlit.A.Max(); } if (AShadedMax < shaded.A.Max()) { AShadedMax = shaded.A.Max(); } } dailyBiomassShoot = dailyBiomass * P_ag; RUE = dailyBiomassShoot / interceptedRadn; k = -Math.Log(1 - interceptedRadn / envModel.radn) / canopy.LAI; A = instants.Sum() / 1000; this.time = modelTime; if (notifyFinish != null) { notifyFinish(); } run(true); if (notifyFinishDay != null) { notifyFinishDay(); } }
//-------------------------------------------------------------- public PhotoLayerSolver(PhotosynthesisModel PM, int layer) { _PM = PM; _layer = layer; }
//-------------------------------------------------------------- public override double calcPhotosynthesis(PhotosynthesisModel PM, SunlitShadedCanopy s, int layer, double _A) { LeafCanopy canopy = PM.canopy; s.calcPhotosynthesis(PM, layer); s.Rm[layer] = s.RdT[layer] * 0.5; canopy.z = (2 + canopy.fQ - canopy.CPath.fcyc) / (canopy.h * (1 - canopy.CPath.fcyc)); s.gbs[layer] = canopy.gbs_CO2 * s.LAIS[layer]; s.Oi[layer] = canopy.oxygenPartialPressure; s.Om[layer] = canopy.oxygenPartialPressure; s.gs_CO2[layer] = canopy.gs_CO2 * s.LAIS[layer]; s.Kp[layer] = TempFunctionExp.val(s.leafTemp[layer], canopy.CPath.Kp_P25, canopy.CPath.Kp_c, canopy.CPath.Kp_b); //Caculate A's s.Aj[layer] = calcAj(canopy, s, layer); s.Ac[layer] = calcAc(canopy, s, layer); if (s.Ac[layer] < 0 || double.IsNaN(s.Ac[layer])) { s.Ac[layer] = 0; } if (s.Aj[layer] < 0 || double.IsNaN(s.Aj[layer])) { s.Aj[layer] = 0; } s.A[layer] = Math.Max(0, Math.Min(s.Aj[layer], s.Ac[layer])); if (PM.conductanceModel == PhotosynthesisModel.ConductanceModel.DETAILED) { s.Ci[layer] = canopy.Ca - s.A[layer] / s.gb_CO2[layer] - s.A[layer] / s.gs_CO2[layer]; } else { s.Ci[layer] = canopy.CPath.CiCaRatio * canopy.Ca; } s.Cm_ac[layer] = s.Ci[layer] - s.Ac[layer] / s.gm_CO2T[layer]; s.Cm_aj[layer] = s.Ci[layer] - s.Aj[layer] / s.gm_CO2T[layer]; double Vp_ac = Math.Min(s.Cm_ac[layer] * s.VpMaxT[layer] / (s.Cm_ac[layer] + s.Kp[layer]), s.Vpr[layer]); double Vp_aj = canopy.CPath.x * s.J[layer] / 2; s.Oc_ac[layer] = canopy.alpha * s.Ac[layer] / (0.047 * s.gbs[layer]) + s.Om[layer]; s.Oc_aj[layer] = canopy.alpha * s.Aj[layer] / (0.047 * s.gbs[layer]) + s.Om[layer]; s.r_ac[layer] = s.g_[layer] * s.Oc_ac[layer]; s.r_aj[layer] = s.g_[layer] * s.Oc_aj[layer]; s.Ccac[layer] = s.Cm_ac[layer] + (Vp_ac - s.Ac[layer] - s.Rm[layer]) / s.gbs[layer]; s.Ccaj[layer] = s.Cm_aj[layer] + (Vp_aj - s.Aj[layer] - s.Rm[layer]) / s.gbs[layer]; if (s.Ccac[layer] < 0 || double.IsNaN(s.Ccac[layer])) { s.Ccac[layer] = 0; } if (s.Ccaj[layer] < 0 || double.IsNaN(s.Ccaj[layer])) { s.Ccaj[layer] = 0; } double F_ac = s.gbs[layer] * (s.Ccac[layer] - s.Cm_ac[layer]) / Vp_ac; double F_aj = s.gbs[layer] * (s.Ccaj[layer] - s.Cm_aj[layer]) / Vp_aj; if (s.Ac[layer] < s.Aj[layer]) { s.Vp[layer] = Vp_ac; s.Cc[layer] = s.Ccac[layer]; s.Cm[layer] = s.Cm_ac[layer]; s.Oc[layer] = s.Oc_ac[layer]; s.r_[layer] = s.r_ac[layer]; s.F[layer] = F_ac; } else { s.Vp[layer] = Vp_aj; s.Cc[layer] = s.Ccaj[layer]; s.Cm[layer] = s.Cm_aj[layer]; s.Oc[layer] = s.Oc_aj[layer]; s.r_[layer] = s.r_aj[layer]; s.F[layer] = F_aj; } s.CiCaRatio[layer] = s.Ci[layer] / canopy.Ca; //return Math.Pow(s.A[layer] - _A, 2); return(0); }
//-------------------------------------------------------------- public override double calcPhotosynthesis(PhotosynthesisModel PM, SunlitShadedCanopy s, int layer, double _Cc) { LeafCanopy canopy = PM.canopy; s.calcPhotosynthesis(PM, layer); s.Oi[layer] = canopy.oxygenPartialPressure; s.Oc[layer] = s.Oi[layer]; s.r_[layer] = s.g_[layer] * s.Oc[layer]; s.Ac[layer] = calcAc(canopy, s, layer); s.Aj[layer] = calcAj(canopy, s, layer); if (s.Ac[layer] < 0 || double.IsNaN(s.Ac[layer])) { s.Ac[layer] = 0; } if (s.Aj[layer] < 0 || double.IsNaN(s.Aj[layer])) { s.Aj[layer] = 0; } s.A[layer] = Math.Min(s.Aj[layer], s.Ac[layer]); if (PM.conductanceModel == PhotosynthesisModel.ConductanceModel.DETAILED) { // s.Ci[layer] = canopy.Ca - s.A[layer] / s.gb_CO2[layer] - s.A[layer] / s.gs_CO2[layer]; } else { s.Ci[layer] = canopy.CPath.CiCaRatio * canopy.Ca; } s.Ccac[layer] = s.Ci[layer] - s.Ac[layer] / s.gm_CO2T[layer]; s.Ccaj[layer] = s.Ci[layer] - s.Aj[layer] / s.gm_CO2T[layer]; if (s.Ccac[layer] < 0 || double.IsNaN(s.Ccac[layer])) { s.Ccac[layer] = 0; } if (s.Ccaj[layer] < 0 || double.IsNaN(s.Ccaj[layer])) { s.Ccaj[layer] = 0; } if (s.Ac[layer] < s.Aj[layer]) { s.Cc[layer] = s.Ac[layer]; } else { s.Cc[layer] = s.Aj[layer]; } s.Cc[layer] = s.Ci[layer] - s.A[layer] / s.gm_CO2T[layer]; if (s.Cc[layer] < 0 || double.IsNaN(s.Cc[layer])) { s.Cc[layer] = 0; } s.CiCaRatio[layer] = s.Ci[layer] / canopy.Ca; return(Math.Pow(s.Cc[layer] - _Cc, 2)); }
public virtual void calcMaxRates(LeafCanopy canopy, SunlitShadedCanopy counterpart, PhotosynthesisModel EM) { }
//---------------------------------------------------------------------- public void calcRubiscoActivity25(LeafCanopy canopy, SunlitShadedCanopy sunlit, PhotosynthesisModel PM) { for (int i = 0; i < _nLayers; i++) { VcMax25[i] = canopy.VcMax25[i] - sunlit.VcMax25[i]; } }