public static void Initialize() { Parameter<string> PressureHeadCalculationMethod = null; if (PlugIn.TryGetParameter(Names.PressureHeadCalculationMethod, out PressureHeadCalculationMethod)) { Parameter<string> p = PlugIn.GetParameter(Names.PressureHeadCalculationMethod); pressureheadtable = new PressureHeadSaxton_Rawls(); } else { string msg = "Missing presciption for calculating pressurehead, expected keyword " + Names.PressureHeadCalculationMethod + " in " + PlugIn.GetParameter(Names.PnETGenericParameters).Value + " or in " + PlugIn.GetParameter(Names.ExtensionName).Value; throw new System.Exception(msg); } PlugIn.ModelCore.UI.WriteLine("Eco\tSoilt\tWiltPnt\tFieldCap(mm)\tFC-WP\tPorosity"); foreach (IEcoregionPnET eco in EcoregionPnET.Ecoregions) if (eco.Active) { // takes PH (MPa) // Calculates water content (m3H2O/m3 SOIL) // Water content at field capacity (calculated as an output variable) // −33 kPa (or −0.33 bar) // mH2O value = kPa value x 0.101972 eco.FieldCap = (float)pressureheadtable.CalculateWaterContent((ushort)3.37, eco.SoilType) * eco.RootingDepth; eco.WiltPnt = (float)pressureheadtable.CalculateWaterContent((ushort)153, eco.SoilType) * eco.RootingDepth; eco.Porosity = (float)pressureheadtable.Porosity(eco.RootingDepth, eco.SoilType); float f = eco.FieldCap - eco.WiltPnt; PlugIn.ModelCore.UI.WriteLine(eco.Name + "\t" + eco.SoilType + "\t" + eco.WiltPnt + "\t" + eco.FieldCap + "\t" + f + "\t" + eco.Porosity ); } }
public static void Initialize() { Parameter <string> PressureHeadCalculationMethod = null; if (PlugIn.TryGetParameter(Names.PressureHeadCalculationMethod, out PressureHeadCalculationMethod)) { Parameter <string> p = PlugIn.GetParameter(Names.PressureHeadCalculationMethod); pressureheadtable = new PressureHeadSaxton_Rawls(); } else { string msg = "Missing presciption for calculating pressurehead, expected keyword " + Names.PressureHeadCalculationMethod + " in " + PlugIn.GetParameter(Names.PnETGenericParameters).Value + " or in " + PlugIn.GetParameter(Names.ExtensionName).Value; throw new System.Exception(msg); } PlugIn.ModelCore.UI.WriteLine("Eco\tSoilt\tWiltPnt\tFieldCap(mm)\tFC-WP\tPorosity"); foreach (IEcoregionPnET eco in EcoregionPnET.Ecoregions) { if (eco.Active) { // Volumetric water content (mm/m) at field capacity // −33 kPa (or −0.33 bar) // Convert kPA to mH2o (/9.804139432) = 3.37 eco.FieldCap = (float)pressureheadtable.CalculateWaterContent(33, eco.SoilType); // Volumetric water content (mm/m) at wilting point // −1500 kPa (or −15 bar) // Convert kPA to mH2o (/9.804139432) = 153.00 eco.WiltPnt = (float)pressureheadtable.CalculateWaterContent(1500, eco.SoilType); // Volumetric water content (mm/m) at porosity eco.Porosity = (float)pressureheadtable.Porosity(eco.SoilType); float f = eco.FieldCap - eco.WiltPnt; PlugIn.ModelCore.UI.WriteLine(eco.Name + "\t" + eco.SoilType + "\t" + eco.WiltPnt + "\t" + eco.FieldCap + "\t" + f + "\t" + eco.Porosity); } } }
public static SortedList <float, float> CalculateMonthlySoilTemps(SortedList <float, float> depthTempDict, IEcoregionPnET Ecoregion, int daysOfWinter, float snowPack, IHydrology hydrology, float lastTempBelowSnow) { //SortedList<float, float> depthTempDict = new SortedList<float, float>(); //for permafrost //float lambAir = 0.023f; //float lambIce = 2.29f; //float omega = (float)(2 * Math.PI / 12.0); float[] snowResults = CalculateSnowDepth(daysOfWinter, snowPack); float sno_dep = snowResults[0]; float Psno_kg_m3 = snowResults[1]; if (Ecoregion.Variables.Tave >= 0) { float fracAbove0 = Ecoregion.Variables.Tmax / (Ecoregion.Variables.Tmax - Ecoregion.Variables.Tmin); sno_dep = sno_dep * fracAbove0; } // from CLM model - https://escomp.github.io/ctsm-docs/doc/build/html/tech_note/Soil_Snow_Temperatures/CLM50_Tech_Note_Soil_Snow_Temperatures.html#soil-and-snow-thermal-properties // Eq. 85 - Jordan (1991) //float lambda_Snow = (float)(lambAir + ((0.0000775 * Psno_kg_m3) + (0.000001105 * Math.Pow(Psno_kg_m3, 2))) * (lambIce - lambAir)) * 3.6F * 24F; //(kJ/m/d/K) includes unit conversion from W to kJ //float damping = (float)Math.Sqrt(omega / (2.0F * lambda_Snow)); float damping = CalculateSnowDamping(Psno_kg_m3); float DRz_snow = (float)Math.Exp(-1.0F * sno_dep * damping); // Damping ratio for snow - adapted from Kang et al. (2000) and Liang et al. (2014) // Permafrost calculations - from "Soil thawing worksheet.xlsx" // //if (Ecoregion.Variables.Tave < minMonthlyAvgTemp) // minMonthlyAvgTemp = Ecoregion.Variables.Tave; float porosity = Ecoregion.Porosity / Ecoregion.RootingDepth; //m3/m3 float waterContent = hydrology.Water / Ecoregion.RootingDepth; //m3/m3 float ga = 0.035F + 0.298F * (waterContent / porosity); float Fa = ((2.0F / 3.0F) / (1.0F + ga * ((Constants.lambda_a / Constants.lambda_w) - 1.0F))) + ((1.0F / 3.0F) / (1.0F + (1.0F - 2.0F * ga) * ((Constants.lambda_a / Constants.lambda_w) - 1.0F))); // ratio of air temp gradient float Fs = PressureHeadSaxton_Rawls.GetFs(Ecoregion.SoilType); float lambda_s = PressureHeadSaxton_Rawls.GetLambda_s(Ecoregion.SoilType); float lambda_theta = (Fs * (1.0F - porosity) * lambda_s + Fa * (porosity - waterContent) * Constants.lambda_a + waterContent * Constants.lambda_w) / (Fs * (1.0F - porosity) + Fa * (porosity - waterContent) + waterContent); //soil thermal conductivity (kJ/m/d/K) float D = lambda_theta / PressureHeadSaxton_Rawls.GetCTheta(Ecoregion.SoilType); //m2/day float Dmonth = D * Ecoregion.Variables.DaySpan; // m2/month float ks = Dmonth * 1000000F / (Ecoregion.Variables.DaySpan * (Constants.SecondsPerHour * 24)); // mm2/s float d = (float)Math.Pow((Constants.omega / (2.0F * Dmonth)), (0.5)); float maxDepth = Ecoregion.RootingDepth + Ecoregion.LeakageFrostDepth; float freezeDepth = maxDepth; float testDepth = 0; //if (lastTempBelowSnow == float.MaxValue) //{ // //int mCount = Math.Min(12, data.Count()); // //float tSum = 0; // //foreach (int z in Enumerable.Range(0, mCount)) // //{ // // tSum += data[z].Tave; // //} // //float annualTavg = tSum / mCount; // float tempBelowSnow = Ecoregion.Variables.Tave; // if (sno_dep > 0) // { // tempBelowSnow = annualTavg + (Ecoregion.Variables.Tave - annualTavg) * DRz_snow; // } // lastTempBelowSnow = tempBelowSnow; // while (testDepth <= (maxDepth / 1000.0)) // { // float DRz = (float)Math.Exp(-1.0F * testDepth * d); // adapted from Kang et al. (2000) and Liang et al. (2014) // float zTemp = annualTavg + (tempBelowSnow - annualTavg) * DRz; // depthTempDict[testDepth] = zTemp; // if ((zTemp <= 0) && (testDepth < freezeDepth)) // freezeDepth = testDepth; // testDepth += 0.25F; // } //} //else //{ float tempBelowSnow = Ecoregion.Variables.Tave; if (sno_dep > 0) { tempBelowSnow = lastTempBelowSnow + (Ecoregion.Variables.Tave - lastTempBelowSnow) * DRz_snow; } lastTempBelowSnow = tempBelowSnow; while (testDepth <= (maxDepth / 1000.0)) { float DRz = (float)Math.Exp(-1.0F * testDepth * d); // adapted from Kang et al. (2000) and Liang et al. (2014) float zTemp = depthTempDict[testDepth] + (tempBelowSnow - depthTempDict[testDepth]) * DRz; depthTempDict[testDepth] = zTemp; //if ((zTemp <= 0) && (testDepth < freezeDepth)) // freezeDepth = testDepth; if (testDepth == 0f) { testDepth = 0.10f; } else if (testDepth == 0.10f) { testDepth = 0.25f; } else { testDepth += 0.25F; } } //} return(depthTempDict); }