/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2012 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /* * Box_BoundaryConditions.cpp * * Created on: Jan 2, 2012 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include #include #include #include #include "Box_BoundaryConditions.hpp" #include "CodePatterns/Assert.hpp" #include "CodePatterns/Log.hpp" #include "CodePatterns/Range.hpp" #include "LinearAlgebra/defs.hpp" /** Constructor of class BCContainer. * * Fills member BCContainer::ConverterBiMap and * BCContainer::ReConverterBiMap. */ BoundaryConditions::BCContainer::BCContainer() { // fill static conversion maps when empty ASSERT(ConverterBiMap.size() == ReConverterBiMap.size(), "BCContainer::BoundaryConditions() - internal string<->enum maps differ in size."); if (ConverterBiMap.empty()) { // hither ConverterBiMap.insert( std::make_pair(BoundaryConditions::Wrap, std::string("Wrap")) ); ConverterBiMap.insert( std::make_pair(BoundaryConditions::Bounce, std::string("Bounce")) ); ConverterBiMap.insert( std::make_pair(BoundaryConditions::Ignore, std::string("Ignore")) ); // thither ReConverterBiMap.insert( std::make_pair(std::string("Wrap"), BoundaryConditions::Wrap) ); ReConverterBiMap.insert( std::make_pair(std::string("Bounce"), BoundaryConditions::Bounce) ); ReConverterBiMap.insert( std::make_pair(std::string("Ignore"), BoundaryConditions::Ignore) ); } ASSERT(ConverterBiMap.size() == (size_t)(BoundaryConditions::MAX_BoundaryCondition_t), "BCContainer::BoundaryConditions() - internal string<->enum map has not the same number of elements " +toString(ConverterBiMap.size())+" as the enum " +toString((size_t)(MAX_BoundaryCondition_t))+"."); // fill us with default values resize(NDIM, BoundaryConditions::Wrap); } /** Destructor of class BCContainer. * */ BoundaryConditions::BCContainer::~BCContainer() { ConverterBiMap.clear(); ReConverterBiMap.clear(); } /** Getter for a all boundary conditions. * * @return vector with the boundary conditions */ const BoundaryConditions::Conditions_t & BoundaryConditions::BCContainer::get() const { return (*this); } /** Getter for the boundary condition of a specific axis. * * @param index axis * @return boundary condition of this axis. */ const BoundaryConditions::BoundaryCondition_t BoundaryConditions::BCContainer::get(size_t index) const { #ifndef NDEBUG range AllowedRange(0, this->size()); ASSERT(AllowedRange.isInRange(index), "BCContainer::get() - index "+toString(index)+" out of bounds " +toString(AllowedRange)+"."); #endif return operator[](index); } /** Setter for all boundary conditions. * * @param _conditions vector with all conditions to set. */ void BoundaryConditions::BCContainer::set(const BoundaryConditions::Conditions_t &_conditions) { ASSERT(_conditions.size() == this->size(), "BCContainer::set() - given vector of conditions and this have unequal size."); for (size_t i = 0; i < _conditions.size(); ++i) (*this)[i] = _conditions[i]; } void BoundaryConditions::BCContainer::set(size_t index, const BoundaryConditions::BoundaryCondition_t _condition) { #ifndef NDEBUG range AllowedRange(0, this->size()); ASSERT(AllowedRange.isInRange(index), "BCContainer::set() - index "+toString(index)+" out of bounds " +toString(AllowedRange)+"."); #endif (*this)[index] = _condition; } /** Converter from enum to string. * * @param condition enum * @return name of the num */ const std::string & BoundaryConditions::BCContainer::getName(const BoundaryConditions::BoundaryCondition_t &condition) const { ASSERT( ((condition >= (BoundaryConditions::BoundaryCondition_t)0) && (condition < BoundaryConditions::MAX_BoundaryCondition_t)), "BCContainer::getName() - enum "+toString(condition)+" is not a valid enum."); EnumToStringMap::const_iterator iter = ConverterBiMap.find(condition); ASSERT(iter != ConverterBiMap.end(), "BCContainer::getName() - enum "+toString(condition)+" is unknown for any enum name."); return iter->second; } /** Converter from string to enum. * * @param condition name of the condition * @return enum index */ const BoundaryConditions::BoundaryCondition_t & BoundaryConditions::BCContainer::getEnum(const std::string &condition) const { StringToEnumMap::const_iterator iter = ReConverterBiMap.find(condition); ASSERT( iter != ReConverterBiMap.end(), "BCContainer::getEnum() - name "+condition+" is unknown for any enum."); return iter->second; } /** Output routine for class BCContainer to stream. * * @param out stream to print to * @param t instance of BCContainer. * @return stream for concatenation */ std::ostream &operator<<(std::ostream &out, const BoundaryConditions::BCContainer &t) { for (BoundaryConditions::BCContainer::const_iterator iter = t.begin(); iter != t.end(); ++iter) { if (iter != t.begin()) out << ", "; out << t.getName(*iter); } return out; } /** Input routine for class BCContainer from stream. * * We expect input as comma-separated list with NDIM values. * * @param in input stream * @param t instance of BCContainer to set * @return input stream for concatenation */ std::istream &operator>>(std::istream &in, BoundaryConditions::BCContainer &t) { // read from stream till semicolon or end std::stringbuf sbuf; in.get(sbuf, ';'); // tokenize typedef boost::tokenizer< boost::char_separator > tokens; BoundaryConditions::Conditions_t conditions; boost::char_separator commasep(","); // it is imperative to copy the content of the stringbuffer, otherwise we'll // get strange bug where 'Wrap' != 'Wrap' and so on. std::string line(sbuf.str()); tokens tok(line, commasep); for(tokens::iterator iter=tok.begin(); iter!=tok.end();++iter) { // remove leading and trailing white space std::string condition(*iter); boost::trim(condition); conditions.push_back(t.getEnum(condition)); } // set t.set(conditions); return in; }