generateInterfacialModels.H
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 Namespace
25  Foam
26 
27 Description
28  Functions for generating tables of interfacial models
29 
30 \*---------------------------------------------------------------------------*/
31 
32 #ifndef generateInterfacialModels_H
33 #define generateInterfacialModels_H
34 
35 #include "phaseSystem.H"
36 #include "TypeSet.H"
40 #include "sidedPhaseInterface.H"
41 
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 
44 namespace Foam
45 {
46 
47 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
48 
49 template<class ModelType>
51 {
53 
54  // Extract the innermost part of the template
55  const word::size_type i0 = name.find_last_of('<');
56  if (i0 != word::npos)
57  {
58  const word::size_type i1 = name.find_first_of('>', i0 + 1);
59  if (i1 != word::npos)
60  {
61  name = name(i0 + 1, i1 - i0 - 1);
62  }
63  }
64 
65  // Strip "Model" off the end of the name
66  if (name(name.size() - 5, 5) == "Model")
67  {
68  name = name(name.size() - 5);
69  }
70 
71  return name;
72 }
73 
74 
76 (
77  const dictionary& dict,
78  const wordHashSet& ignoreKeys = wordHashSet()
79 )
80 {
81  UPtrList<const dictionary> result(dict.size());
82 
83  label n = 0;
84 
86  {
87  if (ignoreKeys.found(iter().keyword())) continue;
88 
89  result.set(n ++, &iter().dict());
90  }
91 
92  result.resize(n);
93 
94  return result;
95 }
96 
97 
98 template<class ModelType>
100 {
101  if (subDicts.empty())
102  {
104  << "No many matching entries for construction of a "
106  << exit(FatalError);
107  }
108 
109  if (subDicts.size() > 1)
110  {
111  wordList toc;
112  forAll(subDicts, i)
113  {
114  toc.append(subDicts[i].dictName());
115  }
116 
118  << "Too many matching entries for construction of a "
119  << ModelType::typeName << nl << toc
120  << exit(FatalError);
121  }
122 
123  return subDicts.first();
124 }
125 
126 
127 template<class ModelType, typename = void>
129 :
130  public std::false_type
131 {
133 
135 
136  typedef TypeSet
137  <
143 };
144 
145 template<class ModelType>
146 struct ModelPhaseInterfaceTypes<ModelType, VoidT<typename ModelType::modelType>>
147 :
148  public std::true_type
149 {
150  typedef typename
152  <
153  typename ModelPhaseInterfaceTypes
154  <
155  typename ModelType::modelType
156  >::required,
157  typename ModelType::requiredPhaseInterfaces
159 
160  typedef typename
162  <
163  typename ModelPhaseInterfaceTypes
164  <
165  typename ModelType::modelType
166  >::allowed,
167  typename ModelType::allowedPhaseInterfaces
169 
170  typedef typename
172  <
174  allowed
176 };
177 
178 
179 template<class ModelType>
181 {
182  return
185 }
186 
187 
188 template<class InterfaceTypeSet>
190 
191 template<class InterfaceType, class ... InterfaceTypes>
192 struct PhaseInterfaceInfo<TypeSet<InterfaceType, InterfaceTypes ...>>
193 {
194  string operator()(const char* andOr) const
195  {
196  const string subS =
197  PhaseInterfaceInfo<TypeSet<InterfaceTypes ...>>()(andOr);
198 
199  string type(InterfaceType::typeName_());
200  type.removeTrailing("PhaseInterface");
201 
202  const string s =
203  type + " (i.e., contains '_" + InterfaceType::separator() + "_')";
204 
205  return
206  sizeof ... (InterfaceTypes) == 0
207  ? s.c_str()
208  : sizeof ... (InterfaceTypes) == 1
209  ? s + ' ' + andOr + ' ' + subS
210  : s + ", " + subS;
211  }
212 };
213 
214 template<>
216 {
217  inline string operator()(const char* andOr) const
218  {
219  return string();
220  }
221 };
222 
223 
224 template<class ModelType>
226 (
227  const phaseSystem& fluid,
228  const dictionary& dict,
229  const wordHashSet& ignoreKeys = wordHashSet()
230 )
231 {
233  {
234  // Get the keyword name and skip if it is ignored
235  const word& modelName = iter().keyword();
236  if (ignoreKeys.found(modelName)) continue;
237 
238  // Construct the associated interface
239  autoPtr<phaseInterface> modelInterfacePtr =
241 
242  // Check the interface against the model's permitted interface types
243  if (!isModelPhaseInterfaceType<ModelType>(modelInterfacePtr()))
244  {
246  << "The interface " << modelName
247  << " is not of suitable type for construction of a "
248  << ModelType::typeName << '.';
249 
250  const string requiredInfo =
252  <
254  >()("and");
255 
256  if (requiredInfo.size())
257  {
259  << " The interface must be of type "
260  << requiredInfo.c_str() << '.';
261  }
262 
263  const string prohibitedInfo =
265  <
267  >()("or");
268 
269  if (prohibitedInfo.size())
270  {
272  << " The interface must NOT be of type "
273  << prohibitedInfo.c_str() << '.';
274  }
275 
277  << exit(FatalIOError);
278  }
279  }
280 }
281 
282 
283 template<class ModelType, class ... InterfaceTypes, class ... Args>
285 (
286  PtrList<phaseInterface>& interfaces,
287  PtrList<ModelType>& models,
288  const phaseSystem& fluid,
289  const UPtrList<const dictionary>& subDicts,
290  const wordHashSet& ignoreKeys,
291  const phaseInterface& interface,
292  const Args& ... args
293 )
294 {
295  // Construct sub-dictionaries and associated interfaces
296  hashedWordList names;
298  forAll(subDicts, subDicti)
299  {
300  // Get the model sub dictionary and name
301  const dictionary& modelDict = subDicts[subDicti];
302  const word& modelName = modelDict.dictName();
303  if (ignoreKeys.found(modelName)) continue;
304 
305  // Construct the interface
306  autoPtr<phaseInterface> modelInterfacePtr =
308 
309  // Check the interface against the model's permitted interface types
310  if
311  (
312  isNull(interface)
313  && !isModelPhaseInterfaceType<ModelType>(modelInterfacePtr())
314  ) continue;
315 
316  // Convert the interface to the first specified type possible
317  autoPtr<phaseInterface> interfacePtr =
318  TypeSet<InterfaceTypes ...>::clone(modelInterfacePtr());
319  if (!interfacePtr.valid())
320  {
321  FatalIOErrorInFunction(modelDict)
322  << "The interface " << modelName
323  << " is not of suitable type for construction of a "
325  << exit(FatalIOError);
326  }
327 
328  // If constructing for a specific interface then combine with this
329  // interface. This ensures interface information propagates through
330  // hierarchical model generation.
331  if (notNull(interface))
332  {
333  interfacePtr = phaseInterface::New(interface, interfacePtr());
334  }
335 
336  // Find an existing dictionary to add to or create a new one
337  const word name = interfacePtr->name();
338  if (!names.found(name))
339  {
340  names.append(name);
341  subDictss.append(UPtrList<const dictionary>());
342  interfaces.append(interfacePtr.ptr());
343  models.append(nullptr);
344  }
345 
346  // Add the model dictionary
347  subDictss[names[name]].append(&modelDict);
348  }
349 
350  // Construct the models
351  forAll(interfaces, i)
352  {
353  models.set(i, ModelType::New(subDictss[i], interfaces[i], args ...));
354  }
355 }
356 
357 
358 template<class ModelType, class ... Args>
360 <
361  ModelType,
365 (
366  const phaseSystem& fluid,
367  const dictionary& dict,
368  const wordHashSet& ignoreKeys,
369  const bool ignoreNonModelPhaseInterfaceTypes,
370  const Args& ... args
371 )
372 {
373  // Check that the dictionary has the correct interface types in it
374  if (!ignoreNonModelPhaseInterfaceTypes)
375  {
376  checkInterfacialModelsDict<ModelType>(fluid, dict, ignoreKeys);
377  }
378 
379  // Construct lists of interfaces and models
380  PtrList<phaseInterface> listInterfaces;
381  PtrList<ModelType> listModels;
382  generateInterfacialModels<ModelType, phaseInterface>
383  (
384  listInterfaces,
385  listModels,
386  fluid,
387  modelSubDicts(dict, ignoreKeys),
388  wordHashSet(),
389  NullObjectRef<phaseInterface>(),
390  args ...
391  );
392 
393  // Transfer to a keyed table
395  forAll(listInterfaces, i)
396  {
397  models.insert(listInterfaces[i], listModels.set(i, nullptr).ptr());
398  }
399 
400  return models;
401 }
402 
403 
404 template<class ModelType>
406 <
407  ModelType,
411 (
412  const phaseSystem& fluid,
413  const dictionary& dict
414 )
415 {
416  return
417  generateInterfacialModels<ModelType>
418  (
419  fluid,
420  dict,
421  wordHashSet(),
422  false
423  );
424 }
425 
426 
427 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
428 
429 } // End namespace Foam
430 
431 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
432 
433 #endif
434 
435 // ************************************************************************* //
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:73
label n
#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
A HashTable specialisation for hashing pointers.
Definition: HashPtrTable.H:68
A HashTable with keys but without contents.
Definition: HashSet.H:62
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
Definition: HashTableI.H:80
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:138
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:178
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: PtrList.H:75
bool set(const label) const
Is element set.
Definition: PtrListI.H:62
void append(T *)
Append an element at the end of the list.
Definition: PtrListI.H:39
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: UPtrList.H:66
T & first()
Return reference to the first element of the list.
Definition: UPtrListI.H:43
bool set(const label) const
Is element set.
Definition: UPtrListI.H:87
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
void resize(const label)
Reset size of UPtrList. This can only be used to set the size.
Definition: UPtrListI.H:71
bool empty() const
Return true if the UPtrList is empty (ie, size() is zero)
Definition: UPtrListI.H:36
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: autoPtr.H:51
bool valid() const
Return true if the autoPtr valid (ie, the pointer is set)
Definition: autoPtrI.H:83
T * ptr()
Return object pointer for reuse.
Definition: autoPtrI.H:90
const word dictName() const
Return the local dictionary name (final part of scoped name)
Definition: dictionary.H:123
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
Class to represent a interface between phases where one phase is considered dispersed within the othe...
Class to represent an interface between phases which has been displaced to some extent by a third pha...
A wordList with hashed indices for faster lookup by name.
bool found(const word &) const
Does the list contain the specified name.
void append(const word &)
Append an element at the end of the list.
Word-pair based class used for keying interface models in hash tables.
Class to represent an interface between phases. Derivations can further specify the configuration of ...
static autoPtr< phaseInterface > New(const phaseSystem &fluid, const word &name)
Select given fluid and name.
Class to represent a system of phases.
Definition: phaseSystem.H:74
Class to represent a interface between phases where the two phases are considered to be segregated; t...
Class to represent a certain side of an interface between phases.
A class for handling character strings derived from std::string.
Definition: string.H:79
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
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.name(), lagrangian::cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
bool isModelPhaseInterfaceType(const phaseInterface &interface)
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
UPtrList< const dictionary > modelSubDicts(const dictionary &dict, const wordHashSet &ignoreKeys=wordHashSet())
void VoidT
Definition: VoidT.H:42
String typeName(const std::type_info &info)
Return the un-mangled name given the standard type info.
void generateInterfacialModels(PtrList< phaseInterface > &interfaces, PtrList< ModelType > &models, const phaseSystem &fluid, const UPtrList< const dictionary > &subDicts, const wordHashSet &ignoreKeys, const phaseInterface &interface, const Args &... args)
void checkInterfacialModelsDict(const phaseSystem &fluid, const dictionary &dict, const wordHashSet &ignoreKeys=wordHashSet())
bool notNull(const T &t)
Return true if t is not a reference to the nullObject of type T.
Definition: nullObjectI.H:64
T clone(const T &t)
Definition: List.H:55
IOerror FatalIOError
const dictionary & modelSubDict(const UPtrList< const dictionary > &subDicts)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
bool isNull(const T &t)
Return true if t is a reference to the nullObject of type T.
Definition: nullObjectI.H:58
HashSet wordHashSet
A HashSet with word keys.
Definition: HashSet.H:210
error FatalError
tmp< DimensionedField< TypeR, GeoMesh, Field > > New(const tmp< DimensionedField< TypeR, GeoMesh, Field >> &tdf1, const word &name, const dimensionSet &dimensions)
static const char nl
Definition: Ostream.H:297
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
Foam::argList args(argc, argv)
TypeSetRemove< typename ModelPhaseInterfaceTypes< void >::prohibited, allowed >::type prohibited
TypeSetConcatenate< typename ModelPhaseInterfaceTypes< typename ModelType::modelType >::allowed, typename ModelType::allowedPhaseInterfaces >::type allowed
TypeSetConcatenate< typename ModelPhaseInterfaceTypes< typename ModelType::modelType >::required, typename ModelType::requiredPhaseInterfaces >::type required
TypeSet< dispersedPhaseInterface, segregatedPhaseInterface, displacedPhaseInterface, sidedPhaseInterface > prohibited
string operator()(const char *andOr) const
Template meta-programming for operations involving sets of types.
Definition: TypeSet.H:47