Merge branch 'master' of ssh://noisy/home/noisy3/OpenFOAM/OpenFOAM-dev

This commit is contained in:
henry
2010-05-19 22:49:00 +01:00
316 changed files with 14159 additions and 6577 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

@ -1,4 +1,4 @@
Info<< "Reading transportProperties\n" << endl;
Info<< "\nReading transportProperties\n" << endl;
IOdictionary transportProperties
(
@ -31,7 +31,7 @@
rhoInfValue
);
Info<< "\nReading field U\n" << endl;
Info<< "Reading field U\n" << endl;
volVectorField U
(
IOobject
@ -127,7 +127,7 @@
if (HdotGradHheader.headerOk())
{
Info<< "\nReading field HdotGradH\n" << endl;
Info<< "Reading field HdotGradH" << endl;
HdotGradHPtr_.reset
(

View File

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

View File

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

View File

@ -158,7 +158,6 @@ void Foam::createShellMesh::calcPointRegions
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::createShellMesh::createShellMesh
@ -184,7 +183,6 @@ Foam::createShellMesh::createShellMesh
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::createShellMesh::setRefinement
(
const pointField& thickness,

View File

@ -130,6 +130,7 @@ Usage
#include "volFields.H"
#include "surfaceFields.H"
#include "cyclicPolyPatch.H"
#include "syncTools.H"
using namespace Foam;
@ -595,6 +596,237 @@ void createDummyFvMeshFiles(const polyMesh& mesh, const word& regionName)
}
//XXXXXXXXX
label findUncoveredPatchFace
(
const fvMesh& mesh,
const UIndirectList<label>& extrudeMeshFaces,// mesh faces that are extruded
const label meshEdgeI // mesh edge
)
{
// Make set of extruded faces.
labelHashSet extrudeFaceSet(extrudeMeshFaces.size());
forAll(extrudeMeshFaces, i)
{
extrudeFaceSet.insert(extrudeMeshFaces[i]);
}
label patchI = -1;
const labelList& eFaces = mesh.edgeFaces()[meshEdgeI];
forAll(eFaces, i)
{
label faceI = eFaces[i];
if (!mesh.isInternalFace(faceI) && !extrudeFaceSet.found(faceI))
{
patchI = mesh.boundaryMesh().whichPatch(faceI);
break;
}
}
return patchI;
}
// Count the number of faces in patches that need to be created
void countExtrudePatches
(
const fvMesh& mesh,
const primitiveFacePatch& extrudePatch,
const label nZones,
const labelList& zoneID,
const labelList& extrudeMeshFaces,
const labelList& extrudeMeshEdges,
labelList& zoneSidePatch,
labelList& zoneZonePatch
)
{
const labelListList& edgeFaces = extrudePatch.edgeFaces();
forAll(edgeFaces, edgeI)
{
const labelList& eFaces = edgeFaces[edgeI];
if (eFaces.size() == 2)
{
label zone0 = zoneID[eFaces[0]];
label zone1 = zoneID[eFaces[1]];
if (zone0 != zone1)
{
label minZone = min(zone0,zone1);
label maxZone = max(zone0,zone1);
zoneZonePatch[minZone*nZones+maxZone]++;
}
}
else
{
// Check whether we are on a mesh edge with external patches. If
// so choose any uncovered one. If none found put face in
// undetermined zone 'side' patch
label patchI = findUncoveredPatchFace
(
mesh,
UIndirectList<label>(extrudeMeshFaces, eFaces),
extrudeMeshEdges[edgeI]
);
if (patchI == -1)
{
// Determine the min zone of all connected zones.
label minZone = zoneID[eFaces[0]];
for (label i = 1; i < eFaces.size(); i++)
{
minZone = min(minZone, zoneID[eFaces[i]]);
}
zoneSidePatch[minZone]++;
}
}
}
Pstream::listCombineGather(zoneSidePatch, plusEqOp<label>());
Pstream::listCombineScatter(zoneSidePatch);
Pstream::listCombineGather(zoneZonePatch, plusEqOp<label>());
Pstream::listCombineScatter(zoneZonePatch);
}
bool lessThan(const point& x, const point& y)
{
for (direction dir = 0; dir < point::nComponents; dir++)
{
if (x[dir] < y[dir]) return true;
if (x[dir] > y[dir]) return false;
}
return false;
}
class minEqVectorListOp
{
public:
void operator()(List<vector>& x, const List<vector>& y) const
{
if (y.size())
{
if (x.size())
{
forAll(x, i)
{
if (lessThan(y[i], x[i]))
{
x[i] = y[i];
}
}
}
else
{
x = y;
}
}
}
};
// Constrain&sync normals on points that are on coupled patches.
void constrainCoupledNormals
(
const fvMesh& mesh,
const primitiveFacePatch& extrudePatch,
const labelList& regionToPoint,
vectorField& regionNormals
)
{
// Invert regionToPoint to create pointToRegions.
labelListList pointToRegions
(
invertOneToMany
(
extrudePatch.nPoints(),
regionToPoint
)
);
// Sort acc. to region so (hopefully) coupled points will do the same.
forAll(pointToRegions, pointI)
{
sort(pointToRegions[pointI]);
}
const polyBoundaryMesh& patches = mesh.boundaryMesh();
// Constrain displacement on cyclic patches
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Note: bit contentious to always do this on cyclic - should user use
// different patch type, e.g. 'cyclicSlip' instead?
forAll(patches, patchI)
{
const polyPatch& pp = patches[patchI];
if (isA<cyclicPolyPatch>(pp))
{
forAll(pp.meshPoints(), pointI)
{
Map<label>::const_iterator fnd =
extrudePatch.meshPointMap().find
(
pp.meshPoints()[pointI]
);
if (fnd != extrudePatch.meshPointMap().end())
{
// fnd() is a point on this cyclic.
const vector& cycNormal = pp.pointNormals()[pointI];
const labelList& pRegions = pointToRegions[fnd()];
forAll(pRegions, i)
{
// Remove cyclic normal component.
vector& regionNormal = regionNormals[pRegions[i]];
regionNormal -= (regionNormal&cycNormal)*cycNormal;
}
}
}
}
}
// Synchronise regionNormals
// ~~~~~~~~~~~~~~~~~~~~~~~~~
// Re-work regionNormals into multiple normals per point
List<List<vector> > pointNormals(mesh.nPoints());
forAll(pointToRegions, pointI)
{
const labelList& pRegions = pointToRegions[pointI];
label meshPointI = extrudePatch.meshPoints()[pointI];
List<vector>& pNormals = pointNormals[meshPointI];
pNormals.setSize(pRegions.size());
forAll(pRegions, i)
{
pNormals[i] = regionNormals[pRegions[i]];
}
}
// Synchronise
syncTools::syncPointList
(
mesh,
pointNormals,
minEqVectorListOp(),
List<vector>(), // nullValue
false // applySeparation
);
// Re-work back into regionNormals
forAll(pointToRegions, pointI)
{
const labelList& pRegions = pointToRegions[pointI];
label meshPointI = extrudePatch.meshPoints()[pointI];
const List<vector>& pNormals = pointNormals[meshPointI];
forAll(pRegions, i)
{
regionNormals[pRegions[i]] = pNormals[i];
}
}
}
//XXXXXXXXX
tmp<pointField> calcOffset
(
const primitiveFacePatch& extrudePatch,
@ -739,6 +971,16 @@ int main(int argc, char *argv[])
<< endl;
// Determine corresponding mesh edges
const labelList extrudeMeshEdges
(
extrudePatch.meshEdges
(
mesh.edges(),
mesh.pointEdges()
)
);
// Check whether the zone is internal or external faces to determine
@ -772,7 +1014,7 @@ int main(int argc, char *argv[])
Info<< "FaceZone " << fz.name() << " has boundary faces" << endl;
}
}
Info<< endl;
@ -866,36 +1108,18 @@ int main(int argc, char *argv[])
labelList zoneSidePatch(faceZones.size(), 0);
labelList zoneZonePatch(faceZones.size()*faceZones.size(), 0);
forAll(edgeFaces, edgeI)
{
const labelList& eFaces = edgeFaces[edgeI];
if (eFaces.size() == 2)
{
label zone0 = zoneID[eFaces[0]];
label zone1 = zoneID[eFaces[1]];
countExtrudePatches
(
mesh,
extrudePatch,
faceZones.size(),
zoneID,
extrudeMeshFaces,
extrudeMeshEdges,
if (zone0 != zone1)
{
label minZone = min(zone0,zone1);
label maxZone = max(zone0,zone1);
zoneZonePatch[minZone*faceZones.size()+maxZone]++;
}
}
else
{
// Determine the min zone of all connected zones.
label minZone = zoneID[eFaces[0]];
for (label i = 1; i < eFaces.size(); i++)
{
minZone = min(minZone, zoneID[eFaces[i]]);
}
zoneSidePatch[minZone]++;
}
}
Pstream::listCombineGather(zoneSidePatch, plusEqOp<label>());
Pstream::listCombineScatter(zoneSidePatch);
Pstream::listCombineGather(zoneZonePatch, plusEqOp<label>());
Pstream::listCombineScatter(zoneZonePatch);
zoneSidePatch,
zoneZonePatch
);
// Now check which patches to add.
Info<< "Adding patches for edges on zones:" << nl << nl
@ -980,6 +1204,7 @@ int main(int argc, char *argv[])
// Is edge an non-manifold edge
PackedBoolList nonManifoldEdge(extrudePatch.nEdges());
// Note: logic has to be same as in countExtrudePatches.
forAll(edgeFaces, edgeI)
{
const labelList& eFaces = edgeFaces[edgeI];
@ -1003,64 +1228,30 @@ int main(int argc, char *argv[])
}
}
else
{
label patchI = findUncoveredPatchFace
(
mesh,
UIndirectList<label>(extrudeMeshFaces, eFaces),
extrudeMeshEdges[edgeI]
);
if (patchI != -1)
{
ePatches.setSize(eFaces.size(), patchI);
}
else
{
ePatches.setSize(eFaces.size());
forAll(eFaces, i)
{
ePatches[i] = zoneSidePatch[zoneID[eFaces[i]]];
}
}
nonManifoldEdge[edgeI] = 1;
}
}
// Override constraint types
{
const edgeList& extrudeEdges = extrudePatch.edges();
const labelList& extrudeMeshPts = extrudePatch.meshPoints();
// Map from mesh edge to local patch edge index
EdgeMap<label> extrudeMeshEdges(extrudePatch.nEdges());
forAll(extrudeEdges, edgeI)
{
if (edgeFaces[edgeI].size() == 1)
{
const edge& e = extrudeEdges[edgeI];
const edge meshE(extrudeMeshPts[e[0]], extrudeMeshPts[e[1]]);
extrudeMeshEdges.insert(meshE, edgeI);
}
}
forAll(patches, patchI)
{
const polyPatch& pp = patches[patchI];
if (polyPatch::constraintType(pp.type()))
{
const edgeList& edges = pp.edges();
forAll(edges, ppEdgeI)
{
const edge& e = edges[ppEdgeI];
edge meshE(pp.meshPoints()[e[0]], pp.meshPoints()[e[1]]);
EdgeMap<label>::const_iterator iter = extrudeMeshEdges.find
(
meshE
);
if (iter != extrudeMeshEdges.end())
{
label extrudeEdgeI = iter();
extrudeEdgePatches[extrudeEdgeI] = labelList
(
edgeFaces[extrudeEdgeI].size(),
patchI
);
}
}
}
}
}
// Assign point regions
@ -1075,6 +1266,7 @@ int main(int argc, char *argv[])
(
extrudePatch,
nonManifoldEdge,
pointRegions,
regionPoints
);
@ -1096,6 +1288,18 @@ int main(int argc, char *argv[])
}
regionNormals /= mag(regionNormals);
// Constrain&sync normals on points that are on coupled patches.
constrainCoupledNormals
(
mesh,
extrudePatch,
regionPoints,
regionNormals
);
// For debugging: dump hedgehog plot of normals
{
OFstream str(runTime.path()/"regionNormals.obj");
@ -1112,7 +1316,7 @@ int main(int argc, char *argv[])
meshTools::writeOBJ(str, pt);
vertI++;
meshTools::writeOBJ(str, pt+0.01*regionNormals[region]);
meshTools::writeOBJ(str, pt+thickness*regionNormals[region]);
vertI++;
str << "l " << vertI-1 << ' ' << vertI << nl;
}

