Skip to content
Snippets Groups Projects
Commit 3c050d06 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

initfile set to AMDiS format

parent bb9b82d4
Branches
No related tags found
No related merge requests found
......@@ -7,6 +7,7 @@ dune_library_add_sources(amdis SOURCES
AdaptStationary.cpp
AMDiS.cpp
Initfile.cpp
InitfileParser.cpp
ProblemInstatBase.cpp
# ProblemInstat.cpp
ProblemStat.cpp
......@@ -31,6 +32,7 @@ install(FILES
GridFunctionOperator.hpp
GridFunctions.hpp
Initfile.hpp
InitfileParser.hpp
LinearAlgebra.hpp
LocalAssembler.hpp
LocalAssemblerBase.hpp
......
#define AMDIS_NO_EXTERN_INITFILE
#include "Initfile.hpp"
#undef AMDIS_NO_EXTERN_INITFILE
#include <dune/amdis/Initfile.hpp>
#include <string>
#ifdef _MSC_VER
#include <io.h> // _access
#else
#include <unistd.h>
#endif
#include <dune/common/parametertreeparser.hh>
#include <dune/amdis/InitfileParser.hpp>
// a parser for arithmetic expressions
// #include <muParser.h>
#include <dune/amdis/Output.hpp>
namespace AMDiS
{
/// check for file existence
inline bool file_exists(std::string const& filename)
{
#ifdef _MSC_VER
return _access(filename.c_str(), 0) == 0;
#else
return access(filename.c_str(), F_OK) == 0;
#endif
}
// namespace detail
// {
// double mu_parser_eval(std::string const& valStr)
......@@ -42,54 +20,41 @@ namespace AMDiS
// }
// }
/// initialize singleton object an global parameters
void Initfile::init(std::string in)
{
singlett().read(in);
singlett().getInternalParameters();
}
/// Fill an initfile from a file with filename fn
void Initfile::read(std::string fn, bool /*force*/)
{
test_exit(file_exists(fn),
"init-file '", fn, "' cannot be opened for reading");
Dune::ParameterTreeParser::readINITree(fn, pt);
}
void Initfile::init(std::string in)
{
singlett().read(in);
singlett().getInternalParameters();
}
/// read standard values for output and information of parameter-values
void Initfile::getInternalParameters()
{
int val = 0;
get("level of information", val);
msgInfo = val;
void Initfile::read(std::string fn, bool /*force*/)
{
InitfileParser::readInitfile(fn, pt_);
}
val = 1;
get("parameter information", val);
paramInfo = val;
val = 0;
get("break on missing tag", val);
breakOnMissingTag = val;
void Initfile::getInternalParameters()
{
int val = 0;
get("level of information", val);
msgInfo = val;
if (msgInfo == 0)
paramInfo = 0;
}
val = 1;
get("parameter information", val);
paramInfo = val;
val = 0;
get("break on missing tag", val);
breakOnMissingTag = val;
/// print all parameters to std::cout
void Initfile::printParameters()
{
// TODO: implement printing of all parameters
}
if (msgInfo == 0)
paramInfo = 0;
}
// explicit template instatiation
template void Initfile::get(std::string, int&);
template void Initfile::get(std::string, double&);
template void Initfile::get(std::string, std::string&);
void Initfile::printParameters()
{
// TODO: implement printing of all parameters
}
} // end namespace AMDiS
#pragma once
#include <array>
#include <string>
#include <iostream>
#include <type_traits>
#include <list>
#include <vector>
#include <boost/lexical_cast.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/tokenizer.hpp>
#include <dune/common/fvector.hh>
#include <dune/common/parametertree.hh>
// #include <boost/property_tree/ptree.hpp>
#include <dune/common/std/optional.hh>
#include <dune/amdis/Output.hpp>
#include <dune/amdis/common/Math.hpp>
namespace AMDiS
{
// /// output-stream for std::list
// template <class T, class Alloc>
// std::ostream& operator<<(std::ostream& out, std::list<T,Alloc> const& l)
// {
// auto it = l.begin();
// out << "[";
// if (l.size() > 0)
// out << *it;
// for (; it != l.end(); ++it)
// out << ", " << *it;
// out << "]";
// return out;
// }
// /// output-stream for std::vector
// template <class T, class Alloc>
// std::ostream& operator<<(std::ostream& out, std::vector<T,Alloc> const& l)
// {
// auto it = l.begin();
// out << "[";
// if (l.size() > 0)
// out << *it;
// for (; it != l.end(); ++it)
// out << ", " << *it;
// out << "]";
// return out;
// }
inline void replaceAll(std::string& str, std::string const& from, std::string const& to)
{
if (from.empty())
return;
std::size_t start_pos = 0;
while ((start_pos = str.find(from, start_pos)) != std::string::npos)
{
str.replace(start_pos, from.length(), to);
start_pos += to.length();
}
}
// _____________________________________________________________________________
/** 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
class Initfile
{
using Self = Initfile;
/** initialize init-file from file with filename in, read data and save it
* to singleton-map
* @param in: filename string
*/
public:
/// initialize singleton object and global parameters
static void init(std::string in);
/// \brief Get parameter-values from parameter-tree
/**
* Looks for the `key` in the parameter-tree and returns
* the stored and parsed value if found and parsable.
*
* Does not thrown an exception if something goes wrong!
**/
template <class T>
static Dune::Std::optional<T> get(std::string key)
{
replaceAll(key, "->", ".");
try {
return singlett().pt.get<T>(key);
return pt().get<T>(key);
}
catch (...) {
return Dune::Std::nullopt;
}
}
/** \brief Static get routine for getting parameter-values from init-file
* initialized in init()-method.
* Cast the value to the desired type.
*
* \param tag: The tag to look for
* \param value: The result.
*/
/// \brief Get parameter-values from parameter-tree with default value
/**
* initialized in init()-method.
* Cast the value to the desired type.
*
* \param key: The tag to look for
* \param value: The default value and result.
**/
template <class T>
static void get(std::string key, T& value)
{
replaceAll(key, "->", ".");
value = singlett().pt.get(key, value);
}
/// update map tag->value_old to tag->value in singleton
template <class T>
static void set(std::string tag, T& value, int debugInfo= -1)
{
if (debugInfo == -1)
debugInfo = singlett().getMsgInfo();
replaceAll(tag, "->", ".");
// auto tagPath = path(tag, '>');
// singlett().pt.put(tagPath, value);
// update msg parameters msgInfo, msgWait, paramInfo
singlett().getInternalParameters();
// if (debugInfo == 2)
// std::cout << "Parameter '" << tag << "'"
// << " set to: " << value << std::endl;
}
/// add map tag->value to data in singleton
template <class T>
static void add(std::string tag, T& value, int debugInfo = -1)
{
set(tag, value, debugInfo);
value = pt().get(key, value);
}
/// Returns specified info level
......@@ -139,47 +53,32 @@ namespace AMDiS
return singlett().msgInfo;
}
/// print all data in singleton to std::cout
static void printParameters();
/// clear data in singleton
static void clearData()
{
// singlett().clear();
}
/// save singlett-data to file with filename fn
static void save(std::string /*fn*/)
{
// using boost::property_tree::json_parser;
// json_parser::write_jason(fn, singlett().pt);
}
static void clearData() {}
protected:
Initfile() = default;
/// return the singleton that contains the data
/// Return the singleton that contains the data
static Initfile& singlett()
{
static Initfile initfile;
return initfile;
}
/** Fill the initfile from an input stream.
* @param in: the stream to fill the data from.
* Current dataformat: tag:value
* Comment char: percent '%'
* Include files: #include "filename" or #include <filename>
*/
void read(std::string fn, bool force = false);
/// Return the parameter-tree
static Dune::ParameterTree& pt()
{
return singlett().pt_;
}
/// Write data-map to initfile with filename fn
/// Fill an parametr-tree from a file with filename fn
void read(std::string fn, bool force = false);
void write(std::string fn);
/// read parameters for msgInfo, msgWait, paramInfo
/// read standard values for output and information of parameter-values
void getInternalParameters();
int msgInfo = 0;
......@@ -187,15 +86,9 @@ namespace AMDiS
int breakOnMissingTag = 0;
/// ParameterTree to read/store parameter values
Dune::ParameterTree pt;
Dune::ParameterTree pt_;
};
using Parameters = Initfile;
#ifndef AMDIS_NO_EXTERN_INITFILE
extern template void Initfile::get(std::string, int&);
extern template void Initfile::get(std::string, double&);
extern template void Initfile::get(std::string, std::string&);
#endif
} // end namespace AMDiS
#include <dune/amdis/InitfileParser.hpp>
#include <dune/amdis/Output.hpp>
#include <dune/amdis/utility/Filesystem.hpp>
#include <dune/amdis/utility/String.hpp>
namespace AMDiS {
void InitfileParser::readInitfile(std::string fn, Dune::ParameterTree& pt, bool overwrite)
{
test_exit(filesystem::exists(fn),
"init-file '", fn, "' cannot be opened for reading");
// read file if its not parsed already
auto ins = includeList().insert(fn);
if (ins.second) {
std::ifstream in(fn.c_str());
readInitfile(in, pt, overwrite);
}
}
void InitfileParser::readInitfile(std::istream& in, Dune::ParameterTree& pt, bool overwrite)
{
std::string swap;
std::getline(in, swap);
while (in.good() || swap.size() > 0) {
std::string whitespaces = " \t\r\f\n";
std::string delimiter = "\r\n";
std::string sw(swap);
std::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
std::size_t pos = sw.find(':');
if (pos == std::string::npos)
throw std::runtime_error("cannot find the delimiter ':' in line '" + sw + "'");
std::string name = sw.substr(0, pos);
std::string value = sw.substr(pos + 1, sw.length() - (pos + 1));
// remove everything after the %
pos = value.find('%');
if (pos != std::string::npos)
value = value.substr(0, pos);
// add parameter to map after variable replacement
std::string paramName = replaceVariable(pt, trim(name));
std::string paramValue = replaceVariable(pt, trim(value));
paramValue = replaceExpression(pt, paramValue);
// add parameter to parametertree
if (overwrite || ! pt.hasKey(paramName))
pt[paramName] = paramValue;
}
else if (pos0 != std::string::npos &&
sw[pos0] == '#' &&
std::size_t(sw.find("#include")) == pos0)
{
// include file by '#include "filename"' or '#include <filename>'
std::size_t pos = sw.find_first_not_of(whitespaces, pos0 + std::string("#include").size() + 1);
std::size_t epos = 0;
std::string fn = "";
switch (char c = swap[pos++]) {
case '<':
c= '>';
case '\"':
delimiter += c;
epos = sw.find_first_of(delimiter, pos);
fn = sw.substr(pos, epos - pos);
if (sw[epos]!=c)
throw std::runtime_error("filename in #include not terminated by " + std::to_string(c));
break;
default:
throw std::runtime_error("no filename given for #include");
}
readInitfile(fn, pt, overwrite);
}
swap.clear();
std::getline(in, swap);
}
}
std::string InitfileParser::replaceVariable(Dune::ParameterTree const& pt, std::string input)
{
std::string whitespaces = " \t\r\f";
std::string allowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
std::string inputSwap = input;
std::size_t posVar = inputSwap.find_first_of('$');
while (posVar != std::string::npos) {
std::size_t posVarBegin, posVarEnd;
if (inputSwap[posVar+1] == '{') { // ${var_name}
posVarEnd = inputSwap.find_first_of('}',posVar + 2);
posVarBegin = posVar + 1;
} else if (inputSwap[posVar+1] != '(' && inputSwap[posVar+1] != '[') { // $var_name
posVarEnd = inputSwap.find_first_not_of(allowedChars, posVar + 1);
posVarBegin = posVar;
} else {
posVar = inputSwap.find_first_of('$',posVar+1);
continue;
}
std::string varName = inputSwap.substr(posVarBegin + 1 , posVarEnd - posVarBegin - 1);
// if varname is found in parameter list then replace variable by value
// otherwise throw tagNotFound exception
if (!pt.hasKey(varName))
throw std::runtime_error("required tag '" + varName + "' for variable substitution not found");
std::string varParam = pt[varName];
std::string replaceName = inputSwap.substr(posVar , posVarEnd - posVar + (posVarBegin - posVar));
inputSwap.replace(inputSwap.find(replaceName), replaceName.length(), varParam);
posVar = inputSwap.find_first_of('$',posVarBegin);
}
return inputSwap;
}
std::string InitfileParser::replaceExpression(Dune::ParameterTree const& pt, std::string input)
{
#if 0
std::string whitespaces = " \t\r\f";
std::string inputSwap = input;
std::size_t posVar = inputSwap.find("$(");
while (posVar != std::string::npos) {
size_t posVarBegin, posVarEnd;
posVarEnd = inputSwap.find_first_of(')',posVar + 2);
posVarBegin = posVar + 1;
std::string varName = inputSwap.substr(posVarBegin + 1 , posVarEnd - posVarBegin - 1);
double value = 0.0;
detail::convert(varName, value); // string -> double (using muparser)
detail::convert(value, varName); // double -> string
std::string replaceName = inputSwap.substr(posVar , posVarEnd - posVar + (posVarBegin - posVar));
inputSwap.replace(inputSwap.find(replaceName), replaceName.length(), varName);
posVar = inputSwap.find("$(",posVarBegin);
}
return inputSwap;
#else
// currently no evaluation implemented.
return input;
#endif
}
} // end namespace AMDiS
#pragma once
#include <fstream>
#include <set>
#include <string>
#include <dune/common/parametertree.hh>
namespace AMDiS
{
/// Parser for AMDiS initfile format
/**
* An AMDiS initfile is a list of pairs `(paramter, value)`
* stored in a structured textfile of the format
* \verbatim
* parameter: value % a comment
*
* #include <filename> % include files
* var_${parameter}: value2 % variable replacement in keys
* parameter2: ${parameter} % variable replacement in values
*
* parameter3: 1 + sin(4.0) % expressions in the values
* parameter4: $(1 + 2) % expression replacement
* \endverbatim
**/
class InitfileParser
{
public:
/// Read initfile from input stream into parameter-tree
static void readInitfile(std::istream& in, Dune::ParameterTree& pt, bool overwrite);
/// Read initfile from input stream into parameter-tree
static void readInitfile(std::string fn, Dune::ParameterTree& pt, bool overwrite = true);
private:
/// Provide a list of already read files. This is necessary to not double include the same file.
static std::set<std::string>& includeList()
{
static std::set<std::string> includeFiles;
return includeFiles;
}
/// \brief Replace variables by its value stored in the parameter-tree
/**
* Replaces variables of the form ${variablename} or $variablename in the `input`
* by a corresponding value already stored in the parameter tree `pt`.
*/
static std::string replaceVariable(Dune::ParameterTree const& pt, std::string input);
/// \brief Evaluate an expression. NOTE: currently not implemented
/**
* Evaluates expressions of the form $(expression) in the `input`
**/
static std::string replaceExpression(Dune::ParameterTree const& pt, std::string input);
};
} // end namespace AMDiS
......@@ -35,11 +35,11 @@ namespace AMDiS
: std::integral_constant<std::size_t, N> {};
template <class T, int N>
struct SizeImpl<Dune::FieldVector<T,N>, std::enable_if_t<(N!=1)>>
struct SizeImpl<Dune::FieldVector<T,N>>
: std::integral_constant<std::size_t, N> {};
template <class T, int N, int M>
struct SizeImpl<Dune::FieldMatrix<T,N,M>, std::enable_if_t<(N!=1 || M!=1)>>
struct SizeImpl<Dune::FieldMatrix<T,N,M>>
: std::integral_constant<std::size_t, N*M> {};
// Specialization for arithmetic types
......
......@@ -89,4 +89,17 @@ namespace AMDiS
}
}
/// Replace all occurences of substring `from` with `to` in source `str`.
inline void replaceAll(std::string& str, std::string const& from, std::string const& to)
{
if (from.empty())
return;
std::size_t start_pos = 0;
while ((start_pos = str.find(from, start_pos)) != std::string::npos)
{
str.replace(start_pos, from.length(), to);
start_pos += to.length();
}
}
} // end namspace AMDiS
dimension of world: 2
elliptMesh->macro file name: ./macro/macro.stand.2d
elliptMesh->global refinements: 5
ellipt->mesh: elliptMesh
ellipt->solver->name: cg
ellipt->solver->max iteration: 1000
ellipt->solver->tolerance: 1.e-8
ellipt->solver->info: 10
ellipt->solver->left precon: diag
ellipt->solver->right precon: no
ellipt->output[0]->filename: ellipt.2d
ellipt->output[0]->name: u
ellipt->output[0]->output directory: ./output
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment