Exemplo n.º 1
0
        static void Main(string[] args)
        {
            string output = string.Empty;
            //define test soils
            SoilParam[] soils = new SoilParam[2];
            soils[0] = new SoilParam(10, 103, 0.4, 2.0, -2.0, -10.0, 1.0 / 3.0, 1.0);
            soils[1] = new SoilParam(10, 109, 0.6, 0.2, -2.0, -40.0, 1.0 / 9.0, 1.0);

            string[] ftname = new string[2];
            int[] sidx;
            int i, j;
            int[] ndz;
            double dzmin;
            double[] x;
            double[,] dz = new double[2, 10]; //only for testing? if not will need to change hardcoded dimensions.
            bool Kgiven = false;
            SoilProps sp1, sp2;
            FluxTable ft1, ft2;

            //define soil profile
            x = new double[] {10,20,30,40,60,80,100,120,160,200}; //length = num soil layers
            sidx = new int[] { 103, 103, 103, 103, 109, 109, 109, 109, 109, 109 }; //soil ident of layers
            dzmin = 1.0; // smallest likely path length
            ndz = new int[] { 2, 4 }; // for the two soil types - gives six flux tables
            //can be done in loops, but clearer this way and will only be used for testing
            dz[0, 0] = 5;
            dz[0, 1] = 10;
            dz[1, 0] = 10;
            dz[1, 1] = 20;
            dz[1, 2] = 30;
            dz[1, 4] = 40;
            for (i = 0; i < 2; i++)
            {
                BinaryWriter b = new BinaryWriter(File.OpenWrite("soil" + soils[i].sid + ".dat"));
                MVG.Params(soils[i].sid, soils[i].ths, soils[i].ks, soils[i].he, soils[i].hd, soils[i].p, soils[i].hg, soils[i].em, soils[i].en);
                soils[i].sp = Soil.gensptbl(dzmin, soils[i], Kgiven);
                b.Write(soils[i].sid);
                WriteProps(b, soils[i].sp);
                b.Close();
                for (j = 0; j < ndz[i]; j++)
                {
                    Fluxes.FluxTable(dz[i, j], soils[i].sp);
                    b = new BinaryWriter(File.OpenWrite("soil" + soils[i].sid + "dz" + dz[i, j] * 10));
                    b.Write(soils[i].sid);
                    WriteFluxes(b, Fluxes.ft);
                    b.Close();
                }
            }

            //generate and write composite flux table for path with two soil types
            sp1 = ReadProps("soil103.dat");
            sp2 = ReadProps("soil109.dat");

            ft1 = ReadFluxes("soil103dz50.dat");
            ft2 = ReadFluxes("soil103dz100.dat");

            FluxTable ftwo = TwoFluxes.TwoTables(ft1, sp1, ft2, sp2);
            BinaryWriter bw = new BinaryWriter(File.OpenWrite("soil0103dz0050_soil0109dz0100.dat"));
            WriteFluxes(bw, ftwo);
        }
