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