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