LagrangianModels.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) 2025-2026 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 "LagrangianModels.H"
27 #include "LagrangianMesh.H"
28 
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 
31 namespace Foam
32 {
34 }
35 
36 
37 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
38 
39 Foam::IOobject Foam::LagrangianModels::io(const LagrangianMesh& mesh) const
40 {
41  typeIOobject<IOdictionary> result
42  (
43  typeName,
44  mesh.time().constant(),
45  mesh,
48  );
49 
50  if (!result.headerOk())
51  {
52  result.readOpt() = IOobject::NO_READ;
53  }
54  else
55  {
56  Info<< indentOrNl << "Constructing " << typeName << " from "
57  << result.relativeObjectPath() << endl;
58  }
59 
60  return result;
61 }
62 
63 
64 void Foam::LagrangianModels::checkApplied() const
65 {
66  const label timeIndex =
67  mesh().time().subCycling()
69  : mesh().time().timeIndex();
70 
71  if (timeIndex > checkTimeIndex_)
72  {
73  const PtrListDictionary<LagrangianModel>& modelList(*this);
74 
75  forAll(modelList, i)
76  {
77  const LagrangianModel& model = modelList[i];
78 
79  wordHashSet notAddSupFields(model.addSupFields());
80  notAddSupFields -= addSupFields_[i];
81 
82  forAllConstIter(wordHashSet, notAddSupFields, iter)
83  {
85  << "Model " << model.name()
86  << " defined for field " << iter.key()
87  << " but never used" << endl;
88  }
89  }
90 
91  checkTimeIndex_ = timeIndex;
92  }
93 }
94 
95 
96 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
97 
99 :
101  <
106  >
107  (
108  io(mesh),
109  mesh
110  ),
112  checkTimeIndex_(mesh.time().timeIndex() + 1),
113  addSupFields_()
114 {
115  const dictionary& dict(*this);
116 
117  // Iterate through the dictionary to determine the number of models
118  label i = 0;
120  {
121  i += iter().isDict();
122  }
123 
124  // Size the storage
126  addSupFields_.setSize(i);
127 
128  printDictionary print(*this);
129 
130  // Iterate through the dictionary to construct the models
131  i = 0;
133  {
134  if (!iter().isDict()) continue;
135 
136  const word& name = iter().keyword();
137  const dictionary& modelDict = iter().dict();
138 
140  (
141  i,
142  name,
143  LagrangianModel::New(name, mesh, modelDict).ptr()
144  );
145 
146  addSupFields_.set(i, new wordHashSet());
147 
148  i ++;
149  }
150 
151  // Do post-construction
152  {
153  PtrListDictionary<LagrangianModel>& modelList(*this);
154 
155  forAll(modelList, i)
156  {
157  modelList[i].postConstruct();
158  }
159  }
160 }
161 
162 
163 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
164 
166 {}
167 
168 
169 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
170 
171 bool Foam::LagrangianModels::addsSupToField(const word& fieldName) const
172 {
173  return addsSupToField(fieldName, fieldName);
174 }
175 
176 
178 (
179  const word& fieldName,
180  const word& eqnFieldName
181 ) const
182 {
183  const PtrListDictionary<LagrangianModel>& modelList(*this);
184 
185  forAll(modelList, i)
186  {
187  const LagrangianModel& model = modelList[i];
188 
189  if (model.addsSupToField(fieldName, eqnFieldName))
190  {
191  return true;
192  }
193  }
194 
195  return false;
196 }
197 
198 
200 {
201  PtrListDictionary<LagrangianModel>& modelList(*this);
202 
203  forAll(modelList, i)
204  {
205  modelList[i].correct();
206  }
207 }
208 
209 
211 (
213 ) const
214 {
215  const PtrListDictionary<LagrangianModel>& modelList(*this);
216 
217  // Get the models to produce a list of which elements are to be modified
218  // and which are to be removed
220  forAll(modelList, i)
221  {
222  modelList[i].preModify(mesh, elementModifications);
223  }
224 
225  // Partition the mesh into modified and removed blocks of elements (and
226  // unmodified elements, at the start)
227  const labelList offsets = mesh.partition(2, elementModifications);
228 
229  // Return the sub-mesh associated with the modified block
230  return
232  (
233  mesh,
235  offsets[1] - offsets[0],
236  offsets[0]
237  );
238 
239  // Note: We don't remove the removed elements here. The outer code might
240  // need to do something with them (e.g., remove them from averages, or
241  // transfer their mass to the carrier) before they get deleted. They will
242  // actually get removed in LagrangianModels::modify.
243 }
244 
245 
247 (
249  const LagrangianSubMesh& modifiedMesh
250 ) const
251 {
252  const PtrListDictionary<LagrangianModel>& modelList(*this);
253 
254  // Remove the removed block from the mesh
255  mesh.remove(mesh.size() - modifiedMesh.end());
256 
257  // Get the models to modify and create elements
258  LagrangianSubMesh modifiedAndCreatedMesh(mesh.subNone());
259  modifiedAndCreatedMesh += modifiedMesh;
260  forAll(modelList, i)
261  {
262  modifiedAndCreatedMesh += modelList[i].modify(mesh, modifiedMesh);
263  }
264 
265  // Return a sub-mesh identifying all modified and created elements
266  return modifiedAndCreatedMesh;
267 }
268 
269 
271 (
272  const LagrangianSubScalarField& deltaT,
273  const bool final
274 )
275 {
276  PtrListDictionary<LagrangianModel>& modelList(*this);
277 
278  forAll(modelList, i)
279  {
280  modelList[i].calculate(deltaT, final);
281  }
282 }
283 
284 
286 (
287  const LagrangianSubScalarField& deltaT,
288  const bool final
289 )
290 {
291  PtrListDictionary<LagrangianModel>& modelList(*this);
292 
293  forAll(modelList, i)
294  {
295  modelList[i].preAddSup(deltaT, final);
296  }
297 }
298 
299 
302 {
303  checkApplied();
304 
306  (
308  (
309  deltaT.mesh()
310  )
311  );
312  LagrangianEqn<scalar>& eqn = tEqn.ref();
313 
314  const PtrListDictionary<LagrangianModel>& modelList(*this);
315 
316  forAll(modelList, i)
317  {
318  const LagrangianModel& model = modelList[i];
319 
321  {
322  addSupFields_[i].insert(word::null);
323 
324  model.addSup(deltaT, eqn);
325  }
326  }
327 
328  return tEqn;
329 }
330 
331 
333 (
334  const LagrangianSubScalarField& deltaT,
335  const bool final
336 )
337 {
338  PtrListDictionary<LagrangianModel>& modelList(*this);
339 
340  forAll(modelList, i)
341  {
342  modelList[i].postAddSup(deltaT, final);
343  }
344 }
345 
346 
348 {
349  return true;
350 }
351 
352 
354 {
355  PtrListDictionary<LagrangianModel>& modelList(*this);
356 
357  forAll(modelList, i)
358  {
359  modelList[i].topoChange(map);
360  }
361 }
362 
363 
365 {
366  PtrListDictionary<LagrangianModel>& modelList(*this);
367 
368  forAll(modelList, i)
369  {
370  modelList[i].mapMesh(map);
371  }
372 }
373 
374 
376 {
377  PtrListDictionary<LagrangianModel>& modelList(*this);
378 
379  forAll(modelList, i)
380  {
381  modelList[i].distribute(map);
382  }
383 }
384 
385 
387 {
388  if (regIOobject::read())
389  {
390  checkTimeIndex_ = mesh().time().timeIndex() + 1;
391 
392  bool allOk = true;
393 
394  PtrListDictionary<LagrangianModel>& modelList(*this);
395 
396  forAll(modelList, i)
397  {
398  const dictionary& modelDict = subDict(modelList[i].name());
399 
400  const bool ok =
401  modelList[i].read
402  (
403  modelDict.optionalTypeDict(modelList[i].type())
404  );
405  allOk = allOk && ok;
406  }
407 
408  return allOk;
409  }
410  else
411  {
412  return false;
413  }
414 }
415 
416 
418 (
422  const bool write
423 ) const
424 {
425  bool allOk = true;
426 
427  const PtrListDictionary<LagrangianModel>& modelList(*this);
428 
429  forAll(modelList, i)
430  {
431  const bool ok = modelList[i].write(write);
432  allOk = allOk && ok;
433 
434  const bool okState = modelList[i].writeState(write);
435  allOk = allOk && okState;
436  }
437 
438  return allOk;
439 }
440 
441 
442 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:492
Templated abstract base-class for demand-driven mesh objects used to automate their allocation to the...
void insert(const word &, T *)
Add at head of dictionary.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
const GeoMesh & mesh() const
Return mesh.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:78
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:57
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
Version number type.
Definition: IOstream.H:97
streamFormat
Enumeration for the format of data in the stream.
Definition: IOstream.H:87
compressionType
Enumeration for the format of data in the stream.
Definition: IOstream.H:194
This class stores the coefficients of a Lagrangian equation, and facilitates solving that equation an...
Definition: LagrangianEqn.H:56
Class containing Lagrangian geometry and topology.
const Time & time() const
Return time.
Base class for Lagrangian models.
virtual void addSup(const LagrangianSubScalarField &deltaT, LagrangianEqn< scalar > &eqn) const
Add a fractional source term.
virtual bool addsSupToField(const word &fieldName, const word &eqnFieldName) const =0
Return true if the LagrangianModel adds a source term to the.
static autoPtr< LagrangianModel > New(const word &name, const LagrangianMesh &mesh, const dictionary &modelDict)
Selector.
List of Lagrangian models, constructed as a (Lagrangian) mesh object. Provides similar functions to t...
virtual bool movePoints()
Update for mesh motion. Only for mesh object. Does nothing.
virtual bool writeObject(IOstream::streamFormat fmt, IOstream::versionNumber ver, IOstream::compressionType cmp, const bool write) const
Write the LagrangianModels.
void correct()
Correct the LagrangianModels.
tmp< LagrangianEqn< scalar > > source(const LagrangianSubScalarField &deltaT) const
Return the fractional source.
virtual void postSource(const LagrangianSubScalarField &deltaT, const bool final)
Hook after source evaluation.
virtual ~LagrangianModels()
Destructor.
virtual void topoChange(const polyTopoChangeMap &)
Update topology using the given map.
virtual void distribute(const polyDistributionMap &)
Redistribute or update using the given distribution map.
virtual void preSource(const LagrangianSubScalarField &deltaT, const bool final)
Hook before source evaluation.
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
LagrangianSubMesh preModify(LagrangianMesh &mesh) const
Identify elements in the Lagrangian mesh which are to be.
LagrangianSubMesh modify(LagrangianMesh &mesh, const LagrangianSubMesh &modifiedMesh) const
Instantaneously modify and/or create and remove elements in the.
bool addsSupToField(const word &fieldName) const
Return true if the LagrangianModels adds a source term to the.
void calculate(const LagrangianSubScalarField &deltaT, const bool final)
Solve equations and/or update continually changing properties.
LagrangianModels(const LagrangianMesh &mesh)
Construct for a mesh.
virtual bool read()
Read the LagrangianModels dictionary if it has changed.
Mesh that relates to a sub-section of a Lagrangian mesh. This is used to construct fields that relate...
label end() const
Return end.
Template dictionary class which manages the storage associated with it.
autoPtr< T > set(const label, const word &key, T *)
Set element to pointer provided and return old element.
void setSize(const label)
Reset size of PtrList. If extending the PtrList, new entries are.
Definition: PtrList.C:131
static const word & constant()
Return constant name.
Definition: TimePaths.H:122
label timeIndex() const
Return current time index.
Definition: TimeStateI.H:28
const TimeState & prevTimeState() const
Return previous TimeState if time is being sub-cycled.
Definition: Time.H:449
bool subCycling() const
Return true if time currently being sub-cycled, otherwise false.
Definition: Time.H:443
const fileName & name() const
Return the dictionary name.
Definition: dictionary.H:111
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
bool isDict(const word &) const
Check if entry is a sub-dictionary.
Definition: dictionary.C:732
const dictionary & optionalTypeDict(const word &typeName) const
Find and return an optional type sub-dictionary.
Definition: dictionary.C:921
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:433
label size() const
Return fvMesh size.
Definition: fvMesh.H:468
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
Class containing mesh-to-mesh mapping information.
Definition: polyMeshMap.H:51
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Enables the printing of a dictionary and subsequently looked-up defaulted entries.
virtual bool read()
Read object.
A class for managing temporary objects.
Definition: tmp.H:55
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:197
Template function which returns the un-mangled name of a given type. Useful for types which do not ha...
A class for handling words, derived from string.
Definition: word.H:63
static const word null
An empty word.
Definition: word.H:78
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define WarningInFunction
Report a warning using Foam::Warning.
const dimensionSet time
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
Namespace for OpenFOAM.
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:288
messageStream Info
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
HashSet wordHashSet
A HashSet with word keys.
Definition: HashSet.H:210
Ostream & indentOrNl(Ostream &os)
Indent stream or add newline if indent level == 0.
Definition: Ostream.H:250
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
label timeIndex
Definition: getTimeIndex.H:4
dictionary dict