Loading [MathJax]/extensions/tex2jax.js
OGS
WellboreSimulatorFEM.h
Go to the documentation of this file.
1
11#pragma once
12
13#include <Eigen/Dense>
14#include <numeric>
15#include <vector>
16
30
31namespace ProcessLib
32{
33namespace WellboreSimulator
34{
35const unsigned NUM_NODAL_DOF = 3;
36
37template <typename ShapeFunction, int GlobalDim>
39{
42
43 using LocalMatrixType = typename ShapeMatricesType::template MatrixType<
44 NUM_NODAL_DOF * ShapeFunction::NPOINTS,
45 NUM_NODAL_DOF * ShapeFunction::NPOINTS>;
47 typename ShapeMatricesType::template VectorType<NUM_NODAL_DOF *
48 ShapeFunction::NPOINTS>;
49
52
57
58public:
60 MeshLib::Element const& element,
61 std::size_t const /*local_matrix_size*/,
62 NumLib::GenericIntegrationMethod const& integration_method,
63 bool const is_axially_symmetric,
64 WellboreSimulatorProcessData const& process_data)
65 : _element(element),
66 _integration_method(integration_method),
67 _is_axially_symmetric(is_axially_symmetric),
68 _process_data(process_data)
69 {
70 // calculate the element direction vector
71 auto const& p0 = element.getNode(0)->asEigenVector3d();
72 auto const& p1 = element.getNode(1)->asEigenVector3d();
73
74 _element_direction = (p1 - p0).normalized();
75
76 unsigned const n_integration_points =
78 _ip_data.reserve(n_integration_points);
79
80 auto const shape_matrices =
82 GlobalDim>(element, is_axially_symmetric,
84
87 auto const& medium =
89 auto const& liquid_phase = medium.phase("AqueousLiquid");
90
91 for (unsigned ip = 0; ip < n_integration_points; ip++)
92 {
93 _ip_data.emplace_back(
94 shape_matrices[ip].N, shape_matrices[ip].dNdx,
96 shape_matrices[ip].integralMeasure *
97 shape_matrices[ip].detJ);
98
100
101 NodalVectorType ref_p =
103 _element, 0);
104 NodalVectorType ref_h =
106 _element, 0);
107
108 vars.liquid_phase_pressure = _ip_data[ip].N.dot(ref_p);
109 vars.enthalpy = _ip_data[ip].N.dot(ref_h);
110
111 // .initialValue
112 _ip_data[ip].temperature =
113 liquid_phase
115 .template value<double>(vars, pos, 0, 0);
116 vars.temperature = _ip_data[ip].temperature;
117 _ip_data[ip].mix_density =
118 liquid_phase
120 .template value<double>(vars, pos, 0, 0);
121 _ip_data[ip].dryness = 0;
122 _ip_data[ip].vapor_volume_fraction = 0;
123 _ip_data[ip].vapor_mass_flow_rate = 0;
124 _ip_data[ip].liquid_mass_flow_rate = 0;
125 _ip_data[ip].pushBackState();
126 }
127 }
128
129 void assemble(double const t, double const dt,
130 std::vector<double> const& local_x,
131 std::vector<double> const& local_x_prev,
132 std::vector<double>& local_M_data,
133 std::vector<double>& local_K_data,
134 std::vector<double>& local_b_data) override;
135
136 static int const jacobian_residual_size = 1;
137 using ResidualVector = Eigen::Matrix<double, jacobian_residual_size, 1>;
139 Eigen::Matrix<double, jacobian_residual_size, jacobian_residual_size,
140 Eigen::RowMajor>;
141 using UnknownVector = Eigen::Matrix<double, jacobian_residual_size, 1>;
142
143 void calculateResidual(double const alpha, double const vapor_water_density,
144 double const liquid_water_density,
145 double const v_mix, double const dryness,
146 double const C_0, double const u_gu,
147 ResidualVector& res)
148 {
149 double const rho_mix =
150 alpha * vapor_water_density + (1 - alpha) * liquid_water_density;
151
152 res(0) =
153 dryness * liquid_water_density * rho_mix * v_mix -
154 alpha * C_0 * dryness * liquid_water_density * rho_mix * v_mix -
155 alpha * C_0 * (1 - dryness) * vapor_water_density * rho_mix *
156 v_mix -
157 alpha * vapor_water_density * liquid_water_density * u_gu;
158 }
159
160 void calculateJacobian(double const alpha, double const vapor_water_density,
161 double const liquid_water_density,
162 double const v_mix, double const dryness,
163 double const C_0, double const u_gu,
164 JacobianMatrix& Jac)
165 {
166 Jac(0) = dryness * liquid_water_density * v_mix *
167 (vapor_water_density - liquid_water_density) -
168 (C_0 * dryness * liquid_water_density +
169 C_0 * (1 - dryness) * vapor_water_density) *
170 (2 * alpha * vapor_water_density +
171 (1 - 2 * alpha) * liquid_water_density) *
172 v_mix -
173 vapor_water_density * liquid_water_density * u_gu;
174 }
175
176 Eigen::Map<const Eigen::RowVectorXd> getShapeMatrix(
177 const unsigned integration_point) const override
178 {
179 auto const& N = _ip_data[integration_point].N;
180
181 // assumes N is stored contiguously in memory
182 return Eigen::Map<const Eigen::RowVectorXd>(N.data(), N.size());
183 }
184
186 double const /*t*/,
187 double const /*dt*/,
188 Eigen::VectorXd const& /*local_x*/,
189 Eigen::VectorXd const& /*local_x_dot*/) override
190 {
191 auto const n_integration_points =
193 auto const ele_id = _element.getID();
194
196 std::accumulate(_ip_data.begin(), _ip_data.end(), 0.,
197 [](double const s, auto const& ip)
198 { return s + ip.mix_density; }) /
199 n_integration_points;
200 }
201
202 void postTimestepConcrete(Eigen::VectorXd const& /*local_x*/,
203 Eigen::VectorXd const& /*local_x_dot*/,
204 double const /*t*/, double const /*dt*/,
205 int const /*process_id*/) override
206 {
207 unsigned const n_integration_points =
209
210 for (unsigned ip = 0; ip < n_integration_points; ip++)
211 {
212 _ip_data[ip].pushBackState();
213 }
214 }
215
216protected:
217 virtual std::vector<double> const& getIntPtVaporMassFlowRate(
218 const double /*t*/,
219 std::vector<GlobalVector*> const& /*x*/,
220 std::vector<NumLib::LocalToGlobalIndexMap const*> const& /*dof_table*/,
221 std::vector<double>& cache) const override
222 {
225 }
226
227 virtual std::vector<double> const& getIntPtLiquidMassFlowRate(
228 const double /*t*/,
229 std::vector<GlobalVector*> const& /*x*/,
230 std::vector<NumLib::LocalToGlobalIndexMap const*> const& /*dof_table*/,
231 std::vector<double>& cache) const override
232 {
235 }
236
237 virtual std::vector<double> const& getIntPtTemperature(
238 const double /*t*/,
239 std::vector<GlobalVector*> const& /*x*/,
240 std::vector<NumLib::LocalToGlobalIndexMap const*> const& /*dof_table*/,
241 std::vector<double>& cache) const override
242 {
245 }
246
247 virtual std::vector<double> const& getIntPtDryness(
248 const double /*t*/,
249 std::vector<GlobalVector*> const& /*x*/,
250 std::vector<NumLib::LocalToGlobalIndexMap const*> const& /*dof_table*/,
251 std::vector<double>& cache) const override
252 {
254 _ip_data, &IpData::dryness, cache);
255 }
256
257 virtual std::vector<double> const& getIntPtVaporVolumeFraction(
258 const double /*t*/,
259 std::vector<GlobalVector*> const& /*x*/,
260 std::vector<NumLib::LocalToGlobalIndexMap const*> const& /*dof_table*/,
261 std::vector<double>& cache) const override
262 {
265 }
266
271
272 Eigen::Vector3d _element_direction;
273
274 using IpData =
276 std::vector<IpData, Eigen::aligned_allocator<IpData>> _ip_data;
277
278protected:
279 static const int pressure_index = 0;
280 static const int velocity_index = ShapeFunction::NPOINTS;
281 static const int enthalpy_index = 2 * ShapeFunction::NPOINTS;
282
283 static const int pressure_size = ShapeFunction::NPOINTS;
284 static const int velocity_size = ShapeFunction::NPOINTS;
285 static const int enthalpy_size = ShapeFunction::NPOINTS;
286};
287
288} // namespace WellboreSimulator
289} // namespace ProcessLib
290
Phase const & phase(std::size_t index) const
Definition Medium.cpp:33
constexpr double getWeight() const
virtual const Node * getNode(unsigned idx) const =0
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)
virtual std::vector< double > const & getIntPtVaporVolumeFraction(const double, std::vector< GlobalVector * > const &, std::vector< NumLib::LocalToGlobalIndexMap const * > const &, std::vector< double > &cache) const override
virtual std::vector< double > const & getIntPtTemperature(const double, std::vector< GlobalVector * > const &, std::vector< NumLib::LocalToGlobalIndexMap const * > const &, std::vector< double > &cache) const override
typename ShapeMatricesType::NodalVectorType NodalVectorType
WellboreSimulatorFEM(MeshLib::Element const &element, std::size_t const, NumLib::GenericIntegrationMethod const &integration_method, bool const is_axially_symmetric, WellboreSimulatorProcessData const &process_data)
typename ShapeMatricesType::template MatrixType< NUM_NODAL_DOF *ShapeFunction::NPOINTS, NUM_NODAL_DOF *ShapeFunction::NPOINTS > LocalMatrixType
Eigen::Matrix< double, jacobian_residual_size, 1 > UnknownVector
typename ShapeMatricesType::GlobalDimMatrixType GlobalDimMatrixType
typename ShapeMatricesType::GlobalDimNodalMatrixType GlobalDimNodalMatrixType
void calculateJacobian(double const alpha, double const vapor_water_density, double const liquid_water_density, double const v_mix, double const dryness, double const C_0, double const u_gu, JacobianMatrix &Jac)
Eigen::Matrix< double, jacobian_residual_size, 1 > ResidualVector
NumLib::GenericIntegrationMethod const & _integration_method
Eigen::Matrix< double, jacobian_residual_size, jacobian_residual_size, Eigen::RowMajor > JacobianMatrix
typename ShapeMatricesType::ShapeMatrices ShapeMatrices
Eigen::Map< const Eigen::RowVectorXd > getShapeMatrix(const unsigned integration_point) const override
Provides the shape matrix at the given integration point.
ShapeMatrixPolicyType< ShapeFunction, GlobalDim > ShapeMatricesType
typename ShapeMatricesType::NodalRowVectorType NodalRowVectorType
typename ShapeMatricesType::GlobalDimVectorType GlobalDimVectorType
virtual std::vector< double > const & getIntPtLiquidMassFlowRate(const double, std::vector< GlobalVector * > const &, std::vector< NumLib::LocalToGlobalIndexMap const * > const &, std::vector< double > &cache) const override
typename ShapeMatricesType::template VectorType< NUM_NODAL_DOF * ShapeFunction::NPOINTS > LocalVectorType
void assemble(double const t, double const dt, std::vector< double > const &local_x, std::vector< double > const &local_x_prev, std::vector< double > &local_M_data, std::vector< double > &local_K_data, std::vector< double > &local_b_data) override
void postTimestepConcrete(Eigen::VectorXd const &, Eigen::VectorXd const &, double const, double const, int const) override
void computeSecondaryVariableConcrete(double const, double const, Eigen::VectorXd const &, Eigen::VectorXd const &) override
void calculateResidual(double const alpha, double const vapor_water_density, double const liquid_water_density, double const v_mix, double const dryness, double const C_0, double const u_gu, ResidualVector &res)
virtual std::vector< double > const & getIntPtDryness(const double, std::vector< GlobalVector * > const &, std::vector< NumLib::LocalToGlobalIndexMap const * > const &, std::vector< double > &cache) const override
virtual std::vector< double > const & getIntPtVaporMassFlowRate(const double, std::vector< GlobalVector * > const &, std::vector< NumLib::LocalToGlobalIndexMap const * > const &, std::vector< double > &cache) const override
std::vector< IpData, Eigen::aligned_allocator< IpData > > _ip_data
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)
std::vector< double > const & getIntegrationPointScalarData(IntegrationPointDataVector const &ip_data_vector, MemberType IpData::*const member, std::vector< double > &cache)
NumLib::ShapeMatrices< NodalRowVectorType, DimNodalMatrixType, DimMatrixType, GlobalDimNodalMatrixType > ShapeMatrices
MatrixType< GlobalDim, ShapeFunction::NPOINTS > GlobalDimNodalMatrixType
MatrixType< GlobalDim, GlobalDim > GlobalDimMatrixType
VectorType< GlobalDim > GlobalDimVectorType
VectorType< ShapeFunction::NPOINTS > NodalVectorType
RowVectorType< ShapeFunction::NPOINTS > NodalRowVectorType
virtual Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > getNodalValuesOnElement(MeshLib::Element const &element, double const t) const
Returns a matrix of values for all nodes of the given element.
Definition Parameter.h:164
MaterialPropertyLib::MaterialSpatialDistributionMap media_map