Merge branch 'dynamicLoadBalancing' into development

This commit is contained in:
Hrvoje Jasak 2018-05-15 10:57:09 +01:00
commit 744ea0ae1f
183 changed files with 9935 additions and 7869 deletions

View file

@ -7,7 +7,10 @@
UEqn.relax
(
mesh.solutionDict().equationRelaxationFactor(U.select(pimple.finalIter()))
mesh.solutionDict().equationRelaxationFactor
(
U.select(pimple.finalIter())
)
);
solve(UEqn == -fvc::grad(p));

View file

@ -27,8 +27,6 @@
fvm::ddt(psis, p)
+ fvm::div(phid, p)
// Convective flux relaxation terms
+ fvm::SuSp(-divPhid, p)
+ divPhid*p
+ fvc::div(phid2)
- fvm::laplacian(rho*rUA, p)
);

View file

@ -8,7 +8,10 @@
UEqn.relax
(
mesh.solutionDict().equationRelaxationFactor(U.select(pimple.finalIter()))
mesh.solutionDict().equationRelaxationFactor
(
U.select(pimple.finalIter())
)
);
solve(UEqn == -fvc::grad(p));

View file

@ -12,4 +12,8 @@
hEqn.solve();
thermo.correct();
// Recalculate density
rho = thermo.rho();
rho.correctBoundaryConditions();
}

View file

@ -1,6 +1,4 @@
{
rho = thermo.rho();
rUA = 1.0/UEqn.A();
U = rUA*UEqn.H();
@ -56,12 +54,10 @@
p.relax();
}
# include "rhoEqn.H"
# include "compressibleContinuityErrs.H"
U -= rUA*fvc::grad(p);
U.correctBoundaryConditions();
DpDt = fvc::DDt(surfaceScalarField("phiU", phi/fvc::interpolate(rho)), p);
dpdt = fvc::ddt(p);
}

View file

@ -79,14 +79,15 @@ int main(int argc, char *argv[])
Info<< "Crank angle = " << runTime.theta() << " CA-deg" << endl;
// Make flux absolute
phi += meshFlux;
// Make the fluxes absolute (using the ddt(rho, U) scheme)
phi += fvc::interpolate(rho)*fvc::meshPhi(rho, U);
bool meshChanged = mesh.update();
# include "volContinuity.H"
mesh.setBoundaryVelocity(U);
// Make the fluxes relative (using the ddt(rho, U) scheme)
phi -= fvc::interpolate(rho)*fvc::meshPhi(rho, U);
if (meshChanged)
{
@ -95,14 +96,7 @@ int main(int argc, char *argv[])
rho.correctBoundaryConditions();
}
meshFlux = fvc::interpolate(rho)*fvc::meshPhi(rho, U);
phi = fvc::interpolate(rho)
*((fvc::interpolate(U) & mesh.Sf()) - fvc::meshPhi(rho, U));
DpDt = dpdt + fvc::div(phi/fvc::interpolate(rho), p)
- fvc::div(phi/fvc::interpolate(rho) + fvc::meshPhi(U))*p;
if (meshChanged)
{
# include "compressibleCourantNo.H"
}
@ -111,22 +105,20 @@ int main(int argc, char *argv[])
while (pimple.loop())
{
# include "rhoEqn.H"
# include "hEqn.H"
# include "UEqn.H"
// --- PISO loop
while (pimple.correct())
{
# include "pEqn.H"
# include "hEqn.H"
}
turbulence->correct();
}
turbulence->correct();
# include "logSummary.H"
rho = thermo.rho();
runTime.write();
# include "infoDataOutput.H"

View file

@ -338,30 +338,39 @@ autoPtr<mapPolyMesh> reorderMesh
(
new mapPolyMesh
(
mesh, //const polyMesh& mesh,
mesh, // const polyMesh& mesh,
mesh.nPoints(), // nOldPoints,
mesh.nFaces(), // nOldFaces,
mesh.nCells(), // nOldCells,
identity(mesh.nPoints()), // pointMap,
List<objectMap>(0), // pointsFromPoints,
faceOrder, // faceMap,
List<objectMap>(0), // facesFromPoints,
List<objectMap>(0), // facesFromEdges,
List<objectMap>(0), // facesFromFaces,
cellOrder, // cellMap,
List<objectMap>(0), // cellsFromPoints,
List<objectMap>(0), // cellsFromEdges,
List<objectMap>(0), // cellsFromFaces,
List<objectMap>(0), // cellsFromCells,
identity(mesh.nPoints()), // reversePointMap,
reverseFaceOrder, // reverseFaceMap,
reverseCellOrder, // reverseCellMap,
labelHashSet(0), // flipFaceFlux,
patchPointMap, // patchPointMap,
labelListList(0), // pointZoneMap,
labelListList(0), // faceZonePointMap,
labelListList(0), // faceZoneFaceMap,
labelListList(0), // cellZoneMap,
boolList(mesh.boundaryMesh().size(), false), // resetPatchFlag
pointField(0), // preMotionPoints,
patchStarts, // oldPatchStarts,
oldPatchNMeshPoints // oldPatchNMeshPoints

View file

@ -1,12 +1,3 @@
decomposeMesh.C
decomposePar.C
domainDecomposition.C
distributeCells.C
faMeshDecomposition.C
fvFieldDecomposer.C
faFieldDecomposer.C
pointFieldDecomposer.C
tetPointFieldDecomposer.C
lagrangianFieldDecomposer.C
EXE = $(FOAM_APPBIN)/decomposePar

View file

@ -1,5 +1,6 @@
EXE_INC = \
-I$(LIB_SRC)/decompositionMethods/decompositionMethods/lnInclude \
-I$(LIB_SRC)/decompositionMethods/decomposeReconstruct/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
@ -8,6 +9,7 @@ EXE_INC = \
EXE_LIBS = \
-ldecompositionMethods \
-ldecomposeReconstruct \
-lmeshTools \
-lfiniteVolume \
-lfiniteArea \

View file

@ -235,26 +235,45 @@ int main(int argc, char *argv[])
}
Info<< "Create mesh for region " << regionName << endl;
domainDecomposition mesh
fvMesh mesh
(
IOobject
(
regionName,
runTime.timeName(),
runTime
runTime,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
domainDecomposition meshDecomp
(
mesh,
IOdictionary
(
IOobject
(
"decomposeParDict",
runTime.system(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
// Decompose the mesh
if (!decomposeFieldsOnly)
{
mesh.decomposeMesh(filterPatches);
meshDecomp.decomposeMesh(filterPatches);
mesh.writeDecomposition();
meshDecomp.writeDecomposition();
if (writeCellDist)
{
const labelList& procIds = mesh.cellToProc();
const labelList& procIds = meshDecomp.cellToProc();
// Write the decomposition as labelList for use with 'manual'
// decomposition method.
@ -345,7 +364,7 @@ int main(int argc, char *argv[])
// Construct the point fields
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
pointMesh pMesh(mesh);
const pointMesh& pMesh = pointMesh::New(mesh);
PtrList<pointScalarField> pointScalarFields;
readFields(pMesh, objects, pointScalarFields);
@ -595,7 +614,7 @@ int main(int argc, char *argv[])
Info<< endl;
// Split the fields over processors
for (label procI = 0; procI < mesh.nProcs(); procI++)
for (label procI = 0; procI < meshDecomp.nProcs(); procI++)
{
Info<< "Processor " << procI << ": field transfer" << endl;
@ -632,6 +651,7 @@ int main(int argc, char *argv[])
processorDb
)
);
procMesh.syncUpdateMesh();
labelIOList cellProcAddressing
(
@ -872,7 +892,7 @@ int main(int argc, char *argv[])
{
const fileName timePath = processorDb.timePath();
if (copyUniform || mesh.distributed())
if (copyUniform || meshDecomp.distributed())
{
cp
(
@ -962,7 +982,7 @@ int main(int argc, char *argv[])
Info << endl;
// Split the fields over processors
for (label procI = 0; procI < mesh.nProcs(); procI++)
for (label procI = 0; procI < meshDecomp.nProcs(); procI++)
{
Info<< "Processor " << procI
<< ": finite area field transfer" << endl;

View file

@ -1,694 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "domainDecomposition.H"
#include "foamTime.H"
#include "dictionary.H"
#include "labelIOList.H"
#include "processorPolyPatch.H"
#include "fvMesh.H"
#include "OSspecific.H"
#include "Map.H"
#include "globalMeshData.H"
#include "DynamicList.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
domainDecomposition::domainDecomposition(const IOobject& io)
:
fvMesh(io),
decompositionDict_
(
IOobject
(
"decomposeParDict",
time().system(),
*this,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
),
nProcs_(readInt(decompositionDict_.lookup("numberOfSubdomains"))),
distributed_(false),
cellToProc_(nCells()),
procPointAddressing_(nProcs_),
procFaceAddressing_(nProcs_),
nInternalProcFaces_(nProcs_),
nLiveProcFaces_(nProcs_),
procCellAddressing_(nProcs_),
procBoundaryAddressing_(nProcs_),
procPatchSize_(nProcs_),
procPatchStartIndex_(nProcs_),
procNeighbourProcessors_(nProcs_),
procProcessorPatchSize_(nProcs_),
procProcessorPatchStartIndex_(nProcs_),
globallySharedPoints_(0),
cyclicParallel_(false)
{
if (decompositionDict_.found("distributed"))
{
distributed_ = Switch(decompositionDict_.lookup("distributed"));
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
domainDecomposition::~domainDecomposition()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool domainDecomposition::writeDecomposition()
{
Info<< "\nConstructing processor meshes" << endl;
// Make a lookup map for globally shared points
Map<label> sharedPointLookup(2*globallySharedPoints_.size());
forAll (globallySharedPoints_, pointi)
{
sharedPointLookup.insert(globallySharedPoints_[pointi], pointi);
}
// Mark point/faces/cells that are in zones. Bad coding - removed
// HJ, 31/Mar/2009
label totProcFaces = 0;
label maxProcPatches = 0;
label maxProcFaces = 0;
// Note: get cellLevel and pointLevel. Avoid checking whether they exist or
// not by hand. If they don't exist, simpy assume that the level is 0
const labelIOList globalCellLevel
(
IOobject
(
"cellLevel",
this->facesInstance(),
polyMesh::meshSubDir,
*this,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE
),
labelList(nCells(), 0)
);
const labelIOList globalPointLevel
(
IOobject
(
"pointLevel",
this->facesInstance(),
polyMesh::meshSubDir,
*this,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE
),
labelList(nPoints(), 0)
);
// Write out the meshes
for (label procI = 0; procI < nProcs_; procI++)
{
// Create processor points
const labelList& curPointLabels = procPointAddressing_[procI];
// Access list of all points in the mesh. HJ, 27/Mar/2009
const pointField& meshPoints = allPoints();
labelList pointLookup(meshPoints.size(), -1);
pointField procPoints(curPointLabels.size());
forAll (curPointLabels, pointi)
{
procPoints[pointi] = meshPoints[curPointLabels[pointi]];
pointLookup[curPointLabels[pointi]] = pointi;
}
// Create processor faces
const labelList& curFaceLabels = procFaceAddressing_[procI];
// Access list of all faces in the mesh. HJ, 27/Mar/2009
const faceList& meshFaces = allFaces();
labelList faceLookup(meshFaces.size(), -1);
faceList procFaces(curFaceLabels.size());
forAll (curFaceLabels, facei)
{
// Mark the original face as used
// Remember to decrement the index by one (turning index)
// HJ, 5/Dec/2001
label curF = mag(curFaceLabels[facei]) - 1;
faceLookup[curF] = facei;
// get the original face
labelList origFaceLabels;
if (curFaceLabels[facei] >= 0)
{
// face not turned
origFaceLabels = meshFaces[curF];
}
else
{
origFaceLabels = meshFaces[curF].reverseFace();
}
// translate face labels into local point list
face& procFaceLabels = procFaces[facei];
procFaceLabels.setSize(origFaceLabels.size());
forAll (origFaceLabels, pointi)
{
procFaceLabels[pointi] = pointLookup[origFaceLabels[pointi]];
}
}
// Create cell lookup
labelList cellLookup(nCells(), -1);
const labelList& curCellLabels = procCellAddressing_[procI];
forAll (curCellLabels, cellI)
{
cellLookup[curCellLabels[cellI]] = cellI;
}
// Get complete owner-neighour addressing in the mesh
const labelList& own = faceOwner();
const labelList& nei = faceNeighbour();
// Calculate owner and neighbour list
// Owner list is sized to number of live faces
// Neighbour list is sized to number of internal faces
labelList procOwner(nLiveProcFaces_[procI]);
// Note: loop over owner, not all faces: sizes are different
forAll (procOwner, faceI)
{
// Remember to decrement the index by one (turning index)
// HJ, 28/Mar/2009
label curF = mag(curFaceLabels[faceI]) - 1;
if (curFaceLabels[faceI] >= 0)
{
procOwner[faceI] = cellLookup[own[curF]];
}
else
{
procOwner[faceI] = cellLookup[nei[curF]];
}
}
labelList procNeighbour(nInternalProcFaces_[procI]);
// Note: loop over neighbour, not all faces: sizes are different
forAll (procNeighbour, faceI)
{
// Remember to decrement the index by one (turning index)
// HJ, 28/Mar/2009
label curF = mag(curFaceLabels[faceI]) - 1;
if (curFaceLabels[faceI] >= 0)
{
procNeighbour[faceI] = cellLookup[nei[curF]];
}
else
{
procNeighbour[faceI] = cellLookup[own[curF]];
}
}
// Create processor cells. No longer needed: using owner and neighbour
// HJ, 28/Mar/2009
// const cellList& meshCells = cells();
// cellList procCells(curCellLabels.size());
// forAll (curCellLabels, cellI)
// {
// const labelList& origCellLabels = meshCells[curCellLabels[cellI]];
// cell& curCell = procCells[cellI];
// curCell.setSize(origCellLabels.size());
// forAll (origCellLabels, cellFaceI)
// {
// curCell[cellFaceI] = faceLookup[origCellLabels[cellFaceI]];
// }
// }
// Create processor mesh without a boundary
fileName processorCasePath
(
time().caseName()/fileName(word("processor") + Foam::name(procI))
);
// make the processor directory
mkDir(time().rootPath()/processorCasePath);
// create a database
Time processorDb
(
Time::controlDictName,
time().rootPath(),
processorCasePath,
"system",
"constant",
true
);
// Create the mesh
polyMesh procMesh
(
IOobject
(
this->polyMesh::name(), // region name of undecomposed mesh
pointsInstance(),
processorDb
),
xferMove(procPoints),
xferMove(procFaces),
xferMove(procOwner),
xferMove(procNeighbour),
false // Do not sync par
// xferMove(procCells) // Old-fashioned mesh creation using cells.
// Deprecated: using face owner/neighbour
// HJ, 30/Mar/2009
);
// Create processor boundary patches
const labelList& curBoundaryAddressing = procBoundaryAddressing_[procI];
const labelList& curPatchSizes = procPatchSize_[procI];
const labelList& curPatchStarts = procPatchStartIndex_[procI];
const labelList& curNeighbourProcessors =
procNeighbourProcessors_[procI];
const labelList& curProcessorPatchSizes =
procProcessorPatchSize_[procI];
const labelList& curProcessorPatchStarts =
procProcessorPatchStartIndex_[procI];
const polyPatchList& meshPatches = boundaryMesh();
List<polyPatch*> procPatches
(
curPatchSizes.size()
+ curProcessorPatchSizes.size(),
reinterpret_cast<polyPatch*>(0)
);
label nPatches = 0;
forAll (curPatchSizes, patchi)
{
procPatches[nPatches] =
meshPatches[curBoundaryAddressing[patchi]].clone
(
procMesh.boundaryMesh(),
nPatches,
curPatchSizes[patchi],
curPatchStarts[patchi]
).ptr();
nPatches++;
}
forAll (curProcessorPatchSizes, procPatchI)
{
procPatches[nPatches] =
new processorPolyPatch
(
word("procBoundary") + Foam::name(procI)
+ word("to")
+ Foam::name(curNeighbourProcessors[procPatchI]),
curProcessorPatchSizes[procPatchI],
curProcessorPatchStarts[procPatchI],
nPatches,
procMesh.boundaryMesh(),
procI,
curNeighbourProcessors[procPatchI]
);
nPatches++;
}
// Add boundary patches
procMesh.addPatches(procPatches);
// Create and add zones
// Note:
// This coding was all wrong, as each point/face/cell may only
// belong to a single zone.
// Additionally, ordering of points/faces/cells in the processor mesh
// needs to match the ordering in global mesh zones. Full rewrite.
// HJ, 30/Mar/2009
// Create zones if needed
if
(
pointZones().size() > 0
|| faceZones().size() > 0
|| cellZones().size() > 0
)
{
// Point zones
List<pointZone*> procPz(pointZones().size());
{
const pointZoneMesh& pz = pointZones();
// Go through all the zoned points and find out if they
// belong to a processor. If so, add it to the zone as
// necessary
forAll (pz, zoneI)
{
const labelList& zonePoints = pz[zoneI];
labelList procZonePoints(zonePoints.size());
label nZonePoints = 0;
forAll (zonePoints, pointI)
{
const label localIndex =
pointLookup[zonePoints[pointI]];
if (localIndex >= 0)
{
// Point live on processor: add to zone
procZonePoints[nZonePoints] = localIndex;
nZonePoints++;
}
}
// Add the zone
procZonePoints.setSize(nZonePoints);
procPz[zoneI] = new pointZone
(
pz[zoneI].name(),
procZonePoints,
zoneI,
procMesh.pointZones()
);
}
}
// Face zones
List<faceZone*> procFz(faceZones().size());
{
const faceZoneMesh& fz = faceZones();
forAll (fz, zoneI)
{
const labelList& zoneFaces = fz[zoneI];
const boolList& flipMap = fz[zoneI].flipMap();
// Go through all the zoned faces and find out if they
// belong to a processor. If so, add it to the zone as
// necessary
labelList procZoneFaces(zoneFaces.size());
boolList procZoneFaceFlips(zoneFaces.size());
label nZoneFaces = 0;
forAll (zoneFaces, faceI)
{
const label localIndex = faceLookup[zoneFaces[faceI]];
if (localIndex >= 0)
{
// Face is present on the processor
// Add the face to the zone
procZoneFaces[nZoneFaces] = localIndex;
// Grab the flip
bool flip = flipMap[faceI];
if (curFaceLabels[localIndex] < 0)
{
flip = !flip;
}
procZoneFaceFlips[nZoneFaces] = flip;
nZoneFaces++;
}
}
// Add the zone
procZoneFaces.setSize(nZoneFaces);
procZoneFaceFlips.setSize(nZoneFaces);
procFz[zoneI] = new faceZone
(
fz[zoneI].name(),
procZoneFaces,
procZoneFaceFlips,
zoneI,
procMesh.faceZones()
);
}
}
// Cell zones
List<cellZone*> procCz(cellZones().size());
{
const cellZoneMesh& cz = cellZones();
// Go through all the zoned cells and find out if they
// belong to a processor. If so, add it to the zone as
// necessary
forAll (cz, zoneI)
{
const labelList& zoneCells = cz[zoneI];
labelList procZoneCells(zoneCells.size());
label nZoneCells = 0;
forAll (zoneCells, cellI)
{
const label localIndex = cellLookup[zoneCells[cellI]];
if (localIndex >= 0)
{
procZoneCells[nZoneCells] = localIndex;
nZoneCells++;
}
}
// Add the zone
procZoneCells.setSize(nZoneCells);
procCz[zoneI] = new cellZone
(
cz[zoneI].name(),
procZoneCells,
zoneI,
procMesh.cellZones()
);
}
}
// Add zones
procMesh.addZones(procPz, procFz, procCz);
}
// Set the precision of the points data to 10
IOstream::defaultPrecision(10);
procMesh.write();
Info<< endl
<< "Processor " << procI << nl
<< " Number of cells = " << procMesh.nCells()
<< endl;
label nBoundaryFaces = 0;
label nProcPatches = 0;
label nProcFaces = 0;
forAll (procMesh.boundaryMesh(), patchi)
{
if
(
procMesh.boundaryMesh()[patchi].type()
== processorPolyPatch::typeName
)
{
const processorPolyPatch& ppp =
refCast<const processorPolyPatch>
(
procMesh.boundaryMesh()[patchi]
);
Info<< " Number of faces shared with processor "
<< ppp.neighbProcNo() << " = " << ppp.size() << endl;
nProcPatches++;
nProcFaces += ppp.size();
}
else
{
nBoundaryFaces += procMesh.boundaryMesh()[patchi].size();
}
}
Info<< " Number of processor patches = " << nProcPatches << nl
<< " Number of processor faces = " << nProcFaces << nl
<< " Number of boundary faces = " << nBoundaryFaces << endl;
totProcFaces += nProcFaces;
maxProcPatches = max(maxProcPatches, nProcPatches);
maxProcFaces = max(maxProcFaces, nProcFaces);
// create and write the addressing information
labelIOList pointProcAddressing
(
IOobject
(
"pointProcAddressing",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procPointAddressing_[procI]
);
pointProcAddressing.write();
labelIOList faceProcAddressing
(
IOobject
(
"faceProcAddressing",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procFaceAddressing_[procI]
);
faceProcAddressing.write();
labelIOList cellProcAddressing
(
IOobject
(
"cellProcAddressing",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procCellAddressing_[procI]
);
cellProcAddressing.write();
labelIOList boundaryProcAddressing
(
IOobject
(
"boundaryProcAddressing",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procBoundaryAddressing_[procI]
);
boundaryProcAddressing.write();
// Create and write cellLevel and pointLevel information
const unallocLabelList& cellMap = cellProcAddressing;
labelIOList procCellLevel
(
IOobject
(
"cellLevel",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
labelList(globalCellLevel, cellMap)
);
procCellLevel.write();
const unallocLabelList& pointMap = pointProcAddressing;
labelIOList procPointLevel
(
IOobject
(
"pointLevel",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
labelList(globalPointLevel, pointMap)
);
procPointLevel.write();
}
Info<< nl
<< "Number of processor faces = " << totProcFaces/2 << nl
<< "Max number of processor patches = " << maxProcPatches << nl
<< "Max number of faces between processors = " << maxProcFaces
<< endl;
return true;
}
// ************************************************************************* //

View file

@ -48,7 +48,7 @@ void Foam::readFields
// Construct the vol scalar fields
fields.setSize(fieldObjects.size());
label fieldi=0;
label fieldI = 0;
for
(
IOobjectList::iterator iter = fieldObjects.begin();
@ -58,7 +58,7 @@ void Foam::readFields
{
fields.set
(
fieldi++,
fieldI++,
new GeoField
(
*iter(),

View file

@ -1,10 +1,4 @@
processorMeshes.C
processorFaMeshes.C
fvFieldReconstructor.C
faFieldReconstructor.C
pointFieldReconstructor.C
tetPointFieldReconstructor.C
reconstructLagrangianPositions.C
reconstructPar.C
EXE = $(FOAM_APPBIN)/reconstructPar

View file

@ -1,12 +1,17 @@
EXE_INC = \
-I$(LIB_SRC)/decompositionMethods/decompositionMethods/lnInclude \
-I$(LIB_SRC)/decompositionMethods/decomposeReconstruct/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/tetFiniteElement/lnInclude
EXE_LIBS = \
-ldecompositionMethods \
-ldecomposeReconstruct \
-lmeshTools \
-lfiniteVolume \
-lfiniteArea \
-llagrangian \
-lmeshTools \
-ltetFiniteElement

View file

@ -1,640 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "faFieldReconstructor.H"
#include "foamTime.H"
#include "PtrList.H"
#include "faPatchFields.H"
#include "emptyFaPatch.H"
#include "emptyFaPatchField.H"
#include "emptyFaePatchField.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::faPatchField, Foam::areaMesh> >
Foam::faFieldReconstructor::reconstructFaAreaField
(
const IOobject& fieldIoObject
)
{
// Read the field for all the processors
PtrList<GeometricField<Type, faPatchField, areaMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
procFields.set
(
procI,
new GeometricField<Type, faPatchField, areaMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI].time().timeName(),
procMeshes_[procI](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
// Create the internalField
Field<Type> internalField(mesh_.nFaces());
// Create the patch fields
PtrList<faPatchField<Type> > patchFields(mesh_.boundary().size());
// Create global mesh patchs starts
labelList gStarts(mesh_.boundary().size(), -1);
if (mesh_.boundary().size() > 0)
{
gStarts[0] = mesh_.nInternalEdges();
}
for(label i=1; i<mesh_.boundary().size(); i++)
{
gStarts[i] = gStarts[i-1] + mesh_.boundary()[i-1].labelList::size();
}
forAll (procMeshes_, procI)
{
const GeometricField<Type, faPatchField, areaMesh>& procField =
procFields[procI];
// Set the face values in the reconstructed field
internalField.rmap
(
procField.internalField(),
faceProcAddressing_[procI]
);
// Set the boundary patch values in the reconstructed field
labelList starts(procMeshes_[procI].boundary().size(), -1);
if(procMeshes_[procI].boundary().size() > 0)
{
starts[0] = procMeshes_[procI].nInternalEdges();
}
for(label i=1; i<procMeshes_[procI].boundary().size(); i++)
{
starts[i] =
starts[i-1]
+ procMeshes_[procI].boundary()[i-1].labelList::size();
}
forAll(boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Get addressing slice for this patch
// const labelList::subList cp =
// procMeshes_[procI].boundary()[patchI].patchSlice
// (
// edgeProcAddressing_[procI]
// );
const labelList::subList cp =
labelList::subList
(
edgeProcAddressing_[procI],
procMeshes_[procI].boundary()[patchI].size(),
starts[patchI]
);
// check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
// Regular patch. Fast looping
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
faPatchField<Type>::New
(
procField.boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, areaMesh>::null(),
faPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procField.boundaryField()[patchI].size()
)
)
);
}
const label curPatchStart = gStarts[curBPatch];
// mesh_.boundary()[curBPatch].start();
labelList reverseAddressing(cp.size());
forAll(cp, edgeI)
{
// Subtract one to take into account offsets for
// face direction.
// reverseAddressing[edgeI] = cp[edgeI] - 1 - curPatchStart;
reverseAddressing[edgeI] = cp[edgeI] - curPatchStart;
}
patchFields[curBPatch].rmap
(
procField.boundaryField()[patchI],
reverseAddressing
);
}
else
{
const Field<Type>& curProcPatch =
procField.boundaryField()[patchI];
// In processor patches, there's a mix of internal faces (some
// of them turned) and possible cyclics. Slow loop
forAll(cp, edgeI)
{
// Subtract one to take into account offsets for
// face direction.
// label curE = cp[edgeI] - 1;
label curE = cp[edgeI];
// Is the face on the boundary?
if (curE >= mesh_.nInternalEdges())
{
// label curBPatch = mesh_.boundary().whichPatch(curE);
label curBPatch = -1;
forAll (mesh_.boundary(), pI)
{
if
(
curE >= gStarts[pI]
&& curE <
(
gStarts[pI]
+ mesh_.boundary()[pI].labelList::size()
)
)
{
curBPatch = pI;
}
}
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
faPatchField<Type>::New
(
mesh_.boundary()[curBPatch].type(),
mesh_.boundary()[curBPatch],
DimensionedField<Type, areaMesh>::null()
)
);
}
// add the edge
// label curPatchEdge =
// mesh_.boundary()
// [curBPatch].whichEdge(curE);
label curPatchEdge = curE - gStarts[curBPatch];
patchFields[curBPatch][curPatchEdge] =
curProcPatch[edgeI];
}
}
}
}
}
forAll(mesh_.boundary(), patchI)
{
// add empty patches
if
(
typeid(mesh_.boundary()[patchI]) == typeid(emptyFaPatch)
&& !patchFields(patchI)
)
{
patchFields.set
(
patchI,
faPatchField<Type>::New
(
emptyFaPatchField<Type>::typeName,
mesh_.boundary()[patchI],
DimensionedField<Type, areaMesh>::null()
)
);
}
}
// Now construct and write the field
// setting the internalField and patchFields
return tmp<GeometricField<Type, faPatchField, areaMesh> >
(
new GeometricField<Type, faPatchField, areaMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[0].dimensions(),
internalField,
patchFields
)
);
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::faePatchField, Foam::edgeMesh> >
Foam::faFieldReconstructor::reconstructFaEdgeField
(
const IOobject& fieldIoObject
)
{
// Read the field for all the processors
PtrList<GeometricField<Type, faePatchField, edgeMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
procFields.set
(
procI,
new GeometricField<Type, faePatchField, edgeMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI].time().timeName(),
procMeshes_[procI](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
// Create the internalField
Field<Type> internalField(mesh_.nInternalEdges());
// Create the patch fields
PtrList<faePatchField<Type> > patchFields(mesh_.boundary().size());
labelList gStarts(mesh_.boundary().size(), -1);
if(mesh_.boundary().size() > 0)
{
gStarts[0] = mesh_.nInternalEdges();
}
for(label i=1; i<mesh_.boundary().size(); i++)
{
gStarts[i] = gStarts[i-1] + mesh_.boundary()[i-1].labelList::size();
}
forAll (procMeshes_, procI)
{
const GeometricField<Type, faePatchField, edgeMesh>& procField =
procFields[procI];
// Set the face values in the reconstructed field
// It is necessary to create a copy of the addressing array to
// take care of the face direction offset trick.
//
{
labelList curAddr(edgeProcAddressing_[procI]);
// forAll (curAddr, addrI)
// {
// curAddr[addrI] -= 1;
// }
internalField.rmap
(
procField.internalField(),
curAddr
);
}
// Set the boundary patch values in the reconstructed field
labelList starts(procMeshes_[procI].boundary().size(), -1);
if(procMeshes_[procI].boundary().size() > 0)
{
starts[0] = procMeshes_[procI].nInternalEdges();
}
for(label i=1; i<procMeshes_[procI].boundary().size(); i++)
{
starts[i] =
starts[i-1]
+ procMeshes_[procI].boundary()[i-1].labelList::size();
}
forAll(boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Get addressing slice for this patch
// const labelList::subList cp =
// procMeshes_[procI].boundary()[patchI].patchSlice
// (
// faceProcAddressing_[procI]
// );
const labelList::subList cp =
labelList::subList
(
edgeProcAddressing_[procI],
procMeshes_[procI].boundary()[patchI].size(),
starts[patchI]
);
// check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
// Regular patch. Fast looping
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
faePatchField<Type>::New
(
procField.boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, edgeMesh>::null(),
faPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procField.boundaryField()[patchI].size()
)
)
);
}
const label curPatchStart = gStarts[curBPatch];
// mesh_.boundary()[curBPatch].start();
labelList reverseAddressing(cp.size());
forAll(cp, edgeI)
{
// Subtract one to take into account offsets for
// face direction.
// reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart;
reverseAddressing[edgeI] = cp[edgeI] - curPatchStart;
}
patchFields[curBPatch].rmap
(
procField.boundaryField()[patchI],
reverseAddressing
);
}
else
{
const Field<Type>& curProcPatch =
procField.boundaryField()[patchI];
// In processor patches, there's a mix of internal faces (some
// of them turned) and possible cyclics. Slow loop
forAll(cp, edgeI)
{
// label curF = cp[edgeI] - 1;
label curE = cp[edgeI];
// Is the face turned the right side round
if (curE >= 0)
{
// Is the face on the boundary?
if (curE >= mesh_.nInternalEdges())
{
// label curBPatch =
// mesh_.boundary().whichPatch(curF);
label curBPatch = -1;
forAll (mesh_.boundary(), pI)
{
if
(
curE >= gStarts[pI]
&& curE <
(
gStarts[pI]
+ mesh_.boundary()[pI].labelList::size()
)
)
{
curBPatch = pI;
}
}
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
faePatchField<Type>::New
(
mesh_.boundary()[curBPatch].type(),
mesh_.boundary()[curBPatch],
DimensionedField<Type, edgeMesh>
::null()
)
);
}
// add the face
// label curPatchFace =
// mesh_.boundary()
// [curBPatch].whichEdge(curF);
label curPatchEdge = curE - gStarts[curBPatch];
patchFields[curBPatch][curPatchEdge] =
curProcPatch[edgeI];
}
else
{
// Internal face
internalField[curE] = curProcPatch[edgeI];
}
}
}
}
}
}
forAll(mesh_.boundary(), patchI)
{
// add empty patches
if
(
typeid(mesh_.boundary()[patchI]) == typeid(emptyFaPatch)
&& !patchFields(patchI)
)
{
patchFields.set
(
patchI,
faePatchField<Type>::New
(
emptyFaePatchField<Type>::typeName,
mesh_.boundary()[patchI],
DimensionedField<Type, edgeMesh>::null()
)
);
}
}
// Now construct and write the field
// setting the internalField and patchFields
return tmp<GeometricField<Type, faePatchField, edgeMesh> >
(
new GeometricField<Type, faePatchField, edgeMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[0].dimensions(),
internalField,
patchFields
)
);
}
// Reconstruct and write all area fields
template<class Type>
void Foam::faFieldReconstructor::reconstructFaAreaFields
(
const IOobjectList& objects
)
{
const word& fieldClassName =
GeometricField<Type, faPatchField, areaMesh>::typeName;
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
for
(
IOobjectList::const_iterator fieldIter = fields.begin();
fieldIter != fields.end();
++fieldIter
)
{
Info << " " << fieldIter()->name() << endl;
reconstructFaAreaField<Type>(*fieldIter())().write();
}
Info<< endl;
}
}
// Reconstruct and write all edge fields
template<class Type>
void Foam::faFieldReconstructor::reconstructFaEdgeFields
(
const IOobjectList& objects
)
{
const word& fieldClassName =
GeometricField<Type, faePatchField, edgeMesh>::typeName;
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
for
(
IOobjectList::const_iterator fieldIter = fields.begin();
fieldIter != fields.end();
++fieldIter
)
{
Info<< " " << fieldIter()->name() << endl;
reconstructFaEdgeField<Type>(*fieldIter())().write();
}
Info<< endl;
}
}
// ************************************************************************* //

View file

@ -1,196 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::fvFieldReconstructor
Description
FV volume and surface field reconstructor.
SourceFiles
fvFieldReconstructor.C
fvFieldReconstructorReconstructFields.C
\*---------------------------------------------------------------------------*/
#ifndef fvFieldReconstructor_H
#define fvFieldReconstructor_H
#include "PtrList.H"
#include "fvMesh.H"
#include "IOobjectList.H"
#include "fvPatchFieldMapper.H"
#include "labelIOList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class fvFieldReconstructor Declaration
\*---------------------------------------------------------------------------*/
class fvFieldReconstructor
{
// Private data
//- Reconstructed mesh reference
fvMesh& mesh_;
//- List of processor meshes
const PtrList<fvMesh>& procMeshes_;
//- List of processor face addressing lists
const PtrList<labelIOList>& faceProcAddressing_;
//- List of processor cell addressing lists
const PtrList<labelIOList>& cellProcAddressing_;
//- List of processor boundary addressing lists
const PtrList<labelIOList>& boundaryProcAddressing_;
// Private Member Functions
//- Disallow default bitwise copy construct
fvFieldReconstructor(const fvFieldReconstructor&);
//- Disallow default bitwise assignment
void operator=(const fvFieldReconstructor&);
public:
class fvPatchFieldReconstructor
:
public fvPatchFieldMapper
{
label size_;
label sizeBeforeMapping_;
public:
// Constructors
//- Construct given size
fvPatchFieldReconstructor
(
const label size,
const label sizeBeforeMapping
)
:
size_(size),
sizeBeforeMapping_(sizeBeforeMapping)
{}
// Member functions
virtual label size() const
{
return size_;
}
virtual label sizeBeforeMapping() const
{
return sizeBeforeMapping_;
}
virtual bool direct() const
{
return true;
}
virtual const unallocLabelList& directAddressing() const
{
return unallocLabelList::null();
}
};
// Constructors
//- Construct from components
fvFieldReconstructor
(
fvMesh& mesh,
const PtrList<fvMesh>& procMeshes,
const PtrList<labelIOList>& faceProcAddressing,
const PtrList<labelIOList>& cellProcAddressing,
const PtrList<labelIOList>& boundaryProcAddressing
);
// Member Functions
//- Reconstruct volume field
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh> >
reconstructFvVolumeField
(
const IOobject& fieldIoObject
);
//- Reconstruct surface field
template<class Type>
tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
reconstructFvSurfaceField
(
const IOobject& fieldIoObject
);
//- Reconstruct and write all/selected volume fields
template<class Type>
void reconstructFvVolumeFields
(
const IOobjectList& objects,
const HashSet<word>& selectedFields
);
//- Reconstruct and write all/selected volume fields
template<class Type>
void reconstructFvSurfaceFields
(
const IOobjectList& objects,
const HashSet<word>& selectedFields
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "fvFieldReconstructorReconstructFields.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,526 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "fvFieldReconstructor.H"
#include "foamTime.H"
#include "PtrList.H"
#include "fvPatchFields.H"
#include "emptyFvPatch.H"
#include "emptyFvPatchField.H"
#include "emptyFvsPatchField.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::fvFieldReconstructor::reconstructFvVolumeField
(
const IOobject& fieldIoObject
)
{
// Read the field for all the processors
PtrList<GeometricField<Type, fvPatchField, volMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
procFields.set
(
procI,
new GeometricField<Type, fvPatchField, volMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI].time().timeName(),
procMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
// Create the internalField
Field<Type> internalField(mesh_.nCells());
// Create the patch fields
PtrList<fvPatchField<Type> > patchFields(mesh_.boundary().size());
forAll (procMeshes_, procI)
{
const GeometricField<Type, fvPatchField, volMesh>& procField =
procFields[procI];
// Set the cell values in the reconstructed field
internalField.rmap
(
procField.internalField(),
cellProcAddressing_[procI]
);
// Set the boundary patch values in the reconstructed field
forAll (boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Get addressing slice for this patch
const labelList::subList cp =
procMeshes_[procI].boundary()[patchI].patchSlice
(
faceProcAddressing_[procI]
);
// check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
// Regular patch. Fast looping
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
fvPatchField<Type>::New
(
procField.boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, volMesh>::null(),
fvPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procField.boundaryField()[patchI].size()
)
)
);
}
const label curPatchStart =
mesh_.boundaryMesh()[curBPatch].start();
labelList reverseAddressing(cp.size());
forAll (cp, faceI)
{
// Subtract one to take into account offsets for
// face direction.
reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart;
}
patchFields[curBPatch].rmap
(
procField.boundaryField()[patchI],
reverseAddressing
);
}
else
{
const Field<Type>& curProcPatch =
procField.boundaryField()[patchI];
// In processor patches, there's a mix of internal faces (some
// of them turned) and possible cyclics. Slow loop
forAll (cp, faceI)
{
// Subtract one to take into account offsets for
// face direction.
label curF = cp[faceI] - 1;
// Is the face on the boundary?
if (curF >= mesh_.nInternalFaces())
{
label curBPatch =
mesh_.boundaryMesh().whichPatch(curF);
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
fvPatchField<Type>::New
(
mesh_.boundary()[curBPatch].type(),
mesh_.boundary()[curBPatch],
DimensionedField<Type, volMesh>::null()
)
);
}
// add the face
label curPatchFace =
mesh_.boundaryMesh()
[curBPatch].whichFace(curF);
patchFields[curBPatch][curPatchFace] =
curProcPatch[faceI];
}
}
}
}
}
forAll (mesh_.boundary(), patchI)
{
// add empty patches
if
(
isType<emptyFvPatch>(mesh_.boundary()[patchI])
&& !patchFields(patchI)
)
{
patchFields.set
(
patchI,
fvPatchField<Type>::New
(
emptyFvPatchField<Type>::typeName,
mesh_.boundary()[patchI],
DimensionedField<Type, volMesh>::null()
)
);
}
}
// Now construct and write the field
// setting the internalField and patchFields
return tmp<GeometricField<Type, fvPatchField, volMesh> >
(
new GeometricField<Type, fvPatchField, volMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[0].dimensions(),
internalField,
patchFields
)
);
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
Foam::fvFieldReconstructor::reconstructFvSurfaceField
(
const IOobject& fieldIoObject
)
{
// Read the field for all the processors
PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
procFields.set
(
procI,
new GeometricField<Type, fvsPatchField, surfaceMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI].time().timeName(),
procMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
// Create the internalField
Field<Type> internalField(mesh_.nInternalFaces());
// Create the patch fields
PtrList<fvsPatchField<Type> > patchFields(mesh_.boundary().size());
forAll (procMeshes_, procI)
{
const GeometricField<Type, fvsPatchField, surfaceMesh>& procField =
procFields[procI];
// Set the face values in the reconstructed field
// It is necessary to create a copy of the addressing array to
// take care of the face direction offset trick.
//
{
labelList curAddr(faceProcAddressing_[procI]);
forAll (curAddr, addrI)
{
curAddr[addrI] -= 1;
}
internalField.rmap
(
procField.internalField(),
curAddr
);
}
// Set the boundary patch values in the reconstructed field
forAll (boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Get addressing slice for this patch
const labelList::subList cp =
procMeshes_[procI].boundary()[patchI].patchSlice
(
faceProcAddressing_[procI]
);
// Check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
// Regular patch. Fast looping
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
fvsPatchField<Type>::New
(
procField.boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, surfaceMesh>::null(),
fvPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procField.boundaryField()[patchI].size()
)
)
);
}
const label curPatchStart =
mesh_.boundaryMesh()[curBPatch].start();
labelList reverseAddressing(cp.size());
forAll (cp, faceI)
{
// Subtract one to take into account offsets for
// face direction.
reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart;
}
patchFields[curBPatch].rmap
(
procField.boundaryField()[patchI],
reverseAddressing
);
}
else
{
const Field<Type>& curProcPatch =
procField.boundaryField()[patchI];
// In processor patches, there's a mix of internal faces (some
// of them turned) and possible cyclics. Slow loop
forAll (cp, faceI)
{
label curF = cp[faceI] - 1;
// Is the face turned the right side round
if (curF >= 0)
{
// Is the face on the boundary?
if (curF >= mesh_.nInternalFaces())
{
label curBPatch =
mesh_.boundaryMesh().whichPatch(curF);
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
fvsPatchField<Type>::New
(
mesh_.boundary()[curBPatch].type(),
mesh_.boundary()[curBPatch],
DimensionedField<Type, surfaceMesh>
::null()
)
);
}
// add the face
label curPatchFace =
mesh_.boundaryMesh()
[curBPatch].whichFace(curF);
patchFields[curBPatch][curPatchFace] =
curProcPatch[faceI];
}
else
{
// Internal face
internalField[curF] = curProcPatch[faceI];
}
}
}
}
}
}
forAll (mesh_.boundary(), patchI)
{
// add empty patches
if
(
isType<emptyFvPatch>(mesh_.boundary()[patchI])
&& !patchFields(patchI)
)
{
patchFields.set
(
patchI,
fvsPatchField<Type>::New
(
emptyFvsPatchField<Type>::typeName,
mesh_.boundary()[patchI],
DimensionedField<Type, surfaceMesh>::null()
)
);
}
}
// Now construct and write the field
// setting the internalField and patchFields
return tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
(
new GeometricField<Type, fvsPatchField, surfaceMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[0].dimensions(),
internalField,
patchFields
)
);
}
// Reconstruct and write all/selected volume fields
template<class Type>
void Foam::fvFieldReconstructor::reconstructFvVolumeFields
(
const IOobjectList& objects,
const HashSet<word>& selectedFields
)
{
const word& fieldClassName =
GeometricField<Type, fvPatchField, volMesh>::typeName;
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
forAllConstIter(IOobjectList, fields, fieldIter)
{
if
(
!selectedFields.size()
|| selectedFields.found(fieldIter()->name())
)
{
Info<< " " << fieldIter()->name() << endl;
reconstructFvVolumeField<Type>(*fieldIter())().write();
}
}
Info<< endl;
}
}
// Reconstruct and write all/selected surface fields
template<class Type>
void Foam::fvFieldReconstructor::reconstructFvSurfaceFields
(
const IOobjectList& objects,
const HashSet<word>& selectedFields
)
{
const word& fieldClassName =
GeometricField<Type, fvsPatchField, surfaceMesh>::typeName;
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
forAllConstIter(IOobjectList, fields, fieldIter)
{
if
(
!selectedFields.size()
|| selectedFields.found(fieldIter()->name())
)
{
Info<< " " << fieldIter()->name() << endl;
reconstructFvSurfaceField<Type>(*fieldIter())().write();
}
}
Info<< endl;
}
}
// ************************************************************************* //

