コード例 #1
0
        /// <summary>Send an energy balance event</summary>
        private void SendEnergyBalanceEvent()
        {
            for (int j = 0; j <= Canopies.Count - 1; j++)
            {
                CanopyType componentData = Canopies[j];

                if (componentData.Canopy != null)
                {
                    CanopyEnergyBalanceInterceptionlayerType[] lightProfile = new CanopyEnergyBalanceInterceptionlayerType[numLayers];
                    double totalPotentialEp  = 0;
                    double totalInterception = 0.0;
                    for (int i = 0; i <= numLayers - 1; i++)
                    {
                        lightProfile[i]           = new CanopyEnergyBalanceInterceptionlayerType();
                        lightProfile[i].thickness = Convert.ToSingle(DeltaZ[i]);
                        lightProfile[i].amount    = Convert.ToSingle(componentData.Rs[i] * RadnGreenFraction(j));
                        totalPotentialEp         += componentData.PET[i];
                        totalInterception        += componentData.interception[i];
                    }

                    componentData.Canopy.PotentialEP  = totalPotentialEp;
                    componentData.Canopy.LightProfile = lightProfile;
                }
            }
        }
コード例 #2
0
        /// <summary>Calculate light extinction parameters</summary>
        private void LightExtinction()
        {
            // Calculate effective K from LAI and cover
            // =========================================
            for (int j = 0; j <= Canopies.Count - 1; j++)
            {
                CanopyType componentData = Canopies[j];

                if (MathUtilities.FloatsAreEqual(Canopies[j].Canopy.CoverGreen, 1.0, 1E-05))
                {
                    throw new Exception("Unrealistically high cover value in MicroMet i.e. > -.9999");
                }

                componentData.K    = MathUtilities.Divide(-Math.Log(1.0 - componentData.Canopy.CoverGreen), componentData.Canopy.LAI, 0.0);
                componentData.Ktot = MathUtilities.Divide(-Math.Log(1.0 - componentData.Canopy.CoverTotal), componentData.Canopy.LAITotal, 0.0);
            }

            // Calculate extinction for individual layers
            // ============================================
            for (int i = 0; i <= numLayers - 1; i++)
            {
                layerKtot[i] = 0.0;
                for (int j = 0; j <= Canopies.Count - 1; j++)
                {
                    CanopyType componentData = Canopies[j];

                    layerKtot[i] += componentData.Ftot[i] * componentData.Ktot;
                }
            }
        }
コード例 #3
0
        /// <summary>Calculate the Penman-Monteith water demand</summary>
        private void CalculatePM()
        {
            // zero a few things, and sum a few others
            double sumRl           = 0.0;
            double sumRsoil        = 0.0;
            double sumInterception = 0.0;
            double freeEvapGa      = 0.0;

            for (int i = 0; i <= numLayers - 1; i++)
            {
                for (int j = 0; j <= Canopies.Count - 1; j++)
                {
                    CanopyType componentData = Canopies[j];
                    componentData.PET[i]  = 0.0;
                    componentData.PETr[i] = 0.0;
                    componentData.PETa[i] = 0.0;
                    sumRl           += componentData.Rl[i];
                    sumRsoil        += componentData.Rsoil[i];
                    sumInterception += componentData.interception[i];
                    freeEvapGa      += componentData.Ga[i];
                }
            }

            double netRadiation = ((1.0 - _albedo) * sumRs + sumRl + sumRsoil) * 1000000.0;

            // MJ/J
            netRadiation = Math.Max(0.0, netRadiation);
            double freeEvapGc = freeEvapGa * 1000000.0;
            // =infinite surface conductance
            double freeEvap = CalcPenmanMonteith(netRadiation, weather.MinT, weather.MaxT, weather.VP, air_pressure, dayLength, freeEvapGa, freeEvapGc);

            dryleaffraction = 1.0 - MathUtilities.Divide(sumInterception * (1.0 - night_interception_fraction), freeEvap, 0.0);
            dryleaffraction = Math.Max(0.0, dryleaffraction);

            for (int i = 0; i <= numLayers - 1; i++)
            {
                for (int j = 0; j <= Canopies.Count - 1; j++)
                {
                    CanopyType componentData = Canopies[j];

                    netRadiation = 1000000.0 * ((1.0 - _albedo) * componentData.Rs[i] + componentData.Rl[i] + componentData.Rsoil[i]);
                    // MJ/J
                    netRadiation = Math.Max(0.0, netRadiation);

                    if (j == 39)
                    {
                        netRadiation += 0.0;
                    }
                    componentData.PETr[i] = CalcPETr(netRadiation * dryleaffraction, weather.MinT, weather.MaxT, air_pressure, componentData.Ga[i], componentData.Gc[i]);

                    componentData.PETa[i] = CalcPETa(weather.MinT, weather.MaxT, weather.VP, air_pressure, dayLength * dryleaffraction, componentData.Ga[i], componentData.Gc[i]);

                    componentData.PET[i] = componentData.PETr[i] + componentData.PETa[i];
                }
            }
        }
