Merge branch 'AMI'

This commit is contained in:
andy
2011-09-07 14:50:57 +01:00
355 changed files with 15525 additions and 941 deletions

View File

@ -136,7 +136,7 @@ void Foam::conformalVoronoiMesh::buildSurfaceConformation
// Surface protrusion conformation is done in two steps.
// 1. the dual edges (of all internal vertices) can stretch to
// 1. the dual edges (of all internal vertices) can stretch to
// 'infinity' so any intersection would be badly behaved. So
// just find the nearest point on the geometry and insert point
// pairs.

View File

@ -310,15 +310,15 @@ void Foam::conformalVoronoiMesh::writeMesh
{
// Determine map from Delaunay vertex to Dual mesh
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// From all Delaunay vertices to cell (positive index)
// or patch face (negative index)
labelList vertexToDualAddressing(number_of_vertices(), 0);
forAll(cellToDelaunayVertex, cellI)
{
label vertI = cellToDelaunayVertex[cellI];
if (vertexToDualAddressing[vertI] != 0)
{
FatalErrorIn("conformalVoronoiMesh::writeMesh(..)")
@ -330,14 +330,14 @@ void Foam::conformalVoronoiMesh::writeMesh
}
vertexToDualAddressing[vertI] = cellI+1;
}
forAll(patchToDelaunayVertex, patchI)
{
const labelList& patchVertices = patchToDelaunayVertex[patchI];
forAll(patchVertices, i)
{
label vertI = patchVertices[i];
if (vertexToDualAddressing[vertI] > 0)
{
FatalErrorIn("conformalVoronoiMesh::writeMesh(..)")
@ -348,7 +348,7 @@ void Foam::conformalVoronoiMesh::writeMesh
<< vertexToDualAddressing[vertI]-1
<< exit(FatalError);
}
// Vertex might be used by multiple faces. Which one to
// use? For now last one wins.
label dualFaceI = dualPatchStarts[patchI]+i;
@ -389,7 +389,7 @@ void Foam::conformalVoronoiMesh::writeMesh
// Calculate map from tet points to dual mesh cells/patch faces
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
labelIOList pointDualAddressing
(
IOobject
@ -408,7 +408,7 @@ void Foam::conformalVoronoiMesh::writeMesh
pointToDelaunayVertex
)()
);
label pointI = findIndex(pointDualAddressing, -1);
if (pointI != -1)
{
@ -422,13 +422,13 @@ void Foam::conformalVoronoiMesh::writeMesh
) << "Delaunay vertex " << pointI
<< " does not have a corresponding dual cell." << endl;
}
Info<< "Writing map from tetDualMesh points to Voronoi mesh to "
<< pointDualAddressing.objectPath() << endl;
pointDualAddressing.write();
// Write tet points corresponding to the Voronoi cell/face centre
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{
@ -457,11 +457,11 @@ void Foam::conformalVoronoiMesh::writeMesh
),
points
);
forAll(pointDualAddressing, pointI)
{
label index = pointDualAddressing[pointI];
if (index > 0)
{
label cellI = index-1;
@ -476,7 +476,7 @@ void Foam::conformalVoronoiMesh::writeMesh
}
}
}
Info<< "Writing new tetDualMesh points mapped onto Voronoi mesh to "
<< dualPoints.objectPath() << endl
<< "Replace the polyMesh/points with these." << endl;

View File

@ -687,7 +687,7 @@ void getInterfaceSizes
}
}
// Rework
// Rework
Pstream::scatter(regionsToSize);

View File

