Example #1
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 = APSIM.Shared.APSoil.SoilUtilities.FindLayerIndex(properties, Convert.ToInt32(irrigation.Depth, CultureInfo.InvariantCulture));
                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[] NO3Values = soilNitrogen.CalculateNO3();
            double[] NH4Values = soilNitrogen.CalculateNH4();

            // Calcualte solute movement down with water.
            double[] NO3Down = CalculateSoluteMovementDown(NO3Values, Water, Flux, SoluteFluxEfficiency);
            double[] NH4Down = CalculateSoluteMovementDown(NH4Values, Water, Flux, SoluteFluxEfficiency);
            MoveDown(NO3Values, NO3Down);
            MoveDown(NH4Values, 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.CalculateNO3(), Water, Flow, SoluteFlowEfficiency);
            double[] NH4Up = CalculateSoluteMovementUpDown(soilNitrogen.CalculateNH4(), Water, Flow, SoluteFlowEfficiency);
            MoveUp(NO3Values, NO3Up);
            MoveUp(NH4Values, NH4Up);

            // Set deltas
            NO3.SetKgHa(SoluteSetterType.Soil, MathUtilities.Subtract(soilNitrogen.CalculateNO3(), NO3Values));
            NH4.SetKgHa(SoluteSetterType.Soil, MathUtilities.Subtract(soilNitrogen.CalculateNH4(), NH4Values));
        }
Example #2
0
        private void OnDoSoilWaterMovement(object sender, EventArgs e)
        {
            // Calculate lateral flow.
            lateralFlowModel.Calculate();
            if (LateralFlow.Length > 0)
            {
                Water = MathUtilities.Subtract(Water, LateralFlow);
            }

            // Calculate runoff.
            Runoff = runoffModel.Value();

            // Calculate infiltration.
            Infiltration = PotentialInfiltration - Runoff;

            Water[0] = Water[0] + Infiltration + Runon;

            // Allow irrigation to infiltrate.
            foreach (var irrigation in irrigations)
            {
                if (irrigation.Amount > 0)
                {
                    int irrigationLayer = soil.LayerIndexOfDepth(Convert.ToInt32(irrigation.Depth, CultureInfo.InvariantCulture));
                    Water[irrigationLayer] += irrigation.Amount;
                    if (irrigationLayer == 0)
                    {
                        Infiltration += irrigation.Amount;
                    }

                    if (no3 != null)
                    {
                        no3.kgha[irrigationLayer] += irrigation.NO3;
                    }

                    if (nh4 != null)
                    {
                        nh4.kgha[irrigationLayer] += irrigation.NH4;
                    }

                    if (cl != null)
                    {
                        cl.kgha[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[] no3Values  = no3.kgha;
            double[] ureaValues = urea.kgha;

            // Calcualte solute movement down with water.
            double[] no3Down = CalculateSoluteMovementDown(no3Values, Water, Flux, SoluteFluxEfficiency);
            MoveDown(no3Values, no3Down);
            double[] ureaDown = CalculateSoluteMovementDown(ureaValues, Water, Flux, SoluteFluxEfficiency);
            MoveDown(ureaValues, ureaDown);

            // Calculate evaporation and remove from top layer.
            double es = evaporationModel.Calculate();

            Water[0] = Water[0] - es;

            // Calculate unsaturated flow of water and apply.
            Flow = unsaturatedFlow.Values;
            MoveUp(Water, Flow);

            // Check for errors in water variables.
            //CheckForErrors();

            // Calculate water table depth.
            waterTableModel.Calculate();

            // Calculate and apply net solute movement.
            double[] no3Up = CalculateNetSoluteMovement(no3Values, Water, Flow, SoluteFlowEfficiency);
            MoveUp(no3Values, no3Up);
            double[] ureaUp = CalculateNetSoluteMovement(ureaValues, Water, Flow, SoluteFlowEfficiency);
            MoveUp(ureaValues, ureaUp);

            // Update flow output variables.
            FlowNO3  = MathUtilities.Subtract(no3Down, no3Up);
            FlowUrea = MathUtilities.Subtract(ureaDown, ureaUp);

            // Set solute state variables.
            no3.SetKgHa(SoluteSetterType.Soil, no3Values);
            urea.SetKgHa(SoluteSetterType.Soil, ureaValues);

            // Now that we've finished moving water, calculate volumetric water
            waterVolumetric = MathUtilities.Divide(Water, soil.Thickness);
        }
Example #3
0
        public void TestEvaporation()
        {
            MockSoil soil = new MockSoil();

            APSIM.Shared.Soils.Soil soilProperties = Setup();
            APSIMReadySoil.Create(soilProperties);

            MockClock clock = new MockClock();
            clock.Today = new DateTime(2015, 6, 1);

            MockWeather weather = new MockWeather();
            weather.MaxT = 30;
            weather.MinT = 10;
            weather.Rain = 100;
            weather.Radn = 25;

            MockSurfaceOrganicMatter surfaceOrganicMatter = new MockSurfaceOrganicMatter();
            surfaceOrganicMatter.Cover = 0.8;

            List<ICanopy> canopies = new List<ICanopy>();

            EvaporationModel evaporation = new EvaporationModel();
            SetLink(soil, "properties", soilProperties);
            SetLink(evaporation, "soil", soil);
            SetLink(evaporation, "clock", clock);
            SetLink(evaporation, "weather", weather);
            SetLink(evaporation, "canopies", canopies);
            SetLink(evaporation, "surfaceOrganicMatter", surfaceOrganicMatter);

            // Empty profile.
            soil.Water = MathUtilities.Multiply(soilProperties.Water.LL15, soilProperties.Water.Thickness);

            evaporation.Calculate();
            Assert.IsTrue(MathUtilities.FloatsAreEqual(evaporation.Es, 3.00359));

            soil.Infiltration = 0;
            evaporation.Calculate();
            Assert.IsTrue(MathUtilities.FloatsAreEqual(evaporation.Es, 2.20072));

            soil.Infiltration = 0;
            evaporation.Calculate();
            Assert.IsTrue(MathUtilities.FloatsAreEqual(evaporation.Es, 1.57064));

            soil.Infiltration = 0;
            evaporation.Calculate();
            Assert.IsTrue(MathUtilities.FloatsAreEqual(evaporation.Es, 0.96006));

            soil.Infiltration = 0;
            evaporation.Calculate();
            Assert.IsTrue(MathUtilities.FloatsAreEqual(evaporation.Es, 0.75946));

            soil.Infiltration = 0;
            evaporation.Calculate();
            Assert.IsTrue(MathUtilities.FloatsAreEqual(evaporation.Es, 0.64851));

            soil.Infiltration = 100;
            evaporation.Calculate();
            Assert.IsTrue(MathUtilities.FloatsAreEqual(evaporation.Es, 3.00359));

            soil.Infiltration = 0;
            evaporation.Calculate();
            Assert.IsTrue(MathUtilities.FloatsAreEqual(evaporation.Es, 2.20072));
        }