timeControl.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "timeControl.H"
27 #include "PstreamReduceOps.H"
28 
29 // * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * //
30 
31 namespace Foam
32 {
33  template<>
34  const char* NamedEnum<timeControl::timeControls, 9>::
35  names[] =
36  {
37  "timeStep",
38  "writeTime",
39  "outputTime",
40  "adjustableRunTime",
41  "runTime",
42  "runTimes",
43  "clockTime",
44  "cpuTime",
45  "none"
46  };
47 }
48 
50  Foam::timeControl::timeControlNames_;
51 
52 
53 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
54 
56 (
57  const Time& t,
58  const dictionary& dict,
59  const word& prefix
60 )
61 :
62  time_(t),
63  prefix_(prefix),
64  timeControl_(timeControls::timeStep),
65  intervalSteps_(0),
66  interval_(-1),
67  timeDelta_(0),
68  executionIndex_(0)
69 {
70  read(dict);
71 }
72 
73 
74 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
75 
77 {}
78 
79 
80 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
81 
83 {
84  word controlName(prefix_ + "Control");
85  word intervalName(prefix_ + "Interval");
86  const word timesName(prefix_ + "Times");
87 
88  // For backward compatibility support the deprecated 'outputControl' option
89  // now superseded by 'writeControl' for compatibility with Time
90  if (prefix_ == "write" && dict.found("outputControl"))
91  {
93  << "Using deprecated 'outputControl'" << nl
94  << " Please use 'writeControl' with 'writeInterval'"
95  << endl;
96 
97  // Change to the old names for this option
98  controlName = "outputControl";
99  intervalName = "outputInterval";
100  }
101 
102  if (dict.found(controlName))
103  {
104  timeControl_ = timeControlNames_.read(dict.lookup(controlName));
105  }
106  else
107  {
108  timeControl_ = timeControls::timeStep;
109  }
110 
111  switch (timeControl_)
112  {
113  case timeControls::timeStep:
114  {
115  intervalSteps_ = dict.lookupOrDefault<label>(intervalName, 0);
116  break;
117  }
118 
119  case timeControls::writeTime:
120  case timeControls::outputTime:
121  {
122  intervalSteps_ = dict.lookupOrDefault<label>(intervalName, 1);
123  break;
124  }
125 
126  case timeControls::clockTime:
127  case timeControls::runTime:
128  case timeControls::cpuTime:
129  case timeControls::adjustableRunTime:
130  {
131  interval_ = time_.userTimeToTime(dict.lookup<scalar>(intervalName));
132 
133  if (timeControl_ == timeControls::adjustableRunTime)
134  {
135  executionIndex_ = label
136  (
137  (
138  (time_.value() - time_.beginTime().value())
139  + 0.5*time_.deltaTValue()
140  )
141  /interval_
142  );
143  }
144 
145  break;
146  }
147 
148  case timeControls::runTimes:
149  {
150  times_ = dict.lookup<scalarList>(timesName);
151  timeDelta_ = dict.lookupOrDefault("timeDelta", 1e-6);
152 
153  forAll(times_, i)
154  {
155  timeIndices_.insert
156  (
157  int64_t((times_[i] + timeDelta_/2.0)/timeDelta_)
158  );
159  }
160 
161  intervalSteps_ = dict.lookupOrDefault<label>(intervalName, 1);
162  break;
163  }
164 
165  default:
166  {
167  break;
168  }
169  }
170 }
171 
172 
174 {
175  switch (timeControl_)
176  {
177  case timeControls::timeStep:
178  {
179  return
180  (
181  (intervalSteps_ <= 1)
182  || !(time_.timeIndex() % intervalSteps_)
183  );
184  break;
185  }
186 
187  case timeControls::writeTime:
188  case timeControls::outputTime:
189  {
190  if (time_.writeTime())
191  {
192  executionIndex_++;
193  return !(executionIndex_ % intervalSteps_);
194  }
195  break;
196  }
197 
198  case timeControls::runTime:
199  case timeControls::adjustableRunTime:
200  {
201  const label executionIndex = label
202  (
203  (
204  (time_.value() - time_.beginTime().value())
205  + 0.5*time_.deltaTValue()
206  )
207  /interval_
208  );
209 
210  if (executionIndex > executionIndex_)
211  {
212  executionIndex_ = executionIndex;
213  return true;
214  }
215  break;
216  }
217 
218  case timeControls::runTimes:
219  {
220  return timeIndices_.found
221  (
222  (time_.userTimeValue() + timeDelta_/2)/timeDelta_
223  );
224 
225  break;
226  }
227 
228  case timeControls::cpuTime:
229  {
230  const label executionIndex = label
231  (
232  returnReduce(time_.elapsedCpuTime(), maxOp<double>())
233  /interval_
234  );
235  if (executionIndex > executionIndex_)
236  {
237  executionIndex_ = executionIndex;
238  return true;
239  }
240  break;
241  }
242 
243  case timeControls::clockTime:
244  {
245  const label executionIndex = label
246  (
247  returnReduce(label(time_.elapsedClockTime()), maxOp<label>())
248  /interval_
249  );
250  if (executionIndex > executionIndex_)
251  {
252  executionIndex_ = executionIndex;
253  return true;
254  }
255  break;
256  }
257 
258  case timeControls::none:
259  {
260  return false;
261  }
262 
263  default:
264  {
266  << "Undefined output control: "
267  << timeControlNames_[timeControl_] << nl
268  << abort(FatalError);
269  break;
270  }
271  }
272 
273  return false;
274 }
275 
276 
278 {
279  switch (timeControl_)
280  {
281  case timeControls::timeStep:
282  case timeControls::writeTime:
283  case timeControls::outputTime:
284  case timeControls::runTime:
285  case timeControls::cpuTime:
286  case timeControls::clockTime:
287  case timeControls::none:
288  {
289  return vGreat;
290  break;
291  }
292 
293  case timeControls::adjustableRunTime:
294  {
295  return
296  max
297  (
298  0.0,
299  (executionIndex_ + 1)*interval_
300  - (time_.value() - time_.beginTime().value())
301  );
302  break;
303  }
304 
305  case timeControls::runTimes:
306  {
307  if (time_.userTimeValue() + timeDelta_ < times_.last())
308  {
309  forAll(times_, i)
310  {
311  if (times_[i] > time_.userTimeValue() + timeDelta_)
312  {
313  return time_.userTimeToTime
314  (
315  times_[i] - time_.userTimeValue()
316  );
317  }
318  }
319  }
320 
321  return vGreat;
322 
323  break;
324  }
325 
326  default:
327  {
329  << "Undefined output control: "
330  << timeControlNames_[timeControl_] << nl
331  << abort(FatalError);
332  break;
333  }
334  }
335 
336  return vGreat;
337 }
338 
339 
340 // ************************************************************************* //
Inter-processor communication reduction functions.
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Initialise the NamedEnum HashTable from the static list of names.
Definition: NamedEnum.H:54
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:160
T lookupOrDefault(const word &, const T &, bool recursive=false, bool patternMatch=true) const
Find and return a T,.
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:860
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:659
timeControls
The time control options.
Definition: timeControl.H:55
void read(const dictionary &)
Read from dictionary.
Definition: timeControl.C:82
~timeControl()
Destructor.
Definition: timeControl.C:76
scalar timeToNextAction()
Return the time to the next write.
Definition: timeControl.C:277
bool execute()
Flag to indicate whether to execute.
Definition: timeControl.C:173
timeControl(const Time &, const dictionary &, const word &prefix)
Construct from Time object and dictionary.
Definition: timeControl.C:56
A class for handling words, derived from string.
Definition: word.H:62
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
Namespace for OpenFOAM.
const doubleScalar e
Definition: doubleScalar.H:105
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
errorManip< error > abort(error &err)
Definition: errorManip.H:131
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
error FatalError
static const char nl
Definition: Ostream.H:260
dictionary dict