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 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 Type value = pTraits<Type>(fieldValueStream);
55 
56  if (&selectedCells == &labelList::null())
57  {
58  field.primitiveFieldRef() = value;
59  }
60  else
61  {
62  forAll(selectedCells, celli)
63  {
64  field[selectedCells[celli]] = value;
65  }
66  }
67 
68  typename VolField<Type>::
69  Boundary& fieldBf = field.boundaryFieldRef();
70 
71  forAll(field.boundaryField(), patchi)
72  {
73  if
74  (
75  extrapolatePatches.found(mesh.boundary()[patchi].name())
77  (
78  extrapolatePatches[mesh.boundary()[patchi].name()]
79  ).match(fieldName)
80  )
81  {
82  fieldBf[patchi] == fieldBf[patchi].patchInternalField();
83  }
84  else
85  {
86  fieldBf[patchi] = fieldBf[patchi].patchInternalField();
87  }
88  }
89 
90  if (!field.write())
91  {
93  << "Failed writing field " << fieldName << endl;
94  }
95  }
96 }
97 
98 
99 template<class Type>
100 void setPatchField
101 (
102  const word& fieldName,
103  const IOobject& fieldHeader,
104  const fvMesh& mesh,
105  const labelList& selectedFaces,
106  Istream& fieldValueStream
107 )
108 {
109  if (fieldHeader.headerClassName() == VolField<Type>::typeName)
110  {
111  Info<< " Setting "
112  << VolField<Type>::typeName << "::Boundary " << fieldName << endl;
113 
114  // Read the field
115  VolField<Type> field(fieldHeader, mesh);
116  typename VolField<Type>::Boundary& fieldBf = field.boundaryFieldRef();
117 
118  // Read the value
119  const Type value = pTraits<Type>(fieldValueStream);
120 
121  // Determine the number of non-processor patches
122  label nNonProcPatches = 0;
123  forAll(fieldBf, patchi)
124  {
125  if (isA<processorFvPatch>(mesh.boundary()[patchi]))
126  {
127  break;
128  }
129  nNonProcPatches = patchi + 1;
130  }
131 
132  // Create a copy of the boundary field
133  typename VolField<Type>::Boundary fieldBfCopy
134  (
136  fieldBf
137  );
138 
139  // Loop selected faces and set values in the copied boundary field
140  bool haveWarnedInternal = false, haveWarnedProc = false;
141  labelList nonProcPatchNChangedFaces(nNonProcPatches, 0);
142  forAll(selectedFaces, i)
143  {
144  const label facei = selectedFaces[i];
145 
146  if (mesh.isInternalFace(facei))
147  {
148  if (!haveWarnedInternal)
149  {
151  << "Ignoring internal face " << facei
152  << ". Suppressing further warnings." << endl;
153  haveWarnedInternal = true;
154  }
155  }
156  else
157  {
158  const labelUList patches =
160  const labelUList patchFaces =
162 
163  forAll(patches, i)
164  {
165  if (patches[i] >= nNonProcPatches)
166  {
167  if (!haveWarnedProc)
168  {
170  << "Ignoring face " << patchFaces[i]
171  << " of processor patch " << patches[i]
172  << ". Suppressing further warnings." << endl;
173  haveWarnedProc = true;
174  }
175  }
176  else
177  {
178  fieldBfCopy[patches[i]][patchFaces[i]] = value;
179  nonProcPatchNChangedFaces[patches[i]] ++;
180  }
181  }
182  }
183  }
185  (
186  nonProcPatchNChangedFaces,
188  );
190  (
191  nonProcPatchNChangedFaces
192  );
193 
194  // Reassign boundary values
195  forAll(nonProcPatchNChangedFaces, patchi)
196  {
197  if (nonProcPatchNChangedFaces[patchi] > 0)
198  {
199  Info<< " On patch "
200  << field.boundaryField()[patchi].patch().name()
201  << " set " << nonProcPatchNChangedFaces[patchi]
202  << " values" << endl;
203  fieldBf[patchi] == fieldBfCopy[patchi];
204  }
205  }
206 
207  if (!field.write())
208  {
210  << "Failed writing field " << field.name() << exit(FatalError);
211  }
212  }
213 }
214 
215 
216 void setVolFields
217 (
218  const fvMesh& mesh,
219  const dictionary& fieldsDict,
220  const labelList& selectedCells,
221  const PtrDictionary<wordReList>& extrapolatePatches
222 )
223 {
224  forAllConstIter(dictionary, fieldsDict, iter)
225  {
226  const word& fieldName = iter().keyword();
227 
228  // Check the current time directory
229  IOobject fieldHeader
230  (
231  fieldName,
232  mesh.time().name(),
233  mesh,
235  );
236 
237  // Check the "constant" directory
238  if (!fieldHeader.headerOk())
239  {
240  fieldHeader = IOobject
241  (
242  fieldName,
243  mesh.time().constant(),
244  mesh,
246  );
247  }
248 
249  // Check field exists
250  if (fieldHeader.headerOk())
251  {
252  #define SetVolField(Type, nullArg) \
253  setVolField<Type> \
254  ( \
255  fieldName, \
256  fieldHeader, \
257  mesh, \
258  selectedCells, \
259  extrapolatePatches, \
260  iter().stream() \
261  );
262 
263  FOR_ALL_FIELD_TYPES(SetVolField);
264 
265  #undef SetCellFieldType
266  }
267  else
268  {
270  << "Field " << fieldName << " not found" << endl;
271  }
272  }
273 }
274 
275 
276 void setPatchFields
277 (
278  const fvMesh& mesh,
279  const dictionary& fieldsDict,
280  const labelList& selectedCells
281 )
282 {
283  forAllConstIter(dictionary, fieldsDict, iter)
284  {
285  const word& fieldName = iter().keyword();
286 
287  // Check the current time directory
288  IOobject fieldHeader
289  (
290  fieldName,
291  mesh.time().name(),
292  mesh,
294  );
295 
296  // Check the "constant" directory
297  if (!fieldHeader.headerOk())
298  {
299  fieldHeader = IOobject
300  (
301  fieldName,
302  mesh.time().constant(),
303  mesh,
305  );
306  }
307 
308  // Check field exists
309  if (fieldHeader.headerOk())
310  {
311  #define SetPatchField(Type, nullArg) \
312  setPatchField<Type> \
313  ( \
314  fieldName, \
315  fieldHeader, \
316  mesh, \
317  selectedCells, \
318  iter().stream() \
319  );
320 
321  FOR_ALL_FIELD_TYPES(SetPatchField);
322 
323  #undef SetCellFieldType
324  }
325  else
326  {
328  << "Field " << fieldName << " not found" << endl;
329  }
330  }
331 }
332 
333 
334 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:476
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
const word & name() const
Return const reference to name.
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:96
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:420
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:957
const UCompactListList< label > & polyBFacePatches() const
Return poly-bFace-patch addressing.
Definition: fvMesh.C:1011
const UCompactListList< label > & polyBFacePatchFaces() const
Return poly-bFace-patch-face addressing.
Definition: fvMesh.C:1087
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:62
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:258
messageStream Info
error FatalError
FOR_ALL_FIELD_TYPES(makeFieldSourceTypedef)