LagrangianSchemes.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 "LagrangianSchemes.H"
27 #include "Time.H"
28 
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 
31 namespace Foam
32 {
34 }
35 
36 
37 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
38 
39 void Foam::LagrangianSchemes::clear()
40 {
41  ddtSchemes_.clear();
42  defaultDdtScheme_.clear();
43  SpSchemes_.clear();
44  defaultSpScheme_.clear();
45  averagingSchemes_.clear();
46  defaultAveragingScheme_.clear();
47  interpolationSchemes_.clear();
48  defaultInterpolationScheme_.clear();
49  accumulationSchemes_.clear();
50  defaultAccumulationScheme_.clear();
51 }
52 
53 
54 void Foam::LagrangianSchemes::readScheme
55 (
56  const word& type,
57  dictionary& typeSchemes,
58  ITstream& defaultTypeScheme
59 )
60 {
61  typeSchemes = subDict(type + "Schemes");
62 
63  if
64  (
65  typeSchemes.found("default")
66  && word(typeSchemes.lookup("default")) != "none"
67  )
68  {
69  defaultTypeScheme = typeSchemes.lookup("default");
70  }
71 }
72 
73 
74 void Foam::LagrangianSchemes::readDict()
75 {
76  readScheme("ddt", ddtSchemes_, defaultDdtScheme_);
77  readScheme("Sp", SpSchemes_, defaultSpScheme_);
78  readScheme
79  (
80  "averaging",
81  averagingSchemes_,
82  defaultAveragingScheme_
83  );
84  readScheme
85  (
86  "interpolation",
87  interpolationSchemes_,
88  defaultInterpolationScheme_
89  );
90  readScheme
91  (
92  "accumulation",
93  accumulationSchemes_,
94  defaultAccumulationScheme_
95  );
96 }
97 
98 
99 Foam::ITstream& Foam::LagrangianSchemes::lookupScheme
100 (
101  const word& name,
102  const dictionary& typeSchemes,
103  const ITstream& defaultTypeScheme
104 )
105 {
106  if (debug)
107  {
108  Info<< "Lookup scheme for " << name << " in dictionary "
109  << typeSchemes.name().caseName() << endl;
110  }
111 
112  // Find all the indices of the sub-strings that might need to be removed
113  DynamicList<Pair<word::size_type>> nameSubIndices;
114  {
115  bool isSub = false;
116 
117  for
118  (
119  word::size_type nameChari = 0;
120  nameChari < name.size();
121  ++ nameChari
122  )
123  {
124  if (isSub)
125  {
126  nameSubIndices.last().second() ++;
127  }
128 
129  if (name[nameChari] == '.' || name[nameChari] == ':')
130  {
131  nameSubIndices.append({nameChari, 0});
132  isSub = true;
133  }
134  else if (!isalnum(name[nameChari]))
135  {
136  isSub = false;
137  }
138  }
139  }
140 
141  // Try looking up the name with all combinations of sub-strings removed.
142  // Preferentially take the most specific entries with the smallest number
143  // of removals. Fail if we get multiple successful lookups with the same
144  // number of removed sub-strings.
145  for (label nRemoves = 0; nRemoves < nameSubIndices.size() + 1; ++ nRemoves)
146  {
147  const entry* schemePtr = nullptr;
148 
149  for
150  (
151  label removeMask = 0;
152  removeMask < (1 << nameSubIndices.size());
153  ++ removeMask
154  )
155  {
156  // Only proceed if the mask has the desired number of removes
157  label thisNRemoves = 0;
158  for (label r = removeMask; r > 0; r >>= 1) thisNRemoves += r % 2;
159  if (thisNRemoves != nRemoves) continue;
160 
161  // Build the filtered name by appending parts of the name,
162  // including or excluding the identified sub-strings as appropriate
163  word filteredName;
164  word::size_type nameChari = 0;
165  forAll(nameSubIndices, nameSubi)
166  {
167  filteredName.append
168  (
169  name
170  (
171  nameChari,
172  nameSubIndices[nameSubi].first() - nameChari
173  )
174  );
175 
176  if (!((1 << nameSubi) & removeMask))
177  {
178  filteredName.append
179  (
180  name
181  (
182  nameSubIndices[nameSubi].first(),
183  nameSubIndices[nameSubi].second()
184  )
185  );
186  }
187 
188  nameChari =
189  nameSubIndices[nameSubi].first()
190  + nameSubIndices[nameSubi].second();
191  }
192  filteredName.append(name(nameChari, name.size() - nameChari));
193 
194  // Look up the scheme
195  const entry* thisSchemePtr =
196  typeSchemes.lookupEntryPtr(filteredName, false, true);
197 
198  // Fail if a scheme was found and if we already have a scheme with
199  // this precedence
200  if (schemePtr && thisSchemePtr)
201  {
202  FatalIOErrorInFunction(typeSchemes)
203  << "keyword " << name << " ambiguously matches multiple "
204  << "schemes in dictionary " << typeSchemes.name()
205  << exit(FatalIOError);
206  }
207 
208  schemePtr = thisSchemePtr;
209  }
210 
211  if (schemePtr)
212  {
213  return schemePtr->stream();
214  }
215  }
216 
217  // An entry was not found. Generate a lookup error if there is no default.
218  if (defaultTypeScheme.empty())
219  {
220  return typeSchemes.lookup(name);
221  }
222 
223  // Return the default scheme
224  const_cast<ITstream&>(defaultTypeScheme).rewind();
225  return const_cast<ITstream&>(defaultTypeScheme);
226 }
227 
228 
229 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
230 
232 :
234  (
235  IOobject
236  (
237  "LagrangianSchemes",
238  db.time().system(),
239  db,
240  IOobject::MUST_READ_IF_MODIFIED,
241  IOobject::NO_WRITE
242  )
243  ),
244  ddtSchemes_(ITstream(objectPath() + ".ddtSchemes", tokenList())()),
245  defaultDdtScheme_(ddtSchemes_.name() + ".default", tokenList()),
246  SpSchemes_(ITstream(objectPath() + ".SpSchemes", tokenList())()),
247  defaultSpScheme_(SpSchemes_.name() + ".default", tokenList()),
248  averagingSchemes_
249  (
250  ITstream
251  (
252  objectPath() + ".averagingSchemes",
253  tokenList()
254  )()
255  ),
256  defaultAveragingScheme_
257  (
258  averagingSchemes_.name() + ".default",
259  tokenList()
260  ),
261  interpolationSchemes_
262  (
263  ITstream
264  (
265  objectPath() + ".interpolationSchemes",
266  tokenList()
267  )()
268  ),
269  defaultInterpolationScheme_
270  (
271  interpolationSchemes_.name() + ".default",
272  tokenList()
273  ),
274  accumulationSchemes_
275  (
276  ITstream
277  (
278  objectPath() + ".accumulationSchemes",
279  tokenList()
280  )()
281  ),
282  defaultAccumulationScheme_
283  (
284  accumulationSchemes_.name() + ".default",
285  tokenList()
286  )
287 {
288  readDict();
289 }
290 
291 
292 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
293 
295 {}
296 
297 
298 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
299 
301 {
302  if (regIOobject::read())
303  {
304  clear();
305 
306  readDict();
307 
308  return true;
309  }
310  else
311  {
312  return false;
313  }
314 }
315 
316 
318 {
319  return lookupScheme(name, ddtSchemes_, defaultDdtScheme_);
320 }
321 
322 
324 {
325  return lookupScheme(name, SpSchemes_, defaultSpScheme_);
326 }
327 
328 
330 {
331  return lookupScheme(name, averagingSchemes_, defaultAveragingScheme_);
332 }
333 
334 
336 {
337  return lookupScheme
338  (
339  name,
340  interpolationSchemes_,
341  defaultInterpolationScheme_
342  );
343 }
344 
345 
347 {
348  return lookupScheme(name, accumulationSchemes_, defaultAccumulationScheme_);
349 }
350 
351 
352 // ************************************************************************* //
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:73
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
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
Input token stream.
Definition: ITstream.H:56
Selector class for Lagrangian schemes.
ITstream & interpolation(const word &name) const
Get the interpolation scheme for the given field name.
ITstream & ddt(const word &name) const
Get the time scheme for the given field name.
ITstream & accumulation(const word &name) const
Get the accumulation scheme for the given field name.
ITstream & Sp(const word &name) const
Get the source scheme for the given field name.
ITstream & averaging(const word &name) const
Get the averaging scheme for the given field name.
LagrangianSchemes(const objectRegistry &db)
Construct for objectRegistry.
bool read()
Read the LagrangianSchemes.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:91
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:125
void clear()
Clear the dictionary.
Definition: dictionary.C:1358
Registry of regIOobjects.
virtual bool read()
Read object.
A class for handling words, derived from string.
Definition: word.H:63
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
tUEqn clear()
const dimensionSet time
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
int system(const std::string &command)
Execute the specified command.
Definition: POSIX.C:1230
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
labelList second(const UList< labelPair > &p)
Definition: patchToPatch.C:49
labelList first(const UList< labelPair > &p)
Definition: patchToPatch.C:39
IOerror FatalIOError
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488