diff --git a/src/container_array.hh b/src/container_array.hh index 5c2fda5..cd1e965 100644 --- a/src/container_array.hh +++ b/src/container_array.hh @@ -1,129 +1,138 @@ /** * @file container_array.hh * * @author Guillaume Anciaux * * @date creation: Fri Oct 12 2012 * @date last modification: Tue Feb 05 2013 * * @brief container array header * * @section LICENSE * * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * IOHelper 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. * * IOHelper 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 IOHelper. If not, see . * */ #ifndef __IOHELPER_CONTAINER_ARRAY_HH__ #define __IOHELPER_CONTAINER_ARRAY_HH__ /* -------------------------------------------------------------------------- */ __BEGIN_IOHELPER__ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ template class ContainerArray { /* ------------------------------------------------------------------------ */ /* Typedefs */ /* ------------------------------------------------------------------------ */ public: class iterator: public ::iohelper::iterator { public: - iterator(T * ptr, UInt dimension, UInt increment){ + iterator(T * ptr, UInt dimension, UInt increment, const ElemType & el_type = MAX_ELEM_TYPE){ this->ptr = ptr; this->increment = increment; this->dimension = dimension; + this->el_type = el_type; }; bool operator!=(const iterator & it) const { return it.ptr != this->ptr; }; iterator & operator++() { ptr += increment; return *this; }; IOHelperVector operator*(){ return IOHelperVector(ptr, increment); }; + virtual ElemType element_type() { return el_type; } + private: T * ptr; UInt increment; UInt dimension; + ElemType el_type; }; /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - ContainerArray(T * data, UInt dimension, UInt size, UInt stride=1){ + ContainerArray(T * data, UInt dimension, UInt size, UInt stride=1,ElemType el_type = MAX_ELEM_TYPE){ this->data = data; this->dimension = dimension; if (this->data == NULL) this->_size = 0; else this->_size = size; this->stride = stride; + this->el_type = el_type; }; virtual ~ContainerArray(){}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ iterator begin(){ - return iterator(data,dimension,stride*dimension); + return iterator(data,dimension,stride*dimension,el_type); }; iterator end(){ return iterator(data+_size*dimension*stride,dimension,stride*dimension); }; UInt getDim(){return dimension;}; UInt size(){return _size;}; bool isHomogeneous(){return true;}; DataType getDataType() { return ::iohelper::getDataType(); } + const ElemType & getElemType() { return el_type;} + void setElemType(const ElemType & type) { el_type = type;} + public: /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: T * data; UInt dimension; UInt stride; UInt _size; + ElemType el_type; }; /* -------------------------------------------------------------------------- */ __END_IOHELPER__ #endif /* __IOHELPER_ITERATOR_ARRAY_HH__ */ diff --git a/src/dumper.cc b/src/dumper.cc index ba6de19..37319d3 100644 --- a/src/dumper.cc +++ b/src/dumper.cc @@ -1,293 +1,294 @@ /** * @file dumper.cc * * @author Guillaume Anciaux * @author David Simon Kammer * @author Nicolas Richart * * @date creation: Thu Mar 11 2010 * @date last modification: Mon Jun 10 2013 * * @brief implementation of main dumper * * @section LICENSE * * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * IOHelper 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. * * IOHelper 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 IOHelper. If not, see . * */ /* -------------------------------------------------------------------------- */ #include #include "dumper.hh" #include "field_inline_impl.cc" #include "variable_inline_impl.cc" /* -------------------------------------------------------------------------- */ #if defined(__INTEL_COMPILER) /// remark #981: operands are evaluated in unspecified order #pragma warning ( disable : 981 ) #endif //defined(__INTEL_COMPILER) __BEGIN_IOHELPER__ /* -------------------------------------------------------------------------- */ Dumper::Dumper(std::string prefix) : dump_step(0), dump_step_width(4), time_step(0), current_time(0), write_time_desc_file(false), mode(0), world_size(-1), my_rank(-1), root_rank(0), my_rank_width(3), time_description_file_name("") { // needs to be after the definition of the directory separator this->setPrefix(prefix); } /* -------------------------------------------------------------------------- */ Dumper::Dumper(std::string prefix, const std::string & base_name) : dump_step(0), dump_step_width(4), time_step(0), current_time(0), write_time_desc_file(false), mode(0), world_size(-1), my_rank(-1), root_rank(0), my_rank_width(3), time_description_file_name("") { // needs to be after the definition of the directory separator this->setPrefix(prefix); setBaseName(base_name); } /* -------------------------------------------------------------------------- */ Dumper::~Dumper(){ { std::map::iterator it = per_node_data.begin(); std::map::iterator end = per_node_data.end(); while (it != end){ delete (*it).second; ++it; } } { std::map::iterator it = per_element_data.begin(); std::map::iterator end = per_element_data.end(); while (it != end){ delete (*it).second; ++it; } } { std::map::iterator it = global_data.begin(); std::map::iterator end = global_data.end(); while (it != end){ delete (*it).second; ++it; } } } /* -------------------------------------------------------------------------- */ void Dumper::dump(const std::string & name, UInt count) { if(count != UInt(-1)) dump_step = count; if(name != "") base_name = name; if(time_description_file_name == "") time_description_file_name = base_name; } /* -------------------------------------------------------------------------- */ void Dumper::registerDumpOptions(const std::string & key, const std::string & folder, const std::string & extension, DumpFlag dump_flag) { DumpOptions & dos = dump_options[key]; dos.setFolder(folder); dos.extension = extension; dos.dump_flags = dump_flag; } /* -------------------------------------------------------------------------- */ void Dumper::init(){ if (world_size == -1 || my_rank == -1){ // DUMP("world_size and my_rank variables are not well set: going to sequential dump"); world_size = 1; my_rank = 0; } } /* -------------------------------------------------------------------------- */ void Dumper::setPoints(Real * points, int dimension, int nb, const std::string & name) { addNodeDataField(std::string("positions"), points, dimension, nb); setBaseName(name); } /* -------------------------------------------------------------------------- */ void Dumper::setBaseName(const std::string & name) { this->base_name = name; } /* -------------------------------------------------------------------------- */ void Dumper::setConnectivity(int * connectivity, ElemType elem_type, UInt nb_elem, int mode) { addElemDataField(std::string("connectivities"), connectivity, + elem_type, nb_node_per_elem[elem_type], nb_elem); - ElemType * types = new ElemType[nb_elem]; - for (UInt i = 0; i < nb_elem; ++i) { - types[i] = elem_type; - } - addElemDataField(std::string("element_type"), types, 1, nb_elem); + // ElemType * types = new ElemType[nb_elem]; + // for (UInt i = 0; i < nb_elem; ++i) { + // types[i] = elem_type; + // } + // addElemDataField(std::string("element_type"), types, 1, nb_elem); connectivity_mode = mode; } /* -------------------------------------------------------------------------- */ void Dumper::DumpOptions::setFolder(const std::string & fld) { this->folder = Dumper::checkDirectoryName(fld);; } /* -------------------------------------------------------------------------- */ const std::string & Dumper::DumpOptions::getFolder() const { return this->folder; } /* -------------------------------------------------------------------------- */ std::string Dumper::checkDirectoryName(std::string fname) { if (fname.size() > 0 && fname[fname.size()-1] != IOHELPER_DIRECTORY_SEPARATOR) { fname += IOHELPER_DIRECTORY_SEPARATOR; } return fname; } /* -------------------------------------------------------------------------- */ Dumper::DumpOptions & Dumper::getDumpOptions(const std::string & key) { DumpOptionsMap::iterator it = this->dump_options.find(key); if(it == this->dump_options.end()) IOHELPER_THROW("No dump options registered under the name " << key, _et_options_error); return it->second; } /* -------------------------------------------------------------------------- */ std::string Dumper::getRelativeFilePath(const std::string & name, const std::string & key, UInt proc) { return this->getRelativeFolderPath(key) + this->getFileName(name, key, proc); } /* -------------------------------------------------------------------------- */ std::string Dumper::getRelativeFilePath(const std::string & name, const std::string & key) { return this->getRelativeFolderPath(key) + this->getFileName(name, key); } /* -------------------------------------------------------------------------- */ std::string Dumper::getAbsoluteFilePath(const std::string & name, const std::string & key, UInt proc) { return prefix + this->getRelativeFilePath(name, key, proc); } /* -------------------------------------------------------------------------- */ std::string Dumper::getAbsoluteFilePath(const std::string & name, const std::string & key) { return prefix + this->getRelativeFilePath(name, key); } /* -------------------------------------------------------------------------- */ std::string Dumper::getFileName(const std::string & name, const std::string & key) { return this->getFileName(name, key, this->my_rank); } /* -------------------------------------------------------------------------- */ std::string Dumper::getFileName(const std::string & name, const std::string & key, UInt proc) { std::stringstream sstr; sstr << name; const DumpOptions & dos = this->getDumpOptions(key); if (dos.dump_flags & _df_counter) { sstr << "_"; sstr.width(this->dump_step_width); sstr.fill('0'); sstr << dump_step; } if (world_size > 1 && (dos.dump_flags & _df_proc_id)) { sstr << ".proc"; sstr.width(this->my_rank_width); sstr.fill('0'); sstr << proc; } sstr << dos.extension; return sstr.str(); } /* -------------------------------------------------------------------------- */ std::string Dumper::getRelativeFolderPath(const std::string & key) { return getDumpOptions(key).getFolder(); } /* -------------------------------------------------------------------------- */ std::string Dumper::getAbsoluteFolderPath(const std::string & key) { return prefix + this->getRelativeFolderPath(key); } /* -------------------------------------------------------------------------- */ std::string Dumper::getBaseName() { return this->base_name; } /* -------------------------------------------------------------------------- */ void Dumper::setParallelContext(int me, int wld_size, int root) { this->my_rank = me; this->world_size = wld_size; this->my_rank_width = std::ceil(std::log10(this->world_size)); this->root_rank = root; } /* -------------------------------------------------------------------------- */ void Dumper::printNodeDataFields() { std::map::iterator it = per_node_data.begin(); std::map::iterator end = per_node_data.end(); int count = 0; while (it != end){ std::cout << "Field " << ++count << " : " << it->second->getName() << std::endl; ++it; } } /* -------------------------------------------------------------------------- */ void Dumper::activateTimeDescFiles(Real delta_t, Real initial_time) { this->time_step = delta_t; this->current_time = initial_time; this->write_time_desc_file = true; } /* -------------------------------------------------------------------------- */ __END_IOHELPER__ diff --git a/src/dumper.hh b/src/dumper.hh index c994f31..9360328 100644 --- a/src/dumper.hh +++ b/src/dumper.hh @@ -1,325 +1,324 @@ /** * @file dumper.hh * * @author Guillaume Anciaux * @author David Simon Kammer * @author Nicolas Richart * * @date creation: Thu Mar 11 2010 * @date last modification: Wed Nov 13 2013 * * @brief dumper interface * * @section LICENSE * * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * IOHelper 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. * * IOHelper 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 IOHelper. If not, see . * */ /* -------------------------------------------------------------------------- */ #ifndef __IOHELPER_DUMPER_H__ #define __IOHELPER_DUMPER_H__ /* -------------------------------------------------------------------------- */ #include #include #include "iohelper_common.hh" #include "field_interface.hh" #include "field.hh" #include "variable_interface.hh" #include "variable.hh" #include "container_array.hh" /* -------------------------------------------------------------------------- */ #include "visitor.hh" /* -------------------------------------------------------------------------- */ #if !defined(_WIN32) # define IOHELPER_DIRECTORY_SEPARATOR '/' #else # define IOHELPER_DIRECTORY_SEPARATOR '\\' #endif __BEGIN_IOHELPER__ /** Class Dumper * Interface of a dumper */ class Dumper { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: Dumper(const std::string prefix, const std::string & base_name); Dumper(const std::string prefix); virtual ~Dumper(); /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ //! dump to file virtual void dump(const std::string & name = std::string(), UInt count = UInt(-1)); //! initialisation of the dumper void init(); //! TODO set comment void printNodeDataFields(); //! dump of field information virtual void dumpDescription(const char descr_sep = ' ') {}; public: /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ //! give vector with coordinates void setPoints(Real * points, int dimension, int nb, const std::string & name); //! set number of filtered elements void setNumberFilteredElements(int nb_filtered); //! give vector to connectivity virtual void setConnectivity(int * connectivity, ElemType element_type, UInt nb_elem, int mode); //! give vector to per node data template void addNodeDataField(const std::string & name, T * data, UInt dimension, UInt size, UInt stride=1); //! give a generic container as per node data template void addNodeDataField(const std::string & name, Cont & data); //! give vector to per element data template void addElemDataField(const std::string & name, T * data, + ElemType elem_type, UInt dimension, UInt size, UInt stride=1); //! give a generic container as per elem data template void addElemDataField(const std::string & name, Cont & data); //! give a generic container as per node data template void addVariable(const std::string & name, VarType & data); //! set mode virtual void setMode(int mode){ this->mode = mode; } //! set rank and world size params for parallel treatment void setParallelContext(int me, int wld_size, int root=0); //! set current value for the dump step void setDumpStep(int s) { dump_step = s; }; Int getDumpStep() { return dump_step; }; Int getDumpStepWidth() { return dump_step_width; }; //! increment the dumpstep void incDumpStep(UInt s = 1) { dump_step += s; }; void setPrefix(const std::string & prefix) { this->prefix = this->checkDirectoryName(prefix); }; virtual void activateTimeDescFiles(Real delta_t, Real initial_time = 0.); void setTimeStep(Real delta_t) { this->time_step = delta_t; } void setCurrentTime(Real time) { this->current_time = time; } void setTimeDescriptionFileName(const std::string & name) { this->time_description_file_name = name; } protected: static std::string checkDirectoryName(std::string fname); std::string getFolder(const std::string & key); //! get file name with relative path std::string getRelativeFilePath(const std::string & name, const std::string & key, UInt proc); std::string getRelativeFilePath(const std::string & name, const std::string & key); std::string getAbsoluteFilePath(const std::string & name, const std::string & key, UInt proc); std::string getAbsoluteFilePath(const std::string & name, const std::string & key); std::string getFileName(const std::string & name, const std::string & key, UInt proc); std::string getFileName(const std::string & name, const std::string & key); std::string getRelativeFolderPath(const std::string & folder); std::string getAbsoluteFolderPath(const std::string & folder); //! get base_name std::string getBaseName(); void setBaseName(const std::string & name); public: enum DumpFlag { _df_no_flag = 0x0, _df_counter = 0x1, _df_proc_id = 0x2 }; protected: struct DumpOptions { private: std::string folder; public: std::string extension; DumpFlag dump_flags; public: void setFolder(const std::string & fld); const std::string & getFolder() const; }; typedef std::map DumpOptionsMap; protected: void registerDumpOptions(const std::string & key, const std::string & folder, const std::string & extension, DumpFlag dump_flag = _df_no_flag); DumpOptions & getDumpOptions(const std::string & key); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: std::string base_name; std::string prefix; DumpOptionsMap dump_options; UInt dump_step; UInt dump_step_width; protected: //! current delta t Real time_step; //! current time (dah!) Real current_time; //! if implemented the dumper will write a time description file bool write_time_desc_file; //! flag to produce zipped files UInt mode; typedef std::map field_map; typedef std::map variable_map; //! vector of additional per node data field_map per_node_data; //! vector of additional per element data field_map per_element_data; //! map of global variables variable_map global_data; //! for parallel runs is the total number of processors Int world_size; //! for parallel runs is rank of the process Int my_rank; //! fortran or C style connectivity indexing Int connectivity_mode; //! for parallel runs is rank of the process that should write the data to file Int root_rank; //! number of zeros to put to my_rank when creating files Int my_rank_width; //! file name for the time description files (if not set use the first base name) std::string time_description_file_name; }; inline Dumper::DumpFlag operator|(const Dumper::DumpFlag & a, const Dumper::DumpFlag & b) { Dumper::DumpFlag tmp = Dumper::DumpFlag(UInt(a) | UInt(b)); return tmp; } /* -------------------------------------------------------------------------- */ template void Dumper::addNodeDataField(const std::string & name, T * data,UInt dimension, UInt size, UInt stride) { ContainerArray * cont = new ContainerArray(data,dimension,size,stride); addNodeDataField(name,*cont); } /* -------------------------------------------------------------------------- */ template void Dumper::addNodeDataField(const std::string & name, Cont & data){ Field *test = new Field(data,name); per_node_data[name] = test; } /* -------------------------------------------------------------------------- */ template void Dumper::addVariable(const std::string & name, VarType & data) { Variable * vari = new Variable(data,name); global_data[name] = vari; } /* -------------------------------------------------------------------------- */ template -void Dumper::addElemDataField(const std::string & name, T * data,UInt dimension, +void Dumper::addElemDataField(const std::string & name, + T * data, + ElemType elem_type, + UInt dimension, UInt size, UInt stride){ ContainerArray * cont = new ContainerArray(data,dimension,size,stride); + cont->setElemType(elem_type); addElemDataField(name,*cont); - // if (stride == 0) stride = dimension; - // if (per_element_data.count(name) != 0) delete(per_element_data[name]); - // if (connec == NULL) FATAL("connectivity should be provided before elemental fields ! Please use SetConnectivity function before AddElemDataField"); - // Field * temp = new Field(data,dimension,connec->getNbDof(),stride); - // temp->setName(name); - // per_element_data[name] = temp; } /* -------------------------------------------------------------------------- */ template void Dumper::addElemDataField(const std::string & name, Cont & data){ Field *test = new Field(data,name); per_element_data[name] = test; } /* -------------------------------------------------------------------------- */ __END_IOHELPER__ #endif /* __IOHELPER_DUMPER_H__ */