OOFEM 3.0
Loading...
Searching...
No Matches
stepfunction.C
Go to the documentation of this file.
1/*
2 *
3 * ##### ##### ###### ###### ### ###
4 * ## ## ## ## ## ## ## ### ##
5 * ## ## ## ## #### #### ## # ##
6 * ## ## ## ## ## ## ## ##
7 * ## ## ## ## ## ## ## ##
8 * ##### ##### ## ###### ## ##
9 *
10 *
11 * OOFEM : Object Oriented Finite Element Code
12 *
13 * Copyright (C) 1993 - 2025 Borek Patzak
14 *
15 *
16 *
17 * Czech Technical University, Faculty of Civil Engineering,
18 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 */
34
35#include "stepfunction.h"
36#include "mathfem.h"
37#include "classfactory.h"
38#include "dynamicinputrecord.h"
39
40#include <fstream>
41#include <sstream>
42
43namespace oofem {
44#define StepFunction_PRECISION 1.e-12
45
47
48StepFunction :: StepFunction(int i, Domain *d) : Function(i, d), datevalues()
49{ }
50
51double StepFunction :: evaluateAtTime(double time)
52/* The function is defined as:
53 * @f[
54 * f(t) = \begin{cases}
55 * v_1, & t < t_2 \\
56 * v_i, & t_i \leq t < t_{i+1}, i= 2, \ldots, n-1 \\
57 * v_n, & t \geq t_n
58 * \end{cases}
59 * @f]
60 * where @f$ (t_i, v_i), i=1,\ldots,n @f$ are the points stored in 'dates' and 'values'.
61 */
62{
63 int size = (int) this->datevalues.size();
64 if ( size == 0 ) {
65 OOFEM_ERROR("Undefined dates and values");
66 } else if ( size == 1) {
67 return std::get<1>(this->datevalues.at(0));
68 }
69 // fast track
70 if (time < std::get<0>(this->datevalues.at(1))) {
71 return std::get<1>(this->datevalues.at(0));
72 } else if (time > std::get<0>(this->datevalues.at(size-1))) {
73 return std::get<1>(this->datevalues.at(size-1));
74 }
75
76 // search
77 auto it = std::upper_bound(
78 datevalues.begin(), datevalues.end(), std::make_tuple(time, 0.0),
79 [](const std::tuple<double, double>& a, const std::tuple<double, double>& b) {
80 return std::get<0>(a) < std::get<0>(b);
81 }
82 );
83
84 if (it != datevalues.end()) {
85 return std::get<1>(*(it - 1));
86 } else {
87 return std::get<1>(this->datevalues.at(size-1));
88 }
89
90 /*
91 const double precision = StepFunction_PRECISION;
92 int size = (int) this->dates.size();
93
94 if ( size == 0 ) {
95 OOFEM_ERROR("Undefined dates and values");
96 } else if ( size == 1) {
97 return this->values.at(1);
98 } else {
99 for ( int i = 2; i <= size; i++ ) {
100 double date = this->dates.at(i);
101 if ( fabs(date - time) < precision ) {
102 return this->values.at(i);
103 } else if ( date > time ) {
104 return this->values.at(i - 1);
105 }
106 }
107 return this->values.at(size);
108 }
109 */
110}
111
112double StepFunction :: evaluateVelocityAtTime(double time)
113// Returns the derivative of the receiver at time 'time'. 'time' should be
114// one of the dates of the receiver (currently there is no interpola-
115// tion between two points).
116{
117 return 0.;
118}
119
120void
121StepFunction :: initializeFrom(InputRecord &ir)
122{
123 Function :: initializeFrom(ir);
124
125 // Optional means, read data from external file (useful for very large sets of data)
127 datevalues.clear();
128 // Open the file;
129 std :: string fname;
131 if (fname != ""){ //allows empty filename when the function will not be used intentionally
132 std :: ifstream file(fname.c_str(), std :: ios :: in);
133 if ( !file.is_open() ) {
134 OOFEM_ERROR("Failed to open data file: %s\n", fname.c_str());
135 }
136 // Data should be stored in two columns (or just interleaved)
137 double temp_t, temp_ft;
138 std :: string sLine = "";
139 while ( !file.eof() ) {
140 getline(file, sLine);
141 if ( sLine [ 0 ] == '#' ) {
142 continue;
143 }
144 std :: stringstream ss1(sLine);
145 ss1 >> temp_t >> temp_ft;
146 datevalues.push_back(std::tuple<double, double>(temp_t, temp_ft));
147 }
148 file.close();
149 }
150 } else {
151 int numberOfPoints;
152 IR_GIVE_OPTIONAL_FIELD(ir, numberOfPoints, "npoints");
153 FloatArray dates, values;
156 if ( dates.size() != values.size() ) {
157 OOFEM_ERROR ("Size of t and f(t) arrays must be equal");
158 }
159 // copy data to internal structure
160 datevalues.clear();
161 for ( int i = 0; i < dates.size(); i++ ) {
162 datevalues.push_back(std::tuple<double, double>(dates(i), values(i)));
163 }
164 }
165}
166
167
168void StepFunction :: giveInputRecord(DynamicInputRecord &input)
169{
170 Function :: giveInputRecord(input);
171
172 int numberOfPoints = (int) this->datevalues.size();
173 input.setField(numberOfPoints, "npoints");
174 FloatArray dates(numberOfPoints), values(numberOfPoints);
175 for ( int i = 0; i < numberOfPoints; i++ ) {
176 dates(i) = std::get<0>(this->datevalues.at(i));
177 values(i) = std::get<1>(this->datevalues.at(i));
178 }
179 input.setField(dates, _IFT_StepFunction_t);
180 input.setField(values, _IFT_StepFunction_ft);
181}
182
183
184
185void
186StepFunction :: saveContext(DataStream &stream, ContextMode mode)
187{
188 if ( mode & CM_Definition ) {
189 int numberOfPoints = (int) this->datevalues.size();
190 FloatArray dates(numberOfPoints), values(numberOfPoints);
191 for ( int i = 0; i < numberOfPoints; i++ ) {
192 dates(i) = std::get<0>(this->datevalues.at(i));
193 values(i) = std::get<1>(this->datevalues.at(i));
194 }
195 dates.storeYourself(stream);
196 values.storeYourself(stream);
197 }
198}
199
200
201void
202StepFunction :: restoreContext(DataStream &stream, ContextMode mode)
203{
204 if ( mode & CM_Definition ) {
205 FloatArray dates, values;
206 dates.restoreYourself(stream);
207 values.restoreYourself(stream);
208 if ( dates.size() != values.size() ) {
209 OOFEM_ERROR ("Size of t and f(t) arrays must be equal");
210 }
211 // copy data to internal structure
212 datevalues.clear();
213 for ( int i = 0; i < dates.size(); i++ ) {
214 datevalues.push_back(std::tuple<double, double>(dates(i), values(i)));
215 }
216 }
217}
218} // end namespace oofem
#define REGISTER_Function(class)
void setField(int item, InputFieldType id)
Index size() const
Definition floatarray.h:162
contextIOResultType storeYourself(DataStream &stream) const
Definition floatarray.C:894
contextIOResultType restoreYourself(DataStream &stream)
Definition floatarray.C:917
Function(int n, Domain *d)
Definition function.C:44
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
std::vector< std::tuple< double, double > > datevalues
#define CM_Definition
Definition contextmode.h:47
#define OOFEM_ERROR(...)
Definition error.h:79
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
long ContextMode
Definition contextmode.h:43
#define _IFT_StepFunction_ft
#define _IFT_StepFunction_dataFile
#define _IFT_StepFunction_t

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011