OGS
removeMeshElements.cpp
Go to the documentation of this file.
1
14#include <tclap/CmdLine.h>
15
16#ifdef USE_PETSC
17#include <mpi.h>
18#endif
19
20#include <memory>
21
22#include "InfoLib/GitInfo.h"
26#include "MeshLib/Mesh.h"
27#include "MeshLib/MeshEnums.h"
29#include "MeshLib/Node.h"
32
33template <typename PROPERTY_TYPE>
34void searchByPropertyValue(std::string const& property_name,
35 std::vector<PROPERTY_TYPE> const& property_values,
36 MeshLib::ElementSearch& searcher)
37{
38 for (auto const& property_value : property_values)
39 {
40 std::size_t n_marked_elements = searcher.searchByPropertyValue<double>(
41 property_name, property_value);
42 if (n_marked_elements == 0)
43 {
44 n_marked_elements = searcher.searchByPropertyValue<int>(
45 property_name, property_value);
46 }
47
48 INFO("{:d} elements with property value {:s} found.", n_marked_elements,
49 std::to_string(property_value));
50 }
51}
52
53void searchByPropertyRange(std::string const& property_name,
54 double const& min_value, double const& max_value,
55 bool const& outside,
56 MeshLib::ElementSearch& searcher)
57{
58 std::size_t n_marked_elements = searcher.searchByPropertyValueRange<double>(
59 property_name, min_value, max_value, outside);
60
61 if (n_marked_elements == 0)
62 {
63 n_marked_elements = searcher.searchByPropertyValueRange<int>(
64 property_name, static_cast<int>(min_value),
65 static_cast<int>(max_value), outside);
66 }
67
68 // add checks for other data types here (if n_marked_elements remains 0)
69
70 INFO("{:d} elements in range [{:s}, {:s}] found.", n_marked_elements,
71 std::to_string(min_value), std::to_string(max_value));
72}
73
74void outputAABB(MeshLib::Mesh const& mesh)
75{
77 auto const [min, max] = aabb.getMinMaxPoints();
78
79 INFO(
80 "Bounding box of \"{:s}\" is\nx = [{:f},{:f}]\ny = [{:f},{:f}]\nz = "
81 "[{:f},{:f}]",
82 mesh.getName(), min.x(), max.x(), min.y(), max.y(), min.z(), max.z());
83}
84
85int main(int argc, char* argv[])
86{
87 TCLAP::CmdLine cmd(
88 "Removes mesh elements based on element type, element volume, scalar "
89 "arrays, or bounding box . The documentation is available at "
90 "https://docs.opengeosys.org/docs/tools/meshing/"
91 "remove-mesh-elements.\n\n"
92 "OpenGeoSys-6 software, version " +
94 ".\n"
95 "Copyright (c) 2012-2024, OpenGeoSys Community "
96 "(http://www.opengeosys.org)",
98
99 // Bounding box params
100 TCLAP::SwitchArg invert_bounding_box_arg(
101 "", "invert", "inverts the specified bounding box", false);
102 cmd.add(invert_bounding_box_arg);
103 TCLAP::ValueArg<double> zLargeArg(
104 "", "z-max", "largest allowed extent in z-dimension", false,
105 std::numeric_limits<double>::max(), "value");
106 cmd.add(zLargeArg);
107 TCLAP::ValueArg<double> zSmallArg(
108 "", "z-min", "smallest allowed extent in z-dimension", false,
109 -1 * std::numeric_limits<double>::max(), "value");
110 cmd.add(zSmallArg);
111 TCLAP::ValueArg<double> yLargeArg(
112 "", "y-max", "largest allowed extent in y-dimension", false,
113 std::numeric_limits<double>::max(), "value");
114 cmd.add(yLargeArg);
115 TCLAP::ValueArg<double> ySmallArg(
116 "", "y-min", "smallest allowed extent in y-dimension", false,
117 -1 * std::numeric_limits<double>::max(), "value");
118 cmd.add(ySmallArg);
119 TCLAP::ValueArg<double> xLargeArg(
120 "", "x-max", "largest allowed extent in x-dimension", false,
121 std::numeric_limits<double>::max(), "value");
122 cmd.add(xLargeArg);
123 TCLAP::ValueArg<double> xSmallArg(
124 "", "x-min", "smallest allowed extent in x-dimension", false,
125 -1 * std::numeric_limits<double>::max(), "value");
126 cmd.add(xSmallArg);
127
128 // Non-bounding-box params
129 TCLAP::SwitchArg zveArg("z", "zero-volume", "remove zero volume elements",
130 false);
131 cmd.add(zveArg);
132
133 std::vector<std::string> allowed_ele_types{
134 "point", "line", "tri", "quad", "hex", "prism", "tet", "pyramid"};
135 TCLAP::ValuesConstraint<std::string> allowedVals{allowed_ele_types};
136 TCLAP::MultiArg<std::string> eleTypeArg(
137 "t", "element-type",
138 "element type to be removed: point | line | tri | quad | hex | prism | "
139 "tet | pyramid",
140 false, &allowedVals);
141 cmd.add(eleTypeArg);
142
143 // scalar array params
144 TCLAP::ValueArg<std::string> property_name_arg(
145 "n", "property-name", "name of property in the mesh", false,
146 "MaterialIDs", "string");
147 cmd.add(property_name_arg);
148
149 TCLAP::MultiArg<int> property_arg(
150 "", "property-value", "value of selected property to be removed", false,
151 "number");
152 cmd.add(property_arg);
153
154 TCLAP::ValueArg<double> min_property_arg(
155 "", "min-value", "minimum value of range for selected property", false,
156 0, "number");
157 cmd.add(min_property_arg);
158
159 TCLAP::ValueArg<double> max_property_arg(
160 "", "max-value", "maximum value of range for selected property", false,
161 0, "number");
162 cmd.add(max_property_arg);
163
164 TCLAP::SwitchArg outside_property_arg(
165 "", "outside", "remove all elements outside the given property range");
166 cmd.add(outside_property_arg);
167
168 TCLAP::SwitchArg inside_property_arg(
169 "", "inside", "remove all elements inside the given property range");
170 cmd.add(inside_property_arg);
171
172 // I/O params
173 TCLAP::ValueArg<std::string> mesh_out(
174 "o", "mesh-output-file",
175 "the name of the file the mesh will be written to", true, "",
176 "file name of output mesh");
177 cmd.add(mesh_out);
178 TCLAP::ValueArg<std::string> mesh_in(
179 "i", "mesh-input-file",
180 "the name of the file containing the input mesh", true, "",
181 "file name of input mesh");
182 cmd.add(mesh_in);
183 cmd.parse(argc, argv);
184
185#ifdef USE_PETSC
186 MPI_Init(&argc, &argv);
187#endif
188
189 std::unique_ptr<MeshLib::Mesh const> mesh(
190 MeshLib::IO::readMeshFromFile(mesh_in.getValue()));
191 if (mesh == nullptr)
192 {
193#ifdef USE_PETSC
194 MPI_Finalize();
195#endif
196 return EXIT_FAILURE;
197 }
198
199 INFO("Mesh read: {:d} nodes, {:d} elements.", mesh->getNumberOfNodes(),
200 mesh->getNumberOfElements());
201 MeshLib::ElementSearch searcher(*mesh);
202
203 // search elements IDs to be removed
204 if (zveArg.isSet())
205 {
206 INFO("{:d} zero volume elements found.", searcher.searchByContent());
207 }
208 if (eleTypeArg.isSet())
209 {
210 const std::vector<std::string> eleTypeNames = eleTypeArg.getValue();
211 for (const auto& typeName : eleTypeNames)
212 {
213 const MeshLib::MeshElemType type =
216 {
217 continue;
218 }
219 INFO("{:d} {:s} elements found.",
220 searcher.searchByElementType(type), typeName);
221 }
222 }
223
224 if (property_name_arg.isSet() || property_arg.isSet() ||
225 min_property_arg.isSet() || max_property_arg.isSet())
226 {
227 if ((property_arg.isSet() || min_property_arg.isSet() ||
228 max_property_arg.isSet()) &&
229 !property_name_arg.isSet())
230 {
231 ERR("Specify a property name for the value/range selected.");
232#ifdef USE_PETSC
233 MPI_Finalize();
234#endif
235 return EXIT_FAILURE;
236 }
237
238 if (property_name_arg.isSet() &&
239 !((min_property_arg.isSet() && max_property_arg.isSet()) ||
240 property_arg.isSet()))
241 {
242 ERR("Specify a value or range ('-min-value' and '-max_value') for "
243 "the property selected.");
244#ifdef USE_PETSC
245 MPI_Finalize();
246#endif
247 return EXIT_FAILURE;
248 }
249
250 // name + value
251 if (property_arg.isSet() && property_name_arg.isSet())
252 {
253 searchByPropertyValue(property_name_arg.getValue(),
254 property_arg.getValue(), searcher);
255 }
256
257 // name + range
258 if (property_name_arg.isSet() && min_property_arg.isSet() &&
259 max_property_arg.isSet())
260 {
261 if ((!outside_property_arg.isSet() &&
262 !inside_property_arg.isSet()) ||
263 (outside_property_arg.isSet() && inside_property_arg.isSet()))
264 {
265 ERR("Specify if the inside or the outside of the selected "
266 "range should be removed.");
267#ifdef USE_PETSC
268 MPI_Finalize();
269#endif
270 return EXIT_FAILURE;
271 }
272
273 bool const outside = outside_property_arg.isSet();
275 property_name_arg.getValue(), min_property_arg.getValue(),
276 max_property_arg.getValue(), outside, searcher);
277 }
278 }
279
280 if (xSmallArg.isSet() || xLargeArg.isSet() || ySmallArg.isSet() ||
281 yLargeArg.isSet() || zSmallArg.isSet() || zLargeArg.isSet())
282 {
283 outputAABB(*mesh);
284 bool aabb_error(false);
285 if (xSmallArg.getValue() >= xLargeArg.getValue())
286 {
287 ERR("Minimum x-extent larger than maximum x-extent.");
288 aabb_error = true;
289 }
290 if (ySmallArg.getValue() >= yLargeArg.getValue())
291 {
292 ERR("Minimum y-extent larger than maximum y-extent.");
293 aabb_error = true;
294 }
295 if (zSmallArg.getValue() >= zLargeArg.getValue())
296 {
297 ERR("Minimum z-extent larger than maximum z-extent.");
298 aabb_error = true;
299 }
300 if (aabb_error)
301 {
302#ifdef USE_PETSC
303 MPI_Finalize();
304#endif
305 return EXIT_FAILURE;
306 }
307
308 std::array<MathLib::Point3d, 2> extent(
309 {{MathLib::Point3d(std::array<double, 3>{{xSmallArg.getValue(),
310 ySmallArg.getValue(),
311 zSmallArg.getValue()}}),
312 MathLib::Point3d(std::array<double, 3>{
313 {xLargeArg.getValue(), yLargeArg.getValue(),
314 zLargeArg.getValue()}})}});
315 INFO("{:d} elements found.",
316 searcher.searchByBoundingBox(
317 GeoLib::AABB(extent.begin(), extent.end()),
318 invert_bounding_box_arg.getValue()));
319 }
320
321 // remove the elements and create a new mesh object.
322 std::unique_ptr<MeshLib::Mesh const> new_mesh(MeshToolsLib::removeElements(
323 *mesh, searcher.getSearchedElementIDs(), mesh->getName()));
324
325 if (new_mesh == nullptr)
326 {
327#ifdef USE_PETSC
328 MPI_Finalize();
329#endif
330 return EXIT_FAILURE;
331 }
332
333 // write into a file
334 MeshLib::IO::writeMeshToFile(*new_mesh, mesh_out.getValue());
335
336#ifdef USE_PETSC
337 MPI_Finalize();
338#endif
339 return EXIT_SUCCESS;
340}
Definition of the Element class.
Git information.
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:35
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:45
Definition of mesh-related Enumerations.
Definition of the MeshInformation class.
Definition of the Mesh class.
Definition of the Node class.
Class AABB is an axis aligned bounding box around a given set of geometric points of (template) type ...
Definition AABB.h:56
Element search class.
std::size_t searchByBoundingBox(GeoLib::AABB const &aabb, bool const invert=false)
const std::vector< std::size_t > & getSearchedElementIDs() const
return marked elements
std::size_t searchByElementType(MeshElemType eleType)
Marks all elements of the given element type.
std::size_t searchByPropertyValueRange(std::string const &property_name, PROPERTY_TYPE const min_property_value, PROPERTY_TYPE const max_property_value, bool outside_of)
std::size_t searchByContent(double eps=std::numeric_limits< double >::epsilon())
Marks all elements with a volume smaller than eps.
std::size_t searchByPropertyValue(std::string const &property_name, PROPERTY_TYPE const property_value)
const std::string getName() const
Get name of the mesh.
Definition Mesh.h:103
static GeoLib::AABB getBoundingBox(const MeshLib::Mesh &mesh)
Returns the bounding box of the mesh.
GITINFOLIB_EXPORT const std::string ogs_version
MeshLib::Mesh * readMeshFromFile(const std::string &file_name, bool const compute_element_neighbors)
int writeMeshToFile(const MeshLib::Mesh &mesh, std::filesystem::path const &file_path, std::set< std::string > variable_output_names)
MeshElemType String2MeshElemType(const std::string &s)
Given a string of the shortened name of the element type, this returns the corresponding MeshElemType...
Definition MeshEnums.cpp:95
MeshElemType
Types of mesh elements supported by OpenGeoSys. Values are from VTKCellType enum.
Definition MeshEnums.h:27
MeshLib::Mesh * removeElements(const MeshLib::Mesh &mesh, const std::vector< std::size_t > &removed_element_ids, const std::string &new_mesh_name)
Definition of readMeshFromFile function.
int main(int argc, char *argv[])
void outputAABB(MeshLib::Mesh const &mesh)
void searchByPropertyValue(std::string const &property_name, std::vector< PROPERTY_TYPE > const &property_values, MeshLib::ElementSearch &searcher)
void searchByPropertyRange(std::string const &property_name, double const &min_value, double const &max_value, bool const &outside, MeshLib::ElementSearch &searcher)