Exemplo n.º 2
0
        public static void GenerateFlux()
        {
            MVG.TestParams(103, 9.0, 0.99670220130280185, 9.99999999999998460E-003);
            SoilProps sp = Soil.gensptbl(1.0, new SoilParam(10, 103, 0.4, 2.0, -2.0, -10.0, 1.0 / 3.0, 1.0), true);
            Fluxes.FluxTable(5.0, sp);
            FluxTable ft = Fluxes.ft;

            string output = string.Empty;
            //define test soils
            SoilParam[] soils = new SoilParam[2];
            soils[0] = new SoilParam(10, 103, 0.4, 2.0, -2.0, -10.0, 1.0 / 3.0, 1.0);
            soils[1] = new SoilParam(10, 109, 0.6, 0.2, -2.0, -40.0, 1.0 / 9.0, 1.0);

            string[] ftname = new string[2];
            int[] sidx;
            int i, j;
            int[] ndz;
            double dzmin;
            double[] x;
            double[,] dz = new double[2, 10]; //only for testing? if not will need to change hardcoded dimensions.
            bool Kgiven = true;

            //define soil profile
            x = new double[] { 10, 20, 30, 40, 60, 80, 100, 120, 160, 200 }; //length = num soil layers
            sidx = new int[] { 103, 103, 103, 103, 109, 109, 109, 109, 109, 109 }; //soil ident of layers
            dzmin = 1.0; // smallest likely path length
            ndz = new int[] { 2, 4 }; // for the two soil types - gives six flux tables
            //can be done in loops, but clearer this way and will only be used for testing
            dz[0, 0] = 5;
            dz[0, 1] = 10;
            dz[1, 0] = 10;
            dz[1, 1] = 20;
            dz[1, 2] = 30;
            dz[1, 4] = 40;
            for (i = 0; i < 2; i++)
            {
                MVG.Params(soils[i].sid, soils[i].ths, soils[i].ks, soils[i].he, soils[i].hd, soils[i].p, soils[i].hg, soils[i].em, soils[i].en); //set MVG params
                soils[i].sp = Soil.gensptbl(dzmin, soils[i], Kgiven); // generate soil props
                Soil.SoilProperties.Add("soil" + soils[i].sid, soils[i].sp);
                for (j = 0; j <= ndz[i]; j++)
                {
                    Fluxes.FluxTable(dz[i, j], soils[i].sp); // generate flux tables
                    using (MemoryStream ms = new MemoryStream()) // make copies of the tables or they get overwritten
                    {
                        BinaryFormatter fm = new BinaryFormatter();
                        fm.Serialize(ms, Fluxes.ft);
                        ms.Position = 0;
                        Fluxes.FluxTables.Add("soil" + soils[i].sid + "dz" + (dz[i, j] * 10), (FluxTable)fm.Deserialize(ms));
                    }
                }
            }
            SoilProps sp1 = Soil.ReadProps("soil103");
            SoilProps sp2 = Soil.ReadProps("soil109");
            FluxTable ft1 = Fluxes.ReadFluxTable("soil103dz50");
            FluxTable ft2 = Fluxes.ReadFluxTable("soil109dz100");
            FluxTable ftwo = TwoFluxes.TwoTables(ft1, sp1, ft2, sp2);
            Fluxes.FluxTables.Add("soil103dz50_soil109dz100", ftwo);
        }
