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 
30 using namespace Foam;
31 
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
33 
34 template<class Type>
35 void setVolField
36 (
37  const word& fieldName,
38  const IOobject& fieldHeader,
39  const fvMesh& mesh,
40  const labelList& selectedCells,
41  Istream& fieldValueStream
42 )
43 {
44  if (fieldHeader.headerClassName() == VolField<Type>::typeName)
45  {
46  Info<< " Setting "
47  << VolField<Type>::typeName << "::Internal " << fieldName << endl;
48 
49  VolField<Type> field(fieldHeader, mesh);
50 
51  const Type value = pTraits<Type>(fieldValueStream);
52 
53  if (&selectedCells == &labelList::null())
54  {
55  field.primitiveFieldRef() = value;
56  }
57  else
58  {
59  forAll(selectedCells, celli)
60  {
61  field[selectedCells[celli]] = value;
62  }
63  }
64 
65  typename VolField<Type>::
66  Boundary& fieldBf = field.boundaryFieldRef();
67 
68  forAll(field.boundaryField(), patchi)
69  {
70  fieldBf[patchi] = fieldBf[patchi].patchInternalField();
71  }
72 
73  if (!field.write())
74  {
76  << "Failed writing field " << fieldName << endl;
77  }
78  }
79 }
80 
81 
82 template<class Type>
83 void setPatchField
84 (
85  const word& fieldName,
86  const IOobject& fieldHeader,
87  const fvMesh& mesh,
88  const labelList& selectedFaces,
89  Istream& fieldValueStream
90 )
91 {
92  if (fieldHeader.headerClassName() == VolField<Type>::typeName)
93  {
94  Info<< " Setting "
95  << VolField<Type>::typeName << "::Boundary " << fieldName << endl;
96 
97  // Read the field
98  VolField<Type> field(fieldHeader, mesh);
99  typename VolField<Type>::Boundary& fieldBf = field.boundaryFieldRef();
100 
101  // Read the value
102  const Type value = pTraits<Type>(fieldValueStream);
103 
104  // Determine the number of non-processor patches
105  label nNonProcPatches = 0;
106  forAll(fieldBf, patchi)
107  {
108  if (isA<processorFvPatch>(mesh.boundary()[patchi]))
109  {
110  break;
111  }
112  nNonProcPatches = patchi + 1;
113  }
114 
115  // Create a copy of the boundary field
116  typename VolField<Type>::Boundary fieldBfCopy
117  (
119  fieldBf
120  );
121 
122  // Loop selected faces and set values in the copied boundary field
123  bool haveWarnedInternal = false, haveWarnedProc = false;
124  labelList nonProcPatchNChangedFaces(nNonProcPatches, 0);
125  forAll(selectedFaces, i)
126  {
127  const label facei = selectedFaces[i];
128 
129  if (mesh.isInternalFace(facei))
130  {
131  if (!haveWarnedInternal)
132  {
134  << "Ignoring internal face " << facei
135  << ". Suppressing further warnings." << endl;
136  haveWarnedInternal = true;
137  }
138  }
139  else
140  {
141  const labelUList patches =
143  const labelUList patchFaces =
145 
146  forAll(patches, i)
147  {
148  if (patches[i] >= nNonProcPatches)
149  {
150  if (!haveWarnedProc)
151  {
153  << "Ignoring face " << patchFaces[i]
154  << " of processor patch " << patches[i]
155  << ". Suppressing further warnings." << endl;
156  haveWarnedProc = true;
157  }
158  }
159  else
160  {
161  fieldBfCopy[patches[i]][patchFaces[i]] = value;
162  nonProcPatchNChangedFaces[patches[i]] ++;
163  }
164  }
165  }
166  }
168  (
169  nonProcPatchNChangedFaces,
171  );
173  (
174  nonProcPatchNChangedFaces
175  );
176 
177  // Reassign boundary values
178  forAll(nonProcPatchNChangedFaces, patchi)
179  {
180  if (nonProcPatchNChangedFaces[patchi] > 0)
181  {
182  Info<< " On patch "
183  << field.boundaryField()[patchi].patch().name()
184  << " set " << nonProcPatchNChangedFaces[patchi]
185  << " values" << endl;
186  fieldBf[patchi] == fieldBfCopy[patchi];
187  }
188  }
189 
190  if (!field.write())
191  {
193  << "Failed writing field " << field.name() << exit(FatalError);
194  }
195  }
196 }
197 
198 
199 void setVolFields
200 (
201  const fvMesh& mesh,
202  const dictionary& fieldsDict,
203  const labelList& selectedCells
204 )
205 {
206  forAllConstIter(dictionary, fieldsDict, iter)
207  {
208  const word& fieldName = iter().keyword();
209 
210  // Check the current time directory
211  IOobject fieldHeader
212  (
213  fieldName,
214  mesh.time().name(),
215  mesh,
217  );
218 
219  // Check the "constant" directory
220  if (!fieldHeader.headerOk())
221  {
222  fieldHeader = IOobject
223  (
224  fieldName,
225  mesh.time().constant(),
226  mesh,
228  );
229  }
230 
231  // Check field exists
232  if (fieldHeader.headerOk())
233  {
234  #define SetVolField(Type, nullArg) \
235  setVolField<Type> \
236  ( \
237  fieldName, \
238  fieldHeader, \
239  mesh, \
240  selectedCells, \
241  iter().stream() \
242  );
243 
244  FOR_ALL_FIELD_TYPES(SetVolField);
245 
246  #undef SetCellFieldType
247  }
248  else
249  {
251  << "Field " << fieldName << " not found" << endl;
252  }
253  }
254 }
255 
256 
257 void setPatchFields
258 (
259  const fvMesh& mesh,
260  const dictionary& fieldsDict,
261  const labelList& selectedCells
262 )
263 {
264  forAllConstIter(dictionary, fieldsDict, iter)
265  {
266  const word& fieldName = iter().keyword();
267 
268  // Check the current time directory
269  IOobject fieldHeader
270  (
271  fieldName,
272  mesh.time().name(),
273  mesh,
275  );
276 
277  // Check the "constant" directory
278  if (!fieldHeader.headerOk())
279  {
280  fieldHeader = IOobject
281  (
282  fieldName,
283  mesh.time().constant(),
284  mesh,
286  );
287  }
288 
289  // Check field exists
290  if (fieldHeader.headerOk())
291  {
292  #define SetPatchField(Type, nullArg) \
293  setPatchField<Type> \
294  ( \
295  fieldName, \
296  fieldHeader, \
297  mesh, \
298  selectedCells, \
299  iter().stream() \
300  );
301 
302  FOR_ALL_FIELD_TYPES(SetPatchField);
303 
304  #undef SetCellFieldType
305  }
306  else
307  {
309  << "Field " << fieldName << " not found" << endl;
310  }
311  }
312 }
313 
314 
315 // ************************************************************************* //
#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
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.
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:962
const UCompactListList< label > & polyBFacePatches() const
Return poly-bFace-patch addressing.
Definition: fvMesh.C:1016
const UCompactListList< label > & polyBFacePatchFaces() const
Return poly-bFace-patch-face addressing.
Definition: fvMesh.C:1092
label nInternalFaces() const
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
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)