Go to the documentation of this file.
18 #include "libmesh/libmesh_config.h"
33 #include "libmesh/boundary_info.h"
34 #include "libmesh/boundary_mesh.h"
35 #include "libmesh/dof_map.h"
36 #include "libmesh/elem.h"
37 #include "libmesh/elem_quality.h"
38 #include "libmesh/gmv_io.h"
39 #include "libmesh/inf_elem_builder.h"
40 #include "libmesh/libmesh.h"
41 #include "libmesh/mesh.h"
42 #include "libmesh/mesh_modification.h"
43 #include "libmesh/mesh_refinement.h"
44 #include "libmesh/statistics.h"
45 #include "libmesh/string_to_enum.h"
46 #include "libmesh/enum_elem_quality.h"
47 #include "libmesh/getpot.h"
56 void usage(
const std::string & prog_name);
58 int main (
int argc,
char ** argv)
62 unsigned int n_subdomains = 1;
63 unsigned int n_rsteps = 0;
64 double dist_fact = 0.;
67 bool convert_first_order =
false;
68 unsigned int convert_second_order = 0;
69 bool triangulate =
false;
70 bool do_quality =
false;
73 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
74 bool addinfelems =
false;
83 std::vector<std::string> names;
84 std::vector<std::string> var_names;
85 std::vector<Number> soln;
89 usage(std::string(argv[0]));
92 GetPot command_line (argc, argv);
95 if (command_line.search(2,
"-h",
"-?"))
99 if (command_line.search(1,
"-i"))
102 tmp = command_line.next(tmp);
104 names.push_back(tmp);
106 libmesh_error_msg(
"ERROR: Input name must precede output name!");
110 if (command_line.search(1,
"-o"))
113 tmp = command_line.next(tmp);
115 names.push_back(tmp);
117 libmesh_error_msg(
"ERROR: Input name must precede output name!");
121 if (command_line.search(1,
"-D"))
122 dist_fact = command_line.next(dist_fact);
125 if (command_line.search(1,
"-r"))
128 tmp = command_line.next(tmp);
129 n_rsteps = cast_int<unsigned int>(tmp);
133 if (command_line.search(1,
"-p"))
136 tmp = command_line.next(tmp);
137 n_subdomains = cast_int<unsigned int>(tmp);
141 if (command_line.search(1,
"-t"))
145 if (command_line.search(1,
"-q"))
149 tmp = command_line.next(tmp);
151 quality_type = Utility::string_to_enum<ElemQuality>(tmp);
155 if (command_line.search(1,
"-v"))
159 if (command_line.search(1,
"-b"))
163 if (command_line.search(1,
"-1"))
164 convert_first_order =
true;
167 if (command_line.search(1,
"-2"))
168 convert_second_order = 2;
171 if (command_line.search(1,
"-3"))
172 convert_second_order = 22;
174 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
177 if (command_line.search(1,
"-a"))
181 if (command_line.search(1,
"-x"))
183 origin_x.first =
true;
184 origin_x.second = command_line.next(origin_x.second);
188 if (command_line.search(1,
"-y"))
190 origin_y.first =
true;
191 origin_y.second = command_line.next(origin_y.second);
195 if (command_line.search(1,
"-z"))
197 origin_z.first =
true;
198 origin_z.second = command_line.next(origin_z.second);
202 if (command_line.search(1,
"-X"))
204 if (command_line.search(1,
"-Y"))
206 if (command_line.search(1,
"-Z"))
209 #endif // LIBMESH_ENABLE_INFINITE_ELEMENTS
232 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
236 if (names.size() == 3)
237 libmesh_error_msg(
"ERROR: Invalid combination: Building infinite elements\n"
238 <<
"not compatible with solution import.");
241 libmesh_error_msg(
"ERROR: Invalid combination: Building infinite elements\n"
242 <<
"not compatible with writing boundary conditions.");
246 if ((x_sym && !origin_x.first) ||
247 (y_sym && !origin_y.first) ||
248 (z_sym && !origin_z.first))
249 libmesh_error_msg(
"ERROR: When x-symmetry is requested using -X, then\n"
250 <<
"the option -x <coord> also has to be given.\n"
251 <<
"This holds obviously for y and z, too.");
267 else if ((origin_x.first || origin_y.first || origin_z.first) ||
268 (x_sym || y_sym || z_sym))
269 libmesh_error_msg(
"ERROR: -x/-y/-z/-X/-Y/-Z is only to be used when\n"
270 <<
"the option -a is also specified!");
294 libMesh::out <<
"Quality bounds for this element type are: ("
302 sv.push_back(elem->quality(quality_type));
304 const unsigned int n_bins = 10;
309 std::vector<dof_id_type> bad_elts = sv.
cut_below(0.8);
312 <<
" elements below the cutoff." << std::endl;
315 std::vector<dof_id_type> histogram;
318 const bool do_matlab =
true;
322 std::ofstream
out (
"histo.m");
324 out <<
"% This is a sample histogram plot for Matlab." << std::endl;
325 out <<
"bin_members = [" << std::endl;
326 for (
unsigned int i=0; i<n_bins; i++)
327 out << static_cast<Real>(histogram[i]) / static_cast<Real>(
mesh.
n_elem())
329 out <<
"];" << std::endl;
331 std::vector<Real> bin_coords(n_bins);
332 const Real max = *(std::max_element(sv.begin(), sv.end()));
333 const Real min = *(std::min_element(sv.begin(), sv.end()));
334 const Real delta = (max - min) / static_cast<Real>(n_bins);
335 for (
unsigned int i=0; i<n_bins; i++)
336 bin_coords[i] = min + (i * delta) + delta / 2.0 ;
338 out <<
"bin_coords = [" << std::endl;
339 for (
unsigned int i=0; i<n_bins; i++)
340 out << bin_coords[i] << std::endl;
341 out <<
"];" << std::endl;
343 out <<
"bar(bin_coords, bin_members, 1);" << std::endl;
344 out <<
"hold on" << std::endl;
345 out <<
"plot (bin_coords, 0, 'kx');" << std::endl;
346 out <<
"xlabel('Quality (0=Worst, 1=Best)');" << std::endl;
347 out <<
"ylabel('Percentage of elements in each bin');" << std::endl;
348 out <<
"axis([" << min <<
"," << max <<
",0, max(bin_members)]);" << std::endl;
357 if (convert_first_order)
360 libMesh::out <<
"Converting elements to first order counterparts\n";
372 if (convert_second_order > 0)
374 bool second_order_mode =
true;
375 std:: string message =
"Converting elements to second order counterparts";
376 if (convert_second_order == 2)
378 second_order_mode =
false;
379 message +=
", lower version: Quad4 -> Quad8, not Quad9";
382 else if (convert_second_order == 22)
384 second_order_mode =
true;
385 message +=
", highest version: Quad4 -> Quad9";
389 libmesh_error_msg(
"Invalid value, convert_second_order = " << convert_second_order);
404 #ifdef LIBMESH_ENABLE_AMR
411 << n_rsteps <<
" times"
440 if (n_subdomains > 1)
445 if (names.size() >= 2)
456 libMesh::out <<
" Mesh got refined, will write only _active_ elements." << std::endl;
466 if (names.size() == 2)
467 new_mesh.
write(names[1]);
468 else if (names.size() == 3)
469 new_mesh.
write(names[1], soln, var_names);
471 libmesh_error_msg(
"Invalid names.size() = " << names.size());
475 if (names.size() == 2)
477 else if (names.size() == 3)
480 libmesh_error_msg(
"Invalid names.size() = " << names.size());
491 std::string boundary_name =
"bndry_";
492 boundary_name += names[1];
498 libmesh_error_msg(
"Invalid value write_bndry = " << write_bndry);
500 if (names.size() == 2)
501 boundary_mesh.
write(boundary_name);
502 else if (names.size() == 3)
503 boundary_mesh.
write(boundary_name, soln, var_names);
511 void usage(
const std::string & prog_name)
513 std::ostringstream helpList;
514 helpList <<
"usage:\n"
517 <<
" [options] ...\n"
520 <<
" -d <dim> <dim>-dimensional mesh\n"
521 <<
" -i <string> Input file name\n"
522 <<
" -o <string> Output file name\n"
523 <<
"\n -b Write the boundary conditions\n"
524 <<
" -D <factor> Randomly move interior nodes by D*hmin\n"
525 <<
" -h Print help menu\n"
526 <<
" -p <count> Partition into <count> subdomains\n"
527 #ifdef LIBMESH_ENABLE_AMR
528 <<
" -r <count> Globally refine <count> times\n"
530 <<
" -t (-d 2 only) Convert to triangles first\n"
531 <<
" (allows to write .unv file of the\n"
532 <<
" boundary with the correct node ids)\n"
534 <<
" -q <metric> Evaluates the named element quality metric\n"
535 <<
" -1 Converts a mesh of higher order elements\n"
536 <<
" to their first-order counterparts:\n"
537 <<
" Quad8 -> Quad4, Tet10 -> Tet4 etc\n"
538 <<
" -2 Converts a mesh of linear elements\n"
539 <<
" to their second-order counterparts:\n"
540 <<
" Quad4 -> Quad8, Tet4 -> Tet10 etc\n"
541 <<
" -3 Same, but to the highest possible:\n"
542 <<
" Quad4 -> Quad9, Hex8 -> Hex27 etc\n"
543 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
544 <<
"\n -a Add infinite elements\n"
545 <<
" -x <coord> Specify infinite element origin\n"
546 <<
" -y <coord> coordinates. If none given, origin\n"
547 <<
" -z <coord> is determined automatically.\n"
548 <<
" -X When building infinite elements \n"
549 <<
" -Y treat mesh as x/y/z-symmetric.\n"
550 <<
" -Z When -X is given, -x <coord> also\n"
551 <<
" has to be given. Similar for y,z.\n"
555 <<
" This program is used to convert and partition from/to a variety of\n"
556 <<
" formats. File types are inferred from file extensions. For example,\n"
559 <<
" ./meshtool -d 2 -i in.e -o out.plt\n"
561 <<
" will read a 2D mesh in the ExodusII format (from Cubit, for example)\n"
562 <<
" from the file in.e. It will then write the mesh in the Tecplot\n"
563 <<
" binary format to out.plt.\n"
567 <<
" ./meshtool -d 3 -i cylinder.msh -o out.e -2\n"
569 <<
" will read the Gmsh formatted mesh file cylinder.msh, convert\n"
570 <<
" the elements to second-order, and write the output in Exodus format\n"
572 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
576 <<
" ./meshtool -d 3 -i dry.unv -o packed.gmv -a -x 30.5 -y -10.5 -X\n"
578 <<
" will read a 3D Universal file, determine the z-coordinate of the origin\n"
579 <<
" automatically, e.g. z_origin = 3., build infinite elements with the\n"
580 <<
" origin (30.5, -10.5, 3.) on top of volume elements, while preserving\n"
581 <<
" a symmetry plane through (30.5, -10.5, 3.) perpendicular to x.\n"
582 <<
" It is imperative that the origin lies _inside_ the given volume mesh.\n"
583 <<
" If not, infinite elements are not correctly built!\n"
586 <<
" Currently this program supports the following formats:\n"
589 <<
" .e -- Sandia's ExodusII binary grid format\n"
590 <<
" .inp -- Abaqus mesh file\n"
591 <<
" .msh -- GMSH ASCII file\n"
592 <<
" .ucd -- AVS unstructured ASCII grid format\n"
593 <<
" .unv -- SDRC I-Deas Universal File ASCII format\n"
594 <<
" .xda -- libMesh human-readable ASCII format\n"
595 <<
" .xdr -- libMesh binary format\n"
598 <<
" .dat -- Tecplot ASCII format\n"
599 <<
" .e -- Sandia's ExodusII format\n"
600 <<
" .exd -- Sandia's ExodusII format\n"
601 <<
" .fro -- ACDL's .fro format\n"
602 <<
" .gmv -- LANL's General Mesh Viewer format\n"
603 <<
" .mesh -- MEdit mesh format\n"
604 <<
" .msh -- GMSH ASCII file\n"
605 <<
" .plt -- Tecplot binary format\n"
606 <<
" .poly -- TetGen ASCII file\n"
607 <<
" .pvtu -- Paraview VTK format\n"
608 <<
" .ucd -- AVS's ASCII UCD format\n"
609 <<
" .unv -- I-deas Universal format\n"
610 <<
" .xda -- libMesh ASCII format\n"
611 <<
" .xdr -- libMesh binary format\n"
612 <<
" .gz -- any above format gzipped\n"
613 <<
" .bz2 -- any above format bzip2'ed\n"
const Point build_inf_elem(const bool be_verbose=false)
Build infinite elements atop a volume-based mesh, determine origin automatically.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
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.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
virtual void all_second_order(const bool full_ordered=true)=0
Converts a (conforming, non-refined) mesh with linear elements into a mesh with second-order elements...
virtual void write(const std::string &name)=0
virtual SimpleRange< element_iterator > active_element_ptr_range()=0
virtual dof_id_type n_elem() const =0
virtual const Elem & elem_ref(const dof_id_type i) const
The libMesh namespace provides an interface to certain functionality in the library.
std::pair< bool, double > InfElemOriginValue
Useful typedef.
const Parallel::Communicator & comm() const
virtual Real mean() const
virtual void histogram(std::vector< dof_id_type > &bin_members, unsigned int n_bins=10)
unsigned int mesh_dimension() const
virtual std::vector< dof_id_type > cut_below(Real cut) const
virtual void write(const std::string &name) override
Write the file specified by name.
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
Implements (adaptive) mesh refinement algorithms for a MeshBase.
void print_summary(std::ostream &out=libMesh::out) const
Prints a summary of the boundary information.
virtual element_iterator active_elements_begin()=0
Active, local, and negation forms of the element iterators described above.
The BoundaryMesh is a Mesh in its own right, but it contains a description of the boundary of some ot...
This class is used to build infinite elements on top of an existing mesh.
virtual std::pair< Real, Real > qual_bounds(const ElemQuality) const
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
virtual void all_first_order()=0
Converts a mesh with higher-order elements into a mesh with linear elements.
ElemQuality
Defines an enum for element quality metrics.
void print_info(std::ostream &os=libMesh::out) const
Prints relevant information about the mesh.
The StatisticsVector class is derived from the std::vector<> and therefore has all of its useful feat...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual element_iterator active_elements_end()=0
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
void sync(UnstructuredMesh &boundary_mesh)
Generates boundary_mesh data structures corresponding to the mesh data structures.
virtual void partition(const unsigned int n_parts)
Call the default partitioner (currently metis_partition()).