diff --git a/src/materials/material_crystal_plasticity_finite.cc b/src/materials/material_crystal_plasticity_finite.cc index bf65eeb..b8767f7 100644 --- a/src/materials/material_crystal_plasticity_finite.cc +++ b/src/materials/material_crystal_plasticity_finite.cc @@ -1,45 +1,68 @@ /** * @file material_crystal_plasticity_finite.cc * * @author Till Junge * @author Francesco Maresca * * @date 23 Feb 2018 * * @brief finite strain crystal plasticity implementation * * Copyright © 2018 Till Junge, Francesco Maresca * * µSpectre is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3, or (at * your option) any later version. * * µSpectre 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 * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Emacs; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "materials/material_crystal_plasticity_finite.hh" namespace muSpectre { template MaterialCrystalPlasticityFinite:: MaterialCrystalPlasticityFinite(std::string name, Real bulk_m, Real shear_m, Real gammadot0, Real m_par, Real tauy0, Real h0, Real s_infty, Real a_par, Real q_n, SlipVecs_ref Slip0, SlipVecs_ref Normal0) : Parent{name}, FpField("Plastic Deformation Gradient Fₚ(t)",this->internal_fields), GammadotField("Plastic slip rates dγᵅ/dt",this->internal_fields), TauyField("Critical resolved shear stress τᵅy(t)",this->internal_fields), GammaField("Accumulated slips γᵅ(t)",this->internal_fields), + EulerField("Euler angles", this->internal_fields), bulk_m{bulk_m}, shear_m{shear_m}, gammadot_0{gammadot_0}, m_par{m_par}, tauy0{tauy0}, h0{h0}, - s_infty{s_infty}, a_par{a_par}, q_n{q_n}, Slip0{Slip0}, Normal0{Normal0}; - {} + s_infty{s_infty}, a_par{a_par}, q_n{q_n}, Slip0{Slip0}, Normal0{Normal0} + { + // Enforce n_0 and s_0 to be unit vectors! + Real lambda{Converter::compute(bulk_m,shear_m)}; + this->C_el=Hooke::compute_C_T4(lambda,shear_m); + } + + template + void MaterialCrystalPlasticityFinite:: + add_pixel(const Ccoord_t & pixel) { + throw std::runtime_error + ("this material needs pixels with matrix of Euler angles"); + } + + template + void MaterialCrystalPlasticityFinite:: + add_pixel(const Ccoord_t & pixel, + const Eigen::Ref> Euler){ + this->internal_fields.add_pixel(pixel); + this->EulerField.push_back(Euler); + } + + + } // muSpectre diff --git a/src/materials/material_crystal_plasticity_finite.hh b/src/materials/material_crystal_plasticity_finite.hh index a2daa81..a3ef7ed 100644 --- a/src/materials/material_crystal_plasticity_finite.hh +++ b/src/materials/material_crystal_plasticity_finite.hh @@ -1,239 +1,271 @@ /** * @file material_crystal_plasticity_finite.hh * * @author Till Junge * @author Francesco Maresca * * @date 23 Feb 2018 * * @brief finite strain crystal plasticity implementation * * Copyright © 2018 Till Junge, Francesco Maresca * * µSpectre is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3, or (at * your option) any later version. * * µSpectre 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 * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Emacs; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef MATERIAL_CRYSTAL_PLASTICITY_FINITE_H #define MATERIAL_CRYSTAL_PLASTICITY_FINITE_H #include "materials/material_muSpectre_base.hh" #include "common/field.hh" #include namespace muSpectre { template class MaterialCrystalPlasticityFinite; /** * traits for objective linear elasticity with eigenstrain */ template struct MaterialMuSpectre_traits> { //! global field collection using GFieldCollection_t = typename MaterialBase::GFieldCollection_t; //! expected map type for strain fields using StrainMap_t = MatrixFieldMap; //! expected map type for stress fields using StressMap_t = MatrixFieldMap; //! expected map type for tangent stiffness fields using TangentMap_t = T4MatrixFieldMap; //! declare what type of strain measure your law takes as input constexpr static auto strain_measure{StrainMeasure::Gradient}; //! declare what type of stress measure your law yields as output constexpr static auto stress_measure{StressMeasure::PK2}; //! declare internal variables //! local field_collections used for internals using LFieldColl_t = LocalFieldCollection; //! plastic deformation gradient Fₚ(t) using FpMap_t = StateFieldMap>; //! plastic slip rates dγᵅ/dt using GammadotMap_t = StateFieldMap>; //! critical resolved shear stresses (CRSS) τᵅy(t) using TauyMap_t = GammadotMap_t; //! plastic slips γᵅ(t) using GammaMap_t = MatrixFieldMap; //! euler angles using EulerMap_t = ArrayFieldMap; using InternalVariables = std::tuple; }; /** * implements finite strain crystal plasticity */ template class MaterialCrystalPlasticityFinite: public MaterialMuSpectre, DimS, DimM> { public: //! base class using Parent = MaterialMuSpectre; //! type for stiffness tensor construction using Stiffness_t = Eigen::TensorFixedSize >; //! traits of this material using traits = MaterialMuSpectre_traits; //! Type of container used for storing eigenstrain using InternalVariables = typename traits::InternalVariables; //! Hooke's law implementation using Hooke = typename MatTB::Hooke; //! Type in which plastic deformation gradient is referenced using Fp_ref = typename traits::FpMap_t::reference; //! Type in which slip rates are referenced using Gammadot_ref = typename traits::GammadotMap_t::reference; //! Type in which CRSS are referenced using Tauy_ref = typename traits::TauyMap_t::reference; //! Type in which accumulated slips are referenced using Gamma_ref = typename traits::GammaMap_t::reference; //! Type in which Euler angles are referenced using Euler_ref = typename traits::EulerMap_t::reference; //! Type in which slip directions and normals are given using SlipVecs = Eigen::Matrix; using SlipVecs_ref = Eigen::Ref; + //! Type for second rank tensors + using T2_t = Eigen::Matrix; + //! Type for fourth rank tensors + using T4_t = T4Mat; //! Default constructor MaterialCrystalPlasticityFinite() = delete; //! Construct by name, Bulk modulus, Shear modulus, Reference slip rate, Strain rate sensitivity, Initial CRSS, Initial hardening modulus, CRSS saturation value, Hardening exponent, Latent/Self-hardening ratio, Slip directions, Slip normals MaterialCrystalPlasticityFinite(std::string name, Real bulk_m, Real shear_m, Real gammadot0, Real m_par, Real tauy0, Real h0, Real s_infty, Real a_par, Real q_n, SlipVecs_ref Slip0, SlipVecs_ref Normal0); //! Copy constructor MaterialCrystalPlasticityFinite(const MaterialCrystalPlasticityFinite &other) = delete; //! Move constructor MaterialCrystalPlasticityFinite(MaterialCrystalPlasticityFinite &&other) = delete; //! Destructor virtual ~MaterialCrystalPlasticityFinite() = default; //! Copy assignment operator MaterialCrystalPlasticityFinite& operator=(const MaterialCrystalPlasticityFinite &other) = delete; //! Move assignment operator MaterialCrystalPlasticityFinite& operator=(MaterialCrystalPlasticityFinite &&other) = delete; /** * evaluates second Piola-Kirchhoff stress given the Deformation Gradient */ template inline decltype(auto) evaluate_stress(s_t && F, Fp_ref Fp, Gammadot_ref Gammadot, Tauy_ref Tauy, Gamma_ref Gamma, Euler_ref Euler); /** * evaluates both second Piola-Kirchhoff stress and stiffness given * the Deformation Gradient */ template inline decltype(auto) evaluate_stress_tangent(s_t && F, Fp_ref Fp, Gammadot_ref Gammadot, Tauy_ref Tauy, Gamma_ref Gamma, Euler_ref Euler); /** * return the internals tuple */ InternalVariables & get_internals() { return this->internal_variables;}; /** * overload add_pixel to write into eigenstrain */ void add_pixel(const Ccoord_t & pixel) override final; /** * overload add_pixel to write into eigenstrain */ void add_pixel(const Ccoord_t & pixel, - const Eigen::Ref> Euler); + const Eigen::Ref> Euler); protected: + constexpr static Int nb_euler{(DimM==3) ? 3 : 1}; //! Storage for Fp using FpField_t = - TensorField; + StateField>; FpField_t & FpField; //! Storage for gammadot using GammadotField_t = StateField>; GammadotField_t & GammadotField; //! Storage for tauy using TauyField_t = GamadotField_t; TauyField_t & TauyField; //! Storage for gamma using GammaField_t = MatrixField; GammaField_t & GammaField; + using EulerField_t = + ArrayField; + EulerField_t & EulerField; //! bulk modulus Real bulk_m; Real shear_m; Real gammadot0; Real m_par; Real tauy0; Real h0; Real s_infty; Real a_par; Real q_n; //! Storage for slip directions alignas(16) Eigen::Matrix Slip0; //! Storage for slip plane normals alignas(16) Eigen::Matrix Normal0; - + T4_t C_el; + //! tuple for iterable eigen_field InternalVariables internal_variables; private: }; /* ---------------------------------------------------------------------- */ template - template + template decltype(auto) MaterialCrystalPlasticityFinite:: - evaluate_stress(s_t && E, eigen_s_t && E_eig) { - return this->material.evaluate_stress(E-E_eig); + evaluate_stress(s_t && F, Fp_ref Fp, Gammadot_ref Gammadot, Tauy_ref Tauy, Gamma_ref Gamma, Euler_ref Euler) { + Rotator Rot(Euler); + T2_t Floc{Rot.glob_to_loc(F)}; + std::array SchmidT; + for (Int i{0}; i < nb_slip; ++i) { + SchmidT[i]=this->Slip0.col(i)*this->Normal0.col(i).transpose(); + } + + // trial elastic deformation + T2_t Fe_star{Floc*Fp.old().inverse()}; + T2_t CGe_star{Fe_star.transpose()*Fe_star}; + T2_t GLe_star{.5*(CGe_star - T2_t::Identity())}; + T2_t SPK_star{Matrices::tensmult(C_el,GLe_star)}; + + std::array tau_star; + // pl_corr is the plastic corrector + std::array pl_corr; + Eigen::Matrix pl_corr_proj; + for (Int i{0}; i < nb_slip; ++i) { + tau_star[i]=(CGe_star*SPK_star*SchmidT[i].transpose()).trace(); + pl_corr[i]=tensmult(C_el,.5*(CGe_star*SchmidT[i]+SchmidT[i].transpose()*CGe_star)); + for (Int j{0}; j < nb_slip; ++j) { + pl_corr_proj(i,j)=(C_el*pl_corr[i]*SchmidT[j].transpose()).trace(); + } + } } /* ---------------------------------------------------------------------- */ template template decltype(auto) MaterialCrystalPlasticityFinite:: evaluate_stress_tangent(s_t && E, eigen_s_t && E_eig) { // using mat = Eigen::Matrix; // mat ecopy{E}; // mat eig_copy{E_eig}; // mat ediff{ecopy-eig_copy}; // std::cout << "eidff - (E-E_eig)" << std::endl << ediff-(E-E_eig) << std::endl; // std::cout << "P1 " << std::endl << mat{std::get<0>(this->material.evaluate_stress_tangent(E-E_eig))} << "" << std::endl; // std::cout << "P2" << std::endl << mat{std::get<0>(this->material.evaluate_stress_tangent(std::move(ediff)))} << std::endl; return this->material.evaluate_stress_tangent(E-E_eig); } } // muSpectre #endif /* MATERIAL_CRYSTAL_PLASTICITY_FINITE_H */