예제 #1
0
        private void OnIncorpFOM(FOMLayerType inFOMdata)
        {
            // Note: In this event all FOM is given as one, so it will be assumed that the CN ratios of all fractions are equal

            foreach (soilCNPatch aPatch in Patch)
            {
                aPatch.OnIncorpFOM(inFOMdata);
            }

            fom_type = Patch[0].fom_type;
        }
예제 #2
0
        /// <summary>Return senescent roots to fresh organic matter pool in the soil</summary>
        /// <param name="amountDM">DM amount to return</param>
        /// <param name="amountN">N amount to return</param>
        private void DoIncorpFomEvent(double amountDM, double amountN)
        {
            Soils.FOMLayerLayerType[] FOMdataLayer = new Soils.FOMLayerLayerType[nLayers];

            // ****  RCichota, Jun/2014
            // root senesced are returned to soil (as FOM) considering return is proportional to root mass

            for (int layer = 0; layer < nLayers; layer++)
            {
                Soils.FOMType fomData = new Soils.FOMType();
                fomData.amount = amountDM * swardRootFraction[layer];
                fomData.N = amountN * swardRootFraction[layer];
                fomData.C = amountDM * swardRootFraction[layer] * CinDM;
                fomData.P = 0.0;			  // P not considered here
                fomData.AshAlk = 0.0;		  // Ash not considered here

                Soils.FOMLayerLayerType layerData = new Soils.FOMLayerLayerType();
                layerData.FOM = fomData;
                layerData.CNR = 0.0;	    // not used here
                layerData.LabileP = 0;      // not used here

                FOMdataLayer[layer] = layerData;
            }

            if (IncorpFOM != null)
            {
                Soils.FOMLayerType FOMData = new Soils.FOMLayerType();
                FOMData.Type = "Pasture";
                FOMData.Layer = FOMdataLayer;
                IncorpFOM.Invoke(FOMData);
            }
        }
예제 #3
0
        /// <summary>Returns a given amount of DM (and N) to fresh organic matter pool in the soil</summary>
        /// <param name="amountDM">DM amount to return (kg/ha)</param>
        /// <param name="amountN">N amount to return (kg/ha)</param>
        private void DoIncorpFomEvent(double amountDM, double amountN)
        {
            FOMLayerLayerType[] FOMdataLayer = new FOMLayerLayerType[nLayers];

            // ****  RCichota, Jun/2014
            // root senesced are returned to soil (as FOM) considering return is proportional to root mass

            for (int layer = 0; layer < nLayers; layer++)
            {
                FOMType fomData = new FOMType();
                fomData.amount = amountDM * roots.Tissue[0].FractionWt[layer];
                fomData.N = amountN * roots.Tissue[0].FractionWt[layer];
                fomData.C = amountDM * CarbonFractionInDM * roots.Tissue[0].FractionWt[layer];
                fomData.P = 0.0; // P not considered here
                fomData.AshAlk = 0.0; // Ash not considered here

                FOMLayerLayerType layerData = new FOMLayerLayerType();
                layerData.FOM = fomData;
                layerData.CNR = 0.0; // not used here
                layerData.LabileP = 0; // not used here

                FOMdataLayer[layer] = layerData;
            }

            if (IncorpFOM != null)
            {
                FOMLayerType FOMData = new FOMLayerType();
                FOMData.Type = mySpeciesFamily.ToString();
                FOMData.Layer = FOMdataLayer;
                IncorpFOM.Invoke(FOMData);
            }
        }
예제 #4
0
        /// <summary>Return scenescent roots to fresh organic matter pool in the soil</summary>
        /// <param name="amountDM">DM amount to return</param>
        /// <param name="amountN">N amount to return</param>
        private void DoIncorpFomEvent(double amountDM, double amountN)
        {
            Soils.FOMLayerLayerType[] FOMdataLayer = new Soils.FOMLayerLayerType[nLayers];

            // ****  RCichota, Jun/2014
            // root senesced are returned to soil (as FOM) considering return is proportional to root mass

            double dAmtLayer = 0.0; //amount of root litter in a layer
            double dNLayer = 0.0;
            for (int layer = 0; layer < nLayers; layer++)
            {
                dAmtLayer = amountDM * rootFraction[layer];
                dNLayer = amountN * rootFraction[layer];

                float amt = (float)dAmtLayer;

                Soils.FOMType fomData = new Soils.FOMType();
                fomData.amount = amountDM * rootFraction[layer];
                fomData.N = amountN * rootFraction[layer];
                fomData.C = amountDM * rootFraction[layer] * CarbonFractionInDM;
                fomData.P = 0.0;			  // P not considered here
                fomData.AshAlk = 0.0;		  // Ash not considered here

                Soils.FOMLayerLayerType layerData = new Soils.FOMLayerLayerType();
                layerData.FOM = fomData;
                layerData.CNR = 0.0;	    // not used here
                layerData.LabileP = 0;      // not used here

                FOMdataLayer[layer] = layerData;
            }

            if (IncorpFOM != null)
            {
                Soils.FOMLayerType FOMData = new Soils.FOMLayerType();
                FOMData.Type = speciesFamily;
                FOMData.Layer = FOMdataLayer;
                IncorpFOM.Invoke(FOMData);
            }
        }
