OGS 6.2.0-97-g4a610c866
QuadraticMeshGenerator.cpp
Go to the documentation of this file.
1 
10 #include "QuadraticMeshGenerator.h"
11 
13 #include "MeshLib/Elements/Hex.h"
14 #include "MeshLib/Elements/Line.h"
15 #include "MeshLib/Elements/Quad.h"
16 #include "MeshLib/Elements/Tet.h"
17 #include "MeshLib/Elements/Tri.h"
19 #include "MeshLib/Node.h"
20 
23 template <typename QuadraticElement>
24 std::unique_ptr<QuadraticElement> convertLinearToQuadratic(
25  MeshLib::Element const& e)
26 {
27  int const n_all_nodes = QuadraticElement::n_all_nodes;
28  int const n_base_nodes = QuadraticElement::n_base_nodes;
29  assert(n_base_nodes == e.getNumberOfBaseNodes());
30 
31  // Copy base nodes of element to the quadratic element new nodes'.
32  std::array<MeshLib::Node*, n_all_nodes> nodes;
33  for (int i = 0; i < n_base_nodes; i++)
34  {
35  nodes[i] = const_cast<MeshLib::Node*>(e.getNode(i));
36  }
37 
38  // For each edge create a middle node.
39  int const number_of_edges = e.getNumberOfEdges();
40  for (int i = 0; i < number_of_edges; i++)
41  {
42  auto const& a = *e.getEdgeNode(i, 0);
43  auto const& b = *e.getEdgeNode(i, 1);
44 
45  nodes[n_base_nodes + i] = new MeshLib::Node(
46  (a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2);
47  }
48 
49  return std::make_unique<QuadraticElement>(nodes, e.getID());
50 }
51 
53 std::unique_ptr<MeshLib::Element> createQuadraticElement(
54  MeshLib::Element const& e)
55 {
57  {
58  return convertLinearToQuadratic<MeshLib::Line3>(e);
59  }
61  {
62  return convertLinearToQuadratic<MeshLib::Tri6>(e);
63  }
65  {
66  return convertLinearToQuadratic<MeshLib::Tet10>(e);
67  }
69  {
70  return convertLinearToQuadratic<MeshLib::Quad8>(e);
71  }
73  {
74  return convertLinearToQuadratic<MeshLib::Hex20>(e);
75  }
76 
77  OGS_FATAL("Mesh element type %s is not supported",
79 }
80 
82 {
84  {
85  return *a < *b;
86  }
87 };
88 
89 namespace MeshLib
90 {
91 std::unique_ptr<Mesh> createQuadraticOrderMesh(Mesh const& linear_mesh)
92 {
93  // Clone the linear mesh nodes.
94  auto quadratic_mesh_nodes = MeshLib::copyNodeVector(linear_mesh.getNodes());
95 
96  // Temporary container for unique quadratic nodes with O(log(n)) search.
97  std::set<MeshLib::Node*, nodeByCoordinatesComparator> unique_nodes;
98 
99  // Create new elements with the quadratic nodes
100  std::vector<MeshLib::Element*> quadratic_elements;
101  auto const& linear_mesh_elements = linear_mesh.getElements();
102  for (MeshLib::Element const* e : linear_mesh_elements)
103  {
104  auto quadratic_element = createQuadraticElement(*e);
105 
106  // Replace the base nodes with cloned linear nodes.
107  int const number_base_nodes = quadratic_element->getNumberOfBaseNodes();
108  for (int i = 0; i < number_base_nodes; ++i)
109  {
110  quadratic_element->setNode(
111  i, quadratic_mesh_nodes[quadratic_element->getNodeIndex(i)]);
112  }
113 
114  // Make the new (middle-edge) nodes unique.
115  int const number_all_nodes = quadratic_element->getNumberOfNodes();
116  for (int i = number_base_nodes; i < number_all_nodes; ++i)
117  {
118  Node* original_node =
119  const_cast<Node*>(quadratic_element->getNode(i));
120 
121  auto it = unique_nodes.insert(original_node);
122  if (!it.second) // same node was already inserted before, no
123  // insertion
124  {
125  // Replace the element's node with the unique node.
126  quadratic_element->setNode(i, *it.first);
127  // And delete the original node
128  delete original_node;
129  }
130  }
131 
132  quadratic_elements.push_back(quadratic_element.release());
133  }
134 
135  // Add the unique quadratic nodes to the cloned linear nodes.
136  quadratic_mesh_nodes.reserve(linear_mesh.getNodes().size() +
137  unique_nodes.size());
138  std::copy(unique_nodes.begin(), unique_nodes.end(),
139  std::back_inserter(quadratic_mesh_nodes));
140 
141  return std::make_unique<MeshLib::Mesh>(
142  linear_mesh.getName(), quadratic_mesh_nodes, quadratic_elements,
143  linear_mesh.getProperties().excludeCopyProperties(
144  std::vector<MeshLib::MeshItemType>(1, MeshLib::MeshItemType::Node)),
145  linear_mesh.getNumberOfNodes());
146 }
147 
148 } // namespace MeshLib
virtual unsigned getNumberOfBaseNodes() const =0
std::size_t getNumberOfNodes() const
Get the number of nodes.
Definition: Mesh.h:99
const std::string CellType2String(const CellType t)
Given a MeshElemType this returns the appropriate string.
Definition: MeshEnums.cpp:154
std::unique_ptr< Mesh > createQuadraticOrderMesh(Mesh const &linear_mesh)
create a quadratic order mesh from the linear order mesh
Definition of the Line class.
std::unique_ptr< MeshLib::Element > createQuadraticElement(MeshLib::Element const &e)
Return a new quadratic element corresponding to the linear element&#39;s type.
Definition of the Node class.
Definition of the Tet class.
std::vector< Node * > const & getNodes() const
Get the nodes-vector for the mesh.
Definition: Mesh.h:105
MeshLib::Properties & getProperties()
Definition: Mesh.h:134
Definition of the Tri class.
Properties excludeCopyProperties(std::vector< std::size_t > const &exclude_elem_ids, std::vector< std::size_t > const &exclude_node_ids) const
Definition: Properties.cpp:61
const std::string getName() const
Get name of the mesh.
Definition: Mesh.h:102
bool operator()(MeshLib::Node *a, MeshLib::Node *b) const
Interface for heuristic search length strategy.
Definition: ProjectData.h:29
Definition of Duplicate functions.
std::unique_ptr< QuadraticElement > convertLinearToQuadratic(MeshLib::Element const &e)
virtual CellType getCellType() const =0
std::vector< MeshLib::Node * > copyNodeVector(const std::vector< MeshLib::Node *> &nodes)
Creates a deep copy of a Node vector.
virtual unsigned getNumberOfEdges() const =0
Get the number of edges for this element.
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
Definition: Mesh.h:108
Definition of the Quad class.
virtual std::size_t getID() const final
Returns the ID of the element.
Definition: Element.h:90
#define OGS_FATAL(fmt,...)
Definition: Error.h:63
void copy(MatrixOrVector const &x, MatrixOrVector &y)
Copies x to y.
Definition: LinAlg.h:36
Definition of the Element class.
virtual Node * getEdgeNode(unsigned edge_id, unsigned node_id) const =0
Return a specific edge node.
Definition of the Hex class.
const Node * getNode(unsigned i) const
Definition: Element.cpp:156