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