/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2012 University of Bonn. All rights reserved. * * * This file is part of MoleCuilder. * * MoleCuilder is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * MoleCuilder 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MoleCuilder. If not, see . */ /* * 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(const std::vector< std::string > &_conditions) { BoundaryConditions::Conditions_t newconditions; for (std::vector< std::string >::const_iterator iter = _conditions.begin(); iter != _conditions.end(); ++iter) newconditions.push_back(getEnum(*iter)); set(newconditions); } 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; } void BoundaryConditions::BCContainer::set(size_t index, const std::string &_condition) { set(index, getEnum(_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; }