Пример #1
0
        /// <summary>Controls the addition of several variables to the especified patches</summary>
        /// <param name="PatchesToAdd">The list of patches to which the stuff will be added</param>
        /// <param name="StuffToAdd">The values of the variables to add (supplied as deltas)</param>
        private void AddStuffToPatches(List <int> PatchesToAdd, AddSoilCNPatchType StuffToAdd)
        {
            // Data passed from OnAddSoilCNPatch event - these are all considered deltas:
            //.Water: amount of water to add per layer (mm), not handled here
            //.Urea: amount of urea to add per layer (kgN/ha)
            //.Urea: amount of urea to add (per layer) - Do we need other N forms?
            //.NH4: amount of ammonium to add per layer (kgN/ha)
            //.NO3: amount of nitrate to add per layer (kgN/ha)
            //.POX: amount of POx to add per layer (kgP/ha)
            //.SO4: amount of SO4 to add per layer (kgS/ha)
            //.Ashalk: ash amount to add per layer (mol/ha)
            //.FOM_C: amount of carbon in fom (all pools) to add per layer (kgC/ha)  -  If present, the pools will be ignored
            //.FOM_C_Pool1: amount of carbon in fom_pool1 to add per layer (kgC/ha)
            //.FOM_C_Pool2: amount of carbon in fom_pool2 to add per layer (kgC/ha)
            //.FOM_C_Pool3: amount of carbon in fom_pool3 to add per layer (kgC/ha)
            //.FOM_N: amount of nitrogen in fom to add per layer (kgN/ha)

            for (int i = PatchesToAdd.Count - 1; i >= 0; i--)
            {
                if ((StuffToAdd.Urea != null) && (StuffToAdd.Urea.Sum() > 0))
                {
                    Patch[PatchesToAdd[i]].dlt_urea = StuffToAdd.Urea;
                }
                if ((StuffToAdd.NH4 != null) && (StuffToAdd.NH4.Sum() > 0))
                {
                    Patch[PatchesToAdd[i]].dlt_nh4 = StuffToAdd.NH4;
                }
                if ((StuffToAdd.NO3 != null) && (StuffToAdd.NO3.Sum() > 0))
                {
                    Patch[PatchesToAdd[i]].dlt_no3 = StuffToAdd.NO3;
                }
                if ((StuffToAdd.FOM_C != null) && (StuffToAdd.FOM_C.Sum() > 0))
                {
                    Patch[PatchesToAdd[i]].dlt_org_c_pool1 = StuffToAdd.FOM_C;
                    Patch[PatchesToAdd[i]].dlt_org_c_pool2 = StuffToAdd.FOM_C;
                    Patch[PatchesToAdd[i]].dlt_org_c_pool3 = StuffToAdd.FOM_C;
                }
                else
                {
                    if ((StuffToAdd.FOM_C != null) && (StuffToAdd.FOM_C_pool1.Sum() > 0))
                    {
                        Patch[PatchesToAdd[i]].dlt_org_c_pool1 = StuffToAdd.FOM_C_pool1;
                    }
                    if ((StuffToAdd.FOM_C != null) && (StuffToAdd.FOM_C_pool2.Sum() > 0))
                    {
                        Patch[PatchesToAdd[i]].dlt_org_c_pool2 = StuffToAdd.FOM_C_pool2;
                    }
                    if ((StuffToAdd.FOM_C != null) && (StuffToAdd.FOM_C_pool3.Sum() > 0))
                    {
                        Patch[PatchesToAdd[i]].dlt_org_c_pool3 = StuffToAdd.FOM_C_pool3;
                    }
                }

                if ((StuffToAdd.FOM_N != null) && (StuffToAdd.FOM_N.Sum() > 0))
                {
                    Patch[PatchesToAdd[i]].dlt_org_n = StuffToAdd.FOM_N;
                }
            }
        }
