44 Foam::vector Foam::cyclicAMIPolyPatch::findFaceNormalMaxRadius
51 const vectorField n((faceCentres - rotationCentre_) ^ rotationAxis_);
59 Info<<
"findFaceMaxRadius(const pointField&) : patch: " <<
name() <<
nl 60 <<
" rotFace = " << faceI <<
nl 61 <<
" point = " << faceCentres[faceI] <<
nl 62 <<
" distance = " <<
Foam::sqrt(magRadSqr[faceI])
78 half0Areas[facei] = half0[facei].normal(half0.
points());
85 half1Areas[facei] = half1[facei].normal(half1.
points());
99 Pout<<
"calcTransforms() : patch: " <<
name() <<
nl 100 <<
" forwardT = " << forwardT() <<
nl 101 <<
" reverseT = " << reverseT() <<
nl 102 <<
" separation = " << separation() <<
nl 103 <<
" collocated = " << collocated() <<
nl <<
endl;
120 <<
"Patch " <<
name()
121 <<
" has transform type " << transformTypeNames[
transform()]
122 <<
", neighbour patch " << neighbPatchName()
123 <<
" has transform type " 124 << neighbPatch().transformTypeNames[neighbPatch().transform()]
137 if (rotationAngleDefined_)
139 const tensor T(rotationAxis_*rotationAxis_);
143 0, -rotationAxis_.z(), rotationAxis_.y(),
144 rotationAxis_.z(), 0, -rotationAxis_.x(),
145 -rotationAxis_.y(), rotationAxis_.x(), 0
152 +
sin(rotationAngle_)*S
159 +
sin(-rotationAngle_)*S
164 const vector transformedAreaPos =
gSum(half1Areas & revTPos);
165 const vector transformedAreaNeg =
gSum(half1Areas & revTNeg);
167 const scalar magArea0 =
mag(area0) + ROOTVSMALL;
171 const scalar errorPos =
mag(transformedAreaPos + area0);
172 const scalar errorNeg =
mag(transformedAreaNeg + area0);
174 const scalar normErrorPos = errorPos/magArea0;
175 const scalar normErrorNeg = errorNeg/magArea0;
177 if (errorPos > errorNeg && normErrorNeg < matchTolerance())
180 rotationAngle_ *= -1;
187 const scalar areaError =
min(normErrorPos, normErrorNeg);
189 if (areaError > matchTolerance())
193 "void Foam::cyclicAMIPolyPatch::calcTransforms" 195 "const primitivePatch&, " 196 "const pointField&, " 197 "const vectorField&, " 198 "const pointField&, " 201 ) <<
"Patch areas are not consistent within " 202 << 100*matchTolerance()
203 <<
" % indicating a possible error in the specified " 204 <<
"angle of rotation" <<
nl 205 <<
" owner patch : " <<
name() <<
nl 206 <<
" neighbour patch : " << neighbPatch().name()
210 <<
" area error : " << 100*areaError <<
" %" 211 <<
" match tolerance : " << matchTolerance()
217 scalar theta =
radToDeg(rotationAngle_);
219 Pout<<
"cyclicAMIPolyPatch::calcTransforms: patch:" 221 <<
" Specified rotation:" 222 <<
" swept angle: " << theta <<
" [deg]" 223 <<
" reverse transform: " << revT
231 if (half0Ctrs.
size())
233 n0 = findFaceNormalMaxRadius(half0Ctrs);
235 if (half1Ctrs.
size())
237 n1 = -findFaceNormalMaxRadius(half1Ctrs);
243 n0 /=
mag(n0) + VSMALL;
244 n1 /=
mag(n1) + VSMALL;
251 (n0 ^ rotationAxis_),
257 (-n1 ^ rotationAxis_),
266 Pout<<
"cyclicAMIPolyPatch::calcTransforms: patch:" 268 <<
" Specified rotation:" 269 <<
" n0:" << n0 <<
" n1:" << n1
270 <<
" swept angle: " << theta <<
" [deg]" 271 <<
" reverse transform: " << revT
287 Pout<<
"cyclicAMIPolyPatch::calcTransforms : patch:" <<
name()
288 <<
" Specified translation : " << separationVector_
308 <<
" Assuming cyclic AMI pairs are colocated" <<
endl;
323 <<
" forwardT = " << forwardT() <<
nl 324 <<
" reverseT = " << reverseT() <<
nl 325 <<
" separation = " << separation() <<
nl 326 <<
" collocated = " << collocated() <<
nl <<
endl;
346 neighbPatch().meshPoints()
357 transformPosition(nbrPoints);
389 AMILowWeightCorrection_,
396 Pout<<
"cyclicAMIPolyPatch : " <<
name()
397 <<
" constructed AMI with " <<
nl 398 <<
" " <<
"srcAddress:" << AMIPtr_().srcAddress().size()
400 <<
" " <<
"tgAddress :" << AMIPtr_().tgtAddress().size()
424 neighbPatch().faceCentres(),
425 neighbPatch().faceAreas(),
426 neighbPatch().faceCellCentres()
490 const word& patchType,
499 rotationAngleDefined_(
false),
504 AMIRequireMatch_(
true),
505 AMILowWeightCorrection_(-1.0),
520 const word& patchType
529 rotationAngleDefined_(
false),
534 AMIRequireMatch_(
true),
535 AMILowWeightCorrection_(dict.
lookupOrDefault(
"lowWeightCorrection", -1.0)),
543 "cyclicAMIPolyPatch::cyclicAMIPolyPatch" 546 "const dictionary&, " 548 "const polyBoundaryMesh&" 551 ) <<
"No \"neighbourPatch\" or \"coupleGroup\" provided." 555 if (nbrPatchName_ == name)
559 "cyclicAMIPolyPatch::cyclicAMIPolyPatch" 562 "const dictionary&, " 564 "const polyBoundaryMesh&" 567 ) <<
"Neighbour patch name " << nbrPatchName_
568 <<
" cannot be the same as this patch " << name
576 dict.
lookup(
"rotationAxis") >> rotationAxis_;
577 dict.
lookup(
"rotationCentre") >> rotationCentre_;
580 rotationAngleDefined_ =
true;
581 rotationAngle_ =
degToRad(rotationAngle_);
585 Info<<
"rotationAngle: " << rotationAngle_ <<
" [rad]" 590 scalar magRot =
mag(rotationAxis_);
595 "cyclicAMIPolyPatch::cyclicAMIPolyPatch" 598 "const dictionary&, " 600 "const polyBoundaryMesh&" 603 ) <<
"Illegal rotationAxis " << rotationAxis_ <<
endl 604 <<
"Please supply a non-zero vector." 607 rotationAxis_ /= magRot;
613 dict.
lookup(
"separationVector") >> separationVector_;
660 const label newStart,
661 const word& nbrPatchName
665 nbrPatchName_(nbrPatchName),
680 if (nbrPatchName_ ==
name())
684 "const cyclicAMIPolyPatch& " 685 "const polyBoundaryMesh&, " 690 ) <<
"Neighbour patch name " << nbrPatchName_
691 <<
" cannot be the same as this patch " <<
name()
737 if (nbrPatchID_ == -1)
739 nbrPatchID_ = this->
boundaryMesh().findPatchID(neighbPatchName());
741 if (nbrPatchID_ == -1)
743 FatalErrorIn(
"cyclicPolyAMIPatch::neighbPatchID() const")
744 <<
"Illegal neighbourPatch name " << neighbPatchName()
745 <<
nl <<
"Valid patch names are " 752 refCast<const cyclicAMIPolyPatch>
759 WarningIn(
"cyclicAMIPolyPatch::neighbPatchID() const")
760 <<
"Patch " <<
name()
761 <<
" specifies neighbour patch " << neighbPatchName()
762 <<
nl <<
" but that in return specifies " 773 return index() < neighbPatchID();
780 return refCast<const cyclicAMIPolyPatch>(pp);
787 const word surfType(surfDict_.lookupOrDefault<
word>(
"type",
"none"));
789 if (!surfPtr_.valid() && owner() && surfType !=
"none")
791 word surfName(surfDict_.lookupOrDefault(
"name", name()));
802 mesh.time().constant(),
822 "const AMIPatchToPatchInterpolation& cyclicAMIPolyPatch::AMI()" 824 <<
"AMI interpolator only available to owner patch" 828 if (!AMIPtr_.valid())
841 return AMI().applyLowWeightCorrection();
845 return neighbPatch().AMI().applyLowWeightCorrection();
864 else if (separated())
895 forwardT().size() == 1
909 else if (separated())
913 separation().size() == 1
915 : separation()[faceI]
933 reverseT().size() == 1
947 else if (separated())
951 separation().size() == 1
953 : separation()[faceI]
971 reverseT().size() == 1
1037 reverseTransformPosition(prt, faceI);
1040 reverseTransformDirection(nrt, faceI);
1042 label nbrFaceI = -1;
1046 nbrFaceI = AMI().tgtPointFace
1057 nbrFaceI = neighbPatch().AMI().srcPointFace
1079 if (!nbrPatchName_.empty())
1084 coupleGroup_.write(os);
1095 if (rotationAngleDefined_)
1105 os.
writeKeyword(
"separationVector") << separationVector_
1125 if (AMILowWeightCorrection_ > 0)
1127 os.
writeKeyword(
"lowWeightCorrection") << AMILowWeightCorrection_
1131 if (!surfDict_.empty())
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
dimensionedScalar sqrt(const dimensionedScalar &ds)
virtual bool owner() const
Does this side own the patch?
const pointField & points
virtual void updateMesh(PstreamBuffers &)
Update of the patch topology.
Buffers for inter-processor communications streams (UOPstream, UIPstream).
bool rotationAngleDefined_
Flag to show whether the rotation angle is defined.
const autoPtr< searchableSurface > & surfPtr() const
Return a reference to the projection surface.
Cyclic patch for Arbitrary Mesh Interface (AMI)
virtual void calcGeometry(PstreamBuffers &)
Calculate the patch geometry.
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject( name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE ))
virtual void reverseTransformPosition(point &l, const label faceI) const
Transform a patch-based position from this side to nbr side.
fileName path() const
Return path.
dimensioned< scalar > mag(const dimensioned< Type > &)
word name(const complex &)
Return a string representation of a complex.
virtual void clearGeom()
Clear geometry.
virtual void initMovePoints(PstreamBuffers &pBufs, const pointField &)
Initialise the patches for moving points.
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
vector separationVector_
Translation vector.
virtual void initGeometry(PstreamBuffers &)
Initialise the calculation of the patch geometry.
dimensioned< scalar > magSqr(const dimensioned< Type > &)
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
cyclicAMIPolyPatch(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 couped patch) components.
virtual ~cyclicAMIPolyPatch()
Destructor.
label findMax(const ListType &, const label start=0)
Find index of max element (and larger than given element).
A class for handling words, derived from string.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface...
virtual void movePoints(PstreamBuffers &pBufs, const pointField &)
Correct patches after moving points.
void size(const label)
Override size to be inconsistent with allocated storage.
errorManipArg< error, int > exit(error &err, const int errNo=1)
virtual void initMovePoints(PstreamBuffers &, const pointField &)
Initialise the patches for moving points.
virtual void updateMesh(PstreamBuffers &)
Update of the patch topology.
virtual label neighbPatchID() const
Neighbour patch ID.
bool AMIRequireMatch_
Flag to indicate that patches should match/overlap.
A list of keyword definitions, which are a keyword followed by any number of values (e...
word nbrPatchName_
Name of other half.
vectorField pointField
pointField is a vectorField.
Field< tensor > tensorField
Specialisation of Field<T> for tensor.
scalar rotationAngle_
Rotation angle.
A patch is a list of labels that address the faces in the global face list.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
const vectorField::subField faceCentres() const
Return face centres.
Type gSum(const FieldField< Field, Type > &f)
interpolationMethod
Enumeration specifying interpolation method.
point rotationCentre_
Point on axis of rotation for rotational cyclics.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
virtual const cyclicAMIPolyPatch & neighbPatch() const
Return a reference to the neighbour patch.
static autoPtr< searchableSurface > New(const word &surfaceType, const IOobject &io, const dictionary &dict)
Return a reference to the selected searchableSurface.
void setSize(const label)
Reset size of List.
Ostream & endl(Ostream &os)
Add newline and flush stream.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
#define WarningIn(functionName)
Report a warning using Foam::Warning.
virtual void initGeometry(PstreamBuffers &)
Initialise the calculation of the patch geometry.
virtual void transformPosition(pointField &) const
Transform patch-based positions from nbr side to this side.
dimensionSet transform(const dimensionSet &)
const coupleGroupIdentifier coupleGroup_
Optional patchGroup to find neighbPatch.
static bool valid(char)
Is this character valid for a word.
const bMesh & mesh() const
virtual void calcTransforms()
Recalculate the transformation tensors.
Field< vector > vectorField
Specialisation of Field<T> for vector.
Interpolation class dealing with transfer of data between two primitive patches with an arbitrary mes...
const scalar AMILowWeightCorrection_
Low weight correction threshold for AMI.
label pointFace(const label faceI, const vector &n, point &p) const
Return face index on neighbour patch which shares point p.
dimensionedScalar cos(const dimensionedScalar &ds)
scalar radToDeg(const scalar rad)
Conversion from radians to degrees.
Macros for easy insertion into run-time selection tables.
dimensionedScalar acos(const dimensionedScalar &ds)
errorManip< error > abort(error &err)
Ostream & writeKeyword(const keyType &)
Write the keyword followed by an appropriate indentation.
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
A list of faces which address into the list of points.
virtual void clearGeom()
Clear geometry.
bool applyLowWeightCorrection() const
Return true if applying the low weight correction.
points setSize(newPointi)
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
const AMIPatchToPatchInterpolation & AMI() const
Return a reference to the AMI interpolator.
virtual void resetAMI(const AMIPatchToPatchInterpolation::interpolationMethod &AMIMethod=AMIPatchToPatchInterpolation::imFaceAreaWeight) const
Reset the AMI interpolator.
Mesh consisting of general polyhedral cells.
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
const bool AMIReverse_
Flag to indicate that slave patch should be reversed for AMI.
T lookupOrDefault(const word &, const T &, bool recursive=false, bool patternMatch=true) const
Find and return a T,.
A class for handling file names.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
scalar degToRad(const scalar deg)
Conversion from degrees to radians.
bool readIfPresent(const word &, T &, bool recursive=false, bool patternMatch=true) const
Find an entry if present, and assign to T.
virtual void initOrder(PstreamBuffers &, const primitivePatch &) const
Initialize ordering for primitivePatch. Does not.
Tensor< Cmpt > T() const
Transpose.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
virtual void reverseTransformDirection(vector &d, const label faceI) const
Transform a patch-based direction from this side to nbr side.
const List< Face > & localFaces() const
Return patch faces addressing into local point list.
A List obtained as a section of another List.
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
virtual void movePoints(const Field< PointType > &)
Correct patch after moving points.
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of point.
#define FatalIOErrorIn(functionName, ios)
Report an error message using Foam::FatalIOError.
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
vector rotationAxis_
Axis of rotation for rotational cyclics.
const Field< PointType > & points() const
Return reference to global points.
const dictionary surfDict_
Dictionary used during projection surface construction.
static const word null
An empty word.
defineTypeNameAndDebug(combustionModel, 0)
virtual bool order(PstreamBuffers &, const primitivePatch &, labelList &faceMap, labelList &rotation) const
Return new ordering for primitivePatch.
const word & neighbPatchName() const
Neighbour patch name.
dictionary subOrEmptyDict(const word &, const bool mustRead=false) const
Find and return a sub-dictionary as a copy, or.
prefixOSstream Pout(cout,"Pout")
List< bool > boolList
Bool container classes.
virtual void movePoints(PstreamBuffers &, const pointField &p)
Correct patches after moving points.
dimensionedScalar sin(const dimensionedScalar &ds)