52Foam::vector Foam::cyclicAMIPolyPatch::findFaceNormalMaxRadius
54 const pointField& faceCentres
63 label facei =
findMax(magRadSqr);
66 <<
"Patch: " <<
name() <<
nl
67 <<
" rotFace = " << facei <<
nl
69 <<
" distance = " <<
Foam::sqrt(magRadSqr[facei])
89 <<
" has transform type " << transformTypeNames[
transform()]
90 <<
", neighbour patch " << neighbPatchName()
91 <<
" has transform type "
92 << neighbPatch().transformTypeNames[neighbPatch().transform()]
105 if (rotationAngleDefined_)
107 const tensor T(rotationAxis_*rotationAxis_);
111 0, -rotationAxis_.z(), rotationAxis_.y(),
112 rotationAxis_.z(), 0, -rotationAxis_.x(),
113 -rotationAxis_.y(), rotationAxis_.x(), 0
120 +
sin(rotationAngle_)*S
127 +
sin(-rotationAngle_)*S
132 const vector transformedAreaPos =
gSum(half1Areas & revTPos);
133 const vector transformedAreaNeg =
gSum(half1Areas & revTNeg);
135 const scalar magArea0 =
mag(area0) + ROOTVSMALL;
139 const scalar errorPos =
mag(transformedAreaPos + area0);
140 const scalar errorNeg =
mag(transformedAreaNeg + area0);
142 const scalar normErrorPos = errorPos/magArea0;
143 const scalar normErrorNeg = errorNeg/magArea0;
145 if (errorPos > errorNeg && normErrorNeg < matchTolerance())
148 rotationAngle_ *= -1;
155 const scalar areaError =
min(normErrorPos, normErrorNeg);
157 if (areaError > matchTolerance())
160 <<
"Patch areas are not consistent within "
161 << 100*matchTolerance()
162 <<
" % indicating a possible error in the specified "
163 <<
"angle of rotation" <<
nl
164 <<
" owner patch : " <<
name() <<
nl
165 <<
" neighbour patch : " << neighbPatch().name()
169 <<
" area error : " << 100*areaError <<
" %"
170 <<
" match tolerance : " << matchTolerance()
176 scalar theta =
radToDeg(rotationAngle_);
178 Pout<<
"cyclicAMIPolyPatch::calcTransforms: patch:"
180 <<
" Specified rotation:"
181 <<
" swept angle: " << theta <<
" [deg]"
182 <<
" reverse transform: " << revT
190 if (half0Ctrs.size())
192 n0 = findFaceNormalMaxRadius(half0Ctrs);
194 if (half1Ctrs.size())
196 n1 = -findFaceNormalMaxRadius(half1Ctrs);
199 reduce(n0, maxMagSqrOp<point>());
200 reduce(n1, maxMagSqrOp<point>());
210 (n0 ^ rotationAxis_),
216 (-n1 ^ rotationAxis_),
225 Pout<<
"cyclicAMIPolyPatch::calcTransforms: patch:"
227 <<
" Specified rotation:"
228 <<
" n0:" << n0 <<
" n1:" << n1
229 <<
" swept angle: " << theta <<
" [deg]"
230 <<
" reverse transform: " << revT
246 Pout<<
"cyclicAMIPolyPatch::calcTransforms : patch:" <<
name()
247 <<
" Specified translation : " << separationVector_
267 <<
" Assuming cyclic AMI pairs are colocated" <<
endl;
282 <<
" forwardT = " << forwardT() <<
nl
283 <<
" reverseT = " << reverseT() <<
nl
284 <<
" separation = " << separation() <<
nl
285 <<
" collocated = " << collocated() <<
nl <<
endl;
293 const label periodicID = periodicPatchID();
294 if (periodicID != -1)
299 refCast<const coupledPolyPatch>
308 if (isA<cyclicPolyPatch>(perPp))
311 refCast<const cyclicPolyPatch>(perPp).rotationAxis();
313 refCast<const cyclicPolyPatch>(perPp).rotationCentre();
315 else if (isA<cyclicAMIPolyPatch>(perPp))
318 refCast<const cyclicAMIPolyPatch>(perPp).rotationAxis();
320 refCast<const cyclicAMIPolyPatch>(perPp).rotationCentre();
325 <<
" have unsupported periodicPatch " << perPp.
name()
341 const word surfType(surfDict_.getOrDefault<
word>(
"type",
"none"));
343 if (!surfPtr_ && owner() && surfType !=
"none")
345 word surfName(surfDict_.getOrDefault(
"name",
name()));
396 label patchSize0 = size();
397 label nbrPatchSize0 = nbr.size();
402 if (srcFaceIDs_.size())
404 patchSize0 = srcFaceIDs_.size();
406 if (tgtFaceIDs_.size())
408 nbrPatchSize0 = tgtFaceIDs_.size();
413 transformPosition(nbrPoints);
437 AMIPtr_->upToDate() =
false;
438 AMIPtr_->calculate(patch0, nbrPatch0, surfPtr());
442 AMIPtr_->checkSymmetricWeights(
true);
455 half0Areas[facei] = half0[facei].areaNormal(half0.
points());
462 half1Areas[facei] = half1[facei].areaNormal(half1.
points());
475 <<
"calcTransforms() : patch: " <<
name() <<
nl
476 <<
" forwardT = " << forwardT() <<
nl
477 <<
" reverseT = " << reverseT() <<
nl
478 <<
" separation = " << separation() <<
nl
479 <<
" collocated = " << collocated() <<
nl <<
endl;
488 AMIPtr_->upToDate() =
false;
528 restoreScaledGeometry();
534 AMIPtr_->upToDate() =
false;
594 AMIPtr_->upToDate() =
false;
610 const word& patchType,
612 const word& defaultAMIMethod
616 nbrPatchName_(
word::null),
620 rotationCentre_(
Zero),
621 rotationAngleDefined_(false),
623 separationVector_(
Zero),
624 periodicPatchName_(
word::null),
625 periodicPatchID_(-1),
629 createAMIFaces_(false),
630 moveFaceCentres_(false),
648 const word& patchType,
649 const word& defaultAMIMethod
653 nbrPatchName_(
dict.getOrDefault<
word>(
"neighbourPatch",
word::null)),
656 fraction_(
dict.getOrDefault<scalar>(
"fraction",
Zero)),
658 rotationCentre_(
Zero),
659 rotationAngleDefined_(false),
661 separationVector_(
Zero),
662 periodicPatchName_(
dict.getOrDefault<
word>(
"periodicPatch",
word::null)),
663 periodicPatchID_(-1),
668 dict.getOrDefault<
word>(
"AMIMethod", defaultAMIMethod),
670 dict.getOrDefault(
"flipNormals", false)
673 surfDict_(
dict.subOrEmptyDict(
"surface")),
675 createAMIFaces_(
dict.getOrDefault(
"createAMIFaces", false)),
676 moveFaceCentres_(false),
686 <<
"No \"neighbourPatch\" or \"coupleGroup\" provided."
694 <<
" cannot be the same as this patch " <<
name
721 <<
"Please supply a non-zero vector."
760 nbrPatchName_(pp.nbrPatchName_),
761 coupleGroup_(pp.coupleGroup_),
763 fraction_(pp.fraction_),
764 rotationAxis_(pp.rotationAxis_),
765 rotationCentre_(pp.rotationCentre_),
766 rotationAngleDefined_(pp.rotationAngleDefined_),
767 rotationAngle_(pp.rotationAngle_),
768 separationVector_(pp.separationVector_),
769 periodicPatchName_(pp.periodicPatchName_),
770 periodicPatchID_(-1),
771 AMIPtr_(pp.AMIPtr_->clone()),
772 surfDict_(pp.surfDict_),
774 createAMIFaces_(pp.createAMIFaces_),
775 moveFaceCentres_(pp.moveFaceCentres_),
793 const label newStart,
794 const word& nbrPatchName
798 nbrPatchName_(nbrPatchName),
799 coupleGroup_(pp.coupleGroup_),
801 fraction_(pp.fraction_),
802 rotationAxis_(pp.rotationAxis_),
803 rotationCentre_(pp.rotationCentre_),
804 rotationAngleDefined_(pp.rotationAngleDefined_),
805 rotationAngle_(pp.rotationAngle_),
806 separationVector_(pp.separationVector_),
807 periodicPatchName_(pp.periodicPatchName_),
808 periodicPatchID_(-1),
809 AMIPtr_(pp.AMIPtr_->clone()),
810 surfDict_(pp.surfDict_),
812 createAMIFaces_(pp.createAMIFaces_),
813 moveFaceCentres_(pp.moveFaceCentres_),
824 <<
" cannot be the same as this patch " <<
name()
843 nbrPatchName_(pp.nbrPatchName_),
844 coupleGroup_(pp.coupleGroup_),
846 fraction_(pp.fraction_),
847 rotationAxis_(pp.rotationAxis_),
848 rotationCentre_(pp.rotationCentre_),
849 rotationAngleDefined_(pp.rotationAngleDefined_),
850 rotationAngle_(pp.rotationAngle_),
851 separationVector_(pp.separationVector_),
852 periodicPatchName_(pp.periodicPatchName_),
853 periodicPatchID_(-1),
854 AMIPtr_(pp.AMIPtr_->clone()),
855 surfDict_(pp.surfDict_),
857 createAMIFaces_(pp.createAMIFaces_),
858 moveFaceCentres_(pp.moveFaceCentres_),
877 forAll (addSourceFaces, faceI)
879 const labelList& nbrFaceIs = addSourceFaces[faceI];
883 label nbrFaceI = nbrFaceIs[j];
885 if (nbrFaceI < neighbPatch().size())
902 if (nbrPatchID_ == -1)
904 nbrPatchID_ = this->
boundaryMesh().findPatchID(neighbPatchName());
906 if (nbrPatchID_ == -1)
909 <<
"Illegal neighbourPatch name " << neighbPatchName()
910 <<
nl <<
"Valid patch names are "
917 refCast<const cyclicAMIPolyPatch>
925 <<
"Patch " <<
name()
926 <<
" specifies neighbour patch " << neighbPatchName()
927 <<
nl <<
" but that in return specifies "
944 if (periodicPatchID_ == -1)
946 periodicPatchID_ =
boundaryMesh().findPatchID(periodicPatchName_);
948 if (periodicPatchID_ == -1)
951 <<
"Illegal neighbourPatch name " << periodicPatchName_
952 <<
nl <<
"Valid patch names are "
957 return periodicPatchID_;
964 return index() < neighbPatchID();
971 return refCast<const cyclicAMIPolyPatch>(pp);
980 <<
"AMI interpolator only available to owner patch"
984 if (!AMIPtr_->upToDate())
997 return AMI().applyLowWeightCorrection();
1001 return neighbPatch().AMI().applyLowWeightCorrection();
1020 else if (separated())
1051 forwardT().size() == 1
1065 else if (separated())
1069 separation().size() == 1
1071 : separation()[facei]
1089 reverseT().size() == 1
1103 else if (separated())
1107 separation().size() == 1
1109 : separation()[facei]
1127 reverseT().size() == 1
1184 reverseTransformPosition(prt, facei);
1187 reverseTransformDirection(nrt, facei);
1189 label nbrFacei = -1;
1193 nbrFacei = AMI().tgtPointFace
1204 nbrFacei = neighbPatch().AMI().srcPointFace
1226 if (!nbrPatchName_.empty())
1239 if (rotationAngleDefined_)
1268 if (!surfDict_.empty())
1270 surfDict_.writeEntry(surfDict_.dictName(),
os);
1273 if (createAMIFaces_)
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
Interpolation class dealing with transfer of data between two primitive patches with an arbitrary mes...
Defines the attributes of an object for which implicit objectRegistry management is supported,...
void setSize(const label n)
Alias for resize()
Output to file stream, using an OSstream.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Ostream & writeEntryIfDifferent(const word &key, const T &value1, const T &value2)
Write a keyword/value entry only when the two values differ.
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
A list of faces which address into the list of points.
const Field< point_type > & localPoints() const
Return pointField of points in patch.
const Field< point_type > & points() const noexcept
Return reference to global points.
const List< face_type > & localFaces() const
Return patch faces addressing into local point list.
Buffers for inter-processor communications streams (UOPstream, UIPstream).
A List obtained as a section of another List.
const word & constant() const
Return constant name.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
fileName path() const
Return path.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
const bMesh & mesh() const
bool valid() const noexcept
Is a valid patchGroup (non-empty) name.
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
virtual transformType transform() const
Type of transform.
virtual bool parallel() const
Are the cyclic planes parallel.
Cyclic patch for Arbitrary Mesh Interface (AMI)
scalar rotationAngle_
Rotation angle.
vector separationVector_
Translation vector.
word nbrPatchName_
Name of other half.
autoPtr< coordSystem::cylindrical > cylindricalCS() const
Create a coordinate system from the periodic patch (or nullptr)
virtual void resetAMI() const
Reset the AMI interpolator, use current patch points.
bool createAMIFaces_
Flag to indicate that new AMI faces will created.
label pointFace(const label facei, const vector &n, point &p) const
const word & neighbPatchName() const
Neighbour patch name.
virtual bool owner() const
Does this side own the patch?
virtual void clearGeom()
Clear geometry.
virtual void newInternalProcFaces(label &, label &) const
Return number of new internal of this polyPatch faces.
virtual void initGeometry(PstreamBuffers &)
Initialise the calculation of the patch geometry.
virtual void initOrder(PstreamBuffers &, const primitivePatch &) const
virtual void reverseTransformDirection(vector &d, const label facei) const
Transform a patch-based direction from this side to.
const AMIPatchToPatchInterpolation & AMI() const
Return a reference to the AMI interpolator.
point rotationCentre_
Point on axis of rotation for rotational cyclics.
virtual const cyclicAMIPolyPatch & neighbPatch() const
Return a reference to the neighbour patch.
labelListList tgtFaceIDs_
labelListList srcFaceIDs_
static const scalar tolerance_
Tolerance used e.g. for area calculations/limits.
const autoPtr< searchableSurface > & surfPtr() const
Create and return pointer to the projection surface.
bool rotationAngleDefined_
Flag to show whether the rotation angle is defined.
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
bool applyLowWeightCorrection() const
Return true if applying the low weight correction.
const coupleGroupIdentifier coupleGroup_
Optional patchGroup to find neighbPatch.
vector rotationAxis_
Axis of rotation for rotational cyclics.
virtual void reverseTransformPosition(point &l, const label facei) const
Transform a patch-based position from this side to nbr side.
bool moveFaceCentres_
Move face centres (default = no)
label periodicPatchID() const
Periodic patch ID (or -1)
virtual void calcTransforms()
Recalculate the transformation tensors.
virtual label neighbPatchID() const
Neighbour patch ID.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, bool mandatory=true) const
void calcGeometry()
Calculate the geometry for the patches.
A class for handling file names.
virtual bool write()
Write the output fields.
const Time & time() const
Return the top-level database.
virtual void initMovePoints()
Initialise the patches for moving points.
order
Enumeration specifying required accuracy.
void movePoints()
Update for new mesh geometry.
void updateMesh()
Update for new mesh topology.
const word & name() const noexcept
The patch name.
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Mesh consisting of general polyhedral cells.
A patch is a list of labels that address the faces in the global face list.
virtual void initGeometry(PstreamBuffers &)
Initialise the calculation of the patch geometry.
virtual void clearGeom()
Clear geometry.
const vectorField::subField faceCentres() const
Return face centres.
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
Tensor of scalars, i.e. Tensor<scalar>.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
A class for handling words, derived from Foam::string.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
OBJstream os(runTime.globalPath()/outputName)
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.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))
#define WarningInFunction
Report a warning using Foam::Warning.
#define DebugInFunction
Report an information message using Foam::Info.
#define DebugPout
Report an information message using Foam::Pout.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Type gSum(const FieldField< Field, Type > &f)
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
dimensionedScalar sin(const dimensionedScalar &ds)
messageStream Info
Information stream (stdout output on master, null elsewhere)
vectorField pointField
pointField is a vectorField.
vector point
Point is a vector.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
A PrimitivePatch with a SubList addressing for the faces, const reference for the point field.
Ostream & endl(Ostream &os)
Add newline and flush stream.
constexpr scalar degToRad() noexcept
Multiplication factor for degrees to radians conversion.
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
constexpr scalar radToDeg() noexcept
Multiplication factor for radians to degrees conversion.
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
errorManip< error > abort(error &err)
Field< vector > vectorField
Specialisation of Field<T> for vector.
List< bool > boolList
A List of bools.
static constexpr const zero Zero
Global zero (0)
Field< tensor > tensorField
Specialisation of Field<T> for tensor.
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh > > &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
label findMax(const ListType &input, label start=0)
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
dimensionedScalar cos(const dimensionedScalar &ds)
dimensionedScalar acos(const dimensionedScalar &ds)
constexpr char nl
The newline '\n' character (0x0a)
points setSize(newPointi)
#define forAll(list, i)
Loop across all elements in list.
Unit conversion functions.