fvMeshDistributeTemplates.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2015-2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "mapPolyMesh.H"
30 
31 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
32 
33 template<class ZoneType, class ZoneMesh>
34 void Foam::fvMeshDistribute::reorderZones
35 (
36  const wordList& zoneNames,
37  ZoneMesh& zones
38 )
39 {
40  zones.clearAddressing();
41 
42  // Shift old ones to new position
43  UPtrList<ZoneType> newZonePtrs(zoneNames.size());
44  forAll(zones, zonei)
45  {
46  auto* zonePtr = zones.get(zonei);
47  if (!zonePtr)
48  {
49  FatalErrorInFunction << "Problem with zones " << zones.names()
50  << exit(FatalError);
51  }
52  const label newIndex = zoneNames.find(zonePtr->name());
53  zonePtr->index() = newIndex;
54  newZonePtrs.set(newIndex, zonePtr);
55  }
56 
57  // Add empty zones for unknown ones
58  forAll(newZonePtrs, i)
59  {
60  if (!newZonePtrs.get(i))
61  {
62  newZonePtrs.set
63  (
64  i,
65  new ZoneType
66  (
67  zoneNames[i],
68  i,
69  zones
70  )
71  );
72  }
73  }
74 
75  // Transfer
76  zones.swap(newZonePtrs);
77 }
78 
79 
80 template<class GeoField>
82 {
83  typedef GeometricField
84  <
85  typename GeoField::value_type,
87  volMesh
88  > excludeType;
89 
91  (
92  mesh.objectRegistry::lookupClass<GeoField>()
93  );
94 
95  forAllConstIters(flds, iter)
96  {
97  const GeoField& fld = *iter();
98  if (!isA<excludeType>(fld))
99  {
100  Pout<< "Field:" << iter.key() << " internalsize:" << fld.size()
101  //<< " value:" << fld
102  << endl;
103  }
104  }
105 }
106 
107 
108 template<class GeoField>
110 {
111  const HashTable<const GeoField*> flds
112  (
113  mesh.objectRegistry::lookupClass<GeoField>()
114  );
115 
116  forAllConstIters(flds, iter)
117  {
118  const GeoField& fld = *iter();
119 
120  Pout<< "Field:" << iter.key() << " internalsize:" << fld.size()
121  //<< " value:" << fld
122  << endl;
123 
124  for (const auto& patchFld : fld.boundaryField())
125  {
126  Pout<< " " << patchFld.patch().index()
127  << ' ' << patchFld.patch().name()
128  << ' ' << patchFld.type()
129  << ' ' << patchFld.size()
130  << nl;
131  }
132  }
133 }
134 
135 
136 template<class T, class Mesh>
137 void Foam::fvMeshDistribute::saveBoundaryFields
138 (
140 ) const
141 {
142  // Save whole boundary field
143 
145 
147  (
148  mesh_.objectRegistry::lookupClass<const fldType>()
149  );
150 
151  bflds.setSize(flds.size());
152 
153  label i = 0;
154  forAllConstIters(flds, iter)
155  {
156  const fldType& fld = *iter();
157 
158  bflds.set(i, fld.boundaryField().clone().ptr());
159 
160  ++i;
161  }
162 }
163 
164 
165 template<class T, class Mesh>
166 void Foam::fvMeshDistribute::mapBoundaryFields
167 (
168  const mapPolyMesh& map,
169  const PtrList<FieldField<fvsPatchField, T>>& oldBflds
170 )
171 {
172  // Map boundary field
173 
174  const labelList& oldPatchStarts = map.oldPatchStarts();
175  const labelList& faceMap = map.faceMap();
176 
177  typedef GeometricField<T, fvsPatchField, Mesh> fldType;
178 
179  HashTable<fldType*> flds
180  (
181  mesh_.objectRegistry::lookupClass<fldType>()
182  );
183 
184  if (flds.size() != oldBflds.size())
185  {
187  << abort(FatalError);
188  }
189 
190  label fieldi = 0;
191 
192  forAllIters(flds, iter)
193  {
194  fldType& fld = *iter();
195  auto& bfld = fld.boundaryFieldRef();
196 
197  const FieldField<fvsPatchField, T>& oldBfld = oldBflds[fieldi++];
198 
199  // Pull from old boundary field into bfld.
200 
201  forAll(bfld, patchi)
202  {
203  fvsPatchField<T>& patchFld = bfld[patchi];
204  label facei = patchFld.patch().start();
205 
206  forAll(patchFld, i)
207  {
208  label oldFacei = faceMap[facei++];
209 
210  // Find patch and local patch face oldFacei was in.
211  forAll(oldPatchStarts, oldPatchi)
212  {
213  label oldLocalI = oldFacei - oldPatchStarts[oldPatchi];
214 
215  if (oldLocalI >= 0 && oldLocalI < oldBfld[oldPatchi].size())
216  {
217  patchFld[i] = oldBfld[oldPatchi][oldLocalI];
218  }
219  }
220  }
221  }
222  }
223 }
224 
225 
226 template<class T>
227 void Foam::fvMeshDistribute::saveInternalFields
228 (
229  PtrList<Field<T>>& iflds
230 ) const
231 {
232  typedef GeometricField<T, fvsPatchField, surfaceMesh> fldType;
233 
234  HashTable<const fldType*> flds
235  (
236  mesh_.objectRegistry::lookupClass<const fldType>()
237  );
238 
239  iflds.setSize(flds.size());
240 
241  label i = 0;
242 
243  forAllConstIters(flds, iter)
244  {
245  const fldType& fld = *iter();
246 
247  iflds.set(i, fld.primitiveField().clone());
248 
249  ++i;
250  }
251 }
252 
253 
254 template<class T>
255 void Foam::fvMeshDistribute::mapExposedFaces
256 (
257  const mapPolyMesh& map,
258  const PtrList<Field<T>>& oldFlds
259 )
260 {
261  // Set boundary values of exposed internal faces
262 
263  const labelList& faceMap = map.faceMap();
264 
265  typedef GeometricField<T, fvsPatchField, surfaceMesh> fldType;
266 
267  HashTable<fldType*> flds
268  (
269  mesh_.objectRegistry::lookupClass<fldType>()
270  );
271 
272  if (flds.size() != oldFlds.size())
273  {
275  << "problem"
276  << abort(FatalError);
277  }
278 
279 
280  label fieldI = 0;
281 
282  forAllIters(flds, iter)
283  {
284  fldType& fld = *iter();
285  const bool oriented = fld.oriented()();
286 
287  typename fldType::Boundary& bfld = fld.boundaryFieldRef();
288 
289  const Field<T>& oldInternal = oldFlds[fieldI++];
290 
291  // Pull from old internal field into bfld.
292 
293  forAll(bfld, patchi)
294  {
295  fvsPatchField<T>& patchFld = bfld[patchi];
296 
297  forAll(patchFld, i)
298  {
299  const label faceI = patchFld.patch().start()+i;
300 
301  label oldFaceI = faceMap[faceI];
302 
303  if (oldFaceI < oldInternal.size())
304  {
305  patchFld[i] = oldInternal[oldFaceI];
306 
307  if (oriented && map.flipFaceFlux().found(faceI))
308  {
309  patchFld[i] = flipOp()(patchFld[i]);
310  }
311  }
312  }
313  }
314  }
315 }
316 
317 
318 template<class GeoField, class PatchFieldType>
319 void Foam::fvMeshDistribute::initPatchFields
320 (
321  const typename GeoField::value_type& initVal
322 )
323 {
324  // Init patch fields of certain type
325 
326  HashTable<GeoField*> flds
327  (
328  mesh_.objectRegistry::lookupClass<GeoField>()
329  );
330 
331  forAllIters(flds, iter)
332  {
333  GeoField& fld = *iter();
334 
335  auto& bfld = fld.boundaryFieldRef();
336 
337  forAll(bfld, patchi)
338  {
339  if (isA<PatchFieldType>(bfld[patchi]))
340  {
341  bfld[patchi] == initVal;
342  }
343  }
344  }
345 }
346 
347 
348 //template<class GeoField>
349 //void Foam::fvMeshDistribute::correctBoundaryConditions()
350 //{
351 // // CorrectBoundaryConditions patch fields of certain type
352 //
353 // HashTable<GeoField*> flds
354 // (
355 // mesh_.objectRegistry::lookupClass<GeoField>()
356 // );
357 //
358 // forAllIters(flds, iter)
359 // {
360 // GeoField& fld = *iter();
361 // fld.correctBoundaryConditions();
362 // }
363 //}
364 
365 
366 template<class GeoField>
367 void Foam::fvMeshDistribute::getFieldNames
368 (
369  const fvMesh& mesh,
370  HashTable<wordList>& allFieldNames,
371  const word& excludeType,
372  const bool syncPar
373 )
374 {
375  wordList& list = allFieldNames(GeoField::typeName);
376  list = mesh.sortedNames<GeoField>();
377 
378  if (!excludeType.empty())
379  {
380  const wordList& excludeList = allFieldNames(excludeType);
381 
382  DynamicList<word> newList(list.size());
383  for(const auto& name : list)
384  {
385  if (!excludeList.found(name))
386  {
387  newList.append(name);
388  }
389  }
390  if (newList.size() < list.size())
391  {
392  list = std::move(newList);
393  }
394  }
395 
396 
397  // Check all procs have same names
398  if (syncPar)
399  {
400  List<wordList> allNames(Pstream::nProcs());
401  allNames[Pstream::myProcNo()] = list;
402  Pstream::gatherList(allNames);
403  Pstream::scatterList(allNames);
404 
405  for (const int proci : Pstream::subProcs())
406  {
407  if (allNames[proci] != allNames[0])
408  {
410  << "When checking for equal "
411  << GeoField::typeName
412  << " :" << nl
413  << "processor0 has:" << allNames[0] << endl
414  << "processor" << proci << " has:" << allNames[proci] << nl
415  << GeoField::typeName
416  << " need to be synchronised on all processors."
417  << exit(FatalError);
418  }
419  }
420  }
421 }
422 
423 
424 template<class GeoField>
425 void Foam::fvMeshDistribute::sendFields
426 (
427  const label domain,
428  const HashTable<wordList>& allFieldNames,
429  const fvMeshSubset& subsetter,
430  Ostream& toNbr
431 )
432 {
433  // Send fields. Note order supplied so we can receive in exactly the same
434  // order.
435  // Note that field gets written as entry in dictionary so we
436  // can construct from subdictionary.
437  // (since otherwise the reading as-a-dictionary mixes up entries from
438  // consecutive fields)
439  // The dictionary constructed is:
440  // volScalarField
441  // {
442  // p {internalField ..; boundaryField ..;}
443  // k {internalField ..; boundaryField ..;}
444  // }
445  // volVectorField
446  // {
447  // U {internalField ... }
448  // }
449 
450  // volVectorField {U {internalField ..; boundaryField ..;}}
451 
452  const wordList& fieldNames =
453  allFieldNames.lookup(GeoField::typeName, wordList::null());
454 
455  toNbr << GeoField::typeName << token::NL << token::BEGIN_BLOCK << token::NL;
456 
457  for (const word& fieldName : fieldNames)
458  {
459  if (debug)
460  {
461  Pout<< "Subsetting " << GeoField::typeName
462  << " field " << fieldName
463  << " for domain:" << domain << endl;
464  }
465 
466  // Send all fieldNames. This has to be exactly the same set as is
467  // being received!
468  const GeoField& fld =
469  subsetter.baseMesh().lookupObject<GeoField>(fieldName);
470 
471  // Note: use subsetter to get sub field. Override default behaviour
472  // to warn for unset fields since they will be reset later on
473  tmp<GeoField> tsubfld = subsetter.interpolate(fld, true);
474 
475  toNbr
476  << fieldName << token::NL << token::BEGIN_BLOCK
477  << tsubfld
479  }
480  toNbr << token::END_BLOCK << token::NL;
481 }
482 
483 
484 template<class GeoField>
485 void Foam::fvMeshDistribute::receiveFields
486 (
487  const label domain,
488  const HashTable<wordList>& allFieldNames,
489  fvMesh& mesh,
490  PtrList<GeoField>& fields,
491  const dictionary& allFieldsDict
492 )
493 {
494  // Opposite of sendFields
495 
496  const wordList& fieldNames =
497  allFieldNames.lookup(GeoField::typeName, wordList::null());
498 
499  const dictionary& fieldDicts =
500  allFieldsDict.subDict(GeoField::typeName);
501 
502 
503  if (debug)
504  {
505  Pout<< "Receiving:" << GeoField::typeName
506  << " fields:" << fieldNames
507  << " from domain:" << domain << endl;
508  }
509 
510  fields.resize(fieldNames.size());
511 
512  label fieldi = 0;
513  for (const word& fieldName : fieldNames)
514  {
515  if (debug)
516  {
517  Pout<< "Constructing type:" << GeoField::typeName
518  << " field:" << fieldName
519  << " from domain:" << domain << endl;
520  }
521 
522  fields.set
523  (
524  fieldi++,
525  new GeoField
526  (
527  IOobject
528  (
529  fieldName,
530  mesh.time().timeName(),
531  mesh,
534  ),
535  mesh,
536  fieldDicts.subDict(fieldName)
537  )
538  );
539  }
540 }
541 
542 
543 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::fvPatchField
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
Definition: volSurfaceMapping.H:51
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::objectRegistry::sortedNames
wordList sortedNames() const
The sorted names of all objects.
Definition: objectRegistry.C:153
Foam::IOobject::AUTO_WRITE
Definition: IOobject.H:194
Foam::List< word >::null
static const List< word > & null()
Return a null List.
Definition: ListI.H:109
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeTopological.C:94
Foam::FieldField
A field of fields is a PtrList of fields with reference counting.
Definition: FieldField.H:53
Foam::Pstream::scatterList
static void scatterList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Scatter data. Reverse of gatherList.
Definition: gatherScatterList.C:215
Foam::volMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: volMesh.H:51
Foam::fvMeshDistribute::printFieldInfo
static void printFieldInfo(const fvMesh &)
Print some field info.
Definition: fvMeshDistributeTemplates.C:109
mapPolyMesh.H
Foam::Time::timeName
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:780
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::wordList
List< word > wordList
A List of words.
Definition: fileName.H:62
Foam::UPstream::subProcs
static rangeType subProcs(const label communicator=worldComm)
Range of process indices for sub-processes.
Definition: UPstream.H:515
Foam::OSstream::name
virtual const fileName & name() const
Get the name of the stream.
Definition: OSstream.H:107
Foam::fileName::type
Type type(bool followLink=true, bool checkGzip=false) const
Definition: fileName.C:360
Foam::dictionary::subDict
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition: dictionary.C:460
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:59
fld
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Definition: gmvOutputLagrangian.H:23
Foam::token::END_BLOCK
End block [isseparator].
Definition: token.H:160
forAllIters
#define forAllIters(container, iter)
Iterate across all elements in the container object.
Definition: stdFoam.H:223
Foam::token::NL
Newline [isspace].
Definition: token.H:124
Foam::FatalError
error FatalError
fieldNames
const wordRes fieldNames(propsDict.getOrDefault< wordRes >("fields", wordRes()))
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:85
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::token::BEGIN_BLOCK
Begin block [isseparator].
Definition: token.H:159
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::HashTable
A HashTable similar to std::unordered_map.
Definition: HashTable.H:105
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::Pstream::gatherList
static void gatherList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Gather data but keep individual values separate.
Definition: gatherScatterList.C:52
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=worldComm)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:463
Foam::nl
constexpr char nl
Definition: Ostream.H:404
forAllConstIters
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
Foam::fvMeshDistribute::printIntFieldInfo
static void printIntFieldInfo(const fvMesh &)
Print some field info.
Definition: fvMeshDistributeTemplates.C:81
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::fvMesh::time
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:280
Foam::GeometricField
Generic GeometricField class.
Definition: areaFieldsFwd.H:53
Foam::IOobject::NO_READ
Definition: IOobject.H:188
fields
multivariateSurfaceInterpolationScheme< scalar >::fieldTable fields
Definition: createFields.H:97
Foam::UPstream::nProcs
static label nProcs(const label communicator=worldComm)
Number of processes in parallel run, and 1 for serial run.
Definition: UPstream.H:445