Exemple #1
0
        public void testUniformGridMesher()
        {
            int[]      dims = new int[] { 5, 7, 8 };
            List <int> dim  = new List <int>(dims);

            FdmLinearOpLayout layout = new FdmLinearOpLayout(dim);
            List <Pair <double?, double?> > boundaries = new List <Pair <double?, double?> > ();;

            boundaries.Add(new Pair <double?, double?>(-5, 10));
            boundaries.Add(new Pair <double?, double?>(5, 100));
            boundaries.Add(new Pair <double?, double?>(10, 20));

            UniformGridMesher mesher = new UniformGridMesher(layout, boundaries);

            double dx1 = 15.0 / (dim[0] - 1);
            double dx2 = 95.0 / (dim[1] - 1);
            double dx3 = 10.0 / (dim[2] - 1);

            double tol = 100 * Const.QL_EPSILON;

            if (Math.Abs(dx1 - mesher.dminus(layout.begin(), 0).Value) > tol ||
                Math.Abs(dx1 - mesher.dplus(layout.begin(), 0).Value) > tol ||
                Math.Abs(dx2 - mesher.dminus(layout.begin(), 1).Value) > tol ||
                Math.Abs(dx2 - mesher.dplus(layout.begin(), 1).Value) > tol ||
                Math.Abs(dx3 - mesher.dminus(layout.begin(), 2).Value) > tol ||
                Math.Abs(dx3 - mesher.dplus(layout.begin(), 2).Value) > tol)
            {
                QAssert.Fail("inconsistent uniform mesher object");
            }
        }
Exemple #2
0
        public void testTripleBandMapSolve()
        {
            int[]      dims = new int[] { 100, 400 };
            List <int> dim  = new List <int>(dims);

            FdmLinearOpLayout layout = new FdmLinearOpLayout(dim);

            List <Pair <double?, double?> > boundaries = new List <Pair <double?, double?> > ();

            boundaries.Add(new Pair <double?, double?>(0, 1.0));
            boundaries.Add(new Pair <double?, double?>(0, 1.0));

            FdmMesher mesher = new UniformGridMesher(layout, boundaries);

            FirstDerivativeOp dy = new FirstDerivativeOp(1, mesher);

            dy.axpyb(new Vector(1, 2.0), dy, dy, new Vector(1, 1.0));

            // check copy constructor
            FirstDerivativeOp copyOfDy = new FirstDerivativeOp(dy);

            Vector u = new Vector(layout.size());

            for (int i = 0; i < layout.size(); ++i)
            {
                u[i] = Math.Sin(0.1 * i) + Math.Cos(0.35 * i);
            }

            Vector t = new Vector(dy.solve_splitting(copyOfDy.apply(u), 1.0, 0.0));

            for (int i = 0; i < u.size(); ++i)
            {
                if (Math.Abs(u[i] - t[i]) > 1e-6)
                {
                    QAssert.Fail("solve and apply are not consistent "
                                 + "\n expected      : " + u[i]
                                 + "\n calculated    : " + t[i]);
                }
            }

            FirstDerivativeOp dx = new FirstDerivativeOp(0, mesher);

            dx.axpyb(new Vector(), dx, dx, new Vector(1, 1.0));

            FirstDerivativeOp copyOfDx = new FirstDerivativeOp(0, mesher);

            // check assignment
            copyOfDx = dx;

            t = dx.solve_splitting(copyOfDx.apply(u), 1.0, 0.0);
            for (int i = 0; i < u.size(); ++i)
            {
                if (Math.Abs(u[i] - t[i]) > 1e-6)
                {
                    QAssert.Fail("solve and apply are not consistent "
                                 + "\n expected      : " + u[i]
                                 + "\n calculated    : " + t[i]);
                }
            }

            SecondDerivativeOp dxx = new SecondDerivativeOp(0, mesher);

            dxx.axpyb(new Vector(1, 0.5), dxx, dx, new Vector(1, 1.0));

            // check of copy constructor
            SecondDerivativeOp copyOfDxx = new SecondDerivativeOp(dxx);

            t = dxx.solve_splitting(copyOfDxx.apply(u), 1.0, 0.0);

            for (int i = 0; i < u.size(); ++i)
            {
                if (Math.Abs(u[i] - t[i]) > 1e-6)
                {
                    QAssert.Fail("solve and apply are not consistent "
                                 + "\n expected      : " + u[i]
                                 + "\n calculated    : " + t[i]);
                }
            }

            //check assignment operator
            copyOfDxx.add(new SecondDerivativeOp(1, mesher));
            copyOfDxx = dxx;

            t = dxx.solve_splitting(copyOfDxx.apply(u), 1.0, 0.0);

            for (int i = 0; i < u.size(); ++i)
            {
                if (Math.Abs(u[i] - t[i]) > 1e-6)
                {
                    QAssert.Fail("solve and apply are not consistent "
                                 + "\n expected      : " + u[i]
                                 + "\n calculated    : " + t[i]);
                }
            }
        }
