/*
* 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;
}