View file

@ -1,173 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::pointFieldReconstructor
Description
Point field reconstructor.
SourceFiles
pointFieldReconstructor.C
\*---------------------------------------------------------------------------*/
#ifndef pointFieldReconstructor_H
#define pointFieldReconstructor_H
#include "pointMesh.H"
#include "pointFields.H"
#include "PointPatchFieldMapperPatchRef.H"
#include "IOobjectList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class pointFieldReconstructor Declaration
\*---------------------------------------------------------------------------*/
class pointFieldReconstructor
{
// Private data
//- Reconstructed mesh reference
const pointMesh& mesh_;
//- List of processor meshes
const PtrList<pointMesh>& procMeshes_;
//- List of processor point addressing lists
const PtrList<labelIOList>& pointProcAddressing_;
//- List of processor boundary addressing lists
const PtrList<labelIOList>& boundaryProcAddressing_;
//- Point patch addressing
labelListListList patchPointAddressing_;
// Private Member Functions
//- Disallow default bitwise copy construct
pointFieldReconstructor
(
const pointFieldReconstructor&
);
//- Disallow default bitwise assignment
void operator=(const pointFieldReconstructor&);
public:
class pointPatchFieldReconstructor
:
public PointPatchFieldMapper
{
label size_;
label sizeBeforeMapping_;
public:
// Constructors
//- Construct given size
pointPatchFieldReconstructor
(
const label size,
const label sizeBeforeMapping
)
:
size_(size),
sizeBeforeMapping_(sizeBeforeMapping)
{}
// Member functions
virtual label size() const
{
return size_;
}
virtual label sizeBeforeMapping() const
{
return sizeBeforeMapping_;
}
virtual bool direct() const
{
return true;
}
virtual const unallocLabelList& directAddressing() const
{
return unallocLabelList::null();
}
};
// Constructors
//- Construct from components
pointFieldReconstructor
(
const pointMesh& mesh,
const PtrList<pointMesh>& procMeshes,
const PtrList<labelIOList>& pointProcAddressing,
const PtrList<labelIOList>& boundaryProcAddressing
);
// Member Functions
//- Reconstruct field
template<class Type>
tmp<GeometricField<Type, pointPatchField, pointMesh> >
reconstructField(const IOobject& fieldIoObject);
//- Reconstruct and write all fields
template<class Type>
void reconstructFields(const IOobjectList& objects);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "pointFieldReconstructorReconstructFields.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,178 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "pointFieldReconstructor.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh> >
Foam::pointFieldReconstructor::reconstructField(const IOobject& fieldIoObject)
{
// Read the field for all the processors
PtrList<GeometricField<Type, pointPatchField, pointMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, proci)
{
procFields.set
(
proci,
new GeometricField<Type, pointPatchField, pointMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[proci]().time().timeName(),
procMeshes_[proci](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[proci]
)
);
}
// Create the internalField
Field<Type> internalField(mesh_.size());
// Create the patch fields
PtrList<pointPatchField<Type> > patchFields(mesh_.boundary().size());
forAll (procMeshes_, proci)
{
const GeometricField<Type, pointPatchField, pointMesh>&
procField = procFields[proci];
// Get processor-to-global addressing for use in rmap
const labelList& procToGlobalAddr = pointProcAddressing_[proci];
// Set the cell values in the reconstructed field
internalField.rmap
(
procField.internalField(),
procToGlobalAddr
);
// Set the boundary patch values in the reconstructed field
forAll(boundaryProcAddressing_[proci], patchi)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[proci][patchi];
// check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
pointPatchField<Type>::New
(
procField.boundaryField()[patchi],
mesh_.boundary()[curBPatch],
DimensionedField<Type, pointMesh>::null(),
pointPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procField.boundaryField()[patchi].size()
)
)
);
}
patchFields[curBPatch].rmap
(
procField.boundaryField()[patchi],
patchPointAddressing_[proci][patchi]
);
}
}
}
// Construct and write the field
// setting the internalField and patchFields
return tmp<GeometricField<Type, pointPatchField, pointMesh> >
(
new GeometricField<Type, pointPatchField, pointMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_().time().timeName(),
mesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[0].dimensions(),
internalField,
patchFields
)
);
}
// Reconstruct and write all point fields
template<class Type>
void Foam::pointFieldReconstructor::reconstructFields
(
const IOobjectList& objects
)
{
word fieldClassName
(
GeometricField<Type, pointPatchField, pointMesh>::typeName
);
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
for
(
IOobjectList::iterator fieldIter = fields.begin();
fieldIter != fields.end();
++fieldIter
)
{
Info<< " " << fieldIter()->name() << endl;
reconstructField<Type>(*fieldIter())().write();
}
Info<< endl;
}
}
// ************************************************************************* //

View file