Exemple #3
0
        public void testSecondOrderMixedDerivativesMapApply()
        {
            int[]      dims = new int[] { 50, 50, 50 };
            List <int> dim  = new List <int>(dims);

            FdmLinearOpLayout index = new FdmLinearOpLayout(dim);

            List <Pair <double?, double?> > boundaries = new List <Pair <double?, double?> > ();

            boundaries.Add(new Pair <double?, double?>(0, 0.5));
            boundaries.Add(new Pair <double?, double?>(0, 0.5));
            boundaries.Add(new Pair <double?, double?>(0, 0.5));

            FdmMesher mesher = new UniformGridMesher(index, boundaries);

            Vector r = new Vector(mesher.layout().size());
            FdmLinearOpIterator endIter = index.end();

            for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter)
            {
                double x = mesher.location(iter, 0);
                double y = mesher.location(iter, 1);
                double z = mesher.location(iter, 2);

                r[iter.index()] = Math.Sin(x) * Math.Cos(y) * Math.Exp(z);
            }

            Vector t = new SecondOrderMixedDerivativeOp(0, 1, mesher).apply(r);
            Vector u = new SecondOrderMixedDerivativeOp(1, 0, mesher).apply(r);

            double tol = 5e-2;

            for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter)
            {
                int    i = iter.index();
                double x = mesher.location(iter, 0);
                double y = mesher.location(iter, 1);
                double z = mesher.location(iter, 2);

                double d = -Math.Cos(x) * Math.Sin(y) * Math.Exp(z);

                if (Math.Abs(d - t[i]) > tol)
                {
                    QAssert.Fail("numerical derivative in dxdy deviation is too big"
                                 + "\n  found at " + x + " " + y + " " + z);
                }

                if (Math.Abs(t[i] - u[i]) > 1e5 * Const.QL_EPSILON)
                {
                    QAssert.Fail("numerical derivative in dxdy not equal to dydx"
                                 + "\n  found at " + x + " " + y + " " + z
                                 + "\n  value    " + Math.Abs(t[i] - u[i]));
                }
            }

            t = new SecondOrderMixedDerivativeOp(0, 2, mesher).apply(r);
            u = new SecondOrderMixedDerivativeOp(2, 0, mesher).apply(r);
            for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter)
            {
                int    i = iter.index();
                double x = mesher.location(iter, 0);
                double y = mesher.location(iter, 1);
                double z = mesher.location(iter, 2);

                double d = Math.Cos(x) * Math.Cos(y) * Math.Exp(z);

                if (Math.Abs(d - t[i]) > tol)
                {
                    QAssert.Fail("numerical derivative in dxdy deviation is too big"
                                 + "\n  found at " + x + " " + y + " " + z);
                }

                if (Math.Abs(t[i] - u[i]) > 1e5 * Const.QL_EPSILON)
                {
                    QAssert.Fail("numerical derivative in dxdz not equal to dzdx"
                                 + "\n  found at " + x + " " + y + " " + z
                                 + "\n  value    " + Math.Abs(t[i] - u[i]));
                }
            }

            t = new SecondOrderMixedDerivativeOp(1, 2, mesher).apply(r);
            u = new SecondOrderMixedDerivativeOp(2, 1, mesher).apply(r);
            for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter)
            {
                int    i = iter.index();
                double x = mesher.location(iter, 0);
                double y = mesher.location(iter, 1);
                double z = mesher.location(iter, 2);

                double d = -Math.Sin(x) * Math.Sin(y) * Math.Exp(z);

                if (Math.Abs(d - t[i]) > tol)
                {
                    QAssert.Fail("numerical derivative in dydz deviation is too big"
                                 + "\n  found at " + x + " " + y + " " + z);
                }

                if (Math.Abs(t[i] - u[i]) > 1e5 * Const.QL_EPSILON)
                {
                    QAssert.Fail("numerical derivative in dydz not equal to dzdy"
                                 + "\n  found at " + x + " " + y + " " + z
                                 + "\n  value    " + Math.Abs(t[i] - u[i]));
                }
            }
        }