Пример #2
0
        /// <summary>Handles the addition of new CNPatches</summary>
        /// <param name="PatchtoAdd">Patch data</param>
        /// <exception cref="System.Exception"> Cannot create new patch, area of selected patches ( + AreaAffected.ToString(#0.00#)
        ///                                    + ) is smaller than area of new patch( + PatchtoAdd.AreaFraction.ToString(#0.00#) + )</exception>
        private void AddNewCNPatch(AddSoilCNPatchType PatchtoAdd)
        {
            // Data passed from OnAddSoilCNPatch event:
            //.Sender: the name of the module that raised this event
            //.DepositionType: the type of deposition:
            //  - ToAllPaddock: No patch is created, add stuff as given to all patches. It is the default;
            //  - ToSpecificPatch: No patch is created, add stuff to given patches;
            //		(recipient patch is given using its index or name; if not supplied, defaults to homogeneous)
            //  - ToNewPatch: create new patch based on an existing patch, add stuff to created patch;
            //		- recipient or base patch is given using index or name; if not supplied, new patch will be based on the base/Patch[0];
            //      - patches are only created is area is larger than a minimum (minPatchArea);
            //      - new areas are proportional to existing patches;
            //  - NewOverlappingPatches: create new patch(es), these overlap with all existing patches, add stuff to created patches;
            //		(new patches are created only if their area is larger than a minimum (minPatchArea))
            //.AffectedPatches_id (AffectedPatchesByIndex): the index of the existing patches to which urine will be added
            //.AffectedPatches_nm (AffectedPatchesByName): the name of the existing patches to which urine will be added
            //.AreaFraction: the relative area of the patch (0-1)
            //.PatchName: the name(s) of the patch)es) being created

            List<int> PatchesToDelete = new List<int>();
            List<int> PatchesJustAdded = new List<int>();

            // get the list of id's of patches which are affected by this addition, and the area affected
            int[] PatchIDs = new int[1];
            double AreaAffected = 0;
            if (PatchtoAdd.DepositionType.ToLower() == "ToNewPatch".ToLower())
            {  // check which patches are affected
                PatchIDs = CheckPatchIDs(PatchtoAdd.AffectedPatches_id, PatchtoAdd.AffectedPatches_nm);
                for (int i = 0; i < PatchIDs.Length; i++)
                    AreaAffected += Patch[PatchIDs[i]].RelativeArea;
            }
            else if (PatchtoAdd.DepositionType.ToLower() == "NewOverlappingPatches".ToLower())
            {  // all patches are affected
                PatchIDs = new int[Patch.Count];
                for (int k = 0; k < Patch.Count; k++)
                    PatchIDs[k] = k;
                AreaAffected = 1.0;
            }

            // check that total area of affected patches is larger than new patch area
            if (AreaAffected < PatchtoAdd.AreaFraction)
            {
                // Existing area is smaller than new patch area, cannot continue
                throw new Exception(" Cannot create new patch, area of selected patches (" + AreaAffected.ToString("#0.00#")
                                   + ") is smaller than area of new patch(" + PatchtoAdd.AreaFraction.ToString("#0.00#") + ")");
            }
            else
            {  // check the area for each patch
                for (int i = 0; i < PatchIDs.Length; i++)
                {
                    double OldPatch_OldArea = Patch[PatchIDs[i]].RelativeArea;
                    double NewPatch_NewArea = PatchtoAdd.AreaFraction * (OldPatch_OldArea / AreaAffected);
                    double OldPatch_NewArea = OldPatch_OldArea - NewPatch_NewArea;
                    if (NewPatch_NewArea < MinimumPatchArea)
                    {  // area to create is too small, patch will not be created
                        Summary.WriteMessage(this, "   attempt to create a new patch with area too small or negative ("
                            + NewPatch_NewArea.ToString("#0.00#") + "). The patch will not be created.");
                    }
                    else if (OldPatch_NewArea < MinimumPatchArea)
                    {  // remaining area is too small or negative, patch will be created but old one will be deleted
                        Summary.WriteMessage(this, " attempt to set the area of existing patch(" + PatchIDs[i].ToString()
                            + ") to a value too small or negative (" + OldPatch_NewArea.ToString("#0.00#")
                            + "). The patch will be eliminated.");

                        // mark old patch for deletion
                        PatchesToDelete.Add(PatchIDs[i]);

                        // create new patch based on old one - uses SplitPatch, the original one will be deleted later
                        SplitPatch(PatchIDs[i]);
                        int k = Patch.Count - 1;
                        if (PatchtoAdd.AreaFraction > 0)
                        {  // a name was supplied
                            Patch[k].PatchName = PatchtoAdd.AreaFraction + "_" + i.ToString();
                        }
                        else
                        {  // use default naming
                            Patch[k].PatchName = "Patch" + k.ToString();
                        }
                        PatchesJustAdded.Add(k);
                    }
                    else
                    {
                        // create new patch by spliting an existing one
                        SplitPatch(PatchIDs[i]);
                        Patch[PatchIDs[i]].RelativeArea = OldPatch_NewArea;
                        int k = Patch.Count - 1;
                        Patch[k].RelativeArea = NewPatch_NewArea;
                        if (PatchtoAdd.PatchName.Length > 0)
                        {  // a name was supplied
                            Patch[k].PatchName = PatchtoAdd.AreaFraction + "_" + i.ToString();
                        }
                        else
                        {  // use default naming
                            Patch[k].PatchName = "Patch" + k.ToString();
                        }
                        PatchesJustAdded.Add(k);
                        Summary.WriteMessage(this, " create new patch, with area = " + NewPatch_NewArea.ToString("#0.00#") + ", based on existing patch("
                            + PatchIDs[i].ToString() + ") - Old area = " + OldPatch_OldArea.ToString("#0.00#") + ", new area = "
                            + OldPatch_NewArea.ToString("#0.00#"));
                    }
                }
            }

            // add the stuff to patches just created
            AddStuffToPatches(PatchesJustAdded, PatchtoAdd);

            // delete the patches in excess
            if (PatchesToDelete.Count > 0)
                DeletePatches(PatchesToDelete);
        }
