diff --git a/src/model/common/constitutive_laws/constitutive_law_tmpl.hh b/src/model/common/constitutive_laws/constitutive_law_tmpl.hh index 2ae629093..9bf0fdbfd 100644 --- a/src/model/common/constitutive_laws/constitutive_law_tmpl.hh +++ b/src/model/common/constitutive_laws/constitutive_law_tmpl.hh @@ -1,561 +1,561 @@ /** * @file constitutive_law_tmpl.hh * * @author Guillaume Anciaux * @author Aurelia Isabel Cuba Ramos * @author Daniel Pino Muñoz * @author Nicolas Richart * @author Marco Vocialta * * @date creation: Tue Jul 27 2010 * @date last modification: Wed Feb 21 2018 * * @brief Implementation of the templated part of the constitutive law class * * * Copyright (©) 2010-2018 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 . * */ /* -------------------------------------------------------------------------- */ #include "constitutive_law.hh" #include "constitutive_laws_handler.hh" #include "fe_engine.hh" #include "internal_field.hh" /* -------------------------------------------------------------------------- */ #ifndef AKANTU_CONSTITUTIVE_LAW_TMPL_HH #define AKANTU_CONSTITUTIVE_LAW_TMPL_HH namespace akantu { /* -------------------------------------------------------------------------- */ inline void ConstitutiveLawInternalHandler::registerInternal( std::shared_ptr vect) { - internal_vectors[vect->getID()] = vect; + internal_vectors[vect->getRegisterID()] = vect; } /* -------------------------------------------------------------------------- */ inline void ConstitutiveLawInternalHandler::unregisterInternal(const ID & id) { internal_vectors.erase(id); } /* -------------------------------------------------------------------------- */ inline void ConstitutiveLawInternalHandler::savePreviousState() { for (auto pair : internal_vectors) { if (pair.second->hasHistory()) { pair.second->saveCurrentValues(); } } } /* -------------------------------------------------------------------------- */ inline void ConstitutiveLawInternalHandler::restorePreviousState() { for (auto pair : internal_vectors) { if (pair.second->hasHistory()) { pair.second->restorePreviousValues(); } } } /* -------------------------------------------------------------------------- */ inline void ConstitutiveLawInternalHandler::resizeInternals() { for (auto && pair : internal_vectors) { pair.second->resize(); } } /* -------------------------------------------------------------------------- */ template const InternalField & ConstitutiveLawInternalHandler::getInternal(const ID & id) const { auto it = internal_vectors.find(this->id + ":" + id); if (it != internal_vectors.end() and aka::is_of_type>(*it->second)) { return aka::as_type>(*it->second); } AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID() << ") does not contain an internal " << id << " (" << (getID() + ":" + id) << ")"); } /* -------------------------------------------------------------------------- */ template InternalField & ConstitutiveLawInternalHandler::getInternal(const ID & id) { auto it = internal_vectors.find(getID() + ":" + id); if (it != internal_vectors.end() and aka::is_of_type>(*it->second)) { return aka::as_type>(*it->second); } AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID() << ") does not contain an internal " << id << " (" << (getID() + ":" + id) << ")"); } /* -------------------------------------------------------------------------- */ template inline bool ConstitutiveLawInternalHandler::isInternal( const ID & id, const ElementKind & element_kind) const { auto it = internal_vectors.find(this->getID() + ":" + id); return (it != internal_vectors.end() and aka::is_of_type>(*it->second) and aka::as_type>(*it->second).getElementKind() != element_kind); } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ template const Array & ConstitutiveLawInternalHandler::getArray(const ID & vect_id, ElementType type, GhostType ghost_type) const { if (isInternal(vect_id, Mesh::getKind(type))) { auto && internal = this->template getInternal(vect_id); if (internal.exists(type, ghost_type)) { return internal(type, ghost_type); } else { AKANTU_SILENT_EXCEPTION( "The internal " << vect_id << " in the constitutive law " << name << " (" << getID() << ") does not contain the type [" << type << ":" << ghost_type << "]"); } } else { AKANTU_SILENT_EXCEPTION("The constitutive law " << name << " (" << getID() << ") does not contain an internal field " << vect_id); } } /* -------------------------------------------------------------------------- */ template Array & ConstitutiveLawInternalHandler::getArray(const ID & vect_id, ElementType type, GhostType ghost_type) { if (isInternal(vect_id, Mesh::getKind(type))) { auto && internal = this->template getInternal(vect_id); if (internal.exists(type, ghost_type)) { return internal(type, ghost_type); } else { AKANTU_SILENT_EXCEPTION( "The internal " << vect_id << " in the constitutive law " << name << " (" << getID() << ") does not contain the type [" << type << ":" << ghost_type << "]"); } } else { AKANTU_SILENT_EXCEPTION("The constitutive law " << name << " (" << getID() << ") does not contain an internal field " << vect_id); } } /* -------------------------------------------------------------------------- */ inline void ConstitutiveLawInternalHandler::removeIntegrationPoints( ElementTypeMapArray & new_numbering) { for (auto pair : internal_vectors) { pair.second->removeIntegrationPoints(new_numbering); } } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ template ConstitutiveLaw::ConstitutiveLaw( ConstitutiveLawsHandler_ & handler, const ID & id, UInt spatial_dimension, ElementKind element_kind, const ID & fe_engine_id) : ConstitutiveLawInternalHandler(id, spatial_dimension), Parsable(ParserType::_constitutive_law, id), handler(handler), element_filter("element_filter", id), default_fe_engine_id(fe_engine_id) { /// for each connectivity types allocate the element filer array of the /// constitutive law element_filter.initialize(handler.getMesh(), _spatial_dimension = handler.getSpatialDimension(), _element_kind = element_kind); this->initialize(); } /* -------------------------------------------------------------------------- */ template void ConstitutiveLaw::initialize() { registerParam("name", name, std::string(), _pat_parsable | _pat_readable); } /* -------------------------------------------------------------------------- */ template void ConstitutiveLaw::initConstitutiveLaw() { this->resizeInternals(); this->updateInternalParameters(); is_init = true; } /* -------------------------------------------------------------------------- */ template void ConstitutiveLaw::addElements( const Array & elements_to_add) { AKANTU_DEBUG_IN(); UInt law_id = handler.getConstitutiveLawIndex(name); for (const auto & element : elements_to_add) { auto index = this->addElement(element); handler.constitutive_law_index(element) = law_id; handler.constitutive_law_local_numbering(element) = index; } this->resizeInternals(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template void ConstitutiveLaw::removeElements( const Array & elements_to_remove) { AKANTU_DEBUG_IN(); auto el_begin = elements_to_remove.begin(); auto el_end = elements_to_remove.end(); if (elements_to_remove.empty()) { return; } auto & mesh = handler.getMesh(); ElementTypeMapArray constitutive_law_local_new_numbering( "remove constitutive law filter elem", id); constitutive_law_local_new_numbering.initialize( mesh, _element_filter = &element_filter, _element_kind = _ek_not_defined, _with_nb_element = true); ElementTypeMapArray element_filter_tmp("element_filter_tmp", id); element_filter_tmp.initialize(mesh, _element_filter = &element_filter, _element_kind = _ek_not_defined); ElementTypeMap new_ids, element_ids; for_each_element( mesh, [&](auto && el) { if (not new_ids(el.type, el.ghost_type)) { element_ids(el.type, el.ghost_type) = 0; } auto & element_id = element_ids(el.type, el.ghost_type); auto l_el = Element{el.type, element_id, el.ghost_type}; if (std::find(el_begin, el_end, el) != el_end) { constitutive_law_local_new_numbering(l_el) = UInt(-1); return; } element_filter_tmp(el.type, el.ghost_type).push_back(el.element); if (not new_ids(el.type, el.ghost_type)) { new_ids(el.type, el.ghost_type) = 0; } auto & new_id = new_ids(el.type, el.ghost_type); constitutive_law_local_new_numbering(l_el) = new_id; handler.constitutive_law_local_numbering(el) = new_id; ++new_id; ++element_id; }, _element_filter = &element_filter, _element_kind = _ek_not_defined); for (auto ghost_type : ghost_types) { for (const auto & type : element_filter.elementTypes( _ghost_type = ghost_type, _element_kind = _ek_not_defined)) { element_filter(type, ghost_type) .copy(element_filter_tmp(type, ghost_type)); } } this->removeIntegrationPoints(constitutive_law_local_new_numbering); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template void ConstitutiveLaw::onElementsAdded( const Array & /*unused*/, const NewElementsEvent & /*unused*/) { this->resizeInternals(); } /* -------------------------------------------------------------------------- */ template void ConstitutiveLaw::onElementsRemoved( const Array & element_list, const ElementTypeMapArray & new_numbering, const RemovedElementsEvent & /*event*/) { UInt my_num = handler.getInternalIndexFromID(getID()); ElementTypeMapArray constitutive_law_local_new_numbering( "remove constitutive law filter elem", getID()); auto el_begin = element_list.begin(); auto el_end = element_list.end(); for (auto && gt : ghost_types) { for (auto && type : new_numbering.elementTypes(_all_dimensions, gt, _ek_not_defined)) { if (not element_filter.exists(type, gt) || element_filter(type, gt).empty()) { continue; } auto & elem_filter = element_filter(type, gt); auto & law_indexes = this->handler.constitutive_law_index(type, gt); auto & law_loc_num = this->handler.constitutive_law_local_numbering(type, gt); auto nb_element = this->handler.getMesh().getNbElement(type, gt); // all constitutive laws will resized to the same size... law_indexes.resize(nb_element); law_loc_num.resize(nb_element); if (!constitutive_law_local_new_numbering.exists(type, gt)) { constitutive_law_local_new_numbering.alloc(elem_filter.size(), 1, type, gt); } auto & law_renumbering = constitutive_law_local_new_numbering(type, gt); const auto & renumbering = new_numbering(type, gt); Array elem_filter_tmp; UInt ni = 0; Element el{type, 0, gt}; for (UInt i = 0; i < elem_filter.size(); ++i) { el.element = elem_filter(i); if (std::find(el_begin, el_end, el) == el_end) { UInt new_el = renumbering(el.element); AKANTU_DEBUG_ASSERT(new_el != UInt(-1), "A not removed element as been badly renumbered"); elem_filter_tmp.push_back(new_el); law_renumbering(i) = ni; law_indexes(new_el) = my_num; law_loc_num(new_el) = ni; ++ni; } else { law_renumbering(i) = UInt(-1); } } elem_filter.resize(elem_filter_tmp.size()); elem_filter.copy(elem_filter_tmp); } } this->removeIntegrationPoints(constitutive_law_local_new_numbering); } /* -------------------------------------------------------------------------- */ template template inline void ConstitutiveLaw::packInternalFieldHelper( const InternalField & data_to_pack, CommunicationBuffer & buffer, const Array & elements) const { DataAccessor::packElementalDataHelper(data_to_pack, buffer, elements, data_to_pack.getFEEngine()); } /* -------------------------------------------------------------------------- */ template template inline void ConstitutiveLaw::unpackInternalFieldHelper( InternalField & data_to_unpack, CommunicationBuffer & buffer, const Array & elements) { DataAccessor::unpackElementalDataHelper(data_to_unpack, buffer, elements, data_to_unpack.getFEEngine()); } /* -------------------------------------------------------------------------- */ template inline Element ConstitutiveLaw::convertToLocalElement( const Element & global_element) const { UInt ge = global_element.element; #ifndef AKANTU_NDEBUG UInt model_law_index = handler.getConstitutiveLawByElement( global_element.type, global_element.ghost_type)(ge); UInt law_index = handler.getConstitutiveLawIndex(this->name); AKANTU_DEBUG_ASSERT(model_law_index == law_index, "Conversion of a global element in a local element for " "the wrong constitutive law " << this->name << std::endl); #endif UInt le = handler.getConstitutiveLawLocalNumbering( global_element.type, global_element.ghost_type)(ge); Element tmp_quad{global_element.type, le, global_element.ghost_type}; return tmp_quad; } /* -------------------------------------------------------------------------- */ template inline Element ConstitutiveLaw::convertToGlobalElement( const Element & local_element) const { UInt le = local_element.element; UInt ge = this->element_filter(local_element.type, local_element.ghost_type)(le); Element tmp_quad{local_element.type, ge, local_element.ghost_type}; return tmp_quad; } /* -------------------------------------------------------------------------- */ template inline UInt ConstitutiveLaw::addElement( ElementType type, UInt element, GhostType ghost_type) { Array & el_filter = this->element_filter(type, ghost_type); el_filter.push_back(element); return el_filter.size() - 1; } /* -------------------------------------------------------------------------- */ template inline UInt ConstitutiveLaw::addElement(const Element & element) { return this->addElement(element.type, element.element, element.ghost_type); } /* -------------------------------------------------------------------------- */ template inline const Parameter & ConstitutiveLaw::getParam(const ID & param) const { try { return get(param); } catch (...) { AKANTU_EXCEPTION("No parameter " << param << " in the constitutive law" << getID()); } } /* -------------------------------------------------------------------------- */ template template inline void ConstitutiveLaw::setParam(const ID & param, T value) { try { set(param, value); } catch (...) { AKANTU_EXCEPTION("No parameter " << param << " in the constitutive law " << getID()); } updateInternalParameters(); } /* -------------------------------------------------------------------------- */ template template inline ElementTypeMap ConstitutiveLaw::getInternalDataPerElem( const ID & field_id, ElementKind element_kind) const { if (not this->template isInternal(field_id, element_kind)) { AKANTU_EXCEPTION("Cannot find internal field " << id << " in the constitutive law " << this->name); } const auto & internal_field = this->template getInternal(field_id); const FEEngine & fe_engine = internal_field.getFEEngine(); UInt nb_data_per_quad = internal_field.getNbComponent(); ElementTypeMap res; for (auto ghost_type : ghost_types) { for (auto & type : internal_field.elementTypes(ghost_type)) { UInt nb_quadrature_points = fe_engine.getNbIntegrationPoints(type, ghost_type); res(type, ghost_type) = nb_data_per_quad * nb_quadrature_points; } } return res; } /* -------------------------------------------------------------------------- */ template template void ConstitutiveLaw::flattenInternal( const std::string & field_id, ElementTypeMapArray & internal_flat, const GhostType ghost_type, ElementKind element_kind) const { if (!this->template isInternal(field_id, element_kind)) { AKANTU_EXCEPTION("Cannot find internal field " << id << " in the constitutive law " << this->name); } const InternalField & internal_field = this->template getInternal(field_id); const FEEngine & fe_engine = internal_field.getFEEngine(); const Mesh & mesh = fe_engine.getMesh(); for (auto && type : internal_field.filterTypes(ghost_type)) { const Array & src_vect = internal_field(type, ghost_type); const Array & filter = internal_field.getFilter(type, ghost_type); // total number of elements in the corresponding mesh UInt nb_element_dst = mesh.getNbElement(type, ghost_type); // number of element in the internal field UInt nb_element_src = filter.size(); // number of quadrature points per elem UInt nb_quad_per_elem = fe_engine.getNbIntegrationPoints(type); // number of data per quadrature point UInt nb_data_per_quad = internal_field.getNbComponent(); if (!internal_flat.exists(type, ghost_type)) { internal_flat.alloc(nb_element_dst * nb_quad_per_elem, nb_data_per_quad, type, ghost_type); } if (nb_element_src == 0) { continue; } // number of data per element UInt nb_data = nb_quad_per_elem * nb_data_per_quad; Array & dst_vect = internal_flat(type, ghost_type); dst_vect.resize(nb_element_dst * nb_quad_per_elem); auto it_dst = make_view(dst_vect, nb_data).begin(); for (auto && data : zip(filter, make_view(src_vect, nb_data))) { it_dst[std::get<0>(data)] = std::get<1>(data); } } } } // namespace akantu #endif // AKANTU_CONSTITUTIVE_LAW_TMPL_HH diff --git a/src/model/common/constitutive_laws/internal_field.hh b/src/model/common/constitutive_laws/internal_field.hh index 2c9b95b4f..744efc136 100644 --- a/src/model/common/constitutive_laws/internal_field.hh +++ b/src/model/common/constitutive_laws/internal_field.hh @@ -1,281 +1,281 @@ /** * @file internal_field.hh * * @author Nicolas Richart * * @date creation: Fri Jun 18 2010 * @date last modification: Thu Feb 08 2018 * * @brief Constitutive law internal properties * * * Copyright (©) 2010-2018 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 . * */ /* -------------------------------------------------------------------------- */ #include "aka_common.hh" #include "element_type_map.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ #ifndef AKANTU_INTERNAL_FIELD_HH_ #define AKANTU_INTERNAL_FIELD_HH_ namespace akantu { class ConstitutiveLawInternalHandler; class FEEngine; } // namespace akantu namespace akantu { class InternalFieldBase : public std::enable_shared_from_this { public: - InternalFieldBase(const ID & id) : id(id) {} + InternalFieldBase(const ID & id) : id_(id) {} /// activate the history of this field virtual void initializeHistory() = 0; /// resize the arrays and set the new element to 0 virtual void resize() = 0; /// save the current values in the history virtual void saveCurrentValues() = 0; /// restore the previous values from the history virtual void restorePreviousValues() = 0; /// remove the quadrature points corresponding to suppressed elements virtual void removeIntegrationPoints(const ElementTypeMapArray & new_numbering) = 0; virtual bool hasHistory() const = 0; - AKANTU_GET_MACRO(ID, id, const ID &); + auto getRegisterID() const { return id_; } protected: - ID id; + ID id_; }; /** * class for the internal fields of constitutive law * to store values for each quadrature */ template class InternalField : public InternalFieldBase, public ElementTypeMapArray { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: InternalField(const ID & id, ConstitutiveLawInternalHandler & constitutive_law); ~InternalField() override; /// This constructor is only here to let cohesive elements compile InternalField(const ID & id, ConstitutiveLawInternalHandler & constitutive_law, const ID & fem_id, const ElementTypeMapArray & element_filter); /// More general constructor InternalField(const ID & id, ConstitutiveLawInternalHandler & constitutive_law, UInt dim, const ID & fem_id, const ElementTypeMapArray & element_filter); InternalField(const ID & id, const InternalField & other); InternalField operator=(const InternalField &) = delete; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// function to reset the FEEngine for the internal fieldx // virtual void setFEEngine(FEEngine & fe_engine); /// function to reset the element kind for the internal virtual void setElementKind(ElementKind element_kind); /// initialize the field to a given number of component virtual void initialize(UInt nb_component); /// activate the history of this field void initializeHistory() override; /// resize the arrays and set the new element to 0 void resize() override; /// set the field to a given value v virtual void setDefaultValue(const T & v); /// reset all the fields to the default value virtual void reset(); /// save the current values in the history void saveCurrentValues() override; /// restore the previous values from the history void restorePreviousValues() override; /// remove the quadrature points corresponding to suppressed elements void removeIntegrationPoints( const ElementTypeMapArray & new_numbering) override; /// print the content void printself(std::ostream & stream, int /*indent*/ = 0) const override; /// get the default value inline operator T() const; virtual FEEngine & getFEEngine() { return fem; } virtual const FEEngine & getFEEngine() const { return fem; } /// AKANTU_GET_MACRO(FEEngine, *fem, FEEngine &); protected: /// initialize the arrays in the ElementTypeMapArray void internalInitialize(UInt nb_component); /// set the values for new internals virtual void setArrayValues(T * begin, T * end); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /// get filter types for range loop decltype(auto) elementTypes(GhostType ghost_type = _not_ghost) const { return ElementTypeMapArray::elementTypes( _spatial_dimension = this->spatial_dimension, _element_kind = this->element_kind, _ghost_type = ghost_type); } /// get filter types for range loop decltype(auto) filterTypes(GhostType ghost_type = _not_ghost) const { return this->element_filter.elementTypes( _spatial_dimension = this->spatial_dimension, _element_kind = this->element_kind, _ghost_type = ghost_type); } /// get the array for a given type of the element_filter const Array & getFilter(ElementType type, GhostType ghost_type = _not_ghost) const { return this->element_filter(type, ghost_type); } /// get the Array corresponding to the type en ghost_type specified virtual Array & operator()(ElementType type, GhostType ghost_type = _not_ghost) { return ElementTypeMapArray::operator()(type, ghost_type); } virtual const Array & operator()(ElementType type, GhostType ghost_type = _not_ghost) const { return ElementTypeMapArray::operator()(type, ghost_type); } virtual Array & previous(ElementType type, GhostType ghost_type = _not_ghost) { AKANTU_DEBUG_ASSERT(previous_values != nullptr, "The history of the internal " << this->getID() << " has not been activated"); return this->previous_values->operator()(type, ghost_type); } virtual const Array & previous(ElementType type, GhostType ghost_type = _not_ghost) const { AKANTU_DEBUG_ASSERT(previous_values != nullptr, "The history of the internal " << this->getID() << " has not been activated"); return this->previous_values->operator()(type, ghost_type); } virtual InternalField & previous() { AKANTU_DEBUG_ASSERT(previous_values != nullptr, "The history of the internal " << this->getID() << " has not been activated"); return *(this->previous_values); } virtual const InternalField & previous() const { AKANTU_DEBUG_ASSERT(previous_values != nullptr, "The history of the internal " << this->getID() << " has not been activated"); return *(this->previous_values); } /// check if the history is used or not bool hasHistory() const override { return (previous_values != nullptr); } /// get the kind treated by the internal ElementKind getElementKind() const { return element_kind; } /// return the number of components UInt getNbComponent() const { return nb_component; } /// return the spatial dimension corresponding to the internal element type /// loop filter UInt getSpatialDimension() const { return this->spatial_dimension; } /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// the constitutive_law for which this is an internal parameter ConstitutiveLawInternalHandler & constitutive_law; /// the fem containing the mesh and the element informations FEEngine & fem; /// Element filter if needed const ElementTypeMapArray & element_filter; /// default value T default_value{}; /// spatial dimension of the element to consider UInt spatial_dimension{0}; /// ElementKind of the element to consider ElementKind element_kind{_ek_regular}; /// Number of component of the internal field UInt nb_component{0}; /// Is the field initialized bool is_init{false}; /// previous values std::unique_ptr> previous_values; }; /// standard output stream operator template inline std::ostream & operator<<(std::ostream & stream, const InternalField & _this) { _this.printself(stream); return stream; } } // namespace akantu #endif /* AKANTU_INTERNAL_FIELD_HH_ */ diff --git a/src/model/common/constitutive_laws/internal_field_tmpl.hh b/src/model/common/constitutive_laws/internal_field_tmpl.hh index da1c90191..14c956d39 100644 --- a/src/model/common/constitutive_laws/internal_field_tmpl.hh +++ b/src/model/common/constitutive_laws/internal_field_tmpl.hh @@ -1,310 +1,310 @@ /** * @file internal_field_tmpl.hh * * @author Nicolas Richart * * @date creation: Wed Nov 13 2013 * @date last modification: Wed Feb 21 2018 * * @brief Constitutive law internal properties * * * Copyright (©) 2014-2018 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 . * */ /* -------------------------------------------------------------------------- */ #include "constitutive_law.hh" /* -------------------------------------------------------------------------- */ #ifndef AKANTU_INTERNAL_FIELD_TMPL_HH_ #define AKANTU_INTERNAL_FIELD_TMPL_HH_ namespace akantu { /* -------------------------------------------------------------------------- */ template InternalField::InternalField( const ID & id, ConstitutiveLawInternalHandler & constitutive_law, UInt dim, const ID & fem_id, const ElementTypeMapArray & element_filter) : InternalFieldBase(id), ElementTypeMapArray(id, constitutive_law.getID()), constitutive_law(constitutive_law), fem(constitutive_law.getFEEngine(fem_id)), element_filter(element_filter), spatial_dimension(dim) {} /* -------------------------------------------------------------------------- */ template InternalField::InternalField( const ID & id, ConstitutiveLawInternalHandler & constitutive_law) : InternalField(id, constitutive_law, constitutive_law.getFEEngine().getElementDimension(), "", constitutive_law.getElementFilter()) {} /* -------------------------------------------------------------------------- */ template InternalField::InternalField( const ID & id, ConstitutiveLawInternalHandler & constitutive_law, const ID & fem_id, const ElementTypeMapArray & element_filter) : InternalField(id, constitutive_law, constitutive_law.getFEEngine().getElementDimension(), fem_id, element_filter) {} /* -------------------------------------------------------------------------- */ template InternalField::InternalField(const ID & id, const InternalField & other) : InternalFieldBase(id), ElementTypeMapArray( id, other.constitutive_law.getID()), constitutive_law(other.constitutive_law), fem(other.fem), element_filter(other.element_filter), default_value(other.default_value), spatial_dimension(other.spatial_dimension), element_kind(other.element_kind), nb_component(other.nb_component) { AKANTU_DEBUG_ASSERT(other.is_init, "Cannot create a copy of a non initialized field"); this->internalInitialize(this->nb_component); } /* -------------------------------------------------------------------------- */ template InternalField::~InternalField() { if (this->is_init) { - this->constitutive_law.unregisterInternal(this->getID()); + this->constitutive_law.unregisterInternal(this->getRegisterID()); } } /* -------------------------------------------------------------------------- */ template void InternalField::setElementKind(ElementKind element_kind) { this->element_kind = element_kind; } /* -------------------------------------------------------------------------- */ template void InternalField::initialize(UInt nb_component) { internalInitialize(nb_component); } /* -------------------------------------------------------------------------- */ template void InternalField::initializeHistory() { if (!previous_values) { previous_values = std::make_unique>("previous_" + this->getID(), *this); } } /* -------------------------------------------------------------------------- */ template void InternalField::resize() { if (!this->is_init) { return; } ElementTypeMap old_sizes; for (auto ghost : ghost_types) { for (const auto & type : this->filterTypes(ghost)) { if (this->exists(type, ghost)) { old_sizes(type, ghost) = this->operator()(type, ghost).size(); } else { old_sizes(type, ghost) = 0; } } } ElementTypeMapArray::initialize( fem, _element_filter = element_filter, _element_kind = element_kind, _nb_component = nb_component, _with_nb_element = true, _do_not_default = true); for (auto ghost : ghost_types) { for (const auto & type : this->filterTypes(ghost)) { auto & vect = this->operator()(type, ghost); auto old_size = old_sizes(type, ghost); auto new_size = vect.size(); this->setArrayValues(vect.storage() + old_size * vect.getNbComponent(), vect.storage() + new_size * vect.getNbComponent()); } } } /* -------------------------------------------------------------------------- */ template void InternalField::setDefaultValue(const T & value) { this->default_value = value; this->reset(); } /* -------------------------------------------------------------------------- */ template void InternalField::reset() { for (auto ghost_type : ghost_types) { for (const auto & type : this->elementTypes(ghost_type)) { Array & vect = (*this)(type, ghost_type); // vect.zero(); this->setArrayValues( vect.storage(), vect.storage() + vect.size() * vect.getNbComponent()); } } } /* -------------------------------------------------------------------------- */ template void InternalField::internalInitialize(UInt nb_component) { if (not this->is_init) { this->nb_component = nb_component; ElementTypeMapArray::initialize( fem, _element_filter = element_filter, _element_kind = element_kind, _nb_component = nb_component, _with_nb_element = true, _do_not_default = true); this->constitutive_law.registerInternal(this->shared_from_this()); this->is_init = true; } this->reset(); if (this->previous_values) { this->previous_values->internalInitialize(nb_component); } } /* -------------------------------------------------------------------------- */ template void InternalField::setArrayValues(T * begin, T * end) { for (; begin < end; ++begin) { *begin = this->default_value; } } /* -------------------------------------------------------------------------- */ template void InternalField::saveCurrentValues() { AKANTU_DEBUG_ASSERT(this->previous_values != nullptr, "The history of the internal " << this->getID() << " has not been activated"); if (not this->is_init) { return; } for (auto ghost_type : ghost_types) { for (const auto & type : this->elementTypes(ghost_type)) { (*this->previous_values)(type, ghost_type) .copy((*this)(type, ghost_type)); } } } /* -------------------------------------------------------------------------- */ template void InternalField::restorePreviousValues() { AKANTU_DEBUG_ASSERT(this->previous_values != nullptr, "The history of the internal " << this->getID() << " has not been activated"); if (not this->is_init) { return; } for (auto ghost_type : ghost_types) { for (const auto & type : this->elementTypes(ghost_type)) { (*this)(type, ghost_type) .copy((*this->previous_values)(type, ghost_type)); } } } /* -------------------------------------------------------------------------- */ template void InternalField::removeIntegrationPoints( const ElementTypeMapArray & new_numbering) { for (auto ghost_type : ghost_types) { for (auto type : new_numbering.elementTypes(_all_dimensions, ghost_type, _ek_not_defined)) { if (not this->exists(type, ghost_type)) { continue; } Array & vect = (*this)(type, ghost_type); if (vect.empty()) { continue; } const Array & renumbering = new_numbering(type, ghost_type); UInt nb_quad_per_elem = fem.getNbIntegrationPoints(type, ghost_type); UInt nb_component = vect.getNbComponent(); Array tmp(renumbering.size() * nb_quad_per_elem, nb_component); AKANTU_DEBUG_ASSERT( tmp.size() == vect.size(), "Something strange append some mater was created from nowhere!!"); AKANTU_DEBUG_ASSERT( tmp.size() == vect.size(), "Something strange append some mater was created or disappeared in " << vect.getID() << "(" << vect.size() << "!=" << tmp.size() << ") " "!!"); UInt new_size = 0; for (UInt i = 0; i < renumbering.size(); ++i) { UInt new_i = renumbering(i); if (new_i != UInt(-1)) { memcpy(tmp.storage() + new_i * nb_component * nb_quad_per_elem, vect.storage() + i * nb_component * nb_quad_per_elem, nb_component * nb_quad_per_elem * sizeof(T)); ++new_size; } } tmp.resize(new_size * nb_quad_per_elem); vect.copy(tmp); } } } /* -------------------------------------------------------------------------- */ template void InternalField::printself(std::ostream & stream, int indent [[gnu::unused]]) const { stream << "InternalField [ " << this->getID(); #if !defined(AKANTU_NDEBUG) if (AKANTU_DEBUG_TEST(dblDump)) { stream << std::endl; ElementTypeMapArray::printself(stream, indent + 3); } else { #endif stream << " {" << this->getData(_not_ghost).size() << " types - " << this->getData(_ghost).size() << " ghost types" << "}"; #if !defined(AKANTU_NDEBUG) } #endif stream << " ]"; } /* -------------------------------------------------------------------------- */ template <> inline void ParameterTyped>::setAuto(const ParserParameter & in_param) { Parameter::setAuto(in_param); Real r = in_param; param.setDefaultValue(r); } /* -------------------------------------------------------------------------- */ template inline InternalField::operator T() const { return default_value; } } // namespace akantu #endif /* AKANTU_INTERNAL_FIELD_TMPL_HH_ */