setVolFields.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 "volFields.H"
27 #include "processorFvPatch.H"
28 #include "CompactListList.H"
29 #include "PtrDictionary.H"
30 #include "wordReListMatcher.H"
31 
32 using namespace Foam;
33 
34 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35 
36 template<class Type>
37 void setVolField
38 (
39  const word& fieldName,
40  const IOobject& fieldHeader,
41  const fvMesh& mesh,
42  const labelList& selectedCells,
43  const PtrDictionary<wordReList>& extrapolatePatches,
44  Istream& fieldValueStream
45 )
46 {
47  if (fieldHeader.headerClassName() == VolField<Type>::typeName)
48  {
49  Info<< " Setting "
50  << VolField<Type>::typeName << "::Internal " << fieldName << endl;
51 
52  VolField<Type> field(fieldHeader, mesh);
53 
54  const dimensioned<Type> value
55  (
56  fieldName,
57  field.dimensions(),
58  fieldValueStream
59  );
60 
61  if (&selectedCells == &labelList::null())
62  {
63  field.primitiveFieldRef() = value.value();
64  }
65  else
66  {
67  forAll(selectedCells, celli)
68  {
69  field[selectedCells[celli]] = value.value();
70  }
71  }
72 
73  typename VolField<Type>::
74  Boundary& fieldBf = field.boundaryFieldRef();
75 
76  forAll(field.boundaryField(), patchi)
77  {
78  if
79  (
80  extrapolatePatches.found(mesh.boundary()[patchi].name())
82  (
83  extrapolatePatches[mesh.boundary()[patchi].name()]
84  ).match(fieldName)
85  )
86  {
87  fieldBf[patchi] == fieldBf[patchi].patchInternalField();
88  }
89  else
90  {
91  fieldBf[patchi] = fieldBf[patchi].patchInternalField();
92  }
93  }
94 
95  if (!field.write())
96  {
98  << "Failed writing field " << fieldName << endl;
99  }
100  }
101 }
102 
103 
104 template<class Type>
105 void setPatchField
106 (
107  const word& fieldName,
108  const IOobject& fieldHeader,
109  const fvMesh& mesh,
110  const labelList& selectedFaces,
111  Istream& fieldValueStream
112 )
113 {
114  if (fieldHeader.headerClassName() == VolField<Type>::typeName)
115  {
116  Info<< " Setting "
117  << VolField<Type>::typeName << "::Boundary " << fieldName << endl;
118 
119  // Read the field
120  VolField<Type> field(fieldHeader, mesh);
121  typename VolField<Type>::Boundary& fieldBf = field.boundaryFieldRef();
122 
123  // Read the value
124  const dimensioned<Type> value
125  (
126  fieldName,
127  field.dimensions(),
128  fieldValueStream
129  );
130 
131  // Determine the number of non-processor patches
132  label nNonProcPatches = 0;
133  forAll(fieldBf, patchi)
134  {
135  if (isA<processorFvPatch>(mesh.boundary()[patchi]))
136  {
137  break;
138  }
139  nNonProcPatches = patchi + 1;
140  }
141 
142  // Create a copy of the boundary field
143  typename VolField<Type>::Boundary fieldBfCopy
144  (
146  fieldBf
147  );
148 
149  // Loop selected faces and set values in the copied boundary field
150  bool haveWarnedInternal = false, haveWarnedProc = false;
151  labelList nonProcPatchNChangedFaces(nNonProcPatches, 0);
152  forAll(selectedFaces, i)
153  {
154  const label facei = selectedFaces[i];
155 
156  if (mesh.isInternalFace(facei))
157  {
158  if (!haveWarnedInternal)
159  {
161  << "Ignoring internal face " << facei
162  << ". Suppressing further warnings." << endl;
163  haveWarnedInternal = true;
164  }
165  }
166  else
167  {
168  const labelUList patches =
170  const labelUList patchFaces =
172 
173  forAll(patches, i)
174  {
175  if (patches[i] >= nNonProcPatches)
176  {
177  if (!haveWarnedProc)
178  {
180  << "Ignoring face " << patchFaces[i]
181  << " of processor patch " << patches[i]
182  << ". Suppressing further warnings." << endl;
183  haveWarnedProc = true;
184  }
185  }
186  else
187  {
188  fieldBfCopy[patches[i]][patchFaces[i]] = value.value();
189  nonProcPatchNChangedFaces[patches[i]] ++;
190  }
191  }
192  }
193  }
195  (
196  nonProcPatchNChangedFaces,
198  );
200  (
201  nonProcPatchNChangedFaces
202  );
203 
204  // Reassign boundary values
205  forAll(nonProcPatchNChangedFaces, patchi)
206  {
207  if (nonProcPatchNChangedFaces[patchi] > 0)
208  {
209  Info<< " On patch "
210  << field.boundaryField()[patchi].patch().name()
211  << " set " << nonProcPatchNChangedFaces[patchi]
212  << " values" << endl;
213  fieldBf[patchi] == fieldBfCopy[patchi];
214  }
215  }
216 
217  if (!field.write())
218  {
220  << "Failed writing field " << field.name() << exit(FatalError);
221  }
222  }
223 }
224 
225 
226 void setVolFields
227 (
228  const fvMesh& mesh,
229  const dictionary& fieldsDict,
230  const labelList& selectedCells,
231  const PtrDictionary<wordReList>& extrapolatePatches
232 )
233 {
234  forAllConstIter(dictionary, fieldsDict, iter)
235  {
236  const word& fieldName = iter().keyword();
237 
238  // Check the current time directory
239  IOobject fieldHeader
240  (
241  fieldName,
242  mesh.time().name(),
243  mesh,
245  );
246 
247  // Check the "constant" directory
248  if (!fieldHeader.headerOk())
249  {
250  fieldHeader = IOobject
251  (
252  fieldName,
253  mesh.time().constant(),
254  mesh,
256  );
257  }
258 
259  // Check field exists
260  if (fieldHeader.headerOk())
261  {
262  #define SetVolField(Type, nullArg) \
263  setVolField<Type> \
264  ( \
265  fieldName, \
266  fieldHeader, \
267  mesh, \
268  selectedCells, \
269  extrapolatePatches, \
270  iter().stream() \
271  );
272 
273  FOR_ALL_FIELD_TYPES(SetVolField);
274 
275  #undef SetCellFieldType
276  }
277  else
278  {
280  << "Field " << fieldName << " not found" << endl;
281  }
282  }
283 }
284 
285 
286 void setPatchFields
287 (
288  const fvMesh& mesh,
289  const dictionary& fieldsDict,
290  const labelList& selectedFaces
291 )
292 {
293  forAllConstIter(dictionary, fieldsDict, iter)
294  {
295  const word& fieldName = iter().keyword();
296 
297  // Check the current time directory
298  IOobject fieldHeader
299  (
300  fieldName,
301  mesh.time().name(),
302  mesh,
304  );
305 
306  // Check the "constant" directory
307  if (!fieldHeader.headerOk())
308  {
309  fieldHeader = IOobject
310  (
311  fieldName,
312  mesh.time().constant(),
313  mesh,
315  );
316  }
317 
318  // Check field exists
319  if (fieldHeader.headerOk())
320  {
321  #define SetPatchField(Type, nullArg) \
322  setPatchField<Type> \
323  ( \
324  fieldName, \
325  fieldHeader, \
326  mesh, \
327  selectedFaces, \
328  iter().stream() \
329  );
330 
331  FOR_ALL_FIELD_TYPES(SetPatchField);
332 
333  #undef SetCellFieldType
334  }
335  else
336  {
338  << "Field " << fieldName << " not found" << endl;
339  }
340  }
341 }
342 
343 
344 // ************************************************************************* //
#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
bool found(const word &) const
Search DictionaryBase for given keyword.
Generic GeometricBoundaryField class.
Generic GeometricField class.
Boundary & boundaryFieldRef()
Return a reference to the boundary field.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
bool headerOk()
Read header of local object without type-checking.
const word & headerClassName() const
Return name of the class name read from header.
Definition: IOobject.H:313
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:60
static const List< label > & null()
Return a null List.
Definition: ListI.H:118
static void listCombineGather(const List< commsStruct > &comms, List< T > &Value, const CombineOp &cop, const int tag, const label comm)
static void listCombineScatter(const List< commsStruct > &comms, List< T > &Value, const int tag, const label comm)
Scatter data. Reverse of combineGather.
Template dictionary class which manages the storage associated with it.
Definition: PtrDictionary.H:56
static const word & constant()
Return constant name.
Definition: TimePaths.H:122
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
Generic dimensioned Type class.
const word & name() const
Return const reference to name.
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:98
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:433
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:932
const UCompactListList< label > & polyBFacePatches() const
Return poly-bFace-patch addressing.
Definition: fvMesh.C:986
const UCompactListList< label > & polyBFacePatchFaces() const
Return poly-bFace-patch-face addressing.
Definition: fvMesh.C:1062
label nInternalFaces() const
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
A wrapper for matching a List of wordRe.
bool match(const string &, bool literalMatch=false) const
Return true if string matches any of the regular expressions.
A class for handling words, derived from string.
Definition: word.H:63
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
label patchi
const fvPatchList & patches
#define WarningInFunction
Report a warning using Foam::Warning.
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
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
FOR_ALL_FIELD_TYPES(makeDimensionedPointFieldFunctions)
messageStream Info
error FatalError