Пример #3
0
        /// <summary>Controls the addition of several variables to the especified patches</summary>
        /// <param name="PatchesToAdd">The list of patches to which the stuff will be added</param>
        /// <param name="StuffToAdd">The values of the variables to add (supplied as deltas)</param>
        private void AddStuffToPatches(List<int> PatchesToAdd, AddSoilCNPatchType StuffToAdd)
        {
            // Data passed from OnAddSoilCNPatch event - these are all considered deltas:
            //.Water: amount of water to add per layer (mm), not handled here
            //.Urea: amount of urea to add per layer (kgN/ha)
            //.Urea: amount of urea to add (per layer) - Do we need other N forms?
            //.NH4: amount of ammonium to add per layer (kgN/ha)
            //.NO3: amount of nitrate to add per layer (kgN/ha)
            //.POX: amount of POx to add per layer (kgP/ha)
            //.SO4: amount of SO4 to add per layer (kgS/ha)
            //.Ashalk: ash amount to add per layer (mol/ha)
            //.FOM_C: amount of carbon in fom (all pools) to add per layer (kgC/ha)  -  If present, the pools will be ignored
            //.FOM_C_Pool1: amount of carbon in fom_pool1 to add per layer (kgC/ha)
            //.FOM_C_Pool2: amount of carbon in fom_pool2 to add per layer (kgC/ha)
            //.FOM_C_Pool3: amount of carbon in fom_pool3 to add per layer (kgC/ha)
            //.FOM_N: amount of nitrogen in fom to add per layer (kgN/ha)

            for (int i = PatchesToAdd.Count - 1; i >= 0; i--)
            {
                if ((StuffToAdd.Urea != null) && (StuffToAdd.Urea.Sum() > 0))
                    Patch[PatchesToAdd[i]].dlt_urea = StuffToAdd.Urea;
                if ((StuffToAdd.NH4 != null) && (StuffToAdd.NH4.Sum() > 0))
                    Patch[PatchesToAdd[i]].dlt_nh4 = StuffToAdd.NH4;
                if ((StuffToAdd.NO3 != null) && (StuffToAdd.NO3.Sum() > 0))
                    Patch[PatchesToAdd[i]].dlt_no3 = StuffToAdd.NO3;
                if ((StuffToAdd.FOM_C != null) && (StuffToAdd.FOM_C.Sum() > 0))
                {
                    Patch[PatchesToAdd[i]].dlt_org_c_pool1 = StuffToAdd.FOM_C;
                    Patch[PatchesToAdd[i]].dlt_org_c_pool2 = StuffToAdd.FOM_C;
                    Patch[PatchesToAdd[i]].dlt_org_c_pool3 = StuffToAdd.FOM_C;
                }
                else
                {
                    if ((StuffToAdd.FOM_C != null) && (StuffToAdd.FOM_C_pool1.Sum() > 0))
                        Patch[PatchesToAdd[i]].dlt_org_c_pool1 = StuffToAdd.FOM_C_pool1;
                    if ((StuffToAdd.FOM_C != null) && (StuffToAdd.FOM_C_pool2.Sum() > 0))
                        Patch[PatchesToAdd[i]].dlt_org_c_pool2 = StuffToAdd.FOM_C_pool2;
                    if ((StuffToAdd.FOM_C != null) && (StuffToAdd.FOM_C_pool3.Sum() > 0))
                        Patch[PatchesToAdd[i]].dlt_org_c_pool3 = StuffToAdd.FOM_C_pool3;
                }

                if ((StuffToAdd.FOM_N != null) && (StuffToAdd.FOM_N.Sum() > 0))
                    Patch[PatchesToAdd[i]].dlt_org_n = StuffToAdd.FOM_N;
            }
        }
