From b015be75ee72e7b5237cc2bf197be3be39d3aee2 Mon Sep 17 00:00:00 2001 From: Graham Date: Tue, 17 Mar 2009 18:45:55 +0000 Subject: [PATCH 01/40] Changing correction magnitude for confused particles from 1e-6 to 1e-3, needed for snappyHexMeshes. --- src/lagrangian/basic/Particle/Particle.C | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lagrangian/basic/Particle/Particle.C b/src/lagrangian/basic/Particle/Particle.C index ec1d09a00f..6c8cbe4aa1 100644 --- a/src/lagrangian/basic/Particle/Particle.C +++ b/src/lagrangian/basic/Particle/Particle.C @@ -390,7 +390,7 @@ Foam::scalar Foam::Particle::trackToFace // slightly towards the cell-centre. if (trackFraction < SMALL) { - position_ += 1.0e-6*(mesh.cellCentres()[celli_] - position_); + position_ += 1.0e-3*(mesh.cellCentres()[celli_] - position_); } return trackFraction; From 6dc53f429fd2e164d1b66771c5e7b6430336b819 Mon Sep 17 00:00:00 2001 From: Graham Date: Tue, 17 Mar 2009 18:52:13 +0000 Subject: [PATCH 02/40] Initialising rhoN, rhoM and iDof fields to VSMALL instead of 0.0 to avoid floating point errors or the need to skip field calculation. Rewritten initialisation function to fill on a cell-by-cell basis, filling into randomly distributed positions in volume weighted selected tetrahedrons (decomposed cells) - much faster. --- .../clouds/Templates/DsmcCloud/DsmcCloud.C | 196 ++++++++++++------ .../clouds/Templates/DsmcCloud/DsmcCloudI.H | 6 +- .../FreeStream/FreeStream.C | 2 +- 3 files changed, 139 insertions(+), 65 deletions(-) diff --git a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C index 4c4bcd0a43..ac3b625638 100644 --- a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C +++ b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C @@ -113,87 +113,161 @@ void Foam::DsmcCloud::initialise numberDensities /= nParticle_; - scalar x0 = mesh_.bounds().min().x(); - scalar xR = mesh_.bounds().max().x() - x0; - - scalar y0 = mesh_.bounds().min().y(); - scalar yR = mesh_.bounds().max().y() - y0; - - scalar z0 = mesh_.bounds().min().z(); - scalar zR = mesh_.bounds().max().z() - z0; - - forAll(molecules, i) + forAll(mesh_.cells(), cell) { - const word& moleculeName(molecules[i]); + const vector& cC = mesh_.cellCentres()[cell]; + const labelList& cellFaces = mesh_.cells()[cell]; + const scalar cV = mesh_.cellVolumes()[cell]; - label typeId(findIndex(typeIdList_, moleculeName)); + label nTets = 0; - if (typeId == -1) + // Each face is split into nEdges (or nVertices) - 2 tets. + forAll(cellFaces, face) { - FatalErrorIn("Foam::DsmcCloud::initialise") - << "typeId " << moleculeName << "not defined." << nl - << abort(FatalError); + nTets += mesh_.faces()[cellFaces[face]].size() - 2; } - const typename ParcelType::constantProperties& cP = constProps(typeId); + // Calculate the cumulative tet volumes circulating around the cell and + // record the vertex labels of each. + scalarList cTetVFracs(nTets, 0.0); - scalar numberDensity = numberDensities[i]; + List tetPtIs(nTets, labelList(3,-1)); - scalar spacing = pow(numberDensity,-(1.0/3.0)); + // Keep track of which tet this is. + label tet = 0; - int ni = label(xR/spacing) + 1; - int nj = label(yR/spacing) + 1; - int nk = label(zR/spacing) + 1; - - vector delta(xR/ni, yR/nj, zR/nk); - - scalar pert = spacing; - - for (int i = 0; i < ni; i++) + forAll(cellFaces, face) { - for (int j = 0; j < nj; j++) + const labelList& facePoints = mesh_.faces()[cellFaces[face]]; + + label pointI = 1; + while ((pointI + 1) < facePoints.size()) { - for (int k = 0; k < nk; k++) + + const vector& pA = mesh_.points()[facePoints[0]]; + const vector& pB = mesh_.points()[facePoints[pointI]]; + const vector& pC = mesh_.points()[facePoints[pointI + 1]]; + + cTetVFracs[tet] = + mag(((pA - cC) ^ (pB - cC)) & (pC - cC))/(cV*6.0) + + cTetVFracs[max((tet - 1),0)]; + + tetPtIs[tet][0] = facePoints[0]; + tetPtIs[tet][1] = facePoints[pointI]; + tetPtIs[tet][2] = facePoints[pointI + 1]; + + pointI++; + tet++; + } + } + + // Force the last volume fraction value to 1.0 to avoid any + // rounding/non-flat face errors giving a value < 1.0 + cTetVFracs[nTets - 1] = 1.0; + + forAll(molecules, i) + { + const word& moleculeName(molecules[i]); + + label typeId(findIndex(typeIdList_, moleculeName)); + + if (typeId == -1) + { + FatalErrorIn("Foam::DsmcCloud::initialise") + << "typeId " << moleculeName << "not defined." << nl + << abort(FatalError); + } + + const typename ParcelType::constantProperties& cP = + constProps(typeId); + + scalar numberDensity = numberDensities[i]; + + // Calculate the number of particles required + scalar particlesRequired = numberDensity*mesh_.cellVolumes()[cell]; + + // Only integer numbers of particles can be inserted + label nParticlesToInsert = label(particlesRequired); + + // Add another particle with a probability proportional to the + // remainder of taking the integer part of particlesRequired + if ((particlesRequired - nParticlesToInsert) > rndGen_.scalar01()) + { + nParticlesToInsert++; + } + + for (label pI = 0; pI < nParticlesToInsert; pI++) + { + // Choose a random point in a generic tetrahedron + + scalar s = rndGen_.scalar01(); + scalar t = rndGen_.scalar01(); + scalar u = rndGen_.scalar01(); + + if (s + t > 1.0) { - point p - ( - x0 + (i + 0.5)*delta.x(), - y0 + (j + 0.5)*delta.y(), - z0 + (k + 0.5)*delta.z() - ); + s = 1.0 - s; + t = 1.0 - t; + } - p.x() += pert*(rndGen_.scalar01() - 0.5); - p.y() += pert*(rndGen_.scalar01() - 0.5); - p.z() += pert*(rndGen_.scalar01() - 0.5); + if (t + u > 1.0) + { + scalar tmp = u; + u = 1.0 - s - t; + t = 1.0 - tmp; + } + else if (s + t + u > 1.0) + { + scalar tmp = u; + u = s + t + u - 1.0; + s = 1.0 - t - tmp; + } - label cell = mesh_.findCell(p); + // Choose a tetrahedron to insert in, based on their relative + // volumes + scalar tetSelection = rndGen_.scalar01(); - vector U = equipartitionLinearVelocity - ( - temperature, - cP.mass() - ); + // Selected tetrahedron + label sTet = -1; - scalar Ei = equipartitionInternalEnergy - ( - temperature, - cP.internalDegreesOfFreedom() - ); + forAll(cTetVFracs, tet) + { + sTet = tet; - U += velocity; - - if (cell >= 0) + if (cTetVFracs[tet] >= tetSelection) { - addNewParcel - ( - p, - U, - Ei, - cell, - typeId - ); + break; } } + + vector p = + (1 - s - t - u)*cC + + s*mesh_.points()[tetPtIs[sTet][0]] + + t*mesh_.points()[tetPtIs[sTet][1]] + + u*mesh_.points()[tetPtIs[sTet][2]]; + + vector U = equipartitionLinearVelocity + ( + temperature, + cP.mass() + ); + + scalar Ei = equipartitionInternalEnergy + ( + temperature, + cP.internalDegreesOfFreedom() + ); + + U += velocity; + + addNewParcel + ( + p, + U, + Ei, + cell, + typeId + ); } } } diff --git a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloudI.H b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloudI.H index 73899636e8..ede1e3559b 100644 --- a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloudI.H +++ b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloudI.H @@ -343,7 +343,7 @@ Foam::DsmcCloud::rhoN() const false ), mesh_, - dimensionedScalar("zero", dimensionSet(0, -3, 0, 0, 0), 0.0) + dimensionedScalar("zero", dimensionSet(0, -3, 0, 0, 0), VSMALL) ) ); @@ -380,7 +380,7 @@ Foam::DsmcCloud::rhoM() const false ), mesh_, - dimensionedScalar("zero", dimensionSet(1, -3, 0, 0, 0), 0.0) + dimensionedScalar("zero", dimensionSet(1, -3, 0, 0, 0), VSMALL) ) ); @@ -568,7 +568,7 @@ Foam::DsmcCloud::iDof() const false ), mesh_, - dimensionedScalar("zero", dimensionSet(0, -3, 0, 0, 0), 0.0) + dimensionedScalar("zero", dimensionSet(0, -3, 0, 0, 0), VSMALL) ) ); diff --git a/src/lagrangian/dsmc/submodels/InflowBoundaryModel/FreeStream/FreeStream.C b/src/lagrangian/dsmc/submodels/InflowBoundaryModel/FreeStream/FreeStream.C index f4203f4d66..02ed6d28b5 100644 --- a/src/lagrangian/dsmc/submodels/InflowBoundaryModel/FreeStream/FreeStream.C +++ b/src/lagrangian/dsmc/submodels/InflowBoundaryModel/FreeStream/FreeStream.C @@ -157,7 +157,7 @@ void Foam::FreeStream::inflow() scalar fA = mag(patch.faceAreas()[f]); - // Cummulative triangle area fractions + // Cumulative triangle area fractions List cTriAFracs(nVertices); for (label v = 0; v < nVertices - 1; v++) From 6d265b0a5f2a5062e69f541cbae6957d7a1423ae Mon Sep 17 00:00:00 2001 From: Graham Date: Wed, 18 Mar 2009 10:29:05 +0000 Subject: [PATCH 03/40] Modifying dsmcFields to allow negative rhoNMean values, only cheching for min(mag(rhoNMean)) < VSMALL --- .../functionObjects/utilities/dsmcFields/dsmcFields.C | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.C b/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.C index 3aaa9c514a..273c88f369 100644 --- a/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.C +++ b/src/postProcessing/functionObjects/utilities/dsmcFields/dsmcFields.C @@ -137,7 +137,7 @@ void Foam::dsmcFields::write() iDofMeanName ); - if (min(rhoNMean).value() > VSMALL) + if (min(mag(rhoNMean)).value() > VSMALL) { Info<< "Calculating dsmcFields." << endl; @@ -223,10 +223,9 @@ void Foam::dsmcFields::write() } else { - Info<< "Small or negative value (" << min(rhoNMean) + Info<< "Small value (" << min(mag(rhoNMean)) << ") found in rhoNMean field. " - << "Not calculating dsmcFields to avoid division by zero " - << "or invalid results." + << "Not calculating dsmcFields to avoid division by zero." << endl; } } From a8b37fc4a725db9dcaa7e30efa6b0fad66cca822 Mon Sep 17 00:00:00 2001 From: graham Date: Mon, 13 Apr 2009 13:02:17 +0100 Subject: [PATCH 04/40] When iDof = 0, equipartitionInternalEnergy will enter an infinite loop, adding a check and return. --- .../dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C index ac3b625638..42a1ba7ea6 100644 --- a/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C +++ b/src/lagrangian/dsmc/clouds/Templates/DsmcCloud/DsmcCloud.C @@ -350,7 +350,7 @@ void Foam::DsmcCloud::collisions() scalar selectedPairs = collisionSelectionRemainder_[celli] - + 0.5*nC*(nC-1)*nParticle_*sigmaTcRMax*deltaT + + 0.5*nC*(nC - 1)*nParticle_*sigmaTcRMax*deltaT /mesh_.cellVolumes()[celli]; label nCandidates(selectedPairs); @@ -859,7 +859,11 @@ Foam::scalar Foam::DsmcCloud::equipartitionInternalEnergy { scalar Ei = 0.0; - if (iDof < 2.0 + SMALL && iDof > 2.0 - SMALL) + if (iDof < SMALL) + { + return Ei; + } + else if (iDof < 2.0 + SMALL && iDof > 2.0 - SMALL) { // Special case for iDof = 2, i.e. diatomics; Ei = -log(rndGen_.scalar01())*kb*temperature; From dbe2b2c5fd368920bb11ec9bd35977bfaade1de3 Mon Sep 17 00:00:00 2001 From: mattijs Date: Wed, 15 Apr 2009 12:30:18 +0100 Subject: [PATCH 05/40] added region option --- .../decomposePar/decomposePar.C | 28 +++++++++++++++---- .../decomposePar/domainDecomposition.C | 2 +- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C index 5edafcf561..476f477373 100644 --- a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C +++ b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C @@ -83,6 +83,7 @@ Usage int main(int argc, char *argv[]) { argList::noParallel(); +# include "addRegionOption.H" argList::validOptions.insert("cellDist", ""); argList::validOptions.insert("copyUniform", ""); argList::validOptions.insert("fields", ""); @@ -92,6 +93,16 @@ int main(int argc, char *argv[]) # include "setRootCase.H" + word regionName = fvMesh::defaultRegion; + + if (args.options().found("region")) + { + regionName = args.options()["region"]; + + Info<< "Decomposing mesh " << regionName << nl << endl; + } + + bool writeCellDist(args.options().found("cellDist")); bool copyUniform(args.options().found("copyUniform")); bool decomposeFieldsOnly(args.options().found("fields")); @@ -119,6 +130,7 @@ int main(int argc, char *argv[]) ( "decomposeParDict", runTime.time().system(), + regionName, runTime, IOobject::MUST_READ, IOobject::NO_WRITE, @@ -196,7 +208,7 @@ int main(int argc, char *argv[]) ( IOobject ( - domainDecomposition::defaultRegion, + regionName, runTime.timeName(), runTime ) @@ -219,7 +231,7 @@ int main(int argc, char *argv[]) ( runTime.path() / mesh.facesInstance() - / polyMesh::defaultRegion + / regionName / "cellDecomposition" ); @@ -383,7 +395,12 @@ int main(int argc, char *argv[]) label i = 0; - forAllIter(Cloud, lagrangianPositions[cloudI], iter) + forAllIter + ( + Cloud, + lagrangianPositions[cloudI], + iter + ) { iter().index() = i++; @@ -405,7 +422,8 @@ int main(int argc, char *argv[]) if (!cellParticles[cloudI][celli]) { - cellParticles[cloudI][celli] = new SLList(); + cellParticles[cloudI][celli] = new SLList + (); } cellParticles[cloudI][celli]->append(&iter()); @@ -513,7 +531,7 @@ int main(int argc, char *argv[]) ( IOobject ( - fvMesh::defaultRegion, + regionName, processorDb.timeName(), processorDb ) diff --git a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C index 989d384e40..2940577d16 100644 --- a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C +++ b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C @@ -268,7 +268,7 @@ bool domainDecomposition::writeDecomposition() ( IOobject ( - polyMesh::defaultRegion, + this->polyMesh::name(), // region name of undecomposed mesh "constant", processorDb ), From 099114d1381fa7924fef7b1ec00e55f2805883d8 Mon Sep 17 00:00:00 2001 From: mattijs Date: Wed, 15 Apr 2009 12:30:49 +0100 Subject: [PATCH 06/40] changed indentation --- .../inletOutletTotalTemperatureFvPatchScalarField.C | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/finiteVolume/fields/fvPatchFields/derived/inletOutletTotalTemperature/inletOutletTotalTemperatureFvPatchScalarField.C b/src/finiteVolume/fields/fvPatchFields/derived/inletOutletTotalTemperature/inletOutletTotalTemperatureFvPatchScalarField.C index 7d316f21fa..d6a83b07cb 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/inletOutletTotalTemperature/inletOutletTotalTemperatureFvPatchScalarField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/inletOutletTotalTemperature/inletOutletTotalTemperatureFvPatchScalarField.C @@ -189,7 +189,8 @@ void Foam::inletOutletTotalTemperatureFvPatchScalarField::updateCoeffs() } -void Foam::inletOutletTotalTemperatureFvPatchScalarField::write(Ostream& os) const +void Foam::inletOutletTotalTemperatureFvPatchScalarField::write(Ostream& os) +const { fvPatchScalarField::write(os); if (UName_ != "U") From 42c075d80abd9760a5339b190eb53d7aa4ce43e6 Mon Sep 17 00:00:00 2001 From: mattijs Date: Wed, 15 Apr 2009 12:31:57 +0100 Subject: [PATCH 07/40] constructSize bug if construct from synchronised info --- .../meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C index f4cbe6e2f3..4bd093e641 100644 --- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C +++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C @@ -205,7 +205,7 @@ Foam::mapDistribute::mapDistribute const labelList& recvProcs ) : - constructSize_(sendProcs.size()), + constructSize_(0), schedulePtr_() { if (sendProcs.size() != recvProcs.size()) @@ -266,6 +266,8 @@ Foam::mapDistribute::mapDistribute { // I am the receiver. constructMap_[sendProc][nRecv[sendProc]++] = sampleI; + // Largest entry inside constructMap + constructSize_ = sampleI+1; } } } From 923764e35a1f8ef6dcfb050ca24d5cd0e3fabffe Mon Sep 17 00:00:00 2001 From: mattijs Date: Wed, 15 Apr 2009 12:32:18 +0100 Subject: [PATCH 08/40] in-place subset bug --- .../mapDistribute/mapDistributeTemplates.C | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C index 330f48be00..5f5d7a9fcf 100644 --- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C +++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C @@ -58,7 +58,13 @@ void Foam::mapDistribute::distribute } // Subset myself - UIndirectList subField(field, subMap[Pstream::myProcNo()]); + const labelList& mySubMap = subMap[Pstream::myProcNo()]; + + List subField(mySubMap.size()); + forAll(mySubMap, i) + { + subField[i] = field[mySubMap[i]]; + } // Receive sub field from myself (subField) const labelList& map = constructMap[Pstream::myProcNo()]; @@ -355,7 +361,13 @@ void Foam::mapDistribute::distribute } // Subset myself - UIndirectList subField(field, subMap[Pstream::myProcNo()]); + const labelList& mySubMap = subMap[Pstream::myProcNo()]; + + List subField(mySubMap.size()); + forAll(mySubMap, i) + { + subField[i] = field[mySubMap[i]]; + } // Receive sub field from myself (subField) const labelList& map = constructMap[Pstream::myProcNo()]; From 676b7bfe7306dc77edb00668e5061404e5ece01e Mon Sep 17 00:00:00 2001 From: mattijs Date: Wed, 15 Apr 2009 12:32:33 +0100 Subject: [PATCH 09/40] added region option --- .../utilities/mesh/conversion/writeMeshObj/writeMeshObj.C | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/applications/utilities/mesh/conversion/writeMeshObj/writeMeshObj.C b/applications/utilities/mesh/conversion/writeMeshObj/writeMeshObj.C index d8042fdaa8..9eaaf2c199 100644 --- a/applications/utilities/mesh/conversion/writeMeshObj/writeMeshObj.C +++ b/applications/utilities/mesh/conversion/writeMeshObj/writeMeshObj.C @@ -344,6 +344,7 @@ int main(int argc, char *argv[]) argList::validOptions.insert("point", "pointI"); argList::validOptions.insert("cellSet", "setName"); argList::validOptions.insert("faceSet", "setName"); +# include "addRegionOption.H" # include "setRootCase.H" # include "createTime.H" @@ -364,7 +365,7 @@ int main(int argc, char *argv[]) instantList timeDirs = timeSelector::select0(runTime, args); -# include "createPolyMesh.H" +# include "createNamedPolyMesh.H" forAll(timeDirs, timeI) { From 485ea4c84f0f1d0ad4d1f794b4338cbbbd424e76 Mon Sep 17 00:00:00 2001 From: mattijs Date: Thu, 16 Apr 2009 17:59:34 +0100 Subject: [PATCH 10/40] region option for decomposePar --- .../decomposePar/decomposePar.C | 17 ++++++-- .../decomposePar/decomposeParDict | 2 +- .../decomposePar/distributeCells.C | 41 ++----------------- 3 files changed, 19 insertions(+), 41 deletions(-) diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C index 476f477373..26ee3e062a 100644 --- a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C +++ b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C @@ -94,11 +94,12 @@ int main(int argc, char *argv[]) # include "setRootCase.H" word regionName = fvMesh::defaultRegion; + word regionDir = word::null; if (args.options().found("region")) { regionName = args.options()["region"]; - + regionDir = regionName; Info<< "Decomposing mesh " << regionName << nl << endl; } @@ -116,7 +117,17 @@ int main(int argc, char *argv[]) // determine the existing processor count directly label nProcs = 0; - while (isDir(runTime.path()/(word("processor") + name(nProcs)))) + while + ( + isDir + ( + runTime.path() + /(word("processor") + name(nProcs)) + /runTime.constant() + /regionDir + /polyMesh::meshSubDir + ) + ) { ++nProcs; } @@ -130,7 +141,7 @@ int main(int argc, char *argv[]) ( "decomposeParDict", runTime.time().system(), - regionName, + regionDir, // use region if non-standard runTime, IOobject::MUST_READ, IOobject::NO_WRITE, diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposeParDict b/applications/utilities/parallelProcessing/decomposePar/decomposeParDict index 288797ed1e..98ec9b7087 100644 --- a/applications/utilities/parallelProcessing/decomposePar/decomposeParDict +++ b/applications/utilities/parallelProcessing/decomposePar/decomposeParDict @@ -19,7 +19,7 @@ FoamFile numberOfSubdomains 4; -// preservePatches (inlet); +//- Keep owner and neighbour on same processor for faces in zones: // preserveFaceZones (heater solid1 solid3); method simple; diff --git a/applications/utilities/parallelProcessing/decomposePar/distributeCells.C b/applications/utilities/parallelProcessing/decomposePar/distributeCells.C index ad78b2a914..af47af244f 100644 --- a/applications/utilities/parallelProcessing/decomposePar/distributeCells.C +++ b/applications/utilities/parallelProcessing/decomposePar/distributeCells.C @@ -45,35 +45,6 @@ void domainDecomposition::distributeCells() labelHashSet sameProcFaces; - if (decompositionDict_.found("preservePatches")) - { - wordList pNames(decompositionDict_.lookup("preservePatches")); - - Info<< "Keeping owner and neighbour of faces in patches " << pNames - << " on same processor" << endl; - - const polyBoundaryMesh& patches = boundaryMesh(); - - forAll(pNames, i) - { - label patchI = patches.findPatchID(pNames[i]); - - if (patchI == -1) - { - FatalErrorIn("domainDecomposition::distributeCells()") - << "Unknown preservePatch " << pNames[i] - << endl << "Valid patches are " << patches.names() - << exit(FatalError); - } - - const polyPatch& pp = patches[patchI]; - - forAll(pp, i) - { - sameProcFaces.insert(pp.start() + i); - } - } - } if (decompositionDict_.found("preserveFaceZones")) { wordList zNames(decompositionDict_.lookup("preserveFaceZones")); @@ -104,14 +75,6 @@ void domainDecomposition::distributeCells() } } - if (sameProcFaces.size()) - { - Info<< "Selected " << sameProcFaces.size() - << " faces whose owner and neighbour cell should be kept on the" - << " same processor" << endl; - } - - // Construct decomposition method and either do decomposition on // cell centres or on agglomeration @@ -129,6 +92,10 @@ void domainDecomposition::distributeCells() } else { + Info<< "Selected " << sameProcFaces.size() + << " faces whose owner and neighbour cell should be kept on the" + << " same processor" << endl; + // Faces where owner and neighbour are not 'connected' (= all except // sameProcFaces) boolList blockedFace(nFaces(), true); From c42f04e843367e25c75b16c3a27beda524e1f6b5 Mon Sep 17 00:00:00 2001 From: mattijs Date: Thu, 16 Apr 2009 18:45:01 +0100 Subject: [PATCH 11/40] multi-region directMapped --- ...ixedTemperatureCoupledFvPatchScalarField.H | 4 +- etc/controlDict | 2 +- .../mapPolyMesh/mapDistribute/mapDistribute.H | 18 + src/finiteVolume/Make/files | 1 + .../directMappedFixedValueFvPatchField.C | 178 +++-- .../directMappedFixedValueFvPatchField.H | 12 - ...MappedVelocityFluxFixedValueFvPatchField.C | 192 ++--- ...MappedVelocityFluxFixedValueFvPatchField.H | 14 - .../directMapped/directMappedWallFvPatch.C | 38 + .../directMapped/directMappedWallFvPatch.H | 84 +++ src/meshTools/Make/files | 3 + .../directMappedWallPointPatch.C | 52 ++ .../directMappedWallPointPatch.H | 84 +++ .../directMappedPatchBase.C | 656 ++++++++++++++++++ .../directMappedPatchBase.H | 248 +++++++ .../directMappedPolyPatch.C | 553 ++------------- .../directMappedPolyPatch.H | 201 +----- .../directMappedWallPolyPatch.C | 171 +++++ .../directMappedWallPolyPatch.H | 181 +++++ .../system/changeDictionaryDict | 1 + 20 files changed, 1753 insertions(+), 940 deletions(-) create mode 100644 src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.C create mode 100644 src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.H create mode 100644 src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.C create mode 100644 src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.H create mode 100644 src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.C create mode 100644 src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.H create mode 100644 src/meshTools/directMapped/directMappedPolyPatch/directMappedWallPolyPatch.C create mode 100644 src/meshTools/directMapped/directMappedPolyPatch/directMappedWallPolyPatch.H diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/derivedFvPatchFields/solidWallMixedTemperatureCoupled/solidWallMixedTemperatureCoupledFvPatchScalarField.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/derivedFvPatchFields/solidWallMixedTemperatureCoupled/solidWallMixedTemperatureCoupledFvPatchScalarField.H index 5a78299a7a..34c32b1abf 100644 --- a/applications/solvers/heatTransfer/chtMultiRegionFoam/derivedFvPatchFields/solidWallMixedTemperatureCoupled/solidWallMixedTemperatureCoupledFvPatchScalarField.H +++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/derivedFvPatchFields/solidWallMixedTemperatureCoupled/solidWallMixedTemperatureCoupledFvPatchScalarField.H @@ -103,8 +103,8 @@ public: const dictionary& ); - //- Construct by mapping given solidWallMixedTemperatureCoupledFvPatchScalarField - // onto a new patch + //- Construct by mapping given + // solidWallMixedTemperatureCoupledFvPatchScalarField onto a new patch solidWallMixedTemperatureCoupledFvPatchScalarField ( const solidWallMixedTemperatureCoupledFvPatchScalarField&, diff --git a/etc/controlDict b/etc/controlDict index 5cbe331fe5..65058af1a6 100644 --- a/etc/controlDict +++ b/etc/controlDict @@ -360,7 +360,7 @@ DebugSwitches diagonal 0; dictionary 0; dimensionSet 1; - directMapped 0; + directMappedBase 0; directMappedPatch 0; directMappedVelocityFlux 0; directionMixed 0; diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H index 4687c8a4b1..3ccf810476 100644 --- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H +++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H @@ -131,18 +131,36 @@ public: return constructSize_; } + //- Constructed data size + label& constructSize() + { + return constructSize_; + } + //- From subsetted data back to original data const labelListList& subMap() const { return subMap_; } + //- From subsetted data back to original data + labelListList& subMap() + { + return subMap_; + } + //- From subsetted data to new reconstructed data const labelListList& constructMap() const { return constructMap_; } + //- From subsetted data to new reconstructed data + labelListList& constructMap() + { + return constructMap_; + } + //- Calculate a schedule. See above. static List schedule ( diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files index 99f3085854..1ad24ecd16 100644 --- a/src/finiteVolume/Make/files +++ b/src/finiteVolume/Make/files @@ -24,6 +24,7 @@ $(constraintFvPatches)/processor/processorFvPatch.C derivedFvPatches = $(fvPatches)/derived $(derivedFvPatches)/wall/wallFvPatch.C $(derivedFvPatches)/directMapped/directMappedFvPatch.C +$(derivedFvPatches)/directMapped/directMappedWallFvPatch.C wallDist = fvMesh/wallDist $(wallDist)/wallPointYPlus/wallPointYPlus.C diff --git a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C index 5322cbf47b..0c3bf43408 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C @@ -25,7 +25,7 @@ License \*---------------------------------------------------------------------------*/ #include "directMappedFixedValueFvPatchField.H" -#include "directMappedFvPatch.H" +#include "directMappedPatchBase.H" #include "volFields.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -61,7 +61,7 @@ directMappedFixedValueFvPatchField::directMappedFixedValueFvPatchField setAverage_(ptf.setAverage_), average_(ptf.average_) { - if (!isType(this->patch())) + if (!isA(this->patch().patch())) { FatalErrorIn ( @@ -74,7 +74,7 @@ directMappedFixedValueFvPatchField::directMappedFixedValueFvPatchField " const fvPatchFieldMapper&\n" ")\n" ) << "\n patch type '" << p.type() - << "' not type '" << typeName << "'" + << "' not type '" << directMappedPatchBase::typeName << "'" << "\n for patch " << p.name() << " of field " << this->dimensionedInternalField().name() << " in file " << this->dimensionedInternalField().objectPath() @@ -95,7 +95,7 @@ directMappedFixedValueFvPatchField::directMappedFixedValueFvPatchField setAverage_(readBool(dict.lookup("setAverage"))), average_(pTraits(dict.lookup("average"))) { - if (!isType(this->patch())) + if (!isA(this->patch().patch())) { FatalErrorIn ( @@ -107,12 +107,19 @@ directMappedFixedValueFvPatchField::directMappedFixedValueFvPatchField " const dictionary& dict\n" ")\n" ) << "\n patch type '" << p.type() - << "' not type '" << typeName << "'" + << "' not type '" << directMappedPatchBase::typeName << "'" << "\n for patch " << p.name() << " of field " << this->dimensionedInternalField().name() << " in file " << this->dimensionedInternalField().objectPath() << exit(FatalError); } + + // Force calculation of schedule (uses parallel comms) + const directMappedPatchBase& mpp = refCast + ( + this->patch().patch() + ); + (void)mpp.map().schedule(); } @@ -143,70 +150,6 @@ directMappedFixedValueFvPatchField::directMappedFixedValueFvPatchField // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -template -void directMappedFixedValueFvPatchField::getNewValues -( - const directMappedPolyPatch& mpp, - const Field& sendValues, - Field& newValues -) const -{ - // Get the scheduling information - const List& schedule = mpp.schedule(); - const labelListList& sendLabels = mpp.sendLabels(); - const labelListList& receiveFaceLabels = mpp.receiveFaceLabels(); - - forAll(schedule, i) - { - const labelPair& twoProcs = schedule[i]; - label sendProc = twoProcs[0]; - label recvProc = twoProcs[1]; - - if (Pstream::myProcNo() == sendProc) - { - OPstream toProc(Pstream::scheduled, recvProc); - toProc<< UIndirectList(sendValues, sendLabels[recvProc])(); - } - else - { - // I am receiver. Receive from sendProc. - IPstream fromProc(Pstream::scheduled, sendProc); - - Field fromFld(fromProc); - - // Destination faces - const labelList& faceLabels = receiveFaceLabels[sendProc]; - - forAll(fromFld, i) - { - label patchFaceI = faceLabels[i]; - - newValues[patchFaceI] = fromFld[i]; - } - } - } - - // Do data from myself - { - UIndirectList fromFld - ( - sendValues, - sendLabels[Pstream::myProcNo()] - ); - - // Destination faces - const labelList& faceLabels = receiveFaceLabels[Pstream::myProcNo()]; - - forAll(fromFld, i) - { - label patchFaceI = faceLabels[i]; - - newValues[patchFaceI] = fromFld[i]; - } - } -} - - template void directMappedFixedValueFvPatchField::updateCoeffs() { @@ -215,65 +158,94 @@ void directMappedFixedValueFvPatchField::updateCoeffs() return; } - // Get the directMappedPolyPatch - const directMappedPolyPatch& mpp = refCast + typedef GeometricField fieldType; + + // Get the scheduling information from the directMappedPatchBase + const directMappedPatchBase& mpp = refCast ( directMappedFixedValueFvPatchField::patch().patch() ); + const mapDistribute& distMap = mpp.map(); + const fvMesh& nbrMesh = refCast(mpp.sampleMesh()); + const word& fldName = this->dimensionedInternalField().name(); - Field newValues(this->size()); + // Result of obtaining remote values + Field newValues; switch (mpp.mode()) { - case directMappedPolyPatch::NEARESTCELL: + case directMappedPatchBase::NEARESTCELL: { - getNewValues(mpp, this->internalField(), newValues); + if (mpp.sameRegion()) + { + newValues = this->internalField(); + } + else + { + newValues = nbrMesh.lookupObject + ( + fldName + ).internalField(); + } + mapDistribute::distribute + ( + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), + newValues + ); break; } - case directMappedPolyPatch::NEARESTPATCHFACE: + case directMappedPatchBase::NEARESTPATCHFACE: { - const label patchID = - this->patch().patch().boundaryMesh().findPatchID - ( - mpp.samplePatch() - ); - if (patchID < 0) + const label nbrPatchID = nbrMesh.boundaryMesh().findPatchID + ( + mpp.samplePatch() + ); + if (nbrPatchID < 0) { FatalErrorIn ( "void directMappedFixedValueFvPatchField::" "updateCoeffs()" )<< "Unable to find sample patch " << mpp.samplePatch() + << " in region " << mpp.sampleRegion() << " for patch " << this->patch().name() << nl << abort(FatalError); } - typedef GeometricField fieldType; - const word& fieldName = this->dimensionedInternalField().name(); - const fieldType& sendField = - this->db().objectRegistry::lookupObject(fieldName); - getNewValues(mpp, sendField.boundaryField()[patchID], newValues); + const fieldType& nbrField = nbrMesh.lookupObject + ( + fldName + ); + newValues = nbrField.boundaryField()[nbrPatchID]; + mapDistribute::distribute + ( + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), + newValues + ); break; } - case directMappedPolyPatch::NEARESTFACE: + case directMappedPatchBase::NEARESTFACE: { - typedef GeometricField fieldType; - const word& fieldName = this->dimensionedInternalField().name(); - const fieldType& sendField = - this->db().objectRegistry::lookupObject(fieldName); + Field allValues(nbrMesh.nFaces(), pTraits::zero); - Field allValues + const fieldType& nbrField = nbrMesh.lookupObject ( - this->patch().patch().boundaryMesh().mesh().nFaces(), - pTraits::zero + fldName ); - - forAll(sendField.boundaryField(), patchI) + forAll(nbrField.boundaryField(), patchI) { const fvPatchField& pf = - sendField.boundaryField()[patchI]; + nbrField.boundaryField()[patchI]; label faceStart = pf.patch().patch().start(); forAll(pf, faceI) @@ -282,9 +254,17 @@ void directMappedFixedValueFvPatchField::updateCoeffs() } } - getNewValues(mpp, allValues, newValues); + mapDistribute::distribute + ( + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), + allValues + ); - newValues = this->patch().patchSlice(newValues); + newValues = this->patch().patchSlice(allValues); break; } diff --git a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H index 8c8da590a8..2382b32db8 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H @@ -62,18 +62,6 @@ class directMappedFixedValueFvPatchField // setAverage_ is set true Type average_; - - // Private member functions - - // Helper function to return the new field values - void getNewValues - ( - const directMappedPolyPatch& mpp, - const Field& sendValues, - Field& newValues - ) const; - - public: //- Runtime type information diff --git a/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C index 92bf63e8c6..5ac329fe31 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C @@ -26,7 +26,7 @@ License #include "directMappedVelocityFluxFixedValueFvPatchField.H" #include "fvPatchFieldMapper.H" -#include "directMappedFvPatch.H" +#include "directMappedPatchBase.H" #include "volFields.H" #include "surfaceFields.H" #include "addToRunTimeSelectionTable.H" @@ -62,12 +62,12 @@ directMappedVelocityFluxFixedValueFvPatchField fixedValueFvPatchVectorField(ptf, p, iF, mapper), phiName_(ptf.phiName_) { - if (!isType(patch())) + if (!isType(this->patch().patch())) { FatalErrorIn ( "directMappedVelocityFluxFixedValueFvPatchField::" - "directMappedFixedValueFvPatchField\n" + "directMappedVelocityFluxFixedValueFvPatchField\n" "(\n" " const directMappedVelocityFluxFixedValueFvPatchField&,\n" " const fvPatch&,\n" @@ -75,7 +75,7 @@ directMappedVelocityFluxFixedValueFvPatchField " const fvPatchFieldMapper&\n" ")\n" ) << "\n patch type '" << p.type() - << "' not type '" << typeName << "'" + << "' not type '" << directMappedPatchBase::typeName << "'" << "\n for patch " << p.name() << " of field " << dimensionedInternalField().name() << " in file " << dimensionedInternalField().objectPath() @@ -95,24 +95,31 @@ directMappedVelocityFluxFixedValueFvPatchField fixedValueFvPatchVectorField(p, iF, dict), phiName_(dict.lookup("phi")) { - if (!isType(patch())) + if (!isType(this->patch().patch())) { FatalErrorIn ( "directMappedVelocityFluxFixedValueFvPatchField::" - "directMappedFixedValueFvPatchField\n" + "directMappedVelocityFluxFixedValueFvPatchField\n" "(\n" " const fvPatch& p,\n" " const DimensionedField& iF,\n" " const dictionary& dict\n" ")\n" ) << "\n patch type '" << p.type() - << "' not type '" << typeName << "'" + << "' not type '" << directMappedPatchBase::typeName << "'" << "\n for patch " << p.name() << " of field " << dimensionedInternalField().name() << " in file " << dimensionedInternalField().objectPath() << exit(FatalError); } + + // Force calculation of schedule (uses parallel comms) + const directMappedPolyPatch& mpp = refCast + ( + patch().patch() + ); + (void)mpp.map().schedule(); } @@ -139,85 +146,6 @@ directMappedVelocityFluxFixedValueFvPatchField {} -void directMappedVelocityFluxFixedValueFvPatchField::getNewValues -( - const directMappedPolyPatch& mpp, - const vectorField& sendUValues, - const scalarField& sendPhiValues, - vectorField& newUValues, - scalarField& newPhiValues -) const -{ - // Get the scheduling information - const List& schedule = mpp.schedule(); - const labelListList& sendLabels = mpp.sendLabels(); - const labelListList& receiveFaceLabels = mpp.receiveFaceLabels(); - - forAll(schedule, i) - { - const labelPair& twoProcs = schedule[i]; - label sendProc = twoProcs[0]; - label recvProc = twoProcs[1]; - - if (Pstream::myProcNo() == sendProc) - { - OPstream toProc(Pstream::scheduled, recvProc); - toProc<< UIndirectList(sendUValues, sendLabels[recvProc])(); - toProc<< UIndirectList - ( - sendPhiValues, - sendLabels[recvProc] - )(); - } - else - { - // I am receiver. Receive from sendProc. - IPstream fromProc(Pstream::scheduled, sendProc); - - vectorField fromUFld(fromProc); - scalarField fromPhiFld(fromProc); - - // Destination faces - const labelList& faceLabels = receiveFaceLabels[sendProc]; - - forAll(fromUFld, i) - { - label patchFaceI = faceLabels[i]; - - newUValues[patchFaceI] = fromUFld[i]; - newPhiValues[patchFaceI] = fromPhiFld[i]; - } - } - } - - // Do data from myself - { - UIndirectList fromUFld - ( - sendUValues, - sendLabels[Pstream::myProcNo()] - ); - - UIndirectList fromPhiFld - ( - sendPhiValues, - sendLabels[Pstream::myProcNo()] - ); - - // Destination faces - const labelList& faceLabels = receiveFaceLabels[Pstream::myProcNo()]; - - forAll(fromUFld, i) - { - label patchFaceI = faceLabels[i]; - - newUValues[patchFaceI] = fromUFld[i]; - newPhiValues[patchFaceI] = fromPhiFld[i]; - } - } -} - - // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void directMappedVelocityFluxFixedValueFvPatchField::updateCoeffs() @@ -227,37 +155,33 @@ void directMappedVelocityFluxFixedValueFvPatchField::updateCoeffs() return; } - // Get the directMappedPolyPatch - const directMappedPolyPatch& mpp = refCast + // Get the directMappedPatchBase + const directMappedPatchBase& mpp = refCast ( directMappedVelocityFluxFixedValueFvPatchField::patch().patch() ); - - vectorField newUValues(size()); - scalarField newPhiValues(size()); - + const mapDistribute& distMap = mpp.map(); + const fvMesh& nbrMesh = refCast(mpp.sampleMesh()); const word& fieldName = dimensionedInternalField().name(); - const volVectorField& UField = db().lookupObject(fieldName); + const volVectorField& UField = nbrMesh.lookupObject + ( + fieldName + ); surfaceScalarField& phiField = const_cast ( - db().lookupObject(phiName_) + nbrMesh.lookupObject(phiName_) ); + vectorField newUValues; + scalarField newPhiValues; + switch (mpp.mode()) { case directMappedPolyPatch::NEARESTFACE: { - vectorField allUValues - ( - patch().patch().boundaryMesh().mesh().nFaces(), - vector::zero - ); - scalarField allPhiValues - ( - patch().patch().boundaryMesh().mesh().nFaces(), - 0.0 - ); + vectorField allUValues(nbrMesh.nFaces(), vector::zero); + scalarField allPhiValues(nbrMesh.nFaces(), 0.0); forAll(UField.boundaryField(), patchI) { @@ -273,34 +197,58 @@ void directMappedVelocityFluxFixedValueFvPatchField::updateCoeffs() } } - getNewValues + mapDistribute::distribute ( - mpp, - allUValues, - allPhiValues, - newUValues, + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), + allUValues + ); + newUValues = patch().patchSlice(newUValues); + + mapDistribute::distribute + ( + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), newPhiValues ); - - newUValues = patch().patchSlice(newUValues); newPhiValues = patch().patchSlice(newPhiValues); break; } case directMappedPolyPatch::NEARESTPATCHFACE: { - const label patchID = - patch().patch().boundaryMesh().findPatchID - ( - mpp.samplePatch() - ); - - getNewValues + const label nbrPatchID = nbrMesh.boundaryMesh().findPatchID ( - mpp, - UField.boundaryField()[patchID], - phiField.boundaryField()[patchID], - newUValues, + mpp.samplePatch() + ); + + newUValues = UField.boundaryField()[nbrPatchID]; + + mapDistribute::distribute + ( + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), + newUValues + ); + + newPhiValues = phiField.boundaryField()[nbrPatchID]; + + mapDistribute::distribute + ( + Pstream::defaultCommsType, + distMap.schedule(), + distMap.constructSize(), + distMap.subMap(), + distMap.constructMap(), newPhiValues ); diff --git a/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.H index b92372eb3a..6ec34d62e1 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.H @@ -57,20 +57,6 @@ class directMappedVelocityFluxFixedValueFvPatchField //- Name of flux field word phiName_; - - // Private member functions - - // Helper function to return the new field values - void getNewValues - ( - const directMappedPolyPatch& mpp, - const vectorField& sendUValues, - const scalarField& sendPhiValues, - vectorField& newUValues, - scalarField& newPhiValues - ) const; - - public: //- Runtime type information diff --git a/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.C b/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.C new file mode 100644 index 0000000000..413d5f86c2 --- /dev/null +++ b/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.C @@ -0,0 +1,38 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "directMappedWallFvPatch.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(directMappedWallFvPatch, 0); + addToRunTimeSelectionTable(fvPatch, directMappedWallFvPatch, polyPatch); +} + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.H b/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.H new file mode 100644 index 0000000000..4be7eed592 --- /dev/null +++ b/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.H @@ -0,0 +1,84 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::directMappedWallFvPatch + +Description + Foam::directMappedWallFvPatch + +SourceFiles + directMappedWallFvPatch.C + +\*---------------------------------------------------------------------------*/ + +#ifndef directMappedWallFvPatch_H +#define directMappedWallFvPatch_H + +#include "fvPatch.H" +#include "directMappedWallPolyPatch.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class directMappedWallFvPatch Declaration +\*---------------------------------------------------------------------------*/ + +class directMappedWallFvPatch +: + public fvPatch +{ + +public: + + //- Runtime type information + TypeName(directMappedWallPolyPatch::typeName_()); + + + // Constructors + + //- Construct from components + directMappedWallFvPatch + ( + const polyPatch& patch, + const fvBoundaryMesh& bm + ) + : + fvPatch(patch, bm) + {} +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files index 9f849c5894..d5133cb33d 100644 --- a/src/meshTools/Make/files +++ b/src/meshTools/Make/files @@ -141,7 +141,10 @@ triSurface/triSurfaceTools/geompack/geompack.C twoDPointCorrector/twoDPointCorrector.C +directMapped/directMappedPolyPatch/directMappedPatchBase.C directMapped/directMappedPolyPatch/directMappedPolyPatch.C +directMapped/directMappedPolyPatch/directMappedWallPolyPatch.C directMapped/directMappedPointPatch/directMappedPointPatch.C +directMapped/directMappedPointPatch/directMappedWallPointPatch.C LIB = $(FOAM_LIBBIN)/libmeshTools diff --git a/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.C b/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.C new file mode 100644 index 0000000000..4633d73ecf --- /dev/null +++ b/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.C @@ -0,0 +1,52 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "directMappedWallPointPatch.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +defineTypeNameAndDebug(directMappedWallPointPatch, 0); + +// Add the patch constructor functions to the hash tables +addToRunTimeSelectionTable +( + facePointPatch, + directMappedWallPointPatch, + polyPatch +); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.H b/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.H new file mode 100644 index 0000000000..28bb877105 --- /dev/null +++ b/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.H @@ -0,0 +1,84 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::directMappedWallPointPatch + +Description + DirectMapped patch. + +SourceFiles + directMappedWallPointPatch.C + +\*---------------------------------------------------------------------------*/ + +#ifndef directMappedWallPointPatch_H +#define directMappedWallPointPatch_H + +#include "facePointPatch.H" +#include "directMappedWallPolyPatch.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class directMappedWallPointPatch Declaration +\*---------------------------------------------------------------------------*/ + +class directMappedWallPointPatch +: + public facePointPatch +{ + +public: + + //- Runtime type information + TypeName(directMappedWallPolyPatch::typeName_()); + + + // Constructors + + //- Construct from polyPatch + directMappedWallPointPatch + ( + const polyPatch& patch, + const pointBoundaryMesh& bm + ) + : + facePointPatch(patch, bm) + {} +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.C b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.C new file mode 100644 index 0000000000..4852a54c2e --- /dev/null +++ b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.C @@ -0,0 +1,656 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "directMappedPatchBase.H" +#include "addToRunTimeSelectionTable.H" +#include "ListListOps.H" +#include "meshSearch.H" +#include "meshTools.H" +#include "OFstream.H" +#include "Random.H" +#include "treeDataFace.H" +#include "indexedOctree.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(directMappedPatchBase, 0); + + template<> + const char* NamedEnum::names[] = + { + "nearestCell", + "nearestPatchFace", + "nearestFace" + }; + + const NamedEnum + directMappedPatchBase::sampleModeNames_; +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::directMappedPatchBase::collectSamples +( + pointField& samples, + labelList& patchFaceProcs, + labelList& patchFaces, + pointField& patchFc +) const +{ + + // Collect all sample points and the faces they come from. + List globalFc(Pstream::nProcs()); + List globalSamples(Pstream::nProcs()); + labelListList globalFaces(Pstream::nProcs()); + + globalFc[Pstream::myProcNo()] = patch_.faceCentres(); + globalSamples[Pstream::myProcNo()] = globalFc[Pstream::myProcNo()]+offset_; + globalFaces[Pstream::myProcNo()] = identity(patch_.size()); + + // Distribute to all processors + Pstream::gatherList(globalSamples); + Pstream::scatterList(globalSamples); + Pstream::gatherList(globalFaces); + Pstream::scatterList(globalFaces); + Pstream::gatherList(globalFc); + Pstream::scatterList(globalFc); + + // Rework into straight list + samples = ListListOps::combine + ( + globalSamples, + accessOp() + ); + patchFaces = ListListOps::combine + ( + globalFaces, + accessOp() + ); + patchFc = ListListOps::combine + ( + globalFc, + accessOp() + ); + + patchFaceProcs.setSize(patchFaces.size()); + labelList nPerProc + ( + ListListOps::subSizes + ( + globalFaces, + accessOp() + ) + ); + label sampleI = 0; + forAll(nPerProc, procI) + { + for (label i = 0; i < nPerProc[procI]; i++) + { + patchFaceProcs[sampleI++] = procI; + } + } +} + + +// Find the processor/cell containing the samples. Does not account +// for samples being found in two processors. +void Foam::directMappedPatchBase::findSamples +( + const pointField& samples, + labelList& sampleProcs, + labelList& sampleIndices, + pointField& sampleLocations +) const +{ + // Lookup the correct region + const polyMesh& mesh = sampleMesh(); + + // All the info for nearest. Construct to miss + List nearest(samples.size()); + + switch (mode_) + { + case NEARESTCELL: + { + if (samplePatch_.size() && samplePatch_ != "none") + { + FatalErrorIn + ( + "directMappedPatchBase::findSamples(const pointField&," + " labelList&, labelList&, pointField&) const" + ) << "No need to supply a patch name when in " + << sampleModeNames_[mode_] << " mode." << exit(FatalError); + } + + // Octree based search engine + meshSearch meshSearchEngine(mesh, false); + + forAll(samples, sampleI) + { + const point& sample = samples[sampleI]; + + label cellI = meshSearchEngine.findCell(sample); + + if (cellI == -1) + { + nearest[sampleI].second().first() = Foam::sqr(GREAT); + nearest[sampleI].second().second() = Pstream::myProcNo(); + } + else + { + const point& cc = mesh.cellCentres()[cellI]; + + nearest[sampleI].first() = pointIndexHit + ( + true, + cc, + cellI + ); + nearest[sampleI].second().first() = magSqr(cc-sample); + nearest[sampleI].second().second() = Pstream::myProcNo(); + } + } + break; + } + + case NEARESTPATCHFACE: + { + Random rndGen(123456); + + const polyPatch& pp = samplePolyPatch(); + + if (pp.empty()) + { + forAll(samples, sampleI) + { + nearest[sampleI].second().first() = Foam::sqr(GREAT); + nearest[sampleI].second().second() = Pstream::myProcNo(); + } + } + else + { + // patch faces + const labelList patchFaces(identity(pp.size()) + pp.start()); + + treeBoundBox patchBb + ( + treeBoundBox(pp.points(), pp.meshPoints()).extend + ( + rndGen, + 1E-4 + ) + ); + patchBb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + patchBb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + + indexedOctree boundaryTree + ( + treeDataFace // all information needed to search faces + ( + false, // do not cache bb + mesh, + patchFaces // boundary faces only + ), + patchBb, // overall search domain + 8, // maxLevel + 10, // leafsize + 3.0 // duplicity + ); + + forAll(samples, sampleI) + { + const point& sample = samples[sampleI]; + + pointIndexHit& nearInfo = nearest[sampleI].first(); + nearInfo = boundaryTree.findNearest + ( + sample, + magSqr(patchBb.span()) + ); + + if (!nearInfo.hit()) + { + nearest[sampleI].second().first() = Foam::sqr(GREAT); + nearest[sampleI].second().second() = + Pstream::myProcNo(); + } + else + { + point fc(pp[nearInfo.index()].centre(pp.points())); + nearInfo.setPoint(fc); + nearest[sampleI].second().first() = magSqr(fc-sample); + nearest[sampleI].second().second() = + Pstream::myProcNo(); + } + } + } + break; + } + + case NEARESTFACE: + { + if (samplePatch_.size() && samplePatch_ != "none") + { + FatalErrorIn + ( + "directMappedPatchBase::findSamples(const pointField&," + " labelList&, labelList&, pointField&) const" + ) << "No need to supply a patch name when in " + << sampleModeNames_[mode_] << " mode." << exit(FatalError); + } + + // Octree based search engine + meshSearch meshSearchEngine(mesh, false); + + forAll(samples, sampleI) + { + const point& sample = samples[sampleI]; + + label faceI = meshSearchEngine.findNearestFace(sample); + + if (faceI == -1) + { + nearest[sampleI].second().first() = Foam::sqr(GREAT); + nearest[sampleI].second().second() = Pstream::myProcNo(); + } + else + { + const point& fc = mesh.faceCentres()[faceI]; + + nearest[sampleI].first() = pointIndexHit + ( + true, + fc, + faceI + ); + nearest[sampleI].second().first() = magSqr(fc-sample); + nearest[sampleI].second().second() = Pstream::myProcNo(); + } + } + break; + } + + default: + { + FatalErrorIn("directMappedPatchBase::findSamples(..)") + << "problem." << abort(FatalError); + } + } + + + // Find nearest. + Pstream::listCombineGather(nearest, nearestEqOp()); + Pstream::listCombineScatter(nearest); + + if (debug) + { + Info<< "directMappedPatchBase::findSamples on mesh " << sampleRegion_ + << " : " << endl; + forAll(nearest, sampleI) + { + label procI = nearest[sampleI].second().second(); + label localI = nearest[sampleI].first().index(); + + Info<< " " << sampleI << " coord:"<< samples[sampleI] + << " found on processor:" << procI + << " in local cell/face:" << localI + << " with cc:" << nearest[sampleI].first().rawPoint() << endl; + } + } + + // Check for samples not being found + forAll(nearest, sampleI) + { + if (!nearest[sampleI].first().hit()) + { + FatalErrorIn + ( + "directMappedPatchBase::findSamples" + "(const pointField&, labelList&" + ", labelList&, pointField&)" + ) << "Did not find sample " << samples[sampleI] + << " on any processor of region" << sampleRegion_ + << exit(FatalError); + } + } + + + // Convert back into proc+local index + sampleProcs.setSize(samples.size()); + sampleIndices.setSize(samples.size()); + sampleLocations.setSize(samples.size()); + + forAll(nearest, sampleI) + { + sampleProcs[sampleI] = nearest[sampleI].second().second(); + sampleIndices[sampleI] = nearest[sampleI].first().index(); + sampleLocations[sampleI] = nearest[sampleI].first().hitPoint(); + } +} + + +void Foam::directMappedPatchBase::calcMapping() const +{ + if (mapPtr_.valid()) + { + FatalErrorIn("directMappedPatchBase::calcMapping() const") + << "Mapping already calculated" << exit(FatalError); + } + + if + ( + offset_ == vector::zero + && sampleRegion_ == patch_.boundaryMesh().mesh().name() + ) + { + FatalErrorIn("directMappedPatchBase::calcMapping() const") + << "Invalid offset " << offset_ << endl + << "Offset is the vector added to the patch face centres to" + << " find the cell supplying the data." + << exit(FatalError); + } + + + // Get global list of all samples and the processor and face they come from. + pointField samples; + labelList patchFaceProcs; + labelList patchFaces; + pointField patchFc; + collectSamples(samples, patchFaceProcs, patchFaces, patchFc); + + // Find processor and cell/face samples are in and actual location. + labelList sampleProcs; + labelList sampleIndices; + pointField sampleLocations; + findSamples(samples, sampleProcs, sampleIndices, sampleLocations); + + + // Now we have all the data we need: + // - where sample originates from (so destination when mapping): + // patchFaces, patchFaceProcs. + // - cell/face sample is in (so source when mapping) + // sampleIndices, sampleProcs. + + //forAll(samples, i) + //{ + // Info<< i << " need data in region " + // << patch_.boundaryMesh().mesh().name() + // << " for proc:" << patchFaceProcs[i] + // << " face:" << patchFaces[i] + // << " at:" << patchFc[i] << endl + // << "Found data in region " << sampleRegion_ + // << " at proc:" << sampleProcs[i] + // << " face:" << sampleIndices[i] + // << " at:" << sampleLocations[i] + // << nl << endl; + //} + + + + if (debug && Pstream::master()) + { + OFstream str + ( + patch_.boundaryMesh().mesh().time().path() + / patch_.name() + + "_directMapped.obj" + ); + Pout<< "Dumping mapping as lines from patch faceCentres to" + << " sampled cellCentres to file " << str.name() << endl; + + label vertI = 0; + + forAll(patchFc, i) + { + meshTools::writeOBJ(str, patchFc[i]); + vertI++; + meshTools::writeOBJ(str, sampleLocations[i]); + vertI++; + str << "l " << vertI-1 << ' ' << vertI << nl; + } + } + + + // Check that actual offset vector (sampleLocations - patchFc) is more or + // less constant. + if (Pstream::master()) + { + const scalarField magOffset(mag(sampleLocations - patchFc)); + const scalar avgOffset(average(magOffset)); + + forAll(magOffset, sampleI) + { + if (mag(magOffset[sampleI]-avgOffset) > 0.001*avgOffset) + { + WarningIn("directMappedPatchBase::calcMapping() const") + << "The actual cell centres picked up using offset " + << offset_ << " are not" << endl + << " on a single plane." + << " This might give numerical problems." << endl + << " At patchface " << patchFc[sampleI] + << " the sampled cell " << sampleLocations[sampleI] << endl + << " is not on a plane " << avgOffset + << " offset from the patch." << endl + << " You might want to shift your plane offset." + << " Set the debug flag to get a dump of sampled cells." + << endl; + break; + } + } + } + + + // Determine schedule. + mapPtr_.reset(new mapDistribute(sampleProcs, patchFaceProcs)); + + // Rework the schedule from indices into samples to cell data to send, + // face data to receive. + + labelListList& subMap = mapPtr_().subMap(); + labelListList& constructMap = mapPtr_().constructMap(); + + forAll(subMap, procI) + { + subMap[procI] = UIndirectList