Exemplo n.º 3
0
        // The above parameters can be varied, but the defaults should usually be ok.

        //subroutine to generate the property values.
        public static SoilProps gensptbl(double dzmin, SoilParam sPar, bool Kgiven)
        {
            int nlimax = 220;
            int i, j, nli1, nc, nld;

            double[] h   = new double[nlimax + 3];
            double[] lhr = new double[nlimax + 3];
            double[] K   = new double[nlimax + 3];
            double[] phi = new double[nlimax + 3];
            double[] S   = new double[nlimax + 3];
            double[] cco = new double[4];

            //diags - timing starts here

            SoilProps sp = new SoilProps();

            sp.sid = sPar.sid; sp.ths = sPar.ths; sp.ks = sPar.ks;
            sp.he  = sPar.he; sp.phie = phie; sp.S = S; sp.n = sPar.layers;

            // Find start of significant fluxes.
            hdry   = sPar.hd;                 // normally -1e7 cm
            phidry = 0.0;
            hwet   = Math.Min(sPar.he, -1.0); // h/hwet used for log spacing

            if (Kgiven)
            {
                dlh    = Math.Log(10.0) / 3.0; // three points per decade
                x      = Math.Exp(-dlh);       // x*x*x=0.1
                h[0]   = hdry;
                K[0]   = MVG.Kofh(h[0]);
                phi[0] = 0.0;
                for (i = 1; i < nlimax; i++) // should exit well before nlimax
                {
                    h[i] = x * h[i - 1];
                    K[i] = MVG.Kofh(h[i]);
                    // Get approx. phi by integration using dln(-h).
                    phi[i] = phi[i - 1] - 0.5 * (K[i] * h[i] - K[i - 1] * h[i - 1]) * dlh;
                    if (phi[i] > qsmall * dzmin)
                    {
                        break; // max flux is approx (phi-0)/dzmin
                    }
                }
                if (i > nlimax)
                {
                    Console.WriteLine("gensptbl: start of significant fluxes not found");
                    Environment.Exit(1);
                }
                hdry   = h[i - 1];
                phidry = phi[i - 1];
            }
            else
            {
                // Calculate K and find start of significant fluxes.
                Props(ref sp, hdry, phidry, lhr, h, Kgiven);
                for (i = 2; i < sp.n; i++)
                {
                    if (phi[i] > qsmall * dzmin)
                    {
                        break;
                    }
                }
                if (i > sp.n)
                {
                    Console.WriteLine("gensptbl: start of significant fluxes not found");
                    Environment.Exit(1);
                }
                i      = i - 1;
                hdry   = h[i];
                phidry = phi[i];
            }

            // hdry and phidry are values where significant fluxes start.
            // Get props.
            sp.Kc = new double[sp.n];
            Props(ref sp, hdry, phidry, lhr, h, Kgiven);
            // Get ln(-h) and S values from dryness to approx -10000 cm.
            // These needed for vapour flux (rel humidity > 0.99 at -10000 cm).
            // To have complete S(h) coverage, bridge any gap between -10000 and h[1].
            x    = Math.Log(-Math.Max(vhmax, h[0]));
            lhd  = Math.Log(-sPar.hd);
            dlh  = Math.Log(10.0) / nhpd; // nhpd points per decade
            nli1 = (int)Math.Round((lhd - x) / dlh, 0);
            nld  = nli1 + 1;
            nc   = 1 + sp.n / 3; // n-1 has been made divisible by 3
            // fill out the rest of the structure.
            sp.nld   = nld; sp.nc = nc;
            sp.h     = h;
            sp.lnh   = new double[nld + 1];
            sp.Sd    = new double[nld + 1];
            sp.Kco   = new double[3 + 1, nc + 1];
            sp.phico = new double[3 + 1, nc + 1];
            sp.Sco   = new double[3 + 1, nc + 1];
            // Store Sd and lnh in sp.
            sp.lnh[1] = lhd;
            for (j = 2; j <= nld; j++)
            {
                sp.lnh[j] = lhd - dlh * (j - 1);
            }

            if (Kgiven)
            {
                sp.Sd[1] = MVG.Sofh(sPar.hd);
                for (j = 2; j <= nld; j++)
                {
                    x        = sp.lnh[j];
                    sp.Sd[j] = MVG.Sofh(-Math.Exp(x));
                }
            }
            else
            {
                MVG.Sdofh(sPar.hd, out x, out dSdh);
                sp.Sd[1] = x;
                for (j = 2; j <= nld; j++)
                {
                    x = sp.lnh[j];
                    MVG.Sdofh(-Math.Exp(x), out x, out dSdh);
                    sp.Sd[j] = x;
                }
            }

            // Get polynomial coefficients.
            j       = 0;
            sp.Sc   = new double[sp.n + 1];
            sp.hc   = new double[sp.n + 1];
            sp.phic = new double[sp.n + 1];
            Matrix <double> KcoM = Matrix <double> .Build.DenseOfArray(sp.Kco);

            Matrix <double> phicoM = Matrix <double> .Build.DenseOfArray(sp.phico);

            Matrix <double> ScoM = Matrix <double> .Build.DenseOfArray(sp.Sco);

            for (i = 1; i <= sp.n; i += 3)
            {
                j          = j + 1;
                sp.Sc[j]   = S[i];
                sp.hc[j]   = h[i];
                sp.Kc[j]   = sp.K[i];
                sp.phic[j] = sp.phi[i];
                if (i == sp.n)
                {
                    break;
                }

                cco = Cuco(sp.phi.Slice(i, i + 3), sp.K.Slice(i, i + 3));
                KcoM.SetColumn(j, cco.Slice(2, 4).ToArray());

                cco = Cuco(sp.S.Slice(i, i + 3), sp.phi.Slice(i, i + 3));
                phicoM.SetColumn(j, cco.Slice(2, 4).ToArray());

                cco = Cuco(sp.phi.Slice(i, i + 3), sp.S.Slice(i, i + 3));
                ScoM.SetColumn(j, cco.Slice(2, 4).ToArray());
            }
            sp.Kco   = KcoM.ToArray();
            sp.phico = phicoM.ToArray();
            sp.Sco   = ScoM.ToArray();
            return(sp);
        }
