cloudSolution.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) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2020-2021 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 "cloudSolution.H"
30 #include "Time.H"
31 #include "localEulerDdtScheme.H"
32 
33 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
34 
36 :
37  mesh_(mesh),
38  dict_(dict),
39  active_(dict.lookup("active")),
40  transient_(false),
41  calcFrequency_(1),
42  logFrequency_(1),
43  maxCo_(0.3),
44  iter_(1),
45  trackTime_(0.0),
46  deltaTMax_(GREAT),
47  coupled_(false),
48  cellValueSourceCorrection_(false),
49  maxTrackTime_(0.0),
50  resetSourcesOnStartup_(true),
51  schemes_()
52 {
53  if (active_)
54  {
55  read();
56  }
57  else
58  {
59  // see if existing source terms should be reset
60  const dictionary sourceTerms(dict_.subOrEmptyDict("sourceTerms"));
61  sourceTerms.readIfPresent("resetOnStartup", resetSourcesOnStartup_);
62 
63  if (resetSourcesOnStartup_)
64  {
65  Info<< "Cloud source terms will be reset" << endl;
66  }
67  else
68  {
69  Info<< "Cloud source terms will be held constant" << endl;
70  }
71 
72  // transient default to false asks for extra massFlowRate
73  // in transient lagrangian
74  transient_ = true;
75  }
76 }
77 
78 
79 Foam::cloudSolution::cloudSolution(const cloudSolution& cs)
80 :
81  mesh_(cs.mesh_),
82  dict_(cs.dict_),
83  active_(cs.active_),
84  transient_(cs.transient_),
85  calcFrequency_(cs.calcFrequency_),
86  logFrequency_(cs.logFrequency_),
87  maxCo_(cs.maxCo_),
88  iter_(cs.iter_),
89  trackTime_(cs.trackTime_),
90  deltaTMax_(cs.deltaTMax_),
91  coupled_(cs.coupled_),
92  cellValueSourceCorrection_(cs.cellValueSourceCorrection_),
93  maxTrackTime_(cs.maxTrackTime_),
94  resetSourcesOnStartup_(cs.resetSourcesOnStartup_),
95  schemes_(cs.schemes_)
96 {}
97 
98 
100 :
101  mesh_(mesh),
102  dict_(),
103  active_(false),
104  transient_(false),
105  calcFrequency_(0),
106  logFrequency_(0),
107  maxCo_(GREAT),
108  iter_(0),
109  trackTime_(0.0),
110  deltaTMax_(GREAT),
111  coupled_(false),
112  cellValueSourceCorrection_(false),
113  maxTrackTime_(0.0),
114  resetSourcesOnStartup_(false),
115  schemes_()
116 {}
117 
118 
119 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
122 {}
123 
124 
125 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
126 
128 {
129  // For transient runs the Lagrangian tracking may be transient or steady
130  transient_ = dict_.getOrDefault("transient", false);
131 
132  // For LTS and steady-state runs the Lagrangian tracking cannot be transient
133  if (transient_)
134  {
135  if (fv::localEulerDdt::enabled(mesh_))
136  {
137  IOWarningInFunction(dict_)
138  << "Transient tracking is not supported for LTS"
139  " simulations, switching to steady state tracking."
140  << endl;
141  transient_ = false;
142  }
143 
144  if (mesh_.steady())
145  {
146  IOWarningInFunction(dict_)
147  << "Transient tracking is not supported for steady-state"
148  " simulations, switching to steady state tracking."
149  << endl;
150  transient_ = false;
151  }
152  }
153 
154  dict_.readEntry("coupled", coupled_);
155  dict_.readEntry("cellValueSourceCorrection", cellValueSourceCorrection_);
156  dict_.readIfPresent("maxCo", maxCo_);
157  dict_.readIfPresent("deltaTMax", deltaTMax_);
158 
159  dict_.readIfPresent("logFrequency", logFrequency_);
160 
161  if (steadyState())
162  {
163  dict_.readEntry("calcFrequency", calcFrequency_);
164  dict_.readEntry("maxTrackTime", maxTrackTime_);
165 
166  if (coupled_)
167  {
168  dict_.subDict("sourceTerms").lookup("resetOnStartup")
169  >> resetSourcesOnStartup_;
170  }
171  }
172 
173  if (coupled_)
174  {
175  const dictionary&
176  schemesDict(dict_.subDict("sourceTerms").subDict("schemes"));
177 
178  wordList vars(schemesDict.toc());
179  schemes_.setSize(vars.size());
180  forAll(vars, i)
181  {
182  // read solution variable name
183  schemes_[i].first() = vars[i];
184 
185  // set semi-implicit (1) explicit (0) flag
186  ITstream& is = schemesDict.lookup(vars[i]);
187  const word scheme(is);
188  if (scheme == "semiImplicit")
189  {
190  schemes_[i].second().first() = true;
191  }
192  else if (scheme == "explicit")
193  {
194  schemes_[i].second().first() = false;
195  }
196  else
197  {
199  << "Invalid scheme " << scheme << ". Valid schemes are "
200  << "explicit and semiImplicit" << exit(FatalError);
201  }
202 
203  // read under-relaxation factor
204  is >> schemes_[i].second().second();
205  }
206  }
207 }
208 
209 
210 Foam::scalar Foam::cloudSolution::relaxCoeff(const word& fieldName) const
211 {
212  forAll(schemes_, i)
213  {
214  if (fieldName == schemes_[i].first())
215  {
216  return schemes_[i].second().second();
217  }
218  }
219 
221  << "Field name " << fieldName << " not found in schemes"
222  << abort(FatalError);
223 
224  return 1.0;
225 }
226 
227 
228 bool Foam::cloudSolution::semiImplicit(const word& fieldName) const
229 {
230  forAll(schemes_, i)
231  {
232  if (fieldName == schemes_[i].first())
233  {
234  return schemes_[i].second().first();
235  }
236  }
237 
239  << "Field name " << fieldName << " not found in schemes"
240  << abort(FatalError);
241 
242  return false;
243 }
244 
245 
247 {
248  return
249  active_
250  && (
251  mesh_.time().writeTime()
252  || (mesh_.time().timeIndex() % calcFrequency_ == 0)
253  );
254 }
255 
256 
258 {
259  if (transient_)
260  {
261  trackTime_ = mesh_.time().deltaTValue();
262  }
263  else
264  {
265  trackTime_ = maxTrackTime_;
266  }
267 
268  return solveThisStep();
269 }
270 
271 
272 bool Foam::cloudSolution::log() const
273 {
274  return
275  active_
276  && (logFrequency_ > 0)
277  && (mesh_.time().timeIndex() % logFrequency_ == 0);
278 }
279 
281 bool Foam::cloudSolution::output() const
282 {
283  return active_ && mesh_.time().writeTime();
284 }
285 
286 
287 Foam::scalar Foam::cloudSolution::deltaTMax(const scalar trackTime) const
288 {
289  if (transient_)
290  {
291  return min(deltaTMax_, maxCo_*trackTime);
292  }
293  else
294  {
295  return min(deltaTMax_, trackTime);
296  }
297 }
298 
299 
300 Foam::scalar Foam::cloudSolution::deltaLMax(const scalar lRef) const
301 {
302  return maxCo_*lRef;
303 }
304 
305 
306 // ************************************************************************* //
virtual ~cloudSolution()
Destructor.
dictionary dict
cloudSolution(const fvMesh &mesh)
Construct null from mesh reference.
Definition: cloudSolution.C:92
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:120
scalar relaxCoeff(const word &fieldName) const
Return relaxation coefficient for field.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:578
static tmp< edgeInterpolationScheme< Type > > scheme(const edgeScalarField &faceFlux, Istream &schemeData)
Return weighting factors for scheme given from Istream.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
scalar deltaLMax(const scalar lRef) const
Return the maximum integration length.
Lookup type of boundary radiation properties.
Definition: lookup.H:57
bool log() const
Returns true if possible to log this step.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:414
bool semiImplicit(const word &fieldName) const
Return semi-implicit flag coefficient for field.
void setSize(const label n)
Alias for resize()
Definition: List.H:289
dynamicFvMesh & mesh
static bool enabled(const fvMesh &mesh)
Return true if LTS is enabled.
Definition: localEulerDdt.C:32
A class for handling words, derived from Foam::string.
Definition: word.H:63
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
errorManip< error > abort(error &err)
Definition: errorManip.H:139
bool solveThisStep() const
Returns true if performing a cloud iteration this calc step.
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry if present, and assign to T val. FatalIOError if it is found and the number of tokens i...
dictionary subOrEmptyDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX, const bool mandatory=false) const
Find and return a sub-dictionary as a copy, otherwise return an empty dictionary. ...
Definition: dictionary.C:533
scalar deltaTMax() const
Return the maximum integration time step.
List< word > wordList
List of word.
Definition: fileName.H:58
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:79
messageStream Info
Information stream (stdout output on master, null elsewhere)
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
void read()
Read properties from dictionary.
bool output() const
Returns true if writing this step.
bool canEvolve()
Returns true if possible to evolve the cloud and sets timestep parameters.