Beispiel #1
0
        /// <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);
            }
        }
Beispiel #2
0
        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;
        }