18 #include "libmesh/libmesh_config.h"    32 #include "libmesh/boundary_info.h"    33 #include "libmesh/boundary_mesh.h"    34 #include "libmesh/dof_map.h"    35 #include "libmesh/elem.h"    36 #include "libmesh/elem_quality.h"    37 #include "libmesh/gmv_io.h"    38 #include "libmesh/inf_elem_builder.h"    39 #include "libmesh/libmesh.h"    40 #include "libmesh/mesh.h"    41 #include "libmesh/mesh_modification.h"    42 #include "libmesh/mesh_refinement.h"    43 #include "libmesh/mesh_netgen_interface.h"    44 #include "libmesh/poly2tri_triangulator.h"    45 #include "libmesh/simplex_refiner.h"    46 #include "libmesh/statistics.h"    47 #include "libmesh/string_to_enum.h"    48 #include "libmesh/enum_elem_quality.h"    49 #include "libmesh/getpot.h"    50 #include <libmesh/mesh_smoother_vsmoother.h>    59 void usage(
const std::string & prog_name);
    61 int main (
int argc, 
char ** argv)
    65   unsigned int n_subdomains = 1;
    67   unsigned int n_rsteps = 0;
    68   Real simplex_refine = 0.;
    69   double dist_fact = 0.;
    72   bool convert_first_order = 
false;
    73   unsigned int convert_second_order = 0;
    74   bool triangulate = 
false;
    75   bool simplex_fill = 
false;
    76   Real desired_measure = 1;
    77   bool do_quality = 
false;
    80 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS    81   bool addinfelems = 
false;
    90   std::vector<std::string> names;
    91   std::vector<std::string> output_names;
    95     usage(std::string(argv[0]));
    98   GetPot command_line (argc, argv);
   101   if (command_line.search(2, 
"-h", 
"-?"))
   105   command_line.disable_loop();
   106   while (command_line.search(1, 
"-i"))
   109       tmp = command_line.next(tmp);
   110       names.push_back(tmp);
   112   command_line.reset_cursor();
   115   while (command_line.search(1, 
"-o"))
   118       tmp = command_line.next(tmp);
   119       output_names.push_back(tmp);
   121   command_line.enable_loop();
   124   if (command_line.search(1, 
"-D"))
   125     dist_fact = command_line.next(dist_fact);
   128   if (command_line.search(1, 
"-r"))
   131       tmp = command_line.next(tmp);
   132       n_rsteps = cast_int<unsigned int>(tmp);
   136   if (command_line.search(1, 
"-s"))
   137     simplex_refine = command_line.next(simplex_refine);
   140   if (command_line.search(1, 
"-p"))
   143       tmp = command_line.next(tmp);
   144       n_subdomains = cast_int<unsigned int>(tmp);
   148   if (command_line.search(1, 
"-V"))
   152   if (command_line.search(1, 
"-t"))
   156   if (command_line.search(1, 
"-T"))
   159       desired_measure = command_line.next(desired_measure);
   163   if (command_line.search(1, 
"-q"))
   167       tmp = command_line.next(tmp);
   169         quality_type = Utility::string_to_enum<ElemQuality>(tmp);
   173   if (command_line.search(1, 
"-v"))
   177   if (command_line.search(1, 
"-b"))
   181   if (command_line.search(1, 
"-1"))
   182     convert_first_order = 
true;
   185   if (command_line.search(1, 
"-2"))
   186     convert_second_order = 2;
   189   if (command_line.search(1, 
"-3"))
   190     convert_second_order = 22;
   192 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS   195   if (command_line.search(1, 
"-a"))
   199   if (command_line.search(1, 
"-x"))
   201       origin_x.first  = 
true;
   202       origin_x.second = command_line.next(origin_x.second);
   206   if (command_line.search(1, 
"-y"))
   208       origin_y.first  = 
true;
   209       origin_y.second = command_line.next(origin_y.second);
   213   if (command_line.search(1, 
"-z"))
   215       origin_z.first  = 
true;
   216       origin_z.second = command_line.next(origin_z.second);
   220   if (command_line.search(1, 
"-X"))
   222   if (command_line.search(1, 
"-Y"))
   224   if (command_line.search(1, 
"-Z"))
   227 #endif // LIBMESH_ENABLE_INFINITE_ELEMENTS   237           libMesh::out << 
"Mesh " << names[0] << 
":" << std::endl;
   242       for (
unsigned int i=1; i < names.size(); ++i)
   245           extra_mesh.
read(names[i]);
   249               libMesh::out << 
"Mesh " << names[i] << 
":" << std::endl;
   250               extra_mesh.print_info();
   251               extra_mesh.get_boundary_info().print_summary();
   255 #ifdef LIBMESH_ENABLE_UNIQUE_ID   259           mesh.copy_nodes_and_elements(extra_mesh, 