예제 #5
0
파일: Sugarcane.cs 프로젝트: hol353/ApsimX
        /// <summary>
        /// Sugar_hill_ups the specified canefr.
        /// </summary>
        /// <param name="canefr">The canefr.</param>
        /// <param name="topsfr">The topsfr.</param>
        /// <exception cref="ApsimXException">Can only hill up during emergence phase</exception>
        void sugar_hill_up(double canefr, double topsfr)
        {
            //*+  Purpose
            //*       Mound soil around base of crop and bury some plant material

            //*+  Mission Statement
            //*     Mound soil around base of crop

            double[] fom = new double[max_layer];
            double[] fon = new double[max_layer];

            if ((int)g_current_stage == emerg)
                {

                //Send Event to IncorpOM

                //create Arrays

                fill_real_array(ref fom, 0.0, max_layer);
                fill_real_array(ref fon, 0.0, max_layer);

                fom[0] = topsfr * (g_dm_green[leaf] + g_dm_green[cabbage] + g_dm_senesced[leaf] + g_dm_senesced[cabbage] + g_dm_dead[leaf] + g_dm_dead[cabbage])
                       + canefr * (g_dm_green[sstem] + g_dm_green[sucrose] + g_dm_senesced[sstem] + g_dm_senesced[sucrose] + g_dm_dead[sstem] + g_dm_dead[sucrose]);

                fon[0] = topsfr * (g_n_green[leaf] + g_n_green[cabbage] + g_n_senesced[leaf] + g_n_senesced[cabbage] + g_n_dead[leaf] + g_n_dead[cabbage])
                       + canefr * (g_n_green[sstem] + g_n_green[sucrose] + g_n_senesced[sstem] + g_n_senesced[sucrose] + g_n_dead[sstem] + g_n_dead[sucrose]);

                //do dotnet event sending

                FOMLayerLayerType[] allLayers = new FOMLayerLayerType[dlayer.Length];

                for (int layer = 0; layer < dlayer.Length; layer++)
                    {
                    FOMType fom_in_layer = new FOMType();
                    fom_in_layer.amount = (float)fom[layer];
                    fom_in_layer.N = (float)fon[layer];
                    fom_in_layer.P = (float)0.0;
                    fom_in_layer.C = (float)0.0;
                    fom_in_layer.AshAlk = (float)0.0;

                    FOMLayerLayerType thisLayer = new FOMLayerLayerType();
                    thisLayer.FOM = fom_in_layer;
                    thisLayer.CNR = (float)0.0;
                    thisLayer.LabileP = (float)0.0;

                    allLayers[layer] = thisLayer;
                    }

                FOMLayerType fomInSoil = new FOMLayerType();
                fomInSoil.Type = crop_type;
                fomInSoil.Layer = allLayers;

                IncorpFOM.Invoke(fomInSoil);   //trigger/invoke the IncorpFOM Event

                //Change Global Variables

                //dm variables

                g_dm_green[leaf] = g_dm_green[leaf] * (1.0 - topsfr);
                g_dm_green[cabbage] = g_dm_green[cabbage] * (1.0 - topsfr);
                g_dm_senesced[leaf] = g_dm_senesced[leaf] * (1.0 - topsfr);
                g_dm_senesced[cabbage] = g_dm_senesced[cabbage] * (1.0 - topsfr);
                g_dm_dead[leaf] = g_dm_dead[leaf] * (1.0 - topsfr);
                g_dm_dead[cabbage] = g_dm_dead[cabbage] * (1.0 - topsfr);

                g_dm_green[sstem] = g_dm_green[sstem] * (1.0 - canefr);
                g_dm_green[sucrose] = g_dm_green[sucrose] * (1.0 - canefr);
                g_dm_senesced[sstem] = g_dm_senesced[sstem] * (1.0 - canefr);
                g_dm_senesced[sucrose] = g_dm_senesced[sucrose] * (1.0 - canefr);
                g_dm_dead[sstem] = g_dm_dead[sstem] * (1.0 - canefr);
                g_dm_dead[sucrose] = g_dm_dead[sucrose] * (1.0 - canefr);

                //nitrogen variables

                g_n_green[leaf] = g_n_green[leaf] * (1.0 - topsfr);
                g_n_green[cabbage] = g_n_green[cabbage] * (1.0 - topsfr);
                g_n_senesced[leaf] = g_n_senesced[leaf] * (1.0 - topsfr);
                g_n_senesced[cabbage] = g_n_senesced[cabbage] * (1.0 - topsfr);
                g_n_dead[leaf] = g_n_dead[leaf] * (1.0 - topsfr);
                g_n_dead[cabbage] = g_n_dead[cabbage] * (1.0 - topsfr);

                g_n_green[sstem] = g_n_green[sstem] * (1.0 - canefr);
                g_n_green[sucrose] = g_n_green[sucrose] * (1.0 - canefr);
                g_n_senesced[sstem] = g_n_senesced[sstem] * (1.0 - canefr);
                g_n_senesced[sucrose] = g_n_senesced[sucrose] * (1.0 - canefr);
                g_n_dead[sstem] = g_n_dead[sstem] * (1.0 - canefr);
                g_n_dead[sucrose] = g_n_dead[sucrose] * (1.0 - canefr);

                //! Now we need to update the leaf tracking info

                g_lai = g_lai * (1.0 - topsfr);
                g_slai = g_slai * (1.0 - topsfr);

                for (int leaf_no = 0; leaf_no < max_leaf; leaf_no++)
                    {
                    g_leaf_area_zb[leaf_no] = g_leaf_area_zb[leaf_no] * (1.0 - topsfr);
                    g_leaf_dm_zb[leaf_no] = g_leaf_dm_zb[leaf_no] * (1.0 - topsfr);
                    }

                }
            else
                {
                throw new ApsimXException(this, "Can only hill up during emergence phase");
                }
        }