View File

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

View File

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

View File

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

View File

@ -560,7 +560,7 @@ void getInterfaceSizes
label cellI = mesh.faceOwner()[i+mesh.nInternalFaces()];
coupledRegion[i] = cellRegion[cellI];
}
syncTools::swapBoundaryFaceList(mesh, coupledRegion, false);
syncTools::swapBoundaryFaceList(mesh, coupledRegion);
forAll(coupledRegion, i)
{
@ -730,7 +730,7 @@ autoPtr<mapPolyMesh> createRegionMesh
label cellI = mesh.faceOwner()[i+mesh.nInternalFaces()];
coupledRegion[i] = cellRegion[cellI];
}
syncTools::swapBoundaryFaceList(mesh, coupledRegion, false);
syncTools::swapBoundaryFaceList(mesh, coupledRegion);
// Topology change container. Start off from existing mesh.
@ -1300,7 +1300,7 @@ void getZoneID
{
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 "fvCFD.H"
#include "IOobjectList.H"
#include "processorFvPatchFields.H"
#include "domainDecomposition.H"
#include "labelIOField.H"
#include "scalarIOField.H"

View File

@ -25,7 +25,7 @@ numberOfSubdomains 4;
//- Keep owner and neighbour on same processor for faces in patches:
// (makes sense only for cyclic patches)
//preservePatches (cyclic_left_right);
//preservePatches (cyclic_half0 cyclic_half1);
method scotch;

View File

@ -28,6 +28,7 @@ License
#include "dictionary.H"
#include "labelIOList.H"
#include "processorPolyPatch.H"
#include "processorCyclicPolyPatch.H"
#include "fvMesh.H"
#include "OSspecific.H"
#include "Map.H"
@ -108,7 +109,8 @@ Foam::domainDecomposition::domainDecomposition(const IOobject& io)
procNeighbourProcessors_(nProcs_),
procProcessorPatchSize_(nProcs_),
procProcessorPatchStartIndex_(nProcs_),
cyclicParallel_(false)
procProcessorPatchSubPatchIDs_(nProcs_),
procProcessorPatchSubPatchStarts_(nProcs_)
{
if (decompositionDict_.found("distributed"))
{
@ -343,12 +345,42 @@ bool Foam::domainDecomposition::writeDecomposition()
const labelList& curProcessorPatchStarts =
procProcessorPatchStartIndex_[procI];
const labelListList& curSubPatchIDs =
procProcessorPatchSubPatchIDs_[procI];
const labelListList& curSubStarts =
procProcessorPatchSubPatchStarts_[procI];
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
// << " patches to neighbouring processors" << endl;
List<polyPatch*> procPatches
(
curPatchSizes.size()
+ curProcessorPatchSizes.size(),
+ nInterProcPatches, //curProcessorPatchSizes.size(),
reinterpret_cast<polyPatch*>(0)
);
@ -385,22 +417,83 @@ bool Foam::domainDecomposition::writeDecomposition()
forAll(curProcessorPatchSizes, procPatchI)
{
const labelList& subPatchID = curSubPatchIDs[procPatchI];
const labelList& subStarts = curSubStarts[procPatchI];
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)
+ word("to")
+ "to"
+ Foam::name(curNeighbourProcessors[procPatchI]),
curProcessorPatchSizes[procPatchI],
curProcessorPatchStarts[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
procMesh.addPatches(procPatches);
@ -667,11 +760,7 @@ bool Foam::domainDecomposition::writeDecomposition()
forAll(procMesh.boundaryMesh(), patchi)
{
if
(
procMesh.boundaryMesh()[patchi].type()
== processorPolyPatch::typeName
)
if (isA<processorPolyPatch>(procMesh.boundaryMesh()[patchi]))
{
const processorPolyPatch& ppp =
refCast<const processorPolyPatch>
@ -749,11 +838,7 @@ bool Foam::domainDecomposition::writeDecomposition()
// (= identity map for original patches, -1 for processor patches)
label nMeshPatches = curPatchSizes.size();
labelList procBoundaryAddressing(identity(nMeshPatches));
procBoundaryAddressing.setSize
(
nMeshPatches+curProcessorPatchSizes.size(),
-1
);
procBoundaryAddressing.setSize(nMeshPatches+nProcPatches, -1);
labelIOList boundaryProcAddressing
(

View File

@ -29,6 +29,7 @@ Description
SourceFiles
domainDecomposition.C
decomposeMesh.C
\*---------------------------------------------------------------------------*/
@ -78,9 +79,9 @@ class domainDecomposition
// index is negative, the processor face is the reverse of the
// original face. In order to do this properly, all face
// 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.
labelListList procFaceAddressing_;
List<DynamicList<label> > procFaceAddressing_;
//- Labels of cells for each processor
labelListList procCellAddressing_;
@ -93,18 +94,23 @@ class domainDecomposition
// Excludes inter-processor boundaries
labelListList procPatchStartIndex_;
// Per inter-processor patch information
//- Neighbour processor ID for inter-processor boundaries
labelListList procNeighbourProcessors_;
//- Sizes for inter-processor patches
labelListList procProcessorPatchSize_;
//- Start indices for inter-processor patches
//- Start indices (in procFaceAddressing_) for inter-processor patches
labelListList procProcessorPatchStartIndex_;
//- Are there cyclic-parallel faces
bool cyclicParallel_;
//- Sub patch IDs for inter-processor patches
List<labelListList> procProcessorPatchSubPatchIDs_;
//- Sub patch sizes for inter-processor patches
List<labelListList> procProcessorPatchSubPatchStarts_;
// Private Member Functions
@ -118,6 +124,21 @@ class domainDecomposition
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:
// Constructors

View File

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

View File

@ -39,6 +39,63 @@ Description
// * * * * * * * * * * * * * 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()
{
// Decide which cell goes to which processor
@ -60,31 +117,8 @@ void Foam::domainDecomposition::decomposeMesh()
Info<< "\nDistributing cells to processors" << endl;
// Memory management
{
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];
}
}
// Cells per processor
procCellAddressing_ = invertOneToMany(nProcs_, cellToProc_);
Info<< "\nDistributing faces to processors" << endl;
@ -93,151 +127,34 @@ void Foam::domainDecomposition::decomposeMesh()
// same processor, the face is an internal face. If they are different,
// it belongs to both processors.
// Memory management
{
List<SLList<label> > procFaceList(nProcs_);
procFaceAddressing_.setSize(nProcs_);
forAll(neighbour, facei)
// Internal faces
forAll (neighbour, facei)
{
if (cellToProc_[owner[facei]] == cellToProc_[neighbour[facei]])
{
// Face internal to processor
procFaceList[cellToProc_[owner[facei]]].append(facei);
// Face internal to processor. Notice no turning index.
procFaceAddressing_[cellToProc_[owner[facei]]].append(facei+1);
}
}
// Detect inter-processor boundaries
// Neighbour processor for each subdomain
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]])
{
// inter - processor patch face found. Go through the list of
// inside boundaries for the owner processor and try to find
// this inter-processor patch.
label ownerProc = cellToProc_[owner[facei]];
label neighbourProc = cellToProc_[neighbour[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(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));
}
}
}
// 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)
forAll (procPatchSize_, procI)
{
procPatchSize_[procI].setSize(patches.size());
procPatchStartIndex_[procI].setSize(patches.size());
}
forAll(patches, patchi)
forAll (patches, patchi)
{
// Reset size and start index for all processors
forAll(procPatchSize_, procI)
forAll (procPatchSize_, procI)
{
procPatchSize_[procI][patchi] = 0;
procPatchStartIndex_[procI][patchi] =
procFaceList[procI].size();
procFaceAddressing_[procI].size();
}
const label patchStart = patches[patchi].start();
@ -250,12 +167,12 @@ void Foam::domainDecomposition::decomposeMesh()
const unallocLabelList& patchFaceCells =
patches[patchi].faceCells();
forAll(patchFaceCells, facei)
forAll (patchFaceCells, facei)
{
const label curProc = cellToProc_[patchFaceCells[facei]];
// add the face
procFaceList[curProc].append(patchStart + facei);
// add the face without turning index
procFaceAddressing_[curProc].append(patchStart+facei+1);
// increment the number of faces for this patch
procPatchSize_[curProc][patchi]++;
@ -263,333 +180,282 @@ void Foam::domainDecomposition::decomposeMesh()
}
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
const cyclicPolyPatch& pp = refCast<const cyclicPolyPatch>
(
cPatch.faceCells(),
cycOffset
patches[patchi]
);
// cyclic: check opposite side on this processor
const unallocLabelList& patchFaceCells = pp.faceCells();
const labelList::subList secondFaceCells
(
cPatch.faceCells(),
cycOffset,
cycOffset
);
const unallocLabelList& nbrPatchFaceCells =
pp.neighbPatch().faceCells();
forAll(firstFaceCells, facei)
forAll (patchFaceCells, facei)
{
if
(
cellToProc_[firstFaceCells[facei]]
!= cellToProc_[secondFaceCells[facei]]
)
const label curProc = cellToProc_[patchFaceCells[facei]];
const label nbrProc = cellToProc_[nbrPatchFaceCells[facei]];
if (curProc == nbrProc)
{
// 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);
// add the face without turning index
procFaceAddressing_[curProc].append(patchStart+facei+1);
// 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
//
procPatchSize_[curProc][patchi]++;
}
}
}
}
// Ordering in cyclic boundaries is important.
// Add the other half of cyclic faces for cyclic boundaries
// that remain on the processor
forAll(secondFaceCells, facei)
// Done internal bits of the new mesh and the ordinary patches.
// 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)
{
if
label ownerProc = cellToProc_[owner[facei]];
label nbrProc = cellToProc_[neighbour[facei]];
if (ownerProc != nbrProc)
{
// inter - processor patch face found.
addInterProcFace
(
cellToProc_[firstFaceCells[facei]]
== cellToProc_[secondFaceCells[facei]]
)
facei,
ownerProc,
nbrProc,
procNbrToInterPatch,
interPatchFaces
);
}
}
// Add the proper processor faces to the sub information. For faces
// originating from internal faces this is always -1.
List<labelListList> subPatchIDs(nProcs_);
List<labelListList> subPatchStarts(nProcs_);
forAll(interPatchFaces, procI)
{
// This cyclic face remains on the processor
label ownerProc = cellToProc_[firstFaceCells[facei]];
label nInterfaces = interPatchFaces[procI].size();
// add the second face
procFaceList[ownerProc].append
(patchStart + cycOffset + facei);
// increment the number of faces for this patch
procPatchSize_[ownerProc][patchi]++;
}
}
}
subPatchIDs[procI].setSize(nInterfaces, labelList(1, -1));
subPatchStarts[procI].setSize(nInterfaces, labelList(1, 0));
}
// Convert linked lists into normal lists
// Add inter-processor boundaries and remember start indices
forAll(procFaceList, procI)
// Processor boundaries from split cyclics
forAll (patches, patchi)
{
// Get internal and regular boundary processor faces
SLList<label>& curProcFaces = procFaceList[procI];
// 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
if (isA<cyclicPolyPatch>(patches[patchi]))
{
const cyclicPolyPatch& pp = refCast<const cyclicPolyPatch>
(
SLList<SLList<label> >::iterator curInterProcBFacesIter =
interProcBFaces[procI].begin();
curInterProcBFacesIter != interProcBFaces[procI].end();
++curInterProcBFacesIter
)
{
nFacesOnProcessor += curInterProcBFacesIter().size();
}
curProcFaceAddressing.setSize(nFacesOnProcessor);
// Fill in the list. Calculate turning index.
// Turning index will be -1 only for some faces on processor
// boundaries, i.e. the ones where the current processor ID
// is in the cell which is a face neighbour.
// Turning index is stored as the sign of the face addressing list
label nFaces = 0;
// Add internal and boundary faces
// Remember to increment the index by one such that the
// turning index works properly.
forAllConstIter(SLList<label>, curProcFaces, curProcFacesIter)
{
curProcFaceAddressing[nFaces] = curProcFacesIter() + 1;
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();
const unallocLabelList& nbrPatchFaceCells =
pp.neighbPatch().faceCells();
// Store old sizes. Used to detect which inter-proc patches
// have been added to.
labelListList oldInterfaceSizes(nProcs_);
forAll(oldInterfaceSizes, procI)
{
labelList& curOldSizes = oldInterfaceSizes[procI];
curOldSizes.setSize(interPatchFaces[procI].size());
forAll(curOldSizes, interI)
{
curOldSizes[interI] =
interPatchFaces[procI][interI].size();
}
}
// 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
(
interProcBoundaries[procI].size()
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[interPatch].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]
);
curProcProcessorPatchStartIndex.setSize
(
interProcBoundaries[procI].size()
);
//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;
label nProcPatches = 0;
// And add all the face labels for interPatch
DynamicList<label>& interPatchFaces =
curInterPatchFaces[interPatch];
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
)
forAll(interPatchFaces, j)
{
curProcNeighbourProcessors[nProcPatches] =
curInterProcBdrsIter();
// Get start index for processor patch
curProcProcessorPatchStartIndex[nProcPatches] = nFaces;
label& curSize =
curProcProcessorPatchSize[nProcPatches];
curSize = 0;
// add faces for this processor boundary
forAllConstIter
(
SLList<label>,
curInterProcBFacesIter(),
curFacesIter
)
{
// add the face
// Remember to increment the index by one such that the
// turning index works properly.
if (cellToProc_[owner[curFacesIter()]] == procI)
{
curProcFaceAddressing[nFaces] = curFacesIter() + 1;
procFaceAddressing_[procI].append(interPatchFaces[j]);
}
else
{
// turning face
curProcFaceAddressing[nFaces] = -(curFacesIter() + 1);
interPatchFaces.clearStorage();
}
curInterPatchFaces.clearStorage();
procFaceAddressing_[procI].shrink();
}
// increment the size
curSize++;
nFaces++;
}
////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;
// }
nProcPatches++;
}
}
}
Info<< "\nDistributing points to processors" << endl;
// For every processor, loop through the list of faces for the processor.

