/// <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); }
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) + ""); } } }
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); }
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(""); }
/// <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); }
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); }
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(""); }
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(""); }
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; } } } }
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); }
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(""); }
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; } }
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); } } } } }
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 + ""); }
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 + ""); }
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(""); } }
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 + "'"); }
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) + ""); } } }
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(""); }
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); }
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; } } }
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(""); }
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); } } } } }
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]; } } }
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(""); }
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); }
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); }
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(""); }