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-2018 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 
30 
31 // For debugging
32 #include "OBJstream.H"
33 #include "PatchTools.H"
34 #include "Time.H"
35 // Note: cannot use vtkSurfaceWriter here - circular linkage
36 // but foamVtkSurfaceWriter (vtk::surfaceWriter) would be okay.
37 //
38 // #include "foamVtkSurfaceWriter.H"
39 
40 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
41 
42 namespace Foam
43 {
44  defineTypeNameAndDebug(cyclicPeriodicAMIPolyPatch, 0);
45 
46  addToRunTimeSelectionTable(polyPatch, cyclicPeriodicAMIPolyPatch, word);
48  (
49  polyPatch,
50  cyclicPeriodicAMIPolyPatch,
51  dictionary
52  );
53 }
54 
55 
56 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
57 
58 void Foam::cyclicPeriodicAMIPolyPatch::syncTransforms() const
59 {
60  if (owner())
61  {
62  // At this point we guarantee that the transformations have been
63  // updated. There is one particular case, where if the periodic patch
64  // locally has zero faces then its transformation will not be set. We
65  // need to synchronise the transforms over the zero-sized patches as
66  // well.
67  //
68  // We can't put the logic into cyclicPolyPatch as
69  // processorCyclicPolyPatch uses cyclicPolyPatch functionality.
70  // Synchronisation will fail because processor-type patches do not exist
71  // on all processors.
72  //
73  // The use in cyclicPeriodicAMI is special; we use the patch even
74  // though we have no faces in it. Ideally, in future, the transformation
75  // logic will be abstracted out, and we won't need a periodic patch
76  // here. Until then, we can just fix the behaviour of the zero-sized
77  // coupled patches here
78 
79  // Get the periodic patch
80  const coupledPolyPatch& periodicPatch
81  (
82  refCast<const coupledPolyPatch>
83  (
85  )
86  );
87 
88  // If there are any zero-sized periodic patches
89  if (returnReduce((size() && !periodicPatch.size()), orOp<bool>()))
90  {
91  if (periodicPatch.separation().size() > 1)
92  {
94  << "Periodic patch " << periodicPatchName_
95  << " has non-uniform separation vector "
96  << periodicPatch.separation()
97  << "This is not allowed inside " << type()
98  << " patch " << name()
99  << exit(FatalError);
100  }
101 
102  if (periodicPatch.forwardT().size() > 1)
103  {
105  << "Periodic patch " << periodicPatchName_
106  << " has non-uniform transformation tensor "
107  << periodicPatch.forwardT()
108  << "This is not allowed inside " << type()
109  << " patch " << name()
110  << exit(FatalError);
111  }
112 
113  // Note that zero-sized patches will have zero-sized fields for the
114  // separation vector, forward and reverse transforms. These need
115  // replacing with the transformations from other processors.
116 
117  // Parallel in this context refers to a parallel transformation,
118  // rather than a rotational transformation.
119 
120  // Note that a cyclic with zero faces is considered parallel so
121  // explicitly check for that.
122  bool isParallel =
123  (
124  periodicPatch.size()
125  && periodicPatch.parallel()
126  );
127  reduce(isParallel, orOp<bool>());
128 
129  if (isParallel)
130  {
131  // Sync a list of separation vectors
132  List<vectorField> sep(Pstream::nProcs());
133  sep[Pstream::myProcNo()] = periodicPatch.separation();
134  Pstream::gatherList(sep);
136 
137  List<boolList> coll(Pstream::nProcs());
138  coll[Pstream::myProcNo()] = periodicPatch.collocated();
139  Pstream::gatherList(coll);
140  Pstream::scatterList(coll);
141 
142  // If locally we have zero faces pick the first one that has a
143  // separation vector
144  if (!periodicPatch.size())
145  {
146  forAll(sep, procI)
147  {
148  if (sep[procI].size())
149  {
150  const_cast<vectorField&>
151  (
152  periodicPatch.separation()
153  ) = sep[procI];
154  const_cast<boolList&>
155  (
156  periodicPatch.collocated()
157  ) = coll[procI];
158 
159  break;
160  }
161  }
162  }
163  }
164  else
165  {
166  // Sync a list of forward and reverse transforms
167  List<tensorField> forwardT(Pstream::nProcs());
168  forwardT[Pstream::myProcNo()] = periodicPatch.forwardT();
171 
172  List<tensorField> reverseT(Pstream::nProcs());
173  reverseT[Pstream::myProcNo()] = periodicPatch.reverseT();
176 
177  // If locally we have zero faces pick the first one that has a
178  // transformation vector
179  if (!periodicPatch.size())
180  {
181  forAll(forwardT, procI)
182  {
183  if (forwardT[procI].size())
184  {
185  const_cast<tensorField&>
186  (
187  periodicPatch.forwardT()
188  ) = forwardT[procI];
189  const_cast<tensorField&>
190  (
191  periodicPatch.reverseT()
192  ) = reverseT[procI];
193 
194  break;
195  }
196  }
197  }
198  }
199  }
200  }
201 }
202 
203 
204 void Foam::cyclicPeriodicAMIPolyPatch::writeOBJ
205 (
206  const primitivePatch& p,
207  OBJstream& str
208 ) const
209 {
210  // Collect faces and points
212  faceList allFaces;
213  labelList pointMergeMap;
215  (
216  -1.0, // do not merge points
217  p,
218  allPoints,
219  allFaces,
220  pointMergeMap
221  );
222 
223  if (Pstream::master())
224  {
225  // Write base geometry
226  str.write(allFaces, allPoints);
227  }
228 }
229 
230 
231 void Foam::cyclicPeriodicAMIPolyPatch::resetAMI
232 (
234 ) const
235 {
236  if (owner())
237  {
238  // Get the periodic patch
239  const coupledPolyPatch& periodicPatch
240  (
241  refCast<const coupledPolyPatch>
242  (
243  boundaryMesh()[periodicPatchID()]
244  )
245  );
246 
247  // Synchronise the transforms
248  syncTransforms();
249 
250  // Create copies of both patches' points, transformed to the owner
251  pointField thisPoints0(localPoints());
252  pointField nbrPoints0(neighbPatch().localPoints());
253  transformPosition(nbrPoints0);
254 
255  // Reset the stored number of periodic transformations to a lower
256  // absolute value if possible
257  if (nSectors_ > 0)
258  {
259  if (nTransforms_ > nSectors_/2)
260  {
261  nTransforms_ -= nSectors_;
262  }
263  else if (nTransforms_ < - nSectors_/2)
264  {
265  nTransforms_ += nSectors_;
266  }
267  }
268 
269  // Apply the stored number of periodic transforms
270  for (label i = 0; i < nTransforms_; ++ i)
271  {
272  periodicPatch.transformPosition(thisPoints0);
273  }
274  for (label i = 0; i > nTransforms_; -- i)
275  {
276  periodicPatch.transformPosition(nbrPoints0);
277  }
278 
279  autoPtr<OBJstream> ownStr;
280  autoPtr<OBJstream> neiStr;
281  if (debug)
282  {
283  const Time& runTime = boundaryMesh().mesh().time();
284 
285  fileName dir(runTime.globalPath());
286  fileName postfix("_" + runTime.timeName()+"_expanded.obj");
287 
288  ownStr.reset(new OBJstream(dir/name() + postfix));
289  neiStr.reset(new OBJstream(dir/neighbPatch().name() + postfix));
290 
292  << "patch:" << name()
293  << " writing accumulated AMI to " << ownStr().name()
294  << " and " << neiStr().name() << endl;
295  }
296 
297  // Create another copy
298  pointField thisPoints(thisPoints0);
299  pointField nbrPoints(nbrPoints0);
300 
301  // Create patches for all the points
302 
303  // Source patch at initial location
304  const primitivePatch thisPatch0
305  (
306  SubList<face>(localFaces(), size()),
307  thisPoints0
308  );
309  // Source patch that gets moved
310  primitivePatch thisPatch
311  (
312  SubList<face>(localFaces(), size()),
313  thisPoints
314  );
315  // Target patch at initial location
316  const primitivePatch nbrPatch0
317  (
318  SubList<face>(neighbPatch().localFaces(), neighbPatch().size()),
319  nbrPoints0
320  );
321  // Target patch that gets moved
322  primitivePatch nbrPatch
323  (
324  SubList<face>(neighbPatch().localFaces(), neighbPatch().size()),
325  nbrPoints
326  );
327 
328  // Construct a new AMI interpolation between the initial patch locations
329  AMIPtr_.reset
330  (
332  (
333  thisPatch0,
334  nbrPatch0,
335  surfPtr(),
337  false,
339  AMILowWeightCorrection_,
340  AMIReverse_
341  )
342  );
343 
344  // Number of geometry replications
345  label iter(0);
346  label nTransformsOld(nTransforms_);
347 
348  if (ownStr.valid())
349  {
350  writeOBJ(thisPatch0, ownStr());
351  }
352  if (neiStr.valid())
353  {
354  writeOBJ(nbrPatch0, neiStr());
355  }
356 
357 
358  // Weight sum averages
359  scalar srcSum(gAverage(AMIPtr_->srcWeightsSum()));
360  scalar tgtSum(gAverage(AMIPtr_->tgtWeightsSum()));
361 
362  // Direction (or rather side of AMI : this or nbr patch) of
363  // geometry replication
364  bool direction = nTransforms_ >= 0;
365 
366  // Increase in the source weight sum for the last iteration in the
367  // opposite direction. If the current increase is less than this, the
368  // direction (= side of AMI to transform) is reversed.
369  // We switch the side to replicate instead of reversing the transform
370  // since at the coupledPolyPatch level there is no
371  // 'reverseTransformPosition' functionality.
372  scalar srcSumDiff = 0;
373 
374  if (debug)
375  {
377  << "patch:" << name()
378  << " srcSum:" << srcSum
379  << " tgtSum:" << tgtSum
380  << " direction:" << direction
381  << endl;
382  }
383 
384  // Loop, replicating the geometry
385  while
386  (
387  (iter < maxIter_)
388  && (
389  (1 - srcSum > matchTolerance())
390  || (1 - tgtSum > matchTolerance())
391  )
392  )
393  {
394  if (direction)
395  {
396  periodicPatch.transformPosition(thisPoints);
397 
398  if (debug)
399  {
401  << "patch:" << name()
402  << " moving this side from:"
403  << gAverage(thisPatch.points())
404  << " to:" << gAverage(thisPoints) << endl;
405  }
406 
407  thisPatch.movePoints(thisPoints);
408 
409  if (debug)
410  {
412  << "patch:" << name()
413  << " appending weights with untransformed slave side"
414  << endl;
415  }
416 
417  AMIPtr_->append(thisPatch, nbrPatch0);
418 
419  if (ownStr.valid())
420  {
421  writeOBJ(thisPatch, ownStr());
422  }
423  }
424  else
425  {
426  periodicPatch.transformPosition(nbrPoints);
427 
428  if (debug)
429  {
431  << "patch:" << name()
432  << " moving neighbour side from:"
433  << gAverage(nbrPatch.points())
434  << " to:" << gAverage(nbrPoints) << endl;
435  }
436 
437  nbrPatch.movePoints(nbrPoints);
438 
439  AMIPtr_->append(thisPatch0, nbrPatch);
440 
441  if (neiStr.valid())
442  {
443  writeOBJ(nbrPatch, neiStr());
444  }
445  }
446 
447  const scalar srcSumNew = gAverage(AMIPtr_->srcWeightsSum());
448  const scalar srcSumDiffNew = srcSumNew - srcSum;
449 
450  if (srcSumDiffNew < srcSumDiff || srcSumDiffNew < SMALL)
451  {
452  direction = !direction;
453 
454  srcSumDiff = srcSumDiffNew;
455  }
456 
457  srcSum = srcSumNew;
458  tgtSum = gAverage(AMIPtr_->tgtWeightsSum());
459 
460  nTransforms_ += direction ? +1 : -1;
461 
462  ++iter;
463 
464  if (debug)
465  {
467  << "patch:" << name()
468  << " iteration:" << iter
469  << " srcSum:" << srcSum
470  << " tgtSum:" << tgtSum
471  << " direction:" << direction
472  << endl;
473  }
474  }
475 
476 
477  // Close debug streams
478  if (ownStr.valid())
479  {
480  ownStr.clear();
481  }
482  if (neiStr.valid())
483  {
484  neiStr.clear();
485  }
486 
487 
488 
489  // Average the number of transformations
490  nTransforms_ = (nTransforms_ + nTransformsOld)/2;
491 
492  // Check that the match is complete
493  if (iter == maxIter_)
494  {
495  // The matching algorithm has exited without getting the
496  // srcSum and tgtSum above 1. This can happen because
497  // - of an incorrect setup
498  // - or because of non-exact meshes and truncation errors
499  // (transformation, accumulation of cutting errors)
500  // so for now this situation is flagged as a SeriousError instead of
501  // a FatalError since the default matchTolerance is quite strict
502  // (0.001) and can get triggered far into the simulation.
504  << "Patches " << name() << " and " << neighbPatch().name()
505  << " do not couple to within a tolerance of "
506  << matchTolerance()
507  << " when transformed according to the periodic patch "
508  << periodicPatch.name() << "." << nl
509  << "The current sum of weights are for owner " << name()
510  << " : " << srcSum << " and for neighbour "
511  << neighbPatch().name() << " : " << tgtSum << nl
512  << "This is only acceptable during post-processing"
513  << "; not during running. Improve your mesh or increase"
514  << " the 'matchTolerance' setting in the patch specification."
515  << endl;
516  }
517 
518  // Check that both patches have replicated an integer number of times
519  if
520  (
521  mag(srcSum - floor(srcSum + 0.5)) > srcSum*matchTolerance()
522  || mag(tgtSum - floor(tgtSum + 0.5)) > tgtSum*matchTolerance()
523  )
524  {
525  // This condition is currently enforced until there is more
526  // experience with the matching algorithm and numerics.
527  // This check means that e.g. different numbers of stator and
528  // rotor partitions are not allowed.
529  // Again see the section above about tolerances.
531  << "Patches " << name() << " and " << neighbPatch().name()
532  << " do not overlap an integer number of times when transformed"
533  << " according to the periodic patch "
534  << periodicPatch.name() << "." << nl
535  << "The current matchTolerance : " << matchTolerance()
536  << ", sum of owner weights : " << srcSum
537  << ", sum of neighbour weights : " << tgtSum
538  << "." << nl
539  << "This is only acceptable during post-processing"
540  << "; not during running. Improve your mesh or increase"
541  << " the 'matchTolerance' setting in the patch specification."
542  << endl;
543  }
544 
545  // Normalise the weights. Disable printing since weights are
546  // still areas.
547  AMIPtr_->normaliseWeights(true, false);
548 
549  // Print some statistics
550  const label nFace = returnReduce(size(), sumOp<label>());
551 
552  if (nFace)
553  {
554  scalarField srcWghtSum(size(), Zero);
555  forAll(srcWghtSum, faceI)
556  {
557  srcWghtSum[faceI] = sum(AMIPtr_->srcWeights()[faceI]);
558  }
559  scalarField tgtWghtSum(neighbPatch().size(), Zero);
560  forAll(tgtWghtSum, faceI)
561  {
562  tgtWghtSum[faceI] = sum(AMIPtr_->tgtWeights()[faceI]);
563  }
564 
565  Info<< indent
566  << "AMI: Patch " << name()
567  << " sum(weights)"
568  << " min:" << gMin(srcWghtSum)
569  << " max:" << gMax(srcWghtSum)
570  << " average:" << gAverage(srcWghtSum) << nl;
571  Info<< indent
572  << "AMI: Patch " << neighbPatch().name()
573  << " sum(weights)"
574  << " min:" << gMin(tgtWghtSum)
575  << " max:" << gMax(tgtWghtSum)
576  << " average:" << gAverage(tgtWghtSum) << nl;
577  }
578  }
579 }
580 
581 
582 // * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * //
583 
585 (
586  const word& name,
587  const label size,
588  const label start,
589  const label index,
590  const polyBoundaryMesh& bm,
591  const word& patchType,
593 )
594 :
595  cyclicAMIPolyPatch(name, size, start, index, bm, patchType, transform),
596  periodicPatchName_(word::null),
597  periodicPatchID_(-1),
598  nTransforms_(0),
599  nSectors_(0),
600  maxIter_(36)
601 {}
602 
603 
605 (
606  const word& name,
607  const dictionary& dict,
608  const label index,
609  const polyBoundaryMesh& bm,
610  const word& patchType
611 )
612 :
613  cyclicAMIPolyPatch(name, dict, index, bm, patchType),
614  periodicPatchName_(dict.lookup("periodicPatch")),
615  periodicPatchID_(-1),
616  nTransforms_(dict.lookupOrDefault<label>("nTransforms", 0)),
617  nSectors_(dict.lookupOrDefault<label>("nSectors", 0)),
618  maxIter_(dict.lookupOrDefault<label>("maxIter", 36))
619 {}
620 
621 
623 (
624  const cyclicPeriodicAMIPolyPatch& pp,
625  const polyBoundaryMesh& bm
626 )
627 :
628  cyclicAMIPolyPatch(pp, bm),
629  periodicPatchName_(pp.periodicPatchName_),
630  periodicPatchID_(-1),
631  nTransforms_(pp.nTransforms_),
632  nSectors_(pp.nSectors_),
633  maxIter_(pp.maxIter_)
634 {}
635 
636 
638 (
639  const cyclicPeriodicAMIPolyPatch& pp,
640  const polyBoundaryMesh& bm,
641  const label index,
642  const label newSize,
643  const label newStart,
644  const word& nbrPatchName
645 )
646 :
647  cyclicAMIPolyPatch(pp, bm, index, newSize, newStart, nbrPatchName),
648  periodicPatchName_(pp.periodicPatchName_),
649  periodicPatchID_(-1),
650  nTransforms_(pp.nTransforms_),
651  nSectors_(pp.nSectors_),
652  maxIter_(pp.maxIter_)
653 {}
654 
655 
657 (
658  const cyclicPeriodicAMIPolyPatch& pp,
659  const polyBoundaryMesh& bm,
660  const label index,
661  const labelUList& mapAddressing,
662  const label newStart
663 )
664 :
665  cyclicAMIPolyPatch(pp, bm, index, mapAddressing, newStart),
666  periodicPatchName_(pp.periodicPatchName_),
667  periodicPatchID_(-1),
668  nTransforms_(pp.nTransforms_),
669  nSectors_(pp.nSectors_),
670  maxIter_(pp.maxIter_)
671 {}
672 
673 
674 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
675 
677 {}
678 
679 
680 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
681 
683 {
684  if (periodicPatchName_ == word::null)
685  {
686  periodicPatchID_ = -1;
687 
688  return periodicPatchID_;
689  }
690 
691  if (periodicPatchID_ == -1)
692  {
693  periodicPatchID_ = this->boundaryMesh().findPatchID(periodicPatchName_);
694 
695  if (periodicPatchID_ == -1)
696  {
698  << "Illegal periodicPatch name " << periodicPatchName_
699  << nl << "Valid patch names are "
700  << this->boundaryMesh().names()
701  << exit(FatalError);
702  }
703 
704  // Check that it is a coupled patch
705  refCast<const coupledPolyPatch>
706  (
707  this->boundaryMesh()[periodicPatchID_]
708  );
709  }
710 
711  return periodicPatchID_;
712 }
713 
714 
716 {
718 
719  os.writeEntry("periodicPatch", periodicPatchName_);
720  os.writeEntryIfDifferent<label>("nTransforms", 0, nTransforms_);
721  os.writeEntryIfDifferent<label>("nSectors", 0, nSectors_);
722  os.writeEntryIfDifferent<label>("maxIter", 36, maxIter_);
723 }
724 
725 
726 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
Foam::AMIInterpolation::interpolationMethod
interpolationMethod
Enumeration specifying interpolation method.
Definition: AMIInterpolation.H:90
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:74
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:231
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:316
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::cyclicAMIPolyPatch::owner
virtual bool owner() const
Does this side own the patch?
Definition: cyclicAMIPolyPatch.C:751
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.
Definition: zero.H:128
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::coupledPolyPatch::forwardT
virtual const tensorField & forwardT() const
Return face transformation tensor.
Definition: coupledPolyPatch.H:296
Foam::UPstream::nProcs
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:426
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:764
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::boolList
List< bool > boolList
A List of bools.
Definition: List.H:72
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::dictionary::lookupOrDefault
T lookupOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionary.H:1241
Foam::cyclicPeriodicAMIPolyPatch::~cyclicPeriodicAMIPolyPatch
virtual ~cyclicPeriodicAMIPolyPatch()
Destructor.
Definition: cyclicPeriodicAMIPolyPatch.C:676
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:290
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::label
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:62
Foam::cyclicAMIPolyPatch::write
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
Definition: cyclicAMIPolyPatch.C:1044
Foam::polyPatch::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundaryMesh reference.
Definition: polyPatch.C:305
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
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:272
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:419
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
Foam::AMIPatchToPatchInterpolation
AMIInterpolation< PrimitivePatch< face, SubList, const pointField & >, PrimitivePatch< face, SubList, const pointField & > > AMIPatchToPatchInterpolation
Definition: AMIPatchToPatchInterpolation.H:45
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:682
Foam::indent
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:307
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:444
Foam::UPstream::master
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:438
Time.H
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
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::nl
constexpr char nl
Definition: Ostream.H:372
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:585
Foam::cyclicPeriodicAMIPolyPatch::write
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
Definition: cyclicPeriodicAMIPolyPatch.C:715
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::start
label ListType::const_reference const label start
Definition: ListOps.H:408
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:47
Foam::word::null
static const word null
An empty word.
Definition: word.H:77
Foam::AMIInterpolation::imPartialFaceAreaWeight
Definition: AMIInterpolation.H:95
Foam::Ostream::writeEntry
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:219
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:61
Foam::primitivePatch
PrimitivePatch< face, SubList, const pointField & > primitivePatch
Addressing for a faceList slice.
Definition: primitivePatch.H:47
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::PatchTools::gatherAndMerge
static void gatherAndMerge(const scalar mergeDist, const PrimitivePatch< Face, FaceList, PointField, PointType > &p, Field< PointType > &mergedPoints, List< Face > &mergedFaces, labelList &pointMergeMap)
Gather points and faces onto master and merge into single patch.
Definition: PatchToolsGatherAndMerge.C:44
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:477
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::patchIdentifier::name
const word & name() const
Return the patch name.
Definition: patchIdentifier.H:109
Foam::gMax
Type gMax(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:592
OBJstream.H
Foam::faceAreaIntersect::tmMesh
Definition: faceAreaIntersect.H:65
Foam::cyclicAMIPolyPatch
Cyclic patch for Arbitrary Mesh Interface (AMI)
Definition: cyclicAMIPolyPatch.H:53