Exemple #1
0
        private void OnDoSoilOrganicMatter(object sender, EventArgs e)
        {
            // Get potential residue decomposition from surfaceom.
            SurfaceOrganicMatterDecompType SurfaceOrganicMatterDecomp = SurfaceOrganicMatter.PotentialDecomposition();

            foreach (soilCNPatch aPatch in Patch)
            {
                aPatch.OnPotentialResidueDecompositionCalculated(SurfaceOrganicMatterDecomp);
            }

            num_residues = SurfaceOrganicMatterDecomp.Pool.Length;

            sw_dep = Soil.Water;

            // calculate C and N processes
            //    - Assesses potential decomposition of surface residues;
            //		. adjust decomposition if needed;
            //		. accounts for mineralisation/immobilisation of N;
            //	  - Compute the transformations on soil organic matter (including N mineralisation/immobilition);
            //    - Calculates hydrolysis of urea, nitrification, and denitrification;
            for (int k = 0; k < Patch.Count; k++)
            {
                Patch[k].Process();
            }

            // send actual decomposition back to surface OM
            if (!is_pond_active)
            {
                SendActualResidueDecompositionCalculated();
            }
        }
Exemple #2
0
        private void OnDoSoilOrganicMatter(object sender, EventArgs e)
        {
            // Get potential residue decomposition from surfaceom.
            SurfaceOrganicMatterDecompType SurfaceOrganicMatterDecomp = SurfaceOrganicMatter.PotentialDecomposition();

            foreach (soilCNPatch aPatch in Patch)
            {
                aPatch.OnPotentialResidueDecompositionCalculated(SurfaceOrganicMatterDecomp);
            }

            num_residues = SurfaceOrganicMatterDecomp.Pool.Length;

            sw_dep = Soil.Water;

            // update soil temperature
            if (use_external_st)
            {
                Tsoil = ave_soil_temp;
            }
            else
            {
                // initialise soil temperature
                if (simpleST == null)
                {
                    simpleST = new simpleSoilTemp(MetFile.Latitude, MetFile.Tav, MetFile.Amp, MetFile.MinT, MetFile.MaxT);
                }

                Tsoil = simpleST.SoilTemperature(Clock.Today, MetFile.MinT, MetFile.MaxT, MetFile.Radn, salb, dlayer, bd, ll15_dep, sw_dep);
            }

            // calculate C and N processes
            //    - Assesses potential decomposition of surface residues;
            //		. adjust decomposition if needed;
            //		. accounts for mineralisation/immobilisation of N;
            //	  - Compute the transformations on soil organic matter (including N mineralisation/immobilition);
            //    - Calculates hydrolysis of urea, nitrification, and denitrification;
            for (int k = 0; k < Patch.Count; k++)
            {
                Patch[k].Process();
            }

            // send actual decomposition back to surface OM
            if (!is_pond_active)
            {
                SendActualResidueDecompositionCalculated();
            }
        }
            /// <summary>
            /// Gather the information about actual residue decomposition, to be sent back to surface OM
            /// </summary>
            /// <remarks>
            /// Currently P is not being computed by SoilNitrogen, so the corresponding variables are set to zero here
            /// </remarks>
            private void PackActualResidueDecomposition()
            {
                soilp_dlt_org_p = new double[g.nLayers];
                double soilp_cpr = MathUtilities.Divide(g.SumDoubleArray(g.pot_p_decomp), g.SumDoubleArray(g.pot_c_decomp), 0.0);

                SurfOMActualDecomposition = new SurfaceOrganicMatterDecompType();
                Array.Resize(ref SurfOMActualDecomposition.Pool, g.nResidues);

                for (int residue = 0; residue < g.nResidues; residue++)
                {
                    double c_summed = g.SumDoubleArray(dlt_c_decomp[residue]);
                    if (Math.Abs(c_summed) < g.epsilon)
                    {
                        c_summed = 0.0;
                    }
                    double n_summed = g.SumDoubleArray(dlt_n_decomp[residue]);
                    if (Math.Abs(n_summed) < g.epsilon)
                    {
                        n_summed = 0.0;
                    }

                    // pack up the structure to return decompositions to SurfaceOrganicMatter
                    SurfOMActualDecomposition.Pool[residue]      = new SurfaceOrganicMatterDecompPoolType();
                    SurfOMActualDecomposition.Pool[residue].FOM  = new FOMType();
                    SurfOMActualDecomposition.Pool[residue].Name = g.residueName[residue];
                    SurfOMActualDecomposition.Pool[residue].OrganicMatterType = g.residueType[residue];
                    SurfOMActualDecomposition.Pool[residue].FOM.amount        = 0.0F;
                    SurfOMActualDecomposition.Pool[residue].FOM.C             = c_summed;
                    SurfOMActualDecomposition.Pool[residue].FOM.N             = n_summed;
                    SurfOMActualDecomposition.Pool[residue].FOM.P             = 0.0F;
                    SurfOMActualDecomposition.Pool[residue].FOM.AshAlk        = 0.0F;
                    // Note: The values for 'amount', 'P', and 'AshAlk' will not be collected by SurfaceOrganicMatter, so send zero as default.
                }

                // dsg 131004  calculate the old dlt_org_p (from the old Decomposed event sent by residue2) for getting by soilp
                double act_c_decomp     = 0.0;
                double tot_pot_c_decomp = g.SumDoubleArray(g.pot_c_decomp);
                double tot_pot_p_decomp = g.SumDoubleArray(g.pot_p_decomp);

                for (int layer = 0; layer < g.nLayers; layer++)
                {
                    act_c_decomp           = dlt_c_res_to_biom[layer] + dlt_c_res_to_hum[layer] + dlt_c_res_to_atm[layer];
                    soilp_dlt_org_p[layer] = tot_pot_p_decomp * MathUtilities.Divide(act_c_decomp, tot_pot_c_decomp, 0.0);
                }
            }