예제 #6
0
파일: Sugarcane.cs 프로젝트: hol353/ApsimX
        //called above
        /// <summary>
        /// Crop_root_incorps the specified i_dlt_dm_root.
        /// </summary>
        /// <param name="i_dlt_dm_root">The i_dlt_dm_root.</param>
        /// <param name="i_dlt_n_root">The i_dlt_n_root.</param>
        /// <param name="i_dlayer">The i_dlayer.</param>
        /// <param name="i_root_length">The i_root_length.</param>
        /// <param name="i_root_depth">The i_root_depth.</param>
        /// <param name="c_crop_type">The c_crop_type.</param>
        /// <param name="i_max_layer">The i_max_layer.</param>
        /// <exception cref="ApsimXException">Too many layers for crop routines</exception>
        void crop_root_incorp(double i_dlt_dm_root, double i_dlt_n_root, double[] i_dlayer, double[] i_root_length, double i_root_depth,
                                string c_crop_type, int i_max_layer)
        {
            //!+  Sub-Program Arguments
            //      real       dlt_dm_root           ! (INPUT) new root residue dm (g/m^2)
            //      real       dlt_N_root            ! (INPUT) new root residue N (g/m^2)
            //      real       g_dlayer(*)           ! (INPUT) layer thicknesses (mm)
            //      real       g_root_length(*)      ! (INPUT) layered root length (mm)
            //      real       g_root_depth          ! (INPUT) root depth (mm)
            //      character  c_crop_type*(*)       ! (INPUT) crop type
            //      integer    max_layer             ! (INPUT) maximum no of soil layers
            //      integer    incorpFOMID           ! (INPUT) ID of incorp fom event.
            //!+  Purpose
            //!       Calculate and provide root matter incorporation information
            //!       to the APSIM messaging system.

            //!+  Mission Statement
            //!   Pass root material to the soil modules (based on root length distribution)

            //!+  Changes
            //!     <insert here>
            //!     280800 jngh changed literal incorp_fom to ACTION_incorp_fom
            //!     011100 dph  added event_interface as a parameter.

            int l_crop_max_layer = 100; //! maximum soil layers    //sv- taken from FortranInfrastructure\ConstantsModule.f90

            double[] l_dlt_dm_incorp = new double[l_crop_max_layer]; //! root residue (kg/ha)
            double[] l_dlt_N_incorp = new double[l_crop_max_layer];  //! root residue N (kg/ha)

            if (i_max_layer > l_crop_max_layer)
                {
                throw new ApsimXException(this, "Too many layers for crop routines");
                }
            else
                {

                if (i_dlt_dm_root > 0.0)
                    {
                    //! send out root residue

                    crop_root_dist(i_dlayer, i_root_length, i_root_depth, ref l_dlt_dm_incorp, i_dlt_dm_root * gm2kg / sm2ha);

                    bound_check_real_array(l_dlt_dm_incorp, 0.0, i_dlt_dm_root * gm2kg / sm2ha, "dlt_dm_incorp", i_max_layer);

                    crop_root_dist(i_dlayer, i_root_length, i_root_depth, ref l_dlt_N_incorp, i_dlt_n_root * gm2kg / sm2ha);

                    bound_check_real_array(l_dlt_N_incorp, 0.0, i_dlt_n_root * gm2kg / sm2ha, "dlt_n_incorp", i_max_layer);

                    //sv- FOMLayerType and FOMLayerLayerType are confusing but what I think they mean is,
                    //    FOMLayer means FOM "IN" the soil as opposed to "ON" the surface of the SOIL
                    //    I think they already used the term FOMType for the Surface Residue so they needed a name
                    //    for the class when they were refering to FOM "in" the soil. So they used the term FOMLayer.
                    //    This then meant when they needed a name for the class for an actual specific Layer they
                    //    then used the silly name of FOMLayerLayer. Meaning a Layer of the FOMLayer type.
                    //    This is silly naming but I think that this is what they have done.
                    //    They should have called it FOMInSoil or something, rather than FOMLayer.

                    FOMLayerLayerType[] allLayers = new FOMLayerLayerType[dlayer.Length];

                    for (int layer = 0; layer < dlayer.Length; layer++)
                        {
                        FOMType fom_in_layer = new FOMType();
                        fom_in_layer.amount = (float)l_dlt_dm_incorp[layer];
                        fom_in_layer.N = (float)l_dlt_N_incorp[layer];
                        fom_in_layer.P = (float)0.0;
                        fom_in_layer.C = (float)0.0;
                        fom_in_layer.AshAlk = (float)0.0;

                        FOMLayerLayerType thisLayer = new FOMLayerLayerType();
                        thisLayer.FOM = fom_in_layer;
                        thisLayer.CNR = (float)0.0;
                        thisLayer.LabileP = (float)0.0;

                        allLayers[layer] = thisLayer;
                        }

                    FOMLayerType fomInSoil = new FOMLayerType();
                    fomInSoil.Type = c_crop_type;
                    fomInSoil.Layer = allLayers;

                    IncorpFOM.Invoke(fomInSoil);   //trigger/invoke the IncorpFOM Event
                    }
                else
                    {
                    //! no roots to incorporate
                    }

                }
        }
