コード例 #1
0
ファイル: RootTissue.cs プロジェクト: BrianCollinss/ApsimNG
        /// <summary>
        /// Move a fraction of the biomass from this tissue to another tissue.
        /// </summary>
        /// <param name="fractionToRemove">The fraction to move.</param>
        /// <param name="toTissue">The tissue to move to biomass to.</param>
        public void MoveFractionToTissue(double fractionToRemove, RootTissue toTissue)
        {
            var removed = RemoveBiomass(fractionToRemove, sendToSurfaceOrganicMatter: false);

            toTissue.AddBiomass(removed.Wt, removed.N);
            if (fractionToRemove == 1)
            {
                Reset();
            }
        }
コード例 #2
0
ファイル: RootTissue.cs プロジェクト: lie112/ApsimX
        /// <summary>Computes the DM and N amounts turned over for this tissue.</summary>
        /// <param name="turnoverRate">The turnover rate for the tissue today.</param>
        /// <param name="receivingTissue">The tissue to move the turned over biomass to.</param>
        /// <param name="nConc">The N concentration threshold to consider.</param>
        /// <remarks>For live tissues, potential N remobilisable is above optimum concentration, for dead is all above minimum</remarks>
        public void DoTissueTurnover(double turnoverRate, RootTissue receivingTissue, double nConc)
        {
            if (DM.Wt > 0.0 && turnoverRate > 0.0)
            {
                var turnedoverDM = DM.Wt * turnoverRate;
                var turnedoverN  = DM.N * turnoverRate;
                DMTransferredOut += turnedoverDM;
                NTransferredOut  += turnedoverN;
                if (receivingTissue != null)
                {
                    receivingTissue.SetBiomassTransferIn(dm: MathUtilities.Multiply_Value(FractionWt, turnedoverDM),
                                                         n: MathUtilities.Multiply_Value(FractionWt, turnedoverN));
                }

                // get the N amount remobilisable (all N in this tissue above the given nConc concentration)
                double totalRemobilisableN = (DM.Wt - DMTransferredOut) * Math.Max(0.0, DM.NConc - nConc);
                totalRemobilisableN += Math.Max(0.0, NTransferredIn - DMTransferredIn * nConc);
                NRemobilisable       = Math.Max(0.0, totalRemobilisableN * FractionNRemobilisable);
            }
        }
コード例 #3
0
ファイル: RootTissue.cs プロジェクト: MikeStower/ApsimX
        /// <summary>Updates each tissue, make changes in DM and N effective.</summary>
        public static void UpdateTissues(RootTissue tissue1, RootTissue tissue2)
        {
            // save current state
            double previousDM = tissue1.DM.Wt + tissue2.DM.Wt;
            double previousN  = tissue1.DM.N + tissue2.DM.N;

            // update all tissues
            tissue1.Update();
            tissue2.Update();

            var currentDM = tissue1.DM.Wt + tissue2.DM.Wt;
            var currentN  = tissue1.DM.N + tissue2.DM.N;

            // check mass balance
            if (!MathUtilities.FloatsAreEqual(0.0, previousDM + tissue1.dmTransferredIn - tissue2.dmTransferredOut - currentDM))
            {
                throw new Exception("Growth and tissue turnover resulted in loss of dry matter mass balance for roots");
            }
            if (!MathUtilities.FloatsAreEqual(0.0, previousN + tissue1.nTransferredIn - tissue1.nRemobilised - tissue2.nRemobilised - tissue2.nTransferredOut - currentN))
            {
                throw new Exception("Growth and tissue turnover resulted in loss of nitrogen mass balance for roots");
            }
        }
コード例 #4
0
ファイル: RootTissue.cs プロジェクト: MikeStower/ApsimX
        /// <summary>Move a fraction of the biomass from this tissue to another tissue.</summary>
        /// <param name="fractionToRemove">The fraction to move.</param>
        /// <param name="toTissue">The tissue to move to biomass to.</param>
        public void MoveFractionToTissue(double fractionToRemove, RootTissue toTissue)
        {
            var removed = RemoveBiomass(fractionToRemove, sendToSoil: false);

            toTissue.AddBiomass(removed.Wt, removed.N);
        }
コード例 #5
0
 /// <summary>Constructor, initialise tissues</summary>
 public PastureBelowGroundOrgan(int numTissues, int numLayers)
 {
     // Typically two tissues below ground, one live and one dead
     TissueCount = numTissues;
     Tissue = new RootTissue[TissueCount];
     for (int t = 0; t < TissueCount; t++)
         Tissue[t] = new RootTissue(numLayers);
 }
コード例 #6
0
 /// <summary>Updates each tissue, make changes in DM and N effective.</summary>
 internal void DoOrganUpdate()
 {
     RootTissue.UpdateTissues(Live, Dead);
 }
コード例 #7
0
        /// <summary>Constructor, initialise tissues for the roots.</summary>
        /// <param name="nameOfSpecies">Name of the pasture species</param>
        /// <param name="numTissues">Number of tissues in this organ</param>
        /// <param name="initialDM">Initial dry matter weight</param>
        /// <param name="initialDepth">Initial root depth</param>
        /// <param name="optNconc">The optimum N concentration</param>
        /// <param name="minNconc">The minimum N concentration</param>
        /// <param name="maxNconc">The maximum N concentration</param>
        /// <param name="minLiveDM">The minimum biomass for this organ</param>
        /// <param name="specificRootLength">The specific root length (m/g)</param>
        /// <param name="rootDepthMaximum">The maximum root depth</param>
        /// <param name="rootDistributionDepthParam">Parameter to compute root distribution, depth with constant root</param>
        /// <param name="rootBottomDistributionFactor">Parameter to compute root distribution, </param>
        /// <param name="rootDistributionExponent">Parameter to compute root distribution, exponent for root decrease</param>
        /// <param name="waterAvailableMethod">Method to compute water available</param>
        /// <param name="nitrogenAvailableMethod">Method to compute N available</param>
        /// <param name="kNH4">Parameter to compute NN4 available, default method</param>
        /// <param name="kNO3">Parameter to compute NO3 available, default method</param>
        /// <param name="maxNUptake">Parameter to compute N uptake, default method</param>
        /// <param name="kuNH4">Parameter to compute NH4 available, alternative method</param>
        /// <param name="kuNO3">Parameter to compute NO3 available, alternative method</param>
        /// <param name="referenceKSuptake">Parameter to compute available water, conductivity</param>
        /// <param name="referenceRLD">Parameter to compute available water, roots</param>
        /// <param name="exponentSoilMoisture">Parameter to compute available water</param>
        /// <param name="theSoil">Reference to the soil in the zone these roots are in</param>
        public PastureBelowGroundOrgan(string nameOfSpecies, int numTissues,
                                       double initialDM, double initialDepth,
                                       double optNconc, double minNconc, double maxNconc,
                                       double minLiveDM,
                                       double specificRootLength, double rootDepthMaximum,
                                       double rootDistributionDepthParam, double rootDistributionExponent,
                                       double rootBottomDistributionFactor,
                                       PastureSpecies.PlantAvailableWaterMethod waterAvailableMethod,
                                       PastureSpecies.PlantAvailableNitrogenMethod nitrogenAvailableMethod,
                                       double kNH4, double kNO3, double maxNUptake,
                                       double kuNH4, double kuNO3, double referenceKSuptake,
                                       double referenceRLD, double exponentSoilMoisture,
                                       Soil theSoil)
        {
            mySoil       = theSoil;
            SoilNitrogen = Apsim.Find(mySoil, typeof(INutrient)) as INutrient;
            if (SoilNitrogen == null)
            {
                throw new Exception("Cannot find SoilNitrogen in zone");
            }

            // Typically two tissues below ground, one live and one dead
            Tissue  = new RootTissue[numTissues];
            nLayers = theSoil.Thickness.Length;
            for (int t = 0; t < Tissue.Length; t++)
            {
                Tissue[t] = new RootTissue(nameOfSpecies, SoilNitrogen, nLayers);
            }

            // save the parameters for this organ
            mySpeciesName                  = nameOfSpecies;
            NConcOptimum                   = optNconc;
            NConcMinimum                   = minNconc;
            NConcMaximum                   = maxNconc;
            MinimumLiveDM                  = minLiveDM;
            mySpecificRootLength           = specificRootLength;
            myRootDepthMaximum             = rootDepthMaximum;
            myRootDistributionDepthParam   = rootDistributionDepthParam;
            myRootDistributionExponent     = rootDistributionExponent;
            myRootBottomDistributionFactor = rootBottomDistributionFactor;
            myWaterAvailableMethod         = waterAvailableMethod;
            myNitrogenAvailableMethod      = nitrogenAvailableMethod;
            myKNO3                 = kNO3;
            myKNH4                 = kNH4;
            myMaximumNUptake       = maxNUptake;
            myKuNH4                = kuNH4;
            myKuNO3                = kuNO3;
            myReferenceKSuptake    = referenceKSuptake;
            myReferenceRLD         = referenceRLD;
            myExponentSoilMoisture = exponentSoilMoisture;

            // Link to soil and initialise variables
            myZoneName         = mySoil.Parent.Name;
            mySoilNH4Available = new double[nLayers];
            mySoilNO3Available = new double[nLayers];
            NO3 = Apsim.Find(mySoil, "NO3") as ISolute;
            NH4 = Apsim.Find(mySoil, "NH4") as ISolute;

            // Initialise root DM, N, depth, and distribution
            Depth = initialDepth;
            TargetDistribution = RootDistributionTarget();
            double[] iniRootFraction = CurrentRootDistributionTarget();
            for (int layer = 0; layer < nLayers; layer++)
            {
                Tissue[0].DMLayer[layer]      = initialDM * iniRootFraction[layer];
                Tissue[0].NamountLayer[layer] = NConcOptimum * Tissue[0].DMLayer[layer];
            }
        }
コード例 #8
0
 /// <summary>Updates each tissue, make changes in DM and N effective.</summary>
 internal void DoOrganUpdate()
 {
     RootTissue.UpdateTissues(Tissue[0], Tissue[1]);
 }