Exemplo n.º 4
0
        static double vhmax = -10000; // for vapour - rel humidity > 0.99 at vhmax

        #endregion Fields

        #region Methods

        // The above parameters can be varied, but the defaults should usually be ok.
        //subroutine to generate the property values.
        public static SoilProps gensptbl(double dzmin, SoilParam sPar, bool Kgiven)
        {
            int nlimax = 220;
            int i, j, nli1, n, nc, nld;
            double[] h= new double[nlimax + 3];
            double[] lhr= new double[nlimax + 3];
            double[] K = new double[nlimax + 3];
            double[] phi = new double[nlimax + 3];
            double[] S = new double[nlimax + 3];
            double[] cco = new double[4];

            //diags - timing starts here

            SoilProps sp = new SoilProps();
            sp.sid = sPar.sid; sp.ths = sPar.ths; sp.ks = sPar.ks;
            sp.he = sPar.he; sp.phie = phie; sp.S = S; sp.n = sPar.layers;
            n = sp.n;

            // Find start of significant fluxes.
            hdry = sPar.hd; // normally -1e7 cm
            phidry = 0.0;
            hwet = Math.Min(sPar.he, -1.0); // h/hwet used for log spacing

            if (Kgiven)
            {
                dlh = Math.Log(10.0) / 3.0; // three points per decade
                x = Math.Exp(-dlh); // x*x*x=0.1
                h[0] = hdry;
                K[0] = MVG.Kofh(h[0]);
                phi[1] = 0.0;
                for (i = 1; i < nlimax; i++) // should exit well before nlimax
                {
                    h[i] = x * h[i - 1];
                    K[i] = MVG.Kofh(h[i]);
                    // Get approx. phi by integration using dln(-h).
                    phi[i] = phi[i - 1] - 0.5 * (K[i] * h[i] - K[i - 1] * h[i - 1]) * dlh;
                    if (phi[i] > qsmall * dzmin)
                        break; // max flux is approx (phi-0)/dzmin
                }
                if (i > nlimax)
                {
                    Console.WriteLine("gensptbl: start of significant fluxes not found");
                    Environment.Exit(1);
                }
                hdry = h[i - 1];
                phidry = phi[i - 1];
            }
            else
            {
                // Calculate K and find start of significant fluxes.
                Props(sp, hdry, phidry, lhr, h, Kgiven);
                for (i = 2; i < n; i++)
                    if (phi[i] > qsmall * dzmin)
                        break;
                if (i > n)
                {
                    Console.WriteLine("gensptbl: start of significant fluxes not found");
                    Environment.Exit(1);
                }
                i = i - 1;
                hdry = h[i];
                phidry = phi[i];
            }

            // hdry and phidry are values where significant fluxes start.
            // Get props.
            sp.Kc = new double[sp.n];
            Props(sp, hdry, phidry, lhr,h,Kgiven);
            // Get ln(-h) and S values from dryness to approx -10000 cm.
            // These needed for vapour flux (rel humidity > 0.99 at -10000 cm).
            // To have complete S(h) coverage, bridge any gap between -10000 and h[1].
            x = Math.Log(-Math.Max(vhmax, h[1]));
            lhd = Math.Log(-sPar.hd);
            dlh = Math.Log(10.0) / nhpd; // nhpd points per decade
            nli1 = (int)Math.Round((lhd - x) / dlh, 0);
            nld = nli1 + 1;
            nc = 1 + n / 3; // n-1 has been made divisible by 3
            // fill out the rest of the structure.
             sp.nld = nld; sp.nc = nc;
             sp.h = h; sp.K = K; sp.phi = phi;
             sp.lnh = new double[nld];
             sp.Sd = new double[nld];
             sp.Kco = new double[3, nc - 1];
             sp.phico = new double[3, nc - 1];
             sp.Sco = new double[3, nc - 1];

            // Store Sd and lnh in sp.
            sp.lnh[0] = lhd;
            for (j = 1; j < nli1; j++)
                sp.lnh[j] = lhd - dlh * j;

            if (Kgiven)
            {
                sp.Sd[0] = MVG.Sofh(sPar.hd);
                for (j = 1; j < nld; j++)
                {
                    x = sp.lnh[j];
                    sp.Sd[j] = MVG.Sofh(-Math.Exp(x));
                }
            }
            else
            {
                MVG.Sdofh(sPar.hd, out x, out dSdh);
                sp.Sd[0] = x;
                for (j = 1; j < nld; j++)
                {
                    x = sp.lnh[j];
                    MVG.Sdofh(-Math.Exp(x), out x, out dSdh);
                    sp.Sd[j] = x;
                }
            }

            // Get polynomial coefficients.
            j = 0;
            sp.Sc = new double[sp.n];
            sp.hc = new double[sp.n];
            sp.phic = new double[sp.n];
            for (i = 0; i < n; i += 3)
            {
                j = j + 1;
                sp.Sc[j] = S[i];
                sp.hc[j] = h[i];
                sp.Kc[j] = K[i];
                sp.phic[j] = phi[i];
                if (i == n)
                    break;

                cco = Cuco(sp.phi.Skip(i).Take(4).ToArray(), sp.K.Skip(i).Take(4).ToArray());
                for (int row = 0; row < sp.Kco.GetLength(0); row++)
                    for (int col = 0; col < 2; col++)
                        sp.Kco[row, col] = cco[col + 2];

                cco = Cuco(sp.S.Skip(i).Take(4).ToArray(), sp.phi.Skip(i).Take(4).ToArray());
                for (int row = 0; row < sp.Kco.GetLength(0); row++)
                    for (int col = 0; col < 2; col++)
                        sp.phico[row, col] = cco[col + 2];

                cco = Cuco(sp.phi.Skip(i).Take(4).ToArray(), sp.S.Skip(i).Take(4).ToArray());
                for (int row = 0; row < sp.Kco.GetLength(0); row++)
                    for (int col = 0; col < 2; col++)
                        sp.Sco[row, col] = cco[col + 2];
            }
            // diags - end timing
            return sp;
        }