예제 #7
0
파일: Root1.cs 프로젝트: hol353/ApsimX
        /// <summary>Disposes the detached material.</summary>
        /// <param name="BiomassToDisposeOf">The biomass to dispose of.</param>
        /// <param name="RootLength">Length of the root.</param>
        private void DisposeDetachedMaterial(Biomass BiomassToDisposeOf, double[] RootLength)
        {
            if (BiomassToDisposeOf.Wt > 0.0)
            {
                // DM
                double[] dlt_dm_incorp = RootDist(BiomassToDisposeOf.Wt * Conversions.gm2kg / Conversions.sm2ha, RootLength);

                // Nitrogen
                double[] dlt_N_incorp = RootDist(BiomassToDisposeOf.N * Conversions.gm2kg / Conversions.sm2ha, RootLength);

                // Phosporous
                //double[] dlt_P_incorp = RootDist(BiomassToDisposeOf.P * Conversions.gm2kg / Conversions.sm2ha);

                FOMLayerType IncorpFOMData = new FOMLayerType();
                IncorpFOMData.Type = Plant.CropType;
                Util.Debug("Root.IncorpFOM.Type=%s", IncorpFOMData.Type.ToLower());
                IncorpFOMData.Layer = new FOMLayerLayerType[dlt_dm_incorp.Length];
                for (int i = 0; i != dlt_dm_incorp.Length; i++)
                {
                    IncorpFOMData.Layer[i] = new FOMLayerLayerType();
                    IncorpFOMData.Layer[i].FOM = new FOMType();
                    IncorpFOMData.Layer[i].FOM.amount = (float)dlt_dm_incorp[i];
                    IncorpFOMData.Layer[i].FOM.N = (float)dlt_N_incorp[i];
                    //IncorpFOMData.Layer[i].FOM.P = (float)dlt_P_incorp[i];
                    IncorpFOMData.Layer[i].FOM.C = (float)0.0;
                    IncorpFOMData.Layer[i].FOM.AshAlk = (float)0.0;
                    IncorpFOMData.Layer[i].CNR = 0;
                    IncorpFOMData.Layer[i].LabileP = 0;
                    Util.Debug("Root.IncorpFOM.FOM.amount=%f2", IncorpFOMData.Layer[i].FOM.amount);
                    Util.Debug("Root.IncorpFOM.FOM.N=%f", IncorpFOMData.Layer[i].FOM.N);

                }
                IncorpFOM.Invoke(IncorpFOMData);
            }
            else
            {
                // no roots to incorporate
            }
        }