Exemple #4
0
        /// <summary>Send back to SurfaceOM the information about residue decomposition</summary>
        private void SendActualResidueDecompositionCalculated()
        {
            // Note:
            //      Potential decomposition was given to this module by a residue/surfaceOM module.
            //		Now we explicitly tell the module the actual decomposition
            //      rate for each of its residues.  If there wasn't enough mineral N to decompose, the rate will be reduced from the potential value.

            // will have to pack the SOMdecomp data from each patch and then invoke the event
            //int num_residues = Patch[0].SOMDecomp.Pool.Length;
            int nLayers = dlayer.Length;

            SurfaceOrganicMatterDecompType ActualSOMDecomp = new SurfaceOrganicMatterDecompType();

            Array.Resize(ref ActualSOMDecomp.Pool, num_residues);

            for (int residue = 0; residue < num_residues; residue++)
            {
                double c_summed = 0.0F;
                double n_summed = 0.0F;
                for (int k = 0; k < Patch.Count; k++)
                {
                    c_summed += Patch[k].SOMDecomp.Pool[residue].FOM.C * Patch[k].RelativeArea;
                    n_summed += Patch[k].SOMDecomp.Pool[residue].FOM.N * Patch[k].RelativeArea;
                }

                ActualSOMDecomp.Pool[residue]      = new SurfaceOrganicMatterDecompPoolType();
                ActualSOMDecomp.Pool[residue].FOM  = new FOMType();
                ActualSOMDecomp.Pool[residue].Name = Patch[0].SOMDecomp.Pool[residue].Name;
                ActualSOMDecomp.Pool[residue].OrganicMatterType = Patch[0].SOMDecomp.Pool[residue].OrganicMatterType;
                ActualSOMDecomp.Pool[residue].FOM.amount        = 0.0F;
                ActualSOMDecomp.Pool[residue].FOM.C             = c_summed;
                ActualSOMDecomp.Pool[residue].FOM.N             = n_summed;
                ActualSOMDecomp.Pool[residue].FOM.P             = 0.0F;
                ActualSOMDecomp.Pool[residue].FOM.AshAlk        = 0.0F;
            }

            SurfaceOrganicMatter.ActualSOMDecomp = ActualSOMDecomp;
        }
