libMesh
meshbcid.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 // Open the mesh named in command line arguments,
19 // apply the named tests on every boundary side and normal vector,
20 // and give the specified boundary condition id to each side
21 // that passes the tests.
22 
23 #include <limits>
24 #include <string>
25 
26 #include "libmesh/libmesh.h"
27 
28 #include "libmesh/boundary_info.h"
29 #include "libmesh/bounding_box.h"
30 #include "libmesh/elem.h"
31 #include "libmesh/fe.h"
32 #include "libmesh/getpot.h"
33 #include "libmesh/mesh.h"
34 #include "libmesh/point.h"
35 #include "libmesh/quadrature_gauss.h"
36 
37 using namespace libMesh;
38 
39 void usage_error(const char * progname)
40 {
41  libMesh::out << "Usage: " << progname
42  << " --dim d --input inputmesh --output outputmesh --newbcid idnum --tests --moretests"
43  << std::endl;
44 
45  exit(1);
46 }
47 
48 int main(int argc, char ** argv)
49 {
50  LibMeshInit init(argc, argv);
51 
52  GetPot cl(argc, argv);
53 
54  unsigned char dim = -1;
55  if (!cl.search("--dim"))
56  {
57  libMesh::err << "No --dim argument found!" << std::endl;
58  usage_error(argv[0]);
59  }
60  dim = cl.next(dim);
61 
62  Mesh mesh(init.comm(), dim);
63 
64  if (!cl.search("--input"))
65  {
66  libMesh::err << "No --input argument found!" << std::endl;
67  usage_error(argv[0]);
68  }
69  const char * meshname = cl.next("mesh.xda");
70 
71  mesh.read(meshname);
72  libMesh::out << "Loaded mesh " << meshname << std::endl;
73 
74  if (!cl.search("--newbcid"))
75  {
76  libMesh::err << "No --bcid argument found!" << std::endl;
77  usage_error(argv[0]);
78  }
79  boundary_id_type bcid = 0;
80  bcid = cl.next(bcid);
81 
82  Point minpt(-std::numeric_limits<Real>::max());
83 #if LIBMESH_DIM > 1
84  minpt(1) = -std::numeric_limits<Real>::max();
85 #endif
86 #if LIBMESH_DIM > 2
87  minpt(2) = -std::numeric_limits<Real>::max();
88 #endif
89  Point maxpt = -minpt;
90 
91  BoundingBox normals(minpt, maxpt),
92  points(minpt, maxpt);
93 
94  if (cl.search("--minnormalx"))
95  normals.min()(0) = cl.next(normals.min()(0));
96  if (cl.search("--maxnormalx"))
97  normals.max()(0) = cl.next(normals.max()(0));
98 
99  if (cl.search("--minpointx"))
100  points.min()(0) = cl.next(points.min()(0));
101  if (cl.search("--maxpointx"))
102  points.max()(0) = cl.next(points.max()(0));
103 
104 #if LIBMESH_DIM > 1
105  if (cl.search("--minnormaly"))
106  normals.min()(1) = cl.next(normals.min()(1));
107  if (cl.search("--maxnormaly"))
108  normals.max()(1) = cl.next(normals.max()(1));
109 
110  if (cl.search("--minpointy"))
111  points.min()(1) = cl.next(points.min()(1));
112  if (cl.search("--maxpointy"))
113  points.max()(1) = cl.next(points.max()(1));
114 #endif
115 
116 #if LIBMESH_DIM > 2
117  if (cl.search("--minnormalz"))
118  normals.min()(2) = cl.next(normals.min()(2));
119  if (cl.search("--maxnormalz"))
120  normals.max()(2) = cl.next(normals.max()(2));
121 
122  if (cl.search("--minpointz"))
123  points.min()(2) = cl.next(points.min()(2));
124  if (cl.search("--maxpointz"))
125  points.max()(2) = cl.next(points.max()(2));
126 #endif
127 
128  libMesh::out << "min point = " << points.min() << std::endl;
129  libMesh::out << "max point = " << points.max() << std::endl;
130  libMesh::out << "min normal = " << normals.min() << std::endl;
131  libMesh::out << "max normal = " << normals.max() << std::endl;
132 
133  bool matcholdbcid = false;
134  boundary_id_type oldbcid = 0;
135  if (cl.search("--oldbcid"))
136  {
137  matcholdbcid = true;
138  oldbcid = cl.next(oldbcid);
139  if (oldbcid < 0)
140  oldbcid = BoundaryInfo::invalid_id;
141  }
142 
143  std::unique_ptr<FEBase> fe = FEBase::build(dim, FEType(FIRST,LAGRANGE));
144  QGauss qface(dim-1, CONSTANT);
145  fe->attach_quadrature_rule(&qface);
146  const std::vector<Point> & face_points = fe->get_xyz();
147  const std::vector<Point> & face_normals = fe->get_normals();
148 
149  for (auto & elem : mesh.element_ptr_range())
150  {
151  unsigned int n_sides = elem->n_sides();
152 
153  // Container to catch ids handed back from BoundaryInfo
154  std::vector<boundary_id_type> ids;
155 
156  for (unsigned short s=0; s != n_sides; ++s)
157  {
158  if (elem->neighbor_ptr(s))
159  continue;
160 
161  fe->reinit(elem,s);
162  const Point & p = face_points[0];
163  const Point & n = face_normals[0];
164 
165  //libMesh::out << "elem = " << elem->id() << std::endl;
166  //libMesh::out << "vertex average = " << elem->vertex_average() << std::endl;
167  //libMesh::out << "p = " << p << std::endl;
168  //libMesh::out << "n = " << n << std::endl;
169 
170  if (points.contains_point(p) &&
171  normals.contains_point(n))
172  {
173  // Get the list of boundary ids for this side
174  mesh.get_boundary_info().boundary_ids(elem, s, ids);
175 
176  // There should be at most one value present, otherwise the
177  // logic here won't work.
178  libmesh_assert(ids.size() <= 1);
179 
180  // A convenient name for the side's ID.
181  boundary_id_type b_id = ids.empty() ? BoundaryInfo::invalid_id : ids[0];
182 
183  if (matcholdbcid && b_id != oldbcid)
184  continue;
185 
187  mesh.get_boundary_info().add_side(elem, s, bcid);
188  //libMesh::out << "Set element " << elem->id() << " side " << s <<
189  // " to boundary " << bcid << std::endl;
190  }
191  }
192  }
193 
194  // We might have removed *every* instance of a given id, and if that
195  // happened then we should make sure that file formats which write
196  // out id sets do not write out the removed id.
198 
199  std::string outputname;
200  if (cl.search("--output"))
201  {
202  outputname = cl.next("mesh.xda");
203  }
204  else
205  {
206  outputname = "new.";
207  outputname += meshname;
208  }
209 
210 
211  mesh.write(outputname.c_str());
212  libMesh::out << "Wrote mesh " << outputname << std::endl;
213 
214  return 0;
215 }
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:196
OStreamProxy err
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.
bool contains_point(const Point &) const
Definition: bounding_box.C:35
unsigned int dim
MeshBase & mesh
void boundary_ids(const Node *node, std::vector< boundary_id_type > &vec_to_fill) const
Fills a user-provided std::vector with the boundary ids associated with Node node.
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition: libmesh.h:90
The libMesh namespace provides an interface to certain functionality in the library.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition: mesh_base.h:165
int8_t boundary_id_type
Definition: id_types.h:51
static const boundary_id_type invalid_id
Number used for internal use.
const Point & min() const
Definition: bounding_box.h:77
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
libmesh_assert(ctx)
void regenerate_id_sets()
Clears and regenerates the cached sets of ids.
virtual void write(const std::string &name) const =0
Defines a Cartesian bounding box by the two corner extremum.
Definition: bounding_box.h:40
void remove_side(const Elem *elem, const unsigned short int side)
Removes all boundary conditions associated with side side of element elem, if any exist...
OStreamProxy out
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
Add side side of element number elem with boundary id id to the boundary information data structure...
This class implements specific orders of Gauss quadrature.
int main(int argc, char **argv)
Definition: meshbcid.C:48
const Point & max() const
Definition: bounding_box.h:86
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition: mesh.h:50
void usage_error(const char *progname)
Definition: meshbcid.C:39
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39