View File

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

View File

@ -26,6 +26,8 @@ License
#include "fvFieldDecomposer.H"
#include "processorFvPatchField.H"
#include "processorFvsPatchField.H"
#include "processorCyclicFvPatchField.H"
#include "processorCyclicFvsPatchField.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -44,7 +46,7 @@ Foam::fvFieldDecomposer::decomposeField
forAll(boundaryAddressing_, patchi)
{
if (boundaryAddressing_[patchi] >= 0)
if (patchFieldDecomposerPtrs_[patchi])
{
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
(
@ -75,6 +94,11 @@ Foam::fvFieldDecomposer::decomposeField
)
);
}
else
{
FatalErrorIn("fvFieldDecomposer::decomposeField()")
<< "Unknown type." << abort(FatalError);
}
}
// Create the field for the processor
@ -155,7 +179,7 @@ Foam::fvFieldDecomposer::decomposeField
forAll(boundaryAddressing_, patchi)
{
if (boundaryAddressing_[patchi] >= 0)
if (patchFieldDecomposerPtrs_[patchi])
{
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
(
@ -186,6 +227,11 @@ Foam::fvFieldDecomposer::decomposeField
)
);
}
else
{
FatalErrorIn("fvFieldDecomposer::decomposeField()")
<< "Unknown type." << abort(FatalError);
}
}
// Create the field for the processor

View File

@ -651,7 +651,7 @@ void Foam::vtkPV3Foam::renderPatchNames(vtkRenderer* renderer, const bool show)
labelList nZones(pbMesh.size(), 0);
// Per global zone number the average face centre position
DynamicList<point> zoneCentre(pbMesh.size());
List<DynamicList<point> > zoneCentre(pbMesh.size());
// Loop through all patches to determine zones, and centre of each zone
@ -693,31 +693,28 @@ void Foam::vtkPV3Foam::renderPatchNames(vtkRenderer* renderer, const bool show)
labelList zoneNFaces(pZones.nZones(), 0);
// Save start of information for current patch
label patchStart = zoneCentre.size();
// Create storage for additional zone centres
forAll(zoneNFaces, zoneI)
{
zoneCentre.append(vector::zero);
zoneCentre[patchI].append(vector::zero);
}
// Do averaging per individual zone
forAll(pp, faceI)
{
label zoneI = pZones[faceI];
zoneCentre[patchStart+zoneI] += pp[faceI].centre(pp.points());
zoneCentre[patchI][zoneI] += pp[faceI].centre(pp.points());
zoneNFaces[zoneI]++;
}
for (label i=0; i<nZones[patchI]; i++)
forAll(zoneCentre[patchI], zoneI)
{
zoneCentre[patchStart + i] /= zoneNFaces[i];
zoneCentre[patchI][zoneI] /= zoneNFaces[zoneI];
}
}
// Count number of zones we're actually going to display. This is truncated
// to a max per patch
// Count number of zones we're actually going to display.
// This is truncated to a max per patch
const label MAXPATCHZONES = 20;
@ -728,13 +725,9 @@ void Foam::vtkPV3Foam::renderPatchNames(vtkRenderer* renderer, const bool show)
displayZoneI += min(MAXPATCHZONES, nZones[patchI]);
}
zoneCentre.shrink();
if (debug)
{
Info<< "patch zone centres = " << zoneCentre << nl
<< "displayed zone centres = " << displayZoneI << nl
Info<< "displayed zone centres = " << displayZoneI << nl
<< "zones per patch = " << nZones << endl;
}
@ -749,13 +742,12 @@ void Foam::vtkPV3Foam::renderPatchNames(vtkRenderer* renderer, const bool show)
// Actor index
displayZoneI = 0;
// Index in zone centres
label globalZoneI = 0;
forAll(pbMesh, patchI)
{
const polyPatch& pp = pbMesh[patchI];
label globalZoneI = 0;
// Only selected patches will have a non-zero number of zones
label nDisplayZones = min(MAXPATCHZONES, nZones[patchI]);
label increment = 1;
@ -769,7 +761,7 @@ void Foam::vtkPV3Foam::renderPatchNames(vtkRenderer* renderer, const bool show)
if (debug)
{
Info<< "patch name = " << pp.name() << nl
<< "anchor = " << zoneCentre[globalZoneI] << nl
<< "anchor = " << zoneCentre[patchI][globalZoneI] << nl
<< "globalZoneI = " << globalZoneI << endl;
}
@ -792,9 +784,9 @@ void Foam::vtkPV3Foam::renderPatchNames(vtkRenderer* renderer, const bool show)
txt->GetPositionCoordinate()->SetValue
(
zoneCentre[globalZoneI].x(),
zoneCentre[globalZoneI].y(),
zoneCentre[globalZoneI].z()
zoneCentre[patchI][globalZoneI].x(),
zoneCentre[patchI][globalZoneI].y(),
zoneCentre[patchI][globalZoneI].z()
);
// Add text to each renderer

View File

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

View File

@ -30,7 +30,6 @@ Description
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "cyclicPolyPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
@ -76,35 +75,12 @@ int main(int argc, char *argv[])
}
// Give patch area
if (isA<cyclicPolyPatch>(mesh.boundaryMesh()[patchI]))
{
Info<< " Cyclic patch vector area: " << nl;
label nFaces = mesh.boundaryMesh()[patchI].size();
vector sum1 = vector::zero;
vector sum2 = vector::zero;
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
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/GAMGInterfaceNew.C
$(GAMGInterfaces)/processorGAMGInterface/processorGAMGInterface.C
$(GAMGInterfaces)/processorCyclicGAMGInterface/processorCyclicGAMGInterface.C
$(GAMGInterfaces)/cyclicGAMGInterface/cyclicGAMGInterface.C
GAMGInterfaceFields = $(GAMG)/interfaceFields
$(GAMGInterfaceFields)/GAMGInterfaceField/GAMGInterfaceField.C
$(GAMGInterfaceFields)/GAMGInterfaceField/GAMGInterfaceFieldNew.C
$(GAMGInterfaceFields)/processorGAMGInterfaceField/processorGAMGInterfaceField.C
$(GAMGInterfaceFields)/processorCyclicGAMGInterfaceField/processorCyclicGAMGInterfaceField.C
$(GAMGInterfaceFields)/cyclicGAMGInterfaceField/cyclicGAMGInterfaceField.C
GAMGAgglomerations = $(GAMG)/GAMGAgglomerations
@ -339,6 +341,7 @@ $(constraintPolyPatches)/empty/emptyPolyPatch.C
$(constraintPolyPatches)/symmetry/symmetryPolyPatch.C
$(constraintPolyPatches)/wedge/wedgePolyPatch.C
$(constraintPolyPatches)/cyclic/cyclicPolyPatch.C
$(constraintPolyPatches)/processorCyclic/processorCyclicPolyPatch.C
$(constraintPolyPatches)/processor/processorPolyPatch.C
derivedPolyPatches = $(polyPatches)/derived
@ -450,6 +453,7 @@ $(constraintPointPatches)/symmetry/symmetryPointPatch.C
$(constraintPointPatches)/wedge/wedgePointPatch.C
$(constraintPointPatches)/cyclic/cyclicPointPatch.C
$(constraintPointPatches)/processor/processorPointPatch.C
$(constraintPointPatches)/processorCyclic/processorCyclicPointPatch.C
derivedPointPatches = $(pointPatches)/derived
$(derivedPointPatches)/coupled/coupledFacePointPatch.C
@ -508,6 +512,7 @@ $(constraintPointPatchFields)/wedge/wedgePointPatchFields.C
$(constraintPointPatchFields)/cyclic/cyclicPointPatchFields.C
$(constraintPointPatchFields)/cyclicSlip/cyclicSlipPointPatchFields.C
$(constraintPointPatchFields)/processor/processorPointPatchFields.C
$(constraintPointPatchFields)/processorCyclic/processorCyclicPointPatchFields.C
derivedPointPatchFields = $(pointPatchFields)/derived
$(derivedPointPatchFields)/slip/slipPointPatchFields.C

View File

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

View File

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

View File

@ -219,6 +219,30 @@ Foam::List<int> Foam::UPstream::procIDs_(1, 0);
// Standard transfer message type
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
Foam::List<Foam::UPstream::commsStruct> Foam::UPstream::linearCommunication_(0);

View File

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

View File

@ -26,6 +26,7 @@ License
#include "emptyPolyPatch.H"
#include "commSchedule.H"
#include "globalMeshData.H"
#include "cyclicPolyPatch.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -251,6 +252,29 @@ GeometricBoundaryField
{
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
(
patchi,
@ -322,7 +346,11 @@ evaluate()
}
// Block for any outstanding requests
if (Pstream::defaultCommsType == Pstream::nonBlocking)
if
(
Pstream::parRun()
&& Pstream::defaultCommsType == Pstream::nonBlocking
)
{
Pstream::waitRequests();
}

View File

@ -25,6 +25,8 @@ License
#include "cyclicPointPatchField.H"
#include "Swap.H"
#include "transformField.H"
#include "pointFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -127,28 +129,57 @@ void cyclicPointPatchField<Type>::swapAddSeparated
Field<Type>& pField
) const
{
// Get neighbouring pointPatch
const cyclicPointPatch& nbrPatch = cyclicPatch_.neighbPatch();
if (cyclicPatch_.cyclicPatch().owner())
{
// We inplace modify pField. To prevent the other side (which gets
// evaluated at a later date) using already changed values we do
// all swaps on the side that gets evaluated first.
// 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)
{
Type tmp = pf[pairs[pairi][0]];
pf[pairs[pairi][0]] = transform(forwardT()[0], pf[pairs[pairi][1]]);
pf[pairs[pairi][1]] = transform(reverseT()[0], tmp);
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]], pf[pairs[pairi][1]]);
Swap(pf[pairs[pairi][0]], nbrPf[pairs[pairi][1]]);
}
}
addToInternalField(pField, pf, cyclicPatch_.separatedPoints());
addToInternalField(pField, pf);
nbr.addToInternalField(pField, nbrPf);
}
}