예제 #8
0
파일: Root.cs 프로젝트: hol353/ApsimX
        /// <summary>Removes biomass from root layers when harvest, graze or cut events are called.</summary>
        public override void DoRemoveBiomass(OrganBiomassRemovalType removal)
        {
            //NOTE: roots don't have dead biomass
            double totalFractionToRemove = removal.FractionLiveToRemove + removal.FractionLiveToResidue;
            if (totalFractionToRemove > 1.0 || totalFractionToRemove < 0)
                throw new Exception("The sum of FractionToResidue and FractionToRemove is greater than 1 or less than 0.");

            if (totalFractionToRemove > 0)
            {
                //NOTE: at the moment Root has no Dead pool
                FOMLayerLayerType[] FOMLayers = new FOMLayerLayerType[PlantZone.soil.Thickness.Length];
                double remainingFraction = 1.0 - (removal.FractionLiveToResidue + removal.FractionLiveToRemove);
                double detachingWt = 0.0;
                double detachingN = 0.0;
                for (int layer = 0; layer < PlantZone.soil.Thickness.Length; layer++)
                {
                    detachingWt = PlantZone.LayerLive[layer].Wt * removal.FractionLiveToResidue;
                    detachingN = PlantZone.LayerLive[layer].N * removal.FractionLiveToResidue;
                    RemovedWt += PlantZone.LayerLive[layer].Wt * removal.FractionLiveToRemove;
                    RemovedN += PlantZone.LayerLive[layer].N * removal.FractionLiveToRemove;
                    DetachedWt += detachingWt;
                    DetachedN += detachingN;

                    PlantZone.LayerLive[layer].StructuralWt *= remainingFraction;
                    PlantZone.LayerLive[layer].NonStructuralWt *= remainingFraction;
                    PlantZone.LayerLive[layer].MetabolicWt *= remainingFraction;

                    PlantZone.LayerLive[layer].StructuralN *= remainingFraction;
                    PlantZone.LayerLive[layer].NonStructuralN *= remainingFraction;
                    PlantZone.LayerLive[layer].MetabolicN *= remainingFraction;

                    FOMType fom = new FOMType();
                    fom.amount = (float)(detachingWt * 10);
                    fom.N = (float)(detachingN * 10);
                    fom.C = (float)(0.40 * detachingWt * 10);
                    fom.P = 0.0;
                    fom.AshAlk = 0.0;

                    FOMLayerLayerType Layer = new FOMLayerLayerType();
                    Layer.FOM = fom;
                    Layer.CNR = 0.0;
                    Layer.LabileP = 0.0;
                    FOMLayers[layer] = Layer;
                }
                FOMLayerType FomLayer = new FOMLayerType();
                FomLayer.Type = Plant.CropType;
                FomLayer.Layer = FOMLayers;
                IncorpFOM.Invoke(FomLayer);
            }
        }
