示例#1
0
        /// <summary>Check general initialisation parameters, and let user know of some settings</summary>
        /// <exception cref="System.Exception">
        /// Number of \fract_carb\ different to \fom_type\
        /// or
        /// Number of \fract_cell\ different to \fom_type\
        /// or
        /// Number of \fract_lign\ different to \fom_type\
        /// </exception>
        private void CheckParams()
        {
            SoilCNParameterSet = SoilCNParameterSet.Trim();
            NPartitionApproach = NPartitionApproach.Trim();

            // check whether ph is supplied, use a default if not - might be better to throw an exception?
            use_external_ph = (ph != null);
            if (!use_external_ph)
            {
                for (int layer = 0; layer < dlayer.Length; ++layer)
                {
                    ph[layer] = 6.0; // ph_ini
                }
            }

            // convert minimum values for nh4 and no3 from ppm to kg/ha
            double convFact = 0;

            for (int layer = 0; layer < dlayer.Length; ++layer)
            {
                convFact        = convFactor_kgha2ppm(layer);
                urea_min[layer] = MathUtilities.Divide(ureappm_min, convFact, 0.0);
                nh4_min[layer]  = MathUtilities.Divide(nh4ppm_min, convFact, 0.0);
                no3_min[layer]  = MathUtilities.Divide(no3ppm_min, convFact, 0.0);
            }

            // Check if all fom values have been supplied
            if (num_fom_types != fract_carb.Length)
            {
                throw new Exception("Number of \"fract_carb\" different to \"fom_type\"");
            }
            if (num_fom_types != fract_cell.Length)
            {
                throw new Exception("Number of \"fract_cell\" different to \"fom_type\"");
            }
            if (num_fom_types != fract_lign.Length)
            {
                throw new Exception("Number of \"fract_lign\" different to \"fom_type\"");
            }

            // Check if all C:N values have been supplied. If not use average C:N ratio in all pools
            if (fomPoolsCNratio == null || fomPoolsCNratio.Length < 3)
            {
                fomPoolsCNratio = new double[3];
                for (int i = 0; i < 3; i++)
                {
                    fomPoolsCNratio[i] = iniFomCNratio;
                }
            }

            // Check if initial fom depth has been supplied, if not assume that initial fom is distributed over the whole profile
            if (iniFomDepth == 0.0)
            {
                for (int i = 0; i < dlayer.Length; ++i)
                {
                    iniFomDepth += dlayer[i];
                }
            }
        }
示例#2
0
        private void OnNitrogenChanged(NitrogenChangedType NitrogenChanges)
        {
            // Note:
            //     Send deltas to each patch, if delta comes from soil or plant then the values are modified (partioned)
            //      based on N content. If sender is any other module then values are passed to patches as they come

            string module = NitrogenChanges.SenderType.ToLower();

            if ((Patch.Count > 1) && (module == "WaterModule".ToLower()) || (module == "Plant".ToLower()))
            {
                // values supplied by a module from which a different treatment for each patch is required,
                //  they will be partitioned according to the N content in each patch, following:
                //  - If module is Plant (uptake): partition is based on the relative concentration, at each layer, of all patches
                //  - If module is WaterModule (leaching):
                //        . if is removal (negative): partition is equal to a plant uptake
                //        . if is incoming leaching: partition is based on relative concentration on the layer and above

                // 1- consider urea:
                if (hasValues(NitrogenChanges.DeltaUrea, EPSILON))
                {
                    // 1.1-send incoming dlt to be partitioned amongst patches
                    double[][] newDelta = partitionDelta(NitrogenChanges.DeltaUrea, "urea", NPartitionApproach.ToLower());
                    // 1.2- send dlt's to each patch
                    for (int k = 0; k < Patch.Count; k++)
                    {
                        Patch[k].dlt_urea = newDelta[k];
                    }
                }

                // 2- consider nh4:
                if (hasValues(NitrogenChanges.DeltaNH4, EPSILON))
                {
                    // 2.1- send incoming dlt to be partitioned amongst patches
                    double[][] newDelta = partitionDelta(NitrogenChanges.DeltaNH4, "NH4", NPartitionApproach.ToLower());
                    // 2.2- send dlt's to each patch
                    for (int k = 0; k < Patch.Count; k++)
                    {
                        Patch[k].dlt_nh4 = newDelta[k];
                    }
                }

                // 3- consider no3:
                if (hasValues(NitrogenChanges.DeltaNO3, EPSILON))
                {
                    // 3.1- send incoming dlt to be partitioned amongst patches
                    double[][] newDelta = partitionDelta(NitrogenChanges.DeltaNO3, "NO3", NPartitionApproach.ToLower());
                    // 3.2- send dlt's to each patch
                    for (int k = 0; k < Patch.Count; k++)
                    {
                        Patch[k].dlt_no3 = newDelta[k];
                    }
                }
            }
            else
            {
                // values will passed to patches as they come
                for (int k = 0; k < Patch.Count; k++)
                {
                    Patch[k].dlt_urea = NitrogenChanges.DeltaUrea;
                    Patch[k].dlt_nh4  = NitrogenChanges.DeltaNH4;
                    Patch[k].dlt_no3  = NitrogenChanges.DeltaNO3;
                }
            }
        }