22template <
typename ShapeFunction,
int DisplacementDim>
25 double const t,
double const dt, Eigen::VectorXd
const& local_x,
26 Eigen::VectorXd
const& ,
int const process_id,
27 std::vector<double>& local_b_data, std::vector<double>& local_Jac_data)
42template <
typename ShapeFunction,
int DisplacementDim>
45 double const t,
double const dt, Eigen::VectorXd
const& local_x,
46 std::vector<double>& local_b_data, std::vector<double>& local_Jac_data)
48 using DeformationMatrix =
64 auto local_pressure = 0.0;
71 for (
int ip = 0; ip < n_integration_points; ip++)
73 auto const& w =
_ip_data[ip].integration_weight;
75 auto const& dNdx =
_ip_data[ip].dNdx;
83 ShapeFunction::NPOINTS,
88 eps.noalias() = B * u;
89 double const k =
_process_data.residual_stiffness(t, x_position)[0];
90 double const ls =
_process_data.crack_length_scale(t, x_position)[0];
91 double const d_ip = N.dot(d);
92 double const degradation =
93 _process_data.degradation_derivative->degradation(d_ip, k, ls);
94 _ip_data[ip].updateConstitutiveRelation(
95 t, x_position, dt, u, degradation,
101 typename ShapeMatricesType::template MatrixType<DisplacementDim,
103 N_u = ShapeMatricesType::template MatrixType<
107 for (
int i = 0; i < DisplacementDim; ++i)
114 auto const rho_sr =
_process_data.solid_density(t, x_position)[0];
117 local_rhs.noalias() -=
118 (B.transpose() * sigma - N_u.transpose() * rho_sr * b -
119 local_pressure * N_u.transpose() * dNdx * d) *
121 local_Jac.noalias() += B.transpose() * D * B * w;
125template <
typename ShapeFunction,
int DisplacementDim>
128 Eigen::VectorXd
const& local_x,
129 std::vector<double>& local_b_data,
130 std::vector<double>& local_Jac_data)
144 auto local_pressure = 0.0;
154 double const k =
_process_data.residual_stiffness(t, x_position)[0];
155 double const ls =
_process_data.crack_length_scale(t, x_position)[0];
156 double const gc =
_process_data.crack_resistance(t, x_position)[0];
159 for (
int ip = 0; ip < n_integration_points; ip++)
161 auto const& w =
_ip_data[ip].integration_weight;
163 auto const& dNdx =
_ip_data[ip].dNdx;
165 double const d_ip = N.dot(d);
166 double const degradation =
167 _process_data.degradation_derivative->degradation(d_ip, k, ls);
168 double const degradation_df1 =
169 _process_data.degradation_derivative->degradationDf1(d_ip, k, ls);
170 double const degradation_df2 =
171 _process_data.degradation_derivative->degradationDf2(d_ip, k, ls);
177 ShapeFunction::NPOINTS,
182 eps.noalias() = B * u;
183 _ip_data[ip].updateConstitutiveRelation(
184 t, x_position, dt, u, degradation,
187 auto const& strain_energy_tensile =
_ip_data[ip].strain_energy_tensile;
190 ip_data.strain_energy_tensile = strain_energy_tensile;
192 typename ShapeMatricesType::template MatrixType<DisplacementDim,
194 N_u = ShapeMatricesType::template MatrixType<
198 for (
int i = 0; i < DisplacementDim; ++i)
205 local_Jac.noalias() +=
206 (N.transpose() * N * degradation_df2 * strain_energy_tensile) * w;
208 local_rhs.noalias() -=
209 (N.transpose() * degradation_df1 * strain_energy_tensile -
210 local_pressure * dNdx.transpose() * N_u * u) *
213 calculateCrackLocalJacobianAndResidual<
214 decltype(dNdx),
decltype(N),
decltype(w),
decltype(d),
215 decltype(local_Jac),
decltype(local_rhs)>(
216 dNdx, N, w, d, local_Jac, local_rhs, gc, ls,
221template <
typename ShapeFunction,
int DisplacementDim>
224 std::size_t mesh_item_id,
225 std::vector<NumLib::LocalToGlobalIndexMap const*>
const& dof_tables,
226 std::vector<GlobalVector*>
const& x,
double const ,
227 double& crack_volume)
229 std::vector<std::vector<GlobalIndexType>> indices_of_processes;
230 indices_of_processes.reserve(dof_tables.size());
231 std::transform(dof_tables.begin(), dof_tables.end(),
232 std::back_inserter(indices_of_processes),
233 [&](
auto const dof_table)
234 { return NumLib::getIndices(mesh_item_id, *dof_table); });
239 auto const d = Eigen::Map<PhaseFieldVector const>(
241 auto const u = Eigen::Map<DeformationVector const>(
248 for (
int ip = 0; ip < n_integration_points; ip++)
250 auto const& w =
_ip_data[ip].integration_weight;
252 auto const& dNdx =
_ip_data[ip].dNdx;
254 typename ShapeMatricesType::template MatrixType<DisplacementDim,
256 N_u = ShapeMatricesType::template MatrixType<
260 for (
int i = 0; i < DisplacementDim; ++i)
267 crack_volume += (N_u * u).dot(dNdx * d) * w;
271template <
typename ShapeFunction,
int DisplacementDim>
273 std::size_t mesh_item_id,
274 std::vector<NumLib::LocalToGlobalIndexMap const*>
const& dof_tables,
275 std::vector<GlobalVector*>
const& x,
double const t,
double& elastic_energy,
276 double& surface_energy,
double& pressure_work)
278 std::vector<std::vector<GlobalIndexType>> indices_of_processes;
279 indices_of_processes.reserve(dof_tables.size());
280 std::transform(dof_tables.begin(), dof_tables.end(),
281 std::back_inserter(indices_of_processes),
282 [&](
auto const dof_table)
283 { return NumLib::getIndices(mesh_item_id, *dof_table); });
285 auto const local_coupled_xs =
289 auto const d = Eigen::Map<PhaseFieldVector const>(
291 auto const u = Eigen::Map<DeformationVector const>(
297 double element_elastic_energy = 0.0;
298 double element_surface_energy = 0.0;
299 double element_pressure_work = 0.0;
301 double const gc =
_process_data.crack_resistance(t, x_position)[0];
302 double const ls =
_process_data.crack_length_scale(t, x_position)[0];
304 for (
int ip = 0; ip < n_integration_points; ip++)
306 auto const& w =
_ip_data[ip].integration_weight;
308 auto const& dNdx =
_ip_data[ip].dNdx;
311 typename ShapeMatricesType::template MatrixType<DisplacementDim,
313 N_u = ShapeMatricesType::template MatrixType<
317 for (
int i = 0; i < DisplacementDim; ++i)
324 element_elastic_energy +=
_ip_data[ip].elastic_energy * w;
326 double const d_ip = N.dot(d);
331 element_surface_energy +=
333 ((1 - d_ip) / ls + (dNdx * d).dot((dNdx * d)) * ls) * w;
339 element_surface_energy += 0.5 * gc *
340 ((1 - d_ip) * (1 - d_ip) / ls +
341 (dNdx * d).dot((dNdx * d)) * ls) *
347 element_surface_energy +=
348 gc / std::numbers::pi *
349 ((1 - d_ip * d_ip) / ls + (dNdx * d).dot((dNdx * d)) * ls) *
357 element_pressure_work += pressure_ip * (N_u * u).dot(dNdx * d) * w;
362 int const n_all_nodes = indices_of_processes[1].size();
363 int const n_regular_nodes = std::count_if(
364 begin(indices_of_processes[1]), end(indices_of_processes[1]),
366 if (n_all_nodes != n_regular_nodes)
368 element_elastic_energy *=
369 static_cast<double>(n_regular_nodes) / n_all_nodes;
370 element_surface_energy *=
371 static_cast<double>(n_regular_nodes) / n_all_nodes;
372 element_pressure_work *=
373 static_cast<double>(n_regular_nodes) / n_all_nodes;
376 elastic_energy += element_elastic_energy;
377 surface_energy += element_surface_energy;
378 pressure_work += element_pressure_work;
381template <
typename ShapeFunctionDisplacement,
int DisplacementDim>
383 ShapeFunctionDisplacement,
385 double const* values,
386 int const integration_order)
388 if (integration_order !=
392 "Setting integration point initial conditions; The integration "
393 "order of the local assembler for element {:d} is different from "
394 "the integration order in the initial condition.",
403 "Setting initial conditions for stress from integration "
404 "point data and from a parameter '{:s}' is not possible "
416template <
typename ShapeFunctionDisplacement,
int DisplacementDim>
424template <
typename ShapeFunctionDisplacement,
int DisplacementDim>
428 auto const kelvin_vector_size =
430 unsigned const n_integration_points =
433 std::vector<double> ip_epsilon_values;
435 double, Eigen::Dynamic, kelvin_vector_size, Eigen::RowMajor>>(
436 ip_epsilon_values, n_integration_points, kelvin_vector_size);
438 for (
unsigned ip = 0; ip < n_integration_points; ++ip)
445 return ip_epsilon_values;
GlobalMatrix::IndexType GlobalIndexType
void setElementID(std::size_t element_id)
MatrixType< _kelvin_vector_size, _number_of_dof > BMatrixType
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
static constexpr int phasefield_size
static const int phase_process_id
PhaseFieldProcessData< DisplacementDim > & _process_data
static constexpr int displacement_index
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)
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)
MeshLib::Element const & _element
NumLib::GenericIntegrationMethod const & _integration_method
static constexpr int displacement_size
std::vector< IpData, Eigen::aligned_allocator< IpData > > _ip_data
static constexpr int phasefield_index
bool const _is_axially_symmetric
void computeCrackIntegral(std::size_t mesh_item_id, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_tables, std::vector< GlobalVector * > const &x, double const t, double &crack_volume) override
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
std::vector< double > getSigma() const override
std::vector< double > getEpsilon() const override
Eigen::Matrix< double, 4, 1 > kelvinVectorToSymmetricTensor(Eigen::Matrix< double, 4, 1, Eigen::ColMajor, 4, 1 > const &v)
constexpr int kelvin_vector_dimensions(int const displacement_dim)
Kelvin vector dimensions for given displacement dimension.
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)
double interpolateXCoordinate(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 > getCoupledLocalSolutions(std::vector< GlobalVector * > const &global_solutions, std::vector< std::vector< GlobalIndexType > > const &indices)
std::vector< double > const & getIntegrationPointKelvinVectorData(IntegrationPointDataVector const &ip_data_vector, MemberType IpData::*const member, std::vector< double > &cache)
std::size_t setIntegrationPointKelvinVectorData(double const *values, IntegrationPointDataVector &ip_data_vector, MemberType IpData::*const member)
void setIPDataInitialConditions(std::vector< std::unique_ptr< MeshLib::IntegrationPointWriter > > const &_integration_point_writer, MeshLib::Properties const &mesh_properties, LocalAssemblersVector &local_assemblers)
BMatricesType::KelvinVectorType sigma