OGS
ReorderMesh.cpp
Go to the documentation of this file.
1
10#include <tclap/CmdLine.h>
11
12#include <memory>
13#include <string>
14
15#include "BaseLib/Logging.h"
16#include "BaseLib/MPI.h"
18#include "InfoLib/GitInfo.h"
22#include "MeshLib/Mesh.h"
23#include "MeshLib/Node.h"
24
25std::vector<std::size_t> generateBulkIDsReverseMapping(
26 std::span<std::size_t const> bulk_ids)
27{
28 std::vector<std::size_t> parallel_to_sequential_node_ids(bulk_ids.size());
29
30 std::size_t pos = 0;
31 for (auto const id : bulk_ids)
32 {
33 parallel_to_sequential_node_ids[id] = pos;
34 pos++;
35 }
36 return parallel_to_sequential_node_ids;
37}
38
39template <typename T>
41 std::span<std::size_t const>
42 bulk_ids,
43 MeshLib::PropertyVector<T>& reordered_pv)
44{
45 if (original_pv.getNumberOfGlobalComponents() !=
46 reordered_pv.getNumberOfGlobalComponents())
47 {
49 "Could not reorder property {} since the number of components "
50 "isn't equal ({} != {}).",
51 original_pv.getPropertyName(),
52 original_pv.getNumberOfGlobalComponents(),
53 reordered_pv.getNumberOfGlobalComponents());
54 }
55
56 auto const number_of_components = original_pv.getNumberOfGlobalComponents();
57 std::size_t pos = 0;
58 for (auto const& id : bulk_ids)
59 {
60 for (int c = 0; c < number_of_components; c++)
61 {
62 reordered_pv.getComponent(id, c) = original_pv.getComponent(pos, c);
63 }
64 pos++;
65 }
66 return true;
67}
68
69template <typename T>
70bool reorderProperty(MeshLib::Properties const& original_properties,
71 std::span<std::size_t const>
72 bulk_ids,
73 std::string const& property_name,
74 MeshLib::Properties& reordered_properties)
75{
76 if (!reordered_properties.existsPropertyVector<T>(property_name))
77 {
78 return false;
79 }
80 auto const& original_property =
81 *original_properties.getPropertyVector<T>(property_name);
82 auto& reordered_property =
83 *reordered_properties.getPropertyVector<T>(property_name);
84 return reorderProperty(original_property, bulk_ids, reordered_property);
85}
86
87void reorderProperties(MeshLib::Properties const& original_properties,
88 std::span<std::size_t const>
89 bulk_ids,
90 std::vector<std::string> const& property_names,
91 MeshLib::Properties& reordered_properties)
92{
93 for (auto const& property_name : property_names)
94 {
95 bool const success =
96 reorderProperty<double>(original_properties, bulk_ids,
97 property_name, reordered_properties) ||
98 reorderProperty<float>(original_properties, bulk_ids, property_name,
99 reordered_properties) ||
100 reorderProperty<int>(original_properties, bulk_ids, property_name,
101 reordered_properties) ||
102 reorderProperty<long>(original_properties, bulk_ids, property_name,
103 reordered_properties) ||
104 reorderProperty<unsigned>(original_properties, bulk_ids,
105 property_name, reordered_properties) ||
106 reorderProperty<unsigned long>(original_properties, bulk_ids,
107 property_name,
108 reordered_properties) ||
109 reorderProperty<std::size_t>(original_properties, bulk_ids,
110 property_name, reordered_properties) ||
111 reorderProperty<char>(original_properties, bulk_ids, property_name,
112 reordered_properties) ||
113 reorderProperty<unsigned char>(original_properties, bulk_ids,
114 property_name, reordered_properties);
115 if (!success)
116 {
117 OGS_FATAL("Could not reorder PropertyVector '{}'.", property_name);
118 }
119 }
120}
121
122int main(int argc, char* argv[])
123{
124 TCLAP::CmdLine cmd(
125 "Reorder mesh nodes and cells.\n\n"
126 "OpenGeoSys-6 software, version " +
128 ".\n"
129 "Copyright (c) 2012-2025, OpenGeoSys Community "
130 "(http://www.opengeosys.org)",
132 TCLAP::ValueArg<std::string> mesh_in_arg(
133 "i", "input", "Input (.vtu). Name of the input mesh file", true, "",
134 "INPUT_FILE");
135 cmd.add(mesh_in_arg);
136 TCLAP::ValueArg<std::string> mesh_out_arg(
137 "o", "output", "Output (.vtu). Name of the output mesh file", true, "",
138 "OUTPUT_FILE");
139 cmd.add(mesh_out_arg);
140
141 auto log_level_arg = BaseLib::makeLogLevelArg();
142 cmd.add(log_level_arg);
143 cmd.parse(argc, argv);
144
145 BaseLib::MPI::Setup mpi_setup(argc, argv);
146 BaseLib::initOGSLogger(log_level_arg.getValue());
147
148 const std::string filename(mesh_in_arg.getValue());
149
150 // read the mesh file
151 auto const mesh =
152 std::unique_ptr<MeshLib::Mesh>(MeshLib::IO::readMeshFromFile(filename));
153 if (!mesh)
154 {
155 return EXIT_FAILURE;
156 }
157
158 auto const* bulk_node_ids = MeshLib::bulkNodeIDs(*mesh);
159 if (!bulk_node_ids)
160 {
161 OGS_FATAL("Property / data array '{}' has not been found in the mesh.",
163 }
164
165 auto const& nodes = mesh->getNodes();
166 auto const node_ids_reverse_mapping(
167 generateBulkIDsReverseMapping(*bulk_node_ids));
168
169 std::vector<MeshLib::Node*> reordered_nodes(nodes.size());
170 std::size_t pos = 0;
171 for (auto const id : node_ids_reverse_mapping)
172 {
173 auto const& n = *(nodes[id]);
174 reordered_nodes[pos] = new MeshLib::Node(n[0], n[1], n[2], pos);
175 pos++;
176 }
177
178 auto const bulk_element_ids_string =
180 if (!mesh->getProperties().existsPropertyVector<std::size_t>(
181 bulk_element_ids_string))
182 {
183 OGS_FATAL("Property / data array '{}' has not been found in the mesh.",
184 bulk_element_ids_string);
185 }
186 auto const& bulk_element_ids =
187 *mesh->getProperties().getPropertyVector<std::size_t>(
188 bulk_element_ids_string);
189
190 std::vector<std::size_t> element_ids_reverse_mapping(
191 generateBulkIDsReverseMapping(bulk_element_ids));
192
193 auto const& elements = mesh->getElements();
194 std::vector<MeshLib::Element*> reordered_elements(elements.size());
195 pos = 0;
196 for (auto const id : element_ids_reverse_mapping)
197 {
198 auto const& e = *elements[id];
199 auto* reordered_element =
200 e.clone(); // use clone to have the same element type
201 // reset the nodes to the reordered nodes
202 auto const number_of_nodes = reordered_element->getNumberOfNodes();
203 for (std::size_t node_number = 0; node_number < number_of_nodes;
204 node_number++)
205 {
206 reordered_element->setNode(
207 node_number,
208 reordered_nodes[(
209 *bulk_node_ids)[e.getNode(node_number)->getID()]]);
210 }
211 reordered_elements[pos] = reordered_element;
212 pos++;
213 }
214 auto const& original_properties = mesh->getProperties();
215 // reordering of PropertyVector with following MeshItemTypes isn't supported
216 std::vector<MeshLib::MeshItemType> const exclude_property_vectors{
219 // Create reordered mesh - only the PropertyVectors for which the reordering
220 // is implemented are copied
221 MeshLib::Mesh reordered_mesh{
222 "reordered_mesh", reordered_nodes, reordered_elements,
223 false /* compute_element_neighbors */,
224 original_properties.excludeCopyProperties(exclude_property_vectors)};
225 auto& properties = reordered_mesh.getProperties();
226
227 // node based properties
228 auto const node_property_names =
229 mesh->getProperties().getPropertyVectorNames(
231 reorderProperties(original_properties, std::span{*bulk_node_ids},
232 node_property_names, properties);
233
234 // element based properties
235 auto const element_property_names =
236 mesh->getProperties().getPropertyVectorNames(
238 reorderProperties(original_properties, bulk_element_ids,
239 element_property_names, properties);
240 MeshLib::IO::writeMeshToFile(reordered_mesh, mesh_out_arg.getValue());
241
242 auto const number_of_properties =
243 mesh->getProperties().getPropertyVectorNames().size();
244 if (node_property_names.size() + element_property_names.size() <
245 number_of_properties)
246 {
247 WARN(
248 "Properties that are not assigened to nodes or elements are not "
249 "transferred to the reordered mesh.");
250 }
251
252 return EXIT_SUCCESS;
253}
Definition of the Element class.
#define OGS_FATAL(...)
Definition Error.h:26
Git information.
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:42
Definition of the Mesh class.
Definition of the Node class.
int main(int argc, char *argv[])
void reorderProperties(MeshLib::Properties const &original_properties, std::span< std::size_t const > bulk_ids, std::vector< std::string > const &property_names, MeshLib::Properties &reordered_properties)
std::vector< std::size_t > generateBulkIDsReverseMapping(std::span< std::size_t const > bulk_ids)
bool reorderProperty(MeshLib::PropertyVector< T > const &original_pv, std::span< std::size_t const > bulk_ids, MeshLib::PropertyVector< T > &reordered_pv)
Properties & getProperties()
Definition Mesh.h:136
Property manager on mesh items. Class Properties manages scalar, vector or matrix properties....
Definition Properties.h:33
std::vector< std::string > getPropertyVectorNames() const
bool existsPropertyVector(std::string_view name) const
PropertyVector< T > const * getPropertyVector(std::string_view name) const
int getNumberOfGlobalComponents() const
std::string const & getPropertyName() const
PROP_VAL_TYPE & getComponent(std::size_t tuple_index, int component)
Returns the value for the given component stored in the given tuple.
TCLAP::ValueArg< std::string > makeLogLevelArg()
void initOGSLogger(std::string const &log_level)
Definition Logging.cpp:64
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)
constexpr std::string_view getBulkIDString(MeshItemType mesh_item_type)
Definition Properties.h:191
PropertyVector< std::size_t > const * bulkNodeIDs(Mesh const &mesh)
Definition Mesh.cpp:293
Definition of readMeshFromFile function.