Exemplo n.º 5
0
        static void Main(string[] args)
        {
            string output = string.Empty;

            //define test soils
            SoilParam[] soils = new SoilParam[2];
            soils[0] = new SoilParam(10, 103, 0.4, 2.0, -2.0, -10.0, 1.0 / 3.0, 1.0);
            soils[1] = new SoilParam(10, 109, 0.6, 0.2, -2.0, -40.0, 1.0 / 9.0, 1.0);

            string[] ftname = new string[2];
            int[]    sidx;
            int      i, j;

            int[]  ndz;
            double dzmin;

            double[] x;
            double[,] dz = new double[2, 10]; //only for testing? if not will need to change hardcoded dimensions.
            bool      Kgiven = false;
            SoilProps sp1, sp2;
            FluxTable ft1, ft2;

            //define soil profile
            x     = new double[] { 10, 20, 30, 40, 60, 80, 100, 120, 160, 200 };    //length = num soil layers
            sidx  = new int[] { 103, 103, 103, 103, 109, 109, 109, 109, 109, 109 }; //soil ident of layers
            dzmin = 1.0;                                                            // smallest likely path length
            ndz   = new int[] { 2, 4 };                                             // for the two soil types - gives six flux tables
            //can be done in loops, but clearer this way and will only be used for testing
            dz[0, 0] = 5;
            dz[0, 1] = 10;
            dz[1, 0] = 10;
            dz[1, 1] = 20;
            dz[1, 2] = 30;
            dz[1, 4] = 40;
            for (i = 0; i < 2; i++)
            {
                BinaryWriter b = new BinaryWriter(File.OpenWrite("soil" + soils[i].sid + ".dat"));
                MVG.Params(soils[i].sid, soils[i].ths, soils[i].ks, soils[i].he, soils[i].hd, soils[i].p, soils[i].hg, soils[i].em, soils[i].en);
                soils[i].sp = Soil.gensptbl(dzmin, soils[i], Kgiven);
                b.Write(soils[i].sid);
                WriteProps(b, soils[i].sp);
                b.Close();
                for (j = 0; j < ndz[i]; j++)
                {
                    Fluxes.FluxTable(dz[i, j], soils[i].sp);
                    b = new BinaryWriter(File.OpenWrite("soil" + soils[i].sid + "dz" + dz[i, j] * 10));
                    b.Write(soils[i].sid);
                    WriteFluxes(b, Fluxes.ft);
                    b.Close();
                }
            }

            //generate and write composite flux table for path with two soil types
            sp1 = ReadProps("soil103.dat");
            sp2 = ReadProps("soil109.dat");

            ft1 = ReadFluxes("soil103dz50.dat");
            ft2 = ReadFluxes("soil103dz100.dat");

            FluxTable    ftwo = TwoFluxes.TwoTables(ft1, sp1, ft2, sp2);
            BinaryWriter bw   = new BinaryWriter(File.OpenWrite("soil0103dz0050_soil0109dz0100.dat"));

            WriteFluxes(bw, ftwo);
        }
