OGS
Interpolation.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 <array>
7#include <cassert>
8
11#include "InitShapeMatrices.h"
12#include "ShapeMatrixPolicy.h"
13
14namespace NumLib
15{
16namespace detail
17{
19template <unsigned DOFOffset, typename NodalValues, typename ShapeMatrix>
20void shapeFunctionInterpolate(const NodalValues& /*nodal_values*/,
21 const ShapeMatrix& /*shape_matrix_N*/)
22{
23}
24
26template <unsigned DOFOffset, typename NodalValues, typename ShapeMatrix,
27 typename... ScalarTypes>
28void shapeFunctionInterpolate(const NodalValues& nodal_values,
29 const ShapeMatrix& shape_matrix_N,
30 double& interpolated_value,
31 ScalarTypes&... interpolated_values)
32{
33 auto const num_nodes = shape_matrix_N.size();
34 double iv = 0.0;
35
36 for (auto n = decltype(num_nodes){0}; n < num_nodes; ++n)
37 {
38 iv += nodal_values[DOFOffset * num_nodes + n] * shape_matrix_N[n];
39 }
40
41 interpolated_value = iv;
42
43 shapeFunctionInterpolate<DOFOffset + 1>(nodal_values, shape_matrix_N,
44 interpolated_values...);
45}
46
47} // namespace detail
48
72template <typename NodalValues, typename ShapeMatrix, typename... ScalarTypes>
73void shapeFunctionInterpolate(const NodalValues& nodal_values,
74 const ShapeMatrix& shape_matrix_N,
75 double& interpolated_value,
76 ScalarTypes&... interpolated_values)
77{
78 auto const num_nodal_dof = sizeof...(interpolated_values) + 1;
79 auto const num_nodes = shape_matrix_N.size();
80
81 assert(num_nodes * num_nodal_dof ==
82 static_cast<std::size_t>(nodal_values.size()));
83 (void)num_nodal_dof;
84 (void)num_nodes; // no warnings when not in debug build
85
86 detail::shapeFunctionInterpolate<0>(nodal_values, shape_matrix_N,
87 interpolated_value,
88 interpolated_values...);
89}
90
98template <typename LowerOrderShapeFunction, typename HigherOrderMeshElementType,
99 int GlobalDim, typename EigenMatrixType>
101 MeshLib::Element const& element, bool const is_axially_symmetric,
102 Eigen::MatrixBase<EigenMatrixType> const& node_values,
103 MeshLib::PropertyVector<double>& interpolated_values_global_vector)
104{
105 assert(dynamic_cast<HigherOrderMeshElementType const*>(&element));
106 assert(node_values.cols() == 1); // Scalar quantity only.
107
108 using SF = LowerOrderShapeFunction;
109 using ShapeMatricesType = ShapeMatrixPolicyType<SF, GlobalDim>;
110
111 int const number_base_nodes = element.getNumberOfBaseNodes();
112 int const number_all_nodes = element.getNumberOfNodes();
113
114 // Copy the values for linear nodes.
115 for (int n = 0; n < number_base_nodes; ++n)
116 {
117 std::size_t const global_index = getNodeIndex(element, n);
118 interpolated_values_global_vector[global_index] = node_values[n];
119 }
120
121 //
122 // Interpolate values for higher order nodes.
123 //
124
125 int const number_higher_order_nodes = number_all_nodes - number_base_nodes;
126 std::vector<MathLib::Point3d> higher_order_nodes;
127 higher_order_nodes.reserve(number_higher_order_nodes);
128 for (int n = 0; n < number_higher_order_nodes; ++n)
129 {
130 higher_order_nodes.emplace_back(
132 [number_base_nodes + n]);
133 }
134
135 // Shape matrices evaluated at higher order nodes' coordinates.
136 auto const shape_matrices =
137 computeShapeMatrices<SF, ShapeMatricesType, GlobalDim,
138 ShapeMatrixType::N>(element, is_axially_symmetric,
139 higher_order_nodes);
140
141 for (int n = 0; n < number_higher_order_nodes; ++n)
142 {
143 std::size_t const global_index =
144 getNodeIndex(element, number_base_nodes + n);
145 interpolated_values_global_vector[global_index] =
146 shape_matrices[n].N * node_values;
147 }
148}
149
150} // namespace NumLib
EigenFixedShapeMatrixPolicy< ShapeFunction, GlobalDim > ShapeMatrixPolicyType
virtual unsigned getNumberOfNodes() const =0
virtual unsigned getNumberOfBaseNodes() const =0
void shapeFunctionInterpolate(const NodalValues &, const ShapeMatrix &)
void interpolateToHigherOrderNodes(MeshLib::Element const &element, bool const is_axially_symmetric, Eigen::MatrixBase< EigenMatrixType > const &node_values, MeshLib::PropertyVector< double > &interpolated_values_global_vector)
std::vector< typename ShapeMatricesType::ShapeMatrices, Eigen::aligned_allocator< typename ShapeMatricesType::ShapeMatrices > > computeShapeMatrices(MeshLib::Element const &e, bool const is_axially_symmetric, PointContainer const &points)