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