OGS
ConvertToLinearMesh.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
5
13#include "MeshLib/Mesh.h"
14#include "MeshLib/Node.h"
15#include "MeshLib/Properties.h"
18
19namespace MeshToolsLib
20{
21namespace
22{
23template <typename T_ELEMENT>
25 std::vector<MeshLib::Node*> const& vec_new_nodes,
26 std::vector<std::size_t> const& map)
27{
28 auto const n_base_nodes = T_ELEMENT::n_base_nodes;
29 auto** nodes = new MeshLib::Node*[n_base_nodes];
30 auto* const* element_nodes = e->getNodes();
31 for (unsigned i = 0; i < n_base_nodes; i++)
32 {
33 auto const n = vec_new_nodes[map[element_nodes[i]->getID()]];
34 nodes[i] = const_cast<MeshLib::Node*>(n);
35 }
36 return new T_ELEMENT(nodes);
37}
38} // unnamed namespace
39
40std::unique_ptr<MeshLib::Mesh> convertToLinearMesh(
41 MeshLib::Mesh const& mesh, std::string const& new_mesh_name)
42{
43 auto const& org_elements = mesh.getElements();
44
45 // mark base nodes
46 std::vector<bool> marked_base_nodes(mesh.getNodes().size(), false);
47 for (auto const org_element : org_elements)
48 {
49 for (std::size_t k = 0; k < org_element->getNumberOfBaseNodes(); ++k)
50 {
51 auto const& base_node = *org_element->getNode(k);
52 marked_base_nodes[base_node.getID()] = true;
53 }
54 }
55
56 // construct map and fill new_mesh_nodes
57 std::vector<MeshLib::Node*> new_mesh_nodes{static_cast<std::size_t>(
58 std::count(begin(marked_base_nodes), end(marked_base_nodes), true))};
59 std::size_t base_node_cnt = 0;
60 auto const& org_nodes = mesh.getNodes();
61 std::vector<std::size_t> base_node_map(org_nodes.size(), -1);
62 for (std::size_t k = 0; k < org_nodes.size(); ++k)
63 {
64 if (marked_base_nodes[k])
65 {
66 new_mesh_nodes[base_node_cnt] =
67 new MeshLib::Node(org_nodes[k]->data(), base_node_cnt);
68 base_node_map[k] = base_node_cnt;
69 base_node_cnt++;
70 }
71 }
72
73 // create new elements with the quadratic nodes
74 std::vector<MeshLib::Element*> vec_new_eles;
75 for (MeshLib::Element const* e : mesh.getElements())
76 {
77 if (e->getCellType() == MeshLib::CellType::LINE3)
78 {
79 vec_new_eles.push_back(createLinearElement<MeshLib::Line>(
80 e, new_mesh_nodes, base_node_map));
81 }
82 else if (e->getCellType() == MeshLib::CellType::QUAD8)
83 {
84 vec_new_eles.push_back(createLinearElement<MeshLib::Quad>(
85 e, new_mesh_nodes, base_node_map));
86 }
87 else if (e->getCellType() == MeshLib::CellType::TRI6)
88 {
89 vec_new_eles.push_back(createLinearElement<MeshLib::Tri>(
90 e, new_mesh_nodes, base_node_map));
91 }
92 else if (e->getCellType() == MeshLib::CellType::HEX20)
93 {
94 vec_new_eles.push_back(createLinearElement<MeshLib::Hex>(
95 e, new_mesh_nodes, base_node_map));
96 }
97 else if (e->getCellType() == MeshLib::CellType::TET10)
98 {
99 vec_new_eles.push_back(createLinearElement<MeshLib::Tet>(
100 e, new_mesh_nodes, base_node_map));
101 }
102 else
103 {
104 OGS_FATAL("Mesh element type {:s} is not supported",
105 MeshLib::CellType2String(e->getCellType()));
106 }
107 }
108
109 auto new_mesh = std::make_unique<MeshLib::Mesh>(
110 new_mesh_name, new_mesh_nodes, vec_new_eles,
111 true /* compute_element_neighbors */,
113 std::vector<MeshLib::MeshItemType>(1,
115
116 // copy property vectors for nodes
117 for (auto [name, property] : mesh.getProperties())
118 {
119 if (property->getMeshItemType() != MeshLib::MeshItemType::Node)
120 {
121 continue;
122 }
123 auto double_property =
124 dynamic_cast<MeshLib::PropertyVector<double>*>(property);
125 if (double_property == nullptr)
126 {
127 continue;
128 }
129 auto const n_src_comp = double_property->getNumberOfGlobalComponents();
130 auto new_prop =
131 new_mesh->getProperties().createNewPropertyVector<double>(
132 name, MeshLib::MeshItemType::Node, new_mesh->getNumberOfNodes(),
133 n_src_comp);
134 assert(new_prop != nullptr);
135
136 for (std::size_t k = 0; k < org_nodes.size(); ++k)
137 {
138 if (!marked_base_nodes[k])
139 {
140 continue;
141 }
142 std::copy_n(double_property->begin() + k * n_src_comp,
143 n_src_comp,
144 new_prop->begin() + base_node_map[k] * n_src_comp);
145 }
146 }
147 return new_mesh;
148}
149
150} // namespace MeshToolsLib
#define OGS_FATAL(...)
Definition Error.h:19
virtual Node *const * getNodes() const =0
Get array of element nodes.
std::vector< Node * > const & getNodes() const
Get the nodes-vector for the mesh.
Definition Mesh.h:97
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
Definition Mesh.h:100
Properties & getProperties()
Definition Mesh.h:125
Properties excludeCopyProperties(std::vector< std::size_t > const &exclude_elem_ids, std::vector< std::size_t > const &exclude_node_ids) const
int getNumberOfGlobalComponents() const
std::string CellType2String(const CellType t)
Given a MeshElemType this returns the appropriate string.
T_ELEMENT * createLinearElement(MeshLib::Element const *e, std::vector< MeshLib::Node * > const &vec_new_nodes, std::vector< std::size_t > const &map)
std::unique_ptr< MeshLib::Mesh > convertToLinearMesh(MeshLib::Mesh const &mesh, std::string const &new_mesh_name)