45 Foam::vector Foam::cyclicAMIPolyPatch::findFaceNormalMaxRadius
52 const vectorField n((faceCentres - rotationCentre_) ^ rotationAxis_);
60 Info<<
"findFaceMaxRadius(const pointField&) : patch: " <<
name() <<
nl 61 <<
" rotFace = " << facei <<
nl 62 <<
" point = " << faceCentres[facei] <<
nl 63 <<
" distance = " <<
Foam::sqrt(magRadSqr[facei])
84 <<
" has transform type " << transformTypeNames[
transform()]
85 <<
", neighbour patch " << neighbPatchName()
86 <<
" has transform type " 87 << neighbPatch().transformTypeNames[neighbPatch().transform()]
100 if (rotationAngleDefined_)
102 const tensor T(rotationAxis_*rotationAxis_);
106 0, -rotationAxis_.z(), rotationAxis_.y(),
107 rotationAxis_.z(), 0, -rotationAxis_.x(),
108 -rotationAxis_.y(), rotationAxis_.x(), 0
115 +
sin(rotationAngle_)*S
122 +
sin(-rotationAngle_)*S
127 const vector transformedAreaPos =
gSum(half1Areas & revTPos);
128 const vector transformedAreaNeg =
gSum(half1Areas & revTNeg);
130 const scalar magArea0 =
mag(area0) + rootVSmall;
134 const scalar errorPos =
mag(transformedAreaPos + area0);
135 const scalar errorNeg =
mag(transformedAreaNeg + area0);
137 const scalar normErrorPos = errorPos/magArea0;
138 const scalar normErrorNeg = errorNeg/magArea0;
140 if (errorPos > errorNeg && normErrorNeg < matchTolerance())
143 rotationAngle_ *= -1;
150 const scalar areaError =
min(normErrorPos, normErrorNeg);
152 if (areaError > matchTolerance())
155 <<
"Patch areas are not consistent within " 156 << 100*matchTolerance()
157 <<
" % indicating a possible error in the specified " 158 <<
"angle of rotation" <<
nl 159 <<
" owner patch : " <<
name() <<
nl 160 <<
" neighbour patch : " << neighbPatch().name()
164 <<
" area error : " << 100*areaError <<
" %" 165 <<
" match tolerance : " << matchTolerance()
171 scalar theta =
radToDeg(rotationAngle_);
173 Pout<<
"cyclicAMIPolyPatch::calcTransforms: patch:" 175 <<
" Specified rotation:" 176 <<
" swept angle: " << theta <<
" [deg]" 177 <<
" reverse transform: " << revT
185 if (half0Ctrs.size())
187 n0 = findFaceNormalMaxRadius(half0Ctrs);
189 if (half1Ctrs.size())
191 n1 = -findFaceNormalMaxRadius(half1Ctrs);
194 reduce(n0, maxMagSqrOp<point>());
195 reduce(n1, maxMagSqrOp<point>());
197 n0 /=
mag(n0) + vSmall;
198 n1 /=
mag(n1) + vSmall;
205 (n0 ^ rotationAxis_),
211 (-n1 ^ rotationAxis_),
220 Pout<<
"cyclicAMIPolyPatch::calcTransforms: patch:" 222 <<
" Specified rotation:" 223 <<
" n0:" << n0 <<
" n1:" << n1
224 <<
" swept angle: " << theta <<
" [deg]" 225 <<
" reverse transform: " << revT
241 Pout<<
"cyclicAMIPolyPatch::calcTransforms : patch:" <<
name()
242 <<
" Specified translation : " << separationVector_
262 <<
" Assuming cyclic AMI pairs are colocated" <<
endl;
277 <<
" forwardT = " << forwardT() <<
nl 278 <<
" reverseT = " << reverseT() <<
nl 279 <<
" separation = " << separation() <<
nl 280 <<
" collocated = " << collocated() <<
nl <<
endl;
295 neighbPatch().meshPoints()
306 transformPosition(nbrPoints);
340 AMILowWeightCorrection_,
349 Pout<<
"cyclicAMIPolyPatch : " <<
name()
350 <<
" constructed AMI with " <<
nl 351 <<
" " <<
"srcAddress:" << AMIs_[0].srcAddress().size()
353 <<
" " <<
"tgAddress :" << AMIs_[0].tgtAddress().size()
366 half0Areas[facei] = half0[facei].area(half0.
points());
373 half1Areas[facei] = half1[facei].area(half1.
points());
387 Pout<<
"calcTransforms() : patch: " <<
name() <<
nl 388 <<
" forwardT = " << forwardT() <<
nl 389 <<
" reverseT = " << reverseT() <<
nl 390 <<
" separation = " << separation() <<
nl 391 <<
" collocated = " << collocated() <<
nl <<
endl;
400 AMITransforms_.clear();
414 neighbPatch().faceCentres(),
415 neighbPatch().faceAreas(),
416 neighbPatch().faceCellCentres()
429 AMITransforms_.clear();
454 AMITransforms_.clear();
470 AMITransforms_.clear();
485 const word& patchType,
487 const bool AMIRequireMatch,
496 rotationAngleDefined_(
false),
498 separationVector_(
Zero),
502 AMIRequireMatch_(AMIRequireMatch),
503 AMILowWeightCorrection_(-1.0),
504 AMIMethod_(AMIMethod),
519 const word& patchType,
520 const bool AMIRequireMatch,
530 rotationAngleDefined_(
false),
532 separationVector_(
Zero),
536 AMIRequireMatch_(AMIRequireMatch),
537 AMILowWeightCorrection_(dict.
lookupOrDefault(
"lowWeightCorrection", -1.0)),
555 ) <<
"No \"neighbourPatch\" or \"coupleGroup\" provided." 559 if (nbrPatchName_ == name)
564 ) <<
"Neighbour patch name " << nbrPatchName_
565 <<
" cannot be the same as this patch " << name
573 dict.
lookup(
"rotationAxis") >> rotationAxis_;
574 dict.
lookup(
"rotationCentre") >> rotationCentre_;
577 rotationAngleDefined_ =
true;
578 rotationAngle_ =
degToRad(rotationAngle_);
582 Info<<
"rotationAngle: " << rotationAngle_ <<
" [rad]" 587 scalar magRot =
mag(rotationAxis_);
593 ) <<
"Illegal rotationAxis " << rotationAxis_ <<
endl 594 <<
"Please supply a non-zero vector." 597 rotationAxis_ /= magRot;
603 dict.
lookup(
"separationVector") >> separationVector_;
652 const label newStart,
653 const word& nbrPatchName
657 nbrPatchName_(nbrPatchName),
674 if (nbrPatchName_ ==
name())
677 <<
"Neighbour patch name " << nbrPatchName_
678 <<
" cannot be the same as this patch " <<
name()
726 if (nbrPatchID_ == -1)
728 nbrPatchID_ = this->
boundaryMesh().findPatchID(neighbPatchName());
730 if (nbrPatchID_ == -1)
733 <<
"Illegal neighbourPatch name " << neighbPatchName()
734 <<
nl <<
"Valid patch names are " 741 refCast<const cyclicAMIPolyPatch>
749 <<
"Patch " <<
name()
750 <<
" specifies neighbour patch " << neighbPatchName()
751 <<
nl <<
" but that in return specifies " 762 return index() < neighbPatchID();
769 return refCast<const cyclicAMIPolyPatch>(pp);
776 const word surfType(surfDict_.lookupOrDefault<
word>(
"type",
"none"));
778 if (!surfPtr_.valid() && owner() && surfType !=
"none")
780 word surfName(surfDict_.lookupOrDefault(
"name", name()));
791 mesh.time().constant(),
811 <<
"AMI interpolators only available to owner patch" 830 <<
"AMI transforms only available to owner patch" 839 return AMITransforms_;
847 return AMILowWeightCorrection_ > 0;
851 return neighbPatch().AMILowWeightCorrection_ > 0;
860 return AMIs()[0].srcWeightsSum();
864 return neighbPatch().AMIs()[0].tgtWeightsSum();
873 return AMIs()[0].tgtWeightsSum();
877 return neighbPatch().AMIs()[0].srcWeightsSum();
896 else if (separated())
927 forwardT().size() == 1
941 else if (separated())
945 separation().size() == 1
947 : separation()[facei]
965 forwardT().size() == 1
985 reverseT().size() == 1
999 else if (separated())
1003 separation().size() == 1
1005 : separation()[facei]
1023 reverseT().size() == 1
1050 pow(
inv(AMITransforms()[i]).
R()(cmpt, cmpt), rank);
1053 AMIs()[i].interpolateToSource(r*fld, defaultValues);
1064 nei.
AMIs()[i].interpolateToTarget(r*fld, defaultValues);
1128 reverseTransformPosition(pt, facei);
1131 reverseTransformDirection(nt, facei);
1137 point ptt = AMITransforms()[i].transformPosition(pt);
1138 const vector ntt = AMITransforms()[i].transform(nt);
1140 const label nbrFacei =
1141 AMIs()[i].tgtPointFace(*
this, neighbPatch(), ntt, facei, ptt);
1152 forAll(neighbPatch().AMIs(), i)
1155 neighbPatch().AMITransforms()[i].invTransformPosition(pt);
1157 neighbPatch().AMITransforms()[i].invTransform(nt);
1159 const label nbrFacei =
1160 neighbPatch().AMIs()[i].srcPointFace
1185 const label proc = patch.
AMIs()[0].singlePatchProc();
1187 for (
label i = 1; i < patch.
AMIs().size(); ++ i)
1189 if (patch.
AMIs()[i].singlePatchProc() != proc)
1202 if (!nbrPatchName_.empty())
1204 writeEntry(os,
"neighbourPatch", nbrPatchName_);
1206 coupleGroup_.write(os);
1212 writeEntry(os,
"rotationAxis", rotationAxis_);
1213 writeEntry(os,
"rotationCentre", rotationCentre_);
1215 if (rotationAngleDefined_)
1224 writeEntry(os,
"separationVector", separationVector_);
1242 if (AMILowWeightCorrection_ > 0)
1244 writeEntry(os,
"lowWeightCorrection", AMILowWeightCorrection_);
1254 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.
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.
Unit conversion functions.
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.
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.
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 AMIInterpolation::interpolationMethod AMIMethod=AMIInterpolation::imFaceAreaWeight)
Construct from (base couped patch) components.
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.
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< 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)
const AMIInterpolation::interpolationMethod AMIMethod_
AMI Method.
const PtrList< AMIInterpolation > & AMIs() const
Return a reference to the AMI interpolators.
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)
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)
void writeEntry(Ostream &os, const HashTable< T, Key, Hash > &ht)
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
PrimitivePatch< SubList< face >, 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.
virtual const cyclicAMIPolyPatch & neighbPatch() const
Return a reference to the neighbour patch.
prefixOSstream Pout(cout, "Pout")
const List< FaceType > & localFaces() const
Return patch faces addressing into local point list.
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.
static interpolationMethod wordTointerpolationMethod(const word &method)
Convert word to interpolationMethod.
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 &)
virtual void transformDirection(vector &d, const label facei) const
Transform a patch-based direction from nbr side to this side.
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.