OGS
NsAndWeight.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/Core>
7
11
13{
14
24template <typename ShapeFunction, typename LowerOrderShapeFunction,
25 typename ShapeMatrix, typename LowerOrderShapeMatrix>
27{
28 static_assert(
29 ShapeFunction::ORDER > LowerOrderShapeFunction::ORDER,
30 "Shape function orders must be different from each other. For same "
31 "orders the class template specialization below should be used.");
32
33 static_assert(ShapeFunction::ORDER == 2);
34 static_assert(LowerOrderShapeFunction::ORDER < 2);
35
36 NsAndWeight(ShapeMatrix&& N1, LowerOrderShapeMatrix&& N2,
37 double const weight)
38 : N_higher_{std::move(N1)}, N_lower_{std::move(N2)}, weight_{weight}
39 {
40 }
41
42 double weight() const { return weight_; }
43
44 Eigen::Ref<const Eigen::RowVectorXd> N(unsigned order) const
45 {
46 if (order < 2)
47 {
48 return N_lower_;
49 }
50
51 if (order == 2)
52 {
53 return N_higher_;
54 }
55
57 "Only shape functions up to order 2 are supported currently. You "
58 "have requested order {}. There might be an error in the OGS "
59 "project file.",
60 order);
61 }
62
63 ShapeMatrix const& NHigherOrder() const { return N_higher_; }
64
65private:
66 ShapeMatrix N_higher_;
67 LowerOrderShapeMatrix N_lower_;
68 double weight_;
69};
70
73template <typename ShapeFunction, typename ShapeMatrix>
74struct NsAndWeight<ShapeFunction, ShapeFunction, ShapeMatrix, ShapeMatrix>
75{
76 static_assert(ShapeFunction::ORDER < 2,
77 "For higher order shape functions the general case of this "
78 "class template should be used. See above.");
79
80 NsAndWeight(ShapeMatrix&& N, double const weight)
81 : N_{std::move(N)}, weight_{weight}
82 {
83 }
84
85 Eigen::Ref<const Eigen::RowVectorXd> N(unsigned order) const
86 {
87 // For point elements shape functions are the same for all orders, so
88 // this specialization will be selected, which is OK for any shape
89 // function order for point elements.
90 if constexpr (!std::is_same_v<ShapeFunction, NumLib::ShapePoint1>)
91 {
92 if (order >= 2)
93 {
95 "Only shape functions of order < 2 are available in the "
96 "current setting. You have requested order {}. Maybe there "
97 "is an error in the OGS project file.",
98 order);
99 }
100 }
101
102 return N_;
103 }
104
105 ShapeMatrix const& NHigherOrder() const { return N_; }
106
107 double weight() const { return weight_; }
108
109private:
110 ShapeMatrix N_;
111 double weight_;
112};
113
115template <typename ShapeFunction, typename LowerOrderShapeFunction,
116 int GlobalDim>
118{
120 using ShapeMatrix = typename ShapeMatrixPolicy::ShapeMatrices::ShapeType;
121
125 typename LowerOrderShapeMatrixPolicy::ShapeMatrices::ShapeType;
126
129 ShapeFunction, LowerOrderShapeFunction, ShapeMatrix,
131};
132
140template <typename ShapeFunction, typename LowerOrderShapeFunction,
141 int GlobalDim, typename IntegrationMethod>
143 bool const is_axially_symmetric,
144 IntegrationMethod const& integration_method)
145{
146 using Traits =
148 using VecOfNsAndWeight = std::vector<typename Traits::NsAndWeight>;
149
150 VecOfNsAndWeight nss_and_weights;
151 nss_and_weights.reserve(integration_method.getNumberOfPoints());
152
153 auto sms =
155 typename Traits::ShapeMatrixPolicy, GlobalDim,
157 element, is_axially_symmetric, integration_method);
158
159 if constexpr (std::is_same_v<ShapeFunction, LowerOrderShapeFunction>)
160 {
161 static_assert(ShapeFunction::ORDER < 2,
162 "We do not expect higher order shape functions here. "
163 "Something must have gone terribly wrong.");
164
165 for (unsigned ip = 0; ip < sms.size(); ++ip)
166 {
167 auto& sm = sms[ip];
168 double const w =
169 sm.detJ * sm.integralMeasure *
170 integration_method.getWeightedPoint(ip).getWeight();
171
172 nss_and_weights.emplace_back(std::move(sm.N), w);
173 }
174 }
175 else
176 {
177 auto sms_lower = NumLib::initShapeMatrices<
178 LowerOrderShapeFunction,
179 typename Traits::LowerOrderShapeMatrixPolicy, GlobalDim,
180 NumLib::ShapeMatrixType::N>(element, is_axially_symmetric,
181 integration_method);
182
183 for (unsigned ip = 0; ip < sms.size(); ++ip)
184 {
185 auto& sm = sms[ip];
186
187 // Note: we use det(J) of the higher order shape function. For
188 // linear geometries (i.e., higher order elements but with flat
189 // surfaces) there should be no difference.
190 double const w =
191 sm.detJ * sm.integralMeasure *
192 integration_method.getWeightedPoint(ip).getWeight();
193
194 nss_and_weights.emplace_back(std::move(sm.N),
195 std::move(sms_lower[ip].N), w);
196 }
197 }
198
199 return nss_and_weights;
200}
201
202} // namespace ProcessLib::Python
#define OGS_FATAL(...)
Definition Error.h:19
EigenFixedShapeMatrixPolicy< ShapeFunction, GlobalDim > ShapeMatrixPolicyType
std::vector< typename ShapeMatricesType::ShapeMatrices, Eigen::aligned_allocator< typename ShapeMatricesType::ShapeMatrices > > initShapeMatrices(MeshLib::Element const &e, bool const is_axially_symmetric, IntegrationMethod const &integration_method)
@ N_J
calculates N, dNdr, J, and detJ
auto computeNsAndWeights(MeshLib::Element const &element, bool const is_axially_symmetric, IntegrationMethod const &integration_method)
NsAndWeight(ShapeMatrix &&N1, LowerOrderShapeMatrix &&N2, double const weight)
Definition NsAndWeight.h:36
Eigen::Ref< const Eigen::RowVectorXd > N(unsigned order) const
Definition NsAndWeight.h:44
Collects common type aliases needed when working with NsAndWeight.
ProcessLib::BoundaryConditionAndSourceTerm::Python::NsAndWeight< ShapeFunction, LowerOrderShapeFunction, ShapeMatrix, LowerOrderShapeMatrix > NsAndWeight
typename LowerOrderShapeMatrixPolicy::ShapeMatrices::ShapeType LowerOrderShapeMatrix
typename ShapeMatrixPolicy::ShapeMatrices::ShapeType ShapeMatrix
ShapeMatrixPolicyType< LowerOrderShapeFunction, GlobalDim > LowerOrderShapeMatrixPolicy
ShapeMatrixPolicyType< ShapeFunction, GlobalDim > ShapeMatrixPolicy