-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathinput.hpp
More file actions
173 lines (149 loc) · 6.79 KB
/
input.hpp
File metadata and controls
173 lines (149 loc) · 6.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// ***********************************************************************************
// Idefix MHD astrophysical code
// Copyright(C) Geoffroy R. J. Lesur <geoffroy.lesur@univ-grenoble-alpes.fr>
// and other code contributors
// Licensed under CeCILL 2.1 License, see COPYING for more information
// ***********************************************************************************
#ifndef INPUT_HPP_
#define INPUT_HPP_
#include <string>
#include <map>
#include <vector>
#include <algorithm>
#include "idefix.hpp"
using IdefixParamContainer = std::vector<std::string>;
using IdefixBlockContainer = std::map<std::string,IdefixParamContainer>;
using IdefixInputContainer = std::map<std::string,IdefixBlockContainer>;
class Input {
public:
// Constructor from a file
Input (int, char ** );
void ShowConfig();
// Accessor to input parameters
// the parameters are always: BlockName, EntryName, ParameterNumber (starting from 0)
// These specialised functions are deprecated. Use the template Get<T> function.
std::string GetString(std::string, std::string, int); ///< Read a string from the input file
real GetReal(std::string, std::string, int); ///< Read a real number from the input file
int GetInt(std::string, std::string, int); ///< Read an integer from the input file
int CheckEntry(std::string, std::string); ///< Check that a block+entry is present
///< in the input file
template<typename T>
T Get(std::string, std::string, int); ///< read a variable from the input file
///< (abort if not found)
template<typename T>
T GetOrSet(std::string, std::string, int, T); ///< read a variable from the input file
///< (set it to T if not found)
bool CheckBlock(std::string); ///< check that whether a block is defined
///< in the input file
bool CheckForAbort(); // have we been asked for an abort?
void CheckForStopFile(); // have we been asked for an abort from
// a stop file?
Input();
void PrintLogo();
void PrintOptions();
void PrintVersion();
bool restartRequested{false}; //< Should we restart?
int restartFileNumber; //< if yes, from which file?
bool forceInitRequested{false}; // call DataBlock::InitFlow even on restarts ?
static bool abortRequested; //< Did we receive an abort signal (USR2) from the system?
int maxCycles{-1}; //< whether we should perform a maximum number of cycles
bool forceNoWrite{false}; //< explicitely disable all writes to disk
private:
std::string inputFileName;
IdefixInputContainer inputParameters;
void ParseCommandLine(int , char **argv);
static void signalHandler(int);
Kokkos::Timer timer;
double lastStopFileCheck;
};
// Template functions
template<typename T>
T Input::Get(std::string blockName, std::string paramName, int num) {
if(CheckEntry(blockName, paramName) <= num) {
std::stringstream msg;
msg << "Mandatory parameter [" << blockName << "]:" << paramName << "(" << num
<< "). Cannot be found in the input file" << std::endl;
IDEFIX_ERROR(msg);
}
// Fetch it
std::string paramString = inputParameters[blockName][paramName][num];
T value;
try {
if constexpr(std::is_same<T, int>::value) {
double dv = std::stod(paramString, NULL);
value = static_cast<int>(std::round(dv));
if (std::abs((dv - value)/dv) > 1e-14) {
IDEFIX_WARNING("Detected a truncation error while reading an integer");
}
} else if constexpr(std::is_same<T, double>::value) {
value = std::stod(paramString, NULL);
} else if constexpr(std::is_same<T, float>::value) {
value = std::stof(paramString, NULL);
} else if constexpr(std::is_same<T, int64_t>::value) {
value = static_cast<int64_t>(std::round(std::stod(paramString, NULL)));
} else if constexpr(std::is_same<T, std::string>::value) {
value = paramString;
} else if constexpr(std::is_same<T, bool>::value) {
// convert string to lower case
std::for_each(paramString.begin(), paramString.end(), [](char & c){
c = ::tolower(c);
});
if(paramString.compare("yes") == 0) {
value = true;
} else if(paramString.compare("true") == 0) {
value = true;
} else if(paramString.compare("debout") == 0) {
value = true;
} else if(paramString.compare("no") == 0) {
value = false;
} else if(paramString.compare("false") == 0) {
value = false;
} else if(paramString.compare("couche") == 0) {
value = false;
} else {
std::stringstream msg;
msg << "Boolean parameter [" << blockName << "]:" << paramName << "(" << num
<< ") cannot be interpreted as boolean in the input file." << std::endl
<< std::endl << "I read \"" << paramString << "\"" << std::endl
<< "Use \"yes\" or \"true\" for boolean true ;"
<< " use \"no\" or \"false\" for boolean false.";
IDEFIX_ERROR(msg);
}
} else {
IDEFIX_ERROR("Unknown type has been requested from the input file");
}
} catch(const std::exception& e) {
std::stringstream errmsg;
errmsg << e.what() << std::endl
<< "Input::Get: Error while reading [" << blockName << "]:" << paramName << "(" << num
<< ")." << std::endl
<< "\"" << paramString << "\" cannot be interpreted as required." << std::endl;
IDEFIX_ERROR(errmsg);
}
return(value);
}
template<typename T>
T Input::GetOrSet(std::string blockName, std::string paramName, int num, T def) {
int entrySize = CheckEntry(blockName, paramName);
if(entrySize <= num ) {
// the requested entry has not been set, add it (if we can), otherwise throw an error
if(entrySize < 0 && num>0) {
std::stringstream msg;
msg << "Entry [" << blockName << "]:" << paramName << "is not defined." << std::endl
<< "Only the first (index 0) parameter can be set by default." << std::endl;
IDEFIX_ERROR(msg);
}
if(entrySize+1 < num) {
std::stringstream msg;
msg << "Entry [" << blockName << "]:" << paramName << "has " << entrySize << " parameters."
<< std::endl << ". Only the " << entrySize << "th (index " << entrySize-1
<< ") parameter can be set by default." << std::endl;
IDEFIX_ERROR(msg);
}
std::stringstream strm;
strm << std::boolalpha << def;
inputParameters[blockName][paramName].push_back(strm.str());
}
return(Get<T>(blockName, paramName, num));
}
#endif // INPUT_HPP_