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