예제 #9
0
파일: OilPalm.cs 프로젝트: hol353/ApsimX
        /// <summary>Does the root growth.</summary>
        /// <param name="Allocation">The allocation.</param>
        /// <exception cref="System.Exception">Error trying to partition root biomass</exception>
        private void DoRootGrowth(double Allocation)
        {
            int RootLayer = LayerIndex(RootDepth);
            RootDepth = RootDepth + RootFrontVelocity.Value * soilCrop.XF[RootLayer];
            RootDepth = Math.Min(MaximumRootDepth, RootDepth);
            RootDepth = Math.Min(MathUtilities.Sum(Soil.Thickness), RootDepth);

            // Calculate Root Activity Values for water and nitrogen
            double[] RAw = new double[Soil.Thickness.Length];
            double[] RAn = new double[Soil.Thickness.Length];
            double TotalRAw = 0;
            double TotalRAn = 0;

            for (int layer = 0; layer < Soil.Thickness.Length; layer++)
            {
                if (layer <= LayerIndex(RootDepth))
                    if (Roots[layer].Mass > 0)
                    {
                        RAw[layer] = SWUptake[layer] / Roots[layer].Mass
                                   * Soil.Thickness[layer]
                                   * RootProportion(layer, RootDepth);
                        RAw[layer] = Math.Max(RAw[layer], 1e-20);  // Make sure small numbers to avoid lack of info for partitioning

                        RAn[layer] = NUptake[layer] / Roots[layer].Mass
                                   * Soil.Thickness[layer]
                                   * RootProportion(layer, RootDepth);
                        RAn[layer] = Math.Max(RAw[layer], 1e-10);  // Make sure small numbers to avoid lack of info for partitioning

                    }
                    else if (layer > 0)
                    {
                        RAw[layer] = RAw[layer - 1];
                        RAn[layer] = RAn[layer - 1];
                    }
                    else
                    {
                        RAw[layer] = 0;
                        RAn[layer] = 0;
                    }
                TotalRAw += RAw[layer];
                TotalRAn += RAn[layer];
            }
            double allocated = 0;
            for (int layer = 0; layer < Soil.Thickness.Length; layer++)
            {
                if (TotalRAw > 0)

                    Roots[layer].Mass += Allocation * RAw[layer] / TotalRAw;
                else if (Allocation > 0)
                    throw new Exception("Error trying to partition root biomass");
                allocated += Allocation * RAw[layer] / TotalRAw;
            }

            // Do Root Senescence
            FOMLayerLayerType[] FOMLayers = new FOMLayerLayerType[Soil.Thickness.Length];

            for (int layer = 0; layer < Soil.Thickness.Length; layer++)
            {
                double Fr = RootSenescenceRate.Value;
                double DM = Roots[layer].Mass * Fr * 10.0;
                double N = Roots[layer].N * Fr * 10.0;
                Roots[layer].Mass *= (1.0 - Fr);
                Roots[layer].N *= (1.0 - Fr);
                Roots[layer].Length *= (1.0 - Fr);

                FOMType fom = new FOMType();
                fom.amount = (float)DM;
                fom.N = (float)N;
                fom.C = (float)(0.44 * DM);
                fom.P = 0;
                fom.AshAlk = 0;

                FOMLayerLayerType Layer = new FOMLayerLayerType();
                Layer.FOM = fom;
                Layer.CNR = 0;
                Layer.LabileP = 0;

                FOMLayers[layer] = Layer;
            }
            FOMLayerType FomLayer = new FOMLayerType();
            FomLayer.Type = CanopyType;
            FomLayer.Layer = FOMLayers;
            IncorpFOM.Invoke(FomLayer);
        }
예제 #10
0
            public void OnIncorpFOM(FOMLayerType FOMdata)
            {
                // +  Purpose:
                //      Partition the given FOM C and N into fractions in each layer.
                //      It will be assumed that the CN ratios of all fractions are equal

                bool nSpecified = false;
                for (int layer = 0; layer < FOMdata.Layer.Length; layer++)
                {
                    // If the caller specified CNR values then use them to calculate N from Amount.
                    if (FOMdata.Layer[layer].CNR > 0.0)
                        FOMdata.Layer[layer].FOM.N = (FOMdata.Layer[layer].FOM.amount * (float)g.c_in_fom) / FOMdata.Layer[layer].CNR;
                    // Was any N specified?
                    nSpecified |= FOMdata.Layer[layer].FOM.N != 0.0;
                }

                if (nSpecified)
                {
                    fom_type = 0; // use as default if fom type not found
                    for (int i = 0; i < g.fom_types.Length; i++)
                    {
                        if (g.fom_types[i].Equals(FOMdata.Type, StringComparison.CurrentCultureIgnoreCase))
                        {
                            fom_type = i;
                            break;
                        }
                    }
                    // Now convert the IncorpFOM.DeltaWt and IncorpFOM.DeltaN arrays to include fraction information and add to pools.
                    for (int layer = 0; layer < FOMdata.Layer.Length; layer++)
                    {
                        if (layer < g.dlayer.Length)
                        {
                            fom_c_pool1[layer] += FOMdata.Layer[layer].FOM.amount * g.fract_carb[fom_type] * g.c_in_fom;
                            fom_c_pool2[layer] += FOMdata.Layer[layer].FOM.amount * g.fract_cell[fom_type] * g.c_in_fom;
                            fom_c_pool3[layer] += FOMdata.Layer[layer].FOM.amount * g.fract_lign[fom_type] * g.c_in_fom;

                            fom_n_pool1[layer] += FOMdata.Layer[layer].FOM.N * g.fract_carb[fom_type];
                            fom_n_pool2[layer] += FOMdata.Layer[layer].FOM.N * g.fract_cell[fom_type];
                            fom_n_pool3[layer] += FOMdata.Layer[layer].FOM.N * g.fract_lign[fom_type];
                        }
                        else
                            g.Summary.WriteMessage(g, " Number of FOM values given is larger than the number of layers, extra values will be ignored");
                    }
                }
            }