Exemple #5
0
        /// <summary>Send back to SurfaceOM the information about residue decomposition</summary>
        private void SendActualResidueDecompositionCalculated()
        {
            // Note:
            //      Potential decomposition was given to this module by a residue/surfaceOM module.
            //		Now we explicitly tell the module the actual decomposition
            //      rate for each of its residues.  If there wasn't enough mineral N to decompose, the rate will be reduced from the potential value.

            // will have to pack the SOMdecomp data from each patch and then invoke the event
            //int num_residues = Patch[0].SOMDecomp.Pool.Length;
            int nLayers = dlayer.Length;

            SurfaceOrganicMatterDecompType ActualSOMDecomp = new SurfaceOrganicMatterDecompType();
            Array.Resize(ref ActualSOMDecomp.Pool, num_residues);

            for (int residue = 0; residue < num_residues; residue++)
            {
                double c_summed = 0.0F;
                double n_summed = 0.0F;
                for (int k = 0; k < Patch.Count; k++)
                {
                    c_summed += Patch[k].SOMDecomp.Pool[residue].FOM.C * Patch[k].RelativeArea;
                    n_summed += Patch[k].SOMDecomp.Pool[residue].FOM.N * Patch[k].RelativeArea;
                }

                ActualSOMDecomp.Pool[residue] = new SurfaceOrganicMatterDecompPoolType();
                ActualSOMDecomp.Pool[residue].FOM = new FOMType();
                ActualSOMDecomp.Pool[residue].Name = Patch[0].SOMDecomp.Pool[residue].Name;
                ActualSOMDecomp.Pool[residue].OrganicMatterType = Patch[0].SOMDecomp.Pool[residue].OrganicMatterType;
                ActualSOMDecomp.Pool[residue].FOM.amount = 0.0F;
                ActualSOMDecomp.Pool[residue].FOM.C = c_summed;
                ActualSOMDecomp.Pool[residue].FOM.N = n_summed;
                ActualSOMDecomp.Pool[residue].FOM.P = 0.0F;
                ActualSOMDecomp.Pool[residue].FOM.AshAlk = 0.0F;
            }

            SurfaceOrganicMatter.ActualSOMDecomp = ActualSOMDecomp;
        }
Exemple #6
0
            public void OnPotentialResidueDecompositionCalculated(SurfaceOrganicMatterDecompType SurfaceOrganicMatterDecomp)
            {
                //+  Purpose
                //     Get information of potential residue decomposition

                num_residues = SurfaceOrganicMatterDecomp.Pool.Length;

                Array.Resize(ref residue_name, num_residues);
                Array.Resize(ref residue_type, num_residues);
                Array.Resize(ref pot_c_decomp, num_residues);
                Array.Resize(ref pot_n_decomp, num_residues);
                Array.Resize(ref pot_p_decomp, num_residues);
                for (int layer = 0; layer < dlt_c_res_2_biom.Length; layer++)
                {
                    Array.Resize(ref dlt_c_res_2_biom[layer], num_residues);
                    Array.Resize(ref dlt_c_res_2_hum[layer], num_residues);
                    Array.Resize(ref dlt_c_res_2_atm[layer], num_residues);
                    Array.Resize(ref dlt_c_decomp[layer], num_residues);
                    Array.Resize(ref dlt_n_decomp[layer], num_residues);
                }

                for (int residue = 0; residue < num_residues; residue++)
                {
                    residue_name[residue] = SurfaceOrganicMatterDecomp.Pool[residue].Name;
                    residue_type[residue] = SurfaceOrganicMatterDecomp.Pool[residue].OrganicMatterType;
                    pot_c_decomp[residue] = SurfaceOrganicMatterDecomp.Pool[residue].FOM.C;
                    pot_n_decomp[residue] = SurfaceOrganicMatterDecomp.Pool[residue].FOM.N;
                    pot_p_decomp[residue] = SurfaceOrganicMatterDecomp.Pool[residue].FOM.P;
                }
            }
