Пример #1
0
        static double[,] isopar;                          //2 params (nt,2)

        //public static void Setup()
        public static void Main(string[] args)
        {
            Soil.SoilProperties = new Dictionary <string, SoilProps>();
            Fluxes.FluxTables   = new Dictionary <string, FluxTable>();
            Program.GenerateFlux();

            c0      = new double[ns + 1];
            cin     = new double[ns + 1];
            h       = new double[n + 1];
            S       = new double[n + 1];
            isotype = new string[nt + 1];
            isopar  = new double[nt + 1, 2 + 1];
            soff    = new double[ns + 1];
            sdrn    = new double[ns + 1];
            sinfil  = new double[ns + 1];
            SoilData sd = new SoilData();

            Flow.sink = new SinkDripperDrain(); //set the type of sink to use
            jt        = new int[n + 1];
            nssteps   = new int[ns + 1];
            sidx      = new int[n + 1];
            sm        = new double[ns + 1, n + 1];
            //set a list of soil layers(cm).
            x = new double[] { 0, 10.0, 20.0, 30.0, 40.0, 60.0, 80.0, 100.0, 120.0, 160.0, 200.0 };
            for (int c = 1; c <= n; c++)
            {
                sidx[c] = c < 5 ? 103 : 109; //soil ident of layers
            }
            //set required soil hydraulic params
            sd.GetTables(n, sidx, x);
            SolProps solProps = new SolProps(nt, ns);

            bd  = new double[] { 0, 1.3, 1.3 };
            dis = new double[] { 0, 20.0, 20.0 };
            //set isotherm type and params for solute 2 here
            isotype[1]   = "Fr";
            isotype[2]   = "La";
            isopar[1, 1] = 1.0;
            isopar[1, 2] = 1.0;
            isopar[2, 1] = 0.5;
            isopar[2, 2] = 0.01;
            Matrix <double> isoparM = Matrix <double> .Build.DenseOfArray(isopar);

            for (j = 1; j <= nt; j++) //set params
            {
                solProps.Solpar(j, bd[j], dis[j]);
                //set isotherm type and params
                solProps.Setiso(j, 2, isotype[j], isoparM.Column(j).ToArray());
            }
            //initialise for run
            ts = 0.0;          //start time
                               //dSmax controls time step.Use 0.05 for a fast but fairly accurate solution.
                               //Use 0.001 to get many steps to test execution time per step.
            Flow.dSmax = 0.01; //0.01 ensures very good accuracy
            for (int c = 1; c <= n; c++)
            {
                jt[c] = c < 5 ? 1 : 2;      //!4 layers of type 1, rest of type2
            }
            h0 = 0.0;                       //pond depth initially zero
            h1 = -1000.0;
            h2 = -400.0;                    //initial matric heads
            double Sh = 0;                  //not used for this call but required as C# does not have 'present' operator

            sd.Sofh(h1, 1, out S1, out Sh); //solve uses degree of satn
            sd.Sofh(h2, 5, out S2, out Sh);
            for (int c = 1; c <= n; c++)
            {
                S[c] = c < 5 ? S1 : S2;
            }
            wpi    = MathUtilities.Sum(MathUtilities.Multiply(MathUtilities.Multiply(sd.ths, S), sd.dx)); //water in profile initially
            nsteps = 0;                                                                                   //no.of time steps for water soln(cumulative)
            win    = 0.0;                                                                                 //water input(total precip)
            evap   = 0.0;
            runoff = 0.0;
            infil  = 0.0;
            drn    = 0.0;
            for (int col = 1; col < sm.GetLength(0); col++)
            {
                sm[col, 1] = 1000.0 / sd.dx[1];
            }
            //initial solute concn(mass units per cc of soil)
            //solute in profile initially
            spi          = new [] { 1000.0, 1000.0 };
            Flow.dsmmax  = 0.1 * sm[1, 1]; //solute stepsize control param
            Flow.nwsteps = 10;
            MathUtilities.Zero(c0);
            MathUtilities.Zero(cin); //no solute input
            nssteps.Populate(0);     //no.of time steps for solute soln(cumulative)
            MathUtilities.Zero(soff);
            MathUtilities.Zero(sinfil);
            MathUtilities.Zero(sdrn);
            qprec          = 1.0;              //precip at 1 cm / h for first 24 h
            ti             = ts;
            qevap          = 0.05;             // potential evap rate from soil surface
            double[,] wex  = new double[1, 1]; //unused option params in FORTRAN... must be a better way of doing this
            double[,,] sex = new double[1, 1, 1];

            //timer here in FORTRAN, this basically runs the solution for 100 days
            for (j = 1; j <= 100; j++)
            {
                tf = ti + 24.0;
                Flow.Solve(solProps, sd, ti, tf, qprec, qevap, ns, Flow.sink.nex, ref h0, ref S, ref evap, ref runoff, ref infil, ref drn, ref nsteps, jt, cin, ref c0, ref sm, ref soff, ref sinfil, ref sdrn, ref nssteps, ref wex, ref sex);
                win = win + qprec * (tf - ti);
                if (j == 1)
                {
                    ti = tf;
                }
                qprec = 0.0;
            }
            win = win + qprec * (tf - ti);
            wp  = MathUtilities.Sum(MathUtilities.Multiply(MathUtilities.Multiply(sd.ths, S), sd.dx)); //!water in profile
            double hS = 0;                                                                             //hS is not used used here, but is a required parameter

            for (j = 1; j <= n; j++)
            {
                sd.hofS(S[j], j, out h[j], out hS);
            }
        }
