diff --git a/src/common/aka_common.hh b/src/common/aka_common.hh index cccd36331..d185511cb 100644 --- a/src/common/aka_common.hh +++ b/src/common/aka_common.hh @@ -1,443 +1,450 @@ /** * @file aka_common.hh * * @author Nicolas Richart * * @date Mon Jun 14 19:12:20 2010 * * @brief common type descriptions for akantu * * @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 . * * @section DESCRIPTION * * All common things to be included in the projects files * */ /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_COMMON_HH__ #define __AKANTU_COMMON_HH__ /* -------------------------------------------------------------------------- */ #include #include /* -------------------------------------------------------------------------- */ #define __BEGIN_AKANTU__ namespace akantu { #define __END_AKANTU__ } /* -------------------------------------------------------------------------- */ #include "aka_config.hh" #include "aka_error.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ /* Common types */ /* -------------------------------------------------------------------------- */ typedef double Real; typedef unsigned int UInt; typedef unsigned long long UInt64; typedef signed int Int; typedef std::string ID; static const Real UINT_INIT_VALUE = 0; #ifdef AKANTU_NDEBUG static const Real REAL_INIT_VALUE = 0; #else static const Real REAL_INIT_VALUE = std::numeric_limits::quiet_NaN(); #endif /* -------------------------------------------------------------------------- */ /* Memory types */ /* -------------------------------------------------------------------------- */ typedef UInt MemoryID; /* -------------------------------------------------------------------------- */ /* Mesh/FEM/Model types */ /* -------------------------------------------------------------------------- */ typedef UInt Surface; typedef std::pair SurfacePair; typedef std::list< SurfacePair > SurfacePairList; /* -------------------------------------------------------------------------- */ /// @boost sequence of element to loop on in global tasks #define AKANTU_REGULAR_ELEMENT_TYPE \ (_not_defined) \ (_segment_2) \ (_segment_3) \ (_triangle_3) \ (_triangle_6) \ (_tetrahedron_4) \ (_tetrahedron_10) \ (_quadrangle_4) \ (_quadrangle_8) \ (_hexahedron_8) \ (_point) \ (_bernoulli_beam_2) #if defined(AKANTU_COHESIVE_ELEMENT) # define AKANTU_COHESIVE_ELEMENT_TYPE \ (_cohesive_2d_4) \ (_cohesive_2d_6) #else # define AKANTU_COHESIVE_ELEMENT_TYPE #endif #define AKANTU_ALL_ELEMENT_TYPE \ AKANTU_REGULAR_ELEMENT_TYPE AKANTU_COHESIVE_ELEMENT_TYPE /// @enum ElementType type of element potentially contained in a Mesh enum ElementType { _not_defined = 0, /// first order segment _segment_2 = 1, /// second order segment _segment_3 = 2, /// first order triangle _triangle_3 = 3, /// second order triangle _triangle_6 = 4, /// first order tetrahedron _tetrahedron_4 = 5, /// second order tetrahedron @remark not implemented yet _tetrahedron_10 = 6, /// first order quadrangle _quadrangle_4, /// second order quadrangle _quadrangle_8, /// first order hexahedron _hexahedron_8, /// point only for some algorithm to be generic like mesh partitioning _point, /// bernoulli beam 2D _bernoulli_beam_2, #if defined(AKANTU_COHESIVE_ELEMENT) /// first order 2D cohesive _cohesive_2d_4, /// second order 2D cohesive _cohesive_2d_6, #endif _max_element_type }; //! standard output stream operator for ElementType inline std::ostream & operator <<(std::ostream & stream, ElementType type); enum ElementKind { _ek_not_defined, _ek_regular, _ek_cohesive }; +/// enum MeshIOType type of mesh reader/writer +enum MeshIOType { + _miot_auto, + _miot_gmsh, + _miot_diana +}; + /// enum AnalysisMethod type of solving method used to solve the equation of motion enum AnalysisMethod { _static, _implicit_dynamic, _explicit_dynamic }; /// myfunction(double * position, double * stress/force, double * normal, unsigned int material_id) typedef void (*BoundaryFunction)(double *,double *, double*, unsigned int); /// @enum BoundaryFunctionType type of function passed for boundary conditions enum BoundaryFunctionType { _bft_stress, _bft_traction }; /// @enum SparseMatrixType type of sparse matrix used enum SparseMatrixType { _unsymmetric, _symmetric }; /* -------------------------------------------------------------------------- */ /* Contact */ /* -------------------------------------------------------------------------- */ typedef ID ContactID; typedef ID ContactSearchID; typedef ID ContactNeighborStructureID; enum ContactType { _ct_not_defined = 0, _ct_2d_expli = 1, _ct_3d_expli = 2, _ct_rigid = 3 }; enum ContactSearchType { _cst_not_defined = 0, _cst_2d_expli = 1, _cst_expli = 2 }; enum ContactNeighborStructureType { _cnst_not_defined = 0, _cnst_regular_grid = 1, _cnst_2d_grid = 2 }; /* -------------------------------------------------------------------------- */ /* Friction */ /* -------------------------------------------------------------------------- */ typedef ID FrictionID; /* -------------------------------------------------------------------------- */ /* Ghosts handling */ /* -------------------------------------------------------------------------- */ typedef ID SynchronizerID; /// @enum CommunicatorType type of communication method to use enum CommunicatorType { _communicator_mpi, _communicator_dummy }; /// @enum SynchronizationTag type of synchronizations enum SynchronizationTag { //--- SolidMechanicsModel tags --- /// synchronization of the SolidMechanicsModel.mass _gst_smm_mass, /// synchronization of the SolidMechanicsModel.current_position _gst_smm_for_strain, /// synchronization of the boundary, forces, velocities and displacement _gst_smm_boundary, /// synchronization of the nodal velocities and displacement _gst_smm_uv, /// synchronization of the nodal residual _gst_smm_res, /// synchronization of the data to initialize materials _gst_smm_init_mat, _gst_smm_stress, //--- HeatTransfer tags --- /// synchronization of the nodal heat capacity _gst_htm_capacity, /// synchronization of the nodal temperature _gst_htm_temperature, /// synchronization of the element gradient temperature _gst_htm_gradient_temperature, //--- Material non local --- /// synchronization of data to average in non local material _gst_mnl_for_average, /// synchronization of data for the weight computations _gst_mnl_weight, /// Test tag _gst_test }; /// standard output stream operator for SynchronizationTag inline std::ostream & operator <<(std::ostream & stream, SynchronizationTag type); /// @enum GhostType type of ghost enum GhostType { _not_ghost, _ghost, _casper // not used but a real cute ghost }; /// standard output stream operator for GhostType inline std::ostream & operator <<(std::ostream & stream, GhostType type); /// @enum SynchronizerOperation reduce operation that the synchronizer can perform enum SynchronizerOperation { _so_sum, _so_min, _so_max, _so_null }; /* -------------------------------------------------------------------------- */ /* Global defines */ /* -------------------------------------------------------------------------- */ #define AKANTU_MIN_ALLOCATION 2000 #define AKANTU_INDENT " " #define AKANTU_INCLUDE_INLINE_IMPL /* -------------------------------------------------------------------------- */ template struct is_scalar { enum{ value = false }; }; #define AKANTU_SPECIFY_IS_SCALAR(type) \ template<> \ struct is_scalar { \ enum { value = true }; \ } AKANTU_SPECIFY_IS_SCALAR(Real); AKANTU_SPECIFY_IS_SCALAR(UInt); AKANTU_SPECIFY_IS_SCALAR(Int); AKANTU_SPECIFY_IS_SCALAR(bool); template < typename T1, typename T2 > struct is_same { enum { value = false }; // is_same represents a bool. }; template < typename T > struct is_same { enum { value = true }; }; /* -------------------------------------------------------------------------- */ #define AKANTU_SET_MACRO(name, variable, type) \ inline void set##name (type variable) { \ this->variable = variable; \ } #define AKANTU_GET_MACRO(name, variable, type) \ inline type get##name () const { \ return variable; \ } #define AKANTU_GET_MACRO_NOT_CONST(name, variable, type) \ inline type get##name () { \ return variable; \ } #define AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(name, variable, type) \ inline const Vector & \ get##name (const ::akantu::ElementType & el_type, \ const GhostType & ghost_type = _not_ghost) const { \ AKANTU_DEBUG_IN(); \ \ AKANTU_DEBUG_OUT(); \ return variable(el_type, ghost_type); \ } #define AKANTU_GET_MACRO_BY_ELEMENT_TYPE(name, variable, type) \ inline Vector & \ get##name (const ::akantu::ElementType & el_type, \ const GhostType & ghost_type = _not_ghost) { \ AKANTU_DEBUG_IN(); \ \ AKANTU_DEBUG_OUT(); \ return variable(el_type, ghost_type); \ } /* -------------------------------------------------------------------------- */ void initialize(int & argc, char ** & argv); /* -------------------------------------------------------------------------- */ void finalize (); /* -------------------------------------------------------------------------- */ /* * For intel compiler annoying remark */ #if defined(__INTEL_COMPILER) /// remark #981: operands are evaluated in unspecified order #pragma warning ( disable : 981 ) /// remark #383: value copied to temporary, reference to temporary used #pragma warning ( disable : 383 ) #endif //defined(__INTEL_COMPILER) /* -------------------------------------------------------------------------- */ /* string manipulation */ /* -------------------------------------------------------------------------- */ inline std::string to_lower(const std::string & str); /* -------------------------------------------------------------------------- */ inline std::string trim(const std::string & to_trim); __END_AKANTU__ #include "aka_common_inline_impl.cc" /* -------------------------------------------------------------------------- */ // BOOST PART: TOUCH ONLY IF YOU KNOW WHAT YOU ARE DOING #include #define AKANTU_EXCLUDE_ELEMENT_TYPE(type) \ AKANTU_DEBUG_ERROR("Type (" << type << ") not handled by this function") #define AKANTU_BOOST_CASE_MACRO(r,macro,type) \ case type : { macro(type); break; } #define AKANTU_BOOST_ELEMENT_SWITCH(macro1, list1, macro2, list2) \ do { \ switch(type) { \ BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_CASE_MACRO, macro1, list1) \ BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_CASE_MACRO, macro2, list2) \ case _max_element_type: { \ AKANTU_DEBUG_ERROR("Wrong type : " << type); \ break; \ } \ } \ } while(0) #define AKANTU_BOOST_ALL_ELEMENT_SWITCH(macro1) \ do { \ switch(type) { \ BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_CASE_MACRO, macro1, AKANTU_ALL_ELEMENT_TYPE) \ case _max_element_type: { \ AKANTU_DEBUG_ERROR("Wrong type : " << type); \ break; \ } \ } \ } while(0) #define AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(macro) \ AKANTU_BOOST_ELEMENT_SWITCH(macro, \ AKANTU_REGULAR_ELEMENT_TYPE, \ AKANTU_EXCLUDE_ELEMENT_TYPE, \ AKANTU_COHESIVE_ELEMENT_TYPE) #define AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(macro) \ AKANTU_BOOST_ELEMENT_SWITCH(macro, \ AKANTU_COHESIVE_ELEMENT_TYPE, \ AKANTU_EXCLUDE_ELEMENT_TYPE, \ AKANTU_REGULAR_ELEMENT_TYPE) #define AKANTU_BOOST_LIST_MACRO(r,macro,type) \ macro(type) #define AKANTU_BOOST_ELEMENT_LIST(macro,list) \ BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_LIST_MACRO,macro,list) #define AKANTU_BOOST_ALL_ELEMENT_LIST(macro) \ AKANTU_BOOST_ELEMENT_LIST(macro, AKANTU_ALL_ELEMENT_TYPE) #define AKANTU_BOOST_REGULAR_ELEMENT_LIST(macro) \ AKANTU_BOOST_ELEMENT_LIST(macro, AKANTU_REGULAR_ELEMENT_TYPE) #define AKANTU_BOOST_COHESIVE_ELEMENT_LIST(macro) \ AKANTU_BOOST_ELEMENT_LIST(macro, AKANTU_COHESIVE_ELEMENT_TYPE) #endif /* __AKANTU_COMMON_HH__ */ diff --git a/src/fem/mesh.cc b/src/fem/mesh.cc index 7dbbef4ac..cacb2991b 100644 --- a/src/fem/mesh.cc +++ b/src/fem/mesh.cc @@ -1,319 +1,332 @@ /** * @file mesh.cc * * @author Guillaume Anciaux * @author Marco Vocialta * @author Nicolas Richart * * @date Fri Jun 18 11:47:19 2010 * * @brief class handling meshes * * @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 . * */ /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ #include "mesh.hh" +#include "mesh_io.hh" #include "element_class.hh" #include "static_communicator.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ const Element ElementNull(_not_defined, 0); /* -------------------------------------------------------------------------- */ void Element::printself(std::ostream & stream, int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Element [" << type << ", " << element << ", " << ghost_type << "]"; } /* -------------------------------------------------------------------------- */ Mesh::Mesh(UInt spatial_dimension, const ID & id, const MemoryID & memory_id) : Memory(memory_id), id(id), nodes_global_ids(NULL), nodes_type(NULL), created_nodes(true), connectivities("connectivities", id), normals("normals", id), spatial_dimension(spatial_dimension), types_offsets(Vector((UInt) _max_element_type + 1, 1)), ghost_types_offsets(Vector((UInt) _max_element_type + 1, 1)), nb_surfaces(0), surface_id("surface_id", id), element_to_subelement("element_to_subelement", id), subelement_to_element("subelement_to_element", id), uint_data("by_element_uint_data", id) { AKANTU_DEBUG_IN(); std::stringstream sstr; sstr << id << ":coordinates"; this->nodes = &(alloc(sstr.str(), 0, this->spatial_dimension)); nb_global_nodes = 0; init(); std::fill_n(lower_bounds, 3, 0.); std::fill_n(upper_bounds, 3, 0.); std::fill_n(size, 3, 0.); std::fill_n(local_lower_bounds, 3, 0.); std::fill_n(local_upper_bounds, 3, 0.); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ Mesh::Mesh(UInt spatial_dimension, const ID & nodes_id, const ID & id, const MemoryID & memory_id) : Memory(memory_id), id(id), nodes_global_ids(NULL), nodes_type(NULL), created_nodes(false), connectivities("connectivities", id), normals("normals", id), spatial_dimension(spatial_dimension), types_offsets(Vector((UInt) _max_element_type + 1, 1)), ghost_types_offsets(Vector((UInt) _max_element_type + 1, 1)), nb_surfaces(0), surface_id("surface_id", id), element_to_subelement("element_to_subelement", id), subelement_to_element("subelement_to_element", id), uint_data("by_element_uint_data", id) { AKANTU_DEBUG_IN(); this->nodes = &(getVector(nodes_id)); nb_global_nodes = nodes->getSize(); init(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ Mesh::Mesh(UInt spatial_dimension, Vector & nodes, const ID & id, const MemoryID & memory_id) : Memory(memory_id), id(id), nodes_global_ids(NULL), nodes_type(NULL), created_nodes(false), connectivities("connectivities", id), normals("normals", id), spatial_dimension(spatial_dimension), types_offsets(Vector(_max_element_type + 1, 1)), ghost_types_offsets(Vector(_max_element_type + 1, 1)), nb_surfaces(0), surface_id("surface_id", id), element_to_subelement("element_to_subelement", id), subelement_to_element("subelement_to_element", id), uint_data("by_element_uint_data", id) { AKANTU_DEBUG_IN(); this->nodes = &(nodes); nb_global_nodes = nodes.getSize(); init(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void Mesh::init() { // this->types_offsets.resize(_max_element_type); nodes_type = NULL; computeBoundingBox(); } /* -------------------------------------------------------------------------- */ Mesh::~Mesh() { AKANTU_DEBUG_IN(); for(UInt g = _not_ghost; g <= _ghost; ++g) { GhostType gt = (GhostType) g; Mesh::type_iterator it = firstType(0, gt); Mesh::type_iterator end = lastType(0, gt); for(; it != end; ++it) { UIntDataMap & map = uint_data(*it, gt); UIntDataMap::iterator dit; for (dit = map.begin(); dit != map.end(); ++dit) { if(dit->second) delete dit->second; } map.clear(); } } AKANTU_DEBUG_OUT(); } +/* -------------------------------------------------------------------------- */ +void Mesh::read (const std::string & filename, const MeshIOType & mesh_io_type) { + MeshIO mesh_io; + mesh_io.read(filename, *this, mesh_io_type); +} + +/* -------------------------------------------------------------------------- */ +void Mesh::write(const std::string & filename, const MeshIOType & mesh_io_type) { + MeshIO mesh_io; + mesh_io.write(filename, *this, mesh_io_type); +} + /* -------------------------------------------------------------------------- */ void Mesh::printself(std::ostream & stream, int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "Mesh [" << std::endl; stream << space << " + id : " << this->id << std::endl; stream << space << " + spatial dimension : " << this->spatial_dimension << std::endl; stream << space << " + nodes [" << std::endl; nodes->printself(stream, indent+2); stream << space << " ]" << std::endl; stream << space << " + connectivities [" << std::endl; connectivities.printself(stream, indent+2); stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ void Mesh::computeBoundingBox(){ AKANTU_DEBUG_IN(); for (UInt k = 0; k < spatial_dimension; ++k) { local_lower_bounds[k] = std::numeric_limits::max(); local_upper_bounds[k] = - std::numeric_limits::max(); } for (UInt i = 0; i < nodes->getSize(); ++i) { if(!isPureGhostNode(i)) for (UInt k = 0; k < spatial_dimension; ++k) { local_lower_bounds[k] = std::min(local_lower_bounds[k], (*nodes)(i, k)); local_upper_bounds[k] = std::max(local_upper_bounds[k], (*nodes)(i, k)); } } StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator(); Real reduce_bounds[2 * spatial_dimension]; for (UInt k = 0; k < spatial_dimension; ++k) { reduce_bounds[2*k ] = local_lower_bounds[k]; reduce_bounds[2*k + 1] = - local_upper_bounds[k]; } comm.allReduce(reduce_bounds, 2 * spatial_dimension, _so_min); for (UInt k = 0; k < spatial_dimension; ++k) { lower_bounds[k] = reduce_bounds[2*k]; upper_bounds[k] = - reduce_bounds[2*k + 1]; } for (UInt k = 0; k < spatial_dimension; ++k) size[k] = upper_bounds[k] - lower_bounds[k]; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void Mesh::setSurfaceIDsFromIntData(const std::string & data_name) { std::set surface_ids; for(UInt g = _not_ghost; g <= _ghost; ++g) { GhostType gt = (GhostType) g; Mesh::type_iterator it = firstType(spatial_dimension - 1, gt); Mesh::type_iterator end = lastType(spatial_dimension - 1, gt); for(; it != end; ++it) { UIntDataMap & map = uint_data(*it, gt); UIntDataMap::iterator it_data = map.find(data_name); AKANTU_DEBUG_ASSERT(it_data != map.end(), "No data named " << data_name << " present in the mesh " << id << " for the element type " << *it); AKANTU_DEBUG_ASSERT(!surface_id.exists(*it, gt), "Surface id for type (" << gt << ":" << *it << ") already set to the vector " << surface_id(*it, gt).getID()); surface_id.setVector(*it, gt, *it_data->second); for (UInt s = 0; s < it_data->second->getSize(); ++s) { surface_ids.insert((*it_data->second)(s)); } } } nb_surfaces = surface_ids.size(); } /* -------------------------------------------------------------------------- */ template void Mesh::initByElementTypeVector(ByElementTypeVector & vect, UInt nb_component, UInt dim, const bool & flag_nb_node_per_elem_multiply, ElementKind element_kind, bool size_to_nb_element) const { AKANTU_DEBUG_IN(); for(UInt g = _not_ghost; g <= _ghost; ++g) { GhostType gt = (GhostType) g; Mesh::type_iterator it = firstType(dim, gt, element_kind); Mesh::type_iterator end = lastType(dim, gt, element_kind); for(; it != end; ++it) { ElementType type = *it; if (flag_nb_node_per_elem_multiply) nb_component *= Mesh::getNbNodesPerElement(*it); UInt size = 0; if (size_to_nb_element) size = this->getNbElement(type, gt); vect.alloc(size, nb_component, type); } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template void Mesh::initByElementTypeVector(ByElementTypeVector & vect, UInt nb_component, UInt dim, const bool & flag_nb_elem_multiply, ElementKind element_kind, bool size_to_nb_element) const; template void Mesh::initByElementTypeVector(ByElementTypeVector & vect, UInt nb_component, UInt dim, const bool & flag_nb_elem_multiply, ElementKind element_kind, bool size_to_nb_element) const; template void Mesh::initByElementTypeVector(ByElementTypeVector & vect, UInt nb_component, UInt dim, const bool & flag_nb_elem_multiply, ElementKind element_kind, bool size_to_nb_element) const; template void Mesh::initByElementTypeVector(ByElementTypeVector & vect, UInt nb_component, UInt dim, const bool & flag_nb_elem_multiply, ElementKind element_kind, bool size_to_nb_element) const; __END_AKANTU__ diff --git a/src/fem/mesh.hh b/src/fem/mesh.hh index 658278e87..5c7916c0b 100644 --- a/src/fem/mesh.hh +++ b/src/fem/mesh.hh @@ -1,603 +1,606 @@ /** * @file mesh.hh * * @author Guillaume Anciaux * @author Marco Vocialta * @author Nicolas Richart * * @date Fri Jun 18 11:47:19 2010 * * @brief the class representing the meshes * * @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 . * */ /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MESH_HH__ #define __AKANTU_MESH_HH__ /* -------------------------------------------------------------------------- */ #include "aka_common.hh" #include "aka_memory.hh" #include "aka_vector.hh" #include "element_class.hh" #include "by_element_type.hh" #include "aka_event_handler.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ /* Element */ /* -------------------------------------------------------------------------- */ class Element { public: Element(ElementType type = _not_defined, UInt element = 0, GhostType ghost_type = _not_ghost, ElementKind kind = _ek_regular) : type(type), element(element), ghost_type(ghost_type), kind(kind) {}; Element(const Element & element) { this->type = element.type; this->element = element.element; this->ghost_type = element.ghost_type; this->kind = element.kind; } inline bool operator==(const Element & elem) const { return ((element == elem.element) && (type == elem.type) && (ghost_type == elem.ghost_type) && (kind == elem.kind)); } inline bool operator!=(const Element & elem) const { return ((element != elem.element) || (type != elem.type) || (ghost_type != elem.ghost_type) || (kind != elem.kind)); } bool operator<(const Element& rhs) const { bool res = ((this->kind < rhs.kind) || ((this->kind == rhs.kind) && ((this->ghost_type < rhs.ghost_type) || ((this->ghost_type == rhs.ghost_type) && ((this->type < rhs.type) || ((this->type == rhs.type) && (this->element < rhs.element))))))); return res; } virtual ~Element() {}; /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const; public: ElementType type; UInt element; GhostType ghost_type; ElementKind kind; }; struct CompElementLess { bool operator() (const Element& lhs, const Element& rhs) const { return lhs < rhs; } }; extern const Element ElementNull; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* Mesh modifications events */ /* -------------------------------------------------------------------------- */ template class MeshEvent { public: const Vector & getList() const { return list; } Vector & getList() { return list; } protected: Vector list; }; class Mesh; class NewNodesEvent : public MeshEvent { }; class RemovedNodesEvent : public MeshEvent { public: inline RemovedNodesEvent(const Mesh & mesh); AKANTU_GET_MACRO_NOT_CONST(NewNumbering, new_numbering, Vector &); AKANTU_GET_MACRO(NewNumbering, new_numbering, const Vector &); private: Vector new_numbering; }; class NewElementsEvent : public MeshEvent { }; class RemovedElementsEvent : public MeshEvent { public: inline RemovedElementsEvent(const Mesh & mesh); AKANTU_GET_MACRO(NewNumbering, new_numbering, const ByElementTypeUInt &); AKANTU_GET_MACRO_NOT_CONST(NewNumbering, new_numbering, ByElementTypeUInt &); AKANTU_GET_MACRO_BY_ELEMENT_TYPE(NewNumbering, new_numbering, UInt); AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(NewNumbering, new_numbering, UInt); protected: ByElementTypeUInt new_numbering; }; /* -------------------------------------------------------------------------- */ class MeshEventHandler { public: virtual ~MeshEventHandler() {}; /* ------------------------------------------------------------------------ */ /* Internal code */ /* ------------------------------------------------------------------------ */ protected: inline void sendEvent(const NewNodesEvent & event) { onNodesAdded (event.getList()); } inline void sendEvent(const RemovedNodesEvent & event) { onNodesRemoved(event.getList(), event.getNewNumbering()); } inline void sendEvent(const NewElementsEvent & event) { onElementsAdded (event.getList()); } inline void sendEvent(const RemovedElementsEvent & event) { onElementsRemoved(event.getList(), event.getNewNumbering()); } template friend class EventHandlerManager; /* ------------------------------------------------------------------------ */ /* Interface */ /* ------------------------------------------------------------------------ */ public: virtual void onNodesAdded (__attribute__((unused)) const Vector & nodes_list) { } virtual void onNodesRemoved(__attribute__((unused)) const Vector & nodes_list, __attribute__((unused)) const Vector & new_numbering) { } virtual void onElementsAdded (__attribute__((unused)) const Vector & elements_list) { } virtual void onElementsRemoved(__attribute__((unused)) const Vector & elements_list, __attribute__((unused)) const ByElementTypeUInt & new_numbering) { } }; /* -------------------------------------------------------------------------- */ /* Mesh */ /* -------------------------------------------------------------------------- */ /** * @class Mesh this contain the coordinates of the nodes in the Mesh.nodes * Vector, and the connectivity. The connectivity are stored in by element * types. * * To know all the element types present in a mesh you can get the * Mesh::ConnectivityTypeList * * In order to loop on all element you have to loop on all types like this : * @code Mesh::type_iterator it = mesh.firstType(dim, ghost_type); Mesh::type_iterator end = mesh.lastType(dim, ghost_type); for(; it != end; ++it) { UInt nb_element = mesh.getNbElement(*it); const Vector & conn = mesh.getConnectivity(*it); for(UInt e = 0; e < nb_element; ++e) { ... } } @endcode */ class Mesh : protected Memory, public EventHandlerManager { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: /// constructor that create nodes coordinates array Mesh(UInt spatial_dimension, const ID & id = "mesh", const MemoryID & memory_id = 0); /// constructor that use an existing nodes coordinates array, by knowing its ID Mesh(UInt spatial_dimension, const ID & nodes_id, const ID & id = "mesh", const MemoryID & memory_id = 0); /** * constructor that use an existing nodes coordinates * array, by getting the vector of coordinates */ Mesh(UInt spatial_dimension, Vector & nodes, const ID & id = "mesh", const MemoryID & memory_id = 0); virtual ~Mesh(); /// @typedef ConnectivityTypeList list of the types present in a Mesh typedef std::set ConnectivityTypeList; - // typedef Vector * NormalsMap[_max_element_type]; + /// read the mesh from a file + void read (const std::string & filename, const MeshIOType & mesh_io_type = _miot_auto); + /// write the mesh to a file + void write(const std::string & filename, const MeshIOType & mesh_io_type = _miot_auto); + private: /// initialize the connectivity to NULL and other stuff void init(); /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const; /// function that computes the bounding box (fills xmin, xmax) void computeBoundingBox(); /// init a by-element-type real vector with provided ids template void initByElementTypeVector(ByElementTypeVector & v, UInt nb_component, UInt spatial_dimension, const bool & flag_nb_node_per_elem_multiply = false, ElementKind element_kind = _ek_regular, bool size_to_nb_element = false) const; /// @todo: think about nicer way to do it /// extract coordinates of nodes from an element template inline void extractNodalValuesFromElement(const Vector & nodal_values, T * elemental_values, UInt * connectivity, UInt n_nodes, UInt nb_degree_of_freedom) const; /// extract coordinates of nodes from a reversed element inline void extractNodalCoordinatesFromPBCElement(Real * local_coords, UInt * connectivity, UInt n_nodes); /// convert a element to a linearized element inline UInt elementToLinearized(const Element & elem) const; /// convert a linearized element to an element inline Element linearizedToElement (UInt linearized_element) const; /// update the types offsets array for the conversions inline void updateTypesOffsets(const GhostType & ghost_type); /// add a Vector of connectivity for the type . inline void addConnectivityType(const ElementType & type); /* ------------------------------------------------------------------------ */ template inline void sendEvent(Event & event) { if(event.getList().getSize() != 0) EventHandlerManager::sendEvent(event); } /* ------------------------------------------------------------------------ */ template inline void removeNodesFromVector(Vector & vect, const Vector & new_numbering); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: AKANTU_GET_MACRO(ID, id, const ID &); /// get the spatial dimension of the mesh = number of component of the coordinates AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt); /// get the nodes Vector aka coordinates AKANTU_GET_MACRO(Nodes, *nodes, const Vector &); AKANTU_GET_MACRO_NOT_CONST(Nodes, *nodes, Vector &); /// get the number of nodes AKANTU_GET_MACRO(NbNodes, nodes->getSize(), UInt); /// get the Vector of global ids of the nodes (only used in parallel) AKANTU_GET_MACRO(GlobalNodesIds, *nodes_global_ids, const Vector &); /// get the global id of a node inline UInt getNodeGlobalId(UInt local_id) const; /// get the global number of nodes inline UInt getNbGlobalNodes() const; /// get the nodes type Vector AKANTU_GET_MACRO(NodesType, *nodes_type, const Vector &); inline Int getNodeType(UInt local_id) const; /// say if a node is a pure ghost node inline bool isPureGhostNode(UInt n) const; /// say if a node is pur local or master node inline bool isLocalOrMasterNode(UInt n) const; inline bool isLocalNode(UInt n) const; inline bool isMasterNode(UInt n) const; inline bool isSlaveNode(UInt n) const; AKANTU_GET_MACRO(XMin, lower_bounds[0], Real); AKANTU_GET_MACRO(YMin, lower_bounds[1], Real); AKANTU_GET_MACRO(ZMin, lower_bounds[2], Real); AKANTU_GET_MACRO(XMax, upper_bounds[0], Real); AKANTU_GET_MACRO(YMax, upper_bounds[1], Real); AKANTU_GET_MACRO(ZMax, upper_bounds[2], Real); inline void getLowerBounds(Real * lower) const; inline void getUpperBounds(Real * upper) const; inline void getLocalLowerBounds(Real * lower) const; inline void getLocalUpperBounds(Real * upper) const; /// get the number of surfaces AKANTU_GET_MACRO(NbSurfaces, nb_surfaces, UInt); /// get the connectivity Vector for a given type AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Connectivity, connectivities, UInt); AKANTU_GET_MACRO_BY_ELEMENT_TYPE(Connectivity, connectivities, UInt); AKANTU_GET_MACRO(Connectivities, connectivities, const ByElementTypeVector &); /// @todo take out this set, if mesh can read surface id /// set the number of surfaces AKANTU_SET_MACRO(NbSurfaces, nb_surfaces, UInt); /// get the number of element of a type in the mesh inline UInt getNbElement(const ElementType & type, const GhostType & ghost_type = _not_ghost) const; // /// get the number of ghost element of a type in the mesh // inline UInt getNbGhostElement(const ElementType & type) const; /// get the connectivity list either for the elements or the ghost elements inline const ConnectivityTypeList & getConnectivityTypeList(const GhostType & ghost_type = _not_ghost) const; /// compute the barycenter of a given element inline void getBarycenter(UInt element, const ElementType & type, Real * barycenter, GhostType ghost_type = _not_ghost) const; /// get the element connected to a subelement AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(ElementToSubelement, element_to_subelement, Vector); AKANTU_GET_MACRO_BY_ELEMENT_TYPE(ElementToSubelement, element_to_subelement, Vector); /// get the subelement connected to an element AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(SubelementToElement, subelement_to_element, Element); AKANTU_GET_MACRO_BY_ELEMENT_TYPE(SubelementToElement, subelement_to_element, Element); /// get the surface values of facets AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(SurfaceID, surface_id, UInt); AKANTU_GET_MACRO_BY_ELEMENT_TYPE(SurfaceID, surface_id, UInt); /// set the int data to the surface id vectors void setSurfaceIDsFromIntData(const std::string & data_name); inline const Vector & getUIntData(const ElementType & el_type, const std::string & data_name, const GhostType & ghost_type = _not_ghost) const; /* ------------------------------------------------------------------------ */ /* Wrappers on ElementClass functions */ /* ------------------------------------------------------------------------ */ public: /// get the number of nodes per element for a given element type static inline UInt getNbNodesPerElement(const ElementType & type); /// get the number of nodes per element for a given element type considered as /// a first order element static inline ElementType getP1ElementType(const ElementType & type); /// get the kind of the element type static inline ElementKind getKind(const ElementType & type); /// get spatial dimension of a type of element static inline UInt getSpatialDimension(const ElementType & type); /// get number of facets of a given element type static inline UInt getNbFacetsPerElement(const ElementType & type); /// get local connectivity of a facet for a given facet type static inline UInt ** getFacetLocalConnectivity(const ElementType & type); /// get the type of the surface element associated to a given element static inline ElementType getFacetElementType(const ElementType & type); /// get the pointer to the list of elements for a given type inline Vector * getReversedElementsPBCPointer(const ElementType & type); /* ------------------------------------------------------------------------ */ /* Element type Iterator */ /* ------------------------------------------------------------------------ */ typedef ByElementTypeUInt::type_iterator type_iterator; inline type_iterator firstType(UInt dim = 0, GhostType ghost_type = _not_ghost, ElementKind kind = _ek_regular) const { return connectivities.firstType(dim, ghost_type, kind); } inline type_iterator lastType(UInt dim = 0, GhostType ghost_type = _not_ghost, ElementKind kind = _ek_regular) const { return connectivities.lastType(dim, ghost_type, kind); } - /* ------------------------------------------------------------------------ */ /* Private methods for friends */ /* ------------------------------------------------------------------------ */ private: friend class MeshIOMSH; friend class MeshIOMSHStruct; friend class MeshIODiana; friend class MeshUtils; friend class DistributedSynchronizer; AKANTU_GET_MACRO(NodesPointer, nodes, Vector *); /// get a pointer to the nodes_global_ids Vector and create it if necessary inline Vector * getNodesGlobalIdsPointer(); /// get a pointer to the nodes_type Vector and create it if necessary inline Vector * getNodesTypePointer(); /// get a pointer to the connectivity Vector for the given type and create it if necessary inline Vector * getConnectivityPointer(const ElementType & type, const GhostType & ghost_type = _not_ghost); // inline Vector * getNormalsPointer(ElementType type) const; /// get a pointer to the surface_id Vector for the given type and create it if necessary inline Vector * getSurfaceIDPointer(const ElementType & type, const GhostType & ghost_type = _not_ghost); /// get the UIntDataMap for a given ElementType inline UIntDataMap & getUIntDataMap(const ElementType & el_type, const GhostType & ghost_type = _not_ghost); /// get the IntDataMap pointer (modifyable) for a given ElementType inline Vector * getUIntDataPointer(const ElementType & el_type, const std::string & data_name, const GhostType & ghost_type = _not_ghost); /// get a pointer to the element_to_subelement Vector for the given type and create it if necessary inline Vector > * getElementToSubelementPointer(const ElementType & type, const GhostType & ghost_type = _not_ghost); /// get a pointer to the subelement_to_element Vector for the given type and create it if necessary inline Vector * getSubelementToElementPointer(const ElementType & type, const GhostType & ghost_type = _not_ghost); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: /// id of the mesh ID id; /// array of the nodes coordinates Vector * nodes; /// global node ids Vector * nodes_global_ids; /// node type, -3 pure ghost, -2 master for the node, -1 normal node, i in /// [0-N] slave node and master is proc i Vector * nodes_type; /// global number of nodes; UInt nb_global_nodes; /// boolean to know if the nodes have to be deleted with the mesh or not bool created_nodes; /// all class of elements present in this mesh (for heterogenous meshes) ByElementTypeUInt connectivities; /// map to normals for all class of elements present in this mesh ByElementTypeReal normals; /// list of all existing types in the mesh ConnectivityTypeList type_set; /// the spatial dimension of this mesh UInt spatial_dimension; /// types offsets Vector types_offsets; /// list of all existing types in the mesh ConnectivityTypeList ghost_type_set; /// ghost types offsets Vector ghost_types_offsets; /// number of surfaces present in this mesh UInt nb_surfaces; /// surface id of the surface elements in this mesh ByElementTypeUInt surface_id; /// min of coordinates Real lower_bounds[3]; /// max of coordinates Real upper_bounds[3]; /// size covered by the mesh on each direction Real size[3]; /// local min of coordinates Real local_lower_bounds[3]; /// local max of coordinates Real local_upper_bounds[3]; /// List of elements connected to subelements ByElementTypeVector > element_to_subelement; /// List of subelements connected to elements ByElementTypeVector subelement_to_element; // /// list of elements that are reversed due to pbc // ByElementTypeUInt reversed_elements_pbc; // /// direction in which pbc are to be applied // UInt pbc_directions[3]; /// list of the vectors corresponding to tags in the mesh ByElementTypeUIntDataMap uint_data; }; /* -------------------------------------------------------------------------- */ /* Inline functions */ /* -------------------------------------------------------------------------- */ /// standard output stream operator inline std::ostream & operator <<(std::ostream & stream, const Element & _this) { _this.printself(stream); return stream; } #if defined (AKANTU_INCLUDE_INLINE_IMPL) # include "mesh_inline_impl.cc" #endif #include "by_element_type_tmpl.hh" /// standard output stream operator inline std::ostream & operator <<(std::ostream & stream, const Mesh & _this) { _this.printself(stream); return stream; } __END_AKANTU__ #endif /* __AKANTU_MESH_HH__ */ diff --git a/src/io/dumper/dumpable.hh b/src/io/dumper/dumpable.hh index 9d32255eb..9d3c3395f 100644 --- a/src/io/dumper/dumpable.hh +++ b/src/io/dumper/dumpable.hh @@ -1,184 +1,228 @@ /** * @file dumpable.hh * * @author Guillaume Anciaux * @author Nicolas Richart * * @date Fri Oct 26 21:52:40 2012 * * @brief Interface for object who wants to dump themselves * * @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 . * */ /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_DUMPABLE_HH__ #define __AKANTU_DUMPABLE_HH__ #ifdef AKANTU_USE_IOHELPER #include "aka_common.hh" #include "dumper_paraview.hh" __BEGIN_AKANTU__ template class Dumpable { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: Dumpable(const std::string & filename) : dumper(filename) {}; virtual ~Dumpable() { }; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: void addDumpMesh(const Mesh & mesh, UInt spatial_dimension = 0, const GhostType & ghost_type = _not_ghost, const ElementKind & element_kind = _ek_not_defined) { dumper.registerMesh(mesh, spatial_dimension, ghost_type, element_kind); } virtual void addDumpField(const std::string & field_id) = 0; - virtual void addDumpFieldExternal(const std::string & field_id, DumperIOHelper::Field * field) { + virtual void addDumpFieldExternal(__attribute__((unused)) const std::string & field_id, + __attribute__((unused)) DumperIOHelper::Field * field) { dumper.registerField(field_id, field); } + template + void addDumpFieldExternal(const std::string & field_id, const Vector & field) { + DumperIOHelper::Field * field_cont = new DumperIOHelper::NodalField(field); + dumper.registerField(field_id, field_cont); + } + + template + void addDumpFieldExternal(const std::string & field_id, + const ByElementTypeVector & field, + UInt spatial_dimension = 0, + const GhostType & ghost_type = _not_ghost, + const ElementKind & element_kind = _ek_not_defined) { + DumperIOHelper::Field * field_cont = new DumperIOHelper::ElementalField(field, + spatial_dimension, + ghost_type, + element_kind); + dumper.registerField(field_id, field_cont); + } + + void removeDumpField(const std::string & field_id) { dumper.unRegisterField(field_id); } void setDirectory(const std::string & directory) { dumper.setDirectory(directory); } void setBaseName(const std::string & basename) { dumper.setBaseName(basename); } void dump() { dumper.dump(); } protected: void addDumpFieldToDumper(const std::string & field_id, DumperIOHelper::Field * field) { dumper.registerField(field_id, field); } protected: /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: Dumper dumper; }; #else __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ class DumperIOHelper { class Field; }; class DumperParaview; /* -------------------------------------------------------------------------- */ template class Dumpable { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: Dumpable(const std::string & filename) { }; virtual ~Dumpable() { }; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: - void addDumpMesh(const Mesh & mesh, UInt spatial_dimension = 0, - const GhostType & ghost_type = _not_ghost, - const ElementKind & element_kind = _ek_not_defined) { + void addDumpMesh(__attribute__((unused)) const Mesh & mesh, + __attribute__((unused)) UInt spatial_dimension = 0, + __attribute__((unused)) const GhostType & ghost_type = _not_ghost, + __attribute__((unused)) const ElementKind & element_kind = _ek_not_defined) { } - virtual void addDumpField(const std::string & field_id) = 0; - virtual void addDumpFieldExternal(const std::string & field_id, DumperIOHelper::Field * field) { + virtual void addDumpField(__attribute__((unused)) const std::string & field_id) = 0; + virtual void addDumpFieldExternal(__attribute__((unused)) const std::string & field_id, + __attribute__((unused)) DumperIOHelper::Field * field) { AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake."); } - virtual void addDumpFieldVector(const std::string & field_id) {}; - virtual void addDumpFieldTensor(const std::string & field_id) {}; - void removeDumpField(const std::string & field_id) { + + template + void addDumpFieldExternal(__attribute__((unused)) const std::string & field_id, + __attribute__((unused)) const Vector & field) { AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake."); } - void setDirectory(const std::string & directory) { + template + void addDumpFieldExternal(__attribute__((unused)) const std::string & field_id, + __attribute__((unused)) const ByElementTypeVector & field, + __attribute__((unused)) UInt spatial_dimension = 0, + __attribute__((unused)) const GhostType & ghost_type = _not_ghost, + __attribute__((unused)) const ElementKind & element_kind = _ek_not_defined) { AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake."); } - void setBaseName(const std::string & basename) { + virtual void addDumpFieldVector(__attribute__((unused)) const std::string & field_id) { + AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake."); + }; + virtual void addDumpFieldTensor(__attribute__((unused)) const std::string & field_id) { + AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake."); + }; + void removeDumpField(__attribute__((unused)) const std::string & field_id) { + AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake."); + } + + void setDirectory(__attribute__((unused)) const std::string & directory) { + AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake."); + } + + void setBaseName(__attribute__((unused)) const std::string & basename) { AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake."); } void dump() { AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake."); } protected: - void addDumpFieldToDumper(const std::string & field_id, DumperIOHelper::Field & field) { + void addDumpFieldToDumper(__attribute__((unused)) const std::string & field_id, + __attribute__((unused)) DumperIOHelper::Field & field) { AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on AKANTU_USE_IOHELPER in cmake."); } protected: /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: }; #endif //AKANTU_USE_IOHELPER __END_AKANTU__ #endif /* __AKANTU_DUMPABLE_HH__ */ diff --git a/src/mesh_utils/mesh_io.cc b/src/mesh_utils/mesh_io.cc index bbbc7671d..eb40b4463 100644 --- a/src/mesh_utils/mesh_io.cc +++ b/src/mesh_utils/mesh_io.cc @@ -1,51 +1,89 @@ /** * @file mesh_io.cc * * @author Nicolas Richart * * @date Thu Jul 15 00:41:12 2010 * * @brief common part for all mesh io classes * * @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 . * */ /* -------------------------------------------------------------------------- */ #include "aka_common.hh" #include "mesh_io.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ MeshIO::MeshIO() { canReadSurface = false; canReadExtendedData = false; } /* -------------------------------------------------------------------------- */ MeshIO::~MeshIO() { } + +/* -------------------------------------------------------------------------- */ +MeshIO * MeshIO::getMeshIO(const std::string & filename, const MeshIOType & type) { + MeshIOType t = type; + if(type == _miot_auto) { + std::string::size_type idx = filename.rfind('.'); + std::string ext; + if(idx != std::string::npos) { + ext = filename.substr(idx+1); + } + + if(ext == "msh") t = _miot_gmsh; + else if(ext == "diana") t = _miot_diana; + else AKANTU_EXCEPTION("Cannot guess the type of file of " + << filename << " (ext "<< ext <<"). " + << "Please provide the MeshIOType to the read function"); + } + + switch(t) { + case _miot_gmsh: return new MeshIOMSH(); + case _miot_diana: return new MeshIODiana(); + default: + return NULL; + } +} + /* -------------------------------------------------------------------------- */ +void MeshIO::read(const std::string & filename, Mesh & mesh, const MeshIOType & type) { + MeshIO * mesh_io = getMeshIO(filename, type); + mesh_io->read(filename, mesh); + delete mesh_io; +} + +/* -------------------------------------------------------------------------- */ +void MeshIO::write(const std::string & filename, Mesh & mesh, const MeshIOType & type) { + MeshIO * mesh_io = getMeshIO(filename, type); + mesh_io->write(filename, mesh); + delete mesh_io; +} __END_AKANTU__ diff --git a/src/mesh_utils/mesh_io.hh b/src/mesh_utils/mesh_io.hh index 17c72b279..4fb3e84fb 100644 --- a/src/mesh_utils/mesh_io.hh +++ b/src/mesh_utils/mesh_io.hh @@ -1,85 +1,92 @@ /** * @file mesh_io.hh * * @author Nicolas Richart * * @date Fri Jun 18 11:47:19 2010 * * @brief interface of a mesh io class, reader and writer * * @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 . * */ /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MESH_IO_HH__ #define __AKANTU_MESH_IO_HH__ /* -------------------------------------------------------------------------- */ #include "aka_common.hh" #include "mesh.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ class MeshIO { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: MeshIO(); virtual ~MeshIO(); /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: + void read(const std::string & filename, Mesh & mesh, const MeshIOType & type); + void write(const std::string & filename, Mesh & mesh, const MeshIOType & type); + /// read a mesh from the file - virtual void read(const std::string & filename, Mesh & mesh) = 0; + virtual void read(const std::string & filename, Mesh & mesh) {}; /// write a mesh to a file - virtual void write(const std::string & filename, const Mesh & mesh) = 0; + virtual void write(const std::string & filename, const Mesh & mesh) {}; + +private: + MeshIO * getMeshIO(const std::string & filename, const MeshIOType & type); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: bool canReadSurface; bool canReadExtendedData; // std::string filename; // Mesh & mesh; }; __END_AKANTU__ #endif /* __AKANTU_MESH_IO_HH__ */ #include "mesh_io_msh.hh" +#include "mesh_io_diana.hh"