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