@ -1,258 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "processorFaMeshes.H"
#include "foamTime.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::processorFaMeshes::read()
{
forAll (fvMeshes_, procI)
{
meshes_.set
(
procI,
new faMesh(fvMeshes_[procI])
);
pointProcAddressing_.set
(
procI,
new labelIOList
(
IOobject
(
"pointProcAddressing",
meshes_[procI].time().findInstance
(
meshes_[procI].meshDir(),
"pointProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
edgeProcAddressing_.set
(
procI,
new labelIOList
(
IOobject
(
"edgeProcAddressing",
meshes_[procI].time().findInstance
(
meshes_[procI].meshDir(),
"edgeProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
faceProcAddressing_.set
(
procI,
new labelIOList
(
IOobject
(
"faceProcAddressing",
meshes_[procI].time().findInstance
(
meshes_[procI].meshDir(),
"faceProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
boundaryProcAddressing_.set
(
procI,
new labelIOList
(
IOobject
(
"boundaryProcAddressing",
meshes_[procI].time().findInstance
(
meshes_[procI].meshDir(),
"faceProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::processorFaMeshes::processorFaMeshes
(
const PtrList<fvMesh>& processorFvMeshes
)
:
fvMeshes_(processorFvMeshes),
meshes_(processorFvMeshes.size()),
pointProcAddressing_(processorFvMeshes.size()),
edgeProcAddressing_(processorFvMeshes.size()),
faceProcAddressing_(processorFvMeshes.size()),
boundaryProcAddressing_(processorFvMeshes.size())
{
read();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Foam::fvMesh::readUpdateState Foam::processorFaMeshes::readUpdate()
// {
// fvMesh::readUpdateState stat = fvMesh::UNCHANGED;
// forAll (databases_, procI)
// {
// // Check if any new meshes need to be read.
// fvMesh::readUpdateState procStat = meshes_[procI].readUpdate();
// /*
// if (procStat != fvMesh::UNCHANGED)
// {
// Info<< "Processor " << procI
// << " at time " << databases_[procI].timeName()
// << " detected mesh change " << procStat
// << endl;
// }
// */
// // Combine into overall mesh change status
// if (stat == fvMesh::UNCHANGED)
// {
// stat = procStat;
// }
// else
// {
// if (stat != procStat)
// {
// FatalErrorIn("processorFaMeshes::readUpdate()")
// << "Processor " << procI
// << " has a different polyMesh at time "
// << databases_[procI].timeName()
// << " compared to any previous processors." << nl
// << "Please check time " << databases_[procI].timeName()
// << " directories on all processors for consistent"
// << " mesh files."
// << exit(FatalError);
// }
// }
// }
// if
// (
// stat == fvMesh::TOPO_CHANGE
// || stat == fvMesh::TOPO_PATCH_CHANGE
// )
// {
// // Reread all meshes and addresssing
// read();
// }
// return stat;
// }
// void Foam::processorFaMeshes::reconstructPoints(fvMesh& mesh)
// {
// // Read the field for all the processors
// PtrList<pointIOField> procsPoints(meshes_.size());
// forAll (meshes_, procI)
// {
// procsPoints.set
// (
// procI,
// new pointIOField
// (
// IOobject
// (
// "points",
// meshes_[procI].time().timeName(),
// polyMesh::meshSubDir,
// meshes_[procI],
// IOobject::MUST_READ,
// IOobject::NO_WRITE
// )
// )
// );
// }
// // Create the new points
// vectorField newPoints(mesh.nPoints());
// forAll (meshes_, procI)
// {
// const vectorField& procPoints = procsPoints[procI];
// // Set the cell values in the reconstructed field
// const labelList& pointProcAddressingI = pointProcAddressing_[procI];
// if (pointProcAddressingI.size() != procPoints.size())
// {
// FatalErrorIn("processorFaMeshes")
// << "problem :"
// << " pointProcAddressingI:" << pointProcAddressingI.size()
// << " procPoints:" << procPoints.size()
// << abort(FatalError);
// }
// forAll(pointProcAddressingI, pointI)
// {
// newPoints[pointProcAddressingI[pointI]] = procPoints[pointI];
// }
// }
// mesh.movePoints(newPoints);
// mesh.write();
// }
// ************************************************************************* //

View file

@ -1,140 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
processorFaMeshes
Description
Container for processor mesh addressing.
Author
Zeljko Tukovic, FSB Zagreb. All rights reserved
SourceFiles
processorFaMeshes.C
\*---------------------------------------------------------------------------*/
#ifndef processorFaMeshes_H
#define processorFaMeshes_H
#include "PtrList.H"
#include "fvMesh.H"
#include "faMesh.H"
#include "IOobjectList.H"
#include "labelIOList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class processorFaMeshes Declaration
\*---------------------------------------------------------------------------*/
class processorFaMeshes
{
// Private data
//- List of processor finite volume meshes
const PtrList<fvMesh>& fvMeshes_;
//- List of processor finite area meshes
PtrList<faMesh> meshes_;
//- List of processor point addressing lists
PtrList<labelIOList> pointProcAddressing_;
//- List of processor face addressing lists
PtrList<labelIOList> edgeProcAddressing_;
//- List of processor cell addressing lists
PtrList<labelIOList> faceProcAddressing_;
//- List of processor boundary addressing lists
PtrList<labelIOList> boundaryProcAddressing_;
// Private Member Functions
//- Read all meshes
void read();
//- Disallow default bitwise copy construct
processorFaMeshes(const processorFaMeshes&);
//- Disallow default bitwise assignment
void operator=(const processorFaMeshes&);
public:
// Constructors
//- Construct from components
processorFaMeshes(const PtrList<fvMesh>& processorFvMeshes);
// Member Functions
//- Update the meshes based on the mesh files saved in
// time directories
// fvMesh::readUpdateState readUpdate();
//- Reconstruct point position after motion in parallel
// void reconstructPoints(faMesh& mesh);
PtrList<faMesh>& meshes()
{
return meshes_;
}
const PtrList<labelIOList>& pointProcAddressing() const
{
return pointProcAddressing_;
}
PtrList<labelIOList>& edgeProcAddressing()
{
return edgeProcAddressing_;
}
const PtrList<labelIOList>& faceProcAddressing() const
{
return faceProcAddressing_;
}
const PtrList<labelIOList>& boundaryProcAddressing() const
{
return boundaryProcAddressing_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,125 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "IOField.H"
#include "foamTime.H"
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::IOField<Type> > Foam::reconstructLagrangianField
(
const word& cloudName,
const polyMesh& mesh,
const PtrList<fvMesh>& meshes,
const word& fieldName
)
{
// Construct empty field on mesh
tmp<IOField<Type> > tfield
(
new IOField<Type>
(
IOobject
(
fieldName,
mesh.time().timeName(),
cloud::prefix/cloudName,
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
Field<Type>(0)
)
);
Field<Type>& field = tfield();
forAll(meshes, i)
{
// Check object on local mesh
IOobject localIOobject
(
fieldName,
meshes[i].time().timeName(),
cloud::prefix/cloudName,
meshes[i],
IOobject::MUST_READ,
IOobject::NO_WRITE
);
if (localIOobject.headerOk())
{
IOField<Type> fieldi(localIOobject);
label offset = field.size();
field.setSize(offset + fieldi.size());
forAll(fieldi, j)
{
field[offset + j] = fieldi[j];
}
}
}
return tfield;
}
template<class Type>
void Foam::reconstructLagrangianFields
(
const word& cloudName,
const polyMesh& mesh,
const PtrList<fvMesh>& meshes,
const IOobjectList& objects
)
{
word fieldClassName(IOField<Type>::typeName);
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing lagrangian "
<< fieldClassName << "s\n" << endl;
forAllIter(IOobjectList, fields, fieldIter)
{
Info<< " " << fieldIter()->name() << endl;
reconstructLagrangianField<Type>
(
cloudName,
mesh,
meshes,
fieldIter()->name()
)().write();
}
Info<< endl;
}
}
// ************************************************************************* //

View file

@ -485,7 +485,8 @@ int main(int argc, char *argv[])
faMesh aMesh(mesh);
processorFaMeshes procFaMeshes(procMeshes.meshes());
// Create mesh addressing by reading from files
processorFaMeshes procFaMeshes(procMeshes.meshes(), true);
faFieldReconstructor faReconstructor
(

View file

@ -1,372 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "tetPointFieldReconstructor.H"
#include "PtrList.H"
#include "tetPolyPatchFields.H"
#include "tetFemMatrices.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
tmp<GeometricField<Type, tetPolyPatchField, tetPointMesh> >
tetPointFieldReconstructor::reconstructTetPointField
(
const IOobject& fieldIoObject
)
{
// Read the field for all the processors
PtrList<GeometricField<Type, tetPolyPatchField, tetPointMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
procFields.set
(
procI,
new GeometricField<Type, tetPolyPatchField, tetPointMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI]().time().timeName(),
procMeshes_[procI](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
// Create the internalField
Field<Type> internalField(mesh_.nPoints());
// Create the patch fields
PtrList<tetPolyPatchField<Type> > patchFields(mesh_.boundary().size());
forAll (procMeshes_, procI)
{
const GeometricField<Type, tetPolyPatchField, tetPointMesh>&
procField = procFields[procI];
// Get processor-to-global addressing for use in rmap
labelList procToGlobalAddr = procAddressing(procI);
// Set the cell values in the reconstructed field
internalField.rmap
(
procField.internalField(),
procToGlobalAddr
);
// Set the boundary patch values in the reconstructed field
forAll(boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
tetPolyPatchField<Type>::New
(
procField.boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, tetPointMesh>::null(),
tetPolyPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procField.boundaryField()[patchI].size()
)
)
);
}
// If the field stores values, do the rmap
if (patchFields[curBPatch].storesFieldData())
{
patchFields[curBPatch].rmap
(
procField.boundaryField()[patchI],
procPatchAddressing
(
procToGlobalAddr,
procI,
patchI
)
);
}
}
}
}
// Now construct and write the field
// setting the internalField and patchFields
return tmp<GeometricField<Type, tetPolyPatchField, tetPointMesh> >
(
new GeometricField<Type, tetPolyPatchField, tetPointMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_().time().timeName(),
mesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[0].dimensions(),
internalField,
patchFields
)
);
}
template<class Type>
tmp<GeometricField<Type, elementPatchField, elementMesh> >
tetPointFieldReconstructor::reconstructElementField
(
const IOobject& fieldIoObject
)
{
// Read the field for all the processors
PtrList<GeometricField<Type, elementPatchField, elementMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
procFields.set
(
procI,
new GeometricField<Type, elementPatchField, elementMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI]().time().timeName(),
procMeshes_[procI](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
// Create the internalField
Field<Type> internalField(mesh_.nCells());
// Create the patch fields
PtrList<elementPatchField<Type> > patchFields(mesh_.boundary().size());
forAll (procMeshes_, procI)
{
const GeometricField<Type, elementPatchField, elementMesh>&
procField = procFields[procI];
// Set the cell values in the reconstructed field
internalField.rmap
(
procField.internalField(),
cellProcAddressing_[procI]
);
// Set the boundary patch values in the reconstructed field
forAll(boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Get addressing slice for this patch
const labelList::subList cp =
procMeshes_[procI]().boundaryMesh()[patchI].patchSlice
(
faceProcAddressing_[procI]
);
// check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
elementPatchField<Type>::New
(
procField.boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, elementMesh>::null(),
tetPolyPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procField.boundaryField()[patchI].size()
)
)
);
}
// If the field stores values, do the rmap
if (patchFields[curBPatch].storesFieldData())
{
const label curPatchStart =
mesh_().boundaryMesh()[curBPatch].start();
labelList reverseAddressing(cp.size());
forAll(cp, faceI)
{
// Subtract one to take into account offsets for
// face direction.
reverseAddressing[faceI] = cp[faceI] - 1
- curPatchStart;
}
patchFields[curBPatch].rmap
(
procField.boundaryField()[patchI],
reverseAddressing
);
}
}
}
}
// Now construct and write the field
// setting the internalField and patchFields
return tmp<GeometricField<Type, elementPatchField, elementMesh> >
(
new GeometricField<Type, elementPatchField, elementMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_().time().timeName(),
mesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[0].dimensions(),
internalField,
patchFields
)
);
}
template<class Type>
void tetPointFieldReconstructor::reconstructTetPointFields
(
const IOobjectList& objects
)
{
word fieldClassName
(
GeometricField<Type, tetPolyPatchField, tetPointMesh>::typeName
);
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
for
(
IOobjectList::iterator fieldIter = fields.begin();
fieldIter != fields.end();
++fieldIter
)
{
Info<< " " << fieldIter()->name() << endl;
reconstructTetPointField<Type>(*fieldIter())().write();
}
Info<< endl;
}
}
template<class Type>
void tetPointFieldReconstructor::reconstructElementFields
(
const IOobjectList& objects
)
{
word fieldClassName
(
GeometricField<Type, elementPatchField, elementMesh>::typeName
);
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
for
(
IOobjectList::iterator fieldIter = fields.begin();
fieldIter != fields.end();
++fieldIter
)
{
Info<< " " << fieldIter()->name() << endl;
reconstructElementField<Type>(*fieldIter())().write();
}
Info<< endl;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -1,14 +1,3 @@
processorMeshesReconstructor.C
processorMeshesRebuild.C
processorFaMeshes.C
fvFieldReconstructor.C
faFieldReconstructor.C
pointFieldReconstructor.C
tetPointFieldReconstructor.C
reconstructLagrangianPositions.C
reconstructParMesh.C
EXE = $(FOAM_APPBIN)/reconstructParMesh

View file

@ -1,10 +1,14 @@
EXE_INC = \
-I$(LIB_SRC)/decompositionMethods/decompositionMethods/lnInclude \
-I$(LIB_SRC)/decompositionMethods/decomposeReconstruct/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/tetFiniteElement/lnInclude
EXE_LIBS = \
-ldecompositionMethods \
-ldecomposeReconstruct \
-lfiniteVolume \
-lfiniteArea \
-llagrangian \

View file

@ -1,197 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
faFieldReconstructor
Description
FA area and edge field reconstructor.
Author
Zeljko Tukovic, FSB Zagreb. All rights reserved
SourceFiles
faFieldReconstructor.C
faFieldReconstructorReconstructFields.C
\*---------------------------------------------------------------------------*/
#ifndef faFieldReconstructor_H
#define faFieldReconstructor_H
#include "PtrList.H"
#include "faMesh.H"
#include "IOobjectList.H"
#include "faPatchFieldMapper.H"
#include "labelIOList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class faFieldReconstructor Declaration
\*---------------------------------------------------------------------------*/
class faFieldReconstructor
{
// Private data
//- Reconstructed mesh reference
faMesh& mesh_;
//- List of processor meshes
const PtrList<faMesh>& procMeshes_;
//- List of processor edge addressing lists
const PtrList<labelIOList>& edgeProcAddressing_;
//- List of processor face addressing lists
const PtrList<labelIOList>& faceProcAddressing_;
//- List of processor boundary addressing lists
const PtrList<labelIOList>& boundaryProcAddressing_;
// Private Member Functions
//- Disallow default bitwise copy construct
faFieldReconstructor(const faFieldReconstructor&);
//- Disallow default bitwise assignment
void operator=(const faFieldReconstructor&);
public:
class faPatchFieldReconstructor
:
public faPatchFieldMapper
{
label size_;
label sizeBeforeMapping_;
public:
// Constructors
//- Construct given size
faPatchFieldReconstructor
(
const label size,
const label sizeBeforeMapping
)
:
size_(size),
sizeBeforeMapping_(sizeBeforeMapping)
{}
// Member functions
virtual label size() const
{
return size_;
}
virtual label sizeBeforeMapping() const
{
return sizeBeforeMapping_;
}
virtual bool direct() const
{
return true;
}
virtual const unallocLabelList& directAddressing() const
{
return unallocLabelList::null();
}
};
// Constructors
//- Construct from components
faFieldReconstructor
(
faMesh& mesh,
const PtrList<faMesh>& procMeshes,
const PtrList<labelIOList>& edgeProcAddressing,
const PtrList<labelIOList>& faceProcAddressing,
const PtrList<labelIOList>& boundaryProcAddressing
);
// Member Functions
//- Reconstruct area field
template<class Type>
tmp<GeometricField<Type, faPatchField, areaMesh> >
reconstructFaAreaField
(
const IOobject& fieldIoObject
);
//- Reconstruct edge field
template<class Type>
tmp<GeometricField<Type, faePatchField, edgeMesh> >
reconstructFaEdgeField
(
const IOobject& fieldIoObject
);
//- Reconstruct and write all area fields
template<class Type>
void reconstructFaAreaFields
(
const IOobjectList& objects
);
//- Reconstruct and write all area fields
template<class Type>
void reconstructFaEdgeFields
(
const IOobjectList& objects
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "faFieldReconstructorReconstructFields.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,640 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "faFieldReconstructor.H"
#include "foamTime.H"
#include "PtrList.H"
#include "faPatchFields.H"
#include "emptyFaPatch.H"
#include "emptyFaPatchField.H"
#include "emptyFaePatchField.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::faPatchField, Foam::areaMesh> >
Foam::faFieldReconstructor::reconstructFaAreaField
(
const IOobject& fieldIoObject
)
{
// Read the field for all the processors
PtrList<GeometricField<Type, faPatchField, areaMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
procFields.set
(
procI,
new GeometricField<Type, faPatchField, areaMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI].time().timeName(),
procMeshes_[procI](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
// Create the internalField
Field<Type> internalField(mesh_.nFaces());
// Create the patch fields
PtrList<faPatchField<Type> > patchFields(mesh_.boundary().size());
// Create global mesh patchs starts
labelList gStarts(mesh_.boundary().size(), -1);
if (mesh_.boundary().size() > 0)
{
gStarts[0] = mesh_.nInternalEdges();
}
for(label i=1; i<mesh_.boundary().size(); i++)
{
gStarts[i] = gStarts[i-1] + mesh_.boundary()[i-1].labelList::size();
}
forAll (procMeshes_, procI)
{
const GeometricField<Type, faPatchField, areaMesh>& procField =
procFields[procI];
// Set the face values in the reconstructed field
internalField.rmap
(
procField.internalField(),
faceProcAddressing_[procI]
);
// Set the boundary patch values in the reconstructed field
labelList starts(procMeshes_[procI].boundary().size(), -1);
if(procMeshes_[procI].boundary().size() > 0)
{
starts[0] = procMeshes_[procI].nInternalEdges();
}
for(label i=1; i<procMeshes_[procI].boundary().size(); i++)
{
starts[i] =
starts[i-1]
+ procMeshes_[procI].boundary()[i-1].labelList::size();
}
forAll(boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Get addressing slice for this patch
// const labelList::subList cp =
// procMeshes_[procI].boundary()[patchI].patchSlice
// (
// edgeProcAddressing_[procI]
// );
const labelList::subList cp =
labelList::subList
(
edgeProcAddressing_[procI],
procMeshes_[procI].boundary()[patchI].size(),
starts[patchI]
);
// check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
// Regular patch. Fast looping
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
faPatchField<Type>::New
(
procField.boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, areaMesh>::null(),
faPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procField.boundaryField()[patchI].size()
)
)
);
}
const label curPatchStart = gStarts[curBPatch];
// mesh_.boundary()[curBPatch].start();
labelList reverseAddressing(cp.size());
forAll(cp, edgeI)
{
// Subtract one to take into account offsets for
// face direction.
// reverseAddressing[edgeI] = cp[edgeI] - 1 - curPatchStart;
reverseAddressing[edgeI] = cp[edgeI] - curPatchStart;
}
patchFields[curBPatch].rmap
(
procField.boundaryField()[patchI],
reverseAddressing
);
}
else
{
const Field<Type>& curProcPatch =
procField.boundaryField()[patchI];
// In processor patches, there's a mix of internal faces (some
// of them turned) and possible cyclics. Slow loop
forAll(cp, edgeI)
{
// Subtract one to take into account offsets for
// face direction.
// label curE = cp[edgeI] - 1;
label curE = cp[edgeI];
// Is the face on the boundary?
if (curE >= mesh_.nInternalEdges())
{
// label curBPatch = mesh_.boundary().whichPatch(curE);
label curBPatch = -1;
forAll (mesh_.boundary(), pI)
{
if
(
curE >= gStarts[pI]
&& curE <
(
gStarts[pI]
+ mesh_.boundary()[pI].labelList::size()
)
)
{
curBPatch = pI;
}
}
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
faPatchField<Type>::New
(
mesh_.boundary()[curBPatch].type(),
mesh_.boundary()[curBPatch],
DimensionedField<Type, areaMesh>::null()
)
);
}
// add the edge
// label curPatchEdge =
// mesh_.boundary()
// [curBPatch].whichEdge(curE);
label curPatchEdge = curE - gStarts[curBPatch];
patchFields[curBPatch][curPatchEdge] =
curProcPatch[edgeI];
}
}
}
}
}
forAll(mesh_.boundary(), patchI)
{
// add empty patches
if
(
typeid(mesh_.boundary()[patchI]) == typeid(emptyFaPatch)
&& !patchFields(patchI)
)
{
patchFields.set
(
patchI,
faPatchField<Type>::New
(
emptyFaPatchField<Type>::typeName,
mesh_.boundary()[patchI],
DimensionedField<Type, areaMesh>::null()
)
);
}
}
// Now construct and write the field
// setting the internalField and patchFields
return tmp<GeometricField<Type, faPatchField, areaMesh> >
(
new GeometricField<Type, faPatchField, areaMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[0].dimensions(),
internalField,
patchFields
)
);
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::faePatchField, Foam::edgeMesh> >
Foam::faFieldReconstructor::reconstructFaEdgeField
(
const IOobject& fieldIoObject
)
{
// Read the field for all the processors
PtrList<GeometricField<Type, faePatchField, edgeMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
procFields.set
(
procI,
new GeometricField<Type, faePatchField, edgeMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI].time().timeName(),
procMeshes_[procI](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
// Create the internalField
Field<Type> internalField(mesh_.nInternalEdges());
// Create the patch fields
PtrList<faePatchField<Type> > patchFields(mesh_.boundary().size());
labelList gStarts(mesh_.boundary().size(), -1);
if(mesh_.boundary().size() > 0)
{
gStarts[0] = mesh_.nInternalEdges();
}
for(label i=1; i<mesh_.boundary().size(); i++)
{
gStarts[i] = gStarts[i-1] + mesh_.boundary()[i-1].labelList::size();
}
forAll (procMeshes_, procI)
{
const GeometricField<Type, faePatchField, edgeMesh>& procField =
procFields[procI];
// Set the face values in the reconstructed field
// It is necessary to create a copy of the addressing array to
// take care of the face direction offset trick.
//
{
labelList curAddr(edgeProcAddressing_[procI]);
// forAll (curAddr, addrI)
// {
// curAddr[addrI] -= 1;
// }
internalField.rmap
(
procField.internalField(),
curAddr
);
}
// Set the boundary patch values in the reconstructed field
labelList starts(procMeshes_[procI].boundary().size(), -1);
if(procMeshes_[procI].boundary().size() > 0)
{
starts[0] = procMeshes_[procI].nInternalEdges();
}
for(label i=1; i<procMeshes_[procI].boundary().size(); i++)
{
starts[i] =
starts[i-1]
+ procMeshes_[procI].boundary()[i-1].labelList::size();
}
forAll(boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Get addressing slice for this patch
// const labelList::subList cp =
// procMeshes_[procI].boundary()[patchI].patchSlice
// (
// faceProcAddressing_[procI]
// );
const labelList::subList cp =
labelList::subList
(
edgeProcAddressing_[procI],
procMeshes_[procI].boundary()[patchI].size(),
starts[patchI]
);
// check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
// Regular patch. Fast looping
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
faePatchField<Type>::New
(
procField.boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, edgeMesh>::null(),
faPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procField.boundaryField()[patchI].size()
)
)
);
}
const label curPatchStart = gStarts[curBPatch];
// mesh_.boundary()[curBPatch].start();
labelList reverseAddressing(cp.size());
forAll(cp, edgeI)
{
// Subtract one to take into account offsets for
// face direction.
// reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart;
reverseAddressing[edgeI] = cp[edgeI] - curPatchStart;
}
patchFields[curBPatch].rmap
(
procField.boundaryField()[patchI],
reverseAddressing
);
}
else
{
const Field<Type>& curProcPatch =
procField.boundaryField()[patchI];
// In processor patches, there's a mix of internal faces (some
// of them turned) and possible cyclics. Slow loop
forAll(cp, edgeI)
{
// label curF = cp[edgeI] - 1;
label curE = cp[edgeI];
// Is the face turned the right side round
if (curE >= 0)
{
// Is the face on the boundary?
if (curE >= mesh_.nInternalEdges())
{
// label curBPatch =
// mesh_.boundary().whichPatch(curF);
label curBPatch = -1;
forAll (mesh_.boundary(), pI)
{
if
(
curE >= gStarts[pI]
&& curE <
(
gStarts[pI]
+ mesh_.boundary()[pI].labelList::size()
)
)
{
curBPatch = pI;
}
}
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
faePatchField<Type>::New
(
mesh_.boundary()[curBPatch].type(),
mesh_.boundary()[curBPatch],
DimensionedField<Type, edgeMesh>
::null()
)
);
}
// add the face
// label curPatchFace =
// mesh_.boundary()
// [curBPatch].whichEdge(curF);
label curPatchEdge = curE - gStarts[curBPatch];
patchFields[curBPatch][curPatchEdge] =
curProcPatch[edgeI];
}
else
{
// Internal face
internalField[curE] = curProcPatch[edgeI];
}
}
}
}
}
}
forAll(mesh_.boundary(), patchI)
{
// add empty patches
if
(
typeid(mesh_.boundary()[patchI]) == typeid(emptyFaPatch)
&& !patchFields(patchI)
)
{
patchFields.set
(
patchI,
faePatchField<Type>::New
(
emptyFaePatchField<Type>::typeName,
mesh_.boundary()[patchI],
DimensionedField<Type, edgeMesh>::null()
)
);
}
}
// Now construct and write the field
// setting the internalField and patchFields
return tmp<GeometricField<Type, faePatchField, edgeMesh> >
(
new GeometricField<Type, faePatchField, edgeMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[0].dimensions(),
internalField,
patchFields
)
);
}
// Reconstruct and write all area fields
template<class Type>
void Foam::faFieldReconstructor::reconstructFaAreaFields
(
const IOobjectList& objects
)
{
const word& fieldClassName =
GeometricField<Type, faPatchField, areaMesh>::typeName;
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
for
(
IOobjectList::const_iterator fieldIter = fields.begin();
fieldIter != fields.end();
++fieldIter
)
{
Info << " " << fieldIter()->name() << endl;
reconstructFaAreaField<Type>(*fieldIter())().write();
}
Info<< endl;
}
}
// Reconstruct and write all edge fields
template<class Type>
void Foam::faFieldReconstructor::reconstructFaEdgeFields
(
const IOobjectList& objects
)
{
const word& fieldClassName =
GeometricField<Type, faePatchField, edgeMesh>::typeName;
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
for
(
IOobjectList::const_iterator fieldIter = fields.begin();
fieldIter != fields.end();
++fieldIter
)
{
Info<< " " << fieldIter()->name() << endl;
reconstructFaEdgeField<Type>(*fieldIter())().write();
}
Info<< endl;
}
}
// ************************************************************************* //

View file

@ -1,526 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "fvFieldReconstructor.H"
#include "foamTime.H"
#include "PtrList.H"
#include "fvPatchFields.H"
#include "emptyFvPatch.H"
#include "emptyFvPatchField.H"
#include "emptyFvsPatchField.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::fvFieldReconstructor::reconstructFvVolumeField
(
const IOobject& fieldIoObject
)
{
// Read the field for all the processors
PtrList<GeometricField<Type, fvPatchField, volMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
procFields.set
(
procI,
new GeometricField<Type, fvPatchField, volMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI].time().timeName(),
procMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
// Create the internalField
Field<Type> internalField(mesh_.nCells());
// Create the patch fields
PtrList<fvPatchField<Type> > patchFields(mesh_.boundary().size());
forAll (procMeshes_, procI)
{
const GeometricField<Type, fvPatchField, volMesh>& procField =
procFields[procI];
// Set the cell values in the reconstructed field
internalField.rmap
(
procField.internalField(),
cellProcAddressing_[procI]
);
// Set the boundary patch values in the reconstructed field
forAll (boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Get addressing slice for this patch
const labelList::subList cp =
procMeshes_[procI].boundary()[patchI].patchSlice
(
faceProcAddressing_[procI]
);
// check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
// Regular patch. Fast looping
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
fvPatchField<Type>::New
(
procField.boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, volMesh>::null(),
fvPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procField.boundaryField()[patchI].size()
)
)
);
}
const label curPatchStart =
mesh_.boundaryMesh()[curBPatch].start();
labelList reverseAddressing(cp.size());
forAll (cp, faceI)
{
// Subtract one to take into account offsets for
// face direction.
reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart;
}
patchFields[curBPatch].rmap
(
procField.boundaryField()[patchI],
reverseAddressing
);
}
else
{
const Field<Type>& curProcPatch =
procField.boundaryField()[patchI];
// In processor patches, there's a mix of internal faces (some
// of them turned) and possible cyclics. Slow loop
forAll (cp, faceI)
{
// Subtract one to take into account offsets for
// face direction.
label curF = cp[faceI] - 1;
// Is the face on the boundary?
if (curF >= mesh_.nInternalFaces())
{
label curBPatch =
mesh_.boundaryMesh().whichPatch(curF);
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
fvPatchField<Type>::New
(
mesh_.boundary()[curBPatch].type(),
mesh_.boundary()[curBPatch],
DimensionedField<Type, volMesh>::null()
)
);
}
// add the face
label curPatchFace =
mesh_.boundaryMesh()
[curBPatch].whichFace(curF);
patchFields[curBPatch][curPatchFace] =
curProcPatch[faceI];
}
}
}
}
}
forAll (mesh_.boundary(), patchI)
{
// add empty patches
if
(
isType<emptyFvPatch>(mesh_.boundary()[patchI])
&& !patchFields(patchI)
)
{
patchFields.set
(
patchI,
fvPatchField<Type>::New
(
emptyFvPatchField<Type>::typeName,
mesh_.boundary()[patchI],
DimensionedField<Type, volMesh>::null()
)
);
}
}
// Now construct and write the field
// setting the internalField and patchFields
return tmp<GeometricField<Type, fvPatchField, volMesh> >
(
new GeometricField<Type, fvPatchField, volMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[0].dimensions(),
internalField,
patchFields
)
);
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
Foam::fvFieldReconstructor::reconstructFvSurfaceField
(
const IOobject& fieldIoObject
)
{
// Read the field for all the processors
PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
procFields.set
(
procI,
new GeometricField<Type, fvsPatchField, surfaceMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI].time().timeName(),
procMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
// Create the internalField
Field<Type> internalField(mesh_.nInternalFaces());
// Create the patch fields
PtrList<fvsPatchField<Type> > patchFields(mesh_.boundary().size());
forAll (procMeshes_, procI)
{
const GeometricField<Type, fvsPatchField, surfaceMesh>& procField =
procFields[procI];
// Set the face values in the reconstructed field
// It is necessary to create a copy of the addressing array to
// take care of the face direction offset trick.
//
{
labelList curAddr(faceProcAddressing_[procI]);
forAll (curAddr, addrI)
{
curAddr[addrI] -= 1;
}
internalField.rmap
(
procField.internalField(),
curAddr
);
}
// Set the boundary patch values in the reconstructed field
forAll (boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Get addressing slice for this patch
const labelList::subList cp =
procMeshes_[procI].boundary()[patchI].patchSlice
(
faceProcAddressing_[procI]
);
// Check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
// Regular patch. Fast looping
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
fvsPatchField<Type>::New
(
procField.boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, surfaceMesh>::null(),
fvPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procField.boundaryField()[patchI].size()
)
)
);
}
const label curPatchStart =
mesh_.boundaryMesh()[curBPatch].start();
labelList reverseAddressing(cp.size());
forAll (cp, faceI)
{
// Subtract one to take into account offsets for
// face direction.
reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart;
}
patchFields[curBPatch].rmap
(
procField.boundaryField()[patchI],
reverseAddressing
);
}
else
{
const Field<Type>& curProcPatch =
procField.boundaryField()[patchI];
// In processor patches, there's a mix of internal faces (some
// of them turned) and possible cyclics. Slow loop
forAll (cp, faceI)
{
label curF = cp[faceI] - 1;
// Is the face turned the right side round
if (curF >= 0)
{
// Is the face on the boundary?
if (curF >= mesh_.nInternalFaces())
{
label curBPatch =
mesh_.boundaryMesh().whichPatch(curF);
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
fvsPatchField<Type>::New
(
mesh_.boundary()[curBPatch].type(),
mesh_.boundary()[curBPatch],
DimensionedField<Type, surfaceMesh>
::null()
)
);
}
// add the face
label curPatchFace =
mesh_.boundaryMesh()
[curBPatch].whichFace(curF);
patchFields[curBPatch][curPatchFace] =
curProcPatch[faceI];
}
else
{
// Internal face
internalField[curF] = curProcPatch[faceI];
}
}
}
}
}
}
forAll (mesh_.boundary(), patchI)
{
// add empty patches
if
(
isType<emptyFvPatch>(mesh_.boundary()[patchI])
&& !patchFields(patchI)
)
{
patchFields.set
(
patchI,
fvsPatchField<Type>::New
(
emptyFvsPatchField<Type>::typeName,
mesh_.boundary()[patchI],
DimensionedField<Type, surfaceMesh>::null()
)
);
}
}
// Now construct and write the field
// setting the internalField and patchFields
return tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
(
new GeometricField<Type, fvsPatchField, surfaceMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[0].dimensions(),
internalField,
patchFields
)
);
}
// Reconstruct and write all/selected volume fields
template<class Type>
void Foam::fvFieldReconstructor::reconstructFvVolumeFields
(
const IOobjectList& objects,
const HashSet<word>& selectedFields
)
{
const word& fieldClassName =
GeometricField<Type, fvPatchField, volMesh>::typeName;
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
forAllConstIter(IOobjectList, fields, fieldIter)
{
if
(
!selectedFields.size()
|| selectedFields.found(fieldIter()->name())
)
{
Info<< " " << fieldIter()->name() << endl;
reconstructFvVolumeField<Type>(*fieldIter())().write();
}
}
Info<< endl;
}
}
// Reconstruct and write all/selected surface fields
template<class Type>
void Foam::fvFieldReconstructor::reconstructFvSurfaceFields
(
const IOobjectList& objects,
const HashSet<word>& selectedFields
)
{
const word& fieldClassName =
GeometricField<Type, fvsPatchField, surfaceMesh>::typeName;
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
forAllConstIter(IOobjectList, fields, fieldIter)
{
if
(
!selectedFields.size()
|| selectedFields.found(fieldIter()->name())
)
{
Info<< " " << fieldIter()->name() << endl;
reconstructFvSurfaceField<Type>(*fieldIter())().write();
}
}
Info<< endl;
}
}
// ************************************************************************* //

View file

@ -1,104 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "pointFieldReconstructor.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::pointFieldReconstructor::pointFieldReconstructor
(
const pointMesh& mesh,
const PtrList<pointMesh>& procMeshes,
const PtrList<labelIOList>& pointProcAddressing,
const PtrList<labelIOList>& boundaryProcAddressing
)
:
mesh_(mesh),
procMeshes_(procMeshes),
pointProcAddressing_(pointProcAddressing),
boundaryProcAddressing_(boundaryProcAddressing),
patchPointAddressing_(procMeshes.size())
{
// Inverse-addressing of the patch point labels.
labelList pointMap(mesh_.size(), -1);
// Create the pointPatch addressing
forAll(procMeshes_, proci)
{
const pointMesh& procMesh = procMeshes_[proci];
patchPointAddressing_[proci].setSize(procMesh.boundary().size());
forAll(procMesh.boundary(), patchi)
{
if (boundaryProcAddressing_[proci][patchi] >= 0)
{
labelList& procPatchAddr = patchPointAddressing_[proci][patchi];
procPatchAddr.setSize(procMesh.boundary()[patchi].size(), -1);
const labelList& patchPointLabels =
mesh_.boundary()[boundaryProcAddressing_[proci][patchi]]
.meshPoints();
// Create the inverse-addressing of the patch point labels.
forAll (patchPointLabels, pointi)
{
pointMap[patchPointLabels[pointi]] = pointi;
}
const labelList& procPatchPoints =
procMesh.boundary()[patchi].meshPoints();
forAll (procPatchPoints, pointi)
{
procPatchAddr[pointi] =
pointMap
[
pointProcAddressing_[proci][procPatchPoints[pointi]]
];
}
if (procPatchAddr.size() && min(procPatchAddr) < 0)
{
FatalErrorIn
(
"pointFieldReconstructor::pointFieldReconstructor"
"(\n"
" const pointMesh& mesh,\n"
" const PtrList<pointMesh>& procMeshes,\n"
" const PtrList<labelIOList>& pointProcAddressing,\n"
" const PtrList<labelIOList>& "
"boundaryProcAddressing\n"
")"
) << "Incomplete patch point addressing"
<< abort(FatalError);
}
}
}
}
}
// ************************************************************************* //

View file

@ -1,178 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "pointFieldReconstructor.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh> >
Foam::pointFieldReconstructor::reconstructField(const IOobject& fieldIoObject)
{
// Read the field for all the processors
PtrList<GeometricField<Type, pointPatchField, pointMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, proci)
{
procFields.set
(
proci,
new GeometricField<Type, pointPatchField, pointMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[proci]().time().timeName(),
procMeshes_[proci](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[proci]
)
);
}
// Create the internalField
Field<Type> internalField(mesh_.size());
// Create the patch fields
PtrList<pointPatchField<Type> > patchFields(mesh_.boundary().size());
forAll (procMeshes_, proci)
{
const GeometricField<Type, pointPatchField, pointMesh>&
procField = procFields[proci];
// Get processor-to-global addressing for use in rmap
const labelList& procToGlobalAddr = pointProcAddressing_[proci];
// Set the cell values in the reconstructed field
internalField.rmap
(
procField.internalField(),
procToGlobalAddr
);
// Set the boundary patch values in the reconstructed field
forAll(boundaryProcAddressing_[proci], patchi)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[proci][patchi];
// check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
pointPatchField<Type>::New
(
procField.boundaryField()[patchi],
mesh_.boundary()[curBPatch],
DimensionedField<Type, pointMesh>::null(),
pointPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procField.boundaryField()[patchi].size()
)
)
);
}
patchFields[curBPatch].rmap
(
procField.boundaryField()[patchi],
patchPointAddressing_[proci][patchi]
);
}
}
}
// Construct and write the field
// setting the internalField and patchFields
return tmp<GeometricField<Type, pointPatchField, pointMesh> >
(
new GeometricField<Type, pointPatchField, pointMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_().time().timeName(),
mesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[0].dimensions(),
internalField,
patchFields
)
);
}
// Reconstruct and write all point fields
template<class Type>
void Foam::pointFieldReconstructor::reconstructFields
(
const IOobjectList& objects
)
{
word fieldClassName
(
GeometricField<Type, pointPatchField, pointMesh>::typeName
);
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
for
(
IOobjectList::iterator fieldIter = fields.begin();
fieldIter != fields.end();
++fieldIter
)
{
Info<< " " << fieldIter()->name() << endl;
reconstructField<Type>(*fieldIter())().write();
}
Info<< endl;
}
}
// ************************************************************************* //

