diff --git a/src/model/phase_field/phasefields/phasefield_exponential.cc b/src/model/phase_field/phasefields/phasefield_exponential.cc index 653ab3e07..cdf434bba 100644 --- a/src/model/phase_field/phasefields/phasefield_exponential.cc +++ b/src/model/phase_field/phasefields/phasefield_exponential.cc @@ -1,153 +1,152 @@ /** * Copyright (©) 2020-2023 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * This file is part of Akantu * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. */ /* -------------------------------------------------------------------------- */ #include "phasefield_exponential.hh" #include "aka_common.hh" #include <tuple> namespace akantu { /* -------------------------------------------------------------------------- */ PhaseFieldExponential::PhaseFieldExponential(PhaseFieldModel & model, const ID & id) : PhaseField(model, id) {} /* -------------------------------------------------------------------------- */ void PhaseFieldExponential::updateInternalParameters() { PhaseField::updateInternalParameters(); for (const auto & type : element_filter.elementTypes(spatial_dimension, _not_ghost)) { for (auto && tuple : zip(make_view(this->damage_energy(type, _not_ghost), spatial_dimension, spatial_dimension), this->g_c(type, _not_ghost))) { Matrix<Real> d = Matrix<Real>::Identity(spatial_dimension, spatial_dimension) * std::get<1>(tuple) * this->l0; std::get<0>(tuple) = d; } } } /* -------------------------------------------------------------------------- */ void PhaseFieldExponential::computeDrivingForce(ElementType el_type, GhostType ghost_type) { if (this->isotropic) { for (auto && tuple : zip(this->phi(el_type, ghost_type), this->phi.previous(el_type, ghost_type), make_view(this->strain(el_type, ghost_type), spatial_dimension, spatial_dimension))) { auto & phi_quad = std::get<0>(tuple); auto & phi_hist_quad = std::get<1>(tuple); auto & strain = std::get<2>(tuple); computePhiIsotropicOnQuad(strain, phi_quad, phi_hist_quad); } } else { for (auto && tuple : zip(this->phi(el_type, ghost_type), this->phi.previous(el_type, ghost_type), make_view(this->strain(el_type, ghost_type), spatial_dimension, spatial_dimension))) { auto & phi_quad = std::get<0>(tuple); auto & phi_hist_quad = std::get<1>(tuple); auto & strain = std::get<2>(tuple); computePhiOnQuad(strain, phi_quad, phi_hist_quad); } } for (auto && tuple : zip(this->phi(el_type, ghost_type), this->driving_force(el_type, ghost_type), this->damage_energy_density(el_type, ghost_type), this->damage_on_qpoints(el_type, _not_ghost), make_view(this->driving_energy(el_type, ghost_type), spatial_dimension), make_view(this->damage_energy(el_type, ghost_type), spatial_dimension, spatial_dimension), make_view(this->gradd(el_type, ghost_type), spatial_dimension), this->g_c(el_type, ghost_type))) { auto & phi_quad = std::get<0>(tuple); auto & driving_force_quad = std::get<1>(tuple); auto & dam_energy_density_quad = std::get<2>(tuple); auto & dam_on_quad = std::get<3>(tuple); auto & driving_energy_quad = std::get<4>(tuple); auto & damage_energy_quad = std::get<5>(tuple); auto & gradd_quad = std::get<6>(tuple); auto & g_c_quad = std::get<7>(tuple); computeDamageEnergyDensityOnQuad(phi_quad, dam_energy_density_quad, g_c_quad); driving_force_quad = dam_on_quad * dam_energy_density_quad - 2 * phi_quad; driving_energy_quad = damage_energy_quad * gradd_quad; } } - /* -------------------------------------------------------------------------- */ void PhaseFieldExponential::computeDissipatedEnergy(ElementType el_type) { AKANTU_DEBUG_IN(); for (auto && tuple : zip(this->dissipated_energy(el_type, _not_ghost), this->damage_on_qpoints(el_type, _not_ghost), make_view(this->gradd(el_type, _not_ghost), spatial_dimension), this->g_c(el_type, _not_ghost))) { this->computeDissipatedEnergyOnQuad(std::get<1>(tuple), std::get<2>(tuple), std::get<0>(tuple), std::get<3>(tuple)); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void PhaseFieldExponential::computeDissipatedEnergyByElement( ElementType type, Idx index, Vector<Real> & edis_on_quad_points) { auto gradd_it = this->gradd(type).begin(spatial_dimension); auto gradd_end = this->gradd(type).begin(spatial_dimension); auto damage_it = this->damage_on_qpoints(type).begin(); auto g_c_it = this->g_c(type).begin(); UInt nb_quadrature_points = fem.getNbIntegrationPoints(type); gradd_it += index * nb_quadrature_points; gradd_end += (index + 1) * nb_quadrature_points; damage_it += index * nb_quadrature_points; g_c_it += index * nb_quadrature_points; Real * edis_quad = edis_on_quad_points.data(); for (; gradd_it != gradd_end; ++gradd_it, ++damage_it, ++edis_quad) { this->computeDissipatedEnergyOnQuad(*damage_it, *gradd_it, *edis_quad, *g_c_it); } } void PhaseFieldExponential::computeDissipatedEnergyByElement( const Element & element, Vector<Real> & edis_on_quad_points) { computeDissipatedEnergyByElement(element.type, element.element, edis_on_quad_points); } INSTANTIATE_PHASEFIELD(exponential, PhaseFieldExponential); } // namespace akantu diff --git a/src/model/solid_mechanics/materials/material_damage/material_phasefield.cc b/src/model/solid_mechanics/materials/material_damage/material_phasefield.cc index 0938837e9..4215cd26b 100644 --- a/src/model/solid_mechanics/materials/material_damage/material_phasefield.cc +++ b/src/model/solid_mechanics/materials/material_damage/material_phasefield.cc @@ -1,101 +1,99 @@ /** * Copyright (©) 2010-2023 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * This file is part of Akantu * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. */ /* -------------------------------------------------------------------------- */ #include "material_phasefield.hh" #include "aka_common.hh" #include "solid_mechanics_model.hh" namespace akantu { /* -------------------------------------------------------------------------- */ template <Int dim> MaterialPhaseField<dim>::MaterialPhaseField(SolidMechanicsModel & model, const ID & id) : Parent(model, id), effective_damage("effective_damage", *this) { this->registerParam("eta", eta, Real(0.), _pat_parsable, "eta"); this->registerParam("is_hybrid", is_hybrid, false, - _pat_parsable | _pat_readable, - "Use hybrid formulation"); + _pat_parsable | _pat_readable, "Use hybrid formulation"); this->damage.initialize(0); this->effective_damage.initialize(1); } /* -------------------------------------------------------------------------- */ template <Int dim> void MaterialPhaseField<dim>::computeStress(ElementType el_type, GhostType ghost_type) { if (this->is_hybrid) { computeEffectiveDamage(el_type, ghost_type); for (auto && args : getArguments(el_type, ghost_type)) { auto && dam = args["effective_damage"_n]; computeStressOnQuad(tuple::replace(args, "damage"_n = dam)); } } else { for (auto && args : getArguments(el_type, ghost_type)) { computeStressOnQuad(args); } } } /* -------------------------------------------------------------------------- */ template <Int dim> void MaterialPhaseField<dim>::computeTangentModuli(ElementType el_type, Array<Real> & tangent_matrix, GhostType ghost_type) { computeEffectiveDamage(el_type, ghost_type); if (this->is_hybrid) { computeEffectiveDamage(el_type, ghost_type); for (auto && args : getArgumentsTangent(tangent_matrix, el_type, ghost_type)) { auto && dam = args["effective_damage"_n]; computeTangentModuliOnQuad(tuple::replace(args, "damage"_n = dam)); } } else { for (auto && args : getArgumentsTangent(tangent_matrix, el_type, ghost_type)) { computeTangentModuliOnQuad(args); } } } - /* -------------------------------------------------------------------------- */ template <Int dim> void MaterialPhaseField<dim>::computeEffectiveDamage(ElementType el_type, GhostType ghost_type) { for (auto && args : getArguments(el_type, ghost_type)) { computeEffectiveDamageOnQuad(args); } } /* -------------------------------------------------------------------------- */ template class MaterialPhaseField<1>; template class MaterialPhaseField<2>; template class MaterialPhaseField<3>; static bool material_is_allocated_phasefield = instantiateMaterial<MaterialPhaseField>("phasefield"); } // namespace akantu