Loading [MathJax]/extensions/tex2jax.js
OGS
StokesFlowFEM.h
Go to the documentation of this file.
1
11#pragma once
12
13#include <Eigen/LU>
14#include <vector>
15
28
30{
31template <typename ShapeFunctionLiquidVelocity, typename ShapeFunctionPressure,
32 int GlobalDim>
34{
35 static const int liquid_velocity_index = 0;
36 static const int pressure_index =
37 ShapeFunctionLiquidVelocity::NPOINTS * GlobalDim;
38
39 static const int liquid_velocity_size =
40 ShapeFunctionLiquidVelocity::NPOINTS * GlobalDim;
41 static const int pressure_size = ShapeFunctionPressure::NPOINTS;
42
47
49
50public:
52 MeshLib::Element const& element,
53 std::size_t const /*local_matrix_size*/,
54 NumLib::GenericIntegrationMethod const& integration_method,
55 bool const is_axially_symmetric,
56 StokesFlowProcessData const& process_data)
57 : _element(element),
58 _is_axially_symmetric(is_axially_symmetric),
59 _integration_method(integration_method),
60 _process_data(process_data)
61 {
62 unsigned const n_integration_points =
64 _ip_data.reserve(n_integration_points);
65
66 auto const shape_matrices_v =
67 NumLib::initShapeMatrices<ShapeFunctionLiquidVelocity,
69 element, is_axially_symmetric, _integration_method);
70
71 auto const shape_matrices_p =
72 NumLib::initShapeMatrices<ShapeFunctionPressure,
73 ShapeMatrixTypePressure, GlobalDim>(
74 element, is_axially_symmetric, _integration_method);
75
76 for (unsigned ip = 0; ip < n_integration_points; ip++)
77 {
78 _ip_data.emplace_back(
79 shape_matrices_v[ip].N, shape_matrices_v[ip].dNdx,
80 shape_matrices_p[ip].N, shape_matrices_p[ip].dNdx,
82 shape_matrices_v[ip].integralMeasure *
83 shape_matrices_v[ip].detJ);
84
85 auto& ip_data = _ip_data[ip];
86
87 ip_data.N_v_op = ShapeMatrixTypeLiquidVelocity::template MatrixType<
88 GlobalDim, liquid_velocity_size>::Zero(GlobalDim,
90
91 ip_data.dNdx_v_op =
92 ShapeMatrixTypeLiquidVelocity::template MatrixType<
93 GlobalDim * GlobalDim,
94 liquid_velocity_size>::Zero(GlobalDim * GlobalDim,
96
97 for (int i = 0; i < GlobalDim; ++i)
98 {
99 ip_data.N_v_op
100 .template block<1, liquid_velocity_size / GlobalDim>(
101 i, i * liquid_velocity_size / GlobalDim)
102 .noalias() = shape_matrices_v[ip].N;
103
104 ip_data.dNdx_v_op
105 .template block<GlobalDim,
106 liquid_velocity_size / GlobalDim>(
107 i * GlobalDim, i * liquid_velocity_size / GlobalDim)
108 .noalias() = shape_matrices_v[ip].dNdx;
109 }
110 }
111 }
112
113 void assemble(double const t, double const dt,
114 std::vector<double> const& local_x,
115 std::vector<double> const& /*local_x_prev*/,
116 std::vector<double>& /*local_M_data*/,
117 std::vector<double>& local_K_data,
118 std::vector<double>& local_b_data) override
119 {
120 auto const local_matrix_size = liquid_velocity_size + pressure_size;
121 assert(local_x.size() == local_matrix_size);
122
123 auto local_p = Eigen::Map<const NodalVectorType>(
124 &local_x[pressure_index], pressure_size);
125
126 auto local_K = MathLib::createZeroedMatrix<
127 typename ShapeMatrixTypeLiquidVelocity::template MatrixType<
128 local_matrix_size, local_matrix_size>>(
129 local_K_data, local_matrix_size, local_matrix_size);
130 auto local_b = MathLib::createZeroedVector<
131 typename ShapeMatrixTypeLiquidVelocity::template VectorType<
132 local_matrix_size>>(local_b_data, local_matrix_size);
133
134 // Get block matrices
135 // Kvv
136 auto Kvv =
137 local_K.template block<liquid_velocity_size, liquid_velocity_size>(
139 // Kvp
140 auto Kvp = local_K.template block<liquid_velocity_size, pressure_size>(
142 // kpv
143 auto Kpv = local_K.template block<pressure_size, liquid_velocity_size>(
145 // bv
146 auto bv = local_b.template segment<liquid_velocity_size>(
148
149 unsigned const n_integration_points =
151
154
155 auto const& b = _process_data.specific_body_force;
156
158
159 // create unit vector
160 assert(GlobalDim == 2);
161 auto const identity_mat =
162 Eigen::Matrix<double, GlobalDim, GlobalDim>::Identity().eval();
163 auto const unit_vector = Eigen::Map<const Eigen::RowVectorXd>(
164 identity_mat.data(), identity_mat.size())
165 .eval();
166
167 // Get material properties
168 auto const& medium =
170 auto const& phase = medium.phase("AqueousLiquid");
171
172 for (unsigned ip(0); ip < n_integration_points; ++ip)
173 {
174 auto const& ip_data = _ip_data[ip];
175
176 auto const& N_p = ip_data.N_p;
177 auto const& N_v_op = ip_data.N_v_op;
178
179 auto const& dNdx_v = ip_data.dNdx_v;
180 auto const& dNdx_v_op = ip_data.dNdx_v_op;
181 auto const& dNdx_p = ip_data.dNdx_p;
182
183 auto const& w = ip_data.integration_weight;
184
185 double p_int_pt = 0.0;
186
187 NumLib::shapeFunctionInterpolate(local_p, N_p, p_int_pt);
188
189 vars.liquid_phase_pressure = p_int_pt;
190
191 // Use the viscosity model to compute the viscosity
193 .template value<double>(vars, pos, t, dt);
194
195 // Kvv
197 {
198 // permeability
201 .value(vars, pos, t, dt));
202
203 Kvv.noalias() +=
204 w * N_v_op.transpose() * mu * K.inverse() * N_v_op;
205 }
206
207 for (int i = 0; i < GlobalDim; ++i)
208 {
209 Kvv.template block<liquid_velocity_size / GlobalDim,
210 liquid_velocity_size / GlobalDim>(
211 i * liquid_velocity_size / GlobalDim,
212 i * liquid_velocity_size / GlobalDim)
213 .noalias() += w * dNdx_v.transpose() * mu * dNdx_v;
214 }
215
216 // Kvp
217 Kvp.noalias() += w * N_v_op.transpose() * dNdx_p;
218
219 // Kpv
220 Kpv.noalias() += w * N_p.transpose() * unit_vector * dNdx_v_op;
221
222 // bv
223 bv.noalias() += w * N_v_op.transpose() * b;
224 }
225 }
226
227 Eigen::Map<const Eigen::RowVectorXd> getShapeMatrix(
228 const unsigned integration_point) const override
229 {
230 auto const& N_p = _ip_data[integration_point].N_p;
231
232 // assumes N_p is stored contiguously in memory
233 return Eigen::Map<const Eigen::RowVectorXd>(N_p.data(), N_p.size());
234 }
235
237 double const /*t*/,
238 double const /*dt*/,
239 Eigen::VectorXd const& local_x,
240 Eigen::VectorXd const& /*local_x_prev*/) override
241 {
242 auto const local_p =
243 local_x.template segment<pressure_size>(pressure_index);
244
246 ShapeFunctionPressure,
247 typename ShapeFunctionLiquidVelocity::MeshElement, GlobalDim>(
250 }
251
252private:
257
259 ShapeMatrixTypePressure, GlobalDim,
260 ShapeFunctionLiquidVelocity::NPOINTS>,
261 Eigen::aligned_allocator<IntegrationPointData<
263 GlobalDim, ShapeFunctionLiquidVelocity::NPOINTS>>>
265};
266
267} // namespace ProcessLib::StokesFlow
Phase const & phase(std::size_t index) const
Definition Medium.cpp:33
constexpr double getWeight() const
std::size_t getID() const
Returns the ID of the element.
Definition Element.h:89
MathLib::WeightedPoint const & getWeightedPoint(unsigned const igp) const
void setElementID(std::size_t element_id)
void computeSecondaryVariableConcrete(double const, double const, Eigen::VectorXd const &local_x, Eigen::VectorXd const &) override
ShapeMatrixPolicyType< ShapeFunctionLiquidVelocity, GlobalDim > ShapeMatrixTypeLiquidVelocity
void assemble(double const t, double const dt, std::vector< double > const &local_x, std::vector< double > const &, std::vector< double > &, std::vector< double > &local_K_data, std::vector< double > &local_b_data) override
StokesFlowProcessData const & _process_data
LocalAssemblerData(MeshLib::Element const &element, std::size_t const, NumLib::GenericIntegrationMethod const &integration_method, bool const is_axially_symmetric, StokesFlowProcessData const &process_data)
NumLib::GenericIntegrationMethod const & _integration_method
Eigen::Map< const Eigen::RowVectorXd > getShapeMatrix(const unsigned integration_point) const override
Provides the shape matrix at the given integration point.
typename ShapeMatrixTypePressure::NodalVectorType NodalVectorType
std::vector< IntegrationPointData< ShapeMatrixTypeLiquidVelocity, ShapeMatrixTypePressure, GlobalDim, ShapeFunctionLiquidVelocity::NPOINTS >, Eigen::aligned_allocator< IntegrationPointData< ShapeMatrixTypeLiquidVelocity, ShapeMatrixTypePressure, GlobalDim, ShapeFunctionLiquidVelocity::NPOINTS > > > _ip_data
ShapeMatrixPolicyType< ShapeFunctionPressure, GlobalDim > ShapeMatrixTypePressure
Eigen::Matrix< double, GlobalDim, GlobalDim > formEigenTensor(MaterialPropertyLib::PropertyDataType const &values)
Eigen::Map< Vector > createZeroedVector(std::vector< double > &data, Eigen::VectorXd::Index size)
Eigen::Map< Matrix > createZeroedMatrix(std::vector< double > &data, Eigen::MatrixXd::Index rows, Eigen::MatrixXd::Index cols)
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 > > initShapeMatrices(MeshLib::Element const &e, bool const is_axially_symmetric, IntegrationMethod const &integration_method)
VectorType< ShapeFunction::NPOINTS > NodalVectorType
Eigen::VectorXd const specific_body_force
an external force that applies in the bulk of the fluid, like gravity.
MaterialPropertyLib::MaterialSpatialDistributionMap media_map
MeshLib::PropertyVector< double > * pressure_interpolated