Ejemplo n.º 1
0
        /// <summary>Does the n partition.</summary>
        /// <param name="n_fix_pot">The n_fix_pot.</param>
        /// <param name="Organs">The organs.</param>
        /// <returns></returns>
        internal double DoNPartition(double n_fix_pot, List <Organ1> Organs)
        {
            double NDemandTotal   = 0;
            double NCapacityTotal = 0;
            double nUptakeSum     = 0;

            foreach (Organ1 Organ in Organs)
            {
                NDemandTotal   += Organ.NDemand;
                NCapacityTotal += Organ.NCapacity;
                nUptakeSum     += Organ.NUptake;
            }
            double n_excess = nUptakeSum - NDemandTotal;

            n_excess = MathUtilities.Constrain(n_excess, 0.0, double.MaxValue);

            // find the proportion of uptake to be distributed to
            // each plant part and distribute it.
            foreach (Organ1 Organ in Organs)
            {
                if (n_excess > 0.0)
                {
                    double plant_part_fract = MathUtilities.Divide(Organ.NCapacity, NCapacityTotal, 0.0);
                    Organ.DoNPartition(Organ.NDemand + n_excess * plant_part_fract);
                }
                else
                {
                    double plant_part_fract = MathUtilities.Divide(Organ.NDemand, NDemandTotal, 0.0);
                    Organ.DoNPartition(nUptakeSum * plant_part_fract);
                }
            }


            // Check Mass Balance
            double GrowthNTotal = 0;

            foreach (Organ1 Organ in Organs)
            {
                GrowthNTotal += Organ.Growth.N;
            }

            if (!MathUtilities.FloatsAreEqual(GrowthNTotal - nUptakeSum, 0.0))
            {
                string msg = "Crop dlt_n_green mass balance is off: dlt_n_green_sum ="
                             + GrowthNTotal.ToString("f6")
                             + " vs n_uptake_sum ="
                             + nUptakeSum.ToString("f6");
                Summary.WriteWarning(this, msg);
            }
            Util.Debug("Arbitrator.nUptakeSum=%f", nUptakeSum);

            // Retranslocate N Fixed
            double NFixDemandTotal = MathUtilities.Constrain(NDemandTotal - nUptakeSum, 0.0, double.MaxValue); // total demand for N fixation (g/m^2)
            double NFixUptake      = MathUtilities.Constrain(n_fix_pot, 0.0, NFixDemandTotal);

            double n_demand_differential = 0;

            foreach (Organ1 Organ in Organs)
            {
                n_demand_differential += Organ.NDemandDifferential;
            }

            // now distribute the n fixed to plant parts
            NFixUptake = NFixUptake * MathUtilities.Divide(n_demand_differential, NFixDemandTotal, 0.0);
            foreach (Organ1 Organ in Organs)
            {
                Organ.DoNFixRetranslocate(NFixUptake, n_demand_differential);
            }
            Util.Debug("Arbitrator.n_demand_differential=%f", n_demand_differential);
            Util.Debug("Arbitrator.NFixUptake=%f", NFixUptake);
            return(NFixUptake);
        }