false,
   282 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS   287                            "ERROR: Invalid combination: Building infinite elements\n"   288                            "not compatible with writing boundary conditions.");
   292       libmesh_error_msg_if((x_sym && !origin_x.first) ||     
   293                            (y_sym && !origin_y.first) ||     
   294                            (z_sym && !origin_z.first),       
   295                            "ERROR: When x-symmetry is requested using -X, then\n"   296                            "the option -x <coord> also has to be given.\n"   297                            "This holds obviously for y and z, too.");
   313     libmesh_error_msg_if((origin_x.first ||  origin_y.first || origin_z.first) ||
   314                          (x_sym          ||  y_sym          || z_sym),
   315                          "ERROR:  -x/-y/-z/-X/-Y/-Z is only to be used when\n"   316                          "the option -a is also specified!");
   335 #ifdef LIBMESH_HAVE_NETGEN   340           libmesh_error_msg(
"Requested triangulation of a 2D boundary without Poly2Tri enabled");
   345 #ifdef LIBMESH_HAVE_POLY2TRI   352           libmesh_error_msg(
"Requested triangulation of a 1D boundary without Poly2Tri enabled");
   367       libMesh::out << 
"Quality bounds for this element type are: ("   374       for (
const auto & elem : 
mesh.active_element_ptr_range())
   375         sv.push_back(elem->quality(quality_type));
   377       const unsigned int n_bins = 10;
   382       std::vector<dof_id_type> bad_elts  = sv.
cut_below(0.8);
   385                    << 
" elements below the cutoff." << std::endl;
   388       std::vector<dof_id_type> histogram;
   391       const bool do_matlab = 
true;
   395           std::ofstream 
out (
"histo.m");
   397           out << 
"% This is a sample histogram plot for Matlab." << std::endl;
   398           out << 
"bin_members = [" << std::endl;
   399           for (
unsigned int i=0; i<n_bins; i++)
   402           out << 
"];" << std::endl;
   404           std::vector<Real> bin_coords(n_bins);
   405           const Real max   = *(std::max_element(sv.begin(), sv.end()));
   406           const Real min   = *(std::min_element(sv.begin(), sv.end()));
   407           const Real delta = (max - min) / static_cast<Real>(n_bins);
   408           for (
unsigned int i=0; i<n_bins; i++)
   409             bin_coords[i] = min + (i * delta) + delta / 2.0 ;
   411           out << 
"bin_coords = [" << std::endl;
   412           for (
unsigned int i=0; i<n_bins; i++)
   413             out << bin_coords[i] << std::endl;
   414           out << 
"];" << std::endl;
   416           out << 
"bar(bin_coords, bin_members, 1);" << std::endl;
   417           out << 
"hold on" << std::endl;
   418           out << 
"plot (bin_coords, 0, 'kx');" << std::endl;
   419           out << 
"xlabel('Quality (0=Worst, 1=Best)');" << std::endl;
   420           out << 
"ylabel('Percentage of elements in each bin');" << std::endl;
   421           out << 
"axis([" << min << 
"," << max << 
",0, max(bin_members)]);" << std::endl;
   430   if (convert_first_order)
   433         libMesh::out << 
"Converting elements to first order counterparts\n";
   445   if (convert_second_order > 0)
   447       bool second_order_mode = 
true;
   448       std:: string message = 
"Converting elements to second order counterparts";
   449       if (convert_second_order == 2)
   451           second_order_mode = 
false;
   452           message += 
", lower version: Quad4 -> Quad8, not Quad9";
   455       else if (convert_second_order == 22)
   457           second_order_mode = 
true;
   458           message += 
", highest version: Quad4 -> Quad9";
   462         libmesh_error_msg(
"Invalid value, convert_second_order = " << convert_second_order);
   483 #ifdef LIBMESH_ENABLE_AMR   490                      << n_rsteps << 
" times"   519   if (n_subdomains > 1)
   530   if (output_names.size())
   541             libMesh::out << 
" Mesh got refined, will write only _active_ elements." << std::endl;
   547              mesh.active_elements_begin(),
   548              mesh.active_elements_end());
   551           for (
auto & output_name : output_names)
   552             new_mesh.
write(output_name);
   557           for (
auto & output_name : output_names)
   573             libmesh_error_msg(
"Invalid value write_bndry = " << write_bndry);
   576           for (
auto boundary_name : output_names)
   578               boundary_name = 
"bndry_" + boundary_name;
   579               boundary_mesh.
write(boundary_name);
   588 void usage(
const std::string & prog_name)
   590   std::ostringstream helpList;
   591   helpList << 
