mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
translation vector on cyclicPolyPatch; adapted createPatch
This commit is contained in:
@ -34,6 +34,7 @@ Description
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "cyclicPolyPatch.H"
|
||||||
#include "syncTools.H"
|
#include "syncTools.H"
|
||||||
#include "argList.H"
|
#include "argList.H"
|
||||||
#include "polyMesh.H"
|
#include "polyMesh.H"
|
||||||
@ -256,27 +257,6 @@ void dumpCyclicMatch(const fileName& prefix, const polyMesh& mesh)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// cycPatch.writeOBJ
|
|
||||||
// (
|
|
||||||
// prefix+cycPatch.name()+"_half0.obj",
|
|
||||||
// SubList<face>
|
|
||||||
// (
|
|
||||||
// cycPatch,
|
|
||||||
// halfSize
|
|
||||||
// ),
|
|
||||||
// cycPatch.points()
|
|
||||||
// );
|
|
||||||
// cycPatch.writeOBJ
|
|
||||||
// (
|
|
||||||
// prefix+cycPatch.name()+"_half1.obj",
|
|
||||||
// SubList<face>
|
|
||||||
// (
|
|
||||||
// cycPatch,
|
|
||||||
// halfSize,
|
|
||||||
// halfSize
|
|
||||||
// ),
|
|
||||||
// cycPatch.points()
|
|
||||||
// );
|
|
||||||
|
|
||||||
// Lines between corresponding face centres
|
// Lines between corresponding face centres
|
||||||
OFstream str(prefix+cycPatch.name()+"_match.obj");
|
OFstream str(prefix+cycPatch.name()+"_match.obj");
|
||||||
@ -289,7 +269,8 @@ void dumpCyclicMatch(const fileName& prefix, const polyMesh& mesh)
|
|||||||
vertI++;
|
vertI++;
|
||||||
|
|
||||||
label nbrFaceI = halfSize + faceI;
|
label nbrFaceI = halfSize + faceI;
|
||||||
const point& fc1 = mesh.faceCentres()[cycPatch.start()+nbrFaceI];
|
const point& fc1 =
|
||||||
|
mesh.faceCentres()[cycPatch.start()+nbrFaceI];
|
||||||
meshTools::writeOBJ(str, fc1);
|
meshTools::writeOBJ(str, fc1);
|
||||||
vertI++;
|
vertI++;
|
||||||
|
|
||||||
@ -300,6 +281,247 @@ void dumpCyclicMatch(const fileName& prefix, const polyMesh& mesh)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void separateList
|
||||||
|
(
|
||||||
|
const vectorField& separation,
|
||||||
|
UList<vector>& field
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (separation.size() == 1)
|
||||||
|
{
|
||||||
|
// Single value for all.
|
||||||
|
|
||||||
|
forAll(field, i)
|
||||||
|
{
|
||||||
|
field[i] += separation[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (separation.size() == field.size())
|
||||||
|
{
|
||||||
|
forAll(field, i)
|
||||||
|
{
|
||||||
|
field[i] += separation[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"separateList(const vectorField&, UList<vector>&)"
|
||||||
|
) << "Sizes of field and transformation not equal. field:"
|
||||||
|
<< field.size() << " transformation:" << separation.size()
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Synchronise points on both sides of coupled boundaries.
|
||||||
|
template <class CombineOp>
|
||||||
|
void syncPoints
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
pointField& points,
|
||||||
|
const CombineOp& cop,
|
||||||
|
const point& nullValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (points.size() != mesh.nPoints())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"syncPoints"
|
||||||
|
"(const polyMesh&, pointField&, const CombineOp&, const point&)"
|
||||||
|
) << "Number of values " << points.size()
|
||||||
|
<< " is not equal to the number of points in the mesh "
|
||||||
|
<< mesh.nPoints() << abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
||||||
|
|
||||||
|
// Is there any coupled patch with transformation?
|
||||||
|
bool hasTransformation = false;
|
||||||
|
|
||||||
|
if (Pstream::parRun())
|
||||||
|
{
|
||||||
|
// Send
|
||||||
|
|
||||||
|
forAll(patches, patchI)
|
||||||
|
{
|
||||||
|
const polyPatch& pp = patches[patchI];
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
isA<processorPolyPatch>(pp)
|
||||||
|
&& pp.nPoints() > 0
|
||||||
|
&& refCast<const processorPolyPatch>(pp).owner()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const processorPolyPatch& procPatch =
|
||||||
|
refCast<const processorPolyPatch>(pp);
|
||||||
|
|
||||||
|
// Get data per patchPoint in neighbouring point numbers.
|
||||||
|
pointField patchInfo(procPatch.nPoints(), nullValue);
|
||||||
|
|
||||||
|
const labelList& meshPts = procPatch.meshPoints();
|
||||||
|
const labelList& nbrPts = procPatch.neighbPoints();
|
||||||
|
|
||||||
|
forAll(nbrPts, pointI)
|
||||||
|
{
|
||||||
|
label nbrPointI = nbrPts[pointI];
|
||||||
|
if (nbrPointI >= 0 && nbrPointI < patchInfo.size())
|
||||||
|
{
|
||||||
|
patchInfo[nbrPointI] = points[meshPts[pointI]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OPstream toNbr(Pstream::blocking, procPatch.neighbProcNo());
|
||||||
|
toNbr << patchInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Receive and set.
|
||||||
|
|
||||||
|
forAll(patches, patchI)
|
||||||
|
{
|
||||||
|
const polyPatch& pp = patches[patchI];
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
isA<processorPolyPatch>(pp)
|
||||||
|
&& pp.nPoints() > 0
|
||||||
|
&& !refCast<const processorPolyPatch>(pp).owner()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const processorPolyPatch& procPatch =
|
||||||
|
refCast<const processorPolyPatch>(pp);
|
||||||
|
|
||||||
|
pointField nbrPatchInfo(procPatch.nPoints());
|
||||||
|
{
|
||||||
|
// We do not know the number of points on the other side
|
||||||
|
// so cannot use Pstream::read.
|
||||||
|
IPstream fromNbr
|
||||||
|
(
|
||||||
|
Pstream::blocking,
|
||||||
|
procPatch.neighbProcNo()
|
||||||
|
);
|
||||||
|
fromNbr >> nbrPatchInfo;
|
||||||
|
}
|
||||||
|
// Null any value which is not on neighbouring processor
|
||||||
|
nbrPatchInfo.setSize(procPatch.nPoints(), nullValue);
|
||||||
|
|
||||||
|
if (!procPatch.parallel())
|
||||||
|
{
|
||||||
|
hasTransformation = true;
|
||||||
|
transformList(procPatch.forwardT(), nbrPatchInfo);
|
||||||
|
}
|
||||||
|
else if (procPatch.separated())
|
||||||
|
{
|
||||||
|
hasTransformation = true;
|
||||||
|
separateList(-procPatch.separation(), nbrPatchInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
const labelList& meshPts = procPatch.meshPoints();
|
||||||
|
|
||||||
|
forAll(meshPts, pointI)
|
||||||
|
{
|
||||||
|
label meshPointI = meshPts[pointI];
|
||||||
|
points[meshPointI] = nbrPatchInfo[pointI];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do the cyclics.
|
||||||
|
forAll(patches, patchI)
|
||||||
|
{
|
||||||
|
const polyPatch& pp = patches[patchI];
|
||||||
|
|
||||||
|
if (isA<cyclicPolyPatch>(pp))
|
||||||
|
{
|
||||||
|
const cyclicPolyPatch& cycPatch =
|
||||||
|
refCast<const cyclicPolyPatch>(pp);
|
||||||
|
|
||||||
|
const edgeList& coupledPoints = cycPatch.coupledPoints();
|
||||||
|
const labelList& meshPts = cycPatch.meshPoints();
|
||||||
|
|
||||||
|
pointField half0Values(coupledPoints.size());
|
||||||
|
|
||||||
|
forAll(coupledPoints, i)
|
||||||
|
{
|
||||||
|
const edge& e = coupledPoints[i];
|
||||||
|
label point0 = meshPts[e[0]];
|
||||||
|
half0Values[i] = points[point0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cycPatch.parallel())
|
||||||
|
{
|
||||||
|
hasTransformation = true;
|
||||||
|
transformList(cycPatch.reverseT(), half0Values);
|
||||||
|
}
|
||||||
|
else if (cycPatch.separated())
|
||||||
|
{
|
||||||
|
hasTransformation = true;
|
||||||
|
const vectorField& v = cycPatch.coupledPolyPatch::separation();
|
||||||
|
separateList(v, half0Values);
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(coupledPoints, i)
|
||||||
|
{
|
||||||
|
const edge& e = coupledPoints[i];
|
||||||
|
label point1 = meshPts[e[1]];
|
||||||
|
points[point1] = half0Values[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Note: hasTransformation is only used for warning messages so
|
||||||
|
// reduction not strictly nessecary.
|
||||||
|
//reduce(hasTransformation, orOp<bool>());
|
||||||
|
|
||||||
|
// Synchronize multiple shared points.
|
||||||
|
const globalMeshData& pd = mesh.globalData();
|
||||||
|
|
||||||
|
if (pd.nGlobalPoints() > 0)
|
||||||
|
{
|
||||||
|
if (hasTransformation)
|
||||||
|
{
|
||||||
|
WarningIn
|
||||||
|
(
|
||||||
|
"syncPoints"
|
||||||
|
"(const polyMesh&, pointField&, const CombineOp&, const point&)"
|
||||||
|
) << "There are decomposed cyclics in this mesh with"
|
||||||
|
<< " transformations." << endl
|
||||||
|
<< "This is not supported. The result will be incorrect"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Values on shared points.
|
||||||
|
pointField sharedPts(pd.nGlobalPoints(), nullValue);
|
||||||
|
|
||||||
|
forAll(pd.sharedPointLabels(), i)
|
||||||
|
{
|
||||||
|
label meshPointI = pd.sharedPointLabels()[i];
|
||||||
|
// Fill my entries in the shared points
|
||||||
|
sharedPts[pd.sharedPointAddr()[i]] = points[meshPointI];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combine on master.
|
||||||
|
Pstream::listCombineGather(sharedPts, cop);
|
||||||
|
Pstream::listCombineScatter(sharedPts);
|
||||||
|
|
||||||
|
// Now we will all have the same information. Merge it back with
|
||||||
|
// my local information.
|
||||||
|
forAll(pd.sharedPointLabels(), i)
|
||||||
|
{
|
||||||
|
label meshPointI = pd.sharedPointLabels()[i];
|
||||||
|
points[meshPointI] = sharedPts[pd.sharedPointAddr()[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Main program:
|
// Main program:
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@ -393,25 +615,28 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
label destPatchI = patches.findPatchID(patchName);
|
label destPatchI = patches.findPatchID(patchName);
|
||||||
|
|
||||||
word patchType(dict.lookup("type"));
|
|
||||||
|
|
||||||
if (destPatchI == -1)
|
if (destPatchI == -1)
|
||||||
{
|
{
|
||||||
|
dictionary patchDict(dict.subDict("dictionary"));
|
||||||
|
|
||||||
destPatchI = allPatches.size();
|
destPatchI = allPatches.size();
|
||||||
|
|
||||||
Info<< "Adding new patch " << patchName
|
Info<< "Adding new patch " << patchName
|
||||||
<< " of type " << patchType
|
<< " as patch " << destPatchI
|
||||||
<< " as patch " << destPatchI << endl;
|
<< " from " << patchDict << endl;
|
||||||
|
|
||||||
|
patchDict.remove("nFaces");
|
||||||
|
patchDict.add("nFaces", 0);
|
||||||
|
patchDict.remove("startFace");
|
||||||
|
patchDict.add("startFace", startFaceI);
|
||||||
|
|
||||||
// Add an empty patch.
|
// Add an empty patch.
|
||||||
allPatches.append
|
allPatches.append
|
||||||
(
|
(
|
||||||
polyPatch::New
|
polyPatch::New
|
||||||
(
|
(
|
||||||
patchType,
|
|
||||||
patchName,
|
patchName,
|
||||||
0, // size
|
patchDict,
|
||||||
startFaceI, // start
|
|
||||||
destPatchI,
|
destPatchI,
|
||||||
patches
|
patches
|
||||||
).ptr()
|
).ptr()
|
||||||
@ -557,16 +782,100 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Info<< "Synchronising points." << nl << endl;
|
||||||
|
|
||||||
|
// This is a bit tricky. Both normal and position might be out and
|
||||||
|
// current separation also includes the normal
|
||||||
|
// ( separation_ = (nf&(Cr - Cf))*nf ).
|
||||||
|
|
||||||
|
// For processor patches:
|
||||||
|
// - disallow multiple separation/transformation. This basically
|
||||||
|
// excludes decomposed cyclics. Use the (probably 0) separation
|
||||||
|
// to align the points.
|
||||||
|
// For cyclic patches:
|
||||||
|
// - for separated ones use our own recalculated offset vector
|
||||||
|
// - for rotational ones use current one.
|
||||||
|
|
||||||
|
forAll(mesh.boundaryMesh(), patchI)
|
||||||
|
{
|
||||||
|
const polyPatch& pp = mesh.boundaryMesh()[patchI];
|
||||||
|
|
||||||
|
if (pp.size() && isA<coupledPolyPatch>(pp))
|
||||||
|
{
|
||||||
|
const coupledPolyPatch& cpp =
|
||||||
|
refCast<const coupledPolyPatch>(pp);
|
||||||
|
|
||||||
|
if (cpp.separated())
|
||||||
|
{
|
||||||
|
Info<< "On coupled patch " << pp.name()
|
||||||
|
<< " separation[0] was "
|
||||||
|
<< cpp.separation()[0] << endl;
|
||||||
|
|
||||||
|
if (isA<cyclicPolyPatch>(pp))
|
||||||
|
{
|
||||||
|
const cyclicPolyPatch& cycpp =
|
||||||
|
refCast<const cyclicPolyPatch>(pp);
|
||||||
|
|
||||||
|
if (cycpp.transform() == cyclicPolyPatch::TRANSLATIONAL)
|
||||||
|
{
|
||||||
|
Info<< "On cyclic translation patch " << pp.name()
|
||||||
|
<< " forcing uniform separation of "
|
||||||
|
<< cycpp.separationVector() << endl;
|
||||||
|
const_cast<vectorField&>(cpp.separation()) =
|
||||||
|
pointField(1, cycpp.separationVector());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const_cast<vectorField&>(cpp.separation()) =
|
||||||
|
pointField
|
||||||
|
(
|
||||||
|
1,
|
||||||
|
pp[pp.size()/2].centre(mesh.points())
|
||||||
|
- pp[0].centre(mesh.points())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const_cast<vectorField&>(cpp.separation())
|
||||||
|
.setSize(1);
|
||||||
|
}
|
||||||
|
Info<< "On coupled patch " << pp.name()
|
||||||
|
<< " forcing uniform separation of "
|
||||||
|
<< cpp.separation() << endl;
|
||||||
|
}
|
||||||
|
else if (!cpp.parallel())
|
||||||
|
{
|
||||||
|
Info<< "On coupled patch " << pp.name()
|
||||||
|
<< " forcing uniform rotation of "
|
||||||
|
<< cpp.forwardT()[0] << endl;
|
||||||
|
|
||||||
|
const_cast<tensorField&>
|
||||||
|
(
|
||||||
|
cpp.forwardT()
|
||||||
|
).setSize(1);
|
||||||
|
const_cast<tensorField&>
|
||||||
|
(
|
||||||
|
cpp.reverseT()
|
||||||
|
).setSize(1);
|
||||||
|
|
||||||
|
Info<< "On coupled patch " << pp.name()
|
||||||
|
<< " forcing uniform rotation of "
|
||||||
|
<< cpp.forwardT() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Info<< "Synchronising points." << endl;
|
Info<< "Synchronising points." << endl;
|
||||||
|
|
||||||
pointField newPoints(mesh.points());
|
pointField newPoints(mesh.points());
|
||||||
syncTools::syncPointList
|
|
||||||
|
syncPoints
|
||||||
(
|
(
|
||||||
mesh,
|
mesh,
|
||||||
newPoints,
|
newPoints,
|
||||||
nearestEqOp(), // cop
|
nearestEqOp(),
|
||||||
point(GREAT, GREAT, GREAT), // nullValue
|
point(GREAT, GREAT, GREAT)
|
||||||
true // applySeparation
|
|
||||||
);
|
);
|
||||||
|
|
||||||
scalarField diff(mag(newPoints-mesh.points()));
|
scalarField diff(mag(newPoints-mesh.points()));
|
||||||
|
|||||||
@ -1,58 +1,77 @@
|
|||||||
/*--------------------------------*- C++ -*----------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
| ========= | |
|
| ========= | |
|
||||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
| \\ / O peration | Version: 1.5 |
|
| \\ / O peration | Version: 1.0 |
|
||||||
| \\ / A nd | Web: http://www.OpenFOAM.org |
|
| \\ / A nd | Web: http://www.openfoam.org |
|
||||||
| \\/ M anipulation | |
|
| \\/ M anipulation | |
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
FoamFile
|
FoamFile
|
||||||
{
|
{
|
||||||
version 2.0;
|
version 2.0;
|
||||||
format ascii;
|
format ascii;
|
||||||
class dictionary;
|
|
||||||
object createPatchDict;
|
root "";
|
||||||
|
case "";
|
||||||
|
instance "system";
|
||||||
|
local "";
|
||||||
|
|
||||||
|
class dictionary;
|
||||||
|
object createPatcheDict;
|
||||||
}
|
}
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
// Tolerance used in matching faces. Absolute tolerance is span of
|
// Tolerance used in matching faces. Absolute tolerance is span of
|
||||||
// face times this factor.
|
// face times this factor.
|
||||||
matchTolerance 1E-3;
|
matchTolerance 1E-6;
|
||||||
|
|
||||||
// Do a synchronisation of coupled points.
|
// Do a synchronisation of coupled points.
|
||||||
pointSync true;
|
pointSync true;
|
||||||
|
|
||||||
|
|
||||||
// Patches to create.
|
// Patches to create.
|
||||||
// If no patches does a coupled point and face synchronisation anyway.
|
// If no patches does a coupled point and face synchronisation anyway.
|
||||||
patches
|
patches
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
// Name of new patch
|
// Name of new patch
|
||||||
name leftRight0;
|
name sidePatches;
|
||||||
|
|
||||||
// Type of new patch
|
// Dictionary for new patch
|
||||||
type cyclic;
|
dictionary
|
||||||
|
{
|
||||||
|
type cyclic;
|
||||||
|
// Optional: used when matching and synchronising points.
|
||||||
|
//transform translational;
|
||||||
|
//separationVector (-2289 0 0);
|
||||||
|
}
|
||||||
|
|
||||||
// How to construct: either 'patches' or 'set'
|
// How to construct: either 'patches' or 'set'
|
||||||
constructFrom patches;
|
constructFrom patches;
|
||||||
|
|
||||||
// If constructFrom = patches : names of patches
|
// If constructFrom = patches : names of patches
|
||||||
patches (half0 half1);
|
//patches (periodic-1 periodic-2);
|
||||||
|
patches (outlet-side1 outlet-side2);
|
||||||
|
|
||||||
// If constructFrom = set : name of faceSet
|
// If constructFrom = set : name of faceSet
|
||||||
set f0;
|
set f0;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
//{
|
||||||
name bottom;
|
// name bottom;
|
||||||
type patch;
|
// // Dictionary for new patch
|
||||||
|
// dictionary
|
||||||
constructFrom set;
|
// {
|
||||||
|
// type patch;
|
||||||
patches (half0 half1);
|
// }
|
||||||
|
//
|
||||||
set bottomFaces;
|
// constructFrom set;
|
||||||
}
|
//
|
||||||
|
// patches (half0 half1);
|
||||||
|
//
|
||||||
|
// set bottomFaces;
|
||||||
|
//}
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -263,6 +263,7 @@ void Foam::coupledPolyPatch::calcTransformTensors
|
|||||||
Pout<< "coupledPolyPatch::calcTransformTensors : " << name() << endl
|
Pout<< "coupledPolyPatch::calcTransformTensors : " << name() << endl
|
||||||
<< " (half)size:" << Cf.size() << nl
|
<< " (half)size:" << Cf.size() << nl
|
||||||
<< " absTol:" << absTol << nl
|
<< " absTol:" << absTol << nl
|
||||||
|
//<< " smallDist:" << smallDist << nl
|
||||||
<< " sum(mag(nf & nr)):" << sum(mag(nf & nr)) << endl;
|
<< " sum(mag(nf & nr)):" << sum(mag(nf & nr)) << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,6 +317,13 @@ void Foam::coupledPolyPatch::calcTransformTensors
|
|||||||
{
|
{
|
||||||
forwardT_.setSize(1);
|
forwardT_.setSize(1);
|
||||||
reverseT_.setSize(1);
|
reverseT_.setSize(1);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< " rotation " << sum(mag(forwardT_ - forwardT_[0]))
|
||||||
|
<< " more than local tolerance " << error
|
||||||
|
<< ". Assuming uniform rotation." << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -384,7 +392,7 @@ void Foam::coupledPolyPatch::calcTransformTensors
|
|||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< " separation_:" << separation_ << nl
|
Pout<< " separation_:" << separation_.size() << nl
|
||||||
<< " forwardT size:" << forwardT_.size() << endl;
|
<< " forwardT size:" << forwardT_.size() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -127,6 +127,22 @@ void Foam::cyclicPolyPatch::calcTransforms()
|
|||||||
Pout<< "cyclicPolyPatch::calcTransforms : Writing half1"
|
Pout<< "cyclicPolyPatch::calcTransforms : Writing half1"
|
||||||
<< " faces to OBJ file " << nm1 << endl;
|
<< " faces to OBJ file " << nm1 << endl;
|
||||||
writeOBJ(nm1, half1, half1.points());
|
writeOBJ(nm1, half1, half1.points());
|
||||||
|
|
||||||
|
OFstream str(casePath/name()+"_half0_to_half1.obj");
|
||||||
|
label vertI = 0;
|
||||||
|
Pout<< "cyclicPolyPatch::calcTransforms :"
|
||||||
|
<< " Writing coupled face centres as lines to " << str.name()
|
||||||
|
<< endl;
|
||||||
|
forAll(half0Ctrs, i)
|
||||||
|
{
|
||||||
|
const point& p0 = half0Ctrs[i];
|
||||||
|
str << "v " << p0.x() << ' ' << p0.y() << ' ' << p0.z() << nl;
|
||||||
|
vertI++;
|
||||||
|
const point& p1 = half1Ctrs[i];
|
||||||
|
str << "v " << p1.x() << ' ' << p1.y() << ' ' << p1.z() << nl;
|
||||||
|
vertI++;
|
||||||
|
str << "l " << vertI-1 << ' ' << vertI << nl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vectorField half0Normals(half0.size());
|
vectorField half0Normals(half0.size());
|
||||||
@ -397,8 +413,6 @@ void Foam::cyclicPolyPatch::getCentresAndAnchors
|
|||||||
anchors0 = getAnchorPoints(half0Faces, pp.points());
|
anchors0 = getAnchorPoints(half0Faces, pp.points());
|
||||||
half1Ctrs = calcFaceCentres(half1Faces, pp.points());
|
half1Ctrs = calcFaceCentres(half1Faces, pp.points());
|
||||||
|
|
||||||
vector n0 = vector::zero;
|
|
||||||
vector n1 = vector::zero;
|
|
||||||
switch (transform_)
|
switch (transform_)
|
||||||
{
|
{
|
||||||
case ROTATIONAL:
|
case ROTATIONAL:
|
||||||
@ -406,12 +420,46 @@ void Foam::cyclicPolyPatch::getCentresAndAnchors
|
|||||||
label face0 = getConsistentRotationFace(half0Ctrs);
|
label face0 = getConsistentRotationFace(half0Ctrs);
|
||||||
label face1 = getConsistentRotationFace(half1Ctrs);
|
label face1 = getConsistentRotationFace(half1Ctrs);
|
||||||
|
|
||||||
n0 = ((half0Ctrs[face0] - rotationCentre_) ^ rotationAxis_);
|
vector n0 = ((half0Ctrs[face0] - rotationCentre_) ^ rotationAxis_);
|
||||||
n1 = ((half1Ctrs[face1] - rotationCentre_) ^ -rotationAxis_);
|
vector n1 = ((half1Ctrs[face1] - rotationCentre_) ^ -rotationAxis_);
|
||||||
n0 /= mag(n0) + VSMALL;
|
n0 /= mag(n0) + VSMALL;
|
||||||
n1 /= mag(n1) + VSMALL;
|
n1 /= mag(n1) + VSMALL;
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "cyclicPolyPatch::getCentresAndAnchors :"
|
||||||
|
<< " Specified rotation :"
|
||||||
|
<< " n0:" << n0 << " n1:" << n1 << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotation (around origin)
|
||||||
|
const tensor reverseT(rotationTensor(n0, -n1));
|
||||||
|
|
||||||
|
// Rotation
|
||||||
|
forAll(half0Ctrs, faceI)
|
||||||
|
{
|
||||||
|
half0Ctrs[faceI] = Foam::transform(reverseT, half0Ctrs[faceI]);
|
||||||
|
anchors0[faceI] = Foam::transform(reverseT, anchors0[faceI]);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
//- Problem: usually specified translation is not accurate enough
|
||||||
|
//- to get proper match so keep automatic determination over here.
|
||||||
|
//case TRANSLATIONAL:
|
||||||
|
//{
|
||||||
|
// // Transform 0 points.
|
||||||
|
//
|
||||||
|
// if (debug)
|
||||||
|
// {
|
||||||
|
// Pout<< "cyclicPolyPatch::getCentresAndAnchors :"
|
||||||
|
// << "Specified translation : " << separationVector_ << endl;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// half0Ctrs += separationVector_;
|
||||||
|
// anchors0 += separationVector_;
|
||||||
|
// break;
|
||||||
|
//}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
// Assumes that cyclic is planar. This is also the initial
|
// Assumes that cyclic is planar. This is also the initial
|
||||||
@ -420,55 +468,67 @@ void Foam::cyclicPolyPatch::getCentresAndAnchors
|
|||||||
// Determine the face with max area on both halves. These
|
// Determine the face with max area on both halves. These
|
||||||
// two faces are used to determine the transformation tensors
|
// two faces are used to determine the transformation tensors
|
||||||
label max0I = findMaxArea(pp.points(), half0Faces);
|
label max0I = findMaxArea(pp.points(), half0Faces);
|
||||||
n0 = half0Faces[max0I].normal(pp.points());
|
vector n0 = half0Faces[max0I].normal(pp.points());
|
||||||
n0 /= mag(n0) + VSMALL;
|
n0 /= mag(n0) + VSMALL;
|
||||||
|
|
||||||
label max1I = findMaxArea(pp.points(), half1Faces);
|
label max1I = findMaxArea(pp.points(), half1Faces);
|
||||||
n1 = half1Faces[max1I].normal(pp.points());
|
vector n1 = half1Faces[max1I].normal(pp.points());
|
||||||
n1 /= mag(n1) + VSMALL;
|
n1 /= mag(n1) + VSMALL;
|
||||||
|
|
||||||
|
if (mag(n0 & n1) < 1-coupledPolyPatch::matchTol)
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "cyclicPolyPatch::getCentresAndAnchors :"
|
||||||
|
<< " Detected rotation :"
|
||||||
|
<< " n0:" << n0 << " n1:" << n1 << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotation (around origin)
|
||||||
|
const tensor reverseT(rotationTensor(n0, -n1));
|
||||||
|
|
||||||
|
// Rotation
|
||||||
|
forAll(half0Ctrs, faceI)
|
||||||
|
{
|
||||||
|
half0Ctrs[faceI] = Foam::transform
|
||||||
|
(
|
||||||
|
reverseT,
|
||||||
|
half0Ctrs[faceI]
|
||||||
|
);
|
||||||
|
anchors0[faceI] = Foam::transform
|
||||||
|
(
|
||||||
|
reverseT,
|
||||||
|
anchors0[faceI]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Parallel translation. Get average of all used points.
|
||||||
|
|
||||||
|
primitiveFacePatch half0(half0Faces, pp.points());
|
||||||
|
const pointField& half0Pts = half0.localPoints();
|
||||||
|
const point ctr0(sum(half0Pts)/half0Pts.size());
|
||||||
|
|
||||||
|
primitiveFacePatch half1(half1Faces, pp.points());
|
||||||
|
const pointField& half1Pts = half1.localPoints();
|
||||||
|
const point ctr1(sum(half1Pts)/half1Pts.size());
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "cyclicPolyPatch::getCentresAndAnchors :"
|
||||||
|
<< " Detected translation :"
|
||||||
|
<< " n0:" << n0 << " n1:" << n1
|
||||||
|
<< " ctr0:" << ctr0 << " ctr1:" << ctr1 << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
half0Ctrs += ctr1 - ctr0;
|
||||||
|
anchors0 += ctr1 - ctr0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mag(n0 & n1) < 1-coupledPolyPatch::matchTol)
|
|
||||||
{
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "cyclicPolyPatch::getCentresAndAnchors : Rotation :"
|
|
||||||
<< " n0:" << n0 << " n1:" << n1 << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rotation (around origin)
|
|
||||||
const tensor reverseT(rotationTensor(n0, -n1));
|
|
||||||
|
|
||||||
// Rotation
|
|
||||||
forAll(half0Ctrs, faceI)
|
|
||||||
{
|
|
||||||
half0Ctrs[faceI] = Foam::transform(reverseT, half0Ctrs[faceI]);
|
|
||||||
anchors0[faceI] = Foam::transform(reverseT, anchors0[faceI]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Parallel translation. Get average of all used points.
|
|
||||||
|
|
||||||
primitiveFacePatch half0(half0Faces, pp.points());
|
|
||||||
const pointField& half0Pts = half0.localPoints();
|
|
||||||
const point ctr0(sum(half0Pts)/half0Pts.size());
|
|
||||||
|
|
||||||
primitiveFacePatch half1(half1Faces, pp.points());
|
|
||||||
const pointField& half1Pts = half1.localPoints();
|
|
||||||
const point ctr1(sum(half1Pts)/half1Pts.size());
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "cyclicPolyPatch::getCentresAndAnchors : Translation :"
|
|
||||||
<< " n0:" << n0 << " n1:" << n1
|
|
||||||
<< " ctr0:" << ctr0 << " ctr1:" << ctr1 << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
half0Ctrs += ctr1 - ctr0;
|
|
||||||
anchors0 += ctr1 - ctr0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate typical distance per face
|
// Calculate typical distance per face
|
||||||
tols = calcFaceTol(half1Faces, pp.points(), half1Ctrs);
|
tols = calcFaceTol(half1Faces, pp.points(), half1Ctrs);
|
||||||
@ -615,7 +675,8 @@ Foam::cyclicPolyPatch::cyclicPolyPatch
|
|||||||
featureCos_(0.9),
|
featureCos_(0.9),
|
||||||
transform_(UNKNOWN),
|
transform_(UNKNOWN),
|
||||||
rotationAxis_(vector::zero),
|
rotationAxis_(vector::zero),
|
||||||
rotationCentre_(point::zero)
|
rotationCentre_(point::zero),
|
||||||
|
separationVector_(vector::zero)
|
||||||
{
|
{
|
||||||
calcTransforms();
|
calcTransforms();
|
||||||
}
|
}
|
||||||
@ -635,7 +696,8 @@ Foam::cyclicPolyPatch::cyclicPolyPatch
|
|||||||
featureCos_(0.9),
|
featureCos_(0.9),
|
||||||
transform_(UNKNOWN),
|
transform_(UNKNOWN),
|
||||||
rotationAxis_(vector::zero),
|
rotationAxis_(vector::zero),
|
||||||
rotationCentre_(point::zero)
|
rotationCentre_(point::zero),
|
||||||
|
separationVector_(vector::zero)
|
||||||
{
|
{
|
||||||
dict.readIfPresent("featureCos", featureCos_);
|
dict.readIfPresent("featureCos", featureCos_);
|
||||||
|
|
||||||
@ -650,9 +712,14 @@ Foam::cyclicPolyPatch::cyclicPolyPatch
|
|||||||
dict.lookup("rotationCentre") >> rotationCentre_;
|
dict.lookup("rotationCentre") >> rotationCentre_;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case TRANSLATIONAL:
|
||||||
|
{
|
||||||
|
dict.lookup("separationVector") >> separationVector_;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
// no additioanl info required
|
// no additional info required
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -673,7 +740,8 @@ Foam::cyclicPolyPatch::cyclicPolyPatch
|
|||||||
featureCos_(pp.featureCos_),
|
featureCos_(pp.featureCos_),
|
||||||
transform_(pp.transform_),
|
transform_(pp.transform_),
|
||||||
rotationAxis_(pp.rotationAxis_),
|
rotationAxis_(pp.rotationAxis_),
|
||||||
rotationCentre_(pp.rotationCentre_)
|
rotationCentre_(pp.rotationCentre_),
|
||||||
|
separationVector_(pp.separationVector_)
|
||||||
{
|
{
|
||||||
calcTransforms();
|
calcTransforms();
|
||||||
}
|
}
|
||||||
@ -694,7 +762,8 @@ Foam::cyclicPolyPatch::cyclicPolyPatch
|
|||||||
featureCos_(pp.featureCos_),
|
featureCos_(pp.featureCos_),
|
||||||
transform_(pp.transform_),
|
transform_(pp.transform_),
|
||||||
rotationAxis_(pp.rotationAxis_),
|
rotationAxis_(pp.rotationAxis_),
|
||||||
rotationCentre_(pp.rotationCentre_)
|
rotationCentre_(pp.rotationCentre_),
|
||||||
|
separationVector_(pp.separationVector_)
|
||||||
{
|
{
|
||||||
calcTransforms();
|
calcTransforms();
|
||||||
}
|
}
|
||||||
@ -1322,6 +1391,8 @@ void Foam::cyclicPolyPatch::write(Ostream& os) const
|
|||||||
{
|
{
|
||||||
os.writeKeyword("transform") << transformTypeNames[TRANSLATIONAL]
|
os.writeKeyword("transform") << transformTypeNames[TRANSLATIONAL]
|
||||||
<< token::END_STATEMENT << nl;
|
<< token::END_STATEMENT << nl;
|
||||||
|
os.writeKeyword("separationVector") << separationVector_
|
||||||
|
<< token::END_STATEMENT << nl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
@ -101,11 +101,18 @@ private:
|
|||||||
//- Type of transformation - rotational or translational
|
//- Type of transformation - rotational or translational
|
||||||
transformType transform_;
|
transformType transform_;
|
||||||
|
|
||||||
//- Axis of rotation for rotational cyclics
|
// For rotation
|
||||||
vector rotationAxis_;
|
|
||||||
|
|
||||||
//- point on axis of rotation for rotational cyclics
|
//- Axis of rotation for rotational cyclics
|
||||||
point rotationCentre_;
|
vector rotationAxis_;
|
||||||
|
|
||||||
|
//- point on axis of rotation for rotational cyclics
|
||||||
|
point rotationCentre_;
|
||||||
|
|
||||||
|
// For translation
|
||||||
|
|
||||||
|
//- Translation vector
|
||||||
|
vector separationVector_;
|
||||||
|
|
||||||
|
|
||||||
// Private member functions
|
// Private member functions
|
||||||
@ -267,66 +274,94 @@ public:
|
|||||||
const edgeList& coupledEdges() const;
|
const edgeList& coupledEdges() const;
|
||||||
|
|
||||||
|
|
||||||
vector separation(const label facei) const
|
|
||||||
{
|
|
||||||
if (facei < size()/2)
|
|
||||||
{
|
|
||||||
return coupledPolyPatch::separation()[0];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return -coupledPolyPatch::separation()[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const tensor& transformT(const label facei) const
|
// Transformation
|
||||||
{
|
|
||||||
if (facei < size()/2)
|
|
||||||
{
|
|
||||||
return reverseT()[0];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return forwardT()[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
vector separation(const label facei) const
|
||||||
T transform(const T& t, const label facei) const
|
|
||||||
{
|
|
||||||
if (parallel())
|
|
||||||
{
|
{
|
||||||
return t;
|
if (facei < size()/2)
|
||||||
|
{
|
||||||
|
return coupledPolyPatch::separation()[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -coupledPolyPatch::separation()[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return Foam::transform(transformT(facei), t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
label transformLocalFace(const label facei) const
|
const tensor& transformT(const label facei) const
|
||||||
{
|
|
||||||
if (facei < size()/2)
|
|
||||||
{
|
{
|
||||||
return facei + size()/2;
|
if (facei < size()/2)
|
||||||
|
{
|
||||||
|
return reverseT()[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return forwardT()[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return facei - size()/2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
label transformGlobalFace(const label facei) const
|
template<class T>
|
||||||
{
|
T transform(const T& t, const label facei) const
|
||||||
if (facei - start() < size()/2)
|
|
||||||
{
|
{
|
||||||
return facei + size()/2;
|
if (parallel())
|
||||||
|
{
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Foam::transform(transformT(facei), t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
label transformLocalFace(const label facei) const
|
||||||
{
|
{
|
||||||
return facei - size()/2;
|
if (facei < size()/2)
|
||||||
|
{
|
||||||
|
return facei + size()/2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return facei - size()/2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
label transformGlobalFace(const label facei) const
|
||||||
|
{
|
||||||
|
if (facei - start() < size()/2)
|
||||||
|
{
|
||||||
|
return facei + size()/2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return facei - size()/2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Type of transform
|
||||||
|
transformType transform() const
|
||||||
|
{
|
||||||
|
return transform_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Axis of rotation for rotational cyclics
|
||||||
|
const vector& rotationAxis() const
|
||||||
|
{
|
||||||
|
return rotationAxis_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- point on axis of rotation for rotational cyclics
|
||||||
|
const point& rotationCentre() const
|
||||||
|
{
|
||||||
|
return rotationCentre_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Translation vector for translational cyclics
|
||||||
|
const vector& separationVector() const
|
||||||
|
{
|
||||||
|
return separationVector_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//- Initialize ordering for primitivePatch. Does not
|
//- Initialize ordering for primitivePatch. Does not
|
||||||
|
|||||||
Reference in New Issue
Block a user