runTimeControl.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2015 OpenFOAM Foundation
9  Copyright (C) 2015-2022 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "runTimeControl.H"
30 #include "dictionary.H"
31 #include "runTimeCondition.H"
32 #include "fvMesh.H"
33 #include "Time.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 namespace Foam
39 {
40 namespace functionObjects
41 {
42 namespace runTimeControls
43 {
44  defineTypeNameAndDebug(runTimeControl, 0);
45  addToRunTimeSelectionTable(functionObject, runTimeControl, dictionary);
46 }
47 }
48 }
49 
51 <
53 >
55 {
56  { satisfiedAction::ABORT, "abort"},
57  { satisfiedAction::END, "end"},
58  { satisfiedAction::SET_TRIGGER, "setTrigger"},
59 };
60 
61 
62 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
63 
64 Foam::functionObjects::runTimeControls::runTimeControl::runTimeControl
65 (
66  const word& name,
67  const Time& runTime,
68  const dictionary& dict
69 )
70 :
72  conditions_(),
73  groupMap_(),
74  nWriteStep_(0),
75  writeStepI_(0),
76  satisfiedAction_(satisfiedAction::END),
77  triggerIndex_(labelMin),
78  active_(getProperty("active", true)),
79  canRestart_(getProperty("canRestart", false))
80 {
82 }
83 
84 
85 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
86 
88 (
89  const dictionary& dict
90 )
91 {
93  {
94  Info<< "Deactivated " << name()
95  << " function object for post-processing"
96  << endl;
97 
98  return false;
99  }
100 
101 
103  {
104  Info<< type() << " " << name() << ":" << nl;
105 
106  const dictionary& conditionsDict = dict.subDict("conditions");
107  const wordList conditionNames(conditionsDict.toc());
108  conditions_.setSize(conditionNames.size());
109 
110  label uniqueGroupi = 0;
111  forAll(conditionNames, conditioni)
112  {
113  const word& conditionName = conditionNames[conditioni];
114  const dictionary& dict = conditionsDict.subDict(conditionName);
115 
116  conditions_.set
117  (
118  conditioni,
119  runTimeCondition::New(conditionName, obr_, dict, *this)
120  );
121 
122  label groupi = conditions_[conditioni].groupID();
123 
124  if (groupMap_.insert(groupi, uniqueGroupi))
125  {
126  ++uniqueGroupi;
127  }
128  }
129 
130  dict.readIfPresent("nWriteStep", nWriteStep_);
131 
132  // Check that some conditions are set
133  if (conditions_.empty())
134  {
135  Info<< " No conditions present" << endl;
136  }
137  else
138  {
139  // Check that at least one condition is active
140  bool check = false;
141  for (const auto& condition : conditions_)
142  {
143  if (condition.active())
144  {
145  check = true;
146  break;
147  }
148  }
149 
150  if (!check)
151  {
152  Info<< " All conditions are inactive" << endl;
153  }
154  }
155 
156  Info<< endl;
157 
158  // Set the action to perform when all conditions are satisfied
159  // - set to end for backwards compatibility with v1806
160  satisfiedAction_ =
161  satisfiedActionNames.getOrDefault
162  (
163  "satisfiedAction",
164  dict,
165  satisfiedAction::END
166  );
167 
168  if (satisfiedAction_ == satisfiedAction::SET_TRIGGER)
169  {
170  triggerIndex_ = dict.get<label>("trigger");
171  }
172 
173  return true;
174  }
175 
176  return false;
177 }
178 
179 
181 {
182  if (canRestart_)
183  {
184  active_ = true;
185  canRestart_ = false;
186  }
187 
188  if (!active_)
189  {
190  return true;
191  }
192 
193  Info<< type() << " " << name() << " output:" << nl;
194 
195  // IDs of satisfied conditions
196  DynamicList<label> IDs(conditions_.size());
197 
198  // Run stops only if all conditions within a group are satisfied
199  List<bool> groupSatisfied(groupMap_.size(), true);
200  List<bool> groupActive(groupMap_.size(), false);
201 
202  forAll(conditions_, conditioni)
203  {
204  runTimeCondition& condition = conditions_[conditioni];
205 
206  if (condition.active())
207  {
208  bool conditionSatisfied = condition.apply();
209 
210  const label groupi = condition.groupID();
211 
212  auto conditionIter = groupMap_.cfind(groupi);
213 
214  if (!conditionIter.good())
215  {
217  << "group " << groupi << " not found in map"
218  << abort(FatalError);
219  }
220 
221  if (conditionSatisfied)
222  {
223  IDs.append(conditioni);
224 
225  groupActive[conditionIter()] = true;
226 
227  if (groupi == -1)
228  {
229  // Condition not part of a group - only requires this to be
230  // satisfied for completion flag to be set
231  groupSatisfied[conditionIter()] = true;
232  break;
233  }
234  }
235  else
236  {
237  groupSatisfied[conditionIter()] = false;
238  }
239  }
240  }
241 
242  bool done = false;
243  forAll(groupSatisfied, groupi)
244  {
245  if (groupSatisfied[groupi] && groupActive[groupi])
246  {
247  done = true;
248  break;
249  }
250  }
251 
252  if (done)
253  {
254  for (label conditioni : IDs)
255  {
256  Info<< " " << conditions_[conditioni].type() << ": "
257  << conditions_[conditioni].name()
258  << " condition satisfied" << nl;
259  }
260 
261  switch (satisfiedAction_)
262  {
263  case satisfiedAction::ABORT:
264  case satisfiedAction::END:
265  {
266  // Set to write a data dump or finalise the calculation
267  Time& time = const_cast<Time&>(time_);
268 
269  if (writeStepI_ < nWriteStep_ - 1)
270  {
271  ++writeStepI_;
272  Info<< " Writing fields - step " << writeStepI_ << nl;
273  time.writeNow();
274  }
275  else
276  {
277  Info<< " Stopping calculation" << nl
278  << " Writing fields";
279 
280  if (nWriteStep_ != 0)
281  {
282  Info<< " - final step";
283  }
284 
285  Info<< nl << endl;
286  active_ = false;
287 
288  // Write any registered objects and set the end-time
289  time.writeAndEnd();
290 
291  // Trigger any function objects
292  time.run();
293 
294  if (satisfiedAction_ == satisfiedAction::ABORT)
295  {
297  << "Abort triggered"
298  << exit(FatalError);
299  }
300  }
301  break;
302  }
303  case satisfiedAction::SET_TRIGGER:
304  {
305  Info<< " Setting trigger " << triggerIndex_ << nl;
306 
307  setTrigger(triggerIndex_);
308 
309  // Deactivate the model
310  active_ = false;
311  setProperty("active", active_);
312 
313  // Can be restarted
314  canRestart_ = true;
315  setProperty("canRestart", canRestart_);
316 
317  // Reset all conditions in case the control is recycled/trigger
318  // index is set to a smaller value
319  forAll(conditions_, conditioni)
320  {
321  runTimeCondition& condition = conditions_[conditioni];
322  condition.reset();
323  }
324 
325  break;
326  }
327  }
328  }
329  else
330  {
331  Info<< " Conditions not met" << nl;
332  }
334  Info<< endl;
335 
336  return true;
337 }
338 
339 
341 {
342  for (auto& condition : conditions_)
343  {
344  condition.write();
345  }
346 
347  return true;
348 }
349 
350 
351 // ************************************************************************* //
dictionary dict
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
static bool postProcess
Global post-processing mode switch.
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
engineTime & runTime
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
constexpr label labelMin
Definition: label.H:54
virtual bool write()
Calculate the runTimeControl and write.
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition: dictionary.C:441
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:69
virtual bool read(const dictionary &)
Read the runTimeControl data.
Macros for easy insertion into run-time selection tables.
wordList toc() const
Return the table of contents.
Definition: dictionary.C:587
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:799
void setSize(const label n)
Alias for resize()
Definition: List.H:316
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
A class for handling words, derived from Foam::string.
Definition: word.H:63
errorManip< error > abort(error &err)
Definition: errorManip.H:139
defineTypeNameAndDebug(averageCondition, 0)
static void check(const int retVal, const char *what)
addToRunTimeSelectionTable(runTimeCondition, averageCondition, dictionary)
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: error.H:64
virtual bool execute()
Execute, currently does nothing.
messageStream Info
Information stream (stdout output on master, null elsewhere)
static autoPtr< runTimeCondition > New(const word &conditionName, const objectRegistry &obr, const dictionary &dict, stateFunctionObject &state)
Selector.
virtual bool read(const dictionary &dict)
Read optional controls.
Specialization of Foam::functionObject for an Foam::fvMesh, providing a reference to the Foam::fvMesh...
entry * set(entry *entryPtr)
Assign a new entry, overwriting any existing entry.
Definition: dictionary.C:765
Namespace for OpenFOAM.