"usage:\n"   594            << 
" [options] ...\n"   597            << 
"    -i <string>                   Input file name, one option per file\n"   598            << 
"                                    Multiple files get concatenated"   599            << 
"    -o <string>                   Output file name, one option per file\n"   600            << 
"\n    -b                            Write the boundary conditions\n"   601            << 
"    -D <factor>                   Randomly move interior nodes by D*hmin\n"   602            << 
"    -h                            Print help menu\n"   603            << 
"    -p <count>                    Partition into <count> subdomains\n"   604            << 
"    -V                            Apply the variational mesh smoother\n"   605 #ifdef LIBMESH_ENABLE_AMR   606            << 
"    -r <count>                    Uniformly refine <count> times\n"   608            << 
"    -s <volume>                   Split-edge refine elements exceeding <volume>\n"   609            << 
"    -t                            Convert all elements to triangles/tets\n"   610            << 
"    -T <desired elem area/vol>    Triangulate/Tetrahedralize the interior\n"   612            << 
"    -q <metric>                   Evaluates the named element quality metric\n"   613            << 
"    -1                            Converts a mesh of higher order elements\n"   614            << 
"                                  to their first-order counterparts:\n"   615            << 
"                                  Quad8 -> Quad4, Tet10 -> Tet4 etc\n"   616            << 
"    -2                            Converts a mesh of linear elements\n"   617            << 
"                                  to their second-order counterparts:\n"   618            << 
"                                  Quad4 -> Quad8, Tet4 -> Tet10 etc\n"   619            << 
"    -3                            Same, but to the highest possible:\n"   620            << 
"                                  Quad4 -> Quad9, Hex8 -> Hex27 etc\n"   621 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS   622            << 
"\n    -a                            Add infinite elements\n"   623            << 
"    -x <coord>                    Specify infinite element origin\n"   624            << 
"    -y <coord>                    coordinates. If none given, origin\n"   625            << 
"    -z <coord>                    is determined automatically.\n"   626            << 
"    -X                            When building infinite elements \n"   627            << 
"    -Y                            treat mesh as x/y/z-symmetric.\n"   628            << 
"    -Z                            When -X is given, -x <coord> also\n"   629            << 
"                                  has to be given.  Similar for y,z.\n"   633            << 
" This program is used to convert and partition from/to a variety of\n"   634            << 
" formats.  File types are inferred from file extensions.  For example,\n"   637            << 
"  ./meshtool -i in.e -o out.plt\n"   639            << 
" will read a mesh in the ExodusII format (from Cubit, for example)\n"   640            << 
" from the file in.e.  It will then write the mesh in the Tecplot\n"   641            << 
" binary format to out.plt.\n"   645            << 
"  ./meshtool -i cylinder.msh -i square.xda -o out.e -2\n"   647            << 
" will read the Gmsh formatted mesh file cylinder.msh, concatenate\n"   648            << 
" the elements and nodes (with shifted id numbers) from the libMesh\n"   649            << 
" mesh file square.xda, convert all first-order elements from both\n"   650            << 
" to second-order, and write the combined mesh in Exodus format to\n"   652 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS   656            << 
"  ./meshtool -i dry.unv -o packed.gmv -a -x 30.5 -y -10.5 -X\n"   658            << 
" will read a Universal file, determine the z-coordinate of the origin\n"   659            << 
" automatically, e.g. z_origin = 3., build infinite elements with the\n"   660            << 
" origin (30.5, -10.5, 3.) on top of volume elements, while preserving\n"   661            << 
" a symmetry plane through (30.5, -10.5, 3.) perpendicular to x.\n"   662            << 
" It is imperative that the origin lies _inside_ the given volume mesh.\n"   663            << 
" If not, infinite elements are not correctly built!\n"   666            << 
" This program supports the I/O formats:\n"   668            << 
"     *.cpa   -- libMesh ASCII checkpoint format\n"   669            << 
"     *.cpr   -- libMesh binary checkpoint format,\n"   670            << 
"     *.e     -- Sandia's ExodusII format\n"   671            << 
"     *.exd   -- Sandia's ExodusII format\n"   672            << 
"     *.gmv   -- LANL's GMV (General Mesh Viewer) format\n"   673            << 
"     *.mesh  -- MEdit mesh format\n"   674            << 
"     *.msh   -- GMSH ASCII file\n"   675            << 
"     *.n     -- Sandia's Nemesis format\n"   676            << 
"     *.nem   -- Sandia's Nemesis format\n"   677            << 
"     *.plt   -- Tecplot binary file\n"   678            << 
"     *.poly  -- TetGen ASCII file\n"   679            << 
"     *.ucd   -- AVS's ASCII UCD format\n"   680            << 
"     *.ugrid -- Kelly's DIVA ASCII format\n"   681            << 
"     *.unv   -- I-deas Universal format\n"   682            << 
"     *.vtu   -- VTK (paraview-readable) format\n"   683            << 
"     *.xda   -- libMesh ASCII format\n"   684            << 
"     *.xdr   -- libMesh binary format,\n"   685            << 
"\n   As well as for input only:\n\n" \
   686            << 
