Commit 6374f084 authored by Praetorius, Simon's avatar Praetorius, Simon

addBoundary*Operator, static updateAnimationFile and small changes in Initfile

parent 52419cef
......@@ -56,6 +56,7 @@
#include <mpi.h>
#endif
#include <boost/algorithm/string.hpp>
#include "boost/tuple/tuple.hpp"
#include "AMDiS_fwd.h"
......@@ -461,6 +462,7 @@ namespace AMDiS {
GRD_PSI,
GRD_PHI
};
}
#endif // AMDIS_GLOBAL_H
......
......@@ -8,25 +8,29 @@ using namespace std;
namespace AMDiS {
/// the small parser for the initfile. see description of read(Initfile&, istream&)
/// the small parser for the initfile. see description of
/// read(Initfile&,istream&)
struct Parser {
Parser(const string& line)
{
size_t pos = line.find(':');
if (pos == string::npos)
throw runtime_error("cannot find the delimiter ':' in line '" + line + "'");
if (pos == string::npos) {
throw runtime_error("cannot find the delimiter ':' in line "
"'" + line + "'");
}
name = line.substr(0, pos);
value = line.substr(pos + 1, line.length() - (pos + 1));
// remove everything after the %
pos = value.find('%');
if (pos != string::npos)
value = value.substr(0, pos);
value = value.substr(0, pos);
}
string name;
string value;
};
Initfile* Initfile::singlett= NULL;
std::set<std::string> Initfile::fn_include_list;
......@@ -39,7 +43,7 @@ namespace AMDiS {
fn_include_list.clear();
singlett->read(in);
singlett->getInternalParameters();
// initialize global strcutures using parameters
Global::init();
}
......@@ -53,8 +57,8 @@ namespace AMDiS {
std::ifstream inputFile;
inputFile.open(fn.c_str(), std::ios::in);
if (!inputFile.is_open())
throw runtime_error("init-file cannot be opened for reading");
throw runtime_error("init-file cannot be opened for reading");
fn_include_list.insert(fn);
read(inputFile);
}
......@@ -71,34 +75,37 @@ namespace AMDiS {
std::string whitespaces = " \t\r\f";
std::string sw(swap);
size_t pos0 = sw.find_first_not_of(whitespaces);
if (pos0 != std::string::npos && sw[pos0] != '%' && sw[pos0] != '#' && sw[pos0] != 0) {
// parse line and extract map: tag->value
Parser parser(sw);
operator[](parser.name) = parser.value;
} else if (sw[pos0] == '#' && static_cast<size_t>(sw.find("#include")) == pos0) {
// include file by '#include "filename"' or '#include <filename>'
size_t pos = sw.find_first_not_of(whitespaces, std::string("#include").size() + 1);
size_t epos = 0;
std::string fn = "";
std::stringstream errorMsg;
switch (char c= swap[pos++]) {
case '<':
c= '>';
case '\"':
whitespaces += c;
epos = sw.find_first_of(whitespaces, pos);
fn = sw.substr(pos, epos - pos);
if (sw[epos]!=c) {
errorMsg << "filename in #include not terminated by " << c;
throw std::runtime_error(errorMsg.str());
}
break;
default:
throw std::runtime_error("no filename given for #include");
}
read(fn);
if (pos0 != std::string::npos && sw[pos0] != '%'
&& sw[pos0] != '#' && sw[pos0] != 0) {
// parse line and extract map: tag->value
Parser parser(sw);
operator[](parser.name) = parser.value;
} else if (sw[pos0] == '#'
&& static_cast<size_t>(sw.find("#include")) == pos0) {
// include file by '#include "filename"' or '#include <filename>'
size_t pos = sw.find_first_not_of(whitespaces,
std::string("#include").size() + 1);
size_t epos = 0;
std::string fn = "";
std::stringstream errorMsg;
switch (char c= swap[pos++]) {
case '<':
c= '>';
case '\"':
whitespaces += c;
epos = sw.find_first_of(whitespaces, pos);
fn = sw.substr(pos, epos - pos);
if (sw[epos]!=c) {
errorMsg << "filename in #include not terminated by " << c;
throw std::runtime_error(errorMsg.str());
}
break;
default:
throw std::runtime_error("no filename given for #include");
}
read(fn);
}
in.getline(swap, line_length);
}
......@@ -109,8 +116,8 @@ namespace AMDiS {
{
for (int i = 0; i < argc; i++) {
if (strcmp("-rs", argv[i]) == 0) {
std::string input(argv[i + 1]);
add("argv->rs", input, 0);
std::string input(argv[i + 1]);
add("argv->rs", input, 0);
}
}
}
......@@ -122,15 +129,15 @@ namespace AMDiS {
int val = 0;
get("level of information", val, 0);
msgInfo = val;
val = 1;
get("WAIT", val, 0);
msgWait = val;
val = 1;
get("parameter information", val, 0);
paramInfo = val;
val = 0;
get("break on missing tag", val, 0);
breakOnMissingTag = val;
......@@ -145,7 +152,7 @@ namespace AMDiS {
{
initIntern();
for (Initfile::iterator it = singlett->begin(); it != singlett->end(); it++)
std::cout << (*it).first << " => " << (*it).second << std::endl;
std::cout << (*it).first << " => " << (*it).second << std::endl;
}
......@@ -153,7 +160,7 @@ namespace AMDiS {
void Initfile::write(ostream& out)
{
for (Initfile::iterator it = begin() ; it!=end(); it++)
out << (*it).first << ": " << (*it).second << std::endl;
out << (*it).first << ": " << (*it).second << std::endl;
}
......@@ -164,8 +171,7 @@ namespace AMDiS {
outFile.open(fn.c_str(), std::ios::out);
if (!outFile.is_open())
throw runtime_error("init-file cannot be opened for writing");
write(outFile);
}
}
} // end namespace AMDiS
//
// Software License for AMDiS
//
// Copyright (c) 2010 Dresden University of Technology
// All rights reserved.
// Authors: Simon Vey, Thomas Witkowski et al.
//
// This file is part of AMDiS
//
// See also license.opensource.txt in the distribution.
#ifndef INITFILE_H
#define INITFILE_H
......@@ -25,23 +36,25 @@
namespace AMDiS {
namespace InitfileInternal {
/// Exceptions
struct WrongVectorSize : std::runtime_error {
WrongVectorSize(std::string m)
: std::runtime_error(m)
: std::runtime_error(m)
{}
};
struct NoDelim : std::runtime_error {
NoDelim(std::string m)
: std::runtime_error(m)
: std::runtime_error(m)
{}
};
struct WrongVectorFormat : std::runtime_error {
WrongVectorFormat(std::string m)
: std::runtime_error(m)
: std::runtime_error(m)
{}
};
......@@ -49,33 +62,33 @@ namespace AMDiS {
struct WrongValueFormat : std::runtime_error {
static std::string name(int)
{
return "int";
return "int";
}
static std::string name(bool)
{
return "bool";
return "bool";
}
static std::string name(double)
{
return "double";
return "double";
}
static std::string name(unsigned int)
{
return "unsigned int";
return "unsigned int";
}
template<typename G>
static std::string name(G)
{
return std::string(typeid(G).name());
return std::string(typeid(G).name());
}
WrongValueFormat(std::string value)
: std::runtime_error(std::string("cannot convert '") +
value + std::string("' into <") + name(T()) + ">")
: std::runtime_error(std::string("cannot convert '") +
value + std::string("' into <") + name(T()) + ">")
{}
};
......@@ -83,38 +96,38 @@ namespace AMDiS {
struct BadArithmeticExpression : std::runtime_error {
static std::string name(int)
{
return "int";
return "int";
}
static std::string name(bool)
{
return "bool";
return "bool";
}
static std::string name(double)
{
return "double";
return "double";
}
static std::string name(unsigned int)
{
return "unsigned int";
return "unsigned int";
}
template<typename G>
static std::string name(G)
{
return std::string(typeid(G).name());
return std::string(typeid(G).name());
}
BadArithmeticExpression(std::string m, std::string value)
: std::runtime_error(std::string("cannot evaluate expression '") +
value + std::string("' into <") + name(T()) +
">\nParser message: '" + m + "'")
: std::runtime_error(std::string("cannot evaluate expression '") +
value + std::string("' into <") + name(T()) +
">\nParser message: '" + m + "'")
{}
};
/// trim std::string
inline std::string trim(const std::string& oldStr)
{
......@@ -124,14 +137,15 @@ namespace AMDiS {
}
/// return the delimiter or throw an exception if there is no known delimiter in value
/// return the delimiter or throw an exception if there is no known
/// delimiter in value
inline size_t checkDelim(const std::string& value, const std::string& delims)
{
size_t pos(std::string::npos);
for (unsigned i = 0; i < delims.length(); i++) {
pos = value.find(delims[i]);
if (pos != std::string::npos)
return i;
pos = value.find(delims[i]);
if (pos != std::string::npos)
return i;
}
throw NoDelim("cannot detect the delimiter in " + value);
return 0;
......@@ -139,12 +153,12 @@ namespace AMDiS {
/** parse an container from tag tag. The Container must have the properties:
* - type value_type
* - member function push_back
*/
* - type value_type
* - member function push_back
*/
template< typename Container >
inline void getContainer(const std::string val_, Container& c)
{
{
// accepted brackets and delimiters for vector input
std::string begBrackets= "{[(";
std::string endBrackets= "}])";
......@@ -154,35 +168,37 @@ namespace AMDiS {
std::string val = trim(val_);
size_t pos = begBrackets.find(val[0]);
if (pos == std::string::npos)
throw WrongVectorFormat("cannot convert '" + val + "' into a list. No leading bracket found!");
throw WrongVectorFormat("cannot convert "
"'" + val + "' into a list. No leading bracket found!");
if (val[val.length() - 1] != endBrackets[pos])
throw WrongVectorFormat("begin and end bracket are different in value '" + val + "'");
throw WrongVectorFormat("begin and end bracket are different in"
" value '" + val + "'");
size_t oldPos = 1;
size_t curDelim = 0;
typedef typename Container::value_type ValueType;
ValueType swap;
try {
curDelim = checkDelim(val, delims);
pos = val.find(delims[curDelim], oldPos);
while (pos != std::string::npos) {
std::string curWord = val.substr(oldPos, pos - oldPos);
oldPos = pos + 1;
convert(curWord, swap);
c.push_back(swap);
pos= val.find(delims[curDelim], oldPos);
}
//last entry
std::string curWord = val.substr(oldPos, val.length() - 1 - oldPos);
convert(curWord, swap);
c.push_back(swap);
curDelim = checkDelim(val, delims);
pos = val.find(delims[curDelim], oldPos);
while (pos != std::string::npos) {
std::string curWord = val.substr(oldPos, pos - oldPos);
oldPos = pos + 1;
convert(curWord, swap);
c.push_back(swap);
pos = val.find(delims[curDelim], oldPos);
}
//last entry
std::string curWord = val.substr(oldPos, val.length() - 1 - oldPos);
convert(curWord, swap);
c.push_back(swap);
} catch (NoDelim nd) {
std::string curWord = val.substr(1, val.length() - 2);
curWord = trim(curWord);
if (curWord.length() > 0) {
// container with one entry
convert(curWord, swap);
c.push_back(swap);
}
std::string curWord = val.substr(1, val.length() - 2);
curWord = trim(curWord);
if (curWord.length() > 0) {
// container with one entry
convert(curWord, swap);
c.push_back(swap);
}
}
}
......@@ -197,43 +213,62 @@ namespace AMDiS {
/// convert string to intrinsic type
template<typename T>
inline void convert(const std::string valStr, T& value ,
typename boost::enable_if<boost::is_pod<T> >::type* p = NULL ,
typename boost::disable_if<boost::is_enum<T> >::type* p2 = NULL)
typename boost::enable_if<boost::is_pod<T> >::type* p = NULL ,
typename boost::disable_if<boost::is_enum<T> >::type* p2 = NULL)
{
using boost::lexical_cast;
using boost::numeric_cast;
mu::Parser parser;
parser.DefineConst(_T("M_PI"), m_pi);
parser.DefineConst(_T("M_E"), m_e);
try {
parser.SetExpr(valStr);
value = numeric_cast< T >(parser.Eval());
} catch(boost::bad_lexical_cast e) {
throw WrongValueFormat< T >(valStr);
} catch(boost::bad_numeric_cast e) {
throw WrongValueFormat< T >(valStr);
parser.SetExpr(valStr);
value = numeric_cast< T >(parser.Eval());
} catch (boost::bad_lexical_cast e) {
throw WrongValueFormat< T >(valStr);
} catch (boost::bad_numeric_cast e) {
throw WrongValueFormat< T >(valStr);
} catch (mu::Parser::exception_type &e) {
throw BadArithmeticExpression<T>(e.GetMsg(), valStr);
throw BadArithmeticExpression<T>(e.GetMsg(), valStr);
}
}
template<typename T>
inline void convert(const std::string valStr, T& value,
typename boost::enable_if< boost::is_enum< T > >::type* p = NULL)
typename boost::enable_if< boost::is_enum< T > >::type* p = NULL)
{
unsigned int swap = 0;
int swap = 0;
try {
swap = boost::lexical_cast<unsigned int>(trim(valStr));
} catch(boost::bad_lexical_cast e) {
throw WrongValueFormat< T >(valStr);
swap = boost::lexical_cast<int>(trim(valStr));
} catch (boost::bad_lexical_cast e) {
throw WrongValueFormat< T >(valStr);
}
value = static_cast< T >(swap);
}
/// convert special enums
inline void convert(const std::string valStr, Norm& value)
{
std::string swapStr = boost::to_upper_copy(valStr);
if (swapStr == "NO_NORM")
value = static_cast< Norm >(NO_NORM);
else if (swapStr == "H1_NORM")
value = static_cast< Norm >(H1_NORM);
else if (swapStr == "L2_NORM")
value = static_cast< Norm >(L2_NORM);
else {
int swap= 0;
convert(valStr, swap);
value = static_cast< Norm >(swap);
}
}
/// convert string to WorldVector
template< typename T >
inline void convert(const std::string valStr, WorldVector<T>& c)
......@@ -241,10 +276,10 @@ namespace AMDiS {
std::vector<T> temp_vec;
getContainer(valStr, temp_vec);
if (static_cast<int>(temp_vec.size()) != c.getSize())
throw WrongVectorSize("wrong number of entries for WorldVector");
throw WrongVectorSize("wrong number of entries for WorldVector");
for (unsigned i = 0; i < temp_vec.size(); i++)
c[i] = temp_vec[i];
c[i] = temp_vec[i];
}
......@@ -264,13 +299,15 @@ namespace AMDiS {
}
/// convert value of arbitrary type to string using stringstream and operator<< for type
/// convert value of arbitrary type to string using stringstream and
/// operator<< for type
template<typename T>
inline void convert(const T value, std::string& valStr)
{
std::stringstream ss;
ss.precision(6);
ss << value;
valStr= ss.str();
valStr = ss.str();
}
......@@ -280,24 +317,23 @@ namespace AMDiS {
{
std::vector<T> temp_vec(c.getSize());
for (unsigned i = 0; i < temp_vec.size(); i++)
temp_vec[i] = c[i];
temp_vec[i] = c[i];
convert(temp_vec, valStr);
}
} // end namespace InitfileInternal
/** The entry in an initfile. This helper class was constructed to allow calls like
* val = data.get(tag)
* for arbitrary types of val. At current stage, only double and bool is supported
*/
/** The entry in an initfile. This helper class was constructed to allow calls
* like val = data.get(tag) for arbitrary types of val. At current stage, only
* double and bool is supported
*/
struct InitEntry {
///the value as string
std::string valStr;
/// initialize with value as string
InitEntry(std::string v = "")
: valStr(v)
: valStr(v)
{}
/// cast string to type T
......@@ -341,59 +377,71 @@ namespace AMDiS {
}
/** Basis data container as a map of tag on a value as strings. The container throws an exception, if the tag was not found.
*/
/** Basis data container as a map of tag on a value as strings. The container
* throws an exception, if the tag was not found.
*/
struct Initfile : public std::map<std::string, std::string>
{
typedef std::map< std::string, std::string > super;
/// Exceptions
struct TagNotFound : std::invalid_argument {
TagNotFound(std::string m)
: std::invalid_argument(m)
: std::invalid_argument(m)
{}
};
struct TagNotFoundBreak : std::invalid_argument { // print 'tag not found' and exit
struct TagNotFoundBreak : std::invalid_argument {
// print 'tag not found' and exit
TagNotFoundBreak(std::string m)
: std::invalid_argument(m)
: std::invalid_argument(m)
{}
};
/** initialize init-file from file with filename in, read data and save it to singleton-map
* @param in: filename string
*/
/** initialize init-file from file with filename in, read data and save it
* to singleton-map
* @param in: filename string
*/
static void init(std::string in);
static void init(int print, string filename, const char *flags = NULL)
{
WARNING("Parameters::init(int,std::string,const char*) is depreciated. Use Parameters::init(std::string) instead!\n");
init(filename);
WARNING("Parameters::init(int,std::string,const char*) is depreciated. "
"Use Parameters::init(std::string) instead!\n");
init(filename);
}
/** Static get routine for getting parameter-values from init-file initialized in init()-method.
* Cast the value to the desired type using std::stringstream.
* @param tag: The tag to look for
* @param value: The result.
* @param debugInfo: msgInfo for current parameter. (0..no printing, 1..print missing parameter info, 2..print parameter value) [optional]
*/
/** Static get routine for getting parameter-values from init-file
* initialized in init()-method.
* Cast the value to the desired type using std::stringstream.
* @param tag: The tag to look for
* @param value: The result.
* @param debugInfo: msgInfo for current parameter. (0..no printing,
* 1..print missing parameter info, 2..print parameter value) [optional]
*/
template<typename T>
static void get(const std::string tag, T& value, int debugInfo = -1)
{
using namespace InitfileInternal;
initIntern();
if (debugInfo == -1)
debugInfo = singlett->getMsgInfo();
debugInfo = singlett->getMsgInfo();