@ -15,7 +15,7 @@ FoamFile
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
numberOfSubdomains 8;
numberOfSubdomains 2;
//- Keep owner and neighbour on same processor for faces in zones:
// preserveFaceZones (heater solid1 solid3);
@ -24,13 +24,22 @@ numberOfSubdomains 8;
// (makes sense only for cyclic patches)
//preservePatches (cyclic_half0 cyclic_half1);
//- Keep all of faceZone on a single processor. This puts all cells
// connected with a point, edge or face on the same processor.
// (just having face connected cells might not guarantee a balanced
// decomposition)
// The processor can be -1 (the decompositionMethod chooses the processor
// for a good load balance) or explicitly provided (upsets balance).
//singleProcessorFaceZones ((f0 -1));
//- Use the volScalarField named here as a weight for each cell in the
// decomposition. For example, use a particle population field to decompose
// for a balanced number of particles in a lagrangian simulation.
// weightField dsmcRhoNMean;
method scotch;
// method hierarchical;
//method hierarchical;
// method simple;
// method metis;
// method manual;
@ -70,7 +79,7 @@ simpleCoeffs
hierarchicalCoeffs
{
n (2 2 1);
n (1 2 1);
delta 0.001;
order xyz;
}

View File

@ -28,6 +28,7 @@ License
#include "cpuTime.H"
#include "cellSet.H"
#include "regionSplit.H"
#include "Tuple2.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -47,7 +48,8 @@ void Foam::domainDecomposition::distributeCells()
{
wordList pNames(decompositionDict_.lookup("preservePatches"));
Info<< "Keeping owner of faces in patches " << pNames
Info<< nl
<< "Keeping owner of faces in patches " << pNames
<< " on same processor. This only makes sense for cyclics." << endl;
const polyBoundaryMesh& patches = boundaryMesh();
@ -76,7 +78,8 @@ void Foam::domainDecomposition::distributeCells()
{
wordList zNames(decompositionDict_.lookup("preserveFaceZones"));
Info<< "Keeping owner and neighbour of faces in zones " << zNames
Info<< nl
<< "Keeping owner and neighbour of faces in zones " << zNames
<< " on same processor" << endl;
const faceZoneMesh& fZones = faceZones();
@ -103,6 +106,65 @@ void Foam::domainDecomposition::distributeCells()
}
// Specified processor for owner and neighbour of faces
Map<label> specifiedProcessorFaces;
List<Tuple2<word, label> > zNameAndProcs;
if (decompositionDict_.found("singleProcessorFaceZones"))
{
decompositionDict_.lookup("singleProcessorFaceZones") >> zNameAndProcs;
const faceZoneMesh& fZones = faceZones();
label nCells = 0;
Info<< endl;
forAll(zNameAndProcs, i)
{
Info<< "Keeping all cells connected to faceZone "
<< zNameAndProcs[i].first()
<< " on processor " << zNameAndProcs[i].second() << endl;
label zoneI = fZones.findZoneID(zNameAndProcs[i].first());
if (zoneI == -1)
{
FatalErrorIn("domainDecomposition::distributeCells()")
<< "Unknown singleProcessorFaceZone "
<< zNameAndProcs[i].first()
<< endl << "Valid faceZones are " << fZones.names()
<< exit(FatalError);
}
const faceZone& fz = fZones[zoneI];
nCells += fz.size();
}
// Size
specifiedProcessorFaces.resize(2*nCells);
// Fill
forAll(zNameAndProcs, i)
{
label zoneI = fZones.findZoneID(zNameAndProcs[i].first());
const faceZone& fz = fZones[zoneI];
label procI = zNameAndProcs[i].second();
forAll(fz, fzI)
{
label faceI = fz[fzI];
specifiedProcessorFaces.insert(faceI, procI);
}
}
}
// Construct decomposition method and either do decomposition on
// cell centres or on agglomeration
@ -112,7 +174,8 @@ void Foam::domainDecomposition::distributeCells()
decompositionDict_
);
if (sameProcFaces.empty())
if (sameProcFaces.empty() && specifiedProcessorFaces.empty())
{
if (decompositionDict_.found("weightField"))
{
@ -146,9 +209,11 @@ void Foam::domainDecomposition::distributeCells()
}
else
{
Info<< "Selected " << sameProcFaces.size()
<< " faces whose owner and neighbour cell should be kept on the"
<< " same processor" << endl;
Info<< "Constrained decomposition:" << endl
<< " faces with same processor owner and neighbour : "
<< sameProcFaces.size() << endl
<< " faces all on same processor : "
<< specifiedProcessorFaces.size() << endl << endl;
// Faces where owner and neighbour are not 'connected' (= all except
// sameProcFaces)
@ -159,6 +224,24 @@ void Foam::domainDecomposition::distributeCells()
blockedFace[iter.key()] = false;
}
// For specifiedProcessorFaces add all point connected faces
{
forAllConstIter(Map<label>, specifiedProcessorFaces, iter)
{
const face& f = faces()[iter.key()];
forAll(f, fp)
{
const labelList& pFaces = pointFaces()[f[fp]];
forAll(pFaces, i)
{
blockedFace[pFaces[i]] = false;
}
}
}
}
// Connect coupled boundary faces
const polyBoundaryMesh& patches = boundaryMesh();
@ -201,10 +284,11 @@ void Foam::domainDecomposition::distributeCells()
// Do decomposition on agglomeration
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
scalarField regionWeights(globalRegion.nRegions(), 0);
if (decompositionDict_.found("weightField"))
{
scalarField regionWeights(globalRegion.nRegions(), 0);
word weightName = decompositionDict_.lookup("weightField");
volScalarField weights
@ -226,23 +310,70 @@ void Foam::domainDecomposition::distributeCells()
regionWeights[regionI] += weights.internalField()[cellI];
}
cellToProc_ = decomposePtr().decompose
(
*this,
globalRegion,
regionCentres,
regionWeights
);
}
else
{
cellToProc_ = decomposePtr().decompose
(
*this,
globalRegion,
regionCentres
);
forAll(globalRegion, cellI)
{
label regionI = globalRegion[cellI];
regionWeights[regionI] += 1.0;
}
}
cellToProc_ = decomposePtr().decompose
(
*this,
globalRegion,
regionCentres,
regionWeights
);
// For specifiedProcessorFaces rework the cellToProc to enforce
// all on one processor since we can't guarantee that the input
// to regionSplit was a single region.
// E.g. faceZone 'a' with the cells split into two regions
// by a notch formed by two walls
//
// \ /
// \ /
// ---a----+-----a-----
//
//
// Note that reworking the cellToProc might make the decomposition
// unbalanced.
if (specifiedProcessorFaces.size())
{
const faceZoneMesh& fZones = faceZones();
forAll(zNameAndProcs, i)
{
label zoneI = fZones.findZoneID(zNameAndProcs[i].first());
const faceZone& fz = fZones[zoneI];
if (fz.size())
{
label procI = zNameAndProcs[i].second();
if (procI == -1)
{
// If no processor specified use the one from the
// 0th element
procI = cellToProc_[faceOwner()[fz[0]]];
}
forAll(fz, fzI)
{
label faceI = fz[fzI];
cellToProc_[faceOwner()[faceI]] = procI;
if (isInternalFace(faceI))
{
cellToProc_[faceNeighbour()[faceI]] = procI;
}
}
}
}
}
}

View File

@ -576,13 +576,13 @@ void ensightPointField
label ensightPatchI = eMesh.patchPartOffset();
forAll(allPatchNames, patchi)
{
const word& patchName = allPatchNames[patchi];
eMesh.barrier();
if (patchNames.empty() || patchNames.found(patchName))
{
const fvPatch& p = mesh.boundary()[patchi];
@ -603,24 +603,24 @@ void ensightPointField
pointToGlobal,
uniqueMeshPointLabels
);
if (Pstream::master())
{
ensightFile.writePartHeader(ensightPatchI);
}
writeField
(
"coordinates",
Field<Type>(pf.internalField(), uniqueMeshPointLabels),
ensightFile
);
ensightPatchI++;
}
}
}
// write faceZones, if requested
if (faceZoneNames.size())
{