diff --git a/CMakeLists.txt b/CMakeLists.txt index d728dc027..4d8ed1f13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,113 +1,115 @@ #=============================================================================== # @file CMakeLists.txt # @author Nicolas Richart # @date Fri Jun 11 09:46:59 2010 # # @section LICENSE # # # # @section DESCRIPTION # #=============================================================================== #=============================================================================== # _ ,-, _ # ,--, /: :\/': :`\/: :\ # |`; ' `,' `.; `: | _ _ # | | | ' | |. | | | | # | : | F E | A S | T++ || __ _| | ____ _ _ __ | |_ _ _ # | :. | : | : | : | \ / _` | |/ / _` | '_ \| __| | | | # \__/: :.. : :.. | :.. | ) | (_| | < (_| | | | | |_| |_| | # `---',\___/,\___/ /' \__,_|_|\_\__,_|_| |_|\__|\__,_| # `==._ .. . /' # `-::-' #=============================================================================== #=============================================================================== # CMake Project #=============================================================================== cmake_minimum_required(VERSION 2.6) project(AKANTU) enable_language(CXX) #=============================================================================== # Misc. #=============================================================================== set(AKANTU_CMAKE_DIR "${AKANTU_SOURCE_DIR}/cmake") set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries.") #=============================================================================== # Version Number #=============================================================================== # AKANTU version number. An even minor number corresponds to releases. set(AKANTU_MAJOR_VERSION 0) set(AKANTU_MINOR_VERSION 1) set(AKANTU_BUILD_VERSION 0) set(AKANTU_VERSION "${AKANTU_MAJOR_VERSION}.${AKANTU_MINOR_VERSION}.${AKANTU_BUILD_VERSION}" ) # Append the library version information to the library target properties if(NOT AKANTU_NO_LIBRARY_VERSION) set(AKANTU_LIBRARY_PROPERTIES ${AKANTU_LIBRARY_PROPERTIES} VERSION "${AKANTU_VERSION}" SOVERSION "${AKANTU_MAJOR_VERSION}.${AKANTU_MINOR_VERSION}" ) endif(NOT AKANTU_NO_LIBRARY_VERSION) #=============================================================================== # Library #=============================================================================== #add_definitions(-DAKANTU_NDEBUG) set(AKANTU_COMMON_SRC common/extern.cc common/static_memory.cc common/memory.cc -# common/vector.cc + common/vector.cc fem/mesh.cc + mesh_io/mesh_io.cc mesh_io/mesh_io_msh.cc ) set(AKANTU_INCLUDE_DIRS common fem/ mesh_io/ ) include_directories( ${AKANTU_INCLUDE_DIRS} ) add_library(akantu ${AKANTU_COMMON_SRC}) set_target_properties(akantu PROPERTIES ${AKANTU_LIBRARY_PROPERTIES}) #=============================================================================== # Tests #=============================================================================== option(BUILD_UNIT_TEST "Build the unit test") if(BUILD_UNIT_TEST) set(AKANTU_UNIT_TESTS test/static_memory.cc + test/mesh_io_msh.cc test/vector.cc ) foreach(_test ${AKANTU_UNIT_TESTS}) get_filename_component(_target "${_test}" NAME_WE) add_executable(test_${_target} ${_test}) target_link_libraries(test_${_target} akantu) endforeach(_test) endif(BUILD_UNIT_TEST) \ No newline at end of file diff --git a/common/common.hh b/common/common.hh index 45d55668a..8809b0328 100644 --- a/common/common.hh +++ b/common/common.hh @@ -1,78 +1,108 @@ /** * @file common.hh * @author Nicolas Richart * @date Fri Jun 11 09:48:06 2010 * * @section LICENSE * * * * @section DESCRIPTION * * All common things to be included in the projects files * */ /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_COMMON_HH__ #define __AKANTU_COMMON_HH__ /* -------------------------------------------------------------------------- */ #include #include #include #include /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ #define __BEGIN_AKANTU__ namespace akantu { #define __END_AKANTU__ }; /* -------------------------------------------------------------------------- */ #include "error.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ /* Memory types */ /* -------------------------------------------------------------------------- */ typedef unsigned int MemoryID; typedef std::string VectorID; +/* -------------------------------------------------------------------------- */ +/* Mesh types */ +/* -------------------------------------------------------------------------- */ + +typedef std::string MeshID; + +enum ElementType { + _not_defined = 0, + _triangle_1 = 1, + _triangle_2 = 2, + _tetrahedra_1 = 3, + _tetrahedra_2 = 4, + _max_element_type +}; + +/* -------------------------------------------------------------------------- */ +//! standard output stream operator for ElementType +inline std::ostream & operator <<(std::ostream & stream, ElementType type) +{ + switch(type) + { + case _triangle_1 : stream << "triangle 1st order" ; break; + case _triangle_2 : stream << "triangle 2nd order" ; break; + case _tetrahedra_1 : stream << "tetrahedra 1st order"; break; + case _tetrahedra_2 : stream << "tetrahedra 2nd order"; break; + default : stream << "unknown ElementType (" << type << ")"; break; + } + return stream; +} + __END_AKANTU__ /* -------------------------------------------------------------------------- */ /* Global defines */ /* -------------------------------------------------------------------------- */ #define AKANTU_MIN_ALLOCATION 2000 #define AKANTU_INDENT " " #define MAX_NUMBER_OF_NODE_PER_ELEMENT 10 // tetrahedron of second order /* -------------------------------------------------------------------------- */ #define AKANTU_SET_MACRO(name, variable, type) \ inline void set##name (type variable) { \ this->variable = variable; \ } #define AKANTU_GET_MACRO(name, variable, type) \ inline const type get##name () const { \ return this->variable; \ } #define AKANTU_GET_MACRO_SCALAR(name, variable, type) \ inline type get##name () const { \ return this->variable; \ } #endif /* __AKANTU_COMMON_HH__ */ diff --git a/common/error.hh b/common/error.hh index 8b4830fa5..ac3c21040 100644 --- a/common/error.hh +++ b/common/error.hh @@ -1,181 +1,181 @@ /** * @file error.hh * @author Nicolas Richart * @date Mon Jun 14 11:43:22 2010 * * @brief error management and internal exceptions * * @section LICENSE * * * */ /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_ERROR_HH__ #define __AKANTU_ERROR_HH__ /* -------------------------------------------------------------------------- */ #include #include /* -------------------------------------------------------------------------- */ #include "common.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ extern std::ostream & _akantu_cout; extern std::ostream & _akantu_debug_cout; extern int _debug_level; /* -------------------------------------------------------------------------- */ /// exception class that can be thrown by akantu class Exception : public std::exception { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: //! full constructor Exception(std::string info, std::string file, unsigned int line) : _info(info), _file(file), _line(line) { } //! destructor virtual ~Exception() throw() {}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: virtual const char* what() const throw() { std::stringstream stream; stream << "akantu::Exception" << " : " << _info << " [" << _file << ":" << _line << "]"; return stream.str().c_str(); } /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: /// exception description and additionals std::string _info; /// file it is thrown from std::string _file; /// ligne it is thrown from unsigned int _line; }; /* -------------------------------------------------------------------------- */ enum DebugLevel { dbl0 = 0, dblError = 0, dbl1 = 1, dblException = 1, dblCritical = 1, dbl2 = 2, dblMajor = 2, dbl3 = 3, dblCall = 3, dblSecondary = 3, dblHead = 3, dbl4 = 4, dblWarning = 4, dbl5 = 5, dblInfo = 5, dbl6 = 6, dblIn = 6, dblOut = 6, dbl7 = 7, dbl8 = 8, dblTrace = 8, dbl9 = 9, dbl10 = 10, dblDump = 100 }; #define AKANTU_LOCATION "(" <<__FILE__ << ":" << __LINE__ << ") " #ifndef AKANTU_MPI #define AKANTU_EXIT(status) \ do { \ exit(status); \ } while(0) #else #define AKANTU_EXIT(status) \ do { \ MPI_Finalize(); \ exit(status); \ } while(0) #endif /* -------------------------------------------------------------------------- */ #ifdef AKANTU_NDEBUG #define AKANTU_DEBUG_TEST(level) (0) #define AKANTU_DEBUG(level,info) #define AKANTU_DEBUG_IN() #define AKANTU_DEBUG_OUT() #define AKANTU_DEBUG_INFO(info) #define AKANTU_DEBUG_WARNING(info) #define AKANTU_DEBUG_TRACE(info) #define AKANTU_DEBUG_ASSERT(test,info) /* -------------------------------------------------------------------------- */ #else #define AKANTU_DEBUG(level,info) \ ((akantu::_debug_level >= level) && \ (_akantu_debug_cout << info << " " << AKANTU_LOCATION << std::endl)) #define AKANTU_DEBUG_TEST(level) \ (akantu::_debug_level >= (level)) #define AKANTU_DEBUG_IN() \ AKANTU_DEBUG(akantu::dblIn , "==> " << __func__ << "()") #define AKANTU_DEBUG_OUT() \ AKANTU_DEBUG(akantu::dblOut , "<== " << __func__ << "()") #define AKANTU_DEBUG_INFO(info) \ AKANTU_DEBUG(akantu::dblInfo , "--- " << info) #define AKANTU_DEBUG_WARNING(info) \ AKANTU_DEBUG(akantu::dblWarning, "??? " << info) #define AKANTU_DEBUG_TRACE(info) \ AKANTU_DEBUG(akantu::dblTrace , ">>> " << info) #define AKANTU_DEBUG_ASSERT(test,info) \ do { \ if (!(test)) { \ - _akantu_debug_cout << "(" <<__FILE__ << ":" << __LINE__ << ") " \ + _akantu_debug_cout << "(" <<__FILE__ << ":" << __LINE__ << ")" \ << "assert [" << #test << "] " \ << "!!! " << info \ << std::endl; \ AKANTU_EXIT(EXIT_FAILURE); \ } \ } while(0) #endif /* -------------------------------------------------------------------------- */ #define AKANTU_DEBUG_ERROR(info) \ do { \ AKANTU_DEBUG(akantu::dblError, "!!! " << info); \ std::stringstream s_info; \ s_info << info ; \ Exception ex(s_info.str(), __FILE__, __LINE__ ); \ throw ex; \ } while(0) /* -------------------------------------------------------------------------- */ __END_AKANTU__ #endif /* __AKANTU_ERROR_HH__ */ diff --git a/common/memory.hh b/common/memory.hh index 2ab156fb1..98e893f34 100644 --- a/common/memory.hh +++ b/common/memory.hh @@ -1,93 +1,81 @@ /** * @file memory.hh * @author Nicolas Richart * @date Tue Jun 15 09:30:23 2010 * * @brief wrapper for the static_memory, all object which wants * to access the ststic_memory as to inherit from the class memory * * @section LICENSE * * * */ /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MEMORY_HH__ #define __AKANTU_MEMORY_HH__ /* -------------------------------------------------------------------------- */ #include "common.hh" #include "static_memory.hh" #include "vector.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ class Memory { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: Memory(MemoryID memory_id = 0); virtual ~Memory() {}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// malloc template inline Vector & malloc(const VectorID & name, unsigned int size, unsigned int nb_component); /* ------------------------------------------------------------------------ */ /// free an array inline void free(const VectorID & name); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: /// the static memory instance StaticMemory * static_memory; /// the id registred in the static memory MemoryID memory_id; }; /* -------------------------------------------------------------------------- */ /* Inline functions */ /* -------------------------------------------------------------------------- */ -template inline Vector & Memory::malloc(const VectorID & name, - unsigned int size, - unsigned int nb_component) { - return static_memory->smalloc(memory_id, name, - size, nb_component); -} - -/* -------------------------------------------------------------------------- */ -inline void Memory::free(const VectorID & name) { - static_memory->sfree(memory_id, name); -} - -/* -------------------------------------------------------------------------- */ +#include "memory_inline_impl.cc" __END_AKANTU__ #endif /* __AKANTU_MEMORY_HH__ */ diff --git a/common/memory_inline_impl.cc b/common/memory_inline_impl.cc new file mode 100644 index 000000000..6ff740ee8 --- /dev/null +++ b/common/memory_inline_impl.cc @@ -0,0 +1,26 @@ +/** + * @file memory_inline_impl.cc + * @author Nicolas Richart + * @date Thu Jul 15 00:22:48 2010 + * + * @brief Implementation of the inline functions of the class Memory + * + * @section LICENSE + * + * + * + */ + +/* -------------------------------------------------------------------------- */ +template inline Vector & Memory::malloc(const VectorID & name, + unsigned int size, + unsigned int nb_component) { + return static_memory->smalloc(memory_id, name, + size, nb_component); +} + +/* -------------------------------------------------------------------------- */ +inline void Memory::free(const VectorID & name) { + static_memory->sfree(memory_id, name); +} + diff --git a/common/static_memory.hh b/common/static_memory.hh index d8389e517..27ec77330 100644 --- a/common/static_memory.hh +++ b/common/static_memory.hh @@ -1,187 +1,132 @@ /** * @file static_memory.hh * @author Nicolas Richart * @date Thu Jun 10 14:19:25 2010 * * @brief Memory management * * @section LICENSE * * * * @section DESCRIPTION * * The class handling the memory, allocation/reallocation/desallocation * The objects can register their array and ask for allocation or realocation */ /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_STATIC_MEMORY_HH__ #define __AKANTU_STATIC_MEMORY_HH__ /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ #include "common.hh" #include "vector.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ typedef std::map VectorMap; typedef std::map MemoryMap; /** * @class StaticMemory * @brief Class for memory management common to all objects (this class as to * be accessed by an interface class memory) */ class StaticMemory { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ private: /// Default constructor StaticMemory() {}; public: ~StaticMemory(); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /// Get the global instance of the StaticMemory static StaticMemory * getStaticMemory(); public: /// access to an Vector inline const VectorBase & getVector(const MemoryID & memory_id, const VectorID & name) const; /// get all vectors of a memory inline const VectorMap & getMemory(const MemoryID & memory_id) const; /* ------------------------------------------------------------------------ */ /* Class Methods */ /* ------------------------------------------------------------------------ */ public: /** * Allocation of an array of type * * @param memory_id the id of the memory accessing to the static memory * @param name name of the array (for example connectivity) * @param size number of size (for example number of nodes) * @param nb_component number of component (for example spatial dimention) * @param type the type code of the array to be allocated * * @return pointer to an array of size nb_tupes * nb_component * sizeof(T) */ template Vector & smalloc(const MemoryID & memory_id, const VectorID & name, unsigned int size, unsigned int nb_component); /** * free the memory associated to the array name * * @param memory_id the id of the memory accessing to the static memory * @param name the name of an existing array */ void sfree(const MemoryID & memory_id, const VectorID & name); /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const; /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: /// unique instance of the StaticMemory static StaticMemory * single_static_memory; /// map of all allocated arrays, indexed by their names MemoryMap memories; }; -/* -------------------------------------------------------------------------- */ -/* inline functions */ -/* -------------------------------------------------------------------------- */ -inline const VectorMap & StaticMemory::getMemory(const MemoryID & memory_id) const { - AKANTU_DEBUG_IN(); - MemoryMap::const_iterator memory_it; - memory_it = memories.find(memory_id); - - if(memory_it == memories.end()) { - AKANTU_DEBUG_ERROR("StaticMemory as no memory with ID " << memory_id); - } - AKANTU_DEBUG_OUT(); - return memory_it->second; -} - -/* -------------------------------------------------------------------------- */ -inline const VectorBase & StaticMemory::getVector(const MemoryID & memory_id, - const VectorID & name) const { - AKANTU_DEBUG_IN(); - - const VectorMap & vectors = getMemory(memory_id); - - VectorMap::const_iterator vectors_it; - vectors_it = vectors.find(name); - if(vectors_it == vectors.end()) { - AKANTU_DEBUG_ERROR("StaticMemory as no array named " << name - << " for the Memory " << memory_id); - } - - AKANTU_DEBUG_OUT(); - return *(vectors_it->second); -} +#include "static_memory_inline_impl.cc" /* -------------------------------------------------------------------------- */ -template Vector & StaticMemory::smalloc(const MemoryID & memory_id, - const VectorID & name, - unsigned int size, - unsigned int nb_component) { - AKANTU_DEBUG_IN(); - - MemoryMap::iterator memory_it; - memory_it = memories.find(memory_id); - - if(memory_it == memories.end()){ - memories[memory_id] = VectorMap(); - memory_it = memories.find(memory_id); - } - - if((memory_it->second).find(name) != (memory_it->second).end()) { - AKANTU_DEBUG_ERROR("The vector " << name << " is already registred in the memory " << memory_id); - } - - (memory_it->second)[name] = new Vector(size, nb_component, name); - - AKANTU_DEBUG_OUT(); - return static_cast &>(*(memory_it->second)[name]); -} - +/* inline functions */ /* -------------------------------------------------------------------------- */ /// standard output stream operator inline std::ostream & operator<<(std::ostream & stream, const StaticMemory & _this) { _this.printself(stream); return stream; } - __END_AKANTU__ #endif /* __AKANTU_STATIC_MEMORY_HH__ */ diff --git a/common/static_memory_inline_impl.cc b/common/static_memory_inline_impl.cc new file mode 100644 index 000000000..a0d6f7377 --- /dev/null +++ b/common/static_memory_inline_impl.cc @@ -0,0 +1,70 @@ +/** + * @file static_memory_inline_impl.cc + * @author Nicolas Richart + * @date Thu Jul 15 00:32:05 2010 + * + * @brief Implementation of inline functions of the class StaticMemory + * + * @section LICENSE + * + * + * + */ + +/* -------------------------------------------------------------------------- */ +inline const VectorMap & StaticMemory::getMemory(const MemoryID & memory_id) const { + AKANTU_DEBUG_IN(); + MemoryMap::const_iterator memory_it; + memory_it = memories.find(memory_id); + + if(memory_it == memories.end()) { + AKANTU_DEBUG_ERROR("StaticMemory as no memory with ID " << memory_id); + } + AKANTU_DEBUG_OUT(); + return memory_it->second; +} + +/* -------------------------------------------------------------------------- */ +inline const VectorBase & StaticMemory::getVector(const MemoryID & memory_id, + const VectorID & name) const { + AKANTU_DEBUG_IN(); + + const VectorMap & vectors = getMemory(memory_id); + + VectorMap::const_iterator vectors_it; + vectors_it = vectors.find(name); + if(vectors_it == vectors.end()) { + AKANTU_DEBUG_ERROR("StaticMemory as no array named " << name + << " for the Memory " << memory_id); + } + + AKANTU_DEBUG_OUT(); + return *(vectors_it->second); +} + +/* -------------------------------------------------------------------------- */ +template Vector & StaticMemory::smalloc(const MemoryID & memory_id, + const VectorID & name, + unsigned int size, + unsigned int nb_component) { + AKANTU_DEBUG_IN(); + + MemoryMap::iterator memory_it; + memory_it = memories.find(memory_id); + + if(memory_it == memories.end()){ + memories[memory_id] = VectorMap(); + memory_it = memories.find(memory_id); + } + + if((memory_it->second).find(name) != (memory_it->second).end()) { + AKANTU_DEBUG_ERROR("The vector " << name << " is already registred in the memory " << memory_id); + } + + (memory_it->second)[name] = new Vector(size, nb_component, name); + + AKANTU_DEBUG_OUT(); + return static_cast &>(*(memory_it->second)[name]); +} + +/* -------------------------------------------------------------------------- */ diff --git a/common/vector.cc b/common/vector.cc index aaa55f0a7..a84e064dc 100644 --- a/common/vector.cc +++ b/common/vector.cc @@ -1,31 +1,155 @@ /** * @file vector.cc * @author Nicolas Richart * @date Thu Jun 17 15:14:24 2010 * * @brief class vector * * @section LICENSE * * * */ /* -------------------------------------------------------------------------- */ #include "common.hh" #include "vector.hh" +__BEGIN_AKANTU__ + + +/* -------------------------------------------------------------------------- */ +/* Functions VectorBase */ +/* -------------------------------------------------------------------------- */ +VectorBase::VectorBase() { + allocated_size = 0; + size = 0; + nb_component = 1; + size_of_type=0; + id = ""; +}; + /* -------------------------------------------------------------------------- */ void VectorBase::printself(std::ostream & stream, int indent) const { std::string space; for(int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << indent << "VectorBase [" << std::endl; - stream << indent << " + nb tuples : " << nb_tuples << std::endl; - stream << indent << " + nb_component : " << nb_component << std::endl; - stream << indent << " + nb allocated tuples : " << nb_allocated_tuples << std::endl; - int size = nb_allocated_tuples * nb_component * size_of_type; - stream << indent << " + size : " << size << "B" << std::endl; + stream << indent << " + size : " << size << std::endl; + stream << indent << " + nb component : " << nb_component << std::endl; + stream << indent << " + allocated size : " << allocated_size << std::endl; + double mem_size = (allocated_size * nb_component * size_of_type) / 1024.; + stream << indent << " + size of type : " << size_of_type << "B" << std::endl; + stream << indent << " + memory allocated : " << mem_size << "kB" << std::endl; stream << indent << "]" << std::endl; } /* -------------------------------------------------------------------------- */ +/* Functions Vector */ +/* -------------------------------------------------------------------------- */ +template Vector::Vector (unsigned int size, + unsigned int nb_component, + const VectorID & id) { + AKANTU_DEBUG_IN(); + this->id = id; + this->values = NULL; + allocate(size, nb_component); + AKANTU_DEBUG_OUT(); +} + +/* -------------------------------------------------------------------------- */ +template Vector::Vector (unsigned int size, + unsigned int nb_component, + const T def_values[], + const VectorID & id) { + AKANTU_DEBUG_IN(); + this->id = id; + this->values = NULL; + allocate(size, nb_component); + + for (unsigned int i = 0; i < size; ++i) { + for (unsigned int j = 0; j < nb_component; ++j) { + values[i*nb_component + j] = def_values[j]; + } + } + AKANTU_DEBUG_OUT(); +} + +/* -------------------------------------------------------------------------- */ +template Vector::Vector (unsigned int size, + unsigned int nb_component, + const T& value, + const VectorID & id) { + AKANTU_DEBUG_IN(); + this->id = id; + this->values = NULL; + allocate(size, nb_component); + + for (unsigned int i = 0; i < nb_component*size; ++i) { + values[i] = value; + } + + AKANTU_DEBUG_OUT(); +} + + +/* -------------------------------------------------------------------------- */ +template Vector::Vector(const Vector& vect, bool deep) { + AKANTU_DEBUG_IN(); + this->id = vect.id; + if (deep) { + allocate(vect.size, vect.nb_component); + for (unsigned int i = 0; i < size; ++i) { + for (unsigned int j = 0; j < nb_component; ++j) { + values[i*nb_component + j] = vect.values[i*nb_component + j]; + } + } + } else { + this->values = vect.values; + this->size = vect.size; + this->nb_component = vect.nb_component; + this->allocated_size = vect.allocated_size; + this->size_of_type = vect.size_of_type; + } + + AKANTU_DEBUG_OUT(); +} + +/* -------------------------------------------------------------------------- */ +template void Vector::allocate(unsigned int size, + unsigned int nb_component) { + AKANTU_DEBUG_IN(); + if (size == 0){ + values = NULL; + } else { + values = static_cast(malloc(nb_component * size * sizeof(T))); + AKANTU_DEBUG_ASSERT(values != NULL, + "Cannot allocate " << nb_component * size * sizeof(T) << " bytes"); + } + + if (values == NULL) { + this->size = this->allocated_size = 0; + } else { + AKANTU_DEBUG_INFO("Allocated " << size * nb_component * sizeof(T) << " bytes"); + this->size = this->allocated_size = size; + } + + this->size_of_type = sizeof(T); + this->nb_component = nb_component; + + AKANTU_DEBUG_OUT(); +} + +/* -------------------------------------------------------------------------- */ +template Vector::~Vector () { + free(values); + size = allocated_size = 0; +} + +/* -------------------------------------------------------------------------- */ + +template class Vector; +template class Vector; +template class Vector; +template class Vector; + +__END_AKANTU__ diff --git a/common/vector.hh b/common/vector.hh index 19c29664d..9e68d1940 100644 --- a/common/vector.hh +++ b/common/vector.hh @@ -1,388 +1,181 @@ /** * @file vector.hh * @author Nicolas Richart * @date Thu Jun 17 10:04:55 2010 * * @brief class of vectors * * @section LICENSE * * * */ /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_VECTOR_HH__ #define __AKANTU_VECTOR_HH__ /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ #include "common.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /// class that afford to store vectors in static memory class VectorBase { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - VectorBase(){ - allocated_size = 0; - size = 0; - nb_component = 1; - size_of_type=0; - id = ""; - }; + VectorBase(); virtual ~VectorBase() {}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// get the amount of space allocated in bytes inline unsigned int getMemorySize() const; /// function to print the containt of the class - virtual void printself(std::ostream & stream, int indent = 0) const {}; + virtual void printself(std::ostream & stream, int indent = 0) const; /* ------------------------------------------------------------------------ */ /* Accesors */ /* ------------------------------------------------------------------------ */ public: AKANTU_GET_MACRO_SCALAR(AllocatedSize, allocated_size, unsigned int); AKANTU_GET_MACRO_SCALAR(Size, size, unsigned int); AKANTU_GET_MACRO_SCALAR(NbComponent, nb_component, unsigned int); - + /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// the size allocated unsigned int allocated_size; /// the size used unsigned int size; /// number of components unsigned int nb_component; /// size of the stored type unsigned int size_of_type; /// id of the vector VectorID id; }; /* -------------------------------------------------------------------------- */ template class Vector : public VectorBase { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: /// Allocation of a new vector Vector(unsigned int size, unsigned int nb_component, const VectorID & id = ""); /// Allocation of a new vector with a default value Vector(unsigned int size, unsigned int nb_component, - const T def_value[], const VectorID & id = ""); + const T def_values[], const VectorID & id = ""); - /// Copy constructor (deep copy if deep=true) \todo to implement + /// Allocation of a new vector with a default value + Vector(unsigned int size, unsigned int nb_component, + const T & value, const VectorID & id = ""); + + /// Copy constructor (deep copy if deep=true) \todo to implement Vector(const Vector& vect, bool deep = true); virtual ~Vector(); - - /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// get jth componemt of the ith tuple inline T & at(unsigned int i, unsigned int j = 0); + /// add an element at the and of the vector with the value value for all + /// component + inline void push_back(const T& value); + /// add an element at the and of the vector inline void push_back(const T new_elem[]); /** * remove an element and move the last one in the hole * /!\ change the order in the vector */ inline void erase(unsigned int i); /// change the size of the vector and allocate more memory if needed void resize(unsigned int size); /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const; + // Vector& operator=(const Vector& vect); - Vector& operator = (const Vector& vect); - protected: /// perform the allocation for the constructors - inline void allocate(unsigned int size, unsigned int nb_component); + void allocate(unsigned int size, unsigned int nb_component); /* ------------------------------------------------------------------------ */ /* Accesors */ /* ------------------------------------------------------------------------ */ public: - unsigned int getSize()const{return this->size;}; + unsigned int getSize() const{ return this->size; }; /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ public: /// array of values T *values; // /!\ very dangerous }; - +#include "vector_inline_impl.cc" /* -------------------------------------------------------------------------- */ /* Inline Functions Vector */ -/* -------------------------------------------------------------------------- */ - -/* -------------------------------------------------------------------------- */ -template Vector::Vector (unsigned int size, - unsigned int nb_component, - const VectorID & id) { - AKANTU_DEBUG_IN(); - this->id = id; - this->values = NULL; - allocate(size, nb_component); - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -template Vector::Vector (unsigned int size, - unsigned int nb_component, - const T def_value[], - const VectorID & id) { - AKANTU_DEBUG_IN(); - this->id = id; - this->values = NULL; - allocate(size, nb_component); - - for (unsigned int i = 0; i < size; ++i) { - for (unsigned int j = 0; j < nb_component; ++j) { - values[i*nb_component + j] = def_value[j]; - } - } - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -template Vector::Vector(const Vector& vect, bool deep) { - AKANTU_DEBUG_IN(); - this->id = vect.id; - if (deep) { - allocate(vect.size, vect.nb_component); - for (unsigned int i = 0; i < size; ++i) { - for (unsigned int j = 0; j < nb_component; ++j) { - values[i*nb_component + j] = vect.values[i*nb_component + j]; - } - } - } else { - this->values = vect.values; - this->size = vect.size; - this->nb_component = vect.nb_component; - this->allocated_size = vect.allocated_size; - this->size_of_type = vect.size_of_type; - } - - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -template Vector& Vector::operator= (const Vector& vect) { - AKANTU_DEBUG_IN(); - // this->id = std::string(vect.id); - allocate(vect.size, vect.nb_component); - for (unsigned int i = 0; i < size; ++i) { - for (unsigned int j = 0; j < nb_component; ++j) { - values[i*nb_component + j] = vect.values[i*nb_component + j]; - } - } - - AKANTU_DEBUG_OUT(); - return *this; -} - -/* -------------------------------------------------------------------------- */ -template inline void Vector::allocate(unsigned int size, - unsigned int nb_component) { - AKANTU_DEBUG_IN(); - if (size == 0){ - values = NULL; - } else { - values = static_cast(malloc(nb_component * size * sizeof(T))); - AKANTU_DEBUG_ASSERT(values != NULL, - "Cannot allocate " << nb_component * size * sizeof(T) << " bytes"); - } - - if (values == NULL) { - this->size = this->allocated_size = 0; - } else { - AKANTU_DEBUG_INFO("Allocated " << size * nb_component * sizeof(T) << " bytes"); - this->size = this->allocated_size = size; - } - - this->size_of_type = sizeof(T); - this->nb_component = nb_component; - - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -template Vector::~Vector () { - free(values); - size = allocated_size = 0; -} - -/* -------------------------------------------------------------------------- */ -template inline T & Vector::at(unsigned int i, unsigned int j) { - AKANTU_DEBUG_IN(); - AKANTU_DEBUG_ASSERT((i < size) && (j < nb_component), - "The value at position [" << i << "," << j - << "] is out of range"); - - AKANTU_DEBUG_OUT(); - return values[i*nb_component + j]; -} - -/* -------------------------------------------------------------------------- */ -template inline void Vector::push_back(const T new_elem[]) { - AKANTU_DEBUG_IN(); - unsigned int pos = size; - - resize(size+1); - for (unsigned int i = 0; i < nb_component; ++i) { - values[pos*nb_component + i] = new_elem[i]; - } - AKANTU_DEBUG_OUT(); -} - - -/* -------------------------------------------------------------------------- */ -template inline void Vector::erase(unsigned int i){ - AKANTU_DEBUG_IN(); - if(i != (size - 1)) { - for (unsigned int j = 0; j < nb_component; ++j) { - values[i*nb_component + j] = values[(size-1)*nb_component + j]; - } - } - - resize(size - 1); - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ - -template void Vector::resize (unsigned int new_size) { - AKANTU_DEBUG_IN(); - if(new_size <= allocated_size) { - if(allocated_size - new_size > AKANTU_MIN_ALLOCATION) { - AKANTU_DEBUG_INFO("Freeing " << (allocated_size - size)*nb_component*sizeof(T) << " bytes"); - - /// Normally there are no allocation problem when reducing an array - values = static_cast(realloc(values, new_size * nb_component * sizeof(T))); - allocated_size = size; - } - - size = new_size; - AKANTU_DEBUG_OUT(); - return; - } - - unsigned int size_to_alloc = (new_size - allocated_size < AKANTU_MIN_ALLOCATION) ? - allocated_size + AKANTU_MIN_ALLOCATION : new_size; - - T *tmp_ptr = static_cast(realloc(values, size_to_alloc * nb_component * sizeof(T))); - AKANTU_DEBUG_ASSERT(tmp_ptr != NULL, - "Cannot allocate " << size_to_alloc * nb_component * sizeof(T) << " bytes"); - if (!tmp_ptr) return; - - AKANTU_DEBUG_INFO("Allocating " << (size_to_alloc - allocated_size)*nb_component*sizeof(T) << " bytes"); - - allocated_size = size_to_alloc; - size = new_size; - values = tmp_ptr; - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -template void Vector::printself(std::ostream & stream, int indent) const { - std::string space; - for(int i = 0; i < indent; i++, space += AKANTU_INDENT); - - int real_size = allocated_size * nb_component * size_of_type; - - stream << space << "Vector<" << typeid(T).name() << "> [" << std::endl; - stream << space << " + id : " << id << std::endl; - stream << space << " + size : " << size << std::endl; - stream << space << " + nb_component : " << nb_component << std::endl; - stream << space << " + allocated size : " << allocated_size << std::endl; - stream << space << " + memory size : " << real_size << "B" << std::endl; - stream << space << " + adresse : " << std::hex << values << std::dec << std::endl; - if(AKANTU_DEBUG_TEST(dblDump)) { - stream << space << " + values : {"; - for (unsigned int i = 0; i < size; ++i) { - stream << "{"; - for (unsigned int j = 0; j < nb_component; ++j) { - stream << values[i*nb_component + j]; - if(j != nb_component - 1) stream << ", "; - } - stream << "}"; - if(i != size - 1) stream << ", "; - } - stream << "}" << std::endl; - } - stream << space << "]" << std::endl; -} - /* -------------------------------------------------------------------------- */ template inline std::ostream & operator<<(std::ostream & stream, const Vector & _this) { _this.printself(stream); return stream; } /* -------------------------------------------------------------------------- */ /* Inline Functions VectorBase */ -/* -------------------------------------------------------------------------- */ - -inline unsigned int VectorBase::getMemorySize() const { - return allocated_size * nb_component * size_of_type; -} - /* -------------------------------------------------------------------------- */ inline std::ostream & operator<<(std::ostream & stream, const VectorBase & _this) { _this.printself(stream); return stream; } __END_AKANTU__ #endif /* __AKANTU_VECTOR_HH__ */ diff --git a/common/vector_inline_impl.cc b/common/vector_inline_impl.cc new file mode 100644 index 000000000..4ce7e0800 --- /dev/null +++ b/common/vector_inline_impl.cc @@ -0,0 +1,131 @@ +/** + * @file vector_inline_impl.cc + * @author Nicolas Richart + * @date Thu Jul 15 00:09:33 2010 + * + * @brief Inline functions of the classes Vector and VectorBase + * + * @section LICENSE + * + * + * + */ + +/* -------------------------------------------------------------------------- */ +/* Inline Functions Vector */ +/* -------------------------------------------------------------------------- */ +template inline T & Vector::at(unsigned int i, unsigned int j) { + AKANTU_DEBUG_IN(); + AKANTU_DEBUG_ASSERT(size > 0, + "The vector is empty"); + AKANTU_DEBUG_ASSERT((i < size) && (j < nb_component), + "The value at position [" << i << "," << j + << "] is out of range"); + + AKANTU_DEBUG_OUT(); + return values[i*nb_component + j]; +} + +/* -------------------------------------------------------------------------- */ +template inline void Vector::push_back(const T new_elem[]) { + AKANTU_DEBUG_IN(); + unsigned int pos = size; + + resize(size+1); + for (unsigned int i = 0; i < nb_component; ++i) { + values[pos*nb_component + i] = new_elem[i]; + } + AKANTU_DEBUG_OUT(); +} + + +/* -------------------------------------------------------------------------- */ +template inline void Vector::erase(unsigned int i){ + AKANTU_DEBUG_IN(); + AKANTU_DEBUG_ASSERT((size > 0), + "The vector is empty"); + AKANTU_DEBUG_ASSERT((i < size), + "The element at position [" << i << "] is out of range"); + + + if(i != (size - 1)) { + for (unsigned int j = 0; j < nb_component; ++j) { + values[i*nb_component + j] = values[(size-1)*nb_component + j]; + } + } + + resize(size - 1); + AKANTU_DEBUG_OUT(); +} + +/* -------------------------------------------------------------------------- */ + +template void Vector::resize (unsigned int new_size) { + AKANTU_DEBUG_IN(); + if(new_size <= allocated_size) { + if(allocated_size - new_size > AKANTU_MIN_ALLOCATION) { + AKANTU_DEBUG_INFO("Freeing " << (allocated_size - size)*nb_component*sizeof(T) << " bytes"); + + /// Normally there are no allocation problem when reducing an array + values = static_cast(realloc(values, new_size * nb_component * sizeof(T))); + allocated_size = size; + } + + size = new_size; + AKANTU_DEBUG_OUT(); + return; + } + + unsigned int size_to_alloc = (new_size - allocated_size < AKANTU_MIN_ALLOCATION) ? + allocated_size + AKANTU_MIN_ALLOCATION : new_size; + + T *tmp_ptr = static_cast(realloc(values, size_to_alloc * nb_component * sizeof(T))); + AKANTU_DEBUG_ASSERT(tmp_ptr != NULL, + "Cannot allocate " << size_to_alloc * nb_component * sizeof(T) << " bytes"); + if (!tmp_ptr) return; + + AKANTU_DEBUG_INFO("Allocating " << (size_to_alloc - allocated_size)*nb_component*sizeof(T) << " bytes"); + + allocated_size = size_to_alloc; + size = new_size; + values = tmp_ptr; + AKANTU_DEBUG_OUT(); +} + +/* -------------------------------------------------------------------------- */ +template void Vector::printself(std::ostream & stream, int indent) const { + std::string space; + for(int i = 0; i < indent; i++, space += AKANTU_INDENT); + + int real_size = allocated_size * nb_component * size_of_type; + + stream << space << "Vector<" << typeid(T).name() << "> [" << std::endl; + stream << space << " + id : " << this->id << std::endl; + stream << space << " + size : " << this->size << std::endl; + stream << space << " + nb_component : " << this->nb_component << std::endl; + stream << space << " + allocated size : " << this->allocated_size << std::endl; + stream << space << " + memory size : " << real_size << "B" << std::endl; + stream << space << " + adresse : " << std::hex << this->values << std::dec << std::endl; + if(AKANTU_DEBUG_TEST(dblDump)) { + stream << space << " + values : {"; + for (unsigned int i = 0; i < this->size; ++i) { + stream << "{"; + for (unsigned int j = 0; j < this->nb_component; ++j) { + stream << this->values[i*nb_component + j]; + if(j != this->nb_component - 1) stream << ", "; + } + stream << "}"; + if(i != this->size - 1) stream << ", "; + } + stream << "}" << std::endl; + } + stream << space << "]" << std::endl; +} + +/* -------------------------------------------------------------------------- */ +/* Inline Functions VectorBase */ +/* -------------------------------------------------------------------------- */ + +inline unsigned int VectorBase::getMemorySize() const { + return allocated_size * nb_component * size_of_type; +} diff --git a/doc/uml.dia b/doc/uml.dia index ec4fe0523..1de03e966 100644 Binary files a/doc/uml.dia and b/doc/uml.dia differ diff --git a/fem/mesh.cc b/fem/mesh.cc index aa16ce546..d8c523685 100644 --- a/fem/mesh.cc +++ b/fem/mesh.cc @@ -1,76 +1,86 @@ /** * @file mesh.cc * @author Nicolas Richart * @date Wed Jun 16 12:02:26 2010 * * @brief class handling meshes * * @section LICENSE * * * */ /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ #include "mesh.hh" #include "element_class.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ -Mesh::Mesh(unsigned int spatial_dimension, MemoryID memory_id) : - Memory(memory_id) { - +Mesh::Mesh(unsigned int spatial_dimension, + const MeshID & id, + const MemoryID & memory_id) : Memory(memory_id) { + AKANTU_DEBUG_IN(); this->spatial_dimension = spatial_dimension; - nodes = NULL; + this->id = id; + + std::stringstream sstr; + sstr << id << ":coordinates"; + Vector & coordinates = malloc(sstr.str(), + 0, + this->spatial_dimension); + nodes = &coordinates; + AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ Vector & Mesh::createConnectivity(ElementType type, unsigned int nb_element) { - + AKANTU_DEBUG_IN(); unsigned int nb_nodes_per_element; switch(type) { case _triangle_1 : { ElementClass<_triangle_1> elem_class; nb_nodes_per_element = elem_class.getNbNodesPerElement(); break; } case _triangle_2 : { ElementClass<_triangle_2> elem_class; nb_nodes_per_element = elem_class.getNbNodesPerElement(); break; } case _tetrahedra_1 : { ElementClass<_tetrahedra_1> elem_class; nb_nodes_per_element = elem_class.getNbNodesPerElement(); break; } case _tetrahedra_2 : { ElementClass<_tetrahedra_2> elem_class; nb_nodes_per_element = elem_class.getNbNodesPerElement(); break; } case _not_defined : case _max_element_type : { nb_nodes_per_element = 0; AKANTU_DEBUG_ERROR("Cannot create a conectivity vector of type : " << type); break; } } std::stringstream sstr; sstr << id << ":connectivity:" << type; Vector & connectivity = malloc(sstr.str(), nb_element, nb_nodes_per_element); connectivities[type] = &connectivity; + AKANTU_DEBUG_OUT(); return connectivity; } /* -------------------------------------------------------------------------- */ __END_AKANTU__ diff --git a/fem/mesh.hh b/fem/mesh.hh index 0cda24c35..f79305f4a 100644 --- a/fem/mesh.hh +++ b/fem/mesh.hh @@ -1,119 +1,107 @@ /** * @file mesh.hh * @author Nicolas Richart * @date Wed Jun 16 11:53:53 2010 * * @brief the class representing the meshes * * @section LICENSE * * * */ /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MESH_HH__ #define __AKANTU_MESH_HH__ /* -------------------------------------------------------------------------- */ #include "common.hh" #include "memory.hh" #include "vector.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ -enum ElementType { - _not_defined = 0, - _triangle_1 = 1, - _triangle_2 = 2, - _tetrahedra_1 = 3, - _tetrahedra_2 = 4, - _max_element_type -}; - -typedef std::string MeshID; - /* -------------------------------------------------------------------------- */ - class Mesh : protected Memory { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: /// constructor that create nodes coordinates array - Mesh(unsigned int spatial_dimension, MemoryID memory_id = 0); + Mesh(unsigned int spatial_dimension, + const MeshID & id = "mesh", + const MemoryID & memory_id = 0); /// constructor that use an existing nodes coordinates array, by knowing its ID Mesh(unsigned int spatial_dimension, - const VectorID & nodes_id, MemoryID memory_id = 0); + const VectorID & nodes_id, + const MeshID & id = "mesh", + const MemoryID & memory_id = 0); /** * constructor that use an existing nodes coordinates * array, by getting the vector of coordinates */ Mesh(unsigned int spatial_dimension, - const Vector & nodes, MemoryID memory_id = 0); + const Vector & nodes, + const MeshID & id = "mesh", + const MemoryID & memory_id = 0); virtual ~Mesh() {}; typedef std::map *> ConnectivityMap; typedef std::map *>::iterator ConnectivityIterator; /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: - inline Vector & getNodes() const {}; + inline Vector & getNodes() const; Vector & createConnectivity(ElementType type, unsigned int nb_element); - inline Vector & getConnectivity(ElementType type) const {}; + inline Vector & getConnectivity(ElementType type) const; + + inline const ConnectivityMap & getConnectivityMap() const; + +private: + friend class MeshIOMSH; + + inline Vector * getConnectivityPointer(ElementType type) const; - inline ConnectivityMap & getConnectivityMap() const {}; /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: /// id of the mesh MeshID id; /// array of the nodes coordinates Vector * nodes; /// all class of elements present in this mesh (for heterogenous meshes) ConnectivityMap connectivities; /// the spatial dimension of this mesh unsigned int spatial_dimension; }; + /* -------------------------------------------------------------------------- */ /* Inline functions */ /* -------------------------------------------------------------------------- */ -//! standard output stream operator -inline std::ostream & operator <<(std::ostream & stream, ElementType type) -{ - switch(type) - { - case _triangle_1 : stream << "triangle 1st order" ; break; - case _triangle_2 : stream << "triangle 2nd order" ; break; - case _tetrahedra_1 : stream << "tetrahedra 1st order"; break; - case _tetrahedra_2 : stream << "tetrahedra 2nd order"; break; - default : stream << "unknown ElementType (" << type << ")"; break; - } - return stream; -} - +#include "mesh_inline_impl.cc" __END_AKANTU__ #endif /* __AKANTU_MESH_HH__ */ diff --git a/fem/mesh_inline_impl.cc b/fem/mesh_inline_impl.cc new file mode 100644 index 000000000..8621a158e --- /dev/null +++ b/fem/mesh_inline_impl.cc @@ -0,0 +1,48 @@ +/** + * @file mesh_inline_impl.cc + * @author Nicolas Richart + * @date Wed Jul 14 23:58:08 2010 + * + * @brief Implementation of the inline functions of the mesh class + * + * @section LICENSE + * + * + * + */ + +/* -------------------------------------------------------------------------- */ +inline Vector & Mesh::getNodes() const { + return *nodes; +} + +/* -------------------------------------------------------------------------- */ +inline Vector & Mesh::getConnectivity(ElementType type) const { + AKANTU_DEBUG_IN(); + ConnectivityMap::const_iterator it = connectivities.find(type); + + AKANTU_DEBUG_ASSERT((it != connectivities.end()), + "The mesh " << id << " as no element of kind : "<< type); + + AKANTU_DEBUG_OUT(); + return *(it->second); +} + +/* -------------------------------------------------------------------------- */ +inline Vector * Mesh::getConnectivityPointer(ElementType type) const { + AKANTU_DEBUG_IN(); + Vector * conn = NULL; + + ConnectivityMap::const_iterator it = connectivities.find(type); + if(it != connectivities.end()) { + conn = it->second; + } + + AKANTU_DEBUG_OUT(); + return conn; +} + +/* -------------------------------------------------------------------------- */ +inline const Mesh::ConnectivityMap & Mesh::getConnectivityMap() const { + return connectivities; +} diff --git a/mesh_io/mesh_io.cc b/mesh_io/mesh_io.cc new file mode 100644 index 000000000..968f3a92d --- /dev/null +++ b/mesh_io/mesh_io.cc @@ -0,0 +1,35 @@ +/** + * @file mesh_io.cc + * @author Nicolas Richart + * @date Wed Jul 14 16:51:22 2010 + * + * @brief common part for all mesh io classes + * + * @section LICENSE + * + * + * + */ + +/* -------------------------------------------------------------------------- */ +#include "common.hh" +#include "mesh_io.hh" + +/* -------------------------------------------------------------------------- */ + + +__BEGIN_AKANTU__ + +/* -------------------------------------------------------------------------- */ +MeshIO::MeshIO() { + canReadSurface = false; + canReadExtendedData = false; +} + +/* -------------------------------------------------------------------------- */ +MeshIO::~MeshIO() { + +} +/* -------------------------------------------------------------------------- */ + +__END_AKANTU__ diff --git a/mesh_io/mesh_io.hh b/mesh_io/mesh_io.hh index 76754bf6b..d18cb6c74 100644 --- a/mesh_io/mesh_io.hh +++ b/mesh_io/mesh_io.hh @@ -1,82 +1,84 @@ /** * @file mesh_io.hh * @author Nicolas Richart * @date Fri Jun 18 10:27:42 2010 * * @brief Interface of a mesh io class, reader and writer * * @section LICENSE * * * */ /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MESH_IO_HH__ #define __AKANTU_MESH_IO_HH__ /* -------------------------------------------------------------------------- */ #include "common.hh" #include "mesh.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ class MeshIO { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: MeshIO(); virtual ~MeshIO(); /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// function to print the containt of the class - virtual void printself(std::ostream & stream, int indent = 0) const; + virtual void printself(std::ostream & stream, int indent = 0) const {}; /// read a mesh from the file virtual void read(const std::string & filename, const Mesh & mesh) = 0; /// write a mesh to a file virtual void write(const std::string & filename, const Mesh & mesh) = 0; /* ------------------------------------------------------------------------ */ - /* Accesors */ + /* Accessors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ -private: +protected: bool canReadSurface; bool canReadExtendedData; - std::string filename; + // std::string filename; - Mesh & mesh; + // Mesh & mesh; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ /// standard output stream operator inline std::ostream & operator <<(std::ostream & stream, const MeshIO & _this) { _this.printself(stream); + + return stream; } __END_AKANTU__ #endif /* __AKANTU_MESH_IO_HH__ */ diff --git a/mesh_io/mesh_io_msh.cc b/mesh_io/mesh_io_msh.cc index 29bbed660..a60c4b558 100644 --- a/mesh_io/mesh_io_msh.cc +++ b/mesh_io/mesh_io_msh.cc @@ -1,379 +1,395 @@ /** * @file mesh_io_msh.cc * @author Nicolas Richart * @date Fri Jun 18 11:36:35 2010 * * @brief Read/Write for MSH files generated by gmsh * * @section LICENSE * * * */ /* ----------------------------------------------------------------------------- Version (Legacy) 1.0 $NOD number-of-nodes node-number x-coord y-coord z-coord ... $ENDNOD $ELM number-of-elements elm-number elm-type reg-phys reg-elem number-of-nodes node-number-list ... $ENDELM ----------------------------------------------------------------------------- Version 2.1 $MeshFormat version-number file-type data-size $EndMeshFormat $Nodes number-of-nodes node-number x-coord y-coord z-coord ... $EndNodes $Elements number-of-elements elm-number elm-type number-of-tags < tag > ... node-number-list ... $EndElements $PhysicalNames number-of-names physical-dimension physical-number "physical-name" ... $EndPhysicalNames $NodeData number-of-string-tags < "string-tag" > ... number-of-real-tags < real-tag > ... number-of-integer-tags < integer-tag > ... node-number value ... ... $EndNodeData $ElementData number-of-string-tags < "string-tag" > ... number-of-real-tags < real-tag > ... number-of-integer-tags < integer-tag > ... elm-number value ... ... $EndElementData $ElementNodeData number-of-string-tags < "string-tag" > ... number-of-real-tags < real-tag > ... number-of-integer-tags < integer-tag > ... elm-number number-of-nodes-per-element value ... ... $ElementEndNodeData ----------------------------------------------------------------------------- elem-type 1: 2-node line. 2: 3-node triangle. 3: 4-node quadrangle. 4: 4-node tetrahedron. 5: 8-node hexahedron. 6: 6-node prism. 7: 5-node pyramid. 8: 3-node second order line 9: 6-node second order triangle 10: 9-node second order quadrangle 11: 10-node second order tetrahedron 12: 27-node second order hexahedron 13: 18-node second order prism 14: 14-node second order pyramid 15: 1-node point. 16: 8-node second order quadrangle 17: 20-node second order hexahedron 18: 15-node second order prism 19: 13-node second order pyramid 20: 9-node third order incomplete triangle 21: 10-node third order triangle 22: 12-node fourth order incomplete triangle 23: 15-node fourth order triangle 24: 15-node fifth order incomplete triangle 25: 21-node fifth order complete triangle 26: 4-node third order edge 27: 5-node fourth order edge 28: 6-node fifth order edge 29: 20-node third order tetrahedron 30: 35-node fourth order tetrahedron 31: 56-node fifth order tetrahedron -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ #include "mesh_io_msh.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ +/* -------------------------------------------------------------------------- */ +/* Constant arrays initialisation */ /* -------------------------------------------------------------------------- */ unsigned int MeshIOMSH::_read_order[_max_element_type][MAX_NUMBER_OF_NODE_PER_ELEMENT] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // _not_defined { 0, 1, 2, 0, 0, 0, 0, 0, 0, 0 }, // _triangle_1 { 0, 1, 2, 3, 4, 5, 6, 0, 0, 0 }, // _triangle_2 { 0, 1, 2, 3, 4, 0, 0, 0, 0, 0 }, // _tetrahedra_1 { 0, 1, 2, 3, 4, 5, 6, 7, 9, 8 }, // _tetrahedra_2 }; unsigned int MeshIOMSH::_msh_nodes_per_elem[16] = { 0, // element types began at 1 2, 3, 4, 4, 8, 6, 5, // 1st order 3, 6, 9, 10, 27, 18, 14, // 2st order - 1 }; + 1 + }; ElementType MeshIOMSH::_msh_to_akantu_element_types[16] = { _not_defined, // element types began at 1 _not_defined, _triangle_1, _not_defined, _tetrahedra_1, _not_defined, _not_defined, _not_defined, // 1st order _not_defined, _triangle_2, _not_defined, _tetrahedra_2, _not_defined, _not_defined, _not_defined, // 2nd order - _not_defined }; + _not_defined + }; MeshIOMSH::MSHElementType MeshIOMSH::_akantu_to_msh_element_types[_max_element_type ] = { _msh_not_defined, // _not_defined _msh_triangle_1, // _triangle_1 _msh_triangle_2, // _triangle_2 _msh_tetrahedron_1, // _tetrahedra_1 _msh_tetrahedron_2 // _tetrahedra_2 }; + +/* -------------------------------------------------------------------------- */ +/* Methods Implentations */ +/* -------------------------------------------------------------------------- */ + +MeshIOMSH::MeshIOMSH() { + canReadSurface = false; + canReadExtendedData = false; +} + +/* -------------------------------------------------------------------------- */ +MeshIOMSH::~MeshIOMSH() { + +} + /* -------------------------------------------------------------------------- */ void MeshIOMSH::read(const std::string & filename, const Mesh & mesh) { std::ifstream infile; infile.open(filename.c_str()); std::string line; unsigned int first_node_number = 0, last_node_number = 0, file_format = 1, current_line = 0; if(!infile.good()) { AKANTU_DEBUG_ERROR("Canot open file " << filename); } while(infile.good()) { std::getline(infile, line); current_line++; /// read the header if(line == "$MeshFormat") { std::getline(infile, line); /// the format line std::getline(infile, line); /// the end of block line current_line += 2; file_format = 2; } /// read all nodes if(line == "$Nodes" || line == "$NOD") { - int nb_nodes; + unsigned int nb_nodes; std::getline(infile, line); std::stringstream sstr(line); sstr >> nb_nodes; current_line++; Vector & nodes = mesh.getNodes(); nodes.resize(nb_nodes); - int index; + unsigned int index; double coord[3]; unsigned int spatial_dimension = nodes.getNbComponent(); /// for each node, read the coordinates for(unsigned int i = 0; i < nb_nodes; ++i) { - int offset = i * spatial_dimension; + unsigned int offset = i * spatial_dimension; std::getline(infile, line); std::stringstream sstr(line); sstr >> index >> coord[0] >> coord[1] >> coord[2]; current_line++; first_node_number = first_node_number < index ? first_node_number : index; last_node_number = last_node_number > index ? last_node_number : index; /// read the coordinates for(unsigned int j = 0; j < spatial_dimension; ++j) nodes.values[offset + j] = coord[j]; } std::getline(infile, line); /// the end of block line } /// read all elements if(line == "$Elements" || line == "$ELM") { - int nb_elements; + unsigned int nb_elements; std::getline(infile, line); std::stringstream sstr(line); sstr >> nb_elements; current_line++; int index; unsigned int msh_type; ElementType akantu_type, akantu_type_old = _not_defined; Vector *connectivity = NULL; unsigned int nb_elements_read = 0; for(unsigned int i = 0; i < nb_elements; ++i) { std::getline(infile, line); std::stringstream sstr(line); current_line++; sstr >> index; sstr >> msh_type; /// get the connectivity vector depending on the element type akantu_type = _msh_to_akantu_element_types[msh_type]; if(akantu_type == _not_defined) continue; if(akantu_type != akantu_type_old) { + connectivity = mesh.getConnectivityPointer(akantu_type); if(connectivity) connectivity->resize(nb_elements_read); + else + connectivity = &(const_cast(mesh).createConnectivity(akantu_type, nb_elements)); - connectivity = &(const_cast(mesh).createConnectivity(akantu_type, nb_elements)); - connectivity->resize(nb_elements); akantu_type_old = akantu_type; nb_elements_read = 0; } /// read tags informations if(file_format == 2) { - int nb_tags; + unsigned int nb_tags; sstr >> nb_tags; for(unsigned int j = 0; j < nb_tags; ++j) { int tag; sstr >> tag; ///@todo read to get extended information on elements } } else if (file_format == 1) { int tag; sstr >> tag; //reg-phys sstr >> tag; //reg-elem sstr >> tag; //number-of-nodes } /// read the connectivities informations unsigned int offset = nb_elements_read * connectivity->getNbComponent(); for(unsigned int j; j < connectivity->getNbComponent(); ++j) { unsigned int index; sstr >> index; AKANTU_DEBUG_ASSERT(index <= last_node_number, "Node number not in range : line " << current_line); index = index - first_node_number + 1; connectivity->values[offset + _read_order[akantu_type][j]] = index; } nb_elements_read++; } connectivity->resize(nb_elements_read); std::getline(infile, line); /// the end of block line } - if(line[0] == '$') { + if((line[0] == '$') && (line.find("End") == std::string::npos)) { AKANTU_DEBUG_WARNING("Unsuported block_kind " << line << " at line " << current_line); } } - // if there is less element than predicted... - - infile.close(); } /* -------------------------------------------------------------------------- */ void MeshIOMSH::write(const std::string & filename, const Mesh & mesh) { std::ofstream outfile; Vector & nodes = mesh.getNodes(); outfile.open(filename.c_str()); outfile << "$MeshFormat" << std::endl; outfile << "2 0 8" << std::endl;; outfile << "$EndMeshFormat" << std::endl;; outfile << "$Nodes" << std::endl;; outfile << nodes.getSize() << std::endl;; outfile << std::uppercase; - for(int i = 0; i < nodes.getSize(); ++i) { + for(unsigned int i = 0; i < nodes.getSize(); ++i) { int offset = i * nodes.getNbComponent(); outfile << i+1; - for(int j = 0; j < nodes.getNbComponent(); ++j) { + for(unsigned int j = 0; j < nodes.getNbComponent(); ++j) { outfile << " " << nodes.values[offset + j]; } if(nodes.getNbComponent() == 2) outfile << " " << 0.; outfile << std::endl;; } outfile << std::nouppercase; outfile << "$EndNodes" << std::endl;; outfile << "$Elements" << std::endl;; - Mesh::ConnectivityMap & connectivity_map = mesh.getConnectivityMap(); + const Mesh::ConnectivityMap & connectivity_map = mesh.getConnectivityMap(); Mesh::ConnectivityMap::const_iterator it; int nb_elements = 0; for(it = connectivity_map.begin(); it != connectivity_map.end(); ++it) { - MSHElementType type = _akantu_to_msh_element_types[it->first]; Vector & connectivity = *(it->second); nb_elements += connectivity.getSize(); } outfile << nb_elements << std::endl; unsigned int element_idx = 1; for(it = connectivity_map.begin(); it != connectivity_map.end(); ++it) { ElementType type = it->first; Vector & connectivity = *(it->second); - for(int i = 0; i < connectivity.getSize(); ++i) { - int offset = i * connectivity.getNbComponent(); + for(unsigned int i = 0; i < connectivity.getSize(); ++i) { + unsigned int offset = i * connectivity.getNbComponent(); outfile << element_idx << " " << type << " 3 0 0 0"; - for(int j = 0; j < connectivity.getNbComponent(); ++j) { + for(unsigned int j = 0; j < connectivity.getNbComponent(); ++j) { outfile << " " << connectivity.values[offset + j]; } outfile << std::endl; } element_idx++; } outfile << "$EndElements" << std::endl;; outfile.close(); } /* -------------------------------------------------------------------------- */ __END_AKANTU__ diff --git a/mesh_io/mesh_io_msh.hh b/mesh_io/mesh_io_msh.hh index a313813f9..e8d9f1bc9 100644 --- a/mesh_io/mesh_io_msh.hh +++ b/mesh_io/mesh_io_msh.hh @@ -1,109 +1,111 @@ /** * @file mesh_io_msh.hh * @author Nicolas Richart * @date Fri Jun 18 11:30:59 2010 * * @brief Read/Write for MSH files * * @section LICENSE * * * */ /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MESH_IO_MSH_HH__ #define __AKANTU_MESH_IO_MSH_HH__ /* -------------------------------------------------------------------------- */ #include "mesh_io.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ -class MeshIOMSH { +class MeshIOMSH : public MeshIO { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: MeshIOMSH(); + virtual ~MeshIOMSH(); /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// function to print the containt of the class - virtual void printself(std::ostream & stream, int indent = 0) const; + virtual void printself(std::ostream & stream, int indent = 0) const {}; /// read a mesh from the file virtual void read(const std::string & filename, const Mesh & mesh); /// write a mesh to a file virtual void write(const std::string & filename, const Mesh & mesh); /* ------------------------------------------------------------------------ */ /* Accesors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: /// MSH element types enum MSHElementType { _msh_not_defined = 0, _msh_line_1 = 1, // 2-node line. _msh_triangle_1 = 2, // 3-node triangle. _msh_quadrangle_1 = 3, // 4-node quadrangle. _msh_tetrahedron_1 = 4, // 4-node tetrahedron. _msh_hexaedron_1 = 5, // 8-node hexahedron. _msh_prism_1 = 6, // 6-node prism. _msh_pyramid_1 = 7, // 5-node pyramid. _msh_line_2 = 8, // 3-node second order line _msh_triangle_2 = 9, // 6-node second order triangle _msh_quadrangle_2 = 10, // 9-node second order quadrangle _msh_tetrahedron_2 = 11, // 10-node second order tetrahedron _msh_hexaedron_2 = 12, // 27-node second order hexahedron _msh_prism_2 = 13, // 18-node second order prism _msh_pyramid_2 = 14, // 14-node second order pyramid _msh_point = 15 // 1-node point. }; /// order in witch element as to be read static unsigned int _read_order[_max_element_type][MAX_NUMBER_OF_NODE_PER_ELEMENT]; /// number of nodes per msh element static unsigned int _msh_nodes_per_elem[16]; // 16 = number of recognized // msh element types +1 (for 0) /// correspondance between msh element types and akantu element types static ElementType _msh_to_akantu_element_types[16]; /// correspondance between akantu element types and msh element types static MSHElementType _akantu_to_msh_element_types[_max_element_type]; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ /// standard output stream operator inline std::ostream & operator <<(std::ostream & stream, const MeshIOMSH & _this) { _this.printself(stream); + return stream; } __END_AKANTU__ #endif /* __AKANTU_MESH_IO_MSH_HH__ */ diff --git a/test/mesh_io_msh.cc b/test/mesh_io_msh.cc new file mode 100644 index 000000000..648337f93 --- /dev/null +++ b/test/mesh_io_msh.cc @@ -0,0 +1,33 @@ +/** + * @file mesh_io_msh.cc + * @author Nicolas Richart + * @date Wed Jul 14 14:27:11 2010 + * + * @brief unit test for the MeshIOMSH class + * + * @section LICENSE + * + * + * + */ + +/* -------------------------------------------------------------------------- */ +#include + +/* -------------------------------------------------------------------------- */ +#include "mesh.hh" +#include "mesh_io.hh" +#include "mesh_io_msh.hh" + +/* -------------------------------------------------------------------------- */ + + +int main(int argc, char *argv[]) { + akantu::MeshIOMSH mesh_io; + akantu::Mesh mesh(3); + + mesh_io.read("./cube.msh", mesh); + + + return EXIT_SUCCESS; +}