Merge commit 'origin/splitCyclic'

This commit is contained in:
mattijs
2010-05-18 13:35:56 +01:00
270 changed files with 11598 additions and 6350 deletions

113
CHANGES-splitCyclic Normal file
View File

@ -0,0 +1,113 @@
Short overview of the changes to have cyclics split into two halves.
Cyclics
-------
The two cyclic halves are now split like processor patches. There should be no
difference in running.
Advantages:
- decomposed cyclics can now be handled properly. It just needs to preserve
the cyclic patch it originates from.
- We can now construct a table of global transformations and handle
points/edges/cells with transformations.
- face ordering after topological changes becomes much easier since we
now preserve what half the face comes from.
- cyclic handling becomes more consistent with processor handling and can
quite often be handled in the same condition.
- transformation tensors now become single entry.
The disadvantages:
- a patch-wise loop now might need to store data to go to the neighbour half
since it is no longer handled in a single patch.
- decomposed cyclics now require overlapping communications so will
only work in non-blocking mode. Hence the underlying message passing library
will require overlapping communications with message tags.
- it is quite a code-change and there might be some oversights.
- once converted (see foamUpgradeCyclics below) cases are not backwards
compatible with previous versions.
blockMesh
---------
blockMeshDict now allows patch definition using the construct-from-dictionary
constructor. This helps defining patches that require additional input e.g.
directMapped and now cyclic:
boundary
(
sides2_half0
{
type cyclic;
neighbourPatch sides2_half1;
faces ((2 4 5 3));
}
The syntax is - like the polyMesh/boundary file - a list of dictionaries with
one additional entry 'faces' for the block faces. Above shows the new
required entry 'neighbourPatch' for cyclic.
blockMesh still reads the old format. For a cyclic it will automatically
introduce two patches for the halves, with names xxx_half0 and xxx_half1.
foamUpgradeCyclics
------------------
This is a tool which reads the polyMesh/boundary file and any vol/surface/point
fields and converts them.
It will check if anything needs to be converted, backup the current file to .old
and split any cyclic patchFields into two entries.
decomposePar
------------
Decomposes cyclics into processorCyclic:
procBoundary0to1throughsides1_half0
{
type processorCyclic;
nFaces 1000;
startFace 91350;
myProcNo 0;
neighbProcNo 1;
referPatch sides1_half0;
}
They have an additional 'referPatch' entry which gives the (cyclic) patch
to use for any transformation.
Details
-------
- the cyclic patch dictionary has an entry neighbourPatch. The
patch has new member functions:
//- Get neighbouring patchID
label neighbPatchID() const
//- Get neighbouring patch
const cyclicPolyPatch& neighbPatch()
//- Am I the owner half
bool owner()
The cyclic still has forward() and reverse() transformations (with
the reverse() equal to the neighbPatch().forward()).
There is no transformLocalFace anymore - the ordering is the same for
both halves.
- 'pure' processor patches now are always coincident - they (should) have no
transformation. As said above cyclics are decomposed into a derived
type 'processorCyclic'.
- processor patches use overlapping communication using a different message
tag. This maps straight through into the MPI message tag.
- when constructing a GeometricField from a dictionary it will explicitly
check for non-existing entries for cyclic patches and exit with an error message
warning to run foamUpgradeCyclics.

100
TODO Normal file
View File

@ -0,0 +1,100 @@
- allocate/free tags.
Not tested.
OK - test blockMesh with cyclics
unitTestCases/singleCyclic/
OK - test cyclics sequential running.
unitTestCases/singleCyclic/
OK - test decomposePar
tested channel395
OK - FaceCellWave
unitTestCases/twoCavityCyclicForWallDistance/
OK - non-parallel finite volume : channelFoam
unitTestCases/channel395-splitCyclic vs. channel395-dev
OK - parallel finite volume with processorCyclic: channelFoam
unitTestCases/channel395-splitCyclic vs. channel395-dev
OK - preProcessing/foamUpgradeCyclics
OK - gamg - sequential.
Tested on channel395-splitCyclic with GAMG.
OK - gamg parallel.
Tested on channel395-splitCyclic with GAMG.
- initTransfer in GAMGprocessorInterfaces using nonblocking+tags
untested.
OK - cyclic baffles.
Tested on t-junction-with-fan
OK. - jumpCyclics/fanFvPatchField. All usages of jump() now need to account
for being owner() or not.
Tested on t-junction-with-fan.
OK - regionSplit
tested on singleCyclic
OK - pointFields on cyclics. volPointInterpolation.
tested on channel395-splitCyclic
OK - fvMeshSubset
tested on singleCyclic
OK - pointEdgeWave (maybe test through inversePointDistanceDiffusivity?)
tested on twoCavityCyclicForWallDistance
OK - scotchDecomp
tested with testCalcCSR on twoCavityCyclicForWallDistance
NOT WORKING - fvMeshDistribute to split cyclic patches into ones
with different separation.
tested on singleCyclic
OK - test createPatch pointSync
note: only works if face-centre position of 0th faces is ok since uses
this for separation. Should in fact make cyclic planar using patch centre and
normal?
test on twoCavityCyclicForWallDistance with point (0 1 0) set to (0 1.001 0)
NO PROBLEM - renumberMesh
It doesn't do renumbering through cyclics.
OK - rotational cyclics.
Tested on movingCone-with-cyclics
OK - LUscalarMatrix::convert still expects interfaces to be cyclic
tested on channel395 with 'directSolveCoarsest true;'
OK - grep for size()/2
- all tutorials with cyclics:
OK - incompressible/DNS/dnsFoam/boxTurb16
OK - incompressible/channelFoam/channel395
slight differences due to divergence. combustion/XiFoam/les/pitzDaily3D
OK - no cyclics. combustion/fireFoam/les/smallPoolFire2D
discreteMethods/dsmcFoam/freeSpacePeriodic
discreteMethods/dsmcFoam/wedge15Ma5
discreteMethods/molecularDynamics/mdEquilibrationFoam/periodicCubeArgon
OK - incompressible/boundaryFoam/boundaryLaunderSharma
OK - incompressible/boundaryFoam/boundaryWallFunctions
OK - incompressible/boundaryFoam/boundaryWallFunctionsProfile
OK - needs createBaffles. incompressible/pimpleFoam/t-junction-with-fan
OK - incompressible/simpleSRFFoam/mixer
OK - needs createBaffles. lagrangian/porousExplicitSourceReactingParcelFoam/filter
needs special coupledbcs. lagrangian/reactingParcelFilmFoam/multipleBoxes
OK - createBaffles
- have foamUpgradeCyclics split 'value' field
- activeBaffleVelocity
- kivaToFoam/readKivaGrid.H sorts cyclics (but in incorrect order?)
- isoSurface.C
- referredCellList.C
- work out scheduled communication?
OK - add neighbourPatch checking to 16x.

View File

@ -295,8 +295,7 @@ label mergePatchFaces
const faceZone& fZone = mesh.faceZones()[zoneID]; const faceZone& fZone = mesh.faceZones()[zoneID];
zoneFlip = fZone.flipMap()[fZone.whichFace(newMasterI)]; zoneFlip = fZone.flipMap()[fZone.whichFace(newMasterI)];
} }
label patchI = mesh.boundaryMesh().whichPatch(newMasterI); label patchID = mesh.boundaryMesh().whichPatch(newMasterI);
Pout<< "Restoring new master face " << newMasterI Pout<< "Restoring new master face " << newMasterI
<< " to vertices " << setFaceVerts[0] << endl; << " to vertices " << setFaceVerts[0] << endl;
@ -311,7 +310,7 @@ label mergePatchFaces
own, // owner own, // owner
-1, // neighbour -1, // neighbour
false, // face flip false, // face flip
patchI, // patch for face patchID, // patch for face
false, // remove from zone false, // remove from zone
zoneID, // zone for face zoneID, // zone for face
zoneFlip // face flip in zone zoneFlip // face flip in zone
@ -336,7 +335,7 @@ label mergePatchFaces
-1, // masterEdgeID, -1, // masterEdgeID,
newMasterI, // masterFaceID, newMasterI, // masterFaceID,
false, // flipFaceFlux, false, // flipFaceFlux,
patchI, // patchID, patchID, // patchID,
zoneID, // zoneID, zoneID, // zoneID,
zoneFlip // zoneFlip zoneFlip // zoneFlip
) )

View File

@ -206,25 +206,8 @@ int main(int argc, char *argv[])
Info<< nl << "Creating polyMesh from blockMesh" << endl; Info<< nl << "Creating polyMesh from blockMesh" << endl;
wordList patchNames = blocks.patchNames();
wordList patchTypes = blocks.patchTypes();
word defaultFacesName = "defaultFaces"; word defaultFacesName = "defaultFaces";
word defaultFacesType = emptyPolyPatch::typeName; word defaultFacesType = emptyPolyPatch::typeName;
wordList patchPhysicalTypes = blocks.patchPhysicalTypes();
preservePatchTypes
(
runTime,
runTime.constant(),
polyMeshDir,
patchNames,
patchTypes,
defaultFacesName,
defaultFacesType,
patchPhysicalTypes
);
polyMesh mesh polyMesh mesh
( (
IOobject IOobject
@ -236,11 +219,9 @@ int main(int argc, char *argv[])
xferCopy(blocks.points()), // could we re-use space? xferCopy(blocks.points()), // could we re-use space?
blocks.cells(), blocks.cells(),
blocks.patches(), blocks.patches(),
patchNames, blocks.patchDicts(),
patchTypes,
defaultFacesName, defaultFacesName,
defaultFacesType, defaultFacesType
patchPhysicalTypes
); );

View File

@ -134,7 +134,13 @@ int main(int argc, char *argv[])
#include "addRegionOption.H" #include "addRegionOption.H"
argList::validArgs.append("faceZone"); argList::validArgs.append("faceZone");
argList::validArgs.append("patch"); argList::validArgs.append("(masterPatch slavePatch)");
argList::addOption
(
"additionalPatches",
"((master2 slave2) .. (masterN slaveN))"
);
argList::addBoolOption("internalFacesOnly");
argList::addOption argList::addOption
( (
@ -159,7 +165,7 @@ int main(int argc, char *argv[])
const faceZoneMesh& faceZones = mesh.faceZones(); const faceZoneMesh& faceZones = mesh.faceZones();
// Faces to baffle // Faces to baffle
faceZoneID zoneID(args[1], faceZones); faceZoneID zoneID(args.additionalArgs()[0], faceZones);
Info<< "Converting faces on zone " << zoneID.name() Info<< "Converting faces on zone " << zoneID.name()
<< " into baffles." << nl << endl; << " into baffles." << nl << endl;
@ -182,28 +188,36 @@ int main(int argc, char *argv[])
fZone.checkParallelSync(true); fZone.checkParallelSync(true);
// Patches to put baffles into // Patches to put baffles into
DynamicList<label> newPatches(1); DynamicList<label> newMasterPatches(1);
DynamicList<label> newSlavePatches(1);
const word patchName = args[2]; const Pair<word> patchNames(IStringStream(args.additionalArgs()[1])());
newPatches.append(findPatchID(mesh, patchName)); newMasterPatches.append(findPatchID(mesh, patchNames[0]));
Info<< "Using patch " << patchName newSlavePatches.append(findPatchID(mesh, patchNames[1]));
<< " at index " << newPatches[0] << endl; Info<< "Using master patch " << patchNames[0]
<< " at index " << newMasterPatches[0] << endl;
Info<< "Using slave patch " << patchNames[1]
<< " at index " << newSlavePatches[0] << endl;
// Additional patches // Additional patches
if (args.optionFound("additionalPatches")) if (args.optionFound("additionalPatches"))
{ {
const wordList patchNames const List<Pair<word> > patchNames
( (
args.optionLookup("additionalPatches")() args.optionLookup("additionalPatches")()
); );
newPatches.reserve(patchNames.size() + 1); newMasterPatches.reserve(patchNames.size() + 1);
newSlavePatches.reserve(patchNames.size() + 1);
forAll(patchNames, i) forAll(patchNames, i)
{ {
newPatches.append(findPatchID(mesh, patchNames[i])); newMasterPatches.append(findPatchID(mesh, patchNames[i][0]));
Info<< "Using additional patch " << patchNames[i] newSlavePatches.append(findPatchID(mesh, patchNames[i][1]));
<< " at index " << newPatches.last() << endl; Info<< "Using additional patches " << patchNames[i]
<< " at indices " << newMasterPatches.last()
<< " and " << newSlavePatches.last()
<< endl;
} }
} }
@ -282,10 +296,8 @@ int main(int argc, char *argv[])
} }
label nModified = 0; label nModified = 0;
forAll(newPatches, i) forAll(newMasterPatches, i)
{ {
label newPatchI = newPatches[i];
// Pass 1. Do selected side of zone // Pass 1. Do selected side of zone
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -305,7 +317,7 @@ int main(int argc, char *argv[])
faceI, // label of face faceI, // label of face
mesh.faceOwner()[faceI],// owner mesh.faceOwner()[faceI],// owner
false, // face flip false, // face flip
newPatchI, // patch for face newMasterPatches[i], // patch for face
zoneID.index(), // zone for face zoneID.index(), // zone for face
false, // face flip in zone false, // face flip in zone
modifiedFace // modify or add status modifiedFace // modify or add status
@ -321,7 +333,7 @@ int main(int argc, char *argv[])
faceI, // label of face faceI, // label of face
mesh.faceNeighbour()[faceI],// owner mesh.faceNeighbour()[faceI],// owner
true, // face flip true, // face flip
newPatchI, // patch for face newMasterPatches[i], // patch for face
zoneID.index(), // zone for face zoneID.index(), // zone for face
true, // face flip in zone true, // face flip in zone
modifiedFace // modify or add status modifiedFace // modify or add status
@ -352,7 +364,7 @@ int main(int argc, char *argv[])
faceI, // label of face faceI, // label of face
mesh.faceNeighbour()[faceI], // owner mesh.faceNeighbour()[faceI], // owner
true, // face flip true, // face flip
newPatchI, // patch for face newSlavePatches[i], // patch for face
zoneID.index(), // zone for face zoneID.index(), // zone for face
true, // face flip in zone true, // face flip in zone
modifiedFace // modify or add modifiedFace // modify or add
@ -368,7 +380,7 @@ int main(int argc, char *argv[])
faceI, // label of face faceI, // label of face
mesh.faceOwner()[faceI],// owner mesh.faceOwner()[faceI],// owner
false, // face flip false, // face flip
newPatchI, // patch for face newSlavePatches[i], // patch for face
zoneID.index(), // zone for face zoneID.index(), // zone for face
false, // face flip in zone false, // face flip in zone
modifiedFace // modify or add status modifiedFace // modify or add status
@ -396,6 +408,8 @@ int main(int argc, char *argv[])
{ {
const polyPatch& pp = patches[patchI]; const polyPatch& pp = patches[patchI];
label newPatchI = newMasterPatches[i];
if (pp.coupled() && patches[newPatchI].coupled()) if (pp.coupled() && patches[newPatchI].coupled())
{ {
// Do not allow coupled faces to be moved to different coupled // Do not allow coupled faces to be moved to different coupled
@ -445,7 +459,7 @@ int main(int argc, char *argv[])
Info<< "Converted " << returnReduce(nModified, sumOp<label>()) Info<< "Converted " << returnReduce(nModified, sumOp<label>())
<< " faces into boundary faces on patch " << patchName << nl << endl; << " faces into boundary faces on patches " << patchNames << nl << endl;
if (!overwrite) if (!overwrite)
{ {

View File

@ -197,69 +197,55 @@ void dumpCyclicMatch(const fileName& prefix, const polyMesh& mesh)
forAll(patches, patchI) forAll(patches, patchI)
{ {
if (isA<cyclicPolyPatch>(patches[patchI])) if
(
isA<cyclicPolyPatch>(patches[patchI])
&& refCast<const cyclicPolyPatch>(patches[patchI]).owner()
)
{ {
const cyclicPolyPatch& cycPatch = const cyclicPolyPatch& cycPatch =
refCast<const cyclicPolyPatch>(patches[patchI]); refCast<const cyclicPolyPatch>(patches[patchI]);
label halfSize = cycPatch.size()/2; // Dump patches
// Dump halves
{ {
OFstream str(prefix+cycPatch.name()+"_half0.obj"); OFstream str(prefix+cycPatch.name()+".obj");
Pout<< "Dumping " << cycPatch.name() Pout<< "Dumping " << cycPatch.name()
<< " half0 faces to " << str.name() << endl; << " faces to " << str.name() << endl;
meshTools::writeOBJ meshTools::writeOBJ
( (
str, str,
static_cast<faceList> cycPatch,
(
SubList<face>
(
cycPatch,
halfSize
)
),
cycPatch.points() cycPatch.points()
); );
} }
const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
{ {
OFstream str(prefix+cycPatch.name()+"_half1.obj"); OFstream str(prefix+nbrPatch.name()+".obj");
Pout<< "Dumping " << cycPatch.name() Pout<< "Dumping " << nbrPatch.name()
<< " half1 faces to " << str.name() << endl; << " faces to " << str.name() << endl;
meshTools::writeOBJ meshTools::writeOBJ
( (
str, str,
static_cast<faceList> nbrPatch,
( nbrPatch.points()
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()+nbrPatch.name()+"_match.obj");
label vertI = 0; label vertI = 0;
Pout<< "Dumping cyclic match as lines between face centres to " Pout<< "Dumping cyclic match as lines between face centres to "
<< str.name() << endl; << str.name() << endl;
for (label faceI = 0; faceI < halfSize; faceI++) forAll(cycPatch, faceI)
{ {
const point& fc0 = mesh.faceCentres()[cycPatch.start()+faceI]; const point& fc0 = mesh.faceCentres()[cycPatch.start()+faceI];
meshTools::writeOBJ(str, fc0); meshTools::writeOBJ(str, fc0);
vertI++; vertI++;
const point& fc1 = mesh.faceCentres()[nbrPatch.start()+faceI];
label nbrFaceI = halfSize + faceI;
const point& fc1 =
mesh.faceCentres()[cycPatch.start()+nbrFaceI];
meshTools::writeOBJ(str, fc1); meshTools::writeOBJ(str, fc1);
vertI++; vertI++;
@ -426,13 +412,19 @@ void syncPoints
{ {
const polyPatch& pp = patches[patchI]; const polyPatch& pp = patches[patchI];
if (isA<cyclicPolyPatch>(pp)) if
(
isA<cyclicPolyPatch>(pp)
&& refCast<const cyclicPolyPatch>(pp).owner()
)
{ {
const cyclicPolyPatch& cycPatch = const cyclicPolyPatch& cycPatch =
refCast<const cyclicPolyPatch>(pp); refCast<const cyclicPolyPatch>(pp);
const edgeList& coupledPoints = cycPatch.coupledPoints(); const edgeList& coupledPoints = cycPatch.coupledPoints();
const labelList& meshPts = cycPatch.meshPoints(); const labelList& meshPts = cycPatch.meshPoints();
const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
const labelList& nbrMeshPts = nbrPatch.meshPoints();
pointField half0Values(coupledPoints.size()); pointField half0Values(coupledPoints.size());
@ -451,14 +443,13 @@ void syncPoints
else if (cycPatch.separated()) else if (cycPatch.separated())
{ {
hasTransformation = true; hasTransformation = true;
const vectorField& v = cycPatch.coupledPolyPatch::separation(); separateList(cycPatch.separation(), half0Values);
separateList(v, half0Values);
} }
forAll(coupledPoints, i) forAll(coupledPoints, i)
{ {
const edge& e = coupledPoints[i]; const edge& e = coupledPoints[i];
label point1 = meshPts[e[1]]; label point1 = nbrMeshPts[e[1]];
points[point1] = half0Values[i]; points[point1] = half0Values[i];
} }
} }
@ -785,13 +776,8 @@ int main(int argc, char *argv[])
// current separation also includes the normal // current separation also includes the normal
// ( separation_ = (nf&(Cr - Cf))*nf ). // ( 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 cyclic patches:
// - for separated ones use our own recalculated offset vector // - for separated ones use user specified offset vector
// - for rotational ones use current one.
forAll(mesh.boundaryMesh(), patchI) forAll(mesh.boundaryMesh(), patchI)
{ {
@ -808,13 +794,14 @@ int main(int argc, char *argv[])
<< " separation[0] was " << " separation[0] was "
<< cpp.separation()[0] << endl; << cpp.separation()[0] << endl;
if (isA<cyclicPolyPatch>(pp)) if (isA<cyclicPolyPatch>(pp) && pp.size())
{ {
const cyclicPolyPatch& cycpp = const cyclicPolyPatch& cycpp =
refCast<const cyclicPolyPatch>(pp); refCast<const cyclicPolyPatch>(pp);
if (cycpp.transform() == cyclicPolyPatch::TRANSLATIONAL) if (cycpp.transform() == cyclicPolyPatch::TRANSLATIONAL)
{ {
// Force to wanted separation
Info<< "On cyclic translation patch " << pp.name() Info<< "On cyclic translation patch " << pp.name()
<< " forcing uniform separation of " << " forcing uniform separation of "
<< cycpp.separationVector() << endl; << cycpp.separationVector() << endl;
@ -823,20 +810,16 @@ int main(int argc, char *argv[])
} }
else else
{ {
const cyclicPolyPatch& nbr = cycpp.neighbPatch();
const_cast<vectorField&>(cpp.separation()) = const_cast<vectorField&>(cpp.separation()) =
pointField pointField
( (
1, 1,
pp[pp.size()/2].centre(mesh.points()) nbr[0].centre(mesh.points())
- pp[0].centre(mesh.points()) - cycpp[0].centre(mesh.points())
); );
} }
} }
else
{
const_cast<vectorField&>(cpp.separation())
.setSize(1);
}
Info<< "On coupled patch " << pp.name() Info<< "On coupled patch " << pp.name()
<< " forcing uniform separation of " << " forcing uniform separation of "
<< cpp.separation() << endl; << cpp.separation() << endl;

View File

@ -305,6 +305,7 @@ autoPtr<mapPolyMesh> reorderMesh
labelList patchStarts(patches.size()); labelList patchStarts(patches.size());
labelList oldPatchNMeshPoints(patches.size()); labelList oldPatchNMeshPoints(patches.size());
labelListList patchPointMap(patches.size()); labelListList patchPointMap(patches.size());
forAll(patches, patchI) forAll(patches, patchI)
{ {
patchSizes[patchI] = patches[patchI].size(); patchSizes[patchI] = patches[patchI].size();
@ -320,7 +321,8 @@ autoPtr<mapPolyMesh> reorderMesh
xferMove(newOwner), xferMove(newOwner),
xferMove(newNeighbour), xferMove(newNeighbour),
patchSizes, patchSizes,
patchStarts patchStarts,
true
); );
return autoPtr<mapPolyMesh> return autoPtr<mapPolyMesh>

View File

@ -560,7 +560,7 @@ void getInterfaceSizes
label cellI = mesh.faceOwner()[i+mesh.nInternalFaces()]; label cellI = mesh.faceOwner()[i+mesh.nInternalFaces()];
coupledRegion[i] = cellRegion[cellI]; coupledRegion[i] = cellRegion[cellI];
} }
syncTools::swapBoundaryFaceList(mesh, coupledRegion, false); syncTools::swapBoundaryFaceList(mesh, coupledRegion);
forAll(coupledRegion, i) forAll(coupledRegion, i)
{ {
@ -730,7 +730,7 @@ autoPtr<mapPolyMesh> createRegionMesh
label cellI = mesh.faceOwner()[i+mesh.nInternalFaces()]; label cellI = mesh.faceOwner()[i+mesh.nInternalFaces()];
coupledRegion[i] = cellRegion[cellI]; coupledRegion[i] = cellRegion[cellI];
} }
syncTools::swapBoundaryFaceList(mesh, coupledRegion, false); syncTools::swapBoundaryFaceList(mesh, coupledRegion);
// Topology change container. Start off from existing mesh. // Topology change container. Start off from existing mesh.
@ -1300,7 +1300,7 @@ void getZoneID
{ {
neiZoneID[i] = zoneID[mesh.faceOwner()[i+mesh.nInternalFaces()]]; neiZoneID[i] = zoneID[mesh.faceOwner()[i+mesh.nInternalFaces()]];
} }
syncTools::swapBoundaryFaceList(mesh, neiZoneID, false); syncTools::swapBoundaryFaceList(mesh, neiZoneID);
} }

View File

@ -62,7 +62,6 @@ Usage
#include "OSspecific.H" #include "OSspecific.H"
#include "fvCFD.H" #include "fvCFD.H"
#include "IOobjectList.H" #include "IOobjectList.H"
#include "processorFvPatchFields.H"
#include "domainDecomposition.H" #include "domainDecomposition.H"
#include "labelIOField.H" #include "labelIOField.H"
#include "scalarIOField.H" #include "scalarIOField.H"

View File

@ -28,6 +28,7 @@ License
#include "dictionary.H" #include "dictionary.H"
#include "labelIOList.H" #include "labelIOList.H"
#include "processorPolyPatch.H" #include "processorPolyPatch.H"
#include "processorCyclicPolyPatch.H"
#include "fvMesh.H" #include "fvMesh.H"
#include "OSspecific.H" #include "OSspecific.H"
#include "Map.H" #include "Map.H"
@ -108,7 +109,8 @@ Foam::domainDecomposition::domainDecomposition(const IOobject& io)
procNeighbourProcessors_(nProcs_), procNeighbourProcessors_(nProcs_),
procProcessorPatchSize_(nProcs_), procProcessorPatchSize_(nProcs_),
procProcessorPatchStartIndex_(nProcs_), procProcessorPatchStartIndex_(nProcs_),
cyclicParallel_(false) procProcessorPatchSubPatchIDs_(nProcs_),
procProcessorPatchSubPatchStarts_(nProcs_)
{ {
if (decompositionDict_.found("distributed")) if (decompositionDict_.found("distributed"))
{ {
@ -343,12 +345,42 @@ bool Foam::domainDecomposition::writeDecomposition()
const labelList& curProcessorPatchStarts = const labelList& curProcessorPatchStarts =
procProcessorPatchStartIndex_[procI]; procProcessorPatchStartIndex_[procI];
const labelListList& curSubPatchIDs =
procProcessorPatchSubPatchIDs_[procI];
const labelListList& curSubStarts =
procProcessorPatchSubPatchStarts_[procI];
const polyPatchList& meshPatches = boundaryMesh(); const polyPatchList& meshPatches = boundaryMesh();
// Count the number of inter-proc patches
label nInterProcPatches = 0;
forAll(curSubPatchIDs, procPatchI)
{
Info<< "For processor " << procI
<< " have to destination processor "
<< curNeighbourProcessors[procPatchI] << endl;
forAll(curSubPatchIDs[procPatchI], i)
{
Info<< " from patch:" << curSubPatchIDs[procPatchI][i]
<< " starting at:" << curSubStarts[procPatchI][i]
<< endl;
}
nInterProcPatches += curSubPatchIDs[procPatchI].size();
}
Info<< "For processor " << procI
<< " have " << nInterProcPatches << " to neighbouring processors"
<< endl;
List<polyPatch*> procPatches List<polyPatch*> procPatches
( (
curPatchSizes.size() curPatchSizes.size()
+ curProcessorPatchSizes.size(), + nInterProcPatches, //curProcessorPatchSizes.size(),
reinterpret_cast<polyPatch*>(0) reinterpret_cast<polyPatch*>(0)
); );
@ -385,23 +417,84 @@ bool Foam::domainDecomposition::writeDecomposition()
forAll(curProcessorPatchSizes, procPatchI) forAll(curProcessorPatchSizes, procPatchI)
{ {
procPatches[nPatches] = const labelList& subPatchID = curSubPatchIDs[procPatchI];
new processorPolyPatch const labelList& subStarts = curSubStarts[procPatchI];
(
word("procBoundary") + Foam::name(procI)
+ word("to")
+ Foam::name(curNeighbourProcessors[procPatchI]),
curProcessorPatchSizes[procPatchI],
curProcessorPatchStarts[procPatchI],
nPatches,
procMesh.boundaryMesh(),
procI,
curNeighbourProcessors[procPatchI]
);
nPatches++; label curStart = curProcessorPatchStarts[procPatchI];
forAll(subPatchID, i)
{
label size =
(
i < subPatchID.size()-1
? subStarts[i+1] - subStarts[i]
: curProcessorPatchSizes[procPatchI] - subStarts[i]
);
Info<< "From processor:" << procI << endl
<< " to processor:" << curNeighbourProcessors[procPatchI]
<< endl
<< " via patch:" << subPatchID[i] << endl
<< " start :" << curStart << endl
<< " size :" << size << endl;
if (subPatchID[i] == -1)
{
// From internal faces
procPatches[nPatches] =
new processorPolyPatch
(
word("procBoundary") + Foam::name(procI)
+ "to"
+ Foam::name(curNeighbourProcessors[procPatchI]),
size,
curStart,
nPatches,
procMesh.boundaryMesh(),
procI,
curNeighbourProcessors[procPatchI]
);
}
else
{
// From cyclic
const word& referPatch =
boundaryMesh()[subPatchID[i]].name();
procPatches[nPatches] =
new processorCyclicPolyPatch
(
word("procBoundary") + Foam::name(procI)
+ "to"
+ Foam::name(curNeighbourProcessors[procPatchI])
+ "through"
+ referPatch,
size,
curStart,
nPatches,
procMesh.boundaryMesh(),
procI,
curNeighbourProcessors[procPatchI],
referPatch
);
}
curStart += size;
nPatches++;
}
} }
forAll(procPatches, patchI)
{
Pout<< " " << patchI
<< '\t' << "name:" << procPatches[patchI]->name()
<< '\t' << "type:" << procPatches[patchI]->type()
<< '\t' << "size:" << procPatches[patchI]->size()
<< endl;
}
// Add boundary patches // Add boundary patches
procMesh.addPatches(procPatches); procMesh.addPatches(procPatches);
@ -667,11 +760,7 @@ bool Foam::domainDecomposition::writeDecomposition()
forAll(procMesh.boundaryMesh(), patchi) forAll(procMesh.boundaryMesh(), patchi)
{ {
if if (isA<processorPolyPatch>(procMesh.boundaryMesh()[patchi]))
(
procMesh.boundaryMesh()[patchi].type()
== processorPolyPatch::typeName
)
{ {
const processorPolyPatch& ppp = const processorPolyPatch& ppp =
refCast<const processorPolyPatch> refCast<const processorPolyPatch>
@ -749,11 +838,7 @@ bool Foam::domainDecomposition::writeDecomposition()
// (= identity map for original patches, -1 for processor patches) // (= identity map for original patches, -1 for processor patches)
label nMeshPatches = curPatchSizes.size(); label nMeshPatches = curPatchSizes.size();
labelList procBoundaryAddressing(identity(nMeshPatches)); labelList procBoundaryAddressing(identity(nMeshPatches));
procBoundaryAddressing.setSize procBoundaryAddressing.setSize(nMeshPatches+nProcPatches, -1);
(
nMeshPatches+curProcessorPatchSizes.size(),
-1
);
labelIOList boundaryProcAddressing labelIOList boundaryProcAddressing
( (

View File

@ -29,6 +29,7 @@ Description
SourceFiles SourceFiles
domainDecomposition.C domainDecomposition.C
decomposeMesh.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -78,9 +79,9 @@ class domainDecomposition
// index is negative, the processor face is the reverse of the // index is negative, the processor face is the reverse of the
// original face. In order to do this properly, all face // original face. In order to do this properly, all face
// indices will be incremented by 1 and the decremented as // indices will be incremented by 1 and the decremented as
// necessary t avoid the problem of face number zero having no // necessary to avoid the problem of face number zero having no
// sign. // sign.
labelListList procFaceAddressing_; List<DynamicList<label> > procFaceAddressing_;
//- Labels of cells for each processor //- Labels of cells for each processor
labelListList procCellAddressing_; labelListList procCellAddressing_;
@ -93,18 +94,23 @@ class domainDecomposition
// Excludes inter-processor boundaries // Excludes inter-processor boundaries
labelListList procPatchStartIndex_; labelListList procPatchStartIndex_;
// Per inter-processor patch information
//- Neighbour processor ID for inter-processor boundaries //- Neighbour processor ID for inter-processor boundaries
labelListList procNeighbourProcessors_; labelListList procNeighbourProcessors_;
//- Sizes for inter-processor patches //- Sizes for inter-processor patches
labelListList procProcessorPatchSize_; labelListList procProcessorPatchSize_;
//- Start indices for inter-processor patches //- Start indices (in procFaceAddressing_) for inter-processor patches
labelListList procProcessorPatchStartIndex_; labelListList procProcessorPatchStartIndex_;
//- Are there cyclic-parallel faces //- Sub patch IDs for inter-processor patches
bool cyclicParallel_; List<labelListList> procProcessorPatchSubPatchIDs_;
//- Sub patch sizes for inter-processor patches
List<labelListList> procProcessorPatchSubPatchStarts_;
// Private Member Functions // Private Member Functions
@ -118,6 +124,21 @@ class domainDecomposition
labelList& elementToZone labelList& elementToZone
); );
//- Append single element to list
static void append(labelList&, const label);
//- Add face to interProcessor patch.
void addInterProcFace
(
const label facei,
const label ownerProc,
const label nbrProc,
List<Map<label> >&,
List<DynamicList<DynamicList<label> > >&
) const;
public: public:
// Constructors // Constructors

View File

@ -26,7 +26,6 @@ License
#include "domainDecomposition.H" #include "domainDecomposition.H"
#include "decompositionMethod.H" #include "decompositionMethod.H"
#include "cpuTime.H" #include "cpuTime.H"
#include "cyclicPolyPatch.H"
#include "cellSet.H" #include "cellSet.H"
#include "regionSplit.H" #include "regionSplit.H"

View File

@ -39,6 +39,63 @@ Description
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::domainDecomposition::append(labelList& lst, const label elem)
{
label sz = lst.size();
lst.setSize(sz+1);
lst[sz] = elem;
}
void Foam::domainDecomposition::addInterProcFace
(
const label facei,
const label ownerProc,
const label nbrProc,
List<Map<label> >& nbrToInterPatch,
List<DynamicList<DynamicList<label> > >& interPatchFaces
) const
{
Map<label>::iterator patchIter = nbrToInterPatch[ownerProc].find(nbrProc);
// Introduce turning index only for internal faces (are duplicated).
label ownerIndex = facei+1;
label nbrIndex = -(facei+1);
if (patchIter != nbrToInterPatch[ownerProc].end())
{
// Existing interproc patch. Add to both sides.
label toNbrProcPatchI = patchIter();
interPatchFaces[ownerProc][toNbrProcPatchI].append(ownerIndex);
if (isInternalFace(facei))
{
label toOwnerProcPatchI = nbrToInterPatch[nbrProc][ownerProc];
interPatchFaces[nbrProc][toOwnerProcPatchI].append(nbrIndex);
}
}
else
{
// Create new interproc patches.
label toNbrProcPatchI = nbrToInterPatch[ownerProc].size();
nbrToInterPatch[ownerProc].insert(nbrProc, toNbrProcPatchI);
DynamicList<label> oneFace;
oneFace.append(ownerIndex);
interPatchFaces[ownerProc].append(oneFace);
if (isInternalFace(facei))
{
label toOwnerProcPatchI = nbrToInterPatch[nbrProc].size();
nbrToInterPatch[nbrProc].insert(ownerProc, toOwnerProcPatchI);
oneFace.clear();
oneFace.append(nbrIndex);
interPatchFaces[nbrProc].append(oneFace);
}
}
}
void Foam::domainDecomposition::decomposeMesh() void Foam::domainDecomposition::decomposeMesh()
{ {
// Decide which cell goes to which processor // Decide which cell goes to which processor
@ -60,31 +117,8 @@ void Foam::domainDecomposition::decomposeMesh()
Info<< "\nDistributing cells to processors" << endl; Info<< "\nDistributing cells to processors" << endl;
// Memory management // Cells per processor
{ procCellAddressing_ = invertOneToMany(nProcs_, cellToProc_);
List<SLList<label> > procCellList(nProcs_);
forAll(cellToProc_, celli)
{
if (cellToProc_[celli] >= nProcs_)
{
FatalErrorIn("domainDecomposition::decomposeMesh()")
<< "Impossible processor label " << cellToProc_[celli]
<< "for cell " << celli
<< abort(FatalError);
}
else
{
procCellList[cellToProc_[celli]].append(celli);
}
}
// Convert linked lists into normal lists
forAll(procCellList, procI)
{
procCellAddressing_[procI] = procCellList[procI];
}
}
Info<< "\nDistributing faces to processors" << endl; Info<< "\nDistributing faces to processors" << endl;
@ -93,504 +127,333 @@ void Foam::domainDecomposition::decomposeMesh()
// same processor, the face is an internal face. If they are different, // same processor, the face is an internal face. If they are different,
// it belongs to both processors. // it belongs to both processors.
// Memory management procFaceAddressing_.setSize(nProcs_);
// Internal faces
forAll (neighbour, facei)
{ {
List<SLList<label> > procFaceList(nProcs_); if (cellToProc_[owner[facei]] == cellToProc_[neighbour[facei]])
forAll(neighbour, facei)
{ {
if (cellToProc_[owner[facei]] == cellToProc_[neighbour[facei]]) // Face internal to processor. Notice no turning index.
{ procFaceAddressing_[cellToProc_[owner[facei]]].append(facei+1);
// Face internal to processor }
procFaceList[cellToProc_[owner[facei]]].append(facei); }
}
// for all processors, set the size of start index and patch size
// lists to the number of patches in the mesh
forAll (procPatchSize_, procI)
{
procPatchSize_[procI].setSize(patches.size());
procPatchStartIndex_[procI].setSize(patches.size());
}
forAll (patches, patchi)
{
// Reset size and start index for all processors
forAll (procPatchSize_, procI)
{
procPatchSize_[procI][patchi] = 0;
procPatchStartIndex_[procI][patchi] =
procFaceAddressing_[procI].size();
} }
// Detect inter-processor boundaries const label patchStart = patches[patchi].start();
// Neighbour processor for each subdomain if (!isA<cyclicPolyPatch>(patches[patchi]))
List<SLList<label> > interProcBoundaries(nProcs_);
// Face labels belonging to each inter-processor boundary
List<SLList<SLList<label> > > interProcBFaces(nProcs_);
List<SLList<label> > procPatchIndex(nProcs_);
forAll(neighbour, facei)
{ {
if (cellToProc_[owner[facei]] != cellToProc_[neighbour[facei]]) // Normal patch. Add faces to processor where the cell
// next to the face lives
const unallocLabelList& patchFaceCells =
patches[patchi].faceCells();
forAll (patchFaceCells, facei)
{ {
// inter - processor patch face found. Go through the list of const label curProc = cellToProc_[patchFaceCells[facei]];
// inside boundaries for the owner processor and try to find
// this inter-processor patch.
label ownerProc = cellToProc_[owner[facei]]; // add the face without turning index
label neighbourProc = cellToProc_[neighbour[facei]]; procFaceAddressing_[curProc].append(patchStart+facei+1);
SLList<label>::iterator curInterProcBdrsOwnIter = // increment the number of faces for this patch
interProcBoundaries[ownerProc].begin(); procPatchSize_[curProc][patchi]++;
SLList<SLList<label> >::iterator curInterProcBFacesOwnIter =
interProcBFaces[ownerProc].begin();
bool interProcBouFound = false;
// WARNING: Synchronous SLList iterators
for
(
;
curInterProcBdrsOwnIter
!= interProcBoundaries[ownerProc].end()
&& curInterProcBFacesOwnIter
!= interProcBFaces[ownerProc].end();
++curInterProcBdrsOwnIter, ++curInterProcBFacesOwnIter
)
{
if (curInterProcBdrsOwnIter() == neighbourProc)
{
// the inter - processor boundary exists. Add the face
interProcBouFound = true;
curInterProcBFacesOwnIter().append(facei);
SLList<label>::iterator curInterProcBdrsNeiIter =
interProcBoundaries[neighbourProc].begin();
SLList<SLList<label> >::iterator
curInterProcBFacesNeiIter =
interProcBFaces[neighbourProc].begin();
bool neighbourFound = false;
// WARNING: Synchronous SLList iterators
for
(
;
curInterProcBdrsNeiIter !=
interProcBoundaries[neighbourProc].end()
&& curInterProcBFacesNeiIter !=
interProcBFaces[neighbourProc].end();
++curInterProcBdrsNeiIter,
++curInterProcBFacesNeiIter
)
{
if (curInterProcBdrsNeiIter() == ownerProc)
{
// boundary found. Add the face
neighbourFound = true;
curInterProcBFacesNeiIter().append(facei);
}
if (neighbourFound) break;
}
if (interProcBouFound && !neighbourFound)
{
FatalErrorIn("domainDecomposition::decomposeMesh()")
<< "Inconsistency in inter - "
<< "processor boundary lists for processors "
<< ownerProc << " and " << neighbourProc
<< abort(FatalError);
}
}
if (interProcBouFound) break;
}
if (!interProcBouFound)
{
// inter - processor boundaries do not exist and need to
// be created
// set the new addressing information
// owner
interProcBoundaries[ownerProc].append(neighbourProc);
interProcBFaces[ownerProc].append(SLList<label>(facei));
// neighbour
interProcBoundaries[neighbourProc].append(ownerProc);
interProcBFaces[neighbourProc].append(SLList<label>(facei));
}
} }
} }
else
// Loop through patches. For cyclic boundaries detect inter-processor
// faces; for all other, add faces to the face list and remember start
// and size of all patches.
// for all processors, set the size of start index and patch size
// lists to the number of patches in the mesh
forAll(procPatchSize_, procI)
{ {
procPatchSize_[procI].setSize(patches.size()); const cyclicPolyPatch& pp = refCast<const cyclicPolyPatch>
procPatchStartIndex_[procI].setSize(patches.size()); (
} patches[patchi]
);
// cyclic: check opposite side on this processor
const unallocLabelList& patchFaceCells = pp.faceCells();
forAll(patches, patchi) const unallocLabelList& nbrPatchFaceCells =
{ pp.neighbPatch().faceCells();
// Reset size and start index for all processors
forAll(procPatchSize_, procI) forAll (patchFaceCells, facei)
{ {
procPatchSize_[procI][patchi] = 0; const label curProc = cellToProc_[patchFaceCells[facei]];
procPatchStartIndex_[procI][patchi] = const label nbrProc = cellToProc_[nbrPatchFaceCells[facei]];
procFaceList[procI].size(); if (curProc == nbrProc)
}
const label patchStart = patches[patchi].start();
if (!isA<cyclicPolyPatch>(patches[patchi]))
{
// Normal patch. Add faces to processor where the cell
// next to the face lives
const unallocLabelList& patchFaceCells =
patches[patchi].faceCells();
forAll(patchFaceCells, facei)
{ {
const label curProc = cellToProc_[patchFaceCells[facei]]; // add the face without turning index
procFaceAddressing_[curProc].append(patchStart+facei+1);
// add the face
procFaceList[curProc].append(patchStart + facei);
// increment the number of faces for this patch // increment the number of faces for this patch
procPatchSize_[curProc][patchi]++; procPatchSize_[curProc][patchi]++;
} }
} }
else
{
// Cyclic patch special treatment
const polyPatch& cPatch = patches[patchi];
const label cycOffset = cPatch.size()/2;
// Set reference to faceCells for both patches
const labelList::subList firstFaceCells
(
cPatch.faceCells(),
cycOffset
);
const labelList::subList secondFaceCells
(
cPatch.faceCells(),
cycOffset,
cycOffset
);
forAll(firstFaceCells, facei)
{
if
(
cellToProc_[firstFaceCells[facei]]
!= cellToProc_[secondFaceCells[facei]]
)
{
// This face becomes an inter-processor boundary face
// inter - processor patch face found. Go through
// the list of inside boundaries for the owner
// processor and try to find this inter-processor
// patch.
cyclicParallel_ = true;
label ownerProc = cellToProc_[firstFaceCells[facei]];
label neighbourProc =
cellToProc_[secondFaceCells[facei]];
SLList<label>::iterator curInterProcBdrsOwnIter =
interProcBoundaries[ownerProc].begin();
SLList<SLList<label> >::iterator
curInterProcBFacesOwnIter =
interProcBFaces[ownerProc].begin();
bool interProcBouFound = false;
// WARNING: Synchronous SLList iterators
for
(
;
curInterProcBdrsOwnIter !=
interProcBoundaries[ownerProc].end()
&& curInterProcBFacesOwnIter !=
interProcBFaces[ownerProc].end();
++curInterProcBdrsOwnIter,
++curInterProcBFacesOwnIter
)
{
if (curInterProcBdrsOwnIter() == neighbourProc)
{
// the inter - processor boundary exists.
// Add the face
interProcBouFound = true;
curInterProcBFacesOwnIter().append
(patchStart + facei);
SLList<label>::iterator curInterProcBdrsNeiIter
= interProcBoundaries[neighbourProc].begin();
SLList<SLList<label> >::iterator
curInterProcBFacesNeiIter =
interProcBFaces[neighbourProc].begin();
bool neighbourFound = false;
// WARNING: Synchronous SLList iterators
for
(
;
curInterProcBdrsNeiIter
!= interProcBoundaries[neighbourProc].end()
&& curInterProcBFacesNeiIter
!= interProcBFaces[neighbourProc].end();
++curInterProcBdrsNeiIter,
++curInterProcBFacesNeiIter
)
{
if (curInterProcBdrsNeiIter() == ownerProc)
{
// boundary found. Add the face
neighbourFound = true;
curInterProcBFacesNeiIter()
.append
(
patchStart
+ cycOffset
+ facei
);
}
if (neighbourFound) break;
}
if (interProcBouFound && !neighbourFound)
{
FatalErrorIn
(
"domainDecomposition::decomposeMesh()"
) << "Inconsistency in inter-processor "
<< "boundary lists for processors "
<< ownerProc << " and " << neighbourProc
<< " in cyclic boundary matching"
<< abort(FatalError);
}
}
if (interProcBouFound) break;
}
if (!interProcBouFound)
{
// inter - processor boundaries do not exist
// and need to be created
// set the new addressing information
// owner
interProcBoundaries[ownerProc]
.append(neighbourProc);
interProcBFaces[ownerProc]
.append(SLList<label>(patchStart + facei));
// neighbour
interProcBoundaries[neighbourProc]
.append(ownerProc);
interProcBFaces[neighbourProc]
.append
(
SLList<label>
(
patchStart
+ cycOffset
+ facei
)
);
}
}
else
{
// This cyclic face remains on the processor
label ownerProc = cellToProc_[firstFaceCells[facei]];
// add the face
procFaceList[ownerProc].append(patchStart + facei);
// increment the number of faces for this patch
procPatchSize_[ownerProc][patchi]++;
// Note: I cannot add the other side of the cyclic
// boundary here because this would violate the order.
// They will be added in a separate loop below
//
}
}
// Ordering in cyclic boundaries is important.
// Add the other half of cyclic faces for cyclic boundaries
// that remain on the processor
forAll(secondFaceCells, facei)
{
if
(
cellToProc_[firstFaceCells[facei]]
== cellToProc_[secondFaceCells[facei]]
)
{
// This cyclic face remains on the processor
label ownerProc = cellToProc_[firstFaceCells[facei]];
// add the second face
procFaceList[ownerProc].append
(patchStart + cycOffset + facei);
// increment the number of faces for this patch
procPatchSize_[ownerProc][patchi]++;
}
}
}
} }
}
// Convert linked lists into normal lists
// Add inter-processor boundaries and remember start indices // Done internal bits of the new mesh and the ordinary patches.
forAll(procFaceList, procI)
// Per processor, from neighbour processor to the interprocessorpatch that
// communicates with that neighbour.
List<Map<label> > procNbrToInterPatch(nProcs_);
// Per processor the faces per interprocessorpatch.
List<DynamicList<DynamicList<label> > > interPatchFaces(nProcs_);
// Processor boundaries from internal faces
forAll (neighbour, facei)
{
label ownerProc = cellToProc_[owner[facei]];
label nbrProc = cellToProc_[neighbour[facei]];
if (ownerProc != nbrProc)
{ {
// Get internal and regular boundary processor faces // inter - processor patch face found.
SLList<label>& curProcFaces = procFaceList[procI]; addInterProcFace
// Get reference to processor face addressing
labelList& curProcFaceAddressing = procFaceAddressing_[procI];
labelList& curProcNeighbourProcessors =
procNeighbourProcessors_[procI];
labelList& curProcProcessorPatchSize =
procProcessorPatchSize_[procI];
labelList& curProcProcessorPatchStartIndex =
procProcessorPatchStartIndex_[procI];
// calculate the size
label nFacesOnProcessor = curProcFaces.size();
for
( (
SLList<SLList<label> >::iterator curInterProcBFacesIter = facei,
interProcBFaces[procI].begin(); ownerProc,
curInterProcBFacesIter != interProcBFaces[procI].end(); nbrProc,
++curInterProcBFacesIter
)
{
nFacesOnProcessor += curInterProcBFacesIter().size();
}
curProcFaceAddressing.setSize(nFacesOnProcessor); procNbrToInterPatch,
interPatchFaces
);
}
}
// Fill in the list. Calculate turning index. // Add the proper processor faces to the sub information. For faces
// Turning index will be -1 only for some faces on processor // originating from internal faces this is always -1.
// boundaries, i.e. the ones where the current processor ID List<labelListList> subPatchIDs(nProcs_);
// is in the cell which is a face neighbour. List<labelListList> subPatchStarts(nProcs_);
// Turning index is stored as the sign of the face addressing list forAll(interPatchFaces, procI)
{
label nInterfaces = interPatchFaces[procI].size();
label nFaces = 0; subPatchIDs[procI].setSize(nInterfaces, labelList(1, -1));
subPatchStarts[procI].setSize(nInterfaces, labelList(1, 0));
}
// Add internal and boundary faces // Processor boundaries from split cyclics
// Remember to increment the index by one such that the forAll (patches, patchi)
// turning index works properly. {
forAllConstIter(SLList<label>, curProcFaces, curProcFacesIter) if (isA<cyclicPolyPatch>(patches[patchi]))
{ {
curProcFaceAddressing[nFaces] = curProcFacesIter() + 1; const cyclicPolyPatch& pp = refCast<const cyclicPolyPatch>
nFaces++;
}
// Add inter-processor boundary faces. At the beginning of each
// patch, grab the patch start index and size
curProcNeighbourProcessors.setSize
( (
interProcBoundaries[procI].size() patches[patchi]
); );
curProcProcessorPatchSize.setSize // cyclic: check opposite side on this processor
( const unallocLabelList& patchFaceCells = pp.faceCells();
interProcBoundaries[procI].size() const unallocLabelList& nbrPatchFaceCells =
); pp.neighbPatch().faceCells();
curProcProcessorPatchStartIndex.setSize // Store old sizes. Used to detect which inter-proc patches
( // have been added to.
interProcBoundaries[procI].size() labelListList oldInterfaceSizes(nProcs_);
); forAll(oldInterfaceSizes, procI)
label nProcPatches = 0;
SLList<label>::iterator curInterProcBdrsIter =
interProcBoundaries[procI].begin();
SLList<SLList<label> >::iterator curInterProcBFacesIter =
interProcBFaces[procI].begin();
for
(
;
curInterProcBdrsIter != interProcBoundaries[procI].end()
&& curInterProcBFacesIter != interProcBFaces[procI].end();
++curInterProcBdrsIter, ++curInterProcBFacesIter
)
{ {
curProcNeighbourProcessors[nProcPatches] = labelList& curOldSizes = oldInterfaceSizes[procI];
curInterProcBdrsIter();
// Get start index for processor patch curOldSizes.setSize(interPatchFaces[procI].size());
curProcProcessorPatchStartIndex[nProcPatches] = nFaces; forAll(curOldSizes, interI)
label& curSize =
curProcProcessorPatchSize[nProcPatches];
curSize = 0;
// add faces for this processor boundary
forAllConstIter
(
SLList<label>,
curInterProcBFacesIter(),
curFacesIter
)
{ {
// add the face curOldSizes[interI] =
interPatchFaces[procI][interI].size();
// Remember to increment the index by one such that the
// turning index works properly.
if (cellToProc_[owner[curFacesIter()]] == procI)
{
curProcFaceAddressing[nFaces] = curFacesIter() + 1;
}
else
{
// turning face
curProcFaceAddressing[nFaces] = -(curFacesIter() + 1);
}
// increment the size
curSize++;
nFaces++;
} }
}
nProcPatches++; // Add faces with different owner and neighbour processors
forAll (patchFaceCells, facei)
{
const label ownerProc = cellToProc_[patchFaceCells[facei]];
const label nbrProc = cellToProc_[nbrPatchFaceCells[facei]];
if (ownerProc != nbrProc)
{
// inter - processor patch face found.
addInterProcFace
(
pp.start()+facei,
ownerProc,
nbrProc,
procNbrToInterPatch,
interPatchFaces
);
}
}
// 1. Check if any faces added to existing interfaces
forAll(oldInterfaceSizes, procI)
{
const labelList& curOldSizes = oldInterfaceSizes[procI];
forAll(curOldSizes, interI)
{
label oldSz = curOldSizes[interI];
if (interPatchFaces[procI][interI].size() > oldSz)
{
// Added faces to this interface. Add an entry
append(subPatchIDs[procI][interI], patchi);
append(subPatchStarts[procI][interI], oldSz);
}
}
}
// 2. Any new interfaces
forAll(subPatchIDs, procI)
{
label nIntfcs = interPatchFaces[procI].size();
subPatchIDs[procI].setSize(nIntfcs, labelList(1, patchi));
subPatchStarts[procI].setSize(nIntfcs, labelList(1, 0));
} }
} }
} }
// Shrink processor patch face addressing
forAll(interPatchFaces, procI)
{
DynamicList<DynamicList<label> >& curInterPatchFaces =
interPatchFaces[procI];
forAll(curInterPatchFaces, i)
{
curInterPatchFaces[i].shrink();
}
curInterPatchFaces.shrink();
}
// Sort inter-proc patch by neighbour
labelList order;
forAll(procNbrToInterPatch, procI)
{
label nInterfaces = procNbrToInterPatch[procI].size();
procNeighbourProcessors_[procI].setSize(nInterfaces);
procProcessorPatchSize_[procI].setSize(nInterfaces);
procProcessorPatchStartIndex_[procI].setSize(nInterfaces);
procProcessorPatchSubPatchIDs_[procI].setSize(nInterfaces);
procProcessorPatchSubPatchStarts_[procI].setSize(nInterfaces);
Info<< "Processor " << procI << endl;
// Get sorted neighbour processors
const Map<label>& curNbrToInterPatch = procNbrToInterPatch[procI];
labelList nbrs = curNbrToInterPatch.toc();
sortedOrder(nbrs, order);
DynamicList<DynamicList<label> >& curInterPatchFaces =
interPatchFaces[procI];
forAll(order, i)
{
const label nbrProc = nbrs[i];
const label interPatch = curNbrToInterPatch[nbrProc];
procNeighbourProcessors_[procI][i] = nbrProc;
procProcessorPatchSize_[procI][i] = curInterPatchFaces[i].size();
procProcessorPatchStartIndex_[procI][i] =
procFaceAddressing_[procI].size();
// Add size as last element to substarts and transfer
append
(
subPatchStarts[procI][interPatch],
curInterPatchFaces[interPatch].size()
);
procProcessorPatchSubPatchIDs_[procI][i].transfer
(
subPatchIDs[procI][interPatch]
);
procProcessorPatchSubPatchStarts_[procI][i].transfer
(
subPatchStarts[procI][interPatch]
);
Info<< " nbr:" << nbrProc << endl;
Info<< " interpatch:" << interPatch << endl;
Info<< " size:" << procProcessorPatchSize_[procI][i] << endl;
Info<< " start:" << procProcessorPatchStartIndex_[procI][i]
<< endl;
Info<< " subPatches:" << procProcessorPatchSubPatchIDs_[procI][i]
<< endl;
Info<< " subStarts:"
<< procProcessorPatchSubPatchStarts_[procI][i] << endl;
// And add all the face labels for interPatch
DynamicList<label>& interPatchFaces =
curInterPatchFaces[interPatch];
forAll(interPatchFaces, j)
{
procFaceAddressing_[procI].append(interPatchFaces[j]);
}
interPatchFaces.clearStorage();
}
curInterPatchFaces.clearStorage();
procFaceAddressing_[procI].shrink();
}
//XXXXXXX
// Print a bit
forAll(procPatchStartIndex_, procI)
{
Info<< "Processor:" << procI << endl;
Info<< " total faces:" << procFaceAddressing_[procI].size() << endl;
const labelList& curProcPatchStartIndex = procPatchStartIndex_[procI];
forAll(curProcPatchStartIndex, patchI)
{
Info<< " patch:" << patchI
<< "\tstart:" << curProcPatchStartIndex[patchI]
<< "\tsize:" << procPatchSize_[procI][patchI]
<< endl;
}
}
Info<< endl;
forAll(procNeighbourProcessors_, procI)
{
Info<< "Processor " << procI << endl;
forAll(procNeighbourProcessors_[procI], i)
{
Info<< " nbr:" << procNeighbourProcessors_[procI][i] << endl;
Info<< " size:" << procProcessorPatchSize_[procI][i] << endl;
Info<< " start:" << procProcessorPatchStartIndex_[procI][i]
<< endl;
}
}
Info<< endl;
// forAll(procFaceAddressing_, procI)
// {
// Info<< "Processor:" << procI << endl;
//
// Info<< " faces:" << procFaceAddressing_[procI] << endl;
// }
Info<< "\nDistributing points to processors" << endl; Info<< "\nDistributing points to processors" << endl;
// For every processor, loop through the list of faces for the processor. // For every processor, loop through the list of faces for the processor.
// For every face, loop through the list of points and mark the point as // For every face, loop through the list of points and mark the point as

View File

@ -144,7 +144,11 @@ Foam::fvFieldDecomposer::fvFieldDecomposer
{ {
forAll(boundaryAddressing_, patchi) forAll(boundaryAddressing_, patchi)
{ {
if (boundaryAddressing_[patchi] >= 0) if
(
boundaryAddressing_[patchi] >= 0
&& !isA<processorLduInterface>(procMesh.boundary()[patchi])
)
{ {
patchFieldDecomposerPtrs_[patchi] = new patchFieldDecomposer patchFieldDecomposerPtrs_[patchi] = new patchFieldDecomposer
( (

View File

@ -26,6 +26,8 @@ License
#include "fvFieldDecomposer.H" #include "fvFieldDecomposer.H"
#include "processorFvPatchField.H" #include "processorFvPatchField.H"
#include "processorFvsPatchField.H" #include "processorFvsPatchField.H"
#include "processorCyclicFvPatchField.H"
#include "processorCyclicFvsPatchField.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -44,7 +46,7 @@ Foam::fvFieldDecomposer::decomposeField
forAll(boundaryAddressing_, patchi) forAll(boundaryAddressing_, patchi)
{ {
if (boundaryAddressing_[patchi] >= 0) if (patchFieldDecomposerPtrs_[patchi])
{ {
patchFields.set patchFields.set
( (
@ -58,7 +60,24 @@ Foam::fvFieldDecomposer::decomposeField
) )
); );
} }
else else if (isA<processorCyclicFvPatch>(procMesh_.boundary()[patchi]))
{
patchFields.set
(
patchi,
new processorCyclicFvPatchField<Type>
(
procMesh_.boundary()[patchi],
DimensionedField<Type, volMesh>::null(),
Field<Type>
(
field.internalField(),
*processorVolPatchFieldDecomposerPtrs_[patchi]
)
)
);
}
else if (isA<processorFvPatch>(procMesh_.boundary()[patchi]))
{ {
patchFields.set patchFields.set
( (
@ -75,6 +94,11 @@ Foam::fvFieldDecomposer::decomposeField
) )
); );
} }
else
{
FatalErrorIn("fvFieldDecomposer::decomposeField()")
<< "Unknown type." << abort(FatalError);
}
} }
// Create the field for the processor // Create the field for the processor
@ -155,7 +179,7 @@ Foam::fvFieldDecomposer::decomposeField
forAll(boundaryAddressing_, patchi) forAll(boundaryAddressing_, patchi)
{ {
if (boundaryAddressing_[patchi] >= 0) if (patchFieldDecomposerPtrs_[patchi])
{ {
patchFields.set patchFields.set
( (
@ -169,7 +193,24 @@ Foam::fvFieldDecomposer::decomposeField
) )
); );
} }
else else if (isA<processorCyclicFvPatch>(procMesh_.boundary()[patchi]))
{
patchFields.set
(
patchi,
new processorCyclicFvsPatchField<Type>
(
procMesh_.boundary()[patchi],
DimensionedField<Type, surfaceMesh>::null(),
Field<Type>
(
allFaceField,
*processorSurfacePatchFieldDecomposerPtrs_[patchi]
)
)
);
}
else if (isA<processorFvPatch>(procMesh_.boundary()[patchi]))
{ {
patchFields.set patchFields.set
( (
@ -186,6 +227,11 @@ Foam::fvFieldDecomposer::decomposeField
) )
); );
} }
else
{
FatalErrorIn("fvFieldDecomposer::decomposeField()")
<< "Unknown type." << abort(FatalError);
}
} }
// Create the field for the processor // Create the field for the processor

View File

@ -79,7 +79,7 @@ void Foam::channelIndex::walkOppositeFaces
isFrontBndFace[faceI-mesh.nInternalFaces()] = true; isFrontBndFace[faceI-mesh.nInternalFaces()] = true;
} }
} }
syncTools::swapBoundaryFaceList(mesh, isFrontBndFace, false); syncTools::swapBoundaryFaceList(mesh, isFrontBndFace);
// Add // Add
forAll(isFrontBndFace, i) forAll(isFrontBndFace, i)

View File

@ -30,7 +30,6 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "fvCFD.H" #include "fvCFD.H"
#include "cyclicPolyPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program: // Main program:
@ -76,35 +75,12 @@ int main(int argc, char *argv[])
} }
// Give patch area // Give patch area
if (isA<cyclicPolyPatch>(mesh.boundaryMesh()[patchI])) Info<< " Area vector of patch "
{ << patchName << '[' << patchI << ']' << " = "
Info<< " Cyclic patch vector area: " << nl; << gSum(mesh.Sf().boundaryField()[patchI]) << endl;
label nFaces = mesh.boundaryMesh()[patchI].size(); Info<< " Area magnitude of patch "
vector sum1 = vector::zero; << patchName << '[' << patchI << ']' << " = "
vector sum2 = vector::zero; << gSum(mesh.magSf().boundaryField()[patchI]) << endl;
for (label i=0; i<nFaces/2; i++)
{
sum1 += mesh.Sf().boundaryField()[patchI][i];
sum2 += mesh.Sf().boundaryField()[patchI][i+nFaces/2];
}
reduce(sum1, sumOp<vector>());
reduce(sum2, sumOp<vector>());
Info<< " - half 1 = " << sum1 << ", " << mag(sum1) << nl
<< " - half 2 = " << sum2 << ", " << mag(sum2) << nl
<< " - total = " << (sum1 + sum2) << ", "
<< mag(sum1 + sum2) << endl;
Info<< " Cyclic patch area magnitude = "
<< gSum(mesh.magSf().boundaryField()[patchI])/2.0 << endl;
}
else
{
Info<< " Area vector of patch "
<< patchName << '[' << patchI << ']' << " = "
<< gSum(mesh.Sf().boundaryField()[patchI]) << endl;
Info<< " Area magnitude of patch "
<< patchName << '[' << patchI << ']' << " = "
<< gSum(mesh.magSf().boundaryField()[patchI]) << endl;
}
// Read field and calc integral // Read field and calc integral
if (fieldHeader.headerClassName() == volScalarField::typeName) if (fieldHeader.headerClassName() == volScalarField::typeName)

View File

@ -0,0 +1,3 @@
foamUpgradeCyclics.C
EXE = $(FOAM_APPBIN)/foamUpgradeCyclics

View File

@ -0,0 +1,6 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lgenericPatchFields

View File

@ -0,0 +1,620 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Application
foamUpgradeCyclics
Description
Tool to upgrade mesh and fields for split cyclics
Usage
- foamUpgradeCyclics [OPTION]
@param -test \n
Suppress writing the updated files with split cyclics
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "Time.H"
#include "timeSelector.H"
#include "IOdictionary.H"
#include "polyMesh.H"
#include "entry.H"
#include "IOPtrList.H"
#include "cyclicPolyPatch.H"
#include "dictionaryEntry.H"
#include "IOobjectList.H"
#include "volFields.H"
#include "pointFields.H"
#include "surfaceFields.H"
#include "string.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
defineTemplateTypeNameAndDebug(IOPtrList<entry>, 0);
}
// Read boundary file without reading mesh
void rewriteBoundary
(
const bool isTestRun,
const IOobject& io,
const fileName& regionPrefix,
HashTable<word>& thisNames,
HashTable<word>& nbrNames
)
{
Info<< "Reading boundary from " << io.filePath() << endl;
// Read PtrList of dictionary.
const word oldTypeName = IOPtrList<entry>::typeName;
const_cast<word&>(IOPtrList<entry>::typeName) = word::null;
IOPtrList<entry> patches(io);
const_cast<word&>(IOPtrList<entry>::typeName) = oldTypeName;
// Fake type back to what was in field
const_cast<word&>(patches.type()) = patches.headerClassName();
// Replace any 'cyclic'
label nOldCyclics = 0;
forAll(patches, patchI)
{
const dictionary& patchDict = patches[patchI].dict();
if (word(patchDict["type"]) == cyclicPolyPatch::typeName)
{
if (!patchDict.found("neighbourPatch"))
{
Info<< "Patch " << patches[patchI].keyword()
<< " does not have 'neighbourPatch' entry; assuming it"
<< " is of the old type." << endl;
nOldCyclics++;
}
}
}
Info<< "Detected " << nOldCyclics << " old cyclics." << nl << endl;
// Save old patches.
PtrList<entry> oldPatches(patches);
// Extend
label nOldPatches = patches.size();
patches.setSize(nOldPatches+nOldCyclics);
// Create reordering map
labelList oldToNew(patches.size());
// Add new entries
label addedPatchI = nOldPatches;
label newPatchI = 0;
forAll(oldPatches, patchI)
{
const dictionary& patchDict = oldPatches[patchI].dict();
if
(
word(patchDict["type"]) == cyclicPolyPatch::typeName
)
{
const word& name = oldPatches[patchI].keyword();
if (patchDict.found("neighbourPatch"))
{
patches.set(patchI, oldPatches.set(patchI, NULL));
oldToNew[patchI] = newPatchI++;
// Check if patches come from automatic conversion
word oldName;
string::size_type i = name.rfind("_half0");
if (i != string::npos)
{
oldName = name.substr(0, i);
thisNames.insert(oldName, name);
Info<< "Detected converted cyclic patch " << name
<< " ; assuming it originates from " << oldName
<< endl;
}
else
{
i = name.rfind("_half1");
if (i != string::npos)
{
oldName = name.substr(0, i);
nbrNames.insert(oldName, name);
Info<< "Detected converted cyclic patch " << name
<< " ; assuming it originates from " << oldName
<< endl;
}
}
}
else
{
label nFaces = readLabel(patchDict["nFaces"]);
label startFace = readLabel(patchDict["startFace"]);
Info<< "Detected old style " << word(patchDict["type"])
<< " patch " << name << " with" << nl
<< " nFaces : " << nFaces << nl
<< " startFace : " << startFace << endl;
word thisName = name + "_half0";
word nbrName = name + "_half1";
thisNames.insert(name, thisName);
nbrNames.insert(name, nbrName);
// Save current dictionary
const dictionary patchDict(patches[patchI].dict());
// Change entry on this side
patches.set(patchI, oldPatches.set(patchI, NULL));
oldToNew[patchI] = newPatchI++;
dictionary& thisPatchDict = patches[patchI].dict();
thisPatchDict.add("neighbourPatch", nbrName);
thisPatchDict.set("nFaces", nFaces/2);
patches[patchI].keyword() = thisName;
// Add entry on other side
patches.set
(
addedPatchI,
new dictionaryEntry
(
nbrName,
dictionary::null,
patchDict
)
);
oldToNew[addedPatchI] = newPatchI++;
dictionary& nbrPatchDict = patches[addedPatchI].dict();
nbrPatchDict.set("neighbourPatch", thisName);
nbrPatchDict.set("nFaces", nFaces/2);
nbrPatchDict.set("startFace", startFace+nFaces/2);
patches[addedPatchI].keyword() = nbrName;
Info<< "Replaced with patches" << nl
<< patches[patchI].keyword() << " with" << nl
<< " nFaces : "
<< readLabel(thisPatchDict.lookup("nFaces"))
<< nl
<< " startFace : "
<< readLabel(thisPatchDict.lookup("startFace")) << nl
<< patches[addedPatchI].keyword() << " with" << nl
<< " nFaces : "
<< readLabel(nbrPatchDict.lookup("nFaces"))
<< nl
<< " startFace : "
<< readLabel(nbrPatchDict.lookup("startFace"))
<< nl << endl;
addedPatchI++;
}
}
else
{
patches.set(patchI, oldPatches.set(patchI, NULL));
oldToNew[patchI] = newPatchI++;
}
}
patches.reorder(oldToNew);
if (returnReduce(nOldCyclics, sumOp<label>()) > 0)
{
if (isTestRun)
{
//Info<< "-test option: no changes made" << nl << endl;
}
else
{
if (mvBak(patches.objectPath(), "old"))
{
Info<< "Backup to "
<< (patches.objectPath() + ".old") << nl;
}
Info<< "Write to "
<< patches.objectPath() << nl << endl;
patches.write();
}
}
else
{
Info<< "No changes made to boundary file." << nl << endl;
}
}
void rewriteField
(
const bool isTestRun,
const Time& runTime,
const word& fieldName,
const HashTable<word>& thisNames,
const HashTable<word>& nbrNames
)
{
// Read dictionary. (disable class type checking so we can load
// field)
Info<< "Loading field " << fieldName << endl;
const word oldTypeName = IOdictionary::typeName;
const_cast<word&>(IOdictionary::typeName) = word::null;
IOdictionary fieldDict
(
IOobject
(
fieldName,
runTime.timeName(),
runTime,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
)
);
const_cast<word&>(IOdictionary::typeName) = oldTypeName;
// Fake type back to what was in field
const_cast<word&>(fieldDict.type()) = fieldDict.headerClassName();
dictionary& boundaryField = fieldDict.subDict("boundaryField");
label nChanged = 0;
forAllConstIter(HashTable<word>, thisNames, iter)
{
const word& patchName = iter.key();
const word& newName = iter();
Info<< "Looking for entry for patch " << patchName << endl;
if (boundaryField.found(patchName) && !boundaryField.found(newName))
{
Info<< " Changing entry " << patchName << " to " << newName
<< endl;
dictionary patchDict(boundaryField.subDict(patchName));
if (patchDict.found("value"))
{
IOWarningIn("rewriteField(..)", patchDict)
<< "Cyclic patch " << patchName
<< " has value entry. Please removed this and rerun."
<< endl;
}
boundaryField.changeKeyword(patchName, newName);
boundaryField.add
(
nbrNames[patchName],
patchDict
);
Info<< " Adding entry " << nbrNames[patchName] << endl;
nChanged++;
}
}
//Info<< "New boundaryField:" << boundaryField << endl;
if (returnReduce(nChanged, sumOp<label>()) > 0)
{
if (isTestRun)
{
//Info<< "-test option: no changes made" << endl;
}
else
{
if (mvBak(fieldDict.objectPath(), "old"))
{
Info<< "Backup to "
<< (fieldDict.objectPath() + ".old") << nl;
}
Info<< "Write to "
<< fieldDict.objectPath() << endl;
fieldDict.regIOobject::write();
}
}
else
{
Info<< "No changes made to field " << fieldName << endl;
}
Info<< endl;
}
void rewriteFields
(
const bool isTestRun,
const Time& runTime,
const wordList& fieldNames,
const HashTable<word>& thisNames,
const HashTable<word>& nbrNames
)
{
forAll(fieldNames, i)
{
rewriteField
(
isTestRun,
runTime,
fieldNames[i],
thisNames,
nbrNames
);
}
}
// Main program:
int main(int argc, char *argv[])
{
timeSelector::addOptions();
argList::addBoolOption("test");
# include "addRegionOption.H"
# include "setRootCase.H"
# include "createTime.H"
instantList timeDirs = timeSelector::select0(runTime, args);
const bool isTestRun = args.optionFound("test");
if (isTestRun)
{
Info<< "-test option: no changes made" << nl << endl;
}
Foam::word regionName = polyMesh::defaultRegion;
args.optionReadIfPresent("region", regionName);
fileName regionPrefix = "";
if (regionName != polyMesh::defaultRegion)
{
regionPrefix = regionName;
}
// Per cyclic patch the new name for this side and the other side
HashTable<word> thisNames;
HashTable<word> nbrNames;
// Rewrite constant boundary file. Return any patches that have been split.
IOobject io
(
"boundary",
runTime.constant(),
polyMesh::meshSubDir,
runTime,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
);
if (io.headerOk())
{
rewriteBoundary
(
isTestRun,
io,
regionPrefix,
thisNames,
nbrNames
);
}
// Convert any fields
forAll(timeDirs, timeI)
{
runTime.setTime(timeDirs[timeI], timeI);
Info<< "Time: " << runTime.timeName() << endl;
// See if mesh in time directory
IOobject io
(
"boundary",
runTime.timeName(),
polyMesh::meshSubDir,
runTime,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
);
if (io.headerOk())
{
rewriteBoundary
(
isTestRun,
io,
regionPrefix,
thisNames,
nbrNames
);
}
IOobjectList objects(runTime, runTime.timeName());
// volFields
// ~~~~~~~~~
rewriteFields
(
isTestRun,
runTime,
objects.names(volScalarField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
isTestRun,
runTime,
objects.names(volVectorField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
isTestRun,
runTime,
objects.names(volSphericalTensorField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
isTestRun,
runTime,
objects.names(volSymmTensorField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
isTestRun,
runTime,
objects.names(volTensorField::typeName),
thisNames,
nbrNames
);
// pointFields
// ~~~~~~~~~~~
rewriteFields
(
isTestRun,
runTime,
objects.names(pointScalarField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
isTestRun,
runTime,
objects.names(pointVectorField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
isTestRun,
runTime,
objects.names(pointSphericalTensorField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
isTestRun,
runTime,
objects.names(pointSymmTensorField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
isTestRun,
runTime,
objects.names(pointTensorField::typeName),
thisNames,
nbrNames
);
// surfaceFields
// ~~~~~~~~~~~
rewriteFields
(
isTestRun,
runTime,
objects.names(surfaceScalarField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
isTestRun,
runTime,
objects.names(surfaceVectorField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
isTestRun,
runTime,
objects.names(surfaceSphericalTensorField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
isTestRun,
runTime,
objects.names(surfaceSymmTensorField::typeName),
thisNames,
nbrNames
);
rewriteFields
(
isTestRun,
runTime,
objects.names(surfaceTensorField::typeName),
thisNames,
nbrNames
);
}
return 0;
}
// ************************************************************************* //

View File

@ -260,12 +260,14 @@ GAMGInterfaces = $(GAMG)/interfaces
$(GAMGInterfaces)/GAMGInterface/GAMGInterface.C $(GAMGInterfaces)/GAMGInterface/GAMGInterface.C
$(GAMGInterfaces)/GAMGInterface/GAMGInterfaceNew.C $(GAMGInterfaces)/GAMGInterface/GAMGInterfaceNew.C
$(GAMGInterfaces)/processorGAMGInterface/processorGAMGInterface.C $(GAMGInterfaces)/processorGAMGInterface/processorGAMGInterface.C
$(GAMGInterfaces)/processorCyclicGAMGInterface/processorCyclicGAMGInterface.C
$(GAMGInterfaces)/cyclicGAMGInterface/cyclicGAMGInterface.C $(GAMGInterfaces)/cyclicGAMGInterface/cyclicGAMGInterface.C
GAMGInterfaceFields = $(GAMG)/interfaceFields GAMGInterfaceFields = $(GAMG)/interfaceFields
$(GAMGInterfaceFields)/GAMGInterfaceField/GAMGInterfaceField.C $(GAMGInterfaceFields)/GAMGInterfaceField/GAMGInterfaceField.C
$(GAMGInterfaceFields)/GAMGInterfaceField/GAMGInterfaceFieldNew.C $(GAMGInterfaceFields)/GAMGInterfaceField/GAMGInterfaceFieldNew.C
$(GAMGInterfaceFields)/processorGAMGInterfaceField/processorGAMGInterfaceField.C $(GAMGInterfaceFields)/processorGAMGInterfaceField/processorGAMGInterfaceField.C
$(GAMGInterfaceFields)/processorCyclicGAMGInterfaceField/processorCyclicGAMGInterfaceField.C
$(GAMGInterfaceFields)/cyclicGAMGInterfaceField/cyclicGAMGInterfaceField.C $(GAMGInterfaceFields)/cyclicGAMGInterfaceField/cyclicGAMGInterfaceField.C
GAMGAgglomerations = $(GAMG)/GAMGAgglomerations GAMGAgglomerations = $(GAMG)/GAMGAgglomerations
@ -339,6 +341,7 @@ $(constraintPolyPatches)/empty/emptyPolyPatch.C
$(constraintPolyPatches)/symmetry/symmetryPolyPatch.C $(constraintPolyPatches)/symmetry/symmetryPolyPatch.C
$(constraintPolyPatches)/wedge/wedgePolyPatch.C $(constraintPolyPatches)/wedge/wedgePolyPatch.C
$(constraintPolyPatches)/cyclic/cyclicPolyPatch.C $(constraintPolyPatches)/cyclic/cyclicPolyPatch.C
$(constraintPolyPatches)/processorCyclic/processorCyclicPolyPatch.C
$(constraintPolyPatches)/processor/processorPolyPatch.C $(constraintPolyPatches)/processor/processorPolyPatch.C
derivedPolyPatches = $(polyPatches)/derived derivedPolyPatches = $(polyPatches)/derived
@ -450,6 +453,7 @@ $(constraintPointPatches)/symmetry/symmetryPointPatch.C
$(constraintPointPatches)/wedge/wedgePointPatch.C $(constraintPointPatches)/wedge/wedgePointPatch.C
$(constraintPointPatches)/cyclic/cyclicPointPatch.C $(constraintPointPatches)/cyclic/cyclicPointPatch.C
$(constraintPointPatches)/processor/processorPointPatch.C $(constraintPointPatches)/processor/processorPointPatch.C
$(constraintPointPatches)/processorCyclic/processorCyclicPointPatch.C
derivedPointPatches = $(pointPatches)/derived derivedPointPatches = $(pointPatches)/derived
$(derivedPointPatches)/coupled/coupledFacePointPatch.C $(derivedPointPatches)/coupled/coupledFacePointPatch.C
@ -508,6 +512,7 @@ $(constraintPointPatchFields)/wedge/wedgePointPatchFields.C
$(constraintPointPatchFields)/cyclic/cyclicPointPatchFields.C $(constraintPointPatchFields)/cyclic/cyclicPointPatchFields.C
$(constraintPointPatchFields)/cyclicSlip/cyclicSlipPointPatchFields.C $(constraintPointPatchFields)/cyclicSlip/cyclicSlipPointPatchFields.C
$(constraintPointPatchFields)/processor/processorPointPatchFields.C $(constraintPointPatchFields)/processor/processorPointPatchFields.C
$(constraintPointPatchFields)/processorCyclic/processorCyclicPointPatchFields.C
derivedPointPatchFields = $(pointPatchFields)/derived derivedPointPatchFields = $(pointPatchFields)/derived
$(derivedPointPatchFields)/slip/slipPointPatchFields.C $(derivedPointPatchFields)/slip/slipPointPatchFields.C

View File

@ -251,12 +251,13 @@ bool Foam::FaceCellWave<Type>::updateFace
template <class Type> template <class Type>
void Foam::FaceCellWave<Type>::checkCyclic(const polyPatch& patch) const void Foam::FaceCellWave<Type>::checkCyclic(const polyPatch& patch) const
{ {
label cycOffset = patch.size()/2; const cyclicPolyPatch& nbrPatch =
refCast<const cyclicPolyPatch>(patch).neighbPatch();
for (label patchFaceI = 0; patchFaceI < cycOffset; patchFaceI++) forAll(patch, patchFaceI)
{ {
label i1 = patch.start() + patchFaceI; label i1 = patch.start() + patchFaceI;
label i2 = i1 + cycOffset; label i2 = nbrPatch.start() + patchFaceI;
if (!allFaceInfo_[i1].sameGeometry(mesh_, allFaceInfo_[i2], geomTol_)) if (!allFaceInfo_[i1].sameGeometry(mesh_, allFaceInfo_[i2], geomTol_))
{ {
@ -334,8 +335,7 @@ void Foam::FaceCellWave<Type>::mergeFaceInfo
const polyPatch& patch, const polyPatch& patch,
const label nFaces, const label nFaces,
const labelList& changedFaces, const labelList& changedFaces,
const List<Type>& changedFacesInfo, const List<Type>& changedFacesInfo
const bool
) )
{ {
for (label changedFaceI = 0; changedFaceI < nFaces; changedFaceI++) for (label changedFaceI = 0; changedFaceI < nFaces; changedFaceI++)
@ -599,8 +599,7 @@ void Foam::FaceCellWave<Type>::handleProcPatches()
patch, patch,
nReceiveFaces, nReceiveFaces,
receiveFaces, receiveFaces,
receiveFacesInfo, receiveFacesInfo
procPatch.parallel()
); );
} }
} }
@ -619,87 +618,42 @@ void Foam::FaceCellWave<Type>::handleCyclicPatches()
if (isA<cyclicPolyPatch>(patch)) if (isA<cyclicPolyPatch>(patch))
{ {
label halfSize = patch.size()/2; const cyclicPolyPatch& nbrPatch =
refCast<const cyclicPolyPatch>(patch).neighbPatch();
// Allocate buffers // Allocate buffers
label nSendFaces;
labelList sendFaces(halfSize);
List<Type> sendFacesInfo(halfSize);
label nReceiveFaces; label nReceiveFaces;
labelList receiveFaces(halfSize); labelList receiveFaces(patch.size());
List<Type> receiveFacesInfo(halfSize); List<Type> receiveFacesInfo(patch.size());
// Half1: Determine which faces changed. Use sendFaces for storage // Determine which faces changed
nSendFaces = getChangedPatchFaces
(
patch,
0,
halfSize,
sendFaces,
sendFacesInfo
);
// Half2: Determine which faces changed. Use receiveFaces_ ,,
nReceiveFaces = getChangedPatchFaces nReceiveFaces = getChangedPatchFaces
( (
patch, nbrPatch,
halfSize, 0,
halfSize, nbrPatch.size(),
receiveFaces, receiveFaces,
receiveFacesInfo receiveFacesInfo
); );
//Info<< "Half1:" << endl; // Adapt wallInfo for leaving domain
//writeFaces(nSendFaces, sendFaces, sendFacesInfo, Info);
//Info<< endl;
//
//Info<< "Half2:" << endl;
//writeFaces(nReceiveFaces, receiveFaces, receiveFacesInfo, Info);
//Info<< endl;
// Half1: Adapt wallInfo for leaving domain
leaveDomain leaveDomain
( (
patch, nbrPatch,
nSendFaces,
sendFaces,
sendFacesInfo
);
// Half2: Adapt wallInfo for leaving domain
leaveDomain
(
patch,
nReceiveFaces, nReceiveFaces,
receiveFaces, receiveFaces,
receiveFacesInfo receiveFacesInfo
); );
// Half1: 'transfer' to other side by offsetting patchFaceI
offset(patch, halfSize, nSendFaces, sendFaces);
// Half2: 'transfer' to other side
offset(patch, -halfSize, nReceiveFaces, receiveFaces);
// Apply rotation for non-parallel planes
const cyclicPolyPatch& cycPatch = const cyclicPolyPatch& cycPatch =
refCast<const cyclicPolyPatch>(patch); refCast<const cyclicPolyPatch>(patch);
if (!cycPatch.parallel()) if (!cycPatch.parallel())
{ {
// sendFaces = received data from half1 // received data from other half
transform transform
( (
cycPatch.forwardT(), cycPatch.forwardT(),
nSendFaces,
sendFacesInfo
);
// receiveFaces = received data from half2
transform
(
cycPatch.reverseT(),
nReceiveFaces, nReceiveFaces,
receiveFacesInfo receiveFacesInfo
); );
@ -707,25 +661,15 @@ void Foam::FaceCellWave<Type>::handleCyclicPatches()
if (debug) if (debug)
{ {
Pout<< " Cyclic patch " << patchI << ' ' << patch.name() Pout<< " Cyclic patch " << patchI << ' ' << cycPatch.name()
<< " Changed on first half : " << nSendFaces << " Changed : " << nReceiveFaces
<< " Changed on second half : " << nReceiveFaces
<< endl; << endl;
} }
// Half1: Adapt wallInfo for entering domain
enterDomain
(
patch,
nSendFaces,
sendFaces,
sendFacesInfo
);
// Half2: Adapt wallInfo for entering domain // Half2: Adapt wallInfo for entering domain
enterDomain enterDomain
( (
patch, cycPatch,
nReceiveFaces, nReceiveFaces,
receiveFaces, receiveFaces,
receiveFacesInfo receiveFacesInfo
@ -734,25 +678,15 @@ void Foam::FaceCellWave<Type>::handleCyclicPatches()
// Merge into global storage // Merge into global storage
mergeFaceInfo mergeFaceInfo
( (
patch, cycPatch,
nSendFaces,
sendFaces,
sendFacesInfo,
cycPatch.parallel()
);
// Merge into global storage
mergeFaceInfo
(
patch,
nReceiveFaces, nReceiveFaces,
receiveFaces, receiveFaces,
receiveFacesInfo, receiveFacesInfo
cycPatch.parallel()
); );
if (debug) if (debug)
{ {
checkCyclic(patch); checkCyclic(cycPatch);
} }
} }
} }

View File

@ -192,8 +192,7 @@ class FaceCellWave
const polyPatch& patch, const polyPatch& patch,
const label nFaces, const label nFaces,
const labelList&, const labelList&,
const List<Type>&, const List<Type>&
const bool isParallel
); );
//- Extract info for single patch only //- Extract info for single patch only

View File

@ -219,6 +219,30 @@ Foam::List<int> Foam::UPstream::procIDs_(1, 0);
// Standard transfer message type // Standard transfer message type
int Foam::UPstream::msgType_(1); int Foam::UPstream::msgType_(1);
// New message type
int Foam::UPstream::freeTag_(msgType()+1);
// Free'd message types
Foam::LIFOStack<int> Foam::UPstream::freedTags_;
int Foam::UPstream::allocateTag()
{
if (freedTags_.empty())
{
return freeTag_++;
}
else
{
return freedTags_.pop();
}
}
void Foam::UPstream::freeTag(const int tag)
{
freedTags_.push(tag);
}
// Linear communication schedule // Linear communication schedule
Foam::List<Foam::UPstream::commsStruct> Foam::UPstream::linearCommunication_(0); Foam::List<Foam::UPstream::commsStruct> Foam::UPstream::linearCommunication_(0);

View File

@ -45,6 +45,7 @@ SourceFiles
#include "HashTable.H" #include "HashTable.H"
#include "string.H" #include "string.H"
#include "NamedEnum.H" #include "NamedEnum.H"
#include "LIFOStack.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -190,6 +191,12 @@ private:
static List<commsStruct> treeCommunication_; static List<commsStruct> treeCommunication_;
//- Current free tag
static int freeTag_;
//- Freed tags
static LIFOStack<int> freedTags_;
// Private Member Functions // Private Member Functions
//- Set data for parallel running //- Set data for parallel running
@ -339,6 +346,11 @@ public:
{ {
return msgType_; return msgType_;
} }
//- Allocate new tag
static int allocateTag();
//- Release allocated tag
static void freeTag(const int tag);
//- Get the communications type of the stream //- Get the communications type of the stream

View File

@ -26,6 +26,7 @@ License
#include "emptyPolyPatch.H" #include "emptyPolyPatch.H"
#include "commSchedule.H" #include "commSchedule.H"
#include "globalMeshData.H" #include "globalMeshData.H"
#include "cyclicPolyPatch.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -251,6 +252,29 @@ GeometricBoundaryField
{ {
if (bmesh_[patchi].type() != emptyPolyPatch::typeName) if (bmesh_[patchi].type() != emptyPolyPatch::typeName)
{ {
if
(
bmesh_[patchi].type() == cyclicPolyPatch::typeName
&& !dict.found(bmesh_[patchi].name())
)
{
FatalIOErrorIn
(
"GeometricField<Type, PatchField, GeoMesh>::\n"
"GeometricBoundaryField::GeometricBoundaryField\n"
"(\n"
" const BoundaryMesh&,\n"
" const DimensionedField<Type, GeoMesh>&,\n"
" const dictionary&\n"
")",
dict
) << "Cannot find patchField entry for cyclic "
<< bmesh_[patchi].name() << endl
<< "Is your field uptodate with split cyclics?" << endl
<< "Run foamUpgradeCyclics to convert mesh and fields"
<< " to split cyclics." << exit(FatalIOError);
}
set set
( (
patchi, patchi,
@ -322,7 +346,11 @@ evaluate()
} }
// Block for any outstanding requests // Block for any outstanding requests
if (Pstream::defaultCommsType == Pstream::nonBlocking) if
(
Pstream::parRun()
&& Pstream::defaultCommsType == Pstream::nonBlocking
)
{ {
Pstream::waitRequests(); Pstream::waitRequests();
} }

View File

@ -25,6 +25,8 @@ License
#include "cyclicPointPatchField.H" #include "cyclicPointPatchField.H"
#include "Swap.H" #include "Swap.H"
#include "transformField.H"
#include "pointFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -127,28 +129,57 @@ void cyclicPointPatchField<Type>::swapAddSeparated
Field<Type>& pField Field<Type>& pField
) const ) const
{ {
Field<Type> pf(this->patchInternalField(pField)); // Get neighbouring pointPatch
const cyclicPointPatch& nbrPatch = cyclicPatch_.neighbPatch();
const edgeList& pairs = cyclicPatch_.transformPairs(); if (cyclicPatch_.cyclicPatch().owner())
if (doTransform())
{ {
forAll(pairs, pairi) // We inplace modify pField. To prevent the other side (which gets
{ // evaluated at a later date) using already changed values we do
Type tmp = pf[pairs[pairi][0]]; // all swaps on the side that gets evaluated first.
pf[pairs[pairi][0]] = transform(forwardT()[0], pf[pairs[pairi][1]]);
pf[pairs[pairi][1]] = transform(reverseT()[0], tmp);
}
}
else
{
forAll(pairs, pairi)
{
Swap(pf[pairs[pairi][0]], pf[pairs[pairi][1]]);
}
}
addToInternalField(pField, pf, cyclicPatch_.separatedPoints()); // Get neighbouring pointPatchField
const GeometricField<Type, pointPatchField, pointMesh>& fld =
refCast<const GeometricField<Type, pointPatchField, pointMesh> >
(
this->dimensionedInternalField()
);
const cyclicPointPatchField<Type>& nbr =
refCast<const cyclicPointPatchField<Type> >
(
fld.boundaryField()[nbrPatch.index()]
);
Field<Type> pf(this->patchInternalField(pField));
Field<Type> nbrPf(nbr.patchInternalField(pField));
const edgeList& pairs = cyclicPatch_.transformPairs();
if (doTransform())
{
// Transform both sides.
forAll(pairs, pairi)
{
label pointi = pairs[pairi][0];
label nbrPointi = pairs[pairi][1];
Type tmp = pf[pointi];
pf[pointi] = transform(forwardT()[0], nbrPf[nbrPointi]);
nbrPf[nbrPointi] = transform(reverseT()[0], tmp);
}
}
else
{
forAll(pairs, pairi)
{
Swap(pf[pairs[pairi][0]], nbrPf[pairs[pairi][1]]);
}
}
addToInternalField(pField, pf);
nbr.addToInternalField(pField, nbrPf);
}
} }

View File

@ -24,7 +24,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "processorPointPatchField.H" #include "processorPointPatchField.H"
#include "transformField.H" //#include "transformField.H"
#include "processorPolyPatch.H" #include "processorPolyPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -102,26 +102,27 @@ void processorPointPatchField<Type>::initSwapAddSeparated
) )
const const
{ {
if (Pstream::parRun()) // if (Pstream::parRun())
{ // {
// Get internal field into correct order for opposite side // // Get internal field into correct order for opposite side
Field<Type> pf // Field<Type> pf
( // (
this->patchInternalField // this->patchInternalField
( // (
pField, // pField,
procPatch_.reverseMeshPoints() // procPatch_.reverseMeshPoints()
) // )
); // );
//
OPstream::write // OPstream::write
( // (
commsType, // commsType,
procPatch_.neighbProcNo(), // procPatch_.neighbProcNo(),
reinterpret_cast<const char*>(pf.begin()), // reinterpret_cast<const char*>(pf.begin()),
pf.byteSize() // pf.byteSize(),
); // procPatch_.tag()
} // );
// }
} }
@ -132,44 +133,29 @@ void processorPointPatchField<Type>::swapAddSeparated
Field<Type>& pField Field<Type>& pField
) const ) const
{ {
if (Pstream::parRun()) // if (Pstream::parRun())
{ // {
Field<Type> pnf(this->size()); // Field<Type> pnf(this->size());
//
IPstream::read // IPstream::read
( // (
commsType, // commsType,
procPatch_.neighbProcNo(), // procPatch_.neighbProcNo(),
reinterpret_cast<char*>(pnf.begin()), // reinterpret_cast<char*>(pnf.begin()),
pnf.byteSize() // pnf.byteSize(),
); // procPatch_.tag()
// );
if (doTransform()) //
{ // if (doTransform())
const processorPolyPatch& ppp = procPatch_.procPolyPatch(); // {
const tensorField& forwardT = ppp.forwardT(); // const processorPolyPatch& ppp = procPatch_.procPolyPatch();
// const tensor& forwardT = ppp.forwardT();
if (forwardT.size() == 1) //
{ // transform(pnf, forwardT, pnf);
transform(pnf, forwardT[0], pnf); // }
} //
else // addToInternalField(pField, pnf, procPatch_.separatedPoints());
{ // }
const labelListList& pointFaces = ppp.pointFaces();
forAll(pointFaces, pfi)
{
pnf[pfi] = transform
(
forwardT[pointFaces[pfi][0]],
pnf[pfi]
);
}
}
}
addToInternalField(pField, pnf, procPatch_.separatedPoints());
}
} }

View File

@ -147,7 +147,7 @@ public:
} }
} }
//- Does the patch field perform the transfromation //- Does the patch field perform the transformation
virtual bool doTransform() const virtual bool doTransform() const
{ {
return return

View File

@ -0,0 +1,168 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "processorCyclicPointPatchField.H"
#include "transformField.H"
#include "processorPolyPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
processorCyclicPointPatchField<Type>::processorCyclicPointPatchField
(
const pointPatch& p,
const DimensionedField<Type, pointMesh>& iF
)
:
coupledPointPatchField<Type>(p, iF),
procPatch_(refCast<const processorCyclicPointPatch>(p))
{}
template<class Type>
processorCyclicPointPatchField<Type>::processorCyclicPointPatchField
(
const pointPatch& p,
const DimensionedField<Type, pointMesh>& iF,
const dictionary& dict
)
:
coupledPointPatchField<Type>(p, iF, dict),
procPatch_(refCast<const processorCyclicPointPatch>(p))
{}
template<class Type>
processorCyclicPointPatchField<Type>::processorCyclicPointPatchField
(
const processorCyclicPointPatchField<Type>& ptf,
const pointPatch& p,
const DimensionedField<Type, pointMesh>& iF,
const pointPatchFieldMapper& mapper
)
:
coupledPointPatchField<Type>(ptf, p, iF, mapper),
procPatch_(refCast<const processorCyclicPointPatch>(ptf.patch()))
{}
template<class Type>
processorCyclicPointPatchField<Type>::processorCyclicPointPatchField
(
const processorCyclicPointPatchField<Type>& ptf,
const DimensionedField<Type, pointMesh>& iF
)
:
coupledPointPatchField<Type>(ptf, iF),
procPatch_(refCast<const processorCyclicPointPatch>(ptf.patch()))
{}
// * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * //
template<class Type>
processorCyclicPointPatchField<Type>::~processorCyclicPointPatchField()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void processorCyclicPointPatchField<Type>::initSwapAddSeparated
(
const Pstream::commsTypes commsType,
Field<Type>& pField
) const
{
if (Pstream::parRun())
{
// Get internal field into correct order for opposite side
Field<Type> pf
(
this->patchInternalField
(
pField,
procPatch_.reverseMeshPoints()
)
);
OPstream::write
(
commsType,
procPatch_.neighbProcNo(),
reinterpret_cast<const char*>(pf.begin()),
pf.byteSize(),
procPatch_.tag()
);
}
}
template<class Type>
void processorCyclicPointPatchField<Type>::swapAddSeparated
(
const Pstream::commsTypes commsType,
Field<Type>& pField
) const
{
if (Pstream::parRun())
{
Field<Type> pnf(this->size());
IPstream::read
(
commsType,
procPatch_.neighbProcNo(),
reinterpret_cast<char*>(pnf.begin()),
pnf.byteSize(),
procPatch_.tag()
);
if (doTransform())
{
const processorCyclicPolyPatch& ppp =
procPatch_.procCyclicPolyPatch();
const tensor& forwardT = ppp.forwardT()[0];
transform(pnf, forwardT, pnf);
}
// All points are separated
addToInternalField(pField, pnf);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,202 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::processorCyclicPointPatchField
Description
Foam::processorCyclicPointPatchField
SourceFiles
processorCyclicPointPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef processorCyclicPointPatchField_H
#define processorCyclicPointPatchField_H
#include "coupledPointPatchField.H"
#include "processorCyclicPointPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class processorCyclicPointPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class processorCyclicPointPatchField
:
public coupledPointPatchField<Type>
{
// Private data
//- Local reference to processor patch
const processorCyclicPointPatch& procPatch_;
public:
//- Runtime type information
TypeName(processorCyclicPointPatch::typeName_());
// Constructors
//- Construct from patch and internal field
processorCyclicPointPatchField
(
const pointPatch&,
const DimensionedField<Type, pointMesh>&
);
//- Construct from patch, internal field and dictionary
processorCyclicPointPatchField
(
const pointPatch&,
const DimensionedField<Type, pointMesh>&,
const dictionary&
);
//- Construct by mapping given patchField<Type> onto a new patch
processorCyclicPointPatchField
(
const processorCyclicPointPatchField<Type>&,
const pointPatch&,
const DimensionedField<Type, pointMesh>&,
const pointPatchFieldMapper&
);
//- Construct and return a clone
virtual autoPtr<pointPatchField<Type> > clone() const
{
return autoPtr<pointPatchField<Type> >
(
new processorCyclicPointPatchField<Type>
(
*this
)
);
}
//- Construct as copy setting internal field reference
processorCyclicPointPatchField
(
const processorCyclicPointPatchField<Type>&,
const DimensionedField<Type, pointMesh>&
);
//- Construct and return a clone setting internal field reference
virtual autoPtr<pointPatchField<Type> > clone
(
const DimensionedField<Type, pointMesh>& iF
) const
{
return autoPtr<pointPatchField<Type> >
(
new processorCyclicPointPatchField<Type>
(
*this,
iF
)
);
}
// Destructor
~processorCyclicPointPatchField();
// Member functions
// Access
//- Return true if running parallel
virtual bool coupled() const
{
if (Pstream::parRun())
{
return true;
}
else
{
return false;
}
}
//- Does the patch field perform the transfromation
virtual bool doTransform() const
{
return
!(
pTraits<Type>::rank == 0
|| procPatch_.procPolyPatch().parallel()
);
}
// Evaluation functions
//- Evaluate the patch field
virtual void evaluate
(
const Pstream::commsTypes commsType=Pstream::blocking
)
{}
//- Initialise swap of non-collocated patch point values
virtual void initSwapAddSeparated
(
const Pstream::commsTypes commsType,
Field<Type>&
) const;
//- Complete swap of patch point values and add to local values
virtual void swapAddSeparated
(
const Pstream::commsTypes commsType,
Field<Type>&
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "processorCyclicPointPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,44 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "processorCyclicPointPatchFields.H"
#include "pointPatchFields.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makePointPatchFields(processorCyclic);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,50 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#ifndef processorCyclicPointPatchFields_H
#define processorCyclicPointPatchFields_H
#include "processorCyclicPointPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePointPatchFieldTypedefs(processorCyclic);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -141,15 +141,7 @@ tmp<Field<Type1> > pointPatchField<Type>::patchInternalField
<< abort(FatalError); << abort(FatalError);
} }
tmp<Field<Type1> > tvalues(new Field<Type1>(meshPoints.size())); return tmp<Field<Type1> >(new Field<Type1>(iF, meshPoints));
Field<Type1>& values = tvalues();
forAll(meshPoints, pointI)
{
values[pointI] = iF[meshPoints[pointI]];
}
return tvalues;
} }

View File

@ -32,8 +32,7 @@ Description
#ifndef parRun_H #ifndef parRun_H
#define parRun_H #define parRun_H
#include "OPstream.H" #include "Pstream.H"
#include "IPstream.H"
#include "IOstreams.H" #include "IOstreams.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -27,6 +27,7 @@ License
#include "lduMatrix.H" #include "lduMatrix.H"
#include "procLduMatrix.H" #include "procLduMatrix.H"
#include "procLduInterface.H" #include "procLduInterface.H"
#include "cyclicLduInterface.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -160,19 +161,27 @@ void Foam::LUscalarMatrix::convert
{ {
const lduInterface& interface = interfaces[inti].interface(); const lduInterface& interface = interfaces[inti].interface();
const label* __restrict__ ulPtr = interface.faceCells().begin(); // Assume any interfaces are cyclic ones
const scalar* __restrict__ upperLowerPtr =
interfaceCoeffs[inti].begin();
register label inFaces = interface.faceCells().size()/2; const label* __restrict__ lPtr = interface.faceCells().begin();
const cyclicLduInterface& cycInterface =
refCast<const cyclicLduInterface>(interface);
label nbrInt = cycInterface.neighbPatchID();
const label* __restrict__ uPtr =
interfaces[nbrInt].interface().faceCells().begin();
const scalar* __restrict__ nbrUpperLowerPtr =
interfaceCoeffs[nbrInt].begin();
register label inFaces = interface.faceCells().size();
for (register label face=0; face<inFaces; face++) for (register label face=0; face<inFaces; face++)
{ {
label uCell = ulPtr[face]; label uCell = lPtr[face];
label lCell = ulPtr[face + inFaces]; label lCell = uPtr[face];
operator[](uCell)[lCell] -= upperLowerPtr[face + inFaces]; operator[](uCell)[lCell] -= nbrUpperLowerPtr[face];
operator[](lCell)[uCell] -= upperLowerPtr[face];
} }
} }
} }

View File

@ -65,6 +65,14 @@ public:
// Access // Access
//- Return neighbour
virtual label neighbPatchID() const = 0;
virtual bool owner() const = 0;
//- Return processor number
virtual const cyclicLduInterface& neighbPatch() const = 0;
//- Return face transformation tensor //- Return face transformation tensor
virtual const tensorField& forwardT() const = 0; virtual const tensorField& forwardT() const = 0;

View File

@ -96,21 +96,6 @@ public:
const unallocLabelList& internalData const unallocLabelList& internalData
) const = 0; ) const = 0;
//- Initialise interface data transfer
virtual void initTransfer
(
const Pstream::commsTypes commsType,
const unallocLabelList& interfaceData
) const
{}
//- Transfer and return neighbour field
virtual tmp<labelField> transfer
(
const Pstream::commsTypes commsType,
const unallocLabelList& interfaceData
) const = 0;
//- Initialise transfer of internal field adjacent to the interface //- Initialise transfer of internal field adjacent to the interface
virtual void initInternalFieldTransfer virtual void initInternalFieldTransfer
( (

View File

@ -93,6 +93,8 @@ public:
//- Return face transformation tensor //- Return face transformation tensor
virtual const tensorField& forwardT() const = 0; virtual const tensorField& forwardT() const = 0;
//- Return message tag used for sending
virtual int tag() const = 0;
// Transfer functions // Transfer functions

View File

@ -43,7 +43,8 @@ void Foam::processorLduInterface::send
commsType, commsType,
neighbProcNo(), neighbProcNo(),
reinterpret_cast<const char*>(f.begin()), reinterpret_cast<const char*>(f.begin()),
f.byteSize() f.byteSize(),
tag()
); );
} }
else if (commsType == Pstream::nonBlocking) else if (commsType == Pstream::nonBlocking)
@ -55,7 +56,8 @@ void Foam::processorLduInterface::send
commsType, commsType,
neighbProcNo(), neighbProcNo(),
receiveBuf_.begin(), receiveBuf_.begin(),
receiveBuf_.size() receiveBuf_.size(),
tag()
); );
resizeBuf(sendBuf_, f.byteSize()); resizeBuf(sendBuf_, f.byteSize());
@ -66,7 +68,8 @@ void Foam::processorLduInterface::send
commsType, commsType,
neighbProcNo(), neighbProcNo(),
sendBuf_.begin(), sendBuf_.begin(),
f.byteSize() f.byteSize(),
tag()
); );
} }
else else
@ -92,7 +95,8 @@ void Foam::processorLduInterface::receive
commsType, commsType,
neighbProcNo(), neighbProcNo(),
reinterpret_cast<char*>(f.begin()), reinterpret_cast<char*>(f.begin()),
f.byteSize() f.byteSize(),
tag()
); );
} }
else if (commsType == Pstream::nonBlocking) else if (commsType == Pstream::nonBlocking)
@ -155,7 +159,8 @@ void Foam::processorLduInterface::compressedSend
commsType, commsType,
neighbProcNo(), neighbProcNo(),
sendBuf_.begin(), sendBuf_.begin(),
nBytes nBytes,
tag()
); );
} }
else if (commsType == Pstream::nonBlocking) else if (commsType == Pstream::nonBlocking)
@ -167,7 +172,8 @@ void Foam::processorLduInterface::compressedSend
commsType, commsType,
neighbProcNo(), neighbProcNo(),
receiveBuf_.begin(), receiveBuf_.begin(),
receiveBuf_.size() receiveBuf_.size(),
tag()
); );
OPstream::write OPstream::write
@ -175,7 +181,8 @@ void Foam::processorLduInterface::compressedSend
commsType, commsType,
neighbProcNo(), neighbProcNo(),
sendBuf_.begin(), sendBuf_.begin(),
nBytes nBytes,
tag()
); );
} }
else else
@ -215,7 +222,8 @@ void Foam::processorLduInterface::compressedReceive
commsType, commsType,
neighbProcNo(), neighbProcNo(),
receiveBuf_.begin(), receiveBuf_.begin(),
nBytes nBytes,
tag()
); );
} }
else if (commsType != Pstream::nonBlocking) else if (commsType != Pstream::nonBlocking)

View File

@ -47,19 +47,10 @@ void Foam::cyclicLduInterfaceField::transformCoupleField
{ {
if (doTransform()) if (doTransform())
{ {
label sizeby2 = pnf.size()/2;
scalar forwardScale = scalar forwardScale =
pow(diag(forwardT()[0]).component(cmpt), rank()); pow(diag(forwardT()[0]).component(cmpt), rank());
scalar reverseScale = pnf *= forwardScale;
pow(diag(reverseT()[0]).component(cmpt), rank());
for (label facei=0; facei<sizeby2; facei++)
{
pnf[facei] *= forwardScale;
pnf[facei + sizeby2] *= reverseScale;
}
} }
} }

View File

@ -111,10 +111,13 @@ void Foam::lduMatrix::updateMatrixInterfaces
) )
{ {
// Block until all sends/receives have been finished // Block until all sends/receives have been finished
if (Pstream::defaultCommsType == Pstream::nonBlocking) if
(
Pstream::parRun()
&& Pstream::defaultCommsType == Pstream::nonBlocking
)
{ {
IPstream::waitRequests(); UPstream::waitRequests();
OPstream::waitRequests();
} }
forAll(interfaces, interfaceI) forAll(interfaces, interfaceI)

View File

@ -229,12 +229,17 @@ void Foam::GAMGAgglomeration::agglomerateLduAddressing
{ {
fineInterfaces[inti].initInternalFieldTransfer fineInterfaces[inti].initInternalFieldTransfer
( (
Pstream::blocking, Pstream::nonBlocking,
restrictMap restrictMap
); );
} }
} }
if (Pstream::parRun())
{
Pstream::waitRequests();
}
// Add the coarse level // Add the coarse level
forAll(fineInterfaces, inti) forAll(fineInterfaces, inti)
{ {
@ -245,11 +250,13 @@ void Foam::GAMGAgglomeration::agglomerateLduAddressing
inti, inti,
GAMGInterface::New GAMGInterface::New
( (
inti,
coarseInterfaces,
fineInterfaces[inti], fineInterfaces[inti],
fineInterfaces[inti].interfaceInternalField(restrictMap), fineInterfaces[inti].interfaceInternalField(restrictMap),
fineInterfaces[inti].internalFieldTransfer fineInterfaces[inti].internalFieldTransfer
( (
Pstream::blocking, Pstream::nonBlocking,
restrictMap restrictMap
) )
).ptr() ).ptr()

View File

@ -80,20 +80,16 @@ void Foam::cyclicGAMGInterfaceField::updateInterfaceMatrix
const Pstream::commsTypes const Pstream::commsTypes
) const ) const
{ {
scalarField pnf(size()); // Get neighbouring field
scalarField pnf
label sizeby2 = size()/2; (
cyclicInterface_.neighbPatch().interfaceInternalField(psiInternal)
const unallocLabelList& faceCells = cyclicInterface_.faceCells(); );
for (label facei=0; facei<sizeby2; facei++)
{
pnf[facei] = psiInternal[faceCells[facei + sizeby2]];
pnf[facei + sizeby2] = psiInternal[faceCells[facei]];
}
transformCoupleField(pnf, cmpt); transformCoupleField(pnf, cmpt);
const unallocLabelList& faceCells = cyclicInterface_.faceCells();
forAll(faceCells, elemI) forAll(faceCells, elemI)
{ {
result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI]; result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];

View File

@ -0,0 +1,108 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "processorCyclicGAMGInterfaceField.H"
#include "addToRunTimeSelectionTable.H"
#include "lduMatrix.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(processorCyclicGAMGInterfaceField, 0);
addToRunTimeSelectionTable
(
GAMGInterfaceField,
processorCyclicGAMGInterfaceField,
lduInterface
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::processorCyclicGAMGInterfaceField::processorCyclicGAMGInterfaceField
(
const GAMGInterface& GAMGCp,
const lduInterfaceField& fineInterface
)
:
processorGAMGInterfaceField(GAMGCp, fineInterface)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::processorCyclicGAMGInterfaceField::~processorCyclicGAMGInterfaceField()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
//void Foam::processorCyclicGAMGInterfaceField::initInterfaceMatrixUpdate
//(
// const scalarField& psiInternal,
// scalarField&,
// const lduMatrix&,
// const scalarField&,
// const direction,
// const Pstream::commsTypes commsType
//) const
//{
// procInterface_.compressedSend
// (
// commsType,
// procInterface_.interfaceInternalField(psiInternal)()
// );
//}
//
//
//void Foam::processorCyclicGAMGInterfaceField::updateInterfaceMatrix
//(
// const scalarField&,
// scalarField& result,
// const lduMatrix&,
// const scalarField& coeffs,
// const direction cmpt,
// const Pstream::commsTypes commsType
//) const
//{
// scalarField pnf
// (
// procInterface_.compressedReceive<scalar>(commsType, coeffs.size())
// );
// transformCoupleField(pnf, cmpt);
//
// const unallocLabelList& faceCells = procInterface_.faceCells();
//
// forAll(faceCells, elemI)
// {
// result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
// }
//}
// ************************************************************************* //

View File

@ -0,0 +1,174 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::processorCyclicGAMGInterfaceField
Description
GAMG agglomerated processor interface field.
SourceFiles
processorCyclicGAMGInterfaceField.C
\*---------------------------------------------------------------------------*/
#ifndef processorCyclicGAMGInterfaceField_H
#define processorCyclicGAMGInterfaceField_H
#include "processorGAMGInterfaceField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class processorCyclicGAMGInterfaceField Declaration
\*---------------------------------------------------------------------------*/
class processorCyclicGAMGInterfaceField
:
public processorGAMGInterfaceField
{
// Private data
// //- Local reference cast into the processor interface
// const processorCyclicGAMGInterface& procInterface_;
//
// //- Is the transform required
// bool doTransform_;
//
// //- Rank of component for transformation
// int rank_;
//
// Private Member Functions
//- Disallow default bitwise copy construct
processorCyclicGAMGInterfaceField(const processorCyclicGAMGInterfaceField&);
//- Disallow default bitwise assignment
void operator=(const processorCyclicGAMGInterfaceField&);
public:
//- Runtime type information
TypeName("processorCyclic");
// Constructors
//- Construct from GAMG interface and fine level interface field
processorCyclicGAMGInterfaceField
(
const GAMGInterface& GAMGCp,
const lduInterfaceField& fineInterface
);
// Destructor
virtual ~processorCyclicGAMGInterfaceField();
// Member Functions
// // Access
//
// //- Return size
// label size() const
// {
// return procInterface_.size();
// }
//
//
// // Interface matrix update
//
// //- Initialise neighbour matrix update
// virtual void initInterfaceMatrixUpdate
// (
// const scalarField& psiInternal,
// scalarField& result,
// const lduMatrix& m,
// const scalarField& coeffs,
// const direction cmpt,
// const Pstream::commsTypes commsType
// ) const;
//
// //- Update result field based on interface functionality
// virtual void updateInterfaceMatrix
// (
// const scalarField& psiInternal,
// scalarField& result,
// const lduMatrix&,
// const scalarField& coeffs,
// const direction cmpt,
// const Pstream::commsTypes commsType
// ) const;
//
//
// //- Processor interface functions
//
// //- Return processor number
// virtual int myProcNo() const
// {
// return procInterface_.myProcNo();
// }
//
// //- Return neigbour processor number
// virtual int neighbProcNo() const
// {
// return procInterface_.neighbProcNo();
// }
//
// //- Does the interface field perform the transfromation
// virtual bool doTransform() const
// {
// return doTransform_;
// }
//
// //- Return face transformation tensor
// virtual const tensorField& forwardT() const
// {
// return procInterface_.forwardT();
// }
//
// //- Return rank of component for transform
// virtual int rank() const
// {
// return rank_;
// }
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -36,8 +36,8 @@ SourceFiles
#ifndef GAMGInterface_H #ifndef GAMGInterface_H
#define GAMGInterface_H #define GAMGInterface_H
#include "lduInterface.H"
#include "autoPtr.H" #include "autoPtr.H"
#include "lduInterfacePtrsList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -57,6 +57,12 @@ protected:
// Protected data // Protected data
//- My index in coarseInterfaces
const label index_;
//- All interfaces
const lduInterfacePtrsList& coarseInterfaces_;
//- Face-cell addressing //- Face-cell addressing
labelField faceCells_; labelField faceCells_;
@ -89,11 +95,15 @@ public:
GAMGInterface, GAMGInterface,
lduInterface, lduInterface,
( (
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface, const lduInterface& fineInterface,
const labelField& localRestrictAddressing, const labelField& localRestrictAddressing,
const labelField& neighbourRestrictAddressing const labelField& neighbourRestrictAddressing
), ),
( (
index,
coarseInterfaces,
fineInterface, fineInterface,
localRestrictAddressing, localRestrictAddressing,
neighbourRestrictAddressing neighbourRestrictAddressing
@ -107,6 +117,8 @@ public:
// the fine interface // the fine interface
static autoPtr<GAMGInterface> New static autoPtr<GAMGInterface> New
( (
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface, const lduInterface& fineInterface,
const labelField& localRestrictAddressing, const labelField& localRestrictAddressing,
const labelField& neighbourRestrictAddressing const labelField& neighbourRestrictAddressing
@ -119,10 +131,15 @@ public:
// local and neighbour restrict addressing // local and neighbour restrict addressing
GAMGInterface GAMGInterface
( (
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface&, const lduInterface&,
const labelField&, const labelField&,
const labelField& const labelField&
) )
:
index_(index),
coarseInterfaces_(coarseInterfaces)
{} {}
@ -136,6 +153,16 @@ public:
return faceCells_.size(); return faceCells_.size();
} }
virtual label index() const
{
return index_;
}
virtual const lduInterfacePtrsList& coarseInterfaces() const
{
return coarseInterfaces_;
}
//- Return faceCell addressing //- Return faceCell addressing
virtual const unallocLabelList& faceCells() const virtual const unallocLabelList& faceCells() const
{ {

View File

@ -31,6 +31,8 @@ License
Foam::autoPtr<Foam::GAMGInterface> Foam::GAMGInterface::New Foam::autoPtr<Foam::GAMGInterface> Foam::GAMGInterface::New
( (
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface, const lduInterface& fineInterface,
const labelField& localRestrictAddressing, const labelField& localRestrictAddressing,
const labelField& neighbourRestrictAddressing const labelField& neighbourRestrictAddressing
@ -59,6 +61,8 @@ Foam::autoPtr<Foam::GAMGInterface> Foam::GAMGInterface::New
( (
cstrIter() cstrIter()
( (
index,
coarseInterfaces,
fineInterface, fineInterface,
localRestrictAddressing, localRestrictAddressing,
neighbourRestrictAddressing neighbourRestrictAddressing

View File

@ -25,6 +25,7 @@ License
#include "cyclicGAMGInterface.H" #include "cyclicGAMGInterface.H"
#include "addToRunTimeSelectionTable.H" #include "addToRunTimeSelectionTable.H"
#include "Map.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -44,6 +45,8 @@ namespace Foam
Foam::cyclicGAMGInterface::cyclicGAMGInterface Foam::cyclicGAMGInterface::cyclicGAMGInterface
( (
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface, const lduInterface& fineInterface,
const labelField& localRestrictAddressing, const labelField& localRestrictAddressing,
const labelField& neighbourRestrictAddressing const labelField& neighbourRestrictAddressing
@ -51,6 +54,8 @@ Foam::cyclicGAMGInterface::cyclicGAMGInterface
: :
GAMGInterface GAMGInterface
( (
index,
coarseInterfaces,
fineInterface, fineInterface,
localRestrictAddressing, localRestrictAddressing,
neighbourRestrictAddressing neighbourRestrictAddressing
@ -58,33 +63,45 @@ Foam::cyclicGAMGInterface::cyclicGAMGInterface
fineCyclicInterface_(refCast<const cyclicLduInterface>(fineInterface)) fineCyclicInterface_(refCast<const cyclicLduInterface>(fineInterface))
{ {
// Make a lookup table of entries for owner/neighbour // Make a lookup table of entries for owner/neighbour
HashTable<SLList<label>, label, Hash<label> > neighboursTable Map<SLList<label> > neighboursTable
( (
localRestrictAddressing.size() localRestrictAddressing.size()
); );
// Table of face-sets to be agglomerated // Table of face-sets to be agglomerated
HashTable<SLList<SLList<label> >, label, Hash<label> > faceFaceTable Map<SLList<SLList<label> > > faceFaceTable
( (
localRestrictAddressing.size() localRestrictAddressing.size()
); );
label nCoarseFaces = 0; label nCoarseFaces = 0;
label sizeBy2 = localRestrictAddressing.size()/2; forAll (localRestrictAddressing, ffi)
for (label ffi=0; ffi<sizeBy2; ffi++)
{ {
label curMaster = localRestrictAddressing[ffi]; label curMaster = -1;
label curSlave = localRestrictAddressing[ffi + sizeBy2]; label curSlave = -1;
// Do switching on master/slave indexes based on the owner/neighbour of
// the processor index such that both sides get the same answer.
if (owner())
{
// Master side
curMaster = localRestrictAddressing[ffi];
curSlave = neighbourRestrictAddressing[ffi];
}
else
{
// Slave side
curMaster = neighbourRestrictAddressing[ffi];
curSlave = localRestrictAddressing[ffi];
}
// Look for the master cell. If it has already got a face, // Look for the master cell. If it has already got a face,
// add the coefficient to the face. If not, create a new // add the coefficient to the face. If not, create a new face.
// face.
if (neighboursTable.found(curMaster)) if (neighboursTable.found(curMaster))
{ {
// Check all current neighbours to see if the current // Check all current neighbours to see if the current slave already
// slave already exists. If so, add the coefficient. // exists and if so, add the fine face to the agglomeration.
SLList<label>& curNbrs = neighboursTable.find(curMaster)(); SLList<label>& curNbrs = neighboursTable.find(curMaster)();
@ -135,69 +152,86 @@ Foam::cyclicGAMGInterface::cyclicGAMGInterface
} // end for all fine faces } // end for all fine faces
faceCells_.setSize(2*nCoarseFaces, -1);
faceRestrictAddressing_.setSize(localRestrictAddressing.size(), -1); faceCells_.setSize(nCoarseFaces, -1);
faceRestrictAddressing_.setSize(localRestrictAddressing.size());
labelList contents = neighboursTable.toc(); labelList contents = neighboursTable.toc();
// Reset face counter for re-use // Reset face counter for re-use
nCoarseFaces = 0; nCoarseFaces = 0;
// On master side, the owner addressing is stored in table of contents if (owner())
forAll(contents, masterI)
{ {
SLList<label>& curNbrs = neighboursTable.find(contents[masterI])(); // On master side, the owner addressing is stored in table of contents
forAll (contents, masterI)
SLList<SLList<label> >& curFaceFaces =
faceFaceTable.find(contents[masterI])();
SLList<label>::iterator nbrsIter = curNbrs.begin();
SLList<SLList<label> >::iterator faceFacesIter = curFaceFaces.begin();
for
(
;
nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
++nbrsIter, ++faceFacesIter
)
{ {
faceCells_[nCoarseFaces] = contents[masterI]; SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
forAllConstIter(SLList<label>, faceFacesIter(), facesIter) SLList<SLList<label> >& curFaceFaces =
faceFaceTable.find(contents[masterI])();
SLList<label>::iterator nbrsIter = curNbrs.begin();
SLList<SLList<label> >::iterator faceFacesIter = curFaceFaces.begin();
for
(
;
nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
++nbrsIter, ++faceFacesIter
)
{ {
faceRestrictAddressing_[facesIter()] = nCoarseFaces; faceCells_[nCoarseFaces] = contents[masterI];
}
nCoarseFaces++; for
(
SLList<label>::iterator facesIter = faceFacesIter().begin();
facesIter != faceFacesIter().end();
++facesIter
)
{
faceRestrictAddressing_[facesIter()] = nCoarseFaces;
}
nCoarseFaces++;
}
} }
} }
else
// On slave side, the owner addressing is stored in linked lists
forAll(contents, masterI)
{ {
SLList<label>& curNbrs = neighboursTable.find(contents[masterI])(); // On slave side, the owner addressing is stored in linked lists
forAll (contents, masterI)
SLList<SLList<label> >& curFaceFaces =
faceFaceTable.find(contents[masterI])();
SLList<label>::iterator nbrsIter = curNbrs.begin();
SLList<SLList<label> >::iterator faceFacesIter = curFaceFaces.begin();
for
(
;
nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
++nbrsIter, ++faceFacesIter
)
{ {
faceCells_[nCoarseFaces] = nbrsIter(); SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
forAllConstIter(SLList<label>, faceFacesIter(), facesIter) SLList<SLList<label> >& curFaceFaces =
faceFaceTable.find(contents[masterI])();
SLList<label>::iterator nbrsIter = curNbrs.begin();
SLList<SLList<label> >::iterator faceFacesIter = curFaceFaces.begin();
for
(
;
nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
++nbrsIter, ++faceFacesIter
)
{ {
faceRestrictAddressing_[facesIter() + sizeBy2] = nCoarseFaces; faceCells_[nCoarseFaces] = nbrsIter();
}
nCoarseFaces++; for
(
SLList<label>::iterator facesIter = faceFacesIter().begin();
facesIter != faceFacesIter().end();
++facesIter
)
{
faceRestrictAddressing_[facesIter()] = nCoarseFaces;
}
nCoarseFaces++;
}
} }
} }
} }
@ -211,42 +245,24 @@ Foam::cyclicGAMGInterface::~cyclicGAMGInterface()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::labelField> Foam::cyclicGAMGInterface::transfer
(
const Pstream::commsTypes,
const unallocLabelList& interfaceData
) const
{
tmp<labelField> tpnf(new labelField(size()));
labelField& pnf = tpnf();
label sizeby2 = size()/2;
for (label facei=0; facei<sizeby2; facei++)
{
pnf[facei] = interfaceData[facei + sizeby2];
pnf[facei + sizeby2] = interfaceData[facei];
}
return tpnf;
}
Foam::tmp<Foam::labelField> Foam::cyclicGAMGInterface::internalFieldTransfer Foam::tmp<Foam::labelField> Foam::cyclicGAMGInterface::internalFieldTransfer
( (
const Pstream::commsTypes, const Pstream::commsTypes,
const unallocLabelList& iF const unallocLabelList& iF
) const ) const
{ {
const cyclicGAMGInterface& nbr = dynamic_cast<const cyclicGAMGInterface&>
(
neighbPatch()
);
const unallocLabelList& nbrFaceCells = nbr.faceCells();
tmp<labelField> tpnf(new labelField(size())); tmp<labelField> tpnf(new labelField(size()));
labelField& pnf = tpnf(); labelField& pnf = tpnf();
label sizeby2 = size()/2; forAll(pnf, facei)
for (label facei=0; facei<sizeby2; facei++)
{ {
pnf[facei] = iF[faceCells_[facei + sizeby2]]; pnf[facei] = iF[nbrFaceCells[facei]];
pnf[facei + sizeby2] = iF[faceCells_[facei]];
} }
return tpnf; return tpnf;

View File

@ -80,6 +80,8 @@ public:
// local and neighbour restrict addressing // local and neighbour restrict addressing
cyclicGAMGInterface cyclicGAMGInterface
( (
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface, const lduInterface& fineInterface,
const labelField& restrictAddressing, const labelField& restrictAddressing,
const labelField& neighbourRestrictAddressing const labelField& neighbourRestrictAddressing
@ -94,13 +96,6 @@ public:
// Interface transfer functions // Interface transfer functions
//- Transfer and return neighbour field
virtual tmp<labelField> transfer
(
const Pstream::commsTypes commsType,
const unallocLabelList& interfaceData
) const;
//- Transfer and return internal field adjacent to the interface //- Transfer and return internal field adjacent to the interface
virtual tmp<labelField> internalFieldTransfer virtual tmp<labelField> internalFieldTransfer
( (
@ -111,6 +106,25 @@ public:
//- Cyclic interface functions //- Cyclic interface functions
//- Return neigbour processor number
virtual label neighbPatchID() const
{
return fineCyclicInterface_.neighbPatchID();
}
virtual bool owner() const
{
return fineCyclicInterface_.owner();
}
virtual const cyclicGAMGInterface& neighbPatch() const
{
return dynamic_cast<const cyclicGAMGInterface&>
(
coarseInterfaces_[neighbPatchID()]
);
}
//- Return face transformation tensor //- Return face transformation tensor
virtual const tensorField& forwardT() const virtual const tensorField& forwardT() const
{ {

View File

@ -0,0 +1,73 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "processorCyclicGAMGInterface.H"
#include "addToRunTimeSelectionTable.H"
#include "Map.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(processorCyclicGAMGInterface, 0);
addToRunTimeSelectionTable
(
GAMGInterface,
processorCyclicGAMGInterface,
lduInterface
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::processorCyclicGAMGInterface::processorCyclicGAMGInterface
(
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface,
const labelField& localRestrictAddressing,
const labelField& neighbourRestrictAddressing
)
:
processorGAMGInterface
(
index,
coarseInterfaces,
fineInterface,
localRestrictAddressing,
neighbourRestrictAddressing
)
{}
// * * * * * * * * * * * * * * * * Desstructor * * * * * * * * * * * * * * * //
Foam::processorCyclicGAMGInterface::~processorCyclicGAMGInterface()
{}
// ************************************************************************* //

View File

@ -0,0 +1,98 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::processorCyclicGAMGInterface
Description
GAMG agglomerated processor interface.
SourceFiles
processorCyclicGAMGInterface.C
processorCyclicGAMGInterfaceTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef processorCyclicGAMGInterface_H
#define processorCyclicGAMGInterface_H
#include "processorGAMGInterface.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class processorCyclicGAMGInterface Declaration
\*---------------------------------------------------------------------------*/
class processorCyclicGAMGInterface
:
public processorGAMGInterface
{
// Private Member Functions
//- Disallow default bitwise copy construct
processorCyclicGAMGInterface(const processorCyclicGAMGInterface&);
//- Disallow default bitwise assignment
void operator=(const processorCyclicGAMGInterface&);
public:
//- Runtime type information
TypeName("processorCyclic");
// Constructors
//- Construct from fine-level interface,
// local and neighbour restrict addressing
processorCyclicGAMGInterface
(
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface,
const labelField& restrictAddressing,
const labelField& neighbourRestrictAddressing
);
// Destructor
virtual ~processorCyclicGAMGInterface();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -25,6 +25,7 @@ License
#include "processorGAMGInterface.H" #include "processorGAMGInterface.H"
#include "addToRunTimeSelectionTable.H" #include "addToRunTimeSelectionTable.H"
#include "Map.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -44,6 +45,8 @@ namespace Foam
Foam::processorGAMGInterface::processorGAMGInterface Foam::processorGAMGInterface::processorGAMGInterface
( (
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface, const lduInterface& fineInterface,
const labelField& localRestrictAddressing, const labelField& localRestrictAddressing,
const labelField& neighbourRestrictAddressing const labelField& neighbourRestrictAddressing
@ -51,6 +54,8 @@ Foam::processorGAMGInterface::processorGAMGInterface
: :
GAMGInterface GAMGInterface
( (
index,
coarseInterfaces,
fineInterface, fineInterface,
localRestrictAddressing, localRestrictAddressing,
neighbourRestrictAddressing neighbourRestrictAddressing
@ -58,13 +63,13 @@ Foam::processorGAMGInterface::processorGAMGInterface
fineProcInterface_(refCast<const processorLduInterface>(fineInterface)) fineProcInterface_(refCast<const processorLduInterface>(fineInterface))
{ {
// Make a lookup table of entries for owner/neighbour // Make a lookup table of entries for owner/neighbour
HashTable<SLList<label>, label, Hash<label> > neighboursTable Map<SLList<label> > neighboursTable
( (
localRestrictAddressing.size() localRestrictAddressing.size()
); );
// Table of face-sets to be agglomerated // Table of face-sets to be agglomerated
HashTable<SLList<SLList<label> >, label, Hash<label> > faceFaceTable Map<SLList<SLList<label> > > faceFaceTable
( (
localRestrictAddressing.size() localRestrictAddressing.size()
); );
@ -233,26 +238,6 @@ Foam::processorGAMGInterface::~processorGAMGInterface()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::processorGAMGInterface::initTransfer
(
const Pstream::commsTypes commsType,
const unallocLabelList& interfaceData
) const
{
send(commsType, interfaceData);
}
Foam::tmp<Foam::labelField> Foam::processorGAMGInterface::transfer
(
const Pstream::commsTypes commsType,
const unallocLabelList& interfaceData
) const
{
return receive<label>(commsType, this->size());
}
void Foam::processorGAMGInterface::initInternalFieldTransfer void Foam::processorGAMGInterface::initInternalFieldTransfer
( (
const Pstream::commsTypes commsType, const Pstream::commsTypes commsType,

View File

@ -80,6 +80,8 @@ public:
// local and neighbour restrict addressing // local and neighbour restrict addressing
processorGAMGInterface processorGAMGInterface
( (
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface, const lduInterface& fineInterface,
const labelField& restrictAddressing, const labelField& restrictAddressing,
const labelField& neighbourRestrictAddressing const labelField& neighbourRestrictAddressing
@ -94,20 +96,6 @@ public:
// Interface transfer functions // Interface transfer functions
//- Initialise interface data transfer
virtual void initTransfer
(
const Pstream::commsTypes commsType,
const unallocLabelList& interfaceData
) const;
//- Transfer and return neighbour field
virtual tmp<labelField> transfer
(
const Pstream::commsTypes commsType,
const unallocLabelList& interfaceData
) const;
//- Initialise neighbour field transfer //- Initialise neighbour field transfer
virtual void initInternalFieldTransfer virtual void initInternalFieldTransfer
( (
@ -142,6 +130,12 @@ public:
{ {
return fineProcInterface_.forwardT(); return fineProcInterface_.forwardT();
} }
//- Return message tag used for sending
virtual int tag() const
{
return fineProcInterface_.tag();
}
}; };

View File

@ -51,28 +51,7 @@ void Foam::cyclicPointPatch::initGeometry(PstreamBuffers&)
void Foam::cyclicPointPatch::calcGeometry(PstreamBuffers&) void Foam::cyclicPointPatch::calcGeometry(PstreamBuffers&)
{ {}
const edgeList& cp = cyclicPolyPatch_.coupledPoints();
const labelList& mp = cyclicPolyPatch_.meshPoints();
DynamicList<label> separated;
forAll(cp, i)
{
const edge& coupledSet = cp[i];
// Assume all points are separated.
separated.append(coupledSet[0]);
separated.append(coupledSet[1]);
}
separatedPoints_.transfer(separated);
if (debug)
{
Pout<< "cyclic:" << cyclicPolyPatch_.name()
<< " separated:" << separatedPoints_.size()
<< " out of points:" << mp.size() << endl;
}
}
void Foam::cyclicPointPatch::initMovePoints(PstreamBuffers&, const pointField&) void Foam::cyclicPointPatch::initMovePoints(PstreamBuffers&, const pointField&)
@ -124,10 +103,4 @@ const Foam::edgeList& Foam::cyclicPointPatch::transformPairs() const
} }
const Foam::labelList& Foam::cyclicPointPatch::separatedPoints() const
{
return separatedPoints_;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -37,6 +37,7 @@ SourceFiles
#include "coupledFacePointPatch.H" #include "coupledFacePointPatch.H"
#include "cyclicPolyPatch.H" #include "cyclicPolyPatch.H"
#include "pointBoundaryMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -56,8 +57,6 @@ class cyclicPointPatch
//- Local reference cast into the cyclic patch //- Local reference cast into the cyclic patch
const cyclicPolyPatch& cyclicPolyPatch_; const cyclicPolyPatch& cyclicPolyPatch_;
//- List of local points that are not collocated
mutable labelList separatedPoints_;
// Private Member Functions // Private Member Functions
@ -125,6 +124,14 @@ public:
return cyclicPolyPatch_; return cyclicPolyPatch_;
} }
//- Return neighbour point patch
const cyclicPointPatch& neighbPatch() const
{
label patchI = cyclicPolyPatch_.neighbPatchID();
const pointPatch& pp = this->boundaryMesh()[patchI];
return refCast<const cyclicPointPatch>(pp);
}
//- Are the cyclic planes parallel //- Are the cyclic planes parallel
bool parallel() const bool parallel() const
{ {
@ -147,11 +154,10 @@ public:
// Access functions for demand driven data // Access functions for demand driven data
//- Return the set of pairs of points that require transformation //- Return the set of pairs of points that require transformation
// and/or mapping // and/or mapping. First index is on this patch, second on the
// neighbour patch.
virtual const edgeList& transformPairs() const; virtual const edgeList& transformPairs() const;
//- List of separated coupled points
virtual const labelList& separatedPoints() const;
}; };

View File

@ -73,51 +73,7 @@ void Foam::processorPointPatch::initGeometry(PstreamBuffers& pBufs)
void Foam::processorPointPatch::calcGeometry(PstreamBuffers& pBufs) void Foam::processorPointPatch::calcGeometry(PstreamBuffers& pBufs)
{ {}
if (Pstream::parRun())
{
const boolList& collocated = procPolyPatch_.collocated();
if (collocated.size() == 0)
{
separatedPoints_.setSize(0);
}
else if (collocated.size() == 1)
{
// Uniformly
if (collocated[0])
{
separatedPoints_.setSize(0);
}
else
{
separatedPoints_ = identity(size());
}
}
else
{
// Per face collocated or not.
const labelListList& pointFaces = procPolyPatch_.pointFaces();
DynamicList<label> separated;
forAll(pointFaces, pfi)
{
if (!collocated[pointFaces[pfi][0]])
{
separated.append(pfi);
}
}
separatedPoints_.transfer(separated);
}
}
if (debug)
{
Pout<< "processor:" << name()
<< " separated:" << separatedPoints_.size()
<< " out of points:" << size() << endl;
}
}
void Foam::processorPointPatch::initMovePoints void Foam::processorPointPatch::initMovePoints
@ -173,10 +129,4 @@ const Foam::labelList& Foam::processorPointPatch::reverseMeshPoints() const
} }
const Foam::labelList& Foam::processorPointPatch::separatedPoints() const
{
return separatedPoints_;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -65,7 +65,6 @@ class processorPointPatch
mutable labelList reverseMeshPoints_; mutable labelList reverseMeshPoints_;
mutable labelList separatedPoints_;
// Private Member Functions // Private Member Functions
@ -129,6 +128,12 @@ public:
} }
} }
//- Return message tag to use for communication
virtual int tag() const
{
return procPolyPatch_.tag();
}
//- Return the constraint type this pointPatch implements. //- Return the constraint type this pointPatch implements.
virtual const word& constraintType() const virtual const word& constraintType() const
{ {
@ -168,9 +173,6 @@ public:
//- Return mesh points in the correct order for the receiving side //- Return mesh points in the correct order for the receiving side
const labelList& reverseMeshPoints() const; const labelList& reverseMeshPoints() const;
//- List of separated coupled points
virtual const labelList& separatedPoints() const;
}; };

View File

@ -0,0 +1,400 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "processorCyclicPointPatch.H"
#include "pointBoundaryMesh.H"
#include "addToRunTimeSelectionTable.H"
//#include "pointMesh.H"
//#include "globalPointPatch.H"
//#include "faceList.H"
//#include "primitiveFacePatch.H"
//#include "emptyPolyPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(processorCyclicPointPatch, 0);
addToRunTimeSelectionTable
(
facePointPatch,
processorCyclicPointPatch,
polyPatch
);
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
//void Foam::processorCyclicPointPatch::initGeometry(PstreamBuffers& pBufs)
//{
// // Algorithm:
// // Depending on whether the patch is a master or a slave, get the primitive
// // patch points and filter away the points from the global patch.
//
// if (isMaster())
// {
// meshPoints_ = procPolyPatch_.meshPoints();
// }
// else
// {
// // Slave side. Create the reversed patch and pick up its points
// // so that the order is correct
// const polyPatch& pp = patch();
//
// faceList masterFaces(pp.size());
//
// forAll (pp, faceI)
// {
// masterFaces[faceI] = pp[faceI].reverseFace();
// }
//
// meshPoints_ = primitiveFacePatch
// (
// masterFaces,
// pp.points()
// ).meshPoints();
// }
//
// if (Pstream::parRun())
// {
// initPatchPatchPoints(pBufs);
// }
//}
//
//
//void Foam::processorCyclicPointPatch::calcGeometry(PstreamBuffers& pBufs)
//{
// if (Pstream::parRun())
// {
// calcPatchPatchPoints(pBufs);
// }
//
// // If it is not runing parallel or there are no global points
// // create a 1->1 map
// if
// (
// !Pstream::parRun()
// || !boundaryMesh().mesh().globalData().nGlobalPoints()
// )
// {
// nonGlobalPatchPoints_.setSize(meshPoints_.size());
// forAll(nonGlobalPatchPoints_, i)
// {
// nonGlobalPatchPoints_[i] = i;
// }
// }
// else
// {
// // Get reference to shared points
// const labelList& sharedPoints =
// boundaryMesh().globalPatch().meshPoints();
//
// nonGlobalPatchPoints_.setSize(meshPoints_.size());
//
// label noFiltPoints = 0;
//
// forAll (meshPoints_, pointI)
// {
// label curP = meshPoints_[pointI];
//
// bool found = false;
//
// forAll (sharedPoints, sharedI)
// {
// if (sharedPoints[sharedI] == curP)
// {
// found = true;
// break;
// }
// }
//
// if (!found)
// {
// nonGlobalPatchPoints_[noFiltPoints] = pointI;
// meshPoints_[noFiltPoints] = curP;
// noFiltPoints++;
// }
// }
//
// nonGlobalPatchPoints_.setSize(noFiltPoints);
// meshPoints_.setSize(noFiltPoints);
// }
//}
//
//
//void processorCyclicPointPatch::initPatchPatchPoints(PstreamBuffers& pBufs)
//{
// if (debug)
// {
// Info<< "processorCyclicPointPatch::initPatchPatchPoints(PstreamBuffers&) : "
// << "constructing patch-patch points"
// << endl;
// }
//
// const polyBoundaryMesh& bm = boundaryMesh().mesh()().boundaryMesh();
//
// // Get the mesh points for this patch corresponding to the faces
// const labelList& ppmp = meshPoints();
//
// // Create a HashSet of the point labels for this patch
// Map<label> patchPointSet(2*ppmp.size());
//
// forAll (ppmp, ppi)
// {
// patchPointSet.insert(ppmp[ppi], ppi);
// }
//
//
// // Create the lists of patch-patch points
// labelListList patchPatchPoints(bm.size());
//
// // Create the lists of patch-patch point normals
// List<List<vector> > patchPatchPointNormals(bm.size());
//
// // Loop over all patches looking for other patches that share points
// forAll(bm, patchi)
// {
// if
// (
// patchi != index() // Ignore self-self
// && !isA<emptyPolyPatch>(bm[patchi]) // Ignore empty
// && !bm[patchi].coupled() // Ignore other couples
// )
// {
// // Get the meshPoints for the other patch
// const labelList& meshPoints = bm[patchi].meshPoints();
//
// // Get the normals for the other patch
// const vectorField& normals = bm[patchi].pointNormals();
//
// label pppi = 0;
// forAll(meshPoints, pointi)
// {
// label ppp = meshPoints[pointi];
//
// // Check to see if the point of the other patch is shared with
// // this patch
// Map<label>::iterator iter = patchPointSet.find(ppp);
//
// if (iter != patchPointSet.end())
// {
// // If it is shared initialise the patchPatchPoints for this
// // patch
// if (!patchPatchPoints[patchi].size())
// {
// patchPatchPoints[patchi].setSize(ppmp.size());
// patchPatchPointNormals[patchi].setSize(ppmp.size());
// }
//
// // and add the entry
// patchPatchPoints[patchi][pppi] = iter();
// patchPatchPointNormals[patchi][pppi] = normals[pointi];
// pppi++;
// }
// }
//
// // Resise the list of shared points and normals for the patch
// // being considerd
// patchPatchPoints[patchi].setSize(pppi);
// patchPatchPointNormals[patchi].setSize(pppi);
// }
// }
//
// // Send the patchPatchPoints to the neighbouring processor
//
// UOPstream toNeighbProc(neighbProcNo(), pBufs);
//
// toNeighbProc
// << ppmp.size() // number of points for checking
// << patchPatchPoints
// << patchPatchPointNormals;
//
// if (debug)
// {
// Info<< "processorCyclicPointPatch::initPatchPatchPoints() : "
// << "constructed patch-patch points"
// << endl;
// }
//}
//
//
//void Foam::processorCyclicPointPatch::calcPatchPatchPoints(PstreamBuffers& pBufs)
//{
// // Get the patchPatchPoints from the neighbouring processor
// UIPstream fromNeighbProc(neighbProcNo(), pBufs);
//
// label nbrNPoints(readLabel(fromNeighbProc));
// labelListList patchPatchPoints(fromNeighbProc);
// List<List<vector> > patchPatchPointNormals(fromNeighbProc);
//
// pointBoundaryMesh& pbm = const_cast<pointBoundaryMesh&>(boundaryMesh());
// const labelList& ppmp = meshPoints();
//
// // Simple check for the very rare situation when not the same number
// // of points on both sides. This can happen with decomposed cyclics.
// // If on one side the cyclic shares a point with proc faces coming from
// // internal faces it will have a different number of points from
// // the situation where the cyclic and the 'normal' proc faces are fully
// // separate.
// if (nbrNPoints != ppmp.size())
// {
// WarningIn("processorCyclicPointPatch::calcPatchPatchPoints(PstreamBuffers&)")
// << "Processor patch " << name()
// << " has " << ppmp.size() << " points; coupled patch has "
// << nbrNPoints << " points." << endl
// << " (usually due to decomposed cyclics)."
// << " This might give problems" << endl
// << " when using point fields (interpolation, mesh motion)."
// << endl;
// }
//
//
//
// // Loop over the patches looking for other patches that share points
// forAll(patchPatchPoints, patchi)
// {
// const labelList& patchPoints = patchPatchPoints[patchi];
// const List<vector>& patchPointNormals = patchPatchPointNormals[patchi];
//
// // If there are potentially shared points for the patch being considered
// if (patchPoints.size())
// {
// // Get the current meshPoints list for the patch
// facePointPatch& fpp = refCast<facePointPatch>(pbm[patchi]);
// const labelList& fmp = fpp.meshPoints();
// labelList& mp = fpp.meshPoints_;
//
// const vectorField& fnormals = fpp.pointNormals();
// vectorField& normals = fpp.pointNormals_;
//
// // Create a HashSet of the point labels for the patch
// Map<label> patchPointSet(2*fmp.size());
//
// forAll (fmp, ppi)
// {
// patchPointSet.insert(fmp[ppi], ppi);
// }
//
// label nPoints = mp.size();
// label lpi = 0;
// bool resized = false;
//
// // For each potentially shared point...
// forAll(patchPoints, ppi)
// {
// // Check if it is not already in the patch,
// // i.e. not part of a face of the patch
// if (!patchPointSet.found(ppmp[patchPoints[ppi]]))
// {
// // If it isn't already in the patch check if the local
// // meshPoints is already set and if not initialise the
// // meshPoints_ and pointNormals_
// if (!resized)
// {
// if (!mp.size() && fmp.size())
// {
// mp = fmp;
// normals = fnormals;
//
// nPoints = mp.size();
// }
//
// mp.setSize(nPoints + patchPoints.size());
// loneMeshPoints_.setSize(patchPoints.size());
// normals.setSize(nPoints + patchPoints.size());
// resized = true;
// }
//
// // Add the new point to the patch
// mp[nPoints] = ppmp[patchPoints[ppi]];
// loneMeshPoints_[lpi++] = ppmp[patchPoints[ppi]];
// normals[nPoints++] = patchPointNormals[ppi];
// }
// }
//
// // If the lists have been resized points have been added.
// // Shrink the lists to the current size.
// if (resized)
// {
// mp.setSize(nPoints);
// loneMeshPoints_.setSize(lpi);
// normals.setSize(nPoints);
// }
// }
// }
//}
//void processorCyclicPointPatch::initMovePoints(PstreamBuffers&, const pointField&)
//{}
//
//
//void processorCyclicPointPatch::movePoints(PstreamBuffers&, const pointField&)
//{}
//
//
//void processorCyclicPointPatch::initUpdateMesh(PstreamBuffers& pBufs)
//{
// facePointPatch::initUpdateMesh(pBufs);
// processorCyclicPointPatch::initGeometry(pBufs);
//}
//
//
//void processorCyclicPointPatch::updateMesh(PstreamBuffers& pBufs)
//{
// facePointPatch::updateMesh(pBufs);
// processorCyclicPointPatch::calcGeometry(pBufs);
//}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
processorCyclicPointPatch::processorCyclicPointPatch
(
const polyPatch& patch,
const pointBoundaryMesh& bm
)
:
processorPointPatch(patch, bm),
procCycPolyPatch_(refCast<const processorCyclicPolyPatch>(patch))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
processorCyclicPointPatch::~processorCyclicPointPatch()
{}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,156 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::processorCyclicPointPatch
Description
Processor patch boundary needs to be such that the ordering of
points in the patch is the same on both sides.
Looking at the creation of the faces on both sides of the processor
patch they need to be identical on both sides with the normals pointing
in opposite directions. This is achieved by calling the reverseFace
function in the decomposition. It is therefore possible to re-create
the ordering of patch points on the slave side by reversing all the
patch faces of the owner.
SourceFiles
processorCyclicPointPatch.C
\*---------------------------------------------------------------------------*/
#ifndef processorCyclicPointPatch_H
#define processorCyclicPointPatch_H
#include "processorPointPatch.H"
#include "processorCyclicPolyPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class processorCyclicPointPatch Declaration
\*---------------------------------------------------------------------------*/
class processorCyclicPointPatch
:
public processorPointPatch
{
// Private data
const processorCyclicPolyPatch& procCycPolyPatch_;
//- Disallow default construct as copy
processorCyclicPointPatch(const processorCyclicPointPatch&);
//- Disallow default assignment
void operator=(const processorCyclicPointPatch&);
public:
//- Runtime type information
TypeName(processorCyclicPolyPatch::typeName_());
// Constructors
//- Construct from components
processorCyclicPointPatch
(
const polyPatch& patch,
const pointBoundaryMesh& bm
);
// Destructor
virtual ~processorCyclicPointPatch();
// Member functions
//- Return message tag to use for communication
virtual int tag() const
{
return procCycPolyPatch_.tag();
}
// //- Return true if running parallel
// virtual bool coupled() const
// {
// if (Pstream::parRun())
// {
// return true;
// }
// else
// {
// return false;
// }
// }
//
// //- Return processor number
// int myProcNo() const
// {
// return procPolyPatch_.myProcNo();
// }
//
// //- Return neigbour processor number
// int neighbProcNo() const
// {
// return procPolyPatch_.neighbProcNo();
// }
//
// //- Is this a master patch
// bool isMaster() const
// {
// return myProcNo() < neighbProcNo();
// }
//
// //- Is this a slave patch
// bool isSlave() const
// {
// return !isMaster();
// }
//
//- Return the underlying processorCyclicPolyPatch
const processorCyclicPolyPatch& procCyclicPolyPatch() const
{
return procCycPolyPatch_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -108,8 +108,6 @@ public:
return true; return true;
} }
//- List of separated coupled points
virtual const labelList& separatedPoints() const = 0;
}; };

View File

@ -77,34 +77,38 @@ void Foam::globalMeshData::initProcAddr()
if (Pstream::parRun()) if (Pstream::parRun())
{ {
PstreamBuffers pBufs(Pstream::nonBlocking);
// Send indices of my processor patches to my neighbours // Send indices of my processor patches to my neighbours
forAll(processorPatches_, i) forAll(processorPatches_, i)
{ {
label patchi = processorPatches_[i]; label patchi = processorPatches_[i];
OPstream toNeighbour UOPstream toNeighbour
( (
Pstream::blocking,
refCast<const processorPolyPatch> refCast<const processorPolyPatch>
( (
mesh_.boundaryMesh()[patchi] mesh_.boundaryMesh()[patchi]
).neighbProcNo() ).neighbProcNo(),
pBufs
); );
toNeighbour << processorPatchIndices_[patchi]; toNeighbour << processorPatchIndices_[patchi];
} }
pBufs.finishedSends();
forAll(processorPatches_, i) forAll(processorPatches_, i)
{ {
label patchi = processorPatches_[i]; label patchi = processorPatches_[i];
IPstream fromNeighbour UIPstream fromNeighbour
( (
Pstream::blocking,
refCast<const processorPolyPatch> refCast<const processorPolyPatch>
( (
mesh_.boundaryMesh()[patchi] mesh_.boundaryMesh()[patchi]
).neighbProcNo() ).neighbProcNo(),
pBufs
); );
fromNeighbour >> processorPatchNeighbours_[patchi]; fromNeighbour >> processorPatchNeighbours_[patchi];
@ -2000,24 +2004,10 @@ void Foam::globalMeshData::updateMesh()
{ {
label patchI = processorPatches_[i]; label patchI = processorPatches_[i];
const processorPolyPatch& procPatch = if (isType<processorPolyPatch>(mesh_.boundaryMesh()[patchI]))
refCast<const processorPolyPatch>(mesh_.boundaryMesh()[patchI]);
if (Pstream::myProcNo() > procPatch.neighbProcNo())
{ {
// Uncount my faces. Handle cyclics separately. // Normal, unseparated processor patch. Remove duplicates.
nTotalFaces_ -= mesh_.boundaryMesh()[patchI].size();
if (procPatch.separated())
{
const vectorField& separationDist = procPatch.separation();
nTotalFaces_ -= countCoincidentFaces(tolDim, separationDist);
}
else
{
// Normal, unseparated processor patch. Remove duplicates.
nTotalFaces_ -= procPatch.size();
}
} }
} }
reduce(nTotalFaces_, sumOp<label>()); reduce(nTotalFaces_, sumOp<label>());
@ -2060,6 +2050,8 @@ void Foam::globalMeshData::updateMesh()
pointStatus.set(meshPointI, SHARED); pointStatus.set(meshPointI, SHARED);
} }
PstreamBuffers pBufs(Pstream::nonBlocking);
// Send patch local points // Send patch local points
forAll(processorPatches_, i) forAll(processorPatches_, i)
{ {
@ -2068,11 +2060,13 @@ void Foam::globalMeshData::updateMesh()
const processorPolyPatch& procPatch = const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(mesh_.boundaryMesh()[patchI]); refCast<const processorPolyPatch>(mesh_.boundaryMesh()[patchI]);
OPstream toNeighbour(Pstream::blocking, procPatch.neighbProcNo()); UOPstream toNeighbour(procPatch.neighbProcNo(), pBufs);
toNeighbour << procPatch.localPoints(); toNeighbour << procPatch.localPoints();
} }
pBufs.finishedSends();
// Receive patch local points and uncount if coincident (and not shared) // Receive patch local points and uncount if coincident (and not shared)
forAll(processorPatches_, i) forAll(processorPatches_, i)
{ {
@ -2081,7 +2075,7 @@ void Foam::globalMeshData::updateMesh()
const processorPolyPatch& procPatch = const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(mesh_.boundaryMesh()[patchI]); refCast<const processorPolyPatch>(mesh_.boundaryMesh()[patchI]);
IPstream fromNeighbour(Pstream::blocking, procPatch.neighbProcNo()); UIPstream fromNeighbour(procPatch.neighbProcNo(), pBufs);
pointField nbrPoints(fromNeighbour); pointField nbrPoints(fromNeighbour);

View File

@ -25,6 +25,7 @@ License
#include "globalPoints.H" #include "globalPoints.H"
#include "processorPolyPatch.H" #include "processorPolyPatch.H"
#include "processorCyclicPolyPatch.H"
#include "cyclicPolyPatch.H" #include "cyclicPolyPatch.H"
#include "polyMesh.H" #include "polyMesh.H"
@ -40,45 +41,6 @@ const Foam::label Foam::globalPoints::fromCollocated = labelMax/2;
// Routines to handle global indices // Routines to handle global indices
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Foam::PackedBoolList Foam::globalPoints::collocatedPoints
(
const coupledPolyPatch& pp
)
{
// Initialise to false
PackedBoolList isCollocated(pp.nPoints());
const boolList& collocated = pp.collocated();
if (collocated.size() == 0)
{
isCollocated = 1;
}
else if (collocated.size() == 1)
{
// Uniform.
if (collocated[0])
{
isCollocated = 1;
}
}
else
{
// Per face collocated or not.
const labelListList& pointFaces = pp.pointFaces();
forAll(pointFaces, pfi)
{
if (collocated[pointFaces[pfi][0]])
{
isCollocated[pfi] = 1;
}
}
}
return isCollocated;
}
Foam::label Foam::globalPoints::toGlobal Foam::label Foam::globalPoints::toGlobal
( (
const label localPointI, const label localPointI,
@ -369,16 +331,9 @@ void Foam::globalPoints::initOwnPoints
|| isA<cyclicPolyPatch>(pp) || isA<cyclicPolyPatch>(pp)
) )
{ {
// Find points with transforms // Assume all processor points are collocated and all
// processorCyclic and cyclic are separated.
PackedBoolList isCollocatedPoint bool isCollocatedPoint = isType<processorPolyPatch>(pp);
(
collocatedPoints
(
refCast<const coupledPolyPatch>(pp)
)
);
const labelList& meshPoints = pp.meshPoints(); const labelList& meshPoints = pp.meshPoints();
@ -396,7 +351,7 @@ void Foam::globalPoints::initOwnPoints
labelList knownInfo labelList knownInfo
( (
1, 1,
toGlobal(localPointI, isCollocatedPoint[patchPointI]) toGlobal(localPointI, isCollocatedPoint)
); );
// Update addressing from point to index in procPoints // Update addressing from point to index in procPoints
@ -425,11 +380,7 @@ void Foam::globalPoints::initOwnPoints
labelList knownInfo labelList knownInfo
( (
1, 1,
toGlobal toGlobal(localPointI, isCollocatedPoint)
(
localPointI,
isCollocatedPoint[boundaryPoints[i]]
)
); );
// Update addressing from point to index in procPoints // Update addressing from point to index in procPoints
@ -461,20 +412,21 @@ void Foam::globalPoints::sendPatchPoints
{ {
const polyPatch& pp = patches[patchI]; const polyPatch& pp = patches[patchI];
if (Pstream::parRun() && isA<processorPolyPatch>(pp)) if
(
Pstream::parRun()
&& (
isType<processorPolyPatch>(pp)
|| (mergeSeparated && isA<processorCyclicPolyPatch>(pp))
)
)
{ {
// processor cyclics are considered separated, pure processor
// always collocated.
const processorPolyPatch& procPatch = const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(pp); refCast<const processorPolyPatch>(pp);
PackedBoolList isCollocatedPoint
(
collocatedPoints
(
procPatch
)
);
// Information to send: // Information to send:
// patch face // patch face
DynamicList<label> patchFaces(pp.nPoints()); DynamicList<label> patchFaces(pp.nPoints());
@ -492,34 +444,31 @@ void Foam::globalPoints::sendPatchPoints
forAll(meshPoints, patchPointI) forAll(meshPoints, patchPointI)
{ {
if (mergeSeparated || isCollocatedPoint[patchPointI]) label meshPointI = meshPoints[patchPointI];
label localPointI = meshToLocalPoint
(
meshToPatchPoint,
meshPointI
);
if (changedPoints.found(localPointI))
{ {
label meshPointI = meshPoints[patchPointI]; label index = meshToProcPoint_[localPointI];
label localPointI = meshToLocalPoint
const labelList& knownInfo = procPoints_[index];
// Add my information about localPointI to the
// send buffers
addToSend
( (
meshToPatchPoint, pp,
meshPointI patchPointI,
knownInfo,
patchFaces,
indexInFace,
allInfo
); );
if (changedPoints.found(localPointI))
{
label index = meshToProcPoint_[localPointI];
const labelList& knownInfo = procPoints_[index];
// Add my information about localPointI to the
// send buffers
addToSend
(
pp,
patchPointI,
knownInfo,
patchFaces,
indexInFace,
allInfo
);
}
} }
} }
@ -560,18 +509,20 @@ void Foam::globalPoints::receivePatchPoints
{ {
const polyPatch& pp = patches[patchI]; const polyPatch& pp = patches[patchI];
if (Pstream::parRun() && isA<processorPolyPatch>(pp)) if
(
Pstream::parRun()
&& (
isType<processorPolyPatch>(pp)
|| (mergeSeparated && isA<processorCyclicPolyPatch>(pp))
)
)
{ {
const processorPolyPatch& procPatch = const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(pp); refCast<const processorPolyPatch>(pp);
PackedBoolList isCollocatedPoint // Processor patch is always collocated, processorCyclic is not.
( bool isCollocatedPoint = isType<processorPolyPatch>(pp);
collocatedPoints
(
procPatch
)
);
labelList patchFaces; labelList patchFaces;
labelList indexInFace; labelList indexInFace;
@ -605,21 +556,13 @@ void Foam::globalPoints::receivePatchPoints
meshPointI meshPointI
); );
if if (storeInfo(nbrInfo[i], localPointI, isCollocatedPoint))
(
storeInfo
(
nbrInfo[i],
localPointI,
isCollocatedPoint[pp.meshPointMap()[meshPointI]]
)
)
{ {
changedPoints.insert(localPointI); changedPoints.insert(localPointI);
} }
} }
} }
else if (isA<cyclicPolyPatch>(pp)) else if (mergeSeparated && isA<cyclicPolyPatch>(pp))
{ {
// Handle cyclics: send lower half to upper half and vice versa. // Handle cyclics: send lower half to upper half and vice versa.
// Or since they both are in memory just do it point by point. // Or since they both are in memory just do it point by point.
@ -627,80 +570,49 @@ void Foam::globalPoints::receivePatchPoints
const cyclicPolyPatch& cycPatch = const cyclicPolyPatch& cycPatch =
refCast<const cyclicPolyPatch>(pp); refCast<const cyclicPolyPatch>(pp);
PackedBoolList isCollocatedPoint
(
collocatedPoints
(
cycPatch
)
);
const labelList& meshPoints = pp.meshPoints(); const labelList& meshPoints = pp.meshPoints();
const labelList coupledMeshPoints(reverseMeshPoints(cycPatch));
//const edgeList& connections = cycPatch.coupledPoints(); forAll(meshPoints, i)
const edgeList connections(coupledPoints(cycPatch));
forAll(connections, i)
{ {
const edge& e = connections[i]; label meshPointA = meshPoints[i];
label meshPointB = coupledMeshPoints[i];
if (mergeSeparated || isCollocatedPoint[e[0]]) label localA = meshToLocalPoint
(
meshToPatchPoint,
meshPointA
);
label localB = meshToLocalPoint
(
meshToPatchPoint,
meshPointB
);
// Do we have information on pointA?
Map<label>::iterator procPointA =
meshToProcPoint_.find(localA);
if (procPointA != meshToProcPoint_.end())
{ {
label meshPointA = meshPoints[e[0]]; // Store A info onto pointB
label meshPointB = meshPoints[e[1]]; if (storeInfo(procPoints_[procPointA()], localB, false))
label localA = meshToLocalPoint
(
meshToPatchPoint,
meshPointA
);
label localB = meshToLocalPoint
(
meshToPatchPoint,
meshPointB
);
// Do we have information on pointA?
Map<label>::iterator procPointA =
meshToProcPoint_.find(localA);
if (procPointA != meshToProcPoint_.end())
{ {
// Store A info onto pointB changedPoints.insert(localB);
if
(
storeInfo
(
procPoints_[procPointA()],
localB,
isCollocatedPoint[e[1]]
)
)
{
changedPoints.insert(localB);
}
} }
}
// Same for info on pointB // Same for info on pointB
Map<label>::iterator procPointB = Map<label>::iterator procPointB =
meshToProcPoint_.find(localB); meshToProcPoint_.find(localB);
if (procPointB != meshToProcPoint_.end()) if (procPointB != meshToProcPoint_.end())
{
// Store B info onto pointA
if (storeInfo(procPoints_[procPointB()], localA, false))
{ {
// Store B info onto pointA changedPoints.insert(localA);
if
(
storeInfo
(
procPoints_[procPointB()],
localA,
isCollocatedPoint[e[0]]
)
)
{
changedPoints.insert(localA);
}
} }
} }
} }
@ -970,7 +882,14 @@ void Foam::globalPoints::sendSharedPoints
{ {
const polyPatch& pp = patches[patchI]; const polyPatch& pp = patches[patchI];
if (Pstream::parRun() && isA<processorPolyPatch>(pp)) if
(
Pstream::parRun()
&& (
isType<processorPolyPatch>(pp)
|| (mergeSeparated && isA<processorCyclicPolyPatch>(pp))
)
)
{ {
const processorPolyPatch& procPatch = const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(pp); refCast<const processorPolyPatch>(pp);
@ -1057,7 +976,14 @@ void Foam::globalPoints::receiveSharedPoints
{ {
const polyPatch& pp = patches[patchI]; const polyPatch& pp = patches[patchI];
if (Pstream::parRun() && isA<processorPolyPatch>(pp)) if
(
Pstream::parRun()
&& (
isType<processorPolyPatch>(pp)
|| (mergeSeparated && isA<processorCyclicPolyPatch>(pp))
)
)
{ {
const processorPolyPatch& procPatch = const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(pp); refCast<const processorPolyPatch>(pp);
@ -1128,19 +1054,11 @@ void Foam::globalPoints::receiveSharedPoints
} }
} }
} }
else if (isA<cyclicPolyPatch>(pp)) else if (mergeSeparated && isA<cyclicPolyPatch>(pp))
{ {
const cyclicPolyPatch& cycPatch = const cyclicPolyPatch& cycPatch =
refCast<const cyclicPolyPatch>(pp); refCast<const cyclicPolyPatch>(pp);
PackedBoolList isCollocatedPoint
(
collocatedPoints
(
cycPatch
)
);
// Build map from mesh or patch point to sharedPoint. // Build map from mesh or patch point to sharedPoint.
Map<label> localToSharedPoint(sharedPointAddr_.size()); Map<label> localToSharedPoint(sharedPointAddr_.size());
forAll(sharedPointLabels_, i) forAll(sharedPointLabels_, i)
@ -1156,80 +1074,76 @@ void Foam::globalPoints::receiveSharedPoints
} }
// Sync all info. // Sync all info.
//const edgeList& connections = cycPatch.coupledPoints();
const edgeList connections(coupledPoints(cycPatch));
forAll(connections, i) const labelList& meshPoints = cycPatch.meshPoints();
const labelList coupledMeshPoints(reverseMeshPoints(cycPatch));
forAll(meshPoints, i)
{ {
const edge& e = connections[i]; label meshPointA = meshPoints[i];
label meshPointB = coupledMeshPoints[i];
if (mergeSeparated || isCollocatedPoint[e[0]]) label localA = meshToLocalPoint
(
meshToPatchPoint,
meshPointA
);
label localB = meshToLocalPoint
(
meshToPatchPoint,
meshPointB
);
// Do we already have shared point for pointA?
Map<label>::iterator fndA = localToSharedPoint.find(localA);
Map<label>::iterator fndB = localToSharedPoint.find(localB);
if (fndA != localToSharedPoint.end())
{ {
label meshPointA = pp.meshPoints()[e[0]]; if (fndB != localToSharedPoint.end())
label meshPointB = pp.meshPoints()[e[1]];
label localA = meshToLocalPoint
(
meshToPatchPoint,
meshPointA
);
label localB = meshToLocalPoint
(
meshToPatchPoint,
meshPointB
);
// Do we already have shared point for pointA?
Map<label>::iterator fndA = localToSharedPoint.find(localA);
Map<label>::iterator fndB = localToSharedPoint.find(localB);
if (fndA != localToSharedPoint.end())
{ {
if (fndB != localToSharedPoint.end()) if (fndA() != fndB())
{ {
if (fndA() != fndB()) FatalErrorIn
{ (
FatalErrorIn "globalPoints::receiveSharedPoints(..)"
( ) << "On patch " << pp.name()
"globalPoints::receiveSharedPoints(..)" << " connected points " << meshPointA
) << "On patch " << pp.name() << ' ' << mesh_.points()[meshPointA]
<< " connected points " << meshPointA << " and " << meshPointB
<< ' ' << mesh_.points()[meshPointA] << ' ' << mesh_.points()[meshPointB]
<< " and " << meshPointB << " are mapped to different shared"
<< ' ' << mesh_.points()[meshPointB] << " points: "
<< " are mapped to different shared" << fndA() << " and " << fndB()
<< " points: " << abort(FatalError);
<< fndA() << " and " << fndB()
<< abort(FatalError);
}
}
else
{
// No shared point yet for B.
label sharedPointI = fndA();
// Store shared point for pointB
label sharedI = meshToShared[localB];
sharedPointAddr_[sharedI] = sharedPointI;
sharedPointLabels_[sharedI] = localB;
changedIndices.append(sharedI);
} }
} }
else else
{ {
// No shared point yet for A. // No shared point yet for B.
if (fndB != localToSharedPoint.end()) label sharedPointI = fndA();
{
label sharedPointI = fndB();
// Store shared point for pointA // Store shared point for pointB
label sharedI = meshToShared[localA]; label sharedI = meshToShared[localB];
sharedPointAddr_[sharedI] = sharedPointI; sharedPointAddr_[sharedI] = sharedPointI;
sharedPointLabels_[sharedI] = localA; sharedPointLabels_[sharedI] = localB;
changedIndices.append(sharedI); changedIndices.append(sharedI);
} }
}
else
{
// No shared point yet for A.
if (fndB != localToSharedPoint.end())
{
label sharedPointI = fndB();
// Store shared point for pointA
label sharedI = meshToShared[localA];
sharedPointAddr_[sharedI] = sharedPointI;
sharedPointLabels_[sharedI] = localA;
changedIndices.append(sharedI);
} }
} }
} }
@ -1241,51 +1155,25 @@ void Foam::globalPoints::receiveSharedPoints
} }
Foam::edgeList Foam::globalPoints::coupledPoints(const cyclicPolyPatch& pp) Foam::labelList Foam::globalPoints::reverseMeshPoints
(
const cyclicPolyPatch& pp
)
{ {
// Look at cyclic patch as two halves, A and B. const cyclicPolyPatch& nbrPatch = pp.neighbPatch();
// Now all we know is that relative face index in halfA is same
// as coupled face in halfB and also that the 0th vertex
// corresponds.
// From halfA point to halfB or -1. faceList masterFaces(nbrPatch.size());
labelList coupledPoint(pp.nPoints(), -1);
for (label patchFaceA = 0; patchFaceA < pp.size()/2; patchFaceA++) forAll (nbrPatch, faceI)
{ {
const face& fA = pp.localFaces()[patchFaceA]; masterFaces[faceI] = nbrPatch[faceI].reverseFace();
forAll(fA, indexA)
{
label patchPointA = fA[indexA];
if (coupledPoint[patchPointA] == -1)
{
const face& fB = pp.localFaces()[patchFaceA + pp.size()/2];
label indexB = (fB.size() - indexA) % fB.size();
coupledPoint[patchPointA] = fB[indexB];
}
}
} }
edgeList connected(pp.nPoints()); return primitiveFacePatch
(
// Extract coupled points. masterFaces,
label connectedI = 0; nbrPatch.points()
).meshPoints();
forAll(coupledPoint, i)
{
if (coupledPoint[i] != -1)
{
connected[connectedI++] = edge(i, coupledPoint[i]);
}
}
connected.setSize(connectedI);
return connected;
} }

View File

@ -158,10 +158,6 @@ class globalPoints
// Private Member Functions // Private Member Functions
//- Return per point collocated status
static PackedBoolList collocatedPoints(const coupledPolyPatch&);
// Wrappers around global point numbering to add collocated bit // Wrappers around global point numbering to add collocated bit
//- Convert into globalIndices and add collocated bit //- Convert into globalIndices and add collocated bit
@ -300,9 +296,8 @@ class globalPoints
DynamicList<label>& DynamicList<label>&
); );
//- Should move into cyclicPolyPatch ordering problem //- Return mesh points of other side in same order as my meshPoints.
// keeps on giving problems. static labelList reverseMeshPoints(const cyclicPolyPatch&);
static edgeList coupledPoints(const cyclicPolyPatch&);
//- Do all calculations. //- Do all calculations.
void calculateSharedPoints void calculateSharedPoints

View File

@ -74,7 +74,7 @@ Foam::List<Foam::labelPair> Foam::mapDistribute::schedule
slave++ slave++
) )
{ {
IPstream fromSlave(Pstream::blocking, slave); IPstream fromSlave(Pstream::scheduled, slave);
List<labelPair> nbrData(fromSlave); List<labelPair> nbrData(fromSlave);
forAll(nbrData, i) forAll(nbrData, i)
@ -95,18 +95,18 @@ Foam::List<Foam::labelPair> Foam::mapDistribute::schedule
slave++ slave++
) )
{ {
OPstream toSlave(Pstream::blocking, slave); OPstream toSlave(Pstream::scheduled, slave);
toSlave << allComms; toSlave << allComms;
} }
} }
else else
{ {
{ {
OPstream toMaster(Pstream::blocking, Pstream::masterNo()); OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
toMaster << allComms; toMaster << allComms;
} }
{ {
IPstream fromMaster(Pstream::blocking, Pstream::masterNo()); IPstream fromMaster(Pstream::scheduled, Pstream::masterNo());
fromMaster >> allComms; fromMaster >> allComms;
} }
} }
@ -595,6 +595,7 @@ void Foam::mapDistribute::compact(const boolList& elemIsUsed)
// Send elemIsUsed field to neighbour. Use nonblocking code from // Send elemIsUsed field to neighbour. Use nonblocking code from
// mapDistribute but in reverse order. // mapDistribute but in reverse order.
if (Pstream::parRun())
{ {
List<boolList> sendFields(Pstream::nProcs()); List<boolList> sendFields(Pstream::nProcs());

View File

@ -41,6 +41,30 @@ void Foam::mapDistribute::distribute
List<T>& field List<T>& field
) )
{ {
if (!Pstream::parRun())
{
// Do only me to me.
const labelList& mySubMap = subMap[Pstream::myProcNo()];
List<T> subField(mySubMap.size());
forAll(mySubMap, i)
{
subField[i] = field[mySubMap[i]];
}
// Receive sub field from myself (subField)
const labelList& map = constructMap[Pstream::myProcNo()];
field.setSize(constructSize);
forAll(map, i)
{
field[map[i]] = subField[i];
}
return;
}
if (commsType == Pstream::blocking) if (commsType == Pstream::blocking)
{ {
// Since buffered sending can reuse the field to collect the // Since buffered sending can reuse the field to collect the
@ -406,6 +430,30 @@ void Foam::mapDistribute::distribute
const T& nullValue const T& nullValue
) )
{ {
if (!Pstream::parRun())
{
// Do only me to me.
const labelList& mySubMap = subMap[Pstream::myProcNo()];
List<T> subField(mySubMap.size());
forAll(mySubMap, i)
{
subField[i] = field[mySubMap[i]];
}
// Receive sub field from myself (subField)
const labelList& map = constructMap[Pstream::myProcNo()];
field.setSize(constructSize);
forAll(map, i)
{
field[map[i]] = subField[i];
}
return;
}
if (commsType == Pstream::blocking) if (commsType == Pstream::blocking)
{ {
// Since buffered sending can reuse the field to collect the // Since buffered sending can reuse the field to collect the

View File

@ -717,6 +717,7 @@ void Foam::polyMesh::resetPrimitives
" const Xfer<labelList>& neighbour,\n" " const Xfer<labelList>& neighbour,\n"
" const labelList& patchSizes,\n" " const labelList& patchSizes,\n"
" const labelList& patchStarts\n" " const labelList& patchStarts\n"
" const bool validBoundary\n"
")\n" ")\n"
) << "Face " << faceI << " contains vertex labels out of range: " ) << "Face " << faceI << " contains vertex labels out of range: "
<< curFace << " Max point index = " << points_.size() << curFace << " Max point index = " << points_.size()
@ -759,9 +760,9 @@ void Foam::polyMesh::resetPrimitives
" const Xfer<labelList>& neighbour,\n" " const Xfer<labelList>& neighbour,\n"
" const labelList& patchSizes,\n" " const labelList& patchSizes,\n"
" const labelList& patchStarts\n" " const labelList& patchStarts\n"
" const bool validBoundary\n"
")\n" ")\n"
) ) << "no points or no cells in mesh" << endl;
<< "no points or no cells in mesh" << endl;
} }
} }
} }

View File

@ -193,6 +193,19 @@ private:
const label patchID const label patchID
) const; ) const;
void setTopology
(
const cellShapeList& cellsAsShapes,
const faceListList& boundaryFaces,
const wordList& boundaryPatchNames,
labelList& patchSizes,
labelList& patchStarts,
label& defaultPatchStart,
label& nFaces,
cellList& cells
);
public: public:
@ -255,6 +268,20 @@ public:
const bool syncPar = true const bool syncPar = true
); );
//- Construct from cell shapes with patch information in dictionary
// format.
polyMesh
(
const IOobject& io,
const Xfer<pointField>& points,
const cellShapeList& shapes,
const faceListList& boundaryFaces,
const PtrList<dictionary>& boundaryDicts,
const word& defaultBoundaryPatchName,
const word& defaultBoundaryPatchType,
const bool syncPar = true
);
//- Destructor //- Destructor
virtual ~polyMesh(); virtual ~polyMesh();
@ -442,8 +469,6 @@ public:
//- Reset mesh primitive data. Assumes all patch info correct //- Reset mesh primitive data. Assumes all patch info correct
// (so does e.g. parallel communication). If not use // (so does e.g. parallel communication). If not use
// validBoundary=false // validBoundary=false
// (still assumes patchStarts[0] = nInternalFaces and last
// patch ends at nActiveFaces) and change patches with addPatches.
void resetPrimitives void resetPrimitives
( (
const Xfer<pointField>& points, const Xfer<pointField>& points,

View File

@ -132,6 +132,291 @@ Foam::labelList Foam::polyMesh::facePatchFaceCells
} }
//- Set faces_, calculate cells and patchStarts.
void Foam::polyMesh::setTopology
(
const cellShapeList& cellsAsShapes,
const faceListList& boundaryFaces,
const wordList& boundaryPatchNames,
labelList& patchSizes,
labelList& patchStarts,
label& defaultPatchStart,
label& nFaces,
cellList& cells
)
{
// Calculate the faces of all cells
// Initialise maximum possible numer of mesh faces to 0
label maxFaces = 0;
// Set up a list of face shapes for each cell
faceListList cellsFaceShapes(cellsAsShapes.size());
cells.setSize(cellsAsShapes.size());
forAll(cellsFaceShapes, cellI)
{
cellsFaceShapes[cellI] = cellsAsShapes[cellI].faces();
cells[cellI].setSize(cellsFaceShapes[cellI].size());
// Initialise cells to -1 to flag undefined faces
static_cast<labelList&>(cells[cellI]) = -1;
// Count maximum possible numer of mesh faces
maxFaces += cellsFaceShapes[cellI].size();
}
// Set size of faces array to maximum possible number of mesh faces
faces_.setSize(maxFaces);
// Initialise number of faces to 0
nFaces = 0;
// set reference to point-cell addressing
labelListList PointCells = cellShapePointCells(cellsAsShapes);
bool found = false;
forAll(cells, cellI)
{
// Note:
// Insertion cannot be done in one go as the faces need to be
// added into the list in the increasing order of neighbour
// cells. Therefore, all neighbours will be detected first
// and then added in the correct order.
const faceList& curFaces = cellsFaceShapes[cellI];
// Record the neighbour cell
labelList neiCells(curFaces.size(), -1);
// Record the face of neighbour cell
labelList faceOfNeiCell(curFaces.size(), -1);
label nNeighbours = 0;
// For all faces ...
forAll(curFaces, faceI)
{
// Skip faces that have already been matched
if (cells[cellI][faceI] >= 0) continue;
found = false;
const face& curFace = curFaces[faceI];
// Get the list of labels
const labelList& curPoints = curFace;
// For all points
forAll(curPoints, pointI)
{
// dGget the list of cells sharing this point
const labelList& curNeighbours =
PointCells[curPoints[pointI]];
// For all neighbours
forAll(curNeighbours, neiI)
{
label curNei = curNeighbours[neiI];
// Reject neighbours with the lower label
if (curNei > cellI)
{
// Get the list of search faces
const faceList& searchFaces = cellsFaceShapes[curNei];
forAll(searchFaces, neiFaceI)
{
if (searchFaces[neiFaceI] == curFace)
{
// Match!!
found = true;
// Record the neighbour cell and face
neiCells[faceI] = curNei;
faceOfNeiCell[faceI] = neiFaceI;
nNeighbours++;
break;
}
}
if (found) break;
}
if (found) break;
}
if (found) break;
} // End of current points
} // End of current faces
// Add the faces in the increasing order of neighbours
for (label neiSearch = 0; neiSearch < nNeighbours; neiSearch++)
{
// Find the lowest neighbour which is still valid
label nextNei = -1;
label minNei = cells.size();
forAll(neiCells, ncI)
{
if (neiCells[ncI] > -1 && neiCells[ncI] < minNei)
{
nextNei = ncI;
minNei = neiCells[ncI];
}
}
if (nextNei > -1)
{
// Add the face to the list of faces
faces_[nFaces] = curFaces[nextNei];
// Set cell-face and cell-neighbour-face to current face label
cells[cellI][nextNei] = nFaces;
cells[neiCells[nextNei]][faceOfNeiCell[nextNei]] = nFaces;
// Stop the neighbour from being used again
neiCells[nextNei] = -1;
// Increment number of faces counter
nFaces++;
}
else
{
FatalErrorIn
(
"polyMesh::setTopology\n"
"(\n"
" const cellShapeList& cellsAsShapes,\n"
" const faceListList& boundaryFaces,\n"
" const wordList& boundaryPatchNames,\n"
" labelList& patchSizes,\n"
" labelList& patchStarts,\n"
" label& defaultPatchStart,\n"
" label& nFaces,\n"
" cellList& cells\n"
")"
) << "Error in internal face insertion"
<< abort(FatalError);
}
}
}
// Do boundary faces
patchSizes.setSize(boundaryFaces.size(), -1);
patchStarts.setSize(boundaryFaces.size(), -1);
forAll(boundaryFaces, patchI)
{
const faceList& patchFaces = boundaryFaces[patchI];
labelList curPatchFaceCells =
facePatchFaceCells
(
patchFaces,
PointCells,
cellsFaceShapes,
patchI
);
// Grab the start label
label curPatchStart = nFaces;
forAll(patchFaces, faceI)
{
const face& curFace = patchFaces[faceI];
const label cellInside = curPatchFaceCells[faceI];
faces_[nFaces] = curFace;
// get faces of the cell inside
const faceList& facesOfCellInside = cellsFaceShapes[cellInside];
bool found = false;
forAll(facesOfCellInside, cellFaceI)
{
if (facesOfCellInside[cellFaceI] == curFace)
{
if (cells[cellInside][cellFaceI] >= 0)
{
FatalErrorIn
(
"polyMesh::setTopology\n"
"(\n"
" const cellShapeList& cellsAsShapes,\n"
" const faceListList& boundaryFaces,\n"
" const wordList& boundaryPatchNames,\n"
" labelList& patchSizes,\n"
" labelList& patchStarts,\n"
" label& defaultPatchStart,\n"
" label& nFaces,\n"
" cellList& cells\n"
")"
) << "Trying to specify a boundary face " << curFace
<< " on the face on cell " << cellInside
<< " which is either an internal face or already "
<< "belongs to some other patch. This is face "
<< faceI << " of patch "
<< patchI << " named "
<< boundaryPatchNames[patchI] << "."
<< abort(FatalError);
}
found = true;
cells[cellInside][cellFaceI] = nFaces;
break;
}
}
if (!found)
{
FatalErrorIn("polyMesh::polyMesh(... construct from shapes...)")
<< "face " << faceI << " of patch " << patchI
<< " does not seem to belong to cell " << cellInside
<< " which, according to the addressing, "
<< "should be next to it."
<< abort(FatalError);
}
// increment the counter of faces
nFaces++;
}
patchSizes[patchI] = nFaces - curPatchStart;
patchStarts[patchI] = curPatchStart;
}
// Grab "non-existing" faces and put them into a default patch
defaultPatchStart = nFaces;
forAll(cells, cellI)
{
labelList& curCellFaces = cells[cellI];
forAll(curCellFaces, faceI)
{
if (curCellFaces[faceI] == -1) // "non-existent" face
{
curCellFaces[faceI] = nFaces;
faces_[nFaces] = cellsFaceShapes[cellI][faceI];
nFaces++;
}
}
}
// Reset the size of the face list
faces_.setSize(nFaces);
return ;
}
Foam::polyMesh::polyMesh Foam::polyMesh::polyMesh
( (
const IOobject& io, const IOobject& io,
@ -273,271 +558,23 @@ Foam::polyMesh::polyMesh
// Remove all of the old mesh files if they exist // Remove all of the old mesh files if they exist
removeFiles(instance()); removeFiles(instance());
// Calculate the faces of all cells // Calculate faces and cells
// Initialise maximum possible numer of mesh faces to 0 labelList patchSizes;
label maxFaces = 0; labelList patchStarts;
label defaultPatchStart;
// Set up a list of face shapes for each cell label nFaces;
faceListList cellsFaceShapes(cellsAsShapes.size()); cellList cells;
cellList cells(cellsAsShapes.size()); setTopology
(
forAll(cellsFaceShapes, cellI) cellsAsShapes,
{ boundaryFaces,
cellsFaceShapes[cellI] = cellsAsShapes[cellI].faces(); boundaryPatchNames,
patchSizes,
cells[cellI].setSize(cellsFaceShapes[cellI].size()); patchStarts,
defaultPatchStart,
// Initialise cells to -1 to flag undefined faces nFaces,
static_cast<labelList&>(cells[cellI]) = -1; cells
);
// Count maximum possible numer of mesh faces
maxFaces += cellsFaceShapes[cellI].size();
}
// Set size of faces array to maximum possible number of mesh faces
faces_.setSize(maxFaces);
// Initialise number of faces to 0
label nFaces = 0;
// set reference to point-cell addressing
labelListList PointCells = cellShapePointCells(cellsAsShapes);
bool found = false;
forAll(cells, cellI)
{
// Note:
// Insertion cannot be done in one go as the faces need to be
// added into the list in the increasing order of neighbour
// cells. Therefore, all neighbours will be detected first
// and then added in the correct order.
const faceList& curFaces = cellsFaceShapes[cellI];
// Record the neighbour cell
labelList neiCells(curFaces.size(), -1);
// Record the face of neighbour cell
labelList faceOfNeiCell(curFaces.size(), -1);
label nNeighbours = 0;
// For all faces ...
forAll(curFaces, faceI)
{
// Skip faces that have already been matched
if (cells[cellI][faceI] >= 0) continue;
found = false;
const face& curFace = curFaces[faceI];
// Get the list of labels
const labelList& curPoints = curFace;
// For all points
forAll(curPoints, pointI)
{
// dGget the list of cells sharing this point
const labelList& curNeighbours =
PointCells[curPoints[pointI]];
// For all neighbours
forAll(curNeighbours, neiI)
{
label curNei = curNeighbours[neiI];
// Reject neighbours with the lower label
if (curNei > cellI)
{
// Get the list of search faces
const faceList& searchFaces = cellsFaceShapes[curNei];
forAll(searchFaces, neiFaceI)
{
if (searchFaces[neiFaceI] == curFace)
{
// Match!!
found = true;
// Record the neighbour cell and face
neiCells[faceI] = curNei;
faceOfNeiCell[faceI] = neiFaceI;
nNeighbours++;
break;
}
}
if (found) break;
}
if (found) break;
}
if (found) break;
} // End of current points
} // End of current faces
// Add the faces in the increasing order of neighbours
for (label neiSearch = 0; neiSearch < nNeighbours; neiSearch++)
{
// Find the lowest neighbour which is still valid
label nextNei = -1;
label minNei = cells.size();
forAll(neiCells, ncI)
{
if (neiCells[ncI] > -1 && neiCells[ncI] < minNei)
{
nextNei = ncI;
minNei = neiCells[ncI];
}
}
if (nextNei > -1)
{
// Add the face to the list of faces
faces_[nFaces] = curFaces[nextNei];
// Set cell-face and cell-neighbour-face to current face label
cells[cellI][nextNei] = nFaces;
cells[neiCells[nextNei]][faceOfNeiCell[nextNei]] = nFaces;
// Stop the neighbour from being used again
neiCells[nextNei] = -1;
// Increment number of faces counter
nFaces++;
}
else
{
FatalErrorIn
(
"polyMesh::polyMesh\n"
"(\n"
" const IOobject&,\n"
" const Xfer<pointField>&,\n"
" const cellShapeList& cellsAsShapes,\n"
" const faceListList& boundaryFaces,\n"
" const wordList& boundaryPatchTypes,\n"
" const wordList& boundaryPatchNames,\n"
" const word& defaultBoundaryPatchType\n"
")"
) << "Error in internal face insertion"
<< abort(FatalError);
}
}
}
// Do boundary faces
labelList patchSizes(boundaryFaces.size(), -1);
labelList patchStarts(boundaryFaces.size(), -1);
forAll(boundaryFaces, patchI)
{
const faceList& patchFaces = boundaryFaces[patchI];
labelList curPatchFaceCells =
facePatchFaceCells
(
patchFaces,
PointCells,
cellsFaceShapes,
patchI
);
// Grab the start label
label curPatchStart = nFaces;
forAll(patchFaces, faceI)
{
const face& curFace = patchFaces[faceI];
const label cellInside = curPatchFaceCells[faceI];
faces_[nFaces] = curFace;
// get faces of the cell inside
const faceList& facesOfCellInside = cellsFaceShapes[cellInside];
bool found = false;
forAll(facesOfCellInside, cellFaceI)
{
if (facesOfCellInside[cellFaceI] == curFace)
{
if (cells[cellInside][cellFaceI] >= 0)
{
FatalErrorIn
(
"polyMesh::polyMesh\n"
"(\n"
" const IOobject&,\n"
" const Xfer<pointField>&,\n"
" const cellShapeList& cellsAsShapes,\n"
" const faceListList& boundaryFaces,\n"
" const wordList& boundaryPatchTypes,\n"
" const wordList& boundaryPatchNames,\n"
" const word& defaultBoundaryPatchType\n"
")"
) << "Trying to specify a boundary face " << curFace
<< " on the face on cell " << cellInside
<< " which is either an internal face or already "
<< "belongs to some other patch. This is face "
<< faceI << " of patch "
<< patchI << " named "
<< boundaryPatchNames[patchI] << "."
<< abort(FatalError);
}
found = true;
cells[cellInside][cellFaceI] = nFaces;
break;
}
}
if (!found)
{
FatalErrorIn("polyMesh::polyMesh(... construct from shapes...)")
<< "face " << faceI << " of patch " << patchI
<< " does not seem to belong to cell " << cellInside
<< " which, according to the addressing, "
<< "should be next to it."
<< abort(FatalError);
}
// increment the counter of faces
nFaces++;
}
patchSizes[patchI] = nFaces - curPatchStart;
patchStarts[patchI] = curPatchStart;
}
// Grab "non-existing" faces and put them into a default patch
label defaultPatchStart = nFaces;
forAll(cells, cellI)
{
labelList& curCellFaces = cells[cellI];
forAll(curCellFaces, faceI)
{
if (curCellFaces[faceI] == -1) // "non-existent" face
{
curCellFaces[faceI] = nFaces;
faces_[nFaces] = cellsFaceShapes[cellI][faceI];
nFaces++;
}
}
}
// Reset the size of the face list
faces_.setSize(nFaces);
// Warning: Patches can only be added once the face list is // Warning: Patches can only be added once the face list is
// completed, as they hold a subList of the face list // completed, as they hold a subList of the face list
@ -654,4 +691,275 @@ Foam::polyMesh::polyMesh
} }
Foam::polyMesh::polyMesh
(
const IOobject& io,
const Xfer<pointField>& points,
const cellShapeList& cellsAsShapes,
const faceListList& boundaryFaces,
const PtrList<dictionary>& boundaryDicts,
const word& defaultBoundaryPatchName,
const word& defaultBoundaryPatchType,
const bool syncPar
)
:
objectRegistry(io),
primitiveMesh(),
points_
(
IOobject
(
"points",
instance(),
meshSubDir,
*this,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
points
),
faces_
(
IOobject
(
"faces",
instance(),
meshSubDir,
*this,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
0
),
owner_
(
IOobject
(
"owner",
instance(),
meshSubDir,
*this,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
0
),
neighbour_
(
IOobject
(
"neighbour",
instance(),
meshSubDir,
*this,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
0
),
clearedPrimitives_(false),
boundary_
(
IOobject
(
"boundary",
instance(),
meshSubDir,
*this,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
*this,
boundaryFaces.size() + 1 // add room for a default patch
),
bounds_(points_, syncPar),
geometricD_(Vector<label>::zero),
solutionD_(Vector<label>::zero),
pointZones_
(
IOobject
(
"pointZones",
instance(),
meshSubDir,
*this,
IOobject::NO_READ,
IOobject::NO_WRITE
),
*this,
0
),
faceZones_
(
IOobject
(
"faceZones",
instance(),
meshSubDir,
*this,
IOobject::NO_READ,
IOobject::NO_WRITE
),
*this,
0
),
cellZones_
(
IOobject
(
"cellZones",
instance(),
meshSubDir,
*this,
IOobject::NO_READ,
IOobject::NO_WRITE
),
*this,
0
),
globalMeshDataPtr_(NULL),
moving_(false),
curMotionTimeIndex_(time().timeIndex()),
oldPointsPtr_(NULL)
{
if (debug)
{
Info<<"Constructing polyMesh from cell and boundary shapes." << endl;
}
// Remove all of the old mesh files if they exist
removeFiles(instance());
wordList boundaryPatchNames(boundaryDicts.size());
forAll(boundaryDicts, patchI)
{
boundaryDicts[patchI].lookup("name") >> boundaryPatchNames[patchI];
}
// Calculate faces and cells
labelList patchSizes;
labelList patchStarts;
label defaultPatchStart;
label nFaces;
cellList cells;
setTopology
(
cellsAsShapes,
boundaryFaces,
boundaryPatchNames,
patchSizes,
patchStarts,
defaultPatchStart,
nFaces,
cells
);
// Warning: Patches can only be added once the face list is
// completed, as they hold a subList of the face list
forAll (boundaryFaces, patchI)
{
dictionary patchDict(boundaryDicts[patchI]);
patchDict.set("nFaces", patchSizes[patchI]);
patchDict.set("startFace", patchStarts[patchI]);
// add the patch to the list
boundary_.set
(
patchI,
polyPatch::New
(
boundaryPatchNames[patchI],
patchDict,
patchI,
boundary_
)
);
}
label nAllPatches = boundaryFaces.size();
if (nFaces > defaultPatchStart)
{
WarningIn("polyMesh::polyMesh(... construct from shapes...)")
<< "Found " << nFaces - defaultPatchStart
<< " undefined faces in mesh; adding to default patch." << endl;
// Check if there already exists a defaultFaces patch as last patch
// and reuse it.
label patchI = findIndex(boundaryPatchNames, defaultBoundaryPatchName);
if (patchI != -1)
{
if (patchI != boundaryFaces.size()-1 || boundary_[patchI].size())
{
FatalErrorIn("polyMesh::polyMesh(... construct from shapes...)")
<< "Default patch " << boundary_[patchI].name()
<< " already has faces in it or is not"
<< " last in list of patches." << exit(FatalError);
}
WarningIn("polyMesh::polyMesh(... construct from shapes...)")
<< "Reusing existing patch " << patchI
<< " for undefined faces." << endl;
boundary_.set
(
patchI,
polyPatch::New
(
boundary_[patchI].type(),
boundary_[patchI].name(),
nFaces - defaultPatchStart,
defaultPatchStart,
patchI,
boundary_
)
);
}
else
{
boundary_.set
(
nAllPatches,
polyPatch::New
(
defaultBoundaryPatchType,
defaultBoundaryPatchName,
nFaces - defaultPatchStart,
defaultPatchStart,
boundary_.size() - 1,
boundary_
)
);
nAllPatches++;
}
}
// Reset the size of the boundary
boundary_.setSize(nAllPatches);
// Set the primitive mesh
initMesh(cells);
if (syncPar)
{
// Calculate topology for the patches (processor-processor comms etc.)
boundary_.updateMesh();
// Calculate the geometry for the patches (transformation tensors etc.)
boundary_.calcGeometry();
}
if (debug)
{
if (checkMesh())
{
Info << "Mesh OK" << endl;
}
}
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -111,23 +111,6 @@ void Foam::coupledPolyPatch::writeOBJ
} }
Foam::pointField Foam::coupledPolyPatch::calcFaceCentres
(
const UList<face>& faces,
const pointField& points
)
{
pointField ctrs(faces.size());
forAll(faces, faceI)
{
ctrs[faceI] = faces[faceI].centre(points);
}
return ctrs;
}
Foam::pointField Foam::coupledPolyPatch::getAnchorPoints Foam::pointField Foam::coupledPolyPatch::getAnchorPoints
( (
const UList<face>& faces, const UList<face>& faces,
@ -145,43 +128,6 @@ Foam::pointField Foam::coupledPolyPatch::getAnchorPoints
} }
bool Foam::coupledPolyPatch::inPatch
(
const labelList& oldToNew,
const label oldFaceI
) const
{
label faceI = oldToNew[oldFaceI];
return faceI >= start() && faceI < start()+size();
}
Foam::label Foam::coupledPolyPatch::whichPatch
(
const labelList& patchStarts,
const label faceI
)
{
forAll(patchStarts, patchI)
{
if (patchStarts[patchI] <= faceI)
{
if (patchI == patchStarts.size()-1)
{
return patchI;
}
else if (patchStarts[patchI+1] > faceI)
{
return patchI;
}
}
}
return -1;
}
Foam::scalarField Foam::coupledPolyPatch::calcFaceTol Foam::scalarField Foam::coupledPolyPatch::calcFaceTol
( (
const UList<face>& faces, const UList<face>& faces,
@ -266,7 +212,8 @@ 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 << " smallDist min:" << min(smallDist) << nl
<< " smallDist max:" << max(smallDist) << nl
<< " sum(mag(nf & nr)):" << sum(mag(nf & nr)) << endl; << " sum(mag(nf & nr)):" << sum(mag(nf & nr)) << endl;
} }
@ -278,7 +225,7 @@ void Foam::coupledPolyPatch::calcTransformTensors
// Then the overall error of summing the normals is sqrt(size())*absTol // Then the overall error of summing the normals is sqrt(size())*absTol
// - separation calculation: pass in from the outside an allowable error. // - separation calculation: pass in from the outside an allowable error.
if (size() == 0) if (Cf.size() == 0)
{ {
// Dummy geometry. // Dummy geometry.
separation_.setSize(0); separation_.setSize(0);

View File

@ -38,6 +38,7 @@ SourceFiles
#define coupledPolyPatch_H #define coupledPolyPatch_H
#include "polyPatch.H" #include "polyPatch.H"
#include "diagTensorField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -133,13 +134,6 @@ protected:
label& vertI label& vertI
); );
//- Calculate face centres
static pointField calcFaceCentres
(
const UList<face>&,
const pointField&
);
//- Get f[0] for all faces //- Get f[0] for all faces
static pointField getAnchorPoints static pointField getAnchorPoints
( (
@ -147,21 +141,6 @@ protected:
const pointField& const pointField&
); );
//- Is face (in old face labels) in current patch?
bool inPatch
(
const labelList& oldToNew,
const label oldFaceI
) const;
//- Given list of starts of patches and a face label determine
// the patch.
static label whichPatch
(
const labelList& patchStarts,
const label faceI
);
//- Calculate typical tolerance per face. Is currently max distance //- Calculate typical tolerance per face. Is currently max distance
// from face centre to any of the face vertices. // from face centre to any of the face vertices.
static scalarField calcFaceTol static scalarField calcFaceTol
@ -248,45 +227,67 @@ public:
return true; return true;
} }
//- Does this side own the patch ?
virtual bool owner() const = 0;
//- Are the coupled planes separated //- Does the coupled side own the patch ?
bool separated() const virtual bool neighbour() const
{
return !owner();
}
//- Transform a patch-based position from other side to this side
virtual void transformPosition(pointField& l) const = 0;
//- Are the planes separated.
virtual bool separated() const
{ {
return separation_.size(); return separation_.size();
} }
//- Return the offset (distance) vector from one side of the couple //- If the planes are separated the separation vector.
// to the other virtual const vectorField& separation() const
const vectorField& separation() const
{ {
return separation_; return separation_;
} }
//- Are the cyclic planes parallel //- Are the cyclic planes parallel.
bool parallel() const virtual bool parallel() const
{ {
return forwardT_.empty(); return forwardT_.empty();
} }
//- Return face transformation tensor //- Return face transformation tensor.
const tensorField& forwardT() const virtual const tensorField& forwardT() const
{ {
return forwardT_; return forwardT_;
} }
//- Return neighbour-cell transformation tensor //- Return neighbour-cell transformation tensor.
const tensorField& reverseT() const virtual const tensorField& reverseT() const
{ {
return reverseT_; return reverseT_;
} }
//- Are faces collocated. Either size 0,1 or length of patch //- Are faces collocated. Either size 0,1 or length of patch
const boolList& collocated() const virtual const boolList& collocated() const
{ {
return collocated_; return collocated_;
} }
//- Calculate the patch geometry
virtual void calcGeometry
(
const primitivePatch& referPatch,
const UList<point>& thisCtrs,
const UList<point>& thisAreas,
const UList<point>& thisCc,
const UList<point>& nbrCtrs,
const UList<point>& nbrAreas,
const UList<point>& nbrCc
) = 0;
//- Initialize ordering for primitivePatch. Does not //- Initialize ordering for primitivePatch. Does not
// refer to *this (except for name() and type() etc.) // refer to *this (except for name() and type() etc.)
virtual void initOrder virtual void initOrder

View File

@ -29,11 +29,10 @@ Description
Note: morph patch face ordering uses geometric matching so with the Note: morph patch face ordering uses geometric matching so with the
following restrictions: following restrictions:
-halves should be flat planes. -coupled patches should be flat planes.
-no rotation in patch plane -no rotation in patch plane
Uses a featureCos to find the two halves (or should be fully Uses coupledPolyPatch::calcFaceTol to calculate
disconnected). Uses coupledPolyPatch::calcFaceTol to calculate
tolerance per face which might need tweaking. tolerance per face which might need tweaking.
Switch on 'cyclicPolyPatch' debug flag to write .obj files to show Switch on 'cyclicPolyPatch' debug flag to write .obj files to show
@ -48,10 +47,9 @@ SourceFiles
#define cyclicPolyPatch_H #define cyclicPolyPatch_H
#include "coupledPolyPatch.H" #include "coupledPolyPatch.H"
#include "SubField.H"
#include "FixedList.H"
#include "edgeList.H" #include "edgeList.H"
#include "transform.H" #include "polyBoundaryMesh.H"
#include "diagTensorField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -82,18 +80,11 @@ private:
// Private data // Private data
//- List of edges formed from connected points. e[0] is the point on //- Name of other half
// the first half of the patch, e[1] the corresponding point on the const word neighbPatchName_;
// second half.
mutable edgeList* coupledPointsPtr_;
//- List of connected edges. e[0] is the edge on the first half of the //- Index of other half
// patch, e[1] the corresponding edge on the second half. mutable label neighbPatchID_;
mutable edgeList* coupledEdgesPtr_;
//- Morph:angle between normals of neighbouring faces.
// Used to split cyclic into halves.
scalar featureCos_;
//- Type of transformation - rotational or translational //- Type of transformation - rotational or translational
transformType transform_; transformType transform_;
@ -112,60 +103,50 @@ private:
vector separationVector_; vector separationVector_;
//- List of edges formed from connected points. e[0] is the point on
// the first half of the patch, e[1] the corresponding point on the
// second half.
mutable edgeList* coupledPointsPtr_;
//- List of connected edges. e[0] is the edge on the first half of the
// patch, e[1] the corresponding edge on the second half.
mutable edgeList* coupledEdgesPtr_;
//- Temporary storage of owner side patch during ordering.
mutable autoPtr<primitivePatch> ownerPatchPtr_;
// Private Member Functions // Private Member Functions
//- Find amongst selected faces the one with the largest area //- Find amongst selected faces the one with the largest area
static label findMaxArea(const pointField&, const faceList&); static label findMaxArea(const pointField&, const faceList&);
void calcTransforms
(
const primitivePatch& half0,
const UList<point>& half0Ctrs,
const UList<point>& half0Areas,
const UList<point>& half1Ctrs,
const UList<point>& half1Areas
);
// Face ordering // Face ordering
//- Find the two parts of the faces of pp using feature edges.
// Returns true if successfull.
bool getGeometricHalves
(
const primitivePatch&,
labelList&,
labelList&
) const;
//- Calculate geometric factors of the two halves. //- Calculate geometric factors of the two halves.
void getCentresAndAnchors void getCentresAndAnchors
( (
const primitivePatch&, const primitivePatch& pp0,
const faceList& half0Faces, const primitivePatch& pp1,
const faceList& half1Faces,
pointField& ppPoints,
pointField& half0Ctrs, pointField& half0Ctrs,
pointField& half1Ctrs, pointField& half1Ctrs,
pointField& anchors0, pointField& anchors0,
scalarField& tols scalarField& tols
) const; ) const;
//- Given matched faces matches the anchor point. Sets faceMap,
// rotation. Returns true if all matched.
bool matchAnchors
(
const bool report,
const primitivePatch&,
const labelList&,
const pointField&,
const labelList&,
const faceList&,
const labelList&,
const scalarField&,
labelList& faceMap,
labelList& rotation
) const;
//- For rotational cases, try to find a unique face on each side //- For rotational cases, try to find a unique face on each side
// of the cyclic. // of the cyclic.
label getConsistentRotationFace label getConsistentRotationFace(const pointField&) const;
(
const pointField& faceCentres
) const;
protected: protected:
@ -178,9 +159,30 @@ protected:
//- Initialise the calculation of the patch geometry //- Initialise the calculation of the patch geometry
virtual void initGeometry(PstreamBuffers&); virtual void initGeometry(PstreamBuffers&);
//- Initialise the calculation of the patch geometry
virtual void initGeometry
(
const primitivePatch& referPatch,
UList<point>& nbrCtrs,
UList<point>& nbrAreas,
UList<point>& nbrCc
);
//- Calculate the patch geometry //- Calculate the patch geometry
virtual void calcGeometry(PstreamBuffers&); virtual void calcGeometry(PstreamBuffers&);
//- Calculate the patch geometry
virtual void calcGeometry
(
const primitivePatch& referPatch,
const UList<point>& thisCtrs,
const UList<point>& thisAreas,
const UList<point>& thisCc,
const UList<point>& nbrCtrs,
const UList<point>& nbrAreas,
const UList<point>& nbrCc
);
//- Initialise the patches for moving points //- Initialise the patches for moving points
virtual void initMovePoints(PstreamBuffers&, const pointField&); virtual void initMovePoints(PstreamBuffers&, const pointField&);
@ -231,7 +233,8 @@ public:
const polyBoundaryMesh& bm, const polyBoundaryMesh& bm,
const label index, const label index,
const label newSize, const label newSize,
const label newStart const label newStart,
const word& neighbPatchName
); );
//- Construct given the original patch and a map //- Construct given the original patch and a map
@ -262,7 +265,15 @@ public:
{ {
return autoPtr<polyPatch> return autoPtr<polyPatch>
( (
new cyclicPolyPatch(*this, bm, index, newSize, newStart) new cyclicPolyPatch
(
*this,
bm,
index,
newSize,
newStart,
neighbPatchName_
)
); );
} }
@ -289,103 +300,107 @@ public:
// Member Functions // Member Functions
//- Return connected points (in patch local point indexing). Demand const word& neighbPatchName() const
// driven calculation. Does primitivePatch::clearOut after calculation! {
return neighbPatchName_;
}
//- Neighbour patchID.
virtual label neighbPatchID() const
{
if (neighbPatchID_ == -1)
{
neighbPatchID_ = this->boundaryMesh().findPatchID
(
neighbPatchName_
);
if (neighbPatchID_ == -1)
{
FatalErrorIn("cyclicPolyPatch::neighbPatchID() const")
<< "Illegal neighbourPatch name " << neighbPatchName_
<< endl << "Valid patch names are "
<< this->boundaryMesh().names()
<< exit(FatalError);
}
}
return neighbPatchID_;
}
virtual bool owner() const
{
return index() < neighbPatchID();
}
virtual bool neighbour() const
{
return !owner();
}
const cyclicPolyPatch& neighbPatch() const
{
const polyPatch& pp = this->boundaryMesh()[neighbPatchID()];
return refCast<const cyclicPolyPatch>(pp);
}
//- Return connected points (from patch local to neighbour patch local)
// Demand driven calculation. Does primitivePatch::clearOut after
// calculation!
const edgeList& coupledPoints() const; const edgeList& coupledPoints() const;
//- Return connected edges (in patch local edge indexing). Demand //- Return connected edges (from patch local to neighbour patch local).
// driven calculation. Does primitivePatch::clearOut after calculation! // Demand driven calculation. Does primitivePatch::clearOut after
// calculation!
const edgeList& coupledEdges() const; const edgeList& coupledEdges() const;
//- Transform a patch-based position from other side to this side
virtual void transformPosition(pointField& l) const;
// Transformation // Transformation
vector separation(const label facei) const label transformGlobalFace(const label facei) const
{ {
if (facei < size()/2) label offset = facei-start();
{ label neighbStart = neighbPatch().start();
return coupledPolyPatch::separation()[0];
}
else
{
return -coupledPolyPatch::separation()[0];
}
}
const tensor& transformT(const label facei) const if (offset >= 0 && offset < size())
{ {
if (facei < size()/2) return neighbStart+offset;
{
return reverseT()[0];
}
else
{
return forwardT()[0];
}
} }
else
template<class T>
T transform(const T& t, const label facei) const
{ {
if (parallel()) FatalErrorIn
{ (
return t; "cyclicPolyPatch::transformGlobalFace(const label) const"
} ) << "Face " << facei << " not in patch " << name()
else << exit(FatalError);
{ return -1;
return Foam::transform(transformT(facei), t);
}
} }
}
label transformLocalFace(const label facei) const //- Type of transform
{ transformType transform() const
if (facei < size()/2) {
{ return transform_;
return facei + size()/2; }
}
else
{
return facei - size()/2;
}
}
label transformGlobalFace(const label facei) const //- Axis of rotation for rotational cyclics
{ const vector& rotationAxis() const
if (facei - start() < size()/2) {
{ return rotationAxis_;
return facei + size()/2; }
}
else
{
return facei - size()/2;
}
}
//- Type of transform //- point on axis of rotation for rotational cyclics
transformType transform() const const point& rotationCentre() const
{ {
return transform_; return rotationCentre_;
} }
//- 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_;
}
//- Translation vector for translational cyclics
const vector& separationVector() const
{
return separationVector_;
}
//- Initialize ordering for primitivePatch. Does not //- Initialize ordering for primitivePatch. Does not

View File

@ -62,9 +62,9 @@ Foam::processorPolyPatch::processorPolyPatch
neighbProcNo_(neighbProcNo), neighbProcNo_(neighbProcNo),
neighbFaceCentres_(), neighbFaceCentres_(),
neighbFaceAreas_(), neighbFaceAreas_(),
neighbFaceCellCentres_(), neighbFaceCellCentres_()
neighbPointsPtr_(NULL), // neighbPointsPtr_(NULL),
neighbEdgesPtr_(NULL) // neighbEdgesPtr_(NULL)
{} {}
@ -81,9 +81,9 @@ Foam::processorPolyPatch::processorPolyPatch
neighbProcNo_(readLabel(dict.lookup("neighbProcNo"))), neighbProcNo_(readLabel(dict.lookup("neighbProcNo"))),
neighbFaceCentres_(), neighbFaceCentres_(),
neighbFaceAreas_(), neighbFaceAreas_(),
neighbFaceCellCentres_(), neighbFaceCellCentres_()
neighbPointsPtr_(NULL), // neighbPointsPtr_(NULL),
neighbEdgesPtr_(NULL) // neighbEdgesPtr_(NULL)
{} {}
@ -98,9 +98,9 @@ Foam::processorPolyPatch::processorPolyPatch
neighbProcNo_(pp.neighbProcNo_), neighbProcNo_(pp.neighbProcNo_),
neighbFaceCentres_(), neighbFaceCentres_(),
neighbFaceAreas_(), neighbFaceAreas_(),
neighbFaceCellCentres_(), neighbFaceCellCentres_()
neighbPointsPtr_(NULL), // neighbPointsPtr_(NULL),
neighbEdgesPtr_(NULL) // neighbEdgesPtr_(NULL)
{} {}
@ -118,9 +118,9 @@ Foam::processorPolyPatch::processorPolyPatch
neighbProcNo_(pp.neighbProcNo_), neighbProcNo_(pp.neighbProcNo_),
neighbFaceCentres_(), neighbFaceCentres_(),
neighbFaceAreas_(), neighbFaceAreas_(),
neighbFaceCellCentres_(), neighbFaceCellCentres_()
neighbPointsPtr_(NULL), // neighbPointsPtr_(NULL),
neighbEdgesPtr_(NULL) // neighbEdgesPtr_(NULL)
{} {}
@ -129,7 +129,7 @@ Foam::processorPolyPatch::processorPolyPatch
const processorPolyPatch& pp, const processorPolyPatch& pp,
const polyBoundaryMesh& bm, const polyBoundaryMesh& bm,
const label index, const label index,
const unallocLabelList& mapAddressing, const unallocLabelList& mapAddressing,
const label newStart const label newStart
) )
: :
@ -138,9 +138,9 @@ Foam::processorPolyPatch::processorPolyPatch
neighbProcNo_(pp.neighbProcNo_), neighbProcNo_(pp.neighbProcNo_),
neighbFaceCentres_(), neighbFaceCentres_(),
neighbFaceAreas_(), neighbFaceAreas_(),
neighbFaceCellCentres_(), neighbFaceCellCentres_()
neighbPointsPtr_(NULL), // neighbPointsPtr_(NULL),
neighbEdgesPtr_(NULL) // neighbEdgesPtr_(NULL)
{} {}
@ -148,8 +148,8 @@ Foam::processorPolyPatch::processorPolyPatch
Foam::processorPolyPatch::~processorPolyPatch() Foam::processorPolyPatch::~processorPolyPatch()
{ {
deleteDemandDrivenData(neighbPointsPtr_); neighbPointsPtr_.clear();
deleteDemandDrivenData(neighbEdgesPtr_); neighbEdgesPtr_.clear();
} }
@ -157,6 +157,7 @@ Foam::processorPolyPatch::~processorPolyPatch()
void Foam::processorPolyPatch::initGeometry(PstreamBuffers& pBufs) void Foam::processorPolyPatch::initGeometry(PstreamBuffers& pBufs)
{ {
//Pout<< "**processorPolyPatch::initGeometry()" << endl;
if (Pstream::parRun()) if (Pstream::parRun())
{ {
UOPstream toNeighbProc(neighbProcNo(), pBufs); UOPstream toNeighbProc(neighbProcNo(), pBufs);
@ -171,6 +172,7 @@ void Foam::processorPolyPatch::initGeometry(PstreamBuffers& pBufs)
void Foam::processorPolyPatch::calcGeometry(PstreamBuffers& pBufs) void Foam::processorPolyPatch::calcGeometry(PstreamBuffers& pBufs)
{ {
//Pout<< "processorPolyPatch::calcGeometry() for " << name() << endl;
if (Pstream::parRun()) if (Pstream::parRun())
{ {
{ {
@ -182,6 +184,9 @@ void Foam::processorPolyPatch::calcGeometry(PstreamBuffers& pBufs)
>> neighbFaceCellCentres_; >> neighbFaceCellCentres_;
} }
//Pout<< "processorPolyPatch::calcGeometry() : received data for "
// << neighbFaceCentres_.size() << " faces." << endl;
// My normals // My normals
vectorField faceNormals(size()); vectorField faceNormals(size());
@ -247,6 +252,9 @@ void Foam::processorPolyPatch::calcGeometry(PstreamBuffers& pBufs)
nbrFaceNormals, nbrFaceNormals,
calcFaceTol(*this, points(), faceCentres()) calcFaceTol(*this, points(), faceCentres())
); );
//Pout<< "**neighbFaceCentres_:" << neighbFaceCentres_ << endl;
//Pout<< "**neighbFaceAreas_:" << neighbFaceAreas_ << endl;
//Pout<< "**neighbFaceCellCentres_:" << neighbFaceCellCentres_ << endl;
} }
} }
@ -276,9 +284,6 @@ void Foam::processorPolyPatch::initUpdateMesh(PstreamBuffers& pBufs)
{ {
polyPatch::initUpdateMesh(pBufs); polyPatch::initUpdateMesh(pBufs);
deleteDemandDrivenData(neighbPointsPtr_);
deleteDemandDrivenData(neighbEdgesPtr_);
if (Pstream::parRun()) if (Pstream::parRun())
{ {
// Express all points as patch face and index in face. // Express all points as patch face and index in face.
@ -327,6 +332,9 @@ void Foam::processorPolyPatch::updateMesh(PstreamBuffers& pBufs)
// For completeness // For completeness
polyPatch::updateMesh(pBufs); polyPatch::updateMesh(pBufs);
neighbPointsPtr_.clear();
neighbEdgesPtr_.clear();
if (Pstream::parRun()) if (Pstream::parRun())
{ {
labelList nbrPointFace; labelList nbrPointFace;
@ -352,8 +360,8 @@ void Foam::processorPolyPatch::updateMesh(PstreamBuffers& pBufs)
// Convert points. // Convert points.
// ~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~
neighbPointsPtr_ = new labelList(nPoints(), -1); neighbPointsPtr_.reset(new labelList(nPoints(), -1));
labelList& neighbPoints = *neighbPointsPtr_; labelList& neighbPoints = neighbPointsPtr_();
forAll(nbrPointFace, nbrPointI) forAll(nbrPointFace, nbrPointI)
{ {
@ -386,8 +394,8 @@ void Foam::processorPolyPatch::updateMesh(PstreamBuffers& pBufs)
// Convert edges. // Convert edges.
// ~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~
neighbEdgesPtr_ = new labelList(nEdges(), -1); neighbEdgesPtr_.reset(new labelList(nEdges(), -1));
labelList& neighbEdges = *neighbEdgesPtr_; labelList& neighbEdges = neighbEdgesPtr_();
forAll(nbrEdgeFace, nbrEdgeI) forAll(nbrEdgeFace, nbrEdgeI)
{ {
@ -425,25 +433,25 @@ void Foam::processorPolyPatch::updateMesh(PstreamBuffers& pBufs)
const Foam::labelList& Foam::processorPolyPatch::neighbPoints() const const Foam::labelList& Foam::processorPolyPatch::neighbPoints() const
{ {
if (!neighbPointsPtr_) if (!neighbPointsPtr_.valid())
{ {
FatalErrorIn("processorPolyPatch::neighbPoints() const") FatalErrorIn("processorPolyPatch::neighbPoints() const")
<< "No extended addressing calculated for patch " << name() << "No extended addressing calculated for patch " << name()
<< abort(FatalError); << abort(FatalError);
} }
return *neighbPointsPtr_; return neighbPointsPtr_();
} }
const Foam::labelList& Foam::processorPolyPatch::neighbEdges() const const Foam::labelList& Foam::processorPolyPatch::neighbEdges() const
{ {
if (!neighbEdgesPtr_) if (!neighbEdgesPtr_.valid())
{ {
FatalErrorIn("processorPolyPatch::neighbEdges() const") FatalErrorIn("processorPolyPatch::neighbEdges() const")
<< "No extended addressing calculated for patch " << name() << "No extended addressing calculated for patch " << name()
<< abort(FatalError); << abort(FatalError);
} }
return *neighbEdgesPtr_; return neighbEdgesPtr_();
} }
@ -470,7 +478,7 @@ void Foam::processorPolyPatch::initOrder
writeOBJ(nm, pp, pp.points()); writeOBJ(nm, pp, pp.points());
// Calculate my face centres // Calculate my face centres
pointField ctrs(calcFaceCentres(pp, pp.points())); const pointField& fc = pp.faceCentres();
OFstream localStr OFstream localStr
( (
@ -478,26 +486,22 @@ void Foam::processorPolyPatch::initOrder
/name() + "_localFaceCentres.obj" /name() + "_localFaceCentres.obj"
); );
Pout<< "processorPolyPatch::order : " Pout<< "processorPolyPatch::order : "
<< "Dumping " << ctrs.size() << "Dumping " << fc.size()
<< " local faceCentres to " << localStr.name() << endl; << " local faceCentres to " << localStr.name() << endl;
forAll(ctrs, faceI) forAll(fc, faceI)
{ {
writeOBJ(localStr, ctrs[faceI]); writeOBJ(localStr, fc[faceI]);
} }
} }
const bool isMaster = Pstream::myProcNo() < neighbProcNo(); if (owner())
if (isMaster)
{ {
pointField ctrs(calcFaceCentres(pp, pp.points()));
pointField anchors(getAnchorPoints(pp, pp.points())); pointField anchors(getAnchorPoints(pp, pp.points()));
// Now send all info over to the neighbour // Now send all info over to the neighbour
UOPstream toNeighbour(neighbProcNo(), pBufs); UOPstream toNeighbour(neighbProcNo(), pBufs);
toNeighbour << ctrs << anchors; toNeighbour << pp.faceCentres() << anchors;
} }
} }
@ -514,6 +518,8 @@ bool Foam::processorPolyPatch::order
labelList& rotation labelList& rotation
) const ) const
{ {
// Note: we only get the faces that originate from internal faces.
if (!Pstream::parRun()) if (!Pstream::parRun())
{ {
return false; return false;
@ -525,9 +531,7 @@ bool Foam::processorPolyPatch::order
rotation.setSize(pp.size()); rotation.setSize(pp.size());
rotation = 0; rotation = 0;
const bool isMaster = Pstream::myProcNo() < neighbProcNo(); if (owner())
if (isMaster)
{ {
// Do nothing (i.e. identical mapping, zero rotation). // Do nothing (i.e. identical mapping, zero rotation).
// See comment at top. // See comment at top.
@ -549,11 +553,8 @@ bool Foam::processorPolyPatch::order
fromNeighbour >> masterCtrs >> masterAnchors; fromNeighbour >> masterCtrs >> masterAnchors;
} }
// Calculate my face centres
pointField ctrs(calcFaceCentres(pp, pp.points()));
// Calculate typical distance from face centre // Calculate typical distance from face centre
scalarField tols(calcFaceTol(pp, pp.points(), ctrs)); scalarField tols(calcFaceTol(pp, pp.points(), pp.faceCentres()));
if (debug || masterCtrs.size() != pp.size()) if (debug || masterCtrs.size() != pp.size())
{ {
@ -591,84 +592,14 @@ bool Foam::processorPolyPatch::order
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 1. Try existing ordering and transformation // 1. Try existing ordering and transformation
bool matchedAll = false; bool matchedAll = matchPoints
if
( (
separated() pp.faceCentres(),
&& (separation().size() == 1 || separation().size() == pp.size()) masterCtrs,
) tols,
{ true,
vectorField transformedCtrs; faceMap
);
const vectorField& v = separation();
if (v.size() == 1)
{
transformedCtrs = masterCtrs-v[0];
}
else
{
transformedCtrs = masterCtrs-v;
}
matchedAll = matchPoints
(
ctrs,
transformedCtrs,
tols,
true,
faceMap
);
if (matchedAll)
{
// Use transformed centers from now on
masterCtrs = transformedCtrs;
// Transform anchors
if (v.size() == 1)
{
masterAnchors -= v[0];
}
else
{
masterAnchors -= v;
}
}
}
else if
(
!parallel()
&& (forwardT().size() == 1 || forwardT().size() == pp.size())
)
{
vectorField transformedCtrs = masterCtrs;
transformList(forwardT(), transformedCtrs);
matchedAll = matchPoints
(
ctrs,
transformedCtrs,
tols,
true,
faceMap
);
if (matchedAll)
{
// Use transformed centers from now on
masterCtrs = transformedCtrs;
// Transform anchors
transformList(forwardT(), masterAnchors);
}
}
// 2. Try zero separation automatic matching
if (!matchedAll)
{
matchedAll = matchPoints(ctrs, masterCtrs, tols, true, faceMap);
}
if (!matchedAll || debug) if (!matchedAll || debug)
{ {
@ -695,14 +626,14 @@ bool Foam::processorPolyPatch::order
label vertI = 0; label vertI = 0;
forAll(ctrs, faceI) forAll(pp.faceCentres(), faceI)
{ {
label masterFaceI = faceMap[faceI]; label masterFaceI = faceMap[faceI];
if (masterFaceI != -1) if (masterFaceI != -1)
{ {
const point& c0 = masterCtrs[masterFaceI]; const point& c0 = masterCtrs[masterFaceI];
const point& c1 = ctrs[faceI]; const point& c1 = pp.faceCentres()[faceI];
writeOBJ(ccStr, c0, c1, vertI); writeOBJ(ccStr, c0, c1, vertI);
} }
} }
@ -718,7 +649,7 @@ bool Foam::processorPolyPatch::order
<< "Cannot match vectors to faces on both sides of patch" << "Cannot match vectors to faces on both sides of patch"
<< endl << endl
<< " masterCtrs[0]:" << masterCtrs[0] << endl << " masterCtrs[0]:" << masterCtrs[0] << endl
<< " ctrs[0]:" << ctrs[0] << endl << " ctrs[0]:" << pp.faceCentres()[0] << endl
<< " Please check your topology changes or maybe you have" << " Please check your topology changes or maybe you have"
<< " multiple separated (from cyclics) processor patches" << " multiple separated (from cyclics) processor patches"
<< endl << endl

View File

@ -40,6 +40,8 @@ SourceFiles
#define processorPolyPatch_H #define processorPolyPatch_H
#include "coupledPolyPatch.H" #include "coupledPolyPatch.H"
#include "polyBoundaryMesh.H"
#include "faceListFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -70,23 +72,11 @@ class processorPolyPatch
//- Corresponding neighbouring local point label for every local point //- Corresponding neighbouring local point label for every local point
// (so localPoints()[i] == neighb.localPoints()[neighbPoints_[i]]) // (so localPoints()[i] == neighb.localPoints()[neighbPoints_[i]])
mutable labelList* neighbPointsPtr_; mutable autoPtr<labelList> neighbPointsPtr_;
//- Corresponding neighbouring local edge label for every local edge //- Corresponding neighbouring local edge label for every local edge
// (so edges()[i] == neighb.edges()[neighbEdges_[i]]) // (so edges()[i] == neighb.edges()[neighbEdges_[i]])
mutable labelList* neighbEdgesPtr_; mutable autoPtr<labelList> neighbEdgesPtr_;
// Private static data
//- Whether to use geometric or topological matching
static bool geometricMatch_;
//- Relative tolerance (for geometric matching only). Is factor of
// maximum edge length per face.
static scalar matchTol_;
protected: protected:
@ -98,6 +88,22 @@ protected:
//- Calculate the patch geometry //- Calculate the patch geometry
void calcGeometry(PstreamBuffers&); void calcGeometry(PstreamBuffers&);
//- Calculate the patch geometry with externally
// provided geometry
virtual void calcGeometry
(
const primitivePatch& referPatch,
const UList<point>& thisCtrs,
const UList<point>& thisAreas,
const UList<point>& thisCc,
const UList<point>& nbrCtrs,
const UList<point>& nbrAreas,
const UList<point>& nbrCc
)
{
notImplemented("processorPolyPatch::calcGeometry(..)");
}
//- Initialise the patches for moving points //- Initialise the patches for moving points
void initMovePoints(PstreamBuffers&, const pointField&); void initMovePoints(PstreamBuffers&, const pointField&);
@ -236,7 +242,7 @@ public:
} }
//- Does the processor own the patch ? //- Does the processor own the patch ?
bool owner() const virtual bool owner() const
{ {
return (myProcNo_ < neighbProcNo_); return (myProcNo_ < neighbProcNo_);
} }
@ -265,16 +271,21 @@ public:
return neighbFaceCellCentres_; return neighbFaceCellCentres_;
} }
//- Return neighbour point labels. This is for my local point (-1 or) //- Return neighbour point labels. WIP.
// the corresponding local point on the other side. It is -1 if
// there are multiple corresponding points on this or the other side
// (can happen for cyclics being converted into proc patches)
const labelList& neighbPoints() const; const labelList& neighbPoints() const;
//- Return neighbour edge labels. This is for my local edge (-1 or) the //- Return neighbour edge labels. WIP.
// corresponding local edge on the other side. See above for -1 cause.
const labelList& neighbEdges() const; const labelList& neighbEdges() const;
//- Return message tag to use for communication
virtual int tag() const
{
return Pstream::msgType();
}
//- Transform a patch-based position from other side to this side
virtual void transformPosition(pointField& l) const
{}
//- Initialize ordering for primitivePatch. Does not //- Initialize ordering for primitivePatch. Does not
// refer to *this (except for name() and type() etc.) // refer to *this (except for name() and type() etc.)

View File

@ -0,0 +1,60 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "processorPolyPatch.H"
#include "transformField.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
void Foam::processorPolyPatch::transform(Field<T>& l) const
{
if (l.size() != size())
{
FatalErrorIn("processorPolyPatch::transform(Field<T>&) const")
<< "Size of field " << l.size() << " differs from patch size "
<< size() << abort(FatalError);
}
forAll(patchIDs_, subI)
{
label patchI = patchIDs_[subI];
if (patchI != -1)
{
// Get field on patch
typename Field<T>::subField subFld(subSlice(l, subI));
refCast<const coupledPolyPatch>
(
boundaryMesh()[patchI]
).transform(subFld);
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,246 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "processorCyclicPolyPatch.H"
#include "addToRunTimeSelectionTable.H"
#include "SubField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(processorCyclicPolyPatch, 0);
addToRunTimeSelectionTable(polyPatch, processorCyclicPolyPatch, dictionary);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::processorCyclicPolyPatch::processorCyclicPolyPatch
(
const word& name,
const label size,
const label start,
const label index,
const polyBoundaryMesh& bm,
const int myProcNo,
const int neighbProcNo,
const word& referPatchName
)
:
processorPolyPatch(name, size, start, index, bm, myProcNo, neighbProcNo),
tag_(UPstream::allocateTag()),
referPatchName_(referPatchName),
referPatchID_(-1)
{}
Foam::processorCyclicPolyPatch::processorCyclicPolyPatch
(
const word& name,
const dictionary& dict,
const label index,
const polyBoundaryMesh& bm
)
:
processorPolyPatch(name, dict, index, bm),
tag_(UPstream::allocateTag()),
referPatchName_(dict.lookup("referPatch")),
referPatchID_(-1)
{}
Foam::processorCyclicPolyPatch::processorCyclicPolyPatch
(
const processorCyclicPolyPatch& pp,
const polyBoundaryMesh& bm
)
:
processorPolyPatch(pp, bm),
tag_(pp.tag_),
referPatchName_(pp.referPatchName()),
referPatchID_(-1)
{}
Foam::processorCyclicPolyPatch::processorCyclicPolyPatch
(
const processorCyclicPolyPatch& pp,
const polyBoundaryMesh& bm,
const label index,
const label newSize,
const label newStart,
const word& referPatchName
)
:
processorPolyPatch(pp, bm, index, newSize, newStart),
tag_(pp.tag_),
referPatchName_(referPatchName),
referPatchID_(-1)
{}
Foam::processorCyclicPolyPatch::processorCyclicPolyPatch
(
const processorCyclicPolyPatch& pp,
const polyBoundaryMesh& bm,
const label index,
const unallocLabelList& mapAddressing,
const label newStart
)
:
processorPolyPatch(pp, bm, index, mapAddressing, newStart),
tag_(pp.tag_),
referPatchName_(pp.referPatchName()),
referPatchID_(-1)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::processorCyclicPolyPatch::~processorCyclicPolyPatch()
{
UPstream::freeTag(tag_);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::processorCyclicPolyPatch::initGeometry(PstreamBuffers& pBufs)
{
// Send over processorPolyPatch data
processorPolyPatch::initGeometry(pBufs);
}
void Foam::processorCyclicPolyPatch::calcGeometry(PstreamBuffers& pBufs)
{
// Receive and initialise processorPolyPatch data
processorPolyPatch::calcGeometry(pBufs);
if (Pstream::parRun())
{
// Where do we store the calculated transformation?
// - on the processor patch?
// - on the underlying cyclic patch?
// - or do we not auto-calculate the transformation but
// have option of reading it.
// Update underlying cyclic
coupledPolyPatch& pp = const_cast<coupledPolyPatch&>(referPatch());
Pout<< "updating geometry on refered patch:" << pp.name() << endl;
pp.calcGeometry
(
*this,
faceCentres(),
faceAreas(),
faceCellCentres(),
neighbFaceCentres(),
neighbFaceAreas(),
neighbFaceCellCentres()
);
}
}
void Foam::processorCyclicPolyPatch::initMovePoints
(
PstreamBuffers& pBufs,
const pointField& p
)
{
// Recalculate geometry
initGeometry(pBufs);
}
void Foam::processorCyclicPolyPatch::movePoints
(
PstreamBuffers& pBufs,
const pointField&
)
{
calcGeometry(pBufs);
}
void Foam::processorCyclicPolyPatch::initUpdateMesh(PstreamBuffers& pBufs)
{
processorPolyPatch::initUpdateMesh(pBufs);
}
void Foam::processorCyclicPolyPatch::updateMesh(PstreamBuffers& pBufs)
{
referPatchID_ = -1;
processorPolyPatch::updateMesh(pBufs);
}
void Foam::processorCyclicPolyPatch::initOrder
(
PstreamBuffers& pBufs,
const primitivePatch& pp
) const
{
// For now use the same algorithm as processorPolyPatch
processorPolyPatch::initOrder(pBufs, pp);
}
// Return new ordering. Ordering is -faceMap: for every face index
// the new face -rotation:for every new face the clockwise shift
// of the original face. Return false if nothing changes (faceMap
// is identity, rotation is 0)
bool Foam::processorCyclicPolyPatch::order
(
PstreamBuffers& pBufs,
const primitivePatch& pp,
labelList& faceMap,
labelList& rotation
) const
{
// For now use the same algorithm as processorPolyPatch
return processorPolyPatch::order(pBufs, pp, faceMap, rotation);
}
void Foam::processorCyclicPolyPatch::write(Ostream& os) const
{
processorPolyPatch::write(os);
os.writeKeyword("referPatch") << referPatchName_
<< token::END_STATEMENT << nl;
}
// ************************************************************************* //

View File

@ -0,0 +1,394 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::processorCyclicPolyPatch
Description
Neighbour processor patch.
Note: morph patch face ordering is geometric.
SourceFiles
processorCyclicPolyPatch.C
\*---------------------------------------------------------------------------*/
#ifndef processorCyclicPolyPatch_H
#define processorCyclicPolyPatch_H
#include "processorPolyPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class processorCyclicPolyPatch Declaration
\*---------------------------------------------------------------------------*/
class processorCyclicPolyPatch
:
public processorPolyPatch
{
// Private data
//- Message tag to use for communication
const int tag_;
//- Name of originating patch
const word referPatchName_;
//- Index of originating patch
mutable label referPatchID_;
// Private member functions
protected:
// Protected Member functions
//- Initialise the calculation of the patch geometry
void initGeometry(PstreamBuffers&);
// //- Initialise the calculation of the patch geometry with externally
// // provided geometry
// virtual void initGeometry
// (
// const primitivePatch& referPatch,
// UList<point>&,
// UList<point>&,
// UList<point>&
// )
// {
// notImplemented("processorCyclicPolyPatch::initGeometry(..)");
// }
//- Calculate the patch geometry
void calcGeometry(PstreamBuffers&);
//- Calculate the patch geometry with externally
// provided geometry
virtual void calcGeometry
(
const primitivePatch& referPatch,
const UList<point>& thisCtrs,
const UList<point>& thisAreas,
const UList<point>& thisCc,
const UList<point>& nbrCtrs,
const UList<point>& nbrAreas,
const UList<point>& nbrCc
)
{
notImplemented("processorCyclicPolyPatch::calcGeometry(..)");
}
//- Initialise the patches for moving points
void initMovePoints(PstreamBuffers&, const pointField&);
//- Correct patches after moving points
void movePoints(PstreamBuffers&, const pointField&);
//- Initialise the update of the patch topology
virtual void initUpdateMesh(PstreamBuffers&);
//- Update of the patch topology
virtual void updateMesh(PstreamBuffers&);
public:
//- Runtime type information
TypeName("processorCyclic");
// Constructors
//- Construct from components
processorCyclicPolyPatch
(
const word& name,
const label size,
const label start,
const label index,
const polyBoundaryMesh& bm,
const int myProcNo,
const int neighbProcNo,
const word& referPatchName
);
//- Construct from dictionary
processorCyclicPolyPatch
(
const word& name,
const dictionary& dict,
const label index,
const polyBoundaryMesh&
);
//- Construct as copy, resetting the boundary mesh
processorCyclicPolyPatch
(
const processorCyclicPolyPatch&,
const polyBoundaryMesh&
);
//- Construct as given the original patch and resetting the
// face list and boundary mesh information
processorCyclicPolyPatch
(
const processorCyclicPolyPatch& pp,
const polyBoundaryMesh& bm,
const label index,
const label newSize,
const label newStart,
const word& referPatchName
);
//- Construct given the original patch and a map
processorCyclicPolyPatch
(
const processorCyclicPolyPatch& pp,
const polyBoundaryMesh& bm,
const label index,
const unallocLabelList& mapAddressing,
const label newStart
);
//- Construct and return a clone, resetting the boundary mesh
virtual autoPtr<polyPatch> clone(const polyBoundaryMesh& bm) const
{
return autoPtr<polyPatch>(new processorCyclicPolyPatch(*this, bm));
}
//- Construct and return a clone, resetting the face list
// and boundary mesh
virtual autoPtr<polyPatch> clone
(
const polyBoundaryMesh& bm,
const label index,
const label newSize,
const label newStart,
const word& referPatchName
) const
{
return autoPtr<polyPatch>
(
new processorCyclicPolyPatch
(
*this,
bm,
index,
newSize,
newStart,
referPatchName
)
);
}
//- Construct and return a clone, resetting the face list
// and boundary mesh
virtual autoPtr<polyPatch> clone
(
const polyBoundaryMesh& bm,
const label index,
const unallocLabelList& mapAddressing,
const label newStart
) const
{
return autoPtr<polyPatch>
(
new processorCyclicPolyPatch
(
*this,
bm,
index,
mapAddressing,
newStart
)
);
}
// Destructor
virtual ~processorCyclicPolyPatch();
// Member functions
const word& referPatchName() const
{
return referPatchName_;
}
//- Referring patchID.
label referPatchID() const
{
if (referPatchID_ == -1)
{
referPatchID_ = this->boundaryMesh().findPatchID
(
referPatchName_
);
if (referPatchID_ == -1)
{
FatalErrorIn
(
"processorCyclicPolyPatch::referPatchID() const"
) << "Illegal referPatch name " << referPatchName_
<< endl << "Valid patch names are "
<< this->boundaryMesh().names()
<< exit(FatalError);
}
}
return referPatchID_;
}
const coupledPolyPatch& referPatch() const
{
const polyPatch& pp = this->boundaryMesh()[referPatchID()];
return refCast<const coupledPolyPatch>(pp);
}
//- Return message tag to use for communication
virtual int tag() const
{
return tag_;
}
//- Does this side own the patch ?
virtual bool owner() const
{
return referPatch().owner();
}
// //- Transform a patch-based field from other side to this side.
// virtual bool doTransform() const
// {
// return referPatch().doTransform();
// }
// virtual void transform(scalarField& l) const
// {
// referPatch().transform(l);
// }
// virtual void transform(vectorField& l) const
// {
// referPatch().transform(l);
// }
// virtual void transform(sphericalTensorField& l) const
// {
// referPatch().transform(l);
// }
// virtual void transform(diagTensorField& l) const
// {
// referPatch().transform(l);
// }
// virtual void transform(symmTensorField& l) const
// {
// referPatch().transform(l);
// }
// virtual void transform(tensorField& l) const
// {
// referPatch().transform(l);
// }
//- Transform a patch-based position from other side to this side
virtual void transformPosition(pointField& l) const
{
referPatch().transformPosition(l);
}
//- Are the planes separated.
virtual bool separated() const
{
return referPatch().separated();
}
//- If the planes are separated the separation vector.
virtual const vectorField& separation() const
{
return referPatch().separation();
}
//- Are the cyclic planes parallel.
virtual bool parallel() const
{
return referPatch().parallel();
}
//- Return face transformation tensor.
virtual const tensorField& forwardT() const
{
return referPatch().forwardT();
}
//- Return neighbour-cell transformation tensor.
virtual const tensorField& reverseT() const
{
return referPatch().reverseT();
}
//- Are faces collocated. Either size 0,1 or length of patch
virtual const boolList& collocated() const
{
return referPatch().collocated();
}
//- Initialize ordering for primitivePatch. Does not
// refer to *this (except for name() and type() etc.)
virtual void initOrder(PstreamBuffers&, const primitivePatch&) const;
//- Return new ordering for primitivePatch.
// Ordering is -faceMap: for every face
// index of the new face -rotation:for every new face the clockwise
// shift of the original face. Return false if nothing changes
// (faceMap is identity, rotation is 0), true otherwise.
virtual bool order
(
PstreamBuffers&,
const primitivePatch&,
labelList& faceMap,
labelList& rotation
) const;
//- Write the polyPatch data as a dictionary
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -87,12 +87,6 @@ class polyPatch
mutable labelList* mePtr_; mutable labelList* mePtr_;
// Private Member Functions
//- Calculate labels of mesh edges
void calcMeshEdges() const;
protected: protected:
// Protected Member Functions // Protected Member Functions

View File

@ -0,0 +1,121 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
InClass
Foam::dummyTransform
Description
Dummy transform to be used with syncTools.
\*---------------------------------------------------------------------------*/
#ifndef dummyTransform_H
#define dummyTransform_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class dummyTransform Declaration
\*---------------------------------------------------------------------------*/
class dummyTransform
{
public:
template<class T>
void operator()(const coupledPolyPatch& cpp, Field<T>& fld) const
{}
template<class T, template<class> class Container>
void operator()(const coupledPolyPatch& cpp, Container<T>& map) const
{}
};
template<class T>
class pTraits<List<T> >
:
public List<T>
{
public:
typedef label cmptType;
pTraits(Istream& is)
:
List<T>(is)
{}
};
template<class T>
class pTraits<UList<T> >
:
public UList<T>
{
public:
typedef label cmptType;
pTraits(Istream& is)
:
UList<T>(is)
{}
};
template<class T>
class pTraits<Field<T> >
:
public Field<T>
{
public:
typedef label cmptType;
pTraits(Istream& is)
:
Field<T>(is)
{}
};
template<>
class pTraits<face>
:
public face
{
public:
typedef label cmptType;
pTraits(Istream& is)
:
face(is)
{}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -28,6 +28,77 @@ License
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
template<>
void Foam::syncTools::transform::operator()
(
const coupledPolyPatch&,
Field<label>&
) const
{}
template<>
void Foam::syncTools::transform::operator()
(
const coupledPolyPatch&,
Map<label>&
) const
{}
template<>
void Foam::syncTools::transform::operator()
(
const coupledPolyPatch&,
EdgeMap<label>&
) const
{}
template<>
void Foam::syncTools::transform::operator()
(
const coupledPolyPatch&,
Field<scalar>&
) const
{}
template<>
void Foam::syncTools::transform::operator()
(
const coupledPolyPatch&,
Map<scalar>&
) const
{}
template<>
void Foam::syncTools::transform::operator()
(
const coupledPolyPatch&,
EdgeMap<scalar>&
) const
{}
template<>
void Foam::syncTools::transform::operator()
(
const coupledPolyPatch&,
Field<bool>&
) const
{}
template<>
void Foam::syncTools::transform::operator()
(
const coupledPolyPatch&,
Map<bool>&
) const
{}
template<>
void Foam::syncTools::transform::operator()
(
const coupledPolyPatch&,
EdgeMap<bool>&
) const
{}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Does anyone have couples? Since meshes might have 0 cells and 0 proc // Does anyone have couples? Since meshes might have 0 cells and 0 proc
// boundaries need to reduce this info. // boundaries need to reduce this info.
bool Foam::syncTools::hasCouples(const polyBoundaryMesh& patches) bool Foam::syncTools::hasCouples(const polyBoundaryMesh& patches)
@ -46,31 +117,6 @@ bool Foam::syncTools::hasCouples(const polyBoundaryMesh& patches)
} }
void Foam::syncTools::checkTransform
(
const coupledPolyPatch& pp,
const bool applySeparation
)
{
if (!pp.parallel() && pp.forwardT().size() > 1)
{
FatalErrorIn("syncTools::checkTransform(const coupledPolyPatch&)")
<< "Non-uniform transformation not supported for point or edge"
<< " fields." << endl
<< "Patch:" << pp.name()
<< abort(FatalError);
}
if (applySeparation && pp.separated() && pp.separation().size() > 1)
{
FatalErrorIn("syncTools::checkTransform(const coupledPolyPatch&)")
<< "Non-uniform separation vector not supported for point or edge"
<< " fields." << endl
<< "Patch:" << pp.name()
<< abort(FatalError);
}
}
// Determines for every point whether it is coupled and if so sets only one. // Determines for every point whether it is coupled and if so sets only one.
Foam::PackedBoolList Foam::syncTools::getMasterPoints(const polyMesh& mesh) Foam::PackedBoolList Foam::syncTools::getMasterPoints(const polyMesh& mesh)
{ {
@ -154,36 +200,16 @@ Foam::PackedBoolList Foam::syncTools::getMasterFaces(const polyMesh& mesh)
{ {
if (patches[patchI].coupled()) if (patches[patchI].coupled())
{ {
if (Pstream::parRun() && isA<processorPolyPatch>(patches[patchI])) const coupledPolyPatch& pp =
{ refCast<const coupledPolyPatch>(patches[patchI]);
const processorPolyPatch& pp =
refCast<const processorPolyPatch>(patches[patchI]);
if (!pp.owner()) if (!pp.owner())
{
forAll(pp, i)
{
isMasterFace.unset(pp.start()+i);
}
}
}
else if (isA<cyclicPolyPatch>(patches[patchI]))
{ {
const cyclicPolyPatch& pp = forAll(pp, i)
refCast<const cyclicPolyPatch>(patches[patchI]);
for (label i = pp.size()/2; i < pp.size(); i++)
{ {
isMasterFace.unset(pp.start()+i); isMasterFace.unset(pp.start()+i);
} }
} }
else
{
FatalErrorIn("syncTools::getMasterFaces(const polyMesh&)")
<< "Cannot handle coupled patch " << patches[patchI].name()
<< " of type " << patches[patchI].type()
<< abort(FatalError);
}
} }
} }
@ -191,100 +217,4 @@ Foam::PackedBoolList Foam::syncTools::getMasterFaces(const polyMesh& mesh)
} }
template <>
void Foam::syncTools::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
(
"syncTools::separateList(const vectorField&, UList<vector>&)"
) << "Sizes of field and transformation not equal. field:"
<< field.size() << " transformation:" << separation.size()
<< abort(FatalError);
}
}
template <>
void Foam::syncTools::separateList
(
const vectorField& separation,
Map<vector>& field
)
{
if (separation.size() == 1)
{
// Single value for all.
forAllIter(Map<vector>, field, iter)
{
iter() += separation[0];
}
}
else if (separation.size() == field.size())
{
forAllIter(Map<vector>, field, iter)
{
iter() += separation[iter.key()];
}
}
else
{
FatalErrorIn
(
"syncTools::separateList(const vectorField&, Map<vector>&)"
) << "Sizes of field and transformation not equal. field:"
<< field.size() << " transformation:" << separation.size()
<< abort(FatalError);
}
}
template <>
void Foam::syncTools::separateList
(
const vectorField& separation,
EdgeMap<vector>& field
)
{
if (separation.size() == 1)
{
// Single value for all.
forAllIter(EdgeMap<vector>, field, iter)
{
iter() += separation[0];
}
}
else
{
FatalErrorIn
(
"syncTools::separateList(const vectorField&, EdgeMap<vector>&)"
) << "Multiple separation vectors not supported. field:"
<< field.size() << " transformation:" << separation.size()
<< abort(FatalError);
}
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -50,10 +50,12 @@ SourceFiles
#include "UList.H" #include "UList.H"
#include "Pstream.H" #include "Pstream.H"
#include "transformList.H"
#include "Map.H" #include "Map.H"
#include "EdgeMap.H" #include "EdgeMap.H"
#include "PackedBoolList.H" #include "PackedBoolList.H"
#include "polyMesh.H"
#include "coupledPolyPatch.H"
#include "transformList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -61,8 +63,6 @@ namespace Foam
{ {
class polyBoundaryMesh; class polyBoundaryMesh;
class polyMesh;
class coupledPolyPatch;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class syncTools Declaration Class syncTools Declaration
@ -75,20 +75,6 @@ class syncTools
//- Check whether uses couples. //- Check whether uses couples.
static bool hasCouples(const polyBoundaryMesh&); static bool hasCouples(const polyBoundaryMesh&);
//- Check for single transformation tensor only.
static void checkTransform(const coupledPolyPatch&, const bool);
//- Apply separation to list. Either single vector or one vector
// per element.
template <class T>
static void separateList(const vectorField&, UList<T>&);
template <class T>
static void separateList(const vectorField&, Map<T>&);
template <class T>
static void separateList(const vectorField&, EdgeMap<T>&);
//- Combine value with existing value in map. //- Combine value with existing value in map.
template <class T, class CombineOp> template <class T, class CombineOp>
static void combine static void combine
@ -112,117 +98,384 @@ class syncTools
public: public:
// Static data members // Public classes
//- Synchronize values on all mesh points. class transform
// Applies rotation and optionally separation for parallel cyclics {
template <class T, class CombineOp> public:
static void syncPointList //- Transform patch-based field
( template<class T>
const polyMesh&, void operator()(const coupledPolyPatch& cpp, Field<T>& fld) const
UList<T>&, {
const CombineOp& cop, if (!cpp.parallel())
const T& nullValue, {
const bool applySeparation transformList(cpp.forwardT(), fld);
); }
}
//- Synchronize values on selected mesh points. //- Transform sparse field
// Applies rotation and optionally separation for parallel cyclics template<class T, template<class> class Container>
template <class T, class CombineOp> void operator()(const coupledPolyPatch& cpp, Container<T>& map)
static void syncPointList const
( {
const polyMesh&, if (!cpp.parallel())
const labelList& meshPoints, {
UList<T>&, transformList(cpp.forwardT(), map);
const CombineOp& bop, }
const T& nullValue, }
const bool applySeparation };
);
//- Synchronize values on all mesh edges. class transformPosition
// Applies rotation and optionally separation for parallel cyclics {
template <class T, class CombineOp> public:
static void syncEdgeList void operator()(const coupledPolyPatch& cpp, pointField& fld) const
( {
const polyMesh&, cpp.transformPosition(fld);
UList<T>&, }
const CombineOp& cop, template<template<class> class Container>
const T& nullValue, void operator()(const coupledPolyPatch& cpp, Container<point>& map)
const bool applySeparation const
); {
Field<point> fld(map.size());
label i = 0;
forAllConstIter(typename Container<point>, map, iter)
{
fld[i++] = iter();
}
cpp.transformPosition(fld);
i = 0;
forAllIter(typename Container<point>, map, iter)
{
iter() = fld[i++];
}
}
};
//- Synchronize values on boundary faces only.
// Optionally applies rotation tensor for non-parallel cyclics
// (but not separation!)
template <class T, class CombineOp>
static void syncBoundaryFaceList
(
const polyMesh&,
UList<T>&,
const CombineOp& cop,
const bool applySeparation
);
//- Synchronize values on all mesh faces. // Basic routines with user-supplied transformation. Preferably
// Optionally applies rotation tensor for non-parallel cyclics // use specialisations below.
// (but not separation!)
template <class T, class CombineOp>
static void syncFaceList
(
const polyMesh&,
UList<T>&,
const CombineOp& cop,
const bool applySeparation
);
//- Swap coupled face values.
// Applies rotation and optionally separation for parallel cyclics
template <class T>
static void swapBoundaryFaceList
(
const polyMesh&,
UList<T>&,
const bool applySeparation
);
//- Swap coupled face values.
// Applies rotation and optionally separation for parallel cyclics
template <class T>
static void swapFaceList
(
const polyMesh&,
UList<T>&,
const bool applySeparation
);
// Sparse versions
//- Synchronize values on selected points. //- Synchronize values on selected points.
// Applies rotation and optionally separation for parallel template <class T, class CombineOp, class TransformOp>
// cyclics.
template <class T, class CombineOp>
static void syncPointMap static void syncPointMap
( (
const polyMesh&, const polyMesh&,
Map<T>& pointValues, Map<T>& pointValues,
const CombineOp& cop, const CombineOp& cop,
const bool applySeparation const TransformOp& top
); );
//- Synchronize values on selected edges. Edges are represented //- Synchronize values on selected edges.
// by the two vertices that make it up so global edges never get template <class T, class CombineOp, class TransformOp>
// constructed.
// Applies rotation and optionally separation for parallel
// cyclics.
template <class T, class CombineOp>
static void syncEdgeMap static void syncEdgeMap
( (
const polyMesh&, const polyMesh&,
EdgeMap<T>& edgeValues, EdgeMap<T>& edgeValues,
const CombineOp& cop, const CombineOp& cop,
const bool applySeparation const TransformOp& top
); );
//- Synchronize values on all mesh points.
template <class T, class CombineOp, class TransformOp>
static void syncPointList
(
const polyMesh&,
UList<T>&,
const CombineOp& cop,
const T& nullValue,
const TransformOp& top
);
//- Synchronize values on selected mesh points.
template <class T, class CombineOp, class TransformOp>
static void syncPointList
(
const polyMesh&,
const labelList& meshPoints,
UList<T>&,
const CombineOp& cop,
const T& nullValue,
const TransformOp& top
);
//- Synchronize values on all mesh edges.
template <class T, class CombineOp, class TransformOp>
static void syncEdgeList
(
const polyMesh&,
UList<T>&,
const CombineOp& cop,
const T& nullValue,
const TransformOp& top
);
//- Synchronize values on boundary faces only.
template <class T, class CombineOp, class TransformOp>
static void syncBoundaryFaceList
(
const polyMesh&,
UList<T>&,
const CombineOp& cop,
const TransformOp& top
);
// Synchronise point-wise data
//- Synchronize values on all mesh points.
template <class T, class CombineOp>
static void syncPointList
(
const polyMesh& mesh,
UList<T>& l,
const CombineOp& cop,
const T& nullValue
)
{
syncPointList(mesh, l, cop, nullValue, transform());
}
//- Synchronize locations on all mesh points.
template <class CombineOp>
static void syncPointPositions
(
const polyMesh& mesh,
UList<point>& l,
const CombineOp& cop,
const point& nullValue
)
{
syncPointList(mesh, l, cop, nullValue, transformPosition());
}
//- Synchronize values on selected mesh points.
template <class T, class CombineOp>
static void syncPointList
(
const polyMesh& mesh,
const labelList& meshPoints,
UList<T>& l,
const CombineOp& cop,
const T& nullValue
)
{
syncPointList
(
mesh,
meshPoints,
l,
cop,
nullValue,
transform()
);
}
//- Synchronize locations on selected mesh points.
template <class CombineOp>
static void syncPointPositions
(
const polyMesh& mesh,
const labelList& meshPoints,
UList<point>& l,
const CombineOp& cop,
const point& nullValue
)
{
syncPointList
(
mesh,
meshPoints,
l,
cop,
nullValue,
transformPosition()
);
}
// Synchronise edge-wise data
//- Synchronize values on all mesh edges.
template <class T, class CombineOp>
static void syncEdgeList
(
const polyMesh& mesh,
UList<T>& l,
const CombineOp& cop,
const T& nullValue
)
{
syncEdgeList(mesh, l, cop, nullValue, transform());
}
//- Synchronize values on all mesh edges.
template <class CombineOp>
static void syncEdgePositions
(
const polyMesh& mesh,
UList<point>& l,
const CombineOp& cop,
const point& nullValue
)
{
syncEdgeList(mesh, l, cop, nullValue, transformPosition());
}
// Synchronise face-wise data
//- Synchronize values on boundary faces only.
template <class T, class CombineOp>
static void syncBoundaryFaceList
(
const polyMesh& mesh,
UList<T>& l,
const CombineOp& cop
)
{
syncBoundaryFaceList(mesh, l, cop, transform());
}
//- Synchronize locations on boundary faces only.
template <class CombineOp>
static void syncBoundaryFacePositions
(
const polyMesh& mesh,
UList<point>& l,
const CombineOp& cop
)
{
syncBoundaryFaceList(mesh, l, cop, transformPosition());
}
//- Synchronize values on all mesh faces.
template <class T, class CombineOp>
static void syncFaceList
(
const polyMesh& mesh,
UList<T>& l,
const CombineOp& cop
)
{
SubList<T> bndValues
(
l,
mesh.nFaces()-mesh.nInternalFaces(),
mesh.nInternalFaces()
);
syncBoundaryFaceList(mesh, bndValues, cop, transform());
}
//- Synchronize locations on all mesh faces.
template <class CombineOp>
static void syncFacePositions
(
const polyMesh& mesh,
UList<point>& l,
const CombineOp& cop
)
{
SubList<point> bndValues
(
l,
mesh.nFaces()-mesh.nInternalFaces(),
mesh.nInternalFaces()
);
syncBoundaryFaceList(mesh, bndValues, cop, transformPosition());
}
//- Swap coupled boundary face values.
template <class T>
static void swapBoundaryFaceList
(
const polyMesh& mesh,
UList<T>& l
)
{
syncBoundaryFaceList(mesh, l, eqOp<T>(), transform());
}
//- Swap coupled positions.
template <class T>
static void swapBoundaryFacePositions
(
const polyMesh& mesh,
UList<T>& l
)
{
syncBoundaryFaceList(mesh, l, eqOp<T>(), transformPosition());
}
//- Swap coupled face values.
template <class T>
static void swapFaceList
(
const polyMesh& mesh,
UList<T>& l
)
{
SubList<T> bndValues
(
l,
mesh.nFaces()-mesh.nInternalFaces(),
mesh.nInternalFaces()
);
syncBoundaryFaceList(mesh, bndValues, eqOp<T>(), transform());
}
// Sparse versions
//- Synchronize values on selected points.
template <class T, class CombineOp>
static void syncPointMap
(
const polyMesh& mesh,
Map<T>& l,
const CombineOp& cop
)
{
syncPointMap(mesh, l, cop, transform());
}
//- Synchronize locations on selected points.
template <class CombineOp>
static void syncPointPositions
(
const polyMesh& mesh,
Map<point>& l,
const CombineOp& cop
)
{
syncPointMap(mesh, l, cop, transformPosition());
}
//- Synchronize values on selected edges. Edges are represented
// by the two vertices that make it up so global edges never get
// constructed.
template <class T, class CombineOp>
static void syncEdgeMap
(
const polyMesh& mesh,
EdgeMap<T>& l,
const CombineOp& cop
)
{
syncEdgeMap(mesh, l, cop, transform());
}
//- Synchronize locations on selected edges.
template <class T, class CombineOp>
static void syncEdgePositions
(
const polyMesh& mesh,
EdgeMap<T>& l,
const CombineOp& cop
)
{
syncEdgeMap(mesh, l, cop, transformPosition());
}
// PackedList versions // PackedList versions
template <unsigned nBits, class CombineOp> template <unsigned nBits, class CombineOp>
@ -273,13 +526,62 @@ public:
template<> template<>
void syncTools::separateList(const vectorField&, UList<vector>&); void syncTools::transform::operator()
(
const coupledPolyPatch&,
Field<label>&
) const;
template<>
void syncTools::transform::operator()
(
const coupledPolyPatch&,
Map<label>&
) const;
template<>
void syncTools::transform::operator()
(
const coupledPolyPatch&,
EdgeMap<label>&
) const;
template<> template<>
void syncTools::separateList(const vectorField&, Map<vector>&); void syncTools::transform::operator()
(
const coupledPolyPatch&,
Field<scalar>&
) const;
template<>
void syncTools::transform::operator()
(
const coupledPolyPatch&,
Map<scalar>&
) const;
template<>
void syncTools::transform::operator()
(
const coupledPolyPatch&,
EdgeMap<scalar>&
) const;
template<> template<>
void syncTools::separateList(const vectorField&, EdgeMap<vector>&); void syncTools::transform::operator()
(
const coupledPolyPatch& cpp,
Field<bool>& fld
) const;
template<>
void syncTools::transform::operator()
(
const coupledPolyPatch&,
Map<bool>&
) const;
template<>
void syncTools::transform::operator()
(
const coupledPolyPatch&,
EdgeMap<bool>&
) const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

File diff suppressed because it is too large Load Diff

View File

@ -463,9 +463,9 @@ bool Foam::faceZone::checkParallelSync(const bool report) const
} }
} }
boolList myZoneFace(neiZoneFace); boolList myZoneFace(neiZoneFace);
syncTools::swapBoundaryFaceList(mesh, neiZoneFace, false); syncTools::swapBoundaryFaceList(mesh, neiZoneFace);
boolList myZoneFlip(neiZoneFlip); boolList myZoneFlip(neiZoneFlip);
syncTools::swapBoundaryFaceList(mesh, neiZoneFlip, false); syncTools::swapBoundaryFaceList(mesh, neiZoneFlip);
forAll(*this, i) forAll(*this, i)
{ {

View File

@ -84,7 +84,7 @@ void Foam::dynamicRefineFvMesh::calculateProtectedCells
{ {
neiLevel[faceI-nInternalFaces()] = cellLevel[faceOwner()[faceI]]; neiLevel[faceI-nInternalFaces()] = cellLevel[faceOwner()[faceI]];
} }
syncTools::swapBoundaryFaceList(*this, neiLevel, false); syncTools::swapBoundaryFaceList(*this, neiLevel);
while (true) while (true)
@ -122,7 +122,7 @@ void Foam::dynamicRefineFvMesh::calculateProtectedCells
} }
} }
syncTools::syncFaceList(*this, seedFace, orEqOp<bool>(), false); syncTools::syncFaceList(*this, seedFace, orEqOp<bool>());
// Extend unrefineableCell // Extend unrefineableCell
@ -846,7 +846,7 @@ void Foam::dynamicRefineFvMesh::extendMarkedCells
} }
} }
syncTools::syncFaceList(*this, markedFace, orEqOp<bool>(), false); syncTools::syncFaceList(*this, markedFace, orEqOp<bool>());
// Update cells using any markedFace // Update cells using any markedFace
for (label faceI = 0; faceI < nInternalFaces(); faceI++) for (label faceI = 0; faceI < nInternalFaces(); faceI++)
@ -933,7 +933,7 @@ Foam::dynamicRefineFvMesh::dynamicRefineFvMesh(const IOobject& io)
{ {
neiLevel[faceI] = cellLevel[faceOwner()[faceI]]; neiLevel[faceI] = cellLevel[faceOwner()[faceI]];
} }
syncTools::swapFaceList(*this, neiLevel, false); syncTools::swapFaceList(*this, neiLevel);
boolList protectedFace(nFaces(), false); boolList protectedFace(nFaces(), false);
@ -965,13 +965,7 @@ Foam::dynamicRefineFvMesh::dynamicRefineFvMesh(const IOobject& io)
} }
} }
syncTools::syncFaceList syncTools::syncFaceList(*this, protectedFace, orEqOp<bool>());
(
*this,
protectedFace,
orEqOp<bool>(),
false
);
for (label faceI = 0; faceI < nInternalFaces(); faceI++) for (label faceI = 0; faceI < nInternalFaces(); faceI++)
{ {

View File

@ -29,6 +29,9 @@ License
#include "faceCoupleInfo.H" #include "faceCoupleInfo.H"
#include "processorFvPatchField.H" #include "processorFvPatchField.H"
#include "processorFvsPatchField.H" #include "processorFvsPatchField.H"
#include "processorCyclicPolyPatch.H"
#include "processorCyclicFvPatchField.H"
#include "processorCyclicFvsPatchField.H"
#include "polyTopoChange.H" #include "polyTopoChange.H"
#include "removeCells.H" #include "removeCells.H"
#include "polyModifyFace.H" #include "polyModifyFace.H"
@ -128,6 +131,7 @@ void Foam::fvMeshDistribute::printMeshInfo(const fvMesh& mesh)
{ {
Pout<< "Primitives:" << nl Pout<< "Primitives:" << nl
<< " points :" << mesh.nPoints() << nl << " points :" << mesh.nPoints() << nl
<< " bb :" << boundBox(mesh.points(), false) << nl
<< " internalFaces:" << mesh.nInternalFaces() << nl << " internalFaces:" << mesh.nInternalFaces() << nl
<< " faces :" << mesh.nFaces() << nl << " faces :" << mesh.nFaces() << nl
<< " cells :" << mesh.nCells() << nl; << " cells :" << mesh.nCells() << nl;
@ -187,7 +191,8 @@ void Foam::fvMeshDistribute::printCoupleInfo
const primitiveMesh& mesh, const primitiveMesh& mesh,
const labelList& sourceFace, const labelList& sourceFace,
const labelList& sourceProc, const labelList& sourceProc,
const labelList& sourceNewProc const labelList& sourcePatch,
const labelList& sourceNewNbrProc
) )
{ {
Pout<< nl Pout<< nl
@ -202,7 +207,7 @@ void Foam::fvMeshDistribute::printCoupleInfo
<< " fc:" << mesh.faceCentres()[meshFaceI] << " fc:" << mesh.faceCentres()[meshFaceI]
<< " connects to proc:" << sourceProc[bFaceI] << " connects to proc:" << sourceProc[bFaceI]
<< "/face:" << sourceFace[bFaceI] << "/face:" << sourceFace[bFaceI]
<< " which will move to proc:" << sourceNewProc[bFaceI] << " which will move to proc:" << sourceNewNbrProc[bFaceI]
<< endl; << endl;
} }
} }
@ -270,32 +275,87 @@ Foam::label Foam::fvMeshDistribute::findNonEmptyPatch() const
} }
// Appends processorPolyPatch. Returns patchID. //// Appends processorPolyPatch. Returns patchID.
Foam::label Foam::fvMeshDistribute::addProcPatch //Foam::label Foam::fvMeshDistribute::addProcPatch
( //(
const word& patchName, // const word& patchName,
const label nbrProc // const label nbrProc
) //)
//{
// // Clear local fields and e.g. polyMesh globalMeshData.
// mesh_.clearOut();
//
//
// polyBoundaryMesh& polyPatches =
// const_cast<polyBoundaryMesh&>(mesh_.boundaryMesh());
// fvBoundaryMesh& fvPatches = const_cast<fvBoundaryMesh&>(mesh_.boundary());
//
// if (polyPatches.findPatchID(patchName) != -1)
// {
// FatalErrorIn("fvMeshDistribute::addProcPatch(const word&, const label)")
// << "Cannot create patch " << patchName << " since already exists."
// << nl
// << "Current patch names:" << polyPatches.names()
// << exit(FatalError);
// }
//
//
//
// // Add the patch
// // ~~~~~~~~~~~~~
//
// label sz = polyPatches.size();
//
// // Add polyPatch
// polyPatches.setSize(sz+1);
// polyPatches.set
// (
// sz,
// new processorPolyPatch
// (
// patchName,
// 0, // size
// mesh_.nFaces(),
// sz,
// mesh_.boundaryMesh(),
// Pstream::myProcNo(),
// nbrProc
// )
// );
// fvPatches.setSize(sz+1);
// fvPatches.set
// (
// sz,
// fvPatch::New
// (
// polyPatches[sz], // point to newly added polyPatch
// mesh_.boundary()
// )
// );
//
// return sz;
//}
// Appends polyPatch. Returns patchID.
Foam::label Foam::fvMeshDistribute::addPatch(polyPatch* patchPtr)
{ {
// Clear local fields and e.g. polyMesh globalMeshData. // Clear local fields and e.g. polyMesh globalMeshData.
mesh_.clearOut(); mesh_.clearOut();
polyBoundaryMesh& polyPatches = polyBoundaryMesh& polyPatches =
const_cast<polyBoundaryMesh&>(mesh_.boundaryMesh()); const_cast<polyBoundaryMesh&>(mesh_.boundaryMesh());
fvBoundaryMesh& fvPatches = const_cast<fvBoundaryMesh&>(mesh_.boundary()); fvBoundaryMesh& fvPatches = const_cast<fvBoundaryMesh&>(mesh_.boundary());
if (polyPatches.findPatchID(patchName) != -1) if (polyPatches.findPatchID(patchPtr->name()) != -1)
{ {
FatalErrorIn("fvMeshDistribute::addProcPatch(const word&, const label)") FatalErrorIn("fvMeshDistribute::addPatch(polyPatch*)")
<< "Cannot create patch " << patchName << " since already exists." << "Cannot create patch " << patchPtr->name()
<< nl << " since already exists." << nl
<< "Current patch names:" << polyPatches.names() << "Current patch names:" << polyPatches.names() << exit(FatalError);
<< exit(FatalError);
} }
// Add the patch // Add the patch
// ~~~~~~~~~~~~~ // ~~~~~~~~~~~~~
@ -303,20 +363,7 @@ Foam::label Foam::fvMeshDistribute::addProcPatch
// Add polyPatch // Add polyPatch
polyPatches.setSize(sz+1); polyPatches.setSize(sz+1);
polyPatches.set polyPatches.set(sz, patchPtr);
(
sz,
new processorPolyPatch
(
patchName,
0, // size
mesh_.nFaces(),
sz,
mesh_.boundaryMesh(),
Pstream::myProcNo(),
nbrProc
)
);
fvPatches.setSize(sz+1); fvPatches.setSize(sz+1);
fvPatches.set fvPatches.set
( (
@ -624,25 +671,27 @@ void Foam::fvMeshDistribute::getNeighbourData
const labelList& distribution, const labelList& distribution,
labelList& sourceFace, labelList& sourceFace,
labelList& sourceProc, labelList& sourceProc,
labelList& sourceNewProc labelList& sourcePatch,
labelList& sourceNewNbrProc
) const ) const
{ {
label nBnd = mesh_.nFaces() - mesh_.nInternalFaces(); label nBnd = mesh_.nFaces() - mesh_.nInternalFaces();
sourceFace.setSize(nBnd); sourceFace.setSize(nBnd);
sourceProc.setSize(nBnd); sourceProc.setSize(nBnd);
sourceNewProc.setSize(nBnd); sourcePatch.setSize(nBnd);
sourceNewNbrProc.setSize(nBnd);
const polyBoundaryMesh& patches = mesh_.boundaryMesh(); const polyBoundaryMesh& patches = mesh_.boundaryMesh();
// Get neighbouring meshFace labels and new processor of coupled boundaries. // Get neighbouring meshFace labels and new processor of coupled boundaries.
labelList nbrFaces(nBnd, -1); labelList nbrFaces(nBnd, -1);
labelList nbrNewProc(nBnd, -1); labelList nbrNewNbrProc(nBnd, -1);
forAll(patches, patchI) forAll(patches, patchI)
{ {
const polyPatch& pp = patches[patchI]; const polyPatch& pp = patches[patchI];
if (isA<processorPolyPatch>(pp)) if (pp.coupled())
{ {
label offset = pp.start() - mesh_.nInternalFaces(); label offset = pp.start() - mesh_.nInternalFaces();
@ -654,7 +703,7 @@ void Foam::fvMeshDistribute::getNeighbourData
} }
// Which processor they will end up on // Which processor they will end up on
SubList<label>(nbrNewProc, pp.size(), offset).assign SubList<label>(nbrNewNbrProc, pp.size(), offset).assign
( (
UIndirectList<label>(distribution, pp.faceCells())() UIndirectList<label>(distribution, pp.faceCells())()
); );
@ -663,8 +712,8 @@ void Foam::fvMeshDistribute::getNeighbourData
// Exchange the boundary data // Exchange the boundary data
syncTools::swapBoundaryFaceList(mesh_, nbrFaces, false); syncTools::swapBoundaryFaceList(mesh_, nbrFaces);
syncTools::swapBoundaryFaceList(mesh_, nbrNewProc, false); syncTools::swapBoundaryFaceList(mesh_, nbrNewNbrProc);
forAll(patches, patchI) forAll(patches, patchI)
@ -679,7 +728,7 @@ void Foam::fvMeshDistribute::getNeighbourData
// Check which of the two faces we store. // Check which of the two faces we store.
if (Pstream::myProcNo() < procPatch.neighbProcNo()) if (procPatch.owner())
{ {
// Use my local face labels // Use my local face labels
forAll(pp, i) forAll(pp, i)
@ -687,7 +736,7 @@ void Foam::fvMeshDistribute::getNeighbourData
label bndI = offset + i; label bndI = offset + i;
sourceFace[bndI] = pp.start()+i; sourceFace[bndI] = pp.start()+i;
sourceProc[bndI] = Pstream::myProcNo(); sourceProc[bndI] = Pstream::myProcNo();
sourceNewProc[bndI] = nbrNewProc[bndI]; sourceNewNbrProc[bndI] = nbrNewNbrProc[bndI];
} }
} }
else else
@ -698,7 +747,50 @@ void Foam::fvMeshDistribute::getNeighbourData
label bndI = offset + i; label bndI = offset + i;
sourceFace[bndI] = nbrFaces[bndI]; sourceFace[bndI] = nbrFaces[bndI];
sourceProc[bndI] = procPatch.neighbProcNo(); sourceProc[bndI] = procPatch.neighbProcNo();
sourceNewProc[bndI] = nbrNewProc[bndI]; sourceNewNbrProc[bndI] = nbrNewNbrProc[bndI];
}
}
label patchI = -1;
if (isA<processorCyclicPolyPatch>(pp))
{
patchI = refCast<const processorCyclicPolyPatch>
(
pp
).referPatchID();
}
forAll(pp, i)
{
label bndI = offset + i;
sourcePatch[bndI] = patchI;
}
}
else if (isA<cyclicPolyPatch>(pp))
{
const cyclicPolyPatch& cpp = refCast<const cyclicPolyPatch>(pp);
if (cpp.owner())
{
forAll(pp, i)
{
label bndI = offset + i;
sourceFace[bndI] = pp.start()+i;
sourceProc[bndI] = Pstream::myProcNo();
sourcePatch[bndI] = patchI;
sourceNewNbrProc[bndI] = nbrNewNbrProc[bndI];
}
}
else
{
forAll(pp, i)
{
label bndI = offset + i;
sourceFace[bndI] = nbrFaces[bndI];
sourceProc[bndI] = Pstream::myProcNo();
sourcePatch[bndI] = patchI;
sourceNewNbrProc[bndI] = nbrNewNbrProc[bndI];
} }
} }
} }
@ -708,9 +800,10 @@ void Foam::fvMeshDistribute::getNeighbourData
forAll(pp, i) forAll(pp, i)
{ {
label bndI = offset + i; label bndI = offset + i;
sourceFace[bndI] = patchI; sourceFace[bndI] = -1;
sourceProc[bndI] = -1; sourceProc[bndI] = -1;
sourceNewProc[bndI] = -1; sourcePatch[bndI] = patchI;
sourceNewNbrProc[bndI] = -1;
} }
} }
} }
@ -731,16 +824,19 @@ void Foam::fvMeshDistribute::subsetBoundaryData
const labelList& sourceFace, const labelList& sourceFace,
const labelList& sourceProc, const labelList& sourceProc,
const labelList& sourceNewProc, const labelList& sourcePatch,
const labelList& sourceNewNbrProc,
labelList& subFace, labelList& subFace,
labelList& subProc, labelList& subProc,
labelList& subNewProc labelList& subPatch,
labelList& subNewNbrProc
) )
{ {
subFace.setSize(mesh.nFaces() - mesh.nInternalFaces()); subFace.setSize(mesh.nFaces() - mesh.nInternalFaces());
subProc.setSize(mesh.nFaces() - mesh.nInternalFaces()); subProc.setSize(mesh.nFaces() - mesh.nInternalFaces());
subNewProc.setSize(mesh.nFaces() - mesh.nInternalFaces()); subPatch.setSize(mesh.nFaces() - mesh.nInternalFaces());
subNewNbrProc.setSize(mesh.nFaces() - mesh.nInternalFaces());
forAll(subFace, newBFaceI) forAll(subFace, newBFaceI)
{ {
@ -753,6 +849,7 @@ void Foam::fvMeshDistribute::subsetBoundaryData
{ {
subFace[newBFaceI] = oldFaceI; subFace[newBFaceI] = oldFaceI;
subProc[newBFaceI] = Pstream::myProcNo(); subProc[newBFaceI] = Pstream::myProcNo();
subPatch[newBFaceI] = -1;
label oldOwn = oldFaceOwner[oldFaceI]; label oldOwn = oldFaceOwner[oldFaceI];
label oldNei = oldFaceNeighbour[oldFaceI]; label oldNei = oldFaceNeighbour[oldFaceI];
@ -760,12 +857,12 @@ void Foam::fvMeshDistribute::subsetBoundaryData
if (oldOwn == cellMap[mesh.faceOwner()[newFaceI]]) if (oldOwn == cellMap[mesh.faceOwner()[newFaceI]])
{ {
// We kept the owner side. Where does the neighbour move to? // We kept the owner side. Where does the neighbour move to?
subNewProc[newBFaceI] = oldDistribution[oldNei]; subNewNbrProc[newBFaceI] = oldDistribution[oldNei];
} }
else else
{ {
// We kept the neighbour side. // We kept the neighbour side.
subNewProc[newBFaceI] = oldDistribution[oldOwn]; subNewNbrProc[newBFaceI] = oldDistribution[oldOwn];
} }
} }
else else
@ -775,7 +872,8 @@ void Foam::fvMeshDistribute::subsetBoundaryData
subFace[newBFaceI] = sourceFace[oldBFaceI]; subFace[newBFaceI] = sourceFace[oldBFaceI];
subProc[newBFaceI] = sourceProc[oldBFaceI]; subProc[newBFaceI] = sourceProc[oldBFaceI];
subNewProc[newBFaceI] = sourceNewProc[oldBFaceI]; subPatch[newBFaceI] = sourcePatch[oldBFaceI];
subNewNbrProc[newBFaceI] = sourceNewNbrProc[oldBFaceI];
} }
} }
} }
@ -788,11 +886,13 @@ void Foam::fvMeshDistribute::findCouples
const primitiveMesh& mesh, const primitiveMesh& mesh,
const labelList& sourceFace, const labelList& sourceFace,
const labelList& sourceProc, const labelList& sourceProc,
const labelList& sourcePatch,
const label domain, const label domain,
const primitiveMesh& domainMesh, const primitiveMesh& domainMesh,
const labelList& domainFace, const labelList& domainFace,
const labelList& domainProc, const labelList& domainProc,
const labelList& domainPatch,
labelList& masterCoupledFaces, labelList& masterCoupledFaces,
labelList& slaveCoupledFaces labelList& slaveCoupledFaces
@ -802,9 +902,16 @@ void Foam::fvMeshDistribute::findCouples
// with same face+proc. // with same face+proc.
HashTable<label, labelPair, labelPair::Hash<> > map(domainFace.size()); HashTable<label, labelPair, labelPair::Hash<> > map(domainFace.size());
forAll(domainFace, bFaceI) forAll(domainProc, bFaceI)
{ {
map.insert(labelPair(domainFace[bFaceI], domainProc[bFaceI]), bFaceI); if (domainProc[bFaceI] != -1 && domainPatch[bFaceI] == -1)
{
map.insert
(
labelPair(domainFace[bFaceI], domainProc[bFaceI]),
bFaceI
);
}
} }
@ -816,7 +923,7 @@ void Foam::fvMeshDistribute::findCouples
forAll(sourceFace, bFaceI) forAll(sourceFace, bFaceI)
{ {
if (sourceProc[bFaceI] != -1) if (sourceProc[bFaceI] != -1 && sourcePatch[bFaceI] == -1)
{ {
labelPair myData(sourceFace[bFaceI], sourceProc[bFaceI]); labelPair myData(sourceFace[bFaceI], sourceProc[bFaceI]);
@ -934,105 +1041,202 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::doRemoveCells
// the processor patchID. // the processor patchID.
void Foam::fvMeshDistribute::addProcPatches void Foam::fvMeshDistribute::addProcPatches
( (
const labelList& neighbourNewProc, // processor that neighbour is on const labelList& nbrProc, // processor that neighbour is now on
labelList& procPatchID const labelList& referPatchID, // patchID (or -1) I originated from
List<Map<label> >& procPatchID
) )
{ {
// Now use the neighbourFace/Proc to repatch the mesh. These two lists // Now use the neighbourFace/Proc to repatch the mesh. These lists
// contain for all current boundary faces the global patchID (for non-proc // contain for all current boundary faces the global patchID (for non-proc
// patch) or the processor. // patch) or the processor.
labelList procPatchSizes(Pstream::nProcs(), 0);
forAll(neighbourNewProc, bFaceI)
{
if (neighbourNewProc[bFaceI] != -1)
{
procPatchSizes[neighbourNewProc[bFaceI]]++;
}
}
// Per neighbour processor the label of the processor patch
procPatchID.setSize(Pstream::nProcs()); procPatchID.setSize(Pstream::nProcs());
forAll(procPatchSizes, procI) forAll(nbrProc, bFaceI)
{ {
if (procPatchSizes[procI] > 0) label procI = nbrProc[bFaceI];
if (procI != -1 && procI != Pstream::myProcNo())
{ {
const word patchName = if (!procPatchID[procI].found(referPatchID[bFaceI]))
"procBoundary" {
+ name(Pstream::myProcNo()) // No patch for neighbour yet. Is either a normal processor
+ "to" // patch or a processorCyclic patch.
+ name(procI);
if (referPatchID[bFaceI] == -1)
{
// Ordinary processor boundary
procPatchID[procI] = addProcPatch(patchName, procI); const word patchName =
addPatchFields<volScalarField> "procBoundary"
( + name(Pstream::myProcNo())
processorFvPatchField<scalar>::typeName + "to"
); + name(procI);
addPatchFields<volVectorField>
(
processorFvPatchField<vector>::typeName
);
addPatchFields<volSphericalTensorField>
(
processorFvPatchField<sphericalTensor>::typeName
);
addPatchFields<volSymmTensorField>
(
processorFvPatchField<symmTensor>::typeName
);
addPatchFields<volTensorField>
(
processorFvPatchField<tensor>::typeName
);
addPatchFields<surfaceScalarField> procPatchID[procI].insert
( (
processorFvPatchField<scalar>::typeName referPatchID[bFaceI],
); addPatch
addPatchFields<surfaceVectorField> (
( new processorPolyPatch
processorFvPatchField<vector>::typeName (
); patchName,
addPatchFields<surfaceSphericalTensorField> 0, // size
( mesh_.nFaces(),
processorFvPatchField<sphericalTensor>::typeName mesh_.boundaryMesh().size(),
); mesh_.boundaryMesh(),
addPatchFields<surfaceSymmTensorField> Pstream::myProcNo(),
( nbrProc[bFaceI]
processorFvPatchField<symmTensor>::typeName )
); )
addPatchFields<surfaceTensorField> );
(
processorFvPatchField<tensor>::typeName addPatchFields<volScalarField>
); (
} processorFvPatchField<scalar>::typeName
else );
{ addPatchFields<volVectorField>
procPatchID[procI] = -1; (
processorFvPatchField<vector>::typeName
);
addPatchFields<volSphericalTensorField>
(
processorFvPatchField<sphericalTensor>::typeName
);
addPatchFields<volSymmTensorField>
(
processorFvPatchField<symmTensor>::typeName
);
addPatchFields<volTensorField>
(
processorFvPatchField<tensor>::typeName
);
addPatchFields<surfaceScalarField>
(
processorFvPatchField<scalar>::typeName
);
addPatchFields<surfaceVectorField>
(
processorFvPatchField<vector>::typeName
);
addPatchFields<surfaceSphericalTensorField>
(
processorFvPatchField<sphericalTensor>::typeName
);
addPatchFields<surfaceSymmTensorField>
(
processorFvPatchField<symmTensor>::typeName
);
addPatchFields<surfaceTensorField>
(
processorFvPatchField<tensor>::typeName
);
}
else
{
// Processor boundary originating from cyclic
const word& cycName = mesh_.boundaryMesh()
[
referPatchID[bFaceI]
].name();
const word patchName =
"procBoundary"
+ name(Pstream::myProcNo())
+ "to"
+ name(procI)
+ "through"
+ cycName;
procPatchID[procI].insert
(
referPatchID[bFaceI],
addPatch
(
new processorCyclicPolyPatch
(
patchName,
0, // size
mesh_.nFaces(),
mesh_.boundaryMesh().size(),
mesh_.boundaryMesh(),
Pstream::myProcNo(),
nbrProc[bFaceI],
cycName
)
)
);
addPatchFields<volScalarField>
(
processorCyclicFvPatchField<scalar>::typeName
);
addPatchFields<volVectorField>
(
processorCyclicFvPatchField<vector>::typeName
);
addPatchFields<volSphericalTensorField>
(
processorCyclicFvPatchField<sphericalTensor>::typeName
);
addPatchFields<volSymmTensorField>
(
processorCyclicFvPatchField<symmTensor>::typeName
);
addPatchFields<volTensorField>
(
processorCyclicFvPatchField<tensor>::typeName
);
addPatchFields<surfaceScalarField>
(
processorCyclicFvPatchField<scalar>::typeName
);
addPatchFields<surfaceVectorField>
(
processorCyclicFvPatchField<vector>::typeName
);
addPatchFields<surfaceSphericalTensorField>
(
processorCyclicFvPatchField<sphericalTensor>::typeName
);
addPatchFields<surfaceSymmTensorField>
(
processorCyclicFvPatchField<symmTensor>::typeName
);
addPatchFields<surfaceTensorField>
(
processorCyclicFvPatchField<tensor>::typeName
);
}
}
} }
} }
} }
// Get boundary faces to be repatched. Is -1 or new patchID // Get boundary faces to be repatched. Is -1 or new patchID
Foam::labelList Foam::fvMeshDistribute::getProcBoundaryPatch Foam::labelList Foam::fvMeshDistribute::getBoundaryPatch
( (
const labelList& neighbourNewProc, // new processor per boundary face const labelList& nbrProc, // new processor per boundary face
const labelList& procPatchID // patchID const labelList& referPatchID, // patchID (or -1) I originated from
const List<Map<label> >& procPatchID // per proc the new procPatches
) )
{ {
labelList patchIDs(neighbourNewProc); labelList patchIDs(nbrProc);
forAll(neighbourNewProc, bFaceI) forAll(nbrProc, bFaceI)
{ {
if (neighbourNewProc[bFaceI] != -1) if (nbrProc[bFaceI] == Pstream::myProcNo())
{ {
label nbrProc = neighbourNewProc[bFaceI]; label origPatchI = referPatchID[bFaceI];
patchIDs[bFaceI] = origPatchI;
patchIDs[bFaceI] = procPatchID[nbrProc]; }
else if (nbrProc[bFaceI] != -1)
{
label origPatchI = referPatchID[bFaceI];
patchIDs[bFaceI] = procPatchID[nbrProc[bFaceI]][origPatchI];
} }
else else
{ {
@ -1055,7 +1259,8 @@ void Foam::fvMeshDistribute::sendMesh
const labelList& sourceFace, const labelList& sourceFace,
const labelList& sourceProc, const labelList& sourceProc,
const labelList& sourceNewProc, const labelList& sourcePatch,
const labelList& sourceNewNbrProc,
UOPstream& toDomain UOPstream& toDomain
) )
{ {
@ -1191,7 +1396,8 @@ void Foam::fvMeshDistribute::sendMesh
<< sourceFace << sourceFace
<< sourceProc << sourceProc
<< sourceNewProc; << sourcePatch
<< sourceNewNbrProc;
if (debug) if (debug)
@ -1212,7 +1418,8 @@ Foam::autoPtr<Foam::fvMesh> Foam::fvMeshDistribute::receiveMesh
const Time& runTime, const Time& runTime,
labelList& domainSourceFace, labelList& domainSourceFace,
labelList& domainSourceProc, labelList& domainSourceProc,
labelList& domainSourceNewProc, labelList& domainSourcePatch,
labelList& domainSourceNewNbrProc,
UIPstream& fromNbr UIPstream& fromNbr
) )
{ {
@ -1230,7 +1437,8 @@ Foam::autoPtr<Foam::fvMesh> Foam::fvMeshDistribute::receiveMesh
fromNbr fromNbr
>> domainSourceFace >> domainSourceFace
>> domainSourceProc >> domainSourceProc
>> domainSourceNewProc; >> domainSourcePatch
>> domainSourceNewNbrProc;
// Construct fvMesh // Construct fvMesh
autoPtr<fvMesh> domainMeshPtr autoPtr<fvMesh> domainMeshPtr
@ -1448,16 +1656,37 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
// physical boundary: // physical boundary:
// sourceProc = -1 // sourceProc = -1
// sourceNewProc = -1 // sourceNewNbrProc = -1
// sourceFace = patchID // sourceFace = -1
// coupled boundary: // sourcePatch = patchID
// sourceProc = proc // processor boundary:
// sourceNewProc = distribution[cell on proc] // sourceProc = proc (on owner side)
// sourceFace = face // sourceNewNbrProc = distribution of coupled cell
// sourceFace = face (on owner side)
// sourcePatch = -1
// ?cyclic:
// ? sourceProc = proc
// ? sourceNewNbrProc = distribution of coupled cell
// ? sourceFace = face (on owner side)
// ? sourcePatch = patchID
// processor-cyclic boundary:
// sourceProc = proc (on owner side)
// sourceNewNbrProc = distribution of coupled cell
// sourceFace = face (on owner side)
// sourcePatch = patchID
labelList sourcePatch;
labelList sourceFace; labelList sourceFace;
labelList sourceProc; labelList sourceProc;
labelList sourceNewProc; labelList sourceNewNbrProc;
getNeighbourData(distribution, sourceFace, sourceProc, sourceNewProc); getNeighbourData
(
distribution,
sourceFace,
sourceProc,
sourcePatch,
sourceNewNbrProc
);
// Remove meshPhi. Since this would otherwise disappear anyway // Remove meshPhi. Since this would otherwise disappear anyway
@ -1529,7 +1758,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
inplaceReorder(bFaceMap, sourceFace); inplaceReorder(bFaceMap, sourceFace);
inplaceReorder(bFaceMap, sourceProc); inplaceReorder(bFaceMap, sourceProc);
inplaceReorder(bFaceMap, sourceNewProc); inplaceReorder(bFaceMap, sourcePatch);
inplaceReorder(bFaceMap, sourceNewNbrProc);
} }
@ -1632,7 +1862,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
// Subset the boundary fields (owner/neighbour/processor) // Subset the boundary fields (owner/neighbour/processor)
labelList procSourceFace; labelList procSourceFace;
labelList procSourceProc; labelList procSourceProc;
labelList procSourceNewProc; labelList procSourcePatch;
labelList procSourceNewNbrProc;
subsetBoundaryData subsetBoundaryData
( (
@ -1647,11 +1878,13 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
sourceFace, sourceFace,
sourceProc, sourceProc,
sourceNewProc, sourcePatch,
sourceNewNbrProc,
procSourceFace, procSourceFace,
procSourceProc, procSourceProc,
procSourceNewProc procSourcePatch,
procSourceNewNbrProc
); );
@ -1668,7 +1901,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
procSourceFace, procSourceFace,
procSourceProc, procSourceProc,
procSourceNewProc, procSourcePatch,
procSourceNewNbrProc,
str str
); );
sendFields<volScalarField>(recvProc, volScalars, subsetter, str); sendFields<volScalarField>(recvProc, volScalars, subsetter, str);
@ -1771,7 +2005,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
// fields // fields
labelList domainSourceFace; labelList domainSourceFace;
labelList domainSourceProc; labelList domainSourceProc;
labelList domainSourceNewProc; labelList domainSourcePatch;
labelList domainSourceNewNbrProc;
subsetBoundaryData subsetBoundaryData
( (
@ -1786,16 +2021,19 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
sourceFace, sourceFace,
sourceProc, sourceProc,
sourceNewProc, sourcePatch,
sourceNewNbrProc,
domainSourceFace, domainSourceFace,
domainSourceProc, domainSourceProc,
domainSourceNewProc domainSourcePatch,
domainSourceNewNbrProc
); );
sourceFace.transfer(domainSourceFace); sourceFace.transfer(domainSourceFace);
sourceProc.transfer(domainSourceProc); sourceProc.transfer(domainSourceProc);
sourceNewProc.transfer(domainSourceNewProc); sourcePatch.transfer(domainSourcePatch);
sourceNewNbrProc.transfer(domainSourceNewNbrProc);
} }
@ -1848,7 +2086,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
// Receive from sendProc // Receive from sendProc
labelList domainSourceFace; labelList domainSourceFace;
labelList domainSourceProc; labelList domainSourceProc;
labelList domainSourceNewProc; labelList domainSourcePatch;
labelList domainSourceNewNbrProc;
autoPtr<fvMesh> domainMeshPtr; autoPtr<fvMesh> domainMeshPtr;
PtrList<volScalarField> vsf; PtrList<volScalarField> vsf;
@ -1874,10 +2113,14 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
const_cast<Time&>(mesh_.time()), const_cast<Time&>(mesh_.time()),
domainSourceFace, domainSourceFace,
domainSourceProc, domainSourceProc,
domainSourceNewProc, domainSourcePatch,
domainSourceNewNbrProc,
str str
); );
fvMesh& domainMesh = domainMeshPtr(); fvMesh& domainMesh = domainMeshPtr();
// Force construction of various on mesh.
//(void)domainMesh.globalData();
// Receive fields. Read as single dictionary because // Receive fields. Read as single dictionary because
// of problems reading consecutive fields from single stream. // of problems reading consecutive fields from single stream.
@ -2006,11 +2249,13 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
sourceFace, sourceFace,
sourceProc, sourceProc,
sourcePatch,
sendProc, sendProc,
domainMesh, domainMesh,
domainSourceFace, domainSourceFace,
domainSourceProc, domainSourceProc,
domainSourcePatch,
masterCoupledFaces, masterCoupledFaces,
slaveCoupledFaces slaveCoupledFaces
@ -2045,33 +2290,38 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
// Update mesh data: sourceFace,sourceProc for added // Update mesh data: sourceFace,sourceProc for added
// mesh. // mesh.
sourceFace = sourceFace = mapBoundaryData
mapBoundaryData (
( mesh_,
mesh_, map(),
map(), sourceFace,
sourceFace, domainMesh.nInternalFaces(),
domainMesh.nInternalFaces(), domainSourceFace
domainSourceFace );
); sourceProc = mapBoundaryData
sourceProc = (
mapBoundaryData mesh_,
( map(),
mesh_, sourceProc,
map(), domainMesh.nInternalFaces(),
sourceProc, domainSourceProc
domainMesh.nInternalFaces(), );
domainSourceProc sourcePatch = mapBoundaryData
); (
sourceNewProc = mesh_,
mapBoundaryData map(),
( sourcePatch,
mesh_, domainMesh.nInternalFaces(),
map(), domainSourcePatch
sourceNewProc, );
domainMesh.nInternalFaces(), sourceNewNbrProc = mapBoundaryData
domainSourceNewProc (
); mesh_,
map(),
sourceNewNbrProc,
domainMesh.nInternalFaces(),
domainSourceNewNbrProc
);
// Update all addressing so xxProcAddressing points to correct item // Update all addressing so xxProcAddressing points to correct item
// in masterMesh. // in masterMesh.
@ -2141,11 +2391,13 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
// Add processorPatches // Add processorPatches
// ~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~
// Per neighbour processor the patchID to it (or -1). // Per neighbour processor, per originating patch, the patchID
labelList procPatchID; // For faces resulting from internal faces or normal processor patches
// the originating patch is -1. For cyclics this is the cyclic patchID.
List<Map<label> > procPatchID;
// Add processor patches. // Add processor and processorCyclic patches.
addProcPatches(sourceNewProc, procPatchID); addProcPatches(sourceNewNbrProc, sourcePatch, procPatchID);
// Put faces into correct patch. Note that we now have proper // Put faces into correct patch. Note that we now have proper
// processorPolyPatches again so repatching will take care of coupled face // processorPolyPatches again so repatching will take care of coupled face
@ -2154,9 +2406,10 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
// Get boundary faces to be repatched. Is -1 or new patchID // Get boundary faces to be repatched. Is -1 or new patchID
labelList newPatchID labelList newPatchID
( (
getProcBoundaryPatch getBoundaryPatch
( (
sourceNewProc, sourceNewNbrProc,
sourcePatch,
procPatchID procPatchID
) )
); );

View File

@ -102,8 +102,8 @@ class fvMeshDistribute
//- Find patch to put exposed faces into. //- Find patch to put exposed faces into.
label findNonEmptyPatch() const; label findNonEmptyPatch() const;
//- Appends processorPolyPatch. Returns patchID. //- Appends polyPatch. Returns patchID.
label addProcPatch(const word& patchName, const label nbrProc); label addPatch(polyPatch*);
//- Add patch field //- Add patch field
template<class GeoField> template<class GeoField>
@ -169,6 +169,7 @@ class fvMeshDistribute
const labelList& distribution, const labelList& distribution,
labelList& sourceFace, labelList& sourceFace,
labelList& sourceProc, labelList& sourceProc,
labelList& sourcePatch,
labelList& sourceNewProc labelList& sourceNewProc
) const; ) const;
@ -186,10 +187,12 @@ class fvMeshDistribute
const labelList& sourceFace, const labelList& sourceFace,
const labelList& sourceProc, const labelList& sourceProc,
const labelList& sourcePatch,
const labelList& sourceNewProc, const labelList& sourceNewProc,
labelList& subFace, labelList& subFace,
labelList& subProc, labelList& subProc,
labelList& subPatch,
labelList& subNewProc labelList& subNewProc
); );
@ -200,11 +203,13 @@ class fvMeshDistribute
const primitiveMesh&, const primitiveMesh&,
const labelList& sourceFace, const labelList& sourceFace,
const labelList& sourceProc, const labelList& sourceProc,
const labelList& sourcePatch,
const label domain, const label domain,
const primitiveMesh& domainMesh, const primitiveMesh& domainMesh,
const labelList& domainFace, const labelList& domainFace,
const labelList& domainProc, const labelList& domainProc,
const labelList& domainPatch,
labelList& masterCoupledFaces, labelList& masterCoupledFaces,
labelList& slaveCoupledFaces labelList& slaveCoupledFaces
@ -235,15 +240,17 @@ class fvMeshDistribute
// proc the processor patchID. // proc the processor patchID.
void addProcPatches void addProcPatches
( (
const labelList&, // processor that neighbour is on const labelList&, // processor that neighbour is now on
labelList& procPatchID const labelList&, // -1 or patch that face originated from
List<Map<label> >& procPatchID
); );
//- Get boundary faces to be repatched. Is -1 or new patchID //- Get boundary faces to be repatched. Is -1 or new patchID
static labelList getProcBoundaryPatch static labelList getBoundaryPatch
( (
const labelList& neighbourNewProc,// new processor per b. face const labelList& neighbourNewProc, // new processor per b. face
const labelList& procPatchID // patchID const labelList& referPatchID, // -1 or original patch
const List<Map<label> >& procPatchID// patchID
); );
//- Send mesh and coupling data. //- Send mesh and coupling data.
@ -256,6 +263,7 @@ class fvMeshDistribute
const wordList& cellZoneNames, const wordList& cellZoneNames,
const labelList& sourceFace, const labelList& sourceFace,
const labelList& sourceProc, const labelList& sourceProc,
const labelList& sourcePatch,
const labelList& sourceNewProc, const labelList& sourceNewProc,
UOPstream& toDomain UOPstream& toDomain
); );
@ -279,6 +287,7 @@ class fvMeshDistribute
const Time& runTime, const Time& runTime,
labelList& domainSourceFace, labelList& domainSourceFace,
labelList& domainSourceProc, labelList& domainSourceProc,
labelList& domainSourcePatch,
labelList& domainSourceNewProc, labelList& domainSourceNewProc,
UIPstream& fromNbr UIPstream& fromNbr
); );
@ -328,6 +337,7 @@ public:
const primitiveMesh&, const primitiveMesh&,
const labelList&, const labelList&,
const labelList&, const labelList&,
const labelList&,
const labelList& const labelList&
); );

View File

@ -40,6 +40,80 @@ defineTypeNameAndDebug(Foam::motionSmoother, 0);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::motionSmoother::testSyncPositions
(
const pointField& fld,
const scalar maxMag
) const
{
pointField syncedFld(fld);
syncTools::syncPointPositions
(
mesh_,
syncedFld,
minEqOp<point>(), // combine op
point(GREAT,GREAT,GREAT) // null
);
forAll(syncedFld, i)
{
if (mag(syncedFld[i] - fld[i]) > maxMag)
{
FatalErrorIn
(
"motionSmoother::testSyncPositions(const pointField&)"
) << "On point " << i << " point:" << fld[i]
<< " synchronised point:" << syncedFld[i]
<< abort(FatalError);
}
}
}
//Foam::tmp<Foam::scalarField> Foam::motionSmoother::sumWeights
//(
// const scalarField& edgeWeight
//) const
//{
// tmp<scalarField> tsumWeight
// (
// new scalarField
// (
// mesh_.nPoints(),
// 0.0
// )
// );
// scalarField& sumWeight = tsumWeight();
//
// const edgeList& edges = mesh_.edges();
//
// forAll(edges, edgeI)
// {
// if (isMasterEdge_.get(edgeI) == 1)
// {
// const edge& e = edges[edgeI];
// const scalar w = edgeWeight[edgeI];
// sumWeight[e[0]] += w;
// sumWeight[e[1]] += w;
// }
// }
//
//
// // Add coupled contributions
// // ~~~~~~~~~~~~~~~~~~~~~~~~~
// syncTools::syncPointList
// (
// mesh,
// sumWeight,
// plusEqOp<scalar>(),
// scalar(0) // null value
// );
//
// return tsumWeight;
//}
// From pointPatchInterpolation // From pointPatchInterpolation
void Foam::motionSmoother::makePatchPatchAddressing() void Foam::motionSmoother::makePatchPatchAddressing()
{ {
@ -209,8 +283,7 @@ void Foam::motionSmoother::minSmooth
tmp<pointScalarField> tavgFld = avg tmp<pointScalarField> tavgFld = avg
( (
fld, fld,
scalarField(mesh_.nEdges(), 1.0), // uniform weighting scalarField(mesh_.nEdges(), 1.0) // uniform weighting
false // fld is not position.
); );
const pointScalarField& avgFld = tavgFld(); const pointScalarField& avgFld = tavgFld();
@ -243,8 +316,7 @@ void Foam::motionSmoother::minSmooth
tmp<pointScalarField> tavgFld = avg tmp<pointScalarField> tavgFld = avg
( (
fld, fld,
scalarField(mesh_.nEdges(), 1.0), // uniform weighting scalarField(mesh_.nEdges(), 1.0) // uniform weighting
false // fld is not position.
); );
const pointScalarField& avgFld = tavgFld(); const pointScalarField& avgFld = tavgFld();
@ -612,8 +684,7 @@ void Foam::motionSmoother::setDisplacement(pointField& patchDisp)
mesh_, mesh_,
displacement_, displacement_,
maxMagEqOp(), // combine op maxMagEqOp(), // combine op
vector::zero, // null value vector::zero // null value
false // no separation
); );
// Adapt the fixedValue bc's (i.e. copy internal point data to // Adapt the fixedValue bc's (i.e. copy internal point data to
@ -718,8 +789,7 @@ void Foam::motionSmoother::correctBoundaryConditions
mesh_, mesh_,
displacement, displacement,
maxMagEqOp(), // combine op maxMagEqOp(), // combine op
vector::zero, // null value vector::zero // null value
false // no separation
); );
} }
@ -769,14 +839,7 @@ Foam::tmp<Foam::scalarField> Foam::motionSmoother::movePoints
{ {
Pout<< "motionSmoother::movePoints : testing sync of newPoints." Pout<< "motionSmoother::movePoints : testing sync of newPoints."
<< endl; << endl;
testSyncField testSyncPositions(newPoints, 1E-6*mesh_.bounds().mag());
(
newPoints,
minEqOp<point>(), // combine op
vector(GREAT,GREAT,GREAT), // null
true, // separation
1E-6*mesh_.bounds().mag()
);
} }
tmp<scalarField> tsweptVol = mesh_.movePoints(newPoints); tmp<scalarField> tsweptVol = mesh_.movePoints(newPoints);
@ -894,8 +957,7 @@ bool Foam::motionSmoother::scaleMesh
mesh_, mesh_,
displacement_, displacement_,
maxMagEqOp(), maxMagEqOp(),
vector::zero, // null value vector::zero // null value
false // no separation
); );
// Set newPoints as old + scale*displacement // Set newPoints as old + scale*displacement
@ -926,7 +988,6 @@ bool Foam::motionSmoother::scaleMesh
totalDisplacement, totalDisplacement,
maxMagEqOp(), maxMagEqOp(),
vector::zero, // null value vector::zero, // null value
false, // separation
1E-6*mesh_.bounds().mag() 1E-6*mesh_.bounds().mag()
); );
} }
@ -1056,8 +1117,7 @@ bool Foam::motionSmoother::scaleMesh
mesh_, mesh_,
scale_, scale_,
maxEqOp<scalar>(), maxEqOp<scalar>(),
-GREAT, // null value -GREAT // null value
false // no separation
); );

View File

@ -183,8 +183,15 @@ class motionSmoother
tmp<GeometricField<Type, pointPatchField, pointMesh> > avg tmp<GeometricField<Type, pointPatchField, pointMesh> > avg
( (
const GeometricField<Type, pointPatchField, pointMesh>& fld, const GeometricField<Type, pointPatchField, pointMesh>& fld,
const scalarField& edgeWeight, const scalarField& edgeWeight
const bool separation ) const;
//- Average postion of connected points.
template <class Type>
tmp<GeometricField<Type, pointPatchField, pointMesh> > avgPositions
(
const GeometricField<Type, pointPatchField, pointMesh>& fld,
const scalarField& edgeWeight
) const; ) const;
//- Check constraints //- Check constraints
@ -201,17 +208,19 @@ class motionSmoother
GeometricField<Type, pointPatchField, pointMesh>& GeometricField<Type, pointPatchField, pointMesh>&
) const; ) const;
//- Test synchronisation of pointField //- Test synchronisation of generic field (not positions!) on points
template<class Type, class CombineOp> template<class Type, class CombineOp>
void testSyncField void testSyncField
( (
const Field<Type>&, const Field<Type>&,
const CombineOp& cop, const CombineOp& cop,
const Type& zero, const Type& zero,
const bool separation,
const scalar maxMag const scalar maxMag
) const; ) const;
//- Test synchronisation of points
void testSyncPositions(const pointField&, const scalar maxMag) const;
//- Assemble tensors for multi-patch constraints //- Assemble tensors for multi-patch constraints
void makePatchPatchAddressing(); void makePatchPatchAddressing();
@ -476,14 +485,13 @@ public:
// Helper functions to manipulate displacement vector. // Helper functions to manipulate displacement vector.
//- Fully explicit smoothing of internal points with varying //- Fully explicit smoothing of fields (not positions)
// diffusivity. // of internal points with varying diffusivity.
template <class Type> template <class Type>
void smooth void smooth
( (
const GeometricField<Type, pointPatchField, pointMesh>& fld, const GeometricField<Type, pointPatchField, pointMesh>& fld,
const scalarField& edgeWeight, const scalarField& edgeWeight,
const bool separation,
GeometricField<Type, pointPatchField, pointMesh>& newFld GeometricField<Type, pointPatchField, pointMesh>& newFld
) const; ) const;
}; };

View File

@ -155,11 +155,10 @@ void Foam::motionSmoother::applyCornerConstraints
// Average of connected points. // Average of connected points.
template <class Type> template <class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh> > Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh> >
Foam::motionSmoother::avg Foam::motionSmoother::avg
( (
const GeometricField<Type, pointPatchField, pointMesh>& fld, const GeometricField<Type, pointPatchField, pointMesh>& fld,
const scalarField& edgeWeight, const scalarField& edgeWeight
const bool separation
) const ) const
{ {
tmp<GeometricField<Type, pointPatchField, pointMesh> > tres tmp<GeometricField<Type, pointPatchField, pointMesh> > tres
@ -172,7 +171,8 @@ Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh> >
fld.time().timeName(), fld.time().timeName(),
fld.db(), fld.db(),
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::NO_WRITE,
false
), ),
fld.mesh(), fld.mesh(),
dimensioned<Type>("zero", fld.dimensions(), pTraits<Type>::zero) dimensioned<Type>("zero", fld.dimensions(), pTraits<Type>::zero)
@ -217,17 +217,14 @@ Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh> >
mesh, mesh,
res, res,
plusEqOp<Type>(), plusEqOp<Type>(),
pTraits<Type>::zero, // null value pTraits<Type>::zero // null value
separation // separation
); );
syncTools::syncPointList syncTools::syncPointList
( (
mesh, mesh,
sumWeight, sumWeight,
plusEqOp<scalar>(), plusEqOp<scalar>(),
scalar(0), // null value scalar(0) // null value
false // separation
); );
@ -260,16 +257,10 @@ void Foam::motionSmoother::smooth
( (
const GeometricField<Type, pointPatchField, pointMesh>& fld, const GeometricField<Type, pointPatchField, pointMesh>& fld,
const scalarField& edgeWeight, const scalarField& edgeWeight,
const bool separation,
GeometricField<Type, pointPatchField, pointMesh>& newFld GeometricField<Type, pointPatchField, pointMesh>& newFld
) const ) const
{ {
tmp<pointVectorField> tavgFld = avg tmp<pointVectorField> tavgFld = avg(fld, edgeWeight);
(
fld,
edgeWeight, // weighting
separation // whether to apply separation vector
);
const pointVectorField& avgFld = tavgFld(); const pointVectorField& avgFld = tavgFld();
forAll(fld, pointI) forAll(fld, pointI)
@ -285,14 +276,13 @@ void Foam::motionSmoother::smooth
} }
//- Test synchronisation of pointField //- Test synchronisation of generic field (not positions!) on points
template<class Type, class CombineOp> template<class Type, class CombineOp>
void Foam::motionSmoother::testSyncField void Foam::motionSmoother::testSyncField
( (
const Field<Type>& fld, const Field<Type>& fld,
const CombineOp& cop, const CombineOp& cop,
const Type& zero, const Type& zero,
const bool separation,
const scalar maxMag const scalar maxMag
) const ) const
{ {
@ -309,13 +299,11 @@ void Foam::motionSmoother::testSyncField
mesh_, mesh_,
syncedFld, syncedFld,
cop, cop,
zero, // null value zero
separation // separation
); );
forAll(syncedFld, i) forAll(syncedFld, i)
{ {
if (syncedFld[i] != fld[i])
if (mag(syncedFld[i] - fld[i]) > maxMag) if (mag(syncedFld[i] - fld[i]) > maxMag)
{ {
FatalErrorIn FatalErrorIn

View File

@ -425,13 +425,13 @@ bool Foam::polyMeshGeometry::checkFaceDotProduct
// Calculate coupled cell centre // Calculate coupled cell centre
vectorField neiCc(mesh.nFaces()-mesh.nInternalFaces()); pointField neiCc(mesh.nFaces()-mesh.nInternalFaces());
for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++) for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++)
{ {
neiCc[faceI-mesh.nInternalFaces()] = cellCentres[own[faceI]]; neiCc[faceI-mesh.nInternalFaces()] = cellCentres[own[faceI]];
} }
syncTools::swapBoundaryFaceList(mesh, neiCc, true); syncTools::swapBoundaryFacePositions(mesh, neiCc);
scalar minDDotS = GREAT; scalar minDDotS = GREAT;
@ -927,13 +927,13 @@ bool Foam::polyMeshGeometry::checkFaceSkewness
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const polyBoundaryMesh& patches = mesh.boundaryMesh();
// Calculate coupled cell centre // Calculate coupled cell centre
vectorField neiCc(mesh.nFaces()-mesh.nInternalFaces()); pointField neiCc(mesh.nFaces()-mesh.nInternalFaces());
for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++) for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++)
{ {
neiCc[faceI-mesh.nInternalFaces()] = cellCentres[own[faceI]]; neiCc[faceI-mesh.nInternalFaces()] = cellCentres[own[faceI]];
} }
syncTools::swapBoundaryFaceList(mesh, neiCc, true); syncTools::swapBoundaryFacePositions(mesh, neiCc);
scalar maxSkew = 0; scalar maxSkew = 0;
@ -1135,13 +1135,13 @@ bool Foam::polyMeshGeometry::checkFaceWeights
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const polyBoundaryMesh& patches = mesh.boundaryMesh();
// Calculate coupled cell centre // Calculate coupled cell centre
vectorField neiCc(mesh.nFaces()-mesh.nInternalFaces()); pointField neiCc(mesh.nFaces()-mesh.nInternalFaces());
for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++) for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++)
{ {
neiCc[faceI-mesh.nInternalFaces()] = cellCentres[own[faceI]]; neiCc[faceI-mesh.nInternalFaces()] = cellCentres[own[faceI]];
} }
syncTools::swapBoundaryFaceList(mesh, neiCc, true); syncTools::swapBoundaryFacePositions(mesh, neiCc);
scalar minWeight = GREAT; scalar minWeight = GREAT;
@ -1298,7 +1298,7 @@ bool Foam::polyMeshGeometry::checkVolRatio
{ {
neiVols[faceI-mesh.nInternalFaces()] = cellVolumes[own[faceI]]; neiVols[faceI-mesh.nInternalFaces()] = cellVolumes[own[faceI]];
} }
syncTools::swapBoundaryFaceList(mesh, neiVols, true); syncTools::swapBoundaryFaceList(mesh, neiVols);
scalar minRatio = GREAT; scalar minRatio = GREAT;
@ -1641,13 +1641,13 @@ bool Foam::polyMeshGeometry::checkFaceTwist
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const polyBoundaryMesh& patches = mesh.boundaryMesh();
// Calculate coupled cell centre // Calculate coupled cell centre
vectorField neiCc(mesh.nFaces()-mesh.nInternalFaces()); pointField neiCc(mesh.nFaces()-mesh.nInternalFaces());
for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++) for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++)
{ {
neiCc[faceI-mesh.nInternalFaces()] = cellCentres[own[faceI]]; neiCc[faceI-mesh.nInternalFaces()] = cellCentres[own[faceI]];
} }
syncTools::swapBoundaryFaceList(mesh, neiCc, true); syncTools::swapBoundaryFacePositions(mesh, neiCc);
forAll(checkFaces, i) forAll(checkFaces, i)
{ {

View File

@ -34,6 +34,7 @@ License
#include "polyModifyFace.H" #include "polyModifyFace.H"
#include "polyAddCell.H" #include "polyAddCell.H"
#include "globalIndex.H" #include "globalIndex.H"
#include "dummyTransform.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -103,8 +104,8 @@ Foam::labelListList Foam::addPatchCellLayer::calcGlobalEdgeFaces
mesh, mesh,
globalEdgeFaces, globalEdgeFaces,
uniqueEqOp(), uniqueEqOp(),
labelList(), // null value labelList(), // null value
false // no separation Foam::dummyTransform() // dummy transform
); );
// Extract pp part // Extract pp part
@ -636,7 +637,7 @@ void Foam::addPatchCellLayer::setRefinement
{ {
labelList n(mesh_.nPoints(), 0); labelList n(mesh_.nPoints(), 0);
UIndirectList<label>(n, meshPoints) = nPointLayers; UIndirectList<label>(n, meshPoints) = nPointLayers;
syncTools::syncPointList(mesh_, n, maxEqOp<label>(), 0, false); syncTools::syncPointList(mesh_, n, maxEqOp<label>(), 0);
// Non-synced // Non-synced
forAll(meshPoints, i) forAll(meshPoints, i)
@ -680,8 +681,7 @@ void Foam::addPatchCellLayer::setRefinement
mesh_, mesh_,
nFromFace, nFromFace,
maxEqOp<label>(), maxEqOp<label>(),
0, 0
false
); );
forAll(nPointLayers, i) forAll(nPointLayers, i)
@ -718,8 +718,7 @@ void Foam::addPatchCellLayer::setRefinement
mesh_, mesh_,
d, d,
minEqOp<vector>(), minEqOp<vector>(),
vector::max, vector::max
false
); );
forAll(meshPoints, i) forAll(meshPoints, i)
@ -1190,8 +1189,7 @@ void Foam::addPatchCellLayer::setRefinement
mesh_, mesh_,
meshEdgeLayers, meshEdgeLayers,
maxEqOp<label>(), maxEqOp<label>(),
0, // initial value 0 // initial value
false // no separation
); );
forAll(meshEdges, edgeI) forAll(meshEdges, edgeI)

View File

@ -708,8 +708,7 @@ void Foam::combineFaces::setRefinement
mesh_, mesh_,
nPointFaces, nPointFaces,
plusEqOp<label>(), plusEqOp<label>(),
0, // null value 0 // null value
false // no separation
); );
// Remove all unused points. Store position if undoable. // Remove all unused points. Store position if undoable.

View File

@ -412,8 +412,7 @@ Foam::scalar Foam::hexRef8::getLevel0EdgeLength() const
mesh_, mesh_,
edgeLevel, edgeLevel,
ifEqEqOp<labelMax>(), ifEqEqOp<labelMax>(),
labelMin, labelMin
false // no separation
); );
// Now use the edgeLevel with a valid value to determine the // Now use the edgeLevel with a valid value to determine the
@ -1618,7 +1617,7 @@ Foam::label Foam::hexRef8::faceConsistentRefinement
} }
// Swap to neighbour // Swap to neighbour
syncTools::swapBoundaryFaceList(mesh_, neiLevel, false); syncTools::swapBoundaryFaceList(mesh_, neiLevel);
// Now we have neighbour value see which cells need refinement // Now we have neighbour value see which cells need refinement
forAll(neiLevel, i) forAll(neiLevel, i)
@ -1700,7 +1699,7 @@ void Foam::hexRef8::checkWantedRefinementLevels
} }
// Swap to neighbour // Swap to neighbour
syncTools::swapBoundaryFaceList(mesh_, neiLevel, false); syncTools::swapBoundaryFaceList(mesh_, neiLevel);
// Now we have neighbour value see which cells need refinement // Now we have neighbour value see which cells need refinement
forAll(neiLevel, i) forAll(neiLevel, i)
@ -2369,8 +2368,7 @@ Foam::labelList Foam::hexRef8::consistentSlowRefinement
mesh_, mesh_,
maxPointCount, maxPointCount,
maxEqOp<label>(), maxEqOp<label>(),
labelMin, // null value labelMin // null value
false // no separation
); );
// Update allFaceInfo from maxPointCount for all points to check // Update allFaceInfo from maxPointCount for all points to check
@ -2509,9 +2507,9 @@ Foam::labelList Foam::hexRef8::consistentSlowRefinement
} }
// Swap to neighbour // Swap to neighbour
syncTools::swapBoundaryFaceList(mesh_, neiLevel, false); syncTools::swapBoundaryFaceList(mesh_, neiLevel);
syncTools::swapBoundaryFaceList(mesh_, neiCount, false); syncTools::swapBoundaryFaceList(mesh_, neiCount);
syncTools::swapBoundaryFaceList(mesh_, neiRefCount, false); syncTools::swapBoundaryFaceList(mesh_, neiRefCount);
// Now we have neighbour value see which cells need refinement // Now we have neighbour value see which cells need refinement
forAll(neiLevel, i) forAll(neiLevel, i)
@ -3156,8 +3154,7 @@ Foam::labelListList Foam::hexRef8::setRefinement
mesh_, mesh_,
edgeMidPoint, edgeMidPoint,
maxEqOp<label>(), maxEqOp<label>(),
labelMin, labelMin
false // no separation
); );
@ -3179,13 +3176,12 @@ Foam::labelListList Foam::hexRef8::setRefinement
edgeMids[edgeI] = mesh_.edges()[edgeI].centre(mesh_.points()); edgeMids[edgeI] = mesh_.edges()[edgeI].centre(mesh_.points());
} }
} }
syncTools::syncEdgeList syncTools::syncEdgePositions
( (
mesh_, mesh_,
edgeMids, edgeMids,
maxEqOp<vector>(), maxEqOp<vector>(),
point(-GREAT, -GREAT, -GREAT), point(-GREAT, -GREAT, -GREAT)
true // apply separation
); );
@ -3310,7 +3306,7 @@ Foam::labelListList Foam::hexRef8::setRefinement
} }
// Swap. // Swap.
syncTools::swapBoundaryFaceList(mesh_, newNeiLevel, false); syncTools::swapBoundaryFaceList(mesh_, newNeiLevel);
// So now we have information on the neighbour. // So now we have information on the neighbour.
@ -3342,8 +3338,7 @@ Foam::labelListList Foam::hexRef8::setRefinement
( (
mesh_, mesh_,
faceMidPoint, faceMidPoint,
maxEqOp<label>(), maxEqOp<label>()
false
); );
@ -3369,12 +3364,11 @@ Foam::labelListList Foam::hexRef8::setRefinement
bFaceMids[i] = mesh_.faceCentres()[faceI]; bFaceMids[i] = mesh_.faceCentres()[faceI];
} }
} }
syncTools::syncBoundaryFaceList syncTools::syncBoundaryFacePositions
( (
mesh_, mesh_,
bFaceMids, bFaceMids,
maxEqOp<vector>(), maxEqOp<vector>()
true // apply separation
); );
forAll(faceMidPoint, faceI) forAll(faceMidPoint, faceI)
@ -4404,7 +4398,7 @@ void Foam::hexRef8::checkMesh() const
} }
// Replace data on coupled patches with their neighbour ones. // Replace data on coupled patches with their neighbour ones.
syncTools::swapBoundaryFaceList(mesh_, nei, false); syncTools::swapBoundaryFaceList(mesh_, nei);
const polyBoundaryMesh& patches = mesh_.boundaryMesh(); const polyBoundaryMesh& patches = mesh_.boundaryMesh();
@ -4459,7 +4453,7 @@ void Foam::hexRef8::checkMesh() const
} }
// Replace data on coupled patches with their neighbour ones. // Replace data on coupled patches with their neighbour ones.
syncTools::swapBoundaryFaceList(mesh_, neiFaceAreas, false); syncTools::swapBoundaryFaceList(mesh_, neiFaceAreas);
forAll(neiFaceAreas, i) forAll(neiFaceAreas, i)
{ {
@ -4502,7 +4496,7 @@ void Foam::hexRef8::checkMesh() const
} }
// Replace data on coupled patches with their neighbour ones. // Replace data on coupled patches with their neighbour ones.
syncTools::swapBoundaryFaceList(mesh_, nVerts, false); syncTools::swapBoundaryFaceList(mesh_, nVerts);
forAll(nVerts, i) forAll(nVerts, i)
{ {
@ -4551,7 +4545,7 @@ void Foam::hexRef8::checkMesh() const
// Replace data on coupled patches with their neighbour ones. Apply // Replace data on coupled patches with their neighbour ones. Apply
// rotation transformation (but not separation since is relative vector // rotation transformation (but not separation since is relative vector
// to point on same face. // to point on same face.
syncTools::swapBoundaryFaceList(mesh_, anchorPoints, false); syncTools::swapBoundaryFaceList(mesh_, anchorPoints);
forAll(anchorPoints, i) forAll(anchorPoints, i)
{ {
@ -4656,7 +4650,7 @@ void Foam::hexRef8::checkRefinementLevels
} }
// No separation // No separation
syncTools::swapBoundaryFaceList(mesh_, neiLevel, false); syncTools::swapBoundaryFaceList(mesh_, neiLevel);
forAll(neiLevel, i) forAll(neiLevel, i)
{ {
@ -4698,8 +4692,7 @@ void Foam::hexRef8::checkRefinementLevels
mesh_, mesh_,
syncPointLevel, syncPointLevel,
minEqOp<label>(), minEqOp<label>(),
labelMax, labelMax
false // no separation
); );
@ -4746,8 +4739,7 @@ void Foam::hexRef8::checkRefinementLevels
mesh_, mesh_,
maxPointLevel, maxPointLevel,
maxEqOp<label>(), maxEqOp<label>(),
labelMin, // null value labelMin // null value
false // no separation
); );
// Check 2:1 across boundary points // Check 2:1 across boundary points
@ -5197,7 +5189,7 @@ Foam::labelList Foam::hexRef8::consistentUnrefinement
} }
// Swap to neighbour // Swap to neighbour
syncTools::swapBoundaryFaceList(mesh_, neiLevel, false); syncTools::swapBoundaryFaceList(mesh_, neiLevel);
forAll(neiLevel, i) forAll(neiLevel, i)
{ {

View File

@ -29,6 +29,7 @@ License
#include "mapPolyMesh.H" #include "mapPolyMesh.H"
#include "globalIndex.H" #include "globalIndex.H"
#include "indirectPrimitivePatch.H" #include "indirectPrimitivePatch.H"
#include "dummyTransform.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -57,15 +58,6 @@ public:
}; };
}; };
// Dummy transform for faces. Used in synchronisation
void transformList
(
const tensorField& rotTensor,
UList<face>& field
)
{};
} }
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -263,8 +255,7 @@ void Foam::localPointRegion::calcPointRegions
mesh, mesh,
candidatePoint, candidatePoint,
orEqOp<bool>(), orEqOp<bool>(),
false, // nullValue false // nullValue
false // applySeparation
); );
@ -419,12 +410,18 @@ void Foam::localPointRegion::calcPointRegions
// Transport minimum across coupled faces // Transport minimum across coupled faces
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
syncTools::syncFaceList SubList<face> l
(
minRegion,
mesh.nFaces()-mesh.nInternalFaces(),
mesh.nInternalFaces()
);
syncTools::syncBoundaryFaceList
( (
mesh, mesh,
minRegion, l,
minEqOpFace(), minEqOpFace(),
false // applySeparation Foam::dummyTransform() // dummy transformation
); );
} }

View File

@ -130,8 +130,7 @@ Foam::labelList Foam::removeCells::getExposedFaces
( (
mesh_, mesh_,
nCellsUsingFace, nCellsUsingFace,
plusEqOp<label>(), plusEqOp<label>()
false
); );
} }

View File

@ -1084,8 +1084,7 @@ void Foam::removeFaces::setRefinement
mesh_, mesh_,
nFacesPerEdge, nFacesPerEdge,
maxEqOp<label>(), maxEqOp<label>(),
labelMin, // guaranteed to be overridden by maxEqOp labelMin // guaranteed to be overridden by maxEqOp
false // no separation
); );
// Convert to labelHashSet // Convert to labelHashSet
@ -1187,8 +1186,7 @@ void Foam::removeFaces::setRefinement
syncTools::swapFaceList syncTools::swapFaceList
( (
mesh_, mesh_,
nbrFaceRegion, nbrFaceRegion
false // no separation
); );
labelList toNbrRegion(nRegions, -1); labelList toNbrRegion(nRegions, -1);
@ -1305,8 +1303,7 @@ void Foam::removeFaces::setRefinement
mesh_, mesh_,
nEdgesPerPoint, nEdgesPerPoint,
maxEqOp<label>(), maxEqOp<label>(),
labelMin, labelMin
false // no separation
); );
forAll(nEdgesPerPoint, pointI) forAll(nEdgesPerPoint, pointI)

View File

@ -33,6 +33,7 @@ License
#include "polyModifyFace.H" #include "polyModifyFace.H"
#include "syncTools.H" #include "syncTools.H"
#include "faceSet.H" #include "faceSet.H"
#include "dummyTransform.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -41,6 +42,55 @@ namespace Foam
defineTypeNameAndDebug(removePoints, 0); defineTypeNameAndDebug(removePoints, 0);
//- Combine-reduce operator to combine data on faces. Takes care
// of reverse orientation on coupled face.
template <class T, template<class> class CombineOp>
class faceEqOp
{
public:
void operator()(List<T>& x, const List<T>& y) const
{
if (y.size() > 0)
{
if (x.size() == 0)
{
x = y;
}
else
{
label j = 0;
forAll(x, i)
{
CombineOp<T>()(x[i], y[j]);
j = y.rcIndex(j);
}
}
}
}
};
//// Dummy transform for List. Used in synchronisation.
//template <class T>
//class dummyTransformList
//{
//public:
// void operator()(const coupledPolyPatch&, Field<List<T> >&) const
// {}
//};
//// Dummy template specialisation. Used in synchronisation.
//template<>
//class pTraits<boolList>
//{
//public:
//
// //- Component type
// typedef label cmptType;
//};
} }
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -247,8 +297,7 @@ Foam::label Foam::removePoints::countPointUsage
mesh_, mesh_,
pointCanBeDeleted, pointCanBeDeleted,
andEqOp<bool>(), andEqOp<bool>(),
true, // null value true // null value
false // no separation
); );
return returnReduce(nDeleted, sumOp<label>()); return returnReduce(nDeleted, sumOp<label>());
@ -662,7 +711,7 @@ void Foam::removePoints::getUnrefimentSet
mesh_, mesh_,
faceVertexRestore, faceVertexRestore,
faceEqOp<bool, orEqOp>(), // special operator to handle faces faceEqOp<bool, orEqOp>(), // special operator to handle faces
false // no separation Foam::dummyTransform() // no transformation
); );
// So now if any of the points-to-restore is used by any coupled face // So now if any of the points-to-restore is used by any coupled face

View File

@ -59,38 +59,6 @@ class face;
class removePoints class removePoints
{ {
// Private classes
//- Combine-reduce operator to combine data on faces. Takes care
// of reverse orientation on coupled face.
template <class T, template<class> class CombineOp>
class faceEqOp
{
public:
void operator()(List<T>& x, const List<T>& y) const
{
if (y.size() > 0)
{
if (x.empty())
{
x = y;
}
else
{
label j = 0;
forAll(x, i)
{
CombineOp<T>()(x[i], y[j]);
j = y.rcIndex(j);
}
}
}
}
};
// Private data // Private data
//- Reference to mesh //- Reference to mesh

View File

@ -21,6 +21,7 @@ $(constraintFvPatches)/symmetry/symmetryFvPatch.C
$(constraintFvPatches)/wedge/wedgeFvPatch.C $(constraintFvPatches)/wedge/wedgeFvPatch.C
$(constraintFvPatches)/cyclic/cyclicFvPatch.C $(constraintFvPatches)/cyclic/cyclicFvPatch.C
$(constraintFvPatches)/processor/processorFvPatch.C $(constraintFvPatches)/processor/processorFvPatch.C
$(constraintFvPatches)/processorCyclic/processorCyclicFvPatch.C
derivedFvPatches = $(fvPatches)/derived derivedFvPatches = $(fvPatches)/derived
$(derivedFvPatches)/wall/wallFvPatch.C $(derivedFvPatches)/wall/wallFvPatch.C
@ -99,6 +100,8 @@ $(constraintFvPatchFields)/empty/emptyFvPatchFields.C
$(constraintFvPatchFields)/jumpCyclic/jumpCyclicFvPatchFields.C $(constraintFvPatchFields)/jumpCyclic/jumpCyclicFvPatchFields.C
$(constraintFvPatchFields)/processor/processorFvPatchFields.C $(constraintFvPatchFields)/processor/processorFvPatchFields.C
$(constraintFvPatchFields)/processor/processorFvPatchScalarField.C $(constraintFvPatchFields)/processor/processorFvPatchScalarField.C
$(constraintFvPatchFields)/processorCyclic/processorCyclicFvPatchFields.C
$(constraintFvPatchFields)/processorCyclic/processorCyclicFvPatchScalarField.C
$(constraintFvPatchFields)/symmetry/symmetryFvPatchFields.C $(constraintFvPatchFields)/symmetry/symmetryFvPatchFields.C
$(constraintFvPatchFields)/wedge/wedgeFvPatchFields.C $(constraintFvPatchFields)/wedge/wedgeFvPatchFields.C
$(constraintFvPatchFields)/wedge/wedgeFvPatchScalarField.C $(constraintFvPatchFields)/wedge/wedgeFvPatchScalarField.C
@ -106,6 +109,7 @@ $(constraintFvPatchFields)/wedge/wedgeFvPatchScalarField.C
derivedFvPatchFields = $(fvPatchFields)/derived derivedFvPatchFields = $(fvPatchFields)/derived
$(derivedFvPatchFields)/activeBaffleVelocity/activeBaffleVelocityFvPatchVectorField.C $(derivedFvPatchFields)/activeBaffleVelocity/activeBaffleVelocityFvPatchVectorField.C
$(derivedFvPatchFields)/advective/advectiveFvPatchFields.C $(derivedFvPatchFields)/advective/advectiveFvPatchFields.C
$(derivedFvPatchFields)/directMappedFixedValue/directMappedFixedValueFvPatchFields.C $(derivedFvPatchFields)/directMappedFixedValue/directMappedFixedValueFvPatchFields.C
$(derivedFvPatchFields)/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C $(derivedFvPatchFields)/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C
$(derivedFvPatchFields)/fan/fanFvPatchFields.C $(derivedFvPatchFields)/fan/fanFvPatchFields.C
@ -165,6 +169,7 @@ constraintFvsPatchFields = $(fvsPatchFields)/constraint
$(constraintFvsPatchFields)/cyclic/cyclicFvsPatchFields.C $(constraintFvsPatchFields)/cyclic/cyclicFvsPatchFields.C
$(constraintFvsPatchFields)/empty/emptyFvsPatchFields.C $(constraintFvsPatchFields)/empty/emptyFvsPatchFields.C
$(constraintFvsPatchFields)/processor/processorFvsPatchFields.C $(constraintFvsPatchFields)/processor/processorFvsPatchFields.C
$(constraintFvsPatchFields)/processorCyclic/processorCyclicFvsPatchFields.C
$(constraintFvsPatchFields)/symmetry/symmetryFvsPatchFields.C $(constraintFvsPatchFields)/symmetry/symmetryFvsPatchFields.C
$(constraintFvsPatchFields)/wedge/wedgeFvsPatchFields.C $(constraintFvsPatchFields)/wedge/wedgeFvsPatchFields.C

Some files were not shown because too many files have changed in this diff Show More