View File

@ -24,7 +24,7 @@ License
\*---------------------------------------------------------------------------*/
#include "processorPointPatchField.H"
#include "transformField.H"
//#include "transformField.H"
#include "processorPolyPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -102,26 +102,27 @@ void processorPointPatchField<Type>::initSwapAddSeparated
)
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()
);
}
// 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()
// );
// }
}
@ -132,44 +133,29 @@ void processorPointPatchField<Type>::swapAddSeparated
Field<Type>& pField
) const
{
if (Pstream::parRun())
{
Field<Type> pnf(this->size());
IPstream::read
(
commsType,
procPatch_.neighbProcNo(),
reinterpret_cast<char*>(pnf.begin()),
pnf.byteSize()
);
if (doTransform())
{
const processorPolyPatch& ppp = procPatch_.procPolyPatch();
const tensorField& forwardT = ppp.forwardT();
if (forwardT.size() == 1)
{
transform(pnf, forwardT[0], pnf);
}
else
{
const labelListList& pointFaces = ppp.pointFaces();
forAll(pointFaces, pfi)
{
pnf[pfi] = transform
(
forwardT[pointFaces[pfi][0]],
pnf[pfi]
);
}
}
}
addToInternalField(pField, pnf, procPatch_.separatedPoints());
}
// 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 processorPolyPatch& ppp = procPatch_.procPolyPatch();
// const tensor& forwardT = ppp.forwardT();
//
// transform(pnf, forwardT, pnf);
// }
//
// 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
{
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);
}
tmp<Field<Type1> > tvalues(new Field<Type1>(meshPoints.size()));
Field<Type1>& values = tvalues();
forAll(meshPoints, pointI)
{
values[pointI] = iF[meshPoints[pointI]];
}
return tvalues;
return tmp<Field<Type1> >(new Field<Type1>(iF, meshPoints));
}

View File

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

View File

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

View File

@ -65,6 +65,14 @@ public:
// 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
virtual const tensorField& forwardT() const = 0;

View File