Пример #2
0
        public void SetIso()
        {
            SolProps sp = new SolProps(2, 10);
            int[] j = { 1, 2 };
            int[] isol = { 2, 2 };
            string[] isotypeji = { "Fr", "La" };
            double[][] isoparji = { new [] { 0, 1, 0.5 }, new [] { 0, 1, 0.01 } };
            double[][] isopar = { new [] { 0, 1, 0.5, 0, 0 }, new [] { 0, 1, 0.01 } };

            for (int i = 0; i < j.Length; i++)
            {
                sp.Setiso(j[i], isol[i], isotypeji[i], isoparji[i]);
                for (int count = 1; count < isopar[i].Length; count++)
                {
                    Assert.AreEqual(isopar[j[i] - 1][count], sp.isopar[isol[i], j[i]][count], Math.Abs(isopar[j[i] - 1][count] * 1E-5));
                }
            }
        }
Пример #3
0
        public void Solute()
        {
            int nt = 2;
            int ns = 2;
            SolProps sp = new SolProps(nt, ns);
            double[] bd = new double[nt + 1];
            double[] dis = new double[nt + 1];
            string[] isotype = { "", "Fr", "La" };
            double[,] isopar = { { 0, 0, 0 }, { 0, 1.0, 1.0 }, { 0, 0.5, 0.01 } };

            Array.Copy(new [] { 0, 1.3, 1.3 }, bd, 3);
            Array.Copy(new [] { 0, 20.0, 20.0 }, dis, 3);
            for (int j = 1; j <= nt; j++)
            {
                sp.Solpar(j, bd[j], dis[j]);
                sp.Setiso(j, 2, isotype[j], Extensions.GetRowCol(isopar, j, true));
            }
            int n = 10;
            int nex = 0;
            double ti = 0;
            double tf = 0.421148079;
            double[] thi = { 0, 8.32952248067425E-02, 8.32952248067425E-02, 8.32952248067425E-02, 8.32952248067425E-02, 4.18896102493218E-01, 4.18896102493218E-01, 4.18896102493218E-01, 4.18896102493218E-01, 4.18896102493218E-01, 4.18896102493218E-01 };
            double[] thf = { 0, 1.23293862599989E-01, 8.33055911391525E-02, 8.32952276559487E-02, 8.33189852482353E-02, 4.18882017281567E-01, 4.18896097739775E-01, 4.18896102481653E-01, 4.18896102470398E-01, 4.18896050247009E-01, 4.18896158171224E-01};
            double[,] dwexs = new double[nex, n];
            double win = 0.400090675;
            double[] cin = { 0, 0, 0 };
            double[] dx = { 0, 10, 10, 10, 10, 20, 20, 20, 20, 40, 40 };
            int[] jt = { 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2 };
            int dsmmax = 10;
            double[,] sm = { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                                           {0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                                           {0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
            double[] sdrn =  { 0, 0, 0 };
            int[] nssteps =  { 0, 0, 0 };
            double[,] c = new double[ns + 1, n + 1];
            double[,,] sex = new double[0, 0, 0];

            double[,] smOUT = { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                                {0, 9.9976219E+01, 2.3781371E-02, 2.2604628E-08, 2.0517180E-14, 1.2161602E-18, 4.8670606E-24, 1.9519348E-29, 7.8282825E-35, 1.2209528E-40, 1.7083828E-46},
                                {0, 9.9983728E+01, 1.6271857E-02, 9.8469378E-11, 5.6908331E-19, 2.1476414E-25, 2.0945763E-31, 2.0471666E-37, 2.0008407E-43, 7.6050509E-50, 2.5932571E-56} };
            double[] sdrnOUT = { 0, 9.10749016E-51, 3.36911468E-61 };
            int[] nsstepsOUT = { 0, 1, 1 };
            double[,] cOUT =  { {0, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
                                {0, 1.20054901384821E+03, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
                                {0, 7.68024454834764E+02, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00} };

            List<object> res = Flow.TestSolute(ti, tf, thi, thf, dwexs, win, cin, n, ns, nex, dx, jt, dsmmax, sm, sdrn, nssteps, c, sex, false, sp);

            double[,] smRes = res[0] as double[,];
            for (int i = 1; i < smOUT.GetLength(0); i++)
                for (int j = 1; j < smOUT.GetLength(1); j++)
                    Assert.AreEqual(smOUT[i, j], smRes[i, j], Math.Abs(smOUT[i, 1] * 1E-5)); //variations in sm at E-40... I don't think we really care at that point. Also probably outside of float range

            double[] sdrnRes = res[1] as double[];
            for (int i = 1; i < sdrnOUT.Length; i++)
                Assert.AreEqual(sdrnOUT[i], sdrnRes[i], 1E-10); //same as above. We're working with -60 exponents here. No bearing to reality.

            int[] nsstepsRes = res[2] as int[];
            for (int i = 1; i < nsstepsOUT.Length; i++)
                Assert.AreEqual(nsstepsOUT[i], nsstepsRes[i]);

            double[,] cRes = res[3] as double[,];
            for (int i = 1; i < cOUT.GetLength(0); i++)
                for (int j = 1; j < cOUT.GetLength(1); j++)
                    Assert.AreEqual(cOUT[i, j], cRes[i, j], Math.Abs(cOUT[i,j] * 1E-7));
        }
Пример #4
0
        static double[,] sm; //(n, ns)

        #endregion Fields

        #region Methods

        //public static void Setup()
        public static void Main(string[] args)
        {
            Soil.SoilProperties = new Dictionary<string, SoilProps>();
            Fluxes.FluxTables = new Dictionary<string, FluxTable>();
            Program.GenerateFlux();

            c0 = new double[ns + 1];
            cin = new double[ns + 1];
            h = new double[n + 1];
            S = new double[n + 1];
            isotype = new string[nt + 1];
            isopar = new double[nt + 1, 2 + 1];
            soff = new double[ns + 1];
            sdrn = new double[ns + 1];
            sinfil = new double[ns + 1];
            SoilData sd = new SoilData();
            Flow.sink = new SinkDripperDrain(); //set the type of sink to use
            jt = new int[n+1];
            nssteps = new int[ns + 1];
            sidx = new int[n+1];
            sm = new double[ns + 1, n + 1];
            //set a list of soil layers(cm).
            x = new double[] { 0, 10.0, 20.0, 30.0, 40.0, 60.0, 80.0, 100.0, 120.0, 160.0, 200.0 };
            for (int c = 1; c <= n; c++)
                sidx[c] = c < 5 ? 103 : 109; //soil ident of layers
                                             //set required soil hydraulic params
            sd.GetTables(n, sidx, x);
            SolProps solProps = new SolProps(nt, ns);
            bd = new double[] {0, 1.3, 1.3 };
            dis = new double[] {0, 20.0, 20.0 };
            //set isotherm type and params for solute 2 here
            isotype[1] = "Fr";
            isotype[2] = "La";
            isopar[1, 1] = 1.0;
            isopar[1, 2] = 1.0;
            isopar[2, 1] = 0.5;
            isopar[2, 2] = 0.01;
            Matrix<double> isoparM = Matrix<double>.Build.DenseOfArray(isopar);
            for (j = 1; j <= nt; j++) //set params
            {
                solProps.Solpar(j, bd[j], dis[j]);
                //set isotherm type and params
                solProps.Setiso(j, 2, isotype[j], isoparM.Column(j).ToArray());
            }
            //initialise for run
            ts = 0.0; //start time
                      //dSmax controls time step.Use 0.05 for a fast but fairly accurate solution.
                      //Use 0.001 to get many steps to test execution time per step.
            Flow.dSmax = 0.01; //0.01 ensures very good accuracy
            for (int c = 1; c <= n; c++)
                jt[c] = c < 5 ? 1 : 2; //!4 layers of type 1, rest of type2
            h0 = 0.0; //pond depth initially zero
            h1 = -1000.0;
            h2 = -400.0; //initial matric heads
            double Sh = 0; //not used for this call but required as C# does not have 'present' operator
            sd.Sofh(h1, 1, out S1, out Sh); //solve uses degree of satn
            sd.Sofh(h2, 5, out S2, out Sh);
            for (int c = 1; c <= n; c++)
                S[c] = c < 5 ? S1 : S2;
            wpi = MathUtilities.Sum(MathUtilities.Multiply(MathUtilities.Multiply(sd.ths, S), sd.dx)); //water in profile initially
            nsteps = 0; //no.of time steps for water soln(cumulative)
            win = 0.0; //water input(total precip)
            evap = 0.0;
            runoff = 0.0;
            infil = 0.0;
            drn = 0.0;
            for (int col = 1; col < sm.GetLength(0); col++)
                sm[col, 1] = 1000.0 / sd.dx[1];
            //initial solute concn(mass units per cc of soil)
            //solute in profile initially
            spi = new []{1000.0, 1000.0};
            Flow.dsmmax = 0.1 * sm[1, 1]; //solute stepsize control param
            Flow.nwsteps = 10;
            MathUtilities.Zero(c0);
            MathUtilities.Zero(cin); //no solute input
            nssteps.Populate(0); //no.of time steps for solute soln(cumulative)
            MathUtilities.Zero(soff);
            MathUtilities.Zero(sinfil);
            MathUtilities.Zero(sdrn);
            qprec = 1.0; //precip at 1 cm / h for first 24 h
            ti = ts;
            qevap = 0.05;// potential evap rate from soil surface
            double[,] wex = new double[1,1]; //unused option params in FORTRAN... must be a better way of doing this
            double[,,] sex=new double[1,1,1];

            //timer here in FORTRAN, this basically runs the solution for 100 days
            for (j = 1; j <= 100; j++)
            {
                tf = ti + 24.0;
                Flow.Solve(solProps, sd, ti, tf, qprec, qevap, ns, Flow.sink.nex, ref h0, ref S, ref evap, ref runoff, ref infil, ref drn, ref nsteps, jt, cin, ref c0, ref sm, ref soff, ref sinfil, ref sdrn, ref nssteps, ref wex,ref sex);
                win = win + qprec * (tf - ti);
                if (j == 1)
                ti = tf;
                qprec = 0.0;
            }
            win = win + qprec * (tf - ti);
            wp = MathUtilities.Sum(MathUtilities.Multiply(MathUtilities.Multiply(sd.ths,S), sd.dx)); //!water in profile
            double hS = 0; //hS is not used used here, but is a required parameter
            for (j = 1; j <= n; j++)
                sd.hofS(S[j], j, out h[j], out hS);
        }