Go to the documentation of this file.
50 cyclicPeriodicAMIPolyPatch,
58 void Foam::cyclicPeriodicAMIPolyPatch::syncTransforms()
const
82 refCast<const coupledPolyPatch>
89 if (
returnReduce((size() && !periodicPatch.size()), orOp<bool>()))
91 if (periodicPatch.separation().size() > 1)
94 <<
"Periodic patch " << periodicPatchName_
95 <<
" has non-uniform separation vector "
96 << periodicPatch.separation()
97 <<
"This is not allowed inside " <<
type()
98 <<
" patch " <<
name()
102 if (periodicPatch.forwardT().size() > 1)
105 <<
"Periodic patch " << periodicPatchName_
106 <<
" has non-uniform transformation tensor "
107 << periodicPatch.forwardT()
108 <<
"This is not allowed inside " <<
type()
109 <<
" patch " <<
name()
125 && periodicPatch.parallel()
127 reduce(isParallel, orOp<bool>());
144 if (!periodicPatch.size())
148 if (sep[procI].size())
152 periodicPatch.separation()
156 periodicPatch.collocated()
179 if (!periodicPatch.size())
187 periodicPatch.forwardT()
191 periodicPatch.reverseT()
204 void Foam::cyclicPeriodicAMIPolyPatch::writeOBJ
231 void Foam::cyclicPeriodicAMIPolyPatch::resetAMI
239 const coupledPolyPatch& periodicPatch
241 refCast<const coupledPolyPatch>
243 boundaryMesh()[periodicPatchID()]
252 pointField nbrPoints0(neighbPatch().localPoints());
253 transformPosition(nbrPoints0);
259 if (nTransforms_ > nSectors_/2)
261 nTransforms_ -= nSectors_;
263 else if (nTransforms_ < - nSectors_/2)
265 nTransforms_ += nSectors_;
270 for (
label i = 0; i < nTransforms_; ++ i)
272 periodicPatch.transformPosition(thisPoints0);
274 for (
label i = 0; i > nTransforms_; -- i)
276 periodicPatch.transformPosition(nbrPoints0);
279 autoPtr<OBJstream> ownStr;
280 autoPtr<OBJstream> neiStr;
283 const Time&
runTime = boundaryMesh().mesh().
time();
288 ownStr.reset(
new OBJstream(dir/
name() + postfix));
289 neiStr.reset(
new OBJstream(dir/neighbPatch().
name() + postfix));
292 <<
"patch:" <<
name()
293 <<
" writing accumulated AMI to " << ownStr().name()
294 <<
" and " << neiStr().name() <<
endl;
306 SubList<face>(localFaces(), size()),
312 SubList<face>(localFaces(), size()),
318 SubList<face>(neighbPatch().localFaces(), neighbPatch().size()),
324 SubList<face>(neighbPatch().localFaces(), neighbPatch().size()),
339 AMILowWeightCorrection_,
346 label nTransformsOld(nTransforms_);
359 scalar srcSum(
gAverage(AMIPtr_->srcWeightsSum()));
360 scalar tgtSum(
gAverage(AMIPtr_->tgtWeightsSum()));
372 scalar srcSumDiff = 0;
377 <<
"patch:" <<
name()
378 <<
" srcSum:" << srcSum
379 <<
" tgtSum:" << tgtSum
389 (1 - srcSum > matchTolerance())
390 || (1 - tgtSum > matchTolerance())
396 periodicPatch.transformPosition(thisPoints);
401 <<
"patch:" <<
name()
402 <<
" moving this side from:"
407 thisPatch.movePoints(thisPoints);
412 <<
"patch:" <<
name()
413 <<
" appending weights with untransformed slave side"
417 AMIPtr_->append(thisPatch, nbrPatch0);
426 periodicPatch.transformPosition(nbrPoints);
431 <<
"patch:" <<
name()
432 <<
" moving neighbour side from:"
437 nbrPatch.movePoints(nbrPoints);
439 AMIPtr_->append(thisPatch0, nbrPatch);
447 const scalar srcSumNew =
gAverage(AMIPtr_->srcWeightsSum());
448 const scalar srcSumDiffNew = srcSumNew - srcSum;
450 if (srcSumDiffNew < srcSumDiff || srcSumDiffNew < SMALL)
454 srcSumDiff = srcSumDiffNew;
458 tgtSum =
gAverage(AMIPtr_->tgtWeightsSum());
467 <<
"patch:" <<
name()
468 <<
" iteration:" << iter
469 <<
" srcSum:" << srcSum
470 <<
" tgtSum:" << tgtSum
490 nTransforms_ = (nTransforms_ + nTransformsOld)/2;
493 if (iter == maxIter_)
504 <<
"Patches " <<
name() <<
" and " << neighbPatch().name()
505 <<
" do not couple to within a tolerance of "
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."
521 mag(srcSum - floor(srcSum + 0.5)) > srcSum*matchTolerance()
522 ||
mag(tgtSum - floor(tgtSum + 0.5)) > tgtSum*matchTolerance()
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
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."
547 AMIPtr_->normaliseWeights(
true,
false);
557 srcWghtSum[faceI] =
sum(AMIPtr_->srcWeights()[faceI]);
562 tgtWghtSum[faceI] =
sum(AMIPtr_->tgtWeights()[faceI]);
566 <<
"AMI: Patch " <<
name()
568 <<
" min:" <<
gMin(srcWghtSum)
569 <<
" max:" <<
gMax(srcWghtSum)
572 <<
"AMI: Patch " << neighbPatch().
name()
574 <<
" min:" <<
gMin(tgtWghtSum)
575 <<
" max:" <<
gMax(tgtWghtSum)
591 const word& patchType,
597 periodicPatchID_(-1),
610 const word& patchType
614 periodicPatchName_(
dict.
lookup(
"periodicPatch")),
615 periodicPatchID_(-1),
629 periodicPatchName_(pp.periodicPatchName_),
630 periodicPatchID_(-1),
631 nTransforms_(pp.nTransforms_),
632 nSectors_(pp.nSectors_),
633 maxIter_(pp.maxIter_)
643 const label newStart,
644 const word& nbrPatchName
648 periodicPatchName_(pp.periodicPatchName_),
649 periodicPatchID_(-1),
650 nTransforms_(pp.nTransforms_),
651 nSectors_(pp.nSectors_),
652 maxIter_(pp.maxIter_)
666 periodicPatchName_(pp.periodicPatchName_),
667 periodicPatchID_(-1),
668 nTransforms_(pp.nTransforms_),
669 nSectors_(pp.nSectors_),
670 maxIter_(pp.maxIter_)
686 periodicPatchID_ = -1;
688 return periodicPatchID_;
691 if (periodicPatchID_ == -1)
693 periodicPatchID_ = this->
boundaryMesh().findPatchID(periodicPatchName_);
695 if (periodicPatchID_ == -1)
698 <<
"Illegal periodicPatch name " << periodicPatchName_
699 <<
nl <<
"Valid patch names are "
705 refCast<const coupledPolyPatch>
711 return periodicPatchID_;
719 os.
writeEntry(
"periodicPatch", periodicPatchName_);
int debug
Static debugging option.
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
interpolationMethod
Enumeration specifying interpolation method.
List< label > labelList
A List of labels.
vectorField pointField
pointField is a vectorField.
Ostream & writeEntryIfDifferent(const word &key, const T &value1, const T &value2)
Write a keyword/value entry only when the two values differ.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
#define InfoInFunction
Report an information message using Foam::Info.
virtual bool owner() const
Does this side own the patch?
A class for handling words, derived from Foam::string.
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
static constexpr const zero Zero
Global zero.
Type gAverage(const FieldField< Field, Type > &f)
static void scatterList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Scatter data. Reverse of gatherList.
virtual const tensorField & forwardT() const
Return face transformation tensor.
static label nProcs(const label communicator=0)
Number of processes in parallel run.
const Time & time() const
Return time.
static word timeName(const scalar t, const int precision=precision_)
virtual const tensorField & reverseT() const
Return neighbour-cell transformation tensor.
Field< tensor > tensorField
Specialisation of Field<T> for tensor.
List< bool > boolList
A List of bools.
Ostream & endl(Ostream &os)
Add newline and flush stream.
T lookupOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
virtual ~cyclicPeriodicAMIPolyPatch()
Destructor.
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
#define forAll(list, i)
Loop across all elements in list.
Field< vector > vectorField
Specialisation of Field<T> for vector.
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
const polyBoundaryMesh & boundaryMesh() const
Return boundaryMesh reference.
messageStream Info
Information stream (uses stdout - output is on the master only)
word name(const complex &c)
Return string representation of complex.
#define SeriousErrorInFunction
Report an error message using Foam::SeriousError.
virtual const fileName & name() const
Return the name of the stream.
ITstream & lookup(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
AMIInterpolation< PrimitivePatch< face, SubList, const pointField & >, PrimitivePatch< face, SubList, const pointField & > > AMIPatchToPatchInterpolation
Macros for easy insertion into run-time selection tables.
virtual label periodicPatchID() const
Periodic patch ID.
Ostream & indent(Ostream &os)
Indent stream.
errorManipArg< error, int > exit(error &err, const int errNo=1)
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
static bool master(const label communicator=0)
Am I the master process.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
static void gatherList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Gather data but keep individual values separate.
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.
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
List< face > faceList
A List of faces.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
label ListType::const_reference const label start
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
static const word null
An empty word.
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
fileName globalPath() const
Return global path for the case.
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
PrimitivePatch< face, SubList, const pointField & > primitivePatch
Addressing for a faceList slice.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Type gMin(const FieldField< Field, Type > &f)
Cyclic patch for periodic Arbitrary Mesh Interface (AMI)
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.
defineTypeNameAndDebug(combustionModel, 0)
const word & name() const
Return the patch name.
Type gMax(const FieldField< Field, Type > &f)
Cyclic patch for Arbitrary Mesh Interface (AMI)