Пример #4
0
        private void OnAddSoilCNPatch(AddSoilCNPatchType PatchtoAdd)
        {
            // data passed with this event:
            //.Sender: the name of the module that raised this event
            //.DepositionType: the type of deposition:
            //  - ToAllPaddock: No patch is created, add stuff as given to all patches. It is the default;
            //  - ToSpecificPatch: No patch is created, add stuff to given patches;
            //		(recipient patch is given using its index or name; if not supplied, defaults to homogeneous)
            //  - ToNewPatch: create new patch based on an existing patch, add stuff to created patch;
            //		- recipient or base patch is given using index or name; if not supplied, new patch will be based on the base/Patch[0];
            //      - patches are only created is area is larger than a minimum (minPatchArea);
            //      - new areas are proportional to existing patches;
            //  - NewOverlappingPatches: create new patch(es), these overlap with all existing patches, add stuff to created patches;
            //		(new patches are created only if their area is larger than a minimum (minPatchArea))
            //.AffectedPatches_id (AffectedPatchesByIndex): the index of the existing patches to which urine will be added
            //.AffectedPatches_nm (AffectedPatchesByName): the name of the existing patches to which urine will be added
            //.AreaFraction: the relative area of the patch (0-1)
            //.PatchName: the name(s) of the patch)es) being created
            //.Water: amount of water to add per layer (mm), not handled here
            //.Urea: amount of urea to add per layer (kgN/ha)
            //.Urea: amount of urea to add (per layer) - Do we need other N forms?
            //.NH4: amount of ammonium to add per layer (kgN/ha)
            //.NO3: amount of nitrate to add per layer (kgN/ha)
            //.POX: amount of POx to add per layer (kgP/ha)
            //.SO4: amount of SO4 to add per layer (kgS/ha)
            //.Ashalk: ash amount to add per layer (mol/ha)
            //.FOM_C: amount of carbon in fom (all pools) to add per layer (kgC/ha)  - if present, the entry for pools will be ignored
            //.FOM_C_pool1: amount of carbon in fom_pool1 to add per layer (kgC/ha)
            //.FOM_C_pool2: amount of carbon in fom_pool2 to add per layer (kgC/ha)
            //.FOM_C_pool3: amount of carbon in fom_pool3 to add per layer (kgC/ha)
            //.FOM_N.: amount of nitrogen in fom to add per layer (kgN/ha)

            List <int> PatchesToAddStuff = new List <int>();

            if ((PatchtoAdd.DepositionType.ToLower() == "ToNewPatch".ToLower()) ||
                (PatchtoAdd.DepositionType.ToLower() == "NewOverlappingPatches".ToLower()))
            { // New patch(es) will be added
                AddNewCNPatch(PatchtoAdd);
            }
            else if (PatchtoAdd.DepositionType.ToLower() == "ToSpecificPatch".ToLower())
            {  // add stuff to selected patches, no new patch will be created
                // 1. get the list of patch id's to which stuff will be added
                int[] PatchIDs = CheckPatchIDs(PatchtoAdd.AffectedPatches_id, PatchtoAdd.AffectedPatches_nm);
                // 2. create the list of patches receiving stuff
                for (int i = 0; i < PatchIDs.Length; i++)
                {
                    PatchesToAddStuff.Add(PatchIDs[i]);
                }
                // 3. add the stuff to patches listed
                AddStuffToPatches(PatchesToAddStuff, PatchtoAdd);
            }
            else
            {  // add urine to all existing patches, no new patch will be created
                // 1. create the list of patches receiving stuff (all)
                for (int k = 0; k < Patch.Count; k++)
                {
                    PatchesToAddStuff.Add(k);
                }
                // 2. add the stuff to patches listed
                AddStuffToPatches(PatchesToAddStuff, PatchtoAdd);
            }
        }
