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])
83 <<
" has transform type " << transformTypeNames[
transform()]
84 <<
", neighbour patch " << neighbPatchName()
85 <<
" has transform type " 86 << neighbPatch().transformTypeNames[neighbPatch().transform()]
99 if (rotationAngleDefined_)
101 const tensor T(rotationAxis_*rotationAxis_);
105 0, -rotationAxis_.z(), rotationAxis_.y(),
106 rotationAxis_.z(), 0, -rotationAxis_.x(),
107 -rotationAxis_.y(), rotationAxis_.x(), 0
114 +
sin(rotationAngle_)*S
121 +
sin(-rotationAngle_)*S
126 const vector transformedAreaPos =
gSum(half1Areas & revTPos);
127 const vector transformedAreaNeg =
gSum(half1Areas & revTNeg);
129 const scalar magArea0 =
mag(area0) + rootVSmall;
133 const scalar errorPos =
mag(transformedAreaPos + area0);
134 const scalar errorNeg =
mag(transformedAreaNeg + area0);
136 const scalar normErrorPos = errorPos/magArea0;
137 const scalar normErrorNeg = errorNeg/magArea0;
139 if (errorPos > errorNeg && normErrorNeg < matchTolerance())
142 rotationAngle_ *= -1;
149 const scalar areaError =
min(normErrorPos, normErrorNeg);
151 if (areaError > matchTolerance())
154 <<
"Patch areas are not consistent within " 155 << 100*matchTolerance()
156 <<
" % indicating a possible error in the specified " 157 <<
"angle of rotation" <<
nl 158 <<
" owner patch : " <<
name() <<
nl 159 <<
" neighbour patch : " << neighbPatch().name()
163 <<
" area error : " << 100*areaError <<
" %" 164 <<
" match tolerance : " << matchTolerance()
170 scalar theta =
radToDeg(rotationAngle_);
172 Pout<<
"cyclicAMIPolyPatch::calcTransforms: patch:" 174 <<
" Specified rotation:" 175 <<
" swept angle: " << theta <<
" [deg]" 176 <<
" reverse transform: " << revT
184 if (half0Ctrs.size())
186 n0 = findFaceNormalMaxRadius(half0Ctrs);
188 if (half1Ctrs.size())
190 n1 = -findFaceNormalMaxRadius(half1Ctrs);
193 reduce(n0, maxMagSqrOp<point>());
194 reduce(n1, maxMagSqrOp<point>());
196 n0 /=
mag(n0) + vSmall;
197 n1 /=
mag(n1) + vSmall;
204 (n0 ^ rotationAxis_),
210 (-n1 ^ rotationAxis_),
219 Pout<<
"cyclicAMIPolyPatch::calcTransforms: patch:" 221 <<
" Specified rotation:" 222 <<
" n0:" << n0 <<
" n1:" << n1
223 <<
" swept angle: " << theta <<
" [deg]" 224 <<
" reverse transform: " << revT
240 Pout<<
"cyclicAMIPolyPatch::calcTransforms : patch:" <<
name()
241 <<
" Specified translation : " << separationVector_
261 <<
" Assuming cyclic AMI pairs are colocated" <<
endl;
276 <<
" forwardT = " << forwardT() <<
nl 277 <<
" reverseT = " << reverseT() <<
nl 278 <<
" separation = " << separation() <<
nl 279 <<
" collocated = " << collocated() <<
nl <<
endl;
294 neighbPatch().meshPoints()
305 transformPosition(nbrPoints);
339 AMILowWeightCorrection_,
348 Pout<<
"cyclicAMIPolyPatch : " <<
name()
349 <<
" constructed AMI with " <<
nl 350 <<
" " <<
"srcAddress:" << AMIs_[0].srcAddress().size()
352 <<
" " <<
"tgAddress :" << AMIs_[0].tgtAddress().size()
365 half0Areas[facei] = half0[facei].area(half0.
points());
372 half1Areas[facei] = half1[facei].area(half1.
points());
386 Pout<<
"calcTransforms() : patch: " <<
name() <<
nl 387 <<
" forwardT = " << forwardT() <<
nl 388 <<
" reverseT = " << reverseT() <<
nl 389 <<
" separation = " << separation() <<
nl 390 <<
" collocated = " << collocated() <<
nl <<
endl;
399 AMITransforms_.clear();
413 neighbPatch().faceCentres(),
414 neighbPatch().faceAreas(),
415 neighbPatch().faceCellCentres()
428 AMITransforms_.clear();
453 AMITransforms_.clear();
469 AMITransforms_.clear();
484 const word& patchType,
486 const bool AMIRequireMatch,
495 rotationAngleDefined_(
false),
497 separationVector_(
Zero),
501 AMIRequireMatch_(AMIRequireMatch),
502 AMILowWeightCorrection_(-1.0),
503 AMIMethod_(AMIMethod),
518 const word& patchType,
519 const bool AMIRequireMatch,
529 rotationAngleDefined_(
false),
531 separationVector_(
Zero),
535 AMIRequireMatch_(AMIRequireMatch),
536 AMILowWeightCorrection_(dict.
lookupOrDefault(
"lowWeightCorrection", -1.0)),
554 ) <<
"No \"neighbourPatch\" or \"coupleGroup\" provided." 558 if (nbrPatchName_ == name)
563 ) <<
"Neighbour patch name " << nbrPatchName_
564 <<
" cannot be the same as this patch " << name
572 dict.
lookup(
"rotationAxis") >> rotationAxis_;
573 dict.
lookup(
"rotationCentre") >> rotationCentre_;
576 rotationAngleDefined_ =
true;
577 rotationAngle_ =
degToRad(rotationAngle_);
581 Info<<
"rotationAngle: " << rotationAngle_ <<
" [rad]" 586 scalar magRot =
mag(rotationAxis_);
592 ) <<
"Illegal rotationAxis " << rotationAxis_ <<
endl 593 <<
"Please supply a non-zero vector." 596 rotationAxis_ /= magRot;
602 dict.
lookup(
"separationVector") >> separationVector_;
651 const label newStart,
652 const word& nbrPatchName
656 nbrPatchName_(nbrPatchName),
673 if (nbrPatchName_ ==
name())
676 <<
"Neighbour patch name " << nbrPatchName_
677 <<
" cannot be the same as this patch " <<
name()
725 if (nbrPatchID_ == -1)
727 nbrPatchID_ = this->
boundaryMesh().findPatchID(neighbPatchName());
729 if (nbrPatchID_ == -1)
732 <<
"Illegal neighbourPatch name " << neighbPatchName()
733 <<
nl <<
"Valid patch names are " 740 refCast<const cyclicAMIPolyPatch>
748 <<
"Patch " <<
name()
749 <<
" specifies neighbour patch " << neighbPatchName()
750 <<
nl <<
" but that in return specifies " 761 return index() < neighbPatchID();
768 return refCast<const cyclicAMIPolyPatch>(pp);
775 const word surfType(surfDict_.lookupOrDefault<
word>(
"type",
"none"));
777 if (!surfPtr_.valid() && owner() && surfType !=
"none")
779 word surfName(surfDict_.lookupOrDefault(
"name", name()));
790 mesh.time().constant(),
810 <<
"AMI interpolators only available to owner patch" 829 <<
"AMI transforms only available to owner patch" 838 return AMITransforms_;
846 return AMILowWeightCorrection_ > 0;
850 return neighbPatch().AMILowWeightCorrection_ > 0;
859 return AMIs()[0].srcWeightsSum();
863 return neighbPatch().AMIs()[0].tgtWeightsSum();
872 return AMIs()[0].tgtWeightsSum();
876 return neighbPatch().AMIs()[0].srcWeightsSum();
895 else if (separated())
926 forwardT().size() == 1
940 else if (separated())
944 separation().size() == 1
946 : separation()[facei]
964 reverseT().size() == 1
978 else if (separated())
982 separation().size() == 1
984 : separation()[facei]
1002 reverseT().size() == 1
1029 pow(
inv(AMITransforms()[i]).
R()(cmpt, cmpt), rank);
1032 AMIs()[i].interpolateToSource(r*fld, defaultValues);
1043 nei.
AMIs()[i].interpolateToTarget(r*fld, defaultValues);
1107 reverseTransformPosition(pt, facei);
1110 reverseTransformDirection(nt, facei);
1116 point ptt = AMITransforms()[i].transformPosition(pt);
1117 const vector ntt = AMITransforms()[i].transform(nt);
1119 const label nbrFacei =
1120 AMIs()[i].tgtPointFace(*
this, neighbPatch(), ntt, facei, ptt);
1131 forAll(neighbPatch().AMIs(), i)
1134 neighbPatch().AMITransforms()[i].invTransformPosition(pt);
1136 neighbPatch().AMITransforms()[i].invTransform(nt);
1138 const label nbrFacei =
1139 neighbPatch().AMIs()[i].srcPointFace
1164 const label proc = patch.
AMIs()[0].singlePatchProc();
1166 for (
label i = 1; i < patch.
AMIs().size(); ++ i)
1168 if (patch.
AMIs()[i].singlePatchProc() != proc)
1181 if (!nbrPatchName_.empty())
1186 coupleGroup_.write(os);
1197 if (rotationAngleDefined_)
1207 os.
writeKeyword(
"separationVector") << separationVector_
1227 if (AMILowWeightCorrection_ > 0)
1229 os.
writeKeyword(
"lowWeightCorrection") << AMILowWeightCorrection_
1237 if (!surfDict_.empty())
virtual void clearGeom()
Clear geometry.
static word interpolationMethodToWord(const interpolationMethod &method)
Convert interpolationMethod to word representation.
virtual void resetAMI() const
Reset the AMI interpolator.
static bool valid(char)
Is this character valid for a word.
vector separationVector_
Translation vector.
dimensionedScalar acos(const dimensionedScalar &ds)
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
#define forAll(list, i)
Loop across all elements in list.
cyclicAMIPolyPatch(const word &name, const label size, const label start, const label index, const polyBoundaryMesh &bm, const word &patchType, const transformType transform=UNKNOWN, const bool AMIRequireMatch=true, const AMIPatchToPatchInterpolation::interpolationMethod AMIMethod=AMIPatchToPatchInterpolation::imFaceAreaWeight)
Construct from (base couped patch) components.
fileName path() const
Return path.
virtual label neighbPatchID() const
Neighbour patch ID.
virtual void movePoints(const Field< PointType > &)
Correct patch after moving points.
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 bool order(PstreamBuffers &, const primitivePatch &, labelList &faceMap, labelList &rotation) const
Return new ordering for primitivePatch.
scalar radToDeg(const scalar rad)
Conversion from radians to degrees.
A class for handling file names.
errorManipArg< error, int > exit(error &err, const int errNo=1)
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
virtual void initGeometry(PstreamBuffers &)
Initialise the calculation of the patch geometry.
A list of keyword definitions, which are a keyword followed by any number of values (e...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
T & ref() const
Return non-const reference or generate a fatal error.
dimensionedSphericalTensor inv(const dimensionedSphericalTensor &dt)
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
void size(const label)
Override size to be inconsistent with allocated storage.
static interpolationMethod wordTointerpolationMethod(const word &method)
Convert word to interpolationMethod.
virtual void calcTransforms()
Recalculate the transformation tensors.
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface...
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
virtual const scalarField & neighbWeightsSum() const
Return the weights sum for the neighbour patch.
labelPair pointAMIAndFace(const label facei, const vector &n, point &p) const
Return the transform and face indices on neighbour patch which.
virtual void transformPosition(pointField &) const
Transform patch-based positions from nbr side to this side.
bool applyLowWeightCorrection() const
Return true if applying the low weight correction.
const PtrList< AMIPatchToPatchInterpolation > & AMIs() const
Return a reference to the AMI interpolators.
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
vector rotationAxis_
Axis of rotation for rotational cyclics.
bool rotationAngleDefined_
Flag to show whether the rotation angle is defined.
virtual void reverseTransformDirection(vector &d, const label facei) const
Transform a patch-based direction from this side to nbr side.
Vector< scalar > vector
A scalar version of the templated Vector.
tmp< Field< Type > > interpolate(const Field< Type > &fld, const UList< Type > &defaultValues=UList< Type >()) const
Interpolate field.
virtual void initMovePoints(PstreamBuffers &, const pointField &)
Initialise the patches for moving points.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Macros for easy insertion into run-time selection tables.
scalar degToRad(const scalar deg)
Conversion from degrees to radians.
virtual void clearGeom()
Clear geometry.
interpolationMethod
Enumeration specifying interpolation method.
virtual void movePoints(PstreamBuffers &, const pointField &p)
Correct patches after moving points.
const bool AMIRequireMatch_
Flag to indicate that patches should match/overlap.
const dictionary surfDict_
Dictionary used during projection surface construction.
virtual void calcGeometry(PstreamBuffers &)
Calculate the patch geometry.
List< bool > boolList
Bool container classes.
const List< Face > & localFaces() const
Return patch faces addressing into local point list.
const List< vectorTensorTransform > & AMITransforms() const
Return a reference to the AMI transforms.
points setSize(newPointi)
const coupleGroupIdentifier coupleGroup_
Optional patchGroup to find neighbPatch.
A list of faces which address into the list of points.
A List obtained as a section of another List.
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))
vectorField pointField
pointField is a vectorField.
const bool AMIReverse_
Flag to indicate that slave patch should be reversed for AMI.
const word & neighbPatchName() const
Neighbour patch name.
An ordered pair of two objects of type <T> with first() and second() elements.
Type gSum(const FieldField< Field, Type > &f)
dimensionedScalar cos(const dimensionedScalar &ds)
A class for handling words, derived from string.
const autoPtr< searchableSurface > & surfPtr() const
Return a reference to the projection surface.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
const scalar AMILowWeightCorrection_
Low weight correction threshold for AMI.
label singlePatchProc() const
Index of processor that holds all of both sides, or -1 if.
point rotationCentre_
Point on axis of rotation for rotational cyclics.
virtual void updateMesh(PstreamBuffers &)
Update of the patch topology.
bool readIfPresent(const word &, T &, bool recursive=false, bool patternMatch=true) const
Find an entry if present, and assign to T.
const Field< PointType > & points() const
Return reference to global points.
static const word null
An empty word.
Pair< label > labelPair
Label pair.
virtual void updateMesh(PstreamBuffers &)
Update of the patch topology.
Cyclic patch for Arbitrary Mesh Interface (AMI)
errorManip< error > abort(error &err)
virtual const scalarField & weightsSum() const
Return the weights sum for this patch.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
virtual ~cyclicAMIPolyPatch()
Destructor.
label findMax(const ListType &, const label start=0)
Find index of max element (and larger than given element).
Templated 3D Vector derived from VectorSpace adding construction from 3 components, element access using x(), y() and z() member functions and the inner-product (dot-product) and cross product operators.
dimensioned< scalar > magSqr(const dimensioned< Type > &)
An Ostream is an abstract base class for all output systems (streams, files, token lists...
dimensionedScalar sin(const dimensionedScalar &ds)
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
const AMIPatchToPatchInterpolation::interpolationMethod AMIMethod_
AMI Method.
defineTypeNameAndDebug(combustionModel, 0)
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
Ostream & writeKeyword(const keyType &)
Write the keyword followed by an appropriate indentation.
Buffers for inter-processor communications streams (UOPstream, UIPstream).
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
PrimitivePatch< face, SubList, const pointField & > primitivePatch
Addressing for a faceList slice.
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
word name(const complex &)
Return a string representation of a complex.
virtual void initGeometry(PstreamBuffers &)
Initialise the calculation of the patch geometry.
Field< tensor > tensorField
Specialisation of Field<T> for tensor.
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
void setSize(const label)
Reset size of List.
virtual void initOrder(PstreamBuffers &, const primitivePatch &) const
Initialize ordering for primitivePatch. Does not.
vector point
Point is a vector.
T lookupOrDefault(const word &, const T &, bool recursive=false, bool patternMatch=true) const
Find and return a T,.
#define R(A, B, C, D, E, F, K, M)
#define WarningInFunction
Report a warning using Foam::Warning.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
virtual const cyclicAMIPolyPatch & neighbPatch() const
Return a reference to the neighbour patch.
prefixOSstream Pout(cout, "Pout")
virtual bool owner() const
Does this side own the patch?
Interpolation class dealing with transfer of data between two primitive patches with an arbitrary mes...
static autoPtr< searchableSurface > New(const word &surfaceType, const IOobject &io, const dictionary &dict)
Return a reference to the selected searchableSurface.
dimensioned< scalar > mag(const dimensioned< Type > &)
Field< vector > vectorField
Specialisation of Field<T> for vector.
Mesh consisting of general polyhedral cells.
const bMesh & mesh() const
A class for managing temporary objects.
A patch is a list of labels that address the faces in the global face list.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
word nbrPatchName_
Name of other half.
Tensor< scalar > tensor
Tensor of scalars.
virtual void reverseTransformPosition(point &l, const label facei) const
Transform a patch-based position from this side to nbr side.
static const Vector< scalar > zero
scalar rotationAngle_
Rotation angle.
dictionary subOrEmptyDict(const word &, const bool mustRead=false) const
Find and return a sub-dictionary as a copy, or.
dimensionSet transform(const dimensionSet &)
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
virtual void movePoints(PstreamBuffers &pBufs, const pointField &)
Correct patches after moving points.
virtual void initMovePoints(PstreamBuffers &pBufs, const pointField &)
Initialise the patches for moving points.
const vectorField::subField faceCentres() const
Return face centres.