diff --git a/src/model/solid_mechanics/material.hh b/src/model/solid_mechanics/material.hh index 86fbcbe90..b83471f38 100644 --- a/src/model/solid_mechanics/material.hh +++ b/src/model/solid_mechanics/material.hh @@ -1,525 +1,529 @@ /** * @file material.hh * @author Nicolas Richart <nicolas.richart@epfl.ch> * @date Fri Jul 23 09:06:29 2010 * * @brief Mother class for all materials * * @section LICENSE * * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * 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 "aka_common.hh" #include "aka_memory.hh" #include "parser.hh" //#include "mesh.hh" #include "data_accessor.hh" //#include "static_communicator.hh" #include "material_parameters.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_HH__ #define __AKANTU_MATERIAL_HH__ /* -------------------------------------------------------------------------- */ namespace akantu { class Model; class SolidMechanicsModel; class CommunicationBuffer; } __BEGIN_AKANTU__ /** * Interface of all materials * Prerequisites for a new material * - inherit from this class * - implement the following methods: * \code * virtual Real getStableTimeStep(Real h, const Element & element = ElementNull); * * virtual void computeStress(ElementType el_type, * GhostType ghost_type = _not_ghost); * * virtual void computeTangentStiffness(const ElementType & el_type, * Vector<Real> & tangent_matrix, * GhostType ghost_type = _not_ghost); * \endcode * */ class Material : protected Memory, public DataAccessor, public Parsable { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: Material(SolidMechanicsModel & model, const ID & id = ""); virtual ~Material(); /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// register a material parameter template<class T> void registerParam(std::string name, T & variable, T default_value, ParamAccessType type, std::string description = ""); template<class T> void registerParam(std::string name, T & variable, ParamAccessType type, std::string description = ""); - /// read properties + /// set properties virtual bool setParam(const std::string & key, const std::string & value, const ID & id); + /// set properties + template <typename T> + bool setParamValue(const std::string & key, const T & value,const ID & id); + /// function called to update the internal parameters when the modifiable /// parameters are modified virtual void updateInternalParameters() {} /// initialize the material computed parameter virtual void initMaterial(); /// compute the residual for this material virtual void updateResidual(GhostType ghost_type = _not_ghost); void assembleResidual(GhostType ghost_type); /// compute the residual for this material virtual void computeAllStresses(GhostType ghost_type = _not_ghost); virtual void computeAllNonLocalStresses(GhostType ghost_type = _not_ghost) {}; /// set material to steady state void setToSteadyState(GhostType ghost_type = _not_ghost); /// compute the stiffness matrix virtual void assembleStiffnessMatrix(GhostType ghost_type); /// compute the stable time step for an element of size h virtual Real getStableTimeStep(__attribute__((unused)) Real h, __attribute__((unused)) const Element & element = ElementNull) { AKANTU_DEBUG_TO_IMPLEMENT(); } /// compute the p-wave speed in the material virtual Real getPushWaveSpeed() const { AKANTU_DEBUG_TO_IMPLEMENT(); }; /// compute the s-wave speed in the material virtual Real getShearWaveSpeed() const { AKANTU_DEBUG_TO_IMPLEMENT(); }; /// add an element to the local mesh filter inline UInt addElement(const ElementType & type, UInt element, const GhostType & ghost_type); /// function to print the contain of the class virtual void printself(std::ostream & stream, int indent = 0) const; /** * interpolate stress on given positions for each element by means * of a geometrical interpolation on quadrature points */ virtual void interpolateStress(const ElementType type, Vector<Real> & result); /** * function to initialize the elemental field interpolation * function by inverting the quadrature points' coordinates */ virtual void initElementalFieldInterpolation(ByElementTypeReal & interpolation_points_coordinates); protected: /// constitutive law virtual void computeStress(__attribute__((unused)) ElementType el_type, __attribute__((unused)) GhostType ghost_type = _not_ghost) { AKANTU_DEBUG_TO_IMPLEMENT(); } /// set the material to steady state (to be implemented for materials that need it) virtual void setToSteadyState(__attribute__((unused)) ElementType el_type, __attribute__((unused)) GhostType ghost_type = _not_ghost) {} /// compute the tangent stiffness matrix virtual void computeTangentModuli(__attribute__((unused)) const ElementType & el_type, __attribute__((unused)) Vector<Real> & tangent_matrix, __attribute__((unused)) GhostType ghost_type = _not_ghost) { AKANTU_DEBUG_TO_IMPLEMENT(); } /// compute the potential energy virtual void computePotentialEnergy(ElementType el_type, GhostType ghost_type = _not_ghost); template<UInt dim> void assembleStiffnessMatrix(const ElementType & type, GhostType ghost_type); /// transfer the B matrix to a Voigt notation B matrix template<UInt dim> inline void transferBMatrixToSymVoigtBMatrix(const types::Matrix & B, types::Matrix & Bvoigt, UInt nb_nodes_per_element) const; inline UInt getTangentStiffnessVoigtSize(UInt spatial_dimension) const; /// compute the potential energy by element void computePotentialEnergyByElement(); /// compute the coordinates of the quadrature points void computeQuadraturePointsCoordinates(ByElementTypeReal & quadrature_points_coordinates) const; /// interpolate an elemental field on given points for each element template <ElementType type> void interpolateElementalField(const Vector<Real> & field, Vector<Real> & result); /// template function to initialize the elemental field interpolation template <ElementType type> void initElementalFieldInterpolation(const Vector<Real> & quad_coordinates, const Vector<Real> & interpolation_points_coordinates); /// build the coordinate matrix for the interpolation on elemental field template <ElementType type> inline void buildElementalFieldInterpolationCoodinates(const types::Matrix & coordinates, types::Matrix & coordMatrix); /// get the size of the coordiante matrix used in the interpolation template <ElementType type> inline UInt getSizeElementalFieldInterpolationCoodinates(); /// extract the field values corresponding to the quadrature points used for the interpolation template <ElementType type> inline void extractElementalFieldForInterplation(const Vector<Real> & field, Vector<Real> & filtered_field); /* ------------------------------------------------------------------------ */ /* Function for all materials */ /* ------------------------------------------------------------------------ */ protected: /// compute the potential energy for on element inline void computePotentialEnergyOnQuad(types::Matrix & grad_u, types::Matrix & sigma, Real & epot); public: /// allocate an internal vector template<typename T> void initInternalVector(ByElementTypeVector<T> & vect, UInt nb_component, ElementKind element_kind = _ek_regular) const; /// resize an internal vector template<typename T> void resizeInternalVector(ByElementTypeVector<T> & vect, ElementKind element_kind = _ek_regular) const; /* ------------------------------------------------------------------------ */ template<UInt dim> inline void gradUToF(const types::Matrix & grad_u, types::Matrix & F); inline void rightCauchy(const types::Matrix & F, types::Matrix & C); inline void leftCauchy (const types::Matrix & F, types::Matrix & B); /* ------------------------------------------------------------------------ */ /* DataAccessor inherited members */ /* ------------------------------------------------------------------------ */ public: virtual inline UInt getNbDataToPack (const Element & element, SynchronizationTag tag) const; virtual inline UInt getNbDataToUnpack(const Element & element, SynchronizationTag tag) const; virtual UInt getNbDataToPack(__attribute__((unused)) SynchronizationTag tag) const { return 0; } virtual UInt getNbDataToUnpack(__attribute__((unused)) SynchronizationTag tag) const { return 0; } virtual inline void packData(CommunicationBuffer & buffer, const Element & element, SynchronizationTag tag) const; virtual void packData(__attribute__((unused)) CommunicationBuffer & buffer, __attribute__((unused)) const UInt index, __attribute__((unused)) SynchronizationTag tag) const { } virtual inline void unpackData(CommunicationBuffer & buffer, const Element & element, SynchronizationTag tag); virtual void unpackData(__attribute__((unused)) CommunicationBuffer & buffer, __attribute__((unused)) const UInt index, __attribute__((unused)) SynchronizationTag tag) { } /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: AKANTU_GET_MACRO(Model, *model, const SolidMechanicsModel &) AKANTU_GET_MACRO(ID, id, const ID &); AKANTU_GET_MACRO(Rho, rho, Real); AKANTU_SET_MACRO(Rho, rho, Real); Real getPotentialEnergy(); virtual Real getEnergy(std::string type); AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(ElementFilter, element_filter, UInt); AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Strain, strain, Real); AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Stress, stress, Real); AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(PotentialEnergy, potential_energy, Real); bool isNonLocal() const { return is_non_local; } const Vector<Real> & getVector(const ID & id, const ElementType & type, const GhostType & ghost_type = _not_ghost) const; virtual Real getProperty(const ID & param) const; virtual void setProperty(const ID & param, Real value); protected: bool isInit() const { return is_init; } /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// id of the material ID id; /// material name std::string name; /// The model to witch the material belong SolidMechanicsModel * model; /// density : rho Real rho; /// stresses arrays ordered by element types ByElementTypeReal stress; /// strains arrays ordered by element types ByElementTypeReal strain; /// list of element handled by the material ByElementTypeUInt element_filter; /// is the vector for potential energy initialized // bool potential_energy_vector; /// potential energy by element ByElementTypeReal potential_energy; /// tell if using in non local mode or not bool is_non_local; /// spatial dimension UInt spatial_dimension; /// elemental field interpolation coordinates ByElementTypeReal interpolation_inverse_coordinates; /// elemental field interpolation points ByElementTypeReal interpolation_points_matrices; /// list of the paramters MaterialParameters params; private: /// boolean to know if the material has been initialized bool is_init; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ #if defined (AKANTU_INCLUDE_INLINE_IMPL) # include "material_inline_impl.cc" #endif /// standard output stream operator inline std::ostream & operator <<(std::ostream & stream, const Material & _this) { _this.printself(stream); return stream; } __END_AKANTU__ /* -------------------------------------------------------------------------- */ /* Auto loop */ /* -------------------------------------------------------------------------- */ #define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type) \ Vector<Real>::iterator<types::Matrix> strain_it = \ this->strain(el_type, ghost_type).begin(spatial_dimension, \ spatial_dimension); \ Vector<Real>::iterator<types::Matrix> strain_end = \ this->strain(el_type, ghost_type).end(spatial_dimension, \ spatial_dimension); \ Vector<Real>::iterator<types::Matrix> stress_it = \ this->stress(el_type, ghost_type).begin(spatial_dimension, \ spatial_dimension); \ \ for(;strain_it != strain_end; ++strain_it, ++stress_it) { \ types::Matrix & __attribute__((unused)) grad_u = *strain_it; \ types::Matrix & __attribute__((unused)) sigma = *stress_it #define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END \ } \ #define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_mat) \ Vector<Real>::iterator<types::Matrix> strain_it = \ this->strain(el_type, ghost_type).begin(spatial_dimension, \ spatial_dimension); \ Vector<Real>::iterator<types::Matrix> strain_end = \ this->strain(el_type, ghost_type).end(spatial_dimension, \ spatial_dimension); \ \ UInt tangent_size = \ this->getTangentStiffnessVoigtSize(spatial_dimension); \ Vector<Real>::iterator<types::Matrix> tangent_it = \ tangent_mat.begin(tangent_size, \ tangent_size); \ \ for(;strain_it != strain_end; ++strain_it, ++tangent_it) { \ types::Matrix & __attribute__((unused)) grad_u = *strain_it; \ types::Matrix & tangent = *tangent_it #define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END \ } /* -------------------------------------------------------------------------- */ /* Material list */ /* -------------------------------------------------------------------------- */ #define AKANTU_CORE_MATERIAL_LIST \ ((2, (elastic , MaterialElastic ))) \ ((2, (elastic_orthotropic, MaterialElasticOrthotropic ))) \ ((2, (neohookean , MaterialNeohookean ))) \ ((2, (sls_deviatoric , MaterialStandardLinearSolidDeviatoric))) \ ((2, (ve_stiffness_prop , MaterialStiffnessProportional ))) #define AKANTU_COHESIVE_MATERIAL_LIST \ ((2, (cohesive_bilinear , MaterialCohesiveBilinear ))) \ ((2, (cohesive_linear , MaterialCohesiveLinear ))) \ ((2, (cohesive_linear_extrinsic, MaterialCohesiveLinearExtrinsic ))) \ ((2, (cohesive_linear_exponential_extrinsic, MaterialCohesiveLinearExponentialExtrinsic ))) \ ((2, (cohesive_exponential , MaterialCohesiveExponential ))) #define AKANTU_DAMAGE_MATERIAL_LIST \ ((2, (damage_linear , MaterialDamageLinear ))) \ ((2, (marigo , MaterialMarigo ))) \ ((2, (mazars , MaterialMazars ))) \ ((2, (vreepeerlings , MaterialVreePeerlings ))) #ifdef AKANTU_DAMAGE_NON_LOCAL #define AKANTU_MATERIAL_WEIGHT_FUNCTION_TMPL_LIST \ ((stress_wf, StressBasedWeightFunction )) \ ((damage_wf, DamagedWeightFunction )) \ ((remove_wf, RemoveDamagedWeightFunction)) \ ((base_wf, BaseWeightFunction )) #define AKANTU_DAMAGE_NON_LOCAL_MATERIAL_LIST \ ((3, (marigo_non_local , MaterialMarigoNonLocal, \ AKANTU_MATERIAL_WEIGHT_FUNCTION_TMPL_LIST))) \ ((2, (mazars_non_local , MaterialMazarsNonLocal))) \ ((3, (vreepeerlings_non_local, MaterialVreePeerlingsNonLocal, \ AKANTU_MATERIAL_WEIGHT_FUNCTION_TMPL_LIST))) #else # define AKANTU_DAMAGE_NON_LOCAL_MATERIAL_LIST #endif #define AKANTU_MATERIAL_LIST \ AKANTU_CORE_MATERIAL_LIST \ AKANTU_COHESIVE_MATERIAL_LIST \ AKANTU_DAMAGE_MATERIAL_LIST \ AKANTU_DAMAGE_NON_LOCAL_MATERIAL_LIST #define INSTANSIATE_MATERIAL(mat_name) \ template class mat_name<1>; \ template class mat_name<2>; \ template class mat_name<3> #if defined(__INTEL_COMPILER) #pragma warning ( push ) /* warning #654: overloaded virtual function "akantu::Material::computeStress" is only partially overridden in class "akantu::Material*" */ #pragma warning ( disable : 654 ) #endif //defined(__INTEL_COMPILER) /* -------------------------------------------------------------------------- */ // elastic materials #include "material_elastic.hh" #include "material_neohookean.hh" #include "material_elastic_orthotropic.hh" // visco-elastic materials #include "material_stiffness_proportional.hh" #include "material_standard_linear_solid_deviatoric.hh" // damage materials #include "material_damage.hh" #include "material_marigo.hh" #include "material_mazars.hh" #include "material_damage_linear.hh" #include "material_vreepeerlings.hh" #if defined(AKANTU_DAMAGE_NON_LOCAL) # include "material_marigo_non_local.hh" # include "material_mazars_non_local.hh" # include "material_vreepeerlings_non_local.hh" #endif // cohesive materials #include "material_cohesive.hh" #include "material_cohesive_linear.hh" #include "material_cohesive_bilinear.hh" #include "material_cohesive_linear_extrinsic.hh" #include "material_cohesive_exponential.hh" #include "material_cohesive_linear_exponential_extrinsic.hh" #if defined(__INTEL_COMPILER) #pragma warning ( pop ) #endif //defined(__INTEL_COMPILER) #endif /* __AKANTU_MATERIAL_HH__ */ diff --git a/src/model/solid_mechanics/material_inline_impl.cc b/src/model/solid_mechanics/material_inline_impl.cc index ad749c712..9cf5cc6e4 100644 --- a/src/model/solid_mechanics/material_inline_impl.cc +++ b/src/model/solid_mechanics/material_inline_impl.cc @@ -1,234 +1,244 @@ /** * @file material_inline_impl.cc * @author Nicolas Richart <nicolas.richart@epfl.ch> * @date Tue Jul 27 11:57:43 2010 * * @brief Implementation of the inline functions of the class material * * @section LICENSE * * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * 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/>. * */ __END_AKANTU__ #include "solid_mechanics_model.hh" __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ inline UInt Material::addElement(const ElementType & type, UInt element, const GhostType & ghost_type) { element_filter(type, ghost_type).push_back(element); return element_filter(type, ghost_type).getSize()-1; } /* -------------------------------------------------------------------------- */ inline UInt Material::getTangentStiffnessVoigtSize(UInt dim) const { return (dim * (dim - 1) / 2 + dim); } /* -------------------------------------------------------------------------- */ template<UInt dim> inline void Material::gradUToF(const types::Matrix & grad_u, types::Matrix & F) { UInt size_F = F.size(); AKANTU_DEBUG_ASSERT(F.size() >= grad_u.size() && grad_u.size() == dim, "The dimension of the tensor F should be greater or equal to the dimension of the tensor grad_u."); for (UInt i = 0; i < dim; ++i) for (UInt j = 0; j < dim; ++j) F(i, j) = grad_u(i, j); for (UInt i = 0; i < size_F; ++i) F(i, i) += 1; } /* -------------------------------------------------------------------------- */ inline void Material::rightCauchy(const types::Matrix & F, types::Matrix & C) { C.mul<true, false>(F, F); } /* -------------------------------------------------------------------------- */ inline void Material::leftCauchy(const types::Matrix & F, types::Matrix & B) { B.mul<false, true>(F, F); } /* -------------------------------------------------------------------------- */ inline void Material::computePotentialEnergyOnQuad(types::Matrix & grad_u, types::Matrix & sigma, Real & epot) { epot = 0.; for (UInt i = 0; i < spatial_dimension; ++i) for (UInt j = 0; j < spatial_dimension; ++j) epot += sigma(i, j) * grad_u(i, j); epot *= .5; } /* -------------------------------------------------------------------------- */ template<UInt dim> inline void Material::transferBMatrixToSymVoigtBMatrix(const types::Matrix & B, types::Matrix & Bvoigt, UInt nb_nodes_per_element) const { Bvoigt.clear(); for (UInt i = 0; i < dim; ++i) for (UInt n = 0; n < nb_nodes_per_element; ++n) Bvoigt(i, i + n*dim) = B(n, i); if(dim == 2) { ///in 2D, fill the @f$ [\frac{\partial N_i}{\partial x}, \frac{\partial N_i}{\partial y}]@f$ row for (UInt n = 0; n < nb_nodes_per_element; ++n) { Bvoigt(2, 1 + n*2) = B(n, 0); Bvoigt(2, 0 + n*2) = B(n, 1); } } if(dim == 3) { for (UInt n = 0; n < nb_nodes_per_element; ++n) { Real dndx = B(n, 0); Real dndy = B(n, 1); Real dndz = B(n, 2); ///in 3D, fill the @f$ [0, \frac{\partial N_i}{\partial y}, \frac{N_i}{\partial z}]@f$ row Bvoigt(3, 1 + n*3) = dndz; Bvoigt(3, 2 + n*3) = dndy; ///in 3D, fill the @f$ [\frac{\partial N_i}{\partial x}, 0, \frac{N_i}{\partial z}]@f$ row Bvoigt(4, 0 + n*3) = dndz; Bvoigt(4, 2 + n*3) = dndx; ///in 3D, fill the @f$ [\frac{\partial N_i}{\partial x}, \frac{N_i}{\partial y}, 0]@f$ row Bvoigt(5, 0 + n*3) = dndy; Bvoigt(5, 1 + n*3) = dndx; } } } /* -------------------------------------------------------------------------- */ template<ElementType type> inline void Material::buildElementalFieldInterpolationCoodinates(__attribute__((unused)) const types::Matrix & coordinates, __attribute__((unused)) types::Matrix & coordMatrix) { AKANTU_DEBUG_TO_IMPLEMENT(); } /* -------------------------------------------------------------------------- */ template<> inline void Material::buildElementalFieldInterpolationCoodinates<_triangle_3>(const types::Matrix & coordinates, types::Matrix & coordMatrix) { for (UInt i = 0; i < coordinates.rows(); ++i) coordMatrix(i, 0) = 1; } /* -------------------------------------------------------------------------- */ template<> inline void Material::buildElementalFieldInterpolationCoodinates<_triangle_6>(const types::Matrix & coordinates, types::Matrix & coordMatrix) { UInt nb_quadrature_points = model->getFEM().getNbQuadraturePoints(_triangle_6); for (UInt i = 0; i < coordinates.rows(); ++i) { coordMatrix(i, 0) = 1; for (UInt j = 1; j < nb_quadrature_points; ++j) coordMatrix(i, j) = coordinates(i, j-1); } } /* -------------------------------------------------------------------------- */ template<ElementType type> inline UInt Material::getSizeElementalFieldInterpolationCoodinates() { return model->getFEM().getNbQuadraturePoints(type); } /* -------------------------------------------------------------------------- */ template <ElementType type> inline void Material::extractElementalFieldForInterplation(const Vector<Real> & field, Vector<Real> & filtered_field) { filtered_field.copy(field); } /* -------------------------------------------------------------------------- */ template<typename T> void Material::registerParam(std::string name, T & variable, T default_value, ParamAccessType type, std::string description) { AKANTU_DEBUG_IN(); params.registerParam<T>(name, variable, default_value, type, description); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template<typename T> void Material::registerParam(std::string name, T & variable, ParamAccessType type, std::string description) { AKANTU_DEBUG_IN(); params.registerParam<T>(name, variable, type, description); AKANTU_DEBUG_OUT(); } -/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ inline UInt Material::getNbDataToPack(const Element & element, SynchronizationTag tag) const { UInt nb_quadrature_points = model->getFEM().getNbQuadraturePoints(element.type); if(tag == _gst_smm_stress) return spatial_dimension * spatial_dimension * sizeof(Real) * nb_quadrature_points; return 0; } /* -------------------------------------------------------------------------- */ inline UInt Material::getNbDataToUnpack(const Element & element, SynchronizationTag tag) const { UInt nb_quadrature_points = model->getFEM().getNbQuadraturePoints(element.type); if(tag == _gst_smm_stress) return spatial_dimension * spatial_dimension * sizeof(Real) * nb_quadrature_points; return 0; } /* -------------------------------------------------------------------------- */ inline void Material::packData(CommunicationBuffer & buffer, const Element & element, SynchronizationTag tag) const { if(tag == _gst_smm_stress) { UInt nb_quadrature_points = model->getFEM().getNbQuadraturePoints(element.type); Vector<Real>::const_iterator<types::Matrix> stress_it = stress(element.type, _not_ghost).begin(spatial_dimension, spatial_dimension); stress_it += element.element * nb_quadrature_points; for (UInt q = 0; q < nb_quadrature_points; ++q, ++stress_it) buffer << *stress_it; } } /* -------------------------------------------------------------------------- */ inline void Material::unpackData(CommunicationBuffer & buffer, const Element & element, SynchronizationTag tag) { if(tag == _gst_smm_stress) { UInt nb_quadrature_points = model->getFEM().getNbQuadraturePoints(element.type); Vector<Real>::iterator<types::Matrix> stress_it = stress(element.type, _ghost).begin(spatial_dimension, spatial_dimension); stress_it += element.element * nb_quadrature_points; for (UInt q = 0; q < nb_quadrature_points; ++q, ++stress_it) buffer >> *stress_it; } } +/* -------------------------------------------------------------------------- */ +template <typename T> +inline bool Material::setParamValue(const std::string & key, const T & value, + __attribute__ ((unused)) const ID & id) { + try { + params.set(key, value); + } catch(...) { return false; } + return true; +} +/* -------------------------------------------------------------------------- */ + diff --git a/src/model/solid_mechanics/solid_mechanics_model_material.cc b/src/model/solid_mechanics/solid_mechanics_model_material.cc index c44b460ea..9db3d0db6 100644 --- a/src/model/solid_mechanics/solid_mechanics_model_material.cc +++ b/src/model/solid_mechanics/solid_mechanics_model_material.cc @@ -1,193 +1,193 @@ /** * @file solid_mechanics_model_material.cc * @author Guillaume ANCIAUX <guillaume.anciaux@epfl.ch> * @date Thu Nov 25 10:48:53 2010 * * @brief * * @section LICENSE * * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * 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 "solid_mechanics_model.hh" #include "material.hh" #include "aka_math.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -#define AKANTU_INTANTIATE_MATERIAL_BY_DYM_NO_TMPL(dim, elem) \ +#define AKANTU_INTANTIATE_MATERIAL_BY_DIM_NO_TMPL(dim, elem) \ material = \ &(registerNewCustomMaterial< BOOST_PP_ARRAY_ELEM(1, elem)< dim > >(mat_type, \ opt_param)) -#define AKANTU_INTANTIATE_MATERIAL_BY_DYM_TMPL_EACH(r, data, i, elem) \ +#define AKANTU_INTANTIATE_MATERIAL_BY_DIM_TMPL_EACH(r, data, i, elem) \ BOOST_PP_EXPR_IF(BOOST_PP_NOT_EQUAL(0, i), else ) \ if(opt_param == BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(2, 0, elem))) { \ material = \ - &(registerNewCurtomMaterial< BOOST_PP_ARRAY_ELEM(1, data)< BOOST_PP_ARRAY_ELEM(0, data), \ + &(registerNewCustomMaterial< BOOST_PP_ARRAY_ELEM(1, data)< BOOST_PP_ARRAY_ELEM(0, data), \ BOOST_PP_TUPLE_ELEM(2, 1, elem) > >(mat_type, opt_param)); \ } -#define AKANTU_INTANTIATE_MATERIAL_BY_DYM_TMPL(dim, elem) \ - BOOST_PP_SEQ_FOR_EACH_I(AKANTU_INTANTIATE_MATERIAL_BY_DYM_TMPL_EACH, \ +#define AKANTU_INTANTIATE_MATERIAL_BY_DIM_TMPL(dim, elem) \ + BOOST_PP_SEQ_FOR_EACH_I(AKANTU_INTANTIATE_MATERIAL_BY_DIM_TMPL_EACH, \ (2, (dim, BOOST_PP_ARRAY_ELEM(1, elem))), \ BOOST_PP_ARRAY_ELEM(2, elem)) \ else { \ - AKANTU_INTANTIATE_MATERIAL_BY_DYM_NO_TMPL(dim, elem); \ + AKANTU_INTANTIATE_MATERIAL_BY_DIM_NO_TMPL(dim, elem); \ } #define AKANTU_INTANTIATE_MATERIAL_BY_DIM(dim, elem) \ BOOST_PP_IF(BOOST_PP_EQUAL(3, BOOST_PP_ARRAY_SIZE(elem) ), \ - AKANTU_INTANTIATE_MATERIAL_BY_DYM_TMPL, \ - AKANTU_INTANTIATE_MATERIAL_BY_DYM_NO_TMPL)(dim, elem) + AKANTU_INTANTIATE_MATERIAL_BY_DIM_TMPL, \ + AKANTU_INTANTIATE_MATERIAL_BY_DIM_NO_TMPL)(dim, elem) #define AKANTU_INTANTIATE_MATERIAL(elem) \ switch(spatial_dimension) { \ case 1: { AKANTU_INTANTIATE_MATERIAL_BY_DIM(1, elem); break; } \ case 2: { AKANTU_INTANTIATE_MATERIAL_BY_DIM(2, elem); break; } \ case 3: { AKANTU_INTANTIATE_MATERIAL_BY_DIM(3, elem); break; } \ } #define AKANTU_INTANTIATE_MATERIAL_IF(elem) \ if (mat_type == BOOST_PP_STRINGIZE(BOOST_PP_ARRAY_ELEM(0, elem))) { \ AKANTU_INTANTIATE_MATERIAL(elem); \ } #define AKANTU_INTANTIATE_OTHER_MATERIAL(r, data, elem) \ else AKANTU_INTANTIATE_MATERIAL_IF(elem) #define AKANTU_INSTANTIATE_MATERIALS() \ do { \ AKANTU_INTANTIATE_MATERIAL_IF(BOOST_PP_SEQ_HEAD(AKANTU_MATERIAL_LIST)) \ BOOST_PP_SEQ_FOR_EACH(AKANTU_INTANTIATE_OTHER_MATERIAL, \ _, \ BOOST_PP_SEQ_TAIL(AKANTU_MATERIAL_LIST)) \ else \ AKANTU_DEBUG_ERROR("Malformed material file : unknown material type " \ << mat_type); \ } while(0) /* -------------------------------------------------------------------------- */ void SolidMechanicsModel::readMaterials(const std::string & filename) { Parser parser; parser.open(filename); std::string opt_param; std::string mat_type = parser.getNextSection("material", opt_param); while (mat_type != ""){ Material & mat = registerNewMaterial(mat_type, opt_param); parser.readSection(mat.getID(), mat); mat_type = parser.getNextSection("material", opt_param); } parser.close(); } /* -------------------------------------------------------------------------- */ Material & SolidMechanicsModel::registerNewMaterial(const ID & mat_type, const std::string & opt_param) { // UInt mat_count = materials.size(); // std::stringstream sstr_mat; sstr_mat << id << ":" << mat_count << ":" << mat_type; // Material * material; // ID mat_id = sstr_mat.str(); // // add all the new materials in the AKANTU_MATERIAL_LIST in the material.hh file // AKANTU_INSTANTIATE_MATERIALS(); // materials.push_back(material); Material * material = NULL; AKANTU_INSTANTIATE_MATERIALS(); return *material; } /* -------------------------------------------------------------------------- */ void SolidMechanicsModel::initMaterials() { AKANTU_DEBUG_ASSERT(materials.size() != 0, "No material to initialize !"); Material ** mat_val = &(materials.at(0)); /// @todo synchronize element material for(UInt g = _not_ghost; g <= _ghost; ++g) { GhostType gt = (GhostType) g; /// fill the element filters of the materials using the element_material arrays Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt); Mesh::type_iterator end = mesh.lastType(spatial_dimension, gt); for(; it != end; ++it) { UInt nb_element = mesh.getNbElement(*it, gt); UInt * elem_mat_val = element_material(*it, gt).storage(); element_index_by_material.alloc(nb_element, 1, *it, gt); for (UInt el = 0; el < nb_element; ++el) { UInt index = mat_val[elem_mat_val[el]]->addElement(*it, el, gt); element_index_by_material(*it, gt)(el) = index; } } } std::vector<Material *>::iterator mat_it; for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) { /// init internals properties (*mat_it)->initMaterial(); } synch_registry->synchronize(_gst_smm_init_mat); } /* -------------------------------------------------------------------------- */ void SolidMechanicsModel::setMaterialIDsFromIntData(const std::string & data_name) { for(UInt g = _not_ghost; g <= _ghost; ++g) { GhostType gt = (GhostType) g; Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt); Mesh::type_iterator end = mesh.lastType(spatial_dimension, gt); for(; it != end; ++it) { try { const Vector<UInt> & data = mesh.getUIntData(*it, data_name, gt); AKANTU_DEBUG_ASSERT(element_material.exists(*it, gt), "element_material for type (" << gt << ":" << *it << ") does not exists!"); element_material(*it, gt).copy(data); } catch(...) { AKANTU_DEBUG_ERROR("No data named " << data_name << " present in the mesh " << id << " for the element type " << *it); } } } } /* -------------------------------------------------------------------------- */ __END_AKANTU__