Alamo
Linear.H
Go to the documentation of this file.
1//
2// This is a general-purpose routine for specifying time-interpolated
3// quantities in an input file.
4// Interpolators obey the following syntax:
5//
6// .. code-block:: bash
7//
8// (t1,t2,..,tn;v1,v2,...,vn)
9//
10// where :code:`tn` are times and :code:`vn` are values at those times.
11//
12// :bdg-danger-line:`Note: do not include whitespace in an interpolator, this will mess with the parser.`
13//
14// Interpolators can usually be used in place of regular numbers, but only
15// when supported by the calling parse function.
16//
17// For instance, the `BC::Operator::Elastic::TensionTest` allows the user to specify
18// fixed displacement; for instance, to specify a value of 0.1:
19//
20// .. code-block:: bash
21//
22// bc.tenstion_test.disp = 0.1
23//
24// However, it may be desirable to change the value over time.
25// In this case, one may specify an interpolator string instead:
26//
27// .. code-block:: bash
28//
29// bc.tenstion_test.disp = (1.0,1.5,2.0;0.0,0.1,0.0)
30//
31// This will cause the displacement value to be zero for :code:`t<1.0`;
32// ramp to :code:`0.1` as :code:`1.0<t<2.0`;
33// ramp back to :code:`0.0` as :code:`2.0<t<3.0`;
34// and then remain at the constant value of :code:`3.0` for :code:`t>3.0`.
35//
36
37#ifndef NUMERIC_INTERPOLATOR_LINEAR_H_
38#define NUMERIC_INTERPOLATOR_LINEAR_H_
39
40#include <AMReX.H>
41#include <AMReX_MultiFab.H>
42#include "Set/Set.H"
43#include "Util/Util.H"
45#include "IO/ParmParse.H"
46
47namespace Numeric
48{
49namespace Interpolator
50{
51template <class T>
52class Linear : public Interpolator<T>
53{
54public:
55 Linear() {};
56 ~Linear() {};
57 Linear(const Set::Scalar &a_val)
58 {
59 interval_points.push_back(0.0);
60 data_points.push_back(a_val);
61 }
62 Linear(const std::string a_str)
63 {
64 define(a_str);
65 }
66 Linear(const std::vector<T> _data_points, const std::vector<Set::Scalar> _interval_points)
67 {
68 define(_data_points,_interval_points);
69 };
70
71 void define(const std::string a_str)
72 {
73 std::string str = a_str;
74
76 {
77 if (!Util::String::Contains(str,"(")) Util::Abort(INFO,"Mismatched parentheses while trying to parse ",str);
78 if (!Util::String::Contains(str,")")) Util::Abort(INFO,"Mismatched parentheses while trying to parse ",str);
79 if (!Util::String::Contains(str,":")) Util::Abort(INFO,"Missing : in interpolator while trying to parse ",str);
80 Util::String::ReplaceAll(str,"(","");
81 Util::String::ReplaceAll(str,")","");
82
83 std::vector<std::string> splitstr = Util::String::Split(str,':');
84 std::string str_time = splitstr[0];
85 std::string str_val = splitstr[1];
86
87 std::vector<std::string> str_time_arr = Util::String::Split(str_time,',');
88 std::vector<std::string> str_val_arr = Util::String::Split(str_val,',');
89
90 if (str_time_arr.size() != str_val_arr.size()) Util::Abort(INFO,"Mismatched number of time values vs array values while trying to parse ", str);
91
92 for (unsigned int i = 0; i < str_time_arr.size(); i++)
93 {
94 interval_points.push_back(std::stod(str_time_arr[i]));
95 if (i > 0) if (interval_points[i] < interval_points[i-1]) Util::Abort(INFO,"Time series must monotonically increase - error while trying to parse ", str);
96 data_points.push_back(std::stod(str_val_arr[i]));
97 }
98 }
99 else
100 {
101 interval_points.push_back(0.0);
102 data_points.push_back(std::stod(a_str));
103 }
104 }
105
106 void define(const std::vector<T> _data_points, const std::vector<Set::Scalar> _interval_points)
107 {
108 data_points = _data_points;
109 interval_points = _interval_points;
110 if(data_points.size() != interval_points.size())
111 Util::Abort(INFO,"Data points and interval points have different sizes");
112 };
113
114 T operator() (const Set::Scalar point) const
115 {
116 // If there is only one point stored, return it.
117 if (data_points.size() == 1) return data_points[0];
118
119 // Do this if point is below interpolation range
120 if(point < interval_points[0])
121 {
122 return data_points[0];
123 }
124
126 int start = 0;
127 if (uniform)
128 {
129 start = (int)( (point - interval_points[0]) / interval);
130 start -= 1;
131 start = std::max(start,0);
132 start = std::min(start,(int)(interval_points.size()-2));
133 }
134
135 // Do this if point is within interpolation range
136 for (unsigned int i = start; i<interval_points.size()-1; i++)
137 {
138 if (interval_points[i] <= point && point <= interval_points[i+1])
139 {
140 return data_points[i] +
141 (point - interval_points[i]) * (data_points[i+1] - data_points[i]) /
143
144 }
145 }
146
147 // Otherwise point must be outside interpolation range, so
148 // return the value for the highest point
149 return data_points[interval_points.size()-1];
150 }
151
152 static void Parse(Linear<T> & value, IO::ParmParse & pp)
153 {
154 std::string in;
155 pp_query("str",in); // Interpolator string used when Parsed from queryclass.
156 value.define(in);
157 }
158
159
160 static Linear<T> Read(std::string filename, int derivative = 0);
161
162protected:
163 std::vector<T> data_points;
164 std::vector<Set::Scalar> interval_points;
165 bool uniform = true;
166
167public:
168 template<class U> friend Linear<U> operator * (const Set::Scalar alpha, const Linear<U> &b);
169};
170
171template<class T>
172AMREX_FORCE_INLINE
174{
175 Linear<T> ret;
176 for (unsigned int i = 0; i < b.data_points.size(); i++)
177 ret.data_points.push_back(alpha * b.data_points[i]);
179 ret.uniform = b.uniform;
180 return ret;
181}
182
183template<>
185Linear<Set::Scalar> Linear<Set::Scalar>::Read(std::string filename, int derivative)
186{
187 std::ifstream input;
188 input.open(filename);
189 std::string line;
190 std::vector<Set::Scalar> theta, w;
191 // parse input
192 while (std::getline(input, line))
193 { std::vector<std::string> dat = Util::String::Split(line);
194 theta.push_back(std::stof(dat[0]));
195 w.push_back(std::stof(dat[1]));
196 }
197 if (derivative == 0)
198 {
199 return Linear<Set::Scalar>(w,theta);
200 }
201 else if (derivative == 1)
202 {
203 std::vector<Set::Scalar> thetasmall, dw;
204 for (unsigned int i = 1; i < theta.size() - 1; i++)
205 {
206 thetasmall.push_back(theta[i]);
207 dw.push_back((w[i + 1] - w[i - 1]) / (theta[i + 1] - theta[i - 1]));
208 }
209 return Linear<Set::Scalar>(dw,thetasmall);
210 }
211 else if (derivative == 2)
212 {
213 std::vector<Set::Scalar> thetasmall, ddw;
214 for (unsigned int i = 1; i < theta.size() - 1; i++)
215 {
216 thetasmall.push_back(theta[i]);
217 ddw.push_back((w[i + 1] - 2.0 * w[i] + w[i - 1]) / ((theta[i + 1] - theta[i]) * (theta[i] - theta[i - 1])));
218 }
219 return Linear<Set::Scalar>(ddw,thetasmall);
220 }
221 else Util::Abort(INFO,"derivative must be 0,1,2 but got ",derivative);
222 exit(-1);
223}
224
225
226}
227}
228
229#endif
#define pp_query(...)
Definition ParmParse.H:106
#define ALAMO_SINGLE_DEFINITION
Definition Util.H:25
#define INFO
Definition Util.H:20
static void Parse(Linear< T > &value, IO::ParmParse &pp)
Definition Linear.H:152
T operator()(const Set::Scalar point) const
Definition Linear.H:114
void define(const std::string a_str)
Definition Linear.H:71
std::vector< T > data_points
Definition Linear.H:163
friend Linear< U > operator*(const Set::Scalar alpha, const Linear< U > &b)
void define(const std::vector< T > _data_points, const std::vector< Set::Scalar > _interval_points)
Definition Linear.H:106
static Linear< T > Read(std::string filename, int derivative=0)
Linear(const std::string a_str)
Definition Linear.H:62
Linear(const std::vector< T > _data_points, const std::vector< Set::Scalar > _interval_points)
Definition Linear.H:66
std::vector< Set::Scalar > interval_points
Definition Linear.H:164
Linear(const Set::Scalar &a_val)
Definition Linear.H:57
AMREX_FORCE_INLINE Linear< T > operator*(const Set::Scalar alpha, const Linear< T > &b)
Definition Linear.H:173
This namespace contains some numerical tools.
Definition Function.H:6
amrex::Real Scalar
Definition Base.H:19
bool Contains(std::string &str, const std::string find)
Definition Util.cpp:306
std::vector< std::string > Split(std::string &str, const char delim)
Definition Util.cpp:296
int ReplaceAll(std::string &str, const std::string before, const std::string after)
Definition Util.cpp:229
void Abort(const char *msg)
Definition Util.cpp:170