Exemple #4
0
        public void testSecondDerivativesMapApply()
        {
            int[]      dims = new int[] { 50, 50, 50 };
            List <int> dim  = new List <int>(dims);

            FdmLinearOpLayout index = new FdmLinearOpLayout(dim);

            List <Pair <double?, double?> > boundaries = new List <Pair <double?, double?> > ();

            boundaries.Add(new Pair <double?, double?>(0, 0.5));
            boundaries.Add(new Pair <double?, double?>(0, 0.5));
            boundaries.Add(new Pair <double?, double?>(0, 0.5));

            FdmMesher mesher = new UniformGridMesher(index, boundaries);

            Vector r = new Vector(mesher.layout().size());
            FdmLinearOpIterator endIter = index.end();

            for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter)
            {
                double x = mesher.location(iter, 0);
                double y = mesher.location(iter, 1);
                double z = mesher.location(iter, 2);

                r[iter.index()] = Math.Sin(x) * Math.Cos(y) * Math.Exp(z);
            }

            Vector t = new SecondDerivativeOp(0, mesher).apply(r);

            double tol = 5e-2;

            for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter)
            {
                int    i = iter.index();
                double x = mesher.location(iter, 0);
                double y = mesher.location(iter, 1);
                double z = mesher.location(iter, 2);

                double d = -Math.Sin(x) * Math.Cos(y) * Math.Exp(z);
                if (iter.coordinates()[0] == 0 || iter.coordinates()[0] == dims[0] - 1)
                {
                    d = 0;
                }

                if (Math.Abs(d - t[i]) > tol)
                {
                    QAssert.Fail("numerical derivative in dx^2 deviation is too big"
                                 + "\n  found at " + x + " " + y + " " + z);
                }
            }

            t = new SecondDerivativeOp(1, mesher).apply(r);
            for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter)
            {
                int    i = iter.index();
                double x = mesher.location(iter, 0);
                double y = mesher.location(iter, 1);
                double z = mesher.location(iter, 2);

                double d = -Math.Sin(x) * Math.Cos(y) * Math.Exp(z);
                if (iter.coordinates()[1] == 0 || iter.coordinates()[1] == dims[1] - 1)
                {
                    d = 0;
                }

                if (Math.Abs(d - t[i]) > tol)
                {
                    QAssert.Fail("numerical derivative in dy^2 deviation is too big"
                                 + "\n  found at " + x + " " + y + " " + z);
                }
            }

            t = new SecondDerivativeOp(2, mesher).apply(r);
            for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter)
            {
                int    i = iter.index();
                double x = mesher.location(iter, 0);
                double y = mesher.location(iter, 1);
                double z = mesher.location(iter, 2);

                double d = Math.Sin(x) * Math.Cos(y) * Math.Exp(z);
                if (iter.coordinates()[2] == 0 || iter.coordinates()[2] == dims[2] - 1)
                {
                    d = 0;
                }

                if (Math.Abs(d - t[i]) > tol)
                {
                    QAssert.Fail("numerical derivative in dz^2 deviation is too big"
                                 + "\n  found at " + x + " " + y + " " + z);
                }
            }
        }
Exemple #5
0
        public void testFirstDerivativesMapApply()
        {
            int[]      dims = new int[] { 400, 100, 50 };
            List <int> dim  = new List <int>(dims);

            FdmLinearOpLayout index = new FdmLinearOpLayout(dim);

            List <Pair <double?, double?> > boundaries = new List <Pair <double?, double?> > ();

            boundaries.Add(new Pair <double?, double?>(-5, 5));
            boundaries.Add(new Pair <double?, double?>(0, 10));
            boundaries.Add(new Pair <double?, double?>(5, 15));

            FdmMesher mesher = new UniformGridMesher(index, boundaries);

            FirstDerivativeOp map = new FirstDerivativeOp(2, mesher);

            Vector r = new Vector(mesher.layout().size());
            FdmLinearOpIterator endIter = index.end();

            for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter)
            {
                r[iter.index()] = Math.Sin(mesher.location(iter, 0))
                                  + Math.Cos(mesher.location(iter, 2));
            }

            Vector t  = map.apply(r);
            double dz = (boundaries[2].second.Value - boundaries[2].first.Value) / (dims[2] - 1);

            for (FdmLinearOpIterator iter = index.begin(); iter != endIter; ++iter)
            {
                int z = iter.coordinates()[2];

                int    z0  = (z > 0) ? z - 1 : 1;
                int    z2  = (z < dims[2] - 1) ? z + 1 : dims[2] - 2;
                double lz0 = boundaries[2].first.Value + z0 * dz;
                double lz2 = boundaries[2].first.Value + z2 * dz;

                double expected;
                if (z == 0)
                {
                    expected = (Math.Cos(boundaries[2].first.Value + dz)
                                - Math.Cos(boundaries[2].first.Value)) / dz;
                }
                else if (z == dim[2] - 1)
                {
                    expected = (Math.Cos(boundaries[2].second.Value)
                                - Math.Cos(boundaries[2].second.Value - dz)) / dz;
                }
                else
                {
                    expected = (Math.Cos(lz2) - Math.Cos(lz0)) / (2 * dz);
                }

                double calculated = t[iter.index()];
                if (Math.Abs(calculated - expected) > 1e-10)
                {
                    QAssert.Fail("first derivative calculation failed."
                                 + "\n    calculated: " + calculated
                                 + "\n    expected:   " + expected);
                }
            }
        }