Exemplo n.º 6
0
        public static void GenerateFlux()
        {
            MVG.TestParams(103, 9.0, 0.99670220130280185, 9.99999999999998460E-003);
            SoilProps sp = Soil.gensptbl(1.0, new SoilParam(10, 103, 0.4, 2.0, -2.0, -10.0, 1.0 / 3.0, 1.0), true);

            Fluxes.FluxTable(5.0, sp);
            FluxTable ft = Fluxes.ft;

            string output = string.Empty;

            //define test soils
            SoilParam[] soils = new SoilParam[2];
            soils[0] = new SoilParam(10, 103, 0.4, 2.0, -2.0, -10.0, 1.0 / 3.0, 1.0);
            soils[1] = new SoilParam(10, 109, 0.6, 0.2, -2.0, -40.0, 1.0 / 9.0, 1.0);

            string[] ftname = new string[2];
            int[]    sidx;
            int      i, j;

            int[]  ndz;
            double dzmin;

            double[] x;
            double[,] dz = new double[2, 10]; //only for testing? if not will need to change hardcoded dimensions.
            bool Kgiven = true;

            //define soil profile
            x     = new double[] { 10, 20, 30, 40, 60, 80, 100, 120, 160, 200 };    //length = num soil layers
            sidx  = new int[] { 103, 103, 103, 103, 109, 109, 109, 109, 109, 109 }; //soil ident of layers
            dzmin = 1.0;                                                            // smallest likely path length
            ndz   = new int[] { 2, 4 };                                             // for the two soil types - gives six flux tables
            //can be done in loops, but clearer this way and will only be used for testing
            dz[0, 0] = 5;
            dz[0, 1] = 10;
            dz[1, 0] = 10;
            dz[1, 1] = 20;
            dz[1, 2] = 30;
            dz[1, 4] = 40;
            for (i = 0; i < 2; i++)
            {
                MVG.Params(soils[i].sid, soils[i].ths, soils[i].ks, soils[i].he, soils[i].hd, soils[i].p, soils[i].hg, soils[i].em, soils[i].en); //set MVG params
                soils[i].sp = Soil.gensptbl(dzmin, soils[i], Kgiven);                                                                             // generate soil props
                Soil.SoilProperties.Add("soil" + soils[i].sid, soils[i].sp);
                for (j = 0; j <= ndz[i]; j++)
                {
                    Fluxes.FluxTable(dz[i, j], soils[i].sp);     // generate flux tables
                    using (MemoryStream ms = new MemoryStream()) // make copies of the tables or they get overwritten
                    {
                        BinaryFormatter fm = new BinaryFormatter();
                        fm.Serialize(ms, Fluxes.ft);
                        ms.Position = 0;
                        Fluxes.FluxTables.Add("soil" + soils[i].sid + "dz" + (dz[i, j] * 10), (FluxTable)fm.Deserialize(ms));
                    }
                }
            }
            SoilProps sp1  = Soil.ReadProps("soil103");
            SoilProps sp2  = Soil.ReadProps("soil109");
            FluxTable ft1  = Fluxes.ReadFluxTable("soil103dz50");
            FluxTable ft2  = Fluxes.ReadFluxTable("soil109dz100");
            FluxTable ftwo = TwoFluxes.TwoTables(ft1, sp1, ft2, sp2);

            Fluxes.FluxTables.Add("soil103dz50_soil109dz100", ftwo);
        }