All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
setFields.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) 2011-2022 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 Description
25  Set values on a selected set of cells/patchfaces through a dictionary.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "argList.H"
30 #include "Time.H"
31 #include "fvMesh.H"
32 #include "topoSetSource.H"
33 #include "cellSet.H"
34 #include "faceSet.H"
35 #include "volFields.H"
36 #include "systemDict.H"
37 #include "processorFvPatch.H"
38 #include "CompactListList.H"
39 
40 using namespace Foam;
41 
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 
44 template<class Type>
45 bool setCellFieldType
46 (
47  const word& fieldTypeDesc,
48  const fvMesh& mesh,
49  const labelList& selectedCells,
50  Istream& fieldValueStream
51 )
52 {
54 
55  if (fieldTypeDesc != fieldType::typeName + "Value")
56  {
57  return false;
58  }
59 
60  word fieldName(fieldValueStream);
61 
62  // Check the current time directory
63  typeIOobject<fieldType> fieldHeader
64  (
65  fieldName,
66  mesh.time().timeName(),
67  mesh,
69  );
70 
71  // Check the "constant" directory
72  if (!fieldHeader.headerOk())
73  {
74  fieldHeader = typeIOobject<fieldType>
75  (
76  fieldName,
77  mesh.time().constant(),
78  mesh,
80  );
81  }
82 
83  // Check field exists
84  if (fieldHeader.headerOk())
85  {
86  Info<< " Setting internal values of "
87  << fieldHeader.headerClassName()
88  << " " << fieldName << endl;
89 
90  fieldType field(fieldHeader, mesh);
91 
92  const Type value = pTraits<Type>(fieldValueStream);
93 
94  if (selectedCells.size() == field.size())
95  {
96  field.primitiveFieldRef() = value;
97  }
98  else
99  {
100  forAll(selectedCells, celli)
101  {
102  field[selectedCells[celli]] = value;
103  }
104  }
105 
107  Boundary& fieldBf = field.boundaryFieldRef();
108 
109  forAll(field.boundaryField(), patchi)
110  {
111  fieldBf[patchi] = fieldBf[patchi].patchInternalField();
112  }
113 
114  if (!field.write())
115  {
117  << "Failed writing field " << fieldName << endl;
118  }
119  }
120  else
121  {
123  << "Field " << fieldName << " not found" << endl;
124 
125  // Consume value
126  (void)pTraits<Type>(fieldValueStream);
127  }
128 
129  return true;
130 }
131 
132 
133 class setCellField
134 {
135 
136 public:
137 
138  setCellField()
139  {}
140 
142  {
143  return autoPtr<setCellField>(new setCellField());
144  }
145 
146  class iNew
147  {
148  const fvMesh& mesh_;
149  const labelList& selectedCells_;
150 
151  public:
152 
153  iNew(const fvMesh& mesh, const labelList& selectedCells)
154  :
155  mesh_(mesh),
156  selectedCells_(selectedCells)
157  {}
158 
159  autoPtr<setCellField> operator()(Istream& fieldValues) const
160  {
161  word fieldType(fieldValues);
162 
163  if
164  (
165  !(
166  setCellFieldType<scalar>
167  (fieldType, mesh_, selectedCells_, fieldValues)
168  || setCellFieldType<vector>
169  (fieldType, mesh_, selectedCells_, fieldValues)
170  || setCellFieldType<sphericalTensor>
171  (fieldType, mesh_, selectedCells_, fieldValues)
172  || setCellFieldType<symmTensor>
173  (fieldType, mesh_, selectedCells_, fieldValues)
174  || setCellFieldType<tensor>
175  (fieldType, mesh_, selectedCells_, fieldValues)
176  )
177  )
178  {
180  << "field type " << fieldType << " not currently supported"
181  << endl;
182  }
183 
184  return autoPtr<setCellField>(new setCellField());
185  }
186  };
187 };
188 
189 
190 template<class Type>
191 bool setFaceFieldType
192 (
193  const word& fieldTypeDesc,
194  const fvMesh& mesh,
195  const labelList& selectedFaces,
196  Istream& fieldValueStream
197 )
198 {
200 
201  if (fieldTypeDesc != fieldType::typeName + "Value")
202  {
203  return false;
204  }
205 
206  word fieldName(fieldValueStream);
207 
208  // Check the current time directory
209  typeIOobject<fieldType> fieldHeader
210  (
211  fieldName,
212  mesh.time().timeName(),
213  mesh,
215  );
216 
217  // Check the "constant" directory
218  if (!fieldHeader.headerOk())
219  {
220  fieldHeader = typeIOobject<fieldType>
221  (
222  fieldName,
223  mesh.time().constant(),
224  mesh,
226  );
227  }
228 
229  // Check field exists
230  if (fieldHeader.headerOk())
231  {
232  Info<< " Setting patchField values of "
233  << fieldHeader.headerClassName()
234  << " " << fieldName << endl;
235 
236  // Read the field
237  fieldType field(fieldHeader, mesh);
238  typename fieldType::Boundary& fieldBf = field.boundaryFieldRef();
239 
240  // Read the value
241  const Type value = pTraits<Type>(fieldValueStream);
242 
243  // Determine the number of non-processor patches
244  label nNonProcPatches = 0;
245  forAll(fieldBf, patchi)
246  {
247  nNonProcPatches = patchi;
248  if (isA<processorFvPatch>(mesh.boundary()[patchi]))
249  {
250  break;
251  }
252  }
253 
254  // Create a copy of the boundary field
255  typename fieldType::Boundary fieldBfCopy
256  (
257  fieldType::Internal::null(),
258  fieldBf
259  );
260 
261  // Loop selected faces and set values in the copied boundary field
262  bool haveWarnedInternal = false, haveWarnedProc = false;
263  labelList nonProcPatchNChangedFaces(nNonProcPatches, 0);
264  forAll(selectedFaces, i)
265  {
266  const label facei = selectedFaces[i];
267 
268  if (mesh.isInternalFace(facei))
269  {
270  if (!haveWarnedInternal)
271  {
273  << "Ignoring internal face " << facei
274  << ". Suppressing further warnings." << endl;
275  haveWarnedInternal = true;
276  }
277  }
278  else
279  {
280  const labelUList patches =
281  mesh.polyBFacePatches()[facei - mesh.nInternalFaces()];
282  const labelUList patchFaces =
283  mesh.polyBFacePatchFaces()[facei - mesh.nInternalFaces()];
284 
285  forAll(patches, i)
286  {
287  if (patches[i] >= nNonProcPatches)
288  {
289  if (!haveWarnedProc)
290  {
292  << "Ignoring face " << patchFaces[i]
293  << " of processor patch " << patches[i]
294  << ". Suppressing further warnings." << endl;
295  haveWarnedProc = true;
296  }
297  }
298  else
299  {
300  fieldBfCopy[patches[i]][patchFaces[i]] = value;
301  nonProcPatchNChangedFaces[patches[i]] ++;
302  }
303  }
304  }
305  }
307  (
308  nonProcPatchNChangedFaces,
310  );
312  (
313  nonProcPatchNChangedFaces
314  );
315 
316  // Reassign boundary values
317  forAll(nonProcPatchNChangedFaces, patchi)
318  {
319  if (nonProcPatchNChangedFaces[patchi] > 0)
320  {
321  Info<< " On patch "
322  << field.boundaryField()[patchi].patch().name()
323  << " set " << nonProcPatchNChangedFaces[patchi]
324  << " values" << endl;
325  fieldBf[patchi] == fieldBfCopy[patchi];
326  }
327  }
328 
329  if (!field.write())
330  {
332  << "Failed writing field " << field.name() << exit(FatalError);
333  }
334  }
335  else
336  {
338  << "Field " << fieldName << " not found" << endl;
339 
340  // Consume value
341  (void)pTraits<Type>(fieldValueStream);
342  }
343 
344  return true;
345 }
346 
347 
348 class setFaceField
349 {
350 
351 public:
352 
353  setFaceField()
354  {}
355 
357  {
358  return autoPtr<setFaceField>(new setFaceField());
359  }
360 
361  class iNew
362  {
363  const fvMesh& mesh_;
364  const labelList& selectedFaces_;
365 
366  public:
367 
368  iNew(const fvMesh& mesh, const labelList& selectedFaces)
369  :
370  mesh_(mesh),
371  selectedFaces_(selectedFaces)
372  {}
373 
374  autoPtr<setFaceField> operator()(Istream& fieldValues) const
375  {
376  word fieldType(fieldValues);
377 
378  if
379  (
380  !(
381  setFaceFieldType<scalar>
382  (fieldType, mesh_, selectedFaces_, fieldValues)
383  || setFaceFieldType<vector>
384  (fieldType, mesh_, selectedFaces_, fieldValues)
385  || setFaceFieldType<sphericalTensor>
386  (fieldType, mesh_, selectedFaces_, fieldValues)
387  || setFaceFieldType<symmTensor>
388  (fieldType, mesh_, selectedFaces_, fieldValues)
389  || setFaceFieldType<tensor>
390  (fieldType, mesh_, selectedFaces_, fieldValues)
391  )
392  )
393  {
395  << "field type " << fieldType << " not currently supported"
396  << endl;
397  }
398 
399  return autoPtr<setFaceField>(new setFaceField());
400  }
401  };
402 };
403 
404 
405 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
406 
407 int main(int argc, char *argv[])
408 {
409  #include "addDictOption.H"
410  #include "addRegionOption.H"
411  #include "setRootCase.H"
412  #include "createTime.H"
413  #include "createNamedMesh.H"
414 
415  const dictionary setFieldsDict(systemDict("setFieldsDict", args, mesh));
416 
417  if (setFieldsDict.found("defaultFieldValues"))
418  {
419  Info<< "Setting field default values" << endl;
420  PtrList<setCellField> defaultFieldValues
421  (
422  setFieldsDict.lookup("defaultFieldValues"),
423  setCellField::iNew(mesh, labelList(mesh.nCells()))
424  );
425  Info<< endl;
426  }
427 
428  Info<< "Setting field region values" << endl;
429 
430  PtrList<entry> regions(setFieldsDict.lookup("regions"));
431 
432  forAll(regions, regionI)
433  {
434  const entry& region = regions[regionI];
435 
436  autoPtr<topoSetSource> source =
437  topoSetSource::New(region.keyword(), mesh, region.dict());
438 
439  if (source().setType() == topoSetSource::CELLSETSOURCE)
440  {
441  cellSet selectedCellSet
442  (
443  mesh,
444  "cellSet",
445  mesh.nCells()/10+1 // Reasonable size estimate.
446  );
447 
448  source->applyToSet
449  (
451  selectedCellSet
452  );
453 
454  PtrList<setCellField> fieldValues
455  (
456  region.dict().lookup("fieldValues"),
457  setCellField::iNew(mesh, selectedCellSet.toc())
458  );
459  }
460  else if (source().setType() == topoSetSource::FACESETSOURCE)
461  {
462  faceSet selectedFaceSet
463  (
464  mesh,
465  "faceSet",
466  (mesh.nFaces()-mesh.nInternalFaces())/10+1
467  );
468 
469  source->applyToSet
470  (
472  selectedFaceSet
473  );
474 
475  PtrList<setFaceField> fieldValues
476  (
477  region.dict().lookup("fieldValues"),
478  setFaceField::iNew(mesh, selectedFaceSet.toc())
479  );
480  }
481  }
482 
483 
484  Info<< "\nEnd\n" << endl;
485 
486  return 0;
487 }
488 
489 
490 // ************************************************************************* //
static void listCombineScatter(const List< commsStruct > &comms, List< T > &Value, const int tag, const label comm)
Scatter data. Reverse of combineGather.
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
A list of face labels.
Definition: faceSet.H:48
const keyType & keyword() const
Return keyword.
Definition: entry.H:123
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
error FatalError
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:156
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
label nInternalFaces() const
label nFaces() const
Templated form of IOobject providing type information for file reading and header type checking...
Definition: IOobject.H:537
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
label nCells() const
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
virtual const dictionary & dict() const =0
Return dictionary if this entry is a dictionary.
Generic GeometricField class.
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:372
fvMesh & mesh
IOdictionary systemDict(const word &dictName, const argList &args, const objectRegistry &ob, const word &regionName=polyMesh::defaultRegion)
Definition: systemDict.C:92
static void listCombineGather(const List< commsStruct > &comms, List< T > &Value, const CombineOp &cop, const int tag, const label comm)
T clone(const T &t)
Definition: List.H:54
static word timeName(const scalar, const int precision=curPrecision_)
Return time name of given scalar time.
Definition: Time.C:666
A class for handling words, derived from string.
Definition: word.H:59
const word & constant() const
Return constant name.
Definition: TimePaths.H:123
List< label > labelList
A List of labels.
Definition: labelList.H:56
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:60
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
static autoPtr< topoSetSource > New(const word &topoSetSourceType, const polyMesh &mesh, const dictionary &dict)
Return a reference to the selected topoSetSource.
Definition: topoSetSource.C:70
const UCompactListList< label > & polyBFacePatchFaces() const
Return poly-bFace-patch-face addressing.
Definition: fvMesh.C:941
label patchi
#define WarningInFunction
Report a warning using Foam::Warning.
const UCompactListList< label > & polyBFacePatches() const
Return poly-bFace-patch addressing.
Definition: fvMesh.C:865
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: List.H:70
A collection of cell labels.
Definition: cellSet.H:48
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:95
messageStream Info
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:52
List< Key > toc() const
Return the table of contents.
Definition: HashTable.C:202
rDeltaTY field()
Foam::argList args(argc, argv)
virtual void applyToSet(const setAction action, topoSet &) const =0
Namespace for OpenFOAM.
A keyword and a list of tokens is an &#39;entry&#39;.
Definition: entry.H:65
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:864
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:800