diff --git a/python/swig/mesh.i b/python/swig/mesh.i index f294f8730..6a1ef95af 100644 --- a/python/swig/mesh.i +++ b/python/swig/mesh.i @@ -1,230 +1,230 @@ /** * @file mesh.i * * @author Guillaume Anciaux * @author Fabian Barras * @author Aurelia Isabel Cuba Ramos * @author Nicolas Richart * * @date creation: Fri Dec 12 2014 * @date last modification: Wed Jan 13 2016 * * @brief mesh wrapper * * @section LICENSE * * Copyright (©) 2015 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 "mesh.hh" #include "node_group.hh" #include "solid_mechanics_model.hh" #include "python_functor.hh" #include "mesh_utils.hh" #include "aka_bbox.hh" #include "mesh_accessor.hh" #include "communicator.hh" using akantu::IntegrationPoint; using akantu::Vector; using akantu::ElementTypeMapArray; using akantu::MatrixProxy; using akantu::Matrix; using akantu::UInt; using akantu::Real; using akantu::Array; using akantu::BBox; using akantu::Communicator; using akantu::SolidMechanicsModel; %} namespace akantu { %ignore NewNodesEvent; %ignore RemovedNodesEvent; %ignore NewElementsEvent; %ignore RemovedElementsEvent; %ignore MeshEventHandler; %ignore MeshEvent< UInt >; %ignore MeshEvent< Element >; %ignore Mesh::extractNodalCoordinatesFromPBCElement; %ignore Mesh::getGroupDumer; %ignore Mesh::getFacetLocalConnectivity; %ignore Mesh::getAllFacetTypes; %ignore Mesh::getCommunicator; %ignore Mesh::getConnectivities; %ignode Mesh::getBBox; %ignore GroupManager::getElementGroups; %ignore Dumpable::addDumpFieldExternalReal; } print_self(Mesh) // Swig considers enums to be ints, and it creates a conflict with two versions of getNbElement() %rename(getNbElementByDimension) akantu::Mesh::getNbElement(const UInt spatial_dimension = _all_dimensions, const GhostType& ghost_type = _not_ghost, const ElementKind& kind = _ek_not_defined) const; %extend akantu::Mesh { - // PyObject * getElementGroups(){ - // return akantu::PythonFunctor::convertToPython($self->getElementGroups()); - // } + PyObject * getElementGroups(){ + return akantu::PythonFunctor::convertToPython($self->getElementGroups()); + } PyObject * getAllConnectivities(){ return akantu::PythonFunctor::convertToPython($self->getConnectivities()); } void resizeMesh(UInt nb_nodes, UInt nb_element, const ElementType & type) { Array & nodes = const_cast &>($self->getNodes()); nodes.resize(nb_nodes); $self->addConnectivityType(type); Array & connectivity = const_cast &>($self->getConnectivity(type)); connectivity.resize(nb_element); } Array & getNodalDataReal(const ID & name, UInt nb_components = 1) { auto && data = $self->getNodalData(name, nb_components); data.resize($self->getNbNodes()); return data; } bool hasDataReal(const ID & name, const ElementType & type) { return $self->hasData(name, type); } Array & getElementalDataReal(const ID & name, const ElementType & type, UInt nb_components = 1) { auto && data = $self->getElementalDataArrayAlloc(name, type, akantu::_not_ghost, nb_components); data.resize($self->getNbElement(type, akantu::_not_ghost)); return data; } Array & getElementalDataUInt(const ID & name, const ElementType & type, UInt nb_components = 1) { auto && data = $self->getElementalDataArrayAlloc(name, type, akantu::_not_ghost, nb_components); data.resize($self->getNbElement(type, akantu::_not_ghost)); return data; } Array & computeBarycenters(const ElementType & type) { auto dim = $self->getSpatialDimension(); auto && data = $self->getElementalDataArrayAlloc("barycenters", type, akantu::_not_ghost, dim); auto nb_el = data.size(); auto total_nb_el = $self->getNbElement(type, akantu::_not_ghost); data.resize(total_nb_el); auto bary_it = make_view(data, dim).begin() + nb_el; for (auto el = nb_el; el < total_nb_el; ++el) { $self->getBarycenter(akantu::Element{type, el, akantu::_not_ghost}, *bary_it); ++bary_it; } return data; } void ready() { akantu::MeshAccessor ma(* $self); ma.makeReady(); } } %extend akantu::GroupManager { void createGroupsFromStringMeshData(const std::string & dataset_name) { if (dataset_name == "physical_names"){ AKANTU_EXCEPTION("Deprecated behavior: no need to call 'createGroupsFromStringMeshData' for physical names"); } $self->createGroupsFromMeshData(dataset_name); } void createGroupsFromUIntMeshData(const std::string & dataset_name) { $self->createGroupsFromMeshData(dataset_name); } } %extend akantu::NodeGroup { akantu::Array & getGroupedNodes(akantu::Array & surface_array, Mesh & mesh) { auto && group_node = $self->getNodes(); auto && full_array = mesh.getNodes(); surface_array.resize(group_node.size()); for (UInt i = 0; i < group_node.size(); ++i) { for (UInt cmp = 0; cmp < full_array.getNbComponent(); ++cmp) { surface_array(i, cmp) = full_array(group_node(i), cmp); } } akantu::Array & res(surface_array); return res; } akantu::Array & getGroupedArray(akantu::Array & surface_array, akantu::SolidMechanicsModel & model, int type) { akantu::Array * full_array; switch (type) { case 0 : full_array = new akantu::Array(model.getDisplacement()); break; case 1 : full_array = new akantu::Array(model.getVelocity()); break; case 2 : full_array = new akantu::Array(model.getExternalForce()); break; } akantu::Array group_node = $self->getNodes(); surface_array.resize(group_node.size()); for (UInt i = 0; i < group_node.size(); ++i) { for (UInt cmp = 0; cmp < full_array->getNbComponent(); ++cmp) { surface_array(i,cmp) = (*full_array)(group_node(i),cmp); } } akantu::Array & res(surface_array); return res; } } %include "group_manager.hh" %include "node_group.hh" %include "dumper_iohelper.hh" %include "dumpable_iohelper.hh" %include "element_group.hh" %include "mesh.hh" %include "mesh_utils.hh" %include "aka_bbox.hh" namespace akantu{ %extend Dumpable { void addDumpFieldExternalReal(const std::string & field_id, const Array & field){ $self->addDumpFieldExternal(field_id,field); } } } diff --git a/src/mesh/group_manager.hh b/src/mesh/group_manager.hh index 8879b03c0..543608c0c 100644 --- a/src/mesh/group_manager.hh +++ b/src/mesh/group_manager.hh @@ -1,364 +1,363 @@ /** * @file group_manager.hh * * @author Guillaume Anciaux * @author Dana Christen * @author David Simon Kammer * @author Nicolas Richart * @author Marco Vocialta * * @date creation: Wed Nov 13 2013 * @date last modification: Wed Feb 07 2018 * * @brief Stores information relevent to the notion of element and nodes * groups. * * @section LICENSE * * 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 . * */ /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_GROUP_MANAGER_HH__ #define __AKANTU_GROUP_MANAGER_HH__ /* -------------------------------------------------------------------------- */ #include "aka_common.hh" #include "aka_iterators.hh" #include "element_type_map.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ namespace akantu { class ElementGroup; class NodeGroup; class Mesh; class Element; class ElementSynchronizer; template class CommunicationBufferTemplated; namespace dumper { class Field; } } // namespace akantu namespace akantu { /* -------------------------------------------------------------------------- */ class GroupManager { /* ------------------------------------------------------------------------ */ /* Typedefs */ /* ------------------------------------------------------------------------ */ private: #ifdef SWIGPYTHON public: using ElementGroups = std::map; using NodeGroups = std::map; private: #else using ElementGroups = std::map; using NodeGroups = std::map; #endif public: using GroupManagerTypeSet = std::set; /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: GroupManager(const Mesh & mesh, const ID & id = "group_manager", const MemoryID & memory_id = 0); virtual ~GroupManager(); /* ------------------------------------------------------------------------ */ /* Groups iterators */ /* ------------------------------------------------------------------------ */ public: using node_group_iterator = NodeGroups::iterator; using element_group_iterator = ElementGroups::iterator; using const_node_group_iterator = NodeGroups::const_iterator; using const_element_group_iterator = ElementGroups::const_iterator; #ifndef SWIG #define AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(group_type, function, \ param_in, param_out) \ inline BOOST_PP_CAT(BOOST_PP_CAT(const_, group_type), _iterator) \ BOOST_PP_CAT(BOOST_PP_CAT(group_type, _), function)(param_in) const { \ return BOOST_PP_CAT(group_type, s).function(param_out); \ }; \ \ inline BOOST_PP_CAT(group_type, _iterator) \ BOOST_PP_CAT(BOOST_PP_CAT(group_type, _), function)(param_in) { \ return BOOST_PP_CAT(group_type, s).function(param_out); \ } #define AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(group_type, function) \ AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION( \ group_type, function, BOOST_PP_EMPTY(), BOOST_PP_EMPTY()) AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(node_group, begin); AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(node_group, end); AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(element_group, begin); AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(element_group, end); AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(element_group, find, const std::string & name, name); AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(node_group, find, const std::string & name, name); #endif public: #ifndef SWIG decltype(auto) iterateNodeGroups() { return make_dereference_adaptor(make_values_adaptor(node_groups)); } decltype(auto) iterateNodeGroups() const { return make_dereference_adaptor(make_values_adaptor(node_groups)); } decltype(auto) iterateElementGroups() { return make_dereference_adaptor(make_values_adaptor(element_groups)); } decltype(auto) iterateElementGroups() const { return make_dereference_adaptor(make_values_adaptor(element_groups)); } - #endif + // just for swig + const ElementGroups & getElementGroups() const { return element_groups; } /* ------------------------------------------------------------------------ */ /* Clustering filter */ - /* -------------------------------------------------------------------9+ ------ */ + /* ------------------------------------------------------------------------ */ public: class ClusteringFilter { public: virtual bool operator()(const Element &) const { return true; } }; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// create an empty node group NodeGroup & createNodeGroup(const std::string & group_name, bool replace_group = false); - /// create an element group and the associated node group + /// create an element group and the associated node group ElementGroup & createElementGroup(const std::string & group_name, UInt dimension = _all_dimensions, bool replace_group = false); /* ------------------------------------------------------------------------ */ /// renames an element group - void renameElementGroup(const std::string & name, const std::string & new_name); + void renameElementGroup(const std::string & name, + const std::string & new_name); /// renames a node group void renameNodeGroup(const std::string & name, const std::string & new_name); /// copy an existing element group - void copyElementGroup(const std::string & name, - const std::string & new_name); + void copyElementGroup(const std::string & name, const std::string & new_name); /// copy an existing node group - void copyNodeGroup(const std::string & name, - const std::string & new_name); + void copyNodeGroup(const std::string & name, const std::string & new_name); /* ------------------------------------------------------------------------ */ /// create a node group from another node group but filtered template NodeGroup & createFilteredNodeGroup(const std::string & group_name, const NodeGroup & node_group, T & filter); /// destroy a node group void destroyNodeGroup(const std::string & group_name); /// create an element group from another element group but filtered template ElementGroup & createFilteredElementGroup(const std::string & group_name, UInt dimension, const NodeGroup & node_group, T & filter); /// destroy an element group and the associated node group void destroyElementGroup(const std::string & group_name, bool destroy_node_group = false); /// destroy all element groups and the associated node groups void destroyAllElementGroups(bool destroy_node_groups = false); /// create a element group using an existing node group ElementGroup & createElementGroup(const std::string & group_name, UInt dimension, NodeGroup & node_group); /// create groups based on values stored in a given mesh data template void createGroupsFromMeshData(const std::string & dataset_name); /// create boundaries group by a clustering algorithm \todo extend to parallel UInt createBoundaryGroupFromGeometry(); /// create element clusters for a given dimension UInt createClusters(UInt element_dimension, Mesh & mesh_facets, std::string cluster_name_prefix = "cluster", const ClusteringFilter & filter = ClusteringFilter()); /// create element clusters for a given dimension UInt createClusters(UInt element_dimension, std::string cluster_name_prefix = "cluster", const ClusteringFilter & filter = ClusteringFilter()); private: /// create element clusters for a given dimension UInt createClusters(UInt element_dimension, const std::string & cluster_name_prefix, const ClusteringFilter & filter, Mesh & mesh_facets); public: /// Create an ElementGroup based on a NodeGroup void createElementGroupFromNodeGroup(const std::string & name, const std::string & node_group, UInt dimension = _all_dimensions); virtual void printself(std::ostream & stream, int indent = 0) const; /// this function insure that the group names are present on all processors /// /!\ it is a SMP call void synchronizeGroupNames(); /// register an elemental field to the given group name (overloading for /// ElementalPartionField) #ifndef SWIG template class dump_type> dumper::Field * createElementalField( const ElementTypeMapArray & field, const std::string & group_name, UInt spatial_dimension, const ElementKind & kind, ElementTypeMap nb_data_per_elem = ElementTypeMap()); /// register an elemental field to the given group name (overloading for /// ElementalField) template class ret_type, template class, bool> class dump_type> dumper::Field * createElementalField( const ElementTypeMapArray & field, const std::string & group_name, UInt spatial_dimension, const ElementKind & kind, ElementTypeMap nb_data_per_elem = ElementTypeMap()); /// register an elemental field to the given group name (overloading for /// MaterialInternalField) template class dump_type> dumper::Field * createElementalField(const ElementTypeMapArray & field, const std::string & group_name, UInt spatial_dimension, const ElementKind & kind, ElementTypeMap nb_data_per_elem); template class ftype> dumper::Field * createNodalField(const ftype * field, const std::string & group_name, UInt padding_size = 0); template class ftype> dumper::Field * createStridedNodalField(const ftype * field, const std::string & group_name, UInt size, UInt stride, UInt padding_size); protected: /// fill a buffer with all the group names void fillBufferWithGroupNames( CommunicationBufferTemplated & comm_buffer) const; /// take a buffer and create the missing groups localy void checkAndAddGroups(CommunicationBufferTemplated & buffer); /// register an elemental field to the given group name template inline dumper::Field * createElementalField(const field_type & field, const std::string & group_name, UInt spatial_dimension, const ElementKind & kind, const ElementTypeMap & nb_data_per_elem); /// register an elemental field to the given group name template inline dumper::Field * createElementalFilteredField(const field_type & field, const std::string & group_name, UInt spatial_dimension, const ElementKind & kind, ElementTypeMap nb_data_per_elem); #endif /* ------------------------------------------------------------------------ */ /* Accessor */ /* ------------------------------------------------------------------------ */ public: - //AKANTU_GET_MACRO(ElementGroups, element_groups, const ElementGroups &); + // AKANTU_GET_MACRO(ElementGroups, element_groups, const ElementGroups &); const ElementGroup & getElementGroup(const std::string & name) const; const NodeGroup & getNodeGroup(const std::string & name) const; ElementGroup & getElementGroup(const std::string & name); NodeGroup & getNodeGroup(const std::string & name); UInt getNbElementGroups(UInt dimension = _all_dimensions) const; UInt getNbNodeGroups() { return node_groups.size(); }; bool elementGroupExists(const std::string & name) { return element_groups.find(name) != element_groups.end(); } bool nodeGroupExists(const std::string & name) { return node_groups.find(name) != node_groups.end(); } - + private: + template + void renameGroup(GroupsType & groups, const std::string & name, + const std::string & new_name); - template - void renameGroup(GroupsType & groups, const std::string & name, const std::string & new_name); - /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// id to create element and node groups ID id; /// memory_id to create element and node groups MemoryID memory_id; /// list of the node groups managed NodeGroups node_groups; /// list of the element groups managed ElementGroups element_groups; /// Mesh to which the element belongs const Mesh & mesh; }; /// standard output stream operator inline std::ostream & operator<<(std::ostream & stream, const GroupManager & _this) { _this.printself(stream); return stream; } } // namespace akantu #endif /* __AKANTU_GROUP_MANAGER_HH__ */