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 <<
" *.exo -- 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 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.
virtual void read(const std::string &name, void *mesh_data=nullptr, bool skip_renumber_nodes_and_elements=false, bool skip_find_neighbors=false, bool skip_detect_interior_parents=false)=0
Interfaces for reading/writing a mesh to/from a file.
Class NetGenMeshInterface provides an interface for tetrahedralization of meshes using the NetGen lib...
static constexpr Real TOLERANCE
virtual void smooth() override
Redefinition of the smooth function from the base class.
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
Prepare a newly created (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...
virtual void read(const std::string &name, void *mesh_data=nullptr, bool skip_renumber_nodes_and_elements=false, bool skip_find_neighbors=false, bool skip_detect_interior_parents=false) override
Reads the file specified by name.
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 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.
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.