mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: parallel: overhaul of parallel mapping
- redistributePar to have almost (complete) functionality of decomposePar+reconstructPar - low-level distributed Field mapping - support for mapping surfaceFields (including flipping faces) - support for decomposing/reconstructing refinement data
This commit is contained in:
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -202,6 +202,7 @@ void subsetSurfaceFields
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const fvMesh& subMesh,
|
||||
const labelList& cellMap,
|
||||
const labelList& faceMap,
|
||||
const labelHashSet& addedPatches
|
||||
)
|
||||
@ -225,6 +226,7 @@ void subsetSurfaceFields
|
||||
fld,
|
||||
subMesh,
|
||||
patchMap,
|
||||
cellMap,
|
||||
faceMap
|
||||
)
|
||||
);
|
||||
@ -830,6 +832,7 @@ void createAndWriteRegion
|
||||
(
|
||||
mesh,
|
||||
newMesh(),
|
||||
map().cellMap(),
|
||||
map().faceMap(),
|
||||
addedPatches
|
||||
);
|
||||
@ -837,6 +840,7 @@ void createAndWriteRegion
|
||||
(
|
||||
mesh,
|
||||
newMesh(),
|
||||
map().cellMap(),
|
||||
map().faceMap(),
|
||||
addedPatches
|
||||
);
|
||||
@ -844,6 +848,7 @@ void createAndWriteRegion
|
||||
(
|
||||
mesh,
|
||||
newMesh(),
|
||||
map().cellMap(),
|
||||
map().faceMap(),
|
||||
addedPatches
|
||||
);
|
||||
@ -851,6 +856,7 @@ void createAndWriteRegion
|
||||
(
|
||||
mesh,
|
||||
newMesh(),
|
||||
map().cellMap(),
|
||||
map().faceMap(),
|
||||
addedPatches
|
||||
);
|
||||
@ -858,6 +864,7 @@ void createAndWriteRegion
|
||||
(
|
||||
mesh,
|
||||
newMesh(),
|
||||
map().cellMap(),
|
||||
map().faceMap(),
|
||||
addedPatches
|
||||
);
|
||||
|
||||
@ -2,6 +2,7 @@ EXE_INC = \
|
||||
-I$(LIB_SRC)/parallel/decompose/decompose/lnInclude \
|
||||
-I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/regionModels/regionModel/lnInclude
|
||||
@ -12,5 +13,6 @@ EXE_LIBS = \
|
||||
-lgenericPatchFields \
|
||||
-ldecompositionMethods -L$(FOAM_LIBBIN)/dummy -lmetisDecomp -lscotchDecomp \
|
||||
-llagrangian \
|
||||
-ldynamicMesh \
|
||||
-lmeshTools \
|
||||
-lregionModels
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -96,6 +96,7 @@ Usage
|
||||
#include "fvFieldDecomposer.H"
|
||||
#include "pointFieldDecomposer.H"
|
||||
#include "lagrangianFieldDecomposer.H"
|
||||
#include "decompositionModel.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -142,6 +143,12 @@ int main(int argc, char *argv[])
|
||||
);
|
||||
|
||||
argList::noParallel();
|
||||
Foam::argList::addOption
|
||||
(
|
||||
"decomposeParDict",
|
||||
"file",
|
||||
"read decomposePar dictionary from specified location"
|
||||
);
|
||||
#include "addRegionOption.H"
|
||||
argList::addBoolOption
|
||||
(
|
||||
@ -199,6 +206,17 @@ int main(int argc, char *argv[])
|
||||
instantList times = timeSelector::selectIfPresent(runTime, args);
|
||||
|
||||
|
||||
// Allow override of decomposeParDict location
|
||||
fileName decompDictFile;
|
||||
if (args.optionReadIfPresent("decomposeParDict", decompDictFile))
|
||||
{
|
||||
if (isDir(decompDictFile))
|
||||
{
|
||||
decompDictFile = decompDictFile/"decomposeParDict";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wordList regionNames;
|
||||
wordList regionDirs;
|
||||
if (allRegions)
|
||||
@ -260,10 +278,13 @@ int main(int argc, char *argv[])
|
||||
++nProcs;
|
||||
}
|
||||
|
||||
// get requested numberOfSubdomains
|
||||
// get requested numberOfSubdomains. Note: have no mesh yet so
|
||||
// cannot use decompositionModel::New
|
||||
const label nDomains = readLabel
|
||||
(
|
||||
IOdictionary
|
||||
(
|
||||
decompositionModel::selectIO
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
@ -274,7 +295,10 @@ int main(int argc, char *argv[])
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
decompDictFile
|
||||
)
|
||||
|
||||
).lookup("numberOfSubdomains")
|
||||
);
|
||||
|
||||
@ -288,8 +312,7 @@ int main(int argc, char *argv[])
|
||||
<< nProcs << " domains"
|
||||
<< nl
|
||||
<< "instead of " << nDomains
|
||||
<< " domains as specified in decomposeParDict"
|
||||
<< nl
|
||||
<< " domains as specified in decomposeParDict" << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
@ -351,7 +374,8 @@ int main(int argc, char *argv[])
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
)
|
||||
),
|
||||
decompDictFile
|
||||
);
|
||||
|
||||
// Decompose the mesh
|
||||
@ -447,15 +471,15 @@ int main(int argc, char *argv[])
|
||||
// Construct the vol fields
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PtrList<volScalarField> volScalarFields;
|
||||
readFields(mesh, objects, volScalarFields);
|
||||
readFields(mesh, objects, volScalarFields, false);
|
||||
PtrList<volVectorField> volVectorFields;
|
||||
readFields(mesh, objects, volVectorFields);
|
||||
readFields(mesh, objects, volVectorFields, false);
|
||||
PtrList<volSphericalTensorField> volSphericalTensorFields;
|
||||
readFields(mesh, objects, volSphericalTensorFields);
|
||||
readFields(mesh, objects, volSphericalTensorFields, false);
|
||||
PtrList<volSymmTensorField> volSymmTensorFields;
|
||||
readFields(mesh, objects, volSymmTensorFields);
|
||||
readFields(mesh, objects, volSymmTensorFields, false);
|
||||
PtrList<volTensorField> volTensorFields;
|
||||
readFields(mesh, objects, volTensorFields);
|
||||
readFields(mesh, objects, volTensorFields, false);
|
||||
|
||||
|
||||
// Construct the dimensioned fields
|
||||
@ -476,15 +500,15 @@ int main(int argc, char *argv[])
|
||||
// Construct the surface fields
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PtrList<surfaceScalarField> surfaceScalarFields;
|
||||
readFields(mesh, objects, surfaceScalarFields);
|
||||
readFields(mesh, objects, surfaceScalarFields, false);
|
||||
PtrList<surfaceVectorField> surfaceVectorFields;
|
||||
readFields(mesh, objects, surfaceVectorFields);
|
||||
readFields(mesh, objects, surfaceVectorFields, false);
|
||||
PtrList<surfaceSphericalTensorField> surfaceSphericalTensorFields;
|
||||
readFields(mesh, objects, surfaceSphericalTensorFields);
|
||||
readFields(mesh, objects, surfaceSphericalTensorFields, false);
|
||||
PtrList<surfaceSymmTensorField> surfaceSymmTensorFields;
|
||||
readFields(mesh, objects, surfaceSymmTensorFields);
|
||||
readFields(mesh, objects, surfaceSymmTensorFields, false);
|
||||
PtrList<surfaceTensorField> surfaceTensorFields;
|
||||
readFields(mesh, objects, surfaceTensorFields);
|
||||
readFields(mesh, objects, surfaceTensorFields, false);
|
||||
|
||||
|
||||
// Construct the point fields
|
||||
@ -492,15 +516,15 @@ int main(int argc, char *argv[])
|
||||
const pointMesh& pMesh = pointMesh::New(mesh);
|
||||
|
||||
PtrList<pointScalarField> pointScalarFields;
|
||||
readFields(pMesh, objects, pointScalarFields);
|
||||
readFields(pMesh, objects, pointScalarFields, false);
|
||||
PtrList<pointVectorField> pointVectorFields;
|
||||
readFields(pMesh, objects, pointVectorFields);
|
||||
readFields(pMesh, objects, pointVectorFields, false);
|
||||
PtrList<pointSphericalTensorField> pointSphericalTensorFields;
|
||||
readFields(pMesh, objects, pointSphericalTensorFields);
|
||||
readFields(pMesh, objects, pointSphericalTensorFields, false);
|
||||
PtrList<pointSymmTensorField> pointSymmTensorFields;
|
||||
readFields(pMesh, objects, pointSymmTensorFields);
|
||||
readFields(pMesh, objects, pointSymmTensorFields, false);
|
||||
PtrList<pointTensorField> pointTensorFields;
|
||||
readFields(pMesh, objects, pointTensorFields);
|
||||
readFields(pMesh, objects, pointTensorFields, false);
|
||||
|
||||
|
||||
// Construct the Lagrangian fields
|
||||
@ -820,16 +844,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
processorDb.setTime(runTime);
|
||||
|
||||
// remove files remnants that can cause horrible problems
|
||||
// - mut and nut are used to mark the new turbulence models,
|
||||
// their existence prevents old models from being upgraded
|
||||
{
|
||||
fileName timeDir(processorDb.path()/processorDb.timeName());
|
||||
|
||||
rm(timeDir/"mut");
|
||||
rm(timeDir/"nut");
|
||||
}
|
||||
|
||||
// read the mesh
|
||||
if (!procMeshList.set(procI))
|
||||
{
|
||||
|
||||
@ -17,11 +17,61 @@ FoamFile
|
||||
|
||||
numberOfSubdomains 2;
|
||||
|
||||
|
||||
// Optional decomposition constraints
|
||||
//constraints
|
||||
//{
|
||||
// preserveBaffles
|
||||
// {
|
||||
// //- Keep owner and neighbour of baffles on same processor (i.e.
|
||||
// // keep it detectable as a baffle). Baffles are two boundary face
|
||||
// // sharing the same points
|
||||
// type preserveBaffles;
|
||||
// }
|
||||
// preserveFaceZones
|
||||
// {
|
||||
// //- Keep owner and neighbour on same processor for faces in zones
|
||||
// type preserveFaceZones;
|
||||
// zones (".*");
|
||||
// }
|
||||
// preservePatches
|
||||
// {
|
||||
// //- Keep owner and neighbour on same processor for faces in patches
|
||||
// // (only makes sense for cyclic patches. Not suitable for e.g.
|
||||
// // cyclicAMI since these are not coupled on the patch level. Use
|
||||
// // singleProcessorFaceSets for those)
|
||||
// type preservePatches;
|
||||
// patches (".*");
|
||||
// }
|
||||
// singleProcessorFaceSets
|
||||
// {
|
||||
// //- Keep all of faceSet on a single processor. This puts all cells
|
||||
// // connected with a point, edge or face on the same processor.
|
||||
// // (just having face connected cells might not guarantee a balanced
|
||||
// // decomposition)
|
||||
// // The processor can be -1 (the decompositionMethod chooses the
|
||||
// // processor for a good load balance) or explicitly provided (upsets
|
||||
// // balance)
|
||||
// type singleProcessorFaceSets;
|
||||
// singleProcessorFaceSets ((f1 -1));
|
||||
// }
|
||||
// refinementHistory
|
||||
// {
|
||||
// //- Decompose cells such that all cell originating from single cell
|
||||
// // end up on same processor
|
||||
// type refinementHistory;
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
// Deprecated form of specifying decomposition constraints:
|
||||
//- Keep owner and neighbour on same processor for faces in zones:
|
||||
// preserveFaceZones (heater solid1 solid3);
|
||||
|
||||
//- Keep owner and neighbour on same processor for faces in patches:
|
||||
// (makes sense only for cyclic patches)
|
||||
// (makes sense only for cyclic patches. Not suitable for e.g. cyclicAMI
|
||||
// since these are not coupled on the patch level. Use
|
||||
// singleProcessorFaceSets for those)
|
||||
//preservePatches (cyclic_half0 cyclic_half1);
|
||||
|
||||
//- Keep all of faceSet on a single processor. This puts all cells
|
||||
@ -32,12 +82,13 @@ numberOfSubdomains 2;
|
||||
// for a good load balance) or explicitly provided (upsets balance).
|
||||
//singleProcessorFaceSets ((f0 -1));
|
||||
|
||||
|
||||
//- Keep owner and neighbour of baffles on same processor (i.e. keep it
|
||||
// detectable as a baffle). Baffles are two boundary face sharing the
|
||||
// same points.
|
||||
//preserveBaffles true;
|
||||
|
||||
|
||||
|
||||
//- Use the volScalarField named here as a weight for each cell in the
|
||||
// decomposition. For example, use a particle population field to decompose
|
||||
// for a balanced number of particles in a lagrangian simulation.
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -31,14 +31,14 @@ License
|
||||
#include "fvMesh.H"
|
||||
#include "OSspecific.H"
|
||||
#include "Map.H"
|
||||
#include "globalMeshData.H"
|
||||
#include "DynamicList.H"
|
||||
#include "fvFieldDecomposer.H"
|
||||
#include "IOobjectList.H"
|
||||
#include "cellSet.H"
|
||||
#include "faceSet.H"
|
||||
#include "pointSet.H"
|
||||
#include "uniformDimensionedFields.H"
|
||||
#include "decompositionModel.H"
|
||||
#include "hexRef8Data.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
@ -69,7 +69,12 @@ void Foam::domainDecomposition::mark
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::domainDecomposition::domainDecomposition(const IOobject& io)
|
||||
// from components
|
||||
Foam::domainDecomposition::domainDecomposition
|
||||
(
|
||||
const IOobject& io,
|
||||
const fileName& decompDictFile
|
||||
)
|
||||
:
|
||||
fvMesh(io),
|
||||
facesInstancePointsPtr_
|
||||
@ -90,18 +95,18 @@ Foam::domainDecomposition::domainDecomposition(const IOobject& io)
|
||||
)
|
||||
: NULL
|
||||
),
|
||||
decompositionDict_
|
||||
decompDictFile_(decompDictFile),
|
||||
nProcs_
|
||||
(
|
||||
IOobject
|
||||
readInt
|
||||
(
|
||||
decompositionModel::New
|
||||
(
|
||||
"decomposeParDict",
|
||||
time().system(),
|
||||
*this,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE
|
||||
decompDictFile
|
||||
).lookup("numberOfSubdomains")
|
||||
)
|
||||
),
|
||||
nProcs_(readInt(decompositionDict_.lookup("numberOfSubdomains"))),
|
||||
distributed_(false),
|
||||
cellToProc_(nCells()),
|
||||
procPointAddressing_(nProcs_),
|
||||
@ -115,7 +120,11 @@ Foam::domainDecomposition::domainDecomposition(const IOobject& io)
|
||||
procProcessorPatchSubPatchIDs_(nProcs_),
|
||||
procProcessorPatchSubPatchStarts_(nProcs_)
|
||||
{
|
||||
decompositionDict_.readIfPresent("distributed", distributed_);
|
||||
decompositionModel::New
|
||||
(
|
||||
*this,
|
||||
decompDictFile
|
||||
).readIfPresent("distributed", distributed_);
|
||||
}
|
||||
|
||||
|
||||
@ -195,57 +204,20 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets)
|
||||
}
|
||||
|
||||
|
||||
autoPtr<labelIOList> cellLevelPtr;
|
||||
{
|
||||
IOobject io
|
||||
// Load refinement data (if any)
|
||||
hexRef8Data baseMeshData
|
||||
(
|
||||
"cellLevel",
|
||||
IOobject
|
||||
(
|
||||
"dummy",
|
||||
facesInstance(),
|
||||
polyMesh::meshSubDir,
|
||||
*this,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
)
|
||||
);
|
||||
if (io.headerOk())
|
||||
{
|
||||
Info<< "Reading hexRef8 data : " << io.name() << endl;
|
||||
cellLevelPtr.reset(new labelIOList(io));
|
||||
}
|
||||
}
|
||||
autoPtr<labelIOList> pointLevelPtr;
|
||||
{
|
||||
IOobject io
|
||||
(
|
||||
"pointLevel",
|
||||
facesInstance(),
|
||||
polyMesh::meshSubDir,
|
||||
*this,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
if (io.headerOk())
|
||||
{
|
||||
Info<< "Reading hexRef8 data : " << io.name() << endl;
|
||||
pointLevelPtr.reset(new labelIOList(io));
|
||||
}
|
||||
}
|
||||
autoPtr<uniformDimensionedScalarField> level0EdgePtr;
|
||||
{
|
||||
IOobject io
|
||||
(
|
||||
"level0Edge",
|
||||
facesInstance(),
|
||||
polyMesh::meshSubDir,
|
||||
*this,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
if (io.headerOk())
|
||||
{
|
||||
Info<< "Reading hexRef8 data : " << io.name() << endl;
|
||||
level0EdgePtr.reset(new uniformDimensionedScalarField(io));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -816,8 +788,8 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets)
|
||||
}
|
||||
}
|
||||
|
||||
// Set the precision of the points data to 10
|
||||
IOstream::defaultPrecision(10);
|
||||
// Set the precision of the points data to be min 10
|
||||
IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
|
||||
|
||||
procMesh.write();
|
||||
|
||||
@ -887,64 +859,23 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets)
|
||||
}
|
||||
|
||||
|
||||
// hexRef8 data
|
||||
if (cellLevelPtr.valid())
|
||||
{
|
||||
labelIOList
|
||||
// Optional hexRef8 data
|
||||
hexRef8Data
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
cellLevelPtr().name(),
|
||||
"dummy",
|
||||
facesInstance(),
|
||||
polyMesh::meshSubDir,
|
||||
procMesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
UIndirectList<label>
|
||||
(
|
||||
cellLevelPtr(),
|
||||
procCellAddressing_[procI]
|
||||
)()
|
||||
).write();
|
||||
}
|
||||
if (pointLevelPtr.valid())
|
||||
{
|
||||
labelIOList
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
pointLevelPtr().name(),
|
||||
facesInstance(),
|
||||
polyMesh::meshSubDir,
|
||||
procMesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
UIndirectList<label>
|
||||
(
|
||||
pointLevelPtr(),
|
||||
baseMeshData,
|
||||
procCellAddressing_[procI],
|
||||
procPointAddressing_[procI]
|
||||
)()
|
||||
).write();
|
||||
}
|
||||
if (level0EdgePtr.valid())
|
||||
{
|
||||
uniformDimensionedScalarField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
level0EdgePtr().name(),
|
||||
facesInstance(),
|
||||
polyMesh::meshSubDir,
|
||||
procMesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
level0EdgePtr()
|
||||
).write();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Statistics
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -61,8 +61,8 @@ class domainDecomposition
|
||||
//- Optional: points at the facesInstance
|
||||
autoPtr<pointIOField> facesInstancePointsPtr_;
|
||||
|
||||
//- Mesh decomposition control dictionary
|
||||
IOdictionary decompositionDict_;
|
||||
//- Optional non-standard file for decomposeParDict
|
||||
const fileName decompDictFile_;
|
||||
|
||||
//- Number of processors in decomposition
|
||||
label nProcs_;
|
||||
@ -159,8 +159,13 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from IOobject
|
||||
domainDecomposition(const IOobject& io);
|
||||
//- Construct from IOobjects (for mesh and optional non-standard
|
||||
// decomposeParDict location)
|
||||
domainDecomposition
|
||||
(
|
||||
const IOobject& io,
|
||||
const fileName& decompDictFile = ""
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -30,6 +30,7 @@ License
|
||||
#include "regionSplit.H"
|
||||
#include "Tuple2.H"
|
||||
#include "faceSet.H"
|
||||
#include "decompositionModel.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -39,15 +40,17 @@ void Foam::domainDecomposition::distributeCells()
|
||||
|
||||
cpuTime decompositionTime;
|
||||
|
||||
autoPtr<decompositionMethod> decomposePtr = decompositionMethod::New
|
||||
const decompositionModel& method = decompositionModel::New
|
||||
(
|
||||
decompositionDict_
|
||||
*this,
|
||||
decompDictFile_
|
||||
);
|
||||
|
||||
|
||||
scalarField cellWeights;
|
||||
if (decompositionDict_.found("weightField"))
|
||||
if (method.found("weightField"))
|
||||
{
|
||||
word weightName = decompositionDict_.lookup("weightField");
|
||||
word weightName = method.lookup("weightField");
|
||||
|
||||
volScalarField weights
|
||||
(
|
||||
@ -64,7 +67,7 @@ void Foam::domainDecomposition::distributeCells()
|
||||
cellWeights = weights.internalField();
|
||||
}
|
||||
|
||||
cellToProc_ = decomposePtr().decompose(*this, cellWeights);
|
||||
cellToProc_ = method.decomposer().decompose(*this, cellWeights);
|
||||
|
||||
Info<< "\nFinished decomposition in "
|
||||
<< decompositionTime.elapsedCpuTime()
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -23,10 +23,48 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "GeometricField.H"
|
||||
#include "readFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||
void Foam::readFields
|
||||
(
|
||||
const typename GeoMesh::Mesh& mesh,
|
||||
const IOobjectList& objects,
|
||||
PtrList<GeometricField<Type, PatchField, GeoMesh> >& fields,
|
||||
const bool readOldTime
|
||||
)
|
||||
{
|
||||
typedef GeometricField<Type, PatchField, GeoMesh> GeoField;
|
||||
|
||||
// Search list of objects for fields of type GeomField
|
||||
IOobjectList fieldObjects(objects.lookupClass(GeoField::typeName));
|
||||
|
||||
// Remove the cellDist field
|
||||
IOobjectList::iterator celDistIter = fieldObjects.find("cellDist");
|
||||
if (celDistIter != fieldObjects.end())
|
||||
{
|
||||
fieldObjects.erase(celDistIter);
|
||||
}
|
||||
|
||||
// Get sorted set of names (different processors might read objects in
|
||||
// different order)
|
||||
const wordList masterNames(fieldObjects.sortedNames());
|
||||
|
||||
// Construct the fields
|
||||
fields.setSize(masterNames.size());
|
||||
|
||||
forAll(masterNames, i)
|
||||
{
|
||||
const IOobject& io = *fieldObjects[masterNames[i]];
|
||||
|
||||
fields.set(i, new GeoField(io, mesh, readOldTime));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Mesh, class GeoField>
|
||||
void Foam::readFields
|
||||
(
|
||||
@ -38,24 +76,21 @@ void Foam::readFields
|
||||
// Search list of objects for fields of type GeomField
|
||||
IOobjectList fieldObjects(objects.lookupClass(GeoField::typeName));
|
||||
|
||||
// Remove the cellDist field
|
||||
IOobjectList::iterator celDistIter = fieldObjects.find("cellDist");
|
||||
if (celDistIter != fieldObjects.end())
|
||||
{
|
||||
fieldObjects.erase(celDistIter);
|
||||
}
|
||||
|
||||
// Construct the fields
|
||||
fields.setSize(fieldObjects.size());
|
||||
|
||||
label fieldI = 0;
|
||||
forAllIter(IOobjectList, fieldObjects, iter)
|
||||
// Get sorted set of names (different processors might read objects in
|
||||
// different order)
|
||||
const wordList masterNames(fieldObjects.sortedNames());
|
||||
|
||||
// Construct the fields
|
||||
fields.setSize(masterNames.size());
|
||||
|
||||
forAll(masterNames, i)
|
||||
{
|
||||
fields.set
|
||||
(
|
||||
fieldI++,
|
||||
new GeoField(*iter(), mesh)
|
||||
);
|
||||
const IOobject& io = *fieldObjects[masterNames[i]];
|
||||
|
||||
fields.set(i, new GeoField(io, mesh));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -41,6 +41,16 @@ SourceFiles
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
// Read the fields and hold on the pointer list
|
||||
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||
void readFields
|
||||
(
|
||||
const typename GeoMesh::Mesh& mesh,
|
||||
const IOobjectList& objects,
|
||||
PtrList<GeometricField<Type, PatchField, GeoMesh> >& fields,
|
||||
const bool readOldTime
|
||||
);
|
||||
|
||||
// Read the fields and hold on the pointer list
|
||||
template<class Mesh, class GeoField>
|
||||
void readFields
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/parallel/reconstruct/reconstruct/lnInclude \
|
||||
-I$(LIB_SRC)/regionModels/regionModel/lnInclude
|
||||
@ -9,6 +10,7 @@ EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-lgenericPatchFields \
|
||||
-llagrangian \
|
||||
-ldynamicMesh \
|
||||
-lmeshTools \
|
||||
-lreconstruct \
|
||||
-lregionModels
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -45,6 +45,8 @@ Description
|
||||
#include "faceSet.H"
|
||||
#include "pointSet.H"
|
||||
|
||||
#include "hexRef8Data.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
bool haveAllTimes
|
||||
@ -865,6 +867,78 @@ int main(int argc, char *argv[])
|
||||
pointSets[i].write();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Reconstruct refinement data
|
||||
{
|
||||
PtrList<hexRef8Data> procData(procMeshes.meshes().size());
|
||||
|
||||
forAll(procMeshes.meshes(), procI)
|
||||
{
|
||||
const fvMesh& procMesh = procMeshes.meshes()[procI];
|
||||
|
||||
procData.set
|
||||
(
|
||||
procI,
|
||||
new hexRef8Data
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"dummy",
|
||||
procMesh.time().timeName(),
|
||||
polyMesh::meshSubDir,
|
||||
procMesh,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Combine individual parts
|
||||
|
||||
const PtrList<labelIOList>& cellAddr =
|
||||
procMeshes.cellProcAddressing();
|
||||
|
||||
UPtrList<const labelList> cellMaps(cellAddr.size());
|
||||
forAll(cellAddr, i)
|
||||
{
|
||||
cellMaps.set(i, &cellAddr[i]);
|
||||
}
|
||||
|
||||
const PtrList<labelIOList>& pointAddr =
|
||||
procMeshes.pointProcAddressing();
|
||||
|
||||
UPtrList<const labelList> pointMaps(pointAddr.size());
|
||||
forAll(pointAddr, i)
|
||||
{
|
||||
pointMaps.set(i, &pointAddr[i]);
|
||||
}
|
||||
|
||||
UPtrList<const hexRef8Data> procRefs(procData.size());
|
||||
forAll(procData, i)
|
||||
{
|
||||
procRefs.set(i, &procData[i]);
|
||||
}
|
||||
|
||||
hexRef8Data
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"dummy",
|
||||
mesh.time().timeName(),
|
||||
polyMesh::meshSubDir,
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
cellMaps,
|
||||
pointMaps,
|
||||
procRefs
|
||||
).write();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -882,7 +956,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "End.\n" << endl;
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -899,7 +899,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
Info<< "End.\n" << endl;
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
parLagrangianRedistributor.C
|
||||
parFvFieldReconstructor.C
|
||||
loadOrCreateMesh.C
|
||||
redistributePar.C
|
||||
|
||||
|
||||
@ -1,13 +1,17 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \
|
||||
-I$(LIB_SRC)/parallel/decompose/decompose/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-lgenericPatchFields \
|
||||
-ldecompositionMethods \
|
||||
-L$(FOAM_LIBBIN)/dummy -lptscotchDecomp \
|
||||
-L$(FOAM_LIBBIN)/dummy -lptscotchDecomp -lscotchDecomp \
|
||||
-ldecompose \
|
||||
-lmeshTools \
|
||||
-llagrangian \
|
||||
-ldynamicMesh
|
||||
|
||||
@ -0,0 +1,131 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::distributedUnallocatedDirectFieldMapper
|
||||
|
||||
Description
|
||||
FieldMapper with direct mapping from remote quantities.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef distributedUnallocatedDirectFieldMapper_H
|
||||
#define distributedUnallocatedDirectFieldMapper_H
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class distributedUnallocatedDirectFieldMapper Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class distributedUnallocatedDirectFieldMapper
|
||||
:
|
||||
public FieldMapper
|
||||
{
|
||||
const labelUList& directAddressing_;
|
||||
|
||||
const mapDistributeBase& distMap_;
|
||||
|
||||
bool hasUnmapped_;
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct given addressing
|
||||
distributedUnallocatedDirectFieldMapper
|
||||
(
|
||||
const labelUList& directAddressing,
|
||||
const mapDistributeBase& distMap
|
||||
)
|
||||
:
|
||||
directAddressing_(directAddressing),
|
||||
distMap_(distMap),
|
||||
hasUnmapped_(false)
|
||||
{
|
||||
if
|
||||
(
|
||||
notNull(directAddressing_)
|
||||
&& directAddressing_.size()
|
||||
&& min(directAddressing_) < 0
|
||||
)
|
||||
{
|
||||
hasUnmapped_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
//- Destructor
|
||||
virtual ~distributedUnallocatedDirectFieldMapper()
|
||||
{}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
virtual label size() const
|
||||
{
|
||||
return
|
||||
(
|
||||
notNull(directAddressing_)
|
||||
? directAddressing_.size()
|
||||
: distMap_.constructSize()
|
||||
);
|
||||
}
|
||||
|
||||
virtual bool direct() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool distributed() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual const mapDistributeBase& distributeMap() const
|
||||
{
|
||||
return distMap_;
|
||||
}
|
||||
|
||||
virtual bool hasUnmapped() const
|
||||
{
|
||||
return hasUnmapped_;
|
||||
}
|
||||
|
||||
virtual const labelUList& directAddressing() const
|
||||
{
|
||||
return directAddressing_;
|
||||
}
|
||||
};
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -22,15 +22,15 @@ License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::weightedFvPatchFieldMapper
|
||||
Foam::distributedUnallocatedDirectFvPatchFieldMapper
|
||||
|
||||
Description
|
||||
FieldMapper with weighted mapping.
|
||||
FieldMapper with direct mapping from remote quantities.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef weightedFvPatchFieldMapper_H
|
||||
#define weightedFvPatchFieldMapper_H
|
||||
#ifndef distributedUnallocatedDirectFvPatchFieldMapper_H
|
||||
#define distributedUnallocatedDirectFvPatchFieldMapper_H
|
||||
|
||||
#include "fvPatchFieldMapper.H"
|
||||
|
||||
@ -40,16 +40,16 @@ namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class weightedFvPatchFieldMapper Declaration
|
||||
Class distributedUnallocatedDirectFvPatchFieldMapper Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class weightedFvPatchFieldMapper
|
||||
class distributedUnallocatedDirectFvPatchFieldMapper
|
||||
:
|
||||
public fvPatchFieldMapper
|
||||
{
|
||||
const labelListList& addressing_;
|
||||
const labelUList& directAddressing_;
|
||||
|
||||
const scalarListList& weights_;
|
||||
const mapDistributeBase& distMap_;
|
||||
|
||||
bool hasUnmapped_;
|
||||
|
||||
@ -58,27 +58,29 @@ public:
|
||||
// Constructors
|
||||
|
||||
//- Construct given addressing
|
||||
weightedFvPatchFieldMapper
|
||||
distributedUnallocatedDirectFvPatchFieldMapper
|
||||
(
|
||||
const labelListList& addressing,
|
||||
const scalarListList& weights
|
||||
const labelUList& directAddressing,
|
||||
const mapDistributeBase& distMap
|
||||
)
|
||||
:
|
||||
addressing_(addressing),
|
||||
weights_(weights),
|
||||
directAddressing_(directAddressing),
|
||||
distMap_(distMap),
|
||||
hasUnmapped_(false)
|
||||
{
|
||||
forAll(addressing_, i)
|
||||
{
|
||||
if (addressing_[i].size() == 0)
|
||||
if
|
||||
(
|
||||
notNull(directAddressing_)
|
||||
&& directAddressing_.size()
|
||||
&& min(directAddressing_) < 0
|
||||
)
|
||||
{
|
||||
hasUnmapped_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- Destructor
|
||||
virtual ~weightedFvPatchFieldMapper()
|
||||
virtual ~distributedUnallocatedDirectFvPatchFieldMapper()
|
||||
{}
|
||||
|
||||
|
||||
@ -86,12 +88,27 @@ public:
|
||||
|
||||
virtual label size() const
|
||||
{
|
||||
return addressing().size();
|
||||
return
|
||||
(
|
||||
notNull(directAddressing_)
|
||||
? directAddressing_.size()
|
||||
: distMap_.constructSize()
|
||||
);
|
||||
}
|
||||
|
||||
virtual bool direct() const
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool distributed() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual const mapDistributeBase& distributeMap() const
|
||||
{
|
||||
return distMap_;
|
||||
}
|
||||
|
||||
virtual bool hasUnmapped() const
|
||||
@ -99,16 +116,10 @@ public:
|
||||
return hasUnmapped_;
|
||||
}
|
||||
|
||||
virtual const labelListList& addressing() const
|
||||
virtual const labelUList& directAddressing() const
|
||||
{
|
||||
return addressing_;
|
||||
return directAddressing_;
|
||||
}
|
||||
|
||||
virtual const scalarListList& weights() const
|
||||
{
|
||||
return weights_;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -27,14 +27,15 @@ License
|
||||
#include "processorPolyPatch.H"
|
||||
#include "processorCyclicPolyPatch.H"
|
||||
#include "Time.H"
|
||||
#include "IOPtrList.H"
|
||||
//#include "IOPtrList.H"
|
||||
#include "polyBoundaryMeshEntries.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTemplateTypeNameAndDebug(IOPtrList<entry>, 0);
|
||||
}
|
||||
//namespace Foam
|
||||
//{
|
||||
// defineTemplateTypeNameAndDebug(IOPtrList<entry>, 0);
|
||||
//}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -46,6 +47,9 @@ Foam::autoPtr<Foam::fvMesh> Foam::loadOrCreateMesh
|
||||
const IOobject& io
|
||||
)
|
||||
{
|
||||
// Region name
|
||||
// ~~~~~~~~~~~
|
||||
|
||||
fileName meshSubDir;
|
||||
|
||||
if (io.name() == polyMesh::defaultRegion)
|
||||
@ -58,24 +62,52 @@ Foam::autoPtr<Foam::fvMesh> Foam::loadOrCreateMesh
|
||||
}
|
||||
|
||||
|
||||
// Scatter master patches
|
||||
// Patch types
|
||||
// ~~~~~~~~~~~
|
||||
// Read and scatter master patches (without reading master mesh!)
|
||||
|
||||
PtrList<entry> patchEntries;
|
||||
if (Pstream::master())
|
||||
{
|
||||
// Read PtrList of dictionary as dictionary.
|
||||
const word oldTypeName = IOPtrList<entry>::typeName;
|
||||
const_cast<word&>(IOPtrList<entry>::typeName) = word::null;
|
||||
IOPtrList<entry> dictList
|
||||
//// Read PtrList of dictionary as dictionary.
|
||||
//const word oldTypeName = IOPtrList<entry>::typeName;
|
||||
//const_cast<word&>(IOPtrList<entry>::typeName) = word::null;
|
||||
//IOPtrList<entry> dictList
|
||||
//(
|
||||
// IOobject
|
||||
// (
|
||||
// "boundary",
|
||||
// io.time().findInstance
|
||||
// (
|
||||
// meshSubDir,
|
||||
// "boundary",
|
||||
// IOobject::MUST_READ
|
||||
// ),
|
||||
// meshSubDir,
|
||||
// io.db(),
|
||||
// IOobject::MUST_READ,
|
||||
// IOobject::NO_WRITE,
|
||||
// false
|
||||
// )
|
||||
//);
|
||||
//const_cast<word&>(IOPtrList<entry>::typeName) = oldTypeName;
|
||||
//// Fake type back to what was in field
|
||||
//const_cast<word&>(dictList.type()) = dictList.headerClassName();
|
||||
//
|
||||
//patchEntries.transfer(dictList);
|
||||
const fileName facesInstance = io.time().findInstance
|
||||
(
|
||||
meshSubDir,
|
||||
"faces",
|
||||
IOobject::MUST_READ
|
||||
);
|
||||
|
||||
patchEntries = polyBoundaryMeshEntries
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"boundary",
|
||||
io.time().findInstance
|
||||
(
|
||||
meshSubDir,
|
||||
"boundary",
|
||||
IOobject::MUST_READ
|
||||
),
|
||||
facesInstance,
|
||||
meshSubDir,
|
||||
io.db(),
|
||||
IOobject::MUST_READ,
|
||||
@ -83,11 +115,6 @@ Foam::autoPtr<Foam::fvMesh> Foam::loadOrCreateMesh
|
||||
false
|
||||
)
|
||||
);
|
||||
const_cast<word&>(IOPtrList<entry>::typeName) = oldTypeName;
|
||||
// Fake type back to what was in field
|
||||
const_cast<word&>(dictList.type()) = dictList.headerClassName();
|
||||
|
||||
patchEntries.transfer(dictList);
|
||||
|
||||
// Send patches
|
||||
for
|
||||
@ -110,8 +137,16 @@ Foam::autoPtr<Foam::fvMesh> Foam::loadOrCreateMesh
|
||||
|
||||
|
||||
|
||||
// Dummy meshes
|
||||
// ~~~~~~~~~~~~
|
||||
|
||||
// Check who has a mesh
|
||||
const bool haveMesh = isDir(io.time().path()/io.instance()/meshSubDir);
|
||||
//const bool haveMesh = isDir(io.time().path()/io.instance()/meshSubDir);
|
||||
const bool haveMesh = isFile
|
||||
(
|
||||
io.time().path()/io.instance()/meshSubDir/"faces"
|
||||
);
|
||||
|
||||
|
||||
if (!haveMesh)
|
||||
{
|
||||
@ -164,6 +199,7 @@ Foam::autoPtr<Foam::fvMesh> Foam::loadOrCreateMesh
|
||||
patches.setSize(nPatches);
|
||||
dummyMesh.addFvPatches(patches, false); // no parallel comms
|
||||
|
||||
|
||||
// Add some dummy zones so upon reading it does not read them
|
||||
// from the undecomposed case. Should be done as extra argument to
|
||||
// regIOobject::readStream?
|
||||
@ -202,6 +238,9 @@ Foam::autoPtr<Foam::fvMesh> Foam::loadOrCreateMesh
|
||||
)
|
||||
);
|
||||
dummyMesh.addZones(pz, fz, cz);
|
||||
dummyMesh.pointZones().clear();
|
||||
dummyMesh.faceZones().clear();
|
||||
dummyMesh.cellZones().clear();
|
||||
//Pout<< "Writing dummy mesh to " << dummyMesh.polyMesh::objectPath()
|
||||
// << endl;
|
||||
dummyMesh.write();
|
||||
@ -209,11 +248,19 @@ Foam::autoPtr<Foam::fvMesh> Foam::loadOrCreateMesh
|
||||
Pstream::parRun() = oldParRun;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Read mesh
|
||||
// ~~~~~~~~~
|
||||
// Now all processors have a (possibly zero size) mesh so read in
|
||||
// parallel
|
||||
|
||||
//Pout<< "Reading mesh from " << io.objectPath() << endl;
|
||||
autoPtr<fvMesh> meshPtr(new fvMesh(io));
|
||||
fvMesh& mesh = meshPtr();
|
||||
|
||||
|
||||
|
||||
// Sync patches
|
||||
// ~~~~~~~~~~~~
|
||||
|
||||
@ -327,17 +374,17 @@ Foam::autoPtr<Foam::fvMesh> Foam::loadOrCreateMesh
|
||||
}
|
||||
|
||||
|
||||
if (!haveMesh)
|
||||
{
|
||||
// We created a dummy mesh file above. Delete it.
|
||||
const fileName meshFiles = io.time().path()/io.instance()/meshSubDir;
|
||||
//Pout<< "Removing dummy mesh " << meshFiles << endl;
|
||||
mesh.removeFiles();
|
||||
rmDir(meshFiles);
|
||||
}
|
||||
|
||||
// if (!haveMesh)
|
||||
// {
|
||||
// // We created a dummy mesh file above. Delete it.
|
||||
// const fileName meshFiles = io.time().path()/io.instance()/meshSubDir;
|
||||
// //Pout<< "Removing dummy mesh " << meshFiles << endl;
|
||||
// mesh.removeFiles();
|
||||
// rmDir(meshFiles);
|
||||
// }
|
||||
//
|
||||
// Force recreation of globalMeshData.
|
||||
mesh.clearOut();
|
||||
// mesh.clearOut();
|
||||
mesh.globalData();
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,113 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "parFvFieldReconstructor.H"
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::parFvFieldReconstructor::createPatchFaceMaps()
|
||||
{
|
||||
const fvBoundaryMesh& fvb = procMesh_.boundary();
|
||||
|
||||
patchFaceMaps_.setSize(fvb.size());
|
||||
forAll(fvb, patchI)
|
||||
{
|
||||
if (!isA<processorFvPatch>(fvb[patchI]))
|
||||
{
|
||||
// Create map for patch faces only
|
||||
|
||||
// Mark all used elements (i.e. destination patch faces)
|
||||
boolList faceIsUsed(distMap_.faceMap().constructSize(), false);
|
||||
const polyPatch& basePatch = baseMesh_.boundaryMesh()[patchI];
|
||||
forAll(basePatch, i)
|
||||
{
|
||||
faceIsUsed[basePatch.start()+i] = true;
|
||||
}
|
||||
|
||||
// Copy face map
|
||||
patchFaceMaps_.set
|
||||
(
|
||||
patchI,
|
||||
new mapDistributeBase(distMap_.faceMap())
|
||||
);
|
||||
|
||||
// Compact out unused elements
|
||||
labelList oldToNewSub;
|
||||
labelList oldToNewConstruct;
|
||||
patchFaceMaps_[patchI].compact
|
||||
(
|
||||
faceIsUsed,
|
||||
procMesh_.nFaces(), // maximum index of subMap
|
||||
oldToNewSub,
|
||||
oldToNewConstruct,
|
||||
UPstream::msgType()
|
||||
);
|
||||
//Pout<< "patchMap:" << patchFaceMaps_[patchI] << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::parFvFieldReconstructor::parFvFieldReconstructor
|
||||
(
|
||||
fvMesh& baseMesh,
|
||||
const fvMesh& procMesh,
|
||||
const mapDistributePolyMesh& distMap,
|
||||
const bool isWriteProc
|
||||
)
|
||||
:
|
||||
baseMesh_(baseMesh),
|
||||
procMesh_(procMesh),
|
||||
distMap_(distMap),
|
||||
isWriteProc_(isWriteProc)
|
||||
{
|
||||
createPatchFaceMaps();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::parFvFieldReconstructor::reconstructPoints()
|
||||
{
|
||||
// Reconstruct the points for moving mesh cases and write
|
||||
// them out
|
||||
distributedUnallocatedDirectFieldMapper mapper
|
||||
(
|
||||
labelUList::null(),
|
||||
distMap_.pointMap()
|
||||
);
|
||||
pointField basePoints(procMesh_.points(), mapper);
|
||||
baseMesh_.movePoints(basePoints);
|
||||
if (Pstream::master())
|
||||
{
|
||||
baseMesh_.write();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,194 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::parFvFieldReconstructor
|
||||
|
||||
Description
|
||||
Finite volume reconstructor for volume and surface fields.
|
||||
|
||||
Runs in parallel. Reconstructs from procMesh to baseMesh. baseMesh
|
||||
is non-zero cells on processor0 only.
|
||||
|
||||
SourceFiles
|
||||
parFvFieldReconstructor.C
|
||||
parFvFieldReconstructorReconstructFields.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef parFvFieldReconstructor_H
|
||||
#define parFvFieldReconstructor_H
|
||||
|
||||
#include "PtrList.H"
|
||||
#include "fvMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
class mapDistributePolyMesh;
|
||||
class mapDistributeBase;
|
||||
class IOobjectList;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class parFvFieldReconstructor Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class parFvFieldReconstructor
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Reconstructed mesh reference
|
||||
fvMesh& baseMesh_;
|
||||
|
||||
//- Processor mesh reference
|
||||
const fvMesh& procMesh_;
|
||||
|
||||
//- Distribution map reference
|
||||
const mapDistributePolyMesh& distMap_;
|
||||
|
||||
//- Do I need to to write (usually master only)
|
||||
const bool isWriteProc_;
|
||||
|
||||
//- Patch mappers
|
||||
PtrList<mapDistributeBase> patchFaceMaps_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Construct per-patch addressing
|
||||
void createPatchFaceMaps();
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
parFvFieldReconstructor(const parFvFieldReconstructor&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const parFvFieldReconstructor&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
parFvFieldReconstructor
|
||||
(
|
||||
fvMesh& baseMesh,
|
||||
const fvMesh& procMesh,
|
||||
const mapDistributePolyMesh& distMap,
|
||||
const bool isWriteProc
|
||||
);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Reconstruct volume internal field
|
||||
template<class Type>
|
||||
tmp<DimensionedField<Type, volMesh> >
|
||||
reconstructFvVolumeInternalField
|
||||
(
|
||||
const DimensionedField<Type, volMesh>&
|
||||
) const;
|
||||
|
||||
//- Read and reconstruct volume internal field
|
||||
template<class Type>
|
||||
tmp<DimensionedField<Type, volMesh> >
|
||||
reconstructFvVolumeInternalField(const IOobject& fieldIoObject) const;
|
||||
|
||||
|
||||
|
||||
//- Reconstruct volume field
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh> >
|
||||
reconstructFvVolumeField
|
||||
(
|
||||
const GeometricField<Type, fvPatchField, volMesh>& fld
|
||||
) const;
|
||||
|
||||
//- Read and 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 GeometricField<Type, fvsPatchField, surfaceMesh>&
|
||||
) const;
|
||||
|
||||
//- Read and reconstruct surface field
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
|
||||
reconstructFvSurfaceField(const IOobject& fieldIoObject) const;
|
||||
|
||||
|
||||
//- Read, reconstruct and write all/selected volume internal fields
|
||||
template<class Type>
|
||||
void reconstructFvVolumeInternalFields
|
||||
(
|
||||
const IOobjectList& objects,
|
||||
const HashSet<word>& selectedFields
|
||||
) const;
|
||||
|
||||
//- Read, reconstruct and write all/selected volume fields
|
||||
template<class Type>
|
||||
void reconstructFvVolumeFields
|
||||
(
|
||||
const IOobjectList& objects,
|
||||
const HashSet<word>& selectedFields
|
||||
) const;
|
||||
|
||||
//- Read, reconstruct and write all/selected surface fields
|
||||
template<class Type>
|
||||
void reconstructFvSurfaceFields
|
||||
(
|
||||
const IOobjectList& objects,
|
||||
const HashSet<word>& selectedFields
|
||||
) const;
|
||||
|
||||
//- Helper: reconstruct and write mesh points
|
||||
// (note: should be moved to something like processorMeshes class)
|
||||
void reconstructPoints();
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "parFvFieldReconstructorReconstructFields.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,543 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "parFvFieldReconstructor.H"
|
||||
#include "Time.H"
|
||||
#include "PtrList.H"
|
||||
#include "fvPatchFields.H"
|
||||
#include "emptyFvPatch.H"
|
||||
#include "emptyFvPatchField.H"
|
||||
#include "emptyFvsPatchField.H"
|
||||
#include "IOobjectList.H"
|
||||
#include "mapDistributePolyMesh.H"
|
||||
#include "processorFvPatch.H"
|
||||
|
||||
#include "directFvPatchFieldMapper.H"
|
||||
#include "distributedUnallocatedDirectFieldMapper.H"
|
||||
#include "distributedUnallocatedDirectFvPatchFieldMapper.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh> >
|
||||
Foam::parFvFieldReconstructor::reconstructFvVolumeInternalField
|
||||
(
|
||||
const DimensionedField<Type, volMesh>& fld
|
||||
) const
|
||||
{
|
||||
distributedUnallocatedDirectFieldMapper mapper
|
||||
(
|
||||
labelUList::null(),
|
||||
distMap_.cellMap()
|
||||
);
|
||||
|
||||
Field<Type> internalField(fld, mapper);
|
||||
|
||||
// Construct a volField
|
||||
IOobject baseIO
|
||||
(
|
||||
fld.name(),
|
||||
baseMesh_.time().timeName(),
|
||||
fld.local(),
|
||||
baseMesh_,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
|
||||
return tmp<DimensionedField<Type, volMesh> >
|
||||
(
|
||||
new DimensionedField<Type, volMesh>
|
||||
(
|
||||
baseIO,
|
||||
baseMesh_,
|
||||
fld.dimensions(),
|
||||
internalField
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh> >
|
||||
Foam::parFvFieldReconstructor::reconstructFvVolumeInternalField
|
||||
(
|
||||
const IOobject& fieldIoObject
|
||||
) const
|
||||
{
|
||||
// Read the field
|
||||
DimensionedField<Type, volMesh> fld
|
||||
(
|
||||
fieldIoObject,
|
||||
procMesh_
|
||||
);
|
||||
|
||||
// Distribute onto baseMesh
|
||||
return reconstructFvVolumeInternalField(fld);
|
||||
}
|
||||
|
||||
|
||||
// Reconstruct a field onto the baseMesh
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
|
||||
Foam::parFvFieldReconstructor::reconstructFvVolumeField
|
||||
(
|
||||
const GeometricField<Type, fvPatchField, volMesh>& fld
|
||||
) const
|
||||
{
|
||||
// Create the internalField by remote mapping
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
distributedUnallocatedDirectFieldMapper mapper
|
||||
(
|
||||
labelUList::null(),
|
||||
distMap_.cellMap()
|
||||
);
|
||||
|
||||
Field<Type> internalField(fld.internalField(), mapper);
|
||||
|
||||
|
||||
|
||||
// Create the patchFields by remote mapping
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Note: patchFields still on mesh, not baseMesh
|
||||
|
||||
PtrList<fvPatchField<Type> > patchFields(fld.mesh().boundary().size());
|
||||
|
||||
const typename GeometricField
|
||||
<
|
||||
Type,
|
||||
fvPatchField,
|
||||
volMesh
|
||||
>::GeometricBoundaryField& bfld = fld.boundaryField();
|
||||
|
||||
forAll(bfld, patchI)
|
||||
{
|
||||
if (patchFaceMaps_.set(patchI))
|
||||
{
|
||||
// Clone local patch field
|
||||
patchFields.set(patchI, bfld[patchI].clone());
|
||||
|
||||
distributedUnallocatedDirectFvPatchFieldMapper mapper
|
||||
(
|
||||
labelUList::null(),
|
||||
patchFaceMaps_[patchI]
|
||||
);
|
||||
|
||||
// Map into local copy
|
||||
patchFields[patchI].autoMap(mapper);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PtrList<fvPatchField<Type> > basePatchFields
|
||||
(
|
||||
baseMesh_.boundary().size()
|
||||
);
|
||||
|
||||
// Clone the patchFields onto the base patches. This is just to reset
|
||||
// the reference to the patch, size and content stay the same.
|
||||
forAll(patchFields, patchI)
|
||||
{
|
||||
if (patchFields.set(patchI))
|
||||
{
|
||||
const fvPatch& basePatch = baseMesh_.boundary()[patchI];
|
||||
|
||||
const fvPatchField<Type>& pfld = patchFields[patchI];
|
||||
|
||||
labelList dummyMap(identity(pfld.size()));
|
||||
directFvPatchFieldMapper dummyMapper(dummyMap);
|
||||
|
||||
basePatchFields.set
|
||||
(
|
||||
patchI,
|
||||
fvPatchField<Type>::New
|
||||
(
|
||||
pfld,
|
||||
basePatch,
|
||||
DimensionedField<Type, volMesh>::null(),
|
||||
dummyMapper
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Add some empty patches on remaining patches (tbd.probably processor
|
||||
// patches)
|
||||
forAll(basePatchFields, patchI)
|
||||
{
|
||||
if (patchI >= patchFields.size() || !patchFields.set(patchI))
|
||||
{
|
||||
basePatchFields.set
|
||||
(
|
||||
patchI,
|
||||
fvPatchField<Type>::New
|
||||
(
|
||||
emptyFvPatchField<Type>::typeName,
|
||||
baseMesh_.boundary()[patchI],
|
||||
DimensionedField<Type, volMesh>::null()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Construct a volField
|
||||
IOobject baseIO
|
||||
(
|
||||
fld.name(),
|
||||
baseMesh_.time().timeName(),
|
||||
fld.local(),
|
||||
baseMesh_,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
|
||||
return tmp<GeometricField<Type, fvPatchField, volMesh> >
|
||||
(
|
||||
new GeometricField<Type, fvPatchField, volMesh>
|
||||
(
|
||||
baseIO,
|
||||
baseMesh_,
|
||||
fld.dimensions(),
|
||||
internalField,
|
||||
basePatchFields
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
|
||||
Foam::parFvFieldReconstructor::reconstructFvVolumeField
|
||||
(
|
||||
const IOobject& fieldIoObject
|
||||
) const
|
||||
{
|
||||
// Read the field
|
||||
GeometricField<Type, fvPatchField, volMesh> fld
|
||||
(
|
||||
fieldIoObject,
|
||||
procMesh_
|
||||
);
|
||||
|
||||
// Distribute onto baseMesh
|
||||
return reconstructFvVolumeField(fld);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
|
||||
Foam::parFvFieldReconstructor::reconstructFvSurfaceField
|
||||
(
|
||||
const GeometricField<Type, fvsPatchField, surfaceMesh>& fld
|
||||
) const
|
||||
{
|
||||
// Create the internalField by remote mapping
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
distributedUnallocatedDirectFieldMapper mapper
|
||||
(
|
||||
labelUList::null(),
|
||||
distMap_.faceMap()
|
||||
);
|
||||
|
||||
// Create flat field of internalField + all patch fields
|
||||
Field<Type> flatFld(fld.mesh().nFaces(), pTraits<Type>::zero);
|
||||
SubList<Type>(flatFld, fld.internalField().size()).assign
|
||||
(
|
||||
fld.internalField()
|
||||
);
|
||||
forAll(fld.boundaryField(), patchI)
|
||||
{
|
||||
const fvsPatchField<Type>& fvp = fld.boundaryField()[patchI];
|
||||
|
||||
SubList<Type>(flatFld, fvp.size(), fvp.patch().start()).assign(fvp);
|
||||
}
|
||||
|
||||
// Map all faces
|
||||
Field<Type> internalField(flatFld, mapper);
|
||||
|
||||
// Trim to internal faces (note: could also have special mapper)
|
||||
internalField.setSize
|
||||
(
|
||||
min
|
||||
(
|
||||
internalField.size(),
|
||||
baseMesh_.nInternalFaces()
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
// Create the patchFields by remote mapping
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Note: patchFields still on mesh, not baseMesh
|
||||
|
||||
PtrList<fvsPatchField<Type> > patchFields(fld.mesh().boundary().size());
|
||||
|
||||
const typename GeometricField
|
||||
<
|
||||
Type,
|
||||
fvsPatchField,
|
||||
surfaceMesh
|
||||
>::GeometricBoundaryField& bfld = fld.boundaryField();
|
||||
|
||||
forAll(bfld, patchI)
|
||||
{
|
||||
if (patchFaceMaps_.set(patchI))
|
||||
{
|
||||
// Clone local patch field
|
||||
patchFields.set(patchI, bfld[patchI].clone());
|
||||
|
||||
distributedUnallocatedDirectFvPatchFieldMapper mapper
|
||||
(
|
||||
labelUList::null(),
|
||||
patchFaceMaps_[patchI]
|
||||
);
|
||||
|
||||
// Map into local copy
|
||||
patchFields[patchI].autoMap(mapper);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PtrList<fvsPatchField<Type> > basePatchFields
|
||||
(
|
||||
baseMesh_.boundary().size()
|
||||
);
|
||||
|
||||
// Clone the patchFields onto the base patches. This is just to reset
|
||||
// the reference to the patch, size and content stay the same.
|
||||
forAll(patchFields, patchI)
|
||||
{
|
||||
if (patchFields.set(patchI))
|
||||
{
|
||||
const fvPatch& basePatch = baseMesh_.boundary()[patchI];
|
||||
|
||||
const fvsPatchField<Type>& pfld = patchFields[patchI];
|
||||
|
||||
labelList dummyMap(identity(pfld.size()));
|
||||
directFvPatchFieldMapper dummyMapper(dummyMap);
|
||||
|
||||
basePatchFields.set
|
||||
(
|
||||
patchI,
|
||||
fvsPatchField<Type>::New
|
||||
(
|
||||
pfld,
|
||||
basePatch,
|
||||
DimensionedField<Type, surfaceMesh>::null(),
|
||||
dummyMapper
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Add some empty patches on remaining patches (tbd.probably processor
|
||||
// patches)
|
||||
forAll(basePatchFields, patchI)
|
||||
{
|
||||
if (patchI >= patchFields.size() || !patchFields.set(patchI))
|
||||
{
|
||||
basePatchFields.set
|
||||
(
|
||||
patchI,
|
||||
fvsPatchField<Type>::New
|
||||
(
|
||||
emptyFvsPatchField<Type>::typeName,
|
||||
baseMesh_.boundary()[patchI],
|
||||
DimensionedField<Type, surfaceMesh>::null()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Construct a volField
|
||||
IOobject baseIO
|
||||
(
|
||||
fld.name(),
|
||||
baseMesh_.time().timeName(),
|
||||
fld.local(),
|
||||
baseMesh_,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
|
||||
return tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
|
||||
(
|
||||
new GeometricField<Type, fvsPatchField, surfaceMesh>
|
||||
(
|
||||
baseIO,
|
||||
baseMesh_,
|
||||
fld.dimensions(),
|
||||
internalField,
|
||||
basePatchFields
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
|
||||
Foam::parFvFieldReconstructor::reconstructFvSurfaceField
|
||||
(
|
||||
const IOobject& fieldIoObject
|
||||
) const
|
||||
{
|
||||
// Read the field
|
||||
GeometricField<Type, fvsPatchField, surfaceMesh> fld
|
||||
(
|
||||
fieldIoObject,
|
||||
procMesh_
|
||||
);
|
||||
|
||||
return reconstructFvSurfaceField(fld);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::parFvFieldReconstructor::reconstructFvVolumeInternalFields
|
||||
(
|
||||
const IOobjectList& objects,
|
||||
const HashSet<word>& selectedFields
|
||||
) const
|
||||
{
|
||||
const word& fieldClassName = DimensionedField<Type, volMesh>::typeName;
|
||||
|
||||
IOobjectList fields = objects.lookupClass(fieldClassName);
|
||||
|
||||
if (fields.size())
|
||||
{
|
||||
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
|
||||
|
||||
forAllConstIter(IOobjectList, fields, fieldIter)
|
||||
{
|
||||
if
|
||||
(
|
||||
selectedFields.empty()
|
||||
|| selectedFields.found(fieldIter()->name())
|
||||
)
|
||||
{
|
||||
Info<< " " << fieldIter()->name() << endl;
|
||||
|
||||
tmp<DimensionedField<Type, volMesh> > tfld
|
||||
(
|
||||
reconstructFvVolumeInternalField<Type>(*fieldIter())
|
||||
);
|
||||
|
||||
if (isWriteProc_)
|
||||
{
|
||||
tfld().write();
|
||||
}
|
||||
}
|
||||
}
|
||||
Info<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::parFvFieldReconstructor::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)
|
||||
{
|
||||
const word& name = fieldIter()->name();
|
||||
|
||||
if
|
||||
(
|
||||
(selectedFields.empty() || selectedFields.found(name))
|
||||
&& name != "cellDist"
|
||||
)
|
||||
{
|
||||
Info<< " " << name << endl;
|
||||
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh> > tfld
|
||||
(
|
||||
reconstructFvVolumeField<Type>(*fieldIter())
|
||||
);
|
||||
if (isWriteProc_)
|
||||
{
|
||||
tfld().write();
|
||||
}
|
||||
}
|
||||
}
|
||||
Info<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::parFvFieldReconstructor::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.empty()
|
||||
|| selectedFields.found(fieldIter()->name())
|
||||
)
|
||||
{
|
||||
Info<< " " << fieldIter()->name() << endl;
|
||||
|
||||
tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tfld
|
||||
(
|
||||
reconstructFvSurfaceField<Type>(*fieldIter())
|
||||
);
|
||||
if (isWriteProc_)
|
||||
{
|
||||
tfld().write();
|
||||
}
|
||||
}
|
||||
}
|
||||
Info<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,321 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "ListOps.H"
|
||||
#include "parLagrangianRedistributor.H"
|
||||
#include "passiveParticleCloud.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::parLagrangianRedistributor::parLagrangianRedistributor
|
||||
(
|
||||
const fvMesh& srcMesh,
|
||||
const fvMesh& tgtMesh,
|
||||
const label nSrcCells,
|
||||
const mapDistributePolyMesh& distMap
|
||||
)
|
||||
:
|
||||
srcMesh_(srcMesh),
|
||||
tgtMesh_(tgtMesh),
|
||||
distMap_(distMap)
|
||||
{
|
||||
const mapDistribute& cellMap = distMap_.cellMap();
|
||||
|
||||
// Get destination processors and cells
|
||||
destinationProcID_ = labelList(tgtMesh_.nCells(), Pstream::myProcNo());
|
||||
cellMap.reverseDistribute(nSrcCells, destinationProcID_);
|
||||
|
||||
destinationCell_ = identity(tgtMesh_.nCells());
|
||||
cellMap.reverseDistribute(nSrcCells, destinationCell_);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
// Find all clouds (on all processors) and for each cloud all the objects.
|
||||
// Result will be synchronised on all processors
|
||||
void Foam::parLagrangianRedistributor::findClouds
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
wordList& cloudNames,
|
||||
List<wordList>& objectNames
|
||||
)
|
||||
{
|
||||
fileNameList localCloudDirs
|
||||
(
|
||||
readDir
|
||||
(
|
||||
mesh.time().timePath()
|
||||
/ mesh.dbDir()
|
||||
/ cloud::prefix,
|
||||
fileName::DIRECTORY
|
||||
)
|
||||
);
|
||||
|
||||
cloudNames.setSize(localCloudDirs.size());
|
||||
forAll(localCloudDirs, i)
|
||||
{
|
||||
cloudNames[i] = localCloudDirs[i];
|
||||
}
|
||||
|
||||
// Synchronise cloud names
|
||||
Pstream::combineGather(cloudNames, ListUniqueEqOp<word>());
|
||||
Pstream::combineScatter(cloudNames);
|
||||
|
||||
objectNames.setSize(cloudNames.size());
|
||||
|
||||
forAll(localCloudDirs, i)
|
||||
{
|
||||
// Do local scan for valid cloud objects
|
||||
IOobjectList sprayObjs
|
||||
(
|
||||
mesh,
|
||||
mesh.time().timeName(),
|
||||
cloud::prefix/localCloudDirs[i]
|
||||
);
|
||||
|
||||
if (sprayObjs.lookup(word("positions")))
|
||||
{
|
||||
// One of the objects is positions so must be valid cloud
|
||||
|
||||
label cloudI = findIndex(cloudNames, localCloudDirs[i]);
|
||||
|
||||
objectNames[cloudI].setSize(sprayObjs.size());
|
||||
label objectI = 0;
|
||||
forAllConstIter(IOobjectList, sprayObjs, iter)
|
||||
{
|
||||
const word& name = iter.key();
|
||||
if (name != "positions")
|
||||
{
|
||||
objectNames[cloudI][objectI++] = name;
|
||||
}
|
||||
}
|
||||
objectNames[cloudI].setSize(objectI);
|
||||
}
|
||||
}
|
||||
|
||||
// Synchronise objectNames
|
||||
forAll(objectNames, cloudI)
|
||||
{
|
||||
Pstream::combineGather(objectNames[cloudI], ListUniqueEqOp<word>());
|
||||
Pstream::combineScatter(objectNames[cloudI]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::autoPtr<Foam::mapDistributeBase>
|
||||
Foam::parLagrangianRedistributor::redistributeLagrangianPositions
|
||||
(
|
||||
passiveParticleCloud& lpi
|
||||
) const
|
||||
{
|
||||
//Debug(lpi.size());
|
||||
|
||||
labelListList subMap;
|
||||
|
||||
|
||||
// Allocate transfer buffers
|
||||
PstreamBuffers pBufs(Pstream::nonBlocking);
|
||||
|
||||
{
|
||||
// List of lists of particles to be transfered for all of the
|
||||
// neighbour processors
|
||||
List<IDLList<passiveParticle> > particleTransferLists
|
||||
(
|
||||
Pstream::nProcs()
|
||||
);
|
||||
|
||||
// Per particle the destination processor
|
||||
labelList destProc(lpi.size());
|
||||
|
||||
label particleI = 0;
|
||||
forAllIter(passiveParticleCloud, lpi, iter)
|
||||
{
|
||||
passiveParticle& ppi = iter();
|
||||
|
||||
label destProcI = destinationProcID_[ppi.cell()];
|
||||
label destCellI = destinationCell_[ppi.cell()];
|
||||
|
||||
ppi.cell() = destCellI;
|
||||
destProc[particleI++] = destProcI;
|
||||
//Pout<< "Sending particle:" << ppi << " to processor " << destProcI
|
||||
// << " to cell " << destCellI << endl;
|
||||
particleTransferLists[destProcI].append(lpi.remove(&ppi));
|
||||
}
|
||||
|
||||
|
||||
// Per processor the indices of the particles to send
|
||||
subMap = invertOneToMany(Pstream::nProcs(), destProc);
|
||||
|
||||
|
||||
// Stream into send buffers
|
||||
forAll(particleTransferLists, procI)
|
||||
{
|
||||
//Pout<< "To proc " << procI << " sending "
|
||||
// << particleTransferLists[procI] << endl;
|
||||
if (particleTransferLists[procI].size())
|
||||
{
|
||||
UOPstream particleStream(procI, pBufs);
|
||||
particleStream << particleTransferLists[procI];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Start sending. Sets number of bytes transferred
|
||||
labelListList allNTrans(Pstream::nProcs());
|
||||
pBufs.finishedSends(allNTrans);
|
||||
|
||||
|
||||
{
|
||||
// Temporarily rename original cloud so we can construct a new one
|
||||
// (to distribute the positions) without getting a duplicate
|
||||
// registration warning
|
||||
const word cloudName = lpi.name();
|
||||
lpi.rename(cloudName + "_old");
|
||||
|
||||
// New cloud on tgtMesh
|
||||
passiveParticleCloud lagrangianPositions
|
||||
(
|
||||
tgtMesh_,
|
||||
cloudName,
|
||||
IDLList<passiveParticle>()
|
||||
);
|
||||
|
||||
|
||||
// Retrieve from receive buffers
|
||||
forAll(allNTrans, procI)
|
||||
{
|
||||
label nRec = allNTrans[procI][Pstream::myProcNo()];
|
||||
|
||||
//Pout<< "From processor " << procI << " receiving bytes " << nRec
|
||||
// << endl;
|
||||
|
||||
if (nRec)
|
||||
{
|
||||
UIPstream particleStream(procI, pBufs);
|
||||
|
||||
IDLList<passiveParticle> newParticles
|
||||
(
|
||||
particleStream,
|
||||
passiveParticle::iNew(tgtMesh_)
|
||||
);
|
||||
|
||||
forAllIter
|
||||
(
|
||||
IDLList<passiveParticle>,
|
||||
newParticles,
|
||||
newpIter
|
||||
)
|
||||
{
|
||||
passiveParticle& newp = newpIter();
|
||||
|
||||
lagrangianPositions.addParticle(newParticles.remove(&newp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//OFstream::debug = 1;
|
||||
//Debug(lagrangianPositions.size());
|
||||
IOPosition<passiveParticleCloud>(lagrangianPositions).write();
|
||||
//OFstream::debug = 0;
|
||||
|
||||
// Restore cloud name
|
||||
lpi.rename(cloudName);
|
||||
}
|
||||
|
||||
// Work the send indices (subMap) into a mapDistributeBase
|
||||
labelListList sizes(Pstream::nProcs());
|
||||
labelList& nsTransPs = sizes[Pstream::myProcNo()];
|
||||
nsTransPs.setSize(Pstream::nProcs());
|
||||
forAll(subMap, sendProcI)
|
||||
{
|
||||
nsTransPs[sendProcI] = subMap[sendProcI].size();
|
||||
}
|
||||
// Send sizes across. Note: blocks.
|
||||
combineReduce(sizes, Pstream::listEq());
|
||||
|
||||
labelListList constructMap(Pstream::nProcs());
|
||||
label constructSize = 0;
|
||||
forAll(constructMap, procI)
|
||||
{
|
||||
label nRecv = sizes[procI][UPstream::myProcNo()];
|
||||
|
||||
labelList& map = constructMap[procI];
|
||||
|
||||
map.setSize(nRecv);
|
||||
forAll(map, i)
|
||||
{
|
||||
map[i] = constructSize++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Construct map
|
||||
return autoPtr<mapDistributeBase>
|
||||
(
|
||||
new mapDistributeBase
|
||||
(
|
||||
constructSize,
|
||||
subMap.xfer(),
|
||||
constructMap.xfer()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Foam::autoPtr<Foam::mapDistributeBase>
|
||||
Foam::parLagrangianRedistributor::redistributeLagrangianPositions
|
||||
(
|
||||
const word& cloudName
|
||||
) const
|
||||
{
|
||||
(void)srcMesh_.tetBasePtIs();
|
||||
(void)tgtMesh_.tetBasePtIs();
|
||||
|
||||
// Temporarily: override master-only checking
|
||||
regIOobject::fileCheckTypes oldCheckType =
|
||||
regIOobject::fileModificationChecking;
|
||||
|
||||
if (oldCheckType == regIOobject::timeStampMaster)
|
||||
{
|
||||
regIOobject::fileModificationChecking = regIOobject::timeStamp;
|
||||
}
|
||||
else if (oldCheckType == regIOobject::inotifyMaster)
|
||||
{
|
||||
regIOobject::fileModificationChecking = regIOobject::inotify;
|
||||
}
|
||||
|
||||
// Load cloud and send particle
|
||||
passiveParticleCloud lpi(srcMesh_, cloudName, false);
|
||||
|
||||
regIOobject::fileModificationChecking = oldCheckType;
|
||||
|
||||
return redistributeLagrangianPositions(lpi);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,186 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::parLagrangianRedistributor
|
||||
|
||||
Description
|
||||
Lagrangian field redistributor.
|
||||
|
||||
Runs in parallel. Redistributes from fromMesh to toMesh.
|
||||
|
||||
SourceFiles
|
||||
parLagrangianRedistributor.C
|
||||
parLagrangianRedistributorRedistributeFields.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef parLagrangianRedistributor_H
|
||||
#define parLagrangianRedistributor_H
|
||||
|
||||
#include "PtrList.H"
|
||||
#include "fvMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
class mapDistributePolyMesh;
|
||||
class mapDistributeBase;
|
||||
class IOobjectList;
|
||||
class passiveParticleCloud;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class parLagrangianRedistributor Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class parLagrangianRedistributor
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Source mesh reference
|
||||
const fvMesh& srcMesh_;
|
||||
|
||||
//- Destination mesh reference
|
||||
const fvMesh& tgtMesh_;
|
||||
|
||||
//- Distribution map reference
|
||||
const mapDistributePolyMesh& distMap_;
|
||||
|
||||
//- For every src cell the target processor
|
||||
labelList destinationProcID_;
|
||||
|
||||
//- For every src cell the target cell
|
||||
labelList destinationCell_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
parLagrangianRedistributor(const parLagrangianRedistributor&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const parLagrangianRedistributor&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
parLagrangianRedistributor
|
||||
(
|
||||
const fvMesh& srcMesh,
|
||||
const fvMesh& tgtMesh,
|
||||
const label nOldCells,
|
||||
const mapDistributePolyMesh& distMap
|
||||
);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Find all clouds (on all processors) and for each cloud all
|
||||
// the objects. Result will be synchronised on all processors
|
||||
static void findClouds
|
||||
(
|
||||
const fvMesh&,
|
||||
wordList& cloudNames,
|
||||
List<wordList>& objectNames
|
||||
);
|
||||
|
||||
//- Redistribute and write lagrangian positions
|
||||
autoPtr<mapDistributeBase> redistributeLagrangianPositions
|
||||
(
|
||||
passiveParticleCloud& cloud
|
||||
) const;
|
||||
|
||||
//- Read, redistribute and write lagrangian positions
|
||||
autoPtr<mapDistributeBase> redistributeLagrangianPositions
|
||||
(
|
||||
const word& cloudName
|
||||
) const;
|
||||
|
||||
//- Pick up any fields of a given type
|
||||
template<class Type>
|
||||
static wordList filterObjects
|
||||
(
|
||||
const IOobjectList& objects,
|
||||
const HashSet<word>& selectedFields
|
||||
);
|
||||
|
||||
//- Read, redistribute and write all/selected lagrangian fields
|
||||
template<class Type>
|
||||
void redistributeLagrangianFields
|
||||
(
|
||||
const mapDistributeBase& map,
|
||||
const word& cloudName,
|
||||
const IOobjectList& objects,
|
||||
const HashSet<word>& selectedFields
|
||||
) const;
|
||||
|
||||
//- Read, redistribute and write all/selected lagrangian fieldFields
|
||||
template<class Type>
|
||||
void redistributeLagrangianFieldFields
|
||||
(
|
||||
const mapDistributeBase& map,
|
||||
const word& cloudName,
|
||||
const IOobjectList& objects,
|
||||
const HashSet<word>& selectedFields
|
||||
) const;
|
||||
|
||||
//- Read and store all fields of a cloud
|
||||
template<class Container>
|
||||
static void readLagrangianFields
|
||||
(
|
||||
const passiveParticleCloud& cloud,
|
||||
const IOobjectList& objects,
|
||||
const HashSet<word>& selectedFields
|
||||
);
|
||||
|
||||
//- Redistribute and write stored lagrangian fields
|
||||
template<class Container>
|
||||
void redistributeStoredLagrangianFields
|
||||
(
|
||||
const mapDistributeBase& map,
|
||||
passiveParticleCloud& cloud
|
||||
) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "parLagrangianRedistributorRedistributeFields.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,320 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "parLagrangianRedistributor.H"
|
||||
#include "Time.H"
|
||||
#include "IOobjectList.H"
|
||||
#include "mapDistributePolyMesh.H"
|
||||
#include "cloud.H"
|
||||
#include "CompactIOField.H"
|
||||
#include "passiveParticleCloud.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Container>
|
||||
Foam::wordList Foam::parLagrangianRedistributor::filterObjects
|
||||
(
|
||||
const IOobjectList& objects,
|
||||
const HashSet<word>& selectedFields
|
||||
)
|
||||
{
|
||||
const word fieldClassName(Container::typeName);
|
||||
|
||||
// Parallel synchronise
|
||||
wordList fieldNames(objects.names(fieldClassName));
|
||||
Pstream::combineGather(fieldNames, ListUniqueEqOp<word>());
|
||||
Pstream::combineScatter(fieldNames);
|
||||
|
||||
if (!selectedFields.empty())
|
||||
{
|
||||
DynamicList<word> selectedNames(fieldNames.size());
|
||||
forAll(fieldNames, i)
|
||||
{
|
||||
if (selectedFields.found(fieldNames[i]))
|
||||
{
|
||||
selectedNames.append(fieldNames[i]);
|
||||
}
|
||||
}
|
||||
fieldNames.transfer(selectedNames);
|
||||
}
|
||||
return fieldNames;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::parLagrangianRedistributor::redistributeLagrangianFields
|
||||
(
|
||||
const mapDistributeBase& map,
|
||||
const word& cloudName,
|
||||
const IOobjectList& objects,
|
||||
const HashSet<word>& selectedFields
|
||||
) const
|
||||
{
|
||||
const wordList objectNames
|
||||
(
|
||||
filterObjects<IOField<Type> >
|
||||
(
|
||||
objects,
|
||||
selectedFields
|
||||
)
|
||||
);
|
||||
|
||||
if (objectNames.size())
|
||||
{
|
||||
const word fieldClassName(IOField<Type>::typeName);
|
||||
|
||||
Info<< " Redistributing lagrangian "
|
||||
<< fieldClassName << "s\n" << endl;
|
||||
|
||||
forAll(objectNames, i)
|
||||
{
|
||||
Info<< " " << objectNames[i] << endl;
|
||||
|
||||
// Read if present
|
||||
IOField<Type> field
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
objectNames[i],
|
||||
srcMesh_.time().timeName(),
|
||||
cloud::prefix/cloudName,
|
||||
srcMesh_,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
0
|
||||
);
|
||||
|
||||
map.distribute(field);
|
||||
|
||||
|
||||
if (field.size())
|
||||
{
|
||||
IOField<Type>
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
objectNames[i],
|
||||
tgtMesh_.time().timeName(),
|
||||
cloud::prefix/cloudName,
|
||||
tgtMesh_,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
xferMove<Field<Type> >(field)
|
||||
).write();
|
||||
}
|
||||
}
|
||||
|
||||
Info<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::parLagrangianRedistributor::redistributeLagrangianFieldFields
|
||||
(
|
||||
const mapDistributeBase& map,
|
||||
const word& cloudName,
|
||||
const IOobjectList& objects,
|
||||
const HashSet<word>& selectedFields
|
||||
) const
|
||||
{
|
||||
wordList objectNames
|
||||
(
|
||||
filterObjects<CompactIOField<Field<Type>, Type> >
|
||||
(
|
||||
objects,
|
||||
selectedFields
|
||||
)
|
||||
);
|
||||
|
||||
// Append IOField names
|
||||
{
|
||||
const wordList ioFieldNames
|
||||
(
|
||||
filterObjects<IOField<Field<Type> > >
|
||||
(
|
||||
objects,
|
||||
selectedFields
|
||||
)
|
||||
);
|
||||
objectNames.append(ioFieldNames);
|
||||
}
|
||||
|
||||
|
||||
if (objectNames.size())
|
||||
{
|
||||
const word fieldClassName(CompactIOField<Field<Type>, Type>::typeName);
|
||||
|
||||
Info<< " Redistributing lagrangian "
|
||||
<< fieldClassName << "s\n" << endl;
|
||||
|
||||
forAll(objectNames, i)
|
||||
{
|
||||
Info<< " " << objectNames[i] << endl;
|
||||
|
||||
// Read if present
|
||||
CompactIOField<Field<Type>, Type > field
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
objectNames[i],
|
||||
srcMesh_.time().timeName(),
|
||||
cloud::prefix/cloudName,
|
||||
srcMesh_,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
0
|
||||
);
|
||||
|
||||
// Distribute
|
||||
map.distribute(field);
|
||||
|
||||
// Write
|
||||
if (field.size())
|
||||
{
|
||||
CompactIOField<Field<Type>, Type>
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
objectNames[i],
|
||||
tgtMesh_.time().timeName(),
|
||||
cloud::prefix/cloudName,
|
||||
tgtMesh_,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
xferMove<Field<Field<Type> > >(field)
|
||||
).write();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Container>
|
||||
void Foam::parLagrangianRedistributor::readLagrangianFields
|
||||
(
|
||||
const passiveParticleCloud& cloud,
|
||||
const IOobjectList& objects,
|
||||
const HashSet<word>& selectedFields
|
||||
)
|
||||
{
|
||||
const wordList objectNames
|
||||
(
|
||||
filterObjects<Container>
|
||||
(
|
||||
objects,
|
||||
selectedFields
|
||||
)
|
||||
);
|
||||
|
||||
if (objectNames.size())
|
||||
{
|
||||
const word fieldClassName(Container::typeName);
|
||||
|
||||
Info<< " Reading lagrangian "
|
||||
<< fieldClassName << "s\n" << endl;
|
||||
|
||||
forAll(objectNames, i)
|
||||
{
|
||||
Info<< " " << objectNames[i] << endl;
|
||||
|
||||
// Read if present
|
||||
Container* fieldPtr = new Container
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
objectNames[i],
|
||||
cloud.time().timeName(),
|
||||
cloud,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
0
|
||||
);
|
||||
|
||||
fieldPtr->store();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Container>
|
||||
void Foam::parLagrangianRedistributor::redistributeStoredLagrangianFields
|
||||
(
|
||||
const mapDistributeBase& map,
|
||||
passiveParticleCloud& cloud
|
||||
) const
|
||||
{
|
||||
HashTable<Container*> fields
|
||||
(
|
||||
cloud.lookupClass<Container >()
|
||||
);
|
||||
|
||||
if (fields.size())
|
||||
{
|
||||
const word fieldClassName(Container::typeName);
|
||||
|
||||
Info<< " Redistributing lagrangian "
|
||||
<< fieldClassName << "s\n" << endl;
|
||||
|
||||
forAllIter(typename HashTable<Container*>, fields, iter)
|
||||
{
|
||||
Container& field = *iter();
|
||||
|
||||
Info<< " " << field.name() << endl;
|
||||
|
||||
map.distribute(field);
|
||||
|
||||
if (field.size())
|
||||
{
|
||||
Container
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
field.name(),
|
||||
tgtMesh_.time().timeName(),
|
||||
cloud::prefix/cloud.name(),
|
||||
tgtMesh_,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
xferMove<Field<typename Container::value_type> >(field)
|
||||
).write();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,112 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::unmappedPassiveParticleCloud
|
||||
|
||||
Description
|
||||
passiveParticleCloud but with autoMap and writing disabled. Only used
|
||||
for its objectRegistry to store lagrangian fields
|
||||
|
||||
SourceFiles
|
||||
unmappedPassiveParticleCloud.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef unmappedPassiveParticleCloud_H
|
||||
#define unmappedPassiveParticleCloud_H
|
||||
|
||||
#include "passiveParticleCloud.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class unmappedPassiveParticleCloud Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class unmappedPassiveParticleCloud
|
||||
:
|
||||
public passiveParticleCloud
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct given mesh
|
||||
unmappedPassiveParticleCloud
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const word& cloudName = "defaultCloud",
|
||||
bool readFields = true
|
||||
)
|
||||
:
|
||||
passiveParticleCloud(mesh, cloudName, readFields)
|
||||
{}
|
||||
|
||||
//- Construct from mesh, cloud name, and a list of particles
|
||||
unmappedPassiveParticleCloud
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const word& cloudName,
|
||||
const IDLList<passiveParticle>& particles
|
||||
)
|
||||
:
|
||||
passiveParticleCloud(mesh, cloudName, particles)
|
||||
{}
|
||||
|
||||
//- Destructor
|
||||
virtual ~unmappedPassiveParticleCloud()
|
||||
{}
|
||||
|
||||
//- Switch off remapping of cells of particles when
|
||||
// mesh topology changes
|
||||
virtual void autoMap(const mapPolyMesh&)
|
||||
{}
|
||||
|
||||
//- Switch off writing the objects
|
||||
virtual bool writeObject
|
||||
(
|
||||
IOstream::streamFormat fmt,
|
||||
IOstream::versionNumber ver,
|
||||
IOstream::compressionType cmp
|
||||
) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,12 +1,14 @@
|
||||
EXE_INC = \
|
||||
/* -DFULLDEBUG -g -O0 */ \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/sampling/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-ldynamicMesh \
|
||||
-lmeshTools \
|
||||
-lsampling \
|
||||
-lgenericPatchFields \
|
||||
|
||||
@ -2,12 +2,14 @@ EXE_INC = \
|
||||
-I$(WM_THIRD_PARTY_DIR)/tecio/tecsrc/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
|
||||
EXE_LIBS = \
|
||||
-llagrangian \
|
||||
-lfiniteVolume \
|
||||
-ldynamicMesh \
|
||||
-lgenericPatchFields \
|
||||
-lmeshTools \
|
||||
-L$(FOAM_EXT_LIBBIN) -ltecio
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-ldynamicMesh \
|
||||
-llagrangian \
|
||||
-lgenericPatchFields \
|
||||
-lmeshTools
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
|
||||
-I../../vtkPV4Readers/lnInclude \
|
||||
-I../PV4FoamReader \
|
||||
@ -15,6 +16,7 @@ EXE_INC = \
|
||||
LIB_LIBS = \
|
||||
-lmeshTools \
|
||||
-lfiniteVolume \
|
||||
-ldynamicMesh \
|
||||
-lgenericPatchFields \
|
||||
-llagrangian \
|
||||
-L$(FOAM_LIBBIN) -lvtkPV4Readers \
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -41,7 +41,8 @@ void mapConsistentMesh
|
||||
(
|
||||
const fvMesh& meshSource,
|
||||
const fvMesh& meshTarget,
|
||||
const meshToMesh::interpolationMethod& mapMethod,
|
||||
const word& mapMethod,
|
||||
const word& AMIMapMethod,
|
||||
const bool subtract,
|
||||
const HashSet<word>& selectedFields,
|
||||
const bool noLagrangian
|
||||
@ -50,7 +51,7 @@ void mapConsistentMesh
|
||||
Info<< nl << "Consistently creating and mapping fields for time "
|
||||
<< meshSource.time().timeName() << nl << endl;
|
||||
|
||||
meshToMesh interp(meshSource, meshTarget, mapMethod);
|
||||
meshToMesh interp(meshSource, meshTarget, mapMethod, AMIMapMethod);
|
||||
|
||||
if (subtract)
|
||||
{
|
||||
@ -79,7 +80,8 @@ void mapSubMesh
|
||||
const fvMesh& meshTarget,
|
||||
const HashTable<word>& patchMap,
|
||||
const wordList& cuttingPatches,
|
||||
const meshToMesh::interpolationMethod& mapMethod,
|
||||
const word& mapMethod,
|
||||
const word& AMIMapMethod,
|
||||
const bool subtract,
|
||||
const HashSet<word>& selectedFields,
|
||||
const bool noLagrangian
|
||||
@ -93,6 +95,7 @@ void mapSubMesh
|
||||
meshSource,
|
||||
meshTarget,
|
||||
mapMethod,
|
||||
AMIMapMethod,
|
||||
patchMap,
|
||||
cuttingPatches
|
||||
);
|
||||
@ -184,7 +187,14 @@ int main(int argc, char *argv[])
|
||||
(
|
||||
"mapMethod",
|
||||
"word",
|
||||
"specify the mapping method"
|
||||
"specify the mapping method "
|
||||
"(direct|mapNearest|cellVolumeWeight|correctedCellVolumeWeight)"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"patchMapMethod",
|
||||
"word",
|
||||
"specify the patch mapping method (direct|mapNearest|faceAreaWeight)"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
@ -231,15 +241,46 @@ int main(int argc, char *argv[])
|
||||
|
||||
const bool consistent = args.optionFound("consistent");
|
||||
|
||||
meshToMesh::interpolationMethod mapMethod =
|
||||
meshToMesh::imCellVolumeWeight;
|
||||
|
||||
if (args.optionFound("mapMethod"))
|
||||
word mapMethod = meshToMesh::interpolationMethodNames_
|
||||
[
|
||||
meshToMesh::imCellVolumeWeight
|
||||
];
|
||||
|
||||
if (args.optionReadIfPresent("mapMethod", mapMethod))
|
||||
{
|
||||
mapMethod = meshToMesh::interpolationMethodNames_[args["mapMethod"]];
|
||||
Info<< "Mapping method: " << mapMethod << endl;
|
||||
}
|
||||
|
||||
Info<< "Mapping method: "
|
||||
<< meshToMesh::interpolationMethodNames_[mapMethod] << endl;
|
||||
|
||||
word patchMapMethod;
|
||||
if (meshToMesh::interpolationMethodNames_.found(mapMethod))
|
||||
{
|
||||
// Lookup corresponding AMI method
|
||||
meshToMesh::interpolationMethod method =
|
||||
meshToMesh::interpolationMethodNames_[mapMethod];
|
||||
|
||||
patchMapMethod = AMIPatchToPatchInterpolation::interpolationMethodToWord
|
||||
(
|
||||
meshToMesh::interpolationMethodAMI(method)
|
||||
);
|
||||
}
|
||||
|
||||
// Optionally override
|
||||
if (args.optionFound("patchMapMethod"))
|
||||
{
|
||||
patchMapMethod = args["patchMapMethod"];
|
||||
|
||||
Info<< "Patch mapping method: " << patchMapMethod << endl;
|
||||
}
|
||||
|
||||
|
||||
if (patchMapMethod.empty())
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "No valid patchMapMethod for method " << mapMethod
|
||||
<< ". Please supply one through the 'patchMapMethod' option"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
const bool subtract = args.optionFound("subtract");
|
||||
@ -304,8 +345,9 @@ int main(int argc, char *argv[])
|
||||
)
|
||||
);
|
||||
|
||||
Info<< "Source mesh size: " << meshSource.nCells() << tab
|
||||
<< "Target mesh size: " << meshTarget.nCells() << nl << endl;
|
||||
Info<< "Source mesh size: " << meshSource.globalData().nTotalCells() << tab
|
||||
<< "Target mesh size: " << meshTarget.globalData().nTotalCells()
|
||||
<< nl << endl;
|
||||
|
||||
if (consistent)
|
||||
{
|
||||
@ -314,6 +356,7 @@ int main(int argc, char *argv[])
|
||||
meshSource,
|
||||
meshTarget,
|
||||
mapMethod,
|
||||
patchMapMethod,
|
||||
subtract,
|
||||
selectedFields,
|
||||
noLagrangian
|
||||
@ -328,6 +371,7 @@ int main(int argc, char *argv[])
|
||||
patchMap,
|
||||
addProcessorPatches(meshTarget, cuttingPatches),
|
||||
mapMethod,
|
||||
patchMapMethod,
|
||||
subtract,
|
||||
selectedFields,
|
||||
noLagrangian
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
# \\ / O peration |
|
||||
# \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
# \\/ M anipulation |
|
||||
# \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
#------------------------------------------------------------------------------
|
||||
# License
|
||||
# This file is part of OpenFOAM.
|
||||
@ -52,7 +52,10 @@ cleanTimeDirectories()
|
||||
rm -rf ./${timeDir} ./-${timeDir} > /dev/null 2>&1
|
||||
zeros="0$zeros"
|
||||
done
|
||||
rm -rf ./[1-9]* ./-[1-9]* ./log ./log.* ./log-* ./logSummary.* ./.fxLock ./*.xml ./ParaView* ./paraFoam* ./*.OpenFOAM ./*.blockMesh ./.setSet > /dev/null 2>&1
|
||||
rm -rf \
|
||||
./[1-9]* ./-[1-9]* ./log ./log.* ./log-* ./logSummary.* \
|
||||
./.fxLock ./*.xml ./ParaView* ./paraFoam* ./*.OpenFOAM ./*.blockMesh \
|
||||
./.setSet > /dev/null 2>&1
|
||||
}
|
||||
|
||||
|
||||
@ -68,6 +71,33 @@ cleanDynamicCode()
|
||||
}
|
||||
|
||||
|
||||
cleanSnappyFiles()
|
||||
{
|
||||
rm -f \
|
||||
constant/polyMesh/cellLevel \
|
||||
constant/polyMesh/pointLevel \
|
||||
constant/polyMesh/refinementHistory \
|
||||
constant/polyMesh/level0Edge \
|
||||
constant/polyMesh/surfaceIndex > /dev/null 2>&1
|
||||
rm -f \
|
||||
processor*/constant/polyMesh/cellLevel \
|
||||
processor*/constant/polyMesh/pointLevel \
|
||||
processor*/constant/polyMesh/refinementHistory \
|
||||
processor*/constant/polyMesh/level0Edge \
|
||||
processor*/constant/polyMesh/surfaceIndex > /dev/null 2>&1
|
||||
rm -f \
|
||||
constant/cellLevel \
|
||||
constant/pointLevel \
|
||||
0/cellLevel \
|
||||
0/pointLevel > /dev/null 2>&1
|
||||
rm -f \
|
||||
processor*/constant/cellLevel \
|
||||
processor*/constant/pointLevel \
|
||||
processor*/0/cellLevel \
|
||||
processor*/0/pointLevel > /dev/null 2>&1
|
||||
}
|
||||
|
||||
|
||||
cleanCase()
|
||||
{
|
||||
cleanTimeDirectories
|
||||
@ -83,26 +113,25 @@ cleanCase()
|
||||
rm -rf cuttingPlane > /dev/null 2>&1
|
||||
rm -rf system/machines > /dev/null 2>&1
|
||||
|
||||
# From mpirunDebug
|
||||
rm -f gdbCommands mpirun.schema
|
||||
|
||||
cleanSnappyFiles
|
||||
if [ -d constant/polyMesh ]
|
||||
then
|
||||
(cd constant/polyMesh && \
|
||||
rm -rf \
|
||||
allOwner* cell* face* meshModifiers* \
|
||||
owner* neighbour* point* edge* \
|
||||
cellLevel* pointLevel* refinementHistory* level0Edge* surfaceIndex* sets \
|
||||
owner* neighbour* point* edge* sets \
|
||||
> /dev/null 2>&1 \
|
||||
)
|
||||
fi
|
||||
(cd constant && \
|
||||
rm -rf \
|
||||
cellToRegion cellLevel* pointLevel* \
|
||||
> /dev/null 2>&1 \
|
||||
)
|
||||
(cd constant && rm -rf cellToRegion > /dev/null 2>&1)
|
||||
|
||||
rm -rf constant/tetDualMesh > /dev/null 2>&1
|
||||
|
||||
rm -rf VTK > /dev/null 2>&1
|
||||
rm -f 0/cellLevel 0/pointLevel 0/cellDist constant/cellDecomposition
|
||||
rm -f 0/cellDist constant/cellDecomposition
|
||||
|
||||
if [ -e constant/polyMesh/blockMeshDict.m4 ]
|
||||
then
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
# \\ / O peration |
|
||||
# \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
# \\/ M anipulation |
|
||||
# \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
#------------------------------------------------------------------------------
|
||||
# License
|
||||
# This file is part of OpenFOAM.
|
||||
@ -40,28 +40,46 @@ getApplication()
|
||||
|
||||
runApplication()
|
||||
{
|
||||
APP_LOGFILE=''
|
||||
if [ "$1" = "-l" ]
|
||||
then
|
||||
APP_LOGFILE=$2
|
||||
shift 2
|
||||
fi
|
||||
|
||||
APP_RUN=$1
|
||||
APP_NAME=${1##*/}
|
||||
shift
|
||||
|
||||
if [ -f log.$APP_NAME ]
|
||||
APP_LOGFILE=${APP_LOGFILE:="log.$APP_NAME"}
|
||||
|
||||
if [ -f $APP_LOGFILE ]
|
||||
then
|
||||
echo "$APP_NAME already run on $PWD: remove log file to re-run"
|
||||
echo "$APP_NAME already run on $PWD: remove log file $APP_LOGFILE to re-run"
|
||||
else
|
||||
echo "Running $APP_RUN on $PWD"
|
||||
$APP_RUN "$@" > log.$APP_NAME 2>&1
|
||||
$APP_RUN "$@" > $APP_LOGFILE 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
runParallel()
|
||||
{
|
||||
APP_LOGFILE=''
|
||||
if [ "$1" = "-l" ]
|
||||
then
|
||||
APP_LOGFILE=$2
|
||||
shift 2
|
||||
fi
|
||||
|
||||
APP_RUN=$1
|
||||
APP_NAME=${1##*/}
|
||||
shift
|
||||
|
||||
if [ -f log.$APP_NAME ]
|
||||
APP_LOGFILE=${APP_LOGFILE:="log.$APP_NAME"}
|
||||
|
||||
if [ -f $APP_LOGFILE ]
|
||||
then
|
||||
echo "$APP_NAME already run on $PWD: remove log file to re-run"
|
||||
echo "$APP_NAME already run on $PWD: remove log file $APP_LOGFILE to re-run"
|
||||
else
|
||||
nProcs=$1
|
||||
shift
|
||||
@ -70,9 +88,9 @@ runParallel()
|
||||
#if [ "$WM_SCHEDULER" ]
|
||||
#then
|
||||
# echo "$PWD: $WM_SCHEDULER -np $nProcs" 1>&2
|
||||
# $WM_SCHEDULER -np $nProcs "( mpirun -np $nProcs $APP_RUN -parallel "$@" < /dev/null > log.$APP_NAME 2>&1 )"
|
||||
# $WM_SCHEDULER -np $nProcs "( mpirun -np $nProcs $APP_RUN -parallel "$@" < /dev/null > $APP_LOGFILE 2>&1 )"
|
||||
#else
|
||||
( mpirun -np $nProcs $APP_RUN -parallel "$@" < /dev/null > log.$APP_NAME 2>&1 )
|
||||
( mpirun -np $nProcs $APP_RUN -parallel "$@" < /dev/null > $APP_LOGFILE 2>&1 )
|
||||
#fi
|
||||
fi
|
||||
}
|
||||
|
||||
@ -91,6 +91,9 @@ $(strings)/wordRe/wordRe.C
|
||||
$(strings)/lists/hashedWordList.C
|
||||
$(strings)/stringOps/stringOps.C
|
||||
|
||||
ops = primitives/ops
|
||||
$(ops)/flipOp.C
|
||||
|
||||
primitives/hashes/Hasher/Hasher.C
|
||||
|
||||
sha1 = primitives/hashes/SHA1
|
||||
@ -505,6 +508,7 @@ $(mapPolyMesh)/mapPolyMesh.C
|
||||
$(mapPolyMesh)/faceMapper/faceMapper.C
|
||||
$(mapPolyMesh)/cellMapper/cellMapper.C
|
||||
$(mapPolyMesh)/mapDistribute/mapDistribute.C
|
||||
$(mapPolyMesh)/mapDistribute/mapDistributeBase.C
|
||||
$(mapPolyMesh)/mapDistribute/mapDistributePolyMesh.C
|
||||
$(mapPolyMesh)/mapDistribute/IOmapDistribute.C
|
||||
$(mapPolyMesh)/mapAddedPolyMesh.C
|
||||
@ -618,6 +622,8 @@ $(derivedPointPatchFields)/codedFixedValue/codedFixedValuePointPatchFields.C
|
||||
|
||||
fields/GeometricFields/pointFields/pointFields.C
|
||||
|
||||
fields/ReadFields/ReadFields.C
|
||||
|
||||
meshes/bandCompression/bandCompression.C
|
||||
meshes/preservePatchTypes/preservePatchTypes.C
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -57,6 +57,24 @@ const Foam::NamedEnum<Foam::UPstream::commsTypes, 3>
|
||||
|
||||
void Foam::UPstream::setParRun(const label nProcs)
|
||||
{
|
||||
if (nProcs == 0)
|
||||
{
|
||||
parRun_ = false;
|
||||
freeCommunicator(UPstream::worldComm);
|
||||
label comm = allocateCommunicator(-1, labelList(1, label(0)), false);
|
||||
if (comm != UPstream::worldComm)
|
||||
{
|
||||
FatalErrorIn("UPstream::setParRun(const label)")
|
||||
<< "problem : comm:" << comm
|
||||
<< " UPstream::worldComm:" << UPstream::worldComm
|
||||
<< Foam::exit(FatalError);
|
||||
}
|
||||
|
||||
Pout.prefix() = "";
|
||||
Perr.prefix() = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
parRun_ = true;
|
||||
|
||||
// Redo worldComm communicator (this has been created at static
|
||||
@ -73,6 +91,7 @@ void Foam::UPstream::setParRun(const label nProcs)
|
||||
|
||||
Pout.prefix() = '[' + name(myProcNo(Pstream::worldComm)) + "] ";
|
||||
Perr.prefix() = '[' + name(myProcNo(Pstream::worldComm)) + "] ";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -197,9 +197,6 @@ private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Set data for parallel running
|
||||
static void setParRun(const label nProcs);
|
||||
|
||||
//- Calculate linear communication schedule
|
||||
static List<commsStruct> calcLinearComm(const label nProcs);
|
||||
|
||||
@ -383,6 +380,10 @@ public:
|
||||
return parRun_;
|
||||
}
|
||||
|
||||
//- Set data for parallel running. Special case nProcs=0 to switch off
|
||||
// parallel running
|
||||
static void setParRun(const label nProcs);
|
||||
|
||||
//- Number of processes in parallel run
|
||||
static label nProcs(const label communicator = 0)
|
||||
{
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -55,7 +55,7 @@ void Pstream::combineGather
|
||||
const label comm
|
||||
)
|
||||
{
|
||||
if (UPstream::nProcs(comm) > 1)
|
||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||
{
|
||||
// Get my communication order
|
||||
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
||||
@ -182,7 +182,7 @@ void Pstream::combineScatter
|
||||
const label comm
|
||||
)
|
||||
{
|
||||
if (UPstream::nProcs(comm) > 1)
|
||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||
{
|
||||
// Get my communication order
|
||||
const UPstream::commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
||||
@ -287,7 +287,7 @@ void Pstream::listCombineGather
|
||||
const label comm
|
||||
)
|
||||
{
|
||||
if (UPstream::nProcs(comm) > 1)
|
||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||
{
|
||||
// Get my communication order
|
||||
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
||||
@ -421,7 +421,7 @@ void Pstream::listCombineScatter
|
||||
const label comm
|
||||
)
|
||||
{
|
||||
if (UPstream::nProcs(comm) > 1)
|
||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||
{
|
||||
// Get my communication order
|
||||
const UPstream::commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
||||
@ -540,7 +540,7 @@ void Pstream::mapCombineGather
|
||||
const label comm
|
||||
)
|
||||
{
|
||||
if (UPstream::nProcs(comm) > 1)
|
||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||
{
|
||||
// Get my communication order
|
||||
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
||||
@ -640,7 +640,7 @@ void Pstream::mapCombineScatter
|
||||
const label comm
|
||||
)
|
||||
{
|
||||
if (UPstream::nProcs(comm) > 1)
|
||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||
{
|
||||
// Get my communication order
|
||||
const UPstream::commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -75,14 +75,15 @@ void Foam::Pstream::exchange
|
||||
// Send sizes across. Note: blocks.
|
||||
combineReduce(sizes, UPstream::listEq(), tag, comm);
|
||||
|
||||
if (UPstream::nProcs(comm) > 1)
|
||||
recvBufs.setSize(sendBufs.size());
|
||||
|
||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||
{
|
||||
label startOfRequests = Pstream::nRequests();
|
||||
|
||||
// Set up receives
|
||||
// ~~~~~~~~~~~~~~~
|
||||
|
||||
recvBufs.setSize(sendBufs.size());
|
||||
forAll(sizes, procI)
|
||||
{
|
||||
label nRecv = sizes[procI][UPstream::myProcNo(comm)];
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -52,7 +52,7 @@ void Pstream::gather
|
||||
const label comm
|
||||
)
|
||||
{
|
||||
if (UPstream::nProcs(comm) > 1)
|
||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||
{
|
||||
// Get my communication order
|
||||
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
||||
@ -151,7 +151,7 @@ void Pstream::scatter
|
||||
const label comm
|
||||
)
|
||||
{
|
||||
if (UPstream::nProcs(comm) > 1)
|
||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||
{
|
||||
// Get my communication order
|
||||
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -53,7 +53,7 @@ void Pstream::gatherList
|
||||
const label comm
|
||||
)
|
||||
{
|
||||
if (UPstream::nProcs(comm) > 1)
|
||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||
{
|
||||
if (Values.size() != UPstream::nProcs(comm))
|
||||
{
|
||||
@ -212,7 +212,7 @@ void Pstream::scatterList
|
||||
const label comm
|
||||
)
|
||||
{
|
||||
if (UPstream::nProcs(comm) > 1)
|
||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||
{
|
||||
if (Values.size() != UPstream::nProcs(comm))
|
||||
{
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -54,7 +54,7 @@ class TimePaths
|
||||
bool processorCase_;
|
||||
const fileName rootPath_;
|
||||
fileName globalCaseName_;
|
||||
const fileName case_;
|
||||
fileName case_;
|
||||
const word system_;
|
||||
const word constant_;
|
||||
|
||||
@ -111,6 +111,12 @@ public:
|
||||
return case_;
|
||||
}
|
||||
|
||||
//- Return case name
|
||||
fileName& caseName()
|
||||
{
|
||||
return case_;
|
||||
}
|
||||
|
||||
//- Return system name
|
||||
const word& system() const
|
||||
{
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -200,7 +200,7 @@ public:
|
||||
dictionary();
|
||||
|
||||
//- Construct top-level empty dictionary with given name
|
||||
dictionary(const fileName& name);
|
||||
explicit dictionary(const fileName& name);
|
||||
|
||||
//- Construct given the entry name, parent dictionary and Istream,
|
||||
// reading entries until lastEntry or EOF
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -35,7 +35,7 @@ Foam::Istream& Foam::regIOobject::readStream()
|
||||
{
|
||||
if (IFstream::debug)
|
||||
{
|
||||
Info<< "regIOobject::readStream() : "
|
||||
Pout<< "regIOobject::readStream() : "
|
||||
<< "reading object " << name()
|
||||
<< " from file " << objectPath()
|
||||
<< endl;
|
||||
@ -112,7 +112,7 @@ Foam::Istream& Foam::regIOobject::readStream(const word& expectName)
|
||||
{
|
||||
if (IFstream::debug)
|
||||
{
|
||||
Info<< "regIOobject::readStream(const word&) : "
|
||||
Pout<< "regIOobject::readStream(const word&) : "
|
||||
<< "reading object " << name()
|
||||
<< " from file " << objectPath()
|
||||
<< endl;
|
||||
@ -149,7 +149,7 @@ void Foam::regIOobject::close()
|
||||
{
|
||||
if (IFstream::debug)
|
||||
{
|
||||
Info<< "regIOobject::close() : "
|
||||
Pout<< "regIOobject::close() : "
|
||||
<< "finished reading " << filePath()
|
||||
<< endl;
|
||||
}
|
||||
@ -288,7 +288,7 @@ bool Foam::regIOobject::readIfModified()
|
||||
if (modified())
|
||||
{
|
||||
const fileName& fName = time().getFile(watchIndex_);
|
||||
Info<< "regIOobject::readIfModified() : " << nl
|
||||
Pout<< "regIOobject::readIfModified() : " << nl
|
||||
<< " Re-reading object " << name()
|
||||
<< " from file " << fName << endl;
|
||||
return read();
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -40,7 +40,7 @@ if (&(df1).mesh() != &(df2).mesh()) \
|
||||
FatalErrorIn("checkField(df1, df2, op)") \
|
||||
<< "different mesh for fields " \
|
||||
<< (df1).name() << " and " << (df2).name() \
|
||||
<< " during operatrion " << op \
|
||||
<< " during operation " << op \
|
||||
<< abort(FatalError); \
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -149,6 +149,15 @@ public:
|
||||
const word& fieldDictEntry="value"
|
||||
);
|
||||
|
||||
//- Construct from dictionary
|
||||
DimensionedField
|
||||
(
|
||||
const IOobject&,
|
||||
const Mesh& mesh,
|
||||
const dictionary& fieldDict,
|
||||
const word& fieldDictEntry="value"
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
DimensionedField
|
||||
(
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -80,6 +80,24 @@ Foam::DimensionedField<Type, GeoMesh>::DimensionedField
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class GeoMesh>
|
||||
Foam::DimensionedField<Type, GeoMesh>::DimensionedField
|
||||
(
|
||||
const IOobject& io,
|
||||
const Mesh& mesh,
|
||||
const dictionary& fieldDict,
|
||||
const word& fieldDictEntry
|
||||
)
|
||||
:
|
||||
regIOobject(io),
|
||||
Field<Type>(0),
|
||||
mesh_(mesh),
|
||||
dimensions_(dimless)
|
||||
{
|
||||
readField(fieldDict, fieldDictEntry);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type, class GeoMesh>
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -27,6 +27,8 @@ License
|
||||
#include "FieldM.H"
|
||||
#include "dictionary.H"
|
||||
#include "contiguous.H"
|
||||
#include "mapDistributeBase.H"
|
||||
#include "flipOp.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Static Members * * * * * * * * * * * * * * //
|
||||
|
||||
@ -115,12 +117,13 @@ template<class Type>
|
||||
Foam::Field<Type>::Field
|
||||
(
|
||||
const UList<Type>& mapF,
|
||||
const FieldMapper& mapper
|
||||
const FieldMapper& mapper,
|
||||
const bool applyFlip
|
||||
)
|
||||
:
|
||||
List<Type>(mapper.size())
|
||||
{
|
||||
map(mapF, mapper);
|
||||
map(mapF, mapper, applyFlip);
|
||||
}
|
||||
|
||||
|
||||
@ -129,12 +132,13 @@ Foam::Field<Type>::Field
|
||||
(
|
||||
const UList<Type>& mapF,
|
||||
const FieldMapper& mapper,
|
||||
const Type& defaultValue
|
||||
const Type& defaultValue,
|
||||
const bool applyFlip
|
||||
)
|
||||
:
|
||||
List<Type>(mapper.size(), defaultValue)
|
||||
{
|
||||
map(mapF, mapper);
|
||||
map(mapF, mapper, applyFlip);
|
||||
}
|
||||
|
||||
|
||||
@ -143,12 +147,13 @@ Foam::Field<Type>::Field
|
||||
(
|
||||
const UList<Type>& mapF,
|
||||
const FieldMapper& mapper,
|
||||
const UList<Type>& defaultValues
|
||||
const UList<Type>& defaultValues,
|
||||
const bool applyFlip
|
||||
)
|
||||
:
|
||||
List<Type>(defaultValues)
|
||||
{
|
||||
map(mapF, mapper);
|
||||
map(mapF, mapper, applyFlip);
|
||||
}
|
||||
|
||||
|
||||
@ -156,12 +161,13 @@ template<class Type>
|
||||
Foam::Field<Type>::Field
|
||||
(
|
||||
const tmp<Field<Type> >& tmapF,
|
||||
const FieldMapper& mapper
|
||||
const FieldMapper& mapper,
|
||||
const bool applyFlip
|
||||
)
|
||||
:
|
||||
List<Type>(mapper.size())
|
||||
{
|
||||
map(tmapF, mapper);
|
||||
map(tmapF, mapper, applyFlip);
|
||||
}
|
||||
|
||||
|
||||
@ -170,12 +176,13 @@ Foam::Field<Type>::Field
|
||||
(
|
||||
const tmp<Field<Type> >& tmapF,
|
||||
const FieldMapper& mapper,
|
||||
const Type& defaultValue
|
||||
const Type& defaultValue,
|
||||
const bool applyFlip
|
||||
)
|
||||
:
|
||||
List<Type>(mapper.size(), defaultValue)
|
||||
{
|
||||
map(tmapF, mapper);
|
||||
map(tmapF, mapper, applyFlip);
|
||||
}
|
||||
|
||||
|
||||
@ -184,12 +191,13 @@ Foam::Field<Type>::Field
|
||||
(
|
||||
const tmp<Field<Type> >& tmapF,
|
||||
const FieldMapper& mapper,
|
||||
const UList<Type>& defaultValues
|
||||
const UList<Type>& defaultValues,
|
||||
const bool applyFlip
|
||||
)
|
||||
:
|
||||
List<Type>(defaultValues)
|
||||
{
|
||||
map(tmapF, mapper);
|
||||
map(tmapF, mapper, applyFlip);
|
||||
}
|
||||
|
||||
|
||||
@ -443,9 +451,44 @@ template<class Type>
|
||||
void Foam::Field<Type>::map
|
||||
(
|
||||
const UList<Type>& mapF,
|
||||
const FieldMapper& mapper
|
||||
const FieldMapper& mapper,
|
||||
const bool applyFlip
|
||||
)
|
||||
{
|
||||
if (mapper.distributed())
|
||||
{
|
||||
// Fetch remote parts of mapF
|
||||
const mapDistributeBase& distMap = mapper.distributeMap();
|
||||
Field<Type> newMapF(mapF);
|
||||
|
||||
if (applyFlip)
|
||||
{
|
||||
distMap.distribute(newMapF);
|
||||
}
|
||||
else
|
||||
{
|
||||
distMap.distribute(newMapF, noOp());
|
||||
}
|
||||
|
||||
if (mapper.direct() && notNull(mapper.directAddressing()))
|
||||
{
|
||||
map(newMapF, mapper.directAddressing());
|
||||
}
|
||||
else if (!mapper.direct())
|
||||
{
|
||||
map(newMapF, mapper.addressing(), mapper.weights());
|
||||
}
|
||||
else if (mapper.direct() && isNull(mapper.directAddressing()))
|
||||
{
|
||||
// Special case, no local mapper. Assume ordering already correct
|
||||
// from distribution. Note: this behaviour is different compared
|
||||
// to local mapper.
|
||||
this->transfer(newMapF);
|
||||
this->setSize(mapper.size());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if
|
||||
(
|
||||
mapper.direct()
|
||||
@ -459,6 +502,7 @@ void Foam::Field<Type>::map
|
||||
{
|
||||
map(mapF, mapper.addressing(), mapper.weights());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -466,10 +510,11 @@ template<class Type>
|
||||
void Foam::Field<Type>::map
|
||||
(
|
||||
const tmp<Field<Type> >& tmapF,
|
||||
const FieldMapper& mapper
|
||||
const FieldMapper& mapper,
|
||||
const bool applyFlip
|
||||
)
|
||||
{
|
||||
map(tmapF(), mapper);
|
||||
map(tmapF(), mapper, applyFlip);
|
||||
tmapF.clear();
|
||||
}
|
||||
|
||||
@ -477,9 +522,45 @@ void Foam::Field<Type>::map
|
||||
template<class Type>
|
||||
void Foam::Field<Type>::autoMap
|
||||
(
|
||||
const FieldMapper& mapper
|
||||
const FieldMapper& mapper,
|
||||
const bool applyFlip
|
||||
)
|
||||
{
|
||||
if (mapper.distributed())
|
||||
{
|
||||
// Fetch remote parts of *this
|
||||
const mapDistributeBase& distMap = mapper.distributeMap();
|
||||
Field<Type> fCpy(*this);
|
||||
|
||||
if (applyFlip)
|
||||
{
|
||||
distMap.distribute(fCpy);
|
||||
}
|
||||
else
|
||||
{
|
||||
distMap.distribute(fCpy, noOp());
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
(mapper.direct()
|
||||
&& notNull(mapper.directAddressing()))
|
||||
|| !mapper.direct()
|
||||
)
|
||||
{
|
||||
this->map(fCpy, mapper);
|
||||
}
|
||||
else if (mapper.direct() && isNull(mapper.directAddressing()))
|
||||
{
|
||||
// Special case, no local mapper. Assume ordering already correct
|
||||
// from distribution. Note: this behaviour is different compared
|
||||
// to local mapper.
|
||||
this->transfer(fCpy);
|
||||
this->setSize(mapper.size());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if
|
||||
(
|
||||
(
|
||||
@ -497,6 +578,7 @@ void Foam::Field<Type>::autoMap
|
||||
{
|
||||
this->setSize(mapper.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -157,7 +157,8 @@ public:
|
||||
Field
|
||||
(
|
||||
const UList<Type>& mapF,
|
||||
const FieldMapper& map
|
||||
const FieldMapper& map,
|
||||
const bool applyFlip = true
|
||||
);
|
||||
|
||||
//- Construct by mapping from the given field
|
||||
@ -165,7 +166,8 @@ public:
|
||||
(
|
||||
const UList<Type>& mapF,
|
||||
const FieldMapper& map,
|
||||
const Type& defaultValue
|
||||
const Type& defaultValue,
|
||||
const bool applyFlip = true
|
||||
);
|
||||
|
||||
//- Construct by mapping from the given field
|
||||
@ -173,14 +175,16 @@ public:
|
||||
(
|
||||
const UList<Type>& mapF,
|
||||
const FieldMapper& map,
|
||||
const UList<Type>& defaultValues
|
||||
const UList<Type>& defaultValues,
|
||||
const bool applyFlip = true
|
||||
);
|
||||
|
||||
//- Construct by mapping from the given tmp field
|
||||
Field
|
||||
(
|
||||
const tmp<Field<Type> >& tmapF,
|
||||
const FieldMapper& map
|
||||
const FieldMapper& map,
|
||||
const bool applyFlip = true
|
||||
);
|
||||
|
||||
//- Construct by mapping from the given tmp field. Supplied uniform
|
||||
@ -189,7 +193,8 @@ public:
|
||||
(
|
||||
const tmp<Field<Type> >& tmapF,
|
||||
const FieldMapper& map,
|
||||
const Type& defaultValue
|
||||
const Type& defaultValue,
|
||||
const bool applyFlip = true
|
||||
);
|
||||
|
||||
//- Construct by mapping from the given tmp field. Supplied values
|
||||
@ -198,7 +203,8 @@ public:
|
||||
(
|
||||
const tmp<Field<Type> >& tmapF,
|
||||
const FieldMapper& map,
|
||||
const UList<Type>& defaultValues
|
||||
const UList<Type>& defaultValues,
|
||||
const bool applyFlip = true
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
@ -269,20 +275,23 @@ public:
|
||||
void map
|
||||
(
|
||||
const UList<Type>& mapF,
|
||||
const FieldMapper& map
|
||||
const FieldMapper& map,
|
||||
const bool applyFlip = true
|
||||
);
|
||||
|
||||
//- Map from the given tmp field
|
||||
void map
|
||||
(
|
||||
const tmp<Field<Type> >& tmapF,
|
||||
const FieldMapper& map
|
||||
const FieldMapper& map,
|
||||
const bool applyFlip = true
|
||||
);
|
||||
|
||||
//- Map from self
|
||||
void autoMap
|
||||
(
|
||||
const FieldMapper& map
|
||||
const FieldMapper& map,
|
||||
const bool applyFlip = true
|
||||
);
|
||||
|
||||
//- 1 to 1 reverse-map from the given field
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -37,6 +37,8 @@ Description
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
class mapDistributeBase;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class FieldMapper Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -64,6 +66,19 @@ public:
|
||||
|
||||
virtual bool direct() const = 0;
|
||||
|
||||
virtual bool distributed() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual const mapDistributeBase& distributeMap() const
|
||||
{
|
||||
FatalErrorIn("FieldMapper::distributeMap() const")
|
||||
<< "attempt to access null distributeMap"
|
||||
<< abort(FatalError);
|
||||
return *reinterpret_cast<mapDistributeBase*>(NULL);
|
||||
}
|
||||
|
||||
//- Are there unmapped values? I.e. do all size() elements get
|
||||
// get value
|
||||
virtual bool hasUnmapped() const = 0;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -37,7 +37,7 @@ if ((gf1).mesh() != (gf2).mesh()) \
|
||||
FatalErrorIn("checkField(gf1, gf2, op)") \
|
||||
<< "different mesh for fields " \
|
||||
<< (gf1).name() << " and " << (gf2).name() \
|
||||
<< " during operatrion " << op \
|
||||
<< " during operation " << op \
|
||||
<< abort(FatalError); \
|
||||
}
|
||||
|
||||
@ -319,7 +319,8 @@ template<class Type, template<class> class PatchField, class GeoMesh>
|
||||
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
|
||||
(
|
||||
const IOobject& io,
|
||||
const Mesh& mesh
|
||||
const Mesh& mesh,
|
||||
const bool readOldTime
|
||||
)
|
||||
:
|
||||
DimensionedField<Type, GeoMesh>(io, mesh, dimless, false),
|
||||
@ -344,7 +345,10 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
if (readOldTime)
|
||||
{
|
||||
readOldTimeIfPresent();
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
@ -384,8 +388,6 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
readOldTimeIfPresent();
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Finishing dictionary-construct of "
|
||||
@ -600,7 +602,7 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
|
||||
if (debug)
|
||||
{
|
||||
Info<< "GeometricField<Type, PatchField, GeoMesh>::GeometricField : "
|
||||
"constructing as copy resetting IO params"
|
||||
"constructing as copy resetting IO params and patch type"
|
||||
<< endl << this->info() << endl;
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -337,7 +337,8 @@ public:
|
||||
GeometricField
|
||||
(
|
||||
const IOobject&,
|
||||
const Mesh&
|
||||
const Mesh&,
|
||||
const bool readOldTime = true
|
||||
);
|
||||
|
||||
//- Construct from dictionary
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -32,19 +32,16 @@ License
|
||||
|
||||
// Read all fields of type. Returns names of fields read. Guarantees all
|
||||
// processors to read fields in same order.
|
||||
template<class GeoField, class Mesh>
|
||||
Foam::wordList Foam::ReadFields
|
||||
Foam::wordList Foam::fieldNames
|
||||
(
|
||||
const Mesh& mesh,
|
||||
const IOobjectList& objects,
|
||||
PtrList<GeoField>& fields,
|
||||
const IOobjectList& fieldObjects,
|
||||
const bool syncPar
|
||||
)
|
||||
{
|
||||
// Search list of objects for wanted type
|
||||
IOobjectList fieldObjects(objects.lookupClass(GeoField::typeName));
|
||||
|
||||
wordList masterNames(fieldObjects.names());
|
||||
// Get sorted field names. Sorting needed in parallel since different
|
||||
// processors (using different file servers) might pick up the files
|
||||
// in different order.
|
||||
wordList masterNames(fieldObjects.sortedNames());
|
||||
|
||||
if (syncPar && Pstream::parRun())
|
||||
{
|
||||
@ -64,9 +61,7 @@ Foam::wordList Foam::ReadFields
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"ReadFields<class GeoField, class Mesh>"
|
||||
"(const Mesh&, const IOobjectList&, PtrList<GeoField>&"
|
||||
", const bool)"
|
||||
"fieldNames(const IOobjectList&, const bool syncPar)"
|
||||
) << "Fields not synchronised across processors." << endl
|
||||
<< "Master has fields " << masterNames
|
||||
<< " processor " << Pstream::myProcNo()
|
||||
@ -82,9 +77,7 @@ Foam::wordList Foam::ReadFields
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"ReadFields<class GeoField, class Mesh>"
|
||||
"(const Mesh&, const IOobjectList&, PtrList<GeoField>&"
|
||||
", const bool)"
|
||||
"fieldNames(const IOobjectList&, const bol syncPar)"
|
||||
) << "Fields not synchronised across processors." << endl
|
||||
<< "Master has fields " << masterNames
|
||||
<< " processor " << Pstream::myProcNo()
|
||||
@ -92,169 +85,8 @@ Foam::wordList Foam::ReadFields
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fields.setSize(masterNames.size());
|
||||
|
||||
// Make sure to read in masterNames order.
|
||||
|
||||
forAll(masterNames, i)
|
||||
{
|
||||
Info<< "Reading " << GeoField::typeName << ' ' << masterNames[i]
|
||||
<< endl;
|
||||
|
||||
const IOobject& io = *fieldObjects[masterNames[i]];
|
||||
|
||||
fields.set
|
||||
(
|
||||
i,
|
||||
new GeoField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
io.name(),
|
||||
io.instance(),
|
||||
io.local(),
|
||||
io.db(),
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE,
|
||||
io.registerObject()
|
||||
),
|
||||
mesh
|
||||
)
|
||||
);
|
||||
}
|
||||
return masterNames;
|
||||
}
|
||||
|
||||
|
||||
template<class GeoField>
|
||||
void Foam::ReadFields
|
||||
(
|
||||
const word& fieldName,
|
||||
const typename GeoField::Mesh& mesh,
|
||||
const wordList& timeNames,
|
||||
objectRegistry& fieldsCache
|
||||
)
|
||||
{
|
||||
// Collect all times that are no longer used
|
||||
{
|
||||
HashSet<word> usedTimes(timeNames);
|
||||
|
||||
DynamicList<word> unusedTimes(fieldsCache.size());
|
||||
|
||||
forAllIter(objectRegistry, fieldsCache, timeIter)
|
||||
{
|
||||
const word& tm = timeIter.key();
|
||||
if (!usedTimes.found(tm))
|
||||
{
|
||||
unusedTimes.append(tm);
|
||||
}
|
||||
}
|
||||
|
||||
//Info<< "Unloading times " << unusedTimes << endl;
|
||||
|
||||
forAll(unusedTimes, i)
|
||||
{
|
||||
objectRegistry& timeCache = const_cast<objectRegistry&>
|
||||
(
|
||||
fieldsCache.lookupObject<objectRegistry>(unusedTimes[i])
|
||||
);
|
||||
fieldsCache.checkOut(timeCache);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Load any new fields
|
||||
forAll(timeNames, i)
|
||||
{
|
||||
const word& tm = timeNames[i];
|
||||
|
||||
// Create if not found
|
||||
if (!fieldsCache.found(tm))
|
||||
{
|
||||
//Info<< "Creating registry for time " << tm << endl;
|
||||
|
||||
// Create objectRegistry if not found
|
||||
objectRegistry* timeCachePtr = new objectRegistry
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
tm,
|
||||
tm,
|
||||
fieldsCache,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
timeCachePtr->store();
|
||||
}
|
||||
|
||||
// Obtain cache for current time
|
||||
const objectRegistry& timeCache =
|
||||
fieldsCache.lookupObject<objectRegistry>
|
||||
(
|
||||
tm
|
||||
);
|
||||
|
||||
// Store field if not found
|
||||
if (!timeCache.found(fieldName))
|
||||
{
|
||||
//Info<< "Loading field " << fieldName
|
||||
// << " for time " << tm << endl;
|
||||
|
||||
GeoField loadedFld
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
fieldName,
|
||||
tm,
|
||||
mesh.thisDb(),
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
mesh
|
||||
);
|
||||
|
||||
// Transfer to timeCache (new objectRegistry and store flag)
|
||||
GeoField* fldPtr = new GeoField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
fieldName,
|
||||
tm,
|
||||
timeCache,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
loadedFld
|
||||
);
|
||||
fldPtr->store();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class GeoField>
|
||||
void Foam::ReadFields
|
||||
(
|
||||
const word& fieldName,
|
||||
const typename GeoField::Mesh& mesh,
|
||||
const wordList& timeNames,
|
||||
const word& registryName
|
||||
)
|
||||
{
|
||||
ReadFields<GeoField>
|
||||
(
|
||||
fieldName,
|
||||
mesh,
|
||||
timeNames,
|
||||
const_cast<objectRegistry&>
|
||||
(
|
||||
mesh.thisDb().subRegistry(registryName, true)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -29,6 +29,7 @@ Description
|
||||
|
||||
SourceFiles
|
||||
ReadFields.C
|
||||
ReadFieldsTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
@ -37,6 +38,7 @@ SourceFiles
|
||||
|
||||
#include "PtrList.H"
|
||||
#include "wordList.H"
|
||||
#include "GeometricField.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -45,7 +47,23 @@ namespace Foam
|
||||
|
||||
class IOobjectList;
|
||||
|
||||
//- Helper routine to read fields
|
||||
|
||||
//- Get sorted names of fields of type. If syncPar and running in parallel
|
||||
// check for identical names
|
||||
wordList fieldNames(const IOobjectList& objects, const bool syncPar);
|
||||
|
||||
//- Helper routine to read Geometric fields
|
||||
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||
wordList ReadFields
|
||||
(
|
||||
const typename GeoMesh::Mesh& mesh,
|
||||
const IOobjectList& objects,
|
||||
PtrList<GeometricField<Type, PatchField, GeoMesh> >& fields,
|
||||
const bool syncPar = true,
|
||||
const bool readOldTime = false
|
||||
);
|
||||
|
||||
//- Helper routine to read other mesh fields
|
||||
template<class GeoField, class Mesh>
|
||||
wordList ReadFields
|
||||
(
|
||||
@ -55,6 +73,16 @@ wordList ReadFields
|
||||
const bool syncPar = true
|
||||
);
|
||||
|
||||
//- Helper routine to read non-mesh fields (e.g. uniformDimensionedField like
|
||||
// 'g')
|
||||
template<class GeoField>
|
||||
wordList ReadFields
|
||||
(
|
||||
const IOobjectList& objects,
|
||||
PtrList<GeoField>& fields,
|
||||
const bool syncPar = true
|
||||
);
|
||||
|
||||
//- Helper routine to read GeometricFields. The fieldsCache is per time
|
||||
// an objectRegistry of all stored fields
|
||||
template<class GeoField>
|
||||
@ -82,7 +110,7 @@ static void ReadFields
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "ReadFields.C"
|
||||
# include "ReadFieldsTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
314
src/OpenFOAM/fields/ReadFields/ReadFieldsTemplates.C
Normal file
314
src/OpenFOAM/fields/ReadFields/ReadFieldsTemplates.C
Normal file
@ -0,0 +1,314 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "ReadFields.H"
|
||||
#include "HashSet.H"
|
||||
#include "IOobjectList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||
|
||||
// Read all GeometricFields of type. Returns names of fields read. Guarantees
|
||||
// all processors to read fields in same order.
|
||||
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||
Foam::wordList Foam::ReadFields
|
||||
(
|
||||
const typename GeoMesh::Mesh& mesh,
|
||||
const IOobjectList& objects,
|
||||
PtrList<GeometricField<Type, PatchField, GeoMesh> >& fields,
|
||||
const bool syncPar,
|
||||
const bool readOldTime
|
||||
)
|
||||
{
|
||||
typedef GeometricField<Type, PatchField, GeoMesh> GeoField;
|
||||
|
||||
// Search list of objects for wanted type
|
||||
IOobjectList fieldObjects(objects.lookupClass(GeoField::typeName));
|
||||
|
||||
const wordList masterNames(fieldNames(fieldObjects, syncPar));
|
||||
|
||||
fields.setSize(masterNames.size());
|
||||
|
||||
// Make sure to read in masterNames order.
|
||||
|
||||
forAll(masterNames, i)
|
||||
{
|
||||
Info<< "Reading " << GeoField::typeName << ' ' << masterNames[i]
|
||||
<< endl;
|
||||
|
||||
const IOobject& io = *fieldObjects[masterNames[i]];
|
||||
|
||||
fields.set
|
||||
(
|
||||
i,
|
||||
new GeoField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
io.name(),
|
||||
io.instance(),
|
||||
io.local(),
|
||||
io.db(),
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE,
|
||||
io.registerObject()
|
||||
),
|
||||
mesh,
|
||||
readOldTime
|
||||
)
|
||||
);
|
||||
}
|
||||
return masterNames;
|
||||
}
|
||||
|
||||
|
||||
// Read all fields of type. Returns names of fields read. Guarantees all
|
||||
// processors to read fields in same order.
|
||||
template<class GeoField, class Mesh>
|
||||
Foam::wordList Foam::ReadFields
|
||||
(
|
||||
const Mesh& mesh,
|
||||
const IOobjectList& objects,
|
||||
PtrList<GeoField>& fields,
|
||||
const bool syncPar
|
||||
)
|
||||
{
|
||||
// Search list of objects for wanted type
|
||||
IOobjectList fieldObjects(objects.lookupClass(GeoField::typeName));
|
||||
|
||||
const wordList masterNames(fieldNames(fieldObjects, syncPar));
|
||||
|
||||
fields.setSize(masterNames.size());
|
||||
|
||||
// Make sure to read in masterNames order.
|
||||
|
||||
forAll(masterNames, i)
|
||||
{
|
||||
Info<< "Reading " << GeoField::typeName << ' ' << masterNames[i]
|
||||
<< endl;
|
||||
|
||||
const IOobject& io = *fieldObjects[masterNames[i]];
|
||||
|
||||
fields.set
|
||||
(
|
||||
i,
|
||||
new GeoField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
io.name(),
|
||||
io.instance(),
|
||||
io.local(),
|
||||
io.db(),
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE,
|
||||
io.registerObject()
|
||||
),
|
||||
mesh
|
||||
)
|
||||
);
|
||||
}
|
||||
return masterNames;
|
||||
}
|
||||
|
||||
|
||||
// Read all (non-mesh) fields of type. Returns names of fields read. Guarantees
|
||||
// all processors to read fields in same order.
|
||||
template<class GeoField>
|
||||
Foam::wordList Foam::ReadFields
|
||||
(
|
||||
const IOobjectList& objects,
|
||||
PtrList<GeoField>& fields,
|
||||
const bool syncPar
|
||||
)
|
||||
{
|
||||
// Search list of objects for wanted type
|
||||
IOobjectList fieldObjects(objects.lookupClass(GeoField::typeName));
|
||||
|
||||
const wordList masterNames(fieldNames(fieldObjects, syncPar));
|
||||
|
||||
fields.setSize(masterNames.size());
|
||||
|
||||
// Make sure to read in masterNames order.
|
||||
|
||||
forAll(masterNames, i)
|
||||
{
|
||||
Info<< "Reading " << GeoField::typeName << ' ' << masterNames[i]
|
||||
<< endl;
|
||||
|
||||
const IOobject& io = *fieldObjects[masterNames[i]];
|
||||
|
||||
fields.set
|
||||
(
|
||||
i,
|
||||
new GeoField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
io.name(),
|
||||
io.instance(),
|
||||
io.local(),
|
||||
io.db(),
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE,
|
||||
io.registerObject()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
return masterNames;
|
||||
}
|
||||
|
||||
|
||||
template<class GeoField>
|
||||
void Foam::ReadFields
|
||||
(
|
||||
const word& fieldName,
|
||||
const typename GeoField::Mesh& mesh,
|
||||
const wordList& timeNames,
|
||||
objectRegistry& fieldsCache
|
||||
)
|
||||
{
|
||||
// Collect all times that are no longer used
|
||||
{
|
||||
HashSet<word> usedTimes(timeNames);
|
||||
|
||||
DynamicList<word> unusedTimes(fieldsCache.size());
|
||||
|
||||
forAllIter(objectRegistry, fieldsCache, timeIter)
|
||||
{
|
||||
const word& tm = timeIter.key();
|
||||
if (!usedTimes.found(tm))
|
||||
{
|
||||
unusedTimes.append(tm);
|
||||
}
|
||||
}
|
||||
|
||||
//Info<< "Unloading times " << unusedTimes << endl;
|
||||
|
||||
forAll(unusedTimes, i)
|
||||
{
|
||||
objectRegistry& timeCache = const_cast<objectRegistry&>
|
||||
(
|
||||
fieldsCache.lookupObject<objectRegistry>(unusedTimes[i])
|
||||
);
|
||||
fieldsCache.checkOut(timeCache);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Load any new fields
|
||||
forAll(timeNames, i)
|
||||
{
|
||||
const word& tm = timeNames[i];
|
||||
|
||||
// Create if not found
|
||||
if (!fieldsCache.found(tm))
|
||||
{
|
||||
//Info<< "Creating registry for time " << tm << endl;
|
||||
|
||||
// Create objectRegistry if not found
|
||||
objectRegistry* timeCachePtr = new objectRegistry
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
tm,
|
||||
tm,
|
||||
fieldsCache,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
timeCachePtr->store();
|
||||
}
|
||||
|
||||
// Obtain cache for current time
|
||||
const objectRegistry& timeCache =
|
||||
fieldsCache.lookupObject<objectRegistry>
|
||||
(
|
||||
tm
|
||||
);
|
||||
|
||||
// Store field if not found
|
||||
if (!timeCache.found(fieldName))
|
||||
{
|
||||
//Info<< "Loading field " << fieldName
|
||||
// << " for time " << tm << endl;
|
||||
|
||||
GeoField loadedFld
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
fieldName,
|
||||
tm,
|
||||
mesh.thisDb(),
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
mesh
|
||||
);
|
||||
|
||||
// Transfer to timeCache (new objectRegistry and store flag)
|
||||
GeoField* fldPtr = new GeoField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
fieldName,
|
||||
tm,
|
||||
timeCache,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
loadedFld
|
||||
);
|
||||
fldPtr->store();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class GeoField>
|
||||
void Foam::ReadFields
|
||||
(
|
||||
const word& fieldName,
|
||||
const typename GeoField::Mesh& mesh,
|
||||
const wordList& timeNames,
|
||||
const word& registryName
|
||||
)
|
||||
{
|
||||
ReadFields<GeoField>
|
||||
(
|
||||
fieldName,
|
||||
mesh,
|
||||
timeNames,
|
||||
const_cast<objectRegistry&>
|
||||
(
|
||||
mesh.thisDb().subRegistry(registryName, true)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -103,7 +103,7 @@ bool Foam::UniformDimensionedField<Type>::writeData(Ostream& os) const
|
||||
os.writeKeyword("value") << this->value()/multiplier << token::END_STATEMENT
|
||||
<< nl << nl;
|
||||
|
||||
return (os.good());
|
||||
return os.good();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -64,6 +64,17 @@ Foam::argList::initValidTables::initValidTables()
|
||||
);
|
||||
validParOptions.set("roots", "(dir1 .. dirN)");
|
||||
|
||||
argList::addOption
|
||||
(
|
||||
"decomposeParDict", "file",
|
||||
"read decomposePar dictionary from specified location"
|
||||
);
|
||||
validParOptions.set
|
||||
(
|
||||
"decomposeParDict",
|
||||
"file"
|
||||
);
|
||||
|
||||
argList::addBoolOption
|
||||
(
|
||||
"noFunctionObjects",
|
||||
@ -147,6 +158,7 @@ void Foam::argList::noParallel()
|
||||
{
|
||||
removeOption("parallel");
|
||||
removeOption("roots");
|
||||
removeOption("decomposeParDict");
|
||||
validParOptions.clear();
|
||||
}
|
||||
|
||||
@ -601,13 +613,23 @@ void Foam::argList::parse
|
||||
}
|
||||
else
|
||||
{
|
||||
source = rootPath_/globalCase_/"system/decomposeParDict";
|
||||
source = rootPath_/globalCase_/"system"/"decomposeParDict";
|
||||
// Override with -decomposeParDict
|
||||
if (options_.found("decomposeParDict"))
|
||||
{
|
||||
source = options_["decomposeParDict"];
|
||||
if (isDir(source))
|
||||
{
|
||||
source = source/"decomposeParDict";
|
||||
}
|
||||
}
|
||||
|
||||
IFstream decompDictStream(source);
|
||||
|
||||
if (!decompDictStream.good())
|
||||
{
|
||||
FatalError
|
||||
<< "Cannot read "
|
||||
<< "Cannot read decomposeParDict from "
|
||||
<< decompDictStream.name()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
@ -770,9 +792,6 @@ void Foam::argList::parse
|
||||
if (Pstream::master())
|
||||
{
|
||||
slaveProcs.setSize(Pstream::nProcs() - 1);
|
||||
string slaveMachine;
|
||||
label slavePid;
|
||||
|
||||
label procI = 0;
|
||||
for
|
||||
(
|
||||
@ -782,15 +801,30 @@ void Foam::argList::parse
|
||||
)
|
||||
{
|
||||
IPstream fromSlave(Pstream::scheduled, slave);
|
||||
fromSlave >> slaveMachine >> slavePid;
|
||||
|
||||
string slaveBuild;
|
||||
string slaveMachine;
|
||||
label slavePid;
|
||||
fromSlave >> slaveBuild >> slaveMachine >> slavePid;
|
||||
|
||||
slaveProcs[procI++] = slaveMachine + "." + name(slavePid);
|
||||
|
||||
// Check build string to make sure all processors are running
|
||||
// the same build
|
||||
if (slaveBuild != Foam::FOAMbuild)
|
||||
{
|
||||
FatalErrorIn(executable())
|
||||
<< "Master is running version " << Foam::FOAMbuild
|
||||
<< "; slave " << procI << " is running version "
|
||||
<< slaveBuild
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
|
||||
toMaster << hostName() << pid();
|
||||
toMaster << string(Foam::FOAMbuild) << hostName() << pid();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -118,6 +118,12 @@ Note:
|
||||
+------+ 0
|
||||
|
||||
|
||||
When constructing from components optionally a 'flip' on
|
||||
the maps can be specified. This will interpret the map
|
||||
values as index+flip, similar to e.g. faceProcAddressing. The flip
|
||||
will only be applied to fieldTypes (scalar, vector, .. triad)
|
||||
|
||||
|
||||
SourceFiles
|
||||
mapDistribute.C
|
||||
mapDistributeTemplates.C
|
||||
@ -127,12 +133,8 @@ SourceFiles
|
||||
#ifndef mapDistribute_H
|
||||
#define mapDistribute_H
|
||||
|
||||
#include "mapDistributeBase.H"
|
||||
#include "transformList.H"
|
||||
#include "labelList.H"
|
||||
#include "labelPair.H"
|
||||
#include "Pstream.H"
|
||||
#include "boolList.H"
|
||||
#include "Map.H"
|
||||
#include "vectorTensorTransform.H"
|
||||
#include "coupledPolyPatch.H"
|
||||
|
||||
@ -141,30 +143,19 @@ SourceFiles
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
class mapPolyMesh;
|
||||
class globalIndex;
|
||||
class PstreamBuffers;
|
||||
class globalIndexAndTransform;
|
||||
//class vectorTensorTransform;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class mapDistribute Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class mapDistribute
|
||||
:
|
||||
public mapDistributeBase
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Size of reconstructed data
|
||||
label constructSize_;
|
||||
|
||||
//- Maps from subsetted data back to original data
|
||||
labelListList subMap_;
|
||||
|
||||
//- Maps from subsetted data to new reconstructed data
|
||||
labelListList constructMap_;
|
||||
|
||||
// Optional transformation
|
||||
|
||||
//- For every globalIndexAndTransform::transformPermutations
|
||||
// gives the elements that need to be transformed
|
||||
labelListList transformElements_;
|
||||
@ -172,51 +163,8 @@ class mapDistribute
|
||||
//- Destination in constructMap for transformed elements
|
||||
labelList transformStart_;
|
||||
|
||||
|
||||
//- Schedule
|
||||
mutable autoPtr<List<labelPair> > schedulePtr_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
static void checkReceivedSize
|
||||
(
|
||||
const label procI,
|
||||
const label expectedSize,
|
||||
const label receivedSize
|
||||
);
|
||||
|
||||
void calcCompactAddressing
|
||||
(
|
||||
const globalIndex& globalNumbering,
|
||||
const labelList& elements,
|
||||
List<Map<label> >& compactMap
|
||||
) const;
|
||||
void calcCompactAddressing
|
||||
(
|
||||
const globalIndex& globalNumbering,
|
||||
const labelListList& elements,
|
||||
List<Map<label> >& compactMap
|
||||
) const;
|
||||
|
||||
void exchangeAddressing
|
||||
(
|
||||
const int tag,
|
||||
const globalIndex& globalNumbering,
|
||||
labelList& elements,
|
||||
List<Map<label> >& compactMap,
|
||||
labelList& compactStart
|
||||
);
|
||||
void exchangeAddressing
|
||||
(
|
||||
const int tag,
|
||||
const globalIndex& globalNumbering,
|
||||
labelListList& elements,
|
||||
List<Map<label> >& compactMap,
|
||||
labelList& compactStart
|
||||
);
|
||||
|
||||
|
||||
//- Helper function: copy transformElements without transformation
|
||||
template<class T>
|
||||
void applyDummyTransforms(List<T>& field) const;
|
||||
@ -241,7 +189,6 @@ class mapDistribute
|
||||
const TransformOp& top
|
||||
) const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Public classes
|
||||
@ -358,7 +305,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Declare name of the class and its debug switch
|
||||
ClassName("mapDistribute");
|
||||
|
||||
@ -373,7 +319,9 @@ public:
|
||||
(
|
||||
const label constructSize,
|
||||
const Xfer<labelListList>& subMap,
|
||||
const Xfer<labelListList>& constructMap
|
||||
const Xfer<labelListList>& constructMap,
|
||||
const bool subHasFlip = false,
|
||||
const bool constructHasFlip = false
|
||||
);
|
||||
|
||||
//- Construct from components
|
||||
@ -383,7 +331,9 @@ public:
|
||||
const Xfer<labelListList>& subMap,
|
||||
const Xfer<labelListList>& constructMap,
|
||||
const Xfer<labelListList>& transformElements,
|
||||
const Xfer<labelList>& transformStart
|
||||
const Xfer<labelList>& transformStart,
|
||||
const bool subHasFlip = false,
|
||||
const bool constructHasFlip = false
|
||||
);
|
||||
|
||||
//- Construct from reverse addressing: per data item the send
|
||||
@ -453,47 +403,22 @@ public:
|
||||
//- Construct copy
|
||||
mapDistribute(const mapDistribute&);
|
||||
|
||||
//- Construct from Istream
|
||||
mapDistribute(Istream&);
|
||||
|
||||
//- Clone
|
||||
autoPtr<mapDistribute> clone() const;
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~mapDistribute()
|
||||
{}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Constructed data size
|
||||
label constructSize() const
|
||||
{
|
||||
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_;
|
||||
}
|
||||
|
||||
//- For every globalIndexAndTransform::transformPermutations
|
||||
// gives the elements that need to be transformed
|
||||
const labelListList& transformElements() const
|
||||
@ -510,17 +435,6 @@ public:
|
||||
//- Find transform from transformElements
|
||||
label whichTransform(const label index) const;
|
||||
|
||||
//- Calculate a schedule. See above.
|
||||
static List<labelPair> schedule
|
||||
(
|
||||
const labelListList& subMap,
|
||||
const labelListList& constructMap,
|
||||
const int tag
|
||||
);
|
||||
|
||||
//- Return a schedule. Demand driven. See above.
|
||||
const List<labelPair>& schedule() const;
|
||||
|
||||
|
||||
// Other
|
||||
|
||||
@ -530,53 +444,25 @@ public:
|
||||
//- Transfer contents to the Xfer container
|
||||
Xfer<mapDistribute> xfer();
|
||||
|
||||
//- Helper for construct from globalIndex. Renumbers element
|
||||
// (in globalIndex numbering) into compact indices.
|
||||
static label renumber
|
||||
(
|
||||
const globalIndex&,
|
||||
const List<Map<label> >& compactMap,
|
||||
const label globalElement
|
||||
);
|
||||
|
||||
//- Compact maps. Gets per field a bool whether it is used (locally)
|
||||
// and works out itself what this side and sender side can remove
|
||||
// from maps.
|
||||
void compact
|
||||
(
|
||||
const boolList& elemIsUsed,
|
||||
const int tag = UPstream::msgType()
|
||||
);
|
||||
|
||||
//- Distribute data. Note:schedule only used for Pstream::scheduled
|
||||
// for now, all others just use send-to-all, receive-from-all.
|
||||
//- Distribute data using default commsType.
|
||||
template<class T>
|
||||
static void distribute
|
||||
void distribute
|
||||
(
|
||||
const Pstream::commsTypes commsType,
|
||||
const List<labelPair>& schedule,
|
||||
const label constructSize,
|
||||
const labelListList& subMap,
|
||||
const labelListList& constructMap,
|
||||
List<T>&,
|
||||
List<T>& fld,
|
||||
const bool dummyTransform = true,
|
||||
const int tag = UPstream::msgType()
|
||||
);
|
||||
) const;
|
||||
|
||||
//- Distribute data. If multiple processors writing to same
|
||||
// position adds contributions using cop.
|
||||
template<class T, class CombineOp>
|
||||
static void distribute
|
||||
//- Distribute data using default commsType.
|
||||
template<class T, class negateOp>
|
||||
void distribute
|
||||
(
|
||||
const Pstream::commsTypes commsType,
|
||||
const List<labelPair>& schedule,
|
||||
const label constructSize,
|
||||
const labelListList& subMap,
|
||||
const labelListList& constructMap,
|
||||
List<T>&,
|
||||
const CombineOp& cop,
|
||||
const T& nullValue,
|
||||
List<T>& fld,
|
||||
const negateOp& negOp,
|
||||
const bool dummyTransform = true,
|
||||
const int tag = UPstream::msgType()
|
||||
);
|
||||
) const;
|
||||
|
||||
//- Distribute data using default commsType.
|
||||
template<class T>
|
||||
@ -587,25 +473,6 @@ public:
|
||||
const int tag = UPstream::msgType()
|
||||
) const;
|
||||
|
||||
//- Distribute data using default commsType.
|
||||
template<class T>
|
||||
void distribute
|
||||
(
|
||||
List<T>& fld,
|
||||
const bool dummyTransform = true,
|
||||
const int tag = UPstream::msgType()
|
||||
) const;
|
||||
|
||||
//- Same but with transforms
|
||||
template<class T, class TransformOp>
|
||||
void distribute
|
||||
(
|
||||
const globalIndexAndTransform&,
|
||||
List<T>& fld,
|
||||
const TransformOp& top,
|
||||
const int tag = UPstream::msgType()
|
||||
) const;
|
||||
|
||||
//- Reverse distribute data using default commsType.
|
||||
template<class T>
|
||||
void reverseDistribute
|
||||
@ -616,17 +483,6 @@ public:
|
||||
const int tag = UPstream::msgType()
|
||||
) const;
|
||||
|
||||
//- Same but with transforms
|
||||
template<class T, class TransformOp>
|
||||
void reverseDistribute
|
||||
(
|
||||
const globalIndexAndTransform&,
|
||||
const label constructSize,
|
||||
List<T>& fld,
|
||||
const TransformOp& top,
|
||||
const int tag = UPstream::msgType()
|
||||
) const;
|
||||
|
||||
//- Reverse distribute data using default commsType.
|
||||
// Since constructSize might be larger than supplied size supply
|
||||
// a nullValue
|
||||
@ -640,7 +496,28 @@ public:
|
||||
const int tag = UPstream::msgType()
|
||||
) const;
|
||||
|
||||
//- Same but with transforms
|
||||
//- Distribute with transforms
|
||||
template<class T, class TransformOp>
|
||||
void distribute
|
||||
(
|
||||
const globalIndexAndTransform&,
|
||||
List<T>& fld,
|
||||
const TransformOp& top,
|
||||
const int tag = UPstream::msgType()
|
||||
) const;
|
||||
|
||||
//- Reverse distribute with transforms
|
||||
template<class T, class TransformOp>
|
||||
void reverseDistribute
|
||||
(
|
||||
const globalIndexAndTransform&,
|
||||
const label constructSize,
|
||||
List<T>& fld,
|
||||
const TransformOp& top,
|
||||
const int tag = UPstream::msgType()
|
||||
) const;
|
||||
|
||||
//- Reverse distribute with transforms
|
||||
template<class T, class TransformOp>
|
||||
void reverseDistribute
|
||||
(
|
||||
@ -652,13 +529,6 @@ public:
|
||||
const int tag = UPstream::msgType()
|
||||
) const;
|
||||
|
||||
//- Do all sends using PstreamBuffers
|
||||
template<class T>
|
||||
void send(PstreamBuffers&, const List<T>&) const;
|
||||
//- Do all receives using PstreamBuffers
|
||||
template<class T>
|
||||
void receive(PstreamBuffers&, List<T>&) const;
|
||||
|
||||
//- Debug: print layout. Can only be used on maps with sorted
|
||||
// storage (local data first, then non-local data)
|
||||
void printLayout(Ostream& os) const;
|
||||
@ -676,7 +546,6 @@ public:
|
||||
|
||||
void operator=(const mapDistribute&);
|
||||
|
||||
|
||||
// IOstream operators
|
||||
|
||||
//- Read dictionary from Istream
|
||||
@ -688,6 +557,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
// Template specialisation for primitives that do not need transform
|
||||
template<>
|
||||
void mapDistribute::transform::operator()
|
||||
(
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,485 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::mapDistributeBase
|
||||
|
||||
Description
|
||||
Class containing processor-to-processor mapping information.
|
||||
|
||||
We store mapping from the bits-to-send to the complete starting list
|
||||
(subXXXMap) and from the received bits to their location in the new
|
||||
list (constructXXXMap).
|
||||
|
||||
Note:
|
||||
Schedule is a list of processor pairs (one send, one receive. One of
|
||||
them will be myself) which forms a scheduled (i.e. non-buffered) exchange.
|
||||
See distribute on how to use it.
|
||||
Note2: number of items sent on one processor have to equal the number
|
||||
of items received on the other processor.
|
||||
|
||||
To aid constructing these maps there are the constructors from global
|
||||
numbering, either with or without transforms.
|
||||
|
||||
Constructors using compact numbering: layout is
|
||||
- all my own elements first (whether used or not)
|
||||
- followed by used-only remote elements sorted by remote processor.
|
||||
So e.g 4 procs and on proc 1 the compact
|
||||
table will first have all globalIndex.localSize() elements from proc1
|
||||
followed by used-only elements of proc0, proc2, proc3.
|
||||
The constructed mapDistributeBase sends the local elements from and
|
||||
receives the remote elements into their compact position.
|
||||
compactMap[procI] is the position of elements from procI in the compact
|
||||
map. compactMap[myProcNo()] is empty since trivial addressing.
|
||||
|
||||
It rewrites the input global indices into indices into the constructed
|
||||
data.
|
||||
|
||||
When constructing from components optionally a 'flip' on
|
||||
the maps can be specified. This will interpret the map
|
||||
values as index+flip, similar to e.g. faceProcAddressing. The flip
|
||||
will only be applied to fieldTypes (scalar, vector, .. triad)
|
||||
|
||||
|
||||
SourceFiles
|
||||
mapDistributeBase.C
|
||||
mapDistributeBaseTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef mapDistributeBase_H
|
||||
#define mapDistributeBase_H
|
||||
|
||||
#include "labelList.H"
|
||||
#include "labelPair.H"
|
||||
#include "Pstream.H"
|
||||
#include "boolList.H"
|
||||
#include "Map.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
class mapPolyMesh;
|
||||
class globalIndex;
|
||||
class PstreamBuffers;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class mapDistributeBase Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class mapDistributeBase
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Size of reconstructed data
|
||||
label constructSize_;
|
||||
|
||||
//- Maps from subsetted data back to original data
|
||||
labelListList subMap_;
|
||||
|
||||
//- Maps from subsetted data to new reconstructed data
|
||||
labelListList constructMap_;
|
||||
|
||||
//- Whether subMap includes flip or not
|
||||
bool subHasFlip_;
|
||||
|
||||
//- Whether constructMap includes flip or not
|
||||
bool constructHasFlip_;
|
||||
|
||||
|
||||
//- Schedule
|
||||
mutable autoPtr<List<labelPair> > schedulePtr_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
static void checkReceivedSize
|
||||
(
|
||||
const label procI,
|
||||
const label expectedSize,
|
||||
const label receivedSize
|
||||
);
|
||||
|
||||
void calcCompactAddressing
|
||||
(
|
||||
const globalIndex& globalNumbering,
|
||||
const labelList& elements,
|
||||
List<Map<label> >& compactMap
|
||||
) const;
|
||||
void calcCompactAddressing
|
||||
(
|
||||
const globalIndex& globalNumbering,
|
||||
const labelListList& elements,
|
||||
List<Map<label> >& compactMap
|
||||
) const;
|
||||
|
||||
void exchangeAddressing
|
||||
(
|
||||
const int tag,
|
||||
const globalIndex& globalNumbering,
|
||||
labelList& elements,
|
||||
List<Map<label> >& compactMap,
|
||||
labelList& compactStart
|
||||
);
|
||||
void exchangeAddressing
|
||||
(
|
||||
const int tag,
|
||||
const globalIndex& globalNumbering,
|
||||
labelListList& elements,
|
||||
List<Map<label> >& compactMap,
|
||||
labelList& compactStart
|
||||
);
|
||||
|
||||
template<class T, class CombineOp, class negateOp>
|
||||
static void flipAndCombine
|
||||
(
|
||||
const UList<label>& map,
|
||||
const bool hasFlip,
|
||||
const UList<T>& rhs,
|
||||
const CombineOp& cop,
|
||||
const negateOp& negOp,
|
||||
List<T>& lhs
|
||||
);
|
||||
|
||||
template<class T, class negateOp>
|
||||
static T accessAndFlip
|
||||
(
|
||||
const UList<T>& fld,
|
||||
const label index,
|
||||
const bool hasFlip,
|
||||
const negateOp& negOp
|
||||
);
|
||||
|
||||
public:
|
||||
|
||||
// Declare name of the class and its debug switch
|
||||
ClassName("mapDistributeBase");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
mapDistributeBase();
|
||||
|
||||
//- Construct from components
|
||||
mapDistributeBase
|
||||
(
|
||||
const label constructSize,
|
||||
const Xfer<labelListList>& subMap,
|
||||
const Xfer<labelListList>& constructMap,
|
||||
const bool subHasFlip = false,
|
||||
const bool constructHasFlip = false
|
||||
);
|
||||
|
||||
//- Construct from reverse addressing: per data item the send
|
||||
// processor and the receive processor. (note: data is not stored
|
||||
// sorted per processor so cannot use printLayout).
|
||||
mapDistributeBase
|
||||
(
|
||||
const labelList& sendProcs,
|
||||
const labelList& recvProcs
|
||||
);
|
||||
|
||||
//- Construct from list of (possibly) remote elements in globalIndex
|
||||
// numbering (or -1). Determines compact numbering (see above) and
|
||||
// distribute map to get data into this ordering and renumbers the
|
||||
// elements to be in compact numbering.
|
||||
mapDistributeBase
|
||||
(
|
||||
const globalIndex&,
|
||||
labelList& elements,
|
||||
List<Map<label> >& compactMap,
|
||||
const int tag = Pstream::msgType()
|
||||
);
|
||||
|
||||
//- Special variant that works with the info sorted into bins
|
||||
// according to local indices. E.g. think cellCells where
|
||||
// cellCells[localCellI] is a list of global cells
|
||||
mapDistributeBase
|
||||
(
|
||||
const globalIndex&,
|
||||
labelListList& cellCells,
|
||||
List<Map<label> >& compactMap,
|
||||
const int tag = Pstream::msgType()
|
||||
);
|
||||
|
||||
//- Construct by transferring parameter content
|
||||
mapDistributeBase(const Xfer<mapDistributeBase>&);
|
||||
|
||||
//- Construct copy
|
||||
mapDistributeBase(const mapDistributeBase&);
|
||||
|
||||
//- Construct from Istream
|
||||
mapDistributeBase(Istream&);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Constructed data size
|
||||
label constructSize() const
|
||||
{
|
||||
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_;
|
||||
}
|
||||
|
||||
//- Does subMap include a sign
|
||||
bool subHasFlip() const
|
||||
{
|
||||
return subHasFlip_;
|
||||
}
|
||||
|
||||
//- Does subMap include a sign
|
||||
bool& subHasFlip()
|
||||
{
|
||||
return subHasFlip_;
|
||||
}
|
||||
|
||||
//- Does constructMap include a sign
|
||||
bool constructHasFlip() const
|
||||
{
|
||||
return constructHasFlip_;
|
||||
}
|
||||
|
||||
//- Does constructMap include a sign
|
||||
bool& constructHasFlip()
|
||||
{
|
||||
return constructHasFlip_;
|
||||
}
|
||||
|
||||
//- Calculate a schedule. See above.
|
||||
static List<labelPair> schedule
|
||||
(
|
||||
const labelListList& subMap,
|
||||
const labelListList& constructMap,
|
||||
const int tag
|
||||
);
|
||||
|
||||
//- Return a schedule. Demand driven. See above.
|
||||
const List<labelPair>& schedule() const;
|
||||
|
||||
|
||||
// Other
|
||||
|
||||
//- Transfer the contents of the argument and annul the argument.
|
||||
void transfer(mapDistributeBase&);
|
||||
|
||||
//- Transfer contents to the Xfer container
|
||||
Xfer<mapDistributeBase> xfer();
|
||||
|
||||
//- Helper for construct from globalIndex. Renumbers element
|
||||
// (in globalIndex numbering) into compact indices.
|
||||
static label renumber
|
||||
(
|
||||
const globalIndex&,
|
||||
const List<Map<label> >& compactMap,
|
||||
const label globalElement
|
||||
);
|
||||
|
||||
//- Compact maps. Gets per field a bool whether it is used (locally)
|
||||
// and works out itself what this side and sender side can remove
|
||||
// from maps. Only compacts non-local elements (i.e. the stuff
|
||||
// that gets sent over), does not change the local layout
|
||||
void compact
|
||||
(
|
||||
const boolList& elemIsUsed,
|
||||
const int tag = UPstream::msgType()
|
||||
);
|
||||
|
||||
//- Compact all maps and layout. Returns compaction maps for
|
||||
// subMap and constructMap
|
||||
void compact
|
||||
(
|
||||
const boolList& elemIsUsed,
|
||||
const label localSize, // max index for subMap
|
||||
labelList& oldToNewSub,
|
||||
labelList& oldToNewConstruct,
|
||||
const int tag = UPstream::msgType()
|
||||
);
|
||||
|
||||
//- Distribute data. Note:schedule only used for Pstream::scheduled
|
||||
// for now, all others just use send-to-all, receive-from-all.
|
||||
template<class T, class negateOp>
|
||||
static void distribute
|
||||
(
|
||||
const Pstream::commsTypes commsType,
|
||||
const List<labelPair>& schedule,
|
||||
const label constructSize,
|
||||
const labelListList& subMap,
|
||||
const bool subHasFlip,
|
||||
const labelListList& constructMap,
|
||||
const bool constructHasFlip,
|
||||
List<T>&,
|
||||
const negateOp& negOp,
|
||||
const int tag = UPstream::msgType()
|
||||
);
|
||||
|
||||
//- Distribute data. If multiple processors writing to same
|
||||
// position adds contributions using cop.
|
||||
template<class T, class CombineOp, class negateOp>
|
||||
static void distribute
|
||||
(
|
||||
const Pstream::commsTypes commsType,
|
||||
const List<labelPair>& schedule,
|
||||
const label constructSize,
|
||||
const labelListList& subMap,
|
||||
const bool subHasFlip,
|
||||
const labelListList& constructMap,
|
||||
const bool constructHasFlip,
|
||||
List<T>&,
|
||||
const CombineOp& cop,
|
||||
const negateOp& negOp,
|
||||
const T& nullValue,
|
||||
const int tag = UPstream::msgType()
|
||||
);
|
||||
|
||||
//- Distribute data using default commsType.
|
||||
template<class T>
|
||||
void distribute
|
||||
(
|
||||
List<T>& fld,
|
||||
const int tag = UPstream::msgType()
|
||||
) const;
|
||||
|
||||
//- Distribute data using default commsType.
|
||||
template<class T, class negateOp>
|
||||
void distribute
|
||||
(
|
||||
List<T>& fld,
|
||||
const negateOp& negOp,
|
||||
const int tag = UPstream::msgType()
|
||||
) const;
|
||||
|
||||
//- Distribute data using default commsType.
|
||||
template<class T>
|
||||
void distribute
|
||||
(
|
||||
DynamicList<T>& fld,
|
||||
const int tag = UPstream::msgType()
|
||||
) const;
|
||||
|
||||
//- Reverse distribute data using default commsType.
|
||||
template<class T>
|
||||
void reverseDistribute
|
||||
(
|
||||
const label constructSize,
|
||||
List<T>&,
|
||||
const int tag = UPstream::msgType()
|
||||
) const;
|
||||
|
||||
//- Reverse distribute data using default commsType.
|
||||
// Since constructSize might be larger than supplied size supply
|
||||
// a nullValue
|
||||
template<class T>
|
||||
void reverseDistribute
|
||||
(
|
||||
const label constructSize,
|
||||
const T& nullValue,
|
||||
List<T>& fld,
|
||||
const int tag = UPstream::msgType()
|
||||
) const;
|
||||
|
||||
//- Do all sends using PstreamBuffers
|
||||
template<class T>
|
||||
void send(PstreamBuffers&, const List<T>&) const;
|
||||
//- Do all receives using PstreamBuffers
|
||||
template<class T>
|
||||
void receive(PstreamBuffers&, List<T>&) const;
|
||||
|
||||
//- Debug: print layout. Can only be used on maps with sorted
|
||||
// storage (local data first, then non-local data)
|
||||
void printLayout(Ostream& os) const;
|
||||
|
||||
//- Correct for topo change.
|
||||
void updateMesh(const mapPolyMesh&)
|
||||
{
|
||||
notImplemented
|
||||
(
|
||||
"mapDistributeBase::updateMesh(const mapPolyMesh&)"
|
||||
);
|
||||
}
|
||||
|
||||
// Member Operators
|
||||
|
||||
void operator=(const mapDistributeBase&);
|
||||
|
||||
// IOstream operators
|
||||
|
||||
//- Read dictionary from Istream
|
||||
friend Istream& operator>>(Istream&, mapDistributeBase&);
|
||||
|
||||
//- Write dictionary to Ostream
|
||||
friend Ostream& operator<<(Ostream&, const mapDistributeBase&);
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "mapDistributeBaseTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
File diff suppressed because it is too large
Load Diff
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -26,13 +26,14 @@ License
|
||||
#include "mapDistributePolyMesh.H"
|
||||
#include "polyMesh.H"
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::mapDistributePolyMesh::calcPatchSizes()
|
||||
{
|
||||
oldPatchSizes_.setSize(oldPatchStarts_.size());
|
||||
|
||||
if (oldPatchStarts_.size())
|
||||
{
|
||||
// Calculate old patch sizes
|
||||
for (label patchI = 0; patchI < oldPatchStarts_.size() - 1; patchI++)
|
||||
{
|
||||
@ -51,12 +52,27 @@ void Foam::mapDistributePolyMesh::calcPatchSizes()
|
||||
<< "Calculated negative old patch size:" << oldPatchSizes_ << nl
|
||||
<< "Error in mapping data" << abort(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
//- Construct from components
|
||||
Foam::mapDistributePolyMesh::mapDistributePolyMesh()
|
||||
:
|
||||
nOldPoints_(0),
|
||||
nOldFaces_(0),
|
||||
nOldCells_(0),
|
||||
oldPatchSizes_(0),
|
||||
oldPatchStarts_(0),
|
||||
oldPatchNMeshPoints_(0),
|
||||
pointMap_(),
|
||||
faceMap_(),
|
||||
cellMap_(),
|
||||
patchMap_()
|
||||
{}
|
||||
|
||||
|
||||
Foam::mapDistributePolyMesh::mapDistributePolyMesh
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
@ -78,10 +94,12 @@ Foam::mapDistributePolyMesh::mapDistributePolyMesh
|
||||
const Xfer<labelListList>& constructPointMap,
|
||||
const Xfer<labelListList>& constructFaceMap,
|
||||
const Xfer<labelListList>& constructCellMap,
|
||||
const Xfer<labelListList>& constructPatchMap
|
||||
const Xfer<labelListList>& constructPatchMap,
|
||||
|
||||
const bool subFaceHasFlip,
|
||||
const bool constructFaceHasFlip
|
||||
)
|
||||
:
|
||||
mesh_(mesh),
|
||||
nOldPoints_(nOldPoints),
|
||||
nOldFaces_(nOldFaces),
|
||||
nOldCells_(nOldCells),
|
||||
@ -89,7 +107,14 @@ Foam::mapDistributePolyMesh::mapDistributePolyMesh
|
||||
oldPatchStarts_(oldPatchStarts),
|
||||
oldPatchNMeshPoints_(oldPatchNMeshPoints),
|
||||
pointMap_(mesh.nPoints(), subPointMap, constructPointMap),
|
||||
faceMap_(mesh.nFaces(), subFaceMap, constructFaceMap),
|
||||
faceMap_
|
||||
(
|
||||
mesh.nFaces(),
|
||||
subFaceMap,
|
||||
constructFaceMap,
|
||||
subFaceHasFlip,
|
||||
constructFaceHasFlip
|
||||
),
|
||||
cellMap_(mesh.nCells(), subCellMap, constructCellMap),
|
||||
patchMap_(mesh.boundaryMesh().size(), subPatchMap, constructPatchMap)
|
||||
{
|
||||
@ -97,8 +122,84 @@ Foam::mapDistributePolyMesh::mapDistributePolyMesh
|
||||
}
|
||||
|
||||
|
||||
Foam::mapDistributePolyMesh::mapDistributePolyMesh
|
||||
(
|
||||
// mesh before changes
|
||||
const label nOldPoints,
|
||||
const label nOldFaces,
|
||||
const label nOldCells,
|
||||
const Xfer<labelList>& oldPatchStarts,
|
||||
const Xfer<labelList>& oldPatchNMeshPoints,
|
||||
|
||||
// how to transfer pieces of mesh
|
||||
const Xfer<mapDistribute>& pointMap,
|
||||
const Xfer<mapDistribute>& faceMap,
|
||||
const Xfer<mapDistribute>& cellMap,
|
||||
const Xfer<mapDistribute>& patchMap
|
||||
)
|
||||
:
|
||||
nOldPoints_(nOldPoints),
|
||||
nOldFaces_(nOldFaces),
|
||||
nOldCells_(nOldCells),
|
||||
oldPatchSizes_(oldPatchStarts().size()),
|
||||
oldPatchStarts_(oldPatchStarts),
|
||||
oldPatchNMeshPoints_(oldPatchNMeshPoints),
|
||||
pointMap_(pointMap),
|
||||
faceMap_(faceMap),
|
||||
cellMap_(cellMap),
|
||||
patchMap_(patchMap)
|
||||
{
|
||||
calcPatchSizes();
|
||||
}
|
||||
|
||||
|
||||
Foam::mapDistributePolyMesh::mapDistributePolyMesh
|
||||
(
|
||||
const Xfer<mapDistributePolyMesh>& map
|
||||
)
|
||||
:
|
||||
nOldPoints_(map().nOldPoints_),
|
||||
nOldFaces_(map().nOldFaces_),
|
||||
nOldCells_(map().nOldCells_),
|
||||
oldPatchSizes_(map().oldPatchSizes_.xfer()),
|
||||
oldPatchStarts_(map().oldPatchStarts_.xfer()),
|
||||
oldPatchNMeshPoints_(map().oldPatchNMeshPoints_.xfer()),
|
||||
pointMap_(map().pointMap_.xfer()),
|
||||
faceMap_(map().faceMap_.xfer()),
|
||||
cellMap_(map().cellMap_.xfer()),
|
||||
patchMap_(map().patchMap_.xfer())
|
||||
{}
|
||||
|
||||
|
||||
Foam::mapDistributePolyMesh::mapDistributePolyMesh(Istream& is)
|
||||
{
|
||||
is >> *this;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::mapDistributePolyMesh::transfer(mapDistributePolyMesh& rhs)
|
||||
{
|
||||
nOldPoints_ = rhs.nOldPoints_;
|
||||
nOldFaces_ = rhs.nOldFaces_;
|
||||
nOldCells_ = rhs.nOldCells_;
|
||||
oldPatchSizes_.transfer(rhs.oldPatchSizes_);
|
||||
oldPatchStarts_.transfer(rhs.oldPatchStarts_);
|
||||
oldPatchNMeshPoints_.transfer(rhs.oldPatchNMeshPoints_);
|
||||
pointMap_.transfer(rhs.pointMap_);
|
||||
faceMap_.transfer(rhs.faceMap_);
|
||||
cellMap_.transfer(rhs.cellMap_);
|
||||
patchMap_.transfer(rhs.patchMap_);
|
||||
}
|
||||
|
||||
|
||||
Foam::Xfer<Foam::mapDistributePolyMesh> Foam::mapDistributePolyMesh::xfer()
|
||||
{
|
||||
return xferMove(*this);
|
||||
}
|
||||
|
||||
|
||||
void Foam::mapDistributePolyMesh::distributePointIndices(labelList& lst) const
|
||||
{
|
||||
// Construct boolList from selected elements
|
||||
@ -187,10 +288,61 @@ void Foam::mapDistributePolyMesh::distributePatchIndices(labelList& lst) const
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::mapDistributePolyMesh::operator=(const mapDistributePolyMesh& rhs)
|
||||
{
|
||||
nOldPoints_ = rhs.nOldPoints_;
|
||||
nOldFaces_ = rhs.nOldFaces_;
|
||||
nOldCells_ = rhs.nOldCells_;
|
||||
oldPatchSizes_ = rhs.oldPatchSizes_;
|
||||
oldPatchStarts_ = rhs.oldPatchStarts_;
|
||||
oldPatchNMeshPoints_ = rhs.oldPatchNMeshPoints_;
|
||||
pointMap_ = rhs.pointMap_;
|
||||
faceMap_ = rhs.faceMap_;
|
||||
cellMap_ = rhs.cellMap_;
|
||||
patchMap_ = rhs.patchMap_;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * Istream Operator * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::Istream& Foam::operator>>(Istream& is, mapDistributePolyMesh& map)
|
||||
{
|
||||
is.fatalCheck("operator>>(Istream&, mapDistributePolyMesh&)");
|
||||
|
||||
is >> map.nOldPoints_
|
||||
>> map.nOldFaces_
|
||||
>> map.nOldCells_
|
||||
>> map.oldPatchSizes_
|
||||
>> map.oldPatchStarts_
|
||||
>> map.oldPatchNMeshPoints_
|
||||
>> map.pointMap_
|
||||
>> map.faceMap_
|
||||
>> map.cellMap_
|
||||
>> map.patchMap_;
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::Ostream& Foam::operator<<(Ostream& os, const mapDistributePolyMesh& map)
|
||||
{
|
||||
os << map.nOldPoints_
|
||||
<< token::SPACE << map.nOldFaces_
|
||||
<< token::SPACE << map.nOldCells_ << token::NL
|
||||
<< map.oldPatchSizes_ << token::NL
|
||||
<< map.oldPatchStarts_ << token::NL
|
||||
<< map.oldPatchNMeshPoints_ << token::NL
|
||||
<< map.pointMap_ << token::NL
|
||||
<< map.faceMap_ << token::NL
|
||||
<< map.cellMap_ << token::NL
|
||||
<< map.patchMap_;
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -59,39 +59,36 @@ class mapDistributePolyMesh
|
||||
{
|
||||
// Private data
|
||||
|
||||
const polyMesh& mesh_;
|
||||
|
||||
//- Number of old live points
|
||||
const label nOldPoints_;
|
||||
label nOldPoints_;
|
||||
|
||||
//- Number of old live faces
|
||||
const label nOldFaces_;
|
||||
label nOldFaces_;
|
||||
|
||||
//- Number of old live cells
|
||||
const label nOldCells_;
|
||||
label nOldCells_;
|
||||
|
||||
//- List of the old patch sizes
|
||||
labelList oldPatchSizes_;
|
||||
|
||||
//- List of the old patch start labels
|
||||
const labelList oldPatchStarts_;
|
||||
labelList oldPatchStarts_;
|
||||
|
||||
//- List of numbers of mesh points per old patch
|
||||
const labelList oldPatchNMeshPoints_;
|
||||
labelList oldPatchNMeshPoints_;
|
||||
|
||||
|
||||
//- Point distribute map
|
||||
const mapDistribute pointMap_;
|
||||
mapDistribute pointMap_;
|
||||
|
||||
//- Face distribute map
|
||||
const mapDistribute faceMap_;
|
||||
mapDistribute faceMap_;
|
||||
|
||||
//- Cell distribute map
|
||||
const mapDistribute cellMap_;
|
||||
mapDistribute cellMap_;
|
||||
|
||||
//- Patch distribute map
|
||||
const mapDistribute patchMap_;
|
||||
|
||||
mapDistribute patchMap_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
@ -101,14 +98,14 @@ class mapDistributePolyMesh
|
||||
//- Disallow default bitwise copy construct
|
||||
mapDistributePolyMesh(const mapDistributePolyMesh&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const mapDistributePolyMesh&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
mapDistributePolyMesh();
|
||||
|
||||
//- Construct from components. Note that mesh has to be changed already
|
||||
// since uses mesh.nPoints etc as the new size.
|
||||
mapDistributePolyMesh
|
||||
@ -132,19 +129,40 @@ public:
|
||||
const Xfer<labelListList>& constructPointMap,
|
||||
const Xfer<labelListList>& constructFaceMap,
|
||||
const Xfer<labelListList>& constructCellMap,
|
||||
const Xfer<labelListList>& constructPatchMap
|
||||
const Xfer<labelListList>& constructPatchMap,
|
||||
|
||||
const bool subFaceHasFlip = false,
|
||||
const bool constructFaceHasFlip = false
|
||||
);
|
||||
|
||||
//- Construct from components
|
||||
mapDistributePolyMesh
|
||||
(
|
||||
// mesh before changes
|
||||
const label nOldPoints,
|
||||
const label nOldFaces,
|
||||
const label nOldCells,
|
||||
const Xfer<labelList>& oldPatchStarts,
|
||||
const Xfer<labelList>& oldPatchNMeshPoints,
|
||||
|
||||
// how to subset pieces of mesh to send across
|
||||
const Xfer<mapDistribute>& pointMap,
|
||||
const Xfer<mapDistribute>& faceMap,
|
||||
const Xfer<mapDistribute>& cellMap,
|
||||
const Xfer<mapDistribute>& patchMap
|
||||
);
|
||||
|
||||
//- Construct by transferring parameter content
|
||||
mapDistributePolyMesh(const Xfer<mapDistributePolyMesh>&);
|
||||
|
||||
//- Construct from Istream
|
||||
mapDistributePolyMesh(Istream&);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
const polyMesh& mesh() const
|
||||
{
|
||||
return mesh_;
|
||||
}
|
||||
|
||||
//- Number of points in mesh before distribution
|
||||
label nOldPoints() const
|
||||
{
|
||||
@ -206,7 +224,13 @@ public:
|
||||
}
|
||||
|
||||
|
||||
// Edit
|
||||
// Other
|
||||
|
||||
//- Transfer the contents of the argument and annul the argument.
|
||||
void transfer(mapDistributePolyMesh&);
|
||||
|
||||
//- Transfer contents to the Xfer container
|
||||
Xfer<mapDistributePolyMesh> xfer();
|
||||
|
||||
//- Distribute list of point data
|
||||
template<class T>
|
||||
@ -254,6 +278,19 @@ public:
|
||||
"mapDistributePolyMesh::updateMesh(const mapPolyMesh&)"
|
||||
);
|
||||
}
|
||||
|
||||
// Member operators
|
||||
|
||||
void operator=(const mapDistributePolyMesh&);
|
||||
|
||||
|
||||
// IOstream operators
|
||||
|
||||
//- Read dictionary from Istream
|
||||
friend Istream& operator>>(Istream&, mapDistributePolyMesh&);
|
||||
|
||||
//- Write dictionary to Ostream
|
||||
friend Ostream& operator<<(Ostream&, const mapDistributePolyMesh&);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -28,768 +28,10 @@ License
|
||||
#include "PstreamCombineReduceOps.H"
|
||||
#include "globalIndexAndTransform.H"
|
||||
#include "transformField.H"
|
||||
#include "flipOp.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
// Distribute list.
|
||||
template<class T>
|
||||
void Foam::mapDistribute::distribute
|
||||
(
|
||||
const Pstream::commsTypes commsType,
|
||||
const List<labelPair>& schedule,
|
||||
const label constructSize,
|
||||
const labelListList& subMap,
|
||||
const labelListList& constructMap,
|
||||
List<T>& field,
|
||||
const int tag
|
||||
)
|
||||
{
|
||||
if (!Pstream::parRun())
|
||||
{
|
||||
// Do only me to me.
|
||||
|
||||
const labelList& mySubMap = subMap[Pstream::myProcNo()];
|
||||
|
||||
List<T> subField(mySubMap.size());
|
||||
forAll(mySubMap, i)
|
||||
{
|
||||
subField[i] = field[mySubMap[i]];
|
||||
}
|
||||
|
||||
// Receive sub field from myself (subField)
|
||||
const labelList& map = constructMap[Pstream::myProcNo()];
|
||||
|
||||
field.setSize(constructSize);
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
field[map[i]] = subField[i];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (commsType == Pstream::blocking)
|
||||
{
|
||||
// Since buffered sending can reuse the field to collect the
|
||||
// received data.
|
||||
|
||||
// Send sub field to neighbour
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
{
|
||||
const labelList& map = subMap[domain];
|
||||
|
||||
if (domain != Pstream::myProcNo() && map.size())
|
||||
{
|
||||
OPstream toNbr(Pstream::blocking, domain, 0, tag);
|
||||
toNbr << UIndirectList<T>(field, map);
|
||||
}
|
||||
}
|
||||
|
||||
// Subset myself
|
||||
const labelList& mySubMap = subMap[Pstream::myProcNo()];
|
||||
|
||||
List<T> subField(mySubMap.size());
|
||||
forAll(mySubMap, i)
|
||||
{
|
||||
subField[i] = field[mySubMap[i]];
|
||||
}
|
||||
|
||||
// Receive sub field from myself (subField)
|
||||
const labelList& map = constructMap[Pstream::myProcNo()];
|
||||
|
||||
field.setSize(constructSize);
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
field[map[i]] = subField[i];
|
||||
}
|
||||
|
||||
// Receive sub field from neighbour
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
{
|
||||
const labelList& map = constructMap[domain];
|
||||
|
||||
if (domain != Pstream::myProcNo() && map.size())
|
||||
{
|
||||
IPstream fromNbr(Pstream::blocking, domain, 0, tag);
|
||||
List<T> subField(fromNbr);
|
||||
|
||||
checkReceivedSize(domain, map.size(), subField.size());
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
field[map[i]] = subField[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (commsType == Pstream::scheduled)
|
||||
{
|
||||
// Need to make sure I don't overwrite field with received data
|
||||
// since the data might need to be sent to another processor. So
|
||||
// allocate a new field for the results.
|
||||
List<T> newField(constructSize);
|
||||
|
||||
// Subset myself
|
||||
UIndirectList<T> subField(field, subMap[Pstream::myProcNo()]);
|
||||
|
||||
// Receive sub field from myself (subField)
|
||||
const labelList& map = constructMap[Pstream::myProcNo()];
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
newField[map[i]] = subField[i];
|
||||
}
|
||||
|
||||
// Schedule will already have pruned 0-sized comms
|
||||
forAll(schedule, i)
|
||||
{
|
||||
const labelPair& twoProcs = schedule[i];
|
||||
// twoProcs is a swap pair of processors. The first one is the
|
||||
// one that needs to send first and then receive.
|
||||
|
||||
label sendProc = twoProcs[0];
|
||||
label recvProc = twoProcs[1];
|
||||
|
||||
if (Pstream::myProcNo() == sendProc)
|
||||
{
|
||||
// I am send first, receive next
|
||||
{
|
||||
OPstream toNbr(Pstream::scheduled, recvProc, 0, tag);
|
||||
toNbr << UIndirectList<T>(field, subMap[recvProc]);
|
||||
}
|
||||
{
|
||||
IPstream fromNbr(Pstream::scheduled, recvProc, 0, tag);
|
||||
List<T> subField(fromNbr);
|
||||
|
||||
const labelList& map = constructMap[recvProc];
|
||||
|
||||
checkReceivedSize(recvProc, map.size(), subField.size());
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
newField[map[i]] = subField[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// I am receive first, send next
|
||||
{
|
||||
IPstream fromNbr(Pstream::scheduled, sendProc, 0, tag);
|
||||
List<T> subField(fromNbr);
|
||||
|
||||
const labelList& map = constructMap[sendProc];
|
||||
|
||||
checkReceivedSize(sendProc, map.size(), subField.size());
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
newField[map[i]] = subField[i];
|
||||
}
|
||||
}
|
||||
{
|
||||
OPstream toNbr(Pstream::scheduled, sendProc, 0, tag);
|
||||
toNbr << UIndirectList<T>(field, subMap[sendProc]);
|
||||
}
|
||||
}
|
||||
}
|
||||
field.transfer(newField);
|
||||
}
|
||||
else if (commsType == Pstream::nonBlocking)
|
||||
{
|
||||
label nOutstanding = Pstream::nRequests();
|
||||
|
||||
if (!contiguous<T>())
|
||||
{
|
||||
PstreamBuffers pBufs(Pstream::nonBlocking, tag);
|
||||
|
||||
// Stream data into buffer
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
{
|
||||
const labelList& map = subMap[domain];
|
||||
|
||||
if (domain != Pstream::myProcNo() && map.size())
|
||||
{
|
||||
// Put data into send buffer
|
||||
UOPstream toDomain(domain, pBufs);
|
||||
toDomain << UIndirectList<T>(field, map);
|
||||
}
|
||||
}
|
||||
|
||||
// Start receiving. Do not block.
|
||||
pBufs.finishedSends(false);
|
||||
|
||||
{
|
||||
// Set up 'send' to myself
|
||||
const labelList& mySubMap = subMap[Pstream::myProcNo()];
|
||||
List<T> mySubField(mySubMap.size());
|
||||
forAll(mySubMap, i)
|
||||
{
|
||||
mySubField[i] = field[mySubMap[i]];
|
||||
}
|
||||
// Combine bits. Note that can reuse field storage
|
||||
field.setSize(constructSize);
|
||||
// Receive sub field from myself
|
||||
{
|
||||
const labelList& map = constructMap[Pstream::myProcNo()];
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
field[map[i]] = mySubField[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Block ourselves, waiting only for the current comms
|
||||
Pstream::waitRequests(nOutstanding);
|
||||
|
||||
// Consume
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
{
|
||||
const labelList& map = constructMap[domain];
|
||||
|
||||
if (domain != Pstream::myProcNo() && map.size())
|
||||
{
|
||||
UIPstream str(domain, pBufs);
|
||||
List<T> recvField(str);
|
||||
|
||||
checkReceivedSize(domain, map.size(), recvField.size());
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
field[map[i]] = recvField[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set up sends to neighbours
|
||||
|
||||
List<List<T > > sendFields(Pstream::nProcs());
|
||||
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
{
|
||||
const labelList& map = subMap[domain];
|
||||
|
||||
if (domain != Pstream::myProcNo() && map.size())
|
||||
{
|
||||
List<T>& subField = sendFields[domain];
|
||||
subField.setSize(map.size());
|
||||
forAll(map, i)
|
||||
{
|
||||
subField[i] = field[map[i]];
|
||||
}
|
||||
|
||||
OPstream::write
|
||||
(
|
||||
Pstream::nonBlocking,
|
||||
domain,
|
||||
reinterpret_cast<const char*>(subField.begin()),
|
||||
subField.byteSize(),
|
||||
tag
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Set up receives from neighbours
|
||||
|
||||
List<List<T > > recvFields(Pstream::nProcs());
|
||||
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
{
|
||||
const labelList& map = constructMap[domain];
|
||||
|
||||
if (domain != Pstream::myProcNo() && map.size())
|
||||
{
|
||||
recvFields[domain].setSize(map.size());
|
||||
IPstream::read
|
||||
(
|
||||
Pstream::nonBlocking,
|
||||
domain,
|
||||
reinterpret_cast<char*>(recvFields[domain].begin()),
|
||||
recvFields[domain].byteSize(),
|
||||
tag
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Set up 'send' to myself
|
||||
|
||||
{
|
||||
const labelList& map = subMap[Pstream::myProcNo()];
|
||||
|
||||
List<T>& subField = sendFields[Pstream::myProcNo()];
|
||||
subField.setSize(map.size());
|
||||
forAll(map, i)
|
||||
{
|
||||
subField[i] = field[map[i]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Combine bits. Note that can reuse field storage
|
||||
|
||||
field.setSize(constructSize);
|
||||
|
||||
|
||||
// Receive sub field from myself (sendFields[Pstream::myProcNo()])
|
||||
{
|
||||
const labelList& map = constructMap[Pstream::myProcNo()];
|
||||
const List<T>& subField = sendFields[Pstream::myProcNo()];
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
field[map[i]] = subField[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Wait for all to finish
|
||||
|
||||
Pstream::waitRequests(nOutstanding);
|
||||
|
||||
|
||||
// Collect neighbour fields
|
||||
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
{
|
||||
const labelList& map = constructMap[domain];
|
||||
|
||||
if (domain != Pstream::myProcNo() && map.size())
|
||||
{
|
||||
const List<T>& subField = recvFields[domain];
|
||||
|
||||
checkReceivedSize(domain, map.size(), subField.size());
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
field[map[i]] = subField[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn("mapDistribute::distribute(..)")
|
||||
<< "Unknown communication schedule " << commsType
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Distribute list.
|
||||
template<class T, class CombineOp>
|
||||
void Foam::mapDistribute::distribute
|
||||
(
|
||||
const Pstream::commsTypes commsType,
|
||||
const List<labelPair>& schedule,
|
||||
const label constructSize,
|
||||
const labelListList& subMap,
|
||||
const labelListList& constructMap,
|
||||
List<T>& field,
|
||||
const CombineOp& cop,
|
||||
const T& nullValue,
|
||||
const int tag
|
||||
)
|
||||
{
|
||||
if (!Pstream::parRun())
|
||||
{
|
||||
// Do only me to me.
|
||||
|
||||
const labelList& mySubMap = subMap[Pstream::myProcNo()];
|
||||
|
||||
List<T> subField(mySubMap.size());
|
||||
forAll(mySubMap, i)
|
||||
{
|
||||
subField[i] = field[mySubMap[i]];
|
||||
}
|
||||
|
||||
// Receive sub field from myself (subField)
|
||||
const labelList& map = constructMap[Pstream::myProcNo()];
|
||||
|
||||
field.setSize(constructSize);
|
||||
field = nullValue;
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
cop(field[map[i]], subField[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (commsType == Pstream::blocking)
|
||||
{
|
||||
// Since buffered sending can reuse the field to collect the
|
||||
// received data.
|
||||
|
||||
// Send sub field to neighbour
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
{
|
||||
const labelList& map = subMap[domain];
|
||||
|
||||
if (domain != Pstream::myProcNo() && map.size())
|
||||
{
|
||||
OPstream toNbr(Pstream::blocking, domain, 0, tag);
|
||||
toNbr << UIndirectList<T>(field, map);
|
||||
}
|
||||
}
|
||||
|
||||
// Subset myself
|
||||
const labelList& mySubMap = subMap[Pstream::myProcNo()];
|
||||
|
||||
List<T> subField(mySubMap.size());
|
||||
forAll(mySubMap, i)
|
||||
{
|
||||
subField[i] = field[mySubMap[i]];
|
||||
}
|
||||
|
||||
// Receive sub field from myself (subField)
|
||||
const labelList& map = constructMap[Pstream::myProcNo()];
|
||||
|
||||
field.setSize(constructSize);
|
||||
field = nullValue;
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
cop(field[map[i]], subField[i]);
|
||||
}
|
||||
|
||||
// Receive sub field from neighbour
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
{
|
||||
const labelList& map = constructMap[domain];
|
||||
|
||||
if (domain != Pstream::myProcNo() && map.size())
|
||||
{
|
||||
IPstream fromNbr(Pstream::blocking, domain, 0, tag);
|
||||
List<T> subField(fromNbr);
|
||||
|
||||
checkReceivedSize(domain, map.size(), subField.size());
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
cop(field[map[i]], subField[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (commsType == Pstream::scheduled)
|
||||
{
|
||||
// Need to make sure I don't overwrite field with received data
|
||||
// since the data might need to be sent to another processor. So
|
||||
// allocate a new field for the results.
|
||||
List<T> newField(constructSize, nullValue);
|
||||
|
||||
// Subset myself
|
||||
UIndirectList<T> subField(field, subMap[Pstream::myProcNo()]);
|
||||
|
||||
// Receive sub field from myself (subField)
|
||||
const labelList& map = constructMap[Pstream::myProcNo()];
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
cop(newField[map[i]], subField[i]);
|
||||
}
|
||||
|
||||
// Schedule will already have pruned 0-sized comms
|
||||
forAll(schedule, i)
|
||||
{
|
||||
const labelPair& twoProcs = schedule[i];
|
||||
// twoProcs is a swap pair of processors. The first one is the
|
||||
// one that needs to send first and then receive.
|
||||
|
||||
label sendProc = twoProcs[0];
|
||||
label recvProc = twoProcs[1];
|
||||
|
||||
if (Pstream::myProcNo() == sendProc)
|
||||
{
|
||||
// I am send first, receive next
|
||||
{
|
||||
OPstream toNbr(Pstream::scheduled, recvProc, 0, tag);
|
||||
toNbr << UIndirectList<T>(field, subMap[recvProc]);
|
||||
}
|
||||
{
|
||||
IPstream fromNbr(Pstream::scheduled, recvProc, 0, tag);
|
||||
List<T> subField(fromNbr);
|
||||
const labelList& map = constructMap[recvProc];
|
||||
|
||||
checkReceivedSize(recvProc, map.size(), subField.size());
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
cop(newField[map[i]], subField[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// I am receive first, send next
|
||||
{
|
||||
IPstream fromNbr(Pstream::scheduled, sendProc, 0, tag);
|
||||
List<T> subField(fromNbr);
|
||||
const labelList& map = constructMap[sendProc];
|
||||
|
||||
checkReceivedSize(sendProc, map.size(), subField.size());
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
cop(newField[map[i]], subField[i]);
|
||||
}
|
||||
}
|
||||
{
|
||||
OPstream toNbr(Pstream::scheduled, sendProc, 0, tag);
|
||||
toNbr << UIndirectList<T>(field, subMap[sendProc]);
|
||||
}
|
||||
}
|
||||
}
|
||||
field.transfer(newField);
|
||||
}
|
||||
else if (commsType == Pstream::nonBlocking)
|
||||
{
|
||||
label nOutstanding = Pstream::nRequests();
|
||||
|
||||
if (!contiguous<T>())
|
||||
{
|
||||
PstreamBuffers pBufs(Pstream::nonBlocking, tag);
|
||||
|
||||
// Stream data into buffer
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
{
|
||||
const labelList& map = subMap[domain];
|
||||
|
||||
if (domain != Pstream::myProcNo() && map.size())
|
||||
{
|
||||
// Put data into send buffer
|
||||
UOPstream toDomain(domain, pBufs);
|
||||
toDomain << UIndirectList<T>(field, map);
|
||||
}
|
||||
}
|
||||
|
||||
// Start receiving. Do not block.
|
||||
pBufs.finishedSends(false);
|
||||
|
||||
{
|
||||
// Set up 'send' to myself
|
||||
List<T> mySubField(field, subMap[Pstream::myProcNo()]);
|
||||
// Combine bits. Note that can reuse field storage
|
||||
field.setSize(constructSize);
|
||||
field = nullValue;
|
||||
// Receive sub field from myself
|
||||
{
|
||||
const labelList& map = constructMap[Pstream::myProcNo()];
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
cop(field[map[i]], mySubField[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Block ourselves, waiting only for the current comms
|
||||
Pstream::waitRequests(nOutstanding);
|
||||
|
||||
// Consume
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
{
|
||||
const labelList& map = constructMap[domain];
|
||||
|
||||
if (domain != Pstream::myProcNo() && map.size())
|
||||
{
|
||||
UIPstream str(domain, pBufs);
|
||||
List<T> recvField(str);
|
||||
|
||||
checkReceivedSize(domain, map.size(), recvField.size());
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
cop(field[map[i]], recvField[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set up sends to neighbours
|
||||
|
||||
List<List<T > > sendFields(Pstream::nProcs());
|
||||
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
{
|
||||
const labelList& map = subMap[domain];
|
||||
|
||||
if (domain != Pstream::myProcNo() && map.size())
|
||||
{
|
||||
List<T>& subField = sendFields[domain];
|
||||
subField.setSize(map.size());
|
||||
forAll(map, i)
|
||||
{
|
||||
subField[i] = field[map[i]];
|
||||
}
|
||||
|
||||
OPstream::write
|
||||
(
|
||||
Pstream::nonBlocking,
|
||||
domain,
|
||||
reinterpret_cast<const char*>(subField.begin()),
|
||||
subField.size()*sizeof(T),
|
||||
tag
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Set up receives from neighbours
|
||||
|
||||
List<List<T > > recvFields(Pstream::nProcs());
|
||||
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
{
|
||||
const labelList& map = constructMap[domain];
|
||||
|
||||
if (domain != Pstream::myProcNo() && map.size())
|
||||
{
|
||||
recvFields[domain].setSize(map.size());
|
||||
UIPstream::read
|
||||
(
|
||||
Pstream::nonBlocking,
|
||||
domain,
|
||||
reinterpret_cast<char*>(recvFields[domain].begin()),
|
||||
recvFields[domain].size()*sizeof(T),
|
||||
tag
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Set up 'send' to myself
|
||||
|
||||
{
|
||||
const labelList& map = subMap[Pstream::myProcNo()];
|
||||
|
||||
List<T>& subField = sendFields[Pstream::myProcNo()];
|
||||
subField.setSize(map.size());
|
||||
forAll(map, i)
|
||||
{
|
||||
subField[i] = field[map[i]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Combine bits. Note that can reuse field storage
|
||||
|
||||
field.setSize(constructSize);
|
||||
field = nullValue;
|
||||
|
||||
// Receive sub field from myself (subField)
|
||||
{
|
||||
const labelList& map = constructMap[Pstream::myProcNo()];
|
||||
const List<T>& subField = sendFields[Pstream::myProcNo()];
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
cop(field[map[i]], subField[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Wait for all to finish
|
||||
|
||||
Pstream::waitRequests(nOutstanding);
|
||||
|
||||
|
||||
// Collect neighbour fields
|
||||
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
{
|
||||
const labelList& map = constructMap[domain];
|
||||
|
||||
if (domain != Pstream::myProcNo() && map.size())
|
||||
{
|
||||
const List<T>& subField = recvFields[domain];
|
||||
|
||||
checkReceivedSize(domain, map.size(), subField.size());
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
cop(field[map[i]], subField[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn("mapDistribute::distribute(..)")
|
||||
<< "Unknown communication schedule " << commsType
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void Foam::mapDistribute::send(PstreamBuffers& pBufs, const List<T>& field)
|
||||
const
|
||||
{
|
||||
// Stream data into buffer
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
{
|
||||
const labelList& map = subMap_[domain];
|
||||
|
||||
if (map.size())
|
||||
{
|
||||
// Put data into send buffer
|
||||
UOPstream toDomain(domain, pBufs);
|
||||
toDomain << UIndirectList<T>(field, map);
|
||||
}
|
||||
}
|
||||
|
||||
// Start sending and receiving but do not block.
|
||||
pBufs.finishedSends(false);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void Foam::mapDistribute::receive(PstreamBuffers& pBufs, List<T>& field) const
|
||||
{
|
||||
// Consume
|
||||
field.setSize(constructSize_);
|
||||
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
{
|
||||
const labelList& map = constructMap_[domain];
|
||||
|
||||
if (map.size())
|
||||
{
|
||||
UIPstream str(domain, pBufs);
|
||||
List<T> recvField(str);
|
||||
|
||||
if (recvField.size() != map.size())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"template<class T>\n"
|
||||
"void mapDistribute::receive\n"
|
||||
"(\n"
|
||||
" PstreamBuffers&,\n"
|
||||
" List<T>&\n"
|
||||
")\n"
|
||||
) << "Expected from processor " << domain
|
||||
<< " " << map.size() << " but received "
|
||||
<< recvField.size() << " elements."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
forAll(map, i)
|
||||
{
|
||||
field[map[i]] = recvField[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// In case of no transform: copy elements
|
||||
template<class T>
|
||||
void Foam::mapDistribute::applyDummyTransforms(List<T>& field) const
|
||||
@ -887,6 +129,39 @@ void Foam::mapDistribute::applyInverseTransforms
|
||||
}
|
||||
|
||||
|
||||
//- Distribute data using default commsType.
|
||||
template<class T, class negateOp>
|
||||
void Foam::mapDistribute::distribute
|
||||
(
|
||||
List<T>& fld,
|
||||
const negateOp& negOp,
|
||||
const bool dummyTransform,
|
||||
const int tag
|
||||
) const
|
||||
{
|
||||
mapDistributeBase::distribute(fld, negOp, tag);
|
||||
|
||||
//- Fill in transformed slots with copies
|
||||
if (dummyTransform)
|
||||
{
|
||||
applyDummyTransforms(fld);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//- Distribute data using default commsType.
|
||||
template<class T>
|
||||
void Foam::mapDistribute::distribute
|
||||
(
|
||||
List<T>& fld,
|
||||
const bool dummyTransform,
|
||||
const int tag
|
||||
) const
|
||||
{
|
||||
distribute(fld, flipOp(), dummyTransform, tag);
|
||||
}
|
||||
|
||||
|
||||
//- Distribute data using default commsType.
|
||||
template<class T>
|
||||
void Foam::mapDistribute::distribute
|
||||
@ -906,63 +181,6 @@ void Foam::mapDistribute::distribute
|
||||
}
|
||||
|
||||
|
||||
//- Distribute data using default commsType.
|
||||
template<class T>
|
||||
void Foam::mapDistribute::distribute
|
||||
(
|
||||
List<T>& fld,
|
||||
const bool dummyTransform,
|
||||
const int tag
|
||||
) const
|
||||
{
|
||||
if (Pstream::defaultCommsType == Pstream::nonBlocking)
|
||||
{
|
||||
distribute
|
||||
(
|
||||
Pstream::nonBlocking,
|
||||
List<labelPair>(),
|
||||
constructSize_,
|
||||
subMap_,
|
||||
constructMap_,
|
||||
fld,
|
||||
tag
|
||||
);
|
||||
}
|
||||
else if (Pstream::defaultCommsType == Pstream::scheduled)
|
||||
{
|
||||
distribute
|
||||
(
|
||||
Pstream::scheduled,
|
||||
schedule(),
|
||||
constructSize_,
|
||||
subMap_,
|
||||
constructMap_,
|
||||
fld,
|
||||
tag
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
distribute
|
||||
(
|
||||
Pstream::blocking,
|
||||
List<labelPair>(),
|
||||
constructSize_,
|
||||
subMap_,
|
||||
constructMap_,
|
||||
fld,
|
||||
tag
|
||||
);
|
||||
}
|
||||
|
||||
//- Fill in transformed slots with copies
|
||||
if (dummyTransform)
|
||||
{
|
||||
applyDummyTransforms(fld);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//- Reverse distribute data using default commsType.
|
||||
template<class T>
|
||||
void Foam::mapDistribute::reverseDistribute
|
||||
@ -978,45 +196,7 @@ void Foam::mapDistribute::reverseDistribute
|
||||
applyDummyInverseTransforms(fld);
|
||||
}
|
||||
|
||||
if (Pstream::defaultCommsType == Pstream::nonBlocking)
|
||||
{
|
||||
distribute
|
||||
(
|
||||
Pstream::nonBlocking,
|
||||
List<labelPair>(),
|
||||
constructSize,
|
||||
constructMap_,
|
||||
subMap_,
|
||||
fld,
|
||||
tag
|
||||
);
|
||||
}
|
||||
else if (Pstream::defaultCommsType == Pstream::scheduled)
|
||||
{
|
||||
distribute
|
||||
(
|
||||
Pstream::scheduled,
|
||||
schedule(),
|
||||
constructSize,
|
||||
constructMap_,
|
||||
subMap_,
|
||||
fld,
|
||||
tag
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
distribute
|
||||
(
|
||||
Pstream::blocking,
|
||||
List<labelPair>(),
|
||||
constructSize,
|
||||
constructMap_,
|
||||
subMap_,
|
||||
fld,
|
||||
tag
|
||||
);
|
||||
}
|
||||
mapDistributeBase::reverseDistribute(constructSize, fld, tag);
|
||||
}
|
||||
|
||||
|
||||
@ -1038,51 +218,7 @@ void Foam::mapDistribute::reverseDistribute
|
||||
applyDummyInverseTransforms(fld);
|
||||
}
|
||||
|
||||
if (Pstream::defaultCommsType == Pstream::nonBlocking)
|
||||
{
|
||||
distribute
|
||||
(
|
||||
Pstream::nonBlocking,
|
||||
List<labelPair>(),
|
||||
constructSize,
|
||||
constructMap_,
|
||||
subMap_,
|
||||
fld,
|
||||
eqOp<T>(),
|
||||
nullValue,
|
||||
tag
|
||||
);
|
||||
}
|
||||
else if (Pstream::defaultCommsType == Pstream::scheduled)
|
||||
{
|
||||
distribute
|
||||
(
|
||||
Pstream::scheduled,
|
||||
schedule(),
|
||||
constructSize,
|
||||
constructMap_,
|
||||
subMap_,
|
||||
fld,
|
||||
eqOp<T>(),
|
||||
nullValue,
|
||||
tag
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
distribute
|
||||
(
|
||||
Pstream::blocking,
|
||||
List<labelPair>(),
|
||||
constructSize,
|
||||
constructMap_,
|
||||
subMap_,
|
||||
fld,
|
||||
eqOp<T>(),
|
||||
nullValue,
|
||||
tag
|
||||
);
|
||||
}
|
||||
mapDistributeBase::reverseDistribute(constructSize, nullValue, fld, tag);
|
||||
}
|
||||
|
||||
|
||||
|
||||
100
src/OpenFOAM/meshes/primitiveShapes/triangle/triPoints.H
Normal file
100
src/OpenFOAM/meshes/primitiveShapes/triangle/triPoints.H
Normal file
@ -0,0 +1,100 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::triPoints
|
||||
|
||||
Description
|
||||
Triangle storage. Null constructable (unfortunately triangle<point, point>
|
||||
is not)
|
||||
|
||||
SourceFiles
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef triPoints_H
|
||||
#define triPoints_H
|
||||
|
||||
#include "FixedList.H"
|
||||
#include "treeBoundBox.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class triPoints Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class triPoints
|
||||
:
|
||||
public FixedList<point, 3>
|
||||
{
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
inline triPoints()
|
||||
{}
|
||||
|
||||
//- Construct from points
|
||||
inline triPoints
|
||||
(
|
||||
const point& a,
|
||||
const point& b,
|
||||
const point& c
|
||||
)
|
||||
{
|
||||
operator[](0) = a;
|
||||
operator[](1) = b;
|
||||
operator[](2) = c;
|
||||
}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Calculate the bounding box
|
||||
inline treeBoundBox bounds() const
|
||||
{
|
||||
treeBoundBox bb(operator[](0), operator[](0));
|
||||
for (label i = 1; i < size(); i++)
|
||||
{
|
||||
bb.min() = min(bb.min(), operator[](i));
|
||||
bb.max() = max(bb.max(), operator[](i));
|
||||
}
|
||||
return bb;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
76
src/OpenFOAM/primitives/ops/flipOp.C
Normal file
76
src/OpenFOAM/primitives/ops/flipOp.C
Normal file
@ -0,0 +1,76 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "flipOp.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<>
|
||||
Foam::scalar Foam::flipOp::operator()(const scalar& v) const
|
||||
{
|
||||
return -v;
|
||||
}
|
||||
|
||||
|
||||
template<> Foam::vector Foam::flipOp::operator()(const vector& v) const
|
||||
{
|
||||
return -v;
|
||||
}
|
||||
|
||||
|
||||
template<>Foam::sphericalTensor Foam::flipOp::operator()
|
||||
(
|
||||
const sphericalTensor& v
|
||||
) const
|
||||
{
|
||||
return -v;
|
||||
}
|
||||
|
||||
|
||||
template<> Foam::symmTensor Foam::flipOp::operator()
|
||||
(
|
||||
const symmTensor& v
|
||||
) const
|
||||
{
|
||||
return -v;
|
||||
}
|
||||
|
||||
|
||||
template<> Foam::tensor Foam::flipOp::operator()(const tensor& v) const
|
||||
{
|
||||
return -v;
|
||||
}
|
||||
|
||||
|
||||
template<> Foam::triad Foam::flipOp::operator()
|
||||
(
|
||||
const triad& v
|
||||
) const
|
||||
{
|
||||
return -v;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
103
src/OpenFOAM/primitives/ops/flipOp.H
Normal file
103
src/OpenFOAM/primitives/ops/flipOp.H
Normal file
@ -0,0 +1,103 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::flipOp
|
||||
|
||||
Description
|
||||
Class containing functor to negate primitives. Dummy for all other types.
|
||||
|
||||
Used in mesh transformations where face can flip.
|
||||
|
||||
SourceFiles
|
||||
flipOp.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef flipOp_H
|
||||
#define flipOp_H
|
||||
|
||||
#include "fieldTypes.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class flipOp Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class flipOp
|
||||
{
|
||||
public:
|
||||
|
||||
template<class Type>
|
||||
Type operator()(const Type& val) const
|
||||
{
|
||||
return val;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class noOp
|
||||
{
|
||||
public:
|
||||
|
||||
template<class Type>
|
||||
Type operator()(const Type& val) const
|
||||
{
|
||||
return val;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class flipLabelOp
|
||||
{
|
||||
public:
|
||||
|
||||
label operator()(const label& val) const
|
||||
{
|
||||
return -val;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Template specialisation for primitives that support negation
|
||||
template<> scalar flipOp::operator()(const scalar&) const;
|
||||
template<> vector flipOp::operator()(const vector&) const;
|
||||
template<> sphericalTensor flipOp::operator()(const sphericalTensor&) const;
|
||||
template<> symmTensor flipOp::operator()(const symmTensor&) const;
|
||||
template<> tensor flipOp::operator()(const tensor&) const;
|
||||
template<> triad flipOp::operator()(const triad&) const;
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -28,17 +28,22 @@ polyTopoChange/polyTopoChange/addPatchCellLayer.C
|
||||
polyTopoChange/polyTopoChange/pointEdgeCollapse/pointEdgeCollapse.C
|
||||
polyTopoChange/polyTopoChange/edgeCollapser.C
|
||||
polyTopoChange/polyTopoChange/faceCollapser.C
|
||||
polyTopoChange/polyTopoChange/hexRef8.C
|
||||
polyTopoChange/polyTopoChange/removeCells.C
|
||||
polyTopoChange/polyTopoChange/removeFaces.C
|
||||
polyTopoChange/polyTopoChange/refinementData.C
|
||||
polyTopoChange/polyTopoChange/refinementDistanceData.C
|
||||
polyTopoChange/polyTopoChange/refinementHistory.C
|
||||
polyTopoChange/polyTopoChange/removePoints.C
|
||||
polyTopoChange/polyTopoChange/combineFaces.C
|
||||
polyTopoChange/polyTopoChange/duplicatePoints.C
|
||||
polyTopoChange/polyTopoChange/tetDecomposer.C
|
||||
|
||||
|
||||
hexRef8 = polyTopoChange/polyTopoChange/hexRef8
|
||||
|
||||
$(hexRef8)/hexRef8.C
|
||||
$(hexRef8)/hexRef8Data.C
|
||||
$(hexRef8)/refinementHistory.C
|
||||
|
||||
slidingInterface/slidingInterface.C
|
||||
slidingInterface/slidingInterfaceProjectPoints.C
|
||||
slidingInterface/coupleSlidingInterface.C
|
||||
@ -78,11 +83,14 @@ polyTopoChange/repatchPolyTopoChanger/repatchPolyTopoChanger.C
|
||||
|
||||
fvMeshAdder/fvMeshAdder.C
|
||||
fvMeshDistribute/fvMeshDistribute.C
|
||||
fvMeshDistribute/IOmapDistributePolyMesh.C
|
||||
polyMeshAdder/faceCoupleInfo.C
|
||||
polyMeshAdder/polyMeshAdder.C
|
||||
|
||||
fvMeshTools/fvMeshTools.C
|
||||
|
||||
fvMeshSubset/fvMeshSubset.C
|
||||
|
||||
motionSmoother/motionSmoother.C
|
||||
motionSmoother/motionSmootherAlgo.C
|
||||
motionSmoother/motionSmootherAlgoCheck.C
|
||||
|
||||
126
src/dynamicMesh/fvMeshDistribute/IOmapDistributePolyMesh.C
Normal file
126
src/dynamicMesh/fvMeshDistribute/IOmapDistributePolyMesh.C
Normal file
@ -0,0 +1,126 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "IOmapDistributePolyMesh.H"
|
||||
|
||||
/* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(IOmapDistributePolyMesh, 0);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::IOmapDistributePolyMesh::IOmapDistributePolyMesh(const IOobject& io)
|
||||
:
|
||||
regIOobject(io)
|
||||
{
|
||||
// Temporary warning
|
||||
if (io.readOpt() == IOobject::MUST_READ_IF_MODIFIED)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"IOmapDistributePolyMesh::IOmapDistributePolyMesh(const IOobject&)"
|
||||
) << "Specified IOobject::MUST_READ_IF_MODIFIED but class"
|
||||
<< " does not support automatic rereading."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
(
|
||||
io.readOpt() == IOobject::MUST_READ
|
||||
|| io.readOpt() == IOobject::MUST_READ_IF_MODIFIED
|
||||
)
|
||||
|| (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
|
||||
)
|
||||
{
|
||||
readStream(typeName) >> *this;
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::IOmapDistributePolyMesh::IOmapDistributePolyMesh
|
||||
(
|
||||
const IOobject& io,
|
||||
const mapDistributePolyMesh& map
|
||||
)
|
||||
:
|
||||
regIOobject(io)
|
||||
{
|
||||
// Temporary warning
|
||||
if (io.readOpt() == IOobject::MUST_READ_IF_MODIFIED)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"IOmapDistributePolyMesh::IOmapDistributePolyMesh(const IOobject&)"
|
||||
) << "Specified IOobject::MUST_READ_IF_MODIFIED but class"
|
||||
<< " does not support automatic rereading."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
(
|
||||
io.readOpt() == IOobject::MUST_READ
|
||||
|| io.readOpt() == IOobject::MUST_READ_IF_MODIFIED
|
||||
)
|
||||
|| (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
|
||||
)
|
||||
{
|
||||
readStream(typeName) >> *this;
|
||||
close();
|
||||
}
|
||||
else
|
||||
{
|
||||
mapDistributePolyMesh::operator=(map);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::IOmapDistributePolyMesh::~IOmapDistributePolyMesh()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::IOmapDistributePolyMesh::readData(Istream& is)
|
||||
{
|
||||
return (is >> *this).good();
|
||||
}
|
||||
|
||||
|
||||
bool Foam::IOmapDistributePolyMesh::writeData(Ostream& os) const
|
||||
{
|
||||
return (os << *this).good();
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
95
src/dynamicMesh/fvMeshDistribute/IOmapDistributePolyMesh.H
Normal file
95
src/dynamicMesh/fvMeshDistribute/IOmapDistributePolyMesh.H
Normal file
@ -0,0 +1,95 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::IOmapDistributePolyMesh
|
||||
|
||||
Description
|
||||
IOmapDistributePolyMesh is derived from mapDistributePolyMesh and
|
||||
IOobject to give the mapDistributePolyMesh
|
||||
automatic IO functionality via the objectRegistry.
|
||||
|
||||
SourceFiles
|
||||
IOmapDistributePolyMesh.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef IOmapDistributePolyMesh_H
|
||||
#define IOmapDistributePolyMesh_H
|
||||
|
||||
#include "mapDistributePolyMesh.H"
|
||||
#include "regIOobject.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class IOmapDistributePolyMesh Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class IOmapDistributePolyMesh
|
||||
:
|
||||
public regIOobject,
|
||||
public mapDistributePolyMesh
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("mapDistributePolyMesh");
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct given an IOobject
|
||||
IOmapDistributePolyMesh(const IOobject&);
|
||||
|
||||
//- Construct given an IOobject and mapDistributePolyMesh
|
||||
IOmapDistributePolyMesh(const IOobject&, const mapDistributePolyMesh&);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~IOmapDistributePolyMesh();
|
||||
|
||||
|
||||
// Member functions
|
||||
|
||||
//- ReadData function required for regIOobject read operation
|
||||
virtual bool readData(Istream&);
|
||||
|
||||
//- WriteData function required for regIOobject write operation
|
||||
virtual bool writeData(Ostream&) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -40,17 +40,129 @@ License
|
||||
#include "syncTools.H"
|
||||
#include "CompactListList.H"
|
||||
#include "fvMeshTools.H"
|
||||
#include "ListOps.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(fvMeshDistribute, 0);
|
||||
|
||||
//- Less function class that can be used for sorting processor patches
|
||||
class lessProcPatches
|
||||
{
|
||||
const labelList& nbrProc_;
|
||||
const labelList& referPatchID_;
|
||||
|
||||
public:
|
||||
|
||||
lessProcPatches( const labelList& nbrProc, const labelList& referPatchID)
|
||||
:
|
||||
nbrProc_(nbrProc),
|
||||
referPatchID_(referPatchID)
|
||||
{}
|
||||
|
||||
bool operator()(const label a, const label b)
|
||||
{
|
||||
if (nbrProc_[a] < nbrProc_[b])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (nbrProc_[a] > nbrProc_[b])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Equal neighbour processor
|
||||
return referPatchID_[a] < referPatchID_[b];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::fvMeshDistribute::inplaceRenumberWithFlip
|
||||
(
|
||||
const labelUList& oldToNew,
|
||||
const bool oldToNewHasFlip,
|
||||
const bool lstHasFlip,
|
||||
labelUList& lst
|
||||
)
|
||||
{
|
||||
if (!lstHasFlip && !oldToNewHasFlip)
|
||||
{
|
||||
Foam::inplaceRenumber(oldToNew, lst);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Either input data or map encodes sign so result encodes sign
|
||||
|
||||
forAll(lst, elemI)
|
||||
{
|
||||
// Extract old value and sign
|
||||
label val = lst[elemI];
|
||||
label sign = 1;
|
||||
if (lstHasFlip)
|
||||
{
|
||||
if (val > 0)
|
||||
{
|
||||
val = val-1;
|
||||
}
|
||||
else if (val < 0)
|
||||
{
|
||||
val = -val-1;
|
||||
sign = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fvMeshDistribute::inplaceRenumberWithFlip(..)"
|
||||
) << "Problem : zero value " << val
|
||||
<< " at index " << elemI << " out of " << lst.size()
|
||||
<< " list with flip bit" << exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Lookup new value and possibly change sign
|
||||
label newVal = oldToNew[val];
|
||||
|
||||
if (oldToNewHasFlip)
|
||||
{
|
||||
if (newVal > 0)
|
||||
{
|
||||
newVal = newVal-1;
|
||||
}
|
||||
else if (newVal < 0)
|
||||
{
|
||||
newVal = -newVal-1;
|
||||
sign = -sign;
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"fvMeshDistribute::inplaceRenumberWithFlip(..)"
|
||||
) << "Problem : zero value " << newVal
|
||||
<< " at index " << elemI << " out of "
|
||||
<< oldToNew.size()
|
||||
<< " list with flip bit" << exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Encode new value and sign
|
||||
lst[elemI] = sign*(newVal+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::fvMeshDistribute::select
|
||||
(
|
||||
const bool selectEqual,
|
||||
@ -277,6 +389,114 @@ Foam::label Foam::fvMeshDistribute::findNonEmptyPatch() const
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::surfaceScalarField> Foam::fvMeshDistribute::generateTestField
|
||||
(
|
||||
const fvMesh& mesh
|
||||
)
|
||||
{
|
||||
vector testNormal(1, 1, 1);
|
||||
testNormal /= mag(testNormal);
|
||||
|
||||
tmp<surfaceScalarField> tfld
|
||||
(
|
||||
new surfaceScalarField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"myFlux",
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimensionedScalar("zero", dimless, 0.0)
|
||||
)
|
||||
);
|
||||
surfaceScalarField& fld = tfld();
|
||||
|
||||
const surfaceVectorField n(mesh.Sf()/mesh.magSf());
|
||||
|
||||
forAll(fld, faceI)
|
||||
{
|
||||
fld[faceI] = (n[faceI] & testNormal);
|
||||
}
|
||||
forAll(fld.boundaryField(), patchI)
|
||||
{
|
||||
fvsPatchScalarField& fvp = fld.boundaryField()[patchI];
|
||||
|
||||
scalarField newPfld(fvp.size());
|
||||
forAll(newPfld, i)
|
||||
{
|
||||
newPfld[i] = (n.boundaryField()[patchI][i] & testNormal);
|
||||
}
|
||||
fvp == newPfld;
|
||||
}
|
||||
|
||||
return tfld;
|
||||
}
|
||||
|
||||
|
||||
void Foam::fvMeshDistribute::testField(const surfaceScalarField& fld)
|
||||
{
|
||||
const fvMesh& mesh = fld.mesh();
|
||||
|
||||
vector testNormal(1, 1, 1);
|
||||
testNormal /= mag(testNormal);
|
||||
|
||||
const surfaceVectorField n(mesh.Sf()/mesh.magSf());
|
||||
|
||||
forAll(fld, faceI)
|
||||
{
|
||||
scalar cos = (n[faceI] & testNormal);
|
||||
|
||||
if (mag(cos-fld[faceI]) > 1e-6)
|
||||
{
|
||||
//FatalErrorIn
|
||||
WarningIn
|
||||
(
|
||||
"fvMeshDistribute::testField(const surfaceScalarField&)"
|
||||
) << "On internal face " << faceI << " at "
|
||||
<< mesh.faceCentres()[faceI]
|
||||
<< " the field value is " << fld[faceI]
|
||||
<< " whereas cos angle of " << testNormal
|
||||
<< " with mesh normal " << n[faceI]
|
||||
<< " is " << cos
|
||||
//<< exit(FatalError);
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
forAll(fld.boundaryField(), patchI)
|
||||
{
|
||||
const fvsPatchScalarField& fvp = fld.boundaryField()[patchI];
|
||||
const fvsPatchVectorField& np = n.boundaryField()[patchI];
|
||||
|
||||
forAll(fvp, i)
|
||||
{
|
||||
scalar cos = (np[i] & testNormal);
|
||||
|
||||
if (mag(cos-fvp[i]) > 1e-6)
|
||||
{
|
||||
label faceI = fvp.patch().start()+i;
|
||||
//FatalErrorIn
|
||||
WarningIn
|
||||
(
|
||||
"fvMeshDistribute::testField(const surfaceScalarField&)"
|
||||
) << "On face " << faceI
|
||||
<< " on patch " << fvp.patch().name()
|
||||
<< " at " << mesh.faceCentres()[faceI]
|
||||
<< " the field value is " << fvp[i]
|
||||
<< " whereas cos angle of " << testNormal
|
||||
<< " with mesh normal " << np[i]
|
||||
<< " is " << cos
|
||||
//<< exit(FatalError);
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Delete all processor patches. Move any processor faces into the last
|
||||
// non-processor patch.
|
||||
Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::deleteProcPatches
|
||||
@ -455,10 +675,15 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::repatch
|
||||
|
||||
forAll(constructFaceMap, procI)
|
||||
{
|
||||
inplaceRenumber(map().reverseFaceMap(), constructFaceMap[procI]);
|
||||
inplaceRenumberWithFlip
|
||||
(
|
||||
map().reverseFaceMap(),
|
||||
false,
|
||||
true,
|
||||
constructFaceMap[procI]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@ -886,18 +1111,52 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::doRemoveCells
|
||||
meshMod
|
||||
);
|
||||
|
||||
|
||||
//// Generate test field
|
||||
//tmp<surfaceScalarField> sfld(generateTestField(mesh_));
|
||||
|
||||
// Save internal fields (note: not as DimensionedFields since would
|
||||
// get mapped)
|
||||
PtrList<Field<scalar> > sFlds;
|
||||
saveInternalFields(sFlds);
|
||||
PtrList<Field<vector> > vFlds;
|
||||
saveInternalFields(vFlds);
|
||||
PtrList<Field<sphericalTensor> > sptFlds;
|
||||
saveInternalFields(sptFlds);
|
||||
PtrList<Field<symmTensor> > sytFlds;
|
||||
saveInternalFields(sytFlds);
|
||||
PtrList<Field<tensor> > tFlds;
|
||||
saveInternalFields(tFlds);
|
||||
|
||||
// Change the mesh. No inflation. Note: no parallel comms allowed.
|
||||
autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh_, false, false);
|
||||
|
||||
// Update fields
|
||||
mesh_.updateMesh(map);
|
||||
|
||||
|
||||
// Any exposed faces in a surfaceField will not be mapped. Map the value
|
||||
// of these separately (until there is support in all PatchFields for
|
||||
// mapping from internal faces ...)
|
||||
|
||||
mapExposedFaces(map(), sFlds);
|
||||
mapExposedFaces(map(), vFlds);
|
||||
mapExposedFaces(map(), sptFlds);
|
||||
mapExposedFaces(map(), sytFlds);
|
||||
mapExposedFaces(map(), tFlds);
|
||||
|
||||
|
||||
//// Test test field
|
||||
//testField(sfld);
|
||||
|
||||
|
||||
// Move mesh (since morphing does not do this)
|
||||
if (map().hasMotionPoints())
|
||||
{
|
||||
mesh_.movePoints(map().preMotionPoints());
|
||||
}
|
||||
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@ -915,10 +1174,18 @@ void Foam::fvMeshDistribute::addProcPatches
|
||||
// contain for all current boundary faces the global patchID (for non-proc
|
||||
// patch) or the processor.
|
||||
|
||||
// Determine a visit order such that the processor patches get added
|
||||
// in order of increasing neighbour processor (and for same neighbour
|
||||
// processor (in case of processor cyclics) in order of increasing
|
||||
// 'refer' patch)
|
||||
labelList indices;
|
||||
sortedOrder(nbrProc, indices, lessProcPatches(nbrProc, referPatchID));
|
||||
|
||||
procPatchID.setSize(Pstream::nProcs());
|
||||
|
||||
forAll(nbrProc, bFaceI)
|
||||
forAll(indices, i)
|
||||
{
|
||||
label bFaceI = indices[i];
|
||||
label procI = nbrProc[bFaceI];
|
||||
|
||||
if (procI != -1 && procI != Pstream::myProcNo())
|
||||
@ -946,7 +1213,7 @@ void Foam::fvMeshDistribute::addProcPatches
|
||||
mesh_.boundaryMesh().size(),
|
||||
mesh_.boundaryMesh(),
|
||||
Pstream::myProcNo(),
|
||||
nbrProc[bFaceI]
|
||||
procI
|
||||
);
|
||||
|
||||
procPatchID[procI].insert
|
||||
@ -989,7 +1256,7 @@ void Foam::fvMeshDistribute::addProcPatches
|
||||
mesh_.boundaryMesh().size(),
|
||||
mesh_.boundaryMesh(),
|
||||
Pstream::myProcNo(),
|
||||
nbrProc[bFaceI],
|
||||
procI,
|
||||
cycName,
|
||||
pcPatch.transform()
|
||||
);
|
||||
@ -1524,7 +1791,33 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
const wordList surfTensors(mesh_.names(surfaceTensorField::typeName));
|
||||
checkEqualWordList("surfaceTensorFields", surfTensors);
|
||||
|
||||
typedef volScalarField::DimensionedInternalField dimScalType;
|
||||
const wordList dimScalars(mesh_.names(dimScalType::typeName));
|
||||
checkEqualWordList("volScalarField::DimensionedInternalField", dimScalars);
|
||||
|
||||
typedef volVectorField::DimensionedInternalField dimVecType;
|
||||
const wordList dimVectors(mesh_.names(dimVecType::typeName));
|
||||
checkEqualWordList("volVectorField::DimensionedInternalField", dimVectors);
|
||||
|
||||
typedef volSphericalTensorField::DimensionedInternalField dimSphereType;
|
||||
const wordList dimSphereTensors(mesh_.names(dimSphereType::typeName));
|
||||
checkEqualWordList
|
||||
(
|
||||
"volSphericalTensorField::DimensionedInternalField",
|
||||
dimSphereTensors
|
||||
);
|
||||
|
||||
typedef volSymmTensorField::DimensionedInternalField dimSymmTensorType;
|
||||
const wordList dimSymmTensors(mesh_.names(dimSymmTensorType::typeName));
|
||||
checkEqualWordList
|
||||
(
|
||||
"volSymmTensorField::DimensionedInternalField",
|
||||
dimSymmTensors
|
||||
);
|
||||
|
||||
typedef volTensorField::DimensionedInternalField dimTensorType;
|
||||
const wordList dimTensors(mesh_.names(dimTensorType::typeName));
|
||||
checkEqualWordList("volTensorField::DimensionedInternalField", dimTensors);
|
||||
|
||||
|
||||
// Find patch to temporarily put exposed and processor faces into.
|
||||
@ -1650,10 +1943,13 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
);
|
||||
|
||||
subCellMap[recvProc] = subsetter.cellMap();
|
||||
subFaceMap[recvProc] = renumber
|
||||
subFaceMap[recvProc] = subsetter.faceFlipMap();
|
||||
inplaceRenumberWithFlip
|
||||
(
|
||||
repatchFaceMap,
|
||||
subsetter.faceMap()
|
||||
false, // oldToNew has flip
|
||||
true, // subFaceMap has flip
|
||||
subFaceMap[recvProc]
|
||||
);
|
||||
subPointMap[recvProc] = subsetter.pointMap();
|
||||
subPatchMap[recvProc] = subsetter.patchMap();
|
||||
@ -1705,6 +2001,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
procSourceNewNbrProc,
|
||||
str
|
||||
);
|
||||
|
||||
// volFields
|
||||
sendFields<volScalarField>(recvProc, volScalars, subsetter, str);
|
||||
sendFields<volVectorField>(recvProc, volVectors, subsetter, str);
|
||||
sendFields<volSphericalTensorField>
|
||||
@ -1723,6 +2021,7 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
);
|
||||
sendFields<volTensorField>(recvProc, volTensors, subsetter, str);
|
||||
|
||||
// surfaceFields
|
||||
sendFields<surfaceScalarField>
|
||||
(
|
||||
recvProc,
|
||||
@ -1758,6 +2057,43 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
subsetter,
|
||||
str
|
||||
);
|
||||
|
||||
// dimensionedFields
|
||||
sendFields<volScalarField::DimensionedInternalField>
|
||||
(
|
||||
recvProc,
|
||||
dimScalars,
|
||||
subsetter,
|
||||
str
|
||||
);
|
||||
sendFields<volVectorField::DimensionedInternalField>
|
||||
(
|
||||
recvProc,
|
||||
dimVectors,
|
||||
subsetter,
|
||||
str
|
||||
);
|
||||
sendFields<volSphericalTensorField::DimensionedInternalField>
|
||||
(
|
||||
recvProc,
|
||||
dimSphereTensors,
|
||||
subsetter,
|
||||
str
|
||||
);
|
||||
sendFields<volSymmTensorField::DimensionedInternalField>
|
||||
(
|
||||
recvProc,
|
||||
dimSymmTensors,
|
||||
subsetter,
|
||||
str
|
||||
);
|
||||
sendFields<volTensorField::DimensionedInternalField>
|
||||
(
|
||||
recvProc,
|
||||
dimTensors,
|
||||
subsetter,
|
||||
str
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1795,12 +2131,24 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
repatchFaceMap,
|
||||
subMap().faceMap()
|
||||
);
|
||||
// Insert the sign bit from face flipping
|
||||
labelList& faceMap = subFaceMap[Pstream::myProcNo()];
|
||||
forAll(faceMap, faceI)
|
||||
{
|
||||
faceMap[faceI] += 1;
|
||||
}
|
||||
const labelHashSet& flip = subMap().flipFaceFlux();
|
||||
forAllConstIter(labelHashSet, flip, iter)
|
||||
{
|
||||
label faceI = iter.key();
|
||||
faceMap[faceI] = -faceMap[faceI];
|
||||
}
|
||||
subPointMap[Pstream::myProcNo()] = subMap().pointMap();
|
||||
subPatchMap[Pstream::myProcNo()] = identity(patches.size());
|
||||
|
||||
// Initialize all addressing into current mesh
|
||||
constructCellMap[Pstream::myProcNo()] = identity(mesh_.nCells());
|
||||
constructFaceMap[Pstream::myProcNo()] = identity(mesh_.nFaces());
|
||||
constructFaceMap[Pstream::myProcNo()] = identity(mesh_.nFaces()) + 1;
|
||||
constructPointMap[Pstream::myProcNo()] = identity(mesh_.nPoints());
|
||||
constructPatchMap[Pstream::myProcNo()] = identity(patches.size());
|
||||
|
||||
@ -1896,17 +2244,26 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
labelList domainSourceNewNbrProc;
|
||||
|
||||
autoPtr<fvMesh> domainMeshPtr;
|
||||
|
||||
PtrList<volScalarField> vsf;
|
||||
PtrList<volVectorField> vvf;
|
||||
PtrList<volSphericalTensorField> vsptf;
|
||||
PtrList<volSymmTensorField> vsytf;
|
||||
PtrList<volTensorField> vtf;
|
||||
|
||||
PtrList<surfaceScalarField> ssf;
|
||||
PtrList<surfaceVectorField> svf;
|
||||
PtrList<surfaceSphericalTensorField> ssptf;
|
||||
PtrList<surfaceSymmTensorField> ssytf;
|
||||
PtrList<surfaceTensorField> stf;
|
||||
|
||||
PtrList<volScalarField::DimensionedInternalField> dsf;
|
||||
PtrList<volVectorField::DimensionedInternalField> dvf;
|
||||
PtrList<volSphericalTensorField::DimensionedInternalField> dstf;
|
||||
PtrList<volSymmTensorField::DimensionedInternalField> dsytf;
|
||||
PtrList<volTensorField::DimensionedInternalField> dtf;
|
||||
|
||||
|
||||
// Opposite of sendMesh
|
||||
{
|
||||
domainMeshPtr = receiveMesh
|
||||
@ -1932,6 +2289,7 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
// of problems reading consecutive fields from single stream.
|
||||
dictionary fieldDicts(str);
|
||||
|
||||
// Vol fields
|
||||
receiveFields<volScalarField>
|
||||
(
|
||||
sendProc,
|
||||
@ -1973,6 +2331,7 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
fieldDicts.subDict(volTensorField::typeName)
|
||||
);
|
||||
|
||||
// Surface fields
|
||||
receiveFields<surfaceScalarField>
|
||||
(
|
||||
sendProc,
|
||||
@ -2013,12 +2372,70 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
stf,
|
||||
fieldDicts.subDict(surfaceTensorField::typeName)
|
||||
);
|
||||
|
||||
// Dimensioned fields
|
||||
receiveFields<volScalarField::DimensionedInternalField>
|
||||
(
|
||||
sendProc,
|
||||
dimScalars,
|
||||
domainMesh,
|
||||
dsf,
|
||||
fieldDicts.subDict
|
||||
(
|
||||
volScalarField::DimensionedInternalField::typeName
|
||||
)
|
||||
);
|
||||
receiveFields<volVectorField::DimensionedInternalField>
|
||||
(
|
||||
sendProc,
|
||||
dimVectors,
|
||||
domainMesh,
|
||||
dvf,
|
||||
fieldDicts.subDict
|
||||
(
|
||||
volVectorField::DimensionedInternalField::typeName
|
||||
)
|
||||
);
|
||||
receiveFields<volSphericalTensorField::DimensionedInternalField>
|
||||
(
|
||||
sendProc,
|
||||
dimSphereTensors,
|
||||
domainMesh,
|
||||
dstf,
|
||||
fieldDicts.subDict
|
||||
(
|
||||
volSphericalTensorField::DimensionedInternalField::
|
||||
typeName
|
||||
)
|
||||
);
|
||||
receiveFields<volSymmTensorField::DimensionedInternalField>
|
||||
(
|
||||
sendProc,
|
||||
dimSymmTensors,
|
||||
domainMesh,
|
||||
dsytf,
|
||||
fieldDicts.subDict
|
||||
(
|
||||
volSymmTensorField::DimensionedInternalField::typeName
|
||||
)
|
||||
);
|
||||
receiveFields<volTensorField::DimensionedInternalField>
|
||||
(
|
||||
sendProc,
|
||||
dimTensors,
|
||||
domainMesh,
|
||||
dtf,
|
||||
fieldDicts.subDict
|
||||
(
|
||||
volTensorField::DimensionedInternalField::typeName
|
||||
)
|
||||
);
|
||||
}
|
||||
const fvMesh& domainMesh = domainMeshPtr();
|
||||
|
||||
|
||||
constructCellMap[sendProc] = identity(domainMesh.nCells());
|
||||
constructFaceMap[sendProc] = identity(domainMesh.nFaces());
|
||||
constructFaceMap[sendProc] = identity(domainMesh.nFaces()) + 1;
|
||||
constructPointMap[sendProc] = identity(domainMesh.nPoints());
|
||||
constructPatchMap[sendProc] =
|
||||
identity(domainMesh.boundaryMesh().size());
|
||||
@ -2129,28 +2546,76 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
domainSourceNewNbrProc
|
||||
);
|
||||
|
||||
// Update all addressing so xxProcAddressing points to correct item
|
||||
// in masterMesh.
|
||||
// Update all addressing so xxProcAddressing points to correct
|
||||
// item in masterMesh.
|
||||
const labelList& oldCellMap = map().oldCellMap();
|
||||
const labelList& oldFaceMap = map().oldFaceMap();
|
||||
const labelList& oldPointMap = map().oldPointMap();
|
||||
const labelList& oldPatchMap = map().oldPatchMap();
|
||||
|
||||
//Note: old mesh faces never flipped!
|
||||
forAll(constructPatchMap, procI)
|
||||
{
|
||||
if (procI != sendProc && constructPatchMap[procI].size())
|
||||
{
|
||||
// Processor already in mesh (either myProcNo or received)
|
||||
inplaceRenumber(oldCellMap, constructCellMap[procI]);
|
||||
inplaceRenumber(oldFaceMap, constructFaceMap[procI]);
|
||||
inplaceRenumberWithFlip
|
||||
(
|
||||
oldFaceMap,
|
||||
false,
|
||||
true,
|
||||
constructFaceMap[procI]
|
||||
);
|
||||
inplaceRenumber(oldPointMap, constructPointMap[procI]);
|
||||
inplaceRenumber(oldPatchMap, constructPatchMap[procI]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
labelHashSet flippedAddedFaces;
|
||||
{
|
||||
// Find out if any faces of domain mesh were flipped (boundary
|
||||
// faces becoming internal)
|
||||
label nBnd = domainMesh.nFaces()-domainMesh.nInternalFaces();
|
||||
flippedAddedFaces.resize(nBnd/4);
|
||||
|
||||
for
|
||||
(
|
||||
label domainFaceI = domainMesh.nInternalFaces();
|
||||
domainFaceI < domainMesh.nFaces();
|
||||
domainFaceI++
|
||||
)
|
||||
{
|
||||
label newFaceI = map().addedFaceMap()[domainFaceI];
|
||||
label newCellI = mesh_.faceOwner()[newFaceI];
|
||||
|
||||
label domainCellI = domainMesh.faceOwner()[domainFaceI];
|
||||
|
||||
if (newCellI != map().addedCellMap()[domainCellI])
|
||||
{
|
||||
flippedAddedFaces.insert(domainFaceI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Added processor
|
||||
inplaceRenumber(map().addedCellMap(), constructCellMap[sendProc]);
|
||||
inplaceRenumber(map().addedFaceMap(), constructFaceMap[sendProc]);
|
||||
// Add flip
|
||||
forAllConstIter(labelHashSet, flippedAddedFaces, iter)
|
||||
{
|
||||
label domainFaceI = iter.key();
|
||||
label& val = constructFaceMap[sendProc][domainFaceI];
|
||||
val = -val;
|
||||
}
|
||||
inplaceRenumberWithFlip
|
||||
(
|
||||
map().addedFaceMap(),
|
||||
false,
|
||||
true, // constructFaceMap has flip sign
|
||||
constructFaceMap[sendProc]
|
||||
);
|
||||
inplaceRenumber(map().addedPointMap(), constructPointMap[sendProc]);
|
||||
inplaceRenumber(map().addedPatchMap(), constructPatchMap[sendProc]);
|
||||
|
||||
@ -2260,35 +2725,6 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
pTraits<tensor>::zero
|
||||
);
|
||||
|
||||
initPatchFields<surfaceScalarField, processorFvsPatchField<scalar> >
|
||||
(
|
||||
pTraits<scalar>::zero
|
||||
);
|
||||
initPatchFields<surfaceVectorField, processorFvsPatchField<vector> >
|
||||
(
|
||||
pTraits<vector>::zero
|
||||
);
|
||||
initPatchFields
|
||||
<
|
||||
surfaceSphericalTensorField,
|
||||
processorFvsPatchField<sphericalTensor>
|
||||
>
|
||||
(
|
||||
pTraits<sphericalTensor>::zero
|
||||
);
|
||||
initPatchFields
|
||||
<
|
||||
surfaceSymmTensorField,
|
||||
processorFvsPatchField<symmTensor>
|
||||
>
|
||||
(
|
||||
pTraits<symmTensor>::zero
|
||||
);
|
||||
initPatchFields<surfaceTensorField, processorFvsPatchField<tensor> >
|
||||
(
|
||||
pTraits<tensor>::zero
|
||||
);
|
||||
|
||||
|
||||
mesh_.setInstance(mesh_.time().timeName());
|
||||
|
||||
@ -2332,7 +2768,10 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||
constructPointMap.xfer(),
|
||||
constructFaceMap.xfer(),
|
||||
constructCellMap.xfer(),
|
||||
constructPatchMap.xfer()
|
||||
constructPatchMap.xfer(),
|
||||
|
||||
true, // subFaceMap has flip
|
||||
true // constructFaceMap has flip
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -82,6 +82,14 @@ class fvMeshDistribute
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
static void inplaceRenumberWithFlip
|
||||
(
|
||||
const labelUList& oldToNew,
|
||||
const bool oldToNewHasFlip,
|
||||
const bool lstHasFlip,
|
||||
labelUList& lst
|
||||
);
|
||||
|
||||
//- Find indices with value
|
||||
static labelList select
|
||||
(
|
||||
@ -117,6 +125,21 @@ class fvMeshDistribute
|
||||
const PtrList<FieldField<fvsPatchField, T> >& oldBflds
|
||||
);
|
||||
|
||||
//- Save internal fields of surfaceFields
|
||||
template<class T>
|
||||
void saveInternalFields
|
||||
(
|
||||
PtrList<Field<T> >& iflds
|
||||
) const;
|
||||
|
||||
//- Set value of patch faces resulting from internal faces
|
||||
template<class T>
|
||||
void mapExposedFaces
|
||||
(
|
||||
const mapPolyMesh& map,
|
||||
const PtrList<Field<T> >& oldFlds
|
||||
);
|
||||
|
||||
//- Init patch fields of certain type
|
||||
template<class GeoField, class PatchFieldType>
|
||||
void initPatchFields
|
||||
@ -337,6 +360,12 @@ public:
|
||||
|
||||
//- Print some info on mesh.
|
||||
static void printMeshInfo(const fvMesh&);
|
||||
|
||||
//- Generate a test field on faces
|
||||
static tmp<surfaceScalarField> generateTestField(const fvMesh&);
|
||||
|
||||
//- Check whether field consistent with face orientation
|
||||
static void testField(const surfaceScalarField&);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -113,8 +113,7 @@ void Foam::fvMeshDistribute::mapBoundaryFields
|
||||
forAllIter(typename HashTable<fldType*>, flds, iter)
|
||||
{
|
||||
fldType& fld = *iter();
|
||||
typename fldType::GeometricBoundaryField& bfld =
|
||||
fld.boundaryField();
|
||||
typename fldType::GeometricBoundaryField& bfld = fld.boundaryField();
|
||||
|
||||
const FieldField<fvsPatchField, T>& oldBfld = oldBflds[fieldI++];
|
||||
|
||||
@ -145,6 +144,94 @@ void Foam::fvMeshDistribute::mapBoundaryFields
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void Foam::fvMeshDistribute::saveInternalFields
|
||||
(
|
||||
PtrList<Field<T> >& iflds
|
||||
) const
|
||||
{
|
||||
typedef GeometricField<T, fvsPatchField, surfaceMesh> fldType;
|
||||
|
||||
HashTable<const fldType*> flds
|
||||
(
|
||||
static_cast<const fvMesh&>(mesh_).objectRegistry::lookupClass<fldType>()
|
||||
);
|
||||
|
||||
iflds.setSize(flds.size());
|
||||
|
||||
label i = 0;
|
||||
|
||||
forAllConstIter(typename HashTable<const fldType*>, flds, iter)
|
||||
{
|
||||
const fldType& fld = *iter();
|
||||
|
||||
iflds.set(i, fld.internalField().clone());
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Set boundary values of exposed internal faces
|
||||
template<class T>
|
||||
void Foam::fvMeshDistribute::mapExposedFaces
|
||||
(
|
||||
const mapPolyMesh& map,
|
||||
const PtrList<Field<T> >& oldFlds
|
||||
)
|
||||
{
|
||||
const labelList& faceMap = map.faceMap();
|
||||
|
||||
typedef GeometricField<T, fvsPatchField, surfaceMesh> fldType;
|
||||
|
||||
HashTable<fldType*> flds
|
||||
(
|
||||
mesh_.objectRegistry::lookupClass<fldType>()
|
||||
);
|
||||
|
||||
if (flds.size() != oldFlds.size())
|
||||
{
|
||||
FatalErrorIn("fvMeshDistribute::mapExposedFaces(..)") << "problem"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
|
||||
label fieldI = 0;
|
||||
|
||||
forAllIter(typename HashTable<fldType*>, flds, iter)
|
||||
{
|
||||
fldType& fld = *iter();
|
||||
typename fldType::GeometricBoundaryField& bfld = fld.boundaryField();
|
||||
|
||||
const Field<T>& oldInternal = oldFlds[fieldI++];
|
||||
|
||||
// Pull from old internal field into bfld.
|
||||
|
||||
forAll(bfld, patchI)
|
||||
{
|
||||
fvsPatchField<T>& patchFld = bfld[patchI];
|
||||
|
||||
forAll(patchFld, i)
|
||||
{
|
||||
const label faceI = patchFld.patch().start()+i;
|
||||
|
||||
label oldFaceI = faceMap[faceI];
|
||||
|
||||
if (oldFaceI < oldInternal.size())
|
||||
{
|
||||
patchFld[i] = oldInternal[oldFaceI];
|
||||
|
||||
if (map.flipFaceFlux().found(faceI))
|
||||
{
|
||||
patchFld[i] = flipOp()(patchFld[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Init patch fields of certain type
|
||||
template<class GeoField, class PatchFieldType>
|
||||
void Foam::fvMeshDistribute::initPatchFields
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -34,6 +34,9 @@ Description
|
||||
#include "emptyPolyPatch.H"
|
||||
#include "demandDrivenData.H"
|
||||
#include "cyclicPolyPatch.H"
|
||||
#include "removeCells.H"
|
||||
#include "polyTopoChange.H"
|
||||
#include "mapPolyMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -354,6 +357,39 @@ void Foam::fvMeshSubset::subsetZones()
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::fvMeshSubset::getCellsToRemove
|
||||
(
|
||||
const labelList& region,
|
||||
const label currentRegion
|
||||
) const
|
||||
{
|
||||
// Count
|
||||
label nKeep = 0;
|
||||
forAll(region, cellI)
|
||||
{
|
||||
if (region[cellI] == currentRegion)
|
||||
{
|
||||
nKeep++;
|
||||
}
|
||||
}
|
||||
|
||||
// Collect cells to remove
|
||||
label nRemove = baseMesh().nCells() - nKeep;
|
||||
labelList cellsToRemove(nRemove);
|
||||
|
||||
nRemove = 0;
|
||||
forAll(region, cellI)
|
||||
{
|
||||
if (region[cellI] != currentRegion)
|
||||
{
|
||||
cellsToRemove[nRemove++] = cellI;
|
||||
}
|
||||
}
|
||||
|
||||
return cellsToRemove;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
// Construct from components
|
||||
@ -364,7 +400,8 @@ Foam::fvMeshSubset::fvMeshSubset(const fvMesh& baseMesh)
|
||||
pointMap_(0),
|
||||
faceMap_(0),
|
||||
cellMap_(0),
|
||||
patchMap_(0)
|
||||
patchMap_(0),
|
||||
faceFlipMapPtr_()
|
||||
{}
|
||||
|
||||
|
||||
@ -404,6 +441,10 @@ void Foam::fvMeshSubset::setCellSubset
|
||||
}
|
||||
|
||||
|
||||
// Clear demand driven data
|
||||
faceFlipMapPtr_.clear();
|
||||
|
||||
|
||||
cellMap_ = globalCellMap.toc();
|
||||
|
||||
// Sort the cell map in the ascending order
|
||||
@ -803,6 +844,8 @@ void Foam::fvMeshSubset::setLargeCellSubset
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Clear demand driven data
|
||||
faceFlipMapPtr_.clear();
|
||||
|
||||
// Get the cells for the current region.
|
||||
cellMap_.setSize(oldCells.size());
|
||||
@ -1371,6 +1414,68 @@ void Foam::fvMeshSubset::setLargeCellSubset
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::fvMeshSubset::getExposedFaces
|
||||
(
|
||||
const labelList& region,
|
||||
const label currentRegion,
|
||||
const bool syncCouples
|
||||
) const
|
||||
{
|
||||
// Collect cells to remove
|
||||
labelList cellsToRemove(getCellsToRemove(region, currentRegion));
|
||||
|
||||
return removeCells(baseMesh(), syncCouples).getExposedFaces(cellsToRemove);
|
||||
}
|
||||
|
||||
|
||||
void Foam::fvMeshSubset::setLargeCellSubset
|
||||
(
|
||||
const labelList& region,
|
||||
const label currentRegion,
|
||||
const labelList& exposedFaces,
|
||||
const labelList& patchIDs,
|
||||
const bool syncCouples
|
||||
)
|
||||
{
|
||||
// Collect cells to remove
|
||||
labelList cellsToRemove(getCellsToRemove(region, currentRegion));
|
||||
|
||||
// Mesh changing engine.
|
||||
polyTopoChange meshMod(baseMesh());
|
||||
|
||||
removeCells cellRemover(baseMesh(), syncCouples);
|
||||
|
||||
cellRemover.setRefinement
|
||||
(
|
||||
cellsToRemove,
|
||||
exposedFaces,
|
||||
patchIDs,
|
||||
meshMod
|
||||
);
|
||||
|
||||
// Create mesh, return map from old to new mesh.
|
||||
autoPtr<mapPolyMesh> map = meshMod.makeMesh
|
||||
(
|
||||
fvMeshSubsetPtr_,
|
||||
IOobject
|
||||
(
|
||||
baseMesh().name(),
|
||||
baseMesh().time().timeName(),
|
||||
baseMesh().time(),
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
baseMesh(),
|
||||
syncCouples
|
||||
);
|
||||
|
||||
pointMap_ = map().pointMap();
|
||||
faceMap_ = map().faceMap();
|
||||
cellMap_ = map().cellMap();
|
||||
patchMap_ = identity(baseMesh().boundaryMesh().size());
|
||||
}
|
||||
|
||||
|
||||
bool Foam::fvMeshSubset::hasSubMesh() const
|
||||
{
|
||||
return fvMeshSubsetPtr_.valid();
|
||||
@ -1409,6 +1514,44 @@ const labelList& Foam::fvMeshSubset::faceMap() const
|
||||
}
|
||||
|
||||
|
||||
const labelList& Foam::fvMeshSubset::faceFlipMap() const
|
||||
{
|
||||
if (!faceFlipMapPtr_.valid())
|
||||
{
|
||||
const labelList& subToBaseFace = faceMap();
|
||||
const labelList& subToBaseCell = cellMap();
|
||||
|
||||
faceFlipMapPtr_.reset(new labelList(subToBaseFace.size()));
|
||||
labelList& faceFlipMap = faceFlipMapPtr_();
|
||||
|
||||
// Only exposed internal faces might be flipped (since we don't do
|
||||
// any cell renumbering, just compacting)
|
||||
label subInt = subMesh().nInternalFaces();
|
||||
const labelList& subOwn = subMesh().faceOwner();
|
||||
const labelList& own = baseMesh_.faceOwner();
|
||||
|
||||
for (label subFaceI = 0; subFaceI < subInt; subFaceI++)
|
||||
{
|
||||
faceFlipMap[subFaceI] = subToBaseFace[subFaceI]+1;
|
||||
}
|
||||
for (label subFaceI = subInt; subFaceI < subOwn.size(); subFaceI++)
|
||||
{
|
||||
label faceI = subToBaseFace[subFaceI];
|
||||
if (subToBaseCell[subOwn[subFaceI]] == own[faceI])
|
||||
{
|
||||
faceFlipMap[subFaceI] = faceI+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
faceFlipMap[subFaceI] = -faceI-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return faceFlipMapPtr_();
|
||||
}
|
||||
|
||||
|
||||
const labelList& Foam::fvMeshSubset::cellMap() const
|
||||
{
|
||||
checkCellSubset();
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -41,10 +41,12 @@ Description
|
||||
a face on a coupled patch 'losing' its neighbour it will move the
|
||||
face into the oldInternalFaces patch.
|
||||
|
||||
- if a user supplied patch is used the mapping becomes a problem.
|
||||
Do the new faces get the value of the internal face they came from?
|
||||
What if e.g. the user supplied patch is a fixedValue 0? So for now
|
||||
they get the face of existing patch face 0.
|
||||
- if a user supplied patch is used it is up to the destination
|
||||
patchField to handle exposed internal faces (mapping from face -1).
|
||||
If not provided the default is to assign the internalField. All the
|
||||
basic patch field types (e.g. fixedValue) will give a warning and
|
||||
preferably derived patch field types should be used that know how to
|
||||
handle exposed faces (e.g. use uniformFixedValue instead of fixedValue)
|
||||
|
||||
SourceFiles
|
||||
fvMeshSubset.C
|
||||
@ -94,6 +96,8 @@ private:
|
||||
//- Patch mapping array
|
||||
labelList patchMap_;
|
||||
|
||||
mutable autoPtr<labelList> faceFlipMapPtr_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
@ -124,6 +128,13 @@ private:
|
||||
//- Create zones for submesh
|
||||
void subsetZones();
|
||||
|
||||
//- Helper: extract cells-to-remove from cells-to-keep
|
||||
labelList getCellsToRemove
|
||||
(
|
||||
const labelList& region,
|
||||
const label currentRegion
|
||||
) const;
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
fvMeshSubset(const fvMeshSubset&);
|
||||
|
||||
@ -174,6 +185,32 @@ public:
|
||||
);
|
||||
|
||||
|
||||
//- Two step subsetting
|
||||
|
||||
//- Get labels of exposed faces.
|
||||
// These are
|
||||
// - internal faces that become boundary faces
|
||||
// - coupled faces that become uncoupled (since one of the
|
||||
// sides gets deleted)
|
||||
labelList getExposedFaces
|
||||
(
|
||||
const labelList& region,
|
||||
const label currentRegion,
|
||||
const bool syncCouples = true
|
||||
) const;
|
||||
|
||||
//- For every exposed face (from above getExposedFaces)
|
||||
// used supplied (existing!) patch
|
||||
void setLargeCellSubset
|
||||
(
|
||||
const labelList& region,
|
||||
const label currentRegion,
|
||||
const labelList& exposedFaces,
|
||||
const labelList& patchIDs,
|
||||
const bool syncCouples = true
|
||||
);
|
||||
|
||||
|
||||
// Access
|
||||
|
||||
//- Original mesh
|
||||
@ -196,6 +233,9 @@ public:
|
||||
//- Return face map
|
||||
const labelList& faceMap() const;
|
||||
|
||||
//- Return face map with sign to encode flipped faces
|
||||
const labelList& faceFlipMap() const;
|
||||
|
||||
//- Return cell map
|
||||
const labelList& cellMap() const;
|
||||
|
||||
@ -224,7 +264,8 @@ public:
|
||||
const GeometricField<Type, fvPatchField, volMesh>&
|
||||
) const;
|
||||
|
||||
//- Map surface field
|
||||
//- Map surface field. Optionally negates value if flipping
|
||||
// a face (from exposing an internal face)
|
||||
template<class Type>
|
||||
static tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
|
||||
interpolate
|
||||
@ -232,14 +273,17 @@ public:
|
||||
const GeometricField<Type, fvsPatchField, surfaceMesh>&,
|
||||
const fvMesh& sMesh,
|
||||
const labelList& patchMap,
|
||||
const labelList& faceMap
|
||||
const labelList& cellMap,
|
||||
const labelList& faceMap,
|
||||
const bool negateIfFlipped = true
|
||||
);
|
||||
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
|
||||
interpolate
|
||||
(
|
||||
const GeometricField<Type, fvsPatchField, surfaceMesh>&
|
||||
const GeometricField<Type, fvsPatchField, surfaceMesh>&,
|
||||
const bool negateIfFlipped = true
|
||||
) const;
|
||||
|
||||
//- Map point field
|
||||
@ -259,6 +303,24 @@ public:
|
||||
(
|
||||
const GeometricField<Type, pointPatchField, pointMesh>&
|
||||
) const;
|
||||
|
||||
//- Map dimensioned fields
|
||||
template<class Type>
|
||||
static tmp<DimensionedField<Type, volMesh> >
|
||||
interpolate
|
||||
(
|
||||
const DimensionedField<Type, volMesh>&,
|
||||
const fvMesh& sMesh,
|
||||
const labelList& cellMap
|
||||
);
|
||||
|
||||
template<class Type>
|
||||
tmp<DimensionedField<Type, volMesh> >
|
||||
interpolate
|
||||
(
|
||||
const DimensionedField<Type, volMesh>&
|
||||
) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -29,6 +29,7 @@ License
|
||||
#include "emptyFvPatchFields.H"
|
||||
#include "directFvPatchFieldMapper.H"
|
||||
#include "directPointPatchFieldMapper.H"
|
||||
#include "flipOp.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -178,7 +179,9 @@ tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > fvMeshSubset::interpolate
|
||||
const GeometricField<Type, fvsPatchField, surfaceMesh>& vf,
|
||||
const fvMesh& sMesh,
|
||||
const labelList& patchMap,
|
||||
const labelList& faceMap
|
||||
const labelList& cellMap,
|
||||
const labelList& faceMap,
|
||||
const bool negateIfFlipped
|
||||
)
|
||||
{
|
||||
// 1. Create the complete field with dummy patch fields
|
||||
@ -297,14 +300,24 @@ tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > fvMeshSubset::interpolate
|
||||
// Postprocess patch field for exposed faces
|
||||
|
||||
fvsPatchField<Type>& pfld = bf[patchI];
|
||||
const labelUList& fc = bf[patchI].patch().faceCells();
|
||||
const labelList& own = vf.mesh().faceOwner();
|
||||
|
||||
forAll(pfld, i)
|
||||
{
|
||||
label baseFaceI = faceMap[subPatch.start()+i];
|
||||
if (baseFaceI < vf.internalField().size())
|
||||
{
|
||||
// Exposed internal face
|
||||
pfld[i] = vf.internalField()[baseFaceI];
|
||||
Type val = vf.internalField()[baseFaceI];
|
||||
|
||||
if (cellMap[fc[i]] == own[baseFaceI] || !negateIfFlipped)
|
||||
{
|
||||
pfld[i] = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
pfld[i] = flipOp()(val);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -329,7 +342,8 @@ tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > fvMeshSubset::interpolate
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > fvMeshSubset::interpolate
|
||||
(
|
||||
const GeometricField<Type, fvsPatchField, surfaceMesh>& sf
|
||||
const GeometricField<Type, fvsPatchField, surfaceMesh>& sf,
|
||||
const bool negateIfFlipped
|
||||
) const
|
||||
{
|
||||
return interpolate
|
||||
@ -337,7 +351,9 @@ tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > fvMeshSubset::interpolate
|
||||
sf,
|
||||
subMesh(),
|
||||
patchMap(),
|
||||
faceMap()
|
||||
cellMap(),
|
||||
faceMap(),
|
||||
negateIfFlipped
|
||||
);
|
||||
}
|
||||
|
||||
@ -489,6 +505,47 @@ tmp<GeometricField<Type, pointPatchField, pointMesh> > fvMeshSubset::interpolate
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
tmp<DimensionedField<Type, volMesh> > fvMeshSubset::interpolate
|
||||
(
|
||||
const DimensionedField<Type, volMesh>& df,
|
||||
const fvMesh& sMesh,
|
||||
const labelList& cellMap
|
||||
)
|
||||
{
|
||||
// Create the complete field from the pieces
|
||||
tmp<DimensionedField<Type, volMesh> > tresF
|
||||
(
|
||||
new DimensionedField<Type, volMesh>
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"subset"+df.name(),
|
||||
sMesh.time().timeName(),
|
||||
sMesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
sMesh,
|
||||
df.dimensions(),
|
||||
Field<Type>(df, cellMap)
|
||||
)
|
||||
);
|
||||
|
||||
return tresF;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
tmp<DimensionedField<Type, volMesh> > fvMeshSubset::interpolate
|
||||
(
|
||||
const DimensionedField<Type, volMesh>& df
|
||||
) const
|
||||
{
|
||||
return interpolate(df, subMesh(), cellMap());
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -23,6 +23,9 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvMeshTools.H"
|
||||
#include "processorCyclicPolyPatch.H"
|
||||
#include "polyBoundaryMeshEntries.H"
|
||||
#include "fvMeshTools.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -352,4 +355,264 @@ void Foam::fvMeshTools::reorderPatches
|
||||
}
|
||||
|
||||
|
||||
Foam::autoPtr<Foam::fvMesh> Foam::fvMeshTools::newMesh
|
||||
(
|
||||
const IOobject& io,
|
||||
const bool masterOnlyReading
|
||||
)
|
||||
{
|
||||
// Region name
|
||||
// ~~~~~~~~~~~
|
||||
|
||||
fileName meshSubDir;
|
||||
|
||||
if (io.name() == polyMesh::defaultRegion)
|
||||
{
|
||||
meshSubDir = polyMesh::meshSubDir;
|
||||
}
|
||||
else
|
||||
{
|
||||
meshSubDir = io.name()/polyMesh::meshSubDir;
|
||||
}
|
||||
|
||||
|
||||
fileName facesInstance;
|
||||
|
||||
// Patch types
|
||||
// ~~~~~~~~~~~
|
||||
// Read and scatter master patches (without reading master mesh!)
|
||||
|
||||
PtrList<entry> patchEntries;
|
||||
if (Pstream::master())
|
||||
{
|
||||
facesInstance = io.time().findInstance
|
||||
(
|
||||
meshSubDir,
|
||||
"faces",
|
||||
IOobject::MUST_READ
|
||||
);
|
||||
|
||||
patchEntries = polyBoundaryMeshEntries
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"boundary",
|
||||
facesInstance,
|
||||
meshSubDir,
|
||||
io.db(),
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
// Send patches
|
||||
for
|
||||
(
|
||||
int slave=Pstream::firstSlave();
|
||||
slave<=Pstream::lastSlave();
|
||||
slave++
|
||||
)
|
||||
{
|
||||
OPstream toSlave(Pstream::scheduled, slave);
|
||||
toSlave << patchEntries;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Receive patches
|
||||
IPstream fromMaster(Pstream::scheduled, Pstream::masterNo());
|
||||
fromMaster >> patchEntries;
|
||||
}
|
||||
|
||||
|
||||
Pstream::scatter(facesInstance);
|
||||
|
||||
// Dummy meshes
|
||||
// ~~~~~~~~~~~~
|
||||
|
||||
// Check who has a mesh
|
||||
const fileName meshDir = io.time().path()/facesInstance/meshSubDir;
|
||||
bool haveMesh = isDir(meshDir);
|
||||
if (masterOnlyReading && !Pstream::master())
|
||||
{
|
||||
haveMesh = false;
|
||||
}
|
||||
|
||||
|
||||
// Set up to read-if-present. Note: does not search for mesh so set
|
||||
// instance explicitly
|
||||
IOobject meshIO(io);
|
||||
meshIO.instance() = facesInstance;
|
||||
if (masterOnlyReading && !Pstream::master())
|
||||
{
|
||||
meshIO.readOpt() = IOobject::NO_READ;
|
||||
}
|
||||
else
|
||||
{
|
||||
meshIO.readOpt() = IOobject::READ_IF_PRESENT;
|
||||
}
|
||||
|
||||
|
||||
// Read mesh
|
||||
// ~~~~~~~~~
|
||||
// Now all processors read a mesh and use supplied points,faces etc
|
||||
// if there is none.
|
||||
// Note: fvSolution, fvSchemes are also using the supplied Ioobject so
|
||||
// on slave will be NO_READ, on master READ_IF_PRESENT. This will
|
||||
// conflict with e.g. timeStampMaster reading so switch off.
|
||||
|
||||
const regIOobject::fileCheckTypes oldCheckType =
|
||||
regIOobject::fileModificationChecking;
|
||||
regIOobject::fileModificationChecking = regIOobject::timeStamp;
|
||||
|
||||
autoPtr<fvMesh> meshPtr
|
||||
(
|
||||
new fvMesh
|
||||
(
|
||||
meshIO,
|
||||
xferCopy(pointField()),
|
||||
xferCopy(faceList()),
|
||||
xferCopy(labelList()),
|
||||
xferCopy(labelList())
|
||||
)
|
||||
);
|
||||
fvMesh& mesh = meshPtr();
|
||||
|
||||
regIOobject::fileModificationChecking = oldCheckType;
|
||||
|
||||
|
||||
|
||||
// Add patches
|
||||
// ~~~~~~~~~~~
|
||||
|
||||
|
||||
bool havePatches = mesh.boundary().size();
|
||||
reduce(havePatches, andOp<bool>());
|
||||
|
||||
if (!havePatches)
|
||||
{
|
||||
// There are one or more processors without full complement of
|
||||
// patches
|
||||
|
||||
DynamicList<polyPatch*> newPatches;
|
||||
|
||||
if (haveMesh) //Pstream::master())
|
||||
{
|
||||
forAll(mesh.boundary(), patchI)
|
||||
{
|
||||
newPatches.append
|
||||
(
|
||||
mesh.boundaryMesh()[patchI].clone(mesh.boundaryMesh()).ptr()
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
forAll(patchEntries, patchI)
|
||||
{
|
||||
const entry& e = patchEntries[patchI];
|
||||
const word type(e.dict().lookup("type"));
|
||||
|
||||
if
|
||||
(
|
||||
type == processorPolyPatch::typeName
|
||||
|| type == processorCyclicPolyPatch::typeName
|
||||
)
|
||||
{}
|
||||
else
|
||||
{
|
||||
dictionary patchDict(e.dict());
|
||||
patchDict.set("nFaces", 0);
|
||||
patchDict.set("startFace", 0);
|
||||
|
||||
newPatches.append
|
||||
(
|
||||
polyPatch::New
|
||||
(
|
||||
patchEntries[patchI].keyword(),
|
||||
patchDict,
|
||||
newPatches.size(),
|
||||
mesh.boundaryMesh()
|
||||
).ptr()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
mesh.removeFvBoundary();
|
||||
mesh.addFvPatches(newPatches);
|
||||
}
|
||||
|
||||
//Pout<< "patches:" << endl;
|
||||
//forAll(mesh.boundary(), patchI)
|
||||
//{
|
||||
// Pout<< " type" << mesh.boundary()[patchI].type()
|
||||
// << " size:" << mesh.boundary()[patchI].size()
|
||||
// << " start:" << mesh.boundary()[patchI].start() << endl;
|
||||
//}
|
||||
//Pout<< endl;
|
||||
|
||||
|
||||
// Determine zones
|
||||
// ~~~~~~~~~~~~~~~
|
||||
|
||||
wordList pointZoneNames(mesh.pointZones().names());
|
||||
Pstream::scatter(pointZoneNames);
|
||||
wordList faceZoneNames(mesh.faceZones().names());
|
||||
Pstream::scatter(faceZoneNames);
|
||||
wordList cellZoneNames(mesh.cellZones().names());
|
||||
Pstream::scatter(cellZoneNames);
|
||||
|
||||
if (!haveMesh)
|
||||
{
|
||||
// Add the zones. Make sure to remove the old dummy ones first
|
||||
mesh.pointZones().clear();
|
||||
mesh.faceZones().clear();
|
||||
mesh.cellZones().clear();
|
||||
|
||||
List<pointZone*> pz(pointZoneNames.size());
|
||||
forAll(pointZoneNames, i)
|
||||
{
|
||||
pz[i] = new pointZone
|
||||
(
|
||||
pointZoneNames[i],
|
||||
labelList(0),
|
||||
i,
|
||||
mesh.pointZones()
|
||||
);
|
||||
}
|
||||
List<faceZone*> fz(faceZoneNames.size());
|
||||
forAll(faceZoneNames, i)
|
||||
{
|
||||
fz[i] = new faceZone
|
||||
(
|
||||
faceZoneNames[i],
|
||||
labelList(0),
|
||||
boolList(0),
|
||||
i,
|
||||
mesh.faceZones()
|
||||
);
|
||||
}
|
||||
List<cellZone*> cz(cellZoneNames.size());
|
||||
forAll(cellZoneNames, i)
|
||||
{
|
||||
cz[i] = new cellZone
|
||||
(
|
||||
cellZoneNames[i],
|
||||
labelList(0),
|
||||
i,
|
||||
mesh.cellZones()
|
||||
);
|
||||
}
|
||||
|
||||
if (pz.size() && fz.size() && cz.size())
|
||||
{
|
||||
mesh.addZones(pz, fz, cz);
|
||||
}
|
||||
}
|
||||
|
||||
return meshPtr;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -112,7 +112,7 @@ public:
|
||||
//- Change patchField to zero on registered fields
|
||||
static void zeroPatchFields(fvMesh& mesh, const label patchI);
|
||||
|
||||
// -Reorder and remove trailing patches. If validBoundary call is parallel
|
||||
//- Reorder and remove trailing patches. If validBoundary call is parallel
|
||||
// synced and all add the same patch with same settings
|
||||
static void reorderPatches
|
||||
(
|
||||
@ -122,6 +122,18 @@ public:
|
||||
const bool validBoundary
|
||||
);
|
||||
|
||||
|
||||
//- Read mesh or create dummy mesh (0 cells, >0 patches). Works in two
|
||||
// modes according to masterOnlyReading:
|
||||
// true : all slaves create dummy mesh
|
||||
// false: checks locally for mesh directories and only creates dummy mesh
|
||||
// if not present
|
||||
static autoPtr<fvMesh> newMesh
|
||||
(
|
||||
const IOobject& io,
|
||||
const bool masterOnlyReading
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -31,7 +31,7 @@ Description
|
||||
cell centre and normal in direction of provided direction. Snaps cuts
|
||||
close to edge endpoints (close = snapTol * minEdgeLen) to vertices.
|
||||
|
||||
Currently determines cuts through edges (and edgeendpoints close to plane)
|
||||
Currently determines cuts through edges (and edge endpoints close to plane)
|
||||
in random order and then sorts them acc. to angle. Could be converted to
|
||||
use walk but problem is that face can be cut multiple times (since does
|
||||
not need to be convex). Another problem is that edges parallel to plane
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -25,17 +25,14 @@ License
|
||||
|
||||
#include "multiDirRefinement.H"
|
||||
#include "polyMesh.H"
|
||||
#include "polyTopoChanger.H"
|
||||
#include "Time.H"
|
||||
#include "undoableMeshCutter.H"
|
||||
#include "hexCellLooper.H"
|
||||
#include "geomCellLooper.H"
|
||||
#include "topoSet.H"
|
||||
#include "directions.H"
|
||||
#include "hexRef8.H"
|
||||
#include "mapPolyMesh.H"
|
||||
#include "polyTopoChange.H"
|
||||
#include "ListOps.H"
|
||||
#include "cellModeller.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
@ -265,7 +262,8 @@ void Foam::multiDirRefinement::refineHex8
|
||||
false
|
||||
),
|
||||
List<refinementHistory::splitCell8>(0),
|
||||
labelList(0)
|
||||
labelList(0),
|
||||
false
|
||||
) // refinement history
|
||||
);
|
||||
|
||||
|
||||
@ -2234,7 +2234,8 @@ Foam::hexRef8::hexRef8
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
List<refinementHistory::splitCell8>(0),
|
||||
labelList(0)
|
||||
labelList(0),
|
||||
false
|
||||
),
|
||||
faceRemover_(mesh_, GREAT), // merge boundary faces wherever possible
|
||||
savedPointLevel_(0),
|
||||
@ -0,0 +1,339 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "IOobject.H"
|
||||
#include "UList.H"
|
||||
|
||||
#include "hexRef8Data.H"
|
||||
#include "mapPolyMesh.H"
|
||||
#include "mapDistributePolyMesh.H"
|
||||
#include "polyMesh.H"
|
||||
#include "syncTools.H"
|
||||
#include "refinementHistory.H"
|
||||
#include "fvMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::hexRef8Data::hexRef8Data(const IOobject& io)
|
||||
{
|
||||
{
|
||||
IOobject rio(io);
|
||||
rio.rename("cellLevel");
|
||||
bool haveFile = returnReduce(rio.headerOk(), orOp<bool>());
|
||||
if (haveFile)
|
||||
{
|
||||
Info<< "Reading hexRef8 data : " << rio.name() << endl;
|
||||
cellLevelPtr_.reset(new labelIOList(rio));
|
||||
}
|
||||
}
|
||||
{
|
||||
IOobject rio(io);
|
||||
rio.rename("pointLevel");
|
||||
bool haveFile = returnReduce(rio.headerOk(), orOp<bool>());
|
||||
if (haveFile)
|
||||
{
|
||||
Info<< "Reading hexRef8 data : " << rio.name() << endl;
|
||||
pointLevelPtr_.reset(new labelIOList(rio));
|
||||
}
|
||||
}
|
||||
{
|
||||
IOobject rio(io);
|
||||
rio.rename("level0Edge");
|
||||
bool haveFile = returnReduce(rio.headerOk(), orOp<bool>());
|
||||
if (haveFile)
|
||||
{
|
||||
Info<< "Reading hexRef8 data : " << rio.name() << endl;
|
||||
level0EdgePtr_.reset(new uniformDimensionedScalarField(rio));
|
||||
}
|
||||
}
|
||||
{
|
||||
IOobject rio(io);
|
||||
rio.rename("refinementHistory");
|
||||
bool haveFile = returnReduce(rio.headerOk(), orOp<bool>());
|
||||
if (haveFile)
|
||||
{
|
||||
Info<< "Reading hexRef8 data : " << rio.name() << endl;
|
||||
refHistoryPtr_.reset(new refinementHistory(rio));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::hexRef8Data::hexRef8Data
|
||||
(
|
||||
const IOobject& io,
|
||||
const hexRef8Data& data,
|
||||
const labelList& cellMap,
|
||||
const labelList& pointMap
|
||||
)
|
||||
{
|
||||
if (data.cellLevelPtr_.valid())
|
||||
{
|
||||
IOobject rio(io);
|
||||
rio.rename(data.cellLevelPtr_().name());
|
||||
|
||||
cellLevelPtr_.reset
|
||||
(
|
||||
new labelIOList
|
||||
(
|
||||
rio,
|
||||
UIndirectList<label>(data.cellLevelPtr_(), cellMap)()
|
||||
)
|
||||
);
|
||||
}
|
||||
if (data.pointLevelPtr_.valid())
|
||||
{
|
||||
IOobject rio(io);
|
||||
rio.rename(data.pointLevelPtr_().name());
|
||||
|
||||
pointLevelPtr_.reset
|
||||
(
|
||||
new labelIOList
|
||||
(
|
||||
rio,
|
||||
UIndirectList<label>(data.pointLevelPtr_(), pointMap)()
|
||||
)
|
||||
);
|
||||
}
|
||||
if (data.level0EdgePtr_.valid())
|
||||
{
|
||||
IOobject rio(io);
|
||||
rio.rename(data.level0EdgePtr_().name());
|
||||
|
||||
level0EdgePtr_.reset
|
||||
(
|
||||
new uniformDimensionedScalarField(rio, data.level0EdgePtr_())
|
||||
);
|
||||
}
|
||||
if (data.refHistoryPtr_.valid())
|
||||
{
|
||||
IOobject rio(io);
|
||||
rio.rename(data.refHistoryPtr_().name());
|
||||
|
||||
refHistoryPtr_ = data.refHistoryPtr_().clone(rio, cellMap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::hexRef8Data::hexRef8Data
|
||||
(
|
||||
const IOobject& io,
|
||||
const UPtrList<const labelList>& cellMaps,
|
||||
const UPtrList<const labelList>& pointMaps,
|
||||
const UPtrList<const hexRef8Data>& procDatas
|
||||
)
|
||||
{
|
||||
const polyMesh& mesh = dynamic_cast<const polyMesh&>(io.db());
|
||||
|
||||
// cellLevel
|
||||
|
||||
if (procDatas[0].cellLevelPtr_.valid())
|
||||
{
|
||||
IOobject rio(io);
|
||||
rio.rename(procDatas[0].cellLevelPtr_().name());
|
||||
|
||||
cellLevelPtr_.reset(new labelIOList(rio, mesh.nCells()));
|
||||
labelList& cellLevel = cellLevelPtr_();
|
||||
|
||||
forAll(procDatas, procI)
|
||||
{
|
||||
const labelList& procCellLevel = procDatas[procI].cellLevelPtr_();
|
||||
UIndirectList<label>(cellLevel, cellMaps[procI]) = procCellLevel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// pointLevel
|
||||
|
||||
if (procDatas[0].pointLevelPtr_.valid())
|
||||
{
|
||||
IOobject rio(io);
|
||||
rio.rename(procDatas[0].pointLevelPtr_().name());
|
||||
|
||||
pointLevelPtr_.reset(new labelIOList(rio, mesh.nPoints()));
|
||||
labelList& pointLevel = pointLevelPtr_();
|
||||
|
||||
forAll(procDatas, procI)
|
||||
{
|
||||
const labelList& procPointLevel = procDatas[procI].pointLevelPtr_();
|
||||
UIndirectList<label>(pointLevel, pointMaps[procI]) = procPointLevel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// level0Edge
|
||||
|
||||
if (procDatas[0].level0EdgePtr_.valid())
|
||||
{
|
||||
IOobject rio(io);
|
||||
rio.rename(procDatas[0].level0EdgePtr_().name());
|
||||
|
||||
level0EdgePtr_.reset
|
||||
(
|
||||
new uniformDimensionedScalarField
|
||||
(
|
||||
rio,
|
||||
procDatas[0].level0EdgePtr_()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// refinementHistory
|
||||
|
||||
if (procDatas[0].refHistoryPtr_.valid())
|
||||
{
|
||||
IOobject rio(io);
|
||||
rio.rename(procDatas[0].refHistoryPtr_().name());
|
||||
|
||||
UPtrList<const refinementHistory> procRefs(procDatas.size());
|
||||
forAll(procDatas, i)
|
||||
{
|
||||
procRefs.set(i, &procDatas[i].refHistoryPtr_());
|
||||
}
|
||||
|
||||
refHistoryPtr_.reset
|
||||
(
|
||||
new refinementHistory
|
||||
(
|
||||
rio,
|
||||
cellMaps,
|
||||
procRefs
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::hexRef8Data::~hexRef8Data()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::hexRef8Data::sync(const IOobject& io)
|
||||
{
|
||||
const polyMesh& mesh = dynamic_cast<const polyMesh&>(io.db());
|
||||
|
||||
bool hasCellLevel = returnReduce(cellLevelPtr_.valid(), orOp<bool>());
|
||||
if (hasCellLevel && !cellLevelPtr_.valid())
|
||||
{
|
||||
IOobject rio(io);
|
||||
rio.rename("cellLevel");
|
||||
rio.readOpt() = IOobject::NO_READ;
|
||||
cellLevelPtr_.reset(new labelIOList(rio, labelList(mesh.nCells(), 0)));
|
||||
}
|
||||
|
||||
bool hasPointLevel = returnReduce(pointLevelPtr_.valid(), orOp<bool>());
|
||||
if (hasPointLevel && !pointLevelPtr_.valid())
|
||||
{
|
||||
IOobject rio(io);
|
||||
rio.rename("pointLevel");
|
||||
rio.readOpt() = IOobject::NO_READ;
|
||||
pointLevelPtr_.reset
|
||||
(
|
||||
new labelIOList(rio, labelList(mesh.nPoints(), 0))
|
||||
);
|
||||
}
|
||||
|
||||
bool hasLevel0Edge = returnReduce(level0EdgePtr_.valid(), orOp<bool>());
|
||||
if (hasLevel0Edge)
|
||||
{
|
||||
// Get master length
|
||||
scalar masterLen = level0EdgePtr_().value();
|
||||
Pstream::scatter(masterLen);
|
||||
if (!level0EdgePtr_.valid())
|
||||
{
|
||||
IOobject rio(io);
|
||||
rio.rename("level0Edge");
|
||||
rio.readOpt() = IOobject::NO_READ;
|
||||
level0EdgePtr_.reset
|
||||
(
|
||||
new uniformDimensionedScalarField
|
||||
(
|
||||
rio,
|
||||
dimensionedScalar("zero", dimLength, masterLen)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
bool hasHistory = returnReduce(refHistoryPtr_.valid(), orOp<bool>());
|
||||
if (hasHistory && !refHistoryPtr_.valid())
|
||||
{
|
||||
IOobject rio(io);
|
||||
rio.rename("refinementHistory");
|
||||
rio.readOpt() = IOobject::NO_READ;
|
||||
refHistoryPtr_.reset(new refinementHistory(rio, mesh.nCells(), true));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::hexRef8Data::distribute(const mapDistributePolyMesh& map)
|
||||
{
|
||||
if (cellLevelPtr_.valid())
|
||||
{
|
||||
map.cellMap().distribute(cellLevelPtr_());
|
||||
}
|
||||
if (pointLevelPtr_.valid())
|
||||
{
|
||||
map.pointMap().distribute(pointLevelPtr_());
|
||||
}
|
||||
|
||||
// No need to distribute the level0Edge
|
||||
|
||||
if (refHistoryPtr_.valid() && refHistoryPtr_().active())
|
||||
{
|
||||
refHistoryPtr_().distribute(map);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Foam::hexRef8Data::write() const
|
||||
{
|
||||
bool ok = true;
|
||||
if (cellLevelPtr_.valid())
|
||||
{
|
||||
ok = ok && cellLevelPtr_().write();
|
||||
}
|
||||
if (pointLevelPtr_.valid())
|
||||
{
|
||||
ok = ok && pointLevelPtr_().write();
|
||||
}
|
||||
if (level0EdgePtr_.valid())
|
||||
{
|
||||
ok = ok && level0EdgePtr_().write();
|
||||
}
|
||||
if (refHistoryPtr_.valid())
|
||||
{
|
||||
ok = ok && refHistoryPtr_().write();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,136 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::hexRef8Data
|
||||
|
||||
Description
|
||||
Various for reading/decomposing/reconstructing/distributing refinement
|
||||
data.
|
||||
|
||||
SourceFiles
|
||||
hexRef8Data.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef hexRef8Data_H
|
||||
#define hexRef8Data_H
|
||||
|
||||
#include "labelIOList.H"
|
||||
#include "uniformDimensionedFields.H"
|
||||
#include "UPtrList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward declaration of classes
|
||||
class mapPolyMesh;
|
||||
class mapDistributePolyMesh;
|
||||
class refinementHistory;
|
||||
class fvMesh;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class hexRef8Data Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class hexRef8Data
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
// Private data
|
||||
|
||||
autoPtr<labelIOList> cellLevelPtr_;
|
||||
|
||||
autoPtr<labelIOList> pointLevelPtr_;
|
||||
|
||||
autoPtr<uniformDimensionedScalarField> level0EdgePtr_;
|
||||
|
||||
autoPtr<refinementHistory> refHistoryPtr_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
hexRef8Data(const hexRef8Data&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const hexRef8Data&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct read. Has special provision for only some processors
|
||||
// having the files so can be used in redistribution.
|
||||
hexRef8Data(const IOobject& io);
|
||||
|
||||
//- Construct as subset
|
||||
hexRef8Data
|
||||
(
|
||||
const IOobject& io,
|
||||
const hexRef8Data&,
|
||||
const labelList& cellMap,
|
||||
const labelList& pointMap
|
||||
);
|
||||
|
||||
//- Construct from multiple hexRef8Data
|
||||
hexRef8Data
|
||||
(
|
||||
const IOobject& io,
|
||||
const UPtrList<const labelList>& cellMaps,
|
||||
const UPtrList<const labelList>& pointMaps,
|
||||
const UPtrList<const hexRef8Data>&
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
~hexRef8Data();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Parallel synchronise. This enforces valid objects on all processors
|
||||
// (even if they don't have a mesh). Used by redistributePar.
|
||||
void sync(const IOobject& io);
|
||||
|
||||
//- In-place distribute
|
||||
void distribute(const mapDistributePolyMesh&);
|
||||
|
||||
//- Write
|
||||
bool write() const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -23,12 +23,11 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "DynamicList.H"
|
||||
#include "refinementHistory.H"
|
||||
#include "ListOps.H"
|
||||
#include "mapPolyMesh.H"
|
||||
#include "mapDistributePolyMesh.H"
|
||||
#include "polyMesh.H"
|
||||
#include "syncTools.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
@ -39,6 +38,139 @@ defineTypeNameAndDebug(refinementHistory, 0);
|
||||
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
//- Construct null
|
||||
Foam::refinementHistory::splitCell8::splitCell8()
|
||||
:
|
||||
parent_(-1),
|
||||
addedCellsPtr_(NULL)
|
||||
{}
|
||||
|
||||
|
||||
//- Construct as child element of parent
|
||||
Foam::refinementHistory::splitCell8::splitCell8(const label parent)
|
||||
:
|
||||
parent_(parent),
|
||||
addedCellsPtr_(NULL)
|
||||
{}
|
||||
|
||||
|
||||
//- Construct from Istream
|
||||
Foam::refinementHistory::splitCell8::splitCell8(Istream& is)
|
||||
{
|
||||
is >> *this;
|
||||
}
|
||||
|
||||
|
||||
//- Construct as (deep) copy.
|
||||
Foam::refinementHistory::splitCell8::splitCell8(const splitCell8& sc)
|
||||
:
|
||||
parent_(sc.parent_),
|
||||
addedCellsPtr_
|
||||
(
|
||||
sc.addedCellsPtr_.valid()
|
||||
? new FixedList<label, 8>(sc.addedCellsPtr_())
|
||||
: NULL
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
|
||||
|
||||
//- Copy operator since autoPtr otherwise 'steals' storage.
|
||||
void Foam::refinementHistory::splitCell8::operator=(const splitCell8& s)
|
||||
{
|
||||
// Check for assignment to self
|
||||
if (this == &s)
|
||||
{
|
||||
FatalErrorIn("splitCell8::operator=(const Foam::splitCell8&)")
|
||||
<< "Attempted assignment to self"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
parent_ = s.parent_;
|
||||
|
||||
addedCellsPtr_.reset
|
||||
(
|
||||
s.addedCellsPtr_.valid()
|
||||
? new FixedList<label, 8>(s.addedCellsPtr_())
|
||||
: NULL
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::refinementHistory::splitCell8::operator==(const splitCell8& s) const
|
||||
{
|
||||
if (addedCellsPtr_.valid() != s.addedCellsPtr_.valid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (parent_ != s.parent_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (addedCellsPtr_.valid())
|
||||
{
|
||||
return addedCellsPtr_() == s.addedCellsPtr_();
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Foam::refinementHistory::splitCell8::operator!=(const splitCell8& s) const
|
||||
{
|
||||
return !operator==(s);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::Istream& Foam::operator>>(Istream& is, refinementHistory::splitCell8& sc)
|
||||
{
|
||||
labelList addedCells;
|
||||
|
||||
is >> sc.parent_ >> addedCells;
|
||||
|
||||
if (addedCells.size())
|
||||
{
|
||||
sc.addedCellsPtr_.reset(new FixedList<label, 8>(addedCells));
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.addedCellsPtr_.reset(NULL);
|
||||
}
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
Foam::Ostream& Foam::operator<<
|
||||
(
|
||||
Ostream& os,
|
||||
const refinementHistory::splitCell8& sc
|
||||
)
|
||||
{
|
||||
// Output as labelList so we can have 0 sized lists. Alternative is to
|
||||
// output as fixedlist with e.g. -1 elements and check for this upon
|
||||
// reading. However would cause much more data to be transferred.
|
||||
|
||||
if (sc.addedCellsPtr_.valid())
|
||||
{
|
||||
return os
|
||||
<< sc.parent_
|
||||
<< token::SPACE
|
||||
<< labelList(sc.addedCellsPtr_());
|
||||
}
|
||||
else
|
||||
{
|
||||
return os << sc.parent_ << token::SPACE << labelList(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
@ -106,89 +238,6 @@ void Foam::refinementHistory::writeDebug
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
//- Construct null
|
||||
Foam::refinementHistory::splitCell8::splitCell8()
|
||||
:
|
||||
parent_(-1),
|
||||
addedCellsPtr_(NULL)
|
||||
{}
|
||||
|
||||
|
||||
//- Construct as child element of parent
|
||||
Foam::refinementHistory::splitCell8::splitCell8(const label parent)
|
||||
:
|
||||
parent_(parent),
|
||||
addedCellsPtr_(NULL)
|
||||
{}
|
||||
|
||||
|
||||
//- Construct from Istream
|
||||
Foam::refinementHistory::splitCell8::splitCell8(Istream& is)
|
||||
{
|
||||
is >> *this;
|
||||
}
|
||||
|
||||
|
||||
//- Construct as (deep) copy.
|
||||
Foam::refinementHistory::splitCell8::splitCell8(const splitCell8& sc)
|
||||
:
|
||||
parent_(sc.parent_),
|
||||
addedCellsPtr_
|
||||
(
|
||||
sc.addedCellsPtr_.valid()
|
||||
? new FixedList<label, 8>(sc.addedCellsPtr_())
|
||||
: NULL
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||
|
||||
Foam::Istream& Foam::operator>>(Istream& is, refinementHistory::splitCell8& sc)
|
||||
{
|
||||
labelList addedCells;
|
||||
|
||||
is >> sc.parent_ >> addedCells;
|
||||
|
||||
if (addedCells.size())
|
||||
{
|
||||
sc.addedCellsPtr_.reset(new FixedList<label, 8>(addedCells));
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.addedCellsPtr_.reset(NULL);
|
||||
}
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
Foam::Ostream& Foam::operator<<
|
||||
(
|
||||
Ostream& os,
|
||||
const refinementHistory::splitCell8& sc
|
||||
)
|
||||
{
|
||||
// Output as labelList so we can have 0 sized lists. Alternative is to
|
||||
// output as fixedlist with e.g. -1 elements and check for this upon
|
||||
// reading. However would cause much more data to be transferred.
|
||||
|
||||
if (sc.addedCellsPtr_.valid())
|
||||
{
|
||||
return os
|
||||
<< sc.parent_
|
||||
<< token::SPACE
|
||||
<< labelList(sc.addedCellsPtr_());
|
||||
}
|
||||
else
|
||||
{
|
||||
return os << sc.parent_ << token::SPACE << labelList(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::refinementHistory::checkIndices() const
|
||||
{
|
||||
// Check indices.
|
||||
@ -325,11 +374,193 @@ void Foam::refinementHistory::markSplit
|
||||
}
|
||||
|
||||
|
||||
// Mark index and all its descendants
|
||||
void Foam::refinementHistory::mark
|
||||
(
|
||||
const label val,
|
||||
const label index,
|
||||
labelList& splitToVal
|
||||
) const
|
||||
{
|
||||
splitToVal[index] = val;
|
||||
|
||||
const splitCell8& split = splitCells_[index];
|
||||
|
||||
if (split.addedCellsPtr_.valid())
|
||||
{
|
||||
const FixedList<label, 8>& splits = split.addedCellsPtr_();
|
||||
|
||||
forAll(splits, i)
|
||||
{
|
||||
if (splits[i] >= 0)
|
||||
{
|
||||
mark(val, splits[i], splitToVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::label Foam::refinementHistory::markCommonCells
|
||||
(
|
||||
labelList& cellToCluster
|
||||
) const
|
||||
{
|
||||
label clusterI = 0;
|
||||
|
||||
labelList splitToCluster(splitCells_.size(), -1);
|
||||
|
||||
// Pass1: find top of all clusters
|
||||
forAll(visibleCells_, cellI)
|
||||
{
|
||||
label index = visibleCells_[cellI];
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
// Find highest ancestor
|
||||
while (splitCells_[index].parent_ != -1)
|
||||
{
|
||||
index = splitCells_[index].parent_;
|
||||
}
|
||||
|
||||
// Mark tree with clusterI
|
||||
if (splitToCluster[index] == -1)
|
||||
{
|
||||
mark(clusterI, index, splitToCluster);
|
||||
clusterI++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pass2: mark all cells with cluster
|
||||
cellToCluster.setSize(visibleCells_.size(), -1);
|
||||
|
||||
forAll(visibleCells_, cellI)
|
||||
{
|
||||
label index = visibleCells_[cellI];
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
cellToCluster[cellI] = splitToCluster[index];
|
||||
}
|
||||
}
|
||||
|
||||
return clusterI;
|
||||
}
|
||||
|
||||
|
||||
void Foam::refinementHistory::add
|
||||
(
|
||||
boolList& blockedFace,
|
||||
PtrList<labelList>& specifiedProcessorFaces,
|
||||
labelList& specifiedProcessor,
|
||||
List<labelPair>& explicitConnections
|
||||
) const
|
||||
{
|
||||
const polyMesh& mesh = dynamic_cast<const polyMesh&>(db());
|
||||
|
||||
blockedFace.setSize(mesh.nFaces(), true);
|
||||
|
||||
// Find common parent for all cells
|
||||
labelList cellToCluster;
|
||||
markCommonCells(cellToCluster);
|
||||
|
||||
|
||||
// Unblock all faces inbetween same cluster
|
||||
|
||||
label nUnblocked = 0;
|
||||
|
||||
forAll(mesh.faceNeighbour(), faceI)
|
||||
{
|
||||
label ownCluster = cellToCluster[mesh.faceOwner()[faceI]];
|
||||
label neiCluster = cellToCluster[mesh.faceNeighbour()[faceI]];
|
||||
|
||||
if (ownCluster != -1 && ownCluster == neiCluster)
|
||||
{
|
||||
if (blockedFace[faceI])
|
||||
{
|
||||
blockedFace[faceI] = false;
|
||||
nUnblocked++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (refinementHistory::debug)
|
||||
{
|
||||
reduce(nUnblocked, sumOp<label>());
|
||||
Info<< type() << " : unblocked " << nUnblocked << " faces" << endl;
|
||||
}
|
||||
|
||||
syncTools::syncFaceList(mesh, blockedFace, andEqOp<bool>());
|
||||
}
|
||||
|
||||
|
||||
void Foam::refinementHistory::apply
|
||||
(
|
||||
const boolList& blockedFace,
|
||||
const PtrList<labelList>& specifiedProcessorFaces,
|
||||
const labelList& specifiedProcessor,
|
||||
const List<labelPair>& explicitConnections,
|
||||
labelList& decomposition
|
||||
) const
|
||||
{
|
||||
const polyMesh& mesh = dynamic_cast<const polyMesh&>(db());
|
||||
|
||||
// Find common parent for all cells
|
||||
labelList cellToCluster;
|
||||
label nClusters = markCommonCells(cellToCluster);
|
||||
|
||||
// Unblock all faces inbetween same cluster
|
||||
|
||||
|
||||
labelList clusterToProc(nClusters, -1);
|
||||
|
||||
label nChanged = 0;
|
||||
|
||||
forAll(mesh.faceNeighbour(), faceI)
|
||||
{
|
||||
label own = mesh.faceOwner()[faceI];
|
||||
label nei = mesh.faceNeighbour()[faceI];
|
||||
|
||||
label ownCluster = cellToCluster[own];
|
||||
label neiCluster = cellToCluster[nei];
|
||||
|
||||
if (ownCluster != -1 && ownCluster == neiCluster)
|
||||
{
|
||||
if (clusterToProc[ownCluster] == -1)
|
||||
{
|
||||
clusterToProc[ownCluster] = decomposition[own];
|
||||
}
|
||||
|
||||
if (decomposition[own] != clusterToProc[ownCluster])
|
||||
{
|
||||
decomposition[own] = clusterToProc[ownCluster];
|
||||
nChanged++;
|
||||
}
|
||||
if (decomposition[nei] != clusterToProc[ownCluster])
|
||||
{
|
||||
decomposition[nei] = clusterToProc[ownCluster];
|
||||
nChanged++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (refinementHistory::debug)
|
||||
{
|
||||
reduce(nChanged, sumOp<label>());
|
||||
Info<< type() << " : changed decomposition on " << nChanged
|
||||
<< " cells" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::refinementHistory::refinementHistory(const IOobject& io)
|
||||
:
|
||||
regIOobject(io)
|
||||
regIOobject(io),
|
||||
refCount(),
|
||||
active_(false)
|
||||
{
|
||||
// Temporary warning
|
||||
if (io.readOpt() == IOobject::MUST_READ_IF_MODIFIED)
|
||||
@ -353,6 +584,11 @@ Foam::refinementHistory::refinementHistory(const IOobject& io)
|
||||
close();
|
||||
}
|
||||
|
||||
// When running in redistributPar + READ_IF_PRESENT it can happen
|
||||
// that some processors do have refinementHistory and some don't so
|
||||
// test for active has to be outside of above condition.
|
||||
active_ = (returnReduce(visibleCells_.size(), sumOp<label>()) > 0);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "refinementHistory::refinementHistory :"
|
||||
@ -369,10 +605,13 @@ Foam::refinementHistory::refinementHistory
|
||||
(
|
||||
const IOobject& io,
|
||||
const List<splitCell8>& splitCells,
|
||||
const labelList& visibleCells
|
||||
const labelList& visibleCells,
|
||||
const bool active
|
||||
)
|
||||
:
|
||||
regIOobject(io),
|
||||
refCount(),
|
||||
active_(active),
|
||||
splitCells_(splitCells),
|
||||
freeSplitCells_(0),
|
||||
visibleCells_(visibleCells)
|
||||
@ -422,6 +661,8 @@ Foam::refinementHistory::refinementHistory
|
||||
)
|
||||
:
|
||||
regIOobject(io),
|
||||
refCount(),
|
||||
active_(false),
|
||||
freeSplitCells_(0)
|
||||
{
|
||||
// Temporary warning
|
||||
@ -429,8 +670,70 @@ Foam::refinementHistory::refinementHistory
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"refinementHistory::refinementHistory"
|
||||
"(const IOobject&, const label)"
|
||||
"refinementHistory::refinementHistory(const IOobject&)"
|
||||
) << "Specified IOobject::MUST_READ_IF_MODIFIED but class"
|
||||
<< " does not support automatic rereading."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
io.readOpt() == IOobject::MUST_READ
|
||||
|| io.readOpt() == IOobject::MUST_READ_IF_MODIFIED
|
||||
|| (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
|
||||
)
|
||||
{
|
||||
readStream(typeName) >> *this;
|
||||
close();
|
||||
}
|
||||
else
|
||||
{
|
||||
visibleCells_.setSize(nCells);
|
||||
splitCells_.setCapacity(nCells);
|
||||
|
||||
for (label cellI = 0; cellI < nCells; cellI++)
|
||||
{
|
||||
visibleCells_[cellI] = cellI;
|
||||
splitCells_.append(splitCell8());
|
||||
}
|
||||
}
|
||||
|
||||
active_ = (returnReduce(visibleCells_.size(), sumOp<label>()) > 0);
|
||||
|
||||
|
||||
// Check indices.
|
||||
checkIndices();
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "refinementHistory::refinementHistory :"
|
||||
<< " constructed history from IOobject or initial size :"
|
||||
<< " splitCells:" << splitCells_.size()
|
||||
<< " visibleCells:" << visibleCells_.size()
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Construct from initial number of cells (all visible)
|
||||
Foam::refinementHistory::refinementHistory
|
||||
(
|
||||
const IOobject& io,
|
||||
const label nCells,
|
||||
const bool active
|
||||
)
|
||||
:
|
||||
regIOobject(io),
|
||||
refCount(),
|
||||
active_(active),
|
||||
freeSplitCells_(0)
|
||||
{
|
||||
// Temporary warning
|
||||
if (io.readOpt() == IOobject::MUST_READ_IF_MODIFIED)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"refinementHistory::refinementHistory(const IOobject&)"
|
||||
) << "Specified IOobject::MUST_READ_IF_MODIFIED but class"
|
||||
<< " does not support automatic rereading."
|
||||
<< endl;
|
||||
@ -480,6 +783,8 @@ Foam::refinementHistory::refinementHistory
|
||||
)
|
||||
:
|
||||
regIOobject(io),
|
||||
refCount(),
|
||||
active_(rh.active_),
|
||||
splitCells_(rh.splitCells()),
|
||||
freeSplitCells_(rh.freeSplitCells()),
|
||||
visibleCells_(rh.visibleCells())
|
||||
@ -492,14 +797,138 @@ Foam::refinementHistory::refinementHistory
|
||||
}
|
||||
|
||||
|
||||
// Construct from multiple
|
||||
Foam::refinementHistory::refinementHistory
|
||||
(
|
||||
const IOobject& io,
|
||||
const UPtrList<const labelList>& cellMaps,
|
||||
const UPtrList<const refinementHistory>& refs
|
||||
)
|
||||
:
|
||||
regIOobject(io),
|
||||
refCount(),
|
||||
active_(false)
|
||||
{
|
||||
if
|
||||
(
|
||||
io.readOpt() == IOobject::MUST_READ
|
||||
|| io.readOpt() == IOobject::MUST_READ_IF_MODIFIED
|
||||
|| (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
|
||||
)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"refinementHistory::refinementHistory(const IOobject&"
|
||||
", const labelListList&, const PtrList<refinementHistory>&)"
|
||||
) << "read option IOobject::MUST_READ, READ_IF_PRESENT or "
|
||||
<< "MUST_READ_IF_MODIFIED"
|
||||
<< " suggests that a read constructor would be more appropriate."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
const polyMesh& mesh = dynamic_cast<const polyMesh&>(db());
|
||||
|
||||
|
||||
// Determine offsets into splitCells
|
||||
labelList offsets(refs.size()+1);
|
||||
offsets[0] = 0;
|
||||
forAll(refs, refI)
|
||||
{
|
||||
const DynamicList<splitCell8>& subSplits = refs[refI].splitCells();
|
||||
offsets[refI+1] = offsets[refI]+subSplits.size();
|
||||
}
|
||||
|
||||
// Construct merged splitCells
|
||||
splitCells_.setSize(offsets.last());
|
||||
forAll(refs, refI)
|
||||
{
|
||||
const DynamicList<splitCell8>& subSplits = refs[refI].splitCells();
|
||||
forAll(subSplits, i)
|
||||
{
|
||||
splitCell8& newSplit = splitCells_[offsets[refI]+i];
|
||||
|
||||
// Copy
|
||||
newSplit = subSplits[i];
|
||||
|
||||
// Offset indices
|
||||
if (newSplit.parent_ >= 0)
|
||||
{
|
||||
newSplit.parent_ += offsets[refI];
|
||||
}
|
||||
|
||||
if (newSplit.addedCellsPtr_.valid())
|
||||
{
|
||||
FixedList<label, 8>& splits = newSplit.addedCellsPtr_();
|
||||
|
||||
forAll(splits, i)
|
||||
{
|
||||
if (splits[i] >= 0)
|
||||
{
|
||||
splits[i] += offsets[refI];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Construct merged visibleCells
|
||||
visibleCells_.setSize(mesh.nCells(), -1);
|
||||
forAll(refs, refI)
|
||||
{
|
||||
const labelList& cellMap = cellMaps[refI];
|
||||
const labelList& subVis = refs[refI].visibleCells();
|
||||
|
||||
forAll(subVis, i)
|
||||
{
|
||||
label& newVis = visibleCells_[cellMap[i]];
|
||||
|
||||
newVis = subVis[i];
|
||||
if (newVis >= 0)
|
||||
{
|
||||
newVis += offsets[refI];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Is active if any of the refinementHistories is active (assumes active
|
||||
// flag parallel synchronised)
|
||||
active_ = false;
|
||||
forAll(refs, refI)
|
||||
{
|
||||
if (refs[refI].active())
|
||||
{
|
||||
active_ = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check indices.
|
||||
checkIndices();
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "refinementHistory::refinementHistory :"
|
||||
<< " constructed history from multiple refinementHistories :"
|
||||
<< " splitCells:" << splitCells_.size()
|
||||
<< " visibleCells:" << visibleCells_.size()
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Construct from Istream
|
||||
Foam::refinementHistory::refinementHistory(const IOobject& io, Istream& is)
|
||||
:
|
||||
regIOobject(io),
|
||||
refCount(),
|
||||
splitCells_(is),
|
||||
freeSplitCells_(0),
|
||||
visibleCells_(is)
|
||||
{
|
||||
active_ = (returnReduce(visibleCells_.size(), sumOp<label>()) > 0);
|
||||
|
||||
// Check indices.
|
||||
checkIndices();
|
||||
|
||||
@ -516,6 +945,192 @@ Foam::refinementHistory::refinementHistory(const IOobject& io, Istream& is)
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::autoPtr<Foam::refinementHistory> Foam::refinementHistory::clone
|
||||
(
|
||||
const IOobject& io,
|
||||
// Per visible cell the processor it is going to
|
||||
const labelList& decomposition,
|
||||
// Per splitCell entry the processor it moves to
|
||||
const labelList& splitCellProc,
|
||||
// Per splitCell entry the number of live cells that move to that processor
|
||||
const labelList& splitCellNum,
|
||||
|
||||
const label procI,
|
||||
|
||||
// From old to new splitCells
|
||||
labelList& oldToNewSplit
|
||||
) const
|
||||
{
|
||||
oldToNewSplit.setSize(splitCells_.size());
|
||||
oldToNewSplit = -1;
|
||||
|
||||
// Compacted splitCells
|
||||
DynamicList<splitCell8> newSplitCells(splitCells_.size());
|
||||
|
||||
// Loop over all entries. Note: could recurse like countProc so only
|
||||
// visit used entries but is probably not worth it.
|
||||
|
||||
forAll(splitCells_, index)
|
||||
{
|
||||
if (splitCellProc[index] == procI && splitCellNum[index] == 8)
|
||||
{
|
||||
// Entry moves in its whole to procI
|
||||
oldToNewSplit[index] = newSplitCells.size();
|
||||
newSplitCells.append(splitCells_[index]);
|
||||
}
|
||||
}
|
||||
|
||||
// Add live cells that are subsetted.
|
||||
forAll(visibleCells_, cellI)
|
||||
{
|
||||
label index = visibleCells_[cellI];
|
||||
|
||||
if (index >= 0 && decomposition[cellI] == procI)
|
||||
{
|
||||
label parent = splitCells_[index].parent_;
|
||||
|
||||
// Create new splitCell with parent
|
||||
oldToNewSplit[index] = newSplitCells.size();
|
||||
newSplitCells.append(splitCell8(parent));
|
||||
}
|
||||
}
|
||||
|
||||
//forAll(oldToNewSplit, index)
|
||||
//{
|
||||
// Pout<< "old:" << index << " new:" << oldToNewSplit[index]
|
||||
// << endl;
|
||||
//}
|
||||
|
||||
newSplitCells.shrink();
|
||||
|
||||
// Renumber contents of newSplitCells
|
||||
forAll(newSplitCells, index)
|
||||
{
|
||||
splitCell8& split = newSplitCells[index];
|
||||
|
||||
if (split.parent_ >= 0)
|
||||
{
|
||||
split.parent_ = oldToNewSplit[split.parent_];
|
||||
}
|
||||
if (split.addedCellsPtr_.valid())
|
||||
{
|
||||
FixedList<label, 8>& splits = split.addedCellsPtr_();
|
||||
|
||||
forAll(splits, i)
|
||||
{
|
||||
if (splits[i] >= 0)
|
||||
{
|
||||
splits[i] = oldToNewSplit[splits[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Count number of cells
|
||||
label nSub = 0;
|
||||
forAll(decomposition, cellI)
|
||||
{
|
||||
if (decomposition[cellI] == procI)
|
||||
{
|
||||
nSub++;
|
||||
}
|
||||
}
|
||||
|
||||
labelList newVisibleCells(nSub);
|
||||
nSub = 0;
|
||||
|
||||
forAll(visibleCells_, cellI)
|
||||
{
|
||||
if (decomposition[cellI] == procI)
|
||||
{
|
||||
label index = visibleCells_[cellI];
|
||||
if (index >= 0)
|
||||
{
|
||||
index = oldToNewSplit[index];
|
||||
}
|
||||
newVisibleCells[nSub++] = index;
|
||||
}
|
||||
}
|
||||
|
||||
return autoPtr<refinementHistory>
|
||||
(
|
||||
new refinementHistory
|
||||
(
|
||||
io,
|
||||
newSplitCells,
|
||||
newVisibleCells,
|
||||
active_
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Foam::autoPtr<Foam::refinementHistory> Foam::refinementHistory::clone
|
||||
(
|
||||
const IOobject& io,
|
||||
const labelList& cellMap
|
||||
) const
|
||||
{
|
||||
if (active_)
|
||||
{
|
||||
// Mark selected cells with '1'
|
||||
labelList decomposition(visibleCells_.size(), 0);
|
||||
forAll(cellMap, i)
|
||||
{
|
||||
decomposition[cellMap[i]] = 1;
|
||||
}
|
||||
|
||||
|
||||
// Per splitCell entry the processor it moves to
|
||||
labelList splitCellProc(splitCells_.size(), -1);
|
||||
// Per splitCell entry the number of live cells that move to that
|
||||
// processor
|
||||
labelList splitCellNum(splitCells_.size(), 0);
|
||||
|
||||
forAll(visibleCells_, cellI)
|
||||
{
|
||||
label index = visibleCells_[cellI];
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
countProc
|
||||
(
|
||||
splitCells_[index].parent_,
|
||||
decomposition[cellI],
|
||||
splitCellProc,
|
||||
splitCellNum
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
labelList oldToNewSplit;
|
||||
return clone
|
||||
(
|
||||
io,
|
||||
decomposition,
|
||||
splitCellProc,
|
||||
splitCellNum,
|
||||
1, //procI,
|
||||
oldToNewSplit
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return autoPtr<refinementHistory>
|
||||
(
|
||||
new refinementHistory
|
||||
(
|
||||
io,
|
||||
DynamicList<splitCell8>(0),
|
||||
labelList(0),
|
||||
false
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::refinementHistory::resize(const label size)
|
||||
{
|
||||
label oldSize = visibleCells_.size();
|
||||
@ -720,9 +1335,6 @@ void Foam::refinementHistory::distribute(const mapDistributePolyMesh& map)
|
||||
}
|
||||
}
|
||||
|
||||
//Pout<< "refinementHistory::distribute :"
|
||||
// << " destination:" << destination << endl;
|
||||
|
||||
// Per splitCell entry the processor it moves to
|
||||
labelList splitCellProc(splitCells_.size(), -1);
|
||||
// Per splitCell entry the number of live cells that move to that processor
|
||||
@ -768,21 +1380,11 @@ void Foam::refinementHistory::distribute(const mapDistributePolyMesh& map)
|
||||
|
||||
forAll(splitCells_, index)
|
||||
{
|
||||
// Pout<< "oldCell:" << index
|
||||
// << " proc:" << splitCellProc[index]
|
||||
// << " nCells:" << splitCellNum[index]
|
||||
// << endl;
|
||||
|
||||
if (splitCellProc[index] == procI && splitCellNum[index] == 8)
|
||||
{
|
||||
// Entry moves in its whole to procI
|
||||
oldToNew[index] = newSplitCells.size();
|
||||
newSplitCells.append(splitCells_[index]);
|
||||
|
||||
//Pout<< "Added oldCell " << index
|
||||
// << " info " << newSplitCells.last()
|
||||
// << " at position " << newSplitCells.size()-1
|
||||
// << endl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -795,10 +1397,6 @@ void Foam::refinementHistory::distribute(const mapDistributePolyMesh& map)
|
||||
{
|
||||
label parent = splitCells_[index].parent_;
|
||||
|
||||
//Pout<< "Adding refined cell " << cellI
|
||||
// << " since moves to "
|
||||
// << procI << " old parent:" << parent << endl;
|
||||
|
||||
// Create new splitCell with parent
|
||||
oldToNew[index] = newSplitCells.size();
|
||||
newSplitCells.append(splitCell8(parent));
|
||||
@ -871,7 +1469,9 @@ void Foam::refinementHistory::distribute(const mapDistributePolyMesh& map)
|
||||
// Remove all entries. Leave storage intact.
|
||||
splitCells_.clear();
|
||||
|
||||
visibleCells_.setSize(map.mesh().nCells());
|
||||
const polyMesh& mesh = dynamic_cast<const polyMesh&>(db());
|
||||
|
||||
visibleCells_.setSize(mesh.nCells());
|
||||
visibleCells_ = -1;
|
||||
|
||||
for (label procI = 0; procI < Pstream::nProcs(); procI++)
|
||||
@ -1160,6 +1760,17 @@ void Foam::refinementHistory::combineCells
|
||||
}
|
||||
|
||||
|
||||
bool Foam::refinementHistory::read()
|
||||
{
|
||||
bool ok = readData(readStream(typeName));
|
||||
close();
|
||||
|
||||
active_ = (returnReduce(visibleCells_.size(), sumOp<label>()) > 0);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::refinementHistory::readData(Istream& is)
|
||||
{
|
||||
is >> *this;
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -71,12 +71,14 @@ SourceFiles
|
||||
#ifndef refinementHistory_H
|
||||
#define refinementHistory_H
|
||||
|
||||
#include "UPtrList.H"
|
||||
#include "DynamicList.H"
|
||||
#include "labelList.H"
|
||||
#include "FixedList.H"
|
||||
#include "SLList.H"
|
||||
#include "autoPtr.H"
|
||||
#include "regIOobject.H"
|
||||
#include "boolList.H"
|
||||
#include "labelPair.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -93,7 +95,8 @@ class mapDistributePolyMesh;
|
||||
|
||||
class refinementHistory
|
||||
:
|
||||
public regIOobject
|
||||
public regIOobject,
|
||||
public refCount
|
||||
{
|
||||
public:
|
||||
|
||||
@ -122,50 +125,11 @@ public:
|
||||
splitCell8(const splitCell8&);
|
||||
|
||||
//- Copy operator since autoPtr otherwise 'steals' storage.
|
||||
void operator=(const splitCell8& s)
|
||||
{
|
||||
// Check for assignment to self
|
||||
if (this == &s)
|
||||
{
|
||||
FatalErrorIn("splitCell8::operator=(const Foam::splitCell8&)")
|
||||
<< "Attempted assignment to self"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
void operator=(const splitCell8& s);
|
||||
|
||||
parent_ = s.parent_;
|
||||
bool operator==(const splitCell8& s) const;
|
||||
|
||||
addedCellsPtr_.reset
|
||||
(
|
||||
s.addedCellsPtr_.valid()
|
||||
? new FixedList<label, 8>(s.addedCellsPtr_())
|
||||
: NULL
|
||||
);
|
||||
}
|
||||
|
||||
bool operator==(const splitCell8& s) const
|
||||
{
|
||||
if (addedCellsPtr_.valid() != s.addedCellsPtr_.valid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (parent_ != s.parent_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (addedCellsPtr_.valid())
|
||||
{
|
||||
return addedCellsPtr_() == s.addedCellsPtr_();
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator!=(const splitCell8& s) const
|
||||
{
|
||||
return !operator==(s);
|
||||
}
|
||||
bool operator!=(const splitCell8& s) const;
|
||||
|
||||
friend Istream& operator>>(Istream&, splitCell8&);
|
||||
friend Ostream& operator<<(Ostream&, const splitCell8&);
|
||||
@ -176,6 +140,9 @@ private:
|
||||
|
||||
// Private data
|
||||
|
||||
//- Is active?
|
||||
bool active_;
|
||||
|
||||
//- Storage for splitCells
|
||||
DynamicList<splitCell8> splitCells_;
|
||||
|
||||
@ -226,6 +193,15 @@ private:
|
||||
labelList& splitCellNum
|
||||
) const;
|
||||
|
||||
// For distribution:
|
||||
|
||||
//- Mark index and all its descendants
|
||||
void mark(const label, const label, labelList&) const;
|
||||
|
||||
//- Mark cells according to top parent. Return number of clusters
|
||||
// (set of cells originating from same parent)
|
||||
label markCommonCells(labelList& cellToCluster) const;
|
||||
|
||||
public:
|
||||
|
||||
// Declare name of the class and its debug switch
|
||||
@ -234,25 +210,47 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct (read) given an IOobject
|
||||
//- Construct (read) given an IOobject. If global number of visible
|
||||
// cells > 0 becomes active
|
||||
refinementHistory(const IOobject&);
|
||||
|
||||
//- Construct (read) or construct null
|
||||
//- Construct (read) or construct from components
|
||||
refinementHistory
|
||||
(
|
||||
const IOobject&,
|
||||
const List<splitCell8>& splitCells,
|
||||
const labelList& visibleCells
|
||||
const labelList& visibleCells,
|
||||
const bool active
|
||||
);
|
||||
|
||||
//- Construct (read) or construct from initial number of cells
|
||||
// (all visible)
|
||||
// (all visible). If global number of visible
|
||||
// cells > 0 becomes active
|
||||
refinementHistory(const IOobject&, const label nCells);
|
||||
|
||||
//- Construct (read) or construct from initial number of cells
|
||||
// (all visible) and active flag
|
||||
refinementHistory
|
||||
(
|
||||
const IOobject&,
|
||||
const label nCells,
|
||||
const bool active
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
refinementHistory(const IOobject&, const refinementHistory&);
|
||||
|
||||
//- Construct from Istream
|
||||
//- Construct from multiple refinement histories. If global number of
|
||||
// visible cells > 0 becomes active
|
||||
refinementHistory
|
||||
(
|
||||
const IOobject&,
|
||||
const UPtrList<const labelList>& cellMaps,
|
||||
const UPtrList<const refinementHistory>&
|
||||
);
|
||||
|
||||
//- Construct from Istream. If global number of
|
||||
// visible cells > 0 becomes active
|
||||
refinementHistory(const IOobject&, Istream&);
|
||||
|
||||
|
||||
@ -278,12 +276,16 @@ public:
|
||||
return freeSplitCells_;
|
||||
}
|
||||
|
||||
//- Is there unrefinement history. Note that this will fall over if
|
||||
// there are 0 cells in the mesh. But this gives problems with
|
||||
// lots of other programs anyway.
|
||||
//- Is there unrefinement history?
|
||||
bool active() const
|
||||
{
|
||||
return visibleCells_.size() > 0;
|
||||
return active_;
|
||||
}
|
||||
|
||||
//- Is there unrefinement history?
|
||||
bool& active()
|
||||
{
|
||||
return active_;
|
||||
}
|
||||
|
||||
//- Get parent of cell
|
||||
@ -314,6 +316,23 @@ public:
|
||||
const labelList& combinedCells
|
||||
);
|
||||
|
||||
//- Low level clone
|
||||
autoPtr<refinementHistory> clone
|
||||
(
|
||||
const IOobject& io,
|
||||
const labelList& decomposition,
|
||||
const labelList& splitCellProc,
|
||||
const labelList& splitCellNum,
|
||||
const label procI,
|
||||
labelList& oldToNewSplit
|
||||
) const;
|
||||
|
||||
//- Create clone from subset
|
||||
autoPtr<refinementHistory> clone
|
||||
(
|
||||
const IOobject& io,
|
||||
const labelList& cellMap
|
||||
) const;
|
||||
|
||||
//- Update numbering for mesh changes
|
||||
void updateMesh(const mapPolyMesh&);
|
||||
@ -331,7 +350,6 @@ public:
|
||||
// handle parts recombined in multiple passes.
|
||||
void distribute(const mapDistributePolyMesh&);
|
||||
|
||||
|
||||
//- Compact splitCells_. Removes all freeSplitCells_ elements.
|
||||
void compact();
|
||||
|
||||
@ -343,20 +361,44 @@ public:
|
||||
void writeDebug() const;
|
||||
|
||||
|
||||
//- ReadData function required for regIOobject read operation
|
||||
//- Read object. If global number of visible cells > 0 becomes active
|
||||
virtual bool read();
|
||||
|
||||
//- ReadData function required for regIOobject read operation. Note:
|
||||
// does not do a reduction - does not set active_ flag
|
||||
virtual bool readData(Istream&);
|
||||
|
||||
//- WriteData function required for regIOobject write operation
|
||||
virtual bool writeData(Ostream&) const;
|
||||
|
||||
// Helpers for decompositionConstraint
|
||||
|
||||
// Friend Functions
|
||||
//- Add my decomposition constraints
|
||||
void add
|
||||
(
|
||||
boolList& blockedFace,
|
||||
PtrList<labelList>& specifiedProcessorFaces,
|
||||
labelList& specifiedProcessor,
|
||||
List<labelPair>& explicitConnections
|
||||
) const;
|
||||
|
||||
//- Apply any additional post-decomposition constraints
|
||||
void apply
|
||||
(
|
||||
const boolList& blockedFace,
|
||||
const PtrList<labelList>& specifiedProcessorFaces,
|
||||
const labelList& specifiedProcessor,
|
||||
const List<labelPair>& explicitConnections,
|
||||
labelList& decomposition
|
||||
) const;
|
||||
|
||||
// Friend Operators
|
||||
|
||||
// IOstream Operators
|
||||
|
||||
//- Istream operator. Note: does not do a reduction - does not set
|
||||
// active_ flag
|
||||
friend Istream& operator>>(Istream&, refinementHistory&);
|
||||
|
||||
friend Ostream& operator<<(Ostream&, const refinementHistory&);
|
||||
};
|
||||
|
||||
@ -2,7 +2,6 @@ fvMesh/fvMeshGeometry.C
|
||||
fvMesh/fvMesh.C
|
||||
|
||||
fvMesh/singleCellFvMesh/singleCellFvMesh.C
|
||||
fvMesh/fvMeshSubset/fvMeshSubset.C
|
||||
|
||||
fvBoundaryMesh = fvMesh/fvBoundaryMesh
|
||||
$(fvBoundaryMesh)/fvBoundaryMesh.C
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -60,16 +60,27 @@ Foam::fixedFluxPressureFvPatchScalarField::fixedFluxPressureFvPatchScalarField
|
||||
gradient().map(ptf.gradient(), mapper);
|
||||
|
||||
// Evaluate the value field from the gradient if the internal field is valid
|
||||
if (notNull(iF) && iF.size())
|
||||
if (notNull(iF))
|
||||
{
|
||||
if (iF.size())
|
||||
{
|
||||
// Note: cannot ask for nf() if zero faces
|
||||
|
||||
scalarField::operator=
|
||||
(
|
||||
//patchInternalField() + gradient()/patch().deltaCoeffs()
|
||||
// ***HGW Hack to avoid the construction of mesh.deltaCoeffs
|
||||
// which fails for AMI patches for some mapping operations
|
||||
patchInternalField() + gradient()*(patch().nf() & patch().delta())
|
||||
patchInternalField()
|
||||
+ gradient()*(patch().nf() & patch().delta())
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Enforce mapping of values so we have a valid starting value
|
||||
this->map(ptf, mapper);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -272,7 +272,7 @@ void timeVaryingMappedFixedValueFvPatchField<Type>::checkTable()
|
||||
IOobject
|
||||
(
|
||||
"points",
|
||||
this->db().time().constant(),
|
||||
this->db().time().caseConstant(),
|
||||
"boundaryData"/this->patch().name(),
|
||||
this->db(),
|
||||
IOobject::MUST_READ,
|
||||
@ -392,7 +392,7 @@ void timeVaryingMappedFixedValueFvPatchField<Type>::checkTable()
|
||||
IOobject
|
||||
(
|
||||
fieldTableName_,
|
||||
this->db().time().constant(),
|
||||
this->db().time().caseConstant(),
|
||||
"boundaryData"
|
||||
/this->patch().name()
|
||||
/sampleTimes_[startSampleTime_].name(),
|
||||
@ -450,7 +450,7 @@ void timeVaryingMappedFixedValueFvPatchField<Type>::checkTable()
|
||||
IOobject
|
||||
(
|
||||
fieldTableName_,
|
||||
this->db().time().constant(),
|
||||
this->db().time().caseConstant(),
|
||||
"boundaryData"
|
||||
/this->patch().name()
|
||||
/sampleTimes_[endSampleTime_].name(),
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -98,7 +98,7 @@ Foam::fvPatchField<Type>::fvPatchField
|
||||
patchType_(ptf.patchType_)
|
||||
{
|
||||
// For unmapped faces set to internal field value (zero-gradient)
|
||||
if (notNull(iF) && iF.size())
|
||||
if (notNull(iF) && mapper.hasUnmapped())
|
||||
{
|
||||
fvPatchField<Type>::operator=(this->patchInternalField());
|
||||
}
|
||||
@ -233,7 +233,7 @@ void Foam::fvPatchField<Type>::autoMap
|
||||
{
|
||||
Field<Type>& f = *this;
|
||||
|
||||
if (!this->size())
|
||||
if (!this->size() && !mapper.distributed())
|
||||
{
|
||||
f.setSize(mapper.size());
|
||||
if (f.size())
|
||||
@ -246,7 +246,12 @@ void Foam::fvPatchField<Type>::autoMap
|
||||
// Map all faces provided with mapping data
|
||||
Field<Type>::autoMap(mapper);
|
||||
|
||||
|
||||
// For unmapped faces set to internal field value (zero-gradient)
|
||||
if (mapper.hasUnmapped())
|
||||
{
|
||||
Field<Type> pif(this->patchInternalField());
|
||||
|
||||
if
|
||||
(
|
||||
mapper.direct()
|
||||
@ -254,8 +259,6 @@ void Foam::fvPatchField<Type>::autoMap
|
||||
&& mapper.directAddressing().size()
|
||||
)
|
||||
{
|
||||
Field<Type> pif(this->patchInternalField());
|
||||
|
||||
const labelList& mapAddressing = mapper.directAddressing();
|
||||
|
||||
forAll(mapAddressing, i)
|
||||
@ -268,8 +271,6 @@ void Foam::fvPatchField<Type>::autoMap
|
||||
}
|
||||
else if (!mapper.direct() && mapper.addressing().size())
|
||||
{
|
||||
Field<Type> pif(this->patchInternalField());
|
||||
|
||||
const labelListList& mapAddressing = mapper.addressing();
|
||||
|
||||
forAll(mapAddressing, i)
|
||||
@ -283,6 +284,7 @@ void Foam::fvPatchField<Type>::autoMap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -159,6 +159,66 @@ void volPointInterpolation::interpolateInternalField
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void volPointInterpolation::interpolateDimensionedInternalField
|
||||
(
|
||||
const DimensionedField<Type, volMesh>& vf,
|
||||
DimensionedField<Type, pointMesh>& pf
|
||||
) const
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "volPointInterpolation::interpolateDimensionedInternalField("
|
||||
<< "const DimensionedField<Type, volMesh>&, "
|
||||
<< "DimensionedField<Type, pointMesh>&) : "
|
||||
<< "interpolating field from cells to points"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
const fvMesh& mesh = vf.mesh();
|
||||
|
||||
const labelListList& pointCells = mesh.pointCells();
|
||||
const pointField& points = mesh.points();
|
||||
const vectorField& cellCentres = mesh.cellCentres();
|
||||
|
||||
// Re-do weights and interpolation since normal interpolation
|
||||
// pointWeights_ are for non-boundary points only. Not efficient but
|
||||
// then saves on space.
|
||||
|
||||
// Multiply volField by weighting factor matrix to create pointField
|
||||
scalarField sumW(points.size(), 0.0);
|
||||
forAll(pointCells, pointi)
|
||||
{
|
||||
const labelList& ppc = pointCells[pointi];
|
||||
|
||||
pf[pointi] = pTraits<Type>::zero;
|
||||
|
||||
forAll(ppc, pointCelli)
|
||||
{
|
||||
label celli = ppc[pointCelli];
|
||||
scalar pw = 1.0/mag(points[pointi] - cellCentres[celli]);
|
||||
|
||||
pf[pointi] += pw*vf[celli];
|
||||
sumW[pointi] += pw;
|
||||
}
|
||||
}
|
||||
|
||||
// Sum collocated contributions
|
||||
pointConstraints::syncUntransformedData(mesh, sumW, plusEqOp<scalar>());
|
||||
pointConstraints::syncUntransformedData(mesh, pf, plusEqOp<Type>());
|
||||
|
||||
// Normalise
|
||||
forAll(pf, pointi)
|
||||
{
|
||||
scalar s = sumW[pointi];
|
||||
if (s > ROOTVSMALL)
|
||||
{
|
||||
pf[pointi] /= s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
tmp<Field<Type> > volPointInterpolation::flatBoundaryField
|
||||
(
|
||||
@ -424,24 +484,13 @@ volPointInterpolation::interpolate
|
||||
if (pf.upToDate(vf)) //TBD: , vf.mesh().points()))
|
||||
{
|
||||
solution::cachePrintMessage("Reusing", name, vf);
|
||||
return pf;
|
||||
}
|
||||
else
|
||||
{
|
||||
solution::cachePrintMessage("Deleting", name, vf);
|
||||
pf.release();
|
||||
delete &pf;
|
||||
|
||||
solution::cachePrintMessage("Recalculating", name, vf);
|
||||
tmp<PointFieldType> tpf = interpolate(vf, name, false);
|
||||
|
||||
solution::cachePrintMessage("Storing", name, vf);
|
||||
PointFieldType* pfPtr = tpf.ptr();
|
||||
regIOobject::store(pfPtr);
|
||||
|
||||
// Note: return reference, not pointer
|
||||
return *pfPtr;
|
||||
solution::cachePrintMessage("Updating", name, vf);
|
||||
interpolate(vf, pf);
|
||||
}
|
||||
return pf;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -473,6 +522,116 @@ volPointInterpolation::interpolate
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
tmp<DimensionedField<Type, pointMesh> >
|
||||
volPointInterpolation::interpolate
|
||||
(
|
||||
const DimensionedField<Type, volMesh>& vf,
|
||||
const word& name,
|
||||
const bool cache
|
||||
) const
|
||||
{
|
||||
typedef DimensionedField<Type, pointMesh> PointFieldType;
|
||||
|
||||
const pointMesh& pm = pointMesh::New(vf.mesh());
|
||||
const objectRegistry& db = pm.thisDb();
|
||||
|
||||
if (!cache || vf.mesh().changing())
|
||||
{
|
||||
// Delete any old occurences to avoid double registration
|
||||
if (db.objectRegistry::template foundObject<PointFieldType>(name))
|
||||
{
|
||||
PointFieldType& pf = const_cast<PointFieldType&>
|
||||
(
|
||||
db.objectRegistry::template lookupObject<PointFieldType>(name)
|
||||
);
|
||||
|
||||
if (pf.ownedByRegistry())
|
||||
{
|
||||
solution::cachePrintMessage("Deleting", name, vf);
|
||||
pf.release();
|
||||
delete &pf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tmp<DimensionedField<Type, pointMesh> > tpf
|
||||
(
|
||||
new DimensionedField<Type, pointMesh>
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
name,
|
||||
vf.instance(),
|
||||
pm.thisDb()
|
||||
),
|
||||
pm,
|
||||
vf.dimensions()
|
||||
)
|
||||
);
|
||||
|
||||
interpolateDimensionedInternalField(vf, tpf());
|
||||
|
||||
return tpf;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!db.objectRegistry::template foundObject<PointFieldType>(name))
|
||||
{
|
||||
solution::cachePrintMessage("Calculating and caching", name, vf);
|
||||
tmp<PointFieldType> tpf = interpolate(vf, name, false);
|
||||
PointFieldType* pfPtr = tpf.ptr();
|
||||
regIOobject::store(pfPtr);
|
||||
return *pfPtr;
|
||||
}
|
||||
else
|
||||
{
|
||||
PointFieldType& pf = const_cast<PointFieldType&>
|
||||
(
|
||||
db.objectRegistry::template lookupObject<PointFieldType>(name)
|
||||
);
|
||||
|
||||
if (pf.upToDate(vf)) //TBD: , vf.mesh().points()))
|
||||
{
|
||||
solution::cachePrintMessage("Reusing", name, vf);
|
||||
}
|
||||
else
|
||||
{
|
||||
solution::cachePrintMessage("Updating", name, vf);
|
||||
interpolateDimensionedInternalField(vf, pf);
|
||||
}
|
||||
|
||||
return pf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
tmp<DimensionedField<Type, pointMesh> >
|
||||
volPointInterpolation::interpolate
|
||||
(
|
||||
const DimensionedField<Type, volMesh>& vf
|
||||
) const
|
||||
{
|
||||
return interpolate(vf, "volPointInterpolate(" + vf.name() + ')', false);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
tmp<DimensionedField<Type, pointMesh> >
|
||||
volPointInterpolation::interpolate
|
||||
(
|
||||
const tmp<DimensionedField<Type, volMesh> >& tvf
|
||||
) const
|
||||
{
|
||||
// Construct tmp<pointField>
|
||||
tmp<DimensionedField<Type, pointMesh> > tpf = interpolate(tvf());
|
||||
tvf.clear();
|
||||
return tpf;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -187,6 +187,22 @@ public:
|
||||
const wordList& patchFieldTypes
|
||||
) const;
|
||||
|
||||
//- Interpolate dimensionedField using inverse distance weighting
|
||||
// returning pointField
|
||||
template<class Type>
|
||||
tmp<DimensionedField<Type, pointMesh> > interpolate
|
||||
(
|
||||
const DimensionedField<Type, volMesh>&
|
||||
) const;
|
||||
|
||||
//- Interpolate tmp<dimensionedField> using inverse distance
|
||||
// weighting returning pointField
|
||||
template<class Type>
|
||||
tmp<DimensionedField<Type, pointMesh> > interpolate
|
||||
(
|
||||
const tmp<DimensionedField<Type, volMesh> >&
|
||||
) const;
|
||||
|
||||
|
||||
// Low level
|
||||
|
||||
@ -236,6 +252,24 @@ public:
|
||||
const bool cache
|
||||
) const;
|
||||
|
||||
//- Interpolate dimensioned internal field from cells to points
|
||||
// using inverse distance weighting
|
||||
template<class Type>
|
||||
void interpolateDimensionedInternalField
|
||||
(
|
||||
const DimensionedField<Type, volMesh>& vf,
|
||||
DimensionedField<Type, pointMesh>& pf
|
||||
) const;
|
||||
|
||||
//- Interpolate dimensionedField using inverse distance weighting
|
||||
// returning pointField with name. Optionally caches
|
||||
template<class Type>
|
||||
tmp<DimensionedField<Type, pointMesh> > interpolate
|
||||
(
|
||||
const DimensionedField<Type, volMesh>&,
|
||||
const word& name,
|
||||
const bool cache
|
||||
) const;
|
||||
|
||||
// Interpolation for displacement (applies 2D correction)
|
||||
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -105,6 +105,30 @@ public:
|
||||
{
|
||||
return autoPtr<particle>(new passiveParticle(*this));
|
||||
}
|
||||
|
||||
|
||||
//- Factory class to read-construct particles used for
|
||||
// parallel transfer
|
||||
class iNew
|
||||
{
|
||||
const polyMesh& mesh_;
|
||||
|
||||
public:
|
||||
|
||||
iNew(const polyMesh& mesh)
|
||||
:
|
||||
mesh_(mesh)
|
||||
{}
|
||||
|
||||
autoPtr<passiveParticle> operator()(Istream& is) const
|
||||
{
|
||||
return autoPtr<passiveParticle>
|
||||
(
|
||||
new passiveParticle(mesh_, is, true)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
531
src/meshTools/AABBTree/AABBTree.C
Normal file
531
src/meshTools/AABBTree/AABBTree.C
Normal file
@ -0,0 +1,531 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "AABBTree.H"
|
||||
#include "meshTools.H"
|
||||
#include "PackedBoolList.H"
|
||||
//#include "OFstream.H"
|
||||
|
||||
template<class Type>
|
||||
Foam::scalar Foam::AABBTree<Type>::tolerance_ = 1e-4;
|
||||
|
||||
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::AABBTree<Type>::writeOBJ
|
||||
(
|
||||
const bool writeLinesOnly,
|
||||
const treeBoundBox& bb,
|
||||
label& vertI,
|
||||
Ostream& os
|
||||
) const
|
||||
{
|
||||
const pointField pts(bb.points());
|
||||
forAll(pts, i)
|
||||
{
|
||||
meshTools::writeOBJ(os, pts[i]);
|
||||
}
|
||||
|
||||
if (writeLinesOnly)
|
||||
{
|
||||
forAll(bb.edges, i)
|
||||
{
|
||||
const edge& e = bb.edges[i];
|
||||
os << "l " << e[0] + vertI + 1 << ' ' << e[1] + vertI + 1 << nl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
forAll(bb.faces, i)
|
||||
{
|
||||
const face& f = bb.faces[i];
|
||||
|
||||
os << 'f';
|
||||
forAll(f, fp)
|
||||
{
|
||||
os << ' ' << f[fp] + vertI + 1;
|
||||
}
|
||||
os << nl;
|
||||
}
|
||||
}
|
||||
|
||||
vertI += pts.size();
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::AABBTree<Type>::writeOBJ
|
||||
(
|
||||
const bool leavesOnly,
|
||||
const bool writeLinesOnly,
|
||||
const treeBoundBox& bb,
|
||||
const label nodeI,
|
||||
const List<Pair<treeBoundBox> >& bbs,
|
||||
const List<Pair<label> >& nodes,
|
||||
label& vertI,
|
||||
Ostream& os
|
||||
) const
|
||||
{
|
||||
if (!leavesOnly || nodeI < 0)
|
||||
{
|
||||
writeOBJ(writeLinesOnly, bb, vertI, os);
|
||||
}
|
||||
|
||||
// recurse to find leaves
|
||||
if (nodeI >= 0)
|
||||
{
|
||||
writeOBJ
|
||||
(
|
||||
leavesOnly,
|
||||
writeLinesOnly,
|
||||
bbs[nodeI].first(),
|
||||
nodes[nodeI].first(),
|
||||
bbs,
|
||||
nodes,
|
||||
vertI,
|
||||
os
|
||||
);
|
||||
writeOBJ
|
||||
(
|
||||
leavesOnly,
|
||||
writeLinesOnly,
|
||||
bbs[nodeI].second(),
|
||||
nodes[nodeI].second(),
|
||||
bbs,
|
||||
nodes,
|
||||
vertI,
|
||||
os
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::AABBTree<Type>::createBoxes
|
||||
(
|
||||
const bool equalBinSize,
|
||||
const label level,
|
||||
const List<Type>& objects,
|
||||
const pointField& points,
|
||||
const DynamicList<label>& objectIDs,
|
||||
const treeBoundBox& bb,
|
||||
const label nodeI,
|
||||
|
||||
DynamicList<Pair<treeBoundBox> >& bbs,
|
||||
DynamicList<labelPair>& nodes,
|
||||
DynamicList<labelList>& addressing
|
||||
) const
|
||||
{
|
||||
const vector span = bb.span();
|
||||
|
||||
// Determine which direction to divide the box
|
||||
|
||||
direction maxDir = 0;
|
||||
scalar maxSpan = span[maxDir];
|
||||
for (label dirI = 1; dirI < 3; dirI++)
|
||||
{
|
||||
if (span[dirI] > maxSpan)
|
||||
{
|
||||
maxSpan = span[dirI];
|
||||
maxDir = dirI;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
scalar divide;
|
||||
|
||||
if (equalBinSize)
|
||||
{
|
||||
// Pick up points used by this set of objects
|
||||
|
||||
PackedBoolList isUsedPoint(points.size());
|
||||
DynamicList<scalar> component(points.size());
|
||||
|
||||
forAll(objectIDs, i)
|
||||
{
|
||||
const label objI = objectIDs[i];
|
||||
const Type& obj = objects[objI];
|
||||
|
||||
forAll(obj, pI)
|
||||
{
|
||||
const label pointI = obj[pI];
|
||||
if (isUsedPoint.set(pointI))
|
||||
{
|
||||
component.append(points[pointI][maxDir]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Determine the median
|
||||
|
||||
Foam::sort(component);
|
||||
|
||||
divide = component[component.size()/2];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Geometric middle
|
||||
divide = bb.min()[maxDir] + 0.5*maxSpan;
|
||||
}
|
||||
|
||||
|
||||
scalar divMin = divide + tolerance_*maxSpan;
|
||||
scalar divMax = divide - tolerance_*maxSpan;
|
||||
|
||||
|
||||
// Assign the objects to min or max bin
|
||||
|
||||
DynamicList<label> minBinObjectIDs(objectIDs.size());
|
||||
treeBoundBox minBb(point::max, point::min);
|
||||
|
||||
DynamicList<label> maxBinObjectIDs(objectIDs.size());
|
||||
treeBoundBox maxBb(point::max, point::min);
|
||||
|
||||
forAll(objectIDs, i)
|
||||
{
|
||||
const label objI = objectIDs[i];
|
||||
const Type& obj = objects[objI];
|
||||
|
||||
bool intoMin = false;
|
||||
bool intoMax = false;
|
||||
|
||||
forAll(obj, pI)
|
||||
{
|
||||
const label pointI = obj[pI];
|
||||
const point& pt = points[pointI];
|
||||
if (pt[maxDir] < divMin)
|
||||
{
|
||||
intoMin = true;
|
||||
}
|
||||
if (pt[maxDir] > divMax)
|
||||
{
|
||||
intoMax = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (intoMin)
|
||||
{
|
||||
minBinObjectIDs.append(objI);
|
||||
const boundBox objBb(points, obj, false);
|
||||
minBb.min() = min(minBb.min(), objBb.min());
|
||||
minBb.max() = max(minBb.max(), objBb.max());
|
||||
}
|
||||
if (intoMax)
|
||||
{
|
||||
maxBinObjectIDs.append(objI);
|
||||
const boundBox objBb(points, obj, false);
|
||||
maxBb.min() = min(maxBb.min(), objBb.min());
|
||||
maxBb.max() = max(maxBb.max(), objBb.max());
|
||||
}
|
||||
}
|
||||
|
||||
// inflate box in case geometry reduces to 2-D
|
||||
if (minBinObjectIDs.size())
|
||||
{
|
||||
minBb.inflate(0.01);
|
||||
}
|
||||
if (maxBinObjectIDs.size())
|
||||
{
|
||||
maxBb.inflate(0.01);
|
||||
}
|
||||
|
||||
minBinObjectIDs.shrink();
|
||||
maxBinObjectIDs.shrink();
|
||||
|
||||
|
||||
label minI;
|
||||
if (minBinObjectIDs.size() > minLeafSize_ && level < maxLevel_)
|
||||
{
|
||||
// new leaf
|
||||
minI = nodes.size();
|
||||
nodes.append(labelPair(-1, -1));
|
||||
}
|
||||
else
|
||||
{
|
||||
// update existing leaf
|
||||
minI = -addressing.size() - 1;
|
||||
addressing.append(minBinObjectIDs);
|
||||
}
|
||||
|
||||
label maxI;
|
||||
if (maxBinObjectIDs.size() > minLeafSize_ && level < maxLevel_)
|
||||
{
|
||||
// new leaf
|
||||
maxI = nodes.size();
|
||||
nodes.append(labelPair(-1, -1));
|
||||
}
|
||||
else
|
||||
{
|
||||
// update existing leaf
|
||||
maxI = -addressing.size() - 1;
|
||||
addressing.append(maxBinObjectIDs);
|
||||
}
|
||||
|
||||
nodes(nodeI) = labelPair(minI, maxI);
|
||||
bbs(nodeI) = Pair<treeBoundBox>(minBb, maxBb);
|
||||
|
||||
// recurse
|
||||
if (minI >= 0)
|
||||
{
|
||||
createBoxes
|
||||
(
|
||||
equalBinSize,
|
||||
level + 1,
|
||||
objects,
|
||||
points,
|
||||
minBinObjectIDs,
|
||||
minBb,
|
||||
minI,
|
||||
bbs,
|
||||
nodes,
|
||||
addressing
|
||||
);
|
||||
}
|
||||
if (maxI >= 0)
|
||||
{
|
||||
createBoxes
|
||||
(
|
||||
equalBinSize,
|
||||
level + 1,
|
||||
objects,
|
||||
points,
|
||||
maxBinObjectIDs,
|
||||
maxBb,
|
||||
maxI,
|
||||
bbs,
|
||||
nodes,
|
||||
addressing
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::AABBTree<Type>::AABBTree()
|
||||
:
|
||||
maxLevel_(0),
|
||||
minLeafSize_(0),
|
||||
boundBoxes_(),
|
||||
addressing_()
|
||||
{}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::AABBTree<Type>::AABBTree
|
||||
(
|
||||
const UList<Type>& objects,
|
||||
const pointField& points,
|
||||
const bool equalBinSize,
|
||||
const label maxLevel,
|
||||
const label minLeafSize
|
||||
)
|
||||
:
|
||||
maxLevel_(maxLevel),
|
||||
minLeafSize_(minLeafSize),
|
||||
boundBoxes_(),
|
||||
addressing_()
|
||||
{
|
||||
if (objects.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
DynamicList<Pair<treeBoundBox> > bbs(maxLevel);
|
||||
DynamicList<labelPair> nodes(maxLevel);
|
||||
DynamicList<labelList> addr(maxLevel);
|
||||
|
||||
nodes.append(labelPair(-1, -1));
|
||||
treeBoundBox topBb(points);
|
||||
topBb.inflate(0.01);
|
||||
|
||||
DynamicList<label> objectIDs(identity(objects.size()));
|
||||
|
||||
createBoxes
|
||||
(
|
||||
equalBinSize,
|
||||
0, // starting at top level
|
||||
objects,
|
||||
points,
|
||||
objectIDs,
|
||||
topBb,
|
||||
0, // starting node
|
||||
|
||||
bbs,
|
||||
nodes,
|
||||
addr
|
||||
);
|
||||
|
||||
|
||||
//{
|
||||
// OFstream os("tree.obj");
|
||||
// label vertI = 0;
|
||||
// writeOBJ
|
||||
// (
|
||||
// true, // leavesOnly
|
||||
// false, // writeLinesOnly
|
||||
//
|
||||
// topBb,
|
||||
// 0,
|
||||
// bbs,
|
||||
// nodes,
|
||||
// vertI,
|
||||
// os
|
||||
// );
|
||||
//}
|
||||
|
||||
|
||||
// transfer flattened tree to persistent storage
|
||||
DynamicList<treeBoundBox> boundBoxes(2*bbs.size());
|
||||
DynamicList<labelList> addressing(2*addr.size());
|
||||
forAll(nodes, nodeI)
|
||||
{
|
||||
if (nodes[nodeI].first() < 0)
|
||||
{
|
||||
boundBoxes.append(bbs[nodeI].first());
|
||||
addressing.append(addr[nodeI + 1]);
|
||||
}
|
||||
if (nodes[nodeI].second() < 0)
|
||||
{
|
||||
boundBoxes.append(bbs[nodeI].second());
|
||||
addressing.append(addr[nodeI + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
boundBoxes_.transfer(boundBoxes);
|
||||
addressing_.transfer(addressing);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
const Foam::List<Foam::treeBoundBox>& Foam::AABBTree<Type>::boundBoxes() const
|
||||
{
|
||||
return boundBoxes_;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
const Foam::List<Foam::labelList>& Foam::AABBTree<Type>::addressing() const
|
||||
{
|
||||
return addressing_;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
bool Foam::AABBTree<Type>::pointInside(const point& pt) const
|
||||
{
|
||||
forAll(boundBoxes_, i)
|
||||
{
|
||||
const treeBoundBox& bb = boundBoxes_[i];
|
||||
|
||||
if (bb.contains(pt))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
bool Foam::AABBTree<Type>::overlaps(const boundBox& bbIn) const
|
||||
{
|
||||
forAll(boundBoxes_, i)
|
||||
{
|
||||
const treeBoundBox& bb = boundBoxes_[i];
|
||||
|
||||
if (bb.overlaps(bbIn))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::Ostream& Foam::operator<<(Ostream& os, const AABBTree<Type>& tree)
|
||||
{
|
||||
if (os.format() == IOstream::ASCII)
|
||||
{
|
||||
os << tree.maxLevel_ << token::SPACE
|
||||
<< tree.minLeafSize_ << token::SPACE
|
||||
<< tree.boundBoxes_ << token::SPACE
|
||||
<< tree.addressing_ << token::SPACE;
|
||||
}
|
||||
else
|
||||
{
|
||||
os.write
|
||||
(
|
||||
reinterpret_cast<const char*>(&tree.maxLevel_),
|
||||
sizeof(tree.maxLevel_)
|
||||
+ sizeof(tree.minLeafSize_)
|
||||
);
|
||||
os << tree.boundBoxes_
|
||||
<< tree.addressing_;
|
||||
}
|
||||
|
||||
os.check("Ostream& operator<<(Ostream&, const AABBTree<Type>&)");
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::Istream& Foam::operator>>(Istream& is, AABBTree<Type>& tree)
|
||||
{
|
||||
if (is.format() == IOstream::ASCII)
|
||||
{
|
||||
is >> tree.maxLevel_
|
||||
>> tree.minLeafSize_
|
||||
>> tree.boundBoxes_
|
||||
>> tree.addressing_;
|
||||
}
|
||||
else
|
||||
{
|
||||
is.read
|
||||
(
|
||||
reinterpret_cast<char*>(&tree.maxLevel_),
|
||||
sizeof(tree.maxLevel_)
|
||||
+ sizeof(tree.minLeafSize_)
|
||||
);
|
||||
is >> tree.boundBoxes_
|
||||
>> tree.addressing_;
|
||||
}
|
||||
|
||||
is.check("Istream& operator>>(Istream&, AABBTree<Type>&)");
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
197
src/meshTools/AABBTree/AABBTree.H
Normal file
197
src/meshTools/AABBTree/AABBTree.H
Normal file
@ -0,0 +1,197 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::AABBTree
|
||||
|
||||
Description
|
||||
Templated tree of axis-aligned bounding boxes (AABB)
|
||||
|
||||
Designed to be templated on either faces or cells, the AABBTree will
|
||||
decompose the input into a tree of AABB's. The maximum number of tree
|
||||
levels and minimum number of objects per leaf are provided on construction,
|
||||
and the contents (addressing) is stored.
|
||||
|
||||
SourceFiles
|
||||
AABBTree.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef AABBTree_H
|
||||
#define AABBTree_H
|
||||
|
||||
#include "labelList.H"
|
||||
#include "labelPair.H"
|
||||
#include "DynamicList.H"
|
||||
#include "pointField.H"
|
||||
#include "treeBoundBox.H"
|
||||
#include "Ostream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward declaration of friend functions and operators
|
||||
|
||||
template<class Type>
|
||||
class AABBTree;
|
||||
|
||||
template<class Type>
|
||||
Istream& operator>>(Istream&, AABBTree<Type>&);
|
||||
|
||||
template<class Type>
|
||||
Ostream& operator<<(Ostream&, const AABBTree<Type>&);
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class AABBTree Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class Type>
|
||||
class AABBTree
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- Tolerance
|
||||
static scalar tolerance_;
|
||||
|
||||
//- Maximum tree level
|
||||
label maxLevel_;
|
||||
|
||||
//- Minimum points per leaf
|
||||
label minLeafSize_;
|
||||
|
||||
//- Bounding boxes making up the tree
|
||||
List<treeBoundBox> boundBoxes_;
|
||||
|
||||
//- Leaf adressing
|
||||
List<labelList> addressing_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Write OBJ file of bounding box
|
||||
void writeOBJ
|
||||
(
|
||||
const bool writeLinesOnly,
|
||||
const treeBoundBox& bb,
|
||||
label& vertI,
|
||||
Ostream& os
|
||||
) const;
|
||||
|
||||
//- Write OBJ for all bounding boxes
|
||||
void writeOBJ
|
||||
(
|
||||
const bool leavesOnly,
|
||||
const bool writeLinesOnly,
|
||||
const treeBoundBox& bb,
|
||||
const label nodeI,
|
||||
const List<Pair<treeBoundBox> >& bbs,
|
||||
const List<Pair<label> >& nodes,
|
||||
label& vertI,
|
||||
Ostream& os
|
||||
) const;
|
||||
|
||||
//- Create the bounding boxes by interrogating points
|
||||
void createBoxes
|
||||
(
|
||||
const bool equalBinSize,
|
||||
const label level,
|
||||
const List<Type>& objects,
|
||||
const pointField& points,
|
||||
const DynamicList<label>& objectIDs,
|
||||
const treeBoundBox& bb,
|
||||
const label nodeI,
|
||||
|
||||
DynamicList<Pair<treeBoundBox> >& bbs,
|
||||
DynamicList<labelPair>& nodes,
|
||||
DynamicList<labelList>& addressing
|
||||
) const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Null constructor
|
||||
AABBTree();
|
||||
|
||||
//- Construct from components
|
||||
// equalBinSize: divide into equal number of elements or
|
||||
// equal span
|
||||
AABBTree
|
||||
(
|
||||
const UList<Type>& objects,
|
||||
const pointField& points,
|
||||
const bool equalBinSize = true,
|
||||
const label maxLevel = 3,
|
||||
const label minBinSize = 100
|
||||
);
|
||||
|
||||
|
||||
// Public Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Return the bounding boxes making up the tree
|
||||
const List<treeBoundBox>& boundBoxes() const;
|
||||
|
||||
//- Return the contents addressing
|
||||
const List<labelList>& addressing() const;
|
||||
|
||||
|
||||
// Evaluation
|
||||
|
||||
//- Determine whether a point is inside the bounding boxes
|
||||
bool pointInside(const point& pt) const;
|
||||
|
||||
//- Determine whether a bounding box overlaps the tree bounding
|
||||
// boxes
|
||||
bool overlaps(const boundBox& bbIn) const;
|
||||
|
||||
|
||||
// IOstream operators
|
||||
|
||||
friend Istream& operator>> <Type>(Istream&, AABBTree&);
|
||||
friend Ostream& operator<< <Type>(Ostream&, const AABBTree&);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "AABBTree.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -27,6 +27,7 @@ License
|
||||
#include "AMIMethod.H"
|
||||
#include "meshTools.H"
|
||||
#include "mapDistribute.H"
|
||||
#include "flipOp.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
@ -604,7 +605,6 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::constructFromSurface
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class SourcePatch, class TargetPatch>
|
||||
@ -965,7 +965,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
|
||||
tgtMagSf_,
|
||||
triMode_,
|
||||
reverseTarget_,
|
||||
requireMatch_
|
||||
requireMatch_ && (lowWeightCorrection_ < 0)
|
||||
)
|
||||
);
|
||||
|
||||
@ -1010,27 +1010,33 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
|
||||
// send data back to originating procs. Note that contributions
|
||||
// from different processors get added (ListAppendEqOp)
|
||||
|
||||
mapDistribute::distribute
|
||||
mapDistributeBase::distribute
|
||||
(
|
||||
Pstream::nonBlocking,
|
||||
List<labelPair>(),
|
||||
tgtPatch.size(),
|
||||
map.constructMap(),
|
||||
false, // has flip
|
||||
map.subMap(),
|
||||
false, // has flip
|
||||
tgtAddress_,
|
||||
ListAppendEqOp<label>(),
|
||||
flipOp(), // flip operation
|
||||
labelList()
|
||||
);
|
||||
|
||||
mapDistribute::distribute
|
||||
mapDistributeBase::distribute
|
||||
(
|
||||
Pstream::nonBlocking,
|
||||
List<labelPair>(),
|
||||
tgtPatch.size(),
|
||||
map.constructMap(),
|
||||
false,
|
||||
map.subMap(),
|
||||
false,
|
||||
tgtWeights_,
|
||||
ListAppendEqOp<scalar>(),
|
||||
flipOp(),
|
||||
scalarList()
|
||||
);
|
||||
|
||||
@ -1082,7 +1088,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
|
||||
tgtMagSf_,
|
||||
triMode_,
|
||||
reverseTarget_,
|
||||
requireMatch_
|
||||
requireMatch_ && (lowWeightCorrection_ < 0)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -26,6 +26,7 @@ License
|
||||
#include "AMIInterpolation.H"
|
||||
#include "mergePoints.H"
|
||||
#include "mapDistribute.H"
|
||||
#include "AABBTree.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
@ -97,11 +98,11 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcOverlappingProcs
|
||||
|
||||
forAll(procBb, procI)
|
||||
{
|
||||
const List<treeBoundBox>& bbs = procBb[procI];
|
||||
const treeBoundBoxList& bbp = procBb[procI];
|
||||
|
||||
forAll(bbs, bbI)
|
||||
forAll(bbp, bbI)
|
||||
{
|
||||
if (bbs[bbI].overlaps(bb))
|
||||
if (bbp[bbI].overlaps(bb))
|
||||
{
|
||||
overlaps[procI] = true;
|
||||
nOverlaps++;
|
||||
@ -109,6 +110,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcOverlappingProcs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nOverlaps;
|
||||
}
|
||||
|
||||
@ -338,33 +340,22 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcProcMap
|
||||
|
||||
if (srcPatch.size())
|
||||
{
|
||||
procBb[Pstream::myProcNo()] = treeBoundBoxList
|
||||
procBb[Pstream::myProcNo()] =
|
||||
AABBTree<face>
|
||||
(
|
||||
1, // For now single bounding box per proc
|
||||
treeBoundBox
|
||||
(
|
||||
srcPatch.points(),
|
||||
srcPatch.meshPoints()
|
||||
)
|
||||
);
|
||||
srcPatch.localFaces(),
|
||||
srcPatch.localPoints(),
|
||||
false
|
||||
).boundBoxes();
|
||||
}
|
||||
else
|
||||
{
|
||||
procBb[Pstream::myProcNo()] = treeBoundBoxList();
|
||||
}
|
||||
|
||||
// slightly increase size of bounding boxes to allow for cases where
|
||||
// bounding boxes are perfectly alligned
|
||||
forAll(procBb[Pstream::myProcNo()], bbI)
|
||||
{
|
||||
treeBoundBox& bb = procBb[Pstream::myProcNo()][bbI];
|
||||
bb.inflate(0.01);
|
||||
}
|
||||
|
||||
Pstream::gatherList(procBb);
|
||||
Pstream::scatterList(procBb);
|
||||
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Determining extent of srcPatch per processor:" << nl
|
||||
@ -375,7 +366,6 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcProcMap
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Determine which faces of tgtPatch overlaps srcPatch per proc
|
||||
const faceList& faces = tgtPatch.localFaces();
|
||||
const pointField& points = tgtPatch.localPoints();
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -221,7 +221,7 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::resetTree()
|
||||
// Clear the old octree
|
||||
treePtr_.clear();
|
||||
|
||||
treeBoundBox bb(tgtPatch_.points());
|
||||
treeBoundBox bb(tgtPatch_.points(), tgtPatch_.meshPoints());
|
||||
bb.inflate(0.01);
|
||||
|
||||
if (!treePtr_.valid())
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2013-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -310,16 +310,14 @@ void Foam::directAMI<SourcePatch, TargetPatch>::calculate
|
||||
forAll(srcAddr, i)
|
||||
{
|
||||
scalar magSf = this->srcMagSf_[i];
|
||||
// srcWeights[i] = scalarList(srcAddr[i].size(), magSf);
|
||||
srcWeights[i] = scalarList(1, magSf);
|
||||
srcAddress[i].transfer(srcAddr[i]);
|
||||
srcWeights[i] = scalarList(1, magSf);
|
||||
}
|
||||
forAll(tgtAddr, i)
|
||||
{
|
||||
scalar magSf = this->tgtMagSf_[i];
|
||||
// tgtWeights[i] = scalarList(tgtAddr[i].size(), magSf);
|
||||
tgtWeights[i] = scalarList(1, magSf);
|
||||
tgtAddress[i].transfer(tgtAddr[i]);
|
||||
tgtWeights[i] = scalarList(1, magSf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -41,6 +41,7 @@ SourceFiles
|
||||
#include "FixedList.H"
|
||||
#include "plane.H"
|
||||
#include "face.H"
|
||||
#include "triPoints.H"
|
||||
#include "NamedEnum.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -56,8 +57,6 @@ class faceAreaIntersect
|
||||
{
|
||||
public:
|
||||
|
||||
typedef FixedList<point, 3> triPoints;
|
||||
|
||||
enum triangulationMode
|
||||
{
|
||||
tmFan,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user