Пример #5
0
        private void OnAddSoilCNPatch(AddSoilCNPatchType PatchtoAdd)
        {
            // data passed with this event:
            //.Sender: the name of the module that raised this event
            //.DepositionType: the type of deposition:
            //  - ToAllPaddock: No patch is created, add stuff as given to all patches. It is the default;
            //  - ToSpecificPatch: No patch is created, add stuff to given patches;
            //		(recipient patch is given using its index or name; if not supplied, defaults to homogeneous)
            //  - ToNewPatch: create new patch based on an existing patch, add stuff to created patch;
            //		- recipient or base patch is given using index or name; if not supplied, new patch will be based on the base/Patch[0];
            //      - patches are only created is area is larger than a minimum (minPatchArea);
            //      - new areas are proportional to existing patches;
            //  - NewOverlappingPatches: create new patch(es), these overlap with all existing patches, add stuff to created patches;
            //		(new patches are created only if their area is larger than a minimum (minPatchArea))
            //.AffectedPatches_id (AffectedPatchesByIndex): the index of the existing patches to which urine will be added
            //.AffectedPatches_nm (AffectedPatchesByName): the name of the existing patches to which urine will be added
            //.AreaFraction: the relative area of the patch (0-1)
            //.PatchName: the name(s) of the patch)es) being created
            //.Water: amount of water to add per layer (mm), not handled here
            //.Urea: amount of urea to add per layer (kgN/ha)
            //.Urea: amount of urea to add (per layer) - Do we need other N forms?
            //.NH4: amount of ammonium to add per layer (kgN/ha)
            //.NO3: amount of nitrate to add per layer (kgN/ha)
            //.POX: amount of POx to add per layer (kgP/ha)
            //.SO4: amount of SO4 to add per layer (kgS/ha)
            //.Ashalk: ash amount to add per layer (mol/ha)
            //.FOM_C: amount of carbon in fom (all pools) to add per layer (kgC/ha)  - if present, the entry for pools will be ignored
            //.FOM_C_pool1: amount of carbon in fom_pool1 to add per layer (kgC/ha)
            //.FOM_C_pool2: amount of carbon in fom_pool2 to add per layer (kgC/ha)
            //.FOM_C_pool3: amount of carbon in fom_pool3 to add per layer (kgC/ha)
            //.FOM_N.: amount of nitrogen in fom to add per layer (kgN/ha)

            List<int> PatchesToAddStuff = new List<int>();

            if ((PatchtoAdd.DepositionType.ToLower() == "ToNewPatch".ToLower()) ||
                (PatchtoAdd.DepositionType.ToLower() == "NewOverlappingPatches".ToLower()))
            { // New patch(es) will be added
                AddNewCNPatch(PatchtoAdd);
            }
            else if (PatchtoAdd.DepositionType.ToLower() == "ToSpecificPatch".ToLower())
            {  // add stuff to selected patches, no new patch will be created

                // 1. get the list of patch id's to which stuff will be added
                int[] PatchIDs = CheckPatchIDs(PatchtoAdd.AffectedPatches_id, PatchtoAdd.AffectedPatches_nm);
                // 2. create the list of patches receiving stuff
                for (int i = 0; i < PatchIDs.Length; i++)
                    PatchesToAddStuff.Add(PatchIDs[i]);
                // 3. add the stuff to patches listed
                AddStuffToPatches(PatchesToAddStuff, PatchtoAdd);
            }
            else
            {  // add urine to all existing patches, no new patch will be created

                // 1. create the list of patches receiving stuff (all)
                for (int k = 0; k < Patch.Count; k++)
                    PatchesToAddStuff.Add(k);
                // 2. add the stuff to patches listed
                AddStuffToPatches(PatchesToAddStuff, PatchtoAdd);
            }
        }
