OGS
LargeDeformationFEM.h
Go to the documentation of this file.
1
11#pragma once
12
13#include <limits>
14#include <memory>
15#include <vector>
16
23#include "NumLib/DOF/LocalDOF.h"
36
37namespace ProcessLib
38{
39namespace LargeDeformation
40{
41namespace MPL = MaterialPropertyLib;
42
45template <typename ShapeMatrixType>
47{
48 std::vector<ShapeMatrixType, Eigen::aligned_allocator<ShapeMatrixType>> N;
49};
50
51template <int DisplacementDim, typename ShapeMatricesType>
52Eigen::Matrix<double, MPL::tensorSize(DisplacementDim),
53 MPL::tensorSize(DisplacementDim)>
54computeSigmaGeom(Eigen::Matrix3d const& sigma_tensor)
55{
56 static constexpr auto& sigma_geom_op = MathLib::eigenBlockMatrixView<
57 DisplacementDim,
58 Eigen::Matrix<double, DisplacementDim, DisplacementDim>>;
59
60 using SigmaGeom = Eigen::Matrix<double, MPL::tensorSize(DisplacementDim),
61 MPL::tensorSize(DisplacementDim)>;
62 if constexpr (DisplacementDim == 2)
63 {
64 SigmaGeom sigma_geom = SigmaGeom::Zero(5, 5);
65 sigma_geom.template block<4, 4>(0, 0) =
66 sigma_geom_op(sigma_tensor.template block<2, 2>(0, 0).eval());
67 sigma_geom(4, 4) = sigma_tensor(2, 2);
68
69 return sigma_geom;
70 }
71
72 if constexpr (DisplacementDim == 3)
73 {
74 return sigma_geom_op(sigma_tensor);
75 }
76}
77
78template <typename ShapeFunction, int DisplacementDim>
80 : public LargeDeformationLocalAssemblerInterface<DisplacementDim>
81{
82public:
89
95
99 using IpData =
101
102 static constexpr auto& N_u_op = MathLib::eigenBlockMatrixView<
103 DisplacementDim, typename ShapeMatricesType::NodalRowVectorType>;
104
106 delete;
108
110 MeshLib::Element const& e,
111 std::size_t const /*local_matrix_size*/,
112 NumLib::GenericIntegrationMethod const& integration_method,
113 bool const is_axially_symmetric,
116 e, integration_method, is_axially_symmetric, process_data)
117 {
118 unsigned const n_integration_points =
120
121 _ip_data.resize(n_integration_points);
122 _secondary_data.N.resize(n_integration_points);
123
124 auto const shape_matrices =
126 DisplacementDim>(
127 e, is_axially_symmetric, this->integration_method_);
128
129 for (unsigned ip = 0; ip < n_integration_points; ip++)
130 {
131 auto& ip_data = _ip_data[ip];
132 auto const& sm = shape_matrices[ip];
133 _ip_data[ip].integration_weight =
135 sm.integralMeasure * sm.detJ;
136
137 ip_data.N = sm.N;
138 ip_data.dNdx = sm.dNdx;
139
140 _secondary_data.N[ip] = shape_matrices[ip].N;
141 }
142 }
143
144 void initializeConcrete() override
145 {
146 unsigned const n_integration_points =
148 for (unsigned ip = 0; ip < n_integration_points; ip++)
149 {
150 auto const& ip_data = _ip_data[ip];
151
152 ParameterLib::SpatialPosition const x_position{
153 std::nullopt, this->element_.getID(), ip,
155 NumLib::interpolateCoordinates<ShapeFunction,
157 this->element_, ip_data.N))};
158
160 if (this->process_data_.initial_stress != nullptr)
161 {
162 this->current_states_[ip].stress_data.sigma.noalias() =
164 DisplacementDim>((*this->process_data_.initial_stress)(
165 std::numeric_limits<
166 double>::quiet_NaN() /* time independent */,
167 x_position));
168 }
169
170 double const t = 0; // TODO (naumov) pass t from top
171 auto& material_state = this->material_states_[ip];
172 this->solid_material_.initializeInternalStateVariables(
173 t, x_position, *material_state.material_state_variables);
174
175 material_state.pushBackState();
176 this->prev_states_[ip] = this->current_states_[ip];
177 }
178 }
179
182 Eigen::Ref<Eigen::VectorXd const> const& u,
183 Eigen::Ref<Eigen::VectorXd const> const& u_prev,
184 ParameterLib::SpatialPosition const& x_position, double const t,
185 double const dt,
187 ip_data,
189 CS,
190 MaterialPropertyLib::Medium const& medium,
192 current_state,
194 prev_state,
197 output_data) const
198 {
199 auto const& N = ip_data.N;
200 auto const& dNdx = ip_data.dNdx;
201 auto const x_coord =
202 NumLib::interpolateXCoordinate<ShapeFunction, ShapeMatricesType>(
203 this->element_, N);
204
205 // For the 2D case the 33-component is needed (and the four entries
206 // of the non-symmetric matrix); In 3d there are nine entries.
208 DisplacementDim * DisplacementDim + (DisplacementDim == 2 ? 1 : 0),
209 ShapeFunction::NPOINTS * DisplacementDim);
210 Deformation::computeGMatrix<DisplacementDim, ShapeFunction::NPOINTS>(
211 dNdx, G, this->is_axially_symmetric_, N, x_coord);
212
213 GradientVectorType const grad_u = G * u;
214
215 auto const B_0 =
216 LinearBMatrix::computeBMatrix<DisplacementDim,
217 ShapeFunction::NPOINTS,
219 dNdx, N, x_coord, this->is_axially_symmetric_);
220
221 auto const B_N = NonLinearBMatrix::computeBMatrix<
222 DisplacementDim, ShapeFunction::NPOINTS,
223 typename BMatricesType::BMatrixType>(dNdx, N, grad_u, x_coord,
225
226 auto const B = B_0 + 0.5 * B_N; // For Green-Lagrange strain.
227
228 double const T_ref =
229 this->process_data_.reference_temperature
230 ? (*this->process_data_.reference_temperature)(t, x_position)[0]
231 : std::numeric_limits<double>::quiet_NaN();
232
234 models(this->process_data_, this->solid_material_);
236 tmp;
238
239 output_data.eps_data.eps = B * u;
240 output_data.deformation_gradient_data.deformation_gradient =
241 grad_u + MathLib::VectorizedTensor::identity<DisplacementDim>();
242 output_data.deformation_gradient_data.volume_ratio =
244 output_data.deformation_gradient_data.deformation_gradient);
245
246 CS.eval(
247 models, t, dt, x_position, //
248 medium, //
249 T_ref, //
250 output_data.deformation_gradient_data, //
251 G * u_prev + MathLib::VectorizedTensor::identity<DisplacementDim>(),
252 current_state, prev_state, material_state, tmp, CD);
253
254 return CD;
255 }
256
257 void assemble(double const /*t*/, double const /*dt*/,
258 std::vector<double> const& /*local_x*/,
259 std::vector<double> const& /*local_x_prev*/,
260 std::vector<double>& /*local_M_data*/,
261 std::vector<double>& /*local_K_data*/,
262 std::vector<double>& /*local_b_data*/) override
263 {
264 OGS_FATAL(
265 "LargeDeformationLocalAssembler: assembly without jacobian is not "
266 "implemented.");
267 }
268
269 void assembleWithJacobian(double const t, double const dt,
270 std::vector<double> const& local_x,
271 std::vector<double> const& local_x_prev,
272 std::vector<double>& /*local_M_data*/,
273 std::vector<double>& /*local_K_data*/,
274 std::vector<double>& local_b_data,
275 std::vector<double>& local_Jac_data) override
276 {
277 auto const local_matrix_size = local_x.size();
278
279 auto local_Jac = MathLib::createZeroedMatrix<StiffnessMatrixType>(
280 local_Jac_data, local_matrix_size, local_matrix_size);
281
282 auto local_b = MathLib::createZeroedVector<NodalDisplacementVectorType>(
283 local_b_data, local_matrix_size);
284
285 auto [u] = localDOF(local_x);
286 auto [u_prev] = localDOF(local_x_prev);
287
288 unsigned const n_integration_points =
290
292 x_position.setElementID(this->element_.getID());
293
295 constitutive_setting;
296 auto const& medium =
297 *this->process_data_.media_map.getMedium(this->element_.getID());
298
299 for (unsigned ip = 0; ip < n_integration_points; ip++)
300 {
301 x_position.setIntegrationPoint(ip);
302 auto const& w = _ip_data[ip].integration_weight;
303 auto const& N = _ip_data[ip].N;
304 auto const& dNdx = _ip_data[ip].dNdx;
305
306 auto const x_coord =
307 NumLib::interpolateXCoordinate<ShapeFunction,
309 this->element_, N);
310
311 // For the 2D case the 33-component is needed (and the four entries
312 // of the non-symmetric matrix); In 3d there are nine entries.
313 GradientMatrixType G(DisplacementDim * DisplacementDim +
314 (DisplacementDim == 2 ? 1 : 0),
315 ShapeFunction::NPOINTS * DisplacementDim);
316 Deformation::computeGMatrix<DisplacementDim,
317 ShapeFunction::NPOINTS>(
318 dNdx, G, this->is_axially_symmetric_, N, x_coord);
319
320 GradientVectorType const grad_u = G * u;
321
322 auto const B_0 = LinearBMatrix::computeBMatrix<
323 DisplacementDim, ShapeFunction::NPOINTS,
325 dNdx, N, x_coord, this->is_axially_symmetric_);
326
327 auto const B_N = NonLinearBMatrix::computeBMatrix<
328 DisplacementDim, ShapeFunction::NPOINTS,
330 dNdx, N, grad_u, x_coord, this->is_axially_symmetric_);
331
332 auto const B = B_0 + B_N;
333
334 auto const CD = updateConstitutiveRelations(
335 u, u_prev, x_position, t, dt, _ip_data[ip],
336 constitutive_setting, medium, this->current_states_[ip],
337 this->prev_states_[ip], this->material_states_[ip],
338 this->output_data_[ip]);
339
340 auto const& sigma = this->current_states_[ip].stress_data.sigma;
341 auto const& b = *CD.volumetric_body_force;
342 auto const& C = CD.s_mech_data.stiffness_tensor;
343
344 local_b.noalias() -=
345 (B.transpose() * sigma - N_u_op(N).transpose() * b) * w;
346
347 auto const sigma_geom =
348 computeSigmaGeom<DisplacementDim, ShapeMatricesType>(
350
351 local_Jac.noalias() += G.transpose() * sigma_geom * G * w;
352
353 local_Jac.noalias() += B.transpose() * C * B * w;
354 }
355 }
356
357 void postTimestepConcrete(Eigen::VectorXd const& local_x,
358 Eigen::VectorXd const& local_x_prev,
359 double const t, double const dt,
360 int const /*process_id*/) override
361 {
362 unsigned const n_integration_points =
364
366 x_position.setElementID(this->element_.getID());
367
369 constitutive_setting;
370
371 auto& medium =
372 *this->process_data_.media_map.getMedium(this->element_.getID());
373
374 for (unsigned ip = 0; ip < n_integration_points; ip++)
375 {
376 x_position.setIntegrationPoint(ip);
377
379 local_x, local_x_prev, x_position, t, dt, _ip_data[ip],
380 constitutive_setting, medium, this->current_states_[ip],
381 this->prev_states_[ip], this->material_states_[ip],
382 this->output_data_[ip]);
383
384 this->material_states_[ip].pushBackState();
385 }
386
387 for (unsigned ip = 0; ip < n_integration_points; ip++)
388 {
389 this->prev_states_[ip] = this->current_states_[ip];
390 }
391 }
392
393 Eigen::Map<const Eigen::RowVectorXd> getShapeMatrix(
394 const unsigned integration_point) const override
395 {
396 auto const& N = _secondary_data.N[integration_point];
397
398 // assumes N is stored contiguously in memory
399 return Eigen::Map<const Eigen::RowVectorXd>(N.data(), N.size());
400 }
401
402private:
403 static constexpr auto localDOF(std::vector<double> const& x)
404 {
405 return NumLib::localDOF<
407 }
408
409private:
410 std::vector<IpData, Eigen::aligned_allocator<IpData>> _ip_data;
411
413
414 static const int displacement_size =
415 ShapeFunction::NPOINTS * DisplacementDim;
416};
417
418} // namespace LargeDeformation
419} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:26
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 setIntegrationPoint(unsigned integration_point)
MatrixType< _kelvin_vector_size, _number_of_dof > BMatrixType
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
LargeDeformationLocalAssembler(MeshLib::Element const &e, std::size_t const, NumLib::GenericIntegrationMethod const &integration_method, bool const is_axially_symmetric, LargeDeformationProcessData< DisplacementDim > &process_data)
typename GMatricesType::GradientVectorType GradientVectorType
typename ShapeMatricesType::ShapeMatrices ShapeMatrices
void assemble(double const, double const, std::vector< double > const &, std::vector< double > const &, std::vector< double > &, std::vector< double > &, std::vector< double > &) override
void assembleWithJacobian(double const t, double const dt, std::vector< double > const &local_x, std::vector< double > const &local_x_prev, std::vector< double > &, std::vector< double > &, std::vector< double > &local_b_data, std::vector< double > &local_Jac_data) override
ConstitutiveRelations::ConstitutiveData< DisplacementDim > updateConstitutiveRelations(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, IntegrationPointData< BMatricesType, ShapeMatricesType, DisplacementDim > &ip_data, 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
typename ShapeMatricesType::NodalVectorType NodalVectorType
static constexpr auto localDOF(std::vector< double > const &x)
SecondaryData< typename ShapeMatrices::ShapeType > _secondary_data
typename BMatricesType::NodalForceVectorType NodalDisplacementVectorType
std::vector< IpData, Eigen::aligned_allocator< IpData > > _ip_data
void postTimestepConcrete(Eigen::VectorXd const &local_x, Eigen::VectorXd const &local_x_prev, double const t, double const dt, int const) override
typename BMatricesType::NodalForceVectorType NodalForceVectorType
typename GMatricesType::GradientMatrixType GradientMatrixType
ShapeMatrixPolicyType< ShapeFunction, DisplacementDim > ShapeMatricesType
typename ShapeMatricesType::NodalMatrixType NodalMatrixType
LargeDeformationLocalAssembler(LargeDeformationLocalAssembler &&)=delete
typename BMatricesType::StiffnessMatrixType StiffnessMatrixType
Eigen::Map< const Eigen::RowVectorXd > getShapeMatrix(const unsigned integration_point) const override
Provides the shape matrix at the given integration point.
LargeDeformationLocalAssembler(LargeDeformationLocalAssembler const &)=delete
constexpr int tensorSize(int dim)
See Tensor type for details.
Definition Tensor.h:19
Eigen::Matrix< double, Eigen::MatrixBase< Derived >::RowsAtCompileTime, 1 > symmetricTensorToKelvinVector(Eigen::MatrixBase< Derived > const &v)
Eigen::Matrix< double, 3, 3 > kelvinVectorToTensor(Eigen::Matrix< double, 4, 1, Eigen::ColMajor, 4, 1 > const &v)
double determinant(Eigen::MatrixBase< Derived > const &tensor)
Computes determinant of a vectorized tensor.
constexpr Eigen::CwiseNullaryOp< EigenBlockMatrixViewFunctor< D, M >, typename EigenBlockMatrixViewFunctor< D, M >::Matrix > eigenBlockMatrixView(const Eigen::MatrixBase< M > &matrix)
double interpolateXCoordinate(MeshLib::Element const &e, typename ShapeMatricesType::ShapeMatrices::ShapeType const &N)
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:64
std::array< double, 3 > interpolateCoordinates(MeshLib::Element const &e, typename ShapeMatricesType::ShapeMatrices::ShapeType const &N)
void computeGMatrix(DNDX_Type const &dNdx, GMatrixType &g_matrix, const bool is_axially_symmetric, N_Type const &N, const double radius)
Fills a G-matrix based on given shape function dN/dx values.
Definition GMatrix.h:25
Eigen::Matrix< double, MPL::tensorSize(DisplacementDim), MPL::tensorSize(DisplacementDim)> computeSigmaGeom(Eigen::Matrix3d const &sigma_tensor)
BMatrixType computeBMatrix(DNDX_Type const &dNdx, N_Type const &N, const double radius, const bool is_axially_symmetric)
Fills a B-matrix based on given shape function dN/dx values.
BMatrixType computeBMatrix(DNDX_Type const &dNdx, N_Type const &N, GradientVectorType const &grad_u, const double radius, const bool is_axially_symmetric)
NumLib::ShapeMatrices< NodalRowVectorType, DimNodalMatrixType, DimMatrixType, GlobalDimNodalMatrixType > ShapeMatrices
MatrixType< ShapeFunction::NPOINTS, ShapeFunction::NPOINTS > NodalMatrixType
VectorType< ShapeFunction::NPOINTS > NodalVectorType
RowVectorType< ShapeFunction::NPOINTS > NodalRowVectorType
std::vector< ShapeMatrixType, Eigen::aligned_allocator< ShapeMatrixType > > N
Data that is needed for the equation system assembly.
void eval(ConstitutiveModels< DisplacementDim > &models, double const t, double const dt, ParameterLib::SpatialPosition const &x_position, MaterialPropertyLib::Medium const &medium, double const T_ref, DeformationGradientData< DisplacementDim > const &deformation_gradient_data, GradientVectorType const &deformation_gradient_prev, StatefulData< DisplacementDim > &state, StatefulDataPrev< DisplacementDim > const &prev_state, MaterialStateData< DisplacementDim > &mat_state, ConstitutiveTempData< DisplacementDim > &tmp, ConstitutiveData< DisplacementDim > &cd) const
Evaluate the constitutive setting.
Data that is needed for output purposes, but not directly for the assembly.
DeformationGradientData< DisplacementDim > deformation_gradient_data
Data whose state must be tracked by the process.
ShapeMatricesType::GlobalDimNodalMatrixType dNdx
std::vector< MaterialStateData< DisplacementDim > > material_states_
std::vector< typename ConstitutiveRelations::StatefulDataPrev< DisplacementDim > > prev_states_
std::vector< typename ConstitutiveRelations::StatefulData< DisplacementDim > > current_states_
std::vector< typename ConstitutiveRelations::OutputData< DisplacementDim > > output_data_
ConstitutiveRelations::SolidConstitutiveRelation< DisplacementDim > const & solid_material_
std::vector< ShapeMatrixType, Eigen::aligned_allocator< ShapeMatrixType > > N