View file

@ -1,258 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "processorFaMeshes.H"
#include "foamTime.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::processorFaMeshes::read()
{
forAll (fvMeshes_, procI)
{
meshes_.set
(
procI,
new faMesh(fvMeshes_[procI])
);
pointProcAddressing_.set
(
procI,
new labelIOList
(
IOobject
(
"pointProcAddressing",
meshes_[procI].time().findInstance
(
meshes_[procI].meshDir(),
"pointProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
edgeProcAddressing_.set
(
procI,
new labelIOList
(
IOobject
(
"edgeProcAddressing",
meshes_[procI].time().findInstance
(
meshes_[procI].meshDir(),
"edgeProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
faceProcAddressing_.set
(
procI,
new labelIOList
(
IOobject
(
"faceProcAddressing",
meshes_[procI].time().findInstance
(
meshes_[procI].meshDir(),
"faceProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
boundaryProcAddressing_.set
(
procI,
new labelIOList
(
IOobject
(
"boundaryProcAddressing",
meshes_[procI].time().findInstance
(
meshes_[procI].meshDir(),
"faceProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::processorFaMeshes::processorFaMeshes
(
const PtrList<fvMesh>& processorFvMeshes
)
:
fvMeshes_(processorFvMeshes),
meshes_(processorFvMeshes.size()),
pointProcAddressing_(processorFvMeshes.size()),
edgeProcAddressing_(processorFvMeshes.size()),
faceProcAddressing_(processorFvMeshes.size()),
boundaryProcAddressing_(processorFvMeshes.size())
{
read();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Foam::fvMesh::readUpdateState Foam::processorFaMeshes::readUpdate()
// {
// fvMesh::readUpdateState stat = fvMesh::UNCHANGED;
// forAll (databases_, procI)
// {
// // Check if any new meshes need to be read.
// fvMesh::readUpdateState procStat = meshes_[procI].readUpdate();
// /*
// if (procStat != fvMesh::UNCHANGED)
// {
// Info<< "Processor " << procI
// << " at time " << databases_[procI].timeName()
// << " detected mesh change " << procStat
// << endl;
// }
// */
// // Combine into overall mesh change status
// if (stat == fvMesh::UNCHANGED)
// {
// stat = procStat;
// }
// else
// {
// if (stat != procStat)
// {
// FatalErrorIn("processorFaMeshes::readUpdate()")
// << "Processor " << procI
// << " has a different polyMesh at time "
// << databases_[procI].timeName()
// << " compared to any previous processors." << nl
// << "Please check time " << databases_[procI].timeName()
// << " directories on all processors for consistent"
// << " mesh files."
// << exit(FatalError);
// }
// }
// }
// if
// (
// stat == fvMesh::TOPO_CHANGE
// || stat == fvMesh::TOPO_PATCH_CHANGE
// )
// {
// // Reread all meshes and addresssing
// read();
// }
// return stat;
// }
// void Foam::processorFaMeshes::reconstructPoints(fvMesh& mesh)
// {
// // Read the field for all the processors
// PtrList<pointIOField> procsPoints(meshes_.size());
// forAll (meshes_, procI)
// {
// procsPoints.set
// (
// procI,
// new pointIOField
// (
// IOobject
// (
// "points",
// meshes_[procI].time().timeName(),
// polyMesh::meshSubDir,
// meshes_[procI],
// IOobject::MUST_READ,
// IOobject::NO_WRITE
// )
// )
// );
// }
// // Create the new points
// vectorField newPoints(mesh.nPoints());
// forAll (meshes_, procI)
// {
// const vectorField& procPoints = procsPoints[procI];
// // Set the cell values in the reconstructed field
// const labelList& pointProcAddressingI = pointProcAddressing_[procI];
// if (pointProcAddressingI.size() != procPoints.size())
// {
// FatalErrorIn("processorFaMeshes")
// << "problem :"
// << " pointProcAddressingI:" << pointProcAddressingI.size()
// << " procPoints:" << procPoints.size()
// << abort(FatalError);
// }
// forAll(pointProcAddressingI, pointI)
// {
// newPoints[pointProcAddressingI[pointI]] = procPoints[pointI];
// }
// }
// mesh.movePoints(newPoints);
// mesh.write();
// }
// ************************************************************************* //

View file

@ -136,8 +136,13 @@ int main(int argc, char *argv[])
}
// Read all meshes and addressing to reconstructed mesh
processorMeshesReconstructor procMeshes(databases, regionName);
processorMeshesReconstructor procMeshes
(
databases,
regionName
);
// Get reconstructed mesh
autoPtr<fvMesh> meshPtr = procMeshes.reconstructMesh(runTime);
@ -629,7 +634,7 @@ int main(int argc, char *argv[])
faMesh aMesh(mesh);
processorFaMeshes procFaMeshes(procMeshes.meshes());
processorFaMeshes procFaMeshes(procMeshes.meshes(), true);
faFieldReconstructor faReconstructor
(

View file

@ -1,163 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "tetPointFieldReconstructor.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Calculate point addressing
labelList tetPointFieldReconstructor::procAddressing
(
const label procNo
) const
{
// Allocate the addressing
labelList addr(procMeshes_[procNo].nPoints(), -1);
const labelList& pointAddr = pointProcAddressing_[procNo];
const labelList& cellAddr = cellProcAddressing_[procNo];
label nAddr = 0;
// Insert point addressing
// Use only live points. HJ, 14/Apr/2009
for (label pointI = 0; pointI < procMeshes_[procNo]().nPoints(); pointI++)
{
addr[nAddr] = pointAddr[pointI];
nAddr++;
}
// Insert face addressing. Only for face decomposition
const labelList& faceAddr = faceProcAddressing_[procNo];
const label faceOffset = mesh_.faceOffset();
// Use only live faces. HJ, 14/Apr/2009
for (label faceI = 0; faceI < procMeshes_[procNo]().nFaces(); faceI++)
{
// Remember to decrement the index by one (turning index)
addr[nAddr] = faceOffset + mag(faceAddr[faceI]) - 1;
nAddr++;
}
// Insert cell addressing
const label cellOffset = mesh_.cellOffset();
forAll (cellAddr, cellI)
{
addr[nAddr] = cellOffset + cellAddr[cellI];
nAddr++;
}
return addr;
}
labelList tetPointFieldReconstructor::procPatchAddressing
(
const labelList& procToGlobalAddr,
const label procNo,
const label patchNo
) const
{
labelList addr(procMeshes_[procNo].boundary()[patchNo].size(), -1);
// Algorithm:
// Go to the global patch, create a lookup list the size of all
// points in the mesh and then gather the points for the current
// patch.
labelList pointLookup(mesh_.nPoints(), -1);
const labelList& globalPatchPoints =
mesh_.boundary()[boundaryProcAddressing_[procNo][patchNo]].meshPoints();
forAll (globalPatchPoints, pointI)
{
pointLookup[globalPatchPoints[pointI]] = pointI;
}
// Gather the information
const labelList& procPatchPoints =
procMeshes_[procNo].boundary()[patchNo].meshPoints();
forAll (procPatchPoints, pointI)
{
addr[pointI] =
pointLookup[procToGlobalAddr[procPatchPoints[pointI]]];
}
if (addr.size() && min(addr) < 0)
{
FatalErrorIn
(
"labelList tetPointFieldReconstructor::"
"patchProcAddressing\n"
"(\n"
" const labelList& procToGlobalAddr,\n"
" const label procNo,\n"
" const label patchNo\n"
") const"
) << "error in addressing"
<< abort(FatalError);
}
return addr;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
tetPointFieldReconstructor::tetPointFieldReconstructor
(
tetPolyMesh& mesh,
const PtrList<tetPolyMesh>& procMeshes,
const PtrList<labelIOList>& pointProcAddressing,
const PtrList<labelIOList>& faceProcAddressing,
const PtrList<labelIOList>& cellProcAddressing,
const PtrList<labelIOList>& boundaryProcAddressing
)
:
mesh_(mesh),
procMeshes_(procMeshes),
pointProcAddressing_(pointProcAddressing),
faceProcAddressing_(faceProcAddressing),
cellProcAddressing_(cellProcAddressing),
boundaryProcAddressing_(boundaryProcAddressing)
{}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -1,217 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
tetPointFieldReconstructor
Description
Tet point field reconstructor.
SourceFiles
tetPointFieldReconstructor.C
\*---------------------------------------------------------------------------*/
#ifndef tetPointFieldReconstructor_H
#define tetPointFieldReconstructor_H
#include "PtrList.H"
#include "objectRegistry.H"
#include "foamTime.H"
#include "tetPolyMesh.H"
#include "tetPointMesh.H"
#include "elementMesh.H"
#include "IOobjectList.H"
#include "tetPolyPatchFields.H"
#include "elementPatchFields.H"
#include "PointPatchFieldMapper.H"
#include "GeometricField.H"
#include "labelIOList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class tetPointFieldReconstructor Declaration
\*---------------------------------------------------------------------------*/
class tetPointFieldReconstructor
{
// Private data
//- Reconstructed mesh reference
const tetPolyMesh& mesh_;
//- List of processor meshes
const PtrList<tetPolyMesh>& procMeshes_;
//- List of processor point addressing lists
const PtrList<labelIOList>& pointProcAddressing_;
//- List of processor face addressing lists
const PtrList<labelIOList>& faceProcAddressing_;
//- List of processor cell addressing lists
const PtrList<labelIOList>& cellProcAddressing_;
//- List of processor boundary addressing lists
const PtrList<labelIOList>& boundaryProcAddressing_;
// Private Member Functions
//- Disallow default bitwise copy construct
tetPointFieldReconstructor
(
const tetPointFieldReconstructor&
);
//- Disallow default bitwise assignment
void operator=(const tetPointFieldReconstructor&);
//- Processor-to-global addressing for all points
labelList procAddressing(const label procNo) const;
//- Patch-to-patch addressing
labelList procPatchAddressing
(
const labelList& procToGlobalAddr,
const label procNo,
const label patchNo
) const;
public:
class tetPolyPatchFieldReconstructor
:
public PointPatchFieldMapper
{
label size_;
label sizeBeforeMapping_;
public:
// Constructors
//- Construct given addressing
tetPolyPatchFieldReconstructor
(
const label size,
const label sizeBeforeMapping
)
:
size_(size),
sizeBeforeMapping_(sizeBeforeMapping)
{}
// Member functions
virtual label size() const
{
return size_;
}
virtual label sizeBeforeMapping() const
{
return sizeBeforeMapping_;
}
virtual bool direct() const
{
return true;
}
virtual const unallocLabelList& directAddressing() const
{
return unallocLabelList::null();
}
};
// Constructors
//- Construct from components
tetPointFieldReconstructor
(
tetPolyMesh& mesh,
const PtrList<tetPolyMesh>& procMeshes,
const PtrList<labelIOList>& pointProcAddressing,
const PtrList<labelIOList>& faceProcAddressing,
const PtrList<labelIOList>& cellProcAddressing,
const PtrList<labelIOList>& boundaryProcAddressing
);
// Member Functions
//- Reconstruct point field
template<class Type>
tmp<GeometricField<Type, tetPolyPatchField, tetPointMesh> >
reconstructTetPointField
(
const IOobject& fieldIoObject
);
//- Reconstruct element field
template<class Type>
tmp<GeometricField<Type, elementPatchField, elementMesh> >
reconstructElementField
(
const IOobject& fieldIoObject
);
//- Reconstruct and write all point fields
template<class Type>
void reconstructTetPointFields
(
const IOobjectList& objects
);
//- Reconstruct and write all element fields
template<class Type>
void reconstructElementFields
(
const IOobjectList& objects
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "tetPointFieldReconstructorReconstructFields.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -1,372 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "tetPointFieldReconstructor.H"
#include "PtrList.H"
#include "tetPolyPatchFields.H"
#include "tetFemMatrices.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
tmp<GeometricField<Type, tetPolyPatchField, tetPointMesh> >
tetPointFieldReconstructor::reconstructTetPointField
(
const IOobject& fieldIoObject
)
{
// Read the field for all the processors
PtrList<GeometricField<Type, tetPolyPatchField, tetPointMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
procFields.set
(
procI,
new GeometricField<Type, tetPolyPatchField, tetPointMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI]().time().timeName(),
procMeshes_[procI](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
// Create the internalField
Field<Type> internalField(mesh_.nPoints());
// Create the patch fields
PtrList<tetPolyPatchField<Type> > patchFields(mesh_.boundary().size());
forAll (procMeshes_, procI)
{
const GeometricField<Type, tetPolyPatchField, tetPointMesh>&
procField = procFields[procI];
// Get processor-to-global addressing for use in rmap
labelList procToGlobalAddr = procAddressing(procI);
// Set the cell values in the reconstructed field
internalField.rmap
(
procField.internalField(),
procToGlobalAddr
);
// Set the boundary patch values in the reconstructed field
forAll(boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
tetPolyPatchField<Type>::New
(
procField.boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, tetPointMesh>::null(),
tetPolyPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procField.boundaryField()[patchI].size()
)
)
);
}
// If the field stores values, do the rmap
if (patchFields[curBPatch].storesFieldData())
{
patchFields[curBPatch].rmap
(
procField.boundaryField()[patchI],
procPatchAddressing
(
procToGlobalAddr,
procI,
patchI
)
);
}
}
}
}
// Now construct and write the field
// setting the internalField and patchFields
return tmp<GeometricField<Type, tetPolyPatchField, tetPointMesh> >
(
new GeometricField<Type, tetPolyPatchField, tetPointMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_().time().timeName(),
mesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[0].dimensions(),
internalField,
patchFields
)
);
}
template<class Type>
tmp<GeometricField<Type, elementPatchField, elementMesh> >
tetPointFieldReconstructor::reconstructElementField
(
const IOobject& fieldIoObject
)
{
// Read the field for all the processors
PtrList<GeometricField<Type, elementPatchField, elementMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
procFields.set
(
procI,
new GeometricField<Type, elementPatchField, elementMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI]().time().timeName(),
procMeshes_[procI](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
// Create the internalField
Field<Type> internalField(mesh_.nCells());
// Create the patch fields
PtrList<elementPatchField<Type> > patchFields(mesh_.boundary().size());
forAll (procMeshes_, procI)
{
const GeometricField<Type, elementPatchField, elementMesh>&
procField = procFields[procI];
// Set the cell values in the reconstructed field
internalField.rmap
(
procField.internalField(),
cellProcAddressing_[procI]
);
// Set the boundary patch values in the reconstructed field
forAll(boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Get addressing slice for this patch
const labelList::subList cp =
procMeshes_[procI]().boundaryMesh()[patchI].patchSlice
(
faceProcAddressing_[procI]
);
// check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
elementPatchField<Type>::New
(
procField.boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, elementMesh>::null(),
tetPolyPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procField.boundaryField()[patchI].size()
)
)
);
}
// If the field stores values, do the rmap
if (patchFields[curBPatch].storesFieldData())
{
const label curPatchStart =
mesh_().boundaryMesh()[curBPatch].start();
labelList reverseAddressing(cp.size());
forAll(cp, faceI)
{
// Subtract one to take into account offsets for
// face direction.
reverseAddressing[faceI] = cp[faceI] - 1
- curPatchStart;
}
patchFields[curBPatch].rmap
(
procField.boundaryField()[patchI],
reverseAddressing
);
}
}
}
}
// Now construct and write the field
// setting the internalField and patchFields
return tmp<GeometricField<Type, elementPatchField, elementMesh> >
(
new GeometricField<Type, elementPatchField, elementMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_().time().timeName(),
mesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[0].dimensions(),
internalField,
patchFields
)
);
}
template<class Type>
void tetPointFieldReconstructor::reconstructTetPointFields
(
const IOobjectList& objects
)
{
word fieldClassName
(
GeometricField<Type, tetPolyPatchField, tetPointMesh>::typeName
);
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
for
(
IOobjectList::iterator fieldIter = fields.begin();
fieldIter != fields.end();
++fieldIter
)
{
Info<< " " << fieldIter()->name() << endl;
reconstructTetPointField<Type>(*fieldIter())().write();
}
Info<< endl;
}
}
template<class Type>
void tetPointFieldReconstructor::reconstructElementFields
(
const IOobjectList& objects
)
{
word fieldClassName
(
GeometricField<Type, elementPatchField, elementMesh>::typeName
);
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
for
(
IOobjectList::iterator fieldIter = fields.begin();
fieldIter != fields.end();
++fieldIter
)
{
Info<< " " << fieldIter()->name() << endl;
reconstructElementField<Type>(*fieldIter())().write();
}
Info<< endl;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -2,6 +2,8 @@
cd ${0%/*} || exit 1 # run from this directory
set -x
wmake libso decomposeReconstruct
wmakeLnInclude decompositionMethods
wmake libso decompositionMethods

View file

@ -2,6 +2,8 @@
cd ${0%/*} || exit 1 # run from this directory
set -x
wmakeLnInclude decomposeReconstruct
wmakeLnInclude decompositionMethods
wmakeLnInclude metisDecomp
wmakeLnInclude parMetisDecomp

View file

@ -0,0 +1,27 @@
passivePatches/passiveProcessorPolyPatch/passiveProcessorPolyPatch.C
passivePatches/passiveProcessorFvPatch/passiveProcessorFvPatch.C
passivePatchFields/passiveFvPatchFields/passiveProcessor/passiveProcessorFvPatchFields.C
passivePatchFields/passiveFvsPatchFields/passiveProcessor/passiveProcessorFvsPatchFields.C
decomposeTools/finiteVolume/domainDecomposition.C
decomposeTools/finiteVolume/distributeCells.C
decomposeTools/finiteVolume/decomposeMesh.C
decomposeTools/finiteVolume/fvFieldDecomposer.C
decomposeTools/finiteArea/faMeshDecomposition.C
decomposeTools/finiteArea/faFieldDecomposer.C
decomposeTools/point/pointFieldDecomposer.C
decomposeTools/tetFiniteElement/tetPointFieldDecomposer.C
decomposeTools/lagrangian/lagrangianFieldDecomposer.C
reconstructTools/finiteVolume/sharedPoints.C
reconstructTools/finiteVolume/processorMeshesReconstructor.C
reconstructTools/finiteVolume/processorMeshesRebuild.C
reconstructTools/finiteVolume/fvFieldReconstructor.C
reconstructTools/finiteArea/processorFaMeshes.C
reconstructTools/finiteArea/faFieldReconstructor.C
reconstructTools/point/pointFieldReconstructor.C
reconstructTools/tetFiniteElement/tetPointFieldReconstructor.C
reconstructTools/lagrangian/reconstructLagrangianPositions.C
LIB = $(FOAM_LIBBIN)/libdecomposeReconstruct

View file

@ -0,0 +1,15 @@
EXE_INC = -std=c++11 \
-I$(LIB_SRC)/decompositionMethods/decompositionMethods/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/tetFiniteElement/lnInclude
LIB_LIBS = \
-ldecompositionMethods \
-lfiniteVolume \
-lmeshTools \
-lfiniteArea \
-llagrangian \
-ltetFiniteElement

View file

@ -36,11 +36,12 @@ Description
#include "boolList.H"
#include "cellList.H"
#include "primitiveMesh.H"
#include "processorPolyPatch.H"
#include "cyclicPolyPatch.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
void Foam::domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
{
// Decide which cell goes to which processor
distributeCells();
@ -50,13 +51,13 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
// calculate the addressing information for the original mesh
Info<< "\nCalculating original mesh data" << endl;
// set references to the original mesh
const polyBoundaryMesh& patches = boundaryMesh();
// Set references to the original mesh
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
// Access all faces to grab the zones
const faceList& fcs = allFaces();
const labelList& owner = faceOwner();
const labelList& neighbour = faceNeighbour();
const faceList& allFaces = mesh_.allFaces();
const labelList& owner = mesh_.faceOwner();
const labelList& neighbour = mesh_.faceNeighbour();
// loop through the list of processor labels for the cell and add the
// cell shape to the list of cells for the appropriate processor
@ -100,12 +101,12 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
{
List<SLList<label> > procFaceList(nProcs_);
forAll (neighbour, facei)
forAll (neighbour, faceI)
{
if (cellToProc_[owner[facei]] == cellToProc_[neighbour[facei]])
if (cellToProc_[owner[faceI]] == cellToProc_[neighbour[faceI]])
{
// Face internal to processor
procFaceList[cellToProc_[owner[facei]]].append(facei);
procFaceList[cellToProc_[owner[faceI]]].append(faceI);
}
}
@ -125,17 +126,168 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
List<SLList<label> > procPatchIndex(nProcs_);
forAll (neighbour, facei)
// Rewrite:
// Handling of coupled patches is changed. HJ, 11/Apr/2018
// Prepare collection of patch faces
// For all processors, set the size of start index and patch size
// lists to the number of patches in the mesh
forAll (procPatchSize_, procI)
{
if (cellToProc_[owner[facei]] != cellToProc_[neighbour[facei]])
procPatchSize_[procI].setSize(patches.size());
procPatchStartIndex_[procI].setSize(patches.size());
}
forAll (patches, patchI)
{
// Reset size for all processors
forAll (procPatchSize_, procI)
{
// inter - processor patch face found. Go through the list of
procPatchSize_[procI][patchI] = 0;
}
}
// Algorithm:
// When running the decomposition in parallel, it is assumed that
// the result will be used in dynamic load balancing
// For load balancing, the processor patches need to match in order for
// the patch-to-patch matching to work propely on mesh reconstruction
// Therefore, all processor patches need to be split into the matching
// and non-matching part be examining the cellToProc_ data on
// the neighbour side. This has been prepared in patchNbrCellToProc_
// HJ, 11/Apr/2018
// The correct order of dumping the faces is to dump the
// slave processor patches first, then internal faces and then
// master processor patches
// HJ, 23/Apr/2018
// Dump current processor patch faces into new processor patches
// that will be created in decomposition when running in parallel
forAll (patches, patchI)
{
// Check the processor patch for which neighbour data exists
if
(
isA<processorPolyPatch>(patches[patchI])
&& !patchNbrCellToProc_[patchI].empty()
)
{
const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(patches[patchI]);
// DO ONLY SLAVE SIDE
if (!procPatch.master())
{
// Get patch start
const label patchStart = patches[patchI].start();
// Get faceCells
const labelList& fc = patches[patchI].faceCells();
// Get neighbour cellToProc addressing across the interface
const labelList& curNbrPtc = patchNbrCellToProc_[patchI];
forAll (fc, patchFaceI)
{
// Local owner proc is looked up using faceCells
const label ownerProc = cellToProc_[fc[patchFaceI]];
// Neighbour proc is looked up directly
const label neighbourProc = curNbrPtc[patchFaceI];
// Check change in processor type across the processor
// boundary
// If ownerProc and neighbourProc are the same, the
// processor face will be merged, meaning that it
// remains in the (old) processor patch
// If ownerProc and neighbourProc are different,
// this will be a new processor boundary created from
// the existing processor face and added afterwards
if (ownerProc != neighbourProc)
{
// Search algorithm repeated in processor patches.
// HJ, 11/Apr/2018
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)
{
// Inter - processor boundary exists.
// Add the face
interProcBouFound = true;
// Add to owner only!
curInterProcBFacesOwnIter().append
(
patchStart + patchFaceI
);
}
if (interProcBouFound) break;
}
if (!interProcBouFound)
{
// inter - processor boundaries do not exist and
// need to be created
// set the new addressing information
// Add to owner only!
interProcBoundaries[ownerProc].append
(
neighbourProc
);
interProcBFaces[ownerProc].append
(
SLList<label>(patchStart + patchFaceI)
);
}
}
// Note: cannot insert regular faces here, because
// they are out of sequence.
// HJ, 24/Apr/2018
}
}
}
}
// Internal mesh faces
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]];
const label ownerProc = cellToProc_[owner[faceI]];
const label neighbourProc = cellToProc_[neighbour[faceI]];
// Search algorithm repeated in processor patches. Reconsider
// HJ, 11/Apr/2018
SLList<label>::iterator curInterProcBdrsOwnIter =
interProcBoundaries[ownerProc].begin();
@ -158,10 +310,10 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
{
if (curInterProcBdrsOwnIter() == neighbourProc)
{
// the inter - processor boundary exists. Add the face
// Inter - processor boundary exists. Add the face
interProcBouFound = true;
curInterProcBFacesOwnIter().append(facei);
curInterProcBFacesOwnIter().append(faceI);
SLList<label>::iterator curInterProcBdrsNeiIter =
interProcBoundaries[neighbourProc].begin();
@ -190,21 +342,25 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
// boundary found. Add the face
neighbourFound = true;
curInterProcBFacesNeiIter().append(facei);
curInterProcBFacesNeiIter().append(faceI);
}
if (neighbourFound) break;
}
if (interProcBouFound && !neighbourFound)
if (!neighbourFound)
{
FatalErrorIn
// Owner found (slave proc boundary), but neighbour
// not found: add it
interProcBoundaries[neighbourProc].append
(
"domainDecomposition::decomposeMesh()"
) << "Inconsistency in inter - "
<< "processor boundary lists for processors "
<< ownerProc << " and " << neighbourProc
<< abort(FatalError);
ownerProc
);
interProcBFaces[neighbourProc].append
(
SLList<label>(faceI)
);
}
}
@ -218,68 +374,191 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
// set the new addressing information
// owner
// Add owner side
interProcBoundaries[ownerProc].append(neighbourProc);
interProcBFaces[ownerProc].append(SLList<label>(facei));
interProcBFaces[ownerProc].append(SLList<label>(faceI));
// neighbour
// Add neighbour side
interProcBoundaries[neighbourProc].append(ownerProc);
interProcBFaces[neighbourProc].append
(
SLList<label>(facei)
SLList<label>(faceI)
);
}
}
}
// Dump current processor patch faces into new processor patches
// that will be created in decomposition when running in parallel
forAll (patches, patchI)
{
// Check the processor patch for which neighbour data exists
if
(
isA<processorPolyPatch>(patches[patchI])
&& !patchNbrCellToProc_[patchI].empty()
)
{
const processorPolyPatch& procPatch =
refCast<const processorPolyPatch>(patches[patchI]);
// DO ONLY MASTER SIDE
if (procPatch.master())
{
// Get patch start
const label patchStart = patches[patchI].start();
// Get faceCells
const labelList& fc = patches[patchI].faceCells();
// Get neighbour cellToProc addressing across the interface
const labelList& curNbrPtc = patchNbrCellToProc_[patchI];
forAll (fc, patchFaceI)
{
// Local owner proc is looked up using faceCells
const label ownerProc = cellToProc_[fc[patchFaceI]];
// Neighbour proc is looked up directly
const label neighbourProc = curNbrPtc[patchFaceI];
// Check change in processor type across the processor
// boundary
// If ownerProc and neighbourProc are the same, the
// processor face will be merged, meaning that it
// remains in the (old) processor patch
// If ownerProc and neighbourProc are different,
// this will be a new processor boundary created from
// the existing processor face and added afterwards
if (ownerProc != neighbourProc)
{
// Search algorithm repeated in processor patches.
// HJ, 11/Apr/2018
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)
{
// Inter - processor boundary exists.
// Add the face
interProcBouFound = true;
// Add to owner only!
curInterProcBFacesOwnIter().append
(
patchStart + patchFaceI
);
}
if (interProcBouFound) break;
}
if (!interProcBouFound)
{
// inter - processor boundaries do not exist and
// need to be created
// set the new addressing information
// Add to owner only!
interProcBoundaries[ownerProc].append
(
neighbourProc
);
interProcBFaces[ownerProc].append
(
SLList<label>(patchStart + patchFaceI)
);
}
}
// Note: cannot insert regular faces here, because
// they are out of sequence.
// HJ, 24/Apr/2018
}
}
}
}
// 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 (patches, patchI)
{
procPatchSize_[procI].setSize(patches.size());
procPatchStartIndex_[procI].setSize(patches.size());
}
forAll (patches, patchi)
{
// Reset size and start index for all processors
// New patch: record start index for all processors
forAll (procPatchSize_, procI)
{
procPatchSize_[procI][patchi] = 0;
procPatchStartIndex_[procI][patchi] =
procPatchStartIndex_[procI][patchI] =
procFaceList[procI].size();
}
const label patchStart = patches[patchi].start();
const label patchStart = patches[patchI].start();
if (!isA<cyclicPolyPatch>(patches[patchi]))
// Do normal patches. Note that processor patches
// have already been partially done and need special treatment
if
(
isA<processorPolyPatch>(patches[patchI])
&& !patchNbrCellToProc_[patchI].empty()
)
{
// Normal patch. Add faces to processor where the cell
// next to the face lives
// Only collect faces where the owner and neighbour processor
// index are the same.
// If owner and neighbour processor index are different,
// the face was already collected into a separate patch
// HJ, 23/Apr/2018
const unallocLabelList& patchFaceCells =
patches[patchi].faceCells();
const unallocLabelList& fc = patches[patchI].faceCells();
forAll (patchFaceCells, facei)
// Get neighbour cellToProc addressing across the interface
const labelList& curNbrPtc = patchNbrCellToProc_[patchI];
forAll (fc, patchFaceI)
{
const label curProc = cellToProc_[patchFaceCells[facei]];
// Local owner proc is looked up using faceCells
const label ownerProc = cellToProc_[fc[patchFaceI]];
// add the face
procFaceList[curProc].append(patchStart + facei);
// Neighbour proc is looked up directly
const label neighbourProc = curNbrPtc[patchFaceI];
// increment the number of faces for this patch
procPatchSize_[curProc][patchi]++;
// If the owner and neighbour processor index is the same,
// the face remains in the processor patch
// In load balancing, it will be re-merged on reconstruction
// HJ, 23/Apr/2018
if (ownerProc == neighbourProc)
{
// Add the face
procFaceList[ownerProc].append(patchStart + patchFaceI);
// Increment the number of faces for this patch
procPatchSize_[ownerProc][patchI]++;
}
}
}
else
else if (isA<cyclicPolyPatch>(patches[patchI]))
{
// Cyclic patch special treatment
const polyPatch& cPatch = patches[patchi];
const polyPatch& cPatch = patches[patchI];
const label cycOffset = cPatch.size()/2;
@ -297,12 +576,12 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
cycOffset
);
forAll (firstFaceCells, facei)
forAll (firstFaceCells, patchFaceI)
{
if
(
cellToProc_[firstFaceCells[facei]]
!= cellToProc_[secondFaceCells[facei]]
cellToProc_[firstFaceCells[patchFaceI]]
!= cellToProc_[secondFaceCells[patchFaceI]]
)
{
// This face becomes an inter-processor boundary face
@ -313,9 +592,11 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
cyclicParallel_ = true;
label ownerProc = cellToProc_[firstFaceCells[facei]];
label ownerProc =
cellToProc_[firstFaceCells[patchFaceI]];
label neighbourProc =
cellToProc_[secondFaceCells[facei]];
cellToProc_[secondFaceCells[patchFaceI]];
SLList<label>::iterator curInterProcBdrsOwnIter =
interProcBoundaries[ownerProc].begin();
@ -346,7 +627,7 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
interProcBouFound = true;
curInterProcBFacesOwnIter().append
(patchStart + facei);
(patchStart + patchFaceI);
SLList<label>::iterator curInterProcBdrsNeiIter
= interProcBoundaries[neighbourProc].begin();
@ -380,7 +661,7 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
(
patchStart
+ cycOffset
+ facei
+ patchFaceI
);
}
@ -415,7 +696,7 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
interProcBoundaries[ownerProc]
.append(neighbourProc);
interProcBFaces[ownerProc]
.append(SLList<label>(patchStart + facei));
.append(SLList<label>(patchStart + patchFaceI));
// neighbour
interProcBoundaries[neighbourProc]
@ -427,7 +708,7 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
(
patchStart
+ cycOffset
+ facei
+ patchFaceI
)
);
}
@ -435,13 +716,14 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
else
{
// This cyclic face remains on the processor
label ownerProc = cellToProc_[firstFaceCells[facei]];
label ownerProc =
cellToProc_[firstFaceCells[patchFaceI]];
// add the face
procFaceList[ownerProc].append(patchStart + facei);
procFaceList[ownerProc].append(patchStart + patchFaceI);
// increment the number of faces for this patch
procPatchSize_[ownerProc][patchi]++;
procPatchSize_[ownerProc][patchI]++;
// Note: I cannot add the other side of the cyclic
// boundary here because this would violate the order.
@ -453,26 +735,44 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
// Ordering in cyclic boundaries is important.
// Add the other half of cyclic faces for cyclic boundaries
// that remain on the processor
forAll (secondFaceCells, facei)
forAll (secondFaceCells, patchFaceI)
{
if
(
cellToProc_[firstFaceCells[facei]]
== cellToProc_[secondFaceCells[facei]]
cellToProc_[firstFaceCells[patchFaceI]]
== cellToProc_[secondFaceCells[patchFaceI]]
)
{
// This cyclic face remains on the processor
label ownerProc = cellToProc_[firstFaceCells[facei]];
label ownerProc =
cellToProc_[firstFaceCells[patchFaceI]];
// add the second face
// Add the second face
procFaceList[ownerProc].append
(patchStart + cycOffset + facei);
(patchStart + cycOffset + patchFaceI);
// increment the number of faces for this patch
procPatchSize_[ownerProc][patchi]++;
// Increment the number of faces for this patch
procPatchSize_[ownerProc][patchI]++;
}
}
}
else
{
// Normal patch. Add faces to processor where the cell
// next to the face lives
const unallocLabelList& fc = patches[patchI].faceCells();
forAll (fc, patchFaceI)
{
const label curProc = cellToProc_[fc[patchFaceI]];
// add the face
procFaceList[curProc].append(patchStart + patchFaceI);
// increment the number of faces for this patch
procPatchSize_[curProc][patchI]++;
}
}
}
// Face zone treatment. HJ, 27/Mar/2009
@ -483,7 +783,7 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
{
wordList fzNames(decompositionDict_.lookup("globalFaceZones"));
const faceZoneMesh& fz = faceZones();
const faceZoneMesh& fz = mesh_.faceZones();
forAll (fzNames, nameI)
{
@ -557,7 +857,7 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
labelList& curProcProcessorPatchStartIndex =
procProcessorPatchStartIndex_[procI];
// calculate the size
// Calculate the size
label nFacesOnProcessor = curProcFaces.size();
for
@ -703,6 +1003,7 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
// are omitted. For processor patches, set index to -1.
// At the same time, filter the procPatchSize_ and procPatchStartIndex_
// lists to exclude zero-size patches
forAll (procPatchSize_, procI)
{
// Make a local copy of old lists
@ -727,15 +1028,25 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
label nPatches = 0;
forAll (oldPatchSizes, patchi)
forAll (oldPatchSizes, patchI)
{
if (!filterEmptyPatches || oldPatchSizes[patchi] > 0)
// If filterEmptyPatches is set to true, or a patch is a
// processor patch, remove it
if
(
(filterEmptyPatches || isA<processorPolyPatch>(patches[patchI]))
&& oldPatchSizes[patchI] == 0
)
{
curBoundaryAddressing[nPatches] = patchi;
// Patch filtered: do nothing
}
else
{
curBoundaryAddressing[nPatches] = patchI;
curPatchSizes[nPatches] = oldPatchSizes[patchi];
curPatchSizes[nPatches] = oldPatchSizes[patchI];
curPatchStarts[nPatches] = oldPatchStarts[patchi];
curPatchStarts[nPatches] = oldPatchStarts[patchI];
nPatches++;
}
@ -767,7 +1078,7 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
forAll (procPointAddressing_, procI)
{
// Dimension list to all points in the mesh. HJ, 27/Mar/2009
boolList pointLabels(allPoints().size(), false);
boolList pointLabels(mesh_.allPoints().size(), false);
// Get reference to list of used faces
const labelList& procFaceLabels = procFaceAddressing_[procI];
@ -788,7 +1099,8 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
for (label faceI = 0; faceI < nLiveProcFaces_[procI]; faceI++)
{
// Because of the turning index, some labels may be negative
const labelList& facePoints = fcs[mag(procFaceLabels[faceI]) - 1];
const labelList& facePoints =
allFaces[mag(procFaceLabels[faceI]) - 1];
forAll (facePoints, pointI)
{
@ -813,7 +1125,7 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
// Second pass: zone faces
// Reset point usage list
boolList pointLabelsSecondPass(allPoints().size(), false);
boolList pointLabelsSecondPass(mesh_.allPoints().size(), false);
for
(
@ -823,7 +1135,8 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
)
{
// Because of the turning index, some labels may be negative
const labelList& facePoints = fcs[mag(procFaceLabels[faceI]) - 1];
const labelList& facePoints =
allFaces[mag(procFaceLabels[faceI]) - 1];
forAll (facePoints, pointI)
{
@ -854,13 +1167,13 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
// Memory management
{
// Dimension list to all points in the mesh. HJ, 27/Mar/2009
labelList pointsUsage(allPoints().size(), 0);
labelList pointsUsage(mesh_.allPoints().size(), 0);
// Globally shared points are the ones used by more than 2 processors
// Size the list approximately and gather the points
labelHashSet gSharedPoints
(
min(100, nPoints()/1000)
min(100, mesh_.nPoints()/1000)
);
// Loop through all the processors and mark up points used by
@ -882,10 +1195,10 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
// Reset the lookup list
pointsUsage = 0;
forAll (curProcessorPatchStarts, patchi)
forAll (curProcessorPatchStarts, patchI)
{
const label curStart = curProcessorPatchStarts[patchi];
const label curEnd = curStart + curProcessorPatchSizes[patchi];
const label curStart = curProcessorPatchStarts[patchI];
const label curEnd = curStart + curProcessorPatchSizes[patchI];
for
(
@ -899,16 +1212,16 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
// HJ, 5/Dec/2001
const label curF = mag(curFaceLabels[faceI]) - 1;
const face& f = fcs[curF];
const face& f = allFaces[curF];
forAll (f, pointI)
{
if (pointsUsage[f[pointI]] == 0)
{
// Point not previously used
pointsUsage[f[pointI]] = patchi + 1;
pointsUsage[f[pointI]] = patchI + 1;
}
else if (pointsUsage[f[pointI]] != patchi + 1)
else if (pointsUsage[f[pointI]] != patchI + 1)
{
// Point used by some other patch = global point!
gSharedPoints.insert(f[pointI]);
@ -923,3 +1236,6 @@ void domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
sort(globallySharedPoints_);
}
}
// ************************************************************************* //

View file

@ -26,19 +26,18 @@ License
#include "domainDecomposition.H"
#include "decompositionMethod.H"
#include "cpuTime.H"
#include "cyclicPolyPatch.H"
#include "processorFvPatch.H"
#include "cellSet.H"
#include "regionSplit.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void domainDecomposition::distributeCells()
void Foam::domainDecomposition::distributeCells()
{
Info<< "\nCalculating distribution of cells" << endl;
cpuTime decompositionTime;
// See if any faces need to have owner and neighbour on same processor
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -51,7 +50,7 @@ void domainDecomposition::distributeCells()
Info<< "Keeping owner and neighbour of faces in patches " << pNames
<< " on same processor" << endl;
const polyBoundaryMesh& patches = boundaryMesh();
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
forAll(pNames, i)
{
@ -73,6 +72,7 @@ void domainDecomposition::distributeCells()
}
}
}
if (decompositionDict_.found("preserveFaceZones"))
{
wordList zNames(decompositionDict_.lookup("preserveFaceZones"));
@ -80,7 +80,7 @@ void domainDecomposition::distributeCells()
Info<< "Keeping owner and neighbour of faces in zones " << zNames
<< " on same processor" << endl;
const faceZoneMesh& fZones = faceZones();
const faceZoneMesh& fZones = mesh_.faceZones();
forAll(zNames, i)
{
@ -106,17 +106,15 @@ void domainDecomposition::distributeCells()
// Construct decomposition method and either do decomposition on
// cell centres or on agglomeration
autoPtr<decompositionMethod> decomposePtr = decompositionMethod::New
(
decompositionDict_,
*this
mesh_
);
if (sameProcFaces.empty())
{
cellToProc_ = decomposePtr().decompose(cellCentres());
cellToProc_ = decomposePtr().decompose(mesh_.cellCentres());
}
else
{
@ -126,7 +124,7 @@ void domainDecomposition::distributeCells()
// Faces where owner and neighbour are not 'connected' (= all except
// sameProcFaces)
boolList blockedFace(nFaces(), true);
boolList blockedFace(mesh_.nFaces(), true);
forAllConstIter(labelHashSet, sameProcFaces, iter)
{
@ -134,7 +132,7 @@ void domainDecomposition::distributeCells()
}
// Connect coupled boundary faces
const polyBoundaryMesh& patches = boundaryMesh();
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
forAll(patches, patchI)
{
@ -150,7 +148,7 @@ void domainDecomposition::distributeCells()
}
// Determine global regions, separated by blockedFaces
regionSplit globalRegion(*this, blockedFace);
regionSplit globalRegion(mesh_, blockedFace);
// Determine region cell centres
@ -171,7 +169,7 @@ void domainDecomposition::distributeCells()
if (regionCentres[regionI] == greatPoint)
{
regionCentres[regionI] = cellCentres()[cellI];
regionCentres[regionI] = mesh_.cellCentres()[cellI];
}
}
@ -180,6 +178,46 @@ void domainDecomposition::distributeCells()
cellToProc_ = decomposePtr().decompose(globalRegion, regionCentres);
}
// If running in parallel, sync cellToProc_ across coupled boundaries
// Initialise transfer of restrict addressing on the interface
if (Pstream::parRun())
{
const fvBoundaryMesh& patches = mesh_.boundary();
forAll (patches, patchI)
{
if (isA<processorFvPatch>(patches[patchI]))
// if (patches[patchI].coupled())
{
const lduInterface& cpPatch =
refCast<const lduInterface>(patches[patchI]);
cpPatch.initInternalFieldTransfer
(
Pstream::blocking,
cellToProc_
);
}
}
forAll (patches, patchI)
{
if (isA<processorFvPatch>(patches[patchI]))
// if (patches[patchI].coupled())
{
const lduInterface& cpPatch =
refCast<const lduInterface>(patches[patchI]);
patchNbrCellToProc_[patchI] =
cpPatch.internalFieldTransfer
(
Pstream::blocking,
cellToProc_
);
}
}
}
Info<< "\nFinished decomposition in "
<< decompositionTime.elapsedCpuTime()
<< " s" << endl;

View file

@ -0,0 +1,740 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "domainDecomposition.H"
#include "foamTime.H"
#include "dictionary.H"
#include "labelIOList.H"
#include "processorPolyPatch.H"
#include "passiveProcessorPolyPatch.H"
#include "fvMesh.H"
#include "OSspecific.H"
#include "Map.H"
#include "DynamicList.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::domainDecomposition, 0);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::domainDecomposition::domainDecomposition
(
const fvMesh& mesh,
const dictionary& dict
)
:
mesh_(mesh),
decompositionDict_(dict),
nProcs_(readInt(decompositionDict_.lookup("numberOfSubdomains"))),
distributed_(false),
gfIndex_(mesh_),
cellToProc_(mesh_.nCells()),
patchNbrCellToProc_(mesh_.boundaryMesh().size()),
procPointAddressing_(nProcs_),
procFaceAddressing_(nProcs_),
nInternalProcFaces_(nProcs_),
nLiveProcFaces_(nProcs_),
procCellAddressing_(nProcs_),
procBoundaryAddressing_(nProcs_),
procPatchSize_(nProcs_),
procPatchStartIndex_(nProcs_),
procNeighbourProcessors_(nProcs_),
procProcessorPatchSize_(nProcs_),
procProcessorPatchStartIndex_(nProcs_),
globallySharedPoints_(0),
cyclicParallel_(false)
{
if (decompositionDict_.found("distributed"))
{
distributed_ = Switch(decompositionDict_.lookup("distributed"));
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::domainDecomposition::~domainDecomposition()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::autoPtr<Foam::fvMesh> Foam::domainDecomposition::processorMesh
(
const label procI,
const Time& processorDb,
const word& regionName,
const bool createPassiveProcPatches
) const
{
// Create processor points
const labelList& curPointLabels = procPointAddressing_[procI];
// Access list of all points in the mesh. HJ, 27/Mar/2009
const pointField& meshPoints = mesh_.allPoints();
labelList pointLookup(meshPoints.size(), -1);
pointField procPoints(curPointLabels.size());
forAll (curPointLabels, pointi)
{
procPoints[pointi] = meshPoints[curPointLabels[pointi]];
pointLookup[curPointLabels[pointi]] = pointi;
}
// Create processor faces
const labelList& curFaceLabels = procFaceAddressing_[procI];
// Access list of all faces in the mesh. HJ, 27/Mar/2009
const faceList& meshFaces = mesh_.allFaces();
labelList faceLookup(meshFaces.size(), -1);
faceList procFaces(curFaceLabels.size());
forAll (curFaceLabels, faceI)
{
// Mark the original face as used
// Remember to decrement the index by one (turning index)
// HJ, 5/Dec/2001
label curF = mag(curFaceLabels[faceI]) - 1;
faceLookup[curF] = faceI;
// get the original face
labelList origFaceLabels;
if (curFaceLabels[faceI] >= 0)
{
// face not turned
origFaceLabels = meshFaces[curF];
}
else
{
origFaceLabels = meshFaces[curF].reverseFace();
}
// translate face labels into local point list
face& procFaceLabels = procFaces[faceI];
procFaceLabels.setSize(origFaceLabels.size());
forAll (origFaceLabels, pointi)
{
procFaceLabels[pointi] = pointLookup[origFaceLabels[pointi]];
}
}
// Create cell lookup
labelList cellLookup(mesh_.nCells(), -1);
const labelList& curCellLabels = procCellAddressing_[procI];
forAll (curCellLabels, cellI)
{
cellLookup[curCellLabels[cellI]] = cellI;
}
// Get complete owner-neighour addressing in the mesh
const labelList& own = mesh_.faceOwner();
const labelList& nei = mesh_.faceNeighbour();
// Calculate owner and neighbour list
// Owner list is sized to number of live faces
// Neighbour list is sized to number of internal faces
labelList procOwner(nLiveProcFaces_[procI]);
// Note: loop over owner, not all faces: sizes are different
forAll (procOwner, faceI)
{
// Remember to decrement the index by one (turning index)
// HJ, 28/Mar/2009
label curF = mag(curFaceLabels[faceI]) - 1;
if (curFaceLabels[faceI] >= 0)
{
procOwner[faceI] = cellLookup[own[curF]];
}
else
{
procOwner[faceI] = cellLookup[nei[curF]];
}
}
labelList procNeighbour(nInternalProcFaces_[procI]);
// Note: loop over neighbour, not all faces: sizes are different
forAll (procNeighbour, faceI)
{
// Remember to decrement the index by one (turning index)
// HJ, 28/Mar/2009
label curF = mag(curFaceLabels[faceI]) - 1;
if (curFaceLabels[faceI] >= 0)
{
procNeighbour[faceI] = cellLookup[nei[curF]];
}
else
{
procNeighbour[faceI] = cellLookup[own[curF]];
}
}
// Create processor mesh without a boundary
autoPtr<fvMesh> procMeshPtr
(
new fvMesh
(
IOobject
(
regionName,
mesh_.pointsInstance(),
processorDb
),
xferMove(procPoints),
xferMove(procFaces),
xferMove(procOwner),
xferMove(procNeighbour),
false // Do not sync par
)
);
fvMesh& procMesh = procMeshPtr();
// Create processor boundary patches
const labelList& curBoundaryAddressing = procBoundaryAddressing_[procI];
const labelList& curPatchSizes = procPatchSize_[procI];
const labelList& curPatchStarts = procPatchStartIndex_[procI];
const labelList& curNeighbourProcessors =
procNeighbourProcessors_[procI];
const labelList& curProcessorPatchSizes =
procProcessorPatchSize_[procI];
const labelList& curProcessorPatchStarts =
procProcessorPatchStartIndex_[procI];
const polyPatchList& meshPatches = mesh_.boundaryMesh();
List<polyPatch*> procPatches
(
curPatchSizes.size()
+ curProcessorPatchSizes.size(),
reinterpret_cast<polyPatch*>(0)
);
label nPatches = 0;
forAll (curPatchSizes, patchi)
{
procPatches[nPatches] =
meshPatches[curBoundaryAddressing[patchi]].clone
(
procMesh.boundaryMesh(),
nPatches,
curPatchSizes[patchi],
curPatchStarts[patchi]
).ptr();
nPatches++;
}
if (createPassiveProcPatches)
{
// Creation of passiveProcessor patches requires a global face index
// Get global index
const labelList& globalIndex = gfIndex_.globalLabel();
forAll (curProcessorPatchSizes, procPatchI)
{
// Assemble the global face index for all passive processor patch
// faces
labelList patchGlobalIndex(curProcessorPatchSizes[procPatchI]);
const label curPatchStart = curProcessorPatchStarts[procPatchI];
forAll (patchGlobalIndex, fI)
{
patchGlobalIndex[fI] =
globalIndex[mag(curFaceLabels[curPatchStart + fI]) - 1];
}
procPatches[nPatches] =
new passiveProcessorPolyPatch
(
word("passiveProcBoundary") + Foam::name(procI)
+ word("to")
+ Foam::name(curNeighbourProcessors[procPatchI]),
curProcessorPatchSizes[procPatchI],
curProcessorPatchStarts[procPatchI],
nPatches,
procMesh.boundaryMesh(),
procI,
curNeighbourProcessors[procPatchI],
patchGlobalIndex
);
nPatches++;
}
}
else
{
forAll (curProcessorPatchSizes, procPatchI)
{
procPatches[nPatches] =
new processorPolyPatch
(
word("procBoundary") + Foam::name(procI)
+ word("to")
+ Foam::name(curNeighbourProcessors[procPatchI]),
curProcessorPatchSizes[procPatchI],
curProcessorPatchStarts[procPatchI],
nPatches,
procMesh.boundaryMesh(),
procI,
curNeighbourProcessors[procPatchI]
);
nPatches++;
}
}
// Add boundary patches to polyMesh and fvMesh
// Note: Mark boundary as invalid to disable analysis
// due to the presence of old/new patches
procMesh.addFvPatches(procPatches, false);
// Create and add zones
// Note:
// This coding was all wrong, as each point/face/cell may only
// belong to a single zone.
// Additionally, ordering of points/faces/cells in the processor mesh
// needs to match the ordering in global mesh zones. Full rewrite.
// HJ, 30/Mar/2009
// Create zones if needed
if
(
!mesh_.pointZones().empty()
|| !mesh_.faceZones().empty()
|| !mesh_.cellZones().empty()
)
{
// Point zones
List<pointZone*> procPz(mesh_.pointZones().size());
{
const pointZoneMesh& pz = mesh_.pointZones();
// Go through all the zoned points and find out if they
// belong to a processor. If so, add it to the zone as
// necessary
forAll (pz, zoneI)
{
const labelList& zonePoints = pz[zoneI];
labelList procZonePoints(zonePoints.size());
label nZonePoints = 0;
forAll (zonePoints, pointI)
{
const label localIndex =
pointLookup[zonePoints[pointI]];
if (localIndex >= 0)
{
// Point live on processor: add to zone
procZonePoints[nZonePoints] = localIndex;
nZonePoints++;
}
}
// Add the zone
procZonePoints.setSize(nZonePoints);
procPz[zoneI] = new pointZone
(
pz[zoneI].name(),
procZonePoints,
zoneI,
procMesh.pointZones()
);
}
}
// Face zones
List<faceZone*> procFz(mesh_.faceZones().size());
{
const faceZoneMesh& fz = mesh_.faceZones();
forAll (fz, zoneI)
{
const labelList& zoneFaces = fz[zoneI];
const boolList& flipMap = fz[zoneI].flipMap();
// Go through all the zoned faces and find out if they
// belong to a processor. If so, add it to the zone as
// necessary
labelList procZoneFaces(zoneFaces.size());
boolList procZoneFaceFlips(zoneFaces.size());
label nZoneFaces = 0;
forAll (zoneFaces, faceI)
{
const label localIndex = faceLookup[zoneFaces[faceI]];
if (localIndex >= 0)
{
// Face is present on the processor
// Add the face to the zone
procZoneFaces[nZoneFaces] = localIndex;
// Grab the flip
bool flip = flipMap[faceI];
if (curFaceLabels[localIndex] < 0)
{
flip = !flip;
}
procZoneFaceFlips[nZoneFaces] = flip;
nZoneFaces++;
}
}
// Add the zone
procZoneFaces.setSize(nZoneFaces);
procZoneFaceFlips.setSize(nZoneFaces);
procFz[zoneI] = new faceZone
(
fz[zoneI].name(),
procZoneFaces,
procZoneFaceFlips,
zoneI,
procMesh.faceZones()
);
}
}
// Cell zones
List<cellZone*> procCz(mesh_.cellZones().size());
{
const cellZoneMesh& cz = mesh_.cellZones();
// Go through all the zoned cells and find out if they
// belong to a processor. If so, add it to the zone as
// necessary
forAll (cz, zoneI)
{
const labelList& zoneCells = cz[zoneI];
labelList procZoneCells(zoneCells.size());
label nZoneCells = 0;
forAll (zoneCells, cellI)
{
const label localIndex = cellLookup[zoneCells[cellI]];
if (localIndex >= 0)
{
procZoneCells[nZoneCells] = localIndex;
nZoneCells++;
}
}
// Add the zone
procZoneCells.setSize(nZoneCells);
procCz[zoneI] = new cellZone
(
cz[zoneI].name(),
procZoneCells,
zoneI,
procMesh.cellZones()
);
}
}
// Add zones
procMesh.addZones(procPz, procFz, procCz);
}
// Return mesh
return procMeshPtr;
}
bool Foam::domainDecomposition::writeDecomposition()
{
Info<< "\nConstructing processor meshes" << endl;
// Make a lookup map for globally shared points
Map<label> sharedPointLookup(2*globallySharedPoints_.size());
forAll (globallySharedPoints_, pointi)
{
sharedPointLookup.insert(globallySharedPoints_[pointi], pointi);
}
// Mark point/faces/cells that are in zones. Bad coding - removed
// HJ, 31/Mar/2009
label totProcFaces = 0;
label maxProcPatches = 0;
label maxProcFaces = 0;
// Note: get cellLevel and pointLevel. Avoid checking whether they exist or
// not by hand. If they don't exist, simply assume that the level is 0
const labelIOList globalCellLevel
(
IOobject
(
"cellLevel",
mesh_.facesInstance(),
polyMesh::meshSubDir,
mesh_,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE
),
labelList(mesh_.nCells(), 0)
);
const labelIOList globalPointLevel
(
IOobject
(
"pointLevel",
mesh_.facesInstance(),
polyMesh::meshSubDir,
mesh_,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE
),
labelList(mesh_.nPoints(), 0)
);
// Write out the meshes
for (label procI = 0; procI < nProcs_; procI++)
{
fileName processorCasePath
(
mesh_.time().caseName()/fileName(word("processor") + name(procI))
);
// make the processor directory
mkDir(mesh_.time().rootPath()/processorCasePath);
// create a database
Time processorDb
(
Time::controlDictName,
mesh_.time().rootPath(),
processorCasePath,
"system",
"constant",
true
);
// Set the precision of the points data to 10
IOstream::defaultPrecision(10);
autoPtr<fvMesh> procMeshPtr = processorMesh
(
procI,
processorDb,
mesh_.polyMesh::name() // region name of undecomposed mesh
);
fvMesh& procMesh = procMeshPtr();
procMesh.write();
Info<< endl
<< "Processor " << procI << nl
<< " Number of cells = " << procMesh.nCells()
<< endl;
label nBoundaryFaces = 0;
label nProcPatches = 0;
label nProcFaces = 0;
forAll (procMesh.boundaryMesh(), patchi)
{
if
(
procMesh.boundaryMesh()[patchi].type()
== processorPolyPatch::typeName
)
{
const processorPolyPatch& ppp =
refCast<const processorPolyPatch>
(
procMesh.boundaryMesh()[patchi]
);
Info<< " Number of faces shared with processor "
<< ppp.neighbProcNo() << " = " << ppp.size() << endl;
nProcPatches++;
nProcFaces += ppp.size();
}
else
{
nBoundaryFaces += procMesh.boundaryMesh()[patchi].size();
}
}
Info<< " Number of processor patches = " << nProcPatches << nl
<< " Number of processor faces = " << nProcFaces << nl
<< " Number of boundary faces = " << nBoundaryFaces << endl;
totProcFaces += nProcFaces;
maxProcPatches = max(maxProcPatches, nProcPatches);
maxProcFaces = max(maxProcFaces, nProcFaces);
// create and write the addressing information
labelIOList pointProcAddressing
(
IOobject
(
"pointProcAddressing",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procPointAddressing_[procI]
);
pointProcAddressing.write();
labelIOList faceProcAddressing
(
IOobject
(
"faceProcAddressing",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procFaceAddressing_[procI]
);
faceProcAddressing.write();
labelIOList cellProcAddressing
(
IOobject
(
"cellProcAddressing",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procCellAddressing_[procI]
);
cellProcAddressing.write();
labelIOList boundaryProcAddressing
(
IOobject
(
"boundaryProcAddressing",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procBoundaryAddressing_[procI]
);
boundaryProcAddressing.write();
// Create and write cellLevel and pointLevel information
const unallocLabelList& cellMap = cellProcAddressing;
labelIOList procCellLevel
(
IOobject
(
"cellLevel",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
labelList(globalCellLevel, cellMap)
);
procCellLevel.write();
const unallocLabelList& pointMap = pointProcAddressing;
labelIOList procPointLevel
(
IOobject
(
"pointLevel",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
labelList(globalPointLevel, pointMap)
);
procPointLevel.write();
}
Info<< nl
<< "Number of processor faces = " << totProcFaces/2 << nl
<< "Max number of processor patches = " << maxProcPatches << nl
<< "Max number of faces between processors = " << maxProcFaces
<< endl;
return true;
}
// ************************************************************************* //

View file

@ -29,6 +29,8 @@ Description
SourceFiles
domainDecomposition.C
distributeCells.C
decomposeMesh.C
\*---------------------------------------------------------------------------*/
@ -40,24 +42,26 @@ SourceFiles
#include "SLList.H"
#include "PtrList.H"
#include "point.H"
#include "globalProcFaceIndex.H"
#ifndef namespaceFoam
#define namespaceFoam
using namespace Foam;
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class domainDecomposition Declaration
\*---------------------------------------------------------------------------*/
class domainDecomposition
:
public fvMesh
{
// Private data
//- Mesh reference
const fvMesh& mesh_;
//- Mesh decomposition control dictionary
IOdictionary decompositionDict_;
dictionary decompositionDict_;
//- Number of processors in decomposition
label nProcs_;
@ -65,9 +69,16 @@ class domainDecomposition
//- Is the decomposition data to be distributed for each processor
bool distributed_;
//- Global face index
globalProcFaceIndex gfIndex_;
//- Processor label for each cell
labelList cellToProc_;
//- Processor label for neighbour cell for each processor boundary
// Data is used when running decomposition in parallel
labelListList patchNbrCellToProc_;
//- Labels of points for each processor
labelListList procPointAddressing_;
@ -119,24 +130,37 @@ class domainDecomposition
// Private Member Functions
//- Create cell-to processor list using domain decomposition tools
void distributeCells();
public:
// Declare name of the class and its debug switch
ClassName("domainDecomposition");
// Constructors
//- Construct from IOobject
domainDecomposition(const IOobject& io);
//- Construct from mesh and dictionary
domainDecomposition
(
const fvMesh& mesh,
const dictionary& dict
);
// Destructor
~domainDecomposition();
//- Destructor
~domainDecomposition();
// Member Functions
//- Return mesh reference
const fvMesh& mesh() const
{
return mesh_;
}
//- Number of processor in decomposition
label nProcs() const
{
@ -144,25 +168,77 @@ public:
}
//- Is the decomposition data to be distributed for each processor
bool distributed() const
inline bool distributed() const
{
return distributed_;
}
//- Return cell-processor decomposition labels
const labelList& cellToProc() const
{
return cellToProc_;
}
//- Return cell-processor decomposition labels for cells across
// coupled boundaries when running decomposition in parallel
const labelListList& patchNbrCellToProc() const
{
return patchNbrCellToProc_;
}
//- Decompose mesh. Optionally remove zero-sized patches.
void decomposeMesh(const bool filterEmptyPatches);
// Decomposed mesh and addressing
//- Create a decomposed mesh for a given processor index
// Note: at the point of construction, the boundary is marked
// as invalid. If the mesh should be used immediately upon
// creation, initialise the boundary patches before use
// HJ, 12/Apr/2018
autoPtr<fvMesh> processorMesh
(
const label procI,
const Time& procDb,
const word& regionName,
const bool createPassiveProcPatches = false
) const;
//- Return processor point addressing
const labelListList& procPointAddressing() const
{
return procPointAddressing_;
}
//- Return processor face addressing
const labelListList& procFaceAddressing() const
{
return procFaceAddressing_;
}
//- Return processor cell addressing
const labelListList& procCellAddressing() const
{
return procCellAddressing_;
}
//- Return processor boundary addressing
const labelListList& procBoundaryAddressing() const
{
return procBoundaryAddressing_;
}
//- Write decomposition
bool writeDecomposition();
//- Cell-processor decomposition labels
const labelList& cellToProc() const
{
return cellToProc_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif

View file

@ -253,9 +253,8 @@ public:
);
// Destructor
~fvFieldDecomposer();
//- Destructor
~fvFieldDecomposer();
// Member Functions
@ -276,6 +275,7 @@ public:
const GeometricField<Type, fvsPatchField, surfaceMesh>& field
) const;
//- Decompose and write all fields from the list
template<class GeoField>
void decomposeFields(const PtrList<GeoField>& fields) const;
};

View file

@ -47,38 +47,45 @@ fvFieldDecomposer::decomposeField
// Create and map the patch field values
PtrList<fvPatchField<Type> > patchFields(boundaryAddressing_.size());
forAll (boundaryAddressing_, patchi)
forAll (boundaryAddressing_, patchI)
{
if (boundaryAddressing_[patchi] >= 0)
if (boundaryAddressing_[patchI] >= 0)
{
patchFields.set
(
patchi,
patchI,
fvPatchField<Type>::New
(
field.boundaryField()[boundaryAddressing_[patchi]],
procMesh_.boundary()[patchi],
field.boundaryField()[boundaryAddressing_[patchI]],
procMesh_.boundary()[patchI],
DimensionedField<Type, volMesh>::null(),
*patchFieldDecomposerPtrs_[patchi]
*patchFieldDecomposerPtrs_[patchI]
)
);
}
else
{
// This will be a processor or passiveProcessor field,
// depending on the patch type. Construct it first and set the
// data by hand
patchFields.set
(
patchi,
new processorFvPatchField<Type>
patchI,
fvPatchField<Type>::New
// new processorFvPatchField<Type>
(
procMesh_.boundary()[patchi],
DimensionedField<Type, volMesh>::null(),
Field<Type>
(
field.internalField(),
*processorVolPatchFieldDecomposerPtrs_[patchi]
)
procMesh_.boundary()[patchI].type(),
procMesh_.boundary()[patchI],
DimensionedField<Type, volMesh>::null()
)
);
patchFields[patchI] ==
Field<Type>
(
field.internalField(),
*processorVolPatchFieldDecomposerPtrs_[patchI]
);
}
}
@ -135,7 +142,9 @@ fvFieldDecomposer::decomposeField
// faces and faces from cyclic boundaries. This is a bit of a hack, but
// I cannot find a better solution without making the internal storage
// mechanism for surfaceFields correspond to the one of faces in polyMesh
// (i.e. using slices)
// (i.e. using slices). HJ, date unknown, before 2004
// Copy all face data into a single array across all patches
Field<Type> allFaceField(field.mesh().nFaces());
forAll (field.internalField(), i)
@ -143,11 +152,11 @@ fvFieldDecomposer::decomposeField
allFaceField[i] = field.internalField()[i];
}
forAll (field.boundaryField(), patchi)
forAll (field.boundaryField(), patchI)
{
const Field<Type> & p = field.boundaryField()[patchi];
const Field<Type> & p = field.boundaryField()[patchI];
const label patchStart = field.mesh().boundaryMesh()[patchi].start();
const label patchStart = field.mesh().boundaryMesh()[patchI].start();
forAll (p, i)
{
@ -158,38 +167,45 @@ fvFieldDecomposer::decomposeField
// Create and map the patch field values
PtrList<fvsPatchField<Type> > patchFields(boundaryAddressing_.size());
forAll (boundaryAddressing_, patchi)
forAll (boundaryAddressing_, patchI)
{
if (boundaryAddressing_[patchi] >= 0)
if (boundaryAddressing_[patchI] >= 0)
{
patchFields.set
(
patchi,
patchI,
fvsPatchField<Type>::New
(
field.boundaryField()[boundaryAddressing_[patchi]],
procMesh_.boundary()[patchi],
field.boundaryField()[boundaryAddressing_[patchI]],
procMesh_.boundary()[patchI],
DimensionedField<Type, surfaceMesh>::null(),
*patchFieldDecomposerPtrs_[patchi]
*patchFieldDecomposerPtrs_[patchI]
)
);
}
else
{
// This will be a processor or passiveProcessor field,
// depending on the patch type. Construct it first and set the
// data by hand
patchFields.set
(
patchi,
new processorFvsPatchField<Type>
patchI,
fvsPatchField<Type>::New
// new processorFvsPatchField<Type>
(
procMesh_.boundary()[patchi],
DimensionedField<Type, surfaceMesh>::null(),
Field<Type>
(
allFaceField,
*processorSurfacePatchFieldDecomposerPtrs_[patchi]
)
procMesh_.boundary()[patchI].type(),
procMesh_.boundary()[patchI],
DimensionedField<Type, surfaceMesh>::null()
)
);
patchFields[patchI] ==
Field<Type>
(
allFaceField,
*processorSurfacePatchFieldDecomposerPtrs_[patchI]
);
}
}

View file

@ -0,0 +1,184 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::processorMeshData
Description
The class holds mesh data required to assemble a single processor mesh
from the decomposition. The data is raw but can be assembled into
a complete mesh
Author
Hrvoje Jasak, Wikki Ltd.
SourceFiles
processorMeshData.C
\*---------------------------------------------------------------------------*/
#ifndef processorMeshData_H
#define processorMeshData_H
#include ".H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class processorMeshData Declaration
\*---------------------------------------------------------------------------*/
class processorMeshData
{
// Private data
// Internal mesh data
//- Points
pointField procPoints_;
//- Faces
faceList procFaces_;
//- Face owner
labelList procOwner_;
//- Face neighbour
labelList procNeighbour_;
// Boundary data, separated into existing and new patches
//- Boundary addressing
labelList boundaryAddressing_;
//- Regular patch sizes
labelList patchSizes_;
//- Regular patch starts
labelList patchStarts_;
//- Processor patch sizes
labelList procPatchSizes_;
//- Processor patch starts
labelList procPatchSizes_;
// Zones
//- Point zones
labelListList pointZones_;
//- Face zones
labelListList faceZones_;
//- Face zone flips
labelListList faceZoneFlips_;
//- Cell zones
labelListList cellZones_;
// Private Member Functions
//- Disallow default bitwise copy construct
processorMeshData(const processorMeshData&);
//- Disallow default bitwise assignment
void operator=(const processorMeshData&);
public:
// Static data members
//- Static data staticData
static const dataType staticData;
// Constructors
//- Construct from components
processorMeshData(const dataType& data);
//- Construct from Istream
processorMeshData(Istream&);
//- Construct as copy
processorMeshData(const processorMeshData&);
// Selectors
//- Select null constructed
static autoPtr<processorMeshData> New();
//- Destructor
~processorMeshData();
// Member Functions
// Access
// Check
// Edit
// Write
// Member Operators
void operator=(const processorMeshData&);
// Friend Functions
// Friend Operators
// IOstream Operators
friend Istream& operator>>(Istream&, processorMeshData&);
friend Ostream& operator<<(Ostream&, const processorMeshData&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "processorMeshDataI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,112 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "passiveProcessorFvPatchField.H"
#include "passiveProcessorFvPatch.H"
#include "IPstream.H"
#include "OPstream.H"
#include "transformField.H"
#include "coeffFields.H"
#include "demandDrivenData.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::passiveProcessorFvPatchField<Type>::passiveProcessorFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
fvPatchField<Type>(p, iF)
{}
template<class Type>
Foam::passiveProcessorFvPatchField<Type>::passiveProcessorFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const Field<Type>& f
)
:
fvPatchField<Type>(p, iF, f)
{}
template<class Type>
Foam::passiveProcessorFvPatchField<Type>::passiveProcessorFvPatchField
(
const passiveProcessorFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fvPatchField<Type>(ptf, p, iF, mapper)
{}
template<class Type>
Foam::passiveProcessorFvPatchField<Type>::passiveProcessorFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
fvPatchField<Type>(p, iF, dict)
{}
template<class Type>
Foam::passiveProcessorFvPatchField<Type>::passiveProcessorFvPatchField
(
const passiveProcessorFvPatchField<Type>& ptf
)
:
fvPatchField<Type>(ptf)
{}
template<class Type>
Foam::passiveProcessorFvPatchField<Type>::passiveProcessorFvPatchField
(
const passiveProcessorFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
fvPatchField<Type>(ptf, iF)
{}
// * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * //
template<class Type>
Foam::passiveProcessorFvPatchField<Type>::~passiveProcessorFvPatchField()
{}
// ************************************************************************* //

View file

@ -0,0 +1,151 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::passiveProcessorFvPatchField
Description
This patch field is used in parallel load balancing to communicate
future passiveProcessor data in parallel decomposition
SourceFiles
passiveProcessorFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef passiveProcessorFvPatchField_H
#define passiveProcessorFvPatchField_H
#include "fvPatchField.H"
#include "passiveProcessorFvPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class passiveProcessorFvPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class passiveProcessorFvPatchField
:
public fvPatchField<Type>
{
public:
//- Runtime type information
TypeName(passiveProcessorFvPatch::typeName_());
// Constructors
//- Construct from patch and internal field
passiveProcessorFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch and internal field and patch field
passiveProcessorFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const Field<Type>&
);
//- Construct from patch, internal field and dictionary
passiveProcessorFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping given passiveProcessorFvPatchField
// onto a new patch
passiveProcessorFvPatchField
(
const passiveProcessorFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
passiveProcessorFvPatchField
(
const passiveProcessorFvPatchField<Type>&
);
//- Construct and return a clone
virtual tmp<fvPatchField<Type> > clone() const
{
return tmp<fvPatchField<Type> >
(
new passiveProcessorFvPatchField<Type>(*this)
);
}
//- Construct as copy setting internal field reference
passiveProcessorFvPatchField
(
const passiveProcessorFvPatchField<Type>&,
const DimensionedField<Type, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchField<Type> > clone
(
const DimensionedField<Type, volMesh>& iF
) const
{
return tmp<fvPatchField<Type> >
(
new passiveProcessorFvPatchField<Type>(*this, iF)
);
}
//- Destructor
virtual ~passiveProcessorFvPatchField();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "passiveProcessorFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -23,25 +23,21 @@ License
\*---------------------------------------------------------------------------*/
#include "faFieldReconstructor.H"
#include "passiveProcessorFvPatchFields.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::faFieldReconstructor::faFieldReconstructor
(
faMesh& mesh,
const PtrList<faMesh>& procMeshes,
const PtrList<labelIOList>& edgeProcAddressing,
const PtrList<labelIOList>& faceProcAddressing,
const PtrList<labelIOList>& boundaryProcAddressing
)
:
mesh_(mesh),
procMeshes_(procMeshes),
edgeProcAddressing_(edgeProcAddressing),
faceProcAddressing_(faceProcAddressing),
boundaryProcAddressing_(boundaryProcAddressing)
{}
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makePatchFields(passiveProcessor);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -23,25 +23,27 @@ License
\*---------------------------------------------------------------------------*/
#include "fvFieldReconstructor.H"
#ifndef passiveProcessorFvPatchFields_H
#define passiveProcessorFvPatchFields_H
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
#include "passiveProcessorFvPatchField.H"
#include "fieldTypes.H"
Foam::fvFieldReconstructor::fvFieldReconstructor
(
fvMesh& mesh,
const PtrList<fvMesh>& procMeshes,
const PtrList<labelIOList>& faceProcAddressing,
const PtrList<labelIOList>& cellProcAddressing,
const PtrList<labelIOList>& boundaryProcAddressing
)
:
mesh_(mesh),
procMeshes_(procMeshes),
faceProcAddressing_(faceProcAddressing),
cellProcAddressing_(cellProcAddressing),
boundaryProcAddressing_(boundaryProcAddressing)
{}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeFieldTypedefs(passiveProcessor)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -21,24 +21,13 @@ License
You should have received a copy of the GNU General Public License
along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
InClass
Foam::reconstructLagrangian
Description
SourceFiles
reconstructLagrangianPositions.C
reconstructLagrangianFields.C
\*---------------------------------------------------------------------------*/
#ifndef reconstructLagrangian_H
#define reconstructLagrangian_H
#ifndef passiveProcessorFvPatchFieldsFwd_H
#define passiveProcessorFvPatchFieldsFwd_H
#include "cloud.H"
#include "polyMesh.H"
#include "IOobjectList.H"
#include "fvMesh.H"
#include "fvPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -47,35 +36,9 @@ namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void reconstructLagrangianPositions
(
const polyMesh& mesh,
const word& cloudName,
const PtrList<fvMesh>& meshes,
const PtrList<labelIOList>& faceProcAddressing,
const PtrList<labelIOList>& cellProcAddressing
);
template<class Type>
tmp<IOField<Type> > reconstructLagrangianField
(
const word& cloudName,
const polyMesh& mesh,
const PtrList<fvMesh>& meshes,
const word& fieldName
);
template<class Type>
void reconstructLagrangianFields
(
const word& cloudName,
const polyMesh& mesh,
const PtrList<fvMesh>& meshes,
const IOobjectList& objects
);
template<class Type> class passiveProcessorFvPatchField;
makePatchTypeFieldTypedefs(passiveProcessor)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -83,12 +46,6 @@ void reconstructLagrangianFields
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "reconstructLagrangianFields.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,116 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "passiveProcessorFvsPatchField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
passiveProcessorFvsPatchField<Type>::passiveProcessorFvsPatchField
(
const fvPatch& p,
const DimensionedField<Type, surfaceMesh>& iF
)
:
fvsPatchField<Type>(p, iF)
{}
template<class Type>
passiveProcessorFvsPatchField<Type>::passiveProcessorFvsPatchField
(
const fvPatch& p,
const DimensionedField<Type, surfaceMesh>& iF,
const Field<Type>& f
)
:
fvsPatchField<Type>(p, iF, f)
{}
// Construct by mapping given passiveProcessorFvsPatchField<Type>
template<class Type>
passiveProcessorFvsPatchField<Type>::passiveProcessorFvsPatchField
(
const passiveProcessorFvsPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, surfaceMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fvsPatchField<Type>(ptf, p, iF, mapper)
{}
template<class Type>
passiveProcessorFvsPatchField<Type>::passiveProcessorFvsPatchField
(
const fvPatch& p,
const DimensionedField<Type, surfaceMesh>& iF,
const dictionary& dict
)
:
fvsPatchField<Type>(p, iF, dict)
{}
template<class Type>
passiveProcessorFvsPatchField<Type>::passiveProcessorFvsPatchField
(
const passiveProcessorFvsPatchField<Type>& ptf
)
:
fvsPatchField<Type>(ptf)
{}
template<class Type>
passiveProcessorFvsPatchField<Type>::passiveProcessorFvsPatchField
(
const passiveProcessorFvsPatchField<Type>& ptf,
const DimensionedField<Type, surfaceMesh>& iF
)
:
fvsPatchField<Type>(ptf, iF)
{}
// * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * //
template<class Type>
passiveProcessorFvsPatchField<Type>::~passiveProcessorFvsPatchField()
{}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,151 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::passiveProcessorFvsPatchField
Description
This patch field is used in parallel load balancing to communicate
future processor data in parallel decomposition
SourceFiles
passiveProcessorFvsPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef passiveProcessorFvsPatchField_H
#define passiveProcessorFvsPatchField_H
#include "fvsPatchField.H"
#include "passiveProcessorFvPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class passiveProcessorFvsPatch Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class passiveProcessorFvsPatchField
:
public fvsPatchField<Type>
{
public:
//- Runtime type information
TypeName(passiveProcessorFvPatch::typeName_());
// Constructors
//- Construct from patch and internal field
passiveProcessorFvsPatchField
(
const fvPatch&,
const DimensionedField<Type, surfaceMesh>&
);
//- Construct from patch and internal field and patch field
passiveProcessorFvsPatchField
(
const fvPatch&,
const DimensionedField<Type, surfaceMesh>&,
const Field<Type>&
);
//- Construct from patch, internal field and dictionary
passiveProcessorFvsPatchField
(
const fvPatch&,
const DimensionedField<Type, surfaceMesh>&,
const dictionary&
);
//- Construct by mapping given passiveProcessorFvsPatchField
// onto a new patch
passiveProcessorFvsPatchField
(
const passiveProcessorFvsPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, surfaceMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
passiveProcessorFvsPatchField
(
const passiveProcessorFvsPatchField<Type>&
);
//- Construct and return a clone
virtual tmp<fvsPatchField<Type> > clone() const
{
return tmp<fvsPatchField<Type> >
(
new passiveProcessorFvsPatchField<Type>(*this)
);
}
//- Construct as copy setting internal field reference
passiveProcessorFvsPatchField
(
const passiveProcessorFvsPatchField<Type>&,
const DimensionedField<Type, surfaceMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvsPatchField<Type> > clone
(
const DimensionedField<Type, surfaceMesh>& iF
) const
{
return tmp<fvsPatchField<Type> >
(
new passiveProcessorFvsPatchField<Type>(*this, iF)
);
}
//- Destructor
virtual ~passiveProcessorFvsPatchField();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "passiveProcessorFvsPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,44 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "passiveProcessorFvsPatchFields.H"
#include "fvPatchFields.H"
#include "fvsPatchFields.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makeFvsPatchFields(passiveProcessor);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -23,53 +23,27 @@ License
\*---------------------------------------------------------------------------*/
#include "reconstructLagrangian.H"
#include "labelIOList.H"
#include "CloudTemplate.H"
#include "passiveParticle.H"
#ifndef passiveProcessorFvsPatchFields_H
#define passiveProcessorFvsPatchFields_H
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
#include "passiveProcessorFvsPatchField.H"
#include "fieldTypes.H"
void Foam::reconstructLagrangianPositions
(
const polyMesh& mesh,
const word& cloudName,
const PtrList<fvMesh>& meshes,
const PtrList<labelIOList>& faceProcAddressing,
const PtrList<labelIOList>& cellProcAddressing
)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
Cloud<passiveParticle> lagrangianPositions
(
mesh,
cloudName,
IDLList<passiveParticle>()
);
forAll(meshes, i)
{
const labelList& cellMap = cellProcAddressing[i];
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Cloud<passiveParticle> lpi(meshes[i], cloudName, false);
makeFvsPatchTypeFieldTypedefs(passiveProcessor)
forAllIter(Cloud<passiveParticle>, lpi, iter)
{
const passiveParticle& ppi = iter();
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
lagrangianPositions.append
(
new passiveParticle
(
lagrangianPositions,
ppi.position(),
cellMap[ppi.cell()]
)
);
}
}
} // End namespace Foam
IOPosition<passiveParticle>(lagrangianPositions).write();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef passiveProcessorFvsPatchFieldsFwd_H
#define passiveProcessorFvsPatchFieldsFwd_H
#include "fvsPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> class passiveProcessorFvsPatchField;
makeFvsPatchTypeFieldTypedefs(passiveProcessor)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "passiveProcessorFvPatch.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(passiveProcessorFvPatch, 0);
addToRunTimeSelectionTable(fvPatch, passiveProcessorFvPatch, polyPatch);
}
// ************************************************************************* //

View file

@ -0,0 +1,94 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::passiveProcessorFvPatch
Description
Passive processor fvPatch. See passiveProcessorPolyPatch
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
passiveProcessorFvPatch.C
\*---------------------------------------------------------------------------*/
#ifndef passiveProcessorFvPatch_H
#define passiveProcessorFvPatch_H
#include "coupledFvPatch.H"
#include "processorLduInterface.H"
#include "passiveProcessorPolyPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class passiveProcessorFvPatch Declaration
\*---------------------------------------------------------------------------*/
class passiveProcessorFvPatch
:
public fvPatch
{
public:
//- Runtime type information
TypeName(passiveProcessorPolyPatch::typeName_());
// Constructors
//- Construct from components
passiveProcessorFvPatch
(
const polyPatch& patch,
const fvBoundaryMesh& bm
)
:
fvPatch(patch, bm)
{}
//- Destructor
virtual ~passiveProcessorFvPatch()
{}
// Member functions
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,148 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "passiveProcessorPolyPatch.H"
#include "addToRunTimeSelectionTable.H"
#include "dictionary.H"
#include "SubField.H"
#include "matchPoints.H"
#include "OFstream.H"
#include "polyBoundaryMesh.H"
#include "polyMesh.H"
#include "foamTime.H"
#include "transformList.H"
#include "demandDrivenData.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(passiveProcessorPolyPatch, 0);
addToRunTimeSelectionTable
(
polyPatch,
passiveProcessorPolyPatch,
dictionary
);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::passiveProcessorPolyPatch::passiveProcessorPolyPatch
(
const word& name,
const label size,
const label start,
const label index,
const polyBoundaryMesh& bm,
const int myProcNo,
const int neighbProcNo,
const labelList& globalFaceIndex
)
:
polyPatch(name, size, start, index, bm),
myProcNo_(myProcNo),
neighbProcNo_(neighbProcNo),
globalFaceIndex_(globalFaceIndex)
{
if (globalFaceIndex.size() != size)
{
FatalErrorIn
(
"passiveProcessorPolyPatch::passiveProcessorPolyPatch(...)"
) << "Bad global index list. Patch size: " << this->size()
<< " global index size: " << globalFaceIndex.size()
<< abort(FatalError);
}
}
Foam::passiveProcessorPolyPatch::passiveProcessorPolyPatch
(
const word& name,
const dictionary& dict,
const label index,
const polyBoundaryMesh& bm
)
:
polyPatch(name, dict, index, bm),
myProcNo_(readLabel(dict.lookup("myProcNo"))),
neighbProcNo_(readLabel(dict.lookup("neighbProcNo"))),
globalFaceIndex_(dict.lookup("globalFaceIndex"))
{}
Foam::passiveProcessorPolyPatch::passiveProcessorPolyPatch
(
const passiveProcessorPolyPatch& pp,
const polyBoundaryMesh& bm
)
:
polyPatch(pp, bm),
myProcNo_(pp.myProcNo_),
neighbProcNo_(pp.neighbProcNo_),
globalFaceIndex_(pp.size(), -1)
{}
Foam::passiveProcessorPolyPatch::passiveProcessorPolyPatch
(
const passiveProcessorPolyPatch& pp,
const polyBoundaryMesh& bm,
const label index,
const label newSize,
const label newStart
)
:
polyPatch(pp, bm, index, newSize, newStart),
myProcNo_(pp.myProcNo_),
neighbProcNo_(pp.neighbProcNo_),
globalFaceIndex_(newSize, -1) // Cannot set global index. HJ, 4/May/2018
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::passiveProcessorPolyPatch::~passiveProcessorPolyPatch()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::passiveProcessorPolyPatch::write(Ostream& os) const
{
polyPatch::write(os);
os.writeKeyword("myProcNo") << myProcNo_
<< token::END_STATEMENT << nl;
os.writeKeyword("neighbProcNo") << neighbProcNo_
<< token::END_STATEMENT << nl;
globalFaceIndex_.writeEntry("globalFaceIndex", os);
}
// ************************************************************************* //

View file

@ -0,0 +1,187 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::passiveProcessorPolyPatch
Description
Passive processor polyPatch.
Passive processor polyPatch is created in load balancing when new processor
faces are built on each parallel decomposition. It contains the data
which is needed to rebuild correct processor boundaries after load balancing
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
passiveProcessorPolyPatch.C
\*---------------------------------------------------------------------------*/
#ifndef passiveProcessorPolyPatch_H
#define passiveProcessorPolyPatch_H
#include "polyBoundaryMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class passiveProcessorPolyPatch Declaration
\*---------------------------------------------------------------------------*/
class passiveProcessorPolyPatch
:
public polyPatch
{
// Private data
//- My processor number
int myProcNo_;
//- Neighbour processor number
int neighbProcNo_;
//- Global processor face index
labelList globalFaceIndex_;
public:
//- Runtime type information
TypeName("passiveProcessor");
// Constructors
//- Construct from components
passiveProcessorPolyPatch
(
const word& name,
const label size,
const label start,
const label index,
const polyBoundaryMesh& bm,
const int myProcNo,
const int neighbProcNo,
const labelList& globalFaceIndex
);
//- Construct from dictionary
passiveProcessorPolyPatch
(
const word& name,
const dictionary& dict,
const label index,
const polyBoundaryMesh&
);
//- Construct as copy, resetting the boundary mesh
passiveProcessorPolyPatch
(
const passiveProcessorPolyPatch&,
const polyBoundaryMesh&
);
//- Construct as given the original patch and resetting the
// face list and boundary mesh information
passiveProcessorPolyPatch
(
const passiveProcessorPolyPatch& pp,
const polyBoundaryMesh& bm,
const label index,
const label newSize,
const label newStart
);
//- Construct and return a clone, resetting the boundary mesh
virtual autoPtr<polyPatch> clone(const polyBoundaryMesh& bm) const
{
return autoPtr<polyPatch>(new passiveProcessorPolyPatch(*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
{
return autoPtr<polyPatch>
(
new passiveProcessorPolyPatch
(
refCast<const passiveProcessorPolyPatch>(*this),
bm,
index,
newSize,
newStart
)
);
}
//- Destructor
virtual ~passiveProcessorPolyPatch();
// Member functions
//- Return processor number
int myProcNo() const
{
return myProcNo_;
}
//- Return neigbour processor number
int neighbProcNo() const
{
return neighbProcNo_;
}
//- Return global processor face index
const labelList& globalFaceIndex() const
{
return globalFaceIndex_;
}
//- Write the polyPatch data as a dictionary
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -29,6 +29,7 @@ Description
Author
Zeljko Tukovic, FSB Zagreb. All rights reserved
Hrvoje Jasak, Wikki Ltd.
SourceFiles
faFieldReconstructor.C
@ -109,6 +110,11 @@ public:
{}
//- Destructor
virtual ~faPatchFieldReconstructor()
{}
// Member functions
virtual label size() const
@ -148,13 +154,33 @@ public:
// Member Functions
//- Reconstruct area field data into a given field
// If a PtrList slot is empty, it is skipped
template<class Type>
void reconstructFaAreaField
(
GeometricField<Type, faPatchField, areaMesh>& reconField,
const PtrList<GeometricField<Type, faPatchField, areaMesh> >&
procFields
) const;
//- Reconstruct area field
template<class Type>
tmp<GeometricField<Type, faPatchField, areaMesh> >
reconstructFaAreaField
(
const IOobject& fieldIoObject
);
) const;
//- Reconstruct edge field data into a given field
// If a PtrList slot is empty, it is skipped
template<class Type>
void reconstructFaEdgeField
(
GeometricField<Type, faePatchField, edgeMesh>& reconField,
const PtrList<GeometricField<Type, faePatchField, edgeMesh> >&
procFields
) const;
//- Reconstruct edge field
template<class Type>
@ -162,21 +188,21 @@ public:
reconstructFaEdgeField
(
const IOobject& fieldIoObject
);
) const;
//- Reconstruct and write all area fields
template<class Type>
void reconstructFaAreaFields
(
const IOobjectList& objects
);
) const;
//- Reconstruct and write all area fields
//- Reconstruct and write all edge fields
template<class Type>
void reconstructFaEdgeFields
(
const IOobjectList& objects
);
) const;
};

View file

@ -0,0 +1,705 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "faFieldReconstructor.H"
#include "foamTime.H"
#include "PtrList.H"
#include "faPatchFields.H"
#include "emptyFaPatch.H"
#include "emptyFaPatchField.H"
#include "emptyFaePatchField.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::faFieldReconstructor::reconstructFaAreaField
(
GeometricField<Type, faPatchField, areaMesh>& reconField,
const PtrList<GeometricField<Type, faPatchField, areaMesh> >& procFields
) const
{
// Get references to internal and boundary field
Field<Type>& iField = reconField.internalField();
typename GeometricField<Type, faPatchField, areaMesh>::
GeometricBoundaryField& bouField = reconField.boundaryField();
// Create global mesh patchs starts
labelList gStarts(mesh_.boundary().size(), -1);
if (mesh_.boundary().size() > 0)
{
gStarts[0] = mesh_.nInternalEdges();
}
for(label i = 1; i < mesh_.boundary().size(); i++)
{
gStarts[i] = gStarts[i - 1] + mesh_.boundary()[i - 1].labelList::size();
}
forAll (procFields, procI)
{
if (procFields.set(procI))
{
const GeometricField<Type, faPatchField, areaMesh>& procField =
procFields[procI];
// Set the face values in the reconstructed field
iField.rmap
(
procField.internalField(),
faceProcAddressing_[procI]
);
// Set the boundary patch values in the reconstructed field
labelList starts(procMeshes_[procI].boundary().size(), -1);
if (procMeshes_[procI].boundary().size() > 0)
{
starts[0] = procMeshes_[procI].nInternalEdges();
}
for(label i = 1; i < procMeshes_[procI].boundary().size(); i++)
{
starts[i] =
starts[i-1]
+ procMeshes_[procI].boundary()[i-1].labelList::size();
}
forAll (boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Get addressing slice for this patch
// const labelList::subList cp =
// procMeshes_[procI].boundary()[patchI].patchSlice
// (
// edgeProcAddressing_[procI]
// );
const labelList::subList cp =
labelList::subList
(
edgeProcAddressing_[procI],
procMeshes_[procI].boundary()[patchI].size(),
starts[patchI]
);
// Check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
// Regular patch. Fast looping
const label curPatchStart = gStarts[curBPatch];
// mesh_.boundary()[curBPatch].start();
labelList reverseAddressing(cp.size());
forAll (cp, edgeI)
{
// Subtract one to take into account offsets for
// face direction.
// reverseAddressing[edgeI] = cp[edgeI] - 1 - curPatchStart;
reverseAddressing[edgeI] = cp[edgeI] - curPatchStart;
}
bouField[curBPatch].rmap
(
procField.boundaryField()[patchI],
reverseAddressing
);
}
else
{
const Field<Type>& curProcPatch =
procField.boundaryField()[patchI];
// In processor patches, there's a mix of internal faces
// (some of them turned) and possible cyclics. Slow loop
forAll (cp, edgeI)
{
// Subtract one to take into account offsets for
// face direction.
// label curE = cp[edgeI] - 1;
label curE = cp[edgeI];
// Is the face on the boundary?
if (curE >= mesh_.nInternalEdges())
{
// label curBPatch = mesh_.boundary().whichPatch(curE);
label curBPatch = -1;
forAll (mesh_.boundary(), pI)
{
if
(
curE >= gStarts[pI]
&& curE <
(
gStarts[pI]
+ mesh_.boundary()[pI].labelList::size()
)
)
{
curBPatch = pI;
}
}
// add the edge
// label curPatchEdge =
// mesh_.boundary()
// [curBPatch].whichEdge(curE);
label curPatchEdge = curE - gStarts[curBPatch];
bouField[curBPatch][curPatchEdge] =
curProcPatch[edgeI];
}
}
}
}
}
}
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::faPatchField, Foam::areaMesh> >
Foam::faFieldReconstructor::reconstructFaAreaField
(
const IOobject& fieldIoObject
) const
{
// Read the field for all the processors
PtrList<GeometricField<Type, faPatchField, areaMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
procFields.set
(
procI,
new GeometricField<Type, faPatchField, areaMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI].time().timeName(),
procMeshes_[procI](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
}
// Create the patch fields
PtrList<faPatchField<Type> > patchFields(mesh_.boundary().size());
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
forAll (boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
// Regular patch. Clone with map
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
faPatchField<Type>::New
(
procFields[procI].boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, areaMesh>::null(),
faPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procFields[procI].boundaryField()
[patchI].size()
)
)
);
}
}
}
}
}
// Add missing patch fields
forAll (mesh_.boundary(), patchI)
{
if (!patchFields(patchI))
{
patchFields.set
(
patchI,
faPatchField<Type>::New
(
emptyFaPatchField<Type>::typeName,
mesh_.boundary()[patchI],
DimensionedField<Type, areaMesh>::null()
)
);
}
}
label firstValidMesh = 0;
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
firstValidMesh = procI;
break;
}
}
// Construct the reconstructed field with patches
tmp<GeometricField<Type, faPatchField, areaMesh> > treconField
(
new GeometricField<Type, faPatchField, areaMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[firstValidMesh].dimensions(),
Field<Type>(mesh_.nFaces()),
patchFields
)
);
reconstructFaAreaField
(
treconField(),
procFields
);
return treconField;
}
template<class Type>
void Foam::faFieldReconstructor::reconstructFaEdgeField
(
GeometricField<Type, Foam::faePatchField, Foam::edgeMesh>& reconField,
const PtrList<GeometricField<Type, faePatchField, edgeMesh> >& procFields
) const
{
// Get references to internal and boundary field
Field<Type>& iField = reconField.internalField();
typename GeometricField<Type, faePatchField, edgeMesh>::
GeometricBoundaryField& bouField = reconField.boundaryField();
labelList gStarts(mesh_.boundary().size(), -1);
if (mesh_.boundary().size() > 0)
{
gStarts[0] = mesh_.nInternalEdges();
}
for(label i = 1; i < mesh_.boundary().size(); i++)
{
gStarts[i] = gStarts[i - 1] + mesh_.boundary()[i - 1].labelList::size();
}
forAll (procMeshes_, procI)
{
if (procFields.set(procI))
{
const GeometricField<Type, faePatchField, edgeMesh>& procField =
procFields[procI];
// Set the edge values in the reconstructed field
// It is necessary to create a copy of the addressing array to
// take care of the face direction offset trick.
//
{
labelList curAddr(edgeProcAddressing_[procI]);
// forAll (curAddr, addrI)
// {
// curAddr[addrI] -= 1;
// }
iField.rmap
(
procField.internalField(),
curAddr
);
}
// Set the boundary patch values in the reconstructed field
labelList starts(procMeshes_[procI].boundary().size(), -1);
if (procMeshes_[procI].boundary().size() > 0)
{
starts[0] = procMeshes_[procI].nInternalEdges();
}
for (label i = 1; i < procMeshes_[procI].boundary().size(); i++)
{
starts[i] =
starts[i - 1]
+ procMeshes_[procI].boundary()[i - 1].labelList::size();
}
forAll (boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Get addressing slice for this patch
// const labelList::subList cp =
// procMeshes_[procI].boundary()[patchI].patchSlice
// (
// faceProcAddressing_[procI]
// );
const labelList::subList cp =
labelList::subList
(
edgeProcAddressing_[procI],
procMeshes_[procI].boundary()[patchI].size(),
starts[patchI]
);
// Check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
// Regular patch. Fast looping
const label curPatchStart = gStarts[curBPatch];
// mesh_.boundary()[curBPatch].start();
labelList reverseAddressing(cp.size());
forAll (cp, edgeI)
{
// Subtract one to take into account offsets for
// face direction.
// reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart;
reverseAddressing[edgeI] = cp[edgeI] - curPatchStart;
}
bouField[curBPatch].rmap
(
procField.boundaryField()[patchI],
reverseAddressing
);
}
else
{
const Field<Type>& curProcPatch =
procField.boundaryField()[patchI];
// In processor patches, there's a mix of internal faces
// (some of them turned) and possible cyclics. Slow loop
forAll (cp, edgeI)
{
// label curF = cp[edgeI] - 1;
label curE = cp[edgeI];
// Is the face turned the right side round
if (curE >= 0)
{
// Is the face on the boundary?
if (curE >= mesh_.nInternalEdges())
{
// label curBPatch =
// mesh_.boundary().whichPatch(curF);
label curBPatch = -1;
forAll (mesh_.boundary(), pI)
{
if
(
curE >= gStarts[pI]
&& curE <
(
gStarts[pI]
+ mesh_.boundary()[pI].labelList::size()
)
)
{
curBPatch = pI;
}
}
// add the face
// label curPatchFace =
// mesh_.boundary()
// [curBPatch].whichEdge(curF);
label curPatchEdge = curE - gStarts[curBPatch];
bouField[curBPatch][curPatchEdge] =
curProcPatch[edgeI];
}
else
{
// Internal face
iField[curE] = curProcPatch[edgeI];
}
}
}
}
}
}
}
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::faePatchField, Foam::edgeMesh> >
Foam::faFieldReconstructor::reconstructFaEdgeField
(
const IOobject& fieldIoObject
) const
{
// Read the field for all the processors
PtrList<GeometricField<Type, faePatchField, edgeMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
procFields.set
(
procI,
new GeometricField<Type, faePatchField, edgeMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI].time().timeName(),
procMeshes_[procI](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
}
// Create the patch fields
PtrList<faePatchField<Type> > patchFields(mesh_.boundary().size());
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
// Set the boundary patch in the reconstructed field
forAll(boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
// Regular patch. Clone with map
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
faePatchField<Type>::New
(
procFields[procI].boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, edgeMesh>::null(),
faPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procFields[procI].boundaryField()
[patchI].size()
)
)
);
}
}
}
}
}
// Add missing patch fields
forAll (mesh_.boundary(), patchI)
{
// add empty patches
if (!patchFields(patchI))
{
patchFields.set
(
patchI,
faePatchField<Type>::New
(
emptyFaePatchField<Type>::typeName,
mesh_.boundary()[patchI],
DimensionedField<Type, edgeMesh>::null()
)
);
}
}
label firstValidMesh = 0;
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
firstValidMesh = procI;
break;
}
}
// Construct the reconstructed field with patches
tmp<GeometricField<Type, faePatchField, edgeMesh> > treconField
(
new GeometricField<Type, faePatchField, edgeMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[firstValidMesh].dimensions(),
Field<Type>(mesh_.nInternalEdges()),
patchFields
)
);
// Reconstruct field
reconstructFaEdgeField
(
treconField(),
procFields
);
return treconField;
}
// Reconstruct and write all area fields
template<class Type>
void Foam::faFieldReconstructor::reconstructFaAreaFields
(
const IOobjectList& objects
) const
{
const word& fieldClassName =
GeometricField<Type, faPatchField, areaMesh>::typeName;
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
for
(
IOobjectList::const_iterator fieldIter = fields.begin();
fieldIter != fields.end();
++fieldIter
)
{
Info << " " << fieldIter()->name() << endl;
reconstructFaAreaField<Type>(*fieldIter())().write();
}
Info<< endl;
}
}
// Reconstruct and write all edge fields
template<class Type>
void Foam::faFieldReconstructor::reconstructFaEdgeFields
(
const IOobjectList& objects
) const
{
const word& fieldClassName =
GeometricField<Type, faePatchField, edgeMesh>::typeName;
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
for
(
IOobjectList::const_iterator fieldIter = fields.begin();
fieldIter != fields.end();
++fieldIter
)
{
Info<< " " << fieldIter()->name() << endl;
reconstructFaEdgeField<Type>(*fieldIter())().write();
}
Info<< endl;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,156 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "processorFaMeshes.H"
#include "foamTime.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::processorFaMeshes::readMeshes()
{
forAll (fvMeshes_, procI)
{
if (fvMeshes_.set(procI))
{
meshes_.set
(
procI,
new faMesh(fvMeshes_[procI])
);
pointProcAddressing_.set
(
procI,
new labelIOList
(
IOobject
(
"pointProcAddressing",
meshes_[procI].time().findInstance
(
meshes_[procI].meshDir(),
"pointProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
edgeProcAddressing_.set
(
procI,
new labelIOList
(
IOobject
(
"edgeProcAddressing",
meshes_[procI].time().findInstance
(
meshes_[procI].meshDir(),
"edgeProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
faceProcAddressing_.set
(
procI,
new labelIOList
(
IOobject
(
"faceProcAddressing",
meshes_[procI].time().findInstance
(
meshes_[procI].meshDir(),
"faceProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
boundaryProcAddressing_.set
(
procI,
new labelIOList
(
IOobject
(
"boundaryProcAddressing",
meshes_[procI].time().findInstance
(
meshes_[procI].meshDir(),
"faceProcAddressing"
),
meshes_[procI].meshSubDir,
fvMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::processorFaMeshes::processorFaMeshes
(
const PtrList<fvMesh>& processorFvMeshes,
const bool read
)
:
fvMeshes_(processorFvMeshes),
meshes_(processorFvMeshes.size()),
pointProcAddressing_(processorFvMeshes.size()),
edgeProcAddressing_(processorFvMeshes.size()),
faceProcAddressing_(processorFvMeshes.size()),
boundaryProcAddressing_(processorFvMeshes.size())
{
if (read)
{
readMeshes();
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// ************************************************************************* //

View file

@ -80,7 +80,10 @@ class processorFaMeshes
// Private Member Functions
//- Read all meshes
void read();
void readMeshes();
//- Return first valid mesh index
label firstValidMesh() const;
//- Disallow default bitwise copy construct
processorFaMeshes(const processorFaMeshes&);
@ -94,34 +97,40 @@ public:
// Constructors
//- Construct from components
processorFaMeshes(const PtrList<fvMesh>& processorFvMeshes);
processorFaMeshes
(
const PtrList<fvMesh>& processorFvMeshes,
const bool read
);
// Member Functions
//- Update the meshes based on the mesh files saved in
// time directories
// fvMesh::readUpdateState readUpdate();
//- Reconstruct point position after motion in parallel
// void reconstructPoints(faMesh& mesh);
PtrList<faMesh>& meshes()
//- Return meshes
const PtrList<faMesh>& meshes() const
{
return meshes_;
}
//- Return point addressing
const PtrList<labelIOList>& pointProcAddressing() const
{
return pointProcAddressing_;
}
//- Return edge addressing
PtrList<labelIOList>& edgeProcAddressing()
{
return edgeProcAddressing_;
}
//- Return face addressing
const PtrList<labelIOList>& faceProcAddressing() const
{
return faceProcAddressing_;
}
//- Return boundary addressing
const PtrList<labelIOList>& boundaryProcAddressing() const
{
return boundaryProcAddressing_;

View file

@ -49,7 +49,7 @@ namespace Foam
/*---------------------------------------------------------------------------*\
Class fvFieldReconstructor Declaration
Class fvFieldReconstructor Declaration
\*---------------------------------------------------------------------------*/
class fvFieldReconstructor
@ -106,6 +106,11 @@ public:
{}
//- Destructor
virtual ~fvPatchFieldReconstructor()
{}
// Member functions
virtual label size() const
@ -143,39 +148,70 @@ public:
);
// Destructor - default
// Member Functions
//- Reconstruct volume field
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh> >
reconstructFvVolumeField
(
const IOobject& fieldIoObject
);
// Single field reconstruction
//- Reconstruct surface field
template<class Type>
tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
reconstructFvSurfaceField
(
const IOobject& fieldIoObject
);
//- Reconstruct volume field data into a given field
// If a PtrList slot is empty, it is skipped
template<class Type>
void reconstructField
(
GeometricField<Type, fvPatchField, volMesh>& reconField,
const PtrList<GeometricField<Type, fvPatchField, volMesh> >&
procFields
) const;
//- Reconstruct and write all/selected volume fields
template<class Type>
void reconstructFvVolumeFields
(
const IOobjectList& objects,
const HashSet<word>& selectedFields
);
//- Reconstruct volume field data into a given field
// If a PtrList slot is empty, it is skipped
template<class Type>
void reconstructField
(
GeometricField<Type, fvsPatchField, surfaceMesh>& reconField,
const PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> >&
procFields
) const;
//- Reconstruct and write all/selected volume fields
template<class Type>
void reconstructFvSurfaceFields
(
const IOobjectList& objects,
const HashSet<word>& selectedFields
);
// Reconstruct and return a single field
//- Reconstruct volume field
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh> >
reconstructFvVolumeField
(
const IOobject& fieldIoObject
) const;
//- Reconstruct surface field
template<class Type>
tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
reconstructFvSurfaceField
(
const IOobject& fieldIoObject
) const;
// Reconstruct and write all/selected fields
//- Reconstruct and write all/selected volume fields
template<class Type>
void reconstructFvVolumeFields
(
const IOobjectList& objects,
const HashSet<word>& selectedFields
) const;
//- Reconstruct and write all/selected volume fields
template<class Type>
void reconstructFvSurfaceFields
(
const IOobjectList& objects,
const HashSet<word>& selectedFields
) const;
};

View file

@ -0,0 +1,601 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "fvFieldReconstructor.H"
#include "foamTime.H"
#include "PtrList.H"
#include "fvPatchFields.H"
#include "emptyFvPatch.H"
#include "emptyFvPatchField.H"
#include "emptyFvsPatchField.H"
#include "processorFvPatch.H"
#include "processorFvPatchField.H"
#include "processorFvsPatchField.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::fvFieldReconstructor::reconstructField
(
GeometricField<Type, fvPatchField, volMesh>& reconField,
const PtrList<GeometricField<Type, fvPatchField, volMesh> >& procFields
) const
{
// Get references to internal and boundary field
Field<Type>& iField = reconField.internalField();
typename GeometricField<Type, fvPatchField, volMesh>::
GeometricBoundaryField& bouField = reconField.boundaryField();
forAll (procFields, procI)
{
if (procFields.set(procI))
{
const GeometricField<Type, fvPatchField, volMesh>& procField =
procFields[procI];
// Set the cell values in the reconstructed field
iField.rmap
(
procField.internalField(),
cellProcAddressing_[procI]
);
// Set the boundary patch values in the reconstructed field
forAll (boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Get addressing slice for this patch
const labelList::subList cp =
procMeshes_[procI].boundary()[patchI].patchSlice
(
faceProcAddressing_[procI]
);
// Check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
// Regular patch. Fast looping
const label curPatchStart =
mesh_.boundaryMesh()[curBPatch].start();
labelList reverseAddressing(cp.size());
forAll (cp, faceI)
{
// Subtract one to take into account offsets for
// face direction.
reverseAddressing[faceI] =
cp[faceI] - 1 - curPatchStart;
}
bouField[curBPatch].rmap
(
procField.boundaryField()[patchI],
reverseAddressing
);
}
else
{
const Field<Type>& curProcPatch =
procField.boundaryField()[patchI];
// General mapping: patch to patch or patch to/from internal
// In processor patches, there's a mix of internal faces
// (some of them turned) and possible cyclics. Slow loop
forAll (cp, faceI)
{
// Subtract one to take into account offsets for
// face direction.
label curF = cp[faceI] - 1;
// Is the face on the boundary?
if (curF >= mesh_.nInternalFaces())
{
label curBPatch =
mesh_.boundaryMesh().whichPatch(curF);
// Add the face
label curPatchFace =
mesh_.boundaryMesh()[curBPatch].whichFace(curF);
bouField[curBPatch][curPatchFace] =
curProcPatch[faceI];
}
}
}
}
}
}
}
template<class Type>
void Foam::fvFieldReconstructor::reconstructField
(
GeometricField<Type, fvsPatchField, surfaceMesh>& reconField,
const PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> >& procFields
) const
{
// Create the internalField
Field<Type>& iField = reconField.internalField();
typename GeometricField<Type, fvsPatchField, surfaceMesh>::
GeometricBoundaryField& bouField = reconField.boundaryField();
forAll (procFields, procI)
{
if (procFields.set(procI))
{
const GeometricField<Type, fvsPatchField, surfaceMesh>& procField =
procFields[procI];
// Set the face values in the reconstructed field
// It is necessary to create a copy of the addressing array to
// take care of the face direction offset trick.
//
{
labelList curAddr(faceProcAddressing_[procI]);
forAll (curAddr, addrI)
{
curAddr[addrI] -= 1;
}
iField.rmap
(
procField.internalField(),
curAddr
);
}
// Set the boundary patch values in the reconstructed field
forAll (boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Get addressing slice for this patch
const labelList::subList cp =
procMeshes_[procI].boundary()[patchI].patchSlice
(
faceProcAddressing_[procI]
);
// Check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
// Regular patch. Fast looping
const label curPatchStart =
mesh_.boundaryMesh()[curBPatch].start();
labelList reverseAddressing(cp.size());
forAll (cp, faceI)
{
// Subtract one to take into account offsets for
// face direction.
reverseAddressing[faceI] =
cp[faceI] - 1 - curPatchStart;
}
bouField[curBPatch].rmap
(
procField.boundaryField()[patchI],
reverseAddressing
);
}
else
{
const Field<Type>& curProcPatch =
procField.boundaryField()[patchI];
// In processor patches, there's a mix of internal faces
// (some of them turned) and possible cyclics. Slow loop
forAll (cp, faceI)
{
label curF = cp[faceI] - 1;
// Is the face turned the right side round
if (curF >= 0)
{
// Is the face on the boundary?
if (curF >= mesh_.nInternalFaces())
{
label curBPatch =
mesh_.boundaryMesh().whichPatch(curF);
// Add the face
label curPatchFace =
mesh_.boundaryMesh()
[curBPatch].whichFace(curF);
bouField[curBPatch][curPatchFace] =
curProcPatch[faceI];
}
else
{
// Internal face
iField[curF] = curProcPatch[faceI];
}
}
}
}
}
}
}
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::fvFieldReconstructor::reconstructFvVolumeField
(
const IOobject& fieldIoObject
) const
{
// Read the field for all the processors
PtrList<GeometricField<Type, fvPatchField, volMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
procFields.set
(
procI,
new GeometricField<Type, fvPatchField, volMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI].time().timeName(),
procMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
}
// Create the patch fields
PtrList<fvPatchField<Type> > patchFields(mesh_.boundary().size());
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
// Set the boundary patch in the reconstructed field
forAll (boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Check if the boundary field is a regular patch field
if (curBPatch >= 0)
{
// Regular patch. Clone with map
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
fvPatchField<Type>::New
(
procFields[procI].boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, volMesh>::null(),
fvPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procFields[procI].boundaryField()
[patchI].size()
)
)
);
}
}
}
}
}
// Add missing patch fields
forAll (mesh_.boundary(), patchI)
{
if (!patchFields(patchI))
{
patchFields.set
(
patchI,
fvPatchField<Type>::New
(
mesh_.boundary()[patchI].type(),
mesh_.boundary()[patchI],
DimensionedField<Type, volMesh>::null()
)
);
}
}
label firstValidMesh = 0;
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
firstValidMesh = procI;
break;
}
}
// Construct the reconstructed field with patches
tmp<GeometricField<Type, fvPatchField, volMesh> > treconField
(
new GeometricField<Type, fvPatchField, volMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[firstValidMesh].dimensions(),
Field<Type>(mesh_.nCells()),
patchFields
)
);
// Reconstruct field
this->reconstructField
(
treconField(),
procFields
);
return treconField;
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
Foam::fvFieldReconstructor::reconstructFvSurfaceField
(
const IOobject& fieldIoObject
) const
{
// Read the field for all the processors
PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
procFields.set
(
procI,
new GeometricField<Type, fvsPatchField, surfaceMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI].time().timeName(),
procMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
}
// Create the patch fields
PtrList<fvsPatchField<Type> > patchFields(mesh_.boundary().size());
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
// Set the boundary patch in the reconstructed field
forAll (boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
// Regular patch. Fast looping
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
fvsPatchField<Type>::New
(
procFields[procI].boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, surfaceMesh>::null(),
fvPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procFields[procI].boundaryField()
[patchI].size()
)
)
);
}
}
}
}
}
// Add missing patch fields
forAll (mesh_.boundary(), patchI)
{
if (!patchFields(patchI))
{
patchFields.set
(
patchI,
fvsPatchField<Type>::New
(
mesh_.boundary()[patchI].type(),
mesh_.boundary()[patchI],
DimensionedField<Type, surfaceMesh>::null()
)
);
}
}
label firstValidMesh = 0;
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
firstValidMesh = procI;
break;
}
}
// Now construct the field with patches
tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > treconField
(
new GeometricField<Type, fvsPatchField, surfaceMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[firstValidMesh].dimensions(),
Field<Type>(mesh_.nInternalFaces()),
patchFields
)
);
// Reconstruct field
reconstructField
(
treconField(),
procFields
);
return treconField;
}
// Reconstruct and write all/selected volume fields
template<class Type>
void Foam::fvFieldReconstructor::reconstructFvVolumeFields
(
const IOobjectList& objects,
const HashSet<word>& selectedFields
) const
{
const word& fieldClassName =
GeometricField<Type, fvPatchField, volMesh>::typeName;
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
forAllConstIter(IOobjectList, fields, fieldIter)
{
if
(
!selectedFields.size()
|| selectedFields.found(fieldIter()->name())
)
{
Info<< " " << fieldIter()->name() << endl;
reconstructFvVolumeField<Type>(*fieldIter())().write();
}
}
Info<< endl;
}
}
// Reconstruct and write all/selected surface fields
template<class Type>
void Foam::fvFieldReconstructor::reconstructFvSurfaceFields
(
const IOobjectList& objects,
const HashSet<word>& selectedFields
) const
{
const word& fieldClassName =
GeometricField<Type, fvsPatchField, surfaceMesh>::typeName;
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
forAllConstIter(IOobjectList, fields, fieldIter)
{
if
(
!selectedFields.size()
|| selectedFields.found(fieldIter()->name())
)
{
Info<< " " << fieldIter()->name() << endl;
reconstructFvSurfaceField<Type>(*fieldIter())().write();
}
}
Info<< endl;
}
}
// ************************************************************************* //

View file

@ -27,9 +27,9 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::processorMeshesReconstructor::readMeshes()
void Foam::processorMeshesReconstructor::readMeshes(PtrList<Time>& databases)
{
forAll (databases_, procI)
forAll (databases, procI)
{
Info<< "Reading mesh for processor " << procI << endl;
meshes_.set
@ -40,8 +40,8 @@ void Foam::processorMeshesReconstructor::readMeshes()
IOobject
(
meshName_,
databases_[procI].timeName(),
databases_[procI]
databases[procI].timeName(),
databases[procI]
)
)
);
@ -64,13 +64,26 @@ void Foam::processorMeshesReconstructor::clearMaps()
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::processorMeshesReconstructor::processorMeshesReconstructor
(
const word& meshName
)
:
meshName_(meshName),
meshes_(),
pointProcAddressing_(),
faceProcAddressing_(),
cellProcAddressing_(),
boundaryProcAddressing_()
{}
Foam::processorMeshesReconstructor::processorMeshesReconstructor
(
PtrList<Time>& databases,
const word& meshName
)
:
databases_(databases),
meshName_(meshName),
meshes_(databases.size()),
pointProcAddressing_(),
@ -78,7 +91,7 @@ Foam::processorMeshesReconstructor::processorMeshesReconstructor
cellProcAddressing_(),
boundaryProcAddressing_()
{
readMeshes();
readMeshes(databases);
}
@ -89,29 +102,34 @@ Foam::processorMeshesReconstructor::readUpdate()
{
polyMesh::readUpdateState stat = polyMesh::UNCHANGED;
forAll (databases_, procI)
forAll (meshes_, procI)
{
// Check if any new meshes need to be read.
polyMesh::readUpdateState procStat = meshes_[procI].readUpdate();
// Only do action if database has been set
if (meshes_.set(procI))
{
// Check if any new meshes need to be read.
polyMesh::readUpdateState procStat = meshes_[procI].readUpdate();
// Combine into overall mesh change status
if (stat == polyMesh::UNCHANGED)
{
stat = procStat;
}
else
{
if (stat != procStat)
// Combine into overall mesh change status
if (stat == polyMesh::UNCHANGED)
{
FatalErrorIn("processorMeshesReconstructor::readUpdate()")
<< "Processor " << procI
<< " has a different polyMesh at time "
<< databases_[procI].timeName()
<< " compared to any previous processors." << nl
<< "Please check time " << databases_[procI].timeName()
<< " directories on all processors for consistent"
<< " mesh files."
<< exit(FatalError);
stat = procStat;
}
else
{
if (stat != procStat)
{
FatalErrorIn("processorMeshesReconstructor::readUpdate()")
<< "Processor " << procI
<< " has a different polyMesh at time "
<< meshes_[procI].time().timeName()
<< " compared to any previous processors." << nl
<< "Please check time "
<< meshes_[procI].time().timeName()
<< " directories on all processors for consistent"
<< " mesh files."
<< exit(FatalError);
}
}
}
}

View file

@ -25,6 +25,14 @@ Class
Foam::processorMeshesReconstructor
Description
The processorMeshesReconstructor will take a list of meshes with
matching processor boundaries and build a single combined mesh by
matching processor patches to each other.
In order to
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
processorMeshesReconstructor.C
@ -51,16 +59,14 @@ namespace Foam
class processorPolyPatch;
/*---------------------------------------------------------------------------*\
Class processorMeshesReconstructor Declaration
Class processorMeshesReconstructor Declaration
\*---------------------------------------------------------------------------*/
class processorMeshesReconstructor
{
// Private data
//- Processor databases
PtrList<Time>& databases_;
//- Name of mesh region to reconstruct
const word meshName_;
//- List of processor meshes
@ -89,11 +95,14 @@ class processorMeshesReconstructor
//- Read all meshes
void readMeshes();
void readMeshes(PtrList<Time>& databases);
//- Attempt to read mapping. If not available, return false
bool readMapping();
//- Return first valid mesh index
label firstValidMesh() const;
//- Return neighbour processor patch
const processorPolyPatch& neighbourProcPatch
(
@ -114,7 +123,10 @@ public:
// Constructors
//- Construct from components
//- Construct given name. Set meshes later
processorMeshesReconstructor(const word& meshName);
//- Construct reading meshes from databases
processorMeshesReconstructor
(
PtrList<Time>& databases,
@ -138,7 +150,13 @@ public:
void reconstructPoints(fvMesh& mesh) const;
//- Return meshes
const PtrList<fvMesh>& meshes()
const PtrList<fvMesh>& meshes() const
{
return meshes_;
}
//- Return access to meshes
PtrList<fvMesh>& meshes()
{
return meshes_;
}

View file

@ -0,0 +1,412 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "sharedPoints.H"
#include "processorPolyPatch.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::labelListList Foam::sharedPoints::procPatchPairs() const
{
labelListList patchPairs(meshes_.size());
// Initialise patch pair indices to -1
forAll (meshes_, meshI)
{
if (meshes_.set(meshI))
{
patchPairs[meshI].setSize(meshes_[meshI].boundaryMesh().size(), -1);
}
}
forAll (meshes_, meshI)
{
if (meshes_.set(meshI))
{
const polyMesh& curMesh = meshes_[meshI];
const polyBoundaryMesh& curPatches = curMesh.boundaryMesh();
forAll (curPatches, patchI)
{
if (isA<processorPolyPatch>(curPatches[patchI]))
{
// Found processor patch
if (patchPairs[meshI][patchI] == -1)
{
// Neighbour not found. Find one
const processorPolyPatch& myProcPatch =
refCast<const processorPolyPatch>
(
curPatches[patchI]
);
const int myProcID = meshI;
const int nbrProcID = myProcPatch.neighbProcNo();
// Get the other mesh
if (!meshes_.set(nbrProcID))
{
FatalErrorIn
(
"labelListList sharedPoints::procPatchPairs()"
) << "Neighbour mesh does not exist for proc "
<< meshI << " patch " << patchI
<< " and neighbour " << nbrProcID
<< abort(FatalError);
}
const polyMesh& nbrMesh = meshes_[nbrProcID];
const polyBoundaryMesh& nbrPatches =
nbrMesh.boundaryMesh();
// Check all neighbour processor patches until a match
// is found
bool found = false;
forAll (nbrPatches, nbrPatchI)
{
if (isA<processorPolyPatch>(nbrPatches[nbrPatchI]))
{
const processorPolyPatch& nbrProcPatch =
refCast<const processorPolyPatch>
(
nbrPatches[nbrPatchI]
);
if (nbrProcPatch.neighbProcNo() == myProcID)
{
// Pair found. Record it twice
patchPairs[myProcID][patchI] = nbrPatchI;
patchPairs[nbrProcID][nbrPatchI] = patchI;
found = true;
}
}
if (found)
{
break;
}
}
if (!found)
{
FatalErrorIn
(
"labelListList sharedPoints::procPatchPairs()"
) << "Neighbour patch does not exist for proc "
<< meshI << " patch " << patchI
<< " and neighbour " << nbrProcID
<< abort(FatalError);
}
}
}
}
}
}
return patchPairs;
}
void Foam::sharedPoints::calcSharedPoints()
{
// Algorithm
// Go through all processor patches and mark local points that are used
// by more than one processor patch and mark them as globally shared
// Pass the data to other processors. Mark the locally multiply shared
// points and pass on the data
// Once all the data is passed forwards and back, check all points on
// all processors. Record globally shared point, its local label and its
// slot in the globally shared point list
// Mark-up:
// 0 = point does not touch a processor boundary
// 1 = point on only one processor boundary: not locally shared
// 2 = locally detected global point
// Mark-up array: procI, procJ,
labelListList markedPoints(meshes_.size());
forAll (meshes_, meshI)
{
if (meshes_.set(meshI))
{
markedPoints[meshI].setSize(meshes_[meshI].nPoints(), 0);
}
}
// Mark up points for the first time
forAll (meshes_, meshI)
{
if (meshes_.set(meshI))
{
const polyMesh& curMesh = meshes_[meshI];
const polyBoundaryMesh& patches = curMesh.boundaryMesh();
// Mark points belonging to processor patches. If the point
// is marked more than once, it may be a globally shared point
labelList& curMarkedPoints = markedPoints[meshI];
forAll (patches, patchI)
{
const polyPatch& pp = patches[patchI];
if (isA<processorPolyPatch>(pp))
{
// Found processor patch
const labelList& patchMeshPoints = pp.meshPoints();
forAll (patchMeshPoints, mpI)
{
// Mark the point
curMarkedPoints[patchMeshPoints[mpI]]++;
}
}
}
}
}
// Get processor patch to neighbour processor patch addressing
labelListList patchPairs = procPatchPairs();
// Communicate and count global points
labelList nGlobalPointsPerProc(meshes_.size(), 0);
// Identify, count and communicate points across processor boundaries
// Repeat until the number of points per processor stabilises,
// ie. no further points are found through communication
label oldNTotalPoints, newNTotalPoints;
do
{
oldNTotalPoints = sum(nGlobalPointsPerProc);
// Reset the list
nGlobalPointsPerProc = 0;
forAll (meshes_, meshI)
{
if (meshes_.set(meshI))
{
const polyMesh& curMesh = meshes_[meshI];
const polyBoundaryMesh& patches = curMesh.boundaryMesh();
labelList& curMarkedPoints = markedPoints[meshI];
// Collect the points that have been addressed multiple times
forAll (patches, patchI)
{
const polyPatch& pp = patches[patchI];
if (isA<processorPolyPatch>(pp))
{
// Found processor patch
const labelList& patchMeshPoints = pp.meshPoints();
// My processor patch
const processorPolyPatch& myProcPatch =
refCast<const processorPolyPatch>(pp);
// Get neighbour processor ID
const int nbrProcID = myProcPatch.neighbProcNo();
// Neighbour patch
const polyPatch& nbrPatch =
meshes_[nbrProcID].boundaryMesh()
[patchPairs[meshI][patchI]];
const labelList& nbrMeshPoints = nbrPatch.meshPoints();
forAll (patchMeshPoints, mpI)
{
if (curMarkedPoints[patchMeshPoints[mpI]] > 1)
{
// Mark the point on the other processor/side
markedPoints[nbrProcID][nbrMeshPoints[mpI]] =
curMarkedPoints[patchMeshPoints[mpI]];
}
}
}
}
// Count number of shared points per processor
forAll (curMarkedPoints, cpI)
{
if (curMarkedPoints[cpI] > 1)
{
nGlobalPointsPerProc[meshI]++;
}
}
}
}
newNTotalPoints = sum(nGlobalPointsPerProc);
Info<< "Proc merge pass: " << oldNTotalPoints << " "
<< newNTotalPoints << endl;
} while (oldNTotalPoints != newNTotalPoints);
Info<< "Number of shared points per processor: " << nGlobalPointsPerProc
<< endl;
// Collect points for every processor, in order to re-use the markedPoints
// list. Note: the list of global labels of shared points
// will be collected later
forAll (meshes_, meshI)
{
if (meshes_.set(meshI))
{
labelList& curSharedPoints = sharedPointLabels_[meshI];
curSharedPoints.setSize(nGlobalPointsPerProc[meshI]);
// Count inserted points
label nShared = 0;
// Get point marking
const labelList& curMarkedPoints = markedPoints[meshI];
forAll (curMarkedPoints, pointI)
{
if (curMarkedPoints[pointI] > 1)
{
curSharedPoints[nShared] = pointI;
nShared++;
}
}
}
}
// Clear markup list. It will be used for the global processor point
forAll (markedPoints, meshI)
{
markedPoints[meshI] = -1;
}
// Provide global mark for all processors and communicate it across
// processor boundaries
forAll (meshes_, meshI)
{
if (meshes_.set(meshI))
{
const polyMesh& curMesh = meshes_[meshI];
const polyBoundaryMesh& patches = curMesh.boundaryMesh();
// Get shared points and assign global shared point index
const labelList& curSharedPoints = sharedPointLabels_[meshI];
// Prepare addressing into the global shared point list
labelList& curSharedAddr = sharedPointAddr_[meshI];
curSharedAddr.setSize(curSharedPoints.size());
labelList& curMarkedPoints = markedPoints[meshI];
forAll (curSharedPoints, spI)
{
if (curMarkedPoints[curSharedPoints[spI]] == -1)
{
// Found new point. Mark it and collect addressing
curMarkedPoints[curSharedPoints[spI]] = nGlobalPoints_;
// Collect addressing
curSharedAddr[spI] = nGlobalPoints_;
nGlobalPoints_++;
}
else
{
// Point already marked. Collect addressing
curSharedAddr[spI] = curMarkedPoints[curSharedPoints[spI]];
}
}
// Communicate labels accross the boundary using processor patches
forAll (patches, patchI)
{
const polyMesh& curMesh = meshes_[meshI];
const polyBoundaryMesh& patches = curMesh.boundaryMesh();
// Get point marking
const labelList& curMarkedPoints = markedPoints[meshI];
const polyPatch& pp = patches[patchI];
if (isA<processorPolyPatch>(pp))
{
// Found processor patch
// My processor patch
const processorPolyPatch& myProcPatch =
refCast<const processorPolyPatch>(pp);
const labelList& patchMeshPoints = pp.meshPoints();
// Get neighbour processor ID
const int nbrProcID = myProcPatch.neighbProcNo();
// Neighbour patch
const polyPatch& nbrPatch =
meshes_[nbrProcID].boundaryMesh()
[patchPairs[meshI][patchI]];
const labelList& nbrMeshPoints = nbrPatch.meshPoints();
forAll (patchMeshPoints, mpI)
{
if (curMarkedPoints[patchMeshPoints[mpI]] > -1)
{
// Mark opposite side
markedPoints[nbrProcID][nbrMeshPoints[mpI]] =
curMarkedPoints[patchMeshPoints[mpI]];
}
}
}
}
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::sharedPoints::sharedPoints(const PtrList<fvMesh>& meshes)
:
meshes_(meshes),
sharedPointAddr_(meshes_.size()),
sharedPointLabels_(meshes_.size()),
nGlobalPoints_(0)
{
calcSharedPoints();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
// Foam::sharedPoints::~sharedPoints()
// {}
// ************************************************************************* //

View file

@ -0,0 +1,166 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::sharedPoints
Description
Calculates points shared by more than two processor patches from a list
of meshes.
Works purely on topology.
Needs:
- domain to be one single domain (i.e. all faces can be reached through
face-cell walk).
- patch face ordering to be ok
- f[0] ordering on patch faces to be ok.
Works by constructing equivalence lists for all the points on processor
patches. These list are procPointList and give processor and meshPoint
label on that processor.
E.g.
@verbatim
((7 93)(4 731)(3 114))
@endverbatim
means point 93 on proc7 is connected to point 731 on proc4 and 114 on proc3.
It then gets the lowest numbered processor (the 'master') to request a
sharedPoint label from processor0 and it redistributes this label back to
the other processors in the equivalence list.
Note
Currently operating with a PtrList<fvMesh>, whereas the operation actually
works on PtrList<polyMesh> as well, due to the calling side
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved
SourceFiles
sharedPoints.C
\*---------------------------------------------------------------------------*/
#ifndef sharedPoints_H
#define sharedPoints_H
#include "PtrList.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class sharedPoints Declaration
\*---------------------------------------------------------------------------*/
class sharedPoints
{
// Private typedefs
//- Define procPointList as holding a list of meshPoint/processor labels
typedef FixedList<label, 2> procPoint;
typedef List<procPoint> procPointList;
// Private data
//- List of meshes
const PtrList<fvMesh>& meshes_;
//- Shared points used by this processor (= global point number)
labelListList sharedPointAddr_;
//- My mesh points corresponding to the shared points
labelListList sharedPointLabels_;
//- Total number of shared points.
label nGlobalPoints_;
// Private Member Functions
//- Disallow default bitwise copy construct
sharedPoints(const sharedPoints&) = delete;
//- Disallow default bitwise assignment
void operator=(const sharedPoints&) = delete;
//- Calculate processor patch pairs
// For each processor patch, find equivalent patch on other mesh
labelListList procPatchPairs() const;
//- Calculate shared points
void calcSharedPoints();
public:
// Static data members
// Constructors
//- Construct from the list of meshes
sharedPoints(const PtrList<fvMesh>& meshes);
//- Destructor
~sharedPoints() = default;
// Member Functions
// Access
//- Shared points used by this processor (= global point number)
inline const labelListList& sharedPointAddr() const
{
return sharedPointAddr_;
}
//- Local mesh points corresponding to the shared points
inline const labelListList& sharedPointLabels() const
{
return sharedPointLabels_;
}
//- Number of globally shared points
inline label nGlobalPoints() const
{
return nGlobalPoints_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -56,29 +56,32 @@ Foam::tmp<Foam::IOField<Type> > Foam::reconstructLagrangianField
);
Field<Type>& field = tfield();
forAll(meshes, i)
forAll (meshes, i)
{
// Check object on local mesh
IOobject localIOobject
(
fieldName,
meshes[i].time().timeName(),
cloud::prefix/cloudName,
meshes[i],
IOobject::MUST_READ,
IOobject::NO_WRITE
);
if (localIOobject.headerOk())
if (meshes.set(i))
{
IOField<Type> fieldi(localIOobject);
// Check object on local mesh
IOobject localIOobject
(
fieldName,
meshes[i].time().timeName(),
cloud::prefix/cloudName,
meshes[i],
IOobject::MUST_READ,
IOobject::NO_WRITE
);
label offset = field.size();
field.setSize(offset + fieldi.size());
forAll(fieldi, j)
if (localIOobject.headerOk())
{
field[offset + j] = fieldi[j];
IOField<Type> fieldi(localIOobject);
label offset = field.size();
field.setSize(offset + fieldi.size());
forAll (fieldi, j)
{
field[offset + j] = fieldi[j];
}
}
}
}

View file

@ -46,25 +46,28 @@ void Foam::reconstructLagrangianPositions
IDLList<passiveParticle>()
);
forAll(meshes, i)
forAll (meshes, i)
{
const labelList& cellMap = cellProcAddressing[i];
Cloud<passiveParticle> lpi(meshes[i], cloudName, false);
forAllIter(Cloud<passiveParticle>, lpi, iter)
if (meshes.set(i))
{
const passiveParticle& ppi = iter();
const labelList& cellMap = cellProcAddressing[i];
lagrangianPositions.append
(
new passiveParticle
Cloud<passiveParticle> lpi(meshes[i], cloudName, false);
forAllIter (Cloud<passiveParticle>, lpi, iter)
{
const passiveParticle& ppi = iter();
lagrangianPositions.append
(
lagrangianPositions,
ppi.position(),
cellMap[ppi.cell()]
)
);
new passiveParticle
(
lagrangianPositions,
ppi.position(),
cellMap[ppi.cell()]
)
);
}
}
}

View file

@ -143,16 +143,29 @@ public:
);
// Destructor - default
// Member Functions
//- Reconstruct field
//- Reconstruct point field data into a given field
// If a PtrList slot is empty, it is skipped
template<class Type>
void reconstructField
(
GeometricField<Type, pointPatchField, pointMesh>& reconField,
const PtrList<GeometricField<Type, pointPatchField, pointMesh> >&
procFields
) const;
//- Reconstruct point field
template<class Type>
tmp<GeometricField<Type, pointPatchField, pointMesh> >
reconstructField(const IOobject& fieldIoObject);
reconstructField(const IOobject& fieldIoObject) const;
//- Reconstruct and write all fields
//- Reconstruct and write all point fields
template<class Type>
void reconstructFields(const IOobjectList& objects);
void reconstructFields(const IOobjectList& objects) const;
};

View file

@ -0,0 +1,252 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "pointFieldReconstructor.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::pointFieldReconstructor::reconstructField
(
GeometricField<Type, pointPatchField, pointMesh>& reconField,
const PtrList<GeometricField<Type, pointPatchField, pointMesh> >& procFields
) const
{
// Get references to internal and boundary field
Field<Type>& iField = reconField.internalField();
typename GeometricField<Type, pointPatchField, pointMesh>::
GeometricBoundaryField& bouField = reconField.boundaryField();
forAll (procMeshes_, procI)
{
if (procFields.set(procI))
{
const GeometricField<Type, pointPatchField, pointMesh>&
procField = procFields[procI];
// Get processor-to-global addressing for use in rmap
const labelList& procToGlobalAddr = pointProcAddressing_[procI];
// Set the cell values in the reconstructed field
iField.rmap
(
procField.internalField(),
procToGlobalAddr
);
// Set the boundary patch values in the reconstructed field
forAll (boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
bouField[curBPatch].rmap
(
procFields[procI].boundaryField()[patchI],
patchPointAddressing_[procI][patchI]
);
}
}
}
}
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh> >
Foam::pointFieldReconstructor::reconstructField
(
const IOobject& fieldIoObject
) const
{
// Read the field for all the processors
PtrList<GeometricField<Type, pointPatchField, pointMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
procFields.set
(
procI,
new GeometricField<Type, pointPatchField, pointMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI]().time().timeName(),
procMeshes_[procI](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
}
// Create the patch fields
PtrList<pointPatchField<Type> > patchFields(mesh_.boundary().size());
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
// Set the boundary patch in the reconstructed field
forAll (boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
pointPatchField<Type>::New
(
procFields[procI].boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, pointMesh>::null(),
pointPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procFields[procI].boundaryField()
[patchI].size()
)
)
);
}
}
}
}
}
// Add missing patch fields
forAll (mesh_.boundary(), patchI)
{
if (!patchFields(patchI))
{
patchFields.set
(
patchI,
pointPatchField<Type>::New
(
mesh_.boundary()[patchI].type(),
mesh_.boundary()[patchI],
DimensionedField<Type, pointMesh>::null()
)
);
}
}
label firstValidMesh = 0;
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
firstValidMesh = procI;
break;
}
}
// Construct the reconstructed field with patches
tmp<GeometricField<Type, pointPatchField, pointMesh> > treconField
(
new GeometricField<Type, pointPatchField, pointMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_().time().timeName(),
mesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[firstValidMesh].dimensions(),
Field<Type>(mesh_.size()),
patchFields
)
);
// Reconstruct field
reconstructField
(
treconField(),
procFields
);
return treconField;
}
// Reconstruct and write all point fields
template<class Type>
void Foam::pointFieldReconstructor::reconstructFields
(
const IOobjectList& objects
) const
{
word fieldClassName
(
GeometricField<Type, pointPatchField, pointMesh>::typeName
);
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
for
(
IOobjectList::iterator fieldIter = fields.begin();
fieldIter != fields.end();
++fieldIter
)
{
Info<< " " << fieldIter()->name() << endl;
reconstructField<Type>(*fieldIter())().write();
}
Info<< endl;
}
}
// ************************************************************************* //