Exemple #7
0
            /// <summary>
            /// Send back the information about actual residue decomposition
            /// </summary>
            private void PackActualResidueDecomposition()
            {
                // Notes:
                //      Potential decomposition was given to this module by a residue/surfaceOM module.  Now we explicitly tell the
                //      module the actual decomposition rate for each of its residues.  If there isn't enough mineral N to decompose,
                //		the rate will be reduced from the potential value.

                int nLayers = g.dlayer.Length;

                soilp_dlt_res_c_atm = new double[nLayers];
                soilp_dlt_res_c_hum = new double[nLayers];
                soilp_dlt_res_c_biom = new double[nLayers];
                soilp_dlt_org_p = new double[nLayers];
                double soilp_cpr = MathUtilities.Divide(SumDoubleArray(pot_p_decomp), SumDoubleArray(pot_c_decomp), 0.0);  // C:P ratio for potential decomposition

                //SurfaceOrganicMatterDecompType SOMDecomp = new SurfaceOrganicMatterDecompType();
                SOMDecomp = new SurfaceOrganicMatterDecompType();
                Array.Resize(ref SOMDecomp.Pool, num_residues);

                for (int residue = 0; residue < num_residues; residue++)
                {
                    double c_summed = 0.0;
                    double n_summed = 0.0;
                    double[] dlt_res_c_decomp = new double[nLayers];
                    double[] dlt_res_n_decomp = new double[nLayers];
                    for (int layer = 0; layer < nLayers; layer++)
                    {
                        dlt_res_c_decomp[layer] = dlt_c_res_2_hum[layer][residue] +
                                                  dlt_c_res_2_biom[layer][residue] +
                                                  dlt_c_res_2_atm[layer][residue];
                        c_summed += dlt_res_c_decomp[layer];

                        //dlt_res_n_decomp[layer] = this.dlt_n_decomp[layer][residue];
                        dlt_res_n_decomp[layer] = dlt_n_decomp[layer][residue];
                        n_summed += dlt_res_n_decomp[layer];
                    }

                    // dsg 131103  Now, pack up the structure to return decompositions to SurfaceOrganicMatter
                    SOMDecomp.Pool[residue] = new SurfaceOrganicMatterDecompPoolType();
                    SOMDecomp.Pool[residue].FOM = new FOMType();
                    SOMDecomp.Pool[residue].Name = residue_name[residue];
                    SOMDecomp.Pool[residue].OrganicMatterType = residue_type[residue];

                    // dsg 131103   The 'amount' value will not be used by SurfaceOrganicMatter, so send zero as default
                    SOMDecomp.Pool[residue].FOM.amount = 0.0F;
                    if (Math.Abs(c_summed) < g.EPSILON)
                        c_summed = 0.0;
                    if (Math.Abs(n_summed) < g.EPSILON)
                        n_summed = 0.0;
                    SOMDecomp.Pool[residue].FOM.C = (float)c_summed;
                    SOMDecomp.Pool[residue].FOM.N = (float)n_summed;

                    // dsg 131103   The 'P' value will not be collected by SurfaceOrganicMatter, so send zero as default.
                    SOMDecomp.Pool[residue].FOM.P = 0.0F;
                    SOMDecomp.Pool[residue].FOM.AshAlk = 0.0F;

                    // dsg 131004 soilp needs some stuff - very ugly process - needs to be streamlined
                    //  create some variables which soilp can "get" - layer based arrays independent of residues
                    for (int layer = 0; layer < nLayers; layer++)
                    {
                        soilp_dlt_res_c_atm[layer] += dlt_c_res_2_atm[layer][residue];
                        soilp_dlt_res_c_hum[layer] += dlt_c_res_2_hum[layer][residue];
                        soilp_dlt_res_c_biom[layer] += dlt_c_res_2_biom[layer][residue];
                        soilp_dlt_org_p[layer] += dlt_res_c_decomp[layer] * soilp_cpr;
                    }
                }
            }