private static void test004() //****************************************************************************80 // // Purpose: // // TEST004 tests TETRAHEDRON_ORDER10_TO_ORDER4. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 30 July 2009 // // Author: // // John Burkardt // { int node_num = 0; int tet_num = 0; const int tet_order = 10; Console.WriteLine(""); Console.WriteLine("TEST004"); Console.WriteLine(" TET_MESH_NODE_ORDER determines the order of "); Console.WriteLine(" each node in a tet mesh."); Console.WriteLine(""); Console.WriteLine(" The order of a node is the number of tetrahedrons"); Console.WriteLine(" that use the node as part of their definition."); TetMesh.tet_mesh_order10_example_size(ref node_num, ref tet_num); Console.WriteLine(""); Console.WriteLine(" This mesh has tetrahedron order " + tet_order + ""); Console.WriteLine(" The number of tetrahedrons is " + tet_num + ""); double[] node_xyz = new double[3 * node_num]; int[] tet_node = new int[tet_order * tet_num]; TetMesh.tet_mesh_order10_example_set(node_num, tet_num, ref node_xyz, ref tet_node); typeMethods.i4mat_transpose_print(tet_order, tet_num, tet_node, " The tet mesh:"); int[] node_order = TetMesh.tet_mesh_node_order(tet_order, tet_num, tet_node, node_num); typeMethods.i4vec_print(node_num, node_order, " Node orders:"); Console.WriteLine(""); Console.WriteLine(" Check that the following are equal:"); Console.WriteLine(""); Console.WriteLine(" Number of tetrahedrons * order = " + tet_num * tet_order + ""); Console.WriteLine(" Sum of node orders = " + typeMethods.i4vec_sum(node_num, node_order) + ""); }
private static void test006() //****************************************************************************80 // // Purpose: // // TEST006 tests TET_MESH_TET_NEIGHBORS. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 18 August 2009 // // Author: // // John Burkardt // { int node_num = 0; int tet_num = 0; const int tet_order = 4; Console.WriteLine(""); Console.WriteLine("TEST006"); Console.WriteLine(" TET_MESH_TET_NEIGHBORS computes the 4 neighboring"); Console.WriteLine(" tetrahedrons of each tetrahedron in a tet mesh."); Console.WriteLine(" containing a point."); // // Set up the example tetrahedron mesh. // TetMesh.tet_mesh_order4_example_size(ref node_num, ref tet_num); Console.WriteLine(""); Console.WriteLine(" This mesh has tetrahedron order " + tet_order + ""); Console.WriteLine(" The number of tetrahedrons is " + tet_num + ""); double[] node_xyz = new double[3 * node_num]; int[] tet_node = new int[tet_order * tet_num]; TetMesh.tet_mesh_order4_example_set(node_num, tet_num, ref node_xyz, ref tet_node); // // Print the tets. // typeMethods.i4mat_transpose_print_some(tet_order, tet_num, tet_node, 1, 1, tet_order, 10, " First 10 Tets:"); // // The TET_NEIGHBOR array is needed by TET_MESH_DELAUNAY_SEARCH. // int[] tet_neighbor = TetMesh.tet_mesh_neighbor_tets(tet_order, tet_num, tet_node); typeMethods.i4mat_transpose_print_some(4, tet_num, tet_neighbor, 1, 1, 4, 10, " First 10 Tet Neighbors:"); }
private static void test007() //****************************************************************************80 // // Purpose: // // TEST007 tests TET_MESH_SEARCH_NAIVE. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 19 August 2009 // // Author: // // John Burkardt // { int face = 0; int node_num = 0; double[] p = new double[3]; int step_num = 0; int test; const int test_num = 5; int tet_num = 0; const int tet_order = 4; double[] tet_xyz = new double[3 * 4]; int seed = 123456789; Console.WriteLine(""); Console.WriteLine("TEST007"); Console.WriteLine(" TET_MESH_SEARCH_NAIVE uses a naive algorithm"); Console.WriteLine(" to search a tetrahedral mesh for the tetrahedron"); Console.WriteLine(" containing a point."); // // Set up the example tetrahedron mesh. // TetMesh.tet_mesh_order4_example_size(ref node_num, ref tet_num); Console.WriteLine(""); Console.WriteLine(" This mesh has tetrahedron order " + tet_order + ""); Console.WriteLine(" The number of tetrahedrons is " + tet_num + ""); double[] node_xyz = new double[3 * node_num]; int[] tet_node = new int[tet_order * tet_num]; TetMesh.tet_mesh_order4_example_set(node_num, tet_num, ref node_xyz, ref tet_node); // // The TET_NEIGHBOR array is needed for the Delaunay search. // int[] tet_neighbor = TetMesh.tet_mesh_neighbor_tets(tet_order, tet_num, tet_node); for (test = 1; test <= test_num; test++) { // // Choose a tetrahedron at random. // int tet1 = UniformRNG.i4_uniform_ab(0, tet_num - 1, ref seed); Console.WriteLine(""); Console.WriteLine(" Point was chosen from tetrahedron " + tet1.ToString(CultureInfo.InvariantCulture).PadLeft(8) + ""); int j; for (j = 0; j < 4; j++) { int k = tet_node[j + tet1 * 4]; int i; for (i = 0; i < 3; i++) { tet_xyz[i + j * 3] = node_xyz[i + k * 3]; } } // // Choose a point in the tetrahedron at random. // Tetrahedron.tetrahedron_sample(tet_xyz, 1, ref seed, ref p); // // Naive search. // int tet2 = TetMesh.tet_mesh_search_naive(node_num, node_xyz, tet_order, tet_num, tet_node, p, ref step_num); Console.WriteLine(" Naive search ended in tetrahedron " + tet2.ToString(CultureInfo.InvariantCulture).PadLeft(8) + ", number of steps = " + step_num + ""); // // Delaunay search. // int tet3 = TetMesh.tet_mesh_search_delaunay(node_num, node_xyz, tet_order, tet_num, tet_node, tet_neighbor, p, ref face, ref step_num); Console.WriteLine(" Delaunay search ended in tetrahedron " + tet3.ToString(CultureInfo.InvariantCulture).PadLeft(8) + ", number of steps = " + step_num + ""); } }
private static void test003() //****************************************************************************80 // // Purpose: // // TEST003 tests TETRAHEDRON_ORDER10_TO_ORDER4. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 22 January 2007 // // Author: // // John Burkardt // { int node_num1 = 0; int node_num2 = 0; int tet_num1 = 0; int tet_num2 = 0; const int tet_order1 = 10; const int tet_order2 = 4; Console.WriteLine(""); Console.WriteLine("TEST003"); Console.WriteLine(" For an order 10 tet mesh,"); Console.WriteLine(" TETRAHEDRON_ORDER10_TO_ORDER4"); Console.WriteLine(" makes a linear (order 4) tet mesh by using"); Console.WriteLine(" the existing nodes, and replacing each"); Console.WriteLine(" quadratic tetrahedron by 8 linear tetrahedrons."); TetMesh.tet_mesh_order10_example_size(ref node_num1, ref tet_num1); double[] node_xyz = new double[3 * node_num1]; int[] tet_node1 = new int[tet_order1 * tet_num1]; TetMesh.tet_mesh_order10_example_set(node_num1, tet_num1, ref node_xyz, ref tet_node1); typeMethods.i4mat_transpose_print_some(tet_order1, tet_num1, tet_node1, 1, 1, tet_order1, 5, " First 5 quadratic tetrahedrons:"); TetMesh.tet_mesh_order10_to_order4_size(node_num1, tet_num1, ref node_num2, ref tet_num2); Console.WriteLine(""); Console.WriteLine(" Quadratic mesh size is " + tet_num1 + ""); Console.WriteLine(" Linearized mesh size will be " + tet_num2 + ""); int[] tet_node2 = new int[tet_order2 * tet_num2]; TetMesh.tet_mesh_order10_to_order4_compute(tet_num1, tet_node1, tet_num2, ref tet_node2); typeMethods.i4mat_transpose_print_some(tet_order2, tet_num2, tet_node2, 1, 1, tet_order2, 5, " First 5 linear tetrahedrons:"); }
private static void Main(string[] args) //****************************************************************************80 // // Purpose: // // MAIN is the main program for TET_MESH_REFINE. // // Discussion: // // TET_MESH_REFINE refines a tetrahedral mesh of order 4 (linear). // // Usage: // // tet_mesh_refine prefix // // where prefix is the common file prefix: // // * prefix_nodes.txt, the node coordinates; // * prefix_elements.txt, the element definitions. // * prefix_ref_nodes.txt, the new node coordinates; // * prefix_ref_elements.txt, the new element definitions. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 18 August 2009 // // Author: // // John Burkardt // { int[] element_node2 = new int[1]; int element_num2 = 0; int node_num2 = 0; double[] node_xyz2 = new double[1]; string prefix; Console.WriteLine(""); Console.WriteLine("TET_MESH_REFINE"); Console.WriteLine(" READ a tet mesh, REFINE it, and WRITE the new data."); Console.WriteLine(""); Console.WriteLine(" READ:"); Console.WriteLine(" a node dataset of NODE_NUM1 points in 3 dimensions."); Console.WriteLine(" a tet mesh of TETRA_NUM1 tets of order TET_ORDER."); Console.WriteLine(""); Console.WriteLine(" REFINE:"); Console.WriteLine(" compute a new set of nodes and tets, which is an"); Console.WriteLine(" eightfold refinement of the input mesh."); Console.WriteLine(""); Console.WriteLine(" WRITE:"); Console.WriteLine(" a node dataset of NODE_NUM2 points in 3 dimensions."); Console.WriteLine(" a tet mesh of 8*TETRA_NUM1 tets of order TET_ORDER."); Console.WriteLine(""); Console.WriteLine(" At the moment, this program only works for a linear"); Console.WriteLine(" mesh (TET_ORDER=4)."); Console.WriteLine(""); // // Get the filename prefix. // try { prefix = args[0]; } catch { Console.WriteLine(""); Console.WriteLine("TET_MESH_REFINE:"); Console.WriteLine(" Please enter the filename prefix."); prefix = Console.ReadLine(); } // // Create the filenames. // string input_node_filename = prefix + "_nodes.txt"; string input_element_filename = prefix + "_elements.txt"; string output_node_filename = prefix + "_ref_nodes.txt"; string output_element_filename = prefix + "_ref_elements.txt"; // // Read the node data. // TableHeader h = typeMethods.r8mat_header_read(input_node_filename); int dim_num = h.m; int node_num1 = h.n; if (dim_num != 3) { Console.WriteLine(""); Console.WriteLine("TET_MESH_REFINE - Fatal error!"); Console.WriteLine(" The spatial dimension must be 3."); return; } Console.WriteLine(""); Console.WriteLine(" Read the header of \"" + input_node_filename + "\"."); Console.WriteLine(""); Console.WriteLine(" Spatial dimension = " + dim_num + ""); Console.WriteLine(" Number of nodes = " + node_num1 + ""); double[] node_xyz1 = typeMethods.r8mat_data_read(input_node_filename, dim_num, node_num1); Console.WriteLine(""); Console.WriteLine(" Read the data in \"" + input_node_filename + "\"."); typeMethods.r8mat_transpose_print_some(dim_num, node_num1, node_xyz1, 1, 1, dim_num, 5, " First 5 input nodes:"); // // Read the tet mesh data. // h = typeMethods.i4mat_header_read(input_element_filename); int element_order = h.m; int element_num1 = h.n; switch (element_order) { case 4: break; case 10: Console.WriteLine(""); Console.WriteLine("TET_MESH_REFINE - Fatal error!"); Console.WriteLine(" The program cannot yet handel the 10-node case."); Console.WriteLine(" Try using the sequence:"); Console.WriteLine(" TET_MESH_Q2L --> TET_MESH_REFINE --> TET_MESH_L2Q."); return; default: Console.WriteLine(""); Console.WriteLine("TET_MESH_REFINE - Fatal error!"); Console.WriteLine(" The tet mesh must have order 4 or order 10."); return; } Console.WriteLine(""); Console.WriteLine(" Read the header of \"" + input_element_filename + "\"."); Console.WriteLine(""); Console.WriteLine(" Tetrahedron order = " + element_order + ""); Console.WriteLine(" Number of tetras = " + element_num1 + ""); int[] element_node1 = typeMethods.i4mat_data_read(input_element_filename, element_order, element_num1); Console.WriteLine(""); Console.WriteLine(" Read the data in \"" + input_element_filename + "\"."); typeMethods.i4mat_transpose_print_some(element_order, element_num1, element_node1, 1, 1, element_order, 5, " First 5 input tetrahedrons:"); // // Check for 1-based node-indexing, and convert it to 0-based. // TetMesh.tet_mesh_base_zero(node_num1, element_order, element_num1, ref element_node1); switch (element_order) { // // Compute the refined mesh. // case 4: int[] edge_data = new int[5 * 6 * element_num1]; TetMesh_Refine.tet_mesh_order4_refine_size(node_num1, element_num1, element_node1, ref node_num2, ref element_num2, ref edge_data); Console.WriteLine(" Number of refined nodes = " + node_num2 + ""); Console.WriteLine(" Number of refined tetras = " + element_num2 + ""); node_xyz2 = new double[dim_num * node_num2]; element_node2 = new int[element_order * element_num2]; TetMesh_Refine.tet_mesh_order4_refine_compute(node_num1, element_num1, node_xyz1, element_node1, node_num2, element_num2, edge_data, ref node_xyz2, ref element_node2); break; case 10: { break; } } // // Print a small amount of the refined data. // typeMethods.r8mat_transpose_print_some(dim_num, node_num2, node_xyz2, 1, 1, dim_num, 5, " First 5 output nodes:"); typeMethods.i4mat_transpose_print_some(element_order, element_num2, element_node2, 1, 1, element_order, 5, " First 5 output tetras"); // // Write out the node and tetra data for the refined mesh // typeMethods.r8mat_write(output_node_filename, dim_num, node_num2, node_xyz2); Console.WriteLine(""); Console.WriteLine(" Wrote the file \"" + output_node_filename + "\"."); typeMethods.i4mat_write(output_element_filename, element_order, element_num2, element_node2); Console.WriteLine(" Wrote the file \"" + output_element_filename + "\"."); Console.WriteLine(""); Console.WriteLine("TET_MESH_REFINE:"); Console.WriteLine(" Normal end of execution."); Console.WriteLine(""); }
public static double[] fem3d_evaluate(int fem_node_num, double[] fem_node_xyz, int fem_element_order, int fem_element_num, int[] fem_element_node, int[] fem_element_neighbor, int fem_value_dim, double[] fem_value, int sample_node_num, double[] sample_node_xyz) //****************************************************************************80 // // Purpose: // // FEM3D_EVALUATE samples an FEM function on a T4 tet mesh. // // Discussion: // // Note that the sample values returned are true values of the underlying // finite element function. They are NOT produced by constructing some // other function that interpolates the data at the finite element nodes // (something which MATLAB's griddata function can easily do.) Instead, // each sampling node is located within one of the associated finite // element tetrahedrons, and the finite element function is developed and // evaluated there. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 08 August 2009 // // Author: // // John Burkardt // // Parameters: // // Input, int FEM_NODE_NUM, the number of nodes. // // Input, double FEM_NODE_XYZ[3*FEM_NODE_NUM], the coordinates // of the nodes. // // Input, int FEM_ELEMENT_ORDER, the order of the elements, // which should be 4. // // Input, int FEM_ELEMENT_NUM, the number of elements. // // Input, int FEM_ELEMENT_NODE[FEM_ELEMENT_ORDER*FEM_ELEMENT_NUM], the // nodes that make up each element. // // Input, int FEM_ELEMENT_NEIGHBOR[4*FEM_ELEMENT_NUM], the // index of the neighboring element on each side, or -1 if no neighbor there. // // Input, int FEM_VALUE_DIM, the "dimension" of the values. // // Input, double FEM_VALUE[FEM_VALUE_DIM*FEM_NODE_NUM], the // finite element coefficient values at each node. // // Input, int SAMPLE_NODE_NUM, the number of sample nodes. // // Input, double SAMPLE_NODE_XYZ[3*SAMPLE_NODE_NUM], the sample nodes. // // Output, double) FEM3D_EVALUATE[FEM_VALUE_DIM*SAMPLE_NODE_NUM], // the sampled values. // { int j; double[] p_xyz = new double[3]; double[] b = new double[fem_element_order]; double[] sample_value = new double[fem_value_dim * sample_node_num]; int[] t_node = new int[fem_element_order]; double[] t_xyz = new double[3 * fem_element_order]; // // For each sample point: find the element T that contains it, // and evaluate the finite element function there. // for (j = 0; j < sample_node_num; j++) { p_xyz[0] = sample_node_xyz[0 + j * 3]; p_xyz[1] = sample_node_xyz[1 + j * 3]; p_xyz[2] = sample_node_xyz[2 + j * 3]; // // Find the element T that contains the point. // int step_num = 0; int t = TetMesh.tet_mesh_search_naive(fem_node_num, fem_node_xyz, fem_element_order, fem_element_num, fem_element_node, p_xyz, ref step_num); // // Evaluate the finite element basis functions at the point in T. // int i; for (i = 0; i < fem_element_order; i++) { t_node[i] = fem_element_node[i + t * fem_element_order]; } for (i = 0; i < fem_element_order; i++) { t_xyz[0 + i * 3] = fem_node_xyz[0 + t_node[i] * 3]; t_xyz[1 + i * 3] = fem_node_xyz[1 + t_node[i] * 3]; t_xyz[2 + i * 3] = fem_node_xyz[2 + t_node[i] * 3]; } Basis_mn.basis_mn_tet4(t_xyz, 1, p_xyz, ref b); // // Multiply by the finite element values to get the sample values. // for (i = 0; i < fem_value_dim; i++) { sample_value[i + j * fem_value_dim] = 0.0; int k; for (k = 0; k < fem_element_order; k++) { sample_value[i + j * fem_value_dim] += fem_value[i + t_node[k] * fem_value_dim] * b[k]; } } } return(sample_value); }
private static void Main(string[] args) //****************************************************************************80 // // Purpose: // // MAIN is the main program for TET_MESH_L2Q. // // Discussion: // // TET_MESH_L2Q makes a quadratic tet mesh from a linear one. // // Usage: // // tet_mesh_l2q prefix // // where prefix is the common file prefix: // // * prefix_nodes.txt, the node coordinates; // * prefix_elements.txt, the linear element definitions. // * prefix_l2q_nodes.txt, the quadratic node coordinates, // * prefix_l2q_elements.txt, the quadratic element definitions. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 01 October 2009 // // Author: // // John Burkardt // { const int element_order2 = 10; int node_num2 = 0; string prefix; Console.WriteLine(""); Console.WriteLine("TET_MESH_L2Q"); Console.WriteLine(" Read a \"linear\" tet mesh and"); Console.WriteLine(" write out a \"quadratic\" one."); Console.WriteLine(""); Console.WriteLine(" Read a node file of NODE_NUM1 nodes in 3 dimensions."); Console.WriteLine(" Read an associated tet mesh of TETRA_NUM"); Console.WriteLine(" tetrahedrons, using 4 nodes per tetrahedron."); Console.WriteLine(""); Console.WriteLine(" Create new nodes which are midpoints of sides,"); Console.WriteLine(" generate new node and tet mesh data for"); Console.WriteLine(" quadratic 10-node tetrahedrons, and write them out."); Console.WriteLine(""); // // Get the filename prefix. // try { prefix = args[0]; } catch { Console.WriteLine(""); Console.WriteLine("TET_MESH_L2Q:"); Console.WriteLine(" Please enter the filename prefix."); prefix = Console.ReadLine(); } // // Create the filenames. // string input_node_filename = prefix + "_nodes.txt"; string input_element_filename = prefix + "_elements.txt"; string output_node_filename = prefix + "_l2q_nodes.txt"; string output_element_filename = prefix + "_l2q_elements.txt"; // // Read the node data. // TableHeader h = typeMethods.r8mat_header_read(input_node_filename); int dim_num = h.m; int node_num1 = h.n; if (dim_num != 3) { Console.WriteLine(""); Console.WriteLine("TET_MESH_L2Q - Fatal error!"); Console.WriteLine(" The spatial dimension must be 3."); Console.WriteLine(" This data has dimension = " + dim_num + ""); return; } Console.WriteLine(""); Console.WriteLine(" Read the header of \"" + input_node_filename + "\"."); Console.WriteLine(""); Console.WriteLine(" Spatial dimension = " + dim_num + ""); Console.WriteLine(" Number of nodes = " + node_num1 + ""); double[] node_xyz1 = typeMethods.r8mat_data_read(input_node_filename, dim_num, node_num1); Console.WriteLine(""); Console.WriteLine(" Read the data in \"" + input_node_filename + "\"."); typeMethods.r8mat_transpose_print_some(dim_num, node_num1, node_xyz1, 1, 1, dim_num, 5, " First 5 nodes:"); // // Read the tet mesh data. // h = typeMethods.i4mat_header_read(input_element_filename); int element_order1 = h.m; int element_num = h.n; if (element_order1 != 4) { Console.WriteLine(""); Console.WriteLine("TET_MESH_L2Q - Fatal error!"); Console.WriteLine(" The tet mesh must have order 4."); Console.WriteLine(" This mesh has order " + element_order1 + ""); return; } Console.WriteLine(""); Console.WriteLine(" Read the header of \"" + input_element_filename + "\"."); Console.WriteLine(""); Console.WriteLine(" Tetrahedron order = " + element_order1 + ""); Console.WriteLine(" Number of tetras = " + element_num + ""); int[] element_node1 = typeMethods.i4mat_data_read(input_element_filename, element_order1, element_num); Console.WriteLine(""); Console.WriteLine(" Read the data in \"" + input_element_filename + "\"."); typeMethods.i4mat_transpose_print_some(element_order1, element_num, element_node1, 1, 1, element_order1, 5, " First 5 tetrahedrons:"); // // If the element information is 1-based, make it 0-based. // TetMesh.tet_mesh_base_zero(node_num1, element_order1, element_num, ref element_node1); // // Compute the quadratic mesh. // int[] edge_data = new int[5 * 6 * element_num]; TetMesh_L2Q.tet_mesh_order4_to_order10_size(element_num, element_node1, node_num1, ref edge_data, ref node_num2); Console.WriteLine(" Number of quadratic nodes = " + node_num2 + ""); double[] node_xyz2 = new double[dim_num * node_num2]; int[] element_node2 = new int[element_order2 * element_num]; TetMesh_L2Q.tet_mesh_order4_to_order10_compute(element_num, element_node1, node_num1, node_xyz1, edge_data, ref element_node2, node_num2, ref node_xyz2); // // Print a small amount of the quadratic data. // typeMethods.r8mat_transpose_print_some(dim_num, node_num2, node_xyz2, 1, 1, dim_num, 5, " First 5 quadratic nodes:"); typeMethods.i4mat_transpose_print_some(element_order2, element_num, element_node2, 1, 1, element_order2, 5, " First 5 quadratic tetras"); // // Write out the node and tetra data for the quadratic mesh // typeMethods.r8mat_write(output_node_filename, dim_num, node_num2, node_xyz2); Console.WriteLine(""); Console.WriteLine(" Wrote the file \"" + output_node_filename + "\"."); typeMethods.i4mat_write(output_element_filename, element_order2, element_num, element_node2); Console.WriteLine(" Wrote the file \"" + output_element_filename + "\"."); Console.WriteLine(""); Console.WriteLine("TET_MESH_L2Q:"); Console.WriteLine(" Normal end of execution."); Console.WriteLine(""); }
private static void Main(string[] args) //****************************************************************************80 // // Purpose: // // MAIN is the main program for TET_MESH_TET_NEIGHBORS. // // Discussion: // // TET_MESH_TET_NEIGHBORS manages the tet mesh neighbor calculation. // // A tet mesh of order 4 or order 10 may be used. // // Usage: // // tet_mesh_tet_neighbors prefix // // where prefix is the common file prefix: // // * prefix_nodes.txt, the node coordinates (not needed by this program); // * prefix_elements.txt, the linear element definitions. // * prefix_element_neighbors.txt, the element neighbors. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 27 September 2009 // // Author: // // John Burkardt // { const int node_num = 0; string prefix; Console.WriteLine(""); Console.WriteLine("TET_MESH_TET_NEIGHBORS"); Console.WriteLine(" Read a tet mesh dataset of TETRA_NUM"); Console.WriteLine(" tetrahedrons, using 4 or 10 nodes."); Console.WriteLine(""); Console.WriteLine(" Compute the tet mesh neighbors, and write this"); Console.WriteLine(" information to a file"); Console.WriteLine(""); // // Get the filename prefix. // try { prefix = args[0]; } catch { Console.WriteLine(""); Console.WriteLine("TET_MESH_TET_NEIGHBORS:"); Console.WriteLine(" Please enter the filename prefix."); prefix = Console.ReadLine(); } // // Create the filenames. // string element_filename = prefix + "_elements.txt"; string neighbor_filename = prefix + "_element_neighbors.txt"; // // Read the tet mesh data. // TableHeader h = typeMethods.i4mat_header_read(element_filename); int element_order = h.m; int element_num = h.n; if (element_order != 4 && element_order != 10) { Console.WriteLine(""); Console.WriteLine("TET_MESH_TET_NEIGHBORS - Fatal error!"); Console.WriteLine(" The tet mesh must have order 4 or order 10."); return; } Console.WriteLine(""); Console.WriteLine(" Read the header of \"" + element_filename + "\"."); Console.WriteLine(""); Console.WriteLine(" Tetrahedron order = " + element_order + ""); Console.WriteLine(" Number of tetras = " + element_num + ""); int[] element_node = typeMethods.i4mat_data_read(element_filename, element_order, element_num); Console.WriteLine(""); Console.WriteLine(" Read the data in \"" + element_filename + "\"."); typeMethods.i4mat_transpose_print_some(element_order, element_num, element_node, 1, 1, element_order, 5, " First 5 tetrahedrons:"); // // Detect and correct 1-based node indexing. // TetMesh.tet_mesh_base_zero(node_num, element_order, element_num, ref element_node); // // Compute the neighbor information. // int[] element_neighbor = TetMesh_Neighbors.tet_mesh_neighbor_tets(element_order, element_num, element_node); typeMethods.i4mat_transpose_print_some(4, element_num, element_neighbor, 1, 1, 4, 5, " First 5 neighbor sets:"); // // Write the neighbor information to a file. // typeMethods.i4mat_write(neighbor_filename, 4, element_num, element_neighbor); Console.WriteLine(""); Console.WriteLine(" Created the file \"" + neighbor_filename + "\"."); Console.WriteLine(""); Console.WriteLine("TET_MESH_TET_NEIGHBORS:"); Console.WriteLine(" Normal end of execution."); Console.WriteLine(""); }
private static void Main(string[] args) //****************************************************************************80 // // Purpose: // // MAIN is the main program for TET_MESH_RCM. // // Discussion: // // TET_MESH_RCM applies the RCM reordering to a tet mesh. // // The user supplies a node file and a tetrahedron file, containing // the coordinates of the nodes, and the indices of the nodes that // make up each tetrahedron. Either 4-node or 10-node tetrahedrons may // be used. // // The program reads the data, computes the adjacency information, // carries out the RCM algorithm to get the permutation, applies // the permutation to the nodes and tetrahedrons, and writes out // new node and tetrahedron files that correspond to the RCM permutation. // // Note that node data is normally three dimensional, that is, // each node has an X, Y and Z coordinate. In some applications, it // may be desirable to specify more information. This program // will accept node data that includes DIM_NUM entries on each line, // as long as DIM_NUM is the same for each entry. // // Thanks to Xingxing Zhang for pointing out some problems with a // previous version of this program, 10 May 2011. // // Usage: // // tet_mesh_rcm prefix // // where prefix is the common file prefix: // // * prefix_nodes.txt, the node coordinates (input); // * prefix_elements.txt, the element definitions (input). // * prefix_rcm_nodes.txt, the new node coordinates (output); // * prefix_rcm_elements.txt, the new element definitions (output). // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 08 March 2013 // // Author: // // John Burkardt // { int[] adj = new int[1]; int adj_num = 0; int[] adj_row = new int[1]; const bool debug = false; int i; int j; string prefix; Console.WriteLine(""); Console.WriteLine(""); Console.WriteLine("TET_MESH_RCM"); Console.WriteLine(" Read a node dataset of NODE_NUM points in 3 dimensions."); Console.WriteLine(" Read an associated tet mesh dataset of TETRA_NUM"); Console.WriteLine(" tetrahedrons using 4 or 10 nodes."); Console.WriteLine(""); Console.WriteLine(" Apply the RCM reordering (Reverse Cuthill-McKee)."); Console.WriteLine(""); Console.WriteLine(" Reorder the data and write it out to files."); Console.WriteLine(""); // // Get the filename prefix. // try { prefix = args[0]; } catch { Console.WriteLine(""); Console.WriteLine("TET_MESH_RCM:"); Console.WriteLine(" Please enter the filename prefix."); prefix = Console.ReadLine(); } // // Create the filenames. // string node_filename = prefix + "_nodes.txt"; string element_filename = prefix + "_elements.txt"; string node_rcm_filename = prefix + "_rcm_nodes.txt"; string element_rcm_filename = prefix + "_rcm_elements.txt"; // // Read the node data. // TableHeader h = typeMethods.r8mat_header_read(node_filename); int dim_num = h.m; int node_num = h.n; Console.WriteLine(""); Console.WriteLine(" Read the header of \"" + node_filename + "\"."); Console.WriteLine(""); Console.WriteLine(" Spatial dimension DIM_NUM = " + dim_num + ""); Console.WriteLine(" Number of points NODE_NUM = " + node_num + ""); double[] node_xyz = typeMethods.r8mat_data_read(node_filename, dim_num, node_num); Console.WriteLine(""); Console.WriteLine(" Read the data in \"" + node_filename + "\"."); typeMethods.r8mat_transpose_print_some(dim_num, node_num, node_xyz, 1, 1, dim_num, 5, " Coordinates of first 5 nodes:"); // // Read the tet mesh data. // h = typeMethods.i4mat_header_read(element_filename); int element_order = h.m; int element_num = h.n; if (element_order != 4 && element_order != 10) { Console.WriteLine(""); Console.WriteLine("TET_MESH_RCM - Fatal error!"); Console.WriteLine(" The tet mesh must have order 4 or order 10."); return; } Console.WriteLine(""); Console.WriteLine(" Read the header of \"" + element_filename + "\"."); Console.WriteLine(""); Console.WriteLine(" Tetrahedron order = " + element_order + ""); Console.WriteLine(" Number of tetras = " + element_num + ""); int[] element_node = typeMethods.i4mat_data_read(element_filename, element_order, element_num); Console.WriteLine(""); Console.WriteLine(" Read the data in \"" + element_filename + "\"."); typeMethods.i4mat_transpose_print_some(element_order, element_num, element_node, 1, 1, element_order, 5, " First 5 tetrahedrons:"); // // If the element information is 1-based, make it 0-based. // int base_user = TetMesh.tet_mesh_base_zero(node_num, element_order, element_num, ref element_node); if (base_user != 0 && base_user != 1) { Console.WriteLine(""); Console.WriteLine("TET_MESH_RCM - Fatal error!"); Console.WriteLine(" The input data does not seem to be 0-based or 1-based."); } switch (element_order) { // // Following code depends on the element order. // case 4: { // // Count the number of adjacencies. // Set up the ADJ_ROW adjacency pointer array. // adj_row = new int[node_num + 1]; TetMesh.tet_mesh_order4_adj_count(node_num, element_num, element_node, ref adj_num, ref adj_row); if (debug || node_num < 10) { Console.WriteLine(""); Console.WriteLine(" ADJ_NUM = " + adj_num + ""); typeMethods.i4vec_print(node_num + 1, adj_row, " ADJ_ROW:"); } // // Set up the ADJ adjacency array. // adj = TetMesh.tet_mesh_order4_adj_set(node_num, element_num, element_node, adj_num, adj_row); switch (node_num) { case < 10: AdjacencyMatrix.adj_print(node_num, adj_num, adj_row, adj, " ADJ"); break; } break; } case 10: { // // Count the number of adjacencies. // Set up the ADJ_ROW adjacency pointer array. // adj_row = new int[node_num + 1]; TetMesh.tet_mesh_order10_adj_count(node_num, element_num, element_node, ref adj_num, ref adj_row); if (debug || node_num < 10) { Console.WriteLine(""); Console.WriteLine(" ADJ_NUM = " + adj_num + ""); typeMethods.i4vec_print(node_num + 1, adj_row, " ADJ_ROW:"); } // // Set up the ADJ adjacency array. // adj = TetMesh.tet_mesh_order10_adj_set(node_num, element_num, element_node, ref adj_num, ref adj_row); switch (node_num) { case < 10: AdjacencyMatrix.adj_print(node_num, adj_num, adj_row, adj, " ADJ"); break; } break; } } // // Compute the bandwidth. // int bandwidth = AdjacencyMatrix.adj_bandwidth(node_num, adj_num, adj_row, adj); Console.WriteLine(""); Console.WriteLine(" ADJ bandwidth = " + bandwidth + ""); // // GENRCM computes the RCM permutation. // int[] perm = GenRCM.genrcm(node_num, adj_num, adj_row, adj); // // Compute the inverse permutation. // int[] perm_inv = typeMethods.perm_inverse3(node_num, perm); switch (node_num) { case < 10: { Console.WriteLine(""); Console.WriteLine(" I PERM[I] INVERSE[I]"); Console.WriteLine(""); for (i = 0; i < node_num; i++) { Console.WriteLine(" " + i.ToString().PadLeft(8) + " " + perm[i].ToString().PadLeft(8) + " " + perm_inv[i].ToString().PadLeft(8) + ""); } break; } } // // Compute the bandwidth of the permuted array. // bandwidth = AdjacencyMatrix.adj_perm_bandwidth(node_num, adj_num, adj_row, adj, perm, perm_inv); Console.WriteLine(""); Console.WriteLine(" ADJ bandwidth after RCM permutation = " + bandwidth + ""); // // Permute the nodes in NODE_XYZ. // int base_internal = 0; typeMethods.r8col_permute(dim_num, node_num, perm, base_internal, node_xyz); // // Permute the node indices in ELEMENT_NODE. // for (j = 0; j < element_num; j++) { for (i = 0; i < element_order; i++) { int node = element_node[i + j * element_order]; element_node[i + j * element_order] = perm_inv[node]; } } switch (base_user) { // // If the user base was 1, restore it! // case 1: { for (i = 0; i < element_num; i++) { for (j = 0; j < element_order; j++) { element_node[i + j * element_order] += 1; } } Console.WriteLine(""); Console.WriteLine(" Output files will use the same 1-based ordering used by the input."); break; } } // // Write the node and element data. // typeMethods.r8mat_write(node_rcm_filename, dim_num, node_num, node_xyz); Console.WriteLine(""); Console.WriteLine(" Created the file \"" + node_rcm_filename + "\"."); typeMethods.i4mat_write(element_rcm_filename, element_order, element_num, element_node); Console.WriteLine(" Created the file \"" + element_rcm_filename + "\"."); Console.WriteLine(""); Console.WriteLine("TET_MESH_RCM:"); Console.WriteLine(" Normal end of execution."); Console.WriteLine(""); }
private static void Main(string[] args) //****************************************************************************80 // // Purpose: // // MAIN is the main program for TET_MESH_TO_GMSH. // // Discussion: // // TET_MESH_TO_GMSH converts a tet mesh, using 4 or 10 node // tetrahedral elements, to a Gmsh file. // // Usage: // // tet_mesh_to_gmsh prefix // // where prefix is the common file prefix: // // * prefix_nodes.txt, the node coordinates; // * prefix_elements.txt, the linear element definitions. // * prefix.msh, the Gmsh msh file. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 31 May 2013 // // Author: // // John Burkardt // // Reference: // // Christophe Geuzaine, Jean-Francois Remacle, // Gmsh: a three-dimensional finite element mesh generator with // built-in pre- and post-processing facilities, // International Journal for Numerical Methods in Engineering, // Volume 79, Number 11, pages 1309-1331, 2009. // { string prefix; Console.WriteLine(""); Console.WriteLine("TET_MESH_TO_GMSH;"); Console.WriteLine(" Convert a linear or quadratic tet mesh to Gmsh format"); Console.WriteLine(""); Console.WriteLine(" Read \"prefix\"_nodes.txt, node coordinates."); Console.WriteLine(" Read \"prefix\"_elements.txt, 4 or 10 node element definitions."); Console.WriteLine(""); Console.WriteLine(" Create \"prefix\".msh, a corresponding Gmsh mesh file."); Console.WriteLine(""); // // Get the filename prefix. // try { prefix = args[0]; } catch { Console.WriteLine(""); Console.WriteLine("TET_MESH_TO_GMSH;:"); Console.WriteLine(" Please enter the filename prefix."); prefix = Console.ReadLine(); } // // Create the filenames. // string node_filename = prefix + "_nodes.txt"; string element_filename = prefix + "_elements.txt"; string gmsh_filename = prefix + ".msh"; // // Read the node data. // TableHeader h = typeMethods.r8mat_header_read(node_filename); int dim_num = h.m; int node_num = h.n; if (dim_num != 3) { Console.WriteLine(""); Console.WriteLine("TET_MESH_TO_GMSH; - Fatal error!"); Console.WriteLine(" The spatial dimension must be 3."); return; } Console.WriteLine(""); Console.WriteLine(" Read the header of \"" + node_filename + "\"."); Console.WriteLine(""); Console.WriteLine(" Spatial dimension = " + dim_num + ""); Console.WriteLine(" Number of nodes = " + node_num + ""); double[] node_xyz = typeMethods.r8mat_data_read(node_filename, dim_num, node_num); Console.WriteLine(""); Console.WriteLine(" Read the data in \"" + node_filename + "\"."); typeMethods.r8mat_transpose_print_some(dim_num, node_num, node_xyz, 1, 1, dim_num, 5, " First 5 nodes:"); // // Read the element data. // h = typeMethods.i4mat_header_read(element_filename); int element_order = h.m; int element_num = h.n; switch (element_order) { case 4: break; case 10: break; case 20: break; default: Console.WriteLine(""); Console.WriteLine("TET_MESH_TO_GMSH; - Fatal error!"); Console.WriteLine(" The tet mesh must have order 4, 10, or 20."); return; } Console.WriteLine(""); Console.WriteLine(" Read the header of \"" + element_filename + "\"."); Console.WriteLine(""); Console.WriteLine(" Element order = " + element_order + ""); Console.WriteLine(" Number of elements = " + element_num + ""); int[] element_node = typeMethods.i4mat_data_read(element_filename, element_order, element_num); Console.WriteLine(""); Console.WriteLine(" Read the data in \"" + element_filename + "\"."); typeMethods.i4mat_transpose_print_some(element_order, element_num, element_node, 1, 1, element_order, 5, " First 5 elements:"); // // Use 1-based indexing. // TetMesh.tet_mesh_base_one(node_num, element_order, element_num, ref element_node); // // Write the Gmsh file. // Burkardt.GMesh.IO.gmsh_write(gmsh_filename, dim_num, node_num, node_xyz, element_order, element_num, element_node); Console.WriteLine(""); Console.WriteLine(" Created GMSH file \"" + gmsh_filename + "\"."); Console.WriteLine(""); Console.WriteLine("TET_MESH_TO_GMSH;"); Console.WriteLine(" Normal end of execution."); Console.WriteLine(""); }
private static void Main(string[] args) //****************************************************************************80 // // Purpose: // // MAIN is the main program for TET_MESH_QUALITY. // // Discussion: // // TET_MESH_QUALITY determines quality measures for a tet mesh. // // Usage: // // tet_mesh_quality prefix // // where prefix is the common file prefix: // // * prefix_nodes.txt contains the node coordinates; // * prefix_elements.txt contains the element definitions. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 27 September 2009 // // Author: // // John Burkardt // { int i; string prefix; double value_max = 0; double value_mean = 0; double value_min = 0; double value_var = 0; Console.WriteLine(""); Console.WriteLine(""); Console.WriteLine("TET_MESH_QUALITY"); Console.WriteLine(" Compute tet mesh quality measures."); Console.WriteLine(""); // // Get the filename prefix. // try { prefix = args[0]; } catch { Console.WriteLine(""); Console.WriteLine("TET_MESH_QUALITY:"); Console.WriteLine(" Please enter the file prefix."); prefix = Console.ReadLine(); } // // Create the filenames. // string node_filename = prefix + "_nodes.txt"; string element_filename = prefix + "_elements.txt"; // // Read the node data. // TableHeader h = typeMethods.r8mat_header_read(node_filename); int dim_num = h.m; int node_num = h.n; Console.WriteLine(""); Console.WriteLine(" Read the header of \"" + node_filename + "\"."); Console.WriteLine(""); Console.WriteLine(" Spatial dimension DIM_NUM = " + dim_num + ""); Console.WriteLine(" Number of points NODE_NUM = " + node_num + ""); if (dim_num != 3) { Console.WriteLine(""); Console.WriteLine("TET_MESH_QUALITY - Fatal error!"); Console.WriteLine(" Dataset must have spatial dimension 3."); return; } double[] node_xyz = typeMethods.r8mat_data_read(node_filename, dim_num, node_num); Console.WriteLine(""); Console.WriteLine(" Read the data in \"" + node_filename + "\"."); typeMethods.r8mat_transpose_print_some(dim_num, node_num, node_xyz, 1, 1, 5, 5, " 5 by 5 portion of data read from file:"); // // Read the tetra data. // h = typeMethods.i4mat_header_read(element_filename); int element_order = h.m; int element_num = h.n; if (element_order != 4) { Console.WriteLine(""); Console.WriteLine("TET_MESH_QUALITY - Fatal error!"); Console.WriteLine(" Data is not for a 4 node tet mesh."); return; } Console.WriteLine(""); Console.WriteLine(" Read the header of \"" + element_filename + "\"."); Console.WriteLine(""); Console.WriteLine(" Element order = " + element_order + ""); Console.WriteLine(" Number of elements = " + element_num + ""); int[] element_node = typeMethods.i4mat_data_read(element_filename, element_order, element_num); Console.WriteLine(""); Console.WriteLine(" Read the data in \"" + element_filename + "\"."); typeMethods.i4mat_transpose_print_some(element_order, element_num, element_node, 1, 1, element_order, 10, " Portion of ELEMENT_NODE:"); // // If the element information is 1-based, make it 0-based. // TetMesh.tet_mesh_base_zero(node_num, element_order, element_num, ref element_node); // // Compute and print the quality measures. // Console.WriteLine(""); Console.WriteLine(" Minimum Mean Maximum Variance"); Console.WriteLine(""); TetMesh.tet_mesh_quality1(node_num, node_xyz, element_order, element_num, element_node, ref value_min, ref value_mean, ref value_max, ref value_var); Console.WriteLine(" Quality measure 1 = " + " " + value_min.ToString(CultureInfo.InvariantCulture).PadLeft(10) + " " + value_mean.ToString(CultureInfo.InvariantCulture).PadLeft(10) + " " + value_max.ToString(CultureInfo.InvariantCulture).PadLeft(10) + " " + value_var.ToString(CultureInfo.InvariantCulture).PadLeft(10) + ""); TetMesh.tet_mesh_quality2(node_num, node_xyz, element_order, element_num, element_node, ref value_min, ref value_mean, ref value_max, ref value_var); Console.WriteLine(" Quality measure 2 = " + " " + value_min.ToString(CultureInfo.InvariantCulture).PadLeft(10) + " " + value_mean.ToString(CultureInfo.InvariantCulture).PadLeft(10) + " " + value_max.ToString(CultureInfo.InvariantCulture).PadLeft(10) + " " + value_var.ToString(CultureInfo.InvariantCulture).PadLeft(10) + ""); TetMesh.tet_mesh_quality3(node_num, node_xyz, element_order, element_num, element_node, ref value_min, ref value_mean, ref value_max, ref value_var); Console.WriteLine(" Quality measure 3 = " + " " + value_min.ToString(CultureInfo.InvariantCulture).PadLeft(10) + " " + value_mean.ToString(CultureInfo.InvariantCulture).PadLeft(10) + " " + value_max.ToString(CultureInfo.InvariantCulture).PadLeft(10) + " " + value_var.ToString(CultureInfo.InvariantCulture).PadLeft(10) + ""); TetMesh.tet_mesh_quality4(node_num, node_xyz, element_order, element_num, element_node, ref value_min, ref value_mean, ref value_max, ref value_var); Console.WriteLine(" Quality measure 4 = " + " " + value_min.ToString(CultureInfo.InvariantCulture).PadLeft(10) + " " + value_mean.ToString(CultureInfo.InvariantCulture).PadLeft(10) + " " + value_max.ToString(CultureInfo.InvariantCulture).PadLeft(10) + " " + value_var.ToString(CultureInfo.InvariantCulture).PadLeft(10) + ""); TetMesh.tet_mesh_quality5(node_num, node_xyz, element_order, element_num, element_node, ref value_min, ref value_mean, ref value_max, ref value_var); Console.WriteLine(" Quality measure 5 = " + " " + value_min.ToString(CultureInfo.InvariantCulture).PadLeft(10) + " " + value_mean.ToString(CultureInfo.InvariantCulture).PadLeft(10) + " " + value_max.ToString(CultureInfo.InvariantCulture).PadLeft(10) + " " + value_var.ToString(CultureInfo.InvariantCulture).PadLeft(10) + ""); int[] node_order = TetMesh.tet_mesh_node_order(element_order, element_num, element_node, node_num); int histo_num = typeMethods.i4vec_max(node_num, node_order); int[] histo_gram = typeMethods.i4vec_histogram(node_num, node_order, histo_num); Console.WriteLine(""); Console.WriteLine(" Here is a numerical histogram of the order of"); Console.WriteLine(" each node in the mesh, that is, the number of"); Console.WriteLine(" tetrahedrons that include that node as a vertex."); Console.WriteLine(""); Console.WriteLine(" For a regular mesh, most nodes would have the"); Console.WriteLine(" same order."); Console.WriteLine(""); Console.WriteLine(" Order Number of Nodes"); Console.WriteLine(""); for (i = 0; i <= histo_num; i++) { if (histo_gram[i] != 0) { Console.WriteLine(" " + i.ToString(CultureInfo.InvariantCulture).PadLeft(6) + " " + histo_gram[i].ToString(CultureInfo.InvariantCulture).PadLeft(6) + ""); } } Console.WriteLine(""); Console.WriteLine("TET_MESH_QUALITY:"); Console.WriteLine(" Normal end of execution."); Console.WriteLine(""); }
private static void Main(string[] args) //****************************************************************************80 // // Purpose: // // MAIN is the main program for TET_MESH_VOLUMES. // // Discussion: // // TET_MESH_VOLUMES determines the element volumes of a tet mesh. // // Usage: // // tet_mesh_volumes prefix // // where // // * prefix_nodes.txt contains nodal coordinates; // * prefix_elements.txt contains the element definitions; // * prefix_volumes.txt will contain the element volumes. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 13 August 2009 // // Author: // // John Burkardt // { int element; string prefix; double[] tetra = new double[3 * 4]; Console.WriteLine(""); Console.WriteLine(""); Console.WriteLine("TET_MESH_VOLUMES"); Console.WriteLine(" Compute volume of each tetrahedron in a tet mesh.."); Console.WriteLine(""); // // Get the filename prefix. // try { prefix = args[0]; } catch { Console.WriteLine(""); Console.WriteLine("TET_MESH_VOLUMES:"); Console.WriteLine(" Please enter the filename prefix."); prefix = Console.ReadLine(); } // // Create the filenames. // string node_filename = prefix + "_nodes.txt"; string element_filename = prefix + "_elements.txt"; string volume_filename = prefix + "_volumes.txt"; // // Read the node data. // TableHeader h = typeMethods.r8mat_header_read(node_filename); int dim_num = h.m; int node_num = h.n; Console.WriteLine(""); Console.WriteLine(" Read the header of \"" + node_filename + "\"."); Console.WriteLine(""); Console.WriteLine(" Spatial dimension DIM_NUM = " + dim_num + ""); Console.WriteLine(" Number of points NODE_NUM = " + node_num + ""); if (dim_num != 3) { Console.WriteLine(""); Console.WriteLine("TET_MESH_VOLUMES - Fatal error!"); Console.WriteLine(" Dataset must have spatial dimension 3."); return; } double[] node_xyz = typeMethods.r8mat_data_read(node_filename, dim_num, node_num); Console.WriteLine(""); Console.WriteLine(" Read the data in \"" + node_filename + "\"."); typeMethods.r8mat_transpose_print_some(dim_num, node_num, node_xyz, 1, 1, 5, 5, " 5 by 5 portion of data read from file:"); // // Read the tetra data. // h = typeMethods.i4mat_header_read(element_filename); int element_order = h.m; int element_num = h.n; if (element_order != 4) { Console.WriteLine(""); Console.WriteLine("TET_MESH_VOLUMES - Fatal error!"); Console.WriteLine(" Data is not for a 4 node tet mesh."); return; } Console.WriteLine(""); Console.WriteLine(" Read the header of \"" + element_filename + "\"."); Console.WriteLine(""); Console.WriteLine(" Tetrahedron order = " + element_order + ""); Console.WriteLine(" Number of tetras = " + element_num + ""); int[] element_node = typeMethods.i4mat_data_read(element_filename, element_order, element_num); Console.WriteLine(""); Console.WriteLine(" Read the data in \"" + element_filename + "\"."); typeMethods.i4mat_transpose_print_some(element_order, element_num, element_node, 1, 1, element_order, 10, " Portion of ELEMENT_NODE:"); // // If the element information is 1-based, make it 0-based. // TetMesh.tet_mesh_base_zero(node_num, element_order, element_num, ref element_node); // // Compute and print the quality measures. // double[] volume = new double[element_num]; for (element = 0; element < element_num; element++) { int j; for (j = 0; j < 4; j++) { int i; for (i = 0; i < 3; i++) { int node = element_node[j + element * element_order]; tetra[i + j * 3] = node_xyz[i + node * 3]; } } volume[element] = Tetrahedron.tetrahedron_volume(tetra); } double volume_max = typeMethods.r8vec_max(element_num, volume); double volume_min = typeMethods.r8vec_min(element_num, volume); double volume_ave = typeMethods.r8vec_mean(element_num, volume); double volume_tot = typeMethods.r8vec_sum(element_num, volume); double volume_var = typeMethods.r8vec_variance(element_num, volume); Console.WriteLine(""); Console.WriteLine(" Minimum: " + volume_min + ""); Console.WriteLine(" Average: " + volume_ave + ""); Console.WriteLine(" Maximum: " + volume_max + ""); Console.WriteLine(" Total: " + volume_tot + ""); Console.WriteLine(" Variance: " + volume_var + ""); typeMethods.r8mat_write(volume_filename, 1, element_num, volume); Console.WriteLine(""); Console.WriteLine(" Full list of volumes written to \"" + volume_filename + "\"."); Console.WriteLine(""); Console.WriteLine("TET_MESH_VOLUMES:"); Console.WriteLine(" Normal end of execution."); Console.WriteLine(""); }
public static double[] projection(int fem_node_num, double[] fem_node_xyz, int fem_element_order, int fem_element_num, int[] fem_element_node, int[] fem_element_neighbor, int fem_value_dim, double[] fem_value, int sample_node_num, double[] sample_node_xyz) //****************************************************************************80 // // Purpose: // // PROJECTION evaluates an FEM function on a T3 or T6 triangulation. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 27 August 2009 // // Author: // // John Burkardt // // Parameters: // // Input, int FEM_NODE_NUM, the number of nodes. // // Input, double FEM_NODE_XYZ[3*FEM_NODE_NUM], the coordinates // of the nodes. // // Input, int FEM_ELEMENT_ORDER, the order of the elements. // // Input, int FEM_ELEMENT_NUM, the number of elements. // // Input, int FEM_ELEMENT_NODE(FEM_ELEMENT_ORDER,FEM_ELEMENT_NUM), the // nodes that make up each element. // // Input, int FEM_ELEMENT_NEIGHBOR[4*FEM_ELEMENT_NUM], the // index of the neighboring element on each side, or -1 if no neighbor there. // // Input, int FEM_VALUE_DIM, the "dimension" of the values. // // Input, double FEM_VALUE[FEM_VALUE_DIM*FEM_NODE_NUM], the // finite element coefficient values at each node. // // Input, int SAMPLE_NODE_NUM, the number of sample nodes. // // Input, double SAMPLE_NODE_XYZ[3*SAMPLE_NODE_NUM], the sample nodes. // // Output, double PROJECTION[FEM_VALUE_DIM*SAMPLE_NODE_NUM], // the sampled values. // { int face = 0; int j; double[] p_xyz = new double[3]; int step_num = 0; double[] b = new double[fem_element_order]; double[] sample_value = new double[fem_value_dim * sample_node_num]; double[] t_xyz = new double[3 * fem_element_order]; // // For each sample point: find the element T that contains it, // and evaluate the finite element function there. // for (j = 0; j < sample_node_num; j++) { p_xyz[0] = sample_node_xyz[0 + 3 * j]; p_xyz[1] = sample_node_xyz[1 + 3 * j]; p_xyz[2] = sample_node_xyz[2 + 3 * j]; // // Find the triangle T that contains the point. // int t = TetMesh.tet_mesh_search_delaunay(fem_node_num, fem_node_xyz, fem_element_order, fem_element_num, fem_element_node, fem_element_neighbor, p_xyz, ref face, ref step_num); switch (t) { case -1: Console.WriteLine(""); Console.WriteLine("PROJECTION - Fatal error!"); Console.WriteLine(" Search failed."); return(null); } // // Evaluate the finite element basis functions at the point in T. // int t_node; int i; for (i = 0; i < fem_element_order; i++) { t_node = fem_element_node[i + t * fem_element_order]; t_xyz[0 + i * 3] = fem_node_xyz[0 + t_node * 3]; t_xyz[1 + i * 3] = fem_node_xyz[1 + t_node * 3]; t_xyz[2 + i * 3] = fem_node_xyz[2 + t_node * 3]; } Basis_mn.basis_mn_tet4(t_xyz, 1, p_xyz, ref b); // // Multiply by the finite element values to get the sample values. // for (i = 0; i < fem_value_dim; i++) { double dot = 0.0; int k; for (k = 0; k < fem_element_order; k++) { t_node = fem_element_node[k + t * fem_element_order]; dot += fem_value[i + t_node * fem_value_dim] * b[k]; } sample_value[i + j * fem_value_dim] = dot; } } return(sample_value); }
private static void Main(string[] args) //****************************************************************************80 // // Purpose: // // MAIN is the main program for TET_MESH_TO_XML. // // Discussion: // // TET_MESH_TO_XML converts a tet mesh, using 4 or 10 node // tetrahedral elements, to a DOLFIN XML mesh file. // // Usage: // // tet_mesh_to_xml prefix // // where prefix is the common file prefix: // // * prefix_nodes.txt, the node coordinates; // * prefix_elements.txt, the linear element definitions. // * prefix.xml, the DOLFIN XML mesh file. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 04 June 2013 // // Author: // // John Burkardt // // Reference: // // Anders Logg, Kent-Andre Mardal, Garth Wells, // Automated Solution of Differential Equations by the Finite Element // Method: The FEniCS Book, // Lecture Notes in Computational Science and Engineering, // Springer, 2011, // ISBN13: 978-3642230981 // { string prefix; Console.WriteLine(""); Console.WriteLine("TET_MESH_TO_XML;"); Console.WriteLine(" Convert a tet mesh to DOLFIN XML format"); Console.WriteLine(""); Console.WriteLine(" Read \"prefix\"_nodes.txt, node coordinates."); Console.WriteLine(" Read \"prefix\"_elements.txt, 4, 10 or 20 node element definitions."); Console.WriteLine(""); Console.WriteLine(" Create \"prefix\".xml, a corresponding DOLFIN XML mesh file."); Console.WriteLine(""); // // Get the filename prefix. // try { prefix = args[0]; } catch { Console.WriteLine(""); Console.WriteLine("TET_MESH_TO_XML:"); Console.WriteLine(" Please enter the filename prefix."); prefix = Console.ReadLine(); } // // Create the filenames. // string node_filename = prefix + "_nodes.txt"; string element_filename = prefix + "_elements.txt"; string xml_filename = prefix + ".xml"; // // Read the node data. // TableHeader h = typeMethods.r8mat_header_read(node_filename); int dim_num = h.m; int node_num = h.n; if (dim_num != 3) { Console.WriteLine(""); Console.WriteLine("TET_MESH_TO_XML; - Fatal error!"); Console.WriteLine(" The spatial dimension must be 3."); return; } Console.WriteLine(""); Console.WriteLine(" Read the header of \"" + node_filename + "\"."); Console.WriteLine(""); Console.WriteLine(" Spatial dimension = " + dim_num + ""); Console.WriteLine(" Number of nodes = " + node_num + ""); double[] node_xyz = typeMethods.r8mat_data_read(node_filename, dim_num, node_num); Console.WriteLine(""); Console.WriteLine(" Read the data in \"" + node_filename + "\"."); typeMethods.r8mat_transpose_print_some(dim_num, node_num, node_xyz, 1, 1, dim_num, 5, " First 5 nodes:"); // // Read the element data. // h = typeMethods.i4mat_header_read(element_filename); int element_order = h.m; int element_num = h.n; switch (element_order) { case 4: break; case 10: break; case 20: break; default: Console.WriteLine(""); Console.WriteLine("TET_MESH_TO_XML - Fatal error!"); Console.WriteLine(" The tet mesh must have order 4, 10, or 20."); return; } Console.WriteLine(""); Console.WriteLine(" Read the header of \"" + element_filename + "\"."); Console.WriteLine(""); Console.WriteLine(" Element order = " + element_order + ""); Console.WriteLine(" Number of elements = " + element_num + ""); int[] element_node = typeMethods.i4mat_data_read(element_filename, element_order, element_num); Console.WriteLine(""); Console.WriteLine(" Read the data in \"" + element_filename + "\"."); typeMethods.i4mat_transpose_print_some(element_order, element_num, element_node, 1, 1, element_order, 5, " First 5 elements:"); // // Use 0-based indexing. // TetMesh.tet_mesh_base_zero(node_num, element_order, element_num, ref element_node); // // Write the DOLFIN XML file. // XML.xml_write(xml_filename, dim_num, node_num, node_xyz, element_order, element_num, element_node); Console.WriteLine(""); Console.WriteLine(" Created XML file \"" + xml_filename + "\"."); Console.WriteLine(""); Console.WriteLine("TET_MESH_TO_XML;"); Console.WriteLine(" Normal end of execution."); Console.WriteLine(""); }
private static void Main(string[] args) //****************************************************************************80 // // Purpose: // // MAIN is the main program for FEM3D_PROJECT. // // Discussion: // // FEM3D_PROJECT reads files defining a sampling of a (scalar or vector) // function of 3 arguments, and a list of nodes and tetrahedral elements // to use for a finite element representation of the data. // // It computes a set of finite element coefficients to be associated with // the given finite element mesh, and writes that information to a file // so that an FEM representation is formed by the node, element and value // files. // // Usage: // // fem3d_project sample_prefix fem_prefix // // where 'sample_prefix' is the common prefix for the SAMPLE files: // // * sample_prefix_nodes.txt, the node coordinates where samples were taken, // * sample_prefix_elements.txt, the 4 nodes that make up each element; // * sample_prefix_values.txt, the sample values. // // and 'fem_prefix' is the common prefix for the FEM files: // // * fem_prefix_nodes.txt, the node coordinates. // * fem_prefix_elements.txt, the 4 nodes that make up each element; // * fem_prefix_values.txt, the values defined at each node (output). // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 25 August 2009 // // Author: // // John Burkardt // { string fem_prefix; int i; int j; string sample_prefix; Console.WriteLine(""); Console.WriteLine("FEM3D_PROJECT"); Console.WriteLine(""); Console.WriteLine(" Read files defining a sampling of a function of 3 arguments."); Console.WriteLine(" Read files defining a finite element mesh."); Console.WriteLine(" Project the sample data onto the mesh, and"); Console.WriteLine(" write a file of FEM coefficient values."); // // Get the number of command line arguments. // try { sample_prefix = args[0]; } catch { Console.WriteLine(""); Console.WriteLine("Enter the sample file prefix:"); sample_prefix = Console.ReadLine(); } try { fem_prefix = args[1]; } catch { Console.WriteLine(""); Console.WriteLine("Enter the FEM file prefix:"); fem_prefix = Console.ReadLine(); } // // Create the filenames. // string sample_node_filename = sample_prefix + "_nodes.txt"; string sample_element_filename = sample_prefix + "_elements.txt"; string sample_value_filename = sample_prefix + "_values.txt"; string fem_node_filename = fem_prefix + "_nodes.txt"; string fem_element_filename = fem_prefix + "_elements.txt"; string fem_value_filename = fem_prefix + "_values.txt"; // // Read the SAMPLE NODE, ELEMENT and VALUE data. // TableHeader h = typeMethods.r8mat_header_read(sample_node_filename); int sample_node_dim = h.m; int sample_node_num = h.n; Console.WriteLine(""); Console.WriteLine(" Sample node spatial dimension is " + sample_node_dim + ""); Console.WriteLine(" Sample node number is " + sample_node_num + ""); if (sample_node_dim != 3) { Console.WriteLine(""); Console.WriteLine("FEM3D_PROJECT - Fatal error!"); Console.WriteLine(" Spatial dimension of the sample nodes is not 3."); return; } double[] sample_node_xyz = typeMethods.r8mat_data_read(sample_node_filename, sample_node_dim, sample_node_num); h = typeMethods.i4mat_header_read(sample_element_filename); int sample_element_order = h.m; int sample_element_num = h.n; Console.WriteLine(""); Console.WriteLine(" Sample element order is " + sample_element_order + ""); Console.WriteLine(" Sample element number is " + sample_element_num + ""); if (sample_element_order != 4) { Console.WriteLine(""); Console.WriteLine("FEM3D_PROJECT - Fatal error!"); Console.WriteLine(" The sample element order must be 4."); return; } int[] sample_element_node = typeMethods.i4mat_data_read(sample_element_filename, sample_element_order, sample_element_num); int element_min = typeMethods.i4mat_min(sample_element_order, sample_element_num, sample_element_node); switch (element_min) { case 1: { Console.WriteLine(""); Console.WriteLine(" Converting 1-based sample element array to 0 base."); for (j = 0; j < sample_element_num; j++) { for (i = 0; i < sample_element_order; i++) { sample_element_node[i + j * sample_element_order] -= 1; } } break; } } h = typeMethods.r8mat_header_read(sample_value_filename); int sample_value_dim = h.m; int sample_value_num = h.n; Console.WriteLine(""); Console.WriteLine(" The sample value dimension is " + sample_value_dim + ""); Console.WriteLine(" The sample value number is " + sample_value_num + ""); if (sample_value_num != sample_node_num) { Console.WriteLine(""); Console.WriteLine("FEM3D_PROJECT - Fatal error!"); Console.WriteLine(" Number of sample values and nodes differ."); return; } double[] sample_value = typeMethods.r8mat_data_read(sample_value_filename, sample_value_dim, sample_value_num); // // Create the sample element neighbor array. // int[] sample_element_neighbor = TetMesh.tet_mesh_neighbor_tets(sample_element_order, sample_element_num, sample_element_node); Console.WriteLine(""); Console.WriteLine(" The element neighbor array has been computed."); // // Read the FEM NODE and ELEMENT data. // h = typeMethods.r8mat_header_read(fem_node_filename); int fem_node_dim = h.m; int fem_node_num = h.n; Console.WriteLine(""); Console.WriteLine(" The FEM node dimension is " + fem_node_dim + ""); Console.WriteLine(" The FEM node number is " + fem_node_num + ""); if (fem_node_dim != 3) { Console.WriteLine(""); Console.WriteLine("FEM3D_PROJECT - Fatal error!"); Console.WriteLine(" Spatial dimension of the nodes is not 3."); return; } double[] fem_node_xyz = typeMethods.r8mat_data_read(fem_node_filename, fem_node_dim, fem_node_num); h = typeMethods.i4mat_header_read(fem_element_filename); int fem_element_order = h.m; int fem_element_num = h.n; Console.WriteLine(" The FEM element order is " + fem_element_order + ""); Console.WriteLine(" The FEM element number is " + fem_element_num + ""); if (fem_element_order != 4) { Console.WriteLine(""); Console.WriteLine("FEM3D_PROJECT - Fatal error!"); Console.WriteLine(" The FEM element order is not 4."); return; } int[] fem_element_node = typeMethods.i4mat_data_read(fem_element_filename, fem_element_order, fem_element_num); element_min = typeMethods.i4mat_min(fem_element_order, fem_element_num, fem_element_node); switch (element_min) { case 1: { Console.WriteLine(""); Console.WriteLine(" Converting 1-based FEM element array to 0 base."); for (j = 0; j < fem_element_num; j++) { for (i = 0; i < fem_element_order; i++) { fem_element_node[i + j * fem_element_order] -= 1; } } break; } } // // Compute the FEM values. // double[] fem_value = FEM_3D_Transfer.fem3d_transfer(sample_node_num, sample_element_order, sample_element_num, sample_value_dim, sample_value_num, sample_node_xyz, sample_element_node, sample_element_neighbor, sample_value, fem_node_num, fem_element_order, fem_element_num, sample_value_dim, fem_node_num, fem_node_xyz, fem_element_node); // // Write the FEM values. // typeMethods.r8mat_write(fem_value_filename, sample_value_dim, fem_node_num, fem_value); Console.WriteLine(""); Console.WriteLine(" FEM value data written to \"" + fem_value_filename + "\""); // // Terminate. // Console.WriteLine(""); Console.WriteLine("FEM3D_PROJECT"); Console.WriteLine(" Normal end of execution."); Console.WriteLine(""); }