예제 #11
0
파일: Root.cs 프로젝트: kiwiroy/ApsimX
        private void OnPlantEnding(object sender, EventArgs e)
        {
            if (sender == Plant)
            {
                FOMLayerLayerType[] FOMLayers = new FOMLayerLayerType[Soil.Thickness.Length];

                for (int layer = 0; layer < Soil.Thickness.Length; layer++)
                {
                    double DM = (LayerLive[layer].Wt + LayerDead[layer].Wt) * 10.0;
                    double N = (LayerLive[layer].N + LayerDead[layer].N) * 10.0;

                    FOMType fom = new FOMType();
                    fom.amount = (float)DM;
                    fom.N = (float)N;
                    fom.C = (float)(0.40 * DM);
                    fom.P = 0;
                    fom.AshAlk = 0;

                    FOMLayerLayerType Layer = new FOMLayerLayerType();
                    Layer.FOM = fom;
                    Layer.CNR = 0;
                    Layer.LabileP = 0;

                    FOMLayers[layer] = Layer;
                }
                FOMLayerType FomLayer = new FOMLayerType();
                FomLayer.Type = Plant.CropType;
                FomLayer.Layer = FOMLayers;
                IncorpFOM.Invoke(FomLayer);

                Clear();
            }
        }
예제 #12
0
파일: Root.cs 프로젝트: kiwiroy/ApsimX
        private void OnDoActualPlantGrowth(object sender, EventArgs e)
        {
            if (Plant.IsAlive)
            {
                // Do Root Front Advance
                int RootLayer = LayerIndex(Depth);
                double TEM = (TemperatureEffect == null) ? 1 : TemperatureEffect.Value;

                Depth = Depth + RootFrontVelocity.Value * soilCrop.XF[RootLayer] * TEM;
                double MaxDepth = 0;
                for (int i = 0; i < Soil.Thickness.Length; i++)
                    if (soilCrop.XF[i] > 0)
                        MaxDepth += Soil.Thickness[i];

                Depth = Math.Min(Depth, MaxDepth);

                // Do Root Senescence
                FOMLayerLayerType[] FOMLayers = new FOMLayerLayerType[Soil.Thickness.Length];

                for (int layer = 0; layer < Soil.Thickness.Length; layer++)
                {
                    double DM = LayerLive[layer].Wt * _SenescenceRate * 10.0;
                    double N = LayerLive[layer].StructuralN * _SenescenceRate * 10.0;
                    LayerLive[layer].StructuralWt *= (1.0 - _SenescenceRate);
                    LayerLive[layer].NonStructuralWt *= (1.0 - _SenescenceRate);
                    LayerLive[layer].StructuralN *= (1.0 - _SenescenceRate);
                    LayerLive[layer].NonStructuralN *= (1.0 - _SenescenceRate);

                    FOMType fom = new FOMType();
                    fom.amount = (float)DM;
                    fom.N = (float)N;
                    fom.C = (float)(0.40 * DM);
                    fom.P = 0;
                    fom.AshAlk = 0;

                    FOMLayerLayerType Layer = new FOMLayerLayerType();
                    Layer.FOM = fom;
                    Layer.CNR = 0;
                    Layer.LabileP = 0;

                    FOMLayers[layer] = Layer;
                }
                FOMLayerType FomLayer = new FOMLayerType();
                FomLayer.Type = Plant.CropType;
                FomLayer.Layer = FOMLayers;
                IncorpFOM.Invoke(FomLayer);
            }
        }
예제 #13
0
파일: AgPasture.cs 프로젝트: hut104/ApsimX
        /// <summary>return scenescent roots into fresh organic matter pool in soil</summary>
        /// <param name="rootSen">The root sen.</param>
        /// <param name="NinRootSen">The nin root sen.</param>
        private void DoIncorpFomEvent(double rootSen, double NinRootSen)
        {
            Soils.FOMLayerLayerType[] fomLL = new Soils.FOMLayerLayerType[Soil.Thickness.Length];

            // ****  RCichota, Jun, 2014 change how RootFraction (rlvp) is used in here ****************************************
            // root senesced are returned to soil (as FOM) considering return is proportional to root mass

            double dAmtLayer = 0.0; //amount of root litter in a layer
            double dNLayer = 0.0;
            for (int i = 0; i < Soil.Thickness.Length; i++)
            {
                dAmtLayer = rootSen * RootFraction[i];
                dNLayer = NinRootSen * RootFraction[i];

                Soils.FOMType fom = new Soils.FOMType();
                fom.amount = dAmtLayer;
                fom.N = dNLayer;// 0.03F * amt;	// N in dead root
                fom.C = 0.40 * dAmtLayer;	//40% of OM is C. Actually, 'C' is not used, as shown in DataTypes.xml
                fom.P = 0;			  //to consider later
                fom.AshAlk = 0;		 //to consider later

                Soils.FOMLayerLayerType Layer = new Soils.FOMLayerLayerType();
                Layer.FOM = fom;
                Layer.CNR = 0;	   //not used
                Layer.LabileP = 0;   //not used

                fomLL[i] = Layer;
            }

            if (IncorpFOM != null)
            {
                Soils.FOMLayerType FomLayer = new Soils.FOMLayerType();
                FomLayer.Type = "agpasture";
                FomLayer.Layer = fomLL;
                IncorpFOM.Invoke(FomLayer);
            }
        }
