OGS
MeshLib/Elements/Utils.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#pragma once
5
6#include <Eigen/Geometry>
7#include <algorithm>
8#include <vector>
9
10#include "BaseLib/Algorithm.h"
11#include "Element.h"
12#include "FaceRule.h"
13#include "MeshLib/Node.h"
14
15namespace MeshLib
16{
19inline std::vector<Node*> getBaseNodes(std::vector<Element*> const& elements)
20{
21 std::vector<Node*> base_nodes;
22 base_nodes.reserve(elements.size() * 2); // Save some of the realloctions.
23
24 for (auto* const e : elements)
25 {
26 std::copy(e->getNodes(), e->getNodes() + e->getNumberOfBaseNodes(),
27 std::back_inserter(base_nodes));
28 }
29
31
32 base_nodes.shrink_to_fit();
33 return base_nodes;
34}
35
36inline Eigen::Vector3d calculateNormalizedSurfaceNormal(
37 MeshLib::Element const& surface_element,
38 MeshLib::Element const& bulk_element)
39{
40 Eigen::Vector3d surface_element_normal;
41
42 switch (surface_element.getDimension())
43 {
44 case 2:
45 surface_element_normal =
47 break;
48 case 1:
49 {
50 auto const bulk_element_normal =
52 auto const& v0 = surface_element.getNode(0)->asEigenVector3d();
53 auto const& v1 = surface_element.getNode(1)->asEigenVector3d();
54 Eigen::Vector3d const edge_vector = v1 - v0;
55 surface_element_normal = -bulk_element_normal.cross(edge_vector);
56 break;
57 }
58 case 0:
59 {
60 assert(surface_element.getCellType() == CellType::POINT1);
61 assert(bulk_element.getCellType() == CellType::LINE2 ||
62 bulk_element.getCellType() == CellType::LINE3);
63
64 auto const& x = surface_element.getNode(0)->asEigenVector3d();
65
66 // The start of the line element.
67 auto const& a = bulk_element.getNode(0)->asEigenVector3d();
68
69 // The end of the line element is the 2nd base node of the line,
70 // which is the 2nd node.
71 auto const& b = bulk_element.getNode(1)->asEigenVector3d();
72
73 // x coincides either with the start or with the end of the line.
74 // a + b - 2 * x evaluates to a - b or to b - a, respectively.
75 // The formula assumes that the line is perfectly straight, even in
76 // the LINE3 case.
77 surface_element_normal = a + b - 2 * x;
78 }
79 }
80
81 surface_element_normal.normalize();
82 // At the moment (2018-04-26) the surface normal is not oriented
83 // according to the right hand rule
84 // for correct results it is necessary to multiply the normal with
85 // -1
86 surface_element_normal *= -1;
87
88 return surface_element_normal;
89}
90
91} // namespace MeshLib
Eigen::Vector3d const & asEigenVector3d() const
Definition Point3d.h:55
virtual CellType getCellType() const =0
virtual const Node * getNode(unsigned idx) const =0
virtual constexpr unsigned getDimension() const =0
Get dimension of the mesh element.
static Eigen::Vector3d getSurfaceNormal(Element const &e)
Returns the surface normal of a 2D element.
Definition FaceRule.cpp:33
void makeVectorUnique(std::vector< T > &v)
Definition Algorithm.h:173
std::vector< Node * > getBaseNodes(std::vector< Element * > const &elements)
bool idsComparator(T const a, T const b)
Definition Mesh.h:197
Eigen::Vector3d calculateNormalizedSurfaceNormal(MeshLib::Element const &surface_element, MeshLib::Element const &bulk_element)