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