예제 #1
0
        /// <summary>
        /// advanced swapping function. It will swap a certain amount, then skip the same amount and then swap again. Untill stop has been reached
        /// </summary>
        /// <param name="FieldPlanRotationListTmp"> a array of FieldPlanRotation</param>
        /// <param name="arreyB">array of doubles</param>
        /// <param name="start">the starting place in those 2 arrays that will be swapped</param>
        /// <param name="stop">the starting place in those 2 arrays that will be swapped</param>
        /// <param name="numbers">The numbers of double/FieldPlanRotation that will be swapped before the next skipping</param>
        public void advancedSwap(ref FieldPlanRotation[] FieldPlanRotationListTmp, ref double[] arreyB, int start, int stop, int numbers)
        {
            if (arreyB.Count() < start || arreyB.Count() < stop || start > stop || (start + stop) < numbers || FieldPlanRotationListTmp.Count() != arreyB.Count())
            {
                Console.WriteLine("something is wrong");
            }

            double[]            tmpDouble           = new double[numbers];
            FieldPlanRotation[] tmpFieldPlanRotatio = new FieldPlanRotation[numbers];
            for (int k = start; k < stop; k = k + numbers * 2)
            {
                start = k;
                for (int i = start; i < (numbers + k); i = i + numbers)
                {
                    for (int j = 0; j < numbers; j++)
                    {
                        tmpDouble[j]           = arreyB[j + i];
                        tmpFieldPlanRotatio[j] = FieldPlanRotationListTmp[j + i];;
                    }
                    for (int j = 0; j < numbers; j++)
                    {
                        arreyB[start + numbers - j - 1] = tmpDouble[j];
                        FieldPlanRotationListTmp[start + numbers - j - 1] = tmpFieldPlanRotatio[j];
                    }
                }
            }
        }
예제 #2
0
        public FieldPlanRotation copyItem()
        {
            FieldPlanRotation newItem = new FieldPlanRotation(this.ID, this.PreviousCrop, this.PreCropOriginalID, this.PreCrop_afterCrop, this.PreCropSecondCrop, this.Crop, this.CropAfterCrop, this.OrganicFertilizer, this.StrawUseType, this.SecondCropID, this.PrePreCropID, this.area, this.UseGrazing, this.SalePart, this.CropFixation, this.SecondCropFixation, this.CropCoeff, this.PreCropCoeff, this.Runoff, this.PotentialDMDeposition, this.FieldNNeed, this.CropYield_N, this.SecondCropYield_N, this.StrawYield_N, this.StrawRemoved_N, this.StrawDMRemoved, this.soilType, this.DeliveryList, this.CropUtilList, this.LossList);

            return(newItem);
        }
