Commit 1c75bd28 authored by steffen.schotthoefer's avatar steffen.schotthoefer
Browse files

new config file style with auto parser. Corresponding changes

parent 938f4e77
Pipeline #85913 passed with stages
in 10 minutes and 58 seconds
......@@ -56,13 +56,13 @@ Execute the compiled binary and hand over a valid *TOML*-styled config file.
Example from inside the `code` directory:
```bash
./bin/RTSN input/example.toml
./bin/RTSN input/example.cfg
```
In order to run the code in parallel execute:
```bash
OMP_NUM_THREADS=N mpirun -np J ./bin/RTSN input/example.toml
OMP_NUM_THREADS=N mpirun -np J ./bin/RTSN input/example.cfg
```
with `N` equal to the number of shared memory threads and `J` equal to the number of distrubuted memory threads.
......
% This is a comment
%%%%%%%%%%%%%%%%%%%%%%
% Example config file
%
% ---- File specifications ----
%
% Output directory
OUTPUT_DIR = ../result
% Output file
OUTPUT_FILE = example
% Log directory
LOG_DIR = ../result/logs
% Mesh File
MESH_FILE = checkerboard.su2
%
% ---- Solver specifications ----
%
% CFL number
CFL_NUMBER = 0.9
% Final time for simulation
TIME_FINAL = 0.3
% ---- Boundary Conditions ----
% Example: BC_DIRICLET = (dummyMarker1, dummyMarker2)
% Dirichlet Boundary
BC_DIRICHLET = ( void )
%
%% Quadrature Specifications
% Quadrature Type
QUAD_TYPE = MONTE_CARLO
% Quadrature Order
QUAD_ORDER = 42
......@@ -28,6 +28,9 @@
#include "mesh.h"
#include "settings.h"
#include "settings/CConfig.h"
using vtkPointsSP = vtkSmartPointer<vtkPoints>;
using vtkUnstructuredGridSP = vtkSmartPointer<vtkUnstructuredGrid>;
using vtkTriangleSP = vtkSmartPointer<vtkTriangle>;
......@@ -41,10 +44,10 @@ using vtkPointDataToCellDataSP = vtkSmartPointer<vtkPointDataToCellData>;
void ExportVTK( const std::string fileName,
const std::vector<std::vector<std::vector<double>>>& results,
const std::vector<std::string> fieldNames,
const Settings* settings,
const CConfig* settings,
const Mesh* mesh );
void InitLogger( std::string logDir, spdlog::level::level_enum terminalLogLvl, spdlog::level::level_enum fileLogLvl );
Mesh* LoadSU2MeshFromFile( const Settings* settings );
Mesh* LoadSU2MeshFromFile( const CConfig* settings );
std::string ParseArguments( int argc, char* argv[] );
Settings* ReadInputFile( std::string inputFile );
void PrintLogHeader( std::string inputFile );
......
......@@ -12,7 +12,7 @@ public:
* @brief LaxFriedrichsFlux
* @param settings
*/
LaxFriedrichsFlux(Settings* settings);
LaxFriedrichsFlux(CConfig* settings);
/**
* @brief Flux computes flux on edge for fixed ordinate at a given edge
......
......@@ -13,7 +13,7 @@
#include "typedef.h"
enum BOUNDARY_TYPE { DIRICHLET, INVALID };
#include "settings/GlobalConstants.h"
class Mesh
{
......
......@@ -2,13 +2,13 @@
#define NUMERICALFLUX_H
#include "typedef.h"
#include "settings.h"
#include "settings/CConfig.h"
class NumericalFlux
{
public:
NumericalFlux(Settings* settings);
static NumericalFlux* Create( Settings* settings );
NumericalFlux(CConfig* settings);
static NumericalFlux* Create( CConfig* settings );
/**
* @brief Flux computes flux on edge for fixed ordinate at a given edge
* @param Omega fixed ordinate for flux computation
......
......@@ -5,7 +5,7 @@
#include <string>
#include "mesh.h"
#include "option_structure.h"
#include "settings/GlobalConstants.h"
class Settings
{
......
/*!
* \file CConfig.h
* \brief Classes for different Options in rtsn
* \author S. Schotthoefer
*
* Disclaimer: This class structure was copied and modifed with open source permission from SU2 v7.0.3 https://su2code.github.io/
*/
#ifndef CONFIG_H
#define CONFIG_H
#include <map>
#include "OptionStructure.h"
#include "GlobalConstants.h"
/*!
* \class CConfig
* \brief Main class for defining the problem; basically this class reads the configuration file, and
* stores all the information.
*/
class CConfig {
private:
std::string _fileName; /*!< \brief Name of the current file without extension */
bool _base_config;
int _comm_rank, _comm_size; /*!< \brief MPI rank and size.*/
// --- Options ---
// File Structure
std::string _outputDir; /*!< \brief Directory for output files*/
std::string _outputFile; /*!< \brief Name of output file*/
std::string _logDir; /*!< \brief Directory of log file*/
std::string _meshFile; /*!< \brief Name of mesh file*/
// Quadrature
QUAD_NAME _quadName; /*!< \brief Quadrature Name*/
unsigned short _quadOrder; /*!< \brief Quadrature Order*/
// Solver
double _CFL; /*!< \brief CFL Number for Solver*/
double _tEnd; /*!< \brief Final Time for Simulation */
// Boundary Conditions
/*!< \brief List of all Pairs (marker, BOUNDARY_TYPE), e.g. (farfield,DIRICHLET).
Each Boundary Conditions must have an entry in enum BOUNDARY_TYPE*/
std::vector<std::pair<std::string, BOUNDARY_TYPE>> _boundaries;
unsigned short _nMarkerDirichlet; /*!< \brief Number of Dirichlet BC markers. Enum entry: DIRICHLET */
std::string *_MarkerDirichlet; /*!< \brief Dirichlet BC markers. */
// --- Parsing Functionality and Initializing of Options ---
/*!
* \brief Set default values for all options not yet set.
*/
void SetDefault(void);
/*!
* \brief Set the config options.
* ==> Set new config options here.
*/
void SetConfigOptions(void);
/*!
* \brief Set the config file parsing.
*/
void SetConfigParsing(char case_filename[MAX_STRING_SIZE]);
/*!
* \brief Config file screen output.
*/
void SetOutput(void);
/*!
* \brief Initializes pointers to null
*/
void SetPointersNull(void);
/*!
* \brief Config file postprocessing.
*/
void SetPostprocessing(void);
/*!
* \brief breaks an input line from the config file into a set of tokens
* \param[in] str - the input line string
* \param[out] option_name - the name of the option found at the beginning of the line
* \param[out] option_value - the tokens found after the "=" sign on the line
* \return false if the line is empty or a commment, true otherwise
*/
bool TokenizeString(std::string & str, std::string & option_name,
std::vector<std::string> & option_value);
/*--- all_options is a map containing all of the options. This is used during config file parsing
to track the options which have not been set (so the default values can be used). Without this map
there would be no list of all the config file options. ---*/
std::map<std::string, bool> all_options;
/*--- brief param is a map from the option name (config file string) to its decoder (the specific child
class of COptionBase that turns the string into a value) ---*/
std::map<std::string, COptionBase*> option_map;
// ---- Option Types ----
// All of the addXxxOptions take in the name of the option, and a refernce to the field of that option
// in the option structure. Depending on the specific type, it may take in a default value, and may
// take in extra options. The addXxxOptions mostly follow the same pattern, so please see addDoubleOption
// for detailed comments.
//
// List options are those that can be an unknown number of elements, and also take in a reference to
// an integer. This integer will be populated with the number of elements of that type unmarshaled.
//
// Array options are those with a fixed number of elements.
//
// List and Array options should also be able to be specified with the string "NONE" indicating that there
// are no elements. This allows the option to be present in a config file but left blank.
/*!< \brief addDoubleOption creates a config file parser for an option with the given name whose
value can be represented by a su2double.*/
// Simple Options
void addBoolOption(const std::string name, bool & option_field, bool default_value);
void addDoubleOption(const std::string name, double & option_field, double default_value);
void addIntegerOption(const std::string name, int & option_field, int default_value);
void addLongOption(const std::string name, long & option_field, long default_value);
void addStringOption(const std::string name, std::string & option_field, std::string default_value);
void addUnsignedLongOption(const std::string name, unsigned long & option_field, unsigned long default_value);
void addUnsignedShortOption(const std::string name, unsigned short & option_field, unsigned short default_value);
// enum types work differently than all of the others because there are a small number of valid
// string entries for the type. One must also provide a list of all the valid strings of that type.
template <class Tenum>
void addEnumOption(const std::string name, Tenum & option_field, const std::map<std::string, Tenum> & enum_map, Tenum default_value);
//List Options
void addStringListOption(const std::string name, unsigned short & num_marker, std::string* & option_field);
public:
/*!
* \brief Constructor of the class which reads the input file.
*/
CConfig(char case_filename[MAX_STRING_SIZE]);
/*!
* \brief Destructor of the class.
*/
~CConfig(void);
// ---- Getters for option values ----
/*!
* \brief Get Value of this option.
* Please keep alphabetical order within each subcategory
*/
// File structure
std::string inline GetMeshFile() const { return _meshFile; }
std::string inline GetOutputDir() const { return _outputDir; }
std::string inline GetOutputFile() const { return _outputFile; }
// Quadrature Structure
QUAD_NAME inline GetQuadName() const {return _quadName;}
unsigned short inline GetQuadOrder() const {return _quadOrder;}
// Solver Structure
double inline GetCFL() const { return _CFL; }
double inline GetTEnd() const { return _tEnd; }
// Boundary Conditions
BOUNDARY_TYPE GetBoundaryType( std::string nameMarker ) const; /*! \brief Get Boundary Type of given marker */
//Output Structure
};
#endif // CONFIG_H
/*!
* \file option_structure.h
* \file GlobalConstants.h
* \brief All global defined (physical) constants, enums etc
* \author <blank>
* \version 0.0
*
*/
#ifndef OPTION_STRUCTURE_H
#define OPTION_STRUCTURE_H
#ifndef GLOBAL_CONSTANTS_H
#define GLOBAL_CONSTANTS_H
#include <map>
#include <cmath>
// Definition for global constants goes here
const double PI_NUMBER = 4.0 * atan(1.0); /*!< \brief Pi number. */
// --- Definition for global constants goes here ---
const double PI_NUMBER = 4.0 * std::atan(1.0); /*!< \brief Pi number. */
const unsigned int MAX_STRING_SIZE = 200; /*!< \brief Maximum size for strings. */
// --- Definition of enums goes here ---
enum BOUNDARY_TYPE{
DIRICHLET,
INVALID
};
// --- Definition of enums for EnumOptions goes here ---
// Definition of enums goes here
/*! \brief Enum for all currently available quadratures in rtsn.
* Option enums are written in capital letters with underscores as spaces (e.g option "time integration" has option enum "TIME_INTEGRATION")
*/
......@@ -38,4 +48,4 @@ inline std::map <std::string,QUAD_NAME> Quadrature_Map {
{ "LDFESA",QUAD_LDFESA }
};
#endif // OPTION_STRUCTURE_H
#endif // GLOBAL_CONSTANTS_H
/*!
* \file OptionStructure.h
* \brief Classes for different Options in rtsn
* \author S. Schotthoefer
*
* Disclaimer: This class structure was copied and modifed with open source permission from SU2 v7.0.3 https://su2code.github.io/
*/
#ifndef OPTION_STRUCTURE_H
#define OPTION_STRUCTURE_H
#include <vector>
#include <string>
#include <map>
#include <sstream>
// Base Class for all kinds of options
class COptionBase {
private:
std::vector<std::string> value;
public:
COptionBase() {};
virtual ~COptionBase() = 0;
virtual std::string SetValue(std::vector<std::string> value){this->value = value; return "";}
std::vector<std::string> GetValue() {return value;}
virtual void SetDefault() = 0;
std::string optionCheckMultipleValues(std::vector<std::string> & option_value, std::string type_id, std::string option_name) {
if (option_value.size() != 1) {
std::string newString;
newString.append(option_name);
newString.append(": multiple values for type ");
newString.append(type_id);
return newString;
}
return "";
}
std::string badValue(std::vector<std::string> & option_value, std::string type_id, std::string option_name) {
std::string newString;
newString.append(option_name);
newString.append(": improper option value for type ");
newString.append(type_id);
return newString;
}
};
inline COptionBase::~COptionBase() {}
template <class Tenum>
class COptionEnum : public COptionBase {
std::map<std::string, Tenum> m;
Tenum & field; // Reference to the feildname
Tenum def; // Default value
std::string name; // identifier for the option
public:
COptionEnum(std::string option_field_name, const std::map<std::string, Tenum> m, Tenum & option_field, Tenum default_value) : field(option_field) {
this->m = m;
this->def = default_value;
this->name = option_field_name;
}
~COptionEnum() override {};
std::string SetValue(std::vector<std::string> option_value) override {
COptionBase::SetValue(option_value);
// Check if there is more than one string
std::string out = optionCheckMultipleValues(option_value, "enum", this->name);
if (out.compare("") != 0) {
return out;
}
// Check to see if the enum value is in the map
if (this->m.find(option_value[0]) == m.end()) {
std::string str;
str.append(this->name);
str.append(": invalid option value ");
str.append(option_value[0]);
str.append(". Check current RTSN options in config_template.cfg.");
return str;
}
// If it is there, set the option value
Tenum val = this->m[option_value[0]];
this->field = val;
return "";
}
void SetDefault() override {
this->field = this->def;
}
};
class COptionDouble : public COptionBase {
double & field; // Reference to the fieldname
double def; // Default value
std::string name; // identifier for the option
public:
COptionDouble(std::string option_field_name, double & option_field, double default_value) : field(option_field) {
this->def = default_value;
this->name = option_field_name;
}
~COptionDouble() override {};
std::string SetValue(std::vector<std::string> option_value) override {
COptionBase::SetValue(option_value);
// check if there is more than one value
std::string out = optionCheckMultipleValues(option_value, "double", this->name);
if (out.compare("") != 0) {
return out;
}
std::istringstream is(option_value[0]);
double val;
if (is >> val) {
this->field = val;
return "";
}
return badValue(option_value, "double", this->name);
}
void SetDefault() override {
this->field = this->def;
}
};
class COptionString : public COptionBase {
std::string & field; // Reference to the fieldname
std::string def; // Default value
std::string name; // identifier for the option
public:
COptionString(std::string option_field_name, std::string & option_field, std::string default_value) : field(option_field) {
this->def = default_value;
this->name = option_field_name;
}
~COptionString() override {};
std::string SetValue(std::vector<std::string> option_value) override {
COptionBase::SetValue(option_value);
// check if there is more than one value
std::string out = optionCheckMultipleValues(option_value, "double", this->name);
if (out.compare("") != 0) {
return out;
}
this->field.assign(option_value[0]);
return "";
}
void SetDefault() override {
this->field = this->def;
}
};
class COptionInt : public COptionBase {
int & field; // Reference to the feildname
int def; // Default value
std::string name; // identifier for the option
public:
COptionInt(std::string option_field_name, int & option_field, int default_value) : field(option_field) {
this->def = default_value;
this->name = option_field_name;
}
~COptionInt() override {};
std::string SetValue(std::vector<std::string> option_value) override {
COptionBase::SetValue(option_value);
std::string out = optionCheckMultipleValues(option_value, "int", this->name);
if (out.compare("") != 0) {
return out;
}
std::istringstream is(option_value[0]);
int val;
if (is >> val) {
this->field = val;
return "";
}
return badValue(option_value, "int", this->name);
}
void SetDefault() override {
this->field = this->def;
}
};
class COptionULong : public COptionBase {
unsigned long & field; // Reference to the feildname
unsigned long def; // Default value
std::string name; // identifier for the option
public:
COptionULong(std::string option_field_name, unsigned long & option_field, unsigned long default_value) : field(option_field) {
this->def = default_value;
this->name = option_field_name;
}
~COptionULong() override {};
std::string SetValue(std::vector<std::string> option_value) override {
COptionBase::SetValue(option_value);
std::string out = optionCheckMultipleValues(option_value, "unsigned long", this->name);
if (out.compare("") != 0) {
return out;
}
std::istringstream is(option_value[0]);
unsigned long val;
if (is >> val) {
this->field = val;
return "";
}
return badValue(option_value, "unsigned long", this->name);
}
void SetDefault() override {
this->field = this->def;
}
};
class COptionUShort : public COptionBase {
unsigned short & field; // Reference to the feildname
unsigned short def; // Default value
std::string name; // identifier for the option
public:
COptionUShort(std::string option_field_name, unsigned short & option_field, unsigned short default_value) : field(option_field) {
this->def = default_value;
this->name = option_field_name;
}
~COptionUShort() override {};
std::string SetValue(std::vector<std::string> option_value) override {
COptionBase::SetValue(option_value);
std::string out = optionCheckMultipleValues(option_value, "unsigned short", this->name);
if (out.compare("") != 0) {
return out;
}
std::istringstream is(option_value[0]);
unsigned short val;
if (is >> val) {
this->field = val;
return "";
}
return badValue(option_value, "unsigned short", this->name);
}
void SetDefault() override {
this->field = this->def;
}
};
class COptionLong : public COptionBase {
long & field; // Reference to the feildname
long def; // Default value
std::string name; // identifier for the option
public: