示例#1
0
    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) + "");
    }
示例#2
0
    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:");
    }
示例#3
0
    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 + "");
        }
    }
示例#4
0
    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:");
    }
示例#5
0
    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);
    }
示例#7
0
    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("");
    }
示例#8
0
    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("");
    }
示例#9
0
    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("");
    }
示例#10
0
    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("");
    }
示例#11
0
    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("");
    }
示例#12
0
    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);
    }
示例#14
0
    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("");
    }
示例#15
0
    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("");
    }