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