View file

@ -54,7 +54,7 @@ namespace Foam
{
/*---------------------------------------------------------------------------*\
Class tetPointFieldReconstructor Declaration
Class tetPointFieldReconstructor Declaration
\*---------------------------------------------------------------------------*/
class tetPointFieldReconstructor
@ -166,37 +166,60 @@ public:
);
// Destructor - default
// Member Functions
//- Reconstruct point field
//- Reconstruct tetPoint field data into a given field
// If a PtrList slot is empty, it is skipped
template<class Type>
void reconstructTetPointField
(
GeometricField<Type, tetPolyPatchField, tetPointMesh>& reconField,
const PtrList<GeometricField<Type, tetPolyPatchField, tetPointMesh> >&
procFields
) const;
//- Reconstruct tetPoint field
template<class Type>
tmp<GeometricField<Type, tetPolyPatchField, tetPointMesh> >
reconstructTetPointField
(
const IOobject& fieldIoObject
);
) const;
//- Reconstruct element field
//- Reconstruct tetElement field data into a given field
// If a PtrList slot is empty, it is skipped
template<class Type>
void reconstructElementField
(
GeometricField<Type, elementPatchField, elementMesh>& reconField,
const PtrList<GeometricField<Type, elementPatchField, elementMesh> >&
procFields
) const;
//- Reconstruct tetElement field
template<class Type>
tmp<GeometricField<Type, elementPatchField, elementMesh> >
reconstructElementField
(
const IOobject& fieldIoObject
);
) const;
//- Reconstruct and write all point fields
//- Reconstruct and write all tetPoint fields
template<class Type>
void reconstructTetPointFields
(
const IOobjectList& objects
);
) const;
//- Reconstruct and write all element fields
//- Reconstruct and write all tetElement fields
template<class Type>
void reconstructElementFields
(
const IOobjectList& objects
);
) const;
};

