/// <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); }