Пример #6
0
        /// <summary>
        /// Add a new patch.
        /// </summary>
        /// <param name="patch">Details of the patch to add.</param>
        public void Add(AddSoilCNPatchType patch)
        {
            AddSoilCNPatchwithFOMType PatchtoAdd = new AddSoilCNPatchwithFOMType();

            PatchtoAdd.Sender             = patch.Sender;
            PatchtoAdd.SuppressMessages   = patch.SuppressMessages;
            PatchtoAdd.DepositionType     = patch.DepositionType;
            PatchtoAdd.AreaNewPatch       = patch.AreaFraction;
            PatchtoAdd.AffectedPatches_id = patch.AffectedPatches_id;
            PatchtoAdd.AffectedPatches_nm = patch.AffectedPatches_nm;
            PatchtoAdd.Urea = patch.Urea;
            PatchtoAdd.NH4  = patch.NH4;
            PatchtoAdd.NO3  = patch.NO3;

            bool isDataOK = true;

            if (PatchtoAdd.DepositionType == DepositionTypeEnum.ToNewPatch)
            {
                if (PatchtoAdd.AffectedPatches_id.Length == 0 && PatchtoAdd.AffectedPatches_nm.Length == 0)
                {
                    summary.WriteMessage(this, " Command to add patch did not supply a valid patch to be used as base for the new one. Command will be ignored.");
                    isDataOK = false;
                }
                else if (PatchtoAdd.AreaNewPatch <= 0.0)
                {
                    summary.WriteMessage(this, " Command to add patch did not supply a valid area fraction for the new patch. Command will be ignored.");
                    isDataOK = false;
                }
            }
            else if (PatchtoAdd.DepositionType == DepositionTypeEnum.ToSpecificPatch)
            {
                if (PatchtoAdd.AffectedPatches_id.Length == 0 && PatchtoAdd.AffectedPatches_nm.Length == 0)
                {
                    summary.WriteMessage(this, " Command to add patch did not supply a valid patch to be used as base for the new one. Command will be ignored.");
                    isDataOK = false;
                }
            }
            else if (PatchtoAdd.DepositionType == DepositionTypeEnum.NewOverlappingPatches)
            {
                if (PatchtoAdd.AreaNewPatch <= 0.0)
                {
                    summary.WriteMessage(this, " Command to add patch did not supply a valid area fraction for the new patch. Command will be ignored.");
                    isDataOK = false;
                }
            }
            else if (PatchtoAdd.DepositionType == DepositionTypeEnum.ToAllPaddock)
            {
                // assume stuff is added homogeneously and with no patch creation, thus no factors are actually required
            }
            else
            {
                summary.WriteMessage(this, " Command to add patch did not supply a valid DepositionType. Command will be ignored.");
                isDataOK = false;
            }

            if (isDataOK)
            {
                List <int> PatchesToAddStuff;

                if ((PatchtoAdd.DepositionType == DepositionTypeEnum.ToNewPatch) ||
                    (PatchtoAdd.DepositionType == DepositionTypeEnum.NewOverlappingPatches))
                { // New patch(es) will be added
                    AddNewCNPatch(PatchtoAdd);
                }
                else if (PatchtoAdd.DepositionType == DepositionTypeEnum.ToSpecificPatch)
                {  // add stuff to selected patches, no new patch will be created
                    // 1. get the list of patch id's to which stuff will be added
                    PatchesToAddStuff = CheckPatchIDs(PatchtoAdd.AffectedPatches_id, PatchtoAdd.AffectedPatches_nm);
                    // 2. add the stuff to patches listed
                    AddStuffToPatches(PatchesToAddStuff, PatchtoAdd);
                }
                else
                {  // add stuff to all existing patches, no new patch will be created
                   // 1. create the list of patches receiving stuff (all)
                    PatchesToAddStuff = new List <int>();
                    for (int k = 0; k < patches.Count; k++)
                    {
                        PatchesToAddStuff.Add(k);
                    }
                    // 2. add the stuff to patches listed
                    AddStuffToPatches(PatchesToAddStuff, PatchtoAdd);
                }
            }
        }