예제 #3
0
        private void FillArrays(Scenario scenario, decimal NPercent, List <BoughtManure> ManureList, int ManureVersion)
        {
            double[]            ArrA;//Den organiske og mineralske gødning der skal fordeles ganget med udnyttelsesprocenten
            double[]            ArrManureUtil;
            int[]               ArrSalesOrderList;
            decimal[][]         ArrAmmoniumAndConversion;
            int[]               ArrSoilType;
            double[][]          ArrDelivery;
            FieldPlanRotation[] ArrBHelp = new FieldPlanRotation[numberOfFieldPlanRotations]; //Gødningsbehovet NNeed for hver record i FieldPlanRotation skal lægge records fra alle rotations sammen i et array
            double[]            ArrB     = new double[numberOfFieldPlanRotations];            //Gødningsbehovet NNeed for hver record i FieldPlanRotation skal lægge records fra alle rotations sammen i et array
            double[][]          ObjectCoeff;                                                  //dimension ArrB * dimension ArrA
            double[][]          ObjectCoeff1;                                                 //dimension ArrA * dimension ArrB
            double[][]          ArrResult;                                                    //dimension ArrA * dimension ArrB
            int     n                 = 0;
            decimal DE_ha             = 0;
            decimal totalArea         = 0;
            decimal Bought_Amount     = 0;
            double  BoughtFertilizer  = 0;
            decimal GrazingUtilDegree = 0;

            sqlconnstr = cfg.GetValue("sqlConnectionStringPublic", typeof(string)).ToString();
            sqlconn    = null;
            try
            {
                sqlconn = new SqlConnection(sqlconnstr);
                sqlconn.Open();
            }
            catch (Exception e)
            {
                message.Instance.addWarnings("Problemer med at forbinde til Databasen", "Cannot open Database connectíon " + e.Message.ToString(), 2);
            }
            int        count = 0;
            int        retval;
            string     cmdstr = "MST_GetSalesOrderList";
            SqlCommand cmd    = new SqlCommand(cmdstr, sqlconn);

            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@count", SqlDbType.Int);
            cmd.Parameters["@count"].Direction = ParameterDirection.Output;
            retval = cmd.ExecuteNonQuery();
            count  = Convert.ToInt32(cmd.Parameters["@count"].Value);
            SqlDataReader reader = cmd.ExecuteReader();

            //}
            ArrA                     = new double[count];
            ArrManureUtil            = new double[count];
            ArrSalesOrderList        = new int[count];
            ArrAmmoniumAndConversion = new decimal[count][];
            ArrSoilType              = new int[numberOfFieldPlanRotations];
            ArrDelivery              = new double[numberOfFieldPlanRotations][];
            count                    = 0;
            while (reader.Read())
            {
                int storageID = Convert.ToInt32(reader["StorageID"]);

                var BoughtAmount =
                    (from m in ManureList
                     where m.getManureType() == storageID
                     select m.getManureAmount()).Sum();
                if (BoughtAmount == null)
                {
                    BoughtAmount = 0m;
                }
                Bought_Amount += BoughtAmount;
                var BoughtUtilDegree =
                    (from m in ManureList
                     where m.getManureType() == storageID
                     select m.getBoughtUtilDegree()).Sum();
                if (storageID == 3)
                {
                    GrazingUtilDegree = BoughtUtilDegree;
                }
                if (BoughtUtilDegree == 0m)
                {
                    BoughtUtilDegree = Convert.ToDecimal(reader["N_UtilizationDegree"]);
                    if (BoughtUtilDegree > 100m)
                    {
                        message.Instance.addWarnings("Gødningens udnyttelsesprocent er ikke angivet", "CalculateManureFertilizerDistributions: Wrong ManureUtilization% from database", 1);
                    }
                    foreach (BoughtManure bm in scenario.ManureList)
                    {
                        if (bm.getManureType() == storageID)
                        {
                            bm.setBoughtUtilDegree(BoughtUtilDegree);
                        }
                    }
                }
                if (Convert.ToInt32(reader["StorageID"]) == 3)//if StorageID == 3: GrazingManure
                {
                    ArrA[count]             = 0;
                    grazingConversionFactor = Convert.ToDecimal(reader["ConversionFactor"]);
                    if (GrazingUtilDegree == 0)
                    {
                        GrazingUtilDegree = Convert.ToDecimal(reader["N_UtilizationDegree"]);
                    }
                }
                else
                {
                    ArrA[count] = Convert.ToDouble(BoughtAmount * BoughtUtilDegree / 100m);
                }
                ArrManureUtil[count]            = Convert.ToDouble(BoughtUtilDegree);
                ArrSalesOrderList[count]        = Convert.ToInt32(reader["StorageID"]);
                ArrAmmoniumAndConversion[count] = new decimal[2];
                decimal[] tmp = new decimal[2];
                tmp[0] = Convert.ToDecimal(reader["AmmoniumRatio"]);
                tmp[1] = Convert.ToDecimal(reader["ConversionFactor"]);
                ArrAmmoniumAndConversion[count] = tmp;
                count = count + 1;
            }
            reader.Close();
            var fertEqDist =
                (from m in ManureList
                 select m.getManureAmount() * m.getBoughtUtilDegree() / 100m).Sum();
            var sortRotList =
                (from Rot in scenario.RotationList
                 orderby Rot.getSoilType()
                 select Rot);

            foreach (Rotation rot in sortRotList)//skal sorteres efter soiltype og cropid
            {
                var sortFplrList =
                    (from Fpl in rot.FieldPlanRotationList
                     orderby Fpl.getCrop(), Fpl.getID()
                     select Fpl);
                foreach (FieldPlanRotation fpl in sortFplrList)
                {
                    if (n < numberOfFieldPlanRotations)
                    {
                        ArrSoilType[n] = rot.getSoilType();
                        ArrBHelp[n]    = fpl;
                    }
                    n         += 1;
                    totalArea += fpl.getArea();
                }
            }
            var ArrBSHelp =
                from FieldPlanRotation fpr in ArrBHelp
                orderby fpr.getSoilType(), fpr.getCrop(), fpr.getID()
            select fpr;

            for (int m = 0; m < ArrBSHelp.Count(); m++)
            {
                ArrB[m] = ArrBSHelp.ElementAt(m).getFieldNNeed() * Convert.ToDouble(ArrBSHelp.ElementAt(m).getArea());    //NNeed skal ganges med den enkelte records areal for at få totalen
                if (boughtGrazingNPrGrazeArea > 0 && ArrBSHelp.ElementAt(m).getUseGrazing() == 1)
                {
                    decimal red = (boughtGrazingNPrGrazeArea * GrazingUtilDegree / 100 * ArrBSHelp.ElementAt(m).getArea());
                    ArrB[m] = (ArrBSHelp.ElementAt(m).getFieldNNeed() * Convert.ToDouble(ArrBSHelp.ElementAt(m).getArea()) - Convert.ToDouble(red));
                    if (ArrB[m] < 0)
                    {
                        message.Instance.addWarnings("Der er ikke græsmarker nok til græssende dyr", "CalculateManureFertilizerDistributions: negative NNeed in ArrB", 3);
                    }
                    ArrBSHelp.ElementAt(m).setGrazingManure(boughtGrazingNPrGrazeArea * ArrBSHelp.ElementAt(m).getArea());
                }
            }
            double TotalManureShareOfNneed = 0;

            if (globalSettings.Instance.getRoundedValuesError() == true)
            {
                TotalManureShareOfNneed =
                    (from b in ArrB
                     select Math.Round(b, 3, MidpointRounding.ToEven)).Sum();
            }
            else
            {
                TotalManureShareOfNneed =
                    (from b in ArrB
                     select b).Sum();
            }

            ObjectCoeff  = new double[numberOfFieldPlanRotations][]; //dimension ArrB * dimension ArrA
            ObjectCoeff1 = new double[count][];                      //dimension ArrB * dimension ArrA
            ArrResult    = new double[count][];                      //dimension ArrA * dimension ArrB
            sqlconnstr   = cfg.GetValue("sqlConnectionStringPublic", typeof(string)).ToString();
            sqlconn      = null;
            try
            {
                sqlconn = new SqlConnection(sqlconnstr);
                sqlconn.Open();
            }
            catch (Exception e)
            {
                message.Instance.addWarnings("Problemer med at forbinde til Databasen", "Cannot open Database connectíon " + e.Message.ToString(), 2);
            }
            DE_ha = Bought_Amount / (100 * totalArea);
            double normReduction = this.GetNormReduction(DE_ha);
            var    totalNNeed    =
                (from fn in ArrBSHelp
                 select fn.getFieldNNeed() * Convert.ToDouble(fn.getArea())).Sum();

            totalNNeed = totalNNeed - normReduction;
            double fertEqNorm = 0;

            if (globalSettings.Instance.getRoundedValuesError())
            {
                fertEqNorm =
                    (from fq in ArrA
                     select Math.Round(fq, 2)).Sum();
            }
            else
            {
                fertEqNorm =
                    (from fq in ArrA
                     select fq).Sum();
            }
            fertEqNorm = fertEqNorm + Convert.ToDouble(boughtGrazing / 100 * GrazingUtilDegree);
            if (fertEqNorm < totalNNeed)
            {
                BoughtFertilizer = totalNNeed - fertEqNorm;//Afgræsning skal også trækkes fra
            }
            else
            {
                BoughtFertilizer = 0;
            }
            fertEqDist     += Convert.ToDecimal(BoughtFertilizer);
            ArrA[count - 1] = Convert.ToDouble(BoughtFertilizer);//Indkøbt gødning lægges i sidste plads i ArrA
            for (int a = 0; a < ArrA.Count(); a++)
            {
                for (int b = 0; b < ArrB.Count(); b++)
                {
                    ArrResult[a]    = new double[numberOfFieldPlanRotations];
                    ObjectCoeff[b]  = new double[count];
                    ObjectCoeff1[a] = new double[numberOfFieldPlanRotations];
                    ArrDelivery[b]  = new double[count];
                    ArrResult[a][b] = -1;
                    ArrDelivery[b]  = ArrBSHelp.ElementAt(b).DeliveryList;
                    ObjectCoeff[b]  = ArrBSHelp.ElementAt(b).CropUtilList;
                    //reader.Close();
                }
            }
            for (int a = 0; a < ObjectCoeff1.Count(); a++)
            {
                for (int b = 0; b < ObjectCoeff.Count(); b++)
                {
                    if (ObjectCoeff[b][a] == -10000)
                    {
                        ObjectCoeff1[a][b] = -10000;
                    }
                    else
                    {
                        ObjectCoeff1[a][b] = Math.Round(10 * ((ObjectCoeff[b][a]) + (5 * ArrSoilType[b])), 0);
                    }
                }
            }
            double scale = 0;

            if (globalSettings.Instance.getRoundedValuesError())
            {
                fertEqDist = Math.Round(fertEqDist - (boughtGrazing / 100 * GrazingUtilDegree), 2);
                scale      = Convert.ToDouble(fertEqDist) / Math.Round(TotalManureShareOfNneed, 1);
            }
            else
            {
                scale = (Convert.ToDouble(fertEqDist) - (Convert.ToDouble(boughtGrazing) / 100 * Convert.ToDouble(GrazingUtilDegree))) / TotalManureShareOfNneed;
            }
            for (int i = 0; i < ArrB.Count(); i++)
            {
                ArrB[i] = Math.Round((ArrB[i] * scale), 2);
            }
            for (int i = 0; i < ArrA.Count(); i++)
            {
                ArrA[i] = Math.Round(ArrA[i], 2);
            }

            double totalA = ArrA.Sum();
            double totalB = ArrB.Sum();

            //double diff = totalB - totalA;
            if (totalA < totalB)
            {
                ArrA[ArrA.Count() - 1] = ArrA[ArrA.Count() - 1] + Math.Round(totalB - totalA, 2);
            }
            else
            {
                ArrB[ArrB.Count() - 1] = ArrB[ArrB.Count() - 1] + Math.Round(totalA - totalB, 2);
            }
            FieldPlanRotation[] ArrBHelp1 = ArrBSHelp.ToArray();
            var numberSameSoilType        =
                (from f in scenario.RotationList
                 group f by f.getSoilType() into s
                 select new { SoilType = s.Key, Number = s.Count() });
            var multiSameSoilType =
                (from s in numberSameSoilType
                 where s.Number > 1
                 select s);

            for (int i = 0; i < multiSameSoilType.Count(); i++)
            {
                int     first = -1;
                int     last  = -1;
                decimal crop  = ArrBHelp1.ElementAt(0).getCrop();
                for (int f = 0; f < ArrBHelp1.Count(); f++)
                {
                    if (ArrBHelp1.ElementAt(f).getSoilType() == multiSameSoilType.ElementAt(i).SoilType&& ArrBHelp1.ElementAt(f).getCrop() == crop)
                    {
                        if (first == -1)
                        {
                            first = f;
                        }
                        last = f;
                    }
                    crop = ArrBHelp1.ElementAt(f).getCrop();
                }
                //advancedSwap(ref ArrBHelp1, ref ArrB, first, last, numberSameSoilType.ElementAt(i).Number);
            }

            totalA = ArrA.Sum();
            totalB = ArrB.Sum();
            double diff = totalB - totalA;

            if (diff > (0.01 * ArrB.Count()) || diff < (-0.01 * ArrB.Count()))
            {
                message.Instance.addWarnings("Algoritmefejl ved afstemning i gødningsberegning", "CalculateManureFertilizerDistribution: FillArrays: Difference mll. ArrA og ArrB for stor", 2);
            }
            if (ManureVersion == 1)
            {
                SendArrays_old(ArrA, ArrB, ref ObjectCoeff1, ref ArrResult);
            }
            else
            {
                SendArrays_new(ArrA, ArrB, ref ObjectCoeff1, ref ArrResult);
            }
            double tempLoss     = 10;
            bool   negativeNeed = false;

            for (int b = 0; b < ObjectCoeff.Count(); b++)
            {
                List <ManureFertilizerDelivery> manureDeliveryList = new List <ManureFertilizerDelivery>();
                for (int a = 0; a < ObjectCoeff1.Count(); a++)
                {
                    if (ArrResult[a][b] > 0.01 && ObjectCoeff1[a][b] > 0)
                    {
                        tempLoss = ArrBSHelp.ElementAt(b).LossList[a];
                        ManureFertilizerDelivery mfd;
                        if (globalSettings.Instance.getRoundedValuesError() == true)
                        {
                            mfd = new ManureFertilizerDelivery(ArrSalesOrderList[a], Convert.ToInt32(ArrDelivery[b][a]), Math.Round(Convert.ToDecimal(Math.Round(ArrResult[a][b], 13) * 100 / ArrManureUtil[a]), 2), Math.Round(Convert.ToDecimal(tempLoss * (Math.Round(ArrResult[a][b], 13) * 100 / ArrManureUtil[a]) / 100), 2), Math.Round(Convert.ToDecimal(Math.Round(ArrResult[a][b], 13)), 4), ArrAmmoniumAndConversion[a][0], ArrAmmoniumAndConversion[a][1]);
                        }
                        else
                        {
                            mfd = new ManureFertilizerDelivery(ArrSalesOrderList[a], Convert.ToInt32(ArrDelivery[b][a]), Convert.ToDecimal(ArrResult[a][b] * 100 / ArrManureUtil[a]), Convert.ToDecimal(tempLoss * (ArrResult[a][b] * 100 / ArrManureUtil[a]) / 100), Convert.ToDecimal(ArrResult[a][b]), ArrAmmoniumAndConversion[a][0], ArrAmmoniumAndConversion[a][1]);
                        }
                        if (mfd.StorageID != 9)
                        {
                            totalManureLoss += mfd.getKg_N_Loss();
                            totalManureDist += mfd.Kg_N_Delivered;
                        }
                        else
                        {
                            totalFertilizerLoss += mfd.getKg_N_Loss();
                            if (globalSettings.Instance.getRoundedValuesError() == true)
                            {
                                totalMineralFertilizerNiveau += Math.Round(ArrResult[a][b], 2);
                            }
                            else
                            {
                                totalMineralFertilizerNiveau += ArrResult[a][b];
                            }
                        }
                        manureDeliveryList.Add(mfd);
                    }
                    else
                    {
                        if (ArrResult[a][b] < 0)
                        {
                            negativeNeed = true;
                        }
                    }
                }
                ArrBHelp1.ElementAt(b).ManureFertilizerDeliveryList = manureDeliveryList;
                manureDeliveryList = null;
            }
            if (negativeNeed == true)
            {
                totalMineralFertilizerNiveauNegativeNeed = BoughtFertilizer;
            }
            if (sqlconn != null)
            {
                sqlconn.Close();
            }
        }