Commit 3c050d06 authored by Praetorius, Simon's avatar Praetorius, Simon

initfile set to AMDiS format

parent bb9b82d4
Pipeline #962 passed with stage
in 9 minutes and 27 seconds
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment