Esempio n. 1
0
        /// <summary>
        /// Developed by: Mehrdad Negahban
        /// Date: 11/12/2012
        ///
        /// Purpose: Construct Quadrature points and weights for different number of integration points
        /// Comments: Gaussian
        ///
        /// Date modified:
        /// Modified by:
        /// Comments:
        /// </summary>
        public static QuadratureRule_ND Make_QuadratureRule_Rectangular_Gaussian_LxMxNPoints(int L_NIP, int M_NIP, int N_NIP)
        {
            QuadratureRule    QR_L  = GaussianQuadratureRule.MakeGaussianQuadrature(L_NIP);
            QuadratureRule    QR_M  = GaussianQuadratureRule.MakeGaussianQuadrature(M_NIP);
            QuadratureRule    QR_N  = GaussianQuadratureRule.MakeGaussianQuadrature(N_NIP);
            QuadratureRule_ND QR_ND = new QuadratureRule_ND();

            QR_ND.NIP = L_NIP * M_NIP * N_NIP;
            QR_ND.wi  = new double[QR_ND.NIP];
            QR_ND.Xi  = new Vector[QR_ND.NIP];
            int Index = 0;

            for (int i = 0; i < L_NIP; i++)
            {
                for (int j = 0; j < M_NIP; j++)
                {
                    for (int k = 0; k < N_NIP; k++)
                    {
                        QR_ND.wi[Index]       = QR_L.wi[i] * QR_M.wi[j] * QR_N.wi[k];
                        QR_ND.Xi[i]           = new Vector(3);
                        QR_ND.Xi[i].Values[0] = QR_L.Xi[i];
                        QR_ND.Xi[i].Values[1] = QR_M.Xi[j];
                        QR_ND.Xi[i].Values[2] = QR_N.Xi[k];
                    }
                }
            }
            return(QR_ND);
        }
Esempio n. 2
0
    private static void triangle_unit_monomial_test(int degree_max)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    TRIANGLE_UNIT_MONOMIAL_TEST tests TRIANGLE_UNIT_MONOMIAL.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    16 April 2009
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int DEGREE_MAX, the maximum total degree of the
    //    monomials to check.
    //
    {
        int alpha;
        int beta;

        int[] expon = new int[2];

        Console.WriteLine("");
        Console.WriteLine("TRIANGLE_UNIT_MONOMIAL_TEST");
        Console.WriteLine("  For the unit triangle,");
        Console.WriteLine("  TRIANGLE_UNIT_MONOMIAL returns the exact value of the");
        Console.WriteLine("  integral of X^ALPHA Y^BETA");
        Console.WriteLine("");
        Console.WriteLine("  Volume = " + QuadratureRule.triangle_unit_volume() + "");
        Console.WriteLine("");
        Console.WriteLine("     ALPHA      BETA      INTEGRAL");
        Console.WriteLine("");

        for (alpha = 0; alpha <= degree_max; alpha++)
        {
            expon[0] = alpha;
            for (beta = 0; beta <= degree_max - alpha; beta++)
            {
                expon[1] = beta;

                double value = QuadratureRule.triangle_unit_monomial(expon);

                Console.WriteLine("  " + expon[0].ToString(CultureInfo.InvariantCulture).PadLeft(8)
                                  + "  " + expon[1].ToString(CultureInfo.InvariantCulture).PadLeft(8)
                                  + "  " + value.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
            }
        }
    }
Esempio n. 3
0
    private static void test03(int degree, int n, string header)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    TEST03 gets a rule and creates GNUPLOT input files.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU GPL license.
    //
    //  Modified:
    //
    //    09 July 2014
    //
    //  Author:
    //
    //    Original FORTRAN77 version by Hong Xiao, Zydrunas Gimbutas.
    //    C++ version by John Burkardt.
    //
    //  Reference:
    //
    //    Hong Xiao, Zydrunas Gimbutas,
    //    A numerical algorithm for the construction of efficient quadrature
    //    rules in two and higher dimensions,
    //    Computers and Mathematics with Applications,
    //    Volume 59, 2010, pages 663-676.
    //
    //  Parameters:
    //
    //    Input, int DEGREE, the desired total polynomial degree exactness
    //    of the quadrature rule.  0 <= DEGREE <= 50.
    //
    //    Input, int N, the number of nodes to be used by the rule.
    //
    //    Input, string HEADER, an identifier for the filenames.
    //
    {
        Console.WriteLine("");
        Console.WriteLine("TEST03");
        Console.WriteLine("  Get a quadrature rule for the symmetric cube.");
        Console.WriteLine("  Set up GNUPLOT graphics input.");
        Console.WriteLine("  Polynomial exactness degree DEGREE = " + degree + "");
        //
        //  Retrieve a symmetric quadrature rule.
        //
        double[] x = new double[3 * n];
        double[] w = new double[n];

        QuadratureRule.cube_arbq(degree, n, ref x, ref w);
        //
        //  Create files for input to GNUPLOT.
        //
        QuadratureRule.cube_arbq_gnuplot(n, x, header);
    }
Esempio n. 4
0
    private static void Main()
    //****************************************************************************80
    //
    //  Purpose:
    //
    //    MAIN is the main program for CUBE_ARBQ_RULE_TEST.
    //
    //  Discussion:
    //
    //    CUBE_ARBQ_RULE_TEST tests the CUBE_ARBQ_RULE library.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU GPL license.
    //
    //  Modified:
    //
    //    09 July 2014
    //
    //  Author:
    //
    //    Original FORTRAN77 version by Hong Xiao, Zydrunas Gimbutas.
    //    C++ version by John Burkardt.
    //
    //  Reference:
    //
    //    Hong Xiao, Zydrunas Gimbutas,
    //    A numerical algorithm for the construction of efficient quadrature
    //    rules in two and higher dimensions,
    //    Computers and Mathematics with Applications,
    //    Volume 59, 2010, pages 663-676.
    //
    {
        Console.WriteLine("");
        Console.WriteLine("CUBE_ARBQ_RULE_TEST");
        Console.WriteLine("  C version");
        Console.WriteLine("  Test the CUBE_ARBQ_RULE library.");

        int    degree = 8;
        int    n      = QuadratureRule.cube_arbq_size(degree);
        string header = "cube08";

        test01(degree, n);

        test02(degree, n, header);

        test03(degree, n, header);

        test04(degree, n);

        Console.WriteLine("");
        Console.WriteLine("CUBE_ARBQ_RULE_TEST");
        Console.WriteLine("  Normal end of execution.");
        Console.WriteLine("");
    }
Esempio n. 5
0
        /// <summary>
        /// Developed by: Mehrdad Negahban
        /// Date: 11/12/2012
        ///
        /// Purpose: Construct Quadrature points and weights for different number of integration points
        /// Comments: Gaussian
        ///
        /// Date modified:
        /// Modified by:
        /// Comments:
        /// </summary>
        public static QuadratureRule_ND Make_QuadratureRule_Gaussian_NPoint(int NIP)
        {
            QuadratureRule    QR    = GaussianQuadratureRule.MakeGaussianQuadrature(NIP);
            QuadratureRule_ND QR_ND = new QuadratureRule_ND();

            QR_ND.NIP = NIP;
            QR_ND.wi  = QR.wi;
            QR_ND.Xi  = new Vector[NIP];
            for (int i = 0; i < NIP; i++)
            {
                QR_ND.Xi[i]           = new Vector(1);
                QR_ND.Xi[i].Values[0] = QR.Xi[i];
            }
            return(QR_ND);
        }
Esempio n. 6
0
    private static void Main()
    //****************************************************************************80
    //
    //  Purpose:
    //
    //    MAIN is the main program for CUBE_FELIPPA_RULE_TEST.
    //
    //  Discussion:
    //
    //    CUBE_FELIPPA_RULE_TEST tests the CUBE_FELIPPA_RULE library.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    05 September 2014
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        Console.WriteLine("");
        Console.WriteLine("CUBE_FELIPPA_RULE_TEST");
        Console.WriteLine("  Test the CUBE_FELIPPA_RULE library.");

        int degree_max = 4;

        Integrals.cube_monomial_test(degree_max);

        degree_max = 6;
        QuadratureRule.cube_quad_test(degree_max);

        Console.WriteLine("");
        Console.WriteLine("CUBE_FELIPPA_RULE_TEST");
        Console.WriteLine("  Normal end of execution.");
        Console.WriteLine("");
    }
        /// <summary>
        /// Developed by: Mehrdad Negahban
        /// Date: 11/12/2012
        ///
        /// Purpose: Construct Quadrature points and weights for different number of integration points
        /// Comments: Gaussian
        ///
        /// Date modified:
        /// Modified by:
        /// Comments:
        /// </summary>
        public static QuadratureRule_ND Make_QuadratureRule_Rectangular_Gaussian_MxNPoints(int M_NIP, int N_NIP)
        {
            QuadratureRule    QR_M  = GaussianQuadratureRule.MakeGaussianQuadrature(M_NIP);
            QuadratureRule    QR_N  = GaussianQuadratureRule.MakeGaussianQuadrature(N_NIP);
            QuadratureRule_ND QR_ND = new QuadratureRule_ND();

            QR_ND.NIP = M_NIP * N_NIP;
            QR_ND.wi  = new double[QR_ND.NIP];
            QR_ND.Xi  = new Vector[QR_ND.NIP];
            int Index = 0;

            for (int i = 0; i < M_NIP; i++)
            {
                for (int j = 0; j < N_NIP; j++)
                {
                    QR_ND.wi[Index]           = QR_M.wi[i] * QR_N.wi[j];
                    QR_ND.Xi[Index]           = new Vector(2);
                    QR_ND.Xi[Index].Values[0] = QR_M.Xi[i];
                    QR_ND.Xi[Index].Values[1] = QR_N.Xi[j];
                    Index++;
                }
            }
            return(QR_ND);
        }
Esempio n. 8
0
    private static void Main(string[] args)
    //****************************************************************************80
    //
    //  Purpose:
    //
    //    MAIN is the main program for GEN_LAGUERRE_RULE.
    //
    //  Discussion:
    //
    //    This program computes a standard or exponentially weighted
    //    Gauss-Laguerre quadrature rule and writes it to a file.
    //
    //    The user specifies:
    //    * the ORDER (number of points) in the rule;
    //    * ALPHA, the exponent of |X|;
    //    * A, the left endpoint;
    //    * B, the scale factor in the exponential;
    //    * FILENAME, the root name of the output files.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    23 February 2010
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        double a;
        double alpha;
        double b;
        string filename;
        int    order;

        Console.WriteLine("");
        Console.WriteLine("");
        Console.WriteLine("GEN_LAGUERRE_RULE");
        Console.WriteLine("");
        Console.WriteLine("  Compute a generalized Gauss-Laguerre rule for approximating");
        Console.WriteLine("    Integral ( a <= x < +oo ) |x-a|^ALPHA exp(-B*x(x-a)) f(x) dx");
        Console.WriteLine("  of order ORDER.");
        Console.WriteLine("");
        Console.WriteLine("  The user specifies ORDER, ALPHA, A, B, and FILENAME.");
        Console.WriteLine("");
        Console.WriteLine("  ORDER is the number of points in the rule:");
        Console.WriteLine("  ALPHA is the exponent of |X|:");
        Console.WriteLine("  A is the left endpoint (typically 0).");
        Console.WriteLine("  B is the exponential scale factor, typically 1:");
        Console.WriteLine("  FILENAME is used  to generate 3 files:");
        Console.WriteLine("  * filename_w.txt - the weight file");
        Console.WriteLine("  * filename_x.txt - the abscissa file.");
        Console.WriteLine("  * filename_r.txt - the region file.");
        //
        //  Initialize parameters;
        //
        double beta = 0.0;

        //
        //  Get ORDER.
        //
        try
        {
            order = Convert.ToInt32(args[0]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the value of ORDER (1 or greater)");
            order = Convert.ToInt32(Console.ReadLine());
        }

        //
        //  Get ALPHA.
        //
        try
        {
            alpha = Convert.ToDouble(args[1]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the value of ALPHA.");
            Console.WriteLine("  ( -1.0 < ALPHA is required.)");
            alpha = Convert.ToDouble(Console.ReadLine());
        }

        //
        //  Get A.
        //
        try
        {
            a = Convert.ToDouble(args[2]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the left endpoint A.");
            a = Convert.ToDouble(Console.ReadLine());
        }

        //
        //  Get B.
        //
        try
        {
            b = Convert.ToDouble(args[3]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the value of B");
            b = Convert.ToDouble(Console.ReadLine());
        }

        //
        //  Get FILENAME.
        //
        try
        {
            filename = args[4];
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter FILENAME the \"root name\" of the quadrature files).");
            filename = Console.ReadLine();
        }

        //
        //  Input summary.
        //
        Console.WriteLine("");
        Console.WriteLine("  ORDER = " + order + "");
        Console.WriteLine("  ALPHA = " + alpha + "");
        Console.WriteLine("  A = " + a + "");
        Console.WriteLine("  B = " + b + "");
        Console.WriteLine("  FILENAME \"" + filename + "\".");
        //
        //  Construct the rule.
        //
        double[] w = new double[order];
        double[] x = new double[order];

        int kind = 5;

        CGQF.cgqf(order, kind, alpha, beta, a, b, ref x, ref w);
        //
        //  Write the rule.
        //
        double[] r = new double[2];
        r[0] = a;
        r[1] = typeMethods.r8_huge();

        QuadratureRule.rule_write(order, filename, x, w, r);

        Console.WriteLine("");
        Console.WriteLine("GEN_LAGUERRE_RULE:");
        Console.WriteLine("  Normal end of execution.");
        Console.WriteLine("");
    }
Esempio n. 9
0
    private static void Main()

    /****************************************************************************80
     * //
     * //  Purpose:
     * //
     * //    MAIN is the main program for FEM2D_POISSON_RECTANGLE.
     * //
     * //  Discussion:
     * //
     * //    FEM2D_POISSON_RECTANGLE solves
     * //
     * //      -Laplacian U(X,Y) = F(X,Y)
     * //
     * //    in a rectangular region in the plane.  Along the boundary,
     * //    Dirichlet boundary conditions are imposed.
     * //
     * //      U(X,Y) = G(X,Y)
     * //
     * //    The code uses continuous piecewise quadratic basis functions on
     * //    triangles determined by a uniform grid of NX by NY points.
     * //
     * //  Licensing:
     * //
     * //    This code is distributed under the GNU LGPL license.
     * //
     * //  Modified:
     * //
     * //    23 September 2008
     * //
     * //  Author:
     * //
     * //    John Burkardt
     * //
     * //  Local parameters:
     * //
     * //    Local, double A[(3*IB+1)*NUNK], the coefficient matrix.
     * //
     * //    Local, double ELEMENT_AREA[ELEMENT_NUM], the area of each element.
     * //
     * //    Local, double C[NUNK], the finite element coefficients, solution of A * C = F.
     * //
     * //    Local, double EH1, the H1 seminorm error.
     * //
     * //    Local, double EL2, the L2 error.
     * //
     * //    Local, int ELEMENT_NODE[ELEMENT_NUM*NNODES]; ELEMENT_NODE(I,J) is the
     * //    global node index of the local node J in element I.
     * //
     * //    Local, int ELEMENT_NUM, the number of elements.
     * //
     * //    Local, double F[NUNK], the right hand side.
     * //
     * //    Local, int IB, the half-bandwidth of the matrix.
     * //
     * //    Local, int INDX[NODE_NUM], gives the index of the unknown quantity
     * //    associated with the given node.
     * //
     * //    Local, int NNODES, the number of nodes used to form one element.
     * //
     * //    Local, double NODE_XY[2*NODE_NUM], the X and Y coordinates of nodes.
     * //
     * //    Local, int NQ, the number of quadrature points used for assembly.
     * //
     * //    Local, int NUNK, the number of unknowns.
     * //
     * //    Local, int NX, the number of points in the X direction.
     * //
     * //    Local, int NY, the number of points in the Y direction.
     * //
     * //    Local, double WQ[NQ], quadrature weights.
     * //
     * //    Local, double XL, XR, YB, YT, the X coordinates of
     * //    the left and right sides of the rectangle, and the Y coordinates
     * //    of the bottom and top of the rectangle.
     * //
     * //    Local, double XQ[NQ*ELEMENT_NUM], YQ[NQ*ELEMENT_NUM], the X and Y
     * //    coordinates of the quadrature points in each element.
     */
    {
        const int NNODES      = 6;
        const int NQ          = 3;
        const int NX          = 7;
        const int NY          = 7;
        const int ELEMENT_NUM = (NX - 1) * (NY - 1) * 2;
        const int NODE_NUM    = (2 * NX - 1) * (2 * NY - 1);

        double eh1 = 0;
        double el2 = 0;

        double[]     element_area       = new double[ELEMENT_NUM];
        int[]        element_node       = new int[NNODES * ELEMENT_NUM];
        int[]        indx               = new int[NODE_NUM];
        const string node_eps_file_name = "fem2d_poisson_rectangle_nodes.eps";
        const string node_txt_file_name = "fem2d_poisson_rectangle_nodes.txt";

        double[]     node_xy = new double[2 * NODE_NUM];
        int          nunk    = 0;
        const string solution_txt_file_name      = "fem2d_poisson_rectangle_solution.txt";
        const string triangulation_eps_file_name = "fem2d_poisson_rectangle_elements.eps";
        const string triangulation_txt_file_name = "fem2d_poisson_rectangle_elements.txt";

        double[]     wq = new double[NQ];
        const double xl = 0.0E+00;

        double[]     xq = new double[NQ * ELEMENT_NUM];
        const double xr = 1.0E+00;
        const double yb = 0.0E+00;

        double[]     yq = new double[NQ * ELEMENT_NUM];
        const double yt = 1.0E+00;

        Console.WriteLine("");
        Console.WriteLine("FEM2D_POISSON_RECTANGLE:");
        Console.WriteLine("");
        Console.WriteLine("  Solution of the Poisson equation on a unit box");
        Console.WriteLine("  in 2 dimensions.");
        Console.WriteLine("");
        Console.WriteLine("  - Uxx - Uyy = F(x,y) in the box");
        Console.WriteLine("       U(x,y) = G(x,y) on the boundary.");
        Console.WriteLine("");
        Console.WriteLine("  The finite element method is used, with piecewise");
        Console.WriteLine("  quadratic basis functions on 6 node triangular");
        Console.WriteLine("  elements.");
        Console.WriteLine("");
        Console.WriteLine("  The corner nodes of the triangles are generated by an");
        Console.WriteLine("  underlying grid whose dimensions are");
        Console.WriteLine("");
        Console.WriteLine("  NX =                 " + NX + "");
        Console.WriteLine("  NY =                 " + NY + "");
        Console.WriteLine("");
        Console.WriteLine("  Number of nodes    = " + NODE_NUM + "");
        Console.WriteLine("  Number of elements = " + ELEMENT_NUM + "");
        //
        //  Set the coordinates of the nodes.
        //
        XY.xy_set(NX, NY, NODE_NUM, xl, xr, yb, yt, ref node_xy);
        //
        //  Organize the nodes into a grid of 6-node triangles.
        //
        Grid.grid_t6(NX, NY, NNODES, ELEMENT_NUM, ref element_node);
        //
        //  Set the quadrature rule for assembly.
        //
        QuadratureRule.quad_a(node_xy, element_node, ELEMENT_NUM, NODE_NUM,
                              NNODES, ref wq, ref xq, ref yq);
        //
        //  Determine the areas of the elements.
        //
        Element.area_set(NODE_NUM, node_xy, NNODES, ELEMENT_NUM,
                         element_node, element_area);
        //
        //  Determine which nodes are boundary nodes and which have a
        //  finite element unknown.  Then set the boundary values.
        //
        Burkardt.FEM.Boundary.indx_set(NX, NY, NODE_NUM, ref indx, ref nunk);

        Console.WriteLine("  Number of unknowns =       " + nunk + "");
        //
        //  Determine the bandwidth of the coefficient matrix.
        //
        int ib = Matrix.bandwidth(NNODES, ELEMENT_NUM, element_node, NODE_NUM, indx);

        Console.WriteLine("");
        Console.WriteLine("  Total bandwidth is " + 3 * ib + 1 + "");
        switch (NX)
        {
        //
        //  Make an EPS picture of the nodes.
        //
        case <= 10 when NY <= 10:
            bool node_label = true;
            typeMethods.nodes_plot(node_eps_file_name, NODE_NUM, node_xy, node_label);

            Console.WriteLine("");
            Console.WriteLine("FEM2D_POISSON_RECTANGLE:");
            Console.WriteLine("  Wrote an EPS file");
            Console.WriteLine("    \"" + node_eps_file_name + "\".");
            Console.WriteLine("  containing a picture of the nodes.");
            break;
        }

        //
        //  Write the nodes to an ASCII file that can be read into MATLAB.
        //
        typeMethods.nodes_write(NODE_NUM, node_xy, node_txt_file_name);

        Console.WriteLine("");
        Console.WriteLine("FEM2D_POISSON_RECTANGLE:");
        Console.WriteLine("  Wrote an ASCII node file");
        Console.WriteLine("    " + node_txt_file_name + "");
        Console.WriteLine("  of the form");
        Console.WriteLine("    X(I), Y(I)");
        Console.WriteLine("  which can be used for plotting.");
        switch (NX)
        {
        //
        //  Make a picture of the elements.
        //
        case <= 10 when NY <= 10:
            int node_show     = 1;
            int triangle_show = 2;

            Plot.triangulation_order6_plot(triangulation_eps_file_name, NODE_NUM,
                                           node_xy, ELEMENT_NUM, element_node, node_show, triangle_show);

            Console.WriteLine("");
            Console.WriteLine("FEM2D_POISSON_RECTANGLE:");
            Console.WriteLine("  Wrote an EPS file");
            Console.WriteLine("    \"" + triangulation_eps_file_name + "\".");
            Console.WriteLine("  containing a picture of the elements.");
            break;
        }

        //
        //  Write the elements to a file that can be read into MATLAB.
        //
        Element.element_write(NNODES, ELEMENT_NUM, element_node,
                              triangulation_txt_file_name);

        Console.WriteLine("");
        Console.WriteLine("FEM2D_POISSON_RECTANGLE:");
        Console.WriteLine("  Wrote an ASCII element file");
        Console.WriteLine("    \"" + triangulation_txt_file_name + "\".");
        Console.WriteLine("  of the form");
        Console.WriteLine("    Node(1) Node(2) Node(3) Node(4) Node(5) Node(6)");
        Console.WriteLine("  which can be used for plotting.");
        //
        //  Allocate space for the coefficient matrix A and right hand side F.
        //
        double[] a     = new double[(3 * ib + 1) * nunk];
        double[] f     = new double[nunk];
        int[]    pivot = new int[nunk];
        //
        //  Assemble the coefficient matrix A and the right-hand side F of the
        //  finite element equations.
        //
        Matrix.assemble(NODE_NUM, node_xy, NNODES,
                        ELEMENT_NUM, element_node, NQ,
                        wq, xq, yq, element_area, indx, ib, nunk, ref a, ref f);
        //
        //  Print a tiny portion of the matrix.
        //
        Matrix.dgb_print_some(nunk, nunk, ib, ib, a, 1, 1, 5, 5,
                              "  Initial 5 x 5 block of coefficient matrix A:");

        typeMethods.r8vec_print_some(nunk, f, 10, "  Part of the right hand side F:");
        //
        //  Modify the coefficient matrix and right hand side to account for
        //  boundary conditions.
        //
        Burkardt.FEM.Boundary.boundary(NX, NY, NODE_NUM, node_xy, indx, ib, nunk, ref a, ref f, exact);
        //
        //  Print a tiny portion of the matrix.
        //
        Matrix.dgb_print_some(nunk, nunk, ib, ib, a, 1, 1, 5, 5,
                              "  A after boundary adjustment:");

        typeMethods.r8vec_print_some(nunk, f, 10, "  F after boundary adjustment:");
        //
        //  Solve the linear system using a banded solver.
        //
        int ierr = Matrix.dgb_fa(nunk, ib, ib, ref a, ref pivot);

        if (ierr != 0)
        {
            Console.WriteLine("");
            Console.WriteLine("FEM2D_POISSON_RECTANGLE - Error!");
            Console.WriteLine("  DGB_FA returned an error condition.");
            Console.WriteLine("");
            Console.WriteLine("  The linear system was not factored, and the");
            Console.WriteLine("  algorithm cannot proceed.");
            return;
        }

        int job = 0;

        double[] c = Matrix.dgb_sl(nunk, ib, ib, a, pivot, f, job);

        typeMethods.r8vec_print_some(nunk, c, 10, "  Part of the solution vector:");
        //
        //  Calculate error using 13 point quadrature rule.
        //
        QuadratureRule.errors(element_area, element_node, indx, node_xy, c,
                              ELEMENT_NUM, NNODES, nunk, NODE_NUM, ref el2, ref eh1, exact);
        //
        //  Compare the exact and computed solutions just at the nodes.
        //
        typeMethods.compare(NODE_NUM, node_xy, indx, nunk, c, exact);
        //
        //  Write an ASCII file that can be read into MATLAB.
        //
        typeMethods.solution_write(c, indx, NODE_NUM, nunk, solution_txt_file_name,
                                   node_xy, exact);

        Console.WriteLine("");
        Console.WriteLine("FEM2D_POISSON_RECTANGLE:");
        Console.WriteLine("  Wrote an ASCII solution file");
        Console.WriteLine("    " + solution_txt_file_name + "");
        Console.WriteLine("  of the form");
        Console.WriteLine("    U( X(I), Y(I) )");
        Console.WriteLine("  which can be used for plotting.");

        Console.WriteLine("");
        Console.WriteLine("FEM2D_POISSON_RECTANGLE:");
        Console.WriteLine("  Normal end of execution.");

        Console.WriteLine("");
    }
Esempio n. 10
0
    public static void sparse_grid_laguerre(int dim_num, int level_max, int point_num,
                                            ref double[] grid_weight, ref double[] grid_point)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    SPARSE_GRID_LAGUERRE computes a sparse grid of Gauss-Laguerre points.
    //
    //  Discussion:
    //
    //    The quadrature rule is associated with a sparse grid derived from
    //    a Smolyak construction using a 1D Gauss-Laguerre quadrature rule.
    //
    //    The user specifies:
    //    * the spatial dimension of the quadrature region,
    //    * the level that defines the Smolyak grid.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    05 July 2008
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Reference:
    //
    //    Fabio Nobile, Raul Tempone, Clayton Webster,
    //    A Sparse Grid Stochastic Collocation Method for Partial Differential
    //    Equations with Random Input Data,
    //    SIAM Journal on Numerical Analysis,
    //    Volume 46, Number 5, 2008, pages 2309-2345.
    //
    //  Parameters:
    //
    //    Input, int DIM_NUM, the spatial dimension.
    //
    //    Input, int LEVEL_MAX, controls the size of the final sparse grid.
    //
    //    Input, int POINT_NUM, the number of points in the grid, as determined
    //    by SPARSE_GRID_LAGUERRE_SIZE.
    //
    //    Output, double GRID_WEIGHT[POINT_NUM], the weights.
    //
    //    Output, double GRID_POINT[DIM_NUM*POINT_NUM], the points.
    //
    {
        int level;
        int point;

        for (point = 0; point < point_num; point++)
        {
            grid_weight[point] = 0.0;
        }

        //
        //  The outer loop generates LEVELs from LEVEL_MIN to LEVEL_MAX.
        //
        int point_num2 = 0;

        int level_min = Math.Max(0, level_max + 1 - dim_num);

        int[] grid_base2 = new int[dim_num];
        int[] level_1d   = new int[dim_num];
        int[] order_1d   = new int[dim_num];

        for (level = level_min; level <= level_max; level++)
        {
            //
            //  The middle loop generates the next partition LEVEL_1D(1:DIM_NUM)
            //  that adds up to LEVEL.
            //
            bool more = false;
            int  h    = 0;
            int  t    = 0;

            for (;;)
            {
                Comp.comp_next(level, dim_num, ref level_1d, ref more, ref h, ref t);
                //
                //  Transform each 1D level to a corresponding 1D order.
                //  The relationship is the same as for other OPEN rules.
                //
                ClenshawCurtis.level_to_order_open(dim_num, level_1d, ref order_1d);

                int dim;
                for (dim = 0; dim < dim_num; dim++)
                {
                    grid_base2[dim] = order_1d[dim];
                }

                //
                //  The product of the 1D orders gives us the number of points in this grid.
                //
                int order_nd = typeMethods.i4vec_product(dim_num, order_1d);
                //
                //  Compute the weights for this product grid.
                //
                double[] grid_weight2 = QuadratureRule.product_weight_laguerre(dim_num, order_1d, order_nd);
                //
                //  Now determine the coefficient of the weight.
                //
                int coeff = (int)(Math.Pow(-1, level_max - level)
                                  * Binomial.choose(dim_num - 1, level_max - level));
                //
                //  The inner (hidden) loop generates all points corresponding to given grid.
                //  The grid indices will be between -M to +M, where 2*M + 1 = ORDER_1D(DIM).
                //
                int[] grid_index2 = Multigrid.multigrid_index_one(dim_num, order_1d, order_nd);

                for (point = 0; point < order_nd; point++)
                {
                    QuadratureRule.laguerre_abscissa(dim_num, 1, grid_index2,
                                                     grid_base2, ref grid_point, gridIndex: +point * dim_num,
                                                     gridPointIndex: +point_num2 * dim_num);

                    grid_weight[point_num2] = coeff * grid_weight2[point];

                    point_num2 += 1;
                }

                if (!more)
                {
                    break;
                }
            }
        }
    }
Esempio n. 11
0
    public static double tetra_07(int setting, Func <int, double, double, double, double> func, double[] x,
                                  double[] y, double[] z)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    TETRA_07 approximates an integral inside a tetrahedron in 3D.
    //
    //  Integration region:
    //
    //    Points inside a tetrahedron whose four corners are given.
    //
    //  Discussion:
    //
    //    A 64 point 7-th degree conical product Gauss formula is used,
    //    Stroud number T3:7-1.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    15 March 2008
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Reference:
    //
    //    Arthur Stroud,
    //    Approximate Calculation of Multiple Integrals,
    //    Prentice Hall, 1971,
    //    ISBN: 0130438936,
    //    LC: QA311.S85.
    //
    //    Arthur Stroud, Don Secrest,
    //    Gaussian Quadrature Formulas,
    //    Prentice Hall, 1966, pages 42-43,
    //    LC: QA299.4G3S7
    //
    //  Parameters:
    //
    //    Input, Func< double, double, double, double > func, the name of the
    //    user supplied function to be integrated.
    //
    //    Input, double X[4], Y[4], Z[4], the coordinates of
    //    the vertices.
    //
    //    Output, double TETRAQ_07, the approximate integral of the function.
    //
    {
        int       i;
        const int order = 4;

        double[] weight1 = new double[4];
        double[] weight2 =
        {
            0.1355069134, 0.2034645680, 0.1298475476, 0.0311809709
        };
        double[] weight3 =
        {
            0.1108884156, 0.1434587898, 0.0686338872, 0.0103522407
        };
        double[] xtab1 = new double[4];
        double[] xtab2 =
        {
            0.0571041961, 0.2768430136, 0.5835904324, 0.8602401357
        };
        double[] xtab3 =
        {
            0.0485005495, 0.2386007376, 0.5170472951, 0.7958514179
        };
        //
        //  Get the Gauss-Legendre weights and abscissas for [-1,1].
        //
        LegendreQuadrature.legendre_set(order, ref xtab1, ref weight1);
        //
        //  Adjust the rule for the interval [0,1].
        //
        const double a = -1.0;
        const double b = +1.0;

        const double c = 0.0;
        const double d = 1.0;

        QuadratureRule.rule_adjust(a, b, c, d, order, ref xtab1, ref weight1);
        //
        //  Carry out the quadrature.
        //
        double quad = 0.0;

        for (i = 0; i < order; i++)
        {
            int j;
            for (j = 0; j < order; j++)
            {
                int k;
                for (k = 0; k < order; k++)
                {
                    //
                    //  Compute the barycentric coordinates of the point in the unit triangle.
                    //
                    double t = xtab3[k];
                    double u = xtab2[j] * (1.0 - xtab3[k]);
                    double v = xtab1[i] * (1.0 - xtab2[j]) * (1.0 - xtab3[k]);
                    double w = 1.0 - t - u - v;
                    //
                    //  Compute the corresponding point in the triangle.
                    //
                    double xval = t * x[0] + u * x[1] + v * x[2] + w * x[3];
                    double yval = t * y[0] + u * y[1] + v * y[2] + w * y[3];
                    double zval = t * z[0] + u * z[1] + v * z[2] + w * z[3];

                    quad += 6.0 * weight1[i] * weight2[j] * weight3[k]
                            * func(setting, xval, yval, zval);
                }
            }
        }

        double volume = tetra_volume(x, y, z);
        double result = quad * volume;

        return(result);
    }
Esempio n. 12
0
    private static void Main(string[] args)
    //****************************************************************************80
    //
    //  Purpose:
    //
    //    MAIN is the main program for LAGUERRE_RULE_SS.
    //
    //  Discussion:
    //
    //    This program computes a standard or exponentially weighted
    //    Gauss-Laguerre quadrature rule and writes it to a file.
    //
    //    The user specifies:
    //    * the ORDER (number of points) in the rule
    //    * the OPTION (standard or reweighted rule)
    //    * the root name of the output files.
    //
    //    The parameter A is meant to represent the left endpoint of the interval
    //    of integration, and is currently fixed at 0.  It might be useful to allow
    //    the user to input a nonzero value of A.  In that case, the weights and
    //    abscissa would need to be appropriately adjusted.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    20 February 2008
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        const double a = 0.0;
        int          option;
        int          order;
        string       output;

        Console.WriteLine("");
        Console.WriteLine("");
        Console.WriteLine("LAGUERRE_RULE_SS");
        Console.WriteLine("");
        Console.WriteLine("  Compute a Gauss-Laguerre rule for approximating");
        Console.WriteLine("");
        Console.WriteLine("    Integral ( A <= x < +oo ) exp(-x) f(x) dx");
        Console.WriteLine("");
        Console.WriteLine("  of order ORDER.");
        Console.WriteLine("");
        Console.WriteLine("  For now, A is fixed at 0.0.");
        Console.WriteLine("");
        Console.WriteLine("  The user specifies ORDER, OPTION, and OUTPUT.");
        Console.WriteLine("");
        Console.WriteLine("  OPTION is:");
        Console.WriteLine("");
        Console.WriteLine("    0 to get the standard rule for handling:");
        Console.WriteLine("      Integral ( A <= x < +oo ) exp(-x) f(x) dx");
        Console.WriteLine("");
        Console.WriteLine("    1 to get the modified rule for handling:");
        Console.WriteLine("      Integral ( A <= x < +oo )         f(x) dx");
        Console.WriteLine("");
        Console.WriteLine("    For OPTION = 1, the weights of the standard rule");
        Console.WriteLine("    are multiplied by exp(+x).");
        Console.WriteLine("");
        Console.WriteLine("  OUTPUT is:");
        Console.WriteLine("");
        Console.WriteLine("  \"C++\" for printed C++ output;");
        Console.WriteLine("  \"F77\" for printed Fortran77 output;");
        Console.WriteLine("  \"F90\" for printed Fortran90 output;");
        Console.WriteLine("  \"MAT\" for printed MATLAB output;");
        Console.WriteLine("");
        Console.WriteLine("  or:");
        Console.WriteLine("");
        Console.WriteLine("  \"filename\" to generate 3 files:");
        Console.WriteLine("");
        Console.WriteLine("    filename_w.txt - the weight file");
        Console.WriteLine("    filename_x.txt - the abscissa file.");
        Console.WriteLine("    filename_r.txt - the region file.");
        //
        //  Get the order.
        //
        try
        {
            order = Convert.ToInt32(args[0]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the value of ORDER (1 or greater)");
            order = Convert.ToInt32(Console.ReadLine());
        }

        Console.WriteLine("");
        Console.WriteLine("  The requested order of the rule is = " + order + "");
        //
        //  Get the option.
        //
        try
        {
            option = Convert.ToInt32(args[1]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  OPTION = 0 to get the standard rule for handling:");
            Console.WriteLine("      Integral ( A <= x < +oo ) exp(-x) f(x) dx");
            Console.WriteLine("");
            Console.WriteLine("  OPTION = 1 to get the modified rule for handling:");
            Console.WriteLine("      Integral ( A <= x < +oo )         f(x) dx");
            Console.WriteLine("");
            Console.WriteLine("  Enter the value of OPTION:");
            option = Convert.ToInt32(Console.ReadLine());
        }

        Console.WriteLine("");
        Console.WriteLine("  The requested value of OPTION = " + option + "");
        //
        //  Get the output option or quadrature file root name:
        //
        try
        {
            output = args[2];
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter OUTPUT (one of C++, F77, F90, MAT");
            Console.WriteLine("  or else the \"root name\" of the quadrature files).");
            output = Console.ReadLine();
        }

        Console.WriteLine("");
        Console.WriteLine("  OUTPUT option is \"" + output + "\".");
        //
        //  Construct the rule and output it.
        //
        QuadratureRule.laguerre_handle(order, a, option, output);
        //
        //  Terminate.
        //
        Console.WriteLine("");
        Console.WriteLine("LAGUERRE_RULE_SS:");
        Console.WriteLine("  Normal end of execution.");
        Console.WriteLine("");
    }
Esempio n. 13
0
    private static void Main(string[] args)
    //****************************************************************************80
    //
    //  Purpose:
    //
    //    MAIN is the main program for JACOBI_RULE.
    //
    //  Discussion:
    //
    //    This program computes a standard Gauss-Jacobi quadrature rule
    //    and writes it to a file.
    //
    //    The user specifies:
    //    * the ORDER (number of points) in the rule
    //    * ALPHA, the exponent of ( 1 - x );
    //    * BETA, the exponent of ( 1 + x );
    //    * A, the left endpoint;
    //    * B, the right endpoint;
    //    * FILENAME, the root name of the output files.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    28 February 2010
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        double a;
        double alpha;
        double b;
        double beta;
        string filename;
        int    order;

        Console.WriteLine("");
        Console.WriteLine("JACOBI_RULE");
        Console.WriteLine("");
        Console.WriteLine("  Compute a Gauss-Jacobi quadrature rule for approximating");
        Console.WriteLine("    Integral ( A <= x <= B ) (B-x)^alpha (x-A)^beta f(x) dx");
        Console.WriteLine("  of order ORDER.");
        Console.WriteLine("");
        Console.WriteLine("  The user specifies ORDER, ALPHA, BETA, A, B, and FILENAME.");
        Console.WriteLine("");
        Console.WriteLine("  ORDER is the number of points.");
        Console.WriteLine("  ALPHA is the exponent of ( B - x );");
        Console.WriteLine("  BETA is the exponent of ( x - A );");
        Console.WriteLine("  A is the left endpoint");
        Console.WriteLine("  B is the right endpoint");
        Console.WriteLine("  FILENAME is used to generate 3 files:");
        Console.WriteLine("    filename_w.txt - the weight file");
        Console.WriteLine("    filename_x.txt - the abscissa file.");
        Console.WriteLine("    filename_r.txt - the region file.");
        //
        //  Get ORDER.
        //
        try
        {
            order = Convert.ToInt32(args[0]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the value of ORDER (1 or greater)");
            order = Convert.ToInt32(Console.ReadLine());
        }

        //
        //  Get ALPHA.
        //
        try
        {
            alpha = Convert.ToDouble(args[1]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  ALPHA is the exponent of (B-x) in the integral:");
            Console.WriteLine("  Note that -1.0 < ALPHA is required.");
            Console.WriteLine("  Enter the value of ALPHA:");
            alpha = Convert.ToDouble(Console.ReadLine());
        }

        //
        //  Get BETA.
        //
        try
        {
            beta = Convert.ToDouble(args[2]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  BETA is the exponent of (x-A) in the integral:");
            Console.WriteLine("  Note that -1.0 < BETA is required.");
            Console.WriteLine("  Enter the value of BETA:");
            beta = Convert.ToDouble(Console.ReadLine());
        }

        //
        //  Get A.
        //
        try
        {
            a = Convert.ToDouble(args[3]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the value of A:");
            a = Convert.ToDouble(Console.ReadLine());
        }

        //
        //  Get B.
        //
        try
        {
            b = Convert.ToDouble(args[4]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the value of B:");
            b = Convert.ToDouble(Console.ReadLine());
        }

        //
        //  Get FILENAME.
        //
        try
        {
            filename = args[5];
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter FILENAME, the \"root name\" of the quadrature files).");
            filename = Console.ReadLine();
        }

        //
        //  Input summary.
        //
        Console.WriteLine("");
        Console.WriteLine("  ORDER = = " + order + "");
        Console.WriteLine("  ALPHA = " + alpha + "");
        Console.WriteLine("  BETA = " + beta + "");
        Console.WriteLine("  A = " + a + "");
        Console.WriteLine("  B = " + b + "");
        Console.WriteLine("  FILENAME is \"" + filename + "\".");
        //
        //  Construct the rule.
        //
        double[] w = new double[order];
        double[] x = new double[order];

        int kind = 4;

        CGQF.cgqf(order, kind, alpha, beta, a, b, ref x, ref w);
        //
        //  Write the rule.
        //
        double[] r = new double[2];
        r[0] = a;
        r[1] = b;

        QuadratureRule.rule_write(order, filename, x, w, r);

        Console.WriteLine("");
        Console.WriteLine("JACOBI_RULE:");
        Console.WriteLine("  Normal end of execution.");
        Console.WriteLine("");
    }
    public static void nwspgr(Func <int, double[], double[], ClenshawCurtis.ccResult> rule,
                              Func <int, int> rule_order, int dim, int k, int r_size, ref int s_size,
                              ref double[] nodes, ref double[] weights)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    NWSPGR generates nodes and weights for sparse grid integration.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    19 April 2013
    //
    //  Author:
    //
    //    Original MATLAB version by Florian Heiss, Viktor Winschel.
    //    C++ version by John Burkardt.
    //
    //  Reference:
    //
    //    Florian Heiss, Viktor Winschel,
    //    Likelihood approximation by numerical integration on sparse grids,
    //    Journal of Econometrics,
    //    Volume 144, 2008, pages 62-80.
    //
    //  Parameters:
    //
    //    Input, void RULE ( int n, double x[], double w[] ), the name of a function
    //    which is given the order N and returns the points X and weights W of the
    //    corresponding 1D quadrature rule.
    //
    //    Input, int RULE_ORDER ( int l ), the name of a function which
    //    is given the level L and returns the order N of the corresponding 1D rule.
    //
    //    Input, int DIM, the spatial dimension.
    //
    //    Input, int K, the level of the sparse rule.
    //
    //    Input, int R_SIZE, the "size" of the sparse rule.
    //
    //    Output, int &S_SIZE, the size of the sparse rule, after
    //    duplicate points have been merged.
    //
    //    Output, double NODES[DIM*R_SIZE], the nodes of the sparse rule.
    //
    //    Output, double WEIGHTS[R_SIZE], the weights of the sparse rule.
    //
    {
        int i;
        int j;
        int level;
        int n;
        int q;

        for (j = 0; j < r_size; j++)
        {
            for (i = 0; i < dim; i++)
            {
                nodes[i + j * dim] = 0.0;
            }
        }

        for (j = 0; j < r_size; j++)
        {
            weights[j] = 0.0;
        }

        //
        //  Create cell arrays that will contain the points and weights
        //  for levels 1 through K.
        //
        int[] n1d     = new int[k];
        int[] x1d_off = new int[k + 1];
        int[] w1d_off = new int[k + 1];

        x1d_off[0] = 0;
        w1d_off[0] = 0;

        for (level = 1; level <= k; level++)
        {
            n = rule_order(level);
            n1d[level - 1] = n;
            x1d_off[level] = x1d_off[level - 1] + n;
            w1d_off[level] = w1d_off[level - 1] + n;
        }

        int n1d_total = x1d_off[k];

        //
        //  Calculate all the 1D rules needed.
        //
        double[] x1d = new double[n1d_total];
        double[] w1d = new double[n1d_total];

        for (level = 1; level <= k; level++)
        {
            n = n1d[level - 1];

            double[] x = new double[n];
            double[] w = new double[n];

            ClenshawCurtis.ccResult result = rule(n, x, w);
            x = result.x;
            w = result.w;

            typeMethods.r8cvv_rset(n1d_total, x1d, k, x1d_off, level - 1, x);
            typeMethods.r8cvv_rset(n1d_total, w1d, k, w1d_off, level - 1, w);
        }

        //
        //  Construct the sparse grid.
        //
        int minq = Math.Max(0, k - dim);
        int maxq = k - 1;

        //
        //  Q is the level total.
        //
        int[] lr = new int[dim];
        int[] nr = new int[dim];

        int r = 0;

        for (q = minq; q <= maxq; q++)
        {
            //
            //  BQ is the combinatorial coefficient applied to the component
            //  product rules which have level Q.
            //
            int bq = typeMethods.i4_mop(maxq - q) * typeMethods.i4_choose(dim - 1, dim + q - k);
            //
            //  Compute the D-dimensional row vectors that sum to DIM+Q.
            //
            int seq_num = Comp.num_seq(q, dim);

            int[] is_ = Comp.get_seq(dim, q + dim, seq_num);
            //
            //  Allocate new rows for nodes and weights.
            //
            int[] rq = new int[seq_num];

            for (j = 0; j < seq_num; j++)
            {
                rq[j] = 1;
                for (i = 0; i < dim; i++)
                {
                    level  = is_[j + i * seq_num] - 1;
                    rq[j] *= n1d[level];
                }
            }

            //
            //  Generate every product rule whose level total is Q.
            //
            int j2;
            for (j2 = 0; j2 < seq_num; j2++)
            {
                for (i = 0; i < dim; i++)
                {
                    lr[i] = is_[j2 + i * seq_num];
                }

                for (i = 0; i < dim; i++)
                {
                    nr[i] = rule_order(lr[i]);
                }

                int[] roff = typeMethods.r8cvv_offset(dim, nr);

                int      nc = typeMethods.i4vec_sum(dim, nr);
                double[] wc = new double[nc];
                double[] xc = new double[nc];
                //
                //  Corrected first argument in calls to R8CVV to N1D_TOTAL,
                //  19 April 2013.
                //
                for (i = 0; i < dim; i++)
                {
                    double[] xr = typeMethods.r8cvv_rget_new(n1d_total, x1d, k, x1d_off, lr[i] - 1);
                    double[] wr = typeMethods.r8cvv_rget_new(n1d_total, w1d, k, w1d_off, lr[i] - 1);
                    typeMethods.r8cvv_rset(nc, xc, dim, roff, i, xr);
                    typeMethods.r8cvv_rset(nc, wc, dim, roff, i, wr);
                }

                int      np = rq[j2];
                double[] wp = new double[np];
                double[] xp = new double[dim * np];

                typeMethods.tensor_product_cell(nc, xc, wc, dim, nr, roff, np, ref xp, ref wp);
                //
                //  Append the new nodes and weights to the arrays.
                //
                for (j = 0; j < np; j++)
                {
                    for (i = 0; i < dim; i++)
                    {
                        nodes[i + (r + j) * dim] = xp[i + j * dim];
                    }
                }

                for (j = 0; j < np; j++)
                {
                    weights[r + j] = bq * wp[j];
                }

                //
                //  Update the count.
                //
                r += rq[j2];
            }
        }

        //
        //  Reorder the rule so the points are in ascending lexicographic order.
        //
        QuadratureRule.rule_sort(dim, r_size, ref nodes, ref weights);
        //
        //  Suppress duplicate points and merge weights.
        //
        r = 0;
        for (j = 1; j < r_size; j++)
        {
            bool equal = true;
            for (i = 0; i < dim; i++)
            {
                if (!(Math.Abs(nodes[i + r * dim] - nodes[i + j * dim]) > double.Epsilon))
                {
                    continue;
                }

                equal = false;
                break;
            }

            switch (equal)
            {
            case true:
                weights[r] += weights[j];
                break;

            default:
            {
                r         += 1;
                weights[r] = weights[j];
                for (i = 0; i < dim; i++)
                {
                    nodes[i + r * dim] = nodes[i + j * dim];
                }

                break;
            }
            }
        }

        r     += 1;
        s_size = r;
        //
        //  Zero out unneeded entries.
        //
        for (j = r; j < r_size; j++)
        {
            for (i = 0; i < dim; i++)
            {
                nodes[i + j * dim] = 0.0;
            }
        }

        for (j = r; j < r_size; j++)
        {
            weights[j] = 0.0;
        }

        //
        //  Normalize the weights to sum to 1.
        //
        double t = typeMethods.r8vec_sum(r, weights);

        for (j = 0; j < r; j++)
        {
            weights[j] /= t;
        }
    }
Esempio n. 15
0
    public static void assemble_poisson(int node_num, double[] node_xy,
                                        int element_num, int[] element_node, int quad_num, int ib, ref double[] a,
                                        ref double[] f, Func <int, double[], double[]> rhs, Func <int, double[], double[]> h_coef,
                                        Func <int, double[], double[]> k_coef)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    ASSEMBLE_POISSON assembles the system for the Poisson equation.
    //
    //  Discussion:
    //
    //    The matrix is known to be banded.  A special matrix storage format
    //    is used to reduce the space required.  Details of this format are
    //    discussed in the routine DGB_FA.
    //
    //    Note that a 3 point quadrature rule, which is sometimes used to
    //    assemble the matrix and right hand side, is just barely accurate
    //    enough for simple problems.  If you want better results, you
    //    should use a quadrature rule that is more accurate.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    06 December 2010
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int NODE_NUM, the number of nodes.
    //
    //    Input, double NODE_XY[2*NODE_NUM], the coordinates of nodes.
    //
    //    Input, int ELEMENT_NUM, the number of elements.
    //
    //    Input, int ELEMENT_NODE[3*ELEMENT_NUM];
    //    ELEMENT_NODE(I,J) is the global index of local node I in element J.
    //
    //    Input, int QUAD_NUM, the number of quadrature points used in assembly.
    //
    //    Input, int IB, the half-bandwidth of the matrix.
    //
    //    Output, double A(3*IB+1,NODE_NUM), the NODE_NUM by NODE_NUM
    //    coefficient matrix, stored in a compressed format.
    //
    //    Output, double F(NODE_NUM), the right hand side.
    //
    //  Local parameters:
    //
    //    Local, double BI, DBIDX, DBIDY, the value of some basis function
    //    and its first derivatives at a quadrature point.
    //
    //    Local, double BJ, DBJDX, DBJDY, the value of another basis
    //    function and its first derivatives at a quadrature point.
    //
    {
        double bi    = 0;
        double bj    = 0;
        double dbidx = 0;
        double dbidy = 0;
        double dbjdx = 0;
        double dbjdy = 0;
        int    element;
        int    i;
        int    node;

        double[] p  = new double[2];
        double[] t3 = new double[2 * 3];

        double[] phys_h   = new double[quad_num];
        double[] phys_k   = new double[quad_num];
        double[] phys_rhs = new double[quad_num];
        double[] phys_xy  = new double[2 * quad_num];
        double[] quad_w   = new double[quad_num];
        double[] quad_xy  = new double[2 * quad_num];
        double[] w        = new double[quad_num];
        //
        //  Initialize the arrays to zero.
        //
        for (node = 0; node < node_num; node++)
        {
            f[node] = 0.0;
        }

        for (node = 0; node < node_num; node++)
        {
            for (i = 0; i < 3 * ib + 1; i++)
            {
                a[i + node * (3 * ib + 1)] = 0.0;
            }
        }

        //
        //  Get the quadrature weights and nodes.
        //
        QuadratureRule.quad_rule(quad_num, ref quad_w, ref quad_xy);
        //
        //  Add up all quantities associated with the ELEMENT-th element.
        //
        for (element = 0; element < element_num; element++)
        {
            //
            //  Make a copy of the element.
            //
            int j;
            for (j = 0; j < 3; j++)
            {
                for (i = 0; i < 2; i++)
                {
                    t3[i + j * 2] = node_xy[i + (element_node[j + element * 3] - 1) * 2];
                }
            }

            //
            //  Map the quadrature points QUAD_XY to points PHYS_XY in the physical element.
            //
            Reference.reference_to_physical_t3(t3, quad_num, quad_xy, ref phys_xy);

            double area = Math.Abs(typeMethods.triangle_area_2d(t3));

            int quad;
            for (quad = 0; quad < quad_num; quad++)
            {
                w[quad] = quad_w[quad] * area;
            }

            phys_rhs = rhs(quad_num, phys_xy);
            phys_h   = h_coef(quad_num, phys_xy);
            phys_k   = k_coef(quad_num, phys_xy);
            //
            //  Consider the QUAD-th quadrature point.
            //
            for (quad = 0; quad < quad_num; quad++)
            {
                p[0] = phys_xy[0 + quad * 2];
                p[1] = phys_xy[1 + quad * 2];
                //
                //  Consider the TEST-th test function.
                //
                //  We generate an integral for every node associated with an unknown.
                //  But if a node is associated with a boundary condition, we do nothing.
                //
                int test;
                for (test = 1; test <= 3; test++)
                {
                    i = element_node[test - 1 + element * 3];

                    Basis11.basis_one_t3(t3, test, p, ref bi, ref dbidx, ref dbidy);

                    f[i - 1] += w[quad] * phys_rhs[quad] * bi;
                    //
                    //  Consider the BASIS-th basis function, which is used to form the
                    //  value of the solution function.
                    //
                    int basis;
                    for (basis = 1; basis <= 3; basis++)
                    {
                        j = element_node[basis - 1 + element * 3];

                        Basis11.basis_one_t3(t3, basis, p, ref bj, ref dbjdx, ref dbjdy);

                        a[i - j + 2 * ib + (j - 1) * (3 * ib + 1)] += w[quad] * (
                            phys_h[quad] *
                            (dbidx * dbjdx + dbidy * dbjdy)
                            + phys_k[quad] * bj * bi);
                    }
                }
            }
        }
    }
Esempio n. 16
0
    private static void test04(int degree, int n)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    TEST04 gets a rule and tests its accuracy.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU GPL license.
    //
    //  Modified:
    //
    //    09 July 2014
    //
    //  Author:
    //
    //    Original FORTRAN77 version by Hong Xiao, Zydrunas Gimbutas.
    //    C++ version by John Burkardt.
    //
    //  Reference:
    //
    //    Hong Xiao, Zydrunas Gimbutas,
    //    A numerical algorithm for the construction of efficient quadrature
    //    rules in two and higher dimensions,
    //    Computers and Mathematics with Applications,
    //    Volume 59, 2010, pages 663-676.
    //
    //  Parameters:
    //
    //    Input, int DEGREE, the desired total polynomial degree exactness
    //    of the quadrature rule.  0 <= DEGREE <= 50.
    //
    //    Input, int N, the number of nodes to be used by the rule.
    //
    {
        int i;
        int j;

        double[] z = new double[3];

        Console.WriteLine("");
        Console.WriteLine("TEST04");
        Console.WriteLine("  Get a quadrature rule for the symmetric cube.");
        Console.WriteLine("  Test its accuracy.");
        Console.WriteLine("  Polynomial exactness degree DEGREE = " + degree + "");
        //
        //  Retrieve a symmetric quadrature rule.
        //
        double[] x = new double[3 * n];
        double[] w = new double[n];

        QuadratureRule.cube_arbq(degree, n, ref x, ref w);

        int npols = (degree + 1) * (degree + 2) * (degree + 3) / 6;

        double[] rints = new double[npols];

        for (j = 0; j < npols; j++)
        {
            rints[j] = 0.0;
        }

        for (i = 0; i < n; i++)
        {
            z[0] = x[0 + i * 3];
            z[1] = x[1 + i * 3];
            z[2] = x[2 + i * 3];

            double[] pols = QuadratureRule.lege3eva(degree, z);
            for (j = 0; j < npols; j++)
            {
                rints[j] += w[i] * pols[j];
            }
        }

        double volume = 8.0;

        double d = 0.0;

        d = Math.Pow(rints[0] - Math.Sqrt(volume), 2);
        for (i = 1; i < npols; i++)
        {
            d += Math.Pow(rints[i], 2);
        }

        d = Math.Sqrt(d) / npols;

        Console.WriteLine("");
        Console.WriteLine("  RMS error = " + d + "");
    }
Esempio n. 17
0
    private static void test01(int degree, int n)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    TEST01 calls CUBE_ARBQ for a quadrature rule of given order.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU GPL license.
    //
    //  Modified:
    //
    //    09 July 2014
    //
    //  Author:
    //
    //    Original FORTRAN77 version by Hong Xiao, Zydrunas Gimbutas.
    //    C++ version by John Burkardt.
    //
    //  Reference:
    //
    //    Hong Xiao, Zydrunas Gimbutas,
    //    A numerical algorithm for the construction of efficient quadrature
    //    rules in two and higher dimensions,
    //    Computers and Mathematics with Applications,
    //    Volume 59, 2010, pages 663-676.
    //
    //  Parameters:
    //
    //    Input, int DEGREE, the desired total polynomial degree exactness
    //    of the quadrature rule.
    //
    //    Input, int N, the number of nodes.
    //
    {
        int j;

        Console.WriteLine("");
        Console.WriteLine("TEST01");
        Console.WriteLine("  Symmetric quadrature rule for a cube.");
        Console.WriteLine("  Polynomial exactness degree DEGREE = " + degree + "");

        double volume = 8.0;

        //
        //  Retrieve and print a symmetric quadrature rule.
        //
        double[] x = new double[3 * n];
        double[] w = new double[n];

        QuadratureRule.cube_arbq(degree, n, ref x, ref w);

        Console.WriteLine("");
        Console.WriteLine("  Number of nodes N = " + n + "");

        Console.WriteLine("");
        Console.WriteLine("     J  W       X       Y      Z");
        Console.WriteLine("");
        for (j = 0; j < n; j++)
        {
            Console.WriteLine(j.ToString(CultureInfo.InvariantCulture).PadLeft(4) + "  "
                              + w[j].ToString(CultureInfo.InvariantCulture).PadLeft(14) + "  "
                              + x[0 + j * 3].ToString(CultureInfo.InvariantCulture).PadLeft(14) + "  "
                              + x[1 + j * 3].ToString(CultureInfo.InvariantCulture).PadLeft(14) + "  "
                              + x[2 + j * 3].ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
        }

        double d = typeMethods.r8vec_sum(n, w);

        Console.WriteLine("   Sum    " + d + "");
        Console.WriteLine("  Volume  " + volume + "");
    }
Esempio n. 18
0
    private static void Main(string[] args)
    //****************************************************************************80
    //
    //  Purpose:
    //
    //    MAIN is the main program for TRUNCATED_NORMAL_RULE.
    //
    //  Discussion:
    //
    //    This program computes a truncated normal quadrature rule
    //    and writes it to a file.
    //
    //    The user specifies:
    //    * option: 0/1/2/3 for none, lower, upper, double truncation.
    //    * N, the number of points in the rule;
    //    * MU, the mean of the original normal distribution;
    //    * SIGMA, the standard deviation of the original normal distribution,
    //    * A, the left endpoint (for options 1 or 3)
    //    * B, the right endpoint (for options 2 or 3);
    //    * FILENAME, the root name of the output files.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    20 September 2013
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        double a;
        double b;
        string filename;

        double[] moment = new double[1];
        double   mu;
        int      n;
        int      option;
        double   sigma;

        Console.WriteLine("");
        Console.WriteLine("TRUNCATED_NORMAL_RULE");
        Console.WriteLine("");
        Console.WriteLine("  For the (truncated) Gaussian probability density function");
        Console.WriteLine("    pdf(x) = exp(-0.5*((x-MU)/SIGMA)^2) / SIGMA / sqrt ( 2 * pi )");
        Console.WriteLine("  compute an N-point quadrature rule for approximating");
        Console.WriteLine("    Integral ( A <= x <= B ) f(x) pdf(x) dx");
        Console.WriteLine("");
        Console.WriteLine("  The value of OPTION determines the truncation interval [A,B]:");
        Console.WriteLine("  0: (-oo,+oo)");
        Console.WriteLine("  1: [A,+oo)");
        Console.WriteLine("  2: (-oo,B]");
        Console.WriteLine("  3: [A,B]");
        Console.WriteLine("");
        Console.WriteLine("  The user specifies OPTION, N, MU, SIGMA, A, B and FILENAME.");
        Console.WriteLine("");
        Console.WriteLine("  FILENAME is used to generate 3 files:");
        Console.WriteLine("");
        Console.WriteLine("    filename_w.txt - the weight file");
        Console.WriteLine("    filename_x.txt - the abscissa file.");
        Console.WriteLine("    filename_r.txt - the region file, listing A and B.");

        int iarg = 0;

        //
        //  Get OPTION.
        //
        try
        {
            option = Convert.ToInt32(args[iarg]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the value of OPTION 0/1/2/3:  ");
            option = Convert.ToInt32(Console.ReadLine());
        }

        switch (option)
        {
        case < 0:
        case > 3:
            Console.WriteLine("");
            Console.WriteLine("TRUNCATED_NORMAL_RULE - Fatal error!");
            Console.WriteLine("  0 <= OPTION <= 3 was required.");
            return;
        }

        //
        //  Get N.
        //
        iarg += 1;
        try
        {
            n = Convert.ToInt32(args[iarg]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the value of N (1 or greater)");
            n = Convert.ToInt32(Console.ReadLine());
        }

        //
        //  Get MU.
        //
        iarg += 1;
        try
        {
            mu = Convert.ToDouble(args[iarg]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter MU, the mean value of the normal distribution:");
            mu = Convert.ToDouble(Console.ReadLine());
        }

        //
        //  Get SIGMA.
        //
        iarg += 1;
        try
        {
            sigma = Convert.ToDouble(args[iarg]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter SIGMA, the standard deviation of the normal distribution:");
            sigma = Convert.ToDouble(Console.ReadLine());
        }

        sigma = Math.Abs(sigma);
        switch (option)
        {
        //
        //  Get A.
        //
        case 1:
        case 3:
            iarg += 1;
            try
            {
                a = Convert.ToDouble(args[iarg]);
            }
            catch
            {
                Console.WriteLine("");
                Console.WriteLine("  Enter the left endpoint A:");
                a = Convert.ToDouble(Console.ReadLine());
            }

            break;

        default:
            a = -typeMethods.r8_huge();
            break;
        }

        switch (option)
        {
        //
        //  Get B.
        //
        case 2:
        case 3:
            iarg += 1;
            try
            {
                b = Convert.ToDouble(args[iarg]);
            }
            catch
            {
                Console.WriteLine("");
                Console.WriteLine("  Enter the right endpoint B:");
                b = Convert.ToDouble(Console.ReadLine());
            }

            break;

        default:
            b = typeMethods.r8_huge();
            break;
        }

        if (b <= a)
        {
            Console.WriteLine("");
            Console.WriteLine("TRUNCATED_NORMAL_RULE - Fatal error!");
            Console.WriteLine("  A < B required!");
            return;
        }

        //
        //  Get FILENAME:
        //
        iarg += 1;
        try
        {
            filename = args[iarg];
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter FILENAME, the \"root name\" of the quadrature files).");
            filename = Console.ReadLine();
        }

        //
        //  Input summary.
        //
        Console.WriteLine("");
        Console.WriteLine("  OPTION = " + option + "");
        Console.WriteLine("  N = " + n + "");
        Console.WriteLine("  MU = " + mu + "");
        Console.WriteLine("  SIGMA = " + sigma + "");
        Console.WriteLine("  A = " + a + "");
        Console.WriteLine("  B = " + b + "");
        Console.WriteLine("  FILENAME = \"" + filename + "\".");
        moment = option switch
        {
            //
            //  Compute the moments.
            //
            0 => Moments.moments_normal(2 * n + 1, mu, sigma),
            1 => Moments.moments_truncated_normal_a(2 * n + 1, mu, sigma, a),
            2 => Moments.moments_truncated_normal_b(2 * n + 1, mu, sigma, b),
            3 => Moments.moments_truncated_normal_ab(2 * n + 1, mu, sigma, a, b),
            _ => moment
        };

        //
        //  Construct the rule from the moments.
        //
        double[] w = new double[n];
        double[] x = new double[n];

        Moments.moment_method(n, moment, ref x, ref w);
        //
        //  Output the rule.
        //
        double[] r = new double[2];
        r[0] = a;
        r[1] = b;

        QuadratureRule.rule_write(n, filename, x, w, r);

        Console.WriteLine("");
        Console.WriteLine("TRUNCATED_NORMAL_RULE:");
        Console.WriteLine("  Normal end of execution.");
        Console.WriteLine("");
    }
}
Esempio n. 19
0
    private static void test02(int degree, int n, string header)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    TEST02 gets a rule and writes it to a file.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU GPL license.
    //
    //  Modified:
    //
    //    09 July 2014
    //
    //  Author:
    //
    //    Original FORTRAN77 version by Hong Xiao, Zydrunas Gimbutas.
    //    C++ version by John Burkardt.
    //
    //  Reference:
    //
    //    Hong Xiao, Zydrunas Gimbutas,
    //    A numerical algorithm for the construction of efficient quadrature
    //    rules in two and higher dimensions,
    //    Computers and Mathematics with Applications,
    //    Volume 59, 2010, pages 663-676.
    //
    //  Parameters:
    //
    //    Input, int DEGREE, the desired total polynomial degree exactness
    //    of the quadrature rule.  0 <= DEGREE <= 50.
    //
    //    Input, int N, the number of nodes to be used by the rule.
    //
    //    Input, string HEADER, an identifier for the filenames.
    //
    {
        int           i;
        List <string> rule_unit = new();

        Console.WriteLine("");
        Console.WriteLine("TEST02");
        Console.WriteLine("  Get a quadrature rule for the symmetric cube.");
        Console.WriteLine("  Then write it to a file.");
        Console.WriteLine("  Polynomial exactness degree DEGREE = " + degree + "");
        //
        //  Retrieve a symmetric quadrature rule.
        //
        double[] x = new double[3 * n];
        double[] w = new double[n];

        QuadratureRule.cube_arbq(degree, n, ref x, ref w);
        //
        //  Write the points and weights to a file.
        //
        string rule_filename = header + ".txt";

        for (i = 0; i < n; i++)
        {
            rule_unit.Add(+x[0 + i * 3] + "  "
                          + x[1 + i * 3] + "  "
                          + x[2 + i * 3] + "  "
                          + w[i] + "");
        }

        File.WriteAllLines(rule_filename, rule_unit);
        Console.WriteLine("");
        Console.WriteLine("  Quadrature rule written to file '" + rule_filename + "'");
    }
Esempio n. 20
0
    private static void test01(int nt)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    TEST01 tests CIRCLE_RULE.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    06 April 2014
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        int[] e = new int[2];
        int   e1;

        Console.WriteLine("");
        Console.WriteLine("TEST01");
        Console.WriteLine("  CIRCLE_RULE can compute a rule Q(f) for the unit circle");
        Console.WriteLine("  using NT equally spaced angles.");
        Console.WriteLine("  Estimate integrals I(f) where f = x^e(1) * y^e(2)");
        Console.WriteLine("  using " + nt + " points.");
        //
        //  Compute the quadrature rule.
        //
        double[] w = new double[nt];
        double[] t = new double[nt];

        QuadratureRule.circle_rule(nt, ref w, ref t);
        //
        //  Apply it to integrands.
        //
        Console.WriteLine("");
        Console.WriteLine("  E(1)  E(2)    I(f)            Q(f)");
        Console.WriteLine("");
        //
        //  Specify a monomial.
        //
        for (e1 = 0; e1 <= 6; e1 += 2)
        {
            e[0] = e1;

            int e2;
            for (e2 = e1; e2 <= 6; e2 += 2)
            {
                e[1] = e2;

                double q = 0.0;
                int    i;
                for (i = 0; i < nt; i++)
                {
                    double x = Math.Cos(t[i]);
                    double y = Math.Sin(t[i]);
                    q += w[i] * Math.Pow(x, e[0]) * Math.Pow(y, e[1]);
                }

                q = 2.0 * Math.PI * q;

                double exact = Integrals.circle01_monomial_integral(e);

                Console.WriteLine("  " + e[0].ToString(CultureInfo.InvariantCulture).PadLeft(2)
                                  + "  " + e[1].ToString(CultureInfo.InvariantCulture).PadLeft(2)
                                  + "  " + exact.ToString(CultureInfo.InvariantCulture).PadLeft(14)
                                  + "  " + q.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");
            }
        }
    }
Esempio n. 21
0
    private static void Main(string[] args)
    //****************************************************************************80
    //
    //  Purpose:
    //
    //    MAIN is the main program for PYRAMID_RULE.
    //
    //  Discussion:
    //
    //    This program computes a quadrature rule for a pyramid
    //    and writes it to a file.
    //
    //    The user specifies:
    //    * the LEGENDRE_ORDER (number of points in the X and Y dimensions)
    //    * the JACOBI_ORDER (number of points in the Z dimension)
    //    * FILENAME, the root name of the output files.
    //
    //    The integration region is:
    //
    //      - ( 1 - Z ) <= X <= 1 - Z
    //      - ( 1 - Z ) <= Y <= 1 - Z
    //                0 <= Z <= 1.
    //
    //    When Z is zero, the integration region is a square lying in the (X,Y)
    //    plane, centered at (0,0,0) with "radius" 1.  As Z increases to 1, the
    //    radius of the square diminishes, and when Z reaches 1, the square has
    //    contracted to the single point (0,0,1).
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    23 July 2009
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        string filename;
        int    jacobi_order;
        int    legendre_order;

        Console.WriteLine("");
        Console.WriteLine("PYRAMID_RULE");
        Console.WriteLine("");
        Console.WriteLine("  Compute a quadrature rule for approximating");
        Console.WriteLine("  the integral of a function over a pyramid.");
        Console.WriteLine("");
        Console.WriteLine("  The user specifies:");
        Console.WriteLine("");
        Console.WriteLine("  LEGENDRE_ORDER, the order of the Legendre rule for X and Y.");
        Console.WriteLine("  JACOBI_ORDER, the order of the Jacobi rule for Z,");
        Console.WriteLine("  FILENAME, the prefix of the three output files:");
        Console.WriteLine("");
        Console.WriteLine("    filename_w.txt - the weight file");
        Console.WriteLine("    filename_x.txt - the abscissa file.");
        Console.WriteLine("    filename_r.txt - the region file.");
        //
        //  Get the Legendre order.
        //
        try
        {
            legendre_order = Convert.ToInt32(args[0]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the Legendre rule order:");
            legendre_order = Convert.ToInt32(Console.ReadLine());
        }

        Console.WriteLine("");
        Console.WriteLine("  The requested Legendre order of the rule is " + legendre_order + "");
        //
        //  Get the Jacobi order.
        //
        try
        {
            jacobi_order = Convert.ToInt32(args[1]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the Jacobi rule order:");
            jacobi_order = Convert.ToInt32(Console.ReadLine());
        }

        Console.WriteLine("");
        Console.WriteLine("  The requested Jacobi order of the rule is " + jacobi_order + "");
        //
        //  Get the output option or quadrature file root name:
        //
        try
        {
            filename = args[2];
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter FILENAME, the root name of the quadrature files.");
            filename = Console.ReadLine();
        }

        QuadratureRule.pyramid_handle(legendre_order, jacobi_order, filename);

        Console.WriteLine("");
        Console.WriteLine("PYRAMID_RULE:");
        Console.WriteLine("  Normal end of execution.");

        Console.WriteLine("");
    }
Esempio n. 22
0
    public static double[] residual_poisson(int node_num, double[] node_xy, int[] node_condition,
                                            int element_num, int[] element_node, int quad_num, int ib, double[] a,
                                            double[] f, double[] node_u, Func <int, double[], double[]> rhs, Func <int, double[], double[]> h_coef,
                                            Func <int, double[], double[]> k_coef, Func <int, double[], double[]> dirichlet_condition)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    RESIDUAL_POISSON evaluates the residual for the Poisson equation.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    14 November 2006
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int NODE_NUM, the number of nodes.
    //
    //    Input, double NODE_XY[2*NODE_NUM], the
    //    coordinates of nodes.
    //
    //    Input, int NODE_CONDITION[NODE_NUM], reports the condition
    //    used to set the unknown associated with the node.
    //    0, unknown.
    //    1, finite element equation.
    //    2, Dirichlet condition;
    //    3, Neumann condition.
    //
    //    Input, int ELEMENT_NUM, the number of elements.
    //
    //    Input, int ELEMENT_NODE[3*ELEMENT_NUM];
    //    ELEMENT_NODE(I,J) is the global index of local node I in element J.
    //
    //    Input, int QUAD_NUM, the number of quadrature points used in assembly.
    //
    //    Input, int IB, the half-bandwidth of the matrix.
    //
    //    Workspace, double A[(3*IB+1)*NODE_NUM], the NODE_NUM by NODE_NUM
    //    coefficient matrix, stored in a compressed format.
    //
    //    Workspace, double F[NODE_NUM], the right hand side.
    //
    //    Input, double NODE_U[NODE_NUM], the value of the solution
    //    at each node.
    //
    //    Output, double NODE_R[NODE_NUM], the finite element
    //    residual at each node.
    //
    //  Local parameters:
    //
    //    Local, double BI, DBIDX, DBIDY, the value of some basis function
    //    and its first derivatives at a quadrature point.
    //
    //    Local, double BJ, DBJDX, DBJDY, the value of another basis
    //    function and its first derivatives at a quadrature point.
    //
    {
        double bi    = 0;
        double bj    = 0;
        double dbidx = 0;
        double dbidy = 0;
        double dbjdx = 0;
        double dbjdy = 0;
        int    element;
        int    i;
        int    node;

        double[] p  = new double[2];
        double[] t3 = new double[2 * 3];

        double[] phys_h   = new double[quad_num];
        double[] phys_k   = new double[quad_num];
        double[] phys_rhs = new double[quad_num];
        double[] phys_xy  = new double[2 * quad_num];

        double[] quad_w  = new double[quad_num];
        double[] quad_xy = new double[2 * quad_num];

        double[] w = new double[quad_num];
        //
        //  Initialize the arrays to zero.
        //
        for (node = 0; node < node_num; node++)
        {
            f[node] = 0.0;
        }

        for (node = 0; node < node_num; node++)
        {
            for (i = 0; i < 3 * ib + 1; i++)
            {
                a[i + node * (3 * ib + 1)] = 0.0;
            }
        }

        //
        //  Get the quadrature weights and nodes.
        //
        QuadratureRule.quad_rule(quad_num, ref quad_w, ref quad_xy);
        //
        //  The actual values of A and F are determined by summing up
        //  contributions from all the elements.
        //
        for (element = 0; element < element_num; element++)
        {
            //
            //  Make a copy of the element.
            //
            int j;
            for (j = 0; j < 3; j++)
            {
                for (i = 0; i < 2; i++)
                {
                    t3[i + j * 2] = node_xy[i + (element_node[j + element * 3] - 1) * 2];
                }
            }

            //
            //  Map the quadrature points QUAD_XY to points XY in the physical element.
            //
            Reference.reference_to_physical_t3(t3, quad_num, quad_xy, ref phys_xy);

            double area = Math.Abs(typeMethods.triangle_area_2d(t3));

            int quad;
            for (quad = 0; quad < quad_num; quad++)
            {
                w[quad] = quad_w[quad] * area;
            }

            phys_rhs = rhs(quad_num, phys_xy);
            phys_h   = h_coef(quad_num, phys_xy);
            phys_k   = k_coef(quad_num, phys_xy);
            //
            //  Consider a quadrature point QUAD, with coordinates (X,Y).
            //
            for (quad = 0; quad < quad_num; quad++)
            {
                p[0] = phys_xy[0 + quad * 2];
                p[1] = phys_xy[1 + quad * 2];
                //
                //  Consider one of the basis functions, which will play the
                //  role of test function in the integral.
                //
                //  We generate an integral for every node associated with an unknown.
                //  But if a node is associated with a boundary condition, we do nothing.
                //
                int test;
                for (test = 1; test <= 3; test++)
                {
                    i = element_node[test - 1 + element * 3];

                    Basis11.basis_one_t3(t3, test, p, ref bi, ref dbidx, ref dbidy);

                    f[i - 1] += w[quad] * phys_rhs[quad] * bi;
                    //
                    //  Consider another basis function, which is used to form the
                    //  value of the solution function.
                    //
                    int basis;
                    for (basis = 1; basis <= 3; basis++)
                    {
                        j = element_node[basis - 1 + element * 3];

                        Basis11.basis_one_t3(t3, basis, p, ref bj, ref dbjdx, ref dbjdy);

                        a[i - j + 2 * ib + (j - 1) * (3 * ib + 1)] += w[quad]
                                                                      * (phys_h[quad] *
                                                                         (dbidx * dbjdx + dbidy * dbjdy)
                                                                         + phys_k[quad] * bj * bi);
                    }
                }
            }
        }

        //
        //  Apply boundary conditions.
        //
        dirichlet_apply(node_num, node_xy, node_condition, ib, ref a, ref f, dirichlet_condition);
        //
        //  Compute A*U.
        //
        double[] node_r = dgb_mxv(node_num, node_num, ib, ib, a, node_u);
        //
        //  Set RES = A * U - F.
        //
        for (node = 0; node < node_num; node++)
        {
            node_r[node] -= f[node];
        }

        return(node_r);
    }
Esempio n. 23
0
    private static void triangle_unit_quad_test(int degree_max)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    TRIANGLE_UNIT_QUAD_TEST tests the rules for the unit triangle.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    18 April 2008
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int DEGREE_MAX, the maximum total degree of the
    //    monomials to check.
    //
    {
        const int DIM_NUM = 2;

        int[]       expon = new int[DIM_NUM];
        int         h     = 0;
        int         t     = 0;
        SubCompData data  = new();

        Console.WriteLine("");
        Console.WriteLine("TRIANGLE_UNIT_QUAD_TEST");
        Console.WriteLine("  For the unit triangle,");
        Console.WriteLine("  we approximate monomial integrals with:");
        Console.WriteLine("  QuadratureRule.triangle_unit_o01,");
        Console.WriteLine("  QuadratureRule.triangle_unit_o03,");
        Console.WriteLine("  QuadratureRule.triangle_unit_o03b,");
        Console.WriteLine("  QuadratureRule.triangle_unit_o06,");
        Console.WriteLine("  QuadratureRule.triangle_unit_o06b,");
        Console.WriteLine("  QuadratureRule.triangle_unit_o07,");
        Console.WriteLine("  QuadratureRule.triangle_unit_o12,");

        bool more = false;

        for (;;)
        {
            SubComp.subcomp_next(ref data, degree_max, DIM_NUM, ref expon, ref more, ref h, ref t);

            Console.WriteLine("");
            string cout = "  Monomial exponents: ";
            int    dim;
            for (dim = 0; dim < DIM_NUM; dim++)
            {
                cout += "  " + expon[dim].ToString(CultureInfo.InvariantCulture).PadLeft(2);
            }

            Console.WriteLine(cout);
            Console.WriteLine("");

            int      order = 1;
            double[] w     = new double[order];
            double[] xy    = new double[DIM_NUM * order];
            QuadratureRule.triangle_unit_o01(ref w, ref xy);
            double[] v    = Monomial.monomial_value(DIM_NUM, order, expon, xy);
            double   quad = QuadratureRule.triangle_unit_volume() * typeMethods.r8vec_dot_product(order, w, v);
            Console.WriteLine("  " + order.ToString(CultureInfo.InvariantCulture).PadLeft(6)
                              + "  " + quad.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");

            order = 3;
            w     = new double[order];
            xy    = new double[DIM_NUM * order];
            QuadratureRule.triangle_unit_o03(ref w, ref xy);
            v    = Monomial.monomial_value(DIM_NUM, order, expon, xy);
            quad = QuadratureRule.triangle_unit_volume() * typeMethods.r8vec_dot_product(order, w, v);
            Console.WriteLine("  " + order.ToString(CultureInfo.InvariantCulture).PadLeft(6)
                              + "  " + quad.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");

            order = 3;
            w     = new double[order];
            xy    = new double[DIM_NUM * order];
            QuadratureRule.triangle_unit_o03b(ref w, ref xy);
            v    = Monomial.monomial_value(DIM_NUM, order, expon, xy);
            quad = QuadratureRule.triangle_unit_volume() * typeMethods.r8vec_dot_product(order, w, v);
            Console.WriteLine("  " + order.ToString(CultureInfo.InvariantCulture).PadLeft(6)
                              + "  " + quad.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");

            order = 6;
            w     = new double[order];
            xy    = new double[DIM_NUM * order];
            QuadratureRule.triangle_unit_o06(ref w, ref xy);
            v    = Monomial.monomial_value(DIM_NUM, order, expon, xy);
            quad = QuadratureRule.triangle_unit_volume() * typeMethods.r8vec_dot_product(order, w, v);
            Console.WriteLine("  " + order.ToString(CultureInfo.InvariantCulture).PadLeft(6)
                              + "  " + quad.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");

            order = 6;
            w     = new double[order];
            xy    = new double[DIM_NUM * order];
            QuadratureRule.triangle_unit_o06b(ref w, ref xy);
            v    = Monomial.monomial_value(DIM_NUM, order, expon, xy);
            quad = QuadratureRule.triangle_unit_volume() * typeMethods.r8vec_dot_product(order, w, v);
            Console.WriteLine("  " + order.ToString(CultureInfo.InvariantCulture).PadLeft(6)
                              + "  " + quad.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");

            order = 7;
            w     = new double[order];
            xy    = new double[DIM_NUM * order];
            QuadratureRule.triangle_unit_o07(ref w, ref xy);
            v    = Monomial.monomial_value(DIM_NUM, order, expon, xy);
            quad = QuadratureRule.triangle_unit_volume() * typeMethods.r8vec_dot_product(order, w, v);
            Console.WriteLine("  " + order.ToString(CultureInfo.InvariantCulture).PadLeft(6)
                              + "  " + quad.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");

            order = 12;
            w     = new double[order];
            xy    = new double[DIM_NUM * order];
            QuadratureRule.triangle_unit_o12(ref w, ref xy);
            v    = Monomial.monomial_value(DIM_NUM, order, expon, xy);
            quad = QuadratureRule.triangle_unit_volume() * typeMethods.r8vec_dot_product(order, w, v);
            Console.WriteLine("  " + order.ToString(CultureInfo.InvariantCulture).PadLeft(6)
                              + "  " + quad.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");

            Console.WriteLine("");
            quad = QuadratureRule.triangle_unit_monomial(expon);
            Console.WriteLine("  " + " Exact"
                              + "  " + quad.ToString(CultureInfo.InvariantCulture).PadLeft(14) + "");

            if (!more)
            {
                break;
            }
        }
    }
Esempio n. 24
0
    private static void Main(string[] args)
    //****************************************************************************80
    //
    //  Purpose:
    //
    //    MAIN is the main program for PATTERSON_RULE.
    //
    //  Discussion:
    //
    //    This program computes a standard Gauss-Patterson quadrature rule
    //    and writes it to a file.
    //
    //  Usage:
    //
    //    patterson_rule order a b output
    //
    //    where
    //
    //    * ORDER is the number of points in the rule, and must be
    //      1, 3, 7, 15, 31, 63, 127, 255 or 511.
    //    * A is the left endpoint;
    //    * B is the right endpoint;
    //    * FILENAME is the "root name" of the output files.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    21 February 2010
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        double a;
        double b;
        string filename;
        int    order;

        Console.WriteLine("");
        Console.WriteLine("PATTERSON_RULE");
        Console.WriteLine("");
        Console.WriteLine("  Compute a Gauss-Patterson rule for approximating");
        Console.WriteLine("    Integral ( -1 <= x <= +1 ) f(x) dx");
        Console.WriteLine("  of order ORDER.");
        Console.WriteLine("");
        Console.WriteLine("  The user specifies ORDER, A, B, and FILENAME.");
        Console.WriteLine("");
        Console.WriteLine("  ORDER is 1, 3, 7, 15, 31, 63, 127, 255 or 511.");
        Console.WriteLine("  A is the left endpoint.");
        Console.WriteLine("  B is the right endpoint.");
        Console.WriteLine("  FILENAME is used to generate 3 files:");
        Console.WriteLine("    filename_w.txt - the weight file");
        Console.WriteLine("    filename_x.txt - the abscissa file.");
        Console.WriteLine("    filename_r.txt - the region file.");
        //
        //  Get ORDER.
        //
        try
        {
            order = Convert.ToInt32(args[0]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the value of ORDER.");
            order = Convert.ToInt32(Console.ReadLine());
        }

        if (!Order.order_check(order))
        {
            Console.WriteLine("");
            Console.WriteLine("PATTERSON_RULE:");
            Console.WriteLine("  ORDER is illegal.");
            Console.WriteLine("  Abnormal end of execution.");
            return;
        }

        //
        //  Get A.
        //
        try
        {
            a = Convert.ToDouble(args[1]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the left endpoint A:");
            a = Convert.ToDouble(Console.ReadLine());
        }

        //
        //  Get B.
        //
        try
        {
            b = Convert.ToDouble(args[2]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the right endpoint B:");
            b = Convert.ToDouble(Console.ReadLine());
        }

        //
        //  Get FILENAME:
        //
        try
        {
            filename = args[3];
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter FILENAME, the \"root name\" of the quadrature files).");
            filename = Console.ReadLine();
        }

        //
        //  Input summary.
        //
        Console.WriteLine("");
        Console.WriteLine("  ORDER = " + order + "");
        Console.WriteLine("  A = " + a + "");
        Console.WriteLine("  B = " + b + "");
        Console.WriteLine("  FILENAME = \"" + filename + "\".");
        //
        //  Construct the rule.
        //
        double[] r = new double[2];
        double[] w = new double[order];
        double[] x = new double[order];

        r[0] = a;
        r[1] = b;

        PattersonQuadrature.patterson_set(order, ref x, ref w);
        //
        //  Rescale the rule.
        //
        ClenshawCurtis.rescale(a, b, order, ref x, ref w);
        //
        //  Output the rule.
        //
        QuadratureRule.rule_write(order, filename, x, w, r);

        Console.WriteLine("");
        Console.WriteLine("PATTERSON_RULE:");
        Console.WriteLine("  Normal end of execution.");
        Console.WriteLine("");
    }
Esempio n. 25
0
    public static void assemble_poisson_dsp(int node_num, double[] node_xy,
                                            int element_num, int[] element_node, int quad_num, int nz_num, int[] ia,
                                            int[] ja, ref double[] a, ref double[] f, Func <int, double[], double[]> rhs, Func <int, double[], double[]> h_coef, Func <int, double[], double[]> k_coef)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    ASSEMBLE_POISSON_DSP assembles the system for the Poisson equation.
    //
    //  Discussion:
    //
    //    The matrix is sparse, and stored in the DSP or "sparse triple" format.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    13 July 2007
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int NODE_NUM, the number of nodes.
    //
    //    Input, double NODE_XY[2*NODE_NUM], the
    //    coordinates of nodes.
    //
    //    Input, int ELEMENT_NUM, the number of triangles.
    //
    //    Input, int ELEMENT_NODE[3*ELEMENT_NUM];
    //    ELEMENT_NODE(I,J) is the global index of local node I in triangle J.
    //
    //    Input, int QUAD_NUM, the number of quadrature points used in assembly.
    //
    //    Input, int NZ_NUM, the number of nonzero entries.
    //
    //    Input, int IA[NZ_NUM], JA[NZ_NUM], the row and column
    //    indices of the nonzero entries.
    //
    //    Output, double A[NZ_NUM], the nonzero entries of the matrix.
    //
    //    Output, double F(NODE_NUM), the right hand side.
    //
    //  Local parameters:
    //
    //    Local, double BI, DBIDX, DBIDY, the value of some basis function
    //    and its first derivatives at a quadrature point.
    //
    //    Local, double BJ, DBJDX, DBJDY, the value of another basis
    //    function and its first derivatives at a quadrature point.
    //
    {
        double bi    = 0;
        double bj    = 0;
        double dbidx = 0;
        double dbidy = 0;
        double dbjdx = 0;
        double dbjdy = 0;
        int    element;
        int    node;
        int    nz;

        double[] p  = new double[2];
        double[] t3 = new double[2 * 3];

        double[] phys_xy = new double[2 * quad_num];

        double[] quad_w  = new double[quad_num];
        double[] quad_xy = new double[2 * quad_num];

        double[] w = new double[quad_num];
        //
        //  Initialize the arrays to zero.
        //
        for (node = 0; node < node_num; node++)
        {
            f[node] = 0.0;
        }

        for (nz = 0; nz < nz_num; nz++)
        {
            a[nz] = 0.0;
        }

        //
        //  Get the quadrature weights and nodes.
        //
        QuadratureRule.quad_rule(quad_num, ref quad_w, ref quad_xy);
        //
        //  Add up all quantities associated with the ELEMENT-th element.
        //
        for (element = 0; element < element_num; element++)
        {
            //
            //  Make a copy of the element.
            //
            int j;
            int i;
            for (j = 0; j < 3; j++)
            {
                for (i = 0; i < 2; i++)
                {
                    t3[i + j * 2] = node_xy[i + (element_node[j + element * 3] - 1) * 2];
                }
            }

            //
            //  Map the quadrature points QUAD_XY to points XY in the physical element.
            //
            Reference.reference_to_physical_t3(t3, quad_num, quad_xy, ref phys_xy);

            double area = Math.Abs(typeMethods.triangle_area_2d(t3));

            int quad;
            for (quad = 0; quad < quad_num; quad++)
            {
                w[quad] = quad_w[quad] * area;
            }

            double[] phys_rhs = rhs(quad_num, phys_xy);
            double[] phys_h   = h_coef(quad_num, phys_xy);
            double[] phys_k   = k_coef(quad_num, phys_xy);
            //
            //  Consider the QUAD-th quadrature point.
            //
            for (quad = 0; quad < quad_num; quad++)
            {
                p[0] = phys_xy[0 + quad * 2];
                p[1] = phys_xy[1 + quad * 2];
                //
                //  Consider the TEST-th test function.
                //
                //  We generate an integral for every node associated with an unknown.
                //  But if a node is associated with a boundary condition, we do nothing.
                //
                int test;
                for (test = 1; test <= 3; test++)
                {
                    i = element_node[test - 1 + element * 3];

                    Basis11.basis_one_t3(t3, test, p, ref bi, ref dbidx, ref dbidy);

                    f[i - 1] += w[quad] * phys_rhs[quad] * bi;
                    //
                    //  Consider the BASIS-th basis function, which is used to form the
                    //  value of the solution function.
                    //
                    int basis;
                    for (basis = 1; basis <= 3; basis++)
                    {
                        j = element_node[basis - 1 + element * 3];

                        Basis11.basis_one_t3(t3, basis, p, ref bj, ref dbjdx, ref dbjdy);

                        int k = dsp_ij_to_k(nz_num, ia, ja, i, j);

                        a[k - 1] += w[quad] * (
                            phys_h[quad] * (dbidx * dbjdx + dbidy * dbjdy)
                            + phys_k[quad] * bj * bi);
                    }
                }
            }
        }
    }
Esempio n. 26
0
    public static void cube_unit_nd(int setting, Func <int, int, double[], double> func, ref double[] qa,
                                    ref double[] qb, int n, int k)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    CUBE_UNIT_ND approximates an integral inside the unit cube in ND.
    //
    //  Integration region:
    //
    //    -1 <= X(1:N) <= 1
    //
    //  Discussion:
    //
    //    A K**N point product formula is used.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    13 April 2008
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Reference:
    //
    //    James Lyness, BJJ McHugh,
    //    Integration Over Multidimensional Hypercubes,
    //    A Progressive Procedure,
    //    The Computer Journal,
    //    Volume 6, 1963, pages 264-270.
    //
    //    Arthur Stroud,
    //    Approximate Calculation of Multiple Integrals,
    //    Prentice Hall, 1971,
    //    ISBN: 0130438936,
    //    LC: QA311.S85.
    //
    //  Parameters:
    //
    //    Input, Func < int, double[], double> func, the name of the
    //    user supplied function to be integrated.
    //
    //    Output, double QA[K], QB[K], two sets of estimates for
    //    the integral.  The QB entries are obtained from the
    //    QA entries by Richardson extrapolation, and QB(K) is
    //    the best estimate for the integral.
    //
    //    Input, int N, the dimension of the cube.
    //
    //    Input, int K, the highest order of integration, and the order
    //    of Richardson extrapolation.  K can be no greater than 10.
    //
    {
        double[]  g = new double[10 * 10];
        int       i;
        const int kmax = 10;

        g[0 + 0 * 10] = 1.0E+00;
        g[1 + 0 * 10] = -0.3333333333333E+00;
        g[1 + 1 * 10] = 0.1333333333333E+01;
        g[2 + 0 * 10] = 0.4166666666667E-01;
        g[2 + 1 * 10] = -0.1066666666667E+01;
        g[2 + 2 * 10] = 0.2025000000000E+01;
        g[3 + 0 * 10] = -0.2777777777778E-02;
        g[3 + 1 * 10] = 0.3555555555556E+00;
        g[3 + 2 * 10] = -0.2603571428571E+01;
        g[3 + 3 * 10] = 0.3250793650794E+01;
        g[4 + 0 * 10] = 0.1157407407407E-03;
        g[4 + 1 * 10] = -0.6772486772487E-01;
        g[4 + 2 * 10] = 0.1464508928571E+01;
        g[4 + 3 * 10] = -0.5779188712522E+01;
        g[4 + 4 * 10] = 0.5382288910935E+01;
        g[5 + 0 * 10] = -0.3306878306878E-05;
        g[5 + 1 * 10] = 0.8465608465608E-02;
        g[5 + 2 * 10] = -0.4881696428571E+00;
        g[5 + 3 * 10] = 0.4623350970018E+01;
        g[5 + 4 * 10] = -0.1223247479758E+02;
        g[5 + 5 * 10] = 0.9088831168831E+01;
        g[6 + 0 * 10] = 0.6889329805996E-07;
        g[6 + 1 * 10] = -0.7524985302763E-03;
        g[6 + 2 * 10] = 0.1098381696429E+00;
        g[6 + 3 * 10] = -0.2241624712736E+01;
        g[6 + 4 * 10] = 0.1274216124748E+02;
        g[6 + 5 * 10] = -0.2516907092907E+02;
        g[6 + 6 * 10] = 0.1555944865432E+02;
        g[7 + 0 * 10] = -0.1093544413650E-08;
        g[7 + 1 * 10] = 0.5016656868509E-04;
        g[7 + 2 * 10] = -0.1797351866883E-01;
        g[7 + 3 * 10] = 0.7472082375786E+00;
        g[7 + 4 * 10] = -0.8168052081717E+01;
        g[7 + 5 * 10] = 0.3236023405166E+02;
        g[7 + 6 * 10] = -0.5082753227079E+02;
        g[7 + 7 * 10] = 0.2690606541646E+02;
        g[8 + 0 * 10] = 0.1366930517063E-10;
        g[8 + 1 * 10] = -0.2606055516108E-05;
        g[8 + 2 * 10] = 0.2246689833604E-02;
        g[8 + 3 * 10] = -0.1839281815578E+00;
        g[8 + 4 * 10] = 0.3646451822195E+01;
        g[8 + 5 * 10] = -0.2588818724133E+02;
        g[8 + 6 * 10] = 0.7782965878964E+02;
        g[8 + 7 * 10] = -0.1012934227443E+03;
        g[8 + 8 * 10] = 0.4688718347156E+02;
        g[9 + 0 * 10] = -0.1380737896023E-12;
        g[9 + 1 * 10] = 0.1085856465045E-06;
        g[9 + 2 * 10] = -0.2222000934334E-03;
        g[9 + 3 * 10] = 0.3503393934435E-01;
        g[9 + 4 * 10] = -0.1215483940732E+01;
        g[9 + 5 * 10] = 0.1456210532325E+02;
        g[9 + 6 * 10] = -0.7477751530769E+02;
        g[9 + 7 * 10] = 0.1800771959898E+03;
        g[9 + 8 * 10] = -0.1998874663788E+03;
        g[9 + 9 * 10] = 0.8220635246624E+02;

        if (kmax < k)
        {
            Console.WriteLine("");
            Console.WriteLine("CUBE_UNIT_ND - Fatal error!");
            Console.WriteLine("  K must be no greater than KMAX = " + kmax + "");
            Console.WriteLine("  but the input K is " + k + "");
            return;
        }

        for (i = 0; i < k; i++)
        {
            qa[i] = QuadratureRule.qmdpt(setting, func, n, i + 1);
        }

        qb[0] = qa[0];

        for (i = 1; i < k; i++)
        {
            qb[i] = 0.0;
            int j;
            for (j = 0; j <= i; j++)
            {
                qb[i] += g[i + j * 10] * qa[j];
            }
        }
    }
Esempio n. 27
0
    private static void Main(string[] args)
    //****************************************************************************80
    //
    //  Purpose:
    //
    //    MAIN is the main program for CHEBYSHEV1_RULE.
    //
    //  Discussion:
    //
    //    This program computes a standard Gauss-Chebyshev type 1 quadrature rule
    //    and writes it to a file.
    //
    //    The user specifies:
    //    * the ORDER (number of points) in the rule
    //    * A, the left endpoint;
    //    * B, the right endpoint;
    //    * FILENAME, the root name of the output files.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    28 February 2010
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        double a;
        double b;
        string filename;
        int    order;

        Console.WriteLine("");
        Console.WriteLine("CHEBYSHEV1_RULE");
        Console.WriteLine("");
        Console.WriteLine("  Compute a Gauss-Chebyshev type 1 rule for approximating");
        Console.WriteLine("");
        Console.WriteLine("    Integral ( A <= x <= B ) f(x) / sqrt ( ( x - A ) * ( B - x ) ) dx");
        Console.WriteLine("");
        Console.WriteLine("  of order ORDER.");
        Console.WriteLine("");
        Console.WriteLine("  The user specifies ORDER, A, B and FILENAME.");
        Console.WriteLine("");
        Console.WriteLine("  Order is the number of points.");
        Console.WriteLine("");
        Console.WriteLine("  A is the left endpoint.");
        Console.WriteLine("");
        Console.WriteLine("  B is the right endpoint.");
        Console.WriteLine("");
        Console.WriteLine("  FILENAME is used to generate 3 files:");
        Console.WriteLine("");
        Console.WriteLine("    filename_w.txt - the weight file");
        Console.WriteLine("    filename_x.txt - the abscissa file.");
        Console.WriteLine("    filename_r.txt - the region file.");
        //
        //  Initialize parameters;
        //
        const double alpha = 0.0;
        const double beta  = 0.0;

        //
        //  Get ORDER.
        //
        try
        {
            order = Convert.ToInt32(args[0]);
        }
        catch (Exception)
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the value of ORDER (1 or greater)");
            order = Convert.ToInt32(Console.ReadLine());
        }

        //
        //  Get A.
        //
        try
        {
            a = Convert.ToDouble(args[1]);
        }
        catch (Exception)
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the value of A:");
            a = Convert.ToDouble(Console.ReadLine());
        }

        //
        //  Get B.
        //
        try
        {
            b = Convert.ToDouble(args[2]);
        }
        catch (Exception)
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the value of B:");
            b = Convert.ToDouble(Console.ReadLine());
        }

        //
        //  Get FILENAME:
        //
        try
        {
            filename = args[3];
        }
        catch (Exception)
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter FILENAME, the \"root name\" of the quadrature files).");
            filename = Console.ReadLine();
        }

        //
        //  Input summary.
        //
        Console.WriteLine("");
        Console.WriteLine("  ORDER = " + order + "");
        Console.WriteLine("  A = " + a + "");
        Console.WriteLine("  B = " + b + "");
        Console.WriteLine("  FILENAME = \"" + filename + "\".");
        //
        //  Construct the rule.
        //
        double[] w = new double[order];
        double[] x = new double[order];

        const int kind = 2;

        CGQF.cgqf(order, kind, alpha, beta, a, b, ref x, ref w);
        //
        //  Write the rule.
        //
        double[] r = new double[2];
        r[0] = a;
        r[1] = b;

        QuadratureRule.rule_write(order, filename, x, w, r);

        Console.WriteLine("");
        Console.WriteLine("CHEBYSHEV1_RULE:");
        Console.WriteLine("  Normal end of execution.");

        Console.WriteLine("");
    }
Esempio n. 28
0
    public static double tetra_tproduct(int setting, Func <int, double, double, double, double> func,
                                        int order, double[] x, double[] y, double[] z)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    TETRA_TPRODUCT approximates an integral in a tetrahedron in 3D.
    //
    //  Discussion:
    //
    //    Integration is carried out over the points inside an arbitrary
    //    tetrahedron whose four vertices are given.
    //
    //    An ORDER**3 point (2*ORDER-1)-th degree triangular product
    //    Gauss-Legendre rule is used.
    //
    //    With ORDER = 8, this routine is equivalent to the routine TETR15
    //    in the reference, page 367.
    //
    //    Thanks to Joerg Behrens, [email protected], for numerous suggestions
    //    and corrections.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    20 March 2008
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Reference:
    //
    //    Arthur Stroud,
    //    Approximate Calculation of Multiple Integrals,
    //    Prentice Hall, 1971,
    //    ISBN: 0130438936,
    //    LC: QA311.S85.
    //
    //  Parameters:
    //
    //    Input, Func< double, double, double, double > func, the name of the
    //    user supplied function to be integrated.
    //
    //    Input, int ORDER, the order of the basic quadrature rules.
    //    ORDER should be between 1 and 9.
    //
    //    Input, double X[4], Y[4], Z[4], the vertices
    //    of the tetrahedron.
    //
    //    Output, double TETRA_TPRODUCT, the approximate integral of the function.
    //
    {
        int i;
        int k;

        switch (order)
        {
        case < 1:
        case > 9:
            Console.WriteLine("");
            Console.WriteLine("TETRA_TPRODUCT - Fatal error!");
            Console.WriteLine("  The quadrature rule orders must be between 1 and 9.");
            Console.WriteLine("  The input value was ORDER = " + order + "");
            return(1);
        }

        //
        //  Get the Gauss-Legendre ORDER point rules on [-1,1] for integrating
        //    F(X),
        //    X * F(X),
        //    X * X * F(X).
        //
        double[] xtab0   = new double[order];
        double[] xtab1   = new double[order];
        double[] xtab2   = new double[order];
        double[] weight0 = new double[order];
        double[] weight1 = new double[order];
        double[] weight2 = new double[order];

        LegendreQuadrature.legendre_set(order, ref xtab0, ref weight0);
        LegendreQuadrature.legendre_set_x1(order, ref xtab1, ref weight1);
        LegendreQuadrature.legendre_set_x2(order, ref xtab2, ref weight2);
        //
        //  Adjust the rules from [-1,1] to [0,1].
        //
        const double a = -1.0;
        const double b = +1.0;
        const double c = 0.0;
        const double d = 1.0;

        QuadratureRule.rule_adjust(a, b, c, d, order, ref xtab0, ref weight0);

        QuadratureRule.rule_adjust(a, b, c, d, order, ref xtab1, ref weight1);

        QuadratureRule.rule_adjust(a, b, c, d, order, ref xtab2, ref weight2);
        //
        //  For rules with a weight function that is not 1, the weight vectors
        //  require further adjustment.
        //
        for (i = 0; i < order; i++)
        {
            weight1[i] /= 2.0;
        }

        for (i = 0; i < order; i++)
        {
            weight2[i] /= 4.0;
        }

        //
        //  Carry out the quadrature.
        //
        double quad = 0.0;

        for (k = 0; k < order; k++)
        {
            int j;
            for (j = 0; j < order; j++)
            {
                for (i = 0; i < order; i++)
                {
                    double xval = x[0] + (((x[3] - x[2]) * xtab0[i]
                                           + (x[2] - x[1])) * xtab1[j]
                                          + (x[1] - x[0])) * xtab2[k];

                    double yval = y[0] + (((y[3] - y[2]) * xtab0[i]
                                           + (y[2] - y[1])) * xtab1[j]
                                          + (y[1] - y[0])) * xtab2[k];

                    double zval = z[0] + (((z[3] - z[2]) * xtab0[i]
                                           + (z[2] - z[1])) * xtab1[j]
                                          + (z[1] - z[0])) * xtab2[k];

                    quad += 6.0 * weight0[i] * weight1[j] * weight2[k]
                            * func(setting, xval, yval, zval);
                }
            }
        }

        //
        //  Compute the volume of the tetrahedron.
        //
        double volume = tetra_volume(x, y, z);
        double result = quad * volume;

        return(result);
    }
Esempio n. 29
0
    public static ClenshawCurtis.ccResult kpu(int n, double[] x_, double[] w_)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    KPU provides data for Kronrod-Patterson quadrature with a uniform weight.
    //
    //  Discussion:
    //
    //    This data assumes integration over the interval [0,1] with
    //    weight function w(x) = 1.
    //
    //    This data was originally supplied with only 7 digit accuracy.
    //    It has been replaced by higher accuracy data, which is defined over [-1,+1],
    //    but adjusted to the interval [0,1] before return.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    11 December 2012
    //
    //  Author:
    //
    //    John Burkardt.
    //
    //  Reference:
    //
    //    Florian Heiss, Viktor Winschel,
    //    Likelihood approximation by numerical integration on sparse grids,
    //    Journal of Econometrics,
    //    Volume 144, 2008, pages 62-80.
    //
    //    Alan Genz, Bradley Keister,
    //    Fully symmetric interpolatory rules for multiple integrals
    //    over infinite regions with Gaussian weight,
    //    Journal of Computational and Applied Mathematics,
    //    Volume 71, 1996, pages 299-309.
    //
    //    Thomas Patterson,
    //    The optimal addition of points to quadrature formulae,
    //    Mathematics of Computation,
    //    Volume 22, Number 104, October 1968, pages 847-856.
    //
    //  Parameters:
    //
    //    Input, int N, the order of the rule.
    //    Only 1, 3, 7, 15, 31 and 63 are legal input values for N.
    //
    //    Output, double X[N], the nodes.
    //
    //    Output, double W[N], the weights.
    //
    {
        ClenshawCurtis.ccResult result = new()
        {
            x = x_,
            w = w_
        };

        double[] x01 =
        {
            0.0000000
        };
        double[] w01 =
        {
            2.0000000
        };
        double[] x03 =
        {
            -0.77459666924148337704,
            0.0,
            0.77459666924148337704
        };
        double[] w03 =
        {
            0.555555555555555555556,
            0.888888888888888888889,
            0.555555555555555555556
        };
        double[] x07 =
        {
            -0.96049126870802028342,
            -0.77459666924148337704,
            -0.43424374934680255800,
            0.0,
            0.43424374934680255800,
            0.77459666924148337704,
            0.96049126870802028342
        };
        double[] w07 =
        {
            0.104656226026467265194,
            0.268488089868333440729,
            0.401397414775962222905,
            0.450916538658474142345,
            0.401397414775962222905,
            0.268488089868333440729,
            0.104656226026467265194
        };
        double[] x15 =
        {
            -0.99383196321275502221,
            -0.96049126870802028342,
            -0.88845923287225699889,
            -0.77459666924148337704,
            -0.62110294673722640294,
            -0.43424374934680255800,
            -0.22338668642896688163,
            0.0,
            0.22338668642896688163,
            0.43424374934680255800,
            0.62110294673722640294,
            0.77459666924148337704,
            0.88845923287225699889,
            0.96049126870802028342,
            0.99383196321275502221
        };
        double[] w15 =
        {
            0.0170017196299402603390,
            0.0516032829970797396969,
            0.0929271953151245376859,
            0.134415255243784220360,
            0.171511909136391380787,
            0.200628529376989021034,
            0.219156858401587496404,
            0.225510499798206687386,
            0.219156858401587496404,
            0.200628529376989021034,
            0.171511909136391380787,
            0.134415255243784220360,
            0.0929271953151245376859,
            0.0516032829970797396969,
            0.0170017196299402603390
        };
        double[] x31 =
        {
            -0.99909812496766759766,
            -0.99383196321275502221,
            -0.98153114955374010687,
            -0.96049126870802028342,
            -0.92965485742974005667,
            -0.88845923287225699889,
            -0.83672593816886873550,
            -0.77459666924148337704,
            -0.70249620649152707861,
            -0.62110294673722640294,
            -0.53131974364437562397,
            -0.43424374934680255800,
            -0.33113539325797683309,
            -0.22338668642896688163,
            -0.11248894313318662575,
            0.0,
            0.11248894313318662575,
            0.22338668642896688163,
            0.33113539325797683309,
            0.43424374934680255800,
            0.53131974364437562397,
            0.62110294673722640294,
            0.70249620649152707861,
            0.77459666924148337704,
            0.83672593816886873550,
            0.88845923287225699889,
            0.92965485742974005667,
            0.96049126870802028342,
            0.98153114955374010687,
            0.99383196321275502221,
            0.99909812496766759766
        };
        double[] w31 =
        {
            0.00254478079156187441540,
            0.00843456573932110624631,
            0.0164460498543878109338,
            0.0258075980961766535646,
            0.0359571033071293220968,
            0.0464628932617579865414,
            0.0569795094941233574122,
            0.0672077542959907035404,
            0.0768796204990035310427,
            0.0857559200499903511542,
            0.0936271099812644736167,
            0.100314278611795578771,
            0.105669893580234809744,
            0.109578421055924638237,
            0.111956873020953456880,
            0.112755256720768691607,
            0.111956873020953456880,
            0.109578421055924638237,
            0.105669893580234809744,
            0.100314278611795578771,
            0.0936271099812644736167,
            0.0857559200499903511542,
            0.0768796204990035310427,
            0.0672077542959907035404,
            0.0569795094941233574122,
            0.0464628932617579865414,
            0.0359571033071293220968,
            0.0258075980961766535646,
            0.0164460498543878109338,
            0.00843456573932110624631,
            0.00254478079156187441540
        };
        double[] x63 =
        {
            -0.99987288812035761194,
            -0.99909812496766759766,
            -0.99720625937222195908,
            -0.99383196321275502221,
            -0.98868475754742947994,
            -0.98153114955374010687,
            -0.97218287474858179658,
            -0.96049126870802028342,
            -0.94634285837340290515,
            -0.92965485742974005667,
            -0.91037115695700429250,
            -0.88845923287225699889,
            -0.86390793819369047715,
            -0.83672593816886873550,
            -0.80694053195021761186,
            -0.77459666924148337704,
            -0.73975604435269475868,
            -0.70249620649152707861,
            -0.66290966002478059546,
            -0.62110294673722640294,
            -0.57719571005204581484,
            -0.53131974364437562397,
            -0.48361802694584102756,
            -0.43424374934680255800,
            -0.38335932419873034692,
            -0.33113539325797683309,
            -0.27774982202182431507,
            -0.22338668642896688163,
            -0.16823525155220746498,
            -0.11248894313318662575,
            -0.056344313046592789972,
            0.0,
            0.056344313046592789972,
            0.11248894313318662575,
            0.16823525155220746498,
            0.22338668642896688163,
            0.27774982202182431507,
            0.33113539325797683309,
            0.38335932419873034692,
            0.43424374934680255800,
            0.48361802694584102756,
            0.53131974364437562397,
            0.57719571005204581484,
            0.62110294673722640294,
            0.66290966002478059546,
            0.70249620649152707861,
            0.73975604435269475868,
            0.77459666924148337704,
            0.80694053195021761186,
            0.83672593816886873550,
            0.86390793819369047715,
            0.88845923287225699889,
            0.91037115695700429250,
            0.92965485742974005667,
            0.94634285837340290515,
            0.96049126870802028342,
            0.97218287474858179658,
            0.98153114955374010687,
            0.98868475754742947994,
            0.99383196321275502221,
            0.99720625937222195908,
            0.99909812496766759766,
            0.99987288812035761194
        };
        double[] w63 =
        {
            0.000363221481845530659694,
            0.00126515655623006801137,
            0.00257904979468568827243,
            0.00421763044155885483908,
            0.00611550682211724633968,
            0.00822300795723592966926,
            0.0104982469096213218983,
            0.0129038001003512656260,
            0.0154067504665594978021,
            0.0179785515681282703329,
            0.0205942339159127111492,
            0.0232314466399102694433,
            0.0258696793272147469108,
            0.0284897547458335486125,
            0.0310735511116879648799,
            0.0336038771482077305417,
            0.0360644327807825726401,
            0.0384398102494555320386,
            0.0407155101169443189339,
            0.0428779600250077344929,
            0.0449145316536321974143,
            0.0468135549906280124026,
            0.0485643304066731987159,
            0.0501571393058995374137,
            0.0515832539520484587768,
            0.0528349467901165198621,
            0.0539054993352660639269,
            0.0547892105279628650322,
            0.0554814043565593639878,
            0.0559784365104763194076,
            0.0562776998312543012726,
            0.0563776283603847173877,
            0.0562776998312543012726,
            0.0559784365104763194076,
            0.0554814043565593639878,
            0.0547892105279628650322,
            0.0539054993352660639269,
            0.0528349467901165198621,
            0.0515832539520484587768,
            0.0501571393058995374137,
            0.0485643304066731987159,
            0.0468135549906280124026,
            0.0449145316536321974143,
            0.0428779600250077344929,
            0.0407155101169443189339,
            0.0384398102494555320386,
            0.0360644327807825726401,
            0.0336038771482077305417,
            0.0310735511116879648799,
            0.0284897547458335486125,
            0.0258696793272147469108,
            0.0232314466399102694433,
            0.0205942339159127111492,
            0.0179785515681282703329,
            0.0154067504665594978021,
            0.0129038001003512656260,
            0.0104982469096213218983,
            0.00822300795723592966926,
            0.00611550682211724633968,
            0.00421763044155885483908,
            0.00257904979468568827243,
            0.00126515655623006801137,
            0.000363221481845530659694
        };

        switch (n)
        {
        case 1:
            typeMethods.r8vec_copy(n, x01, ref result.x);
            typeMethods.r8vec_copy(n, w01, ref result.w);
            break;

        case 3:
            typeMethods.r8vec_copy(n, x03, ref result.x);
            typeMethods.r8vec_copy(n, w03, ref result.w);
            break;

        case 7:
            typeMethods.r8vec_copy(n, x07, ref result.x);
            typeMethods.r8vec_copy(n, w07, ref result.w);
            break;

        case 15:
            typeMethods.r8vec_copy(n, x15, ref result.x);
            typeMethods.r8vec_copy(n, w15, ref result.w);
            break;

        case 31:
            typeMethods.r8vec_copy(n, x31, ref result.x);
            typeMethods.r8vec_copy(n, w31, ref result.w);
            break;

        case 63:
            typeMethods.r8vec_copy(n, x63, ref result.x);
            typeMethods.r8vec_copy(n, w63, ref result.w);
            break;

        default:
            Console.WriteLine("");
            Console.WriteLine("KPU - Fatal error!");
            Console.WriteLine("  Illegal value of N.");
            return(result);
        }

        //
        //  The rule as stored is for the interval [-1,+1].
        //  Adjust it to the interval [0,1].
        //
        QuadratureRule.rule_adjust(-1.0, +1.0, 0.0, 1.0, n, ref result.x, ref result.w);

        return(result);
    }
Esempio n. 30
0
    private static void Main(string[] args)
    //****************************************************************************80
    //
    //  Purpose:
    //
    //    MAIN is the main program for INT_EXACTNESS_GEN_LAGUERRE.
    //
    //  Discussion:
    //
    //    This program investigates a generalized Gauss-Laguerre quadrature rule
    //    by using it to integrate monomials over [0,+oo), and comparing the
    //    approximate result to the known exact value.
    //
    //    The user specifies:
    //    * the "root" name of the R, W and X files that specify the rule;
    //    * DEGREE_MAX, the maximum monomial degree to be checked.
    //    * ALPHA, the power of X in the weighting function.
    //    * OPTION, whether the rule is for x^alpha*exp(-x)*f(x) or f(x).
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    05 August 2009
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        double alpha;
        int    degree;
        int    degree_max;
        int    i;
        int    option;
        string quad_filename;

        Console.WriteLine("");
        Console.WriteLine("INT_EXACTNESS_GEN_LAGUERRE");
        Console.WriteLine("");
        Console.WriteLine("  Investigate the polynomial exactness of a generalized Gauss-Laguerre");
        Console.WriteLine("  quadrature rule by integrating exponentially weighted");
        Console.WriteLine("  monomials up to a given degree over the [0,+oo) interval.");
        Console.WriteLine("");
        Console.WriteLine("  The rule may be defined on another interval, [A,+oo)");
        Console.WriteLine("  in which case it is adjusted to the [0,+oo) interval.");
        //
        //  Get the quadrature file rootname.
        //
        try
        {
            quad_filename = args[0];
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter the quadrature file rootname:");
            quad_filename = Console.ReadLine();
        }

        Console.WriteLine("");
        Console.WriteLine("  The quadrature file rootname is \"" + quad_filename + "\".");
        //
        //  Create the names of:
        //    the quadrature X file;
        //    the quadrature W file;
        //    the quadrature R file;
        //
        string quad_w_filename = quad_filename + "_w.txt";
        string quad_x_filename = quad_filename + "_x.txt";
        string quad_r_filename = quad_filename + "_r.txt";

        //
        //  Get the maximum degree:
        //
        try
        {
            degree_max = Convert.ToInt32(args[1]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  Enter DEGREE_MAX, the maximum monomial degree to check.");
            degree_max = Convert.ToInt32(Console.ReadLine());
        }

        Console.WriteLine("");
        Console.WriteLine("  The requested maximum monomial degree is = " + degree_max + "");
        //
        //  Get the exponent ALPHA:
        //
        try
        {
            alpha = Convert.ToDouble(args[2]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("  ALPHA is the power of X in the weighting function.");
            Console.WriteLine("");
            Console.WriteLine("  ALPHA is a real number greater than -1.0;");
            Console.WriteLine("");
            Console.WriteLine("  Enter ALPHA.");
            alpha = Convert.ToDouble(Console.ReadLine());
        }

        Console.WriteLine("");
        Console.WriteLine("  The requested value of ALPHA = " + alpha + "");
        //
        //  The fourth command line argument is OPTION.
        //  0 for the standard rule for integrating x^alpha*exp(-x)*f(x),
        //  1 for a rule for integrating f(x).
        //
        try
        {
            option = Convert.ToInt32(args[3]);
        }
        catch
        {
            Console.WriteLine("");
            Console.WriteLine("OPTION chooses the standard or modified rule.");
            Console.WriteLine("0: standard rule for integrating x^allpha*exp(-x)*f(x)");
            Console.WriteLine("1: modified rule for integrating                  f(x)");
            option = Convert.ToInt32(Console.ReadLine());
        }

        //
        //  Summarize the input.
        //
        Console.WriteLine("");
        Console.WriteLine("INT_EXACTNESS_GEN_LAGUERRE: User input:");
        Console.WriteLine("  Quadrature rule X file = \"" + quad_x_filename + "\".");
        Console.WriteLine("  Quadrature rule W file = \"" + quad_w_filename + "\".");
        Console.WriteLine("  Quadrature rule R file = \"" + quad_r_filename + "\".");
        Console.WriteLine("  Maximum degree to check = " + degree_max + "");
        Console.WriteLine("  Weighting exponent ALPHA = " + alpha + "");
        switch (option)
        {
        case 0:
            Console.WriteLine("  OPTION = 0, integrate x^alpha*exp(-x)*f(x)");
            break;

        default:
            Console.WriteLine("  OPTION = 1, integrate                 f(x)");
            break;
        }

        //
        //  Read the X file.
        //
        TableHeader h       = typeMethods.r8mat_header_read(quad_x_filename);
        int         dim_num = h.m;
        int         order   = h.n;

        if (dim_num != 1)
        {
            Console.WriteLine("");
            Console.WriteLine("INT_EXACTNESS_GEN_LAGUERRE - Fatal error!");
            Console.WriteLine("  The spatial dimension of X should be 1.");
            Console.WriteLine(" The implicit input dimension was DIM_NUM = " + dim_num + "");
            return;
        }

        Console.WriteLine("");
        Console.WriteLine("  Spatial dimension = " + dim_num + "");
        Console.WriteLine("  Number of points  = " + order + "");

        double[] x = typeMethods.r8mat_data_read(quad_x_filename, dim_num, order);
        //
        //  Read the W file.
        //
        h = typeMethods.r8mat_header_read(quad_w_filename);
        int dim_num2  = h.m;
        int point_num = h.n;

        if (dim_num2 != 1)
        {
            Console.WriteLine("");
            Console.WriteLine("INT_EXACTNESS_GEN_LAGUERRE - Fatal error!");
            Console.WriteLine("  The quadrature weight file should have exactly");
            Console.WriteLine("  one value on each line.");
            return;
        }

        if (point_num != order)
        {
            Console.WriteLine("");
            Console.WriteLine("INT_EXACTNESS_GEN_LAGUERRE - Fatal error!");
            Console.WriteLine("  The quadrature weight file should have exactly");
            Console.WriteLine("  the same number of lines as the abscissa file.");
            return;
        }

        double[] w = typeMethods.r8mat_data_read(quad_w_filename, dim_num, order);
        //
        //  Read the R file.
        //
        h        = typeMethods.r8mat_header_read(quad_r_filename);
        dim_num2 = h.m;
        int point_num2 = h.n;

        if (dim_num2 != dim_num)
        {
            Console.WriteLine("");
            Console.WriteLine("INT_EXACTNESS_GEN_LAGUERRE - Fatal error!");
            Console.WriteLine("  The quadrature region file should have the");
            Console.WriteLine("  same number of values on each line as the");
            Console.WriteLine("  abscissa file does.");
            return;
        }

        if (point_num2 != 2)
        {
            Console.WriteLine("");
            Console.WriteLine("INT_EXACTNESS_GEN_LAGUERDRE - Fatal error!");
            Console.WriteLine("  The quadrature region file should have two lines.");
            return;
        }

        double[] r = typeMethods.r8mat_data_read(quad_r_filename, dim_num, point_num2);
        //
        //  Print the input quadrature rule.
        //
        double a = r[0];

        Console.WriteLine("");
        Console.WriteLine("  The quadrature rule to be tested is");
        Console.WriteLine("  a generalized Gauss-Laguerre rule");
        Console.WriteLine("  ORDER = " + order + "");
        Console.WriteLine("  with A =     " + a + "");
        Console.WriteLine("  and  ALPHA = " + alpha + "");
        Console.WriteLine("");
        switch (option)
        {
        case 0:
            Console.WriteLine("  Standard rule:");
            Console.WriteLine("    Integral ( A <= x < +oo ) x^alpha exp(-x) f(x) dx");
            Console.WriteLine("    is to be approximated by");
            Console.WriteLine("    sum ( 1 <= I <= ORDER ) w(i) * f(x(i)).");
            break;

        default:
            Console.WriteLine("  Modified rule:");
            Console.WriteLine("    Integral ( A <= x < +oo )         f(x) dx");
            Console.WriteLine("    is to be approximated by");
            Console.WriteLine("    sum ( 1 <= I <= ORDER ) w(i) * f(x(i)).");
            break;
        }

        Console.WriteLine("");
        Console.WriteLine("  Weights W:");
        Console.WriteLine("");
        for (i = 0; i < order; i++)
        {
            Console.WriteLine("  w[" + i.ToString().PadLeft(2)
                              + "] = " + w[i].ToString("0.################").PadLeft(24) + "");
        }

        Console.WriteLine("");
        Console.WriteLine("  Abscissas X:");
        Console.WriteLine("");
        for (i = 0; i < order; i++)
        {
            Console.WriteLine("  x[" + i.ToString().PadLeft(2)
                              + "] = " + x[i].ToString("0.################").PadLeft(24) + "");
        }

        Console.WriteLine("");
        Console.WriteLine("  Region R:");
        Console.WriteLine("");

        for (i = 0; i < 2; i++)
        {
            Console.WriteLine("  r[" + i.ToString().PadLeft(2)
                              + "] = " + r[i].ToString("0.################").PadLeft(24) + "");
        }

        //
        //  Supposing the input rule is defined on [A,+oo),
        //  rescale the weights, and translate the abscissas,
        //  so our rule is defined on [0,+oo).
        //
        double volume = Math.Exp(-a);

        for (i = 0; i < order; i++)
        {
            w[i] /= volume;
        }

        for (i = 0; i < order; i++)
        {
            x[i] -= a;
        }

        //
        //  Explore the monomials.
        //
        Console.WriteLine("");
        Console.WriteLine("  A generalized Gauss-Laguerre rule would be able to exactly");
        Console.WriteLine("  integrate monomials up to and including degree = " +
                          (2 * order - 1) + "");
        Console.WriteLine("");
        Console.WriteLine("          Error          Degree");
        Console.WriteLine("");

        for (degree = 0; degree <= degree_max; degree++)
        {
            double quad_error = QuadratureRule.monomial_quadrature_gen_laguerre(degree, alpha, order,
                                                                                option, w, x);

            Console.WriteLine("  " + quad_error.ToString("0.################").PadLeft(24)
                              + "  " + degree.ToString().PadLeft(2) + "");
        }

        Console.WriteLine("");
        Console.WriteLine("INT_EXACTNESS_GEN_LAGUERRE:");
        Console.WriteLine("  Normal end of execution.");
        Console.WriteLine("");
    }