/// <summary>The method used to arbitrate N allocations</summary>
        public List <ZoneWaterAndN> GetUptakeEstimates(SoilState soilstate, IArbitration[] Organs)
        {
            // Get all water supplies.
            double waterSupply = 0;  //NOTE: This is in L, not mm, to arbitrate water demands for spatial simulations.

            List <double[]>      supplies = new List <double[]>();
            List <ZoneWaterAndN> zones    = new List <ZoneWaterAndN>();

            foreach (ZoneWaterAndN zone in soilstate.Zones)
            {
                foreach (IOrgan o in Organs)
                {
                    if (o is IWaterNitrogenUptake)
                    {
                        double[] organSupply = (o as IWaterNitrogenUptake).CalculateWaterSupply(zone);
                        if (organSupply != null)
                        {
                            supplies.Add(organSupply);
                            zones.Add(zone);
                            waterSupply += MathUtilities.Sum(organSupply) * zone.Zone.Area;
                        }
                    }
                }
            }

            // Calculate total water demand.
            double waterDemand = 0; //NOTE: This is in L, not mm, to arbitrate water demands for spatial simulations.

            foreach (IHasWaterDemand WD in WaterDemands)
            {
                waterDemand += WD.CalculateWaterDemand() * plant.Zone.Area;
            }

            // Calculate demand / supply ratio.
            double fractionUsed = 0;

            if (waterSupply > 0)
            {
                fractionUsed = Math.Min(1.0, waterDemand / waterSupply);
            }

            // Apply demand supply ratio to each zone and create a ZoneWaterAndN structure
            // to return to caller.
            List <ZoneWaterAndN> ZWNs = new List <ZoneWaterAndN>();

            for (int i = 0; i < supplies.Count; i++)
            {
                // Just send uptake from my zone
                ZoneWaterAndN uptake = new ZoneWaterAndN(zones[i]);
                uptake.Water = MathUtilities.Multiply_Value(supplies[i], fractionUsed);
                uptake.NO3N  = new double[uptake.Water.Length];
                uptake.NH4N  = new double[uptake.Water.Length];
                uptake.PlantAvailableNO3N = new double[uptake.Water.Length];
                uptake.PlantAvailableNH4N = new double[uptake.Water.Length];
                ZWNs.Add(uptake);
            }
            return(ZWNs);
        }
Beispiel #2
0
        /// <summary>
        /// Set the sw uptake for today
        /// </summary>
        public override void SetActualWaterUptake(List <ZoneWaterAndN> zones)
        {
            // Calculate the total water supply across all zones.
            double waterSupply = 0;   //NOTE: This is in L, not mm, to arbitrate water demands for spatial simulations.

            foreach (ZoneWaterAndN Z in zones)
            {
                // Z.Water calculated as Supply * fraction used
                waterSupply += MathUtilities.Sum(Z.Water) * Z.Zone.Area;
            }

            // Calculate total plant water demand.
            WDemand = 0.0; //NOTE: This is in L, not mm, to arbitrate water demands for spatial simulations.
            foreach (IArbitration o in Organs)
            {
                if (o is IHasWaterDemand)
                {
                    WDemand += (o as IHasWaterDemand).CalculateWaterDemand() * Plant.Zone.Area;
                }
            }

            // Calculate the fraction of water demand that has been given to us.
            double fraction = 1;

            if (MathUtilities.IsPositive(WDemand))
            {
                fraction = Math.Min(1.0, waterSupply / WDemand);
            }

            // Proportionally allocate supply across organs.
            WAllocated = 0.0;

            foreach (IHasWaterDemand WD in WaterDemands)
            {
                double demand     = WD.CalculateWaterDemand();
                double allocation = fraction * demand;
                WD.WaterAllocation = allocation;
                WAllocated        += allocation;
            }

            // Give the water uptake for each zone to Root so that it can perform the uptake
            // i.e. Root will do pass the uptake to the soil water balance.
            foreach (ZoneWaterAndN zone in zones)
            {
                StoreWaterVariablesForNitrogenUptake(zone);
            }

            foreach (ZoneWaterAndN zone in zones)
            {
                Plant.Root.DoWaterUptake(zone.Water, zone.Zone.Name);
            }
        }
        /// Calculating the actual water uptake across all zones.
        public void SetActualUptakes(List <ZoneWaterAndN> zones, IArbitration[] Organs)
        {
            // Calculate the total water supply across all zones.
            double waterSupply = 0;   //NOTE: This is in L, not mm, to arbitrate water demands for spatial simulations.

            foreach (ZoneWaterAndN Z in zones)
            {
                waterSupply += MathUtilities.Sum(Z.Water) * Z.Zone.Area;
            }
            // Calculate total plant water demand.
            WDemand = 0.0; //NOTE: This is in L, not mm, to arbitrate water demands for spatial simulations.
            foreach (IArbitration o in Organs)
            {
                if (o is IHasWaterDemand)
                {
                    WDemand += (o as IHasWaterDemand).CalculateWaterDemand() * plant.Zone.Area;
                }
            }

            // Calculate the fraction of water demand that has been given to us.
            double fraction = 1;

            if (WDemand > 0)
            {
                fraction = Math.Min(1.0, waterSupply / WDemand);
            }

            // Proportionally allocate supply across organs.
            WAllocated = 0.0;

            foreach (IHasWaterDemand WD in WaterDemands)
            {
                double demand     = WD.CalculateWaterDemand();
                double allocation = fraction * demand;
                WD.WaterAllocation = allocation;
                WAllocated        += allocation;
            }
            foreach (ZoneWaterAndN Z in zones)
            {
                StoreWaterVariablesForNitrogenUptake(Z);
            }
        }