Пример #7
0
        /// <summary>Handles the addition of new CNPatches</summary>
        /// <param name="PatchtoAdd">Patch data</param>
        /// <exception cref="System.Exception"> Cannot create new patch, area of selected patches ( + AreaAffected.ToString(#0.00#)
        ///                                    + ) is smaller than area of new patch( + PatchtoAdd.AreaFraction.ToString(#0.00#) + )</exception>
        private void AddNewCNPatch(AddSoilCNPatchType PatchtoAdd)
        {
            // Data passed from OnAddSoilCNPatch event:
            //.Sender: the name of the module that raised this event
            //.DepositionType: the type of deposition:
            //  - ToAllPaddock: No patch is created, add stuff as given to all patches. It is the default;
            //  - ToSpecificPatch: No patch is created, add stuff to given patches;
            //		(recipient patch is given using its index or name; if not supplied, defaults to homogeneous)
            //  - ToNewPatch: create new patch based on an existing patch, add stuff to created patch;
            //		- recipient or base patch is given using index or name; if not supplied, new patch will be based on the base/Patch[0];
            //      - patches are only created is area is larger than a minimum (minPatchArea);
            //      - new areas are proportional to existing patches;
            //  - NewOverlappingPatches: create new patch(es), these overlap with all existing patches, add stuff to created patches;
            //		(new patches are created only if their area is larger than a minimum (minPatchArea))
            //.AffectedPatches_id (AffectedPatchesByIndex): the index of the existing patches to which urine will be added
            //.AffectedPatches_nm (AffectedPatchesByName): the name of the existing patches to which urine will be added
            //.AreaFraction: the relative area of the patch (0-1)
            //.PatchName: the name(s) of the patch)es) being created

            List <int> PatchesToDelete  = new List <int>();
            List <int> PatchesJustAdded = new List <int>();


            // get the list of id's of patches which are affected by this addition, and the area affected
            int[]  PatchIDs     = new int[1];
            double AreaAffected = 0;

            if (PatchtoAdd.DepositionType.ToLower() == "ToNewPatch".ToLower())
            {  // check which patches are affected
                PatchIDs = CheckPatchIDs(PatchtoAdd.AffectedPatches_id, PatchtoAdd.AffectedPatches_nm);
                for (int i = 0; i < PatchIDs.Length; i++)
                {
                    AreaAffected += Patch[PatchIDs[i]].RelativeArea;
                }
            }
            else if (PatchtoAdd.DepositionType.ToLower() == "NewOverlappingPatches".ToLower())
            {  // all patches are affected
                PatchIDs = new int[Patch.Count];
                for (int k = 0; k < Patch.Count; k++)
                {
                    PatchIDs[k] = k;
                }
                AreaAffected = 1.0;
            }

            // check that total area of affected patches is larger than new patch area
            if (AreaAffected < PatchtoAdd.AreaFraction)
            {
                // Existing area is smaller than new patch area, cannot continue
                throw new Exception(" Cannot create new patch, area of selected patches (" + AreaAffected.ToString("#0.00#")
                                    + ") is smaller than area of new patch(" + PatchtoAdd.AreaFraction.ToString("#0.00#") + ")");
            }
            else
            {  // check the area for each patch
                for (int i = 0; i < PatchIDs.Length; i++)
                {
                    double OldPatch_OldArea = Patch[PatchIDs[i]].RelativeArea;
                    double NewPatch_NewArea = PatchtoAdd.AreaFraction * (OldPatch_OldArea / AreaAffected);
                    double OldPatch_NewArea = OldPatch_OldArea - NewPatch_NewArea;
                    if (NewPatch_NewArea < MinimumPatchArea)
                    {  // area to create is too small, patch will not be created
                        Summary.WriteMessage(this, "   attempt to create a new patch with area too small or negative ("
                                             + NewPatch_NewArea.ToString("#0.00#") + "). The patch will not be created.");
                    }
                    else if (OldPatch_NewArea < MinimumPatchArea)
                    {  // remaining area is too small or negative, patch will be created but old one will be deleted
                        Summary.WriteMessage(this, " attempt to set the area of existing patch(" + PatchIDs[i].ToString()
                                             + ") to a value too small or negative (" + OldPatch_NewArea.ToString("#0.00#")
                                             + "). The patch will be eliminated.");

                        // mark old patch for deletion
                        PatchesToDelete.Add(PatchIDs[i]);

                        // create new patch based on old one - uses SplitPatch, the original one will be deleted later
                        SplitPatch(PatchIDs[i]);
                        int k = Patch.Count - 1;
                        if (PatchtoAdd.AreaFraction > 0)
                        {  // a name was supplied
                            Patch[k].PatchName = PatchtoAdd.AreaFraction + "_" + i.ToString();
                        }
                        else
                        {  // use default naming
                            Patch[k].PatchName = "Patch" + k.ToString();
                        }
                        PatchesJustAdded.Add(k);
                    }
                    else
                    {
                        // create new patch by spliting an existing one
                        SplitPatch(PatchIDs[i]);
                        Patch[PatchIDs[i]].RelativeArea = OldPatch_NewArea;
                        int k = Patch.Count - 1;
                        Patch[k].RelativeArea = NewPatch_NewArea;
                        if (PatchtoAdd.PatchName.Length > 0)
                        {  // a name was supplied
                            Patch[k].PatchName = PatchtoAdd.AreaFraction + "_" + i.ToString();
                        }
                        else
                        {  // use default naming
                            Patch[k].PatchName = "Patch" + k.ToString();
                        }
                        PatchesJustAdded.Add(k);
                        Summary.WriteMessage(this, " create new patch, with area = " + NewPatch_NewArea.ToString("#0.00#") + ", based on existing patch("
                                             + PatchIDs[i].ToString() + ") - Old area = " + OldPatch_OldArea.ToString("#0.00#") + ", new area = "
                                             + OldPatch_NewArea.ToString("#0.00#"));
                    }
                }
            }

            // add the stuff to patches just created
            AddStuffToPatches(PatchesJustAdded, PatchtoAdd);

            // delete the patches in excess
            if (PatchesToDelete.Count > 0)
            {
                DeletePatches(PatchesToDelete);
            }
        }