"     *.bext  -- Bezier files in DYNA format\n" \
   687            << 
"     *.bxt   -- Bezier files in DYNA format\n" \
   688            << 
"     *.inp   -- Abaqus .inp format\n" \
   689            << 
"     *.mat   -- Matlab triangular ASCII file\n" \
   690            << 
"     *.off   -- OOGL OFF surface format\n" \
   691            << 
"     *.ogl   -- OOGL OFF surface format\n" \
   692            << 
"     *.oogl  -- OOGL OFF surface format\n" \
   693            << 
"\n   As well as for output only:\n\n" \
   694            << 
"     *.dat   -- Tecplot ASCII file\n"   695            << 
"     *.fro   -- ACDL's surface triangulation file\n"   696            << 
"     *.poly  -- TetGen ASCII file\n" std::string name(const ElemQuality q)
This function returns a string containing some name for q. 
virtual void read(const std::string &name, void *mesh_data=nullptr, bool skip_renumber_nodes_and_elements=false, bool skip_find_neighbors=false)=0
Interfaces for reading/writing a mesh to/from a file. 
virtual unique_id_type parallel_max_unique_id() const =0
virtual Real mean() const
void sync(UnstructuredMesh &boundary_mesh)
Generates boundary_mesh data structures corresponding to the mesh data structures. 
Real & desired_volume()
Sets and/or gets the desired tetrahedron volume. 
Class NetGenMeshInterface provides an interface for tetrahedralization of meshes using the NetGen lib...
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
Prepare a newly ecreated (or read) mesh for use. 
const Parallel::Communicator & comm() const
The StatisticsVector class is derived from the std::vector<> and therefore has all of its useful feat...
virtual void triangulate() override
Method invokes NetGen library to compute a tetrahedralization. 
Real & desired_volume()
Sets and/or gets the desired element volume. 
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g. 
The libMesh namespace provides an interface to certain functionality in the library. 
virtual void all_first_order()=0
Converts a mesh with higher-order elements into a mesh with linear elements. 
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh. 
TriangulationType & triangulation_type()
Sets and/or gets the desired triangulation type. 
virtual void partition(const unsigned int n_parts)
Call the default partitioner (currently metis_partition()). 
A C++ class to refine a simplicial mesh via splitting edges that exceed a given metric. 
The BoundaryMesh is a Mesh in its own right, but it contains a description of the boundary of some ot...
std::pair< bool, double > InfElemOriginValue
Useful typedef. 
Implements (adaptive) mesh refinement algorithms for a MeshBase. 
Real & minimum_angle()
Sets and/or gets the minimum desired angle. 
void print_info(std::ostream &os=libMesh::out, const unsigned int verbosity=0, const bool global=true) const
Prints relevant information about the mesh. 
bool refine_elements()
Finds elements which exceed the requested metric and refines them via subdivision into new simplices ...
virtual dof_id_type max_elem_id() const =0
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary. 
virtual void histogram(std::vector< dof_id_type > &bin_members, unsigned int n_bins=10)
ElemQuality
Defines an enum for element quality metrics. 
virtual void write(const std::string &name) const =0
virtual void triangulate() override
Internally, this calls the poly2tri triangulation code in a loop, inserting our owner Steiner points ...
Real & desired_area()
Sets and/or gets the desired triangle area. 
This class is used to build infinite elements on top of an existing mesh. 
Triangulate the interior of a Planar Straight Line Graph, which is defined implicitly by the order of...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const Point build_inf_elem(const bool be_verbose=false)
Build infinite elements atop a volume-based mesh, determine origin automatically. ...
This is an implementation of Larisa Branets' smoothing algorithms. 
virtual std::vector< dof_id_type > cut_below(Real cut) const
virtual const Elem & elem_ref(const dof_id_type i) const
void all_second_order(const bool full_ordered=true)
Calls the range-based version of this function with a range consisting of all elements in the mesh...
unsigned int mesh_dimension() const
A C++ interface between LibMesh and the poly2tri library, with custom code for Steiner point insertio...
virtual std::pair< Real, Real > qual_bounds(const ElemQuality) const
virtual void read(const std::string &name, void *mesh_data=nullptr, bool skip_renumber_nodes_and_elements=false, bool skip_find_neighbors=false) override
Reads the file specified by name. 
virtual dof_id_type max_node_id() const =0
void print_summary(std::ostream &out_stream=libMesh::out) const
Prints a summary of the boundary information. 
virtual dof_id_type n_elem() const =0
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default. 
virtual void write(const std::string &name) const override
Write the file specified by name. 
virtual void smooth() override
Redefinition of the smooth function from the base class. 
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.