OGS
SmallDeformationFEM.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 <limits>
7#include <memory>
8#include <optional>
9#include <vector>
10
15#include "NumLib/DOF/LocalDOF.h"
26
27namespace ProcessLib
28{
29namespace SmallDeformation
30{
31namespace MPL = MaterialPropertyLib;
32
33template <typename BMatricesType, typename ShapeMatricesType,
34 int DisplacementDim>
36{
38 typename ShapeMatricesType::NodalRowVectorType N_u;
39 typename ShapeMatricesType::GlobalDimNodalMatrixType dNdx_u;
40
42};
43
46template <typename ShapeMatrixType>
48{
49 std::vector<ShapeMatrixType, Eigen::aligned_allocator<ShapeMatrixType>> N;
50};
51
52template <typename ShapeFunction, int DisplacementDim>
54 : public SmallDeformationLocalAssemblerInterface<DisplacementDim>
55{
56public:
63
70
74 using IpData =
76
77 static constexpr auto& N_u_op = MathLib::eigenBlockMatrixView<
78 DisplacementDim, typename ShapeMatricesType::NodalRowVectorType>;
79
81 delete;
83
85 MeshLib::Element const& e,
86 std::size_t const /*local_matrix_size*/,
87 NumLib::GenericIntegrationMethod const& integration_method,
88 bool const is_axially_symmetric,
91 e, integration_method, is_axially_symmetric, process_data)
92 {
93 unsigned const n_integration_points =
94 this->integration_method_.getNumberOfPoints();
95
96 ip_data_.resize(n_integration_points);
97 secondary_data_.N.resize(n_integration_points);
98
99 auto const shape_matrices =
101 DisplacementDim>(
102 e, is_axially_symmetric, this->integration_method_);
103
104 for (unsigned ip = 0; ip < n_integration_points; ip++)
105 {
106 auto& ip_data = ip_data_[ip];
107 auto const& sm = shape_matrices[ip];
108 ip_data_[ip].integration_weight =
109 this->integration_method_.getWeightedPoint(ip).getWeight() *
110 sm.integralMeasure * sm.detJ;
111
112 ip_data.N_u = sm.N;
113 ip_data.dNdx_u = sm.dNdx;
114
115 secondary_data_.N[ip] = shape_matrices[ip].N;
116 }
117 }
118
119 void initializeConcrete() override
120 {
121 unsigned const n_integration_points =
122 this->integration_method_.getNumberOfPoints();
123 for (unsigned ip = 0; ip < n_integration_points; ip++)
124 {
125 auto const& ip_data = ip_data_[ip];
126
127 ParameterLib::SpatialPosition const x_position{
128 std::nullopt, this->element_.getID(),
132 this->element_, ip_data.N_u))};
133
135 if (this->process_data_.initial_stress != nullptr)
136 {
137 std::get<StressData<DisplacementDim>>(this->current_states_[ip])
138 .sigma.noalias() =
140 DisplacementDim>((*this->process_data_.initial_stress)(
141 std::numeric_limits<
142 double>::quiet_NaN() /* time independent */,
143 x_position));
144 }
145
146 double const t = 0; // TODO (naumov) pass t from top
147 auto& material_state = this->material_states_[ip];
148 this->solid_material_.initializeInternalStateVariables(
149 t, x_position, *material_state.material_state_variables);
150
154
155 material_state.pushBackState();
156 }
157
158 for (unsigned ip = 0; ip < n_integration_points; ip++)
159 {
160 this->prev_states_[ip] = this->current_states_[ip];
161 }
162 }
163
164 void setInitialConditionsConcrete(Eigen::VectorXd const local_x,
165 double const /*t*/,
166 int const /*process_id*/) override
167 {
168 unsigned const n_integration_points =
169 this->integration_method_.getNumberOfPoints();
170 auto const B_dil_bar = getDilatationalBBarMatrix();
171
172 for (unsigned ip = 0; ip < n_integration_points; ip++)
173 {
174 auto const& N = ip_data_[ip].N_u;
175 auto const& dNdx = ip_data_[ip].dNdx_u;
176 ParameterLib::SpatialPosition const x_position{
177 std::nullopt, this->element_.getID(),
181 this->element_, N))};
182
183 auto const x_coord =
184 x_position.getCoordinates().value()[0]; // r for axisymetric
186 DisplacementDim, ShapeFunction::NPOINTS, BBarMatrixType,
188 dNdx, N, B_dil_bar, x_coord, this->is_axially_symmetric_);
189
190 std::get<StrainData<DisplacementDim>>(this->output_data_[ip])
191 .eps.noalias() = B * local_x;
192 }
193 }
194
197 BMatrixType const& B, Eigen::Ref<Eigen::VectorXd const> const& u,
198 Eigen::Ref<Eigen::VectorXd const> const& u_prev,
199 ParameterLib::SpatialPosition const& x_position, double const t,
200 double const dt,
202 CS,
203 MaterialPropertyLib::Medium const& medium,
205 current_state,
207 prev_state,
210 output_data) const
211 {
212 double const T_ref =
213 this->process_data_.reference_temperature
214 ? (*this->process_data_.reference_temperature)(t, x_position)[0]
215 : std::numeric_limits<double>::quiet_NaN();
216
217 auto models =
219 this->process_data_, this->solid_material_);
221 tmp;
223
224 CS.eval(models, t, dt, x_position, //
225 medium, //
226 T_ref, B * u, B * u_prev, //
227 current_state, prev_state, material_state, tmp, output_data,
228 CD);
229
230 return CD;
231 }
232
233 void assemble(double const /*t*/, double const /*dt*/,
234 std::vector<double> const& /*local_x*/,
235 std::vector<double> const& /*local_x_prev*/,
236 std::vector<double>& /*local_M_data*/,
237 std::vector<double>& /*local_K_data*/,
238 std::vector<double>& /*local_b_data*/) override
239 {
240 OGS_FATAL(
241 "SmallDeformationLocalAssembler: assembly without jacobian is not "
242 "implemented.");
243 }
244
245 std::optional<BBarMatrixType> getDilatationalBBarMatrix() const
246 {
247 if (!(this->process_data_.use_b_bar))
248 {
249 return std::nullopt;
250 }
251
253 DisplacementDim, ShapeFunction::NPOINTS, ShapeFunction,
257 }
258
259 void assembleWithJacobian(double const t, double const dt,
260 std::vector<double> const& local_x,
261 std::vector<double> const& local_x_prev,
262 std::vector<double>& local_b_data,
263 std::vector<double>& local_Jac_data) override
264 {
265 auto const local_matrix_size = local_x.size();
266
268 local_Jac_data, local_matrix_size, local_matrix_size);
269
271 local_b_data, local_matrix_size);
272
273 auto [u] = localDOF(local_x);
274 auto [u_prev] = localDOF(local_x_prev);
275
276 unsigned const n_integration_points =
277 this->integration_method_.getNumberOfPoints();
278
281 auto const& medium =
282 *this->process_data_.media_map.getMedium(this->element_.getID());
283
284 auto const B_dil_bar = getDilatationalBBarMatrix();
285
286 for (unsigned ip = 0; ip < n_integration_points; ip++)
287 {
288 auto const& w = ip_data_[ip].integration_weight;
289 auto const& N = ip_data_[ip].N_u;
290 auto const& dNdx = ip_data_[ip].dNdx_u;
291
292 ParameterLib::SpatialPosition const x_position{
293 std::nullopt, this->element_.getID(),
297 this->element_, N))};
298
299 auto const x_coord =
300 x_position.getCoordinates().value()[0]; // r for axisymetric
302 DisplacementDim, ShapeFunction::NPOINTS, BBarMatrixType,
304 dNdx, N, B_dil_bar, x_coord, this->is_axially_symmetric_);
305
306 auto const CD = updateConstitutiveRelations(
307 B, u, u_prev, x_position, t, dt, constitutive_setting, medium,
308 this->current_states_[ip], this->prev_states_[ip],
309 this->material_states_[ip], this->output_data_[ip]);
310
311 auto const& sigma =
312 std::get<StressData<DisplacementDim>>(this->current_states_[ip])
313 .sigma;
314 auto const& b = *std::get<VolumetricBodyForce<DisplacementDim>>(CD);
315 auto const& C =
317 DisplacementDim>>(CD)
318 .stiffness_tensor;
319
320 local_b.noalias() -=
321 (B.transpose() * sigma - N_u_op(N).transpose() * b) * w;
322 local_Jac.noalias() += B.transpose() * C * B * w;
323 }
324 }
325
326 void postTimestepConcrete(Eigen::VectorXd const& local_x,
327 Eigen::VectorXd const& local_x_prev,
328 double const t, double const dt,
329 int const /*process_id*/) override
330 {
331 unsigned const n_integration_points =
332 this->integration_method_.getNumberOfPoints();
333
336
337 auto const& medium =
338 *this->process_data_.media_map.getMedium(this->element_.getID());
339
340 auto const B_dil_bar = getDilatationalBBarMatrix();
341
342 for (unsigned ip = 0; ip < n_integration_points; ip++)
343 {
344 auto const& N = ip_data_[ip].N_u;
345 auto const& dNdx = ip_data_[ip].dNdx_u;
346
347 ParameterLib::SpatialPosition const x_position{
348 std::nullopt, this->element_.getID(),
352 this->element_, N))};
353
354 auto const x_coord =
355 x_position.getCoordinates().value()[0]; // r for axisymetric
357 DisplacementDim, ShapeFunction::NPOINTS, BBarMatrixType,
359 dNdx, N, B_dil_bar, x_coord, this->is_axially_symmetric_);
360
362 B, local_x, local_x_prev, x_position, t, dt,
363 constitutive_setting, medium, this->current_states_[ip],
364 this->prev_states_[ip], this->material_states_[ip],
365 this->output_data_[ip]);
366
367 this->material_states_[ip].pushBackState();
368 }
369
370 for (unsigned ip = 0; ip < n_integration_points; ip++)
371 {
372 this->prev_states_[ip] = this->current_states_[ip];
373 }
374 }
375
376 std::vector<double> const& getMaterialForces(
377 std::vector<double> const& local_x,
378 std::vector<double>& nodal_values) override
379 {
381 DisplacementDim, ShapeFunction, ShapeMatricesType,
384 GradientMatrixType>(local_x, nodal_values,
386 this->current_states_, this->output_data_,
387 this->element_, this->is_axially_symmetric_);
388 }
389
390 Eigen::Map<const Eigen::RowVectorXd> getShapeMatrix(
391 const unsigned integration_point) const override
392 {
393 auto const& N = secondary_data_.N[integration_point];
394
395 // assumes N is stored contiguously in memory
396 return Eigen::Map<const Eigen::RowVectorXd>(N.data(), N.size());
397 }
398
399private:
400 static constexpr auto localDOF(std::vector<double> const& x)
401 {
402 return NumLib::localDOF<
404 }
405
406private:
407 std::vector<IpData, Eigen::aligned_allocator<IpData>> ip_data_;
408
410};
411
412} // namespace SmallDeformation
413} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:19
EigenFixedShapeMatrixPolicy< ShapeFunction, GlobalDim > ShapeMatrixPolicyType
std::optional< MathLib::Point3d > const getCoordinates() const
MatrixType< _kelvin_vector_size, _number_of_dof > BMatrixType
MatrixType< 3, ShapeFunction::NPOINTS > BBarMatrixType
MatrixType< _number_of_dof, _number_of_dof > StiffnessMatrixType
VectorType< _number_of_dof > NodalForceVectorType
Rhs residual.
VectorTypeFixedSize< MathLib::VectorizedTensor::size(DisplacementDim)> GradientVectorType
MatrixType< MathLib::VectorizedTensor::size(DisplacementDim), _number_of_dof > GradientMatrixType
typename BMatricesType::NodalForceVectorType NodalForceVectorType
typename ShapeMatricesType::NodalVectorType NodalVectorType
void assembleWithJacobian(double const t, double const dt, std::vector< double > const &local_x, std::vector< double > const &local_x_prev, std::vector< double > &local_b_data, std::vector< double > &local_Jac_data) override
ConstitutiveRelations::ConstitutiveData< DisplacementDim > updateConstitutiveRelations(BMatrixType const &B, Eigen::Ref< Eigen::VectorXd const > const &u, Eigen::Ref< Eigen::VectorXd const > const &u_prev, ParameterLib::SpatialPosition const &x_position, double const t, double const dt, typename ConstitutiveRelations::ConstitutiveSetting< DisplacementDim > &CS, MaterialPropertyLib::Medium const &medium, typename ConstitutiveRelations::StatefulData< DisplacementDim > &current_state, typename ConstitutiveRelations::StatefulDataPrev< DisplacementDim > const &prev_state, MaterialStateData< DisplacementDim > &material_state, typename ConstitutiveRelations::OutputData< DisplacementDim > &output_data) const
Eigen::Map< const Eigen::RowVectorXd > getShapeMatrix(const unsigned integration_point) const override
Provides the shape matrix at the given integration point.
GMatrixPolicyType< ShapeFunction, DisplacementDim > GMatricesType
std::optional< BBarMatrixType > getDilatationalBBarMatrix() const
typename BMatricesType::NodalForceVectorType NodalDisplacementVectorType
typename ShapeMatricesType::ShapeMatrices ShapeMatrices
void postTimestepConcrete(Eigen::VectorXd const &local_x, Eigen::VectorXd const &local_x_prev, double const t, double const dt, int const) override
typename ShapeMatricesType::NodalMatrixType NodalMatrixType
void setInitialConditionsConcrete(Eigen::VectorXd const local_x, double const, int const) override
BMatrixPolicyType< ShapeFunction, DisplacementDim > BMatricesType
SecondaryData< typename ShapeMatrices::ShapeType > secondary_data_
typename GMatricesType::GradientMatrixType GradientMatrixType
ShapeMatrixPolicyType< ShapeFunction, DisplacementDim > ShapeMatricesType
std::vector< double > const & getMaterialForces(std::vector< double > const &local_x, std::vector< double > &nodal_values) override
typename BMatricesType::StiffnessMatrixType StiffnessMatrixType
SmallDeformationLocalAssembler(SmallDeformationLocalAssembler &&)=delete
static constexpr auto localDOF(std::vector< double > const &x)
typename GMatricesType::GradientVectorType GradientVectorType
std::vector< IpData, Eigen::aligned_allocator< IpData > > ip_data_
void assemble(double const, double const, std::vector< double > const &, std::vector< double > const &, std::vector< double > &, std::vector< double > &, std::vector< double > &) override
SmallDeformationLocalAssembler(MeshLib::Element const &e, std::size_t const, NumLib::GenericIntegrationMethod const &integration_method, bool const is_axially_symmetric, SmallDeformationProcessData< DisplacementDim > &process_data)
SmallDeformationLocalAssembler(SmallDeformationLocalAssembler const &)=delete
IntegrationPointData< BMatricesType, ShapeMatricesType, DisplacementDim > IpData
Eigen::Matrix< double, Eigen::MatrixBase< Derived >::RowsAtCompileTime, 1 > symmetricTensorToKelvinVector(Eigen::MatrixBase< Derived > const &v)
constexpr Eigen::CwiseNullaryOp< EigenBlockMatrixViewFunctor< D, M >, typename EigenBlockMatrixViewFunctor< D, M >::Matrix > eigenBlockMatrixView(const Eigen::MatrixBase< M > &matrix)
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)
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)
auto localDOF(ElementDOFVector const &x)
Definition LocalDOF.h:56
std::array< double, 3 > interpolateCoordinates(MeshLib::Element const &e, typename ShapeMatricesType::ShapeMatrices::ShapeType const &N)
BBarMatrixType computeDilatationalBbar(std::vector< IpData, Eigen::aligned_allocator< IpData > > const &ip_data, MeshLib::Element const &element, NumLib::GenericIntegrationMethod const &integration_method, const bool is_axially_symmetric)
BMatrixType computeBMatrixPossiblyWithBbar(DNDX_Type const &dNdx, N_Type const &N, std::optional< BBarMatrixType > const &B_dil_bar, const double radius, const bool is_axially_symmetric)
Fills a B matrix, or a B bar matrix if required.
ProcessLib::ConstitutiveRelations::PrevStateOf< StatefulData< DisplacementDim > > StatefulDataPrev
std::tuple< StressData< DisplacementDim > > StatefulData
Data whose state must be tracked by the process.
std::tuple< SolidMechanicsDataStateless< DisplacementDim >, VolumetricBodyForce< DisplacementDim > > ConstitutiveData
Data that is needed for the equation system assembly.
std::tuple< StrainData< DisplacementDim >, FreeEnergyDensityData > OutputData
Data that is needed for output purposes, but not directly for the assembly.
ConstitutiveModels< DisplacementDim > createConstitutiveModels(SDProcessData const &process_data, SolidConstitutiveRelation< DisplacementDim > const &solid_material)
std::tuple< PrevState< StrainData< DisplacementDim > >, SolidDensity > ConstitutiveTempData
std::vector< double > const & getMaterialForces(std::vector< double > const &local_x, std::vector< double > &nodal_values, IntegrationMethod const &integration_method, IPData const &ip_data, StressData const &stress_data, OutputData const &output_data, MeshLib::Element const &element, bool const is_axially_symmetric)
NumLib::ShapeMatrices< NodalRowVectorType, DimNodalMatrixType, DimMatrixType, GlobalDimNodalMatrixType > ShapeMatrices
MatrixType< ShapeFunction::NPOINTS, ShapeFunction::NPOINTS > NodalMatrixType
VectorType< ShapeFunction::NPOINTS > NodalVectorType
RowVectorType< ShapeFunction::NPOINTS > NodalRowVectorType
void eval(ConstitutiveModels< DisplacementDim > &models, double const t, double const dt, ParameterLib::SpatialPosition const &x_position, MaterialPropertyLib::Medium const &medium, double const T_ref, KelvinVector< DisplacementDim > const &eps, KelvinVector< DisplacementDim > const &eps_prev, StatefulData< DisplacementDim > &state, StatefulDataPrev< DisplacementDim > const &prev_state, MaterialStateData< DisplacementDim > &mat_state, ConstitutiveTempData< DisplacementDim > &tmp, OutputData< DisplacementDim > &out, ConstitutiveData< DisplacementDim > &cd) const
Evaluate the constitutive setting.
ShapeMatricesType::GlobalDimNodalMatrixType dNdx_u
std::vector< ShapeMatrixType, Eigen::aligned_allocator< ShapeMatrixType > > N
ConstitutiveRelations::ConstitutiveSetting< DisplacementDim > constitutive_setting
std::vector< typename ConstitutiveRelations::StatefulDataPrev< DisplacementDim > > prev_states_
std::vector< typename ConstitutiveRelations::StatefulData< DisplacementDim > > current_states_
std::vector< typename ConstitutiveRelations::OutputData< DisplacementDim > > output_data_
SmallDeformationLocalAssemblerInterface(MeshLib::Element const &e, NumLib::GenericIntegrationMethod const &integration_method, bool const is_axially_symmetric, SmallDeformationProcessData< DisplacementDim > &process_data)
MaterialLib::Solids::MechanicsBase< DisplacementDim > const & solid_material_