@ -96,21 +96,6 @@ public:
const unallocLabelList& internalData
) 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
virtual void initInternalFieldTransfer
(

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -80,20 +80,16 @@ void Foam::cyclicGAMGInterfaceField::updateInterfaceMatrix
const Pstream::commsTypes
) const
{
scalarField pnf(size());
label sizeby2 = size()/2;
const unallocLabelList& faceCells = cyclicInterface_.faceCells();
for (label facei=0; facei<sizeby2; facei++)
{
pnf[facei] = psiInternal[faceCells[facei + sizeby2]];
pnf[facei + sizeby2] = psiInternal[faceCells[facei]];
}
// Get neighbouring field
scalarField pnf
(
cyclicInterface_.neighbPatch().interfaceInternalField(psiInternal)
);
transformCoupleField(pnf, cmpt);
const unallocLabelList& faceCells = cyclicInterface_.faceCells();
forAll(faceCells, 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
#define GAMGInterface_H
#include "lduInterface.H"
#include "autoPtr.H"
#include "lduInterfacePtrsList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -57,6 +57,12 @@ protected:
// Protected data
//- My index in coarseInterfaces
const label index_;
//- All interfaces
const lduInterfacePtrsList& coarseInterfaces_;
//- Face-cell addressing
labelField faceCells_;
@ -89,11 +95,15 @@ public:
GAMGInterface,
lduInterface,
(
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface,
const labelField& localRestrictAddressing,
const labelField& neighbourRestrictAddressing
),
(
index,
coarseInterfaces,
fineInterface,
localRestrictAddressing,
neighbourRestrictAddressing
@ -107,6 +117,8 @@ public:
// the fine interface
static autoPtr<GAMGInterface> New
(
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface,
const labelField& localRestrictAddressing,
const labelField& neighbourRestrictAddressing
@ -119,10 +131,15 @@ public:
// local and neighbour restrict addressing
GAMGInterface
(
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface&,
const labelField&,
const labelField&
)
:
index_(index),
coarseInterfaces_(coarseInterfaces)
{}
@ -136,6 +153,16 @@ public:
return faceCells_.size();
}
virtual label index() const
{
return index_;
}
virtual const lduInterfacePtrsList& coarseInterfaces() const
{
return coarseInterfaces_;
}
//- Return faceCell addressing
virtual const unallocLabelList& faceCells() const
{

View File

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

View File

@ -25,6 +25,7 @@ License
#include "cyclicGAMGInterface.H"
#include "addToRunTimeSelectionTable.H"
#include "Map.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -44,6 +45,8 @@ namespace Foam
Foam::cyclicGAMGInterface::cyclicGAMGInterface
(
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface,
const labelField& localRestrictAddressing,
const labelField& neighbourRestrictAddressing
@ -51,6 +54,8 @@ Foam::cyclicGAMGInterface::cyclicGAMGInterface
:
GAMGInterface
(
index,
coarseInterfaces,
fineInterface,
localRestrictAddressing,
neighbourRestrictAddressing
@ -58,33 +63,45 @@ Foam::cyclicGAMGInterface::cyclicGAMGInterface
fineCyclicInterface_(refCast<const cyclicLduInterface>(fineInterface))
{
// Make a lookup table of entries for owner/neighbour
HashTable<SLList<label>, label, Hash<label> > neighboursTable
Map<SLList<label> > neighboursTable
(
localRestrictAddressing.size()
);
// Table of face-sets to be agglomerated
HashTable<SLList<SLList<label> >, label, Hash<label> > faceFaceTable
Map<SLList<SLList<label> > > faceFaceTable
(
localRestrictAddressing.size()
);
label nCoarseFaces = 0;
label sizeBy2 = localRestrictAddressing.size()/2;
for (label ffi=0; ffi<sizeBy2; ffi++)
forAll (localRestrictAddressing, ffi)
{
label curMaster = localRestrictAddressing[ffi];
label curSlave = localRestrictAddressing[ffi + sizeBy2];
label curMaster = -1;
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,
// add the coefficient to the face. If not, create a new
// face.
// add the coefficient to the face. If not, create a new face.
if (neighboursTable.found(curMaster))
{
// Check all current neighbours to see if the current
// slave already exists. If so, add the coefficient.
// Check all current neighbours to see if the current slave already
// exists and if so, add the fine face to the agglomeration.
SLList<label>& curNbrs = neighboursTable.find(curMaster)();
@ -135,16 +152,19 @@ Foam::cyclicGAMGInterface::cyclicGAMGInterface
} // 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();
// Reset face counter for re-use
nCoarseFaces = 0;
if (owner())
{
// On master side, the owner addressing is stored in table of contents
forAll(contents, masterI)
forAll (contents, masterI)
{
SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
@ -163,7 +183,12 @@ Foam::cyclicGAMGInterface::cyclicGAMGInterface
{
faceCells_[nCoarseFaces] = contents[masterI];
forAllConstIter(SLList<label>, faceFacesIter(), facesIter)
for
(
SLList<label>::iterator facesIter = faceFacesIter().begin();
facesIter != faceFacesIter().end();
++facesIter
)
{
faceRestrictAddressing_[facesIter()] = nCoarseFaces;
}
@ -171,9 +196,11 @@ Foam::cyclicGAMGInterface::cyclicGAMGInterface
nCoarseFaces++;
}
}
}
else
{
// On slave side, the owner addressing is stored in linked lists
forAll(contents, masterI)
forAll (contents, masterI)
{
SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
@ -181,6 +208,7 @@ Foam::cyclicGAMGInterface::cyclicGAMGInterface
faceFaceTable.find(contents[masterI])();
SLList<label>::iterator nbrsIter = curNbrs.begin();
SLList<SLList<label> >::iterator faceFacesIter = curFaceFaces.begin();
for
@ -192,14 +220,20 @@ Foam::cyclicGAMGInterface::cyclicGAMGInterface
{
faceCells_[nCoarseFaces] = nbrsIter();
forAllConstIter(SLList<label>, faceFacesIter(), facesIter)
for
(
SLList<label>::iterator facesIter = faceFacesIter().begin();
facesIter != faceFacesIter().end();
++facesIter
)
{
faceRestrictAddressing_[facesIter() + sizeBy2] = nCoarseFaces;
faceRestrictAddressing_[facesIter()] = nCoarseFaces;
}
nCoarseFaces++;
}
}
}
}
@ -211,42 +245,24 @@ Foam::cyclicGAMGInterface::~cyclicGAMGInterface()
// * * * * * * * * * * * * * * * 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
(
const Pstream::commsTypes,
const unallocLabelList& iF
) const
{
const cyclicGAMGInterface& nbr = dynamic_cast<const cyclicGAMGInterface&>
(
neighbPatch()
);
const unallocLabelList& nbrFaceCells = nbr.faceCells();
tmp<labelField> tpnf(new labelField(size()));
labelField& pnf = tpnf();
label sizeby2 = size()/2;
for (label facei=0; facei<sizeby2; facei++)
forAll(pnf, facei)
{
pnf[facei] = iF[faceCells_[facei + sizeby2]];
pnf[facei + sizeby2] = iF[faceCells_[facei]];
pnf[facei] = iF[nbrFaceCells[facei]];
}
return tpnf;

View File

@ -80,6 +80,8 @@ public:
// local and neighbour restrict addressing
cyclicGAMGInterface
(
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface,
const labelField& restrictAddressing,
const labelField& neighbourRestrictAddressing
@ -94,13 +96,6 @@ public:
// 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
virtual tmp<labelField> internalFieldTransfer
(
@ -111,6 +106,25 @@ public:
//- 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
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 "addToRunTimeSelectionTable.H"
#include "Map.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -44,6 +45,8 @@ namespace Foam
Foam::processorGAMGInterface::processorGAMGInterface
(
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface,
const labelField& localRestrictAddressing,
const labelField& neighbourRestrictAddressing
@ -51,6 +54,8 @@ Foam::processorGAMGInterface::processorGAMGInterface
:
GAMGInterface
(
index,
coarseInterfaces,
fineInterface,
localRestrictAddressing,
neighbourRestrictAddressing
@ -58,13 +63,13 @@ Foam::processorGAMGInterface::processorGAMGInterface
fineProcInterface_(refCast<const processorLduInterface>(fineInterface))
{
// Make a lookup table of entries for owner/neighbour
HashTable<SLList<label>, label, Hash<label> > neighboursTable
Map<SLList<label> > neighboursTable
(
localRestrictAddressing.size()
);
// Table of face-sets to be agglomerated
HashTable<SLList<SLList<label> >, label, Hash<label> > faceFaceTable
Map<SLList<SLList<label> > > faceFaceTable
(
localRestrictAddressing.size()
);
@ -233,26 +238,6 @@ Foam::processorGAMGInterface::~processorGAMGInterface()
// * * * * * * * * * * * * * * * 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
(
const Pstream::commsTypes commsType,

View File

@ -80,6 +80,8 @@ public:
// local and neighbour restrict addressing
processorGAMGInterface
(
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface,
const labelField& restrictAddressing,
const labelField& neighbourRestrictAddressing
@ -94,20 +96,6 @@ public:
// 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
virtual void initInternalFieldTransfer
(
@ -142,6 +130,12 @@ public:
{
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&)
{
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&)
@ -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 "cyclicPolyPatch.H"
#include "pointBoundaryMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -56,8 +57,6 @@ class cyclicPointPatch
//- Local reference cast into the cyclic patch
const cyclicPolyPatch& cyclicPolyPatch_;
//- List of local points that are not collocated
mutable labelList separatedPoints_;
// Private Member Functions
@ -125,6 +124,14 @@ public:
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
bool parallel() const
{
@ -147,11 +154,10 @@ public:
// Access functions for demand driven data
//- 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;
//- 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)
{
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
@ -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 separatedPoints_;
// 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.
virtual const word& constraintType() const
{
@ -168,9 +173,6 @@ public:
//- Return mesh points in the correct order for the receiving side
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;
}
//- List of separated coupled points
virtual const labelList& separatedPoints() const = 0;
};

View File

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

View File

@ -25,6 +25,7 @@ License
#include "globalPoints.H"
#include "processorPolyPatch.H"
#include "processorCyclicPolyPatch.H"
#include "cyclicPolyPatch.H"
#include "polyMesh.H"
@ -40,45 +41,6 @@ const Foam::label Foam::globalPoints::fromCollocated = labelMax/2;
// 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
(
const label localPointI,
@ -369,16 +331,9 @@ void Foam::globalPoints::initOwnPoints
|| isA<cyclicPolyPatch>(pp)
)
{
// Find points with transforms
PackedBoolList isCollocatedPoint
(
collocatedPoints
(
refCast<const coupledPolyPatch>(pp)
)
);
// Assume all processor points are collocated and all
// processorCyclic and cyclic are separated.
bool isCollocatedPoint = isType<processorPolyPatch>(pp);
const labelList& meshPoints = pp.meshPoints();
@ -396,7 +351,7 @@ void Foam::globalPoints::initOwnPoints
labelList knownInfo
(
1,
toGlobal(localPointI, isCollocatedPoint[patchPointI])
toGlobal(localPointI, isCollocatedPoint)
);
// Update addressing from point to index in procPoints
@ -425,11 +380,7 @@ void Foam::globalPoints::initOwnPoints
labelList knownInfo
(
1,
toGlobal
(
localPointI,
isCollocatedPoint[boundaryPoints[i]]
)
toGlobal(localPointI, isCollocatedPoint)
);
// Update addressing from point to index in procPoints
@ -461,20 +412,21 @@ void Foam::globalPoints::sendPatchPoints
{
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 =
refCast<const processorPolyPatch>(pp);
PackedBoolList isCollocatedPoint
(
collocatedPoints
(
procPatch
)
);
// Information to send:
// patch face
DynamicList<label> patchFaces(pp.nPoints());
@ -491,8 +443,6 @@ void Foam::globalPoints::sendPatchPoints
const labelList& meshPoints = pp.meshPoints();
forAll(meshPoints, patchPointI)
{
if (mergeSeparated || isCollocatedPoint[patchPointI])
{
label meshPointI = meshPoints[patchPointI];
label localPointI = meshToLocalPoint
@ -521,7 +471,6 @@ void Foam::globalPoints::sendPatchPoints
);
}
}
}
// Send to neighbour
if (debug)
@ -560,18 +509,20 @@ void Foam::globalPoints::receivePatchPoints
{
const polyPatch& pp = patches[patchI];
if (Pstream::parRun() && isA<processorPolyPatch>(pp))
if
(
Pstream::parRun()
&& (
isType<processorPolyPatch>(pp)
|| (mergeSeparated && isA<processorCyclicPolyPatch>(pp))
)
)
{
const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(pp);
PackedBoolList isCollocatedPoint
(
collocatedPoints
(
procPatch
)
);
// Processor patch is always collocated, processorCyclic is not.
bool isCollocatedPoint = isType<processorPolyPatch>(pp);
labelList patchFaces;
labelList indexInFace;
@ -605,21 +556,13 @@ void Foam::globalPoints::receivePatchPoints
meshPointI
);
if
(
storeInfo
(
nbrInfo[i],
localPointI,
isCollocatedPoint[pp.meshPointMap()[meshPointI]]
)
)
if (storeInfo(nbrInfo[i], localPointI, isCollocatedPoint))
{
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.
// Or since they both are in memory just do it point by point.
@ -627,27 +570,13 @@ void Foam::globalPoints::receivePatchPoints
const cyclicPolyPatch& cycPatch =
refCast<const cyclicPolyPatch>(pp);
PackedBoolList isCollocatedPoint
(
collocatedPoints
(
cycPatch
)
);
const labelList& meshPoints = pp.meshPoints();
const labelList coupledMeshPoints(reverseMeshPoints(cycPatch));
//const edgeList& connections = cycPatch.coupledPoints();
const edgeList connections(coupledPoints(cycPatch));
forAll(connections, i)
forAll(meshPoints, i)
{
const edge& e = connections[i];
if (mergeSeparated || isCollocatedPoint[e[0]])
{
label meshPointA = meshPoints[e[0]];
label meshPointB = meshPoints[e[1]];
label meshPointA = meshPoints[i];
label meshPointB = coupledMeshPoints[i];
label localA = meshToLocalPoint
(
@ -668,15 +597,7 @@ void Foam::globalPoints::receivePatchPoints
if (procPointA != meshToProcPoint_.end())
{
// Store A info onto pointB
if
(
storeInfo
(
procPoints_[procPointA()],
localB,
isCollocatedPoint[e[1]]
)
)
if (storeInfo(procPoints_[procPointA()], localB, false))
{
changedPoints.insert(localB);
}
@ -689,15 +610,7 @@ void Foam::globalPoints::receivePatchPoints
if (procPointB != meshToProcPoint_.end())
{
// Store B info onto pointA
if
(
storeInfo
(
procPoints_[procPointB()],
localA,
isCollocatedPoint[e[0]]
)
)
if (storeInfo(procPoints_[procPointB()], localA, false))
{
changedPoints.insert(localA);
}
@ -705,7 +618,6 @@ void Foam::globalPoints::receivePatchPoints
}
}
}
}
}
@ -970,7 +882,14 @@ void Foam::globalPoints::sendSharedPoints
{
const polyPatch& pp = patches[patchI];
if (Pstream::parRun() && isA<processorPolyPatch>(pp))
if
(
Pstream::parRun()
&& (
isType<processorPolyPatch>(pp)
|| (mergeSeparated && isA<processorCyclicPolyPatch>(pp))
)
)
{
const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(pp);
@ -1057,7 +976,14 @@ void Foam::globalPoints::receiveSharedPoints
{
const polyPatch& pp = patches[patchI];
if (Pstream::parRun() && isA<processorPolyPatch>(pp))
if
(
Pstream::parRun()
&& (
isType<processorPolyPatch>(pp)
|| (mergeSeparated && isA<processorCyclicPolyPatch>(pp))
)
)
{
const processorPolyPatch& procPatch =
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 =
refCast<const cyclicPolyPatch>(pp);
PackedBoolList isCollocatedPoint
(
collocatedPoints
(
cycPatch
)
);
// Build map from mesh or patch point to sharedPoint.
Map<label> localToSharedPoint(sharedPointAddr_.size());
forAll(sharedPointLabels_, i)
@ -1156,17 +1074,14 @@ void Foam::globalPoints::receiveSharedPoints
}
// Sync all info.
//const edgeList& connections = cycPatch.coupledPoints();
const edgeList connections(coupledPoints(cycPatch));
forAll(connections, i)
{
const edge& e = connections[i];
const labelList& meshPoints = cycPatch.meshPoints();
const labelList coupledMeshPoints(reverseMeshPoints(cycPatch));
if (mergeSeparated || isCollocatedPoint[e[0]])
forAll(meshPoints, i)
{
label meshPointA = pp.meshPoints()[e[0]];
label meshPointB = pp.meshPoints()[e[1]];
label meshPointA = meshPoints[i];
label meshPointB = coupledMeshPoints[i];
label localA = meshToLocalPoint
(
@ -1234,58 +1149,31 @@ void Foam::globalPoints::receiveSharedPoints
}
}
}
}
// Extend shared points from local connections.
extendSharedPoints(meshToShared, changedIndices);
}
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.
// 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.
const cyclicPolyPatch& nbrPatch = pp.neighbPatch();
// From halfA point to halfB or -1.
labelList coupledPoint(pp.nPoints(), -1);
faceList masterFaces(nbrPatch.size());
for (label patchFaceA = 0; patchFaceA < pp.size()/2; patchFaceA++)
forAll (nbrPatch, faceI)
{
const face& fA = pp.localFaces()[patchFaceA];
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];
}
}
masterFaces[faceI] = nbrPatch[faceI].reverseFace();
}
edgeList connected(pp.nPoints());
// Extract coupled points.
label connectedI = 0;
forAll(coupledPoint, i)
{
if (coupledPoint[i] != -1)
{
connected[connectedI++] = edge(i, coupledPoint[i]);
}
}
connected.setSize(connectedI);
return connected;
return primitiveFacePatch
(
masterFaces,
nbrPatch.points()
).meshPoints();
}

View File

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

View File

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

View File

@ -41,6 +41,30 @@ void Foam::mapDistribute::distribute
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)
{
// Since buffered sending can reuse the field to collect the
@ -406,6 +430,30 @@ void Foam::mapDistribute::distribute
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)
{
// 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 labelList& patchSizes,\n"
" const labelList& patchStarts\n"
" const bool validBoundary\n"
")\n"
) << "Face " << faceI << " contains vertex labels out of range: "
<< curFace << " Max point index = " << points_.size()
@ -759,9 +760,9 @@ void Foam::polyMesh::resetPrimitives
" const Xfer<labelList>& neighbour,\n"
" const labelList& patchSizes,\n"
" const labelList& patchStarts\n"
" const bool validBoundary\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;
void setTopology
(
const cellShapeList& cellsAsShapes,
const faceListList& boundaryFaces,
const wordList& boundaryPatchNames,
labelList& patchSizes,
labelList& patchStarts,
label& defaultPatchStart,
label& nFaces,
cellList& cells
);
public:
@ -255,6 +268,20 @@ public:
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
virtual ~polyMesh();
@ -442,8 +469,6 @@ public:
//- Reset mesh primitive data. Assumes all patch info correct
// (so does e.g. parallel communication). If not use
// validBoundary=false
// (still assumes patchStarts[0] = nInternalFaces and last
// patch ends at nActiveFaces) and change patches with addPatches.
void resetPrimitives
(
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
(
const IOobject& io,
@ -273,272 +558,24 @@ Foam::polyMesh::polyMesh
// Remove all of the old mesh files if they exist
removeFiles(instance());
// 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());
cellList cells(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
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
// Calculate faces and cells
labelList patchSizes;
labelList patchStarts;
label defaultPatchStart;
label nFaces;
cellList cells;
setTopology
(
"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
cellsAsShapes,
boundaryFaces,
boundaryPatchNames,
patchSizes,
patchStarts,
defaultPatchStart,
nFaces,
cells
);
// 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
// completed, as they hold a subList of the face list
forAll(boundaryFaces, patchI)
@ -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
(
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
(
const UList<face>& faces,
@ -266,7 +212,8 @@ void Foam::coupledPolyPatch::calcTransformTensors
Pout<< "coupledPolyPatch::calcTransformTensors : " << name() << endl
<< " (half)size:" << Cf.size() << 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;
}
@ -278,7 +225,7 @@ void Foam::coupledPolyPatch::calcTransformTensors
// Then the overall error of summing the normals is sqrt(size())*absTol
// - separation calculation: pass in from the outside an allowable error.
if (size() == 0)
if (Cf.size() == 0)
{
// Dummy geometry.
separation_.setSize(0);

View File

@ -38,6 +38,7 @@ SourceFiles
#define coupledPolyPatch_H
#include "polyPatch.H"
#include "diagTensorField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -133,13 +134,6 @@ protected:
label& vertI
);
//- Calculate face centres
static pointField calcFaceCentres
(
const UList<face>&,
const pointField&
);
//- Get f[0] for all faces
static pointField getAnchorPoints
(
@ -147,21 +141,6 @@ protected:
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
// from face centre to any of the face vertices.
static scalarField calcFaceTol
@ -248,45 +227,67 @@ public:
return true;
}
//- Does this side own the patch ?
virtual bool owner() const = 0;
//- Are the coupled planes separated
bool separated() const
//- Does the coupled side own the patch ?
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 the offset (distance) vector from one side of the couple
// to the other
const vectorField& separation() const
//- If the planes are separated the separation vector.
virtual const vectorField& separation() const
{
return separation_;
}
//- Are the cyclic planes parallel
bool parallel() const
//- Are the cyclic planes parallel.
virtual bool parallel() const
{
return forwardT_.empty();
}
//- Return face transformation tensor
const tensorField& forwardT() const
//- Return face transformation tensor.
virtual const tensorField& forwardT() const
{
return forwardT_;
}
//- Return neighbour-cell transformation tensor
const tensorField& reverseT() const
//- Return neighbour-cell transformation tensor.
virtual const tensorField& reverseT() const
{
return reverseT_;
}
//- Are faces collocated. Either size 0,1 or length of patch
const boolList& collocated() const
virtual const boolList& collocated() const
{
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
// refer to *this (except for name() and type() etc.)
virtual void initOrder

View File

@ -29,11 +29,10 @@ Description
Note: morph patch face ordering uses geometric matching so with the
following restrictions:
-halves should be flat planes.
-coupled patches should be flat planes.
-no rotation in patch plane
Uses a featureCos to find the two halves (or should be fully
disconnected). Uses coupledPolyPatch::calcFaceTol to calculate
Uses coupledPolyPatch::calcFaceTol to calculate
tolerance per face which might need tweaking.
Switch on 'cyclicPolyPatch' debug flag to write .obj files to show
@ -48,10 +47,9 @@ SourceFiles
#define cyclicPolyPatch_H
#include "coupledPolyPatch.H"
#include "SubField.H"
#include "FixedList.H"
#include "edgeList.H"
#include "transform.H"
#include "polyBoundaryMesh.H"
#include "diagTensorField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -82,18 +80,11 @@ private:
// Private data
//- 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_;
//- Name of other half
const word neighbPatchName_;
//- 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_;
//- Morph:angle between normals of neighbouring faces.
// Used to split cyclic into halves.
scalar featureCos_;
//- Index of other half
mutable label neighbPatchID_;
//- Type of transformation - rotational or translational
transformType transform_;
@ -112,60 +103,50 @@ private:
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
//- Find amongst selected faces the one with the largest area
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
//- 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.
void getCentresAndAnchors
(
const primitivePatch&,
const faceList& half0Faces,
const faceList& half1Faces,
const primitivePatch& pp0,
const primitivePatch& pp1,
pointField& ppPoints,
pointField& half0Ctrs,
pointField& half1Ctrs,
pointField& anchors0,
scalarField& tols
) 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
// of the cyclic.
label getConsistentRotationFace
(
const pointField& faceCentres
) const;
label getConsistentRotationFace(const pointField&) const;
protected:
@ -178,9 +159,30 @@ protected:
//- Initialise the calculation of the patch geometry
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
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
virtual void initMovePoints(PstreamBuffers&, const pointField&);
@ -231,7 +233,8 @@ public:
const polyBoundaryMesh& bm,
const label index,
const label newSize,
const label newStart
const label newStart,
const word& neighbPatchName
);
//- Construct given the original patch and a map
@ -262,7 +265,15 @@ public:
{
return autoPtr<polyPatch>
(
new cyclicPolyPatch(*this, bm, index, newSize, newStart)
new cyclicPolyPatch
(
*this,
bm,
index,
newSize,
newStart,
neighbPatchName_
)
);
}
@ -289,76 +300,81 @@ public:
// Member Functions
//- Return connected points (in patch local point indexing). Demand
// driven calculation. Does primitivePatch::clearOut after calculation!
const word& neighbPatchName() const
{
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;
//- Return connected edges (in patch local edge indexing). Demand
// driven calculation. Does primitivePatch::clearOut after calculation!
//- Return connected edges (from patch local to neighbour patch local).
// Demand driven calculation. Does primitivePatch::clearOut after
// calculation!
const edgeList& coupledEdges() const;
//- Transform a patch-based position from other side to this side
virtual void transformPosition(pointField& l) const;
// Transformation
vector separation(const label facei) const
{
if (facei < size()/2)
{
return coupledPolyPatch::separation()[0];
}
else
{
return -coupledPolyPatch::separation()[0];
}
}
const tensor& transformT(const label facei) const
{
if (facei < size()/2)
{
return reverseT()[0];
}
else
{
return forwardT()[0];
}
}
template<class T>
T transform(const T& t, const label facei) const
{
if (parallel())
{
return t;
}
else
{
return Foam::transform(transformT(facei), t);
}
}
label transformLocalFace(const label facei) const
{
if (facei < size()/2)
{
return facei + size()/2;
}
else
{
return facei - size()/2;
}
}
label transformGlobalFace(const label facei) const
{
if (facei - start() < size()/2)
label offset = facei-start();
label neighbStart = neighbPatch().start();
if (offset >= 0 && offset < size())
{
return facei + size()/2;
return neighbStart+offset;
}
else
{
return facei - size()/2;
FatalErrorIn
(
"cyclicPolyPatch::transformGlobalFace(const label) const"
) << "Face " << facei << " not in patch " << name()
<< exit(FatalError);
return -1;
}
}
@ -387,7 +403,6 @@ public:
}
//- Initialize ordering for primitivePatch. Does not
// refer to *this (except for name() and type() etc.)
virtual void initOrder(PstreamBuffers&, const primitivePatch&) const;

View File

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

View File

@ -40,6 +40,8 @@ SourceFiles
#define processorPolyPatch_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
// (so localPoints()[i] == neighb.localPoints()[neighbPoints_[i]])
mutable labelList* neighbPointsPtr_;
mutable autoPtr<labelList> neighbPointsPtr_;
//- Corresponding neighbouring local edge label for every local edge
// (so edges()[i] == neighb.edges()[neighbEdges_[i]])
mutable 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_;
mutable autoPtr<labelList> neighbEdgesPtr_;
protected:
@ -98,6 +88,22 @@ protected:
//- 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("processorPolyPatch::calcGeometry(..)");
}
//- Initialise the patches for moving points
void initMovePoints(PstreamBuffers&, const pointField&);
@ -236,7 +242,7 @@ public:
}
//- Does the processor own the patch ?
bool owner() const
virtual bool owner() const
{
return (myProcNo_ < neighbProcNo_);
}
@ -265,16 +271,21 @@ public:
return neighbFaceCellCentres_;
}
//- Return neighbour point labels. This is for my local point (-1 or)
// 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)
//- Return neighbour point labels. WIP.
const labelList& neighbPoints() const;
//- Return neighbour edge labels. This is for my local edge (-1 or) the
// corresponding local edge on the other side. See above for -1 cause.
//- Return neighbour edge labels. WIP.
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
// 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_;
// Private Member Functions
//- Calculate labels of mesh edges
void calcMeshEdges() const;
protected:
// 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 * * * * * * * * * * * * * //
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
// boundaries need to reduce this info.
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.
Foam::PackedBoolList Foam::syncTools::getMasterPoints(const polyMesh& mesh)
{
@ -154,10 +200,8 @@ Foam::PackedBoolList Foam::syncTools::getMasterFaces(const polyMesh& mesh)
{
if (patches[patchI].coupled())
{
if (Pstream::parRun() && isA<processorPolyPatch>(patches[patchI]))
{
const processorPolyPatch& pp =
refCast<const processorPolyPatch>(patches[patchI]);
const coupledPolyPatch& pp =
refCast<const coupledPolyPatch>(patches[patchI]);
if (!pp.owner())
{
@ -167,124 +211,10 @@ Foam::PackedBoolList Foam::syncTools::getMasterFaces(const polyMesh& mesh)
}
}
}
else if (isA<cyclicPolyPatch>(patches[patchI]))
{
const cyclicPolyPatch& pp =
refCast<const cyclicPolyPatch>(patches[patchI]);
for (label i = pp.size()/2; i < pp.size(); 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);
}
}
}
return isMasterFace;
}
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 "Pstream.H"
#include "transformList.H"
#include "Map.H"
#include "EdgeMap.H"
#include "PackedBoolList.H"
#include "polyMesh.H"
#include "coupledPolyPatch.H"
#include "transformList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -61,8 +63,6 @@ namespace Foam
{
class polyBoundaryMesh;
class polyMesh;
class coupledPolyPatch;
/*---------------------------------------------------------------------------*\
Class syncTools Declaration
@ -75,20 +75,6 @@ class syncTools
//- Check whether uses couples.
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.
template <class T, class CombineOp>
static void combine
@ -112,116 +98,383 @@ class syncTools
public:
// Static data members
// Public classes
class transform
{
public:
//- Transform patch-based field
template<class T>
void operator()(const coupledPolyPatch& cpp, Field<T>& fld) const
{
if (!cpp.parallel())
{
transformList(cpp.forwardT(), fld);
}
}
//- Transform sparse field
template<class T, template<class> class Container>
void operator()(const coupledPolyPatch& cpp, Container<T>& map)
const
{
if (!cpp.parallel())
{
transformList(cpp.forwardT(), map);
}
}
};
class transformPosition
{
public:
void operator()(const coupledPolyPatch& cpp, pointField& fld) const
{
cpp.transformPosition(fld);
}
template<template<class> class Container>
void operator()(const coupledPolyPatch& cpp, Container<point>& map)
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++];
}
}
};
// Basic routines with user-supplied transformation. Preferably
// use specialisations below.
//- Synchronize values on selected points.
template <class T, class CombineOp, class TransformOp>
static void syncPointMap
(
const polyMesh&,
Map<T>& pointValues,
const CombineOp& cop,
const TransformOp& top
);
//- Synchronize values on selected edges.
template <class T, class CombineOp, class TransformOp>
static void syncEdgeMap
(
const polyMesh&,
EdgeMap<T>& edgeValues,
const CombineOp& cop,
const TransformOp& top
);
//- Synchronize values on all mesh points.
// Applies rotation and optionally separation for parallel cyclics
template <class T, class CombineOp>
template <class T, class CombineOp, class TransformOp>
static void syncPointList
(
const polyMesh&,
UList<T>&,
const CombineOp& cop,
const T& nullValue,
const bool applySeparation
const TransformOp& top
);
//- Synchronize values on selected mesh points.
// Applies rotation and optionally separation for parallel cyclics
template <class T, class CombineOp>
template <class T, class CombineOp, class TransformOp>
static void syncPointList
(
const polyMesh&,
const labelList& meshPoints,
UList<T>&,
const CombineOp& bop,
const CombineOp& cop,
const T& nullValue,
const bool applySeparation
const TransformOp& top
);
//- Synchronize values on all mesh edges.
// Applies rotation and optionally separation for parallel cyclics
template <class T, class CombineOp>
template <class T, class CombineOp, class TransformOp>
static void syncEdgeList
(
const polyMesh&,
UList<T>&,
const CombineOp& cop,
const T& nullValue,
const bool applySeparation
const TransformOp& top
);
//- Synchronize values on boundary faces only.
// Optionally applies rotation tensor for non-parallel cyclics
// (but not separation!)
template <class T, class CombineOp>
template <class T, class CombineOp, class TransformOp>
static void syncBoundaryFaceList
(
const polyMesh&,
UList<T>&,
const CombineOp& cop,
const bool applySeparation
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.
// Optionally applies rotation tensor for non-parallel cyclics
// (but not separation!)
template <class T, class CombineOp>
static void syncFaceList
(
const polyMesh&,
UList<T>&,
const CombineOp& cop,
const bool applySeparation
const polyMesh& mesh,
UList<T>& l,
const CombineOp& cop
)
{
SubList<T> bndValues
(
l,
mesh.nFaces()-mesh.nInternalFaces(),
mesh.nInternalFaces()
);
//- Swap coupled face values.
// Applies rotation and optionally separation for parallel cyclics
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&,
UList<T>&,
const bool applySeparation
);
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.
// Applies rotation and optionally separation for parallel cyclics
template <class T>
static void swapFaceList
(
const polyMesh&,
UList<T>&,
const bool applySeparation
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.
// Applies rotation and optionally separation for parallel
// cyclics.
template <class T, class CombineOp>
static void syncPointMap
(
const polyMesh&,
Map<T>& pointValues,
const CombineOp& cop,
const bool applySeparation
);
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.
// Applies rotation and optionally separation for parallel
// cyclics.
template <class T, class CombineOp>
static void syncEdgeMap
(
const polyMesh&,
EdgeMap<T>& edgeValues,
const CombineOp& cop,
const bool applySeparation
);
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
@ -273,13 +526,62 @@ public:
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<>
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<>
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);
syncTools::swapBoundaryFaceList(mesh, neiZoneFace, false);
syncTools::swapBoundaryFaceList(mesh, neiZoneFace);
boolList myZoneFlip(neiZoneFlip);
syncTools::swapBoundaryFaceList(mesh, neiZoneFlip, false);
syncTools::swapBoundaryFaceList(mesh, neiZoneFlip);
forAll(*this, i)
{

View File

@ -84,7 +84,7 @@ void Foam::dynamicRefineFvMesh::calculateProtectedCells
{
neiLevel[faceI-nInternalFaces()] = cellLevel[faceOwner()[faceI]];
}
syncTools::swapBoundaryFaceList(*this, neiLevel, false);
syncTools::swapBoundaryFaceList(*this, neiLevel);
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
@ -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
for (label faceI = 0; faceI < nInternalFaces(); faceI++)
@ -933,7 +933,7 @@ Foam::dynamicRefineFvMesh::dynamicRefineFvMesh(const IOobject& io)
{
neiLevel[faceI] = cellLevel[faceOwner()[faceI]];
}
syncTools::swapFaceList(*this, neiLevel, false);
syncTools::swapFaceList(*this, neiLevel);
boolList protectedFace(nFaces(), false);
@ -965,13 +965,7 @@ Foam::dynamicRefineFvMesh::dynamicRefineFvMesh(const IOobject& io)
}
}
syncTools::syncFaceList
(
*this,
protectedFace,
orEqOp<bool>(),
false
);
syncTools::syncFaceList(*this, protectedFace, orEqOp<bool>());
for (label faceI = 0; faceI < nInternalFaces(); faceI++)
{

View File

@ -29,6 +29,9 @@ License
#include "faceCoupleInfo.H"
#include "processorFvPatchField.H"
#include "processorFvsPatchField.H"
#include "processorCyclicPolyPatch.H"
#include "processorCyclicFvPatchField.H"
#include "processorCyclicFvsPatchField.H"
#include "polyTopoChange.H"
#include "removeCells.H"
#include "polyModifyFace.H"
@ -128,6 +131,7 @@ void Foam::fvMeshDistribute::printMeshInfo(const fvMesh& mesh)
{
Pout<< "Primitives:" << nl
<< " points :" << mesh.nPoints() << nl
<< " bb :" << boundBox(mesh.points(), false) << nl
<< " internalFaces:" << mesh.nInternalFaces() << nl
<< " faces :" << mesh.nFaces() << nl
<< " cells :" << mesh.nCells() << nl;
@ -187,7 +191,8 @@ void Foam::fvMeshDistribute::printCoupleInfo
const primitiveMesh& mesh,
const labelList& sourceFace,
const labelList& sourceProc,
const labelList& sourceNewProc
const labelList& sourcePatch,
const labelList& sourceNewNbrProc
)
{
Pout<< nl
@ -202,7 +207,7 @@ void Foam::fvMeshDistribute::printCoupleInfo
<< " fc:" << mesh.faceCentres()[meshFaceI]
<< " connects to proc:" << sourceProc[bFaceI]
<< "/face:" << sourceFace[bFaceI]
<< " which will move to proc:" << sourceNewProc[bFaceI]
<< " which will move to proc:" << sourceNewNbrProc[bFaceI]
<< endl;
}
}
@ -270,32 +275,87 @@ Foam::label Foam::fvMeshDistribute::findNonEmptyPatch() const
}
// Appends processorPolyPatch. Returns patchID.
Foam::label Foam::fvMeshDistribute::addProcPatch
(
const word& patchName,
const label nbrProc
)
//// Appends processorPolyPatch. Returns patchID.
//Foam::label Foam::fvMeshDistribute::addProcPatch
//(
// const word& patchName,
// 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.
mesh_.clearOut();
polyBoundaryMesh& polyPatches =
const_cast<polyBoundaryMesh&>(mesh_.boundaryMesh());
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)")
<< "Cannot create patch " << patchName << " since already exists."
<< nl
<< "Current patch names:" << polyPatches.names()
<< exit(FatalError);
FatalErrorIn("fvMeshDistribute::addPatch(polyPatch*)")
<< "Cannot create patch " << patchPtr->name()
<< " since already exists." << nl
<< "Current patch names:" << polyPatches.names() << exit(FatalError);
}
// Add the patch
// ~~~~~~~~~~~~~
@ -303,20 +363,7 @@ Foam::label Foam::fvMeshDistribute::addProcPatch
// Add polyPatch
polyPatches.setSize(sz+1);
polyPatches.set
(
sz,
new processorPolyPatch
(
patchName,
0, // size
mesh_.nFaces(),
sz,
mesh_.boundaryMesh(),
Pstream::myProcNo(),
nbrProc
)
);
polyPatches.set(sz, patchPtr);
fvPatches.setSize(sz+1);
fvPatches.set
(
@ -624,25 +671,27 @@ void Foam::fvMeshDistribute::getNeighbourData
const labelList& distribution,
labelList& sourceFace,
labelList& sourceProc,
labelList& sourceNewProc
labelList& sourcePatch,
labelList& sourceNewNbrProc
) const
{
label nBnd = mesh_.nFaces() - mesh_.nInternalFaces();
sourceFace.setSize(nBnd);
sourceProc.setSize(nBnd);
sourceNewProc.setSize(nBnd);
sourcePatch.setSize(nBnd);
sourceNewNbrProc.setSize(nBnd);
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
// Get neighbouring meshFace labels and new processor of coupled boundaries.
labelList nbrFaces(nBnd, -1);
labelList nbrNewProc(nBnd, -1);
labelList nbrNewNbrProc(nBnd, -1);
forAll(patches, patchI)
{
const polyPatch& pp = patches[patchI];
if (isA<processorPolyPatch>(pp))
if (pp.coupled())
{
label offset = pp.start() - mesh_.nInternalFaces();
@ -654,7 +703,7 @@ void Foam::fvMeshDistribute::getNeighbourData
}
// 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())()
);
@ -663,8 +712,8 @@ void Foam::fvMeshDistribute::getNeighbourData
// Exchange the boundary data
syncTools::swapBoundaryFaceList(mesh_, nbrFaces, false);
syncTools::swapBoundaryFaceList(mesh_, nbrNewProc, false);
syncTools::swapBoundaryFaceList(mesh_, nbrFaces);
syncTools::swapBoundaryFaceList(mesh_, nbrNewNbrProc);
forAll(patches, patchI)
@ -679,7 +728,7 @@ void Foam::fvMeshDistribute::getNeighbourData
// Check which of the two faces we store.
if (Pstream::myProcNo() < procPatch.neighbProcNo())
if (procPatch.owner())
{
// Use my local face labels
forAll(pp, i)
@ -687,7 +736,7 @@ void Foam::fvMeshDistribute::getNeighbourData
label bndI = offset + i;
sourceFace[bndI] = pp.start()+i;
sourceProc[bndI] = Pstream::myProcNo();
sourceNewProc[bndI] = nbrNewProc[bndI];
sourceNewNbrProc[bndI] = nbrNewNbrProc[bndI];
}
}
else
@ -698,7 +747,50 @@ void Foam::fvMeshDistribute::getNeighbourData
label bndI = offset + i;
sourceFace[bndI] = nbrFaces[bndI];
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)
{
label bndI = offset + i;
sourceFace[bndI] = patchI;
sourceFace[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& sourceProc,
const labelList& sourceNewProc,
const labelList& sourcePatch,
const labelList& sourceNewNbrProc,
labelList& subFace,
labelList& subProc,
labelList& subNewProc
labelList& subPatch,
labelList& subNewNbrProc
)
{
subFace.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)
{
@ -753,6 +849,7 @@ void Foam::fvMeshDistribute::subsetBoundaryData
{
subFace[newBFaceI] = oldFaceI;
subProc[newBFaceI] = Pstream::myProcNo();
subPatch[newBFaceI] = -1;
label oldOwn = oldFaceOwner[oldFaceI];
label oldNei = oldFaceNeighbour[oldFaceI];
@ -760,12 +857,12 @@ void Foam::fvMeshDistribute::subsetBoundaryData
if (oldOwn == cellMap[mesh.faceOwner()[newFaceI]])
{
// We kept the owner side. Where does the neighbour move to?
subNewProc[newBFaceI] = oldDistribution[oldNei];
subNewNbrProc[newBFaceI] = oldDistribution[oldNei];
}
else
{
// We kept the neighbour side.
subNewProc[newBFaceI] = oldDistribution[oldOwn];
subNewNbrProc[newBFaceI] = oldDistribution[oldOwn];
}
}
else
@ -775,7 +872,8 @@ void Foam::fvMeshDistribute::subsetBoundaryData
subFace[newBFaceI] = sourceFace[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 labelList& sourceFace,
const labelList& sourceProc,
const labelList& sourcePatch,
const label domain,
const primitiveMesh& domainMesh,
const labelList& domainFace,
const labelList& domainProc,
const labelList& domainPatch,
labelList& masterCoupledFaces,
labelList& slaveCoupledFaces
@ -802,9 +902,16 @@ void Foam::fvMeshDistribute::findCouples
// with same face+proc.
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)
{
if (sourceProc[bFaceI] != -1)
if (sourceProc[bFaceI] != -1 && sourcePatch[bFaceI] == -1)
{
labelPair myData(sourceFace[bFaceI], sourceProc[bFaceI]);
@ -934,39 +1041,56 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::doRemoveCells
// the processor patchID.
void Foam::fvMeshDistribute::addProcPatches
(
const labelList& neighbourNewProc, // processor that neighbour is on
labelList& procPatchID
const labelList& nbrProc, // processor that neighbour is now on
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
// 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());
forAll(procPatchSizes, procI)
forAll(nbrProc, bFaceI)
{
if (procPatchSizes[procI] > 0)
label procI = nbrProc[bFaceI];
if (procI != -1 && procI != Pstream::myProcNo())
{
if (!procPatchID[procI].found(referPatchID[bFaceI]))
{
// No patch for neighbour yet. Is either a normal processor
// patch or a processorCyclic patch.
if (referPatchID[bFaceI] == -1)
{
// Ordinary processor boundary
const word patchName =
"procBoundary"
+ name(Pstream::myProcNo())
+ "to"
+ name(procI);
procPatchID[procI].insert
(
referPatchID[bFaceI],
addPatch
(
new processorPolyPatch
(
patchName,
0, // size
mesh_.nFaces(),
mesh_.boundaryMesh().size(),
mesh_.boundaryMesh(),
Pstream::myProcNo(),
nbrProc[bFaceI]
)
)
);
procPatchID[procI] = addProcPatch(patchName, procI);
addPatchFields<volScalarField>
(
processorFvPatchField<scalar>::typeName
@ -1011,28 +1135,108 @@ void Foam::fvMeshDistribute::addProcPatches
}
else
{
procPatchID[procI] = -1;
// 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
Foam::labelList Foam::fvMeshDistribute::getProcBoundaryPatch
Foam::labelList Foam::fvMeshDistribute::getBoundaryPatch
(
const labelList& neighbourNewProc, // new processor per boundary face
const labelList& procPatchID // patchID
const labelList& nbrProc, // new processor per boundary face
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];
patchIDs[bFaceI] = procPatchID[nbrProc];
label origPatchI = referPatchID[bFaceI];
patchIDs[bFaceI] = origPatchI;
}
else if (nbrProc[bFaceI] != -1)
{
label origPatchI = referPatchID[bFaceI];
patchIDs[bFaceI] = procPatchID[nbrProc[bFaceI]][origPatchI];
}
else
{
@ -1055,7 +1259,8 @@ void Foam::fvMeshDistribute::sendMesh
const labelList& sourceFace,
const labelList& sourceProc,
const labelList& sourceNewProc,
const labelList& sourcePatch,
const labelList& sourceNewNbrProc,
UOPstream& toDomain
)
{
@ -1191,7 +1396,8 @@ void Foam::fvMeshDistribute::sendMesh
<< sourceFace
<< sourceProc
<< sourceNewProc;
<< sourcePatch
<< sourceNewNbrProc;
if (debug)
@ -1212,7 +1418,8 @@ Foam::autoPtr<Foam::fvMesh> Foam::fvMeshDistribute::receiveMesh
const Time& runTime,
labelList& domainSourceFace,
labelList& domainSourceProc,
labelList& domainSourceNewProc,
labelList& domainSourcePatch,
labelList& domainSourceNewNbrProc,
UIPstream& fromNbr
)
{
@ -1230,7 +1437,8 @@ Foam::autoPtr<Foam::fvMesh> Foam::fvMeshDistribute::receiveMesh
fromNbr
>> domainSourceFace
>> domainSourceProc
>> domainSourceNewProc;
>> domainSourcePatch
>> domainSourceNewNbrProc;
// Construct fvMesh
autoPtr<fvMesh> domainMeshPtr
@ -1448,16 +1656,37 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
// physical boundary:
// sourceProc = -1
// sourceNewProc = -1
// sourceFace = patchID
// coupled boundary:
// sourceProc = proc
// sourceNewProc = distribution[cell on proc]
// sourceFace = face
// sourceNewNbrProc = -1
// sourceFace = -1
// sourcePatch = patchID
// processor boundary:
// sourceProc = proc (on owner side)
// 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 sourceProc;
labelList sourceNewProc;
getNeighbourData(distribution, sourceFace, sourceProc, sourceNewProc);
labelList sourceNewNbrProc;
getNeighbourData
(
distribution,
sourceFace,
sourceProc,
sourcePatch,
sourceNewNbrProc
);
// Remove meshPhi. Since this would otherwise disappear anyway
@ -1529,7 +1758,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
inplaceReorder(bFaceMap, sourceFace);
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)
labelList procSourceFace;
labelList procSourceProc;
labelList procSourceNewProc;
labelList procSourcePatch;
labelList procSourceNewNbrProc;
subsetBoundaryData
(
@ -1647,11 +1878,13 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
sourceFace,
sourceProc,
sourceNewProc,
sourcePatch,
sourceNewNbrProc,
procSourceFace,
procSourceProc,
procSourceNewProc
procSourcePatch,
procSourceNewNbrProc
);
@ -1668,7 +1901,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
procSourceFace,
procSourceProc,
procSourceNewProc,
procSourcePatch,
procSourceNewNbrProc,
str
);
sendFields<volScalarField>(recvProc, volScalars, subsetter, str);
@ -1771,7 +2005,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
// fields
labelList domainSourceFace;
labelList domainSourceProc;
labelList domainSourceNewProc;
labelList domainSourcePatch;
labelList domainSourceNewNbrProc;
subsetBoundaryData
(
@ -1786,16 +2021,19 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
sourceFace,
sourceProc,
sourceNewProc,
sourcePatch,
sourceNewNbrProc,
domainSourceFace,
domainSourceProc,
domainSourceNewProc
domainSourcePatch,
domainSourceNewNbrProc
);
sourceFace.transfer(domainSourceFace);
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
labelList domainSourceFace;
labelList domainSourceProc;
labelList domainSourceNewProc;
labelList domainSourcePatch;
labelList domainSourceNewNbrProc;
autoPtr<fvMesh> domainMeshPtr;
PtrList<volScalarField> vsf;
@ -1874,10 +2113,14 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
const_cast<Time&>(mesh_.time()),
domainSourceFace,
domainSourceProc,
domainSourceNewProc,
domainSourcePatch,
domainSourceNewNbrProc,
str
);
fvMesh& domainMesh = domainMeshPtr();
// Force construction of various on mesh.
//(void)domainMesh.globalData();
// Receive fields. Read as single dictionary because
// of problems reading consecutive fields from single stream.
@ -2006,11 +2249,13 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
sourceFace,
sourceProc,
sourcePatch,
sendProc,
domainMesh,
domainSourceFace,
domainSourceProc,
domainSourcePatch,
masterCoupledFaces,
slaveCoupledFaces
@ -2045,8 +2290,7 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
// Update mesh data: sourceFace,sourceProc for added
// mesh.
sourceFace =
mapBoundaryData
sourceFace = mapBoundaryData
(
mesh_,
map(),
@ -2054,8 +2298,7 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
domainMesh.nInternalFaces(),
domainSourceFace
);
sourceProc =
mapBoundaryData
sourceProc = mapBoundaryData
(
mesh_,
map(),
@ -2063,14 +2306,21 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
domainMesh.nInternalFaces(),
domainSourceProc
);
sourceNewProc =
mapBoundaryData
sourcePatch = mapBoundaryData
(
mesh_,
map(),
sourceNewProc,
sourcePatch,
domainMesh.nInternalFaces(),
domainSourceNewProc
domainSourcePatch
);
sourceNewNbrProc = mapBoundaryData
(
mesh_,
map(),
sourceNewNbrProc,
domainMesh.nInternalFaces(),
domainSourceNewNbrProc
);
// Update all addressing so xxProcAddressing points to correct item
@ -2141,11 +2391,13 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
// Add processorPatches
// ~~~~~~~~~~~~~~~~~~~~
// Per neighbour processor the patchID to it (or -1).
labelList procPatchID;
// Per neighbour processor, per originating patch, the patchID
// 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.
addProcPatches(sourceNewProc, procPatchID);
// Add processor and processorCyclic patches.
addProcPatches(sourceNewNbrProc, sourcePatch, procPatchID);
// Put faces into correct patch. Note that we now have proper
// 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
labelList newPatchID
(
getProcBoundaryPatch
getBoundaryPatch
(
sourceNewProc,
sourceNewNbrProc,
sourcePatch,
procPatchID
)
);

View File

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

View File

@ -40,6 +40,80 @@ defineTypeNameAndDebug(Foam::motionSmoother, 0);
// * * * * * * * * * * * * * 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
void Foam::motionSmoother::makePatchPatchAddressing()
{
@ -209,8 +283,7 @@ void Foam::motionSmoother::minSmooth
tmp<pointScalarField> tavgFld = avg
(
fld,
scalarField(mesh_.nEdges(), 1.0), // uniform weighting
false // fld is not position.
scalarField(mesh_.nEdges(), 1.0) // uniform weighting
);
const pointScalarField& avgFld = tavgFld();
@ -243,8 +316,7 @@ void Foam::motionSmoother::minSmooth
tmp<pointScalarField> tavgFld = avg
(
fld,
scalarField(mesh_.nEdges(), 1.0), // uniform weighting
false // fld is not position.
scalarField(mesh_.nEdges(), 1.0) // uniform weighting
);
const pointScalarField& avgFld = tavgFld();
@ -612,8 +684,7 @@ void Foam::motionSmoother::setDisplacement(pointField& patchDisp)
mesh_,
displacement_,
maxMagEqOp(), // combine op
vector::zero, // null value
false // no separation
vector::zero // null value
);
// Adapt the fixedValue bc's (i.e. copy internal point data to
@ -718,8 +789,7 @@ void Foam::motionSmoother::correctBoundaryConditions
mesh_,
displacement,
maxMagEqOp(), // combine op
vector::zero, // null value
false // no separation
vector::zero // null value
);
}
@ -769,14 +839,7 @@ Foam::tmp<Foam::scalarField> Foam::motionSmoother::movePoints
{
Pout<< "motionSmoother::movePoints : testing sync of newPoints."
<< endl;
testSyncField
(
newPoints,
minEqOp<point>(), // combine op
vector(GREAT,GREAT,GREAT), // null
true, // separation
1E-6*mesh_.bounds().mag()
);
testSyncPositions(newPoints, 1E-6*mesh_.bounds().mag());
}
tmp<scalarField> tsweptVol = mesh_.movePoints(newPoints);
@ -894,8 +957,7 @@ bool Foam::motionSmoother::scaleMesh
mesh_,
displacement_,
maxMagEqOp(),
vector::zero, // null value
false // no separation
vector::zero // null value
);
// Set newPoints as old + scale*displacement
@ -926,7 +988,6 @@ bool Foam::motionSmoother::scaleMesh
totalDisplacement,
maxMagEqOp(),
vector::zero, // null value
false, // separation
1E-6*mesh_.bounds().mag()
);
}
@ -1056,8 +1117,7 @@ bool Foam::motionSmoother::scaleMesh
mesh_,
scale_,
maxEqOp<scalar>(),
-GREAT, // null value
false // no separation
-GREAT // null value
);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -29,6 +29,7 @@ License
#include "mapPolyMesh.H"
#include "globalIndex.H"
#include "indirectPrimitivePatch.H"
#include "dummyTransform.H"
// * * * * * * * * * * * * * * 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 * * * * * * * * * * * //
@ -263,8 +255,7 @@ void Foam::localPointRegion::calcPointRegions
mesh,
candidatePoint,
orEqOp<bool>(),
false, // nullValue
false // applySeparation
false // nullValue
);
@ -419,12 +410,18 @@ void Foam::localPointRegion::calcPointRegions
// Transport minimum across coupled faces
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
syncTools::syncFaceList
SubList<face> l
(
minRegion,
mesh.nFaces()-mesh.nInternalFaces(),
mesh.nInternalFaces()
);
syncTools::syncBoundaryFaceList
(
mesh,
minRegion,
l,
minEqOpFace(),
false // applySeparation
Foam::dummyTransform() // dummy transformation
);
}

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