OGS
HydroMechanicsLocalAssemblerMatrix-impl.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
20
21namespace ProcessLib
22{
23namespace LIE
24{
25namespace HydroMechanics
26{
27namespace MPL = MaterialPropertyLib;
28
29template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
30 int DisplacementDim>
31HydroMechanicsLocalAssemblerMatrix<ShapeFunctionDisplacement,
32 ShapeFunctionPressure, DisplacementDim>::
33 HydroMechanicsLocalAssemblerMatrix(
34 MeshLib::Element const& e,
35 std::size_t const n_variables,
36 std::size_t const /*local_matrix_size*/,
37 std::vector<unsigned> const& dofIndex_to_localIndex,
38 NumLib::GenericIntegrationMethod const& integration_method,
39 bool const is_axially_symmetric,
42 e, is_axially_symmetric, integration_method,
43 (n_variables - 1) * ShapeFunctionDisplacement::NPOINTS *
44 DisplacementDim +
45 ShapeFunctionPressure::NPOINTS,
46 dofIndex_to_localIndex),
47 _process_data(process_data)
48{
49 unsigned const n_integration_points =
50 integration_method.getNumberOfPoints();
51
52 _ip_data.reserve(n_integration_points);
53 _secondary_data.N.resize(n_integration_points);
54
55 auto const shape_matrices_u =
56 NumLib::initShapeMatrices<ShapeFunctionDisplacement,
58 DisplacementDim>(e, is_axially_symmetric,
59 integration_method);
60
61 auto const shape_matrices_p =
62 NumLib::initShapeMatrices<ShapeFunctionPressure,
63 ShapeMatricesTypePressure, DisplacementDim>(
64 e, is_axially_symmetric, integration_method);
65
67 _process_data.solid_materials, _process_data.material_ids, e.getID());
68
70 x_position.setElementID(e.getID());
71 for (unsigned ip = 0; ip < n_integration_points; ip++)
72 {
73 _ip_data.emplace_back(solid_material);
74 auto& ip_data = _ip_data[ip];
75 auto const& sm_u = shape_matrices_u[ip];
76 auto const& sm_p = shape_matrices_p[ip];
77
78 ip_data.integration_weight =
79 sm_u.detJ * sm_u.integralMeasure *
80 integration_method.getWeightedPoint(ip).getWeight();
81 ip_data.darcy_velocity.setZero();
82
83 ip_data.N_u = sm_u.N;
84 ip_data.dNdx_u = sm_u.dNdx;
85 ip_data.H_u.setZero(DisplacementDim, displacement_size);
86 for (int i = 0; i < DisplacementDim; ++i)
87 {
88 ip_data.H_u
89 .template block<1, displacement_size / DisplacementDim>(
90 i, i * displacement_size / DisplacementDim)
91 .noalias() = ip_data.N_u;
92 }
93
94 ip_data.N_p = sm_p.N;
95 ip_data.dNdx_p = sm_p.dNdx;
96
97 _secondary_data.N[ip] = sm_u.N;
98
99 ip_data.sigma_eff.setZero(kelvin_vector_size);
100 ip_data.eps.setZero(kelvin_vector_size);
101
102 ip_data.sigma_eff_prev.resize(kelvin_vector_size);
103 ip_data.eps_prev.resize(kelvin_vector_size);
104 ip_data.C.resize(kelvin_vector_size, kelvin_vector_size);
105
106 auto const initial_effective_stress =
107 _process_data.initial_effective_stress(0, x_position);
108 for (unsigned i = 0; i < kelvin_vector_size; i++)
109 {
110 ip_data.sigma_eff[i] = initial_effective_stress[i];
111 ip_data.sigma_eff_prev[i] = initial_effective_stress[i];
112 }
113 }
114}
115
116template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
117 int DisplacementDim>
119 ShapeFunctionDisplacement, ShapeFunctionPressure, DisplacementDim>::
120 assembleWithJacobianConcrete(double const t, double const dt,
121 Eigen::VectorXd const& local_x,
122 Eigen::VectorXd const& local_x_prev,
123 Eigen::VectorXd& local_rhs,
124 Eigen::MatrixXd& local_Jac)
125{
126 auto p = const_cast<Eigen::VectorXd&>(local_x).segment(pressure_index,
128 auto const p_prev = local_x_prev.segment(pressure_index, pressure_size);
129
130 if (_process_data.deactivate_matrix_in_flow)
131 {
133 }
134
135 auto u = local_x.segment(displacement_index, displacement_size);
136 auto u_prev = local_x_prev.segment(displacement_index, displacement_size);
137
138 auto rhs_p = local_rhs.template segment<pressure_size>(pressure_index);
139 auto rhs_u =
140 local_rhs.template segment<displacement_size>(displacement_index);
141
142 auto J_pp = local_Jac.template block<pressure_size, pressure_size>(
144 auto J_pu = local_Jac.template block<pressure_size, displacement_size>(
146 auto J_uu = local_Jac.template block<displacement_size, displacement_size>(
148 auto J_up = local_Jac.template block<displacement_size, pressure_size>(
150
151 assembleBlockMatricesWithJacobian(t, dt, p, p_prev, u, u_prev, rhs_p, rhs_u,
152 J_pp, J_pu, J_uu, J_up);
153}
154
155template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
156 int DisplacementDim>
158 ShapeFunctionDisplacement, ShapeFunctionPressure, DisplacementDim>::
159 assembleBlockMatricesWithJacobian(
160 double const t, double const dt,
161 Eigen::Ref<const Eigen::VectorXd> const& p,
162 Eigen::Ref<const Eigen::VectorXd> const& p_prev,
163 Eigen::Ref<const Eigen::VectorXd> const& u,
164 Eigen::Ref<const Eigen::VectorXd> const& u_prev,
165 Eigen::Ref<Eigen::VectorXd> rhs_p, Eigen::Ref<Eigen::VectorXd> rhs_u,
166 Eigen::Ref<Eigen::MatrixXd> J_pp, Eigen::Ref<Eigen::MatrixXd> J_pu,
167 Eigen::Ref<Eigen::MatrixXd> J_uu, Eigen::Ref<Eigen::MatrixXd> J_up)
168{
169 assert(this->_element.getDimension() == DisplacementDim);
170
172 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
174
176 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
178
179 typename ShapeMatricesTypeDisplacement::template MatrixType<
181 Kup = ShapeMatricesTypeDisplacement::template MatrixType<
184
185 auto const& gravity_vec = _process_data.specific_body_force;
186
187 MPL::VariableArray variables;
188 MPL::VariableArray variables_prev;
190 x_position.setElementID(_element.getID());
191
192 auto const& medium = _process_data.media_map.getMedium(_element.getID());
193 auto const& liquid_phase = medium->phase("AqueousLiquid");
194 auto const& solid_phase = medium->phase("Solid");
195
196 auto const T_ref =
198 .template value<double>(variables, x_position, t, dt);
199 variables.temperature = T_ref;
200 variables_prev.temperature = T_ref;
201
202 bool const has_storage_property =
203 medium->hasProperty(MPL::PropertyType::storage);
204
205 auto const B_dil_bar = getDilatationalBBarMatrix();
206
207 unsigned const n_integration_points = _ip_data.size();
208 for (unsigned ip = 0; ip < n_integration_points; ip++)
209 {
210 auto& ip_data = _ip_data[ip];
211 auto const& ip_w = ip_data.integration_weight;
212 auto const& N_u = ip_data.N_u;
213 auto const& dNdx_u = ip_data.dNdx_u;
214 auto const& N_p = ip_data.N_p;
215 auto const& dNdx_p = ip_data.dNdx_p;
216 auto const& H_u = ip_data.H_u;
217
218 variables.liquid_phase_pressure = N_p.dot(p);
219
220 x_position = {
221 std::nullopt, _element.getID(),
223 NumLib::interpolateCoordinates<ShapeFunctionDisplacement,
225 _element, N_u))};
226
227 auto const x_coord = x_position.getCoordinates().value()[0];
228
229 auto const B =
231 DisplacementDim, ShapeFunctionDisplacement::NPOINTS,
233 dNdx_u, N_u, B_dil_bar, x_coord, this->_is_axially_symmetric)
234 .eval();
235
236 auto const& eps_prev = ip_data.eps_prev;
237 auto const& sigma_eff_prev = ip_data.sigma_eff_prev;
238 auto& sigma_eff = ip_data.sigma_eff;
239
240 auto& eps = ip_data.eps;
241 auto& state = ip_data.material_state_variables;
242
243 auto const rho_sr =
244 solid_phase.property(MPL::PropertyType::density)
245 .template value<double>(variables, x_position, t, dt);
246 auto const rho_fr =
247 liquid_phase.property(MPL::PropertyType::density)
248 .template value<double>(variables, x_position, t, dt);
249
250 auto const alpha =
252 .template value<double>(variables, x_position, t, dt);
253 auto const porosity =
254 medium->property(MPL::PropertyType::porosity)
255 .template value<double>(variables, x_position, t, dt);
256
257 double const rho = rho_sr * (1 - porosity) + porosity * rho_fr;
258 auto const& identity2 =
260
261 eps.noalias() = B * u;
262
263 variables.mechanical_strain
265 eps);
266
267 variables_prev.stress
269 sigma_eff_prev);
270 variables_prev.mechanical_strain
272 eps_prev);
273 variables_prev.temperature = T_ref;
274
275 auto&& solution = _ip_data[ip].solid_material.integrateStress(
276 variables_prev, variables, t, x_position, dt, *state);
277
278 if (!solution)
279 {
280 OGS_FATAL("Computation of local constitutive relation failed.");
281 }
282
284 std::tie(sigma_eff, state, C) = std::move(*solution);
285
286 J_uu.noalias() += (B.transpose() * C * B) * ip_w;
287
288 rhs_u.noalias() -= B.transpose() * sigma_eff * ip_w;
289 rhs_u.noalias() -= -H_u.transpose() * rho * gravity_vec * ip_w;
290
291 //
292 // pressure equation, pressure part and displacement equation, pressure
293 // part
294 //
295 if (!_process_data.deactivate_matrix_in_flow) // Only for hydraulically
296 // active matrix
297 {
298 Kup.noalias() += B.transpose() * alpha * identity2 * N_p * ip_w;
299
300 variables.density = rho_fr;
301 auto const mu =
302 liquid_phase.property(MPL::PropertyType::viscosity)
303 .template value<double>(variables, x_position, t, dt);
304
305 auto const k_over_mu =
307 medium->property(MPL::PropertyType::permeability)
308 .value(variables, x_position, t, dt)) /
309 mu)
310 .eval();
311
312 double const S =
313 has_storage_property
314 ? medium->property(MPL::PropertyType::storage)
315 .template value<double>(variables, x_position, t, dt)
316 : porosity *
317 (liquid_phase.property(MPL::PropertyType::density)
318 .template dValue<double>(
319 variables,
321 x_position, t, dt) /
322 rho_fr) +
323 (alpha - porosity) * (1.0 - alpha) /
324 _ip_data[ip].solid_material.getBulkModulus(
325 t, x_position, &C);
326
327 auto q = ip_data.darcy_velocity.head(DisplacementDim);
328 q.noalias() = -k_over_mu * (dNdx_p * p + rho_fr * gravity_vec);
329
330 laplace_p.noalias() +=
331 dNdx_p.transpose() * k_over_mu * dNdx_p * ip_w;
332 storage_p.noalias() += N_p.transpose() * S * N_p * ip_w;
333
334 rhs_p.noalias() +=
335 dNdx_p.transpose() * rho_fr * k_over_mu * gravity_vec * ip_w;
336 }
337 }
338
339 // displacement equation, pressure part
340 J_up.noalias() -= Kup;
341
342 // pressure equation, pressure part.
343 J_pp.noalias() += laplace_p + storage_p / dt;
344
345 // pressure equation, displacement part.
346 J_pu.noalias() += Kup.transpose() / dt;
347
348 // pressure equation
349 rhs_p.noalias() -= laplace_p * p + storage_p * (p - p_prev) / dt +
350 Kup.transpose() * (u - u_prev) / dt;
351
352 // displacement equation
353 rhs_u.noalias() -= -Kup * p;
354}
355
356template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
357 int DisplacementDim>
359 ShapeFunctionDisplacement, ShapeFunctionPressure, DisplacementDim>::
360 postTimestepConcreteWithVector(double const t, double const dt,
361 Eigen::VectorXd const& local_x)
362{
363 auto p = const_cast<Eigen::VectorXd&>(local_x).segment(pressure_index,
365 if (_process_data.deactivate_matrix_in_flow)
366 {
368 }
369 auto u = local_x.segment(displacement_index, displacement_size);
370
372}
373
374template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
375 int DisplacementDim>
377 ShapeFunctionDisplacement, ShapeFunctionPressure, DisplacementDim>::
378 postTimestepConcreteWithBlockVectors(
379 double const t, double const dt,
380 Eigen::Ref<const Eigen::VectorXd> const& p,
381 Eigen::Ref<const Eigen::VectorXd> const& u)
382{
383 MPL::VariableArray variables;
384 MPL::VariableArray variables_prev;
386
387 auto const e_id = _element.getID();
388 x_position.setElementID(e_id);
389
391 KV sigma_avg = KV::Zero();
392 DisplacementDimVector velocity_avg;
393 velocity_avg.setZero();
394
395 unsigned const n_integration_points = _ip_data.size();
396
397 auto const& medium = _process_data.media_map.getMedium(_element.getID());
398 auto const& liquid_phase = medium->phase("AqueousLiquid");
399 auto const T_ref =
401 .template value<double>(variables, x_position, t, dt);
402 variables.temperature = T_ref;
403 variables_prev.temperature = T_ref;
404
405 auto const B_dil_bar = getDilatationalBBarMatrix();
406
407 for (unsigned ip = 0; ip < n_integration_points; ip++)
408 {
409 auto& ip_data = _ip_data[ip];
410
411 auto const& eps_prev = ip_data.eps_prev;
412 auto const& sigma_eff_prev = ip_data.sigma_eff_prev;
413
414 auto& eps = ip_data.eps;
415 auto& sigma_eff = ip_data.sigma_eff;
416 auto& state = ip_data.material_state_variables;
417
418 auto const& N_u = ip_data.N_u;
419 auto const& N_p = ip_data.N_p;
420 auto const& dNdx_u = ip_data.dNdx_u;
421
422 variables.liquid_phase_pressure = N_p.dot(p);
423
424 x_position = {
425 std::nullopt, _element.getID(),
427 NumLib::interpolateCoordinates<ShapeFunctionDisplacement,
429 _element, N_u))};
430
431 auto const x_coord = x_position.getCoordinates().value()[0];
432
433 auto const B =
435 DisplacementDim, ShapeFunctionDisplacement::NPOINTS,
437 dNdx_u, N_u, B_dil_bar, x_coord, this->_is_axially_symmetric)
438 .eval();
439
440 eps.noalias() = B * u;
441
442 variables.mechanical_strain
444 eps);
445
446 variables_prev.stress
448 sigma_eff_prev);
449 variables_prev.mechanical_strain
451 eps_prev);
452
453 auto&& solution = _ip_data[ip].solid_material.integrateStress(
454 variables_prev, variables, t, x_position, dt, *state);
455
456 if (!solution)
457 {
458 OGS_FATAL("Computation of local constitutive relation failed.");
459 }
460
462 std::tie(sigma_eff, state, C) = std::move(*solution);
463
464 sigma_avg += ip_data.sigma_eff;
465
466 if (!_process_data.deactivate_matrix_in_flow) // Only for hydraulically
467 // active matrix
468 {
469 auto const rho_fr =
470 liquid_phase.property(MPL::PropertyType::density)
471 .template value<double>(variables, x_position, t, dt);
472 variables.density = rho_fr;
473 auto const mu =
474 liquid_phase.property(MPL::PropertyType::viscosity)
475 .template value<double>(variables, x_position, t, dt);
476
478 medium->property(MPL::PropertyType::permeability)
479 .value(variables, x_position, t, dt))
480 .eval();
481
482 GlobalDimMatrixType const k_over_mu = k / mu;
483
484 auto const& gravity_vec = _process_data.specific_body_force;
485 auto const& dNdx_p = ip_data.dNdx_p;
486
487 ip_data.darcy_velocity.head(DisplacementDim).noalias() =
488 -k_over_mu * (dNdx_p * p + rho_fr * gravity_vec);
489 velocity_avg.noalias() +=
490 ip_data.darcy_velocity.head(DisplacementDim);
491 }
492 }
493
494 sigma_avg /= n_integration_points;
495 velocity_avg /= n_integration_points;
496
497 Eigen::Map<KV>(
498 &(*_process_data.element_stresses)[e_id * KV::RowsAtCompileTime]) =
500
501 Eigen::Map<DisplacementDimVector>(
502 &(*_process_data.element_velocities)[e_id * DisplacementDim]) =
503 velocity_avg;
504
506 ShapeFunctionPressure, typename ShapeFunctionDisplacement::MeshElement,
507 DisplacementDim>(_element, _is_axially_symmetric, p,
508 *_process_data.mesh_prop_nodal_p);
509}
510
511template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
512 int DisplacementDim>
514 ShapeFunctionDisplacement, ShapeFunctionPressure,
515 DisplacementDim>::setPressureOfInactiveNodes(double const t,
516 Eigen::Ref<Eigen::VectorXd> p)
517{
519 x_position.setElementID(_element.getID());
520 for (unsigned i = 0; i < pressure_size; i++)
521 {
522 // only inactive nodes
523 if (_process_data.p_element_status->isActiveNode(_element.getNode(i)))
524 {
525 continue;
526 }
527 x_position.setNodeID(getNodeIndex(_element, i));
528 auto const p0 = (*_process_data.p0)(t, x_position)[0];
529 p[i] = p0;
530 }
531}
532
533template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
534 int DisplacementDim>
535std::vector<double> const& HydroMechanicsLocalAssemblerMatrix<
536 ShapeFunctionDisplacement, ShapeFunctionPressure, DisplacementDim>::
537 getIntPtSigma(
538 const double /*t*/,
539 std::vector<GlobalVector*> const& /*x*/,
540 std::vector<NumLib::LocalToGlobalIndexMap const*> const& /*dof_table*/,
541 std::vector<double>& cache) const
542{
545}
546template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
547 int DisplacementDim>
548std::vector<double> const& HydroMechanicsLocalAssemblerMatrix<
549 ShapeFunctionDisplacement, ShapeFunctionPressure, DisplacementDim>::
550 getIntPtEpsilon(
551 const double /*t*/,
552 std::vector<GlobalVector*> const& /*x*/,
553 std::vector<NumLib::LocalToGlobalIndexMap const*> const& /*dof_table*/,
554 std::vector<double>& cache) const
555{
558}
559
560template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
561 int DisplacementDim>
562std::vector<double> const& HydroMechanicsLocalAssemblerMatrix<
563 ShapeFunctionDisplacement, ShapeFunctionPressure, DisplacementDim>::
564 getIntPtDarcyVelocity(
565 const double /*t*/,
566 std::vector<GlobalVector*> const& /*x*/,
567 std::vector<NumLib::LocalToGlobalIndexMap const*> const& /*dof_table*/,
568 std::vector<double>& cache) const
569{
570 unsigned const n_integration_points = _ip_data.size();
571
572 cache.clear();
573 auto cache_matrix = MathLib::createZeroedMatrix<Eigen::Matrix<
574 double, DisplacementDim, Eigen::Dynamic, Eigen::RowMajor>>(
575 cache, DisplacementDim, n_integration_points);
576
577 for (unsigned ip = 0; ip < n_integration_points; ip++)
578 {
579 cache_matrix.col(ip).noalias() = _ip_data[ip].darcy_velocity;
580 }
581
582 return cache;
583}
584} // namespace HydroMechanics
585} // namespace LIE
586} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:19
constexpr double getWeight() const
std::size_t getID() const
Returns the ID of the element.
Definition Element.h:80
MathLib::WeightedPoint const & getWeightedPoint(unsigned const igp) const
void setNodeID(std::size_t node_id)
void setElementID(std::size_t element_id)
std::optional< MathLib::Point3d > const getCoordinates() const
MatrixType< _kelvin_vector_size, _number_of_dof > BMatrixType
HydroMechanicsLocalAssemblerInterface(MeshLib::Element const &element, bool const is_axially_symmetric, NumLib::GenericIntegrationMethod const &integration_method, std::size_t n_local_size, std::vector< unsigned > dofIndex_to_localIndex)
std::vector< IntegrationPointDataType, Eigen::aligned_allocator< IntegrationPointDataType > > _ip_data
typename ShapeMatricesTypePressure::GlobalDimMatrixType GlobalDimMatrixType
ShapeMatrixPolicyType< ShapeFunctionDisplacement, DisplacementDim > ShapeMatricesTypeDisplacement
void postTimestepConcreteWithBlockVectors(double const t, double const dt, Eigen::Ref< const Eigen::VectorXd > const &p, Eigen::Ref< const Eigen::VectorXd > const &u)
ShapeMatrixPolicyType< ShapeFunctionPressure, DisplacementDim > ShapeMatricesTypePressure
SecondaryData< typename ShapeMatricesTypeDisplacement::ShapeMatrices::ShapeType > _secondary_data
void assembleBlockMatricesWithJacobian(double const t, double const dt, Eigen::Ref< const Eigen::VectorXd > const &p, Eigen::Ref< const Eigen::VectorXd > const &p_prev, Eigen::Ref< const Eigen::VectorXd > const &u, Eigen::Ref< const Eigen::VectorXd > const &u_prev, Eigen::Ref< Eigen::VectorXd > rhs_p, Eigen::Ref< Eigen::VectorXd > rhs_u, Eigen::Ref< Eigen::MatrixXd > J_pp, Eigen::Ref< Eigen::MatrixXd > J_pu, Eigen::Ref< Eigen::MatrixXd > J_uu, Eigen::Ref< Eigen::MatrixXd > J_up)
auto & selectSolidConstitutiveRelation(SolidMaterialsMap const &constitutive_relations, MeshLib::PropertyVector< int > const *const material_ids, std::size_t const element_id)
constexpr Eigen::Matrix< double, GlobalDim, GlobalDim > formEigenTensor(MaterialPropertyLib::PropertyDataType const &values)
Eigen::Matrix< double, 4, 1 > kelvinVectorToSymmetricTensor(Eigen::Matrix< double, 4, 1, Eigen::ColMajor, 4, 1 > const &v)
Eigen::Matrix< double, kelvin_vector_dimensions(DisplacementDim), 1, Eigen::ColMajor > KelvinVectorType
Eigen::Matrix< double, kelvin_vector_dimensions(DisplacementDim), kelvin_vector_dimensions(DisplacementDim), Eigen::RowMajor > KelvinMatrixType
Eigen::Map< Matrix > createZeroedMatrix(std::vector< double > &data, Eigen::MatrixXd::Index rows, Eigen::MatrixXd::Index cols)
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)
std::array< double, 3 > interpolateCoordinates(MeshLib::Element const &e, typename ShapeMatricesType::ShapeMatrices::ShapeType const &N)
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.
std::vector< double > const & getIntegrationPointKelvinVectorData(IntegrationPointDataVector const &ip_data_vector, MemberType IpData::*const member, std::vector< double > &cache)
MatrixType< ShapeFunction::NPOINTS, ShapeFunction::NPOINTS > NodalMatrixType
static Eigen::Matrix< double, KelvinVectorSize, 1 > const identity2
Kelvin mapping of 2nd order identity tensor.