예제 #14
0
파일: Root.cs 프로젝트: byzheng/ApsimX
        /// <summary>Performs the removal of roots</summary>
        /// <param name="detachFraction">Fraction to send to residue (soil FOM)</param>
        /// <param name="removeFraction">Fraction to remove from the system</param>
        private void DoRootBiomassRemoval(double detachFraction, double removeFraction = 0.0)
        {
            //NOTE: at the moment Root has no Dead pool
            FOMLayerLayerType[] FOMLayers = new FOMLayerLayerType[Soil.Thickness.Length];
            double RemainingFraction = 1.0 - (detachFraction + removeFraction);
            double detachingWt = 0.0;
            double detachingN = 0.0;
            for (int layer = 0; layer < Soil.Thickness.Length; layer++)
            {
                detachingWt = LayerLive[layer].Wt * detachFraction;
                detachingN = LayerLive[layer].N * detachFraction;
                RemovedWt += LayerLive[layer].Wt * removeFraction;
                RemovedN += LayerLive[layer].N * removeFraction;
                DetachedWt += detachingWt;
                DetachedN += detachingN;

                LayerLive[layer].StructuralWt *= RemainingFraction;
                LayerLive[layer].NonStructuralWt *= RemainingFraction;
                LayerLive[layer].MetabolicWt *= RemainingFraction;

                LayerLive[layer].StructuralN *= RemainingFraction;
                LayerLive[layer].NonStructuralN *= RemainingFraction;
                LayerLive[layer].MetabolicN *= RemainingFraction;

                FOMType fom = new FOMType();
                fom.amount = (float) (detachingWt * 10);
                fom.N = (float) (detachingN * 10);
                fom.C = (float) (0.40 * detachingWt * 10);
                fom.P = 0.0;
                fom.AshAlk = 0.0;

                FOMLayerLayerType Layer = new FOMLayerLayerType();
                Layer.FOM = fom;
                Layer.CNR = 0.0;
                Layer.LabileP = 0.0;
                FOMLayers[layer] = Layer;
            }
            FOMLayerType FomLayer = new FOMLayerType();
            FomLayer.Type = Plant.CropType;
            FomLayer.Layer = FOMLayers;
            IncorpFOM.Invoke(FomLayer);
        }
예제 #15
0
        private void OnIncorpFOM(FOMLayerType inFOMdata)
        {
            // Note: In this event all FOM is given as one, so it will be assumed that the CN ratios of all fractions are equal

            foreach (soilCNPatch aPatch in Patch)
                aPatch.OnIncorpFOM(inFOMdata);

            fom_type = Patch[0].fom_type;
        }
예제 #16
0
        /// <summary>Adds a given amount of detached root material (DM and N) to the soil's FOM pool.</summary>
        /// <param name="amountDM">The DM amount to send (kg/ha)</param>
        /// <param name="amountN">The N amount to send (kg/ha)</param>
        private void DoAddDetachedRootToSoilFOM(double amountDM, double amountN)
        {
            FOMLayerLayerType[] FOMdataLayer = new FOMLayerLayerType[nLayers];
            for (int layer = 0; layer < nLayers; layer++)
            {
                FOMType fomData = new FOMType();
                fomData.amount = amountDM * RootWtFraction[layer];
                fomData.N = amountN * RootWtFraction[layer];
                fomData.C = amountDM * RootWtFraction[layer] * CarbonInDM;
                fomData.P = 0.0; // P not considered here
                fomData.AshAlk = 0.0; // Ash not considered here

                FOMLayerLayerType layerData = new FOMLayerLayerType();
                layerData.FOM = fomData;
                layerData.CNR = 0.0; // not used here
                layerData.LabileP = 0; // not used here

                FOMdataLayer[layer] = layerData;
            }

            if (IncorpFOM != null)
            {
                FOMLayerType FOMData = new FOMLayerType();
                FOMData.Type = "Pasture";
                FOMData.Layer = FOMdataLayer;
                IncorpFOM.Invoke(FOMData);
            }
        }
예제 #17
0
 private void OnIncorpFOM(FOMLayerType inFOMdata)
 {
     DoIncorpFOM(inFOMdata);
 }