50 cyclicPeriodicAMIPolyPatch,
58 void Foam::cyclicPeriodicAMIPolyPatch::syncTransforms()
const 82 refCast<const coupledPolyPatch>
91 if (periodicPatch.separation().size() > 1)
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)
106 <<
" has non-uniform transformation tensor " 107 << periodicPatch.forwardT()
108 <<
"This is not allowed inside " <<
type()
109 <<
" patch " <<
name()
127 periodicPatch.size() && periodicPatch.parallel()
142 if (!periodicPatch.size())
146 if (sep[procI].size())
150 periodicPatch.separation()
154 periodicPatch.collocated()
175 if (!periodicPatch.size())
183 periodicPatch.forwardT()
187 periodicPatch.reverseT()
200 void Foam::cyclicPeriodicAMIPolyPatch::writeOBJ
225 void Foam::cyclicPeriodicAMIPolyPatch::resetAMI()
const 230 const coupledPolyPatch& periodicPatch
232 refCast<const coupledPolyPatch>
234 boundaryMesh()[periodicPatchID()]
243 pointField nbrPoints0(neighbPatch().localPoints());
244 transformPosition(nbrPoints0);
250 if (nTransforms_ > nSectors_/2)
252 nTransforms_ -= nSectors_;
254 else if (nTransforms_ < - nSectors_/2)
256 nTransforms_ += nSectors_;
261 for (label i = 0; i < nTransforms_; ++ i)
263 periodicPatch.transformPosition(thisPoints0);
265 for (label i = 0; i > nTransforms_; -- i)
267 periodicPatch.transformPosition(nbrPoints0);
270 autoPtr<OBJstream> ownStr;
271 autoPtr<OBJstream> neiStr;
274 const Time&
runTime = boundaryMesh().mesh().
time();
279 ownStr.reset(
new OBJstream(dir/
name() + postfix));
280 neiStr.reset(
new OBJstream(dir/neighbPatch().
name() + postfix));
283 <<
"patch:" <<
name()
284 <<
" writing accumulated AMI to " << ownStr().name()
285 <<
" and " << neiStr().name() <<
endl;
297 SubList<face>(localFaces(), size()),
303 SubList<face>(localFaces(), size()),
309 SubList<face>(neighbPatch().localFaces(), neighbPatch().size()),
315 SubList<face>(neighbPatch().localFaces(), neighbPatch().size()),
320 AMIPtr_->setRequireMatch(
false);
321 AMIPtr_->calculate(thisPatch0, nbrPatch0, surfPtr());
325 label nTransformsOld(nTransforms_);
338 scalar srcSum(
gAverage(AMIPtr_->srcWeightsSum()));
339 scalar tgtSum(
gAverage(AMIPtr_->tgtWeightsSum()));
350 scalar srcSumDiff = 0;
353 <<
"patch:" <<
name()
354 <<
" srcSum:" << srcSum
355 <<
" tgtSum:" << tgtSum
364 (1 - srcSum > matchTolerance())
365 || (1 - tgtSum > matchTolerance())
371 periodicPatch.transformPosition(thisPoints);
374 <<
"patch:" <<
name()
375 <<
" moving this side from:" 379 thisPatch.movePoints(thisPoints);
382 <<
"patch:" <<
name()
383 <<
" appending weights with untransformed slave side" 386 AMIPtr_->append(thisPatch, nbrPatch0);
395 periodicPatch.transformPosition(nbrPoints);
398 <<
"patch:" <<
name()
399 <<
" moving neighbour side from:" 403 nbrPatch.movePoints(nbrPoints);
405 AMIPtr_->append(thisPatch0, nbrPatch);
413 const scalar srcSumNew =
gAverage(AMIPtr_->srcWeightsSum());
414 const scalar srcSumDiffNew = srcSumNew - srcSum;
416 if (srcSumDiffNew < srcSumDiff || srcSumDiffNew < SMALL)
420 srcSumDiff = srcSumDiffNew;
424 tgtSum =
gAverage(AMIPtr_->tgtWeightsSum());
431 <<
"patch:" <<
name()
432 <<
" iteration:" << iter
433 <<
" srcSum:" << srcSum
434 <<
" tgtSum:" << tgtSum
441 ownStr.reset(
nullptr);
442 neiStr.reset(
nullptr);
446 nTransforms_ = (nTransforms_ + nTransformsOld)/2;
449 if (iter == maxIter_)
460 <<
"Patches " <<
name() <<
" and " << neighbPatch().name()
461 <<
" do not couple to within a tolerance of " 463 <<
" when transformed according to the periodic patch " 464 << periodicPatch.name() <<
"." <<
nl 465 <<
"The current sum of weights are for owner " <<
name()
466 <<
" : " << srcSum <<
" and for neighbour " 467 << neighbPatch().name() <<
" : " << tgtSum <<
nl 468 <<
"This is only acceptable during post-processing" 469 <<
"; not during running. Improve your mesh or increase" 470 <<
" the 'matchTolerance' setting in the patch specification." 477 mag(srcSum - floor(srcSum + 0.5)) > srcSum*matchTolerance()
478 ||
mag(tgtSum - floor(tgtSum + 0.5)) > tgtSum*matchTolerance()
487 <<
"Patches " <<
name() <<
" and " << neighbPatch().name()
488 <<
" do not overlap an integer number of times when transformed" 489 <<
" according to the periodic patch " 490 << periodicPatch.name() <<
"." <<
nl 491 <<
"The current matchTolerance : " << matchTolerance()
492 <<
", sum of owner weights : " << srcSum
493 <<
", sum of neighbour weights : " << tgtSum
495 <<
"This is only acceptable during post-processing" 496 <<
"; not during running. Improve your mesh or increase" 497 <<
" the 'matchTolerance' setting in the patch specification." 507 srcWghtSum[faceI] =
sum(AMIPtr_->srcWeights()[faceI]);
512 tgtWghtSum[faceI] =
sum(AMIPtr_->tgtWeights()[faceI]);
516 <<
"AMI: Patch " <<
name()
518 <<
" min:" <<
gMin(srcWghtSum)
519 <<
" max:" <<
gMax(srcWghtSum)
522 <<
"AMI: Patch " << neighbPatch().
name()
524 <<
" min:" <<
gMin(tgtWghtSum)
525 <<
" max:" <<
gMax(tgtWghtSum)
540 const polyBoundaryMesh& bm,
541 const word& patchType,
554 faceAreaWeightAMI::typeName
560 AMIPtr_->setRequireMatch(
false);
570 const word& patchType
582 nTransforms_(
dict.getOrDefault<label>(
"nTransforms", 0)),
583 nSectors_(
dict.getOrDefault<label>(
"nSectors", 0)),
584 maxIter_(
dict.getOrDefault<label>(
"maxIter", 36))
586 AMIPtr_->setRequireMatch(
false);
597 nTransforms_(
pp.nTransforms_),
598 nSectors_(
pp.nSectors_),
599 maxIter_(
pp.maxIter_)
601 AMIPtr_->setRequireMatch(
false);
611 const label newStart,
612 const word& nbrPatchName
616 nTransforms_(
pp.nTransforms_),
617 nSectors_(
pp.nSectors_),
618 maxIter_(
pp.maxIter_)
620 AMIPtr_->setRequireMatch(
false);
634 nTransforms_(
pp.nTransforms_),
635 nSectors_(
pp.nSectors_),
636 maxIter_(
pp.maxIter_)
638 AMIPtr_->setRequireMatch(
false);
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1)
Ostream & indent(Ostream &os)
Indent stream.
virtual const fileName & name() const
The name of the stream.
errorManipArg< error, int > exit(error &err, const int errNo=1)
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.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Type gMin(const FieldField< Field, Type > &f)
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.
constexpr char nl
The newline '\n' character (0x0a)
virtual ~cyclicPeriodicAMIPolyPatch()
Destructor.
Ostream & endl(Ostream &os)
Add newline and flush stream.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Macros for easy insertion into run-time selection tables.
virtual const tensorField & forwardT() const
Return face transformation tensor.
#define SeriousErrorInFunction
Report an error message using Foam::SeriousError.
#define forAll(list, i)
Loop across all elements in list.
Face area weighted Arbitrary Mesh Interface (AMI) method.
static void allGatherList(List< T > &values, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Gather data, but keep individual values separate. Uses linear/tree communication. ...
List< face > faceList
List of faces.
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
vectorField pointField
pointField is a vectorField.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundaryMesh reference.
fileName globalPath() const
Return global path for the case = rootPath/globalCaseName. Same as TimePaths::globalPath() ...
A class for handling words, derived from Foam::string.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
const Time & time() const noexcept
Return time registry.
#define DebugInFunction
Report an information message using Foam::Info.
word periodicPatchName_
Periodic patch name.
Cyclic patch for Arbitrary Mesh Interface (AMI)
label periodicPatchID() const
Periodic patch ID (or -1)
Ostream & writeEntryIfDifferent(const word &key, const T &value1, const T &value2)
Write a keyword/value entry only when the two values differ.
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO...
const word & name() const noexcept
The patch name.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
static word timeName(const scalar t, const int precision=precision_)
Return a time name for the given scalar time value formatted with the given precision.
int debug
Static debugging option.
Type gMax(const FieldField< Field, Type > &f)
OBJstream os(runTime.globalPath()/outputName)
defineTypeNameAndDebug(combustionModel, 0)
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
A PrimitivePatch with a SubList addressing for the faces, const reference for the point field...
Field< tensor > tensorField
Specialisation of Field<T> for tensor.
virtual const tensorField & reverseT() const
Return neighbour-cell transformation tensor.
Type gAverage(const FieldField< Field, Type > &f)
virtual bool owner() const
Does this side own the patch?
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Cyclic patch for periodic Arbitrary Mesh Interface (AMI)
Field< vector > vectorField
Specialisation of Field<T> for vector.
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
List< bool > boolList
A List of bools.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
addToRunTimeSelectionTable(functionObject, pointHistory, dictionary)
#define InfoInFunction
Report an information message using Foam::Info.
static constexpr const zero Zero
Global zero (0)