コード例 #4
0
        /// <summary>Calculate the aerodynamic decoupling for system compartments</summary>
        private void CalculateOmega()
        {
            for (int i = 0; i <= numLayers - 1; i++)
            {
                for (int j = 0; j <= Canopies.Count - 1; j++)
                {
                    CanopyType componentData = Canopies[j];

                    componentData.Omega[i] = CalcOmega(weather.MinT, weather.MaxT, air_pressure, componentData.Ga[i], componentData.Gc[i]);
                }
            }
        }
コード例 #5
0
        /// <summary>Break the components into layers</summary>
        private void DivideComponents()
        {
            double[] Ld = new double[Canopies.Count];
            for (int j = 0; j <= Canopies.Count - 1; j++)
            {
                CanopyType componentData = Canopies[j];

                componentData.layerLAI    = new double[numLayers];
                componentData.layerLAItot = new double[numLayers];
                Ld[j] = MathUtilities.Divide(componentData.Canopy.LAITotal, componentData.DepthMetres, 0.0);
            }
            double top    = 0.0;
            double bottom = 0.0;

            for (int i = 0; i <= numLayers - 1; i++)
            {
                bottom         = top;
                top            = top + DeltaZ[i];
                layerLAIsum[i] = 0.0;

                // Calculate LAI for layer i and component j
                // ===========================================
                for (int j = 0; j <= Canopies.Count - 1; j++)
                {
                    CanopyType componentData = Canopies[j];

                    if ((componentData.HeightMetres > bottom) && (componentData.HeightMetres - componentData.DepthMetres < top))
                    {
                        componentData.layerLAItot[i] = Ld[j] * DeltaZ[i];
                        componentData.layerLAI[i]    = componentData.layerLAItot[i] * MathUtilities.Divide(componentData.Canopy.LAI, componentData.Canopy.LAITotal, 0.0);
                        layerLAIsum[i] += componentData.layerLAItot[i];
                    }
                }

                // Calculate fractional contribution for layer i and component j
                // ====================================================================
                for (int j = 0; j <= Canopies.Count - 1; j++)
                {
                    CanopyType componentData = Canopies[j];

                    componentData.Ftot[i] = MathUtilities.Divide(componentData.layerLAItot[i], layerLAIsum[i], 0.0);
                    // Note: Sum of Fgreen will be < 1 as it is green over total
                    componentData.Fgreen[i] = MathUtilities.Divide(componentData.layerLAI[i], layerLAIsum[i], 0.0);
                }
            }
        }
コード例 #6
0
        public static CanopyParameters SetUpCanopy(
            CanopyType type,
            double airCO2,
            double curvatureFactor,
            double diffusivitySolubilityRatio,
            double airO2,
            double diffuseExtCoeff,
            double diffuseExtCoeffNIR,
            double diffuseReflectionCoeff,
            double diffuseReflectionCoeffNIR,
            double leafAngle,
            double leafScatteringCoeff,
            double leafScatteringCoeffNIR,
            double leafWidth,
            double slnRatioTop,
            double minimumN,
            double windspeed,
            double windSpeedExtinction
            )
        {
            var CP = new CanopyParameters
            {
                Type                       = type,
                AirCO2                     = airCO2,
                CurvatureFactor            = curvatureFactor,
                DiffusivitySolubilityRatio = diffusivitySolubilityRatio,
                AirO2                      = airO2,
                DiffuseExtCoeff            = diffuseExtCoeff,
                DiffuseExtCoeffNIR         = diffuseExtCoeffNIR,
                DiffuseReflectionCoeff     = diffuseReflectionCoeff,
                DiffuseReflectionCoeffNIR  = diffuseReflectionCoeffNIR,
                LeafAngle                  = leafAngle,
                LeafScatteringCoeff        = leafScatteringCoeff,
                LeafScatteringCoeffNIR     = leafScatteringCoeffNIR,
                LeafWidth                  = leafWidth,
                SLNRatioTop                = slnRatioTop,
                MinimumN                   = minimumN,
                Windspeed                  = windspeed,
                WindSpeedExtinction        = windSpeedExtinction
            };

            return(CP);
        }
コード例 #7
0
        /// <summary>Calculate the canopy conductance for system compartments</summary>
        private void CalculateGc()
        {
            double Rin = weather.Radn;

            for (int i = numLayers - 1; i >= 0; i += -1)
            {
                double Rflux = Rin * 1000000.0 / (dayLength * hr2s) * (1.0 - _albedo);
                double Rint  = 0.0;

                for (int j = 0; j <= Canopies.Count - 1; j++)
                {
                    CanopyType componentData = Canopies[j];

                    componentData.Gc[i] = CanopyConductance(componentData.Canopy.Gsmax, componentData.Canopy.R50, componentData.Canopy.FRGR, componentData.Fgreen[i], layerKtot[i], layerLAIsum[i], Rflux);

                    Rint += componentData.Rs[i];
                }
                // Calculate Rin for the next layer down
                Rin -= Rint;
            }
        }