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