View file

@ -0,0 +1,517 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "tetPointFieldReconstructor.H"
#include "PtrList.H"
#include "tetPolyPatchFields.H"
#include "tetFemMatrices.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void tetPointFieldReconstructor::reconstructTetPointField
(
GeometricField<Type, tetPolyPatchField, tetPointMesh>& reconField,
const PtrList<GeometricField<Type, tetPolyPatchField, tetPointMesh> >&
procFields
) const
{
// Get references to internal and boundary field
Field<Type>& iField = reconField.internalField();
typename GeometricField<Type, tetPolyPatchField, tetPointMesh>::
GeometricBoundaryField& bouField = reconField.boundaryField();
forAll (procMeshes_, procI)
{
if (procFields.set(procI))
{
const GeometricField<Type, tetPolyPatchField, tetPointMesh>&
procField = procFields[procI];
// Get processor-to-global addressing for use in rmap
labelList procToGlobalAddr = procAddressing(procI);
// Set the cell values in the reconstructed field
iField.rmap
(
procField.internalField(),
procToGlobalAddr
);
// Set the boundary patch values in the reconstructed field
forAll(boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
// If the field stores values, do the rmap
if (bouField[curBPatch].storesFieldData())
{
bouField[curBPatch].rmap
(
procField.boundaryField()[patchI],
procPatchAddressing
(
procToGlobalAddr,
procI,
patchI
)
);
}
}
}
}
}
}
template<class Type>
tmp<GeometricField<Type, tetPolyPatchField, tetPointMesh> >
tetPointFieldReconstructor::reconstructTetPointField
(
const IOobject& fieldIoObject
) const
{
// Read the field for all the processors
PtrList<GeometricField<Type, tetPolyPatchField, tetPointMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
procFields.set
(
procI,
new GeometricField<Type, tetPolyPatchField, tetPointMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI]().time().timeName(),
procMeshes_[procI](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
}
// Create the patch fields
PtrList<tetPolyPatchField<Type> > patchFields(mesh_.boundary().size());
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
// Set the boundary patch values in the reconstructed field
forAll(boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
tetPolyPatchField<Type>::New
(
procFields[procI].boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, tetPointMesh>::null(),
tetPolyPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procFields[procI].boundaryField()
[patchI].size()
)
)
);
}
}
}
}
}
// Add missing patch fields
forAll (mesh_.boundary(), patchI)
{
if (!patchFields(patchI))
{
patchFields.set
(
patchI,
tetPolyPatchField<Type>::New
(
mesh_.boundary()[patchI].type(),
mesh_.boundary()[patchI],
DimensionedField<Type, tetPointMesh>::null()
)
);
}
}
label firstValidMesh = 0;
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
firstValidMesh = procI;
break;
}
}
// Construct the reconstructed field with patches
tmp<GeometricField<Type, tetPolyPatchField, tetPointMesh> > treconField
(
new GeometricField<Type, tetPolyPatchField, tetPointMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_().time().timeName(),
mesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[firstValidMesh].dimensions(),
Field<Type>(mesh_.nPoints()),
patchFields
)
);
// Reconstruct field
reconstructTetPointField
(
treconField(),
procFields
);
return treconField;
}
template<class Type>
void tetPointFieldReconstructor::reconstructElementField
(
GeometricField<Type, elementPatchField, elementMesh>& reconField,
const PtrList<GeometricField<Type, elementPatchField, elementMesh> >&
procFields
) const
{
// Get references to internal and boundary field
Field<Type>& iField = reconField.internalField();
typename GeometricField<Type, elementPatchField, elementMesh>::
GeometricBoundaryField& bouField = reconField.boundaryField();
forAll (procMeshes_, procI)
{
if (procFields.set(procI))
{
const GeometricField<Type, elementPatchField, elementMesh>&
procField = procFields[procI];
// Set the cell values in the reconstructed field
iField.rmap
(
procField.internalField(),
cellProcAddressing_[procI]
);
// Set the boundary patch values in the reconstructed field
forAll (boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Get addressing slice for this patch
const labelList::subList cp =
procMeshes_[procI]().boundaryMesh()[patchI].patchSlice
(
faceProcAddressing_[procI]
);
// Check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
// If the field stores values, do the rmap
if (bouField[curBPatch].storesFieldData())
{
const label curPatchStart =
mesh_().boundaryMesh()[curBPatch].start();
labelList reverseAddressing(cp.size());
forAll (cp, faceI)
{
// Subtract one to take into account offsets for
// face direction.
reverseAddressing[faceI] = cp[faceI] - 1
- curPatchStart;
}
bouField[curBPatch].rmap
(
procField.boundaryField()[patchI],
reverseAddressing
);
}
}
}
}
}
}
template<class Type>
tmp<GeometricField<Type, elementPatchField, elementMesh> >
tetPointFieldReconstructor::reconstructElementField
(
const IOobject& fieldIoObject
) const
{
// Read the field for all the processors
PtrList<GeometricField<Type, elementPatchField, elementMesh> > procFields
(
procMeshes_.size()
);
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
procFields.set
(
procI,
new GeometricField<Type, elementPatchField, elementMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI]().time().timeName(),
procMeshes_[procI](),
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
}
// Create the patch fields
PtrList<elementPatchField<Type> > patchFields(mesh_.boundary().size());
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
// Set the boundary patch values in the reconstructed field
forAll(boundaryProcAddressing_[procI], patchI)
{
// Get patch index of the original patch
const label curBPatch = boundaryProcAddressing_[procI][patchI];
// Check if the boundary patch is not a processor patch
if (curBPatch >= 0)
{
if (!patchFields(curBPatch))
{
patchFields.set
(
curBPatch,
elementPatchField<Type>::New
(
procFields[procI].boundaryField()[patchI],
mesh_.boundary()[curBPatch],
DimensionedField<Type, elementMesh>::null(),
tetPolyPatchFieldReconstructor
(
mesh_.boundary()[curBPatch].size(),
procFields[procI].boundaryField()
[patchI].size()
)
)
);
}
}
}
}
}
// Add missing patch fields
forAll (mesh_.boundary(), patchI)
{
if (!patchFields(patchI))
{
patchFields.set
(
patchI,
elementPatchField<Type>::New
(
mesh_.boundary()[patchI].type(),
mesh_.boundary()[patchI],
DimensionedField<Type, elementMesh>::null()
)
);
}
}
label firstValidMesh = 0;
forAll (procMeshes_, procI)
{
if (procMeshes_.set(procI))
{
firstValidMesh = procI;
break;
}
}
// Construct the reconstructed field with patches
tmp<GeometricField<Type, elementPatchField, elementMesh> > treconField
(
new GeometricField<Type, elementPatchField, elementMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_().time().timeName(),
mesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
procFields[firstValidMesh].dimensions(),
Field<Type>(mesh_.nCells()),
patchFields
)
);
// Reconstruct field
reconstructElementField
(
treconField(),
procFields
);
return treconField;
}
template<class Type>
void tetPointFieldReconstructor::reconstructTetPointFields
(
const IOobjectList& objects
) const
{
word fieldClassName
(
GeometricField<Type, tetPolyPatchField, tetPointMesh>::typeName
);
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
for
(
IOobjectList::iterator fieldIter = fields.begin();
fieldIter != fields.end();
++fieldIter
)
{
Info<< " " << fieldIter()->name() << endl;
reconstructTetPointField<Type>(*fieldIter())().write();
}
Info<< endl;
}
}
template<class Type>
void tetPointFieldReconstructor::reconstructElementFields
(
const IOobjectList& objects
) const
{
word fieldClassName
(
GeometricField<Type, elementPatchField, elementMesh>::typeName
);
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
for
(
IOobjectList::iterator fieldIter = fields.begin();
fieldIter != fields.end();
++fieldIter
)
{
Info<< " " << fieldIter()->name() << endl;
reconstructElementField<Type>(*fieldIter())().write();
}
Info<< endl;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -494,22 +494,24 @@ Foam::autoPtr<Foam::decompositionMethod> Foam::decompositionMethod::New
void Foam::decompositionMethod::loadExternalLibraries()
{
wordList libNames(3);
libNames[0]=word("scotchDecomp");
libNames[1]=word("metisDecomp");
libNames[2]=word("parMetisDecomp");
forAll(libNames,i) {
libNames[0] = word("scotchDecomp");
libNames[1] = word("metisDecomp");
libNames[2] = word("parMetisDecomp");
forAll (libNames,i)
{
const word libName("lib"+libNames[i]+".so");
// Info << "Loading " << libName << endl;
bool ok = dlLibraryTable::open(libName);
bool ok=dlLibraryTable::open(libName);
if(!ok) {
if (!ok)
{
WarningIn("decompositionMethod::loadExternalLibraries()")
<< "Loading of decomposition library " << libName
<< " unsuccesful. Some decomposition methods may not be "
<< " available"
<< endl;
<< " unsuccesful. Some decomposition methods may not be "
<< "available"
<< endl;
}
}
}

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