cyclicPeriodicAMIPolyPatch.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) 2015-2020 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
31 
32 // For debugging
33 #include "OBJstream.H"
34 #include "PatchTools.H"
35 #include "Time.H"
36 // Note: cannot use vtkSurfaceWriter here - circular linkage
37 // but foamVtkSurfaceWriter (vtk::surfaceWriter) would be okay.
38 //
39 // #include "foamVtkSurfaceWriter.H"
40 
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 
43 namespace Foam
44 {
45  defineTypeNameAndDebug(cyclicPeriodicAMIPolyPatch, 0);
46 
47  addToRunTimeSelectionTable(polyPatch, cyclicPeriodicAMIPolyPatch, word);
49  (
50  polyPatch,
51  cyclicPeriodicAMIPolyPatch,
52  dictionary
53  );
54 }
55 
56 
57 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
58 
59 void Foam::cyclicPeriodicAMIPolyPatch::syncTransforms() const
60 {
61  if (owner())
62  {
63  // At this point we guarantee that the transformations have been
64  // updated. There is one particular case, where if the periodic patch
65  // locally has zero faces then its transformation will not be set. We
66  // need to synchronise the transforms over the zero-sized patches as
67  // well.
68  //
69  // We can't put the logic into cyclicPolyPatch as
70  // processorCyclicPolyPatch uses cyclicPolyPatch functionality.
71  // Synchronisation will fail because processor-type patches do not exist
72  // on all processors.
73  //
74  // The use in cyclicPeriodicAMI is special; we use the patch even
75  // though we have no faces in it. Ideally, in future, the transformation
76  // logic will be abstracted out, and we won't need a periodic patch
77  // here. Until then, we can just fix the behaviour of the zero-sized
78  // coupled patches here
79 
80  // Get the periodic patch
81  const coupledPolyPatch& periodicPatch
82  (
83  refCast<const coupledPolyPatch>
84  (
86  )
87  );
88 
89  // If there are any zero-sized periodic patches
90  if (returnReduce((size() && !periodicPatch.size()), orOp<bool>()))
91  {
92  if (periodicPatch.separation().size() > 1)
93  {
95  << "Periodic patch " << periodicPatchName_
96  << " has non-uniform separation vector "
97  << periodicPatch.separation()
98  << "This is not allowed inside " << type()
99  << " patch " << name()
100  << exit(FatalError);
101  }
102 
103  if (periodicPatch.forwardT().size() > 1)
104  {
106  << "Periodic patch " << periodicPatchName_
107  << " has non-uniform transformation tensor "
108  << periodicPatch.forwardT()
109  << "This is not allowed inside " << type()
110  << " patch " << name()
111  << exit(FatalError);
112  }
113 
114  // Note that zero-sized patches will have zero-sized fields for the
115  // separation vector, forward and reverse transforms. These need
116  // replacing with the transformations from other processors.
117 
118  // Parallel in this context refers to a parallel transformation,
119  // rather than a rotational transformation.
120 
121  // Note that a cyclic with zero faces is considered parallel so
122  // explicitly check for that.
123  bool isParallel =
124  (
125  periodicPatch.size()
126  && periodicPatch.parallel()
127  );
128  reduce(isParallel, orOp<bool>());
129 
130  if (isParallel)
131  {
132  // Sync a list of separation vectors
133  List<vectorField> sep(Pstream::nProcs());
134  sep[Pstream::myProcNo()] = periodicPatch.separation();
135  Pstream::gatherList(sep);
137 
138  List<boolList> coll(Pstream::nProcs());
139  coll[Pstream::myProcNo()] = periodicPatch.collocated();
140  Pstream::gatherList(coll);
141  Pstream::scatterList(coll);
142 
143  // If locally we have zero faces pick the first one that has a
144  // separation vector
145  if (!periodicPatch.size())
146  {
147  forAll(sep, procI)
148  {
149  if (sep[procI].size())
150  {
151  const_cast<vectorField&>
152  (
153  periodicPatch.separation()
154  ) = sep[procI];
155  const_cast<boolList&>
156  (
157  periodicPatch.collocated()
158  ) = coll[procI];
159 
160  break;
161  }
162  }
163  }
164  }
165  else
166  {
167  // Sync a list of forward and reverse transforms
168  List<tensorField> forwardT(Pstream::nProcs());
169  forwardT[Pstream::myProcNo()] = periodicPatch.forwardT();
172 
173  List<tensorField> reverseT(Pstream::nProcs());
174  reverseT[Pstream::myProcNo()] = periodicPatch.reverseT();
177 
178  // If locally we have zero faces pick the first one that has a
179  // transformation vector
180  if (!periodicPatch.size())
181  {
182  forAll(forwardT, procI)
183  {
184  if (forwardT[procI].size())
185  {
186  const_cast<tensorField&>
187  (
188  periodicPatch.forwardT()
189  ) = forwardT[procI];
190  const_cast<tensorField&>
191  (
192  periodicPatch.reverseT()
193  ) = reverseT[procI];
194 
195  break;
196  }
197  }
198  }
199  }
200  }
201  }
202 }
203 
204 
205 void Foam::cyclicPeriodicAMIPolyPatch::writeOBJ
206 (
207  const primitivePatch& p,
208  OBJstream& str
209 ) const
210 {
211  // Collect faces and points
213  faceList allFaces;
214  labelList pointMergeMap;
216  (
217  -1.0, // do not merge points
218  p,
219  allPoints,
220  allFaces,
221  pointMergeMap
222  );
223 
224  if (Pstream::master())
225  {
226  // Write base geometry
227  str.write(allFaces, allPoints);
228  }
229 }
230 
231 
232 void Foam::cyclicPeriodicAMIPolyPatch::resetAMI() const
233 {
234  if (owner())
235  {
236  // Get the periodic patch
237  const coupledPolyPatch& periodicPatch
238  (
239  refCast<const coupledPolyPatch>
240  (
241  boundaryMesh()[periodicPatchID()]
242  )
243  );
244 
245  // Synchronise the transforms
246  syncTransforms();
247 
248  // Create copies of both patches' points, transformed to the owner
249  pointField thisPoints0(localPoints());
250  pointField nbrPoints0(neighbPatch().localPoints());
251  transformPosition(nbrPoints0);
252 
253  // Reset the stored number of periodic transformations to a lower
254  // absolute value if possible
255  if (nSectors_ > 0)
256  {
257  if (nTransforms_ > nSectors_/2)
258  {
259  nTransforms_ -= nSectors_;
260  }
261  else if (nTransforms_ < - nSectors_/2)
262  {
263  nTransforms_ += nSectors_;
264  }
265  }
266 
267  // Apply the stored number of periodic transforms
268  for (label i = 0; i < nTransforms_; ++ i)
269  {
270  periodicPatch.transformPosition(thisPoints0);
271  }
272  for (label i = 0; i > nTransforms_; -- i)
273  {
274  periodicPatch.transformPosition(nbrPoints0);
275  }
276 
277  autoPtr<OBJstream> ownStr;
278  autoPtr<OBJstream> neiStr;
279  if (debug)
280  {
281  const Time& runTime = boundaryMesh().mesh().time();
282 
283  fileName dir(runTime.globalPath());
284  fileName postfix("_" + runTime.timeName()+"_expanded.obj");
285 
286  ownStr.reset(new OBJstream(dir/name() + postfix));
287  neiStr.reset(new OBJstream(dir/neighbPatch().name() + postfix));
288 
290  << "patch:" << name()
291  << " writing accumulated AMI to " << ownStr().name()
292  << " and " << neiStr().name() << endl;
293  }
294 
295  // Create another copy
296  pointField thisPoints(thisPoints0);
297  pointField nbrPoints(nbrPoints0);
298 
299  // Create patches for all the points
300 
301  // Source patch at initial location
302  const primitivePatch thisPatch0
303  (
304  SubList<face>(localFaces(), size()),
305  thisPoints0
306  );
307  // Source patch that gets moved
308  primitivePatch thisPatch
309  (
310  SubList<face>(localFaces(), size()),
311  thisPoints
312  );
313  // Target patch at initial location
314  const primitivePatch nbrPatch0
315  (
316  SubList<face>(neighbPatch().localFaces(), neighbPatch().size()),
317  nbrPoints0
318  );
319  // Target patch that gets moved
320  primitivePatch nbrPatch
321  (
322  SubList<face>(neighbPatch().localFaces(), neighbPatch().size()),
323  nbrPoints
324  );
325 
326  // Construct a new AMI interpolation between the initial patch locations
327  AMIPtr_->setRequireMatch(false);
328  AMIPtr_->calculate(thisPatch0, nbrPatch0, surfPtr());
329 
330  // Number of geometry replications
331  label iter(0);
332  label nTransformsOld(nTransforms_);
333 
334  if (ownStr)
335  {
336  writeOBJ(thisPatch0, *ownStr);
337  }
338  if (neiStr)
339  {
340  writeOBJ(nbrPatch0, *neiStr);
341  }
342 
343 
344  // Weight sum averages
345  scalar srcSum(gAverage(AMIPtr_->srcWeightsSum()));
346  scalar tgtSum(gAverage(AMIPtr_->tgtWeightsSum()));
347  // Direction (or rather side of AMI : this or nbr patch) of
348  // geometry replication
349  bool direction = nTransforms_ >= 0;
350 
351  // Increase in the source weight sum for the last iteration in the
352  // opposite direction. If the current increase is less than this, the
353  // direction (= side of AMI to transform) is reversed.
354  // We switch the side to replicate instead of reversing the transform
355  // since at the coupledPolyPatch level there is no
356  // 'reverseTransformPosition' functionality.
357  scalar srcSumDiff = 0;
358 
360  << "patch:" << name()
361  << " srcSum:" << srcSum
362  << " tgtSum:" << tgtSum
363  << " direction:" << direction
364  << endl;
365 
366  // Loop, replicating the geometry
367  while
368  (
369  (iter < maxIter_)
370  && (
371  (1 - srcSum > matchTolerance())
372  || (1 - tgtSum > matchTolerance())
373  )
374  )
375  {
376  if (direction)
377  {
378  periodicPatch.transformPosition(thisPoints);
379 
381  << "patch:" << name()
382  << " moving this side from:"
383  << gAverage(thisPatch.points())
384  << " to:" << gAverage(thisPoints) << endl;
385 
386  thisPatch.movePoints(thisPoints);
387 
389  << "patch:" << name()
390  << " appending weights with untransformed slave side"
391  << endl;
392 
393  AMIPtr_->append(thisPatch, nbrPatch0);
394 
395  if (ownStr)
396  {
397  writeOBJ(thisPatch, *ownStr);
398  }
399  }
400  else
401  {
402  periodicPatch.transformPosition(nbrPoints);
403 
405  << "patch:" << name()
406  << " moving neighbour side from:"
407  << gAverage(nbrPatch.points())
408  << " to:" << gAverage(nbrPoints) << endl;
409 
410  nbrPatch.movePoints(nbrPoints);
411 
412  AMIPtr_->append(thisPatch0, nbrPatch);
413 
414  if (neiStr)
415  {
416  writeOBJ(nbrPatch, *neiStr);
417  }
418  }
419 
420  const scalar srcSumNew = gAverage(AMIPtr_->srcWeightsSum());
421  const scalar srcSumDiffNew = srcSumNew - srcSum;
422 
423  if (srcSumDiffNew < srcSumDiff || srcSumDiffNew < SMALL)
424  {
425  direction = !direction;
426 
427  srcSumDiff = srcSumDiffNew;
428  }
429 
430  srcSum = srcSumNew;
431  tgtSum = gAverage(AMIPtr_->tgtWeightsSum());
432 
433  nTransforms_ += direction ? +1 : -1;
434 
435  ++iter;
436 
438  << "patch:" << name()
439  << " iteration:" << iter
440  << " srcSum:" << srcSum
441  << " tgtSum:" << tgtSum
442  << " direction:" << direction
443  << endl;
444  }
445 
446 
447  // Close debug streams
448  ownStr.reset(nullptr);
449  neiStr.reset(nullptr);
450 
451 
452  // Average the number of transformations
453  nTransforms_ = (nTransforms_ + nTransformsOld)/2;
454 
455  // Check that the match is complete
456  if (iter == maxIter_)
457  {
458  // The matching algorithm has exited without getting the
459  // srcSum and tgtSum above 1. This can happen because
460  // - of an incorrect setup
461  // - or because of non-exact meshes and truncation errors
462  // (transformation, accumulation of cutting errors)
463  // so for now this situation is flagged as a SeriousError instead of
464  // a FatalError since the default matchTolerance is quite strict
465  // (0.001) and can get triggered far into the simulation.
467  << "Patches " << name() << " and " << neighbPatch().name()
468  << " do not couple to within a tolerance of "
469  << matchTolerance()
470  << " when transformed according to the periodic patch "
471  << periodicPatch.name() << "." << nl
472  << "The current sum of weights are for owner " << name()
473  << " : " << srcSum << " and for neighbour "
474  << neighbPatch().name() << " : " << tgtSum << nl
475  << "This is only acceptable during post-processing"
476  << "; not during running. Improve your mesh or increase"
477  << " the 'matchTolerance' setting in the patch specification."
478  << endl;
479  }
480 
481  // Check that both patches have replicated an integer number of times
482  if
483  (
484  mag(srcSum - floor(srcSum + 0.5)) > srcSum*matchTolerance()
485  || mag(tgtSum - floor(tgtSum + 0.5)) > tgtSum*matchTolerance()
486  )
487  {
488  // This condition is currently enforced until there is more
489  // experience with the matching algorithm and numerics.
490  // This check means that e.g. different numbers of stator and
491  // rotor partitions are not allowed.
492  // Again see the section above about tolerances.
494  << "Patches " << name() << " and " << neighbPatch().name()
495  << " do not overlap an integer number of times when transformed"
496  << " according to the periodic patch "
497  << periodicPatch.name() << "." << nl
498  << "The current matchTolerance : " << matchTolerance()
499  << ", sum of owner weights : " << srcSum
500  << ", sum of neighbour weights : " << tgtSum
501  << "." << nl
502  << "This is only acceptable during post-processing"
503  << "; not during running. Improve your mesh or increase"
504  << " the 'matchTolerance' setting in the patch specification."
505  << endl;
506  }
507 
508  // Print some statistics
509  const label nFace = returnReduce(size(), sumOp<label>());
510 
511  if (nFace)
512  {
513  scalarField srcWghtSum(size(), Zero);
514  forAll(srcWghtSum, faceI)
515  {
516  srcWghtSum[faceI] = sum(AMIPtr_->srcWeights()[faceI]);
517  }
518  scalarField tgtWghtSum(neighbPatch().size(), Zero);
519  forAll(tgtWghtSum, faceI)
520  {
521  tgtWghtSum[faceI] = sum(AMIPtr_->tgtWeights()[faceI]);
522  }
523 
524  Info<< indent
525  << "AMI: Patch " << name()
526  << " sum(weights)"
527  << " min:" << gMin(srcWghtSum)
528  << " max:" << gMax(srcWghtSum)
529  << " average:" << gAverage(srcWghtSum) << nl;
530  Info<< indent
531  << "AMI: Patch " << neighbPatch().name()
532  << " sum(weights)"
533  << " min:" << gMin(tgtWghtSum)
534  << " max:" << gMax(tgtWghtSum)
535  << " average:" << gAverage(tgtWghtSum) << nl;
536  }
537  }
538 }
539 
540 
541 // * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * //
542 
544 (
545  const word& name,
546  const label size,
547  const label start,
548  const label index,
549  const polyBoundaryMesh& bm,
550  const word& patchType,
552 )
553 :
555  (
556  name,
557  size,
558  start,
559  index,
560  bm,
561  patchType,
562  transform,
563  partialFaceAreaWeightAMI::typeName
564  ),
565  periodicPatchName_(word::null),
566  periodicPatchID_(-1),
567  nTransforms_(0),
568  nSectors_(0),
569  maxIter_(36)
570 {}
571 
572 
574 (
575  const word& name,
576  const dictionary& dict,
577  const label index,
578  const polyBoundaryMesh& bm,
579  const word& patchType
580 )
581 :
583  (
584  name,
585  dict,
586  index,
587  bm,
588  patchType,
589  partialFaceAreaWeightAMI::typeName
590  ),
591  periodicPatchName_(dict.lookup("periodicPatch")),
592  periodicPatchID_(-1),
593  nTransforms_(dict.getOrDefault<label>("nTransforms", 0)),
594  nSectors_(dict.getOrDefault<label>("nSectors", 0)),
595  maxIter_(dict.getOrDefault<label>("maxIter", 36))
596 {}
597 
598 
600 (
601  const cyclicPeriodicAMIPolyPatch& pp,
602  const polyBoundaryMesh& bm
603 )
604 :
605  cyclicAMIPolyPatch(pp, bm),
606  periodicPatchName_(pp.periodicPatchName_),
607  periodicPatchID_(-1),
608  nTransforms_(pp.nTransforms_),
609  nSectors_(pp.nSectors_),
610  maxIter_(pp.maxIter_)
611 {}
612 
613 
615 (
616  const cyclicPeriodicAMIPolyPatch& pp,
617  const polyBoundaryMesh& bm,
618  const label index,
619  const label newSize,
620  const label newStart,
621  const word& nbrPatchName
622 )
623 :
624  cyclicAMIPolyPatch(pp, bm, index, newSize, newStart, nbrPatchName),
625  periodicPatchName_(pp.periodicPatchName_),
626  periodicPatchID_(-1),
627  nTransforms_(pp.nTransforms_),
628  nSectors_(pp.nSectors_),
629  maxIter_(pp.maxIter_)
630 {}
631 
632 
634 (
635  const cyclicPeriodicAMIPolyPatch& pp,
636  const polyBoundaryMesh& bm,
637  const label index,
638  const labelUList& mapAddressing,
639  const label newStart
640 )
641 :
642  cyclicAMIPolyPatch(pp, bm, index, mapAddressing, newStart),
643  periodicPatchName_(pp.periodicPatchName_),
644  periodicPatchID_(-1),
645  nTransforms_(pp.nTransforms_),
646  nSectors_(pp.nSectors_),
647  maxIter_(pp.maxIter_)
648 {}
649 
650 
651 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
652 
654 {}
655 
656 
657 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
658 
660 {
661  if (periodicPatchName_ == word::null)
662  {
663  periodicPatchID_ = -1;
664 
665  return periodicPatchID_;
666  }
667 
668  if (periodicPatchID_ == -1)
669  {
670  periodicPatchID_ = this->boundaryMesh().findPatchID(periodicPatchName_);
671 
672  if (periodicPatchID_ == -1)
673  {
675  << "Illegal periodicPatch name " << periodicPatchName_
676  << nl << "Valid patch names are "
677  << this->boundaryMesh().names()
678  << exit(FatalError);
679  }
680 
681  // Check that it is a coupled patch
682  refCast<const coupledPolyPatch>
683  (
684  this->boundaryMesh()[periodicPatchID_]
685  );
686  }
687 
688  return periodicPatchID_;
689 }
690 
691 
693 {
695 
696  os.writeEntry("periodicPatch", periodicPatchName_);
697  os.writeEntryIfDifferent<label>("nTransforms", 0, nTransforms_);
698  os.writeEntryIfDifferent<label>("nSectors", 0, nSectors_);
699  os.writeEntryIfDifferent<label>("maxIter", 36, maxIter_);
700 }
701 
702 
703 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:71
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::Ostream::writeEntryIfDifferent
Ostream & writeEntryIfDifferent(const word &key, const T &value1, const T &value2)
Write a keyword/value entry only when the two values differ.
Definition: Ostream.H:244
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:52
InfoInFunction
#define InfoInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:325
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::cyclicAMIPolyPatch::owner
virtual bool owner() const
Does this side own the patch?
Definition: cyclicAMIPolyPatch.C:848
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
Foam::polyBoundaryMesh
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Definition: polyBoundaryMesh.H:62
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
PatchTools.H
Foam::gAverage
Type gAverage(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:604
Foam::meshTools::writeOBJ
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of a point.
Definition: meshTools.C:203
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::PatchTools::gatherAndMerge
static void gatherAndMerge(const scalar mergeDist, const PrimitivePatch< FaceList, PointField > &p, Field< typename PrimitivePatch< FaceList, PointField >::point_type > &mergedPoints, List< typename PrimitivePatch< FaceList, PointField >::face_type > &mergedFaces, labelList &pointMergeMap)
Gather points and faces onto master and merge into single patch.
Definition: PatchToolsGatherAndMerge.C:38
Foam::coupledPolyPatch::forwardT
virtual const tensorField & forwardT() const
Return face transformation tensor.
Definition: coupledPolyPatch.H:296
Foam::objectRegistry::time
const Time & time() const
Return time.
Definition: objectRegistry.H:186
Foam::Time::timeName
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:780
Foam::coupledPolyPatch::reverseT
virtual const tensorField & reverseT() const
Return neighbour-cell transformation tensor.
Definition: coupledPolyPatch.H:302
Foam::tensorField
Field< tensor > tensorField
Specialisation of Field<T> for tensor.
Definition: primitiveFieldsFwd.H:57
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:458
Foam::boolList
List< bool > boolList
A List of bools.
Definition: List.H:69
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::cyclicPeriodicAMIPolyPatch::~cyclicPeriodicAMIPolyPatch
virtual ~cyclicPeriodicAMIPolyPatch()
Destructor.
Definition: cyclicPeriodicAMIPolyPatch.C:653
Foam::transform
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
Definition: dimensionSet.C:519
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::vectorField
Field< vector > vectorField
Specialisation of Field<T> for vector.
Definition: primitiveFieldsFwd.H:54
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:51
Foam::cyclicAMIPolyPatch::write
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
Definition: cyclicAMIPolyPatch.C:1109
Foam::polyPatch::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundaryMesh reference.
Definition: polyPatch.C:307
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
DebugInFunction
#define DebugInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:365
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
SeriousErrorInFunction
#define SeriousErrorInFunction
Report an error message using Foam::SeriousError.
Definition: messageStream.H:281
Foam::IOstream::name
virtual const fileName & name() const
Return the name of the stream.
Definition: IOstream.C:39
cyclicPeriodicAMIPolyPatch.H
Foam::dictionary::lookup
ITstream & lookup(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionary.C:424
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::cyclicPeriodicAMIPolyPatch::periodicPatchID
virtual label periodicPatchID() const
Periodic patch ID.
Definition: cyclicPeriodicAMIPolyPatch.C:659
Foam::indent
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:320
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Time.H
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
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:464
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::cyclicPeriodicAMIPolyPatch::cyclicPeriodicAMIPolyPatch
cyclicPeriodicAMIPolyPatch(const word &name, const label size, const label start, const label index, const polyBoundaryMesh &bm, const word &patchType, const transformType transform=UNKNOWN)
Construct from (base coupled patch) components.
Definition: cyclicPeriodicAMIPolyPatch.C:544
Foam::cyclicPeriodicAMIPolyPatch::write
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
Definition: cyclicPeriodicAMIPolyPatch.C:692
Foam::faceList
List< face > faceList
A List of faces.
Definition: faceListFwd.H:47
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::type
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:590
Foam::UList< label >
Foam::sum
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:327
Foam::direction
uint8_t direction
Definition: direction.H:52
Foam::word::null
static const word null
An empty word.
Definition: word.H:77
Foam::Ostream::writeEntry
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:232
Foam::TimePaths::globalPath
fileName globalPath() const
Return global path for the case.
Definition: TimePathsI.H:72
Foam::boundaryMesh
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
Definition: boundaryMesh.H:62
Foam::primitivePatch
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
A PrimitivePatch with a SubList addressing for the faces, const reference for the point field.
Definition: primitivePatch.H:51
Foam::DelaunayMeshTools::allPoints
tmp< pointField > allPoints(const Triangulation &t)
Extract all points in vertex-index order.
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::gMin
Type gMin(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:593
Foam::coupledPolyPatch::transformType
transformType
Definition: coupledPolyPatch.H:59
Foam::cyclicPeriodicAMIPolyPatch
Cyclic patch for periodic Arbitrary Mesh Interface (AMI)
Definition: cyclicPeriodicAMIPolyPatch.H:52
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:122
Foam::coupledPolyPatch::coupledPolyPatch
coupledPolyPatch(const word &name, const label size, const label start, const label index, const polyBoundaryMesh &bm, const word &patchType, const transformType transform)
Construct from components.
Definition: coupledPolyPatch.C:478
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::patchIdentifier::name
const word & name() const
The patch name.
Definition: patchIdentifier.H:134
Foam::gMax
Type gMax(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:592
OBJstream.H
Foam::UPstream::nProcs
static label nProcs(const label communicator=worldComm)
Number of processes in parallel run, and 1 for serial run.
Definition: UPstream.H:446
partialFaceAreaWeightAMI.H
Foam::cyclicAMIPolyPatch
Cyclic patch for Arbitrary Mesh Interface (AMI)
Definition: cyclicAMIPolyPatch.H:67