public static void AdjustAvailableN(ICohort cohort, ActiveSite site, double[] actualANPP)
        {
            // Because Growth used some Nitrogen, it must be subtracted from the appropriate pools, either resorbed or mineral.

            double totalNdemand  = AvailableN.CalculateCohortNDemand(cohort.Species, site, cohort, actualANPP);
            double adjNdemand    = totalNdemand;
            double resorbedNused = 0.0;
            //double mineralNused = 0.0;

            // Use resorbed N first and only if it is spring time unless you are evergreen.
            double leafLongevity = SpeciesData.LeafLongevity[cohort.Species];

            if ((leafLongevity <= 1.0 && Century.Month > 2 && Century.Month < 6) || leafLongevity > 1.0)
            {
                double resorbedNallocation = Math.Max(0.0, AvailableN.GetResorbedNallocation(cohort, site));

                resorbedNused = resorbedNallocation - Math.Max(0.0, resorbedNallocation - totalNdemand);

                AvailableN.SetResorbedNallocation(cohort, Math.Max(0.0, resorbedNallocation - totalNdemand), site);

                adjNdemand = Math.Max(0.0, totalNdemand - resorbedNallocation);
            }

            // Reduce available N after taking into account that some N may have been provided
            // via resorption (above).
            double Nuptake = 0.0;

            if (SiteVars.MineralN[site] >= adjNdemand)
            {
                SiteVars.MineralN[site] -= adjNdemand;
                //mineralNused = adjNdemand;
                Nuptake = adjNdemand;
            }

            else
            {
                adjNdemand = SiteVars.MineralN[site];
                //mineralNused = SiteVars.MineralN[site];
                SiteVars.MineralN[site] = 0.0;
                Nuptake = SiteVars.MineralN[site];
            }

            SiteVars.TotalNuptake[site] += Nuptake;

            if (OtherData.CalibrateMode && PlugIn.ModelCore.CurrentTime > 0)
            {
                //Outputs.CalibrateLog.Write("{0:0.00}, {1:0.00}, {2:0.00}, {3:0.00},", deltaWood, deltaLeaf, totalMortality[0], totalMortality[1]);
                Outputs.CalibrateLog.Write("{0:0.00},{1:0.00},{2:0.00},", resorbedNused, Nuptake, totalNdemand);
            }
        }
Exemplo n.º 2
0
        //--------------------------------------------------------------------------
        //N limit is actual demand divided by maximum uptake.
        private double calculateN_Limit(ActiveSite site, ICohort cohort, double NPP, double leafFractionNPP)
        {
            //Get Cohort Mineral and Resorbed N allocation.
            double mineralNallocation  = AvailableN.GetMineralNallocation(cohort);
            double resorbedNallocation = AvailableN.GetResorbedNallocation(cohort, site);

            //double LeafNPP = Math.Max(NPP * leafFractionNPP, 0.002 * cohort.WoodBiomass);  This allowed for Ndemand in winter when there was no leaf NPP
            double LeafNPP = (NPP * leafFractionNPP);

            double WoodNPP = NPP * (1.0 - leafFractionNPP);

            double limitN = 0.0;

            if (SpeciesData.NFixer[cohort.Species])
            {
                limitN = 1.0;  // No limit for N-fixing shrubs
            }
            else
            {
                // Divide allocation N by N demand here:
                //PlugIn.ModelCore.UI.WriteLine("  WoodNPP={0:0.00}, LeafNPP={1:0.00}, FineRootNPP={2:0.00}, CoarseRootNPP={3:0.00}.", WoodNPP, LeafNPP);
                double Ndemand = (AvailableN.CalculateCohortNDemand(cohort.Species, site, cohort, new double[] { WoodNPP, LeafNPP }));

                if (Ndemand > 0.0)
                {
                    limitN = Math.Min(1.0, (mineralNallocation + resorbedNallocation) / Ndemand);
                }
                else
                {
                    limitN = 1.0; // No demand means that it is a new or very small cohort.  Will allow it to grow anyways.
                }
            }


            if (PlugIn.ModelCore.CurrentTime > 0 && OtherData.CalibrateMode)
            {
                Outputs.CalibrateLog.Write("{0:0.00},{1:0.00},", mineralNallocation, resorbedNallocation);
            }

            return(Math.Max(limitN, 0.0));
        }