Go to the documentation of this file.
51 cyclicPeriodicAMIPolyPatch,
59 void Foam::cyclicPeriodicAMIPolyPatch::syncTransforms()
const
83 refCast<const coupledPolyPatch>
90 if (
returnReduce((size() && !periodicPatch.size()), orOp<bool>()))
92 if (periodicPatch.separation().size() > 1)
95 <<
"Periodic patch " << periodicPatchName_
96 <<
" has non-uniform separation vector "
97 << periodicPatch.separation()
98 <<
"This is not allowed inside " <<
type()
99 <<
" patch " <<
name()
103 if (periodicPatch.forwardT().size() > 1)
106 <<
"Periodic patch " << periodicPatchName_
107 <<
" has non-uniform transformation tensor "
108 << periodicPatch.forwardT()
109 <<
"This is not allowed inside " <<
type()
110 <<
" patch " <<
name()
126 && periodicPatch.parallel()
128 reduce(isParallel, orOp<bool>());
145 if (!periodicPatch.size())
149 if (sep[procI].size())
153 periodicPatch.separation()
157 periodicPatch.collocated()
180 if (!periodicPatch.size())
188 periodicPatch.forwardT()
192 periodicPatch.reverseT()
205 void Foam::cyclicPeriodicAMIPolyPatch::writeOBJ
232 void Foam::cyclicPeriodicAMIPolyPatch::resetAMI()
const
237 const coupledPolyPatch& periodicPatch
239 refCast<const coupledPolyPatch>
241 boundaryMesh()[periodicPatchID()]
250 pointField nbrPoints0(neighbPatch().localPoints());
251 transformPosition(nbrPoints0);
257 if (nTransforms_ > nSectors_/2)
259 nTransforms_ -= nSectors_;
261 else if (nTransforms_ < - nSectors_/2)
263 nTransforms_ += nSectors_;
268 for (label i = 0; i < nTransforms_; ++ i)
270 periodicPatch.transformPosition(thisPoints0);
272 for (label i = 0; i > nTransforms_; -- i)
274 periodicPatch.transformPosition(nbrPoints0);
277 autoPtr<OBJstream> ownStr;
278 autoPtr<OBJstream> neiStr;
281 const Time&
runTime = boundaryMesh().mesh().
time();
286 ownStr.reset(
new OBJstream(dir/
name() + postfix));
287 neiStr.reset(
new OBJstream(dir/neighbPatch().
name() + postfix));
290 <<
"patch:" <<
name()
291 <<
" writing accumulated AMI to " << ownStr().name()
292 <<
" and " << neiStr().name() <<
endl;
304 SubList<face>(localFaces(), size()),
310 SubList<face>(localFaces(), size()),
316 SubList<face>(neighbPatch().localFaces(), neighbPatch().size()),
322 SubList<face>(neighbPatch().localFaces(), neighbPatch().size()),
327 AMIPtr_->setRequireMatch(
false);
328 AMIPtr_->calculate(thisPatch0, nbrPatch0, surfPtr());
332 label nTransformsOld(nTransforms_);
345 scalar srcSum(
gAverage(AMIPtr_->srcWeightsSum()));
346 scalar tgtSum(
gAverage(AMIPtr_->tgtWeightsSum()));
357 scalar srcSumDiff = 0;
360 <<
"patch:" <<
name()
361 <<
" srcSum:" << srcSum
362 <<
" tgtSum:" << tgtSum
371 (1 - srcSum > matchTolerance())
372 || (1 - tgtSum > matchTolerance())
378 periodicPatch.transformPosition(thisPoints);
381 <<
"patch:" <<
name()
382 <<
" moving this side from:"
386 thisPatch.movePoints(thisPoints);
389 <<
"patch:" <<
name()
390 <<
" appending weights with untransformed slave side"
393 AMIPtr_->append(thisPatch, nbrPatch0);
402 periodicPatch.transformPosition(nbrPoints);
405 <<
"patch:" <<
name()
406 <<
" moving neighbour side from:"
410 nbrPatch.movePoints(nbrPoints);
412 AMIPtr_->append(thisPatch0, nbrPatch);
420 const scalar srcSumNew =
gAverage(AMIPtr_->srcWeightsSum());
421 const scalar srcSumDiffNew = srcSumNew - srcSum;
423 if (srcSumDiffNew < srcSumDiff || srcSumDiffNew < SMALL)
427 srcSumDiff = srcSumDiffNew;
431 tgtSum =
gAverage(AMIPtr_->tgtWeightsSum());
438 <<
"patch:" <<
name()
439 <<
" iteration:" << iter
440 <<
" srcSum:" << srcSum
441 <<
" tgtSum:" << tgtSum
460 nTransforms_ = (nTransforms_ + nTransformsOld)/2;
463 if (iter == maxIter_)
474 <<
"Patches " <<
name() <<
" and " << neighbPatch().name()
475 <<
" do not couple to within a tolerance of "
477 <<
" when transformed according to the periodic patch "
478 << periodicPatch.name() <<
"." <<
nl
479 <<
"The current sum of weights are for owner " <<
name()
480 <<
" : " << srcSum <<
" and for neighbour "
481 << neighbPatch().name() <<
" : " << tgtSum <<
nl
482 <<
"This is only acceptable during post-processing"
483 <<
"; not during running. Improve your mesh or increase"
484 <<
" the 'matchTolerance' setting in the patch specification."
491 mag(srcSum - floor(srcSum + 0.5)) > srcSum*matchTolerance()
492 ||
mag(tgtSum - floor(tgtSum + 0.5)) > tgtSum*matchTolerance()
501 <<
"Patches " <<
name() <<
" and " << neighbPatch().name()
502 <<
" do not overlap an integer number of times when transformed"
503 <<
" according to the periodic patch "
504 << periodicPatch.name() <<
"." <<
nl
505 <<
"The current matchTolerance : " << matchTolerance()
506 <<
", sum of owner weights : " << srcSum
507 <<
", sum of neighbour weights : " << tgtSum
509 <<
"This is only acceptable during post-processing"
510 <<
"; not during running. Improve your mesh or increase"
511 <<
" the 'matchTolerance' setting in the patch specification."
516 const label nFace =
returnReduce(size(), sumOp<label>());
523 srcWghtSum[faceI] =
sum(AMIPtr_->srcWeights()[faceI]);
528 tgtWghtSum[faceI] =
sum(AMIPtr_->tgtWeights()[faceI]);
532 <<
"AMI: Patch " <<
name()
534 <<
" min:" <<
gMin(srcWghtSum)
535 <<
" max:" <<
gMax(srcWghtSum)
538 <<
"AMI: Patch " << neighbPatch().
name()
540 <<
" min:" <<
gMin(tgtWghtSum)
541 <<
" max:" <<
gMax(tgtWghtSum)
557 const word& patchType,
570 partialFaceAreaWeightAMI::typeName
573 periodicPatchID_(-1),
586 const word& patchType
596 partialFaceAreaWeightAMI::typeName
598 periodicPatchName_(
dict.
lookup(
"periodicPatch")),
599 periodicPatchID_(-1),
613 periodicPatchName_(pp.periodicPatchName_),
614 periodicPatchID_(-1),
615 nTransforms_(pp.nTransforms_),
616 nSectors_(pp.nSectors_),
617 maxIter_(pp.maxIter_)
627 const label newStart,
628 const word& nbrPatchName
632 periodicPatchName_(pp.periodicPatchName_),
633 periodicPatchID_(-1),
634 nTransforms_(pp.nTransforms_),
635 nSectors_(pp.nSectors_),
636 maxIter_(pp.maxIter_)
650 periodicPatchName_(pp.periodicPatchName_),
651 periodicPatchID_(-1),
652 nTransforms_(pp.nTransforms_),
653 nSectors_(pp.nSectors_),
654 maxIter_(pp.maxIter_)
670 periodicPatchID_ = -1;
672 return periodicPatchID_;
675 if (periodicPatchID_ == -1)
677 periodicPatchID_ = this->
boundaryMesh().findPatchID(periodicPatchName_);
679 if (periodicPatchID_ == -1)
682 <<
"Illegal periodicPatch name " << periodicPatchName_
683 <<
nl <<
"Valid patch names are "
689 refCast<const coupledPolyPatch>
695 return periodicPatchID_;
703 os.
writeEntry(
"periodicPatch", periodicPatchName_);
int debug
Static debugging option.
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
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 (0)
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.
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)
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)
#define DebugInFunction
Report an information message using Foam::Info.
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,...
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)
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< SubList< face >, const pointField & > primitivePatch
A PrimitivePatch with a SubList addressing for the faces, const reference for the point field.
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)
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
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
The patch name.
Type gMax(const FieldField< Field, Type > &f)
Cyclic patch for Arbitrary Mesh Interface (AMI)