Go to the documentation of this file.
59 scalar maxAreaSqr = -GREAT;
65 if (areaSqr > maxAreaSqr)
84 half0Areas[facei] = half0[facei].normal(half0.
points());
92 half1Areas[facei] = half1[facei].normal(half1.
points());
116 if (debug && owner())
121 Pout<<
"cyclicPolyPatch::calcTransforms : Writing " <<
name()
122 <<
" faces to OBJ file " << nm0 <<
endl;
128 Pout<<
"cyclicPolyPatch::calcTransforms : Writing " << half1.
name()
129 <<
" faces to OBJ file " << nm1 <<
endl;
135 Pout<<
"cyclicPolyPatch::calcTransforms :"
136 <<
" Writing coupled face centres as lines to " << str.
name()
140 const point& p0 = half0Ctrs[i];
141 str <<
"v " << p0.
x() <<
' ' << p0.
y() <<
' ' << p0.
z() <<
nl;
143 const point& p1 = half1Ctrs[i];
144 str <<
"v " << p1.
x() <<
' ' << p1.
y() <<
' ' << p1.
z() <<
nl;
146 str <<
"l " << vertI-1 <<
' ' << vertI <<
nl;
154 if (half0Ctrs.size() != half1Ctrs.size())
157 <<
"For patch " <<
name()
158 <<
" there are " << half0Ctrs.size()
159 <<
" face centres, for the neighbour patch " << neighbPatch().name()
160 <<
" there are " << half1Ctrs.size()
167 <<
"Patch " <<
name()
168 <<
" has transform type " << transformTypeNames[
transform()]
169 <<
", neighbour patch " << neighbPatchName()
170 <<
" has transform type "
171 << neighbPatch().transformTypeNames[neighbPatch().transform()]
178 if (half0Ctrs.size() > 0)
183 scalar maxAreaDiff = -GREAT;
184 label maxAreaFacei = -1;
188 scalar magSf =
mag(half0Areas[facei]);
189 scalar nbrMagSf =
mag(half1Areas[facei]);
190 scalar avSf = (magSf + nbrMagSf)/2.0;
192 if (magSf < ROOTVSMALL && nbrMagSf < ROOTVSMALL)
197 half0Normals[facei] =
point(1, 0, 0);
198 half1Normals[facei] = half0Normals[facei];
202 scalar areaDiff =
mag(magSf - nbrMagSf)/avSf;
204 if (areaDiff > maxAreaDiff)
206 maxAreaDiff = areaDiff;
207 maxAreaFacei = facei;
210 if (areaDiff > matchTolerance())
214 <<
" area does not match neighbour by "
216 <<
"% -- possible face ordering problem." <<
endl
217 <<
"patch:" <<
name()
218 <<
" my area:" << magSf
219 <<
" neighbour area:" << nbrMagSf
220 <<
" matching tolerance:" << matchTolerance()
222 <<
"Mesh face:" << start()+facei
223 <<
" fc:" << half0Ctrs[facei]
225 <<
"Neighbour fc:" << half1Ctrs[facei]
227 <<
"If you are certain your matching is correct"
228 <<
" you can increase the 'matchTolerance' setting"
229 <<
" in the patch dictionary in the boundary file."
231 <<
"Rerun with cyclic debug flag set"
236 half0Normals[facei] = half0Areas[facei] / magSf;
237 half1Normals[facei] = half1Areas[facei] / nbrMagSf;
246 Pout<<
"cyclicPolyPatch::calcTransforms :"
247 <<
" patch:" <<
name()
248 <<
" Max area error:" << 100*maxAreaDiff <<
"% at face:"
249 << maxAreaFacei <<
" at:" << half0Ctrs[maxAreaFacei]
250 <<
" coupled face at:" << half1Ctrs[maxAreaFacei]
261 vector n0 = findFaceMaxRadius(half0Ctrs);
262 vector n1 = -findFaceMaxRadius(half1Ctrs);
263 n0 /=
mag(n0) + VSMALL;
264 n1 /=
mag(n1) + VSMALL;
270 Pout<<
"cyclicPolyPatch::calcTransforms :"
271 <<
" patch:" <<
name()
272 <<
" Specified rotation :"
273 <<
" n0:" << n0 <<
" n1:" << n1
274 <<
" swept angle: " << theta <<
" [deg]"
283 (n0 ^ rotationAxis_),
289 (-n1 ^ rotationAxis_),
292 const tensor revT(E1.
T() & E0);
328 Pout<<
"cyclicPolyPatch::calcTransforms :"
329 <<
" patch:" <<
name()
330 <<
" Specified separation vector : "
331 << separationVector_ <<
endl;
335 const scalar avgTol =
average(half0Tols);
338 mag(separationVector_ + neighbPatch().separationVector_)
343 <<
"Specified separation vector " << separationVector_
344 <<
" differs by that of neighbouring patch "
345 << neighbPatch().separationVector_
346 <<
" by more than tolerance " << avgTol <<
endl
347 <<
"patch:" <<
name()
348 <<
" neighbour:" << neighbPatchName()
356 separation().size() != 1
357 ||
mag(separation()[0] - separationVector_) > avgTol
361 <<
"Specified separationVector " << separationVector_
362 <<
" differs from computed separation vector "
363 << separation() <<
endl
364 <<
"This probably means your geometry is not consistent"
365 <<
" with the specified separation and might lead"
366 <<
" to problems." <<
endl
367 <<
"Continuing with specified separation vector "
368 << separationVector_ <<
endl
369 <<
"patch:" <<
name()
370 <<
" neighbour:" << neighbPatchName()
407 Pout<<
"cyclicPolyPatch::getCentresAndAnchors :"
408 <<
" patch:" <<
name() <<
nl
409 <<
"half0 untransformed faceCentres (avg) : "
411 <<
"half1 untransformed faceCentres (avg) : "
415 if (half0Ctrs.size())
421 vector n0 = findFaceMaxRadius(half0Ctrs);
422 vector n1 = -findFaceMaxRadius(half1Ctrs);
423 n0 /=
mag(n0) + VSMALL;
424 n1 /=
mag(n1) + VSMALL;
430 Pout<<
"cyclicPolyPatch::getCentresAndAnchors :"
431 <<
" patch:" <<
name()
432 <<
" Specified rotation :"
433 <<
" n0:" << n0 <<
" n1:" << n1
434 <<
" swept angle: " << theta <<
" [deg]"
443 (n0 ^ rotationAxis_),
449 (-n1 ^ rotationAxis_),
452 const tensor revT(E1.
T() & E0);
461 half0Ctrs[faceI] - rotationCentre_
468 anchors0[faceI] - rotationCentre_
481 Pout<<
"cyclicPolyPatch::getCentresAndAnchors :"
482 <<
" patch:" <<
name()
483 <<
"Specified translation : " << separationVector_
490 half0Ctrs -= separationVector_;
491 anchors0 -= separationVector_;
503 n0 /=
mag(n0) + VSMALL;
507 n1 /=
mag(n1) + VSMALL;
509 if (
mag(n0 & n1) < 1-matchTolerance())
513 Pout<<
"cyclicPolyPatch::getCentresAndAnchors :"
514 <<
" patch:" <<
name()
515 <<
" Detected rotation :"
516 <<
" n0:" << n0 <<
" n1:" << n1 <<
endl;
546 Pout<<
"cyclicPolyPatch::getCentresAndAnchors :"
547 <<
" patch:" <<
name()
548 <<
" Detected translation :"
549 <<
" n0:" << n0 <<
" n1:" << n1
550 <<
" ctr0:" << ctr0 <<
" ctr1:" << ctr1 <<
endl;
553 half0Ctrs += ctr1 - ctr0;
554 anchors0 += ctr1 - ctr0;
562 tols = matchTolerance()*calcFaceTol(pp1, pp1.
points(), half1Ctrs);
573 const vectorField n((faceCentres - rotationCentre_) ^ rotationAxis_);
581 Info<<
"findFaceMaxRadius(const pointField&) : patch: " <<
name() <<
nl
582 <<
" rotFace = " << faceI <<
nl
583 <<
" point = " << faceCentres[faceI] <<
nl
584 <<
" distance = " <<
Foam::sqrt(magRadSqr[faceI])
601 const word& patchType,
611 coupledPointsPtr_(NULL),
612 coupledEdgesPtr_(NULL)
626 const word& neighbPatchName,
628 const vector& rotationAxis,
629 const point& rotationCentre,
630 const vector& separationVector
634 neighbPatchName_(neighbPatchName),
636 rotationAxis_(rotationAxis),
637 rotationCentre_(rotationCentre),
638 separationVector_(separationVector),
639 coupledPointsPtr_(NULL),
640 coupledEdgesPtr_(NULL)
653 const word& patchType
663 coupledPointsPtr_(NULL),
664 coupledEdgesPtr_(NULL)
671 ) <<
"No \"neighbourPatch\" provided." <<
endl
672 <<
"Is your mesh uptodate with split cyclics?" <<
endl
673 <<
"Run foamUpgradeCyclics to convert mesh and fields"
677 if (neighbPatchName_ ==
name)
680 <<
"Neighbour patch name " << neighbPatchName_
681 <<
" cannot be the same as this patch " <<
name
690 dict.
lookup(
"rotationCentre") >> rotationCentre_;
692 scalar magRot =
mag(rotationAxis_);
696 <<
"Illegal rotationAxis " << rotationAxis_ <<
endl
697 <<
"Please supply a non-zero vector."
700 rotationAxis_ /= magRot;
706 dict.
lookup(
"separationVector") >> separationVector_;
733 coupledPointsPtr_(NULL),
734 coupledEdgesPtr_(NULL)
747 const label newStart,
748 const word& neighbName
752 neighbPatchName_(neighbName),
758 coupledPointsPtr_(NULL),
759 coupledEdgesPtr_(NULL)
761 if (neighbName ==
name())
764 <<
"Neighbour patch name " << neighbName
765 <<
" cannot be the same as this patch " <<
name()
790 coupledPointsPtr_(NULL),
791 coupledEdgesPtr_(NULL)
808 if (neighbPatchName_.empty())
811 label patchID = coupleGroup_.findOtherPatchID(*
this);
815 return neighbPatchName_;
821 if (neighbPatchID_ == -1)
825 if (neighbPatchID_ == -1)
828 <<
"Illegal neighbourPatch name " << neighbPatchName()
829 <<
endl <<
"Valid patch names are "
843 <<
"Patch " <<
name()
844 <<
" specifies neighbour patch " << neighbPatchName()
845 <<
endl <<
" but that in return specifies "
850 return neighbPatchID_;
869 else if (separated())
896 forwardT().size() == 1
910 else if (separated())
914 separation().size() == 1
916 : separation()[facei]
970 neighbPatch().faceCentres(),
971 neighbPatch().faceAreas(),
972 neighbPatch().faceCellCentres()
1014 if (!coupledPointsPtr_)
1016 const faceList& nbrLocalFaces = neighbPatch().localFaces();
1017 const labelList& nbrMeshPoints = neighbPatch().meshPoints();
1026 forAll(*
this, patchFaceI)
1028 const face& fA = localFaces()[patchFaceI];
1029 const face& fB = nbrLocalFaces[patchFaceI];
1033 label patchPointA = fA[indexA];
1035 if (coupledPoint[patchPointA] == -1)
1040 if (meshPoints()[patchPointA] != nbrMeshPoints[fB[indexB]])
1042 coupledPoint[patchPointA] = fB[indexB];
1049 edgeList& connected = *coupledPointsPtr_;
1052 label connectedI = 0;
1056 if (coupledPoint[i] != -1)
1058 connected[connectedI++] =
edge(i, coupledPoint[i]);
1062 connected.
setSize(connectedI);
1069 /
name() +
"_coupledPoints.obj"
1073 Pout<<
"Writing file " << str.
name() <<
" with coordinates of "
1074 <<
"coupled points" <<
endl;
1078 const point& a =
points()[meshPoints()[connected[i][0]]];
1079 const point&
b =
points()[nbrMeshPoints[connected[i][1]]];
1081 str<<
"v " << a.
x() <<
' ' << a.
y() <<
' ' << a.
z() <<
nl;
1082 str<<
"v " <<
b.x() <<
' ' <<
b.y() <<
' ' <<
b.z() <<
nl;
1085 str<<
"l " << vertI-1 <<
' ' << vertI <<
nl;
1089 return *coupledPointsPtr_;
1095 if (!coupledEdgesPtr_)
1097 const edgeList& pointCouples = coupledPoints();
1104 const edge&
e = pointCouples[i];
1106 aToB.insert(
e[0],
e[1]);
1112 forAll(*
this, patchFaceI)
1114 const labelList& fEdges = faceEdges()[patchFaceI];
1118 label edgeI = fEdges[i];
1120 const edge&
e = edges()[edgeI];
1124 if (fnd0 != aToB.end())
1127 if (fnd1 != aToB.end())
1144 edgeList& coupledEdges = *coupledEdgesPtr_;
1147 forAll(neighbPatch, patchFaceI)
1153 label edgeI = fEdges[i];
1160 if (iter != edgeMap.end())
1162 label edgeA = iter();
1163 const edge& eA = edges()[edgeA];
1169 !=
edge(nbrMp[
e[0]], nbrMp[
e[1]])
1172 coupledEdges[coupleI++] =
edge(edgeA, edgeI);
1176 edgeMap.
erase(iter);
1180 coupledEdges.
setSize(coupleI);
1187 const edge&
e = coupledEdges[i];
1189 if (
e[0] < 0 ||
e[1] < 0)
1192 <<
"Problem : at position " << i
1193 <<
" illegal couple:" <<
e
1203 /
name() +
"_coupledEdges.obj"
1207 Pout<<
"Writing file " << str.
name() <<
" with centres of "
1208 <<
"coupled edges" <<
endl;
1212 const edge&
e = coupledEdges[i];
1220 str<<
"v " << a.
x() <<
' ' << a.
y() <<
' ' << a.
z() <<
nl;
1221 str<<
"v " <<
b.x() <<
' ' <<
b.y() <<
' ' <<
b.z() <<
nl;
1224 str<<
"l " << vertI-1 <<
' ' << vertI <<
nl;
1228 return *coupledEdgesPtr_;
1242 ownerPatchPtr_.reset
1264 Pout<<
"order : of " << pp.size()
1265 <<
" faces of patch:" <<
name()
1266 <<
" neighbour:" << neighbPatchName()
1287 faceMap[patchFaceI] = patchFaceI;
1300 getCentresAndAnchors
1313 Pout<<
"half0 transformed faceCentres (avg) : "
1315 <<
"half1 untransformed faceCentres (avg) : "
1329 if (!matchedAll || debug)
1335 /neighbPatch().
name()+
"_faces.obj"
1337 Pout<<
"cyclicPolyPatch::order : Writing neighbour"
1338 <<
" faces to OBJ file " << nm0 <<
endl;
1344 /
name()+
"_faces.obj"
1346 Pout<<
"cyclicPolyPatch::order : Writing my"
1347 <<
" faces to OBJ file " << nm1 <<
endl;
1353 /
name() +
"_faceCentres.obj"
1355 Pout<<
"cyclicPolyPatch::order : "
1356 <<
"Dumping currently found cyclic match as lines between"
1357 <<
" corresponding face centres to file " << ccStr.
name()
1371 const point&
c1 = half1Ctrs[i];
1380 <<
"Patch:" <<
name() <<
" : "
1381 <<
"Cannot match vectors to faces on both sides of patch"
1383 <<
" Perhaps your faces do not match?"
1384 <<
" The obj files written contain the current match." <<
endl
1385 <<
" Continuing with incorrect face ordering from now on!"
1401 const point& wantedAnchor = anchors0[newFaceI];
1403 rotation[newFaceI] = getRotation
1411 if (rotation[newFaceI] == -1)
1414 <<
"in patch " <<
name()
1416 <<
"Cannot find point on face " << pp[oldFaceI]
1417 <<
" with vertices "
1419 <<
" that matches point " << wantedAnchor
1420 <<
" when matching the halves of processor patch " <<
name()
1421 <<
"Continuing with incorrect face ordering from now on!"
1428 ownerPatchPtr_.clear();
1434 if (
faceMap[faceI] != faceI || rotation[faceI] != 0)
1448 if (!neighbPatchName_.empty())
1453 coupleGroup_.write(os);
1466 os.
writeKeyword(
"separationVector") << separationVector_
Templated 3D tensor derived from VectorSpace adding construction from 9 components,...
static label findMaxArea(const pointField &, const faceList &)
Find amongst selected faces the one with the largest area.
points setSize(newPointi)
static bool valid(char)
Is this character valid for a word.
const dimensionedScalar mp
Proton mass.
label findMax(const ListType &, const label start=0)
Find index of max element (and larger than given element).
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
virtual void updateMesh(PstreamBuffers &)
Update of the patch topology.
virtual void initMovePoints(PstreamBuffers &, const pointField &)
Initialise the patches for moving points.
const Field< PointType > & points() const
Return reference to global points.
A class for handling words, derived from string.
A class for handling file names.
virtual void movePoints(PstreamBuffers &, const pointField &p)
Correct patches after moving points.
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
#define forAll(list, i)
Loop across all elements in list.
void writeOBJ(Ostream &os, label &vertI, const tetPoints &tet)
Type gAverage(const FieldField< Field, Type > &f)
virtual void initGeometry(PstreamBuffers &)
Initialise the calculation of the patch geometry.
const cyclicPolyPatch & neighbPatch() const
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
virtual bool order(PstreamBuffers &, const primitivePatch &, labelList &faceMap, labelList &rotation) const
Return new ordering for primitivePatch.
Template functions to aid in the implementation of demand driven data.
const Field< PointType > & localPoints() const
Return pointField of points in patch.
Buffers for inter-processor communications streams (UOPstream, UIPstream).
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Field< tensor > tensorField
Specialisation of Field<T> for tensor.
vector separationVector_
Translation vector.
T lookupOrDefault(const word &, const T &, bool recursive=false, bool patternMatch=true) const
Find and return a T,.
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
Unit conversion functions.
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
Ostream & endl(Ostream &os)
Add newline and flush stream.
The coupledPolyPatch is an abstract base class for patches that couple regions of the computational d...
const labelListList & faceEdges() const
Return face-edge addressing.
dimensioned< scalar > mag(const dimensioned< Type > &)
virtual void updateMesh(PstreamBuffers &)
Update of the patch topology.
dimensionSet transform(const dimensionSet &)
const edgeList & coupledPoints() const
Return connected points (from patch local to neighbour patch local)
void deleteDemandDrivenData(DataPtr &dataPtr)
vector rotationAxis_
Axis of rotation for rotational cyclics.
Determine correspondence between points. See below.
virtual void initUpdateMesh(PstreamBuffers &)
Initialise the update of the patch topology.
const dimensionedScalar c1
First radiation constant: default SI units: [W/m2].
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Pre-declare SubField and related Field type.
point rotationCentre_
Point on axis of rotation for rotational cyclics.
virtual void initMovePoints(PstreamBuffers &, const pointField &)
Initialise the patches for moving points.
virtual void calcGeometry(PstreamBuffers &)
Calculate the patch geometry.
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
A List with indirect addressing.
#define SeriousErrorInFunction
Report an error message using Foam::SeriousError.
const Vector< Cmpt > & centre(const Foam::List< Vector< Cmpt > > &) const
Return *this (used for point which is a typedef to Vector<scalar>.
bool erase(const iterator &)
Erase a hashedEntry specified by given iterator.
virtual void initGeometry(PstreamBuffers &)
Initialise the calculation of the patch geometry.
void getCentresAndAnchors(const primitivePatch &pp0, const primitivePatch &pp1, pointField &half0Ctrs, pointField &half1Ctrs, pointField &anchors0, scalarField &tols) const
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
const edgeList & coupledEdges() const
Return connected edges (from patch local to neighbour patch local).
label nPoints() const
Return number of points supporting patch faces.
A list of keyword definitions, which are a keyword followed by any number of values (e....
label size() const
Return number of elements in table.
virtual void transformPosition(pointField &l) const
Transform a patch-based position from other side to this side.
Macros for easy insertion into run-time selection tables.
virtual ~cyclicPolyPatch()
Destructor.
errorManip< error > abort(error &err)
const double e
Elementary charge.
List< bool > boolList
Bool container classes.
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))
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
errorManipArg< error, int > exit(error &err, const int errNo=1)
const coupleGroupIdentifier coupleGroup_
Optional patchGroup to find neighbPatch.
virtual void movePoints(PstreamBuffers &, const pointField &)
Correct patches after moving points.
void setSize(const label)
Reset size of List.
vector findFaceMaxRadius(const pointField &faceCentres) const
Return normal of face at max distance from rotation axis.
virtual void initOrder(PstreamBuffers &, const primitivePatch &) const
Initialize ordering for primitivePatch. Does not.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
prefixOSstream Pout(cout, "Pout")
const vectorField::subField faceCentres() const
Return face centres.
virtual void write(Ostream &) const
Write the polyPatch data as a dictionary.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensionedScalar acos(const dimensionedScalar &ds)
word neighbPatchName_
Name of other half.
const Field< PointType > & faceCentres() const
Return face centres for patch.
Ostream & writeKeyword(const keyType &)
Write the keyword followed by an appropriate indentation.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
static const word null
An empty word.
virtual void calcTransforms()
Recalculate the transformation tensors.
scalar radToDeg(const scalar rad)
Conversion from radians to degrees.
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
A face is a list of labels corresponding to mesh vertices.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
label findPatchID(const polyPatchList &, const word &) const
Get index of polypatch by name.
const fileName & name() const
Return the name of the stream.
void size(const label)
Override size to be inconsistent with allocated storage.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
tensor rotationTensor(const vector &n1, const vector &n2)
vector point
Point is a vector.
const labelList & meshPoints() const
Return labelList of mesh points in patch.
defineTypeNameAndDebug(combustionModel, 0)
const word & name() const
Return name.
virtual label neighbPatchID() const
Neighbour patchID.
bool matchPoints(const UList< point > &pts0, const UList< point > &pts1, const UList< scalar > &matchDistance, const bool verbose, labelList &from0To1, const point &origin=point::zero)
Determine correspondence between pointFields. Gets passed.
#define WarningInFunction
Report a warning using Foam::Warning.
const word & neighbPatchName() const
Neighbour patch name.
dimensioned< scalar > magSqr(const dimensioned< Type > &)
word name(const complex &)
Return a string representation of a complex.
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &df)
A normal distribution model.
A list of faces which address into the list of points.
cyclicPolyPatch(const word &name, const label size, const label start, const label index, const polyBoundaryMesh &bm, const word &patchType, const transformType transform=UNKNOWN)
Construct from components.
Tensor< Cmpt > T() const
Transpose.