OGS
HMPhaseFieldFEM-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 <Eigen/Core>
7#include <Eigen/Eigenvalues>
8#include <utility>
9
19
20namespace ProcessLib
21{
22namespace HMPhaseField
23{
24template <typename ShapeFunction, int DisplacementDim>
26 assembleWithJacobianForStaggeredScheme(double const t, double const dt,
27 Eigen::VectorXd const& local_x,
28 Eigen::VectorXd const& local_x_prev,
29 int const process_id,
30 std::vector<double>& local_b_data,
31 std::vector<double>& local_Jac_data)
32{
33 // For the equations with phase field.
34 if (process_id == _process_data._phasefield_process_id)
35 {
36 assembleWithJacobianPhaseFieldEquations(t, dt, local_x, local_b_data,
37 local_Jac_data);
38 return;
39 }
40
41 // For the equations for hydro
42 if (process_id == _process_data._hydro_process_id)
43 {
44 assembleWithJacobianHydroEquations(t, dt, local_x, local_x_prev,
45 local_b_data, local_Jac_data);
46 return;
47 }
48
49 // For the equations with deformation
50 assembleWithJacobianForDeformationEquations(t, dt, local_x, local_b_data,
51 local_Jac_data);
52}
53
54template <typename ShapeFunction, int DisplacementDim>
57 double const t, double const dt, Eigen::VectorXd const& local_x,
58 std::vector<double>& local_b_data, std::vector<double>& local_Jac_data)
59{
60 auto const d = local_x.template segment<phasefield_size>(phasefield_index);
61 auto const u =
62 local_x.template segment<displacement_size>(displacement_index);
63 auto const p = local_x.template segment<pressure_size>(pressure_index);
64
66 local_Jac_data, displacement_size, displacement_size);
67
69 local_b_data, displacement_size);
70
71 auto const& medium = _process_data.media_map.getMedium(_element.getID());
72 auto const& solid = medium->phase(MaterialPropertyLib::PhaseName::Solid);
73 auto const& fluid = fluidPhase(*medium);
75
76 auto const& identity2 = Invariants::identity2;
77
78 int const n_integration_points = _integration_method.getNumberOfPoints();
79 for (int ip = 0; ip < n_integration_points; ip++)
80 {
81 auto const& w = _ip_data[ip].integration_weight;
82 auto const& N = _ip_data[ip].N;
83 auto const& dNdx = _ip_data[ip].dNdx;
84 double const d_ip = N.dot(d);
85 double const p_ip = N.dot(p);
86
87 ParameterLib::SpatialPosition const x_position{
88 std::nullopt, this->_element.getID(),
91 this->_element, N))};
92
93 auto const x_coord =
94 x_position.getCoordinates().value()[0]; // r for axisymmetry
95
96 auto const& B =
97 LinearBMatrix::computeBMatrix<DisplacementDim,
98 ShapeFunction::NPOINTS,
100 dNdx, N, x_coord, _is_axially_symmetric);
101
102 auto& eps = _ip_data[ip].eps;
103 eps.noalias() = B * u;
104
105 double const k = _process_data.residual_stiffness(t, x_position)[0];
106 double const ls = _process_data.crack_length_scale(t, x_position)[0];
107
108 double const degradation =
109 _process_data.degradation_derivative->degradation(d_ip, k, ls);
110 _ip_data[ip].updateConstitutiveRelation(
111 t, x_position, dt, u, degradation,
112 _process_data.energy_split_model);
113
114 auto const& sigma = _ip_data[ip].sigma;
115 auto const& D = _ip_data[ip].D;
116
117 auto& biot_coefficient = _ip_data[ip].biot_coefficient;
118 auto& biot_modulus_inv = _ip_data[ip].biot_modulus_inv;
119 auto const& fracture_enhanced_porosity =
120 _ip_data[ip].fracture_enhanced_porosity;
121
122 // Update the effective bulk modulus
123 auto const& P_sph = Invariants::spherical_projection;
124 auto const D_sph = P_sph * D * identity2;
125 double const bulk_modulus_eff = Invariants::trace(D_sph) / 9.;
126
127 auto const& solid_material =
129 _process_data.solid_materials, _process_data.material_ids,
130 _element.getID());
131 auto const bulk_modulus = solid_material.getBulkModulus(t, x_position);
132 auto const alpha_0 =
134 .template value<double>(vars, x_position, t, dt);
135 auto const porosity_0 =
136 medium->property(MPL::PropertyType::porosity)
137 .template value<double>(vars, x_position, t, dt);
138 double const bulk_modulus_degradation = bulk_modulus_eff / bulk_modulus;
139
140 // Update Biot's coefficient
141 biot_coefficient = 1. - bulk_modulus_degradation * (1. - alpha_0);
142
143 // The reference porosity
144 auto const porosity_reference = porosity_0 + fracture_enhanced_porosity;
145
146 // Update Biot's modulus
147 biot_modulus_inv = bulk_modulus_degradation * (alpha_0 - porosity_0) *
148 (1. - alpha_0) / bulk_modulus;
149
150 auto const rho_sr =
151 solid.property(MPL::PropertyType::density)
152 .template value<double>(vars, x_position, t, dt);
153 auto const rho_fr =
154 fluid.property(MPL::PropertyType::density)
155 .template value<double>(vars, x_position, t, dt);
156
157 auto const rho =
158 rho_sr * (1. - porosity_reference) + porosity_reference * rho_fr;
159 auto const& b = _process_data.specific_body_force;
160
161 local_rhs.noalias() -=
162 (B.transpose() * (sigma - biot_coefficient * p_ip * identity2) -
163 N_u_op(N).transpose() * rho * b) *
164 w;
165 local_Jac.noalias() += B.transpose() * D * B * w;
166 }
167}
168
169template <typename ShapeFunction, int DisplacementDim>
171 assembleWithJacobianHydroEquations(double const t, double const dt,
172 Eigen::VectorXd const& local_x,
173 Eigen::VectorXd const& local_x_prev,
174 std::vector<double>& local_b_data,
175 std::vector<double>& local_Jac_data)
176{
177 auto const d = local_x.template segment<phasefield_size>(phasefield_index);
178
179 auto const p = local_x.template segment<pressure_size>(pressure_index);
180 auto const p_prev =
181 local_x_prev.template segment<pressure_size>(pressure_index);
182
184 local_Jac_data, pressure_size, pressure_size);
185
186 auto local_rhs = MathLib::createZeroedVector<PressureVector>(local_b_data,
188
190 ShapeMatricesType::NodalMatrixType::Zero(pressure_size, pressure_size);
191
192 typename ShapeMatricesType::NodalMatrixType laplace =
193 ShapeMatricesType::NodalMatrixType::Zero(pressure_size, pressure_size);
194
195 typename ShapeMatricesType::NodalMatrixType stabilizing =
196 ShapeMatricesType::NodalMatrixType::Zero(pressure_size, pressure_size);
197
199 x_position.setElementID(_element.getID());
200
201 auto const& medium = _process_data.media_map.getMedium(_element.getID());
202 auto const& fluid = fluidPhase(*medium);
204
205 auto const& P_sph = Invariants::spherical_projection;
206 auto const& P_dev = Invariants::deviatoric_projection;
207 auto const& identity2 = Invariants::identity2;
208 auto const& ones2 = Invariants::ones2;
209
210 double const k = _process_data.residual_stiffness(t, x_position)[0];
211 double const ls = _process_data.crack_length_scale(t, x_position)[0];
212 double const width = (*_process_data.width)[_element.getID()];
213 double const fracture_threshold = _process_data.fracture_threshold;
214 double const fracture_permeability_parameter =
215 _process_data.fracture_permeability_parameter;
216 double const fixed_stress_stabilization_parameter =
217 _process_data.fixed_stress_stabilization_parameter;
218 double const spatial_stabilization_parameter =
219 _process_data.spatial_stabilization_parameter;
220 auto const he =
221 ls / _process_data.diffused_range_parameter; // element size
222
223 int const n_integration_points = _integration_method.getNumberOfPoints();
224 for (int ip = 0; ip < n_integration_points; ip++)
225 {
226 auto const& w = _ip_data[ip].integration_weight;
227 auto const& N = _ip_data[ip].N;
228 auto const& dNdx = _ip_data[ip].dNdx;
229 double const d_ip = N.dot(d);
230
231 auto const rho_fr =
232 fluid.property(MPL::PropertyType::density)
233 .template value<double>(vars, x_position, t, dt);
234 double const cf = _process_data.fluid_compressibility;
235 auto const Km = medium->property(MPL::PropertyType::permeability)
236 .template value<double>(vars, x_position, t, dt);
237 auto const K = MPL::formEigenTensor<DisplacementDim>(Km);
238 auto const mu = fluid.property(MPL::PropertyType::viscosity)
239 .template value<double>(vars, x_position, t, dt);
240
241 auto const vol_strain = Invariants::trace(_ip_data[ip].eps);
242 auto const vol_strain_prev = Invariants::trace(_ip_data[ip].eps_prev);
243 auto const& biot_coefficient = _ip_data[ip].biot_coefficient;
244 auto const& biot_modulus_inv = _ip_data[ip].biot_modulus_inv;
245 auto const& fracture_enhanced_porosity =
246 _ip_data[ip].fracture_enhanced_porosity;
247
248 // The reference porosity
249 auto const porosity_0 =
250 medium->property(MPL::PropertyType::porosity)
251 .template value<double>(vars, x_position, t, dt);
252 auto const porosity_reference = porosity_0 + fracture_enhanced_porosity;
253
254 double const dv_dt = (vol_strain - vol_strain_prev) / dt;
255
256 // The degraded shear modulus
257 auto const& D = _ip_data[ip].D;
258 auto const D_sph = P_sph * D * identity2;
259 auto const D_dev = P_dev * D * (ones2 - identity2) / std::sqrt(2.);
260 auto const degraded_shear_modulus =
261 Invariants::FrobeniusNorm(D_dev) / 2.;
262 auto const degraded_bulk_modulus = Invariants::trace(D_sph) / 9.;
263
264 double const residual_bulk_modulus = [&]
265 {
266 if ((*_process_data.ele_d)[_element.getID()] <
267 _process_data.fracture_threshold)
268 {
269 // The residual bulk modulus in the fractured element
270 double const degradation_threshold =
271 _process_data.degradation_derivative->degradation(
272 fracture_threshold, k, ls);
273 auto const& D_threshold =
274 degradation_threshold * _ip_data[ip].C_tensile +
275 _ip_data[ip].C_compressive;
276 auto const D_sph_threshold = P_sph * D_threshold * identity2;
277
278 return Invariants::trace(D_sph_threshold) / 9.;
279 }
280 return degraded_bulk_modulus;
281 }();
282
283 double const modulus_rm = fixed_stress_stabilization_parameter *
284 biot_coefficient * biot_coefficient /
285 residual_bulk_modulus;
286
287 double const stablization_spatial =
288 spatial_stabilization_parameter * 0.25 * he * he /
289 (degraded_bulk_modulus + 4. / 3. * degraded_shear_modulus);
290 stabilizing.noalias() +=
291 dNdx.transpose() * stablization_spatial * dNdx * w;
292
293 mass.noalias() +=
294 (biot_modulus_inv + cf * porosity_reference + modulus_rm) *
295 N.transpose() * N * w;
296
297 auto const K_over_mu = K / mu;
298 laplace.noalias() += dNdx.transpose() * K_over_mu * dNdx * w;
299 auto const& b = _process_data.specific_body_force;
300
301 // bodyforce-driven Darcy flow
302 local_rhs.noalias() += dNdx.transpose() * rho_fr * K_over_mu * b * w;
303
304 local_rhs.noalias() -= (biot_coefficient * dv_dt -
305 modulus_rm * _ip_data[ip].coupling_pressure) *
306 N.transpose() * w;
307
308 if ((*_process_data.ele_d)[_element.getID()] <
309 _process_data.irreversible_threshold)
310 {
311 // Fracture-enhanced permeability
312 auto const& normal_ip = _ip_data[ip].normal_ip;
313 auto const Kf =
314 std::pow(1. - d_ip, fracture_permeability_parameter) * width *
315 width * width / he / 12.0 *
316 (Eigen::Matrix<double, DisplacementDim,
317 DisplacementDim>::Identity() -
318 normal_ip * normal_ip.transpose());
319 laplace.noalias() += dNdx.transpose() * Kf / mu * dNdx * w;
320 }
321 }
322 local_Jac.noalias() = laplace + mass / dt + stabilizing / dt;
323
324 local_rhs.noalias() -= laplace * p + mass * (p - p_prev) / dt +
325 stabilizing * (p - p_prev) / dt;
326}
327
328template <typename ShapeFunction, int DisplacementDim>
330 assembleWithJacobianPhaseFieldEquations(double const t, double const dt,
331 Eigen::VectorXd const& local_x,
332 std::vector<double>& local_b_data,
333 std::vector<double>& local_Jac_data)
334{
335 auto const d = local_x.template segment<phasefield_size>(phasefield_index);
336 auto const p = local_x.template segment<pressure_size>(pressure_index);
337 auto const u =
338 local_x.template segment<displacement_size>(displacement_index);
339
341 local_Jac_data, phasefield_size, phasefield_size);
343 local_b_data, phasefield_size);
344
346 x_position.setElementID(_element.getID());
347
348 auto const& solid_material =
350 _process_data.solid_materials, _process_data.material_ids,
351 _element.getID());
352
353 auto const bulk_modulus = solid_material.getBulkModulus(t, x_position);
354 auto const& medium = _process_data.media_map.getMedium(_element.getID());
355 auto const& solid = medium->phase(MaterialPropertyLib::PhaseName::Solid);
357
358 double const k = _process_data.residual_stiffness(t, x_position)[0];
359 double const ls = _process_data.crack_length_scale(t, x_position)[0];
360 double const gc = _process_data.crack_resistance(t, x_position)[0];
361
362 auto const& identity2 = Invariants::identity2;
363
364 int const n_integration_points = _integration_method.getNumberOfPoints();
365 for (int ip = 0; ip < n_integration_points; ip++)
366 {
367 auto const& w = _ip_data[ip].integration_weight;
368 auto const& N = _ip_data[ip].N;
369 auto const& dNdx = _ip_data[ip].dNdx;
370
371 double const d_ip = N.dot(d);
372 double const p_ip = N.dot(p);
373 double const degradation =
374 _process_data.degradation_derivative->degradation(d_ip, k, ls);
375 double const degradation_df1 =
376 _process_data.degradation_derivative->degradationDf1(d_ip, k, ls);
377 double const degradation_df2 =
378 _process_data.degradation_derivative->degradationDf2(d_ip, k, ls);
379
380 _ip_data[ip].updateConstitutiveRelation(
381 t, x_position, dt, u, degradation,
382 _process_data.energy_split_model);
383
384 auto& biot_coefficient = _ip_data[ip].biot_coefficient;
385 auto& biot_modulus_inv = _ip_data[ip].biot_modulus_inv;
386
387 auto const alpha_0 =
389 .template value<double>(vars, x_position, t, dt);
390 auto const porosity_0 =
391 medium->property(MPL::PropertyType::porosity)
392 .template value<double>(vars, x_position, t, dt);
393
394 auto const& D = _ip_data[ip].D;
395 auto const& P_sph = Invariants::spherical_projection;
396 auto const D_sph = P_sph * D * identity2;
397 double const bulk_modulus_eff = Invariants::trace(D_sph) / 9.;
398 double const bulk_modulus_degradation = bulk_modulus_eff / bulk_modulus;
399
400 // Update Biot's coefficient
401 biot_coefficient = 1. - bulk_modulus_degradation * (1. - alpha_0);
402
403 // Update Biot's modulus
404 biot_modulus_inv = bulk_modulus_degradation * (alpha_0 - porosity_0) *
405 (1. - alpha_0) / bulk_modulus;
406
407 auto const& strain_energy_tensile = _ip_data[ip].strain_energy_tensile;
408 auto const& C_tensile = _ip_data[ip].C_tensile;
409 auto const C_tensile_sph = P_sph * C_tensile * identity2;
410 double const bulk_modulus_plus = Invariants::trace(C_tensile_sph) / 9.;
411
412 auto const driven_energy =
413 N.transpose() *
414 (strain_energy_tensile + p_ip * p_ip / 2. * bulk_modulus_plus /
415 bulk_modulus * (alpha_0 - porosity_0) *
416 (1. - alpha_0) / bulk_modulus) *
417 w;
418
419 local_Jac.noalias() += driven_energy * N * degradation_df2;
420
421 local_rhs.noalias() -= driven_energy * degradation_df1;
422
423 calculateCrackLocalJacobianAndResidual<
424 decltype(dNdx), decltype(N), decltype(w), decltype(d),
425 decltype(local_Jac), decltype(local_rhs)>(
426 dNdx, N, w, d, local_Jac, local_rhs, gc, ls,
427 _process_data.phasefield_model);
428 }
429}
430
431template <typename ShapeFunction, int DisplacementDim>
433 postNonLinearSolverConcrete(Eigen::VectorXd const& local_x,
434 Eigen::VectorXd const& local_x_prev,
435 double const /*t*/, double const dt,
436 int const /*process_id*/)
437{
438 int const n_integration_points = _integration_method.getNumberOfPoints();
439 auto const p = local_x.template segment<pressure_size>(pressure_index);
440 auto const p_prev =
441 local_x_prev.template segment<pressure_size>(pressure_index);
442
443 for (int ip = 0; ip < n_integration_points; ip++)
444 {
445 auto const& N = _ip_data[ip].N;
446 _ip_data[ip].coupling_pressure = N.dot(p - p_prev) / dt;
447 }
448}
449
450template <typename ShapeFunction, int DisplacementDim>
453 std::size_t mesh_item_id,
454 std::vector<NumLib::LocalToGlobalIndexMap const*> const& dof_tables,
455 std::vector<GlobalVector*> const& x, double const t,
456 double const /*dt*/)
457{
458 std::vector<std::vector<GlobalIndexType>> indices_of_processes;
459 indices_of_processes.reserve(dof_tables.size());
460 std::transform(dof_tables.begin(), dof_tables.end(),
461 std::back_inserter(indices_of_processes),
462 [&](auto const dof_table)
463 { return NumLib::getIndices(mesh_item_id, *dof_table); });
464
465 auto local_coupled_xs = getCoupledLocalSolutions(x, indices_of_processes);
466 assert(local_coupled_xs.size() ==
468
469 auto const d = Eigen::Map<PhaseFieldVector const>(
470 &local_coupled_xs[phasefield_index], phasefield_size);
471
473 x_position.setElementID(_element.getID());
474
475 double const ele_d = std::clamp(d.sum() / d.size(), 0.0, 1.0);
476 (*_process_data.ele_d)[_element.getID()] = ele_d;
477
478 if ((*_process_data.ele_d)[_element.getID()] <
479 _process_data.irreversible_threshold)
480 {
481 double const width_init = _process_data.width_init(t, x_position)[0];
482 double const k = _process_data.residual_stiffness(t, x_position)[0];
483 double const ls = _process_data.crack_length_scale(t, x_position)[0];
484 double const he = ls / _process_data.diffused_range_parameter;
485
486 int const n_integration_points =
487 _integration_method.getNumberOfPoints();
488 double width = 0.0;
489 for (int ip = 0; ip < n_integration_points; ip++)
490 {
491 auto eps_tensor =
493 Eigen::EigenSolver<decltype(eps_tensor)> eigen_solver(eps_tensor);
494 Eigen::MatrixXf::Index maxIndex;
495 double const max_principal_strain =
496 eigen_solver.eigenvalues().real().maxCoeff(&maxIndex);
497 auto const max_eigen_vector =
498 eigen_solver.eigenvectors().real().col(maxIndex);
499
500 // Fracture aperture estimation
501 auto& width_ip = _ip_data[ip].width_ip;
502 width_ip = max_principal_strain * he;
503 width_ip = width_ip < width_init ? width_init : width_ip;
504 width += width_ip;
505
506 // Fracture direction estimation
507 auto& normal_ip = _ip_data[ip].normal_ip;
508 if (std::abs(max_principal_strain) > k)
509 {
510 for (int i = 0; i < DisplacementDim; i++)
511 {
512 normal_ip[i] = max_eigen_vector[i];
513 }
514 }
515
516 // Fracture enhanced porosity
517 auto& fracture_enhanced_porosity =
518 _ip_data[ip].fracture_enhanced_porosity;
519 fracture_enhanced_porosity = width_ip / he;
520 }
521
522 // Update aperture for the fractured element
523 (*_process_data.width)[_element.getID()] = width / n_integration_points;
524 }
525}
526
527template <typename ShapeFunction, int DisplacementDim>
529 std::size_t mesh_item_id,
530 std::vector<NumLib::LocalToGlobalIndexMap const*> const& dof_tables,
531 std::vector<GlobalVector*> const& x, double const t, double& elastic_energy,
532 double& surface_energy, double& pressure_work)
533{
534 std::vector<std::vector<GlobalIndexType>> indices_of_processes;
535 indices_of_processes.reserve(dof_tables.size());
536 std::transform(dof_tables.begin(), dof_tables.end(),
537 std::back_inserter(indices_of_processes),
538 [&](auto const dof_table)
539 { return NumLib::getIndices(mesh_item_id, *dof_table); });
540
541 auto const local_coupled_xs =
542 getCoupledLocalSolutions(x, indices_of_processes);
543 assert(local_coupled_xs.size() ==
545
546 auto const d = Eigen::Map<PhaseFieldVector const>(
547 &local_coupled_xs[phasefield_index], phasefield_size);
548 auto const u = Eigen::Map<DeformationVector const>(
549 &local_coupled_xs[displacement_index], displacement_size);
550 auto const p = Eigen::Map<PressureVector const>(
551 &local_coupled_xs[pressure_index], pressure_size);
552
554 x_position.setElementID(_element.getID());
555
556 double element_elastic_energy = 0.0;
557 double element_surface_energy = 0.0;
558 double element_pressure_work = 0.0;
559
560 double const gc = _process_data.crack_resistance(t, x_position)[0];
561 double const ls = _process_data.crack_length_scale(t, x_position)[0];
562 int const n_integration_points = _integration_method.getNumberOfPoints();
563 for (int ip = 0; ip < n_integration_points; ip++)
564 {
565 auto const& w = _ip_data[ip].integration_weight;
566 auto const& N = _ip_data[ip].N;
567 auto const& dNdx = _ip_data[ip].dNdx;
568 double const d_ip = N.dot(d);
569 double const p_ip = N.dot(p);
570
571 element_elastic_energy += _ip_data[ip].elastic_energy * w;
572
573 switch (_process_data.phasefield_model)
574 {
576 {
577 element_surface_energy +=
578 gc * 0.375 *
579 ((1 - d_ip) / ls + (dNdx * d).dot((dNdx * d)) * ls) * w;
580
581 break;
582 }
584 {
585 element_surface_energy += 0.5 * gc *
586 ((1 - d_ip) * (1 - d_ip) / ls +
587 (dNdx * d).dot((dNdx * d)) * ls) *
588 w;
589 break;
590 }
592 {
593 element_surface_energy +=
594 gc / std::numbers::pi *
595 ((1 - d_ip * d_ip) / ls + (dNdx * d).dot((dNdx * d)) * ls) *
596 w;
597 break;
598 }
599 }
600
601 element_pressure_work += p_ip * (N_u_op(N) * u).dot(dNdx * d) * w;
602 }
603
604#ifdef USE_PETSC
605 int const n_all_nodes = indices_of_processes[1].size();
606 int const n_regular_nodes = std::count_if(
607 begin(indices_of_processes[1]), end(indices_of_processes[1]),
608 [](GlobalIndexType const& index) { return index >= 0; });
609 if (n_all_nodes != n_regular_nodes)
610 {
611 element_elastic_energy *=
612 static_cast<double>(n_regular_nodes) / n_all_nodes;
613 element_surface_energy *=
614 static_cast<double>(n_regular_nodes) / n_all_nodes;
615 element_pressure_work *=
616 static_cast<double>(n_regular_nodes) / n_all_nodes;
617 }
618#endif // USE_PETSC
619 elastic_energy += element_elastic_energy;
620 surface_energy += element_surface_energy;
621 pressure_work += element_pressure_work;
622}
623
624template <typename ShapeFunction, int DisplacementDim>
625std::vector<double> const&
627 const double /*t*/,
628 std::vector<GlobalVector*> const& /*x*/,
629 std::vector<NumLib::LocalToGlobalIndexMap const*> const& /*dof_table*/,
630 std::vector<double>& cache) const
631{
633 &IpData::width_ip, cache);
634}
635} // namespace HMPhaseField
636} // namespace ProcessLib
GlobalMatrix::IndexType GlobalIndexType
void setElementID(std::size_t element_id)
std::optional< MathLib::Point3d > const getCoordinates() const
MatrixType< _kelvin_vector_size, _number_of_dof > BMatrixType
void approximateFractureWidth(std::size_t mesh_item_id, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_tables, std::vector< GlobalVector * > const &x, double const t, double const dt) override
std::vector< IpData, Eigen::aligned_allocator< IpData > > _ip_data
void computeEnergy(std::size_t mesh_item_id, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_tables, std::vector< GlobalVector * > const &x, double const t, double &elastic_energy, double &surface_energy, double &pressure_work) override
void assembleWithJacobianForStaggeredScheme(double const t, double const dt, Eigen::VectorXd const &local_x, Eigen::VectorXd const &local_x_prev, int const process_id, std::vector< double > &local_b_data, std::vector< double > &local_Jac_data) override
HMPhaseFieldProcessData< DisplacementDim > & _process_data
void postNonLinearSolverConcrete(Eigen::VectorXd const &local_x, Eigen::VectorXd const &local_x_prev, double const t, double const dt, int const process_id) override
std::vector< double > const & getIntPtWidth(const double, std::vector< GlobalVector * > const &, std::vector< NumLib::LocalToGlobalIndexMap const * > const &, std::vector< double > &cache) const override
ShapeMatrixPolicyType< ShapeFunction, DisplacementDim > ShapeMatricesType
void assembleWithJacobianPhaseFieldEquations(double const t, double const dt, Eigen::VectorXd const &local_x, std::vector< double > &local_b_data, std::vector< double > &local_Jac_data)
void assembleWithJacobianHydroEquations(const double t, double const dt, Eigen::VectorXd const &local_x, Eigen::VectorXd const &local_x_prev, std::vector< double > &local_b_data, std::vector< double > &local_Jac_data)
void assembleWithJacobianForDeformationEquations(double const t, double const dt, Eigen::VectorXd const &local_x, std::vector< double > &local_b_data, std::vector< double > &local_Jac_data)
NumLib::GenericIntegrationMethod const & _integration_method
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, 3, 3 > kelvinVectorToTensor(Eigen::Matrix< double, 4, 1, Eigen::ColMajor, 4, 1 > const &v)
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::array< double, 3 > interpolateCoordinates(MeshLib::Element const &e, typename ShapeMatricesType::ShapeMatrices::ShapeType const &N)
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.
std::vector< double > const & getIntegrationPointScalarData(IntegrationPointDataVector const &ip_data_vector, MemberType IpData::*const member, std::vector< double > &cache)
std::vector< double > getCoupledLocalSolutions(std::vector< GlobalVector * > const &global_solutions, std::vector< std::vector< GlobalIndexType > > const &indices)
MatrixType< ShapeFunction::NPOINTS, ShapeFunction::NPOINTS > NodalMatrixType
static Eigen::Matrix< double, KelvinVectorSize, KelvinVectorSize > const spherical_projection
static double FrobeniusNorm(Eigen::Matrix< double, KelvinVectorSize, 1 > const &deviatoric_v)
Get the norm of the deviatoric stress.
static Eigen::Matrix< double, KelvinVectorSize, 1 > const identity2
Kelvin mapping of 2nd order identity tensor.
static Eigen::Matrix< double, KelvinVectorSize, KelvinVectorSize > const deviatoric_projection
static Eigen::Matrix< double, KelvinVectorSize, 1 > const ones2
static double trace(Eigen::Matrix< double, KelvinVectorSize, 1 > const &v)
Trace of the corresponding tensor.