/// <summary> /// Send the nitrogen uptake arrays back to the plants and send the change in nitrogen back to the soil /// </summary> /// <param name="resourceToArbitrate"></param> private void SetNitrogenUptake(string resourceToArbitrate) { zones = -1; int maxPlants = 0; int maxLayers = 0; foreach (Zone zone in Apsim.FindAll(Simulation, typeof(Zone))) //foreach (Zone zone in Simulation.FindAll(typeof(Zone))) { zones += 1; // Find plants in paddock. List <ICrop2> plants = zone.Plants; maxPlants = Math.Max(plants.Count, maxPlants); // Find soil in paddock. Soil Soil = (Soil)Apsim.Find(zone, typeof(Soil)); maxLayers = Math.Max(Soil.Thickness.Length, maxLayers); double[] dummyArray1 = new double[Soil.Thickness.Length]; // have to create a new array for each plant to avoid the .NET pointer thing - will have to re-think this with when zones come in double[] dummyArray2 = new double[Soil.Thickness.Length]; // have to create a new array for each plant to avoid the .NET pointer thing - will have to re-think this with when zones come in // move this inside the zone loop - needs to get zeroed for each seperate zone double[] DeltaNO3 = new double[Soil.Thickness.Length]; double[] DeltaNH4 = new double[Soil.Thickness.Length]; for (int p = 0; p < maxPlants; p++) { for (int l = 0; l < maxLayers; l++) { for (int b = 0; b < bounds; b++) { for (int f = 0; f < forms; f++) { dummyArray1[l] += uptake[p, l, z, b, f]; // add the forms together to give the total nitrogen uptake if (f == 0) { DeltaNO3[l] += -1.0 * uptake[p, l, z, b, f]; dummyArray2[l] += uptake[p, l, z, b, f]; // nitrate only uptake so can do the proportion before sending to the plant } else { DeltaNH4[l] += -1.0 * uptake[p, l, z, b, f]; } } } } // set uptakes in each plant plants[p].uptakeNitrogen = dummyArray1; for (int l = 0; l < Soil.Thickness.Length; l++) // don't forget to deal with zones at some point { dummyArray2[l] = MathUtilities.Divide(dummyArray2[l], dummyArray1[l], 0.0); // would be nice to have a utility for this } plants[p].uptakeNitrogenPropNO3 = dummyArray2; } // and finally set the changed soil resources solutes.Add("NO3", DeltaNO3); solutes.Add("NH4", DeltaNH4); } }
private void OnDoSoilWaterMovement(object sender, EventArgs e) { // Calculate lateral flow. LateralFlow = lateralFlowModel.Values; MathUtilities.Subtract(Water, LateralFlow); // Calculate runoff. Runoff = runoffModel.Value(); // Calculate infiltration. Infiltration = PotentialInfiltration - Runoff; Water[0] = Water[0] + Infiltration; // Allow irrigation to infiltrate. if (!irrigation.WillRunoff) { int irrigationLayer = SoilUtilities.FindLayerIndex(properties, Convert.ToInt32(irrigation.Depth)); Water[irrigationLayer] = irrigation.IrrigationApplied; Infiltration += irrigation.IrrigationApplied; // DeanH - haven't implemented solutes in irrigation water yet. // NO3[irrigationLayer] = irrigation.NO3; // NH4[irrigationLayer] = irrigation.NH4; // CL[irrigationLayer] = irrigation.Cl; } // Saturated flow. Flux = saturatedFlow.Values; // Add backed up water to runoff. Water[0] = Water[0] - saturatedFlow.backedUpSurface; // Now reduce the infiltration amount by what backed up. Infiltration = Infiltration - saturatedFlow.backedUpSurface; // Turn the proportion of the infiltration that backed up into runoff. Runoff = Runoff + saturatedFlow.backedUpSurface; // Should go to pond if one exists. // pond = Math.Min(Runoff, max_pond); MoveDown(Water, Flux); double[] NO3 = soilNitrogen.NO3; double[] NH4 = soilNitrogen.NH4; // Calcualte solute movement down with water. double[] NO3Down = CalculateSoluteMovementDown(NO3, Water, Flux, SoluteFluxEfficiency); double[] NH4Down = CalculateSoluteMovementDown(NH4, Water, Flux, SoluteFluxEfficiency); MoveDown(NO3, NO3Down); MoveDown(NH4, NH4Down); double es = evaporationModel.Calculate(); Water[0] = Water[0] - es; Flow = unsaturatedFlow.Values; MoveUp(Water, Flow); CheckForErrors(); double waterTableDepth = waterTableModel.Value(); double[] NO3Up = CalculateSoluteMovementUpDown(soilNitrogen.NO3, Water, Flow, SoluteFlowEfficiency); double[] NH4Up = CalculateSoluteMovementUpDown(soilNitrogen.NH4, Water, Flow, SoluteFlowEfficiency); MoveUp(NO3, NO3Up); MoveUp(NH4, NH4Up); // Set deltas solutes.Add("NO3", MathUtilities.Subtract(soilNitrogen.NO3, NO3)); solutes.Add("NH4", MathUtilities.Subtract(soilNitrogen.NH4, NH4)); ResidueInterception = 0; CanopyInterception = 0; }