diff --git a/applications/utilities/finiteArea/makeFaMesh/Make/options b/applications/utilities/finiteArea/makeFaMesh/Make/options index 98ba4f7225daeac475fec261a9a17f85c892c959..7a28b2c4b67d5b655edcd69b39ea0baae8c47e33 100644 --- a/applications/utilities/finiteArea/makeFaMesh/Make/options +++ b/applications/utilities/finiteArea/makeFaMesh/Make/options @@ -1,8 +1,13 @@ EXE_INC = \ -I$(LIB_SRC)/finiteArea/lnInclude \ - -I$(LIB_SRC)/finiteVolume/lnInclude \ - -I$(LIB_SRC)/cfdTools/general/lnInclude + -I$(LIB_SRC)/fileFormats/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/parallel/decompose/faDecompose/lnInclude \ + -I$(LIB_SRC)/parallel/reconstruct/faReconstruct/lnInclude EXE_LIBS = \ -lfiniteArea \ - -lfiniteVolume + -lfileFormats \ + -lmeshTools \ + -lfaDecompose \ + -lfaReconstruct diff --git a/applications/utilities/finiteArea/makeFaMesh/decomposeFaFields.H b/applications/utilities/finiteArea/makeFaMesh/decomposeFaFields.H new file mode 100644 index 0000000000000000000000000000000000000000..5c38c9b4f13471be875283634693cbfcf3c72fc7 --- /dev/null +++ b/applications/utilities/finiteArea/makeFaMesh/decomposeFaFields.H @@ -0,0 +1,94 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM, distributed under GPL-3.0-or-later. + +Description + Decompose area fields, when mesh was generated in parallel + +\*---------------------------------------------------------------------------*/ + +if (Pstream::parRun()) +{ + faMeshReconstructor reconstructor(areaMesh); + reconstructor.writeAddressing(); + + // Handle area fields + // ------------------ + + PtrList<areaScalarField> areaScalarFields; + PtrList<areaVectorField> areaVectorFields; + PtrList<areaSphericalTensorField> areaSphTensorFields; + PtrList<areaSymmTensorField> areaSymmTensorFields; + PtrList<areaTensorField> areaTensorFields; + + const faMesh& fullMesh = reconstructor.mesh(); + + { + // Use uncollated (or master uncollated) file handler here. + // - each processor is reading in the identical serial fields. + // - nothing should be parallel-coordinated. + + // Similarly, if we write the serial finite-area mesh, this is only + // done from one processor! + + reconstructor.writeMesh(); + + const bool oldDistributed = fileHandler().distributed(); + auto oldHandler = fileHandler(fileOperation::NewUncollated()); + fileHandler().distributed(true); + + IOobjectList objects(fullMesh.time(), runTime.timeName()); + + faFieldDecomposer::readFields(fullMesh, objects, areaScalarFields); + faFieldDecomposer::readFields(fullMesh, objects, areaVectorFields); + faFieldDecomposer::readFields(fullMesh, objects, areaSphTensorFields); + faFieldDecomposer::readFields(fullMesh, objects, areaSymmTensorFields); + faFieldDecomposer::readFields(fullMesh, objects, areaTensorFields); + + // Restore old settings + if (oldHandler) + { + fileHandler(std::move(oldHandler)); + } + fileHandler().distributed(oldDistributed); + } + + const label nAreaFields = + ( + areaScalarFields.size() + + areaVectorFields.size() + + areaSphTensorFields.size() + + areaSymmTensorFields.size() + + areaTensorFields.size() + ); + + if (nAreaFields) + { + Info<< "Decomposing " << nAreaFields << " area fields" << nl << endl; + + faFieldDecomposer fieldDecomposer + ( + fullMesh, + areaMesh, + reconstructor.edgeProcAddressing(), + reconstructor.faceProcAddressing(), + reconstructor.boundaryProcAddressing() + ); + + fieldDecomposer.decomposeFields(areaScalarFields); + fieldDecomposer.decomposeFields(areaVectorFields); + fieldDecomposer.decomposeFields(areaSphTensorFields); + fieldDecomposer.decomposeFields(areaSymmTensorFields); + fieldDecomposer.decomposeFields(areaTensorFields); + } +} + +// ************************************************************************* // diff --git a/applications/utilities/finiteArea/makeFaMesh/faMeshWriteEdgesOBJ.H b/applications/utilities/finiteArea/makeFaMesh/faMeshWriteEdgesOBJ.H new file mode 100644 index 0000000000000000000000000000000000000000..a50d18df3c3e492fe2809b0116b8a3ae77bf83d3 --- /dev/null +++ b/applications/utilities/finiteArea/makeFaMesh/faMeshWriteEdgesOBJ.H @@ -0,0 +1,43 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM, distributed under GPL-3.0-or-later. + +Description + OBJ output of faMesh edges + +\*---------------------------------------------------------------------------*/ + +{ + Info<< "Writing edges in obj format" << endl; + + word outputName("faMesh-edges.obj"); + + if (Pstream::parRun()) + { + outputName = word + ( + "faMesh-edges-" + Foam::name(Pstream::myProcNo()) + ".obj" + ); + } + + OBJstream os(runTime.globalPath()/outputName); + + os.writeQuoted + ( + ("# " + outputName + "\n"), + false + ); + + os.write(areaMesh.patch().edges(), areaMesh.patch().localPoints()); +} + + +// ************************************************************************* // diff --git a/applications/utilities/finiteArea/makeFaMesh/findMeshDefinitionDict.H b/applications/utilities/finiteArea/makeFaMesh/findMeshDefinitionDict.H new file mode 100644 index 0000000000000000000000000000000000000000..8a678fdcc8c789a5de4eb4151d2d3b7fe0282330 --- /dev/null +++ b/applications/utilities/finiteArea/makeFaMesh/findMeshDefinitionDict.H @@ -0,0 +1,97 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM, distributed under GPL-3.0-or-later. + +Description + Search for the appropriate faMeshDefinition dictionary.... + +\*---------------------------------------------------------------------------*/ + +const word dictName("faMeshDefinition"); + +autoPtr<IOdictionary> meshDictPtr; + +{ + fileName dictPath; + + const word& regionDir = + (regionName == polyMesh::defaultRegion ? word::null : regionName); + + if (args.readIfPresent("dict", dictPath)) + { + // Dictionary specified on the command-line ... + + if (isDir(dictPath)) + { + dictPath /= dictName; + } + } + else if + ( + // Check global location + exists + ( + runTime.path()/runTime.caseConstant() + /regionDir/faMesh::meshSubDir/dictName + ) + ) + { + // Dictionary present in constant faMesh directory (old-style) + + dictPath = + runTime.constant() + /regionDir/faMesh::meshSubDir/dictName; + + // Warn that constant/faMesh/faMeshDefinition was used + // instead of system/faMeshDefinition + #if 0 + WarningIn(args.executable()) + << "Using the old faMeshDefinition location: " + << dictPath << nl + << " instead of default location: " + << runTime.system()/regionDir/dictName << nl + << endl; + #endif + } + else + { + // Assume dictionary is in the system directory + + dictPath = runTime.system()/regionDir/dictName; + } + + IOobject meshDictIO + ( + dictPath, + runTime, + IOobject::MUST_READ, + IOobject::NO_WRITE, + false, // no registerObject + true // is globalObject + ); + + if (!meshDictIO.typeHeaderOk<IOdictionary>(true)) + { + FatalErrorInFunction + << meshDictIO.objectPath() << nl + << exit(FatalError); + } + + Info<< "Creating faMesh from definition: " + << runTime.relativePath(meshDictIO.objectPath()) << endl; + + meshDictPtr = autoPtr<IOdictionary>::New(meshDictIO); +} + +IOdictionary& meshDefDict = *meshDictPtr; + + +// ************************************************************************* // diff --git a/applications/utilities/finiteArea/makeFaMesh/makeFaMesh.C b/applications/utilities/finiteArea/makeFaMesh/makeFaMesh.C index 0010be3dabc1a6a7758d642769210d1fadbf41e0..e80ed303d9f65195f5d0e59b1a3b1eff77d0c1e8 100644 --- a/applications/utilities/finiteArea/makeFaMesh/makeFaMesh.C +++ b/applications/utilities/finiteArea/makeFaMesh/makeFaMesh.C @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -28,6 +29,8 @@ Application Description A mesh generator for finiteArea mesh. + When called in parallel, it will also try to act like decomposePar, + create procAddressing and decompose serial finite-area fields. Author Zeljko Tukovic, FAMENA @@ -35,35 +38,19 @@ Author \*---------------------------------------------------------------------------*/ -#include "objectRegistry.H" #include "Time.H" #include "argList.H" #include "OSspecific.H" #include "faMesh.H" -#include "fvMesh.H" +#include "IOdictionary.H" +#include "IOobjectList.H" -using namespace Foam; - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -class faPatchData -{ -public: - word name_; - word type_; - dictionary dict_; - label ownPolyPatchID_; - label ngbPolyPatchID_; - labelList edgeLabels_; - faPatchData() - : - name_(word::null), - type_(word::null), - ownPolyPatchID_(-1), - ngbPolyPatchID_(-1) - {} -}; +#include "areaFields.H" +#include "faFieldDecomposer.H" +#include "faMeshReconstructor.H" +#include "OBJstream.H" +using namespace Foam; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -73,286 +60,64 @@ int main(int argc, char *argv[]) ( "A mesh generator for finiteArea mesh" ); - - #include "addRegionOption.H" - argList::noParallel(); - - #include "setRootCase.H" - #include "createTime.H" - #include "createNamedMesh.H" - - // Reading faMeshDefinition dictionary - IOdictionary faMeshDefinition - ( - IOobject - ( - "faMeshDefinition", - runTime.constant(), - "faMesh", - mesh, - IOobject::MUST_READ, - IOobject::NO_WRITE - ) - ); - - wordList polyMeshPatches + argList::addOption ( - faMeshDefinition.get<wordList>("polyMeshPatches") + "empty-patch", + "name", + "Specify name for a default empty patch", + false // An advanced option, but not enough to worry about that ); + argList::addOption("dict", "file", "Alternative faMeshDefinition"); - const dictionary& bndDict = faMeshDefinition.subDict("boundary"); - - const wordList faPatchNames(bndDict.toc()); - - List<faPatchData> faPatches(faPatchNames.size()+1); - - forAll(faPatchNames, patchI) - { - const dictionary& curPatchDict = bndDict.subDict(faPatchNames[patchI]); - - faPatches[patchI].name_ = faPatchNames[patchI]; - - faPatches[patchI].type_ = curPatchDict.get<word>("type"); - - const word ownName(curPatchDict.get<word>("ownerPolyPatch")); - - faPatches[patchI].ownPolyPatchID_ = - mesh.boundaryMesh().findPatchID(ownName); - - if (faPatches[patchI].ownPolyPatchID_ < 0) - { - FatalErrorIn("makeFaMesh:") - << "neighbourPolyPatch " << ownName << " does not exist" - << exit(FatalError); - } - - const word neiName(curPatchDict.get<word>("neighbourPolyPatch")); - - faPatches[patchI].ngbPolyPatchID_ = - mesh.boundaryMesh().findPatchID(neiName); - - if (faPatches[patchI].ngbPolyPatchID_ < 0) - { - FatalErrorIn("makeFaMesh:") - << "neighbourPolyPatch " << neiName << " does not exist" - << exit(FatalError); - } - } - - // Setting faceLabels list size - label size = 0; - - labelList patchIDs(polyMeshPatches.size(), -1); - - forAll(polyMeshPatches, patchI) - { - patchIDs[patchI] = - mesh.boundaryMesh().findPatchID(polyMeshPatches[patchI]); - - if (patchIDs[patchI] < 0) - { - FatalErrorIn("makeFaMesh:") - << "Patch " << polyMeshPatches[patchI] << " does not exist" - << exit(FatalError); - } - - size += mesh.boundaryMesh()[patchIDs[patchI]].size(); - } - - labelList faceLabels(size, -1); - - sort(patchIDs); - - - // Filling of faceLabels list - label faceI = -1; - - forAll(polyMeshPatches, patchI) - { - label start = mesh.boundaryMesh()[patchIDs[patchI]].start(); - - label size = mesh.boundaryMesh()[patchIDs[patchI]].size(); - - for (label i = 0; i < size; ++i) - { - faceLabels[++faceI] = start + i; - } - } - - // Creating faMesh - Info << "Create faMesh ... "; - - faMesh areaMesh + argList::addBoolOption ( - mesh, - faceLabels + "write-edges-obj", + "Write mesh edges as obj files and exit", + false // could make an advanced option ); - Info << "Done" << endl; - - - // Determination of faPatch ID for each boundary edge. - // Result is in the bndEdgeFaPatchIDs list - const indirectPrimitivePatch& patch = areaMesh.patch(); - - labelList faceCells(faceLabels.size(), -1); - - forAll(faceCells, faceI) - { - label faceID = faceLabels[faceI]; - - faceCells[faceI] = mesh.faceOwner()[faceID]; - } - - labelList meshEdges = - patch.meshEdges - ( - mesh.edges(), - mesh.cellEdges(), - faceCells - ); - - const labelListList& edgeFaces = mesh.edgeFaces(); - - const label nTotalEdges = patch.nEdges(); - const label nInternalEdges = patch.nInternalEdges(); - - labelList bndEdgeFaPatchIDs(nTotalEdges - nInternalEdges, -1); - - for (label edgeI = nInternalEdges; edgeI < nTotalEdges; ++edgeI) - { - label curMeshEdge = meshEdges[edgeI]; - - labelList curEdgePatchIDs(2, label(-1)); - - label patchI = -1; - forAll(edgeFaces[curMeshEdge], faceI) - { - label curFace = edgeFaces[curMeshEdge][faceI]; - - label curPatchID = mesh.boundaryMesh().whichPatch(curFace); - - if (curPatchID != -1) - { - curEdgePatchIDs[++patchI] = curPatchID; - } - } - - for (label pI = 0; pI < faPatches.size() - 1; ++pI) - { - if - ( - ( - curEdgePatchIDs[0] == faPatches[pI].ownPolyPatchID_ - && curEdgePatchIDs[1] == faPatches[pI].ngbPolyPatchID_ - ) - || - ( - curEdgePatchIDs[1] == faPatches[pI].ownPolyPatchID_ - && curEdgePatchIDs[0] == faPatches[pI].ngbPolyPatchID_ - ) - ) - { - bndEdgeFaPatchIDs[edgeI - nInternalEdges] = pI; - break; - } - } - } - - - // Set edgeLabels for each faPatch - for (label pI=0; pI<(faPatches.size()-1); ++pI) - { - SLList<label> tmpList; - - forAll(bndEdgeFaPatchIDs, eI) - { - if (bndEdgeFaPatchIDs[eI] == pI) - { - tmpList.append(nInternalEdges + eI); - } - } - - faPatches[pI].edgeLabels_ = tmpList; - } + #include "addRegionOption.H" + #include "setRootCase.H" + #include "createTime.H" + #include "createNamedPolyMesh.H" - // Check for undefined edges - SLList<label> tmpList; + // Reading faMeshDefinition dictionary + #include "findMeshDefinitionDict.H" - forAll(bndEdgeFaPatchIDs, eI) + // Inject/overwrite name for optional 'empty' patch + word patchName; + if (args.readIfPresent("empty-patch", patchName)) { - if (bndEdgeFaPatchIDs[eI] == -1) - { - tmpList.append(nInternalEdges + eI); - } + meshDefDict.add("emptyPatch", patchName, true); } - if (tmpList.size() > 0) - { - label pI = faPatches.size()-1; - - faPatches[pI].name_ = "undefined"; - faPatches[pI].type_ = "patch"; - faPatches[pI].edgeLabels_ = tmpList; - } + // Create + faMesh areaMesh(mesh, meshDefDict); - // Add good patches to faMesh - SLList<faPatch*> faPatchLst; + bool quickExit = false; - for (label pI = 0; pI < faPatches.size(); ++pI) + if (args.found("write-edges-obj")) { - faPatches[pI].dict_.add("type", faPatches[pI].type_); - faPatches[pI].dict_.add("edgeLabels", faPatches[pI].edgeLabels_); - faPatches[pI].dict_.add - ( - "ngbPolyPatchIndex", - faPatches[pI].ngbPolyPatchID_ - ); - - if(faPatches[pI].edgeLabels_.size() > 0) - { - faPatchLst.append - ( - faPatch::New - ( - faPatches[pI].name_, - faPatches[pI].dict_, - pI, - areaMesh.boundary() - ).ptr() - ); - } + quickExit = true; + #include "faMeshWriteEdgesOBJ.H" } - word emptyPatchName; - if (args.readIfPresent("addEmptyPatch", emptyPatchName)) + if (quickExit) { - dictionary emptyPatchDict; - emptyPatchDict.add("type", "empty"); - emptyPatchDict.add("edgeLabels", labelList()); - emptyPatchDict.add("ngbPolyPatchIndex", -1); - - faPatchLst.append - ( - faPatch::New - ( - emptyPatchName, - emptyPatchDict, - faPatchLst.size(), - areaMesh.boundary() - ).ptr() - ); + Info<< "\nEnd\n" << endl; + return 0; } - Info << "Add faPatches ... "; - areaMesh.addFaPatches(List<faPatch*>(faPatchLst)); - Info << "Done" << endl; + // Set the precision of the points data to 10 + IOstream::defaultPrecision(10); - // Writing faMesh - Info << "Write finite area mesh ... "; + Info<< nl << "Write finite area mesh." << nl; areaMesh.write(); + Info<< endl; + + #include "decomposeFaFields.H" - Info << "\nEnd" << endl; + Info << "\nEnd\n" << endl; return 0; } diff --git a/applications/utilities/parallelProcessing/decomposePar/Make/files b/applications/utilities/parallelProcessing/decomposePar/Make/files index 03abb7247f26cd5ae2498557e2ded310f474c2ed..d8bc47a3151310dffc671ff0de244ac13d44fa7e 100644 --- a/applications/utilities/parallelProcessing/decomposePar/Make/files +++ b/applications/utilities/parallelProcessing/decomposePar/Make/files @@ -1,4 +1,5 @@ decomposePar.C + domainDecomposition.C domainDecompositionMesh.C domainDecompositionDistribute.C @@ -7,10 +8,6 @@ domainDecompositionWrite.C domainDecompositionDryRun.C domainDecompositionDryRunWrite.C -dimFieldDecomposer.C -pointFieldDecomposer.C -faMeshDecomposition.C -faFieldDecomposer.C lagrangianFieldDecomposer.C EXE = $(FOAM_APPBIN)/decomposePar diff --git a/applications/utilities/parallelProcessing/decomposePar/Make/options b/applications/utilities/parallelProcessing/decomposePar/Make/options index 104ca56d7c66b44bb916a3f1649c0e33422f0f5d..4acbf00e42e6142854f1cbeb7e47b383055aeac2 100644 --- a/applications/utilities/parallelProcessing/decomposePar/Make/options +++ b/applications/utilities/parallelProcessing/decomposePar/Make/options @@ -6,7 +6,8 @@ EXE_INC = \ -I$(LIB_SRC)/lagrangian/basic/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \ -I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \ - -I$(LIB_SRC)/parallel/decompose/decompose/lnInclude + -I$(LIB_SRC)/parallel/decompose/decompose/lnInclude \ + -I$(LIB_SRC)/parallel/decompose/faDecompose/lnInclude EXE_LIBS = \ -lfiniteArea \ @@ -18,5 +19,6 @@ EXE_LIBS = \ -lgenericPatchFields \ -ldecompositionMethods \ -ldecompose \ + -lfaDecompose \ -L$(FOAM_LIBBIN)/dummy \ -lkahipDecomp -lmetisDecomp -lscotchDecomp diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C index 7c9784ce8db8b298d397034cc1ff7135daecdccb..292e694f71e8d19d31c7473f7dd062bcfa81a961 100644 --- a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C +++ b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C @@ -162,7 +162,6 @@ Usage #include "regionProperties.H" #include "readFields.H" -#include "dimFieldDecomposer.H" #include "fvFieldDecomposer.H" #include "pointFieldDecomposer.H" #include "lagrangianFieldDecomposer.H" @@ -173,11 +172,52 @@ Usage #include "faMeshDecomposition.H" #include "faFieldDecomposer.H" -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // namespace Foam { +// Read proc addressing at specific instance. +// Uses polyMesh/fvMesh meshSubDir by default +autoPtr<labelIOList> procAddressing +( + const fvMesh& procMesh, + const word& name, + const word& instance, + const word& local = fvMesh::meshSubDir +) +{ + return autoPtr<labelIOList>::New + ( + IOobject + ( + name, + instance, + local, + procMesh, + IOobject::MUST_READ, + IOobject::NO_WRITE, + false // do not register + ) + ); +} + + +// Read proc addressing at specific instance. +// Uses the finiteArea meshSubDir +autoPtr<labelIOList> faProcAddressing +( + const fvMesh& procMesh, + const word& name, + const word& instance, + const word& local = faMesh::meshSubDir +) +{ + return procAddressing(procMesh, name, instance, local); +} + + +// Return cached or read proc addressing from facesInstance const labelIOList& procAddressing ( const PtrList<fvMesh>& procMeshList, @@ -193,19 +233,7 @@ const labelIOList& procAddressing procAddressingList.set ( proci, - new labelIOList - ( - IOobject - ( - name, - procMesh.facesInstance(), - procMesh.meshSubDir, - procMesh, - IOobject::MUST_READ, - IOobject::NO_WRITE, - false - ) - ) + procAddressing(procMesh, name, procMesh.facesInstance()) ); } return procAddressingList[proci]; @@ -275,7 +303,7 @@ void decomposeUniform } } -} +} // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -682,7 +710,6 @@ int main(int argc, char *argv[]) PtrList<labelIOList> cellProcAddressingList(mesh.nProcs()); PtrList<labelIOList> boundaryProcAddressingList(mesh.nProcs()); PtrList<fvFieldDecomposer> fieldDecomposerList(mesh.nProcs()); - PtrList<dimFieldDecomposer> dimFieldDecomposerList(mesh.nProcs()); PtrList<labelIOList> pointProcAddressingList(mesh.nProcs()); PtrList<pointFieldDecomposer> pointFieldDecomposerList ( @@ -1047,7 +1074,6 @@ int main(int argc, char *argv[]) { Info<< "Processor " << proci << ": field transfer" << endl; - // open the database if (!processorDbList.set(proci)) { @@ -1112,7 +1138,7 @@ int main(int argc, char *argv[]) ); - // FV fields + // FV fields: volume, surface, internal { if (!fieldDecomposerList.set(proci)) { @@ -1132,6 +1158,7 @@ int main(int argc, char *argv[]) const fvFieldDecomposer& fieldDecomposer = fieldDecomposerList[proci]; + // vol fields fieldDecomposer.decomposeFields(volScalarFields); fieldDecomposer.decomposeFields(volVectorFields); fieldDecomposer.decomposeFields @@ -1141,6 +1168,7 @@ int main(int argc, char *argv[]) fieldDecomposer.decomposeFields(volSymmTensorFields); fieldDecomposer.decomposeFields(volTensorFields); + // surface fields fieldDecomposer.decomposeFields(surfaceScalarFields); fieldDecomposer.decomposeFields(surfaceVectorFields); fieldDecomposer.decomposeFields @@ -1153,6 +1181,13 @@ int main(int argc, char *argv[]) ); fieldDecomposer.decomposeFields(surfaceTensorFields); + // internal fields + fieldDecomposer.decomposeFields(dimScalarFields); + fieldDecomposer.decomposeFields(dimVectorFields); + fieldDecomposer.decomposeFields(dimSphericalTensorFields); + fieldDecomposer.decomposeFields(dimSymmTensorFields); + fieldDecomposer.decomposeFields(dimTensorFields); + if (times.size() == 1) { // Clear cached decomposer @@ -1160,37 +1195,6 @@ int main(int argc, char *argv[]) } } - // Dimensioned fields - { - if (!dimFieldDecomposerList.set(proci)) - { - dimFieldDecomposerList.set - ( - proci, - new dimFieldDecomposer - ( - mesh, - procMesh, - faceProcAddressing, - cellProcAddressing - ) - ); - } - const dimFieldDecomposer& dimDecomposer = - dimFieldDecomposerList[proci]; - - dimDecomposer.decomposeFields(dimScalarFields); - dimDecomposer.decomposeFields(dimVectorFields); - dimDecomposer.decomposeFields(dimSphericalTensorFields); - dimDecomposer.decomposeFields(dimSymmTensorFields); - dimDecomposer.decomposeFields(dimTensorFields); - - if (times.size() == 1) - { - dimFieldDecomposerList.set(proci, nullptr); - } - } - // Point fields if @@ -1366,18 +1370,24 @@ int main(int argc, char *argv[]) faMesh::meshSubDir, mesh, IOobject::READ_IF_PRESENT, - IOobject::NO_WRITE + IOobject::NO_WRITE, + false // not registered ); if (faMeshBoundaryIOobj.typeHeaderOk<faBoundaryMesh>(true)) { - Info << "\nFinite area mesh decomposition" << endl; + Info<< "\nFinite area mesh decomposition" << endl; - faMeshDecomposition aMesh(mesh); + // Always based on the volume decomposition! + faMeshDecomposition aMesh + ( + mesh, + mesh.nProcs(), + mesh.model() + ); aMesh.decomposeMesh(); - aMesh.writeDecomposition(); @@ -1404,13 +1414,29 @@ int main(int argc, char *argv[]) PtrList<edgeScalarField> edgeScalarFields; readFields(aMesh, objects, edgeScalarFields); - Info << endl; + const label nAreaFields = + ( + areaScalarFields.size() + + areaVectorFields.size() + + areaSphericalTensorFields.size() + + areaSymmTensorFields.size() + + areaTensorFields.size() + + edgeScalarFields.size() + ); + + Info<< endl; + Info<< "Finite area field transfer: " + << nAreaFields << " fields" << endl; // Split the fields over processors - for (label procI = 0; procI < mesh.nProcs(); procI++) + for + ( + label proci = 0; + nAreaFields && proci < mesh.nProcs(); + ++proci + ) { - Info<< "Processor " << procI - << ": finite area field transfer" << endl; + Info<< " Processor " << proci << endl; // open the database Time processorDb @@ -1418,7 +1444,7 @@ int main(int argc, char *argv[]) Time::controlDictName, args.rootPath(), args.caseName() - / ("processor" + Foam::name(procI)) + / ("processor" + Foam::name(proci)) ); processorDb.setTime(runTime); @@ -1441,7 +1467,7 @@ int main(int argc, char *argv[]) // procAddressing // ( // procMeshList, - // procI, + // proci, // "faceProcAddressing", // faceProcAddressingList // ); @@ -1450,84 +1476,59 @@ int main(int argc, char *argv[]) // procAddressing // ( // procMeshList, - // procI, + // proci, // "boundaryProcAddressing", // boundaryProcAddressingList // ); - labelIOList faceProcAddressing - ( - IOobject - ( - "faceProcAddressing", - "constant", - procMesh.meshSubDir, - procFvMesh, - IOobject::MUST_READ, - IOobject::NO_WRITE - ) - ); + // Addressing from faMesh (not polyMesh) meshSubDir - labelIOList boundaryProcAddressing - ( - IOobject + autoPtr<labelIOList> tfaceProcAddr = + faProcAddressing ( - "boundaryProcAddressing", - "constant", - procMesh.meshSubDir, procFvMesh, - IOobject::MUST_READ, - IOobject::NO_WRITE - ) - ); - - // FA fields - if - ( - areaScalarFields.size() - || areaVectorFields.size() - || areaSphericalTensorFields.size() - || areaSymmTensorFields.size() - || areaTensorFields.size() - || edgeScalarFields.size() - ) - { - labelIOList edgeProcAddressing - ( - IOobject - ( - "edgeProcAddressing", - "constant", - procMesh.meshSubDir, - procFvMesh, - IOobject::MUST_READ, - IOobject::NO_WRITE - ) + "faceProcAddressing", + runTime.constant() ); + auto& faceProcAddressing = *tfaceProcAddr; - faFieldDecomposer fieldDecomposer + autoPtr<labelIOList> tboundaryProcAddr = + faProcAddressing ( - aMesh, - procMesh, - edgeProcAddressing, - faceProcAddressing, - boundaryProcAddressing + procFvMesh, + "boundaryProcAddressing", + runTime.constant() ); + auto& boundaryProcAddressing = *tboundaryProcAddr; - fieldDecomposer.decomposeFields(areaScalarFields); - fieldDecomposer.decomposeFields(areaVectorFields); - fieldDecomposer.decomposeFields + autoPtr<labelIOList> tedgeProcAddr = + faProcAddressing ( - areaSphericalTensorFields - ); - fieldDecomposer.decomposeFields - ( - areaSymmTensorFields + procFvMesh, + "edgeProcAddressing", + runTime.constant() ); - fieldDecomposer.decomposeFields(areaTensorFields); + const auto& edgeProcAddressing = *tedgeProcAddr; - fieldDecomposer.decomposeFields(edgeScalarFields); - } + faFieldDecomposer fieldDecomposer + ( + aMesh, + procMesh, + edgeProcAddressing, + faceProcAddressing, + boundaryProcAddressing + ); + + fieldDecomposer.decomposeFields(areaScalarFields); + fieldDecomposer.decomposeFields(areaVectorFields); + fieldDecomposer.decomposeFields + ( + areaSphericalTensorFields + ); + fieldDecomposer.decomposeFields(areaSymmTensorFields); + fieldDecomposer.decomposeFields(areaTensorFields); + + fieldDecomposer.decomposeFields(edgeScalarFields); } } } diff --git a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C index 40efd741514c9c903bc8a273c8e99d918b50ef26..f3e7c2dfc7ff682b14e46c54a648807da89972ca 100644 --- a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C +++ b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C @@ -120,16 +120,27 @@ Foam::domainDecomposition::domainDecomposition procProcessorPatchSubPatchIDs_(nProcs_), procProcessorPatchSubPatchStarts_(nProcs_) { - decompositionModel::New - ( - *this, - decompDictFile - ).readIfPresent("distributed", distributed_); + updateParameters(this->model()); } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +const Foam::decompositionModel& Foam::domainDecomposition::model() const +{ + return decompositionModel::New(*this, decompDictFile_); +} + + +void Foam::domainDecomposition::updateParameters +( + const dictionary& params +) +{ + params.readIfPresent("distributed", distributed_); +} + + bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets) { Info<< "\nConstructing processor meshes" << endl; @@ -408,10 +419,9 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets) nInterProcPatches += curSubPatchIDs[procPatchi].size(); } - List<polyPatch*> procPatches + PtrList<polyPatch> procPatches ( - curPatchSizes.size() + nInterProcPatches, - reinterpret_cast<polyPatch*>(0) + curPatchSizes.size() + nInterProcPatches ); label nPatches = 0; @@ -434,13 +444,17 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets) ); // Map existing patches - procPatches[nPatches] = meshPatch.clone + procPatches.set ( - procMesh.boundaryMesh(), nPatches, - patchMapper.directAddressing(), - curPatchStarts[patchi] - ).ptr(); + meshPatch.clone + ( + procMesh.boundaryMesh(), + nPatches, + patchMapper.directAddressing(), + curPatchStarts[patchi] + ) + ); nPatches++; } @@ -464,7 +478,9 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets) if (subPatchID[i] == -1) { // From internal faces - procPatches[nPatches] = + procPatches.set + ( + nPatches, new processorPolyPatch ( size, @@ -473,7 +489,8 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets) procMesh.boundaryMesh(), proci, curNeighbourProcessors[procPatchi] - ); + ) + ); } else { @@ -483,7 +500,9 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets) boundaryMesh()[subPatchID[i]] ); - procPatches[nPatches] = + procPatches.set + ( + nPatches, new processorCyclicPolyPatch ( size, @@ -494,12 +513,12 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets) curNeighbourProcessors[procPatchi], pcPatch.name(), pcPatch.transform() - ); + ) + ); } curStart += size; - - nPatches++; + ++nPatches; } } diff --git a/applications/utilities/parallelProcessing/decomposePar/domainDecompositionDistribute.C b/applications/utilities/parallelProcessing/decomposePar/domainDecompositionDistribute.C index aedbbb34e59d5d557d0184c939c4a7c35a4c8a2d..a448982b1f681126e000aaf91b5542af39eb17ac 100644 --- a/applications/utilities/parallelProcessing/decomposePar/domainDecompositionDistribute.C +++ b/applications/utilities/parallelProcessing/decomposePar/domainDecompositionDistribute.C @@ -26,12 +26,8 @@ License \*---------------------------------------------------------------------------*/ #include "domainDecomposition.H" -#include "decompositionMethod.H" #include "cpuTime.H" -#include "cellSet.H" -#include "regionSplit.H" -#include "Tuple2.H" -#include "faceSet.H" +#include "decompositionMethod.H" #include "decompositionModel.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/applications/utilities/parallelProcessing/decomposePar/faFieldDecomposer.C b/applications/utilities/parallelProcessing/decomposePar/faFieldDecomposer.C deleted file mode 100644 index 2ee76091d3e757214371c93c4832b560d90cdf56..0000000000000000000000000000000000000000 --- a/applications/utilities/parallelProcessing/decomposePar/faFieldDecomposer.C +++ /dev/null @@ -1,238 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | www.openfoam.com - \\/ M anipulation | -------------------------------------------------------------------------------- - Copyright (C) 2016-2017 Wikki 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 "faFieldDecomposer.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -faFieldDecomposer::patchFieldDecomposer::patchFieldDecomposer -( - const label sizeBeforeMapping, - const labelUList& addressingSlice, - const label addressingOffset -) -: - sizeBeforeMapping_(sizeBeforeMapping), - directAddressing_(addressingSlice) -{ - forAll(directAddressing_, i) - { - // Subtract one to align addressing. - // directAddressing_[i] -= addressingOffset + 1; - // ZT, 12/Nov/2010 - directAddressing_[i] -= addressingOffset; - } -} - - -faFieldDecomposer::processorAreaPatchFieldDecomposer:: -processorAreaPatchFieldDecomposer -( - const faMesh& mesh, - const labelUList& addressingSlice -) -: - sizeBeforeMapping_(mesh.nFaces()), - addressing_(addressingSlice.size()), - weights_(addressingSlice.size()) -{ - const scalarField& weights = mesh.weights().internalField(); - const labelList& own = mesh.edgeOwner(); - const labelList& neighb = mesh.edgeNeighbour(); - - forAll(addressing_, i) - { - // Subtract one to align addressing. - label ai = addressingSlice[i]; -// label ai = mag(addressingSlice[i]) - 1; - - if (ai < neighb.size()) - { - // This is a regular edge. it has been an internal edge - // of the original mesh and now it has become a edge - // on the parallel boundary - addressing_[i].setSize(2); - weights_[i].setSize(2); - - addressing_[i][0] = own[ai]; - addressing_[i][1] = neighb[ai]; - - weights_[i][0] = weights[ai]; - weights_[i][1] = 1.0 - weights[ai]; - } - else - { - // This is a edge that used to be on a cyclic boundary - // but has now become a parallel patch edge. I cannot - // do the interpolation properly (I would need to look - // up the different (edge) list of data), so I will - // just grab the value from the owner face - // - addressing_[i].setSize(1); - weights_[i].setSize(1); - - addressing_[i][0] = own[ai]; - - weights_[i][0] = 1.0; - } - } -} - - -faFieldDecomposer::processorEdgePatchFieldDecomposer:: -processorEdgePatchFieldDecomposer -( - label sizeBeforeMapping, - const labelUList& addressingSlice -) -: - sizeBeforeMapping_(sizeBeforeMapping), - addressing_(addressingSlice.size()), - weights_(addressingSlice.size()) -{ - forAll(addressing_, i) - { - addressing_[i].setSize(1); - weights_[i].setSize(1); - - addressing_[i][0] = mag(addressingSlice[i]) - 1; - weights_[i][0] = sign(addressingSlice[i]); - } -} - - -faFieldDecomposer::faFieldDecomposer -( - const faMesh& completeMesh, - const faMesh& procMesh, - const labelList& edgeAddressing, - const labelList& faceAddressing, - const labelList& boundaryAddressing -) -: - completeMesh_(completeMesh), - procMesh_(procMesh), - edgeAddressing_(edgeAddressing), - faceAddressing_(faceAddressing), - boundaryAddressing_(boundaryAddressing), - patchFieldDecomposerPtrs_ - ( - procMesh_.boundary().size(), - static_cast<patchFieldDecomposer*>(NULL) - ), - processorAreaPatchFieldDecomposerPtrs_ - ( - procMesh_.boundary().size(), - static_cast<processorAreaPatchFieldDecomposer*>(NULL) - ), - processorEdgePatchFieldDecomposerPtrs_ - ( - procMesh_.boundary().size(), - static_cast<processorEdgePatchFieldDecomposer*>(NULL) - ) -{ - forAll(boundaryAddressing_, patchi) - { - if (boundaryAddressing_[patchi] >= 0) - { - patchFieldDecomposerPtrs_[patchi] = new patchFieldDecomposer - ( - completeMesh_.boundary()[boundaryAddressing_[patchi]].size(), - procMesh_.boundary()[patchi].patchSlice(edgeAddressing_), -// completeMesh_.boundaryMesh() - completeMesh_.boundary() - [ - boundaryAddressing_[patchi] - ].start() - ); - } - else - { - processorAreaPatchFieldDecomposerPtrs_[patchi] = - new processorAreaPatchFieldDecomposer - ( - completeMesh_, - procMesh_.boundary()[patchi].patchSlice(edgeAddressing_) - ); - - processorEdgePatchFieldDecomposerPtrs_[patchi] = - new processorEdgePatchFieldDecomposer - ( - procMesh_.boundary()[patchi].size(), - static_cast<const labelUList&> - ( - procMesh_.boundary()[patchi].patchSlice - ( - edgeAddressing_ - ) - ) - ); - } - } -} - - -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // - -faFieldDecomposer::~faFieldDecomposer() -{ - forAll(patchFieldDecomposerPtrs_, patchi) - { - if (patchFieldDecomposerPtrs_[patchi]) - { - delete patchFieldDecomposerPtrs_[patchi]; - } - } - - forAll(processorAreaPatchFieldDecomposerPtrs_, patchi) - { - if (processorAreaPatchFieldDecomposerPtrs_[patchi]) - { - delete processorAreaPatchFieldDecomposerPtrs_[patchi]; - } - } - - forAll(processorEdgePatchFieldDecomposerPtrs_, patchi) - { - if (processorEdgePatchFieldDecomposerPtrs_[patchi]) - { - delete processorEdgePatchFieldDecomposerPtrs_[patchi]; - } - } -} - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// ************************************************************************* // diff --git a/applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposer.H b/applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposer.H index 31e209c871bab8077901011c6e9875f7b34c8a76..18a1746cb4e00feb0421241df72e6a44bf51df92 100644 --- a/applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposer.H +++ b/applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposer.H @@ -31,7 +31,7 @@ Description SourceFiles lagrangianFieldDecomposer.C - lagrangianFieldDecomposerDecomposeFields.C + lagrangianFieldDecomposerFields.C \*---------------------------------------------------------------------------*/ @@ -84,7 +84,7 @@ public: //- Construct from components lagrangianFieldDecomposer ( - const polyMesh& mesh, + const polyMesh& mesh, //<! unused const polyMesh& procMesh, const labelList& faceProcAddressing, const labelList& cellProcAddressing, @@ -156,7 +156,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "lagrangianFieldDecomposerDecomposeFields.C" + #include "lagrangianFieldDecomposerFields.C" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposerDecomposeFields.C b/applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposerFields.C similarity index 100% rename from applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposerDecomposeFields.C rename to applications/utilities/parallelProcessing/decomposePar/lagrangianFieldDecomposerFields.C diff --git a/applications/utilities/parallelProcessing/decomposePar/readFields.C b/applications/utilities/parallelProcessing/decomposePar/readFields.C index 231981bcee1fe41e1a4d994f6d779f991f0d8a6e..1b0c948c9c1507338bfc139e3fb012eb27169e5a 100644 --- a/applications/utilities/parallelProcessing/decomposePar/readFields.C +++ b/applications/utilities/parallelProcessing/decomposePar/readFields.C @@ -42,7 +42,7 @@ void Foam::readFields typedef GeometricField<Type, PatchField, GeoMesh> GeoField; // Search list of objects for fields of type GeoField - IOobjectList fieldObjects(objects.lookupClass(GeoField::typeName)); + IOobjectList fieldObjects(objects.lookupClass<GeoField>()); // Remove the cellDist field auto iter = fieldObjects.find("cellDist"); @@ -51,12 +51,12 @@ void Foam::readFields fieldObjects.erase(iter); } - // Get sorted set of names (different processors might read objects in - // different order) + // Use sorted set of names + // (different processors might read objects in different order) const wordList masterNames(fieldObjects.sortedNames()); // Construct the fields - fields.setSize(masterNames.size()); + fields.resize(masterNames.size()); forAll(masterNames, i) { @@ -76,17 +76,14 @@ void Foam::readFields ) { // Search list of objects for fields of type GeomField - IOobjectList fieldObjects(objects.lookupClass(GeoField::typeName)); + IOobjectList fieldObjects(objects.lookupClass<GeoField>()); - // Construct the fields - fields.setSize(fieldObjects.size()); - - // Get sorted set of names (different processors might read objects in - // different order) + // Use sorted set of names + // (different processors might read objects in different order) const wordList masterNames(fieldObjects.sortedNames()); // Construct the fields - fields.setSize(masterNames.size()); + fields.resize(masterNames.size()); forAll(masterNames, i) { diff --git a/applications/utilities/parallelProcessing/reconstructPar/Make/files b/applications/utilities/parallelProcessing/reconstructPar/Make/files index 660641033b0b5ba9bfb380cb125176cc5e285806..37acabe62dbc9c7eb1c485f2ee7df91c734e1bc2 100644 --- a/applications/utilities/parallelProcessing/reconstructPar/Make/files +++ b/applications/utilities/parallelProcessing/reconstructPar/Make/files @@ -1,5 +1,3 @@ -processorFaMeshes.C -faFieldReconstructor.C reconstructPar.C EXE = $(FOAM_APPBIN)/reconstructPar diff --git a/applications/utilities/parallelProcessing/reconstructPar/Make/options b/applications/utilities/parallelProcessing/reconstructPar/Make/options index 75f62d17291a44a32bcb0efbb11e542378497eb8..a526d94fbc4eacbf7f58eb18eef3dd4c882d4405 100644 --- a/applications/utilities/parallelProcessing/reconstructPar/Make/options +++ b/applications/utilities/parallelProcessing/reconstructPar/Make/options @@ -4,7 +4,8 @@ EXE_INC = \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \ - -I$(LIB_SRC)/parallel/reconstruct/reconstruct/lnInclude + -I$(LIB_SRC)/parallel/reconstruct/reconstruct/lnInclude \ + -I$(LIB_SRC)/parallel/reconstruct/faReconstruct/lnInclude EXE_LIBS = \ -lfiniteArea \ @@ -13,4 +14,5 @@ EXE_LIBS = \ -llagrangian \ -lgenericPatchFields \ -ldynamicMesh \ - -lreconstruct + -lreconstruct \ + -lfaReconstruct diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/writeAreaFields.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/writeAreaFields.H index 959881e65a45d083c9de5233270576f9fb2b4cd9..9bd2cb8c37c6f0dd479d9fe02669ef51df2b596d 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/writeAreaFields.H +++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/writeAreaFields.H @@ -39,7 +39,7 @@ SourceFiles #define writeAreaFields_H #include "readFields.H" -#include "foamVtkIndPatchGeoFieldsWriter.H" +#include "foamVtkUIndPatchGeoFieldsWriter.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -47,7 +47,7 @@ namespace Foam { // Writer type for finite-area mesh + fields -typedef vtk::indirectPatchGeoFieldsWriter vtkWriterType_areaMesh; +typedef vtk::uindirectPatchGeoFieldsWriter vtkWriterType_areaMesh; template<class GeoField> bool writeAreaField diff --git a/bin/tools/CleanFunctions b/bin/tools/CleanFunctions index d001d44bde72c603c0d07da3a28ed824f9b93b3e..f23d7f05675d5606f380e742812cbefc2f4e832c 100644 --- a/bin/tools/CleanFunctions +++ b/bin/tools/CleanFunctions @@ -6,7 +6,7 @@ # \\/ M anipulation | #------------------------------------------------------------------------------ # Copyright (C) 2011-2016 OpenFOAM Foundation -# Copyright (C) 2015-2020 OpenCFD Ltd. +# Copyright (C) 2015-2021 OpenCFD Ltd. #------------------------------------------------------------------------------ # License # This file is part of OpenFOAM, distributed under GPL-3.0-or-later. @@ -138,15 +138,16 @@ cleanCase() then rm -f polyMesh/blockMeshDict echo - echo "Warning: not removing constant/polyMesh/ " - echo " it contains a blockMeshDict, which should normally be under system/ instead" + echo "Warning: not removing constant/polyMesh/" + echo " It contains a 'blockMeshDict.m4' file." + echo " Relocate the file to system/ to avoid this warning" echo elif [ -e polyMesh/blockMeshDict ] then echo - echo "Warning: not removing constant/polyMesh/ " - echo " it contains a blockMeshDict, which should normally be under system/ instead" - echo + echo "Warning: not removing constant/polyMesh/" + echo " It contains a 'blockMeshDict' file." + echo " Relocate the file to system/ to avoid this warning" else # Remove polyMesh entirely if there is no blockMeshDict rm -rf polyMesh @@ -187,12 +188,26 @@ cleanUcomponents() } -cleanFaMesh () +cleanFaMesh() { - rm -rf \ - constant/faMesh/faceLabels* \ - constant/faMesh/faBoundary* \ - ; + ( + cd constant 2>/dev/null || exit 0 + + # Old constant/polyMesh location for blockMeshDict still in use? + # - emit a gentle warning + if [ -e faMesh/faMeshDefinition ] + then + rm -f faMesh/faceLabels* faMesh/faBoundary* + echo + echo "Warning: not removing the constant/faMesh/ directory" + echo " It contains a 'faMeshDefinition' file" + echo " Relocate the file to system/ to avoid this warning" + echo + else + # Remove faMesh/ entirely if there is no faMeshDefinition + rm -rf faMesh + fi + ) } diff --git a/src/dynamicFaMesh/interfaceTrackingFvMesh/interfaceTrackingFvMesh.C b/src/dynamicFaMesh/interfaceTrackingFvMesh/interfaceTrackingFvMesh.C index bf90e5220abc223071128c4ee322d9efd72c5194..5e2cb8a3caa3cc3cce2982b1988718819a5fbc41 100644 --- a/src/dynamicFaMesh/interfaceTrackingFvMesh/interfaceTrackingFvMesh.C +++ b/src/dynamicFaMesh/interfaceTrackingFvMesh/interfaceTrackingFvMesh.C @@ -48,7 +48,7 @@ License #include "turbulentTransportModel.H" #include "demandDrivenData.H" #include "unitConversion.H" -#include "foamVtkIndPatchWriter.H" +#include "foamVtkUIndPatchWriter.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -2270,7 +2270,7 @@ bool Foam::interfaceTrackingFvMesh::update() void Foam::interfaceTrackingFvMesh::writeVTK() const { - vtk::indirectPatchWriter writer + vtk::uindirectPatchWriter writer ( aMesh().patch(), vtk::formatType::LEGACY_ASCII, diff --git a/src/faOptions/faOption/faOption.C b/src/faOptions/faOption/faOption.C index 708f73885113285098a924d9105967a6391ff50e..9f98da33fe5691a5e9ae556d20a2024ed863d34b 100644 --- a/src/faOptions/faOption/faOption.C +++ b/src/faOptions/faOption/faOption.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2019-2020 OpenCFD Ltd. + Copyright (C) 2019-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -40,17 +40,6 @@ namespace Foam } -// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // - -void Foam::fa::option::constructMeshObjects() -{ - regionMeshPtr_.reset(new faMesh(mesh_)); - - vsmPtr_.reset(new volSurfaceMapping(regionMeshPtr_())); -} - - - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::fa::option::option @@ -67,16 +56,15 @@ Foam::fa::option::option patch_(patch), dict_(dict), coeffs_(dict.optionalSubDict(modelType + "Coeffs")), - active_(dict.getOrDefault<Switch>("active", true)), fieldNames_(), applied_(), regionName_(dict.get<word>("region")), regionMeshPtr_(nullptr), - vsmPtr_(nullptr) + vsmPtr_(nullptr), + active_(dict.getOrDefault("active", true)), + log(true) { - constructMeshObjects(); - - Info<< incrIndent << indent << "Source: " << name_ << endl << decrIndent; + Log << incrIndent << indent << "Source: " << name_ << endl << decrIndent; } diff --git a/src/faOptions/faOption/faOption.H b/src/faOptions/faOption/faOption.H index 253c26e2b1536ab21fb5e0340378cbfb899aaeb7..c8d69e473f999b9de9a202f7fbda15599033aee5 100644 --- a/src/faOptions/faOption/faOption.H +++ b/src/faOptions/faOption/faOption.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2019-2020 OpenCFD Ltd. + Copyright (C) 2019-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -75,13 +75,12 @@ SourceFiles #ifndef faOption_H #define faOption_H -#include "faMatrices.H" -#include "areaFields.H" +#include "faMatricesFwd.H" +#include "areaFieldsFwd.H" #include "dictionary.H" -#include "Switch.H" -#include "runTimeSelectionTables.H" #include "fvMesh.H" #include "volSurfaceMapping.H" +#include "runTimeSelectionTables.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -124,27 +123,35 @@ protected: //- Dictionary containing source coefficients dictionary coeffs_; - //- Source active flag - Switch active_; - //- Field names to apply source to - populated by derived models wordList fieldNames_; //- Applied flag list - corresponds to each fieldNames_ entry List<bool> applied_; - //- Region name + //- Region name (finite-area) word regionName_; - //- Pointer to the region mesh database - autoPtr<faMesh> regionMeshPtr_; +private: - //-Volume-to surface mapping - autoPtr<volSurfaceMapping> vsmPtr_; + // Private Data + + //- Demand-driven: pointer to region mesh database + mutable autoPtr<faMesh> regionMeshPtr_; + + //- Demand-driven: volume-to-surface mapping + mutable autoPtr<volSurfaceMapping> vsmPtr_; + + //- Source active flag + bool active_; public: + //- Switch write log to Info + bool log; + + //- Runtime type information TypeName("option"); @@ -188,7 +195,6 @@ public: //- on the freestore from an Istream class iNew { - //- Reference to the patch const fvPatch& patch_; @@ -239,37 +245,37 @@ public: // Access //- Return const access to the source name - inline const word& name() const; + inline const word& name() const noexcept; //- Return const access to the mesh database - inline const fvMesh& mesh() const; + inline const fvMesh& mesh() const noexcept; //- Return const access to fvPatch - inline const fvPatch& patch() const; + inline const fvPatch& patch() const noexcept; //- Return dictionary - inline const dictionary& coeffs() const; + inline const dictionary& coeffs() const noexcept; //- Return const access to the source active flag - inline bool active() const; + inline bool active() const noexcept; //- Set the applied flag to true for field index fieldi inline void setApplied(const label fieldi); - //- Return the region mesh database + //- The region name + inline const word& regionName() const noexcept; + + //- Return the region mesh database (demand-driven) inline const faMesh& regionMesh() const; - //- Return volSurfaceMapping + //- Return volSurfaceMapping (demand-driven) inline const volSurfaceMapping& vsm() const; - //- Region name - inline const word& regionName() const; - // Edit - //- Return access to the source active flag - inline Switch& active(); + //- Change source active flag, return previous value + inline bool active(const bool on) noexcept; // Checks diff --git a/src/faOptions/faOption/faOptionI.H b/src/faOptions/faOption/faOptionI.H index a541123f2752e01909762b7faed3d1420c7cdd2e..42ef920af60712fbbb6d692c4e559006c5a1d5e2 100644 --- a/src/faOptions/faOption/faOptionI.H +++ b/src/faOptions/faOption/faOptionI.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2019-2020 OpenCFD Ltd. + Copyright (C) 2019-2021 OpenCFD Ltd. ------------------------------------------------------------------------------ License This file is part of OpenFOAM. @@ -27,49 +27,51 @@ License // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -inline const Foam::word& Foam::fa::option::name() const +inline const Foam::word& Foam::fa::option::name() const noexcept { return name_; } -inline const Foam::fvMesh& Foam::fa::option::mesh() const +inline const Foam::fvMesh& Foam::fa::option::mesh() const noexcept { return mesh_; } -inline const Foam::fvPatch& Foam::fa::option::patch() const +inline const Foam::fvPatch& Foam::fa::option::patch() const noexcept { return patch_; } -inline const Foam::dictionary& Foam::fa::option::coeffs() const +inline const Foam::dictionary& Foam::fa::option::coeffs() const noexcept { return coeffs_; } -inline bool Foam::fa::option::active() const +inline bool Foam::fa::option::active() const noexcept { return active_; } -inline void Foam::fa::option::setApplied(const label fieldi) +inline bool Foam::fa::option::active(const bool on) noexcept { - applied_[fieldi] = true; + bool old(active_); + active_ = on; + return old; } -inline Foam::Switch& Foam::fa::option::active() +inline void Foam::fa::option::setApplied(const label fieldi) { - return active_; + applied_[fieldi] = true; } -inline const Foam::word& Foam::fa::option::regionName() const +inline const Foam::word& Foam::fa::option::regionName() const noexcept { return regionName_; } @@ -77,31 +79,21 @@ inline const Foam::word& Foam::fa::option::regionName() const inline const Foam::faMesh& Foam::fa::option::regionMesh() const { - if (regionMeshPtr_.valid()) + if (!regionMeshPtr_) { - return regionMeshPtr_(); + regionMeshPtr_.reset(new faMesh(mesh_)); } - else - { - FatalErrorInFunction - << "Region mesh not available" << abort(FatalError); - } - return *(new faMesh(mesh_)); + return *regionMeshPtr_; } inline const Foam::volSurfaceMapping& Foam::fa::option::vsm() const { - if (vsmPtr_.valid()) - { - return vsmPtr_(); - } - else + if (!vsmPtr_) { - FatalErrorInFunction - << "vsmPtr not available" << abort(FatalError); + vsmPtr_.reset(new volSurfaceMapping(this->regionMesh())); } - return *(new volSurfaceMapping(regionMeshPtr_())); + return *vsmPtr_; } diff --git a/src/faOptions/faOption/faOptionList.C b/src/faOptions/faOption/faOptionList.C index 80de3cf682efd2dbed3808cd6dd4c3699f4041a4..b722e457a6f91031ec4e6ca79f3b3fcd5b4ee342 100644 --- a/src/faOptions/faOption/faOptionList.C +++ b/src/faOptions/faOption/faOptionList.C @@ -92,7 +92,7 @@ Foam::fa::optionList::optionList const dictionary& dict ) : - PtrList<option>(), + PtrList<fa::option>(), mesh_(p.boundaryMesh().mesh()), patch_(p), checkTimeIndex_(mesh_.time().startTimeIndex() + 2) @@ -103,7 +103,7 @@ Foam::fa::optionList::optionList Foam::fa::optionList::optionList(const fvPatch& p) : - PtrList<option>(), + PtrList<fa::option>(), mesh_(p.boundaryMesh().mesh()), patch_(p), checkTimeIndex_(mesh_.time().startTimeIndex() + 2) diff --git a/src/faOptions/faOption/faOptionList.H b/src/faOptions/faOption/faOptionList.H index 290dc794a6596c960307fee872f9109fec70bad2..a479c9719667fea3bebc34f301462b6db50bfd72 100644 --- a/src/faOptions/faOption/faOptionList.H +++ b/src/faOptions/faOption/faOptionList.H @@ -46,10 +46,9 @@ SourceFile // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Forward Declarations namespace Foam { - -// Forward declaration of friend functions and operators namespace fa { class optionList; @@ -66,7 +65,7 @@ namespace fa class optionList : - public PtrList<option> + public PtrList<fa::option> { protected: @@ -118,7 +117,7 @@ public: // Constructors - //- Construct null + //- Construct from patch optionList(const fvPatch& p); //- Construct from mesh and dictionary @@ -126,8 +125,7 @@ public: //- Destructor - virtual ~optionList() - {} + virtual ~optionList() = default; // Member Functions diff --git a/src/faOptions/faOption/faOptionListTemplates.C b/src/faOptions/faOption/faOptionListTemplates.C index 1a954bcce453918c6aad227c2aba433930bd5001..96a266e5a38105d20979dbfbf8f88d55b4e5c5ac 100644 --- a/src/faOptions/faOption/faOptionListTemplates.C +++ b/src/faOptions/faOption/faOptionListTemplates.C @@ -26,6 +26,7 @@ License \*---------------------------------------------------------------------------*/ #include "profiling.H" +#include "areaFields.H" // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // diff --git a/src/faOptions/faceSetOption/faceSetOption.H b/src/faOptions/faceSetOption/faceSetOption.H index edbf26ed53b90f7b6b9a29da625338ca722dd07c..559cacdae264fa444b8d29ca4818081b3fd843c3 100644 --- a/src/faOptions/faceSetOption/faceSetOption.H +++ b/src/faOptions/faceSetOption/faceSetOption.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2019-2020 OpenCFD Ltd. + Copyright (C) 2019-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -102,7 +102,7 @@ namespace fa class faceSetOption : - public option + public fa::option { public: diff --git a/src/faOptions/sources/derived/contactHeatFluxSource/contactHeatFluxSource.H b/src/faOptions/sources/derived/contactHeatFluxSource/contactHeatFluxSource.H index 699c5214c0c52407e96d3d9ebbbc1b1c0c9c9c24..b5aeb34bb39ddf51ddac2520bc73832d5b3520cb 100644 --- a/src/faOptions/sources/derived/contactHeatFluxSource/contactHeatFluxSource.H +++ b/src/faOptions/sources/derived/contactHeatFluxSource/contactHeatFluxSource.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2019-2020 OpenCFD Ltd. + Copyright (C) 2019-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -98,7 +98,7 @@ namespace fa class contactHeatFluxSource : - public faceSetOption, + public fa::faceSetOption, public temperatureCoupledBase { // Private Data diff --git a/src/faOptions/sources/derived/externalFileSource/externalFileSource.C b/src/faOptions/sources/derived/externalFileSource/externalFileSource.C index f5a95479d23288d4df5861a6b943fcbbd405d045..81e93caa40eae7e80f831d807f34bacf220e1c1b 100644 --- a/src/faOptions/sources/derived/externalFileSource/externalFileSource.C +++ b/src/faOptions/sources/derived/externalFileSource/externalFileSource.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2019-2020 OpenCFD Ltd. + Copyright (C) 2019-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -26,8 +26,8 @@ License \*---------------------------------------------------------------------------*/ #include "externalFileSource.H" -#include "faMatrices.H" -#include "faCFD.H" +#include "fam.H" +#include "faScalarMatrix.H" #include "zeroGradientFaPatchFields.H" #include "addToRunTimeSelectionTable.H" diff --git a/src/faOptions/sources/derived/externalFileSource/externalFileSource.H b/src/faOptions/sources/derived/externalFileSource/externalFileSource.H index 6d6c0ec2dadfd0feed004bf0a6808d07a1709959..974f23925a100a23fe66c1796aa5d0c983c018ab 100644 --- a/src/faOptions/sources/derived/externalFileSource/externalFileSource.H +++ b/src/faOptions/sources/derived/externalFileSource/externalFileSource.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2019-2020 OpenCFD Ltd. + Copyright (C) 2019-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -89,7 +89,7 @@ namespace fa class externalFileSource : - public faceSetOption + public fa::faceSetOption { // Private Data diff --git a/src/faOptions/sources/derived/externalHeatFluxSource/externalHeatFluxSource.C b/src/faOptions/sources/derived/externalHeatFluxSource/externalHeatFluxSource.C index 478fc81b5cecb3f82c4b78f4e05cf0ded6076f02..22c8404e198428af53acfc82d9ebccfb070b372a 100644 --- a/src/faOptions/sources/derived/externalHeatFluxSource/externalHeatFluxSource.C +++ b/src/faOptions/sources/derived/externalHeatFluxSource/externalHeatFluxSource.C @@ -26,7 +26,8 @@ License \*---------------------------------------------------------------------------*/ #include "externalHeatFluxSource.H" -#include "addToRunTimeSelectionTable.H" +#include "fam.H" +#include "faScalarMatrix.H" #include "physicoChemicalConstants.H" #include "zeroGradientFaPatchFields.H" #include "addToRunTimeSelectionTable.H" diff --git a/src/faOptions/sources/derived/externalHeatFluxSource/externalHeatFluxSource.H b/src/faOptions/sources/derived/externalHeatFluxSource/externalHeatFluxSource.H index 97873b29ffd9fbd0178c9c12e896960646424624..26e8385276e7a47a3334c74ff4cc2d72025cd68a 100644 --- a/src/faOptions/sources/derived/externalHeatFluxSource/externalHeatFluxSource.H +++ b/src/faOptions/sources/derived/externalHeatFluxSource/externalHeatFluxSource.H @@ -121,7 +121,6 @@ SourceFiles #include "Function1.H" #include "areaFields.H" #include "faceSetOption.H" -#include "faCFD.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -136,7 +135,7 @@ namespace fa class externalHeatFluxSource : - public faceSetOption + public fa::faceSetOption { public: diff --git a/src/faOptions/sources/derived/jouleHeatingSource/jouleHeatingSource.C b/src/faOptions/sources/derived/jouleHeatingSource/jouleHeatingSource.C index 2d9cfc63218bb8a7993052feb939d735caa5d8e8..a752b74eff6e023ebf017e61a149c28a141ba05b 100644 --- a/src/faOptions/sources/derived/jouleHeatingSource/jouleHeatingSource.C +++ b/src/faOptions/sources/derived/jouleHeatingSource/jouleHeatingSource.C @@ -26,8 +26,8 @@ License \*---------------------------------------------------------------------------*/ #include "jouleHeatingSource.H" -#include "faMatrices.H" -#include "faCFD.H" +#include "fam.H" +#include "faScalarMatrix.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // diff --git a/src/faOptions/sources/derived/jouleHeatingSource/jouleHeatingSource.H b/src/faOptions/sources/derived/jouleHeatingSource/jouleHeatingSource.H index 4a5a279a145362059d9906fdd3dd5fc1f647c723..e3c99f68d1bc1aa0ea2384b56241433f325f362d 100644 --- a/src/faOptions/sources/derived/jouleHeatingSource/jouleHeatingSource.H +++ b/src/faOptions/sources/derived/jouleHeatingSource/jouleHeatingSource.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2019-2020 OpenCFD Ltd. + Copyright (C) 2019-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -156,7 +156,7 @@ namespace fa class jouleHeatingSource : - public faceSetOption + public fa::faceSetOption { // Private Data diff --git a/src/finiteArea/Make/files b/src/finiteArea/Make/files index e21879123296469a793dc1f06c1320c4b4164fcb..7a96d8c4a1ef5c25e0f3b7611f220daccd7c9d14 100644 --- a/src/finiteArea/Make/files +++ b/src/finiteArea/Make/files @@ -1,11 +1,13 @@ faMesh/faGlobalMeshData/faGlobalMeshData.C faMesh/faMesh.C faMesh/faMeshDemandDrivenData.C +faMesh/faMeshPatches.C faMesh/faMeshUpdate.C faMesh/faBoundaryMesh/faBoundaryMesh.C faPatches = faMesh/faPatches $(faPatches)/faPatch/faPatch.C +$(faPatches)/faPatch/faPatchData.C $(faPatches)/faPatch/faPatchNew.C $(faPatches)/basic/coupled/coupledFaPatch.C $(faPatches)/constraint/empty/emptyFaPatch.C diff --git a/src/finiteArea/faMatrices/faMatricesFwd.H b/src/finiteArea/faMatrices/faMatricesFwd.H new file mode 100644 index 0000000000000000000000000000000000000000..7383f960d0e0a09ddc95b995d33d85c11078c0a3 --- /dev/null +++ b/src/finiteArea/faMatrices/faMatricesFwd.H @@ -0,0 +1,59 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 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/>. + +Description + Forward declarations of standard faMatrix types/specializations. + +\*---------------------------------------------------------------------------*/ + +#ifndef faMatricesFwd_H +#define faMatricesFwd_H + +#include "fieldTypes.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template<class Type> class faMatrix; + +typedef faMatrix<scalar> faScalarMatrix; +typedef faMatrix<vector> faVectorMatrix; +typedef faMatrix<sphericalTensor> faSphericalTensorMatrix; +typedef faMatrix<symmTensor> faSymmTensorMatrix; +typedef faMatrix<tensor> faTensorMatrix; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteArea/faMesh/faBoundaryMesh/faBoundaryMesh.C b/src/finiteArea/faMesh/faBoundaryMesh/faBoundaryMesh.C index b436ecf9962bb54bac90a2d2e7d62d3774cc979c..da7962e51b101bb62f0f06704f188d47bc05d6c0 100644 --- a/src/finiteArea/faMesh/faBoundaryMesh/faBoundaryMesh.C +++ b/src/finiteArea/faMesh/faBoundaryMesh/faBoundaryMesh.C @@ -54,7 +54,7 @@ Foam::faBoundaryMesh::faBoundaryMesh { faPatchList& patches = *this; - // Read polyPatchList + // Read faPatch list Istream& is = readStream(typeName); PtrList<entry> patchEntries(is); @@ -117,12 +117,6 @@ void Foam::faBoundaryMesh::calcGeometry() } -const Foam::faMesh& Foam::faBoundaryMesh::mesh() const -{ - return mesh_; -} - - Foam::lduInterfacePtrsList Foam::faBoundaryMesh::interfaces() const { lduInterfacePtrsList interfaces(size()); @@ -143,6 +137,26 @@ Foam::lduInterfacePtrsList Foam::faBoundaryMesh::interfaces() const } +Foam::label Foam::faBoundaryMesh::nNonProcessor() const +{ + const faPatchList& patches = *this; + + label nonProc = 0; + + for (const faPatch& p : patches) + { + if (isA<processorFaPatch>(p)) + { + break; + } + + ++nonProc; + } + + return nonProc; +} + + Foam::wordList Foam::faBoundaryMesh::names() const { return PtrListOps::get<word>(*this, nameOp<faPatch>()); @@ -155,6 +169,71 @@ Foam::wordList Foam::faBoundaryMesh::types() const } +Foam::labelList Foam::faBoundaryMesh::patchStarts() const +{ + // Manually: faPatch does not have independent start() information + + const faPatchList& patches = *this; + + labelList list(patches.size()); + + label beg = mesh_.nInternalEdges(); + forAll(patches, patchi) + { + const label len = patches[patchi].nEdges(); + list[patchi] = beg; + beg += len; + } + return list; +} + + +Foam::labelList Foam::faBoundaryMesh::patchSizes() const +{ + return + PtrListOps::get<label> + ( + *this, + [](const faPatch& p) { return p.nEdges(); } // avoid virtual + ); +} + + +Foam::List<Foam::labelRange> Foam::faBoundaryMesh::patchRanges() const +{ + const faPatchList& patches = *this; + + List<labelRange> list(patches.size()); + + label beg = mesh_.nInternalEdges(); + forAll(patches, patchi) + { + const label len = patches[patchi].nEdges(); + list[patchi].reset(beg, len); + beg += len; + } + return list; +} + + +Foam::label Foam::faBoundaryMesh::start() const +{ + return mesh_.nInternalEdges(); +} + + +Foam::label Foam::faBoundaryMesh::nEdges() const +{ + return mesh_.nBoundaryEdges(); +} + + +Foam::labelRange Foam::faBoundaryMesh::range() const +{ + return labelRange(mesh_.nInternalEdges(), mesh_.nBoundaryEdges()); +} + + Foam::labelList Foam::faBoundaryMesh::indices ( const wordRe& matcher, @@ -355,6 +434,22 @@ bool Foam::faBoundaryMesh::writeData(Ostream& os) const } +bool Foam::faBoundaryMesh::writeObject +( + IOstreamOption streamOpt, + const bool valid +) const +{ + // Allow/disallow compression? + // 1. keep readable + // 2. save some space + // ??? streamOpt.compression(IOstreamOption::UNCOMPRESSED); + return regIOobject::writeObject(streamOpt, valid); +} + + +// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // + Foam::Ostream& Foam::operator<<(Ostream& os, const faBoundaryMesh& bm) { bm.writeData(os); diff --git a/src/finiteArea/faMesh/faBoundaryMesh/faBoundaryMesh.H b/src/finiteArea/faMesh/faBoundaryMesh/faBoundaryMesh.H index 4c2c69ead5b3f234234dd76bff74e694f1181d32..397719aedf1ad492ad327e7e0dffa08f8c245185 100644 --- a/src/finiteArea/faMesh/faBoundaryMesh/faBoundaryMesh.H +++ b/src/finiteArea/faMesh/faBoundaryMesh/faBoundaryMesh.H @@ -53,8 +53,6 @@ Author namespace Foam { -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - // Forward Declarations class faMesh; class faBoundaryMesh; @@ -89,14 +87,14 @@ public: // Constructors - //- Construct from dictionary + //- Construct from faMesh faBoundaryMesh ( const IOobject& io, const faMesh& fam ); - //- Construct given size + //- Construct from faMesh and given size faBoundaryMesh ( const IOobject& io, @@ -111,62 +109,95 @@ public: // Member Functions - // Access + //- Return the mesh reference + const faMesh& mesh() const noexcept + { + return mesh_; + } + + //- Return a list of pointers for each patch + //- with only those pointing to interfaces being set + lduInterfacePtrsList interfaces() const; + + //- The number of patches before the first processor patch. + label nNonProcessor() const; + + //- Return a list of patch names + wordList names() const; - //- Calculate the geometry for the patches - // (transformation tensors etc.) - void calcGeometry(); + //- Return a list of patch types + wordList types() const; - //- Return the mesh reference - const faMesh& mesh() const; + //- Return a list of patch start indices + labelList patchStarts() const; - //- Return a list of pointers for each patch - //- with only those pointing to interfaces being set - lduInterfacePtrsList interfaces() const; + //- Return a list of patch sizes (number of edges in each patch) + labelList patchSizes() const; - //- Return a list of patch names - wordList names() const; + //- Return a list of patch ranges + List<labelRange> patchRanges() const; - //- Return a list of patch types - wordList types() const; + //- The start label of the edges in the faMesh edges list + // Same as mesh.nInternalEdges() + label start() const; - //- Return patch indices for all matches. - // A no-op (returns -1) for an empty key - // \note Matching patchGroups currently not supported - labelList indices - ( - const wordRe& matcher, - const bool useGroups = false /* ignored */ - ) const; + //- The number of boundary edges for the underlying mesh + // Same as mesh.nBoundaryEdges() + label nEdges() const; - //- Return patch index for the first match, return -1 if not found - // A no-op (returns -1) for an empty key - label findIndex(const wordRe& key) const; + //- The edge range for all boundary edges + // Spans [nInternalEdges, nEdges) of the underlying mesh + labelRange range() const; - //- Find patch index given a name, return -1 if not found - // A no-op (returns -1) for an empty name - label findPatchID(const word& patchName) const; - //- Return patch index for a given edge label - label whichPatch(const label edgeIndex) const; + //- Return patch indices for all matches. + // A no-op (returns -1) for an empty key + // \note Matching patchGroups currently not supported + labelList indices + ( + const wordRe& matcher, + const bool useGroups = false /* ignored */ + ) const; + + //- Return patch index for the first match, return -1 if not found + // A no-op (returns -1) for an empty key + label findIndex(const wordRe& key) const; + + //- Find patch index given a name, return -1 if not found + // A no-op (returns -1) for an empty name + label findPatchID(const word& patchName) const; + + //- Return patch index for a given edge label + label whichPatch(const label edgeIndex) const; - //- Check boundary definition - bool checkDefinition(const bool report = false) const; + //- Check boundary definition + bool checkDefinition(const bool report = false) const; - // Edit + // Edit - //- Correct faBoundaryMesh after moving points - void movePoints(const pointField&); + //- Calculate the geometry for the patches + // (transformation tensors etc.) + void calcGeometry(); - //- Correct faBoundaryMesh after topology update - void updateMesh(); + //- Correct faBoundaryMesh after moving points + void movePoints(const pointField&); - //- writeData member function required by regIOobject - bool writeData(Ostream&) const; + //- Correct faBoundaryMesh after topology update + void updateMesh(); + + //- The writeData member function required by regIOobject + bool writeData(Ostream& os) const; + + //- Write using stream options + virtual bool writeObject + ( + IOstreamOption streamOpt, + const bool valid + ) const; - // Ostream operator + // Ostream Operator friend Ostream& operator<<(Ostream&, const faBoundaryMesh&); diff --git a/src/finiteArea/faMesh/faMesh.C b/src/finiteArea/faMesh/faMesh.C index 1e06c4cc03c57ee7f76940574a87e70193d52ebe..d53be6060464c32cc5fbebd450c88df3ab00544f 100644 --- a/src/finiteArea/faMesh/faMesh.C +++ b/src/finiteArea/faMesh/faMesh.C @@ -47,75 +47,122 @@ namespace Foam defineTypeNameAndDebug(faMesh, 0); } + +const Foam::word Foam::faMesh::prefix("finite-area"); + Foam::word Foam::faMesh::meshSubDir = "faMesh"; -const int Foam::faMesh::quadricsFit_ = 0; +const int Foam::faMesh::quadricsFit_ = 0; // Tuning -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // +// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // -void Foam::faMesh::setPrimitiveMeshData() +namespace Foam { - DebugInFunction << "Setting primitive data" << endl; - const indirectPrimitivePatch& bp = patch(); - - // Set faMesh edges - edges_.setSize(bp.nEdges()); +// Convert patch names to face labels. Preserve patch order +static labelList selectPatchFaces +( + const polyBoundaryMesh& pbm, + const wordList& polyPatchNames +) +{ + labelHashSet patchIDs; - label edgeI = -1; + label nFaceLabels = 0; + for (const word& patchName : polyPatchNames) + { + const label polyPatchi = pbm.findPatchID(patchName); - label nIntEdges = bp.nInternalEdges(); + if (polyPatchi < 0) + { + FatalErrorInFunction + << "Patch " << patchName << " not found" + << exit(FatalError); + } - for (label curEdge = 0; curEdge < nIntEdges; ++curEdge) - { - edges_[++edgeI] = bp.edges()[curEdge]; + if (patchIDs.insert(polyPatchi)) + { + nFaceLabels += pbm[polyPatchi].size(); + } } - forAll(boundary(), patchI) - { - const labelList& curP = boundary()[patchI]; + labelList faceLabels(nFaceLabels); - forAll(curP, eI) + nFaceLabels = 0; + for (const label polyPatchi : patchIDs.sortedToc()) + { + for (const label facei : pbm[polyPatchi].range()) { - edges_[++edgeI] = bp.edges()[curP[eI]]; + faceLabels[nFaceLabels] = facei; + ++nFaceLabels; } } - nEdges_ = edges_.size(); - nInternalEdges_ = nIntEdges; + return faceLabels; +} + +} // End namespace Foam + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::faMesh::initPatch() const +{ + if (patchPtr_) + { + delete patchPtr_; + } + patchPtr_ = new uindirectPrimitivePatch + ( + UIndirectList<face>(mesh().faces(), faceLabels_), + mesh().points() + ); +} + + +void Foam::faMesh::setPrimitiveMeshData() +{ + DebugInFunction << "Setting primitive data" << endl; + const uindirectPrimitivePatch& bp = patch(); + const labelListList& edgeFaces = bp.edgeFaces(); - // Set edge owner and neighbour - edgeOwner_.setSize(nEdges()); - edgeNeighbour_.setSize(nInternalEdges()); + // Dimensions - edgeI = -1; + nEdges_ = bp.nEdges(); + nInternalEdges_ = bp.nInternalEdges(); + nFaces_ = bp.size(); + nPoints_ = bp.nPoints(); - const labelListList& bpef = bp.edgeFaces(); + edges_.resize(nEdges_); + edgeOwner_.resize(nEdges_); + edgeNeighbour_.resize(nInternalEdges_); - for (label curEdge = 0; curEdge < nIntEdges; ++curEdge) + // Internal edges + for (label edgei = 0; edgei < nInternalEdges_; ++edgei) { - edgeOwner_[++edgeI] = bpef[curEdge][0]; + edges_[edgei] = bp.edges()[edgei]; + + edgeOwner_[edgei] = edgeFaces[edgei][0]; - edgeNeighbour_[edgeI] = bpef[curEdge][1]; + edgeNeighbour_[edgei] = edgeFaces[edgei][1]; } - forAll(boundary(), patchI) - { - const labelList& curP = boundary()[patchI]; + // Continue with boundary edges + label edgei = nInternalEdges_; - forAll(curP, eI) + for (const faPatch& p : boundary()) + { + for (const label patchEdgei : p.edgeLabels()) { - edgeOwner_[++edgeI] = bpef[curP[eI]][0]; - } - } + edges_[edgei] = bp.edges()[patchEdgei]; - // Set number of faces - nFaces_ = bp.size(); + edgeOwner_[edgei] = edgeFaces[patchEdgei][0]; - // Set number of points - nPoints_ = bp.nPoints(); + ++edgei; + } + } } @@ -161,15 +208,20 @@ void Foam::faMesh::clearOut() const { clearGeom(); clearAddressing(); - deleteDemandDrivenData(globalMeshDataPtr_); + globalMeshDataPtr_.reset(nullptr); } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // +Foam::faMesh::faMesh(const polyMesh& pMesh, const zero) +: + faMesh(pMesh, labelList()) +{} + + Foam::faMesh::faMesh(const polyMesh& pMesh) : - GeoMesh<polyMesh>(pMesh), MeshObject<polyMesh, Foam::UpdateableMeshObject, faMesh>(pMesh), edgeInterpolation(*this), faSchemes(mesh()), @@ -181,7 +233,7 @@ Foam::faMesh::faMesh(const polyMesh& pMesh) ( "faceLabels", time().findInstance(meshDir(), "faceLabels"), - meshSubDir, + faMesh::meshSubDir, mesh(), IOobject::MUST_READ, IOobject::NO_WRITE @@ -193,7 +245,7 @@ Foam::faMesh::faMesh(const polyMesh& pMesh) ( "faBoundary", time().findInstance(meshDir(), "faBoundary"), - meshSubDir, + faMesh::meshSubDir, mesh(), IOobject::MUST_READ, IOobject::NO_WRITE @@ -220,7 +272,7 @@ Foam::faMesh::faMesh(const polyMesh& pMesh) correctPatchPointNormalsPtr_(nullptr), globalMeshDataPtr_(nullptr) { - DebugInFunction << "Creating faMesh from IOobject" << endl; + DebugInFunction << "Creating from IOobject" << endl; setPrimitiveMeshData(); @@ -244,7 +296,7 @@ Foam::faMesh::faMesh(const polyMesh& pMesh) ( "S0", time().timeName(), - meshSubDir, + faMesh::meshSubDir, mesh(), IOobject::MUST_READ, IOobject::AUTO_WRITE @@ -258,10 +310,9 @@ Foam::faMesh::faMesh(const polyMesh& pMesh) Foam::faMesh::faMesh ( const polyMesh& pMesh, - const labelList& faceLabels + const UList<label>& faceLabels ) : - GeoMesh<polyMesh>(pMesh), MeshObject<polyMesh, Foam::UpdateableMeshObject, faMesh>(pMesh), edgeInterpolation(*this), faSchemes(mesh()), @@ -273,7 +324,7 @@ Foam::faMesh::faMesh ( "faceLabels", mesh().facesInstance(), - meshSubDir, + faMesh::meshSubDir, mesh(), IOobject::NO_READ, IOobject::NO_WRITE @@ -286,13 +337,13 @@ Foam::faMesh::faMesh ( "faBoundary", mesh().facesInstance(), - meshSubDir, + faMesh::meshSubDir, mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), *this, - 0 + label(0) ), comm_(Pstream::worldComm), patchPtr_(nullptr), @@ -313,434 +364,77 @@ Foam::faMesh::faMesh edgeTransformTensorsPtr_(nullptr), correctPatchPointNormalsPtr_(nullptr), globalMeshDataPtr_(nullptr) -{ - DebugInFunction << "Creating faMesh from components" << endl; -} +{} -Foam::faMesh::faMesh -( - const polyMesh& pMesh, - const fileName& defFile -) +Foam::faMesh::faMesh(const polyPatch& pp) : - GeoMesh<polyMesh>(pMesh), - MeshObject<polyMesh, Foam::UpdateableMeshObject, faMesh>(pMesh), - edgeInterpolation(*this), - faSchemes(mesh()), - faSolution(mesh()), - data(mesh()), - faceLabels_ - ( - IOobject - ( - "faceLabels", - mesh().facesInstance(), - meshSubDir, - mesh(), - IOobject::NO_READ, - IOobject::NO_WRITE - ), - List<label>(0) - ), - boundary_ + faMesh ( - IOobject - ( - "faBoundary", - mesh().facesInstance(), - meshSubDir, - mesh(), - IOobject::NO_READ, - IOobject::NO_WRITE - ), - *this, - 0 - ), - comm_(Pstream::worldComm), - patchPtr_(nullptr), - lduPtr_(nullptr), - curTimeIndex_(time().timeIndex()), - SPtr_(nullptr), - S0Ptr_(nullptr), - S00Ptr_(nullptr), - patchStartsPtr_(nullptr), - LePtr_(nullptr), - magLePtr_(nullptr), - centresPtr_(nullptr), - edgeCentresPtr_(nullptr), - faceAreaNormalsPtr_(nullptr), - edgeAreaNormalsPtr_(nullptr), - pointAreaNormalsPtr_(nullptr), - faceCurvaturesPtr_(nullptr), - edgeTransformTensorsPtr_(nullptr), - correctPatchPointNormalsPtr_(nullptr), - globalMeshDataPtr_(nullptr) + pp.boundaryMesh().mesh(), + identity(pp.range()) + ) { - DebugInFunction << "Creating faMesh from definition file" << endl; - - // Reading faMeshDefinition dictionary - IOdictionary faMeshDefinition - ( - IOobject - ( - defFile, - mesh().time().constant(), - meshSubDir, - mesh(), - IOobject::MUST_READ, - IOobject::NO_WRITE - ) - ); + DebugInFunction << "Creating from polyPatch:" << pp.name() << endl; - const wordList polyMeshPatches + // Add single faPatch "default", but with processor connections + PtrList<faPatch> newPatches ( - faMeshDefinition.get<wordList>("polyMeshPatches") + createOnePatch("default") ); - const dictionary& bndDict = faMeshDefinition.subDict("boundary"); - - const wordList faPatchNames(bndDict.toc()); - - List<faPatchData> faPatches(faPatchNames.size() + 1); - - const polyBoundaryMesh& pbm = pMesh.boundaryMesh(); - - forAll(faPatchNames, patchI) - { - dictionary curPatchDict = bndDict.subDict(faPatchNames[patchI]); - - faPatches[patchI].name_ = faPatchNames[patchI]; - - faPatches[patchI].type_ = curPatchDict.get<word>("type"); - - faPatches[patchI].ownPolyPatchID_ = - pbm.findPatchID(curPatchDict.get<word>("ownerPolyPatch")); - - faPatches[patchI].ngbPolyPatchID_ = - pbm.findPatchID(curPatchDict.get<word>("neighbourPolyPatch")); - } - - - // Setting faceLabels list size - label size = 0; - - labelList patchIDs(polyMeshPatches.size(), -1); - - forAll(polyMeshPatches, patchI) - { - patchIDs[patchI] = pbm.findPatchID(polyMeshPatches[patchI]); + addFaPatches(newPatches); - size += pbm[patchIDs[patchI]].size(); - } - - faceLabels_ = labelList(size, -1); - - - // Filling of faceLabels list - label faceI = -1; - - sort(patchIDs); + setPrimitiveMeshData(); - forAll(polyMeshPatches, patchI) + // Create global mesh data + if (Pstream::parRun()) { - label start = pbm[patchIDs[patchI]].start(); - label size = pbm[patchIDs[patchI]].size(); - - for (label i = 0; i < size; ++i) - { - faceLabels_[++faceI] = start + i; - } + globalData(); } + // Calculate topology for the patches (processor-processor comms etc.) + boundary_.updateMesh(); - // Determination of faPatch ID for each boundary edge. - // Result is in the bndEdgeFaPatchIDs list - labelList faceCells(faceLabels_.size(), -1); - - forAll(faceCells, faceI) - { - label faceID = faceLabels_[faceI]; + // Calculate the geometry for the patches (transformation tensors etc.) + boundary_.calcGeometry(); +} - faceCells[faceI] = mesh().faceOwner()[faceID]; - } - labelList meshEdges = - patch().meshEdges +Foam::faMesh::faMesh +( + const polyMesh& pMesh, + const dictionary& faMeshDefinition +) +: + faMesh + ( + pMesh, + selectPatchFaces ( - mesh().edges(), - mesh().cellEdges(), - faceCells - ); - - const labelListList& edgeFaces = mesh().edgeFaces(); - - const label nTotalEdges = patch().nEdges(); - const label nInternalEdges = patch().nInternalEdges(); - - labelList bndEdgeFaPatchIDs(nTotalEdges - nInternalEdges, -1); - - for (label edgeI = nInternalEdges; edgeI < nTotalEdges; ++edgeI) - { - label curMeshEdge = meshEdges[edgeI]; - - labelList curEdgePatchIDs(2, label(-1)); - - label patchI = -1; - - forAll(edgeFaces[curMeshEdge], faceI) - { - label curFace = edgeFaces[curMeshEdge][faceI]; - - label curPatchID = pbm.whichPatch(curFace); - - if (curPatchID != -1) - { - curEdgePatchIDs[++patchI] = curPatchID; - } - } - - for (label pI = 0; pI < faPatches.size() - 1; ++pI) - { - if - ( - ( - curEdgePatchIDs[0] == faPatches[pI].ownPolyPatchID_ - && curEdgePatchIDs[1] == faPatches[pI].ngbPolyPatchID_ - ) - || - ( - curEdgePatchIDs[1] == faPatches[pI].ownPolyPatchID_ - && curEdgePatchIDs[0] == faPatches[pI].ngbPolyPatchID_ - ) - ) - { - bndEdgeFaPatchIDs[edgeI - nInternalEdges] = pI; - break; - } - } - } - - - // Set edgeLabels for each faPatch - for (label pI = 0; pI < (faPatches.size() - 1); ++pI) - { - SLList<label> tmpList; - - forAll(bndEdgeFaPatchIDs, eI) - { - if (bndEdgeFaPatchIDs[eI] == pI) - { - tmpList.append(nInternalEdges + eI); - } - } - - faPatches[pI].edgeLabels_ = tmpList; - } - - // Check for undefined edges - SLList<label> tmpList; - - forAll(bndEdgeFaPatchIDs, eI) - { - if (bndEdgeFaPatchIDs[eI] == -1) - { - tmpList.append(nInternalEdges + eI); - } - } - - if (tmpList.size() > 0) - { - // Check for processor edges - labelList allUndefEdges(tmpList); - labelList ngbPolyPatch(allUndefEdges.size(), -1); - forAll(ngbPolyPatch, edgeI) - { - label curEdge = allUndefEdges[edgeI]; - - label curPMeshEdge = meshEdges[curEdge]; - - forAll(edgeFaces[curPMeshEdge], faceI) - { - label curFace = edgeFaces[curPMeshEdge][faceI]; - - if (faceLabels_.found(curFace)) - { - label polyPatchID = pbm.whichPatch(curFace); - - if (polyPatchID != -1) - { - ngbPolyPatch[edgeI] = polyPatchID; - } - } - } - } - - // Count ngb processorPolyPatch-es - labelHashSet processorPatchSet; - forAll(ngbPolyPatch, edgeI) - { - if (ngbPolyPatch[edgeI] != -1) - { - if (isA<processorPolyPatch>(pbm[ngbPolyPatch[edgeI]])) - { - processorPatchSet.insert(ngbPolyPatch[edgeI]); - } - } - } - labelList processorPatches(processorPatchSet.toc()); - faPatches.setSize(faPatches.size() + processorPatches.size()); - - for (label i = 0; i < processorPatches.size(); ++i) - { - SLList<label> tmpLst; - - forAll(ngbPolyPatch, eI) - { - if (ngbPolyPatch[eI] == processorPatches[i]) - { - tmpLst.append(allUndefEdges[eI]); - } - } - - faPatches[faPatchNames.size() + i].edgeLabels_ = tmpLst; - - faPatches[faPatchNames.size() + i].name_ = - pbm[processorPatches[i]].name(); - - faPatches[faPatchNames.size() + i].type_ = - processorFaPatch::typeName; - - faPatches[faPatchNames.size() + i].ngbPolyPatchID_ = - processorPatches[i]; - } - - // Remaining undefined edges - SLList<label> undefEdges; - forAll(ngbPolyPatch, eI) - { - if (ngbPolyPatch[eI] == -1) - { - undefEdges.append(allUndefEdges[eI]); - } - else if (!isA<processorPolyPatch>(pbm[ngbPolyPatch[eI]])) - { - undefEdges.append(allUndefEdges[eI]); - } - } - - if (undefEdges.size() > 0) - { - label pI = faPatches.size()-1; - - faPatches[pI].name_ = "undefined"; - faPatches[pI].type_ = "patch"; - faPatches[pI].edgeLabels_ = undefEdges; - } - else - { - faPatches.setSize(faPatches.size() - 1); - } - } - else - { - faPatches.setSize(faPatches.size() - 1); - } - - - // Reorder processorFaPatch using - // ordering of ngb processorPolyPatch - forAll(faPatches, patchI) - { - if (faPatches[patchI].type_ == processorFaPatch::typeName) - { - labelList ngbFaces(faPatches[patchI].edgeLabels_.size(), -1); - - forAll(ngbFaces, edgeI) - { - label curEdge = faPatches[patchI].edgeLabels_[edgeI]; - - label curPMeshEdge = meshEdges[curEdge]; - - forAll(edgeFaces[curPMeshEdge], faceI) - { - label curFace = edgeFaces[curPMeshEdge][faceI]; - - label curPatchID = pbm.whichPatch(curFace); - - if (curPatchID == faPatches[patchI].ngbPolyPatchID_) - { - ngbFaces[edgeI] = curFace; - } - } - } - - SortableList<label> sortedNgbFaces(ngbFaces); - labelList reorderedEdgeLabels(ngbFaces.size(), -1); - for (label i = 0; i < reorderedEdgeLabels.size(); ++i) - { - reorderedEdgeLabels[i] = - faPatches[patchI].edgeLabels_ - [ - sortedNgbFaces.indices()[i] - ]; - } - - faPatches[patchI].edgeLabels_ = reorderedEdgeLabels; - } - } - - - // Add good patches to faMesh - SLList<faPatch*> faPatchLst; + pMesh.boundaryMesh(), + faMeshDefinition.get<wordList>("polyMeshPatches") + ) + ) +{ + DebugInFunction << "Creating from definition (dictionary)" << endl; - for (label pI = 0; pI < faPatches.size(); ++pI) - { - faPatches[pI].dict_.add("type", faPatches[pI].type_); - faPatches[pI].dict_.add("edgeLabels", faPatches[pI].edgeLabels_); - faPatches[pI].dict_.add + PtrList<faPatch> newPatches + ( + createPatchList ( - "ngbPolyPatchIndex", - faPatches[pI].ngbPolyPatchID_ - ); + faMeshDefinition.subDict("boundary"), - if (faPatches[pI].type_ == processorFaPatch::typeName) - { - if (faPatches[pI].ngbPolyPatchID_ == -1) - { - FatalErrorInFunction - << "ngbPolyPatch is not defined for processorFaPatch: " - << faPatches[pI].name_ - << abort(FatalError); - } - - const processorPolyPatch& procPolyPatch = - refCast<const processorPolyPatch> - ( - pbm[faPatches[pI].ngbPolyPatchID_] - ); + // Optional 'empty' patch + faMeshDefinition.getOrDefault<word>("emptyPatch", word::null), - faPatches[pI].dict_.add("myProcNo", procPolyPatch.myProcNo()); - faPatches[pI].dict_.add - ( - "neighbProcNo", - procPolyPatch.neighbProcNo() - ); - } + // Optional specification for default patch + faMeshDefinition.findDict("defaultPatch") + ) + ); - faPatchLst.append - ( - faPatch::New - ( - faPatches[pI].name_, - faPatches[pI].dict_, - pI, - boundary() - ).ptr() - ); - } - addFaPatches(List<faPatch*>(faPatchLst)); + addFaPatches(newPatches); // Create global mesh data if (Pstream::parRun()) @@ -762,7 +456,7 @@ Foam::faMesh::faMesh ( "S0", time().timeName(), - meshSubDir, + faMesh::meshSubDir, mesh(), IOobject::MUST_READ, IOobject::AUTO_WRITE @@ -773,111 +467,6 @@ Foam::faMesh::faMesh } -Foam::faMesh::faMesh -( - const polyMesh& pMesh, - const label polyPatchID -) -: - GeoMesh<polyMesh>(pMesh), - MeshObject<polyMesh, Foam::UpdateableMeshObject, faMesh>(pMesh), - edgeInterpolation(*this), - faSchemes(mesh()), - faSolution(mesh()), - data(mesh()), - faceLabels_ - ( - IOobject - ( - "faceLabels", - mesh().facesInstance(), - meshSubDir, - mesh(), - IOobject::NO_READ, - IOobject::NO_WRITE - ), - labelList(pMesh.boundaryMesh()[polyPatchID].size(), -1) - ), - boundary_ - ( - IOobject - ( - "faBoundary", - mesh().facesInstance(), - meshSubDir, - mesh(), - IOobject::NO_READ, - IOobject::NO_WRITE - ), - *this, - 0 - ), - comm_(Pstream::worldComm), - patchPtr_(nullptr), - lduPtr_(nullptr), - curTimeIndex_(time().timeIndex()), - SPtr_(nullptr), - S0Ptr_(nullptr), - S00Ptr_(nullptr), - patchStartsPtr_(nullptr), - LePtr_(nullptr), - magLePtr_(nullptr), - centresPtr_(nullptr), - edgeCentresPtr_(nullptr), - faceAreaNormalsPtr_(nullptr), - edgeAreaNormalsPtr_(nullptr), - pointAreaNormalsPtr_(nullptr), - faceCurvaturesPtr_(nullptr), - edgeTransformTensorsPtr_(nullptr), - correctPatchPointNormalsPtr_(nullptr), - globalMeshDataPtr_(nullptr) -{ - DebugInFunction << "Creating faMesh from polyPatch" << endl; - - const polyBoundaryMesh& pbm = pMesh.boundaryMesh(); - - // Set faceLabels - forAll(faceLabels_, faceI) - { - faceLabels_[faceI] = pbm[polyPatchID].start() + faceI; - } - - // Add one faPatch - const indirectPrimitivePatch& bp = patch(); - - const label nTotalEdges = bp.nEdges(); - - const label nInternalEdges = bp.nInternalEdges(); - - labelList edgeLabels(nTotalEdges - nInternalEdges, -1); - - forAll(edgeLabels, edgeI) - { - edgeLabels[edgeI] = nInternalEdges + edgeI; - } - - dictionary patchDict; - - patchDict.add("type", "patch"); - patchDict.add("edgeLabels", edgeLabels); - patchDict.add("ngbPolyPatchIndex", -1); - - List<faPatch*> faPatchLst(1); - - faPatchLst[0] = faPatch::New("default", patchDict, 0, boundary()).ptr(); - - addFaPatches(faPatchLst); - - setPrimitiveMeshData(); - - // Calculate topology for the patches (processor-processor comms etc.) - boundary_.updateMesh(); - - // Calculate the geometry for the patches (transformation tensors etc.) - boundary_.calcGeometry(); -} - - // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::faMesh::~faMesh() @@ -890,7 +479,7 @@ Foam::faMesh::~faMesh() Foam::fileName Foam::faMesh::meshDir() const { - return mesh().dbDir()/meshSubDir; + return mesh().dbDir()/faMesh::meshSubDir; } @@ -912,98 +501,6 @@ const Foam::fileName& Foam::faMesh::facesInstance() const } -const Foam::indirectPrimitivePatch& Foam::faMesh::patch() const -{ - if (!patchPtr_) - { - patchPtr_ = new indirectPrimitivePatch - ( - IndirectList<face> - ( - mesh().faces(), - faceLabels_ - ), - mesh().points() - ); - } - - return *patchPtr_; -} - - -Foam::indirectPrimitivePatch& Foam::faMesh::patch() -{ - if (!patchPtr_) - { - patchPtr_ = new indirectPrimitivePatch - ( - IndirectList<face> - ( - mesh().faces(), - faceLabels_ - ), - mesh().points() - ); - } - - return *patchPtr_; -} - - -const Foam::pointField& Foam::faMesh::points() const -{ - return patch().localPoints(); -} - - -const Foam::edgeList& Foam::faMesh::edges() const -{ - return edges_; -} - - -const Foam::faceList& Foam::faMesh::faces() const -{ - return patch().localFaces(); -} - - -void Foam::faMesh::addFaPatches(const List<faPatch*>& p) -{ - DebugInFunction << "Adding patches to faMesh" << endl; - - if (boundary().size() > 0) - { - FatalErrorInFunction - << "boundary already exists" - << abort(FatalError); - } - - boundary_.setSize(p.size()); - - forAll(p, patchI) - { - boundary_.set(patchI, p[patchI]); - } - - setPrimitiveMeshData(); - - boundary_.checkDefinition(); -} - - -Foam::label Foam::faMesh::comm() const -{ - return comm_; -} - - -Foam::label& Foam::faMesh::comm() -{ - return comm_; -} - - bool Foam::faMesh::hasDb() const { return true; @@ -1016,12 +513,6 @@ const Foam::objectRegistry& Foam::faMesh::thisDb() const } -const Foam::faBoundaryMesh& Foam::faMesh::boundary() const -{ - return boundary_; -} - - const Foam::labelList& Foam::faMesh::patchStarts() const { if (!patchStartsPtr_) @@ -1193,7 +684,7 @@ const Foam::faGlobalMeshData& Foam::faMesh::globalData() const { if (!globalMeshDataPtr_) { - globalMeshDataPtr_ = new faGlobalMeshData(*this); + globalMeshDataPtr_.reset(new faGlobalMeshData(*this)); } return *globalMeshDataPtr_; diff --git a/src/finiteArea/faMesh/faMesh.H b/src/finiteArea/faMesh/faMesh.H index 8715a22f010b1f84c72cac3bbb014157eda06aef..8a9b16501181a82973c33de49a4e98f833713a46 100644 --- a/src/finiteArea/faMesh/faMesh.H +++ b/src/finiteArea/faMesh/faMesh.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -42,7 +43,6 @@ Author #ifndef faMesh_H #define faMesh_H -#include "GeoMesh.H" #include "MeshObject.H" #include "polyMesh.H" #include "lduMesh.H" @@ -53,7 +53,7 @@ Author #include "DimensionedField.H" #include "areaFieldsFwd.H" #include "edgeFieldsFwd.H" -#include "indirectPrimitivePatch.H" +#include "uindirectPrimitivePatch.H" #include "edgeInterpolation.H" #include "labelIOList.H" #include "FieldFields.H" @@ -67,9 +67,11 @@ Author namespace Foam { -// Class forward declarations +// Forward Declarations class faMeshLduAddressing; class faMeshMapper; +class faPatchData; +template<class T> class LabelledItem; /*---------------------------------------------------------------------------*\ Class faMesh Declaration @@ -77,7 +79,6 @@ class faMeshMapper; class faMesh : - public GeoMesh<polyMesh>, public MeshObject<polyMesh, Foam::UpdateableMeshObject, faMesh>, public lduMesh, public edgeInterpolation, @@ -85,7 +86,7 @@ class faMesh public faSolution, public data { - // Private data + // Private Data //- Face labels labelIOList faceLabels_; @@ -130,7 +131,7 @@ class faMesh // Demand-driven data //- Primitive patch - mutable indirectPrimitivePatch* patchPtr_; + mutable uindirectPrimitivePatch* patchPtr_; //- Ldu addressing data mutable faMeshLduAddressing* lduPtr_; @@ -186,8 +187,8 @@ class faMesh // Other mesh-related data - //- Parallel info - mutable faGlobalMeshData* globalMeshDataPtr_; + //- Parallel info + mutable autoPtr<faGlobalMeshData> globalMeshDataPtr_; // Static Private Data @@ -204,6 +205,8 @@ class faMesh //- No copy assignment void operator=(const faMesh&) = delete; + //- Set indirect patch, removing any old one + void initPatch() const; //- Set primitive mesh data void setPrimitiveMeshData(); @@ -262,9 +265,39 @@ class faMesh //- Clear demand-driven data void clearOut() const; + + // Helpers + + //- Get the polyPatch pairs for the boundary edges (natural order) + List<LabelledItem<edge>> getBoundaryEdgePatchPairs() const; + + //- Create a single patch + PtrList<faPatch> createOnePatch + ( + const word& patchName, + const word& patchType = "" + ) const; + + //- Create list of patches from boundary definition + PtrList<faPatch> createPatchList + ( + const dictionary& bndDict, + const word& emptyPatchName = "", + const dictionary* defaultPatchDefinition = nullptr + ) const; + + //- Reorder processor edges using order of the + //- neighbour processorPolyPatch + void reorderProcEdges + ( + faPatchData& patchDef, + const List<LabelledItem<edge>>& bndEdgePatchPairs + ) const; + + public: - // Public typedefs + // Public Typedefs typedef faMesh Mesh; typedef faBoundaryMesh BoundaryMesh; @@ -273,36 +306,38 @@ public: //- Runtime type information TypeName("faMesh"); + //- The prefix to local: %finite-area + static const word prefix; - //- Return the mesh sub-directory name (usually "faMesh") - static word meshSubDir; + //- The mesh sub-directory name (usually "faMesh") + static word meshSubDir; // Constructors + //- Construct zero-sized from polyMesh + // Boundary is added using addFaPatches() member function + faMesh(const polyMesh& pMesh, const Foam::zero); + //- Construct from polyMesh - explicit faMesh(const polyMesh& m); + explicit faMesh(const polyMesh& pMesh); - //- Construct from components without boundary. + //- Construct for specified face labels without boundary. // Boundary is added using addFaPatches() member function faMesh ( - const polyMesh& m, - const labelList& faceLabels + const polyMesh& pMesh, + const UList<label>& faceLabels ); - //- Construct from finite area mesh definition file - faMesh - ( - const polyMesh& m, - const fileName& defFile - ); + //- Construct from single polyPatch + explicit faMesh(const polyPatch& pp); - //- Construct from polyPatch + //- Construct from definition faMesh ( - const polyMesh& m, - const label polyPatchID + const polyMesh& pMesh, + const dictionary& faMeshDefinition ); @@ -312,25 +347,30 @@ public: // Member Functions - // Helpers + // Helpers - //- Add boundary patches. Constructor helper - void addFaPatches(const List<faPatch*> &); + //- Add boundary patches. Constructor helper + void addFaPatches + ( + PtrList<faPatch>& plist, + const bool validBoundary = true + ); + + //- Add boundary patches. Constructor helper + void addFaPatches + ( + const List<faPatch*>& p, + const bool validBoundary = true + ); // Database //- Return access to polyMesh - const polyMesh& mesh() const - { - return - MeshObject - < - polyMesh, - Foam::UpdateableMeshObject, - faMesh - >::mesh(); - } + inline const polyMesh& mesh() const; + + //- Interface to referenced polyMesh (similar to GeoMesh) + const polyMesh& operator()() const { return mesh(); } //- Return the local mesh directory (dbDir()/meshSubDir) fileName meshDir() const; @@ -347,60 +387,50 @@ public: const fileName& facesInstance() const; + // Communication support + + //- Return communicator used for parallel communication + inline label comm() const noexcept; + + //- Return communicator used for parallel communication + inline label& comm() noexcept; + + // Mesh size parameters - inline label nPoints() const - { - return nPoints_; - } + //- Number of local mesh points + inline label nPoints() const noexcept; - inline label nEdges() const - { - return nEdges_; - } + //- Number of local mesh edges + inline label nEdges() const noexcept; - inline label nInternalEdges() const - { - return nInternalEdges_; - } + //- Number of internal faces + inline label nInternalEdges() const noexcept; - inline label nFaces() const - { - return nFaces_; - } + //- Number of boundary edges (== nEdges - nInternalEdges) + inline label nBoundaryEdges() const noexcept; + + //- Number of patch faces + inline label nFaces() const noexcept; // Primitive mesh data - //- Return mesh points - const pointField& points() const; + //- Return local patch points + inline const pointField& points() const; - //- Return edges - const edgeList& edges() const; + //- Return local patch edges with reordered boundary + inline const edgeList& edges() const noexcept; - //- Return faces - const faceList& faces() const; + //- Return local patch faces + inline const faceList& faces() const; //- Edge owner addressing - inline const labelList& edgeOwner() const - { - return edgeOwner_; - } + inline const labelList& edgeOwner() const noexcept; //- Edge neighbour addressing - inline const labelList& edgeNeighbour() const - { - return edgeNeighbour_; - } - - - // Communication support - - //- Return communicator used for parallel communication - label comm() const; + inline const labelList& edgeNeighbour() const noexcept; - //- Return communicator used for parallel communication - label& comm(); // Access @@ -419,13 +449,10 @@ public: } //- Return constant reference to boundary mesh - const faBoundaryMesh& boundary() const; + inline const faBoundaryMesh& boundary() const noexcept; //- Return faMesh face labels - const labelList& faceLabels() const - { - return faceLabels_; - } + inline const labelList& faceLabels() const noexcept; //- Return parallel info @@ -453,10 +480,10 @@ public: return lduAddr().upperAddr(); } - //- Return true if given edge label is internal to the mesh - inline bool isInternalEdge(const label edgeIndex) const + //- True if given edge label is internal to the mesh + bool isInternalEdge(const label edgeIndex) const { - return edgeIndex < nInternalEdges(); + return (edgeIndex < nInternalEdges_); } @@ -487,10 +514,10 @@ public: // Demand-driven data //- Return constant reference to primitive patch - const indirectPrimitivePatch& patch() const; + inline const uindirectPrimitivePatch& patch() const; //- Return reference to primitive patch - indirectPrimitivePatch& patch(); + inline uindirectPrimitivePatch& patch(); //- Return patch starts const labelList& patchStarts() const; @@ -546,6 +573,7 @@ public: //- Set whether point normals should be corrected for a patch boolList& correctPatchPointNormals() const; + //- Write mesh virtual bool write(const bool valid = true) const; @@ -564,6 +592,8 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +#include "faMeshI.H" + #ifdef NoRepository #include "faPatchFaMeshTemplates.C" #endif diff --git a/src/finiteArea/faMesh/faMeshDemandDrivenData.C b/src/finiteArea/faMesh/faMeshDemandDrivenData.C index 7a363fd2ab6b9a84d34bc18d6d3b1ac1d85cc234..63ec9815bdc7ac037e5bbec5d081ef185f9962d4 100644 --- a/src/finiteArea/faMesh/faMeshDemandDrivenData.C +++ b/src/finiteArea/faMesh/faMeshDemandDrivenData.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd - Copyright (C) 2018-2020 OpenCFD Ltd. + Copyright (C) 2018-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -40,6 +40,30 @@ License #include "processorFaPatchFields.H" #include "emptyFaPatchFields.H" + +// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // + +namespace Foam +{ + +// A bitSet (size patch nPoints()) with boundary points marked +static Foam::bitSet markupBoundaryPoints(const uindirectPrimitivePatch& p) +{ + // Initially all unmarked + bitSet markPoints(p.nPoints()); + for (const edge& e : p.boundaryEdges()) + { + // Mark boundary points + markPoints.set(e.first()); + markPoints.set(e.second()); + } + + return markPoints; +} + +} // End namespace Foam + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void Foam::faMesh::calcLduAddressing() const @@ -70,16 +94,7 @@ void Foam::faMesh::calcPatchStarts() const << abort(FatalError); } - patchStartsPtr_ = new labelList(boundary().size(), -1); - labelList& patchStarts = *patchStartsPtr_; - - patchStarts[0] = nInternalEdges(); - - for (label i = 1; i < boundary().size(); ++i) - { - patchStarts[i] = - patchStarts[i - 1] + boundary()[i - 1].faPatch::size(); - } + patchStartsPtr_ = new labelList(boundary().patchStarts()); } @@ -211,13 +226,11 @@ void Foam::faMesh::calcMagLe() const const pointField& localPoints = points(); - const edgeList::subList internalEdges = - edgeList::subList(edges(), nInternalEdges()); - - - forAll(internalEdges, edgeI) + label edgei = 0; + for (const edge& e : patch().internalEdges()) { - magLe.ref()[edgeI] = internalEdges[edgeI].mag(localPoints); + magLe.ref()[edgei] = e.mag(localPoints); + ++edgei; } @@ -331,13 +344,12 @@ void Foam::faMesh::calcEdgeCentres() const const pointField& localPoints = points(); - const edgeList::subList internalEdges = - edgeList::subList(edges(), nInternalEdges()); - - forAll(internalEdges, edgeI) + label edgei = 0; + for (const edge& e : patch().internalEdges()) { - edgeCentres.ref()[edgeI] = internalEdges[edgeI].centre(localPoints); + edgeCentres.ref()[edgei] = e.centre(localPoints); + ++edgei; } @@ -850,31 +862,10 @@ Foam::labelList Foam::faMesh::internalPoints() const DebugInFunction << "Calculating internal points" << endl; - const edgeList& edges = patch().edges(); - label nIntEdges = patch().nInternalEdges(); - - List<bool> internal(nPoints(), true); - - for (label curEdge = nIntEdges; curEdge < edges.size(); ++curEdge) - { - internal[edges[curEdge].start()] = false; + bitSet markPoints(markupBoundaryPoints(this->patch())); + markPoints.flip(); - internal[edges[curEdge].end()] = false; - } - - SLList<label> internalPoints; - - forAll(internal, pointI) - { - if (internal[pointI]) - { - internalPoints.append(pointI); - } - } - - labelList result(internalPoints); - - return result; + return markPoints.sortedToc(); } @@ -883,31 +874,9 @@ Foam::labelList Foam::faMesh::boundaryPoints() const DebugInFunction << "Calculating boundary points" << endl; - const edgeList& edges = patch().edges(); - label nIntEdges = patch().nInternalEdges(); - - List<bool> internal(nPoints(), true); - - for (label curEdge = nIntEdges; curEdge < edges.size(); ++curEdge) - { - internal[edges[curEdge].start()] = false; - - internal[edges[curEdge].end()] = false; - } - - SLList<label> boundaryPoints; - - forAll(internal, pointI) - { - if (!internal[pointI]) - { - boundaryPoints.append(pointI); - } - } - - labelList result(boundaryPoints); + bitSet markPoints(markupBoundaryPoints(this->patch())); - return result; + return markPoints.sortedToc(); } @@ -1168,7 +1137,7 @@ void Foam::faMesh::calcPointAreaNormals() const if (correctPatchPointNormals(patchI) && !fap.coupled()) { - if (fap.ngbPolyPatchIndex() == -1) + if (fap.ngbPolyPatchIndex() < 0) { FatalErrorInFunction << "Neighbour polyPatch index is not defined " diff --git a/src/finiteArea/faMesh/faMeshI.H b/src/finiteArea/faMesh/faMeshI.H new file mode 100644 index 0000000000000000000000000000000000000000..a3d79328606337f6c291467b5bec28d6ce0e0346 --- /dev/null +++ b/src/finiteArea/faMesh/faMeshI.H @@ -0,0 +1,142 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2016-2017 Wikki Ltd + Copyright (C) 2021 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/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +inline const Foam::polyMesh& Foam::faMesh::mesh() const +{ + return + MeshObject<polyMesh, Foam::UpdateableMeshObject, faMesh>::mesh(); +} + + +inline const Foam::faBoundaryMesh& Foam::faMesh::boundary() const noexcept +{ + return boundary_; +} + + +inline Foam::label Foam::faMesh::comm() const noexcept +{ + return comm_; +} + + +inline Foam::label& Foam::faMesh::comm() noexcept +{ + return comm_; +} + + +inline Foam::label Foam::faMesh::nPoints() const noexcept +{ + return nPoints_; +} + + +inline Foam::label Foam::faMesh::nEdges() const noexcept +{ + return nEdges_; +} + + +inline Foam::label Foam::faMesh::nInternalEdges() const noexcept +{ + return nInternalEdges_; +} + + +inline Foam::label Foam::faMesh::nBoundaryEdges() const noexcept +{ + return nEdges_ - nInternalEdges_; +} + + +inline Foam::label Foam::faMesh::nFaces() const noexcept +{ + return nFaces_; +} + + +inline const Foam::pointField& Foam::faMesh::points() const +{ + return patch().localPoints(); +} + + +inline const Foam::edgeList& Foam::faMesh::edges() const noexcept +{ + return edges_; +} + + +inline const Foam::faceList& Foam::faMesh::faces() const +{ + return patch().localFaces(); +} + + +inline const Foam::labelList& Foam::faMesh::edgeOwner() const noexcept +{ + return edgeOwner_; +} + + +inline const Foam::labelList& Foam::faMesh::edgeNeighbour() const noexcept +{ + return edgeNeighbour_; +} + + +inline const Foam::labelList& Foam::faMesh::faceLabels() const noexcept +{ + return faceLabels_; +} + + +inline const Foam::uindirectPrimitivePatch& Foam::faMesh::patch() const +{ + if (!patchPtr_) + { + initPatch(); + } + return *patchPtr_; +} + + +inline Foam::uindirectPrimitivePatch& Foam::faMesh::patch() +{ + if (!patchPtr_) + { + initPatch(); + } + return *patchPtr_; +} + + +// ************************************************************************* // diff --git a/src/finiteArea/faMesh/faMeshPatches.C b/src/finiteArea/faMesh/faMeshPatches.C new file mode 100644 index 0000000000000000000000000000000000000000..889bdd7826c301813a9eb69d7d4b2aa3fb7c023d --- /dev/null +++ b/src/finiteArea/faMesh/faMeshPatches.C @@ -0,0 +1,954 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2017 Wikki Ltd + Copyright (C) 2021 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 "faMesh.H" +#include "IndirectList.H" +#include "faPatchData.H" +#include "processorPolyPatch.H" +#include "processorFaPatch.H" +#include "globalMeshData.H" +#include "indirectPrimitivePatch.H" +#include "edgeHashes.H" +#include "LabelledItem.H" + +// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Manage patch pairs with a 'labelled' edge. +// The edge first/second correspond to the owner/neighbour patches. +// The index is a face index on the neighbour patch (FUTURE). + +// Local typedefs + +typedef LabelledItem<edge> patchPairInfo; +typedef List<patchPairInfo> patchPairInfoList; +typedef UIndirectList<patchPairInfo> patchPairInfoUIndList; + + +// Handling of dangling coupled edges. +// Tag values to "push" with special -(patchId+2) +struct combineDanglingEdge +{ + const label upperLimit; + + // Set dangling patchId from real patchId + static void setDangling(patchPairInfo& pairing, const label patchId) + { + pairing.first() = pairing.second() = -(patchId + 2); + pairing.setIndex(-1); // Invalidate + } + + // Convert dangling patchId to real patchId + static void correct(patchPairInfo& pairing) + { + if (pairing.first() < -1) + { + pairing.first() = -(pairing.first() + 2); + } + if (pairing.second() < -1) + { + pairing.second() = -(pairing.second() + 2); + } + } + + //- Construct with upper limit (the number of non-processor patches) + explicit combineDanglingEdge(const label nNonProcessor) + : + upperLimit(nNonProcessor) + {} + + + // Combine operation: overwrite unused or processor patches with + // 'dangling' patch information only + void operator()(patchPairInfo& x, const patchPairInfo& y) const + { + if (y.first() < -1 && edge::compare(x, y) == 0) + { + if (x.first() == -1 || x.first() >= upperLimit) + { + x.first() = y.first(); + } + if (x.second() == -1 || x.second() >= upperLimit) + { + x.second() = y.first(); + x.index() = y.index(); + } + } + } +}; + + +// Populate patch pairings according to the boundary edges +void findEdgePatchPairing +( + const polyBoundaryMesh& pbm, + const EdgeMap<label>& edgeToIndex, + patchPairInfoList& patchPairs, + label nMissing = -1 +) +{ + // Count how many slots (both sides) to be filled + if (nMissing < 0) + { + nMissing = 0; + for (const patchPairInfo& pairing : patchPairs) + { + if (pairing.first() == -1) ++nMissing; + if (pairing.second() == -1) ++nMissing; + } + } + + forAll(pbm, patchID) + { + if (!nMissing) break; // Everything filled + + const polyPatch& pp = pbm[patchID]; + + const bool isProcPatch = isA<processorPolyPatch>(pp); + + // Examine neighbour boundary edges + for (label edgei = pp.nInternalEdges(); edgei < pp.nEdges(); ++edgei) + { + // Lookup global edge of this neighbour, + // find matching owner boundary edge + + const label edgeIndex = + edgeToIndex.lookup(pp.meshEdge(edgei), -1); + + if (edgeIndex != -1) + { + // Add patchId. + // - hash-like so will only insert once + // - also add in the attached patch face (there is only one), + // saved in mesh face numbering for processor patches + + patchPairInfo& pairing = patchPairs[edgeIndex]; + + if (pairing.insert(patchID)) + { + if (isProcPatch) + { + // Save the mesh face + + const label patchFacei = pp.edgeFaces()[edgei][0]; + + pairing.index() = (pp.start() + patchFacei); + } + + --nMissing; + + if (!nMissing) break; // Early exit + } + } + } + } +} + +} // End namespace Foam + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::faMesh::reorderProcEdges +( + faPatchData& patchDef, + const List<LabelledItem<edge>>& bndEdgePatchPairs +) const +{ + if (!patchDef.coupled() || patchDef.edgeLabels_.empty()) + { + return; + } + + const polyBoundaryMesh& pbm = mesh().boundaryMesh(); + + const label procPatchID = patchDef.neighPolyPatchId_; + + const auto* procPatch = isA<processorPolyPatch>(pbm[procPatchID]); + + if (!procPatch) + { + FatalErrorInFunction + << "Internal addressing error. Patch " << procPatchID + << " is not a processor patch" << nl + << abort(FatalError); + } + + // Reorder processor edges using order of neighbour processorPolyPatch + + const label nProcEdges = patchDef.edgeLabels_.size(); + + labelList procFaces(nProcEdges, -1); + + forAll(procFaces, edgei) + { + const label bndEdgei = + (patchDef.edgeLabels_[edgei] - patch().nInternalEdges()); + + procFaces[edgei] = bndEdgePatchPairs[bndEdgei].index(); + } + + // Ascending proc-face numbering + const labelList sortIndices(Foam::sortedOrder(procFaces)); + + if (procFaces.size() && procFaces[sortIndices[0]] < 0) + { + FatalErrorInFunction + << "Internal addressing error. Patch " << procPatchID + << " with negative face" << nl + << abort(FatalError); + } + + + const labelList& oldEdgeLabels = patchDef.edgeLabels_; + labelList newEdgeLabels(oldEdgeLabels.size()); + + // Most of the time, an individual proc-face will only be singly + // attached to the finite-area patch. In rarer case, there could + // multiple connections. For these cases, need to walk the face + // edges - the direction depends on owner vs neighbour side. + + EdgeMap<label> multihit; + + for (label edgei = 0; edgei < nProcEdges; /*nil*/) + { + const label meshFacei = procFaces[sortIndices[edgei]]; + + // Find all identical faces + label endEdgei = edgei + 1; // one beyond + while + ( + (endEdgei < nProcEdges) + && (meshFacei == procFaces[sortIndices[endEdgei]]) + ) + { + ++endEdgei; + } + + if (edgei + 1 == endEdgei) + { + // Simplest case - a single connection + + newEdgeLabels[edgei] = oldEdgeLabels[sortIndices[edgei]]; + } + else + { + multihit.clear(); + + // Map from global edge to patch local edgeId + for (label i = edgei; i < endEdgei; ++i) + { + const label patchEdgei = oldEdgeLabels[sortIndices[i]]; + + // The edge in mesh numbering + multihit.insert + ( + patch().meshEdge(patchEdgei), + patchEdgei + ); + } + + if (multihit.size() != (endEdgei - edgei)) + { + FatalErrorInFunction + << "Could only hash " << multihit.size() + << " edges from " << (endEdgei - edgei) + << " ... indicates a non-manifold connection" << nl + << multihit << nl + << abort(FatalError); + } + + const face& f = mesh().faces()[meshFacei]; + + forAll(f, fedgei) // Note size() == nEdges() + { + edge e = + ( + patchDef.owner() + ? f.edge(fedgei) // Forward walk + : f.rcEdge(fedgei) // Reverse walk + ); + + auto iter = multihit.find(e); + if (iter.found()) + { + newEdgeLabels[edgei++] = iter.val(); + multihit.erase(iter); + if (multihit.empty()) + { + break; + } + } + } + + if (edgei != endEdgei) + { + FatalErrorInFunction + << "Missed " << (edgei < endEdgei) + << " edges for face: " << meshFacei + << " ... indicates serious geometry issue" << nl + << multihit << nl + << abort(FatalError); + } + if (!multihit.empty()) + { + FatalErrorInFunction + << "Missed edges for face: " << meshFacei + << " ... indicates serious geometry issue" << nl + << multihit << nl + << abort(FatalError); + } + } + edgei = endEdgei; + } + + patchDef.edgeLabels_.transfer(newEdgeLabels); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::faMesh::addFaPatches +( + PtrList<faPatch>& plist, + const bool validBoundary +) +{ + if (!boundary().empty()) + { + FatalErrorInFunction + << "boundary already exists" + << abort(FatalError); + } + + globalMeshDataPtr_.reset(nullptr); + + boundary_.transfer(plist); + + setPrimitiveMeshData(); + + if (validBoundary) + { + boundary_.checkDefinition(); + } +} + + +void Foam::faMesh::addFaPatches +( + const List<faPatch*>& p, + const bool validBoundary +) +{ + // Acquire ownership of the pointers + PtrList<faPatch> plist(const_cast<List<faPatch*>&>(p)); + + addFaPatches(plist, validBoundary); +} + + +Foam::PtrList<Foam::faPatch> Foam::faMesh::createOnePatch +( + const word& patchName, + const word& patchType +) const +{ + dictionary onePatchDict; + if (!patchName.empty()) + { + onePatchDict.add("name", patchName); + } + if (!patchType.empty()) + { + onePatchDict.add("type", patchType); + } + + return createPatchList + ( + dictionary::null, + word::null, // Name for empty patch placeholder + &onePatchDict // Definitions for defaultPatch + ); +} + + +Foam::List<Foam::LabelledItem<Foam::edge>> +Foam::faMesh::getBoundaryEdgePatchPairs() const +{ + const polyBoundaryMesh& pbm = mesh().boundaryMesh(); + + const label nInternalEdges = patch().nInternalEdges(); + const label nBoundaryEdges = patch().nBoundaryEdges(); + + // Map edges (mesh numbering) back to a boundary index + EdgeMap<label> edgeToBoundaryIndex(2*nBoundaryEdges); + + // Use labelled 'edge' for accounting of patch pairs + patchPairInfoList bndEdgePatchPairs(nBoundaryEdges); + + + // Pass 1: + // - setup lookup (edge -> bnd index) + // - add owner patch for each boundary edge + { + const SubList<labelList> bndEdgeToPatchFace + ( + patch().edgeFaces(), + patch().nBoundaryEdges(), + patch().nInternalEdges() + ); + + for (label bndEdgei = 0; bndEdgei < nBoundaryEdges; ++bndEdgei) + { + edgeToBoundaryIndex.insert + ( + patch().meshEdge(bndEdgei + nInternalEdges), + edgeToBoundaryIndex.size() + ); + + // The attached patch face (there is only one): + const label patchFacei = bndEdgeToPatchFace[bndEdgei][0]; + + const label meshFacei = faceLabels_[patchFacei]; + + const label patchId = pbm.whichPatch(meshFacei); + + bndEdgePatchPairs[bndEdgei].insert(patchId); + } + } + + // Pass 2: + // - Add in first neighbour patch for the boundary edges + // - examine all possible connecting neighbours + + findEdgePatchPairing + ( + pbm, + edgeToBoundaryIndex, + bndEdgePatchPairs, + edgeToBoundaryIndex.size() // Number of places to still fill + ); + + + // Nothing dangling if running in serial - can return already + if (!Pstream::parRun()) + { + return bndEdgePatchPairs; + } + + // In parallel need to check for "dangling" edges, which are finiteArea + // boundary edges that only exist on one side of a proc boundary. + // Eg, proc boundary coincides with the outer extent of the finiteArea + + const globalMeshData& globalData = mesh().globalData(); + const indirectPrimitivePatch& cpp = globalData.coupledPatch(); + const mapDistribute& map = globalData.globalEdgeSlavesMap(); + + // Construct coupled edge usage with all data + List<unsigned char> coupledEdgesUsed(map.constructSize(), 0u); + + forAll(cpp.edges(), coupledEdgei) + { + const auto iter = + edgeToBoundaryIndex.cfind(cpp.meshEdge(coupledEdgei)); + + // Used from this side or other other side + coupledEdgesUsed[coupledEdgei] = (iter.found() ? 1 : 2); + } + + // Save the original (pre-sync) coupling state + const List<unsigned char> coupledEdgesOrig(coupledEdgesUsed); + + globalData.syncData + ( + coupledEdgesUsed, + globalData.globalEdgeSlaves(), + globalData.globalEdgeTransformedSlaves(), // probably not used + map, + bitOrEqOp<unsigned char>() + ); + + + // Check for one-sided edge coupling (coupled value == 3) + // original == 1: + // - coupled to a real finiteArea edge. + // - receive a patch-pair value + // + // original == 2: + // - a "dangled" edge. Information required for other procs. + // - push a patch-pair value + + // Map edges (mesh numbering) back to a coupled index. + // These are the edges to 'push' information for. + + EdgeMap<label> edgeToCoupledIndex; + + label nEdgesPull = 0; + + forAll(coupledEdgesUsed, coupledEdgei) + { + if (coupledEdgesUsed[coupledEdgei] == 3) + { + if (coupledEdgesOrig[coupledEdgei] == 1) + { + // Coupled side with finiteArea + ++nEdgesPull; + } + else if (coupledEdgesOrig[coupledEdgei] == 2) + { + // Coupled side without finiteArea + edgeToCoupledIndex.insert + ( + cpp.meshEdge(coupledEdgei), + coupledEdgei + ); + } + } + } + + // Nothing to do - can return already + if (returnReduce(edgeToCoupledIndex.empty(), andOp<bool>())) + { + return bndEdgePatchPairs; + } + + // Data locations to pull + labelList patchEdgeLabels(nEdgesPull); + labelList coupledEdgeLabels(nEdgesPull); + + // Populate the locations + { + nEdgesPull = 0; + + forAll(cpp.edges(), coupledEdgei) + { + if + ( + coupledEdgesUsed[coupledEdgei] == 3 + && coupledEdgesOrig[coupledEdgei] == 1 + ) + { + // Pull this edge + const auto iter = + edgeToBoundaryIndex.cfind(cpp.meshEdge(coupledEdgei)); + + if (iter.found()) + { + patchEdgeLabels[nEdgesPull] = iter.val(); + coupledEdgeLabels[nEdgesPull] = coupledEdgei; + ++nEdgesPull; + } + else + { + // Should be impossible to fail here + FatalErrorInFunction + << "Failed on second lookup of " + << cpp.meshEdge(coupledEdgei) << nl + << abort(FatalError); + } + } + } + + if (nEdgesPull != coupledEdgeLabels.size()) + { + FatalErrorInFunction + << "Failed lookup of some coupled edges" << nl + << abort(FatalError); + } + } + + //- Construct edge sync with all data + patchPairInfoList cppEdgeData(map.constructSize()); + + // Fill in for 'push' locations. Only really interested in the owner + // (corresponds to non-proc connection), but grab everything + findEdgePatchPairing + ( + pbm, + edgeToCoupledIndex, + cppEdgeData, + 2*edgeToCoupledIndex.size() // Accept both sides? + ); + + + const label nNonProcessor = pbm.nNonProcessor(); + + // Adjust patch information to reflect dangling patch neighbour + // Tag with -(value+2) + forAllConstIters(edgeToCoupledIndex, iter) + { + const edge& e = iter.key(); + const label coupledEdgei = iter.val(); + + patchPairInfo& pairing = cppEdgeData[coupledEdgei]; + const label ownerPatchId = pairing.first(); + + // Some sanity checks + if (ownerPatchId < 0) + { + FatalErrorInFunction + << "Error finding dangling edge at " + << cpp.points()[e.first()] << ' ' + << cpp.points()[e.second()] << nl + << abort(FatalError); + } + else if (ownerPatchId >= nNonProcessor) + { + FatalErrorInFunction + << "Cannot handle edge on processor-processor connection at " + << cpp.points()[e.first()] << ' ' + << cpp.points()[e.second()] << nl + << abort(FatalError); + } + + combineDanglingEdge::setDangling(pairing, ownerPatchId); + + // TBD: + // may wish to remember the corresponding proc number, + // if we wish to bridge across 'fan-like' connections. + // + // pairing.setIndex(-(Pstream::myProcNo() + 2)); + } + + + // Synchronize edge information + + const combineDanglingEdge edgeCombineOp(nNonProcessor); + + globalMeshData::syncData + ( + cppEdgeData, + globalData.globalEdgeSlaves(), + globalData.globalEdgeTransformedSlaves(), // probably not used + map, + edgeCombineOp + ); + + + // Combine back from pushed cpp-edge data + + forAll(patchEdgeLabels, i) + { + patchPairInfo& pairing = bndEdgePatchPairs[patchEdgeLabels[i]]; + const patchPairInfo& other = cppEdgeData[coupledEdgeLabels[i]]; + + edgeCombineOp(pairing, other); + + // Resolve special tagging + combineDanglingEdge::correct(pairing); + } + + return bndEdgePatchPairs; +} + + +Foam::PtrList<Foam::faPatch> Foam::faMesh::createPatchList +( + const dictionary& bndDict, + const word& emptyPatchName, + const dictionary* defaultPatchDefinition +) const +{ + const polyBoundaryMesh& pbm = mesh().boundaryMesh(); + + // Transcribe into patch definitions + DynamicList<faPatchData> faPatchDefs(bndDict.size() + 4); + for (const entry& dEntry : bndDict) + { + if (!dEntry.isDict()) + { + WarningInFunction + << "Not a dictionary entry: " << dEntry.name() << nl; + continue; + } + const dictionary& patchDict = dEntry.dict(); + + // Add entry + faPatchDefs.append(faPatchData()); + + auto& patchDef = faPatchDefs.last(); + patchDef.name_ = dEntry.keyword(); + patchDef.type_ = patchDict.get<word>("type"); + + const word ownName(patchDict.get<word>("ownerPolyPatch")); + const word neiName(patchDict.get<word>("neighbourPolyPatch")); + + patchDef.ownerPolyPatchId_ = pbm.findPatchID(ownName); + patchDef.neighPolyPatchId_ = pbm.findPatchID(neiName); + + if (patchDef.ownerPolyPatchId_ < 0) + { + FatalErrorInFunction + << "ownerPolyPatch " << ownName << " not found" + << exit(FatalError); + } + if (patchDef.neighPolyPatchId_ < 0) + { + FatalErrorInFunction + << "neighbourPolyPatch " << neiName << " not found" + << exit(FatalError); + } + } + + // Additional empty placeholder patch? + if (!emptyPatchName.empty()) + { + faPatchDefs.append(faPatchData()); + + auto& patchDef = faPatchDefs.last(); + patchDef.name_ = emptyPatchName; + patchDef.type_ = "empty"; + } + + // Placeholder for any undefined edges + const label undefPatchId = faPatchDefs.size(); + { + faPatchDefs.append(faPatchData()); + + auto& patchDef = faPatchDefs.last(); + patchDef.name_ = "undefined"; + patchDef.type_ = "patch"; + + if (defaultPatchDefinition) + { + (*defaultPatchDefinition).readIfPresent("name", patchDef.name_); + (*defaultPatchDefinition).readIfPresent("type", patchDef.type_); + } + } + + // ---------------------------------------------------------------------- + + const label nInternalEdges = patch().nInternalEdges(); + const label nBoundaryEdges = patch().nBoundaryEdges(); + + patchPairInfoList bndEdgePatchPairs(this->getBoundaryEdgePatchPairs()); + + labelList bndEdgeFaPatchIDs(nBoundaryEdges, -1); + + for (label bndEdgei = 0; bndEdgei < nBoundaryEdges; ++bndEdgei) + { + const patchPairInfo& patchPair = bndEdgePatchPairs[bndEdgei]; + + if (patchPair.valid()) + { + // Non-negative, unique pairing + // - find corresponding definition + + for (label patchi = 0; patchi < faPatchDefs.size(); ++patchi) + { + if (faPatchDefs[patchi].foundPatchPair(patchPair)) + { + bndEdgeFaPatchIDs[bndEdgei] = patchi; + break; + } + } + } + } + + + // Extract which edges map to which patch + // and set edgeLabels for each faPatch + + DynamicList<label> selectEdges(bndEdgeFaPatchIDs.size()); + + for (label patchi = 0; patchi < faPatchDefs.size(); ++patchi) + { + auto& patchDef = faPatchDefs[patchi]; + + selectEdges.clear(); + + forAll(bndEdgeFaPatchIDs, bndEdgei) + { + if (bndEdgeFaPatchIDs[bndEdgei] == patchi) + { + selectEdges.append(bndEdgei + nInternalEdges); + } + } + + patchDef.edgeLabels_ = selectEdges; + } + + // Check for undefined edges + selectEdges.clear(); + + forAll(bndEdgeFaPatchIDs, bndEdgei) + { + if (bndEdgeFaPatchIDs[bndEdgei] == -1) + { + selectEdges.append(bndEdgei + nInternalEdges); + } + } + + // Save the information + faPatchDefs[undefPatchId].edgeLabels_ = selectEdges; + + bool hasUndefined = returnReduce(!selectEdges.empty(), orOp<bool>()); + + if (hasUndefined) + { + // The initial edges to consider + const labelList& undefinedEdges = + faPatchDefs[undefPatchId].edgeLabels_; + + // Check for edges that butt against a processor (or other) patch + + labelList edgeNbrPolyPatch(undefinedEdges.size(), -1); + forAll(edgeNbrPolyPatch, edgei) + { + const label patchEdgei = undefinedEdges[edgei]; + const label bndEdgei = (patchEdgei - nInternalEdges); + + edgeNbrPolyPatch[edgei] = bndEdgePatchPairs[bndEdgei].second(); + } + + // Categorize as processor/non-processor associations + labelHashSet procPatchIDs; + labelHashSet nonProcPatchIDs; + + for (const label polyPatchID : edgeNbrPolyPatch) + { + if (polyPatchID == -1) + { + nonProcPatchIDs.insert(polyPatchID); + } + else if + ( + !nonProcPatchIDs.found(polyPatchID) + && !procPatchIDs.found(polyPatchID) + ) + { + if (isA<processorPolyPatch>(pbm[polyPatchID])) + { + procPatchIDs.insert(polyPatchID); + } + else + { + nonProcPatchIDs.insert(polyPatchID); + } + } + } + + // Select by processor association + for (const label polyPatchID : procPatchIDs.sortedToc()) + { + selectEdges.clear(); + + forAll(edgeNbrPolyPatch, edgei) + { + if (edgeNbrPolyPatch[edgei] == polyPatchID) + { + selectEdges.append(undefinedEdges[edgei]); + } + } + + faPatchDefs.append(faPatchData()); + + auto& patchDef = faPatchDefs.last(); + patchDef.name_ = pbm[polyPatchID].name(); + patchDef.type_ = processorFaPatch::typeName; + patchDef.neighPolyPatchId_ = polyPatchID; // Needed for reorder + + const auto* ppp = isA<processorPolyPatch>(pbm[polyPatchID]); + if (ppp) + { + patchDef.ownerProcId_ = ppp->myProcNo(); + patchDef.neighProcId_ = ppp->neighbProcNo(); + } + + patchDef.edgeLabels_ = selectEdges; + } + + + // Check for any remaining undefined edges + selectEdges.clear(); + + // Simply grab any/all (don't worry about which patch) + if (!nonProcPatchIDs.empty()) + { + forAll(edgeNbrPolyPatch, edgei) + { + const label polyPatchID = edgeNbrPolyPatch[edgei]; + if (nonProcPatchIDs.found(polyPatchID)) + { + selectEdges.append(undefinedEdges[edgei]); + } + } + } + + // Complete the information + faPatchDefs[undefPatchId].edgeLabels_ = selectEdges; + + hasUndefined = returnReduce(!selectEdges.empty(), orOp<bool>()); + } + + // Remove unnecessary entry + if (!hasUndefined) + { + faPatchDefs.remove(undefPatchId); + } + + for (auto& patchDef : faPatchDefs) + { + if (patchDef.coupled()) + { + reorderProcEdges(patchDef, bndEdgePatchPairs); + patchDef.neighPolyPatchId_ = -1; // No lookup of neighbour faces + } + } + + // Now convert list of definitions to list of patches + + label nPatches = 0; + PtrList<faPatch> newPatches(faPatchDefs.size()); + + for (faPatchData& patchDef : faPatchDefs) + { + newPatches.set + ( + nPatches, + faPatch::New + ( + patchDef.name(), // name + patchDef.dict(false), // withEdgeLabels == false + nPatches, // index + boundary() + ) + ); + + // Transfer edge labels + newPatches[nPatches].resetEdges(std::move(patchDef.edgeLabels_)); + ++nPatches; + } + + return newPatches; +} + + +// ************************************************************************* // diff --git a/src/finiteArea/faMesh/faMeshUpdate.C b/src/finiteArea/faMesh/faMeshUpdate.C index cb518d77eff128dcbcb63f70f7c7feb247c4393a..1e8593b261f0d9a09283321059a1db4b752d5e3e 100644 --- a/src/finiteArea/faMesh/faMeshUpdate.C +++ b/src/finiteArea/faMesh/faMeshUpdate.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd - Copyright (C) 2020 OpenCFD Ltd. + Copyright (C) 2020-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -61,11 +61,12 @@ void Foam::faMesh::updateMesh(const mapPolyMesh& mpm) // Set new labels m.faceLabels_ = mapper.areaMap().newFaceLabels(); - const indirectPrimitivePatch& bp = patch(); + const uindirectPrimitivePatch& bp = patch(); // Collect patch data const label nTotalEdges = bp.nEdges(); const label nInternalEdges = bp.nInternalEdges(); + const label nBoundaryEdges = bp.nBoundaryEdges(); const labelListList& edgeFaces = bp.edgeFaces(); labelListList patchEdges(boundary_.size()); @@ -73,7 +74,7 @@ void Foam::faMesh::updateMesh(const mapPolyMesh& mpm) // Special handling required for faces that have more than one edge // Each patch will be visited separately - labelList edgeToPatch(nTotalEdges - nInternalEdges, -1); + labelList edgeToPatch(nBoundaryEdges, -1); const labelList& newFaceLabelsMap = mapper.areaMap().newFaceLabelsMap(); const labelListList& oldPatchEdgeFaces = mapper.oldPatchEdgeFaces(); @@ -81,7 +82,7 @@ void Foam::faMesh::updateMesh(const mapPolyMesh& mpm) forAll(oldPatchEdgeFaces, patchI) { labelList& curPatchEdges = patchEdges[patchI]; - curPatchEdges.setSize(nTotalEdges - nInternalEdges); + curPatchEdges.resize(nBoundaryEdges); label nCurPatchEdges = 0; // Note: it is possible to pick up the old-to-new boundary patch diff --git a/src/finiteArea/faMesh/faPatches/basic/coupled/coupledFaPatch.C b/src/finiteArea/faMesh/faPatches/basic/coupled/coupledFaPatch.C index bbc073bfc2105aed7e55976bf4e2ad6884a28826..8ca96bbdaa68aeb647f177a7ccda8327d8845a4d 100644 --- a/src/finiteArea/faMesh/faPatches/basic/coupled/coupledFaPatch.C +++ b/src/finiteArea/faMesh/faPatches/basic/coupled/coupledFaPatch.C @@ -117,10 +117,4 @@ void Foam::coupledFaPatch::calcTransformTensors } -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // - -Foam::coupledFaPatch::~coupledFaPatch() -{} - - // ************************************************************************* // diff --git a/src/finiteArea/faMesh/faPatches/basic/coupled/coupledFaPatch.H b/src/finiteArea/faMesh/faPatches/basic/coupled/coupledFaPatch.H index d5424a42a4ad82902108f53b68ca03deaf2ce169..7f5ddc489be08b6fb3e769cd77d3334d897bc370 100644 --- a/src/finiteArea/faMesh/faPatches/basic/coupled/coupledFaPatch.H +++ b/src/finiteArea/faMesh/faPatches/basic/coupled/coupledFaPatch.H @@ -135,7 +135,7 @@ public: //- Destructor - virtual ~coupledFaPatch(); + virtual ~coupledFaPatch() = default; // Member Functions diff --git a/src/finiteArea/faMesh/faPatches/constraint/empty/emptyFaPatch.C b/src/finiteArea/faMesh/faPatches/constraint/empty/emptyFaPatch.C index 5b4c4bb971e89553655511df023be8241f505782..93c69622e8d4b4f06a5c99944edba05b75dd6bb0 100644 --- a/src/finiteArea/faMesh/faPatches/constraint/empty/emptyFaPatch.C +++ b/src/finiteArea/faMesh/faPatches/constraint/empty/emptyFaPatch.C @@ -28,19 +28,50 @@ License #include "emptyFaPatch.H" #include "addToRunTimeSelectionTable.H" -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - // Patch name defineTypeNameAndDebug(emptyFaPatch, 0); // Add the patch constructor functions to the hash tables addToRunTimeSelectionTable(faPatch, emptyFaPatch, dictionary); +} // End namespace Foam + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::emptyFaPatch::emptyFaPatch +( + const word& name, + const label index, + const faBoundaryMesh& bm, + const label ngbPolyPatchIndex +) +: + emptyFaPatch(name, labelList(), index, bm, ngbPolyPatchIndex) +{} + + +Foam::emptyFaPatch::emptyFaPatch +( + const word& name, + const labelList& edgeLabels, + const label index, + const faBoundaryMesh& bm, + const label ngbPolyPatchIndex +) +: + faPatch(name, edgeLabels, index, bm, ngbPolyPatchIndex) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + + // Over-riding the face normals return from the underlying patch // This is the only piece of info used out of the underlying primitivePatch // I choose to store it there because it is used in primitive patch operations @@ -54,8 +85,4 @@ addToRunTimeSelectionTable(faPatch, emptyFaPatch, dictionary); // } -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - // ************************************************************************* // diff --git a/src/finiteArea/faMesh/faPatches/constraint/empty/emptyFaPatch.H b/src/finiteArea/faMesh/faPatches/constraint/empty/emptyFaPatch.H index 0ff674f5663b3956853c1c18e496354202df95a3..e9ecd37363eaedeaf7fd5f17e3eaad16a61b1b1c 100644 --- a/src/finiteArea/faMesh/faPatches/constraint/empty/emptyFaPatch.H +++ b/src/finiteArea/faMesh/faPatches/constraint/empty/emptyFaPatch.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -57,7 +58,6 @@ class emptyFaPatch : public faPatch { - public: //- Runtime type information @@ -66,7 +66,16 @@ public: // Constructors - //- Construct from components + //- Minimal construct from components + emptyFaPatch + ( + const word& name, + const label index, + const faBoundaryMesh& bm, + const label ngbPolyPatchIndex = -1 + ); + + //- Construct from components emptyFaPatch ( const word& name, @@ -74,10 +83,7 @@ public: const label index, const faBoundaryMesh& bm, const label ngbPolyPatchIndex - ) - : - faPatch(name, edgeLabels, index, bm, ngbPolyPatchIndex) - {} + ); //- Construct from dictionary emptyFaPatch @@ -114,6 +120,7 @@ public: ); } + // Member Functions virtual label size() const @@ -124,7 +131,6 @@ public: //- Return face normals. Over-riding base class return to get zero size // // virtual const vectorField& edgeNormals() const; - }; diff --git a/src/finiteArea/faMesh/faPatches/constraint/processor/processorFaPatch.H b/src/finiteArea/faMesh/faPatches/constraint/processor/processorFaPatch.H index 4bf3f9d68331eb2740b7a23efd2f4e7294d74799..c48962843c6bdcc1b5136f0cc0640ff4c4af84f6 100644 --- a/src/finiteArea/faMesh/faPatches/constraint/processor/processorFaPatch.H +++ b/src/finiteArea/faMesh/faPatches/constraint/processor/processorFaPatch.H @@ -122,7 +122,6 @@ protected: public: //- Runtime type information -// TypeName(processorPolyPatch::typeName_()); TypeName("processor"); @@ -174,7 +173,7 @@ public: virtual ~processorFaPatch(); - // Member functions + // Member Functions //- Return interface size virtual label interfaceSize() const diff --git a/src/finiteArea/faMesh/faPatches/constraint/symmetry/symmetryFaPatch.C b/src/finiteArea/faMesh/faPatches/constraint/symmetry/symmetryFaPatch.C index 437b03474b2e9ce19aef86b63e21fb265df7272a..bdf45fac31a395603ad7ca966e8d8650f2298bb6 100644 --- a/src/finiteArea/faMesh/faPatches/constraint/symmetry/symmetryFaPatch.C +++ b/src/finiteArea/faMesh/faPatches/constraint/symmetry/symmetryFaPatch.C @@ -70,7 +70,7 @@ Foam::symmetryFaPatch::symmetryFaPatch : faPatch(name, dict, index, bm) { - if (ngbPolyPatchIndex() == -1) + if (ngbPolyPatchIndex() < 0) { FatalErrorInFunction << "Neighbour polyPatch index is not specified for faPatch " diff --git a/src/finiteArea/faMesh/faPatches/constraint/wedge/wedgeFaPatch.C b/src/finiteArea/faMesh/faPatches/constraint/wedge/wedgeFaPatch.C index 8cca67583a7fd040bd1e8ee4b1c09b67d5ae33e2..c841637f4591865f41ab8a5afe23285ed5ef139f 100644 --- a/src/finiteArea/faMesh/faPatches/constraint/wedge/wedgeFaPatch.C +++ b/src/finiteArea/faMesh/faPatches/constraint/wedge/wedgeFaPatch.C @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -87,22 +88,21 @@ Foam::wedgeFaPatch::wedgeFaPatch axisPoint_(-1), axisPointChecked_(false) { - if (ngbPolyPatchIndex() == -1) + if (ngbPolyPatchIndex() < 0) { FatalErrorInFunction << "Neighbour polyPatch index is not specified for faPatch " << this->name() << exit(FatalError); } - if (isA<wedgePolyPatch>(bm.mesh()().boundaryMesh()[ngbPolyPatchIndex()])) - { - const wedgePolyPatch& wedge = - refCast<const wedgePolyPatch> - ( - bm.mesh()().boundaryMesh()[ngbPolyPatchIndex()] - ); + const auto* wedgePtr = isA<wedgePolyPatch> + ( + bm.mesh()().boundaryMesh()[ngbPolyPatchIndex()] + ); - wedgePolyPatchPtr_ = ∧ + if (wedgePtr) + { + wedgePolyPatchPtr_ = wedgePtr; } else { diff --git a/src/finiteArea/faMesh/faPatches/faPatch/faPatch.C b/src/finiteArea/faMesh/faPatches/faPatch/faPatch.C index 52f7a3ba6247d45e950bb2f58e34282bd940a269..a050e497a84077104fce80d4ebbc5ce8b3e6087f 100644 --- a/src/finiteArea/faMesh/faPatches/faPatch/faPatch.C +++ b/src/finiteArea/faMesh/faPatches/faPatch/faPatch.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd - Copyright (C) 2019-2020 OpenCFD Ltd. + Copyright (C) 2019-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -21,7 +21,7 @@ License 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 + You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. \*---------------------------------------------------------------------------*/ @@ -68,7 +68,7 @@ Foam::faPatch::faPatch : labelList(edgeLabels), patchIdentifier(name, index), - ngbPolyPatchIndex_(ngbPolyPatchIndex), + nbrPolyPatchId_(ngbPolyPatchIndex), boundaryMesh_(bm), edgeFacesPtr_(nullptr), pointLabelsPtr_(nullptr), @@ -86,7 +86,7 @@ Foam::faPatch::faPatch : labelList(dict.get<labelList>("edgeLabels")), patchIdentifier(name, dict, index), - ngbPolyPatchIndex_(dict.get<label>("ngbPolyPatchIndex")), + nbrPolyPatchId_(dict.get<label>("ngbPolyPatchIndex")), boundaryMesh_(bm), edgeFacesPtr_(nullptr), pointLabelsPtr_(nullptr), @@ -98,7 +98,7 @@ Foam::faPatch::faPatch(const faPatch& p, const faBoundaryMesh& bm) : labelList(p), patchIdentifier(p, p.index()), - ngbPolyPatchIndex_(p.ngbPolyPatchIndex_), + nbrPolyPatchId_(p.nbrPolyPatchId_), boundaryMesh_(bm), edgeFacesPtr_(nullptr), pointLabelsPtr_(nullptr), @@ -116,13 +116,13 @@ Foam::faPatch::~faPatch() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -Foam::label Foam::faPatch::ngbPolyPatchIndex() const +Foam::label Foam::faPatch::ngbPolyPatchIndex() const noexcept { - return ngbPolyPatchIndex_; + return nbrPolyPatchId_; } -const Foam::faBoundaryMesh& Foam::faPatch::boundaryMesh() const +const Foam::faBoundaryMesh& Foam::faPatch::boundaryMesh() const noexcept { return boundaryMesh_; } @@ -240,38 +240,22 @@ const Foam::labelListList& Foam::faPatch::pointEdges() const Foam::labelList Foam::faPatch::ngbPolyPatchFaces() const { - labelList ngbFaces; - - if (ngbPolyPatchIndex() == -1) + if (nbrPolyPatchId_ < 0) { - return ngbFaces; + return labelList(); } - ngbFaces.setSize(faPatch::size()); + labelList ngbFaces(faPatch::size()); const faMesh& aMesh = boundaryMesh().mesh(); - const polyMesh& pMesh = aMesh(); - const indirectPrimitivePatch& patch = aMesh.patch(); + const polyMesh& pMesh = aMesh.mesh(); + const auto& patch = aMesh.patch(); const labelListList& edgeFaces = pMesh.edgeFaces(); - labelList faceCells(patch.size(), -1); - - forAll(faceCells, faceI) - { - label faceID = aMesh.faceLabels()[faceI]; - - faceCells[faceI] = pMesh.faceOwner()[faceID]; - } - - labelList meshEdges + const labelList meshEdges ( - patch.meshEdges - ( - pMesh.edges(), - pMesh.cellEdges(), - faceCells - ) + patch.meshEdges(pMesh.edges(), pMesh.pointEdges()) ); forAll(ngbFaces, edgeI) @@ -288,7 +272,7 @@ Foam::labelList Foam::faPatch::ngbPolyPatchFaces() const label curPatchID = pMesh.boundaryMesh().whichPatch(curFace); - if (curPatchID == ngbPolyPatchIndex()) + if (curPatchID == nbrPolyPatchId_) { ngbFaces[edgeI] = curFace; } @@ -308,14 +292,14 @@ Foam::labelList Foam::faPatch::ngbPolyPatchFaces() const Foam::tmp<Foam::vectorField> Foam::faPatch::ngbPolyPatchFaceNormals() const { - auto tfN = tmp<vectorField>::New(); - auto& fN = tfN.ref(); - - if (ngbPolyPatchIndex() == -1) + if (nbrPolyPatchId_ < 0) { - return tfN; + return tmp<vectorField>::New(); } + auto tfN = tmp<vectorField>::New(); + auto& fN = tfN.ref(); + fN.setSize(faPatch::size()); labelList ngbFaces = ngbPolyPatchFaces(); @@ -336,7 +320,7 @@ Foam::tmp<Foam::vectorField> Foam::faPatch::ngbPolyPatchFaceNormals() const Foam::tmp<Foam::vectorField> Foam::faPatch::ngbPolyPatchPointNormals() const { - if (ngbPolyPatchIndex() == -1) + if (nbrPolyPatchId_ < 0) { return tmp<vectorField>::New(); } @@ -468,12 +452,17 @@ void Foam::faPatch::movePoints(const pointField& points) {} -void Foam::faPatch::resetEdges(const labelList& newEdges) +void Foam::faPatch::resetEdges(const UList<label>& newEdges) { - Info<< "Resetting patch edges" << endl; - labelList::operator=(newEdges); + clearOut(); + static_cast<labelList&>(*this) = newEdges; +} + +void Foam::faPatch::resetEdges(labelList&& newEdges) +{ clearOut(); + static_cast<labelList&>(*this) = std::move(newEdges); } @@ -483,9 +472,8 @@ void Foam::faPatch::write(Ostream& os) const patchIdentifier::write(os); - const labelList& edgeLabels = *this; - edgeLabels.writeEntry("edgeLabels", os); - os.writeEntry("ngbPolyPatchIndex", ngbPolyPatchIndex_); + os.writeEntry("ngbPolyPatchIndex", nbrPolyPatchId_); + static_cast<const labelList&>(*this).writeEntry("edgeLabels", os); } diff --git a/src/finiteArea/faMesh/faPatches/faPatch/faPatch.H b/src/finiteArea/faMesh/faPatches/faPatch/faPatch.H index 52fb33e613a85966c8978da476aa6d4dca8718ea..98bb9efe764d2decfdf002567567c79a44750ebe 100644 --- a/src/finiteArea/faMesh/faPatches/faPatch/faPatch.H +++ b/src/finiteArea/faMesh/faPatches/faPatch/faPatch.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd - Copyright (C) 2020 OpenCFD Ltd. + Copyright (C) 2020-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -58,6 +58,7 @@ SourceFiles namespace Foam { +// Forward Declarations class faBoundaryMesh; class faPatch; Ostream& operator<<(Ostream&, const faPatch&); @@ -74,7 +75,7 @@ class faPatch // Private Data //- Neighbour polyPatch index - const label ngbPolyPatchIndex_; + const label nbrPolyPatchId_; //- Reference to boundary mesh const faBoundaryMesh& boundaryMesh_; @@ -100,7 +101,6 @@ class faPatch //- No copy assignment void operator=(const faPatch&) = delete; - //- Clear out topological patch data void clearOut(); @@ -225,17 +225,31 @@ public: // Member Functions - //- Return number of patch points + //- Return the list of edges + const labelList& edgeLabels() const noexcept + { + return static_cast<const labelList&>(*this); + } + + void edgeLabels(const UList<label>& newEdgeLabels); + + //- Number of patch points label nPoints() const { return pointLabels().size(); } + //- Number of edge labels (boundary edges) addressed by this patch + label nEdges() const noexcept + { + return labelList::size(); + } + //- Return neighbour polyPatch index - label ngbPolyPatchIndex() const; + label ngbPolyPatchIndex() const noexcept; //- Return boundaryMesh reference - const faBoundaryMesh& boundaryMesh() const; + const faBoundaryMesh& boundaryMesh() const noexcept; //- Return true if this patch is coupled virtual bool coupled() const @@ -246,7 +260,7 @@ public: //- Patch start in edge list label start() const; - //- Patch size + //- Patch size is the number of edge labels virtual label size() const { return labelList::size(); @@ -330,8 +344,11 @@ public: // Topological changes - //- Reset edge list - void resetEdges(const labelList&); + //- Reset the list of edges (use with caution) + void resetEdges(const UList<label>& newEdges); + + //- Reset the list of edges (use with caution) + void resetEdges(labelList&& newEdges); // Evaluation diff --git a/src/finiteArea/faMesh/faPatches/faPatch/faPatchData.C b/src/finiteArea/faMesh/faPatches/faPatch/faPatchData.C new file mode 100644 index 0000000000000000000000000000000000000000..7d712c99efd0dedaef42878732ea8956a5187cf8 --- /dev/null +++ b/src/finiteArea/faMesh/faPatches/faPatch/faPatchData.C @@ -0,0 +1,130 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 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 "faPatchData.H" +#include "edge.H" +#include "dictionary.H" +#include "processorFaPatch.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::faPatchData::faPatchData() +: + ownerPolyPatchId_(-1), + neighPolyPatchId_(-1), + ownerProcId_(-1), + neighProcId_(-1) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +const Foam::word& Foam::faPatchData::name() const noexcept +{ + return name_; +} + + +Foam::dictionary Foam::faPatchData::dict(const bool withEdgeLabels) const +{ + dictionary patchDict; + patchDict.add("type", type_); + + if (withEdgeLabels) + { + patchDict.add("edgeLabels", edgeLabels_); + } + else + { + patchDict.add("edgeLabels", labelList()); + } + patchDict.add("ngbPolyPatchIndex", neighPolyPatchId_); + + if (coupled()) + { + patchDict.add("myProcNo", ownerProcId_); + patchDict.add("neighbProcNo", neighProcId_); + } + + return patchDict; +} + + +void Foam::faPatchData::clear() +{ + name_.clear(); + type_.clear(); + + ownerPolyPatchId_ = -1; + neighPolyPatchId_ = -1; + + ownerProcId_ = -1; + neighProcId_ = -1; + + edgeLabels_.clear(); +} + + +void Foam::faPatchData::assign(const faPatch& fap) +{ + clear(); + + // Copy information + name_ = fap.name(); + type_ = fap.type(); + + neighPolyPatchId_ = fap.ngbPolyPatchIndex(); + edgeLabels_ = fap.edgeLabels(); + + const auto* fapp = isA<processorFaPatch>(fap); + if (fapp) + { + ownerProcId_ = fapp->myProcNo(); + neighProcId_ = fapp->neighbProcNo(); + } +} + + +bool Foam::faPatchData::foundPatchPair(const edge& patchPair) const +{ + // Same as edge::compare + return + ( + ( + ownerPolyPatchId_ == patchPair.first() + && neighPolyPatchId_ == patchPair.second() + ) + || + ( + ownerPolyPatchId_ == patchPair.second() + && neighPolyPatchId_ == patchPair.first() + ) + ); +} + + +// ************************************************************************* // diff --git a/src/finiteArea/faMesh/faPatches/faPatch/faPatchData.H b/src/finiteArea/faMesh/faPatches/faPatch/faPatchData.H index c8d46697913293b4097f369885274a924cc1a08e..4f785b351562ef63647effede34ec1299ed10dfb 100644 --- a/src/finiteArea/faMesh/faPatches/faPatch/faPatchData.H +++ b/src/finiteArea/faMesh/faPatches/faPatch/faPatchData.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -27,7 +28,8 @@ Class Foam::faPatchData Description - Class which holds data needed for faPatch construction + Helper class for holding data during faPatch construction. + Most data members are exposed at the moment. \*---------------------------------------------------------------------------*/ @@ -41,25 +43,81 @@ Description namespace Foam { +// Forward Declarations +class edge; +class faPatch; +class dictionary; + /*---------------------------------------------------------------------------*\ Class faPatchData Declaration \*---------------------------------------------------------------------------*/ -struct faPatchData +class faPatchData { - word name_; - word type_; - dictionary dict_; - label ownPolyPatchID_; - label ngbPolyPatchID_; - labelList edgeLabels_; - faPatchData() - : - name_(word::null), - type_(word::null), - ownPolyPatchID_(-1), - ngbPolyPatchID_(-1) - {} +public: + + // Data Members + + word name_; + word type_; + + label ownerPolyPatchId_; + label neighPolyPatchId_; + + //- The owner/neighbour for processor patches + int ownerProcId_; + int neighProcId_; + + // Storge (temporary or otherwise) for edge labels + labelList edgeLabels_; + + + // Constructors + + //- Default construct + faPatchData(); + + + // Member Functions + + // Opaque read-only access + + //- Return the name + const word& name() const noexcept; + + //- Contents transcribed into a patch dictionary, + //- usually including the edge labels. + dictionary dict(const bool withEdgeLabels = true) const; + + + // Other Functions + + //- Reset data + void clear(); + + //- Clear and populate with values from finiteArea patch + void assign(const faPatch& fap); + + //- True if owner/neighbour processor ids are non-equal + bool coupled() const noexcept + { + return (ownerProcId_ != neighProcId_); + } + + //- Does this side own the patch? Also true for non-coupled patches + bool owner() const noexcept + { + return (ownerProcId_ <= neighProcId_); + } + + //- Does the other side own the patch? + bool neighbour() const noexcept + { + return !owner(); + } + + //- True it matches the owner/neighbour patch pair (any order) + bool foundPatchPair(const edge& patchPair) const; }; diff --git a/src/finiteArea/faMesh/faPatches/faPatch/faPatchFaMeshTemplates.C b/src/finiteArea/faMesh/faPatches/faPatch/faPatchFaMeshTemplates.C index 6e3fab5ee86b6ac4590f372ff9a00c68bd650668..ce4a007e11a64f3bc08a54da665ec6b43b7e20dc 100644 --- a/src/finiteArea/faMesh/faPatches/faPatch/faPatchFaMeshTemplates.C +++ b/src/finiteArea/faMesh/faPatches/faPatch/faPatchFaMeshTemplates.C @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -39,10 +40,8 @@ const typename GeometricField::Patch& Foam::faPatch::lookupPatchField { return patchField<GeometricField, Type> ( - boundaryMesh().mesh()().objectRegistry::lookupObject<GeometricField> - ( - name - ) + boundaryMesh().mesh().mesh().objectRegistry::template + lookupObject<GeometricField>(name) ); } diff --git a/src/finiteVolume/cfdTools/general/fvOptions/fvOption.C b/src/finiteVolume/cfdTools/general/fvOptions/fvOption.C index e2c5e73ed7edf9c63060c0a995f1a15f6a06e1ee..4614b1b8acc5e09e524e107598b20f406648883e 100644 --- a/src/finiteVolume/cfdTools/general/fvOptions/fvOption.C +++ b/src/finiteVolume/cfdTools/general/fvOptions/fvOption.C @@ -58,9 +58,9 @@ Foam::fv::option::option mesh_(mesh), dict_(dict), coeffs_(dict.optionalSubDict(modelType + "Coeffs")), - active_(dict_.getOrDefault<Switch>("active", true)), fieldNames_(), applied_(), + active_(dict_.getOrDefault("active", true)), log(true) { Log << incrIndent << indent << "Source: " << name_ << endl << decrIndent; @@ -101,7 +101,7 @@ Foam::autoPtr<Foam::fv::option> Foam::fv::option::New ) << exit(FatalIOError); } - return autoPtr<option>(cstrIter()(name, modelType, coeffs, mesh)); + return autoPtr<fv::option>(cstrIter()(name, modelType, coeffs, mesh)); } diff --git a/src/finiteVolume/cfdTools/general/fvOptions/fvOption.H b/src/finiteVolume/cfdTools/general/fvOptions/fvOption.H index e1859a714da3f46219afd6dc34f5e82c89d5a99b..84539964ac498733f4724d67f547b3546ecc9aef 100644 --- a/src/finiteVolume/cfdTools/general/fvOptions/fvOption.H +++ b/src/finiteVolume/cfdTools/general/fvOptions/fvOption.H @@ -113,23 +113,25 @@ protected: //- Dictionary containing source coefficients dictionary coeffs_; - //- Source active flag - Switch active_; - //- Field names to apply source to - populated by derived models wordList fieldNames_; //- Applied flag list - corresponds to each fieldNames_ entry List<bool> applied_; + //- Source active flag + bool active_; + public: + //- Switch write log to Info + bool log; + + //- Runtime type information TypeName("option"); - //- Switch write log to Info - bool log; // Declare run-time constructor selection table @@ -219,16 +221,16 @@ public: // Access //- Return const access to the source name - inline const word& name() const; + inline const word& name() const noexcept; //- Return const access to the mesh database - inline const fvMesh& mesh() const; + inline const fvMesh& mesh() const noexcept; //- Return dictionary - inline const dictionary& coeffs() const; + inline const dictionary& coeffs() const noexcept; - //- Return const access to the source active flag - inline bool active() const; + //- True if source is active + inline bool active() const noexcept; //- Set the applied flag to true for field index fieldi inline void setApplied(const label fieldi); @@ -236,8 +238,8 @@ public: // Edit - //- Return access to the source active flag - inline Switch& active(); + //- Change source active flag, return previous value + inline bool active(const bool on) noexcept; // Checks diff --git a/src/finiteVolume/cfdTools/general/fvOptions/fvOptionI.H b/src/finiteVolume/cfdTools/general/fvOptions/fvOptionI.H index f15e73aa172d547ba2ac7a5265e9ebb2b8f8d7ab..586024e2e6bdf31f0e420956167c339654af4e60 100644 --- a/src/finiteVolume/cfdTools/general/fvOptions/fvOptionI.H +++ b/src/finiteVolume/cfdTools/general/fvOptions/fvOptionI.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -27,39 +28,41 @@ License // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -inline const Foam::word& Foam::fv::option::name() const +inline const Foam::word& Foam::fv::option::name() const noexcept { return name_; } -inline const Foam::fvMesh& Foam::fv::option::mesh() const +inline const Foam::fvMesh& Foam::fv::option::mesh() const noexcept { return mesh_; } -inline const Foam::dictionary& Foam::fv::option::coeffs() const +inline const Foam::dictionary& Foam::fv::option::coeffs() const noexcept { return coeffs_; } -inline bool Foam::fv::option::active() const +inline bool Foam::fv::option::active() const noexcept { return active_; } -inline void Foam::fv::option::setApplied(const label fieldi) +inline bool Foam::fv::option::active(const bool on) noexcept { - applied_[fieldi] = true; + bool old(active_); + active_ = on; + return old; } -inline Foam::Switch& Foam::fv::option::active() +inline void Foam::fv::option::setApplied(const label fieldi) { - return active_; + applied_[fieldi] = true; } diff --git a/src/finiteVolume/cfdTools/general/fvOptions/fvOptionList.C b/src/finiteVolume/cfdTools/general/fvOptions/fvOptionList.C index 78f4a6fa58a25c18b68bfc93d33d1eebb2d2f313..2fe08194b560182ac3ab1f444adb89351243fba1 100644 --- a/src/finiteVolume/cfdTools/general/fvOptions/fvOptionList.C +++ b/src/finiteVolume/cfdTools/general/fvOptions/fvOptionList.C @@ -89,7 +89,7 @@ void Foam::fv::optionList::checkApplied() const Foam::fv::optionList::optionList(const fvMesh& mesh, const dictionary& dict) : - PtrList<option>(), + PtrList<fv::option>(), mesh_(mesh), checkTimeIndex_(mesh_.time().startTimeIndex() + 2) { @@ -99,7 +99,7 @@ Foam::fv::optionList::optionList(const fvMesh& mesh, const dictionary& dict) Foam::fv::optionList::optionList(const fvMesh& mesh) : - PtrList<option>(), + PtrList<fv::option>(), mesh_(mesh), checkTimeIndex_(mesh_.time().startTimeIndex() + 2) {} diff --git a/src/finiteVolume/cfdTools/general/fvOptions/fvOptionList.H b/src/finiteVolume/cfdTools/general/fvOptions/fvOptionList.H index a6cd374fae4c438968738b671d484339535a8798..1cbca46098bc8e6a50a2f3a905e3197bb4e39f26 100644 --- a/src/finiteVolume/cfdTools/general/fvOptions/fvOptionList.H +++ b/src/finiteVolume/cfdTools/general/fvOptions/fvOptionList.H @@ -69,7 +69,7 @@ namespace fv class optionList : - public PtrList<option> + public PtrList<fv::option> { protected: diff --git a/src/fvOptions/cellSetOption/cellSetOption.H b/src/fvOptions/cellSetOption/cellSetOption.H index 32f1609518e7aaa00fc24f02932c08b9debf5c0f..02b2931fdc908451016d44fd2a14908a973e00cd 100644 --- a/src/fvOptions/cellSetOption/cellSetOption.H +++ b/src/fvOptions/cellSetOption/cellSetOption.H @@ -117,7 +117,7 @@ namespace fv class cellSetOption : - public option + public fv::option { public: diff --git a/src/fvOptions/interRegionOption/interRegionOption.H b/src/fvOptions/interRegionOption/interRegionOption.H index 3496f0b70c5bcea40f8060f994c6b31dd928250f..315f9808b726aa90713029330b3821aedff6442b 100644 --- a/src/fvOptions/interRegionOption/interRegionOption.H +++ b/src/fvOptions/interRegionOption/interRegionOption.H @@ -87,7 +87,7 @@ namespace fv class interRegionOption : - public option + public fv::option { protected: diff --git a/src/fvOptions/sources/derived/buoyancyEnergy/buoyancyEnergy.H b/src/fvOptions/sources/derived/buoyancyEnergy/buoyancyEnergy.H index d40d1ed239977ab28955ee2054aa3e814e1347c7..361853bd8e7c8c95fab3b83ddd2e9255c991da40 100644 --- a/src/fvOptions/sources/derived/buoyancyEnergy/buoyancyEnergy.H +++ b/src/fvOptions/sources/derived/buoyancyEnergy/buoyancyEnergy.H @@ -118,7 +118,7 @@ namespace fv class buoyancyEnergy : - public option + public fv::option { // Private Data diff --git a/src/fvOptions/sources/derived/buoyancyForce/buoyancyForce.H b/src/fvOptions/sources/derived/buoyancyForce/buoyancyForce.H index 0ef9438b85bce14f47118119a09a956528a1379c..07f785ab337f983a041d962f2155489e4e5a01ce 100644 --- a/src/fvOptions/sources/derived/buoyancyForce/buoyancyForce.H +++ b/src/fvOptions/sources/derived/buoyancyForce/buoyancyForce.H @@ -110,7 +110,7 @@ namespace fv class buoyancyForce : - public option + public fv::option { // Private Data diff --git a/src/fvOptions/sources/derived/jouleHeatingSource/jouleHeatingSource.H b/src/fvOptions/sources/derived/jouleHeatingSource/jouleHeatingSource.H index b2ea0e06ad076ed7f521dff0a4e70287ac5a2287..d748dcdab84dec42084d8e866dc58ba50a7793ce 100644 --- a/src/fvOptions/sources/derived/jouleHeatingSource/jouleHeatingSource.H +++ b/src/fvOptions/sources/derived/jouleHeatingSource/jouleHeatingSource.H @@ -175,7 +175,7 @@ namespace fv class jouleHeatingSource : - public option + public fv::option { // Private Data diff --git a/src/fvOptions/sources/derived/multiphaseStabilizedTurbulence/multiphaseStabilizedTurbulence.H b/src/fvOptions/sources/derived/multiphaseStabilizedTurbulence/multiphaseStabilizedTurbulence.H index 4d0e7db9e7564a14f18699735146f24789f34392..033669bfd4fa0ab9e9ccdf149f839ed5c9e51ca2 100644 --- a/src/fvOptions/sources/derived/multiphaseStabilizedTurbulence/multiphaseStabilizedTurbulence.H +++ b/src/fvOptions/sources/derived/multiphaseStabilizedTurbulence/multiphaseStabilizedTurbulence.H @@ -133,7 +133,7 @@ namespace fv class multiphaseStabilizedTurbulence : - public option + public fv::option { // Private Data diff --git a/src/fvOptions/sources/derived/phaseLimitStabilization/PhaseLimitStabilization.H b/src/fvOptions/sources/derived/phaseLimitStabilization/PhaseLimitStabilization.H index 8ea0073ba4c3d80d965d338a64007aff64718a21..234d7d7caf361e68508dd1e594b652a35eca5a3f 100644 --- a/src/fvOptions/sources/derived/phaseLimitStabilization/PhaseLimitStabilization.H +++ b/src/fvOptions/sources/derived/phaseLimitStabilization/PhaseLimitStabilization.H @@ -108,7 +108,7 @@ namespace fv template<class Type> class PhaseLimitStabilization : - public option + public fv::option { // Private Data diff --git a/src/fvOptions/sources/derived/tabulatedAccelerationSource/tabulatedAccelerationSource.H b/src/fvOptions/sources/derived/tabulatedAccelerationSource/tabulatedAccelerationSource.H index 6541bb805bd17beffd8afb703b919fa35afe97c2..5a6007bb0929d3b4cc7c4076f090ff1e94f00eda 100644 --- a/src/fvOptions/sources/derived/tabulatedAccelerationSource/tabulatedAccelerationSource.H +++ b/src/fvOptions/sources/derived/tabulatedAccelerationSource/tabulatedAccelerationSource.H @@ -87,7 +87,7 @@ namespace fv class tabulatedAccelerationSource : - public option + public fv::option { protected: diff --git a/src/fvOptions/sources/derived/viscousDissipation/viscousDissipation.H b/src/fvOptions/sources/derived/viscousDissipation/viscousDissipation.H index 805bf12c11edf072ce24bfa2e857846904b19b7b..b8740163c52442611b9e26d1e876f2f73cf94a5a 100644 --- a/src/fvOptions/sources/derived/viscousDissipation/viscousDissipation.H +++ b/src/fvOptions/sources/derived/viscousDissipation/viscousDissipation.H @@ -111,7 +111,7 @@ namespace fv class viscousDissipation : - public option + public fv::option { // Private Data diff --git a/src/parallel/decompose/Allwclean b/src/parallel/decompose/Allwclean index e6b78d10c682bc6b2c5d0fd61bce888bcf751f83..a0a7d6335f81ae79bf8e0fc50b0f79f8935bfb18 100755 --- a/src/parallel/decompose/Allwclean +++ b/src/parallel/decompose/Allwclean @@ -8,6 +8,7 @@ wclean kahipDecomp wclean scotchDecomp wclean decompositionMethods wclean decompose +wclean faDecompose ./Allwclean-mpi diff --git a/src/parallel/decompose/Allwmake b/src/parallel/decompose/Allwmake index c9bc6b610af90330d172de8f6460a64e9199adf7..b1681aa0b7f03d08c166e47ea65824333ada3cbc 100755 --- a/src/parallel/decompose/Allwmake +++ b/src/parallel/decompose/Allwmake @@ -12,6 +12,7 @@ export FOAM_EXT_LIBBIN wmake $targetType decompositionMethods wmake $targetType decompose +wmake $targetType faDecompose if have_kahip then diff --git a/src/parallel/decompose/decompose/Make/files b/src/parallel/decompose/decompose/Make/files index 225a27dfad890ce4248954ff1be2aca2c4dfbf16..e55de05d2e5d5a56b14b936672d4c578a1e8b379 100644 --- a/src/parallel/decompose/decompose/Make/files +++ b/src/parallel/decompose/decompose/Make/files @@ -1,5 +1,8 @@ decompositionInformation.C decompositionModel.C + +dimFieldDecomposer.C fvFieldDecomposer.C +pointFieldDecomposer.C LIB = $(FOAM_LIBBIN)/libdecompose diff --git a/applications/utilities/parallelProcessing/decomposePar/dimFieldDecomposer.C b/src/parallel/decompose/decompose/dimFieldDecomposer.C similarity index 82% rename from applications/utilities/parallelProcessing/decomposePar/dimFieldDecomposer.C rename to src/parallel/decompose/decompose/dimFieldDecomposer.C index 391d2bf5c8576948fc7dfb8cb8c6b78fd9aad365..dbef4df61ed9c78126677e6f9ffb8d5d0196e1cd 100644 --- a/applications/utilities/parallelProcessing/decomposePar/dimFieldDecomposer.C +++ b/src/parallel/decompose/decompose/dimFieldDecomposer.C @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011 OpenFOAM Foundation + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -27,27 +28,30 @@ License #include "dimFieldDecomposer.H" - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::dimFieldDecomposer::dimFieldDecomposer ( - const fvMesh& completeMesh, const fvMesh& procMesh, - const labelList& faceAddressing, const labelList& cellAddressing ) : - completeMesh_(completeMesh), procMesh_(procMesh), - faceAddressing_(faceAddressing), cellAddressing_(cellAddressing) {} -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // - -Foam::dimFieldDecomposer::~dimFieldDecomposer() +Foam::dimFieldDecomposer::dimFieldDecomposer +( + const fvMesh& /* unused: completeMesh */, + const fvMesh& procMesh, + const labelList& /* unused: faceAddressing */, + const labelList& cellAddressing +) +: + procMesh_(procMesh), + //UNUSED: faceAddressing_(faceAddressing), + cellAddressing_(cellAddressing) {} diff --git a/applications/utilities/parallelProcessing/decomposePar/dimFieldDecomposer.H b/src/parallel/decompose/decompose/dimFieldDecomposer.H similarity index 77% rename from applications/utilities/parallelProcessing/decomposePar/dimFieldDecomposer.H rename to src/parallel/decompose/decompose/dimFieldDecomposer.H index 26710ce5e8aad31991c096d1bab0b32198bad583..ec80c621cd9cb8e28bd6cd80fb93d0c72e82ba10 100644 --- a/applications/utilities/parallelProcessing/decomposePar/dimFieldDecomposer.H +++ b/src/parallel/decompose/decompose/dimFieldDecomposer.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -31,7 +32,7 @@ Description SourceFiles dimFieldDecomposer.C - dimFieldDecomposerDecomposeFields.C + dimFieldDecomposerFields.C \*---------------------------------------------------------------------------*/ @@ -46,69 +47,68 @@ SourceFiles namespace Foam { -class IOobjectList; - /*---------------------------------------------------------------------------*\ Class fvFieldDecomposer Declaration \*---------------------------------------------------------------------------*/ class dimFieldDecomposer { -private: - - // Private data - - //- Reference to complete mesh - const fvMesh& completeMesh_; + // Private Data //- Reference to processor mesh const fvMesh& procMesh_; //- Reference to face addressing - const labelList& faceAddressing_; + //UNUSED: const labelList& faceAddressing_; //- Reference to cell addressing const labelList& cellAddressing_; - // Private Member Functions - - //- No copy construct - dimFieldDecomposer(const dimFieldDecomposer&) = delete; +public: - //- No copy assignment - void operator=(const dimFieldDecomposer&) = delete; + //- No copy construct + dimFieldDecomposer(const dimFieldDecomposer&) = delete; + //- No copy assignment + void operator=(const dimFieldDecomposer&) = delete; -public: // Constructors - //- Construct from components + //- Construct from minimal components + dimFieldDecomposer + ( + const fvMesh& procMesh, + const labelList& cellAddressing + ); + + //- Construct from components with API as per fvFieldDecomposer dimFieldDecomposer ( - const fvMesh& completeMesh, + const fvMesh& completeMesh, //!< unused const fvMesh& procMesh, - const labelList& faceAddressing, + const labelList& faceAddressing, //!< unused const labelList& cellAddressing ); //- Destructor - ~dimFieldDecomposer(); + ~dimFieldDecomposer() = default; // Member Functions //- Decompose field template<class Type> - tmp<DimensionedField<Type, volMesh>> decomposeField + tmp<DimensionedField<Type, volMesh>> + decomposeField ( const DimensionedField<Type, volMesh>& field ) const; - //- Decompose llist of fields + //- Decompose list of fields template<class GeoField> void decomposeFields(const PtrList<GeoField>& fields) const; }; @@ -121,7 +121,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "dimFieldDecomposerDecomposeFields.C" + #include "dimFieldDecomposerFields.C" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/applications/utilities/parallelProcessing/decomposePar/dimFieldDecomposerDecomposeFields.C b/src/parallel/decompose/decompose/dimFieldDecomposerFields.C similarity index 91% rename from applications/utilities/parallelProcessing/decomposePar/dimFieldDecomposerDecomposeFields.C rename to src/parallel/decompose/decompose/dimFieldDecomposerFields.C index 2d4c2bf98784953d334e81df0d7a2f5b6323b8cf..7da59d8d1964a9490cfae0cc903558c44dff3981 100644 --- a/applications/utilities/parallelProcessing/decomposePar/dimFieldDecomposerDecomposeFields.C +++ b/src/parallel/decompose/decompose/dimFieldDecomposerFields.C @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -40,9 +41,8 @@ Foam::dimFieldDecomposer::decomposeField Field<Type> mappedField(field, cellAddressing_); // Create the field for the processor - return tmp<DimensionedField<Type, volMesh>> - ( - new DimensionedField<Type, volMesh> + return + tmp<DimensionedField<Type, volMesh>>::New ( IOobject ( @@ -55,9 +55,8 @@ Foam::dimFieldDecomposer::decomposeField ), procMesh_, field.dimensions(), - mappedField - ) - ); + std::move(mappedField) + ); } @@ -67,9 +66,9 @@ void Foam::dimFieldDecomposer::decomposeFields const PtrList<GeoField>& fields ) const { - forAll(fields, fieldi) + for (const auto& fld : fields) { - decomposeField(fields[fieldi])().write(); + decomposeField(fld)().write(); } } diff --git a/src/parallel/decompose/decompose/fvFieldDecomposer.C b/src/parallel/decompose/decompose/fvFieldDecomposer.C index 8cc5acdf68396132be9dad392e489a6b582ac20c..61ade1be3bc6a567abdbe8e110407d727dfc432e 100644 --- a/src/parallel/decompose/decompose/fvFieldDecomposer.C +++ b/src/parallel/decompose/decompose/fvFieldDecomposer.C @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -27,7 +28,6 @@ License #include "fvFieldDecomposer.H" - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::fvFieldDecomposer::patchFieldDecomposer::patchFieldDecomposer @@ -49,21 +49,19 @@ Foam::fvFieldDecomposer::patchFieldDecomposer::patchFieldDecomposer Foam::fvFieldDecomposer::processorVolPatchFieldDecomposer:: processorVolPatchFieldDecomposer ( - const fvMesh& mesh, + const labelUList& owner, // == mesh.faceOwner() + const labelUList& neigh, // == mesh.faceNeighbour() const labelUList& addressingSlice ) : directAddressing_(addressingSlice.size()) { - const labelList& own = mesh.faceOwner(); - const labelList& neighb = mesh.faceNeighbour(); - forAll(directAddressing_, i) { // Subtract one to align addressing. label ai = mag(addressingSlice[i]) - 1; - if (ai < neighb.size()) + if (ai < neigh.size()) { // This is a regular face. it has been an internal face // of the original mesh and now it has become a face @@ -73,11 +71,11 @@ processorVolPatchFieldDecomposer if (addressingSlice[i] >= 0) { // I have the owner so use the neighbour value - directAddressing_[i] = neighb[ai]; + directAddressing_[i] = neigh[ai]; } else { - directAddressing_[i] = own[ai]; + directAddressing_[i] = owner[ai]; } } else @@ -88,12 +86,28 @@ processorVolPatchFieldDecomposer // up the different (face) list of data), so I will // just grab the value from the owner cell - directAddressing_[i] = own[ai]; + directAddressing_[i] = owner[ai]; } } } +Foam::fvFieldDecomposer::processorVolPatchFieldDecomposer:: +processorVolPatchFieldDecomposer +( + const fvMesh& mesh, + const labelUList& addressingSlice +) +: + processorVolPatchFieldDecomposer + ( + mesh.faceOwner(), + mesh.faceNeighbour(), + addressingSlice + ) +{} + + Foam::fvFieldDecomposer::processorSurfacePatchFieldDecomposer:: processorSurfacePatchFieldDecomposer ( @@ -105,8 +119,8 @@ processorSurfacePatchFieldDecomposer { forAll(addressing_, i) { - addressing_[i].setSize(1); - weights_[i].setSize(1); + addressing_[i].resize(1); + weights_[i].resize(1); addressing_[i][0] = mag(addressingSlice[i]) - 1; weights_[i][0] = 1; @@ -116,31 +130,113 @@ processorSurfacePatchFieldDecomposer Foam::fvFieldDecomposer::fvFieldDecomposer ( - const fvMesh& completeMesh, + const Foam::zero, const fvMesh& procMesh, const labelList& faceAddressing, const labelList& cellAddressing, const labelList& boundaryAddressing ) : - completeMesh_(completeMesh), procMesh_(procMesh), faceAddressing_(faceAddressing), cellAddressing_(cellAddressing), boundaryAddressing_(boundaryAddressing), - patchFieldDecomposerPtrs_(procMesh_.boundary().size()), - processorVolPatchFieldDecomposerPtrs_(procMesh_.boundary().size()), - processorSurfacePatchFieldDecomposerPtrs_(procMesh_.boundary().size()), - faceSign_(procMesh_.boundary().size()) + // Mappers + patchFieldDecomposerPtrs_(), + processorVolPatchFieldDecomposerPtrs_(), + processorSurfacePatchFieldDecomposerPtrs_(), + faceSign_() +{} + + +Foam::fvFieldDecomposer::fvFieldDecomposer +( + const fvMesh& completeMesh, + const fvMesh& procMesh, + const labelList& faceAddressing, + const labelList& cellAddressing, + const labelList& boundaryAddressing +) +: + fvFieldDecomposer + ( + zero{}, + procMesh, + faceAddressing, + cellAddressing, + boundaryAddressing + ) { + reset(completeMesh); +} + + +Foam::fvFieldDecomposer::fvFieldDecomposer +( + const List<labelRange>& boundaryRanges, + const labelUList& faceOwner, + const labelUList& faceNeighbour, + + const fvMesh& procMesh, + const labelList& faceAddressing, + const labelList& cellAddressing, + const labelList& boundaryAddressing +) +: + fvFieldDecomposer + ( + zero{}, + procMesh, + faceAddressing, + cellAddressing, + boundaryAddressing + ) +{ + reset(boundaryRanges, faceOwner, faceNeighbour); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::fvFieldDecomposer::empty() const +{ + return patchFieldDecomposerPtrs_.empty(); +} + + +void Foam::fvFieldDecomposer::clear() +{ + patchFieldDecomposerPtrs_.clear(); + processorVolPatchFieldDecomposerPtrs_.clear(); + processorSurfacePatchFieldDecomposerPtrs_.clear(); + faceSign_.clear(); +} + + +void Foam::fvFieldDecomposer::reset +( + const List<labelRange>& boundaryRanges, + const labelUList& faceOwner, + const labelUList& faceNeighbour +) +{ + clear(); + const label nMappers = procMesh_.boundary().size(); + patchFieldDecomposerPtrs_.resize(nMappers); + processorVolPatchFieldDecomposerPtrs_.resize(nMappers); + processorSurfacePatchFieldDecomposerPtrs_.resize(nMappers); + faceSign_.resize(nMappers); + forAll(boundaryAddressing_, patchi) { + const label oldPatchi = boundaryAddressing_[patchi]; const fvPatch& fvp = procMesh_.boundary()[patchi]; + const labelSubList localPatchSlice(fvp.patchSlice(faceAddressing_)); if ( - boundaryAddressing_[patchi] >= 0 - && !isA<processorLduInterface>(procMesh.boundary()[patchi]) + oldPatchi >= 0 + && !isA<processorLduInterface>(procMesh_.boundary()[patchi]) ) { patchFieldDecomposerPtrs_.set @@ -148,11 +244,8 @@ Foam::fvFieldDecomposer::fvFieldDecomposer patchi, new patchFieldDecomposer ( - fvp.patchSlice(faceAddressing_), - completeMesh_.boundaryMesh() - [ - boundaryAddressing_[patchi] - ].start() + localPatchSlice, + boundaryRanges[oldPatchi].start() ) ); } @@ -163,8 +256,9 @@ Foam::fvFieldDecomposer::fvFieldDecomposer patchi, new processorVolPatchFieldDecomposer ( - completeMesh_, - fvp.patchSlice(faceAddressing_) + faceOwner, + faceNeighbour, + localPatchSlice ) ); @@ -173,28 +267,21 @@ Foam::fvFieldDecomposer::fvFieldDecomposer patchi, new processorSurfacePatchFieldDecomposer ( - static_cast<const labelUList&> - ( - fvp.patchSlice - ( - faceAddressing_ - ) - ) + static_cast<const labelUList&>(localPatchSlice) ) ); faceSign_.set ( patchi, - new scalarField(fvp.patchSlice(faceAddressing_).size()) + new scalarField(localPatchSlice.size()) ); { - const SubList<label> fa = fvp.patchSlice(faceAddressing_); scalarField& s = faceSign_[patchi]; forAll(s, i) { - s[i] = sign(fa[i]); + s[i] = sign(localPatchSlice[i]); } } } @@ -202,10 +289,74 @@ Foam::fvFieldDecomposer::fvFieldDecomposer } -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // +void Foam::fvFieldDecomposer::reset(const fvMesh& completeMesh) +{ + clear(); + const label nMappers = procMesh_.boundary().size(); + patchFieldDecomposerPtrs_.resize(nMappers); + processorVolPatchFieldDecomposerPtrs_.resize(nMappers); + processorSurfacePatchFieldDecomposerPtrs_.resize(nMappers); + faceSign_.resize(nMappers); -Foam::fvFieldDecomposer::~fvFieldDecomposer() -{} + forAll(boundaryAddressing_, patchi) + { + const label oldPatchi = boundaryAddressing_[patchi]; + const fvPatch& fvp = procMesh_.boundary()[patchi]; + const labelSubList localPatchSlice(fvp.patchSlice(faceAddressing_)); + + if + ( + oldPatchi >= 0 + && !isA<processorLduInterface>(procMesh_.boundary()[patchi]) + ) + { + patchFieldDecomposerPtrs_.set + ( + patchi, + new patchFieldDecomposer + ( + localPatchSlice, + completeMesh.boundaryMesh()[oldPatchi].start() + ) + ); + } + else + { + processorVolPatchFieldDecomposerPtrs_.set + ( + patchi, + new processorVolPatchFieldDecomposer + ( + completeMesh, + localPatchSlice + ) + ); + + processorSurfacePatchFieldDecomposerPtrs_.set + ( + patchi, + new processorSurfacePatchFieldDecomposer + ( + static_cast<const labelUList&>(localPatchSlice) + ) + ); + + faceSign_.set + ( + patchi, + new scalarField(localPatchSlice.size()) + ); + + { + scalarField& s = faceSign_[patchi]; + forAll(s, i) + { + s[i] = sign(localPatchSlice[i]); + } + } + } + } +} // ************************************************************************* // diff --git a/src/parallel/decompose/decompose/fvFieldDecomposer.H b/src/parallel/decompose/decompose/fvFieldDecomposer.H index 34a0904a580e0abac6d21b001a1021ecd2f7010a..a0dab98a4df0df00256937431aba7c6037643520 100644 --- a/src/parallel/decompose/decompose/fvFieldDecomposer.H +++ b/src/parallel/decompose/decompose/fvFieldDecomposer.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -31,7 +32,7 @@ Description SourceFiles fvFieldDecomposer.C - fvFieldDecomposerDecomposeFields.C + fvFieldDecomposerFields.C \*---------------------------------------------------------------------------*/ @@ -47,8 +48,6 @@ SourceFiles namespace Foam { -class IOobjectList; - /*---------------------------------------------------------------------------*\ Class fvFieldDecomposer Declaration \*---------------------------------------------------------------------------*/ @@ -62,7 +61,7 @@ public: : public fvPatchFieldMapper { - // Private data + // Private Data labelList directAddressing_; @@ -78,7 +77,7 @@ public: ); - // Member functions + // Member Functions label size() const { @@ -110,13 +109,21 @@ public: : public fvPatchFieldMapper { - // Private data + // Private Data labelList directAddressing_; public: - //- Construct given addressing + //- Construct addressing from details + processorVolPatchFieldDecomposer + ( + const labelUList& faceOwner, + const labelUList& faceNeigbour, + const labelUList& addressingSlice + ); + + //- Construct given addressing from complete mesh processorVolPatchFieldDecomposer ( const fvMesh& mesh, @@ -124,7 +131,7 @@ public: ); - // Member functions + // Member Functions label size() const { @@ -199,10 +206,7 @@ public: private: - // Private data - - //- Reference to complete mesh - const fvMesh& completeMesh_; + // Private Data //- Reference to processor mesh const fvMesh& procMesh_; @@ -225,24 +229,31 @@ private: PtrList<processorSurfacePatchFieldDecomposer> processorSurfacePatchFieldDecomposerPtrs_; - PtrList<scalarField> faceSign_; - // Private Member Functions - - //- No copy construct - fvFieldDecomposer(const fvFieldDecomposer&) = delete; +public: - //- No copy assignment - void operator=(const fvFieldDecomposer&) = delete; + //- No copy construct + fvFieldDecomposer(const fvFieldDecomposer&) = delete; + //- No copy assignment + void operator=(const fvFieldDecomposer&) = delete; -public: // Constructors - //- Construct from components + //- Construct without mappers, added later with reset() + fvFieldDecomposer + ( + const Foam::zero, + const fvMesh& procMesh, + const labelList& faceAddressing, + const labelList& cellAddressing, + const labelList& boundaryAddressing + ); + + //- Construct from components using information from the complete mesh fvFieldDecomposer ( const fvMesh& completeMesh, @@ -252,13 +263,56 @@ public: const labelList& boundaryAddressing ); + //- Construct from components without the complete mesh + fvFieldDecomposer + ( + // Information about the complete mesh + const List<labelRange>& boundaryRanges, + const labelUList& faceOwner, + const labelUList& faceNeigbour, + + // Addressing for processor mesh + const fvMesh& procMesh, + const labelList& faceAddressing, + const labelList& cellAddressing, + const labelList& boundaryAddressing + ); + //- Destructor - ~fvFieldDecomposer(); + ~fvFieldDecomposer() = default; // Member Functions + //- True if no mappers have been allocated + bool empty() const; + + //- Remove all mappers + void clear(); + + //- Reset mappers using information from the complete mesh + void reset(const fvMesh& completeMesh); + + //- Reset mapper using information about the complete mesh + void reset + ( + const List<labelRange>& boundaryRanges, + const labelUList& faceOwner, + const labelUList& faceNeigbour + ); + + + // Mapping + + //- Decompose internal field + template<class Type> + tmp<DimensionedField<Type, volMesh>> + decomposeField + ( + const DimensionedField<Type, volMesh>& field + ) const; + //- Decompose volume field template<class Type> tmp<GeometricField<Type, fvPatchField, volMesh>> @@ -276,6 +330,7 @@ public: const GeometricField<Type, fvsPatchField, surfaceMesh>& field ) const; + //- Decompose list of fields template<class GeoField> void decomposeFields(const PtrList<GeoField>& fields) const; }; @@ -288,7 +343,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "fvFieldDecomposerDecomposeFields.C" + #include "fvFieldDecomposerFields.C" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/parallel/decompose/decompose/fvFieldDecomposerDecomposeFields.C b/src/parallel/decompose/decompose/fvFieldDecomposerFields.C similarity index 92% rename from src/parallel/decompose/decompose/fvFieldDecomposerDecomposeFields.C rename to src/parallel/decompose/decompose/fvFieldDecomposerFields.C index 2e9bcd9a5a5b6134dd375505a1c32dc6faf2591d..05c730a27dd30eb42432c250b442a9803069f028 100644 --- a/src/parallel/decompose/decompose/fvFieldDecomposerDecomposeFields.C +++ b/src/parallel/decompose/decompose/fvFieldDecomposerFields.C @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -34,6 +35,36 @@ License // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +template<class Type> +Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh>> +Foam::fvFieldDecomposer::decomposeField +( + const DimensionedField<Type, volMesh>& field +) const +{ + // Create and map the internal field values + Field<Type> mappedField(field, cellAddressing_); + + // Create the field for the processor + return + tmp<DimensionedField<Type, volMesh>>::New + ( + IOobject + ( + field.name(), + procMesh_.time().timeName(), + procMesh_, + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ), + procMesh_, + field.dimensions(), + std::move(mappedField) + ); +} + + template<class Type> Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>> Foam::fvFieldDecomposer::decomposeField @@ -338,9 +369,9 @@ void Foam::fvFieldDecomposer::decomposeFields const PtrList<GeoField>& fields ) const { - forAll(fields, fieldi) + for (const auto& fld : fields) { - decomposeField(fields[fieldi])().write(); + decomposeField(fld)().write(); } } diff --git a/applications/utilities/parallelProcessing/decomposePar/pointFieldDecomposer.C b/src/parallel/decompose/decompose/pointFieldDecomposer.C similarity index 72% rename from applications/utilities/parallelProcessing/decomposePar/pointFieldDecomposer.C rename to src/parallel/decompose/decompose/pointFieldDecomposer.C index a4c40ee980697cf2161506376bc9b923ae1b9603..4b1a29a1c51e70c67001127875068bd1dc2f5b25 100644 --- a/applications/utilities/parallelProcessing/decomposePar/pointFieldDecomposer.C +++ b/src/parallel/decompose/decompose/pointFieldDecomposer.C @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -78,51 +79,82 @@ Foam::pointFieldDecomposer::patchFieldDecomposer::patchFieldDecomposer Foam::pointFieldDecomposer::pointFieldDecomposer ( - const pointMesh& completeMesh, + const Foam::zero, const pointMesh& procMesh, const labelList& pointAddressing, const labelList& boundaryAddressing ) : - completeMesh_(completeMesh), procMesh_(procMesh), pointAddressing_(pointAddressing), boundaryAddressing_(boundaryAddressing), - patchFieldDecomposerPtrs_ + // Mappers + patchFieldDecomposerPtrs_() +{} + + +Foam::pointFieldDecomposer::pointFieldDecomposer +( + const pointMesh& completeMesh, + const pointMesh& procMesh, + const labelList& pointAddressing, + const labelList& boundaryAddressing +) +: + pointFieldDecomposer ( - procMesh_.boundary().size(), - static_cast<patchFieldDecomposer*>(nullptr) + zero{}, + procMesh, + pointAddressing, + boundaryAddressing ) { - forAll(boundaryAddressing_, patchi) - { - if (boundaryAddressing_[patchi] >= 0) - { - patchFieldDecomposerPtrs_[patchi] = new patchFieldDecomposer - ( - completeMesh_.boundary()[boundaryAddressing_[patchi]], - procMesh_.boundary()[patchi], - pointAddressing_ - ); - } - } + reset(completeMesh); } -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::pointFieldDecomposer::empty() const +{ + return patchFieldDecomposerPtrs_.empty(); +} + -Foam::pointFieldDecomposer::~pointFieldDecomposer() +void Foam::pointFieldDecomposer::clear() { - forAll(patchFieldDecomposerPtrs_, patchi) + patchFieldDecomposerPtrs_.clear(); +} + + +void Foam::pointFieldDecomposer::reset +( + const pointMesh& completeMesh +) +{ + clear(); + const label nMappers = procMesh_.boundary().size(); + patchFieldDecomposerPtrs_.resize(nMappers); + + forAll(boundaryAddressing_, patchi) { - if (patchFieldDecomposerPtrs_[patchi]) + const label oldPatchi = boundaryAddressing_[patchi]; + + if (oldPatchi >= 0) { - delete patchFieldDecomposerPtrs_[patchi]; + patchFieldDecomposerPtrs_.set + ( + patchi, + new patchFieldDecomposer + ( + completeMesh.boundary()[oldPatchi], + procMesh_.boundary()[patchi], + pointAddressing_ + ) + ); } } } -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - // ************************************************************************* // diff --git a/applications/utilities/parallelProcessing/decomposePar/pointFieldDecomposer.H b/src/parallel/decompose/decompose/pointFieldDecomposer.H similarity index 80% rename from applications/utilities/parallelProcessing/decomposePar/pointFieldDecomposer.H rename to src/parallel/decompose/decompose/pointFieldDecomposer.H index f59b4f33b200a2d91a53d94831b22aa70ee51e01..b4c730105998691ae90b6e36d19663376704e672 100644 --- a/applications/utilities/parallelProcessing/decomposePar/pointFieldDecomposer.H +++ b/src/parallel/decompose/decompose/pointFieldDecomposer.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -31,7 +32,7 @@ Description SourceFiles pointFieldDecomposer.C - pointFieldDecomposerDecomposeFields.C + pointFieldDecomposerFields.C \*---------------------------------------------------------------------------*/ @@ -48,12 +49,11 @@ namespace Foam { /*---------------------------------------------------------------------------*\ - Class pointFieldDecomposer Declaration + Class pointFieldDecomposer Declaration \*---------------------------------------------------------------------------*/ class pointFieldDecomposer { - public: //- Point patch field decomposer class @@ -107,10 +107,7 @@ public: private: - // Private data - - //- Reference to complete mesh - const pointMesh& completeMesh_; + // Private Data //- Reference to processor mesh const pointMesh& procMesh_; @@ -122,22 +119,29 @@ private: const labelList& boundaryAddressing_; //- List of patch field decomposers - List<patchFieldDecomposer*> patchFieldDecomposerPtrs_; - + PtrList<patchFieldDecomposer> patchFieldDecomposerPtrs_; - // Private Member Functions - //- No copy construct - pointFieldDecomposer(const pointFieldDecomposer&) = delete; +public: - //- No copy assignment - void operator=(const pointFieldDecomposer&) = delete; + //- No copy construct + pointFieldDecomposer(const pointFieldDecomposer&) = delete; + //- No copy assignment + void operator=(const pointFieldDecomposer&) = delete; -public: // Constructors + //- Construct without mappers, added later with reset() + pointFieldDecomposer + ( + const Foam::zero, + const pointMesh& procMesh, + const labelList& pointAddressing, + const labelList& boundaryAddressing + ); + //- Construct from components pointFieldDecomposer ( @@ -149,11 +153,23 @@ public: //- Destructor - ~pointFieldDecomposer(); + ~pointFieldDecomposer() = default; // Member Functions + //- True if no mappers have been allocated + bool empty() const; + + //- Remove all mappers + void clear(); + + //- Reset mappers using information from the complete mesh + void reset(const pointMesh& completeMesh); + + + // Mapping + //- Decompose point field template<class Type> tmp<GeometricField<Type, pointPatchField, pointMesh>> @@ -162,6 +178,7 @@ public: const GeometricField<Type, pointPatchField, pointMesh>& ) const; + //- Decompose list of fields template<class GeoField> void decomposeFields(const PtrList<GeoField>& fields) const; }; @@ -174,7 +191,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "pointFieldDecomposerDecomposeFields.C" + #include "pointFieldDecomposerFields.C" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/applications/utilities/parallelProcessing/decomposePar/pointFieldDecomposerDecomposeFields.C b/src/parallel/decompose/decompose/pointFieldDecomposerFields.C similarity index 90% rename from applications/utilities/parallelProcessing/decomposePar/pointFieldDecomposerDecomposeFields.C rename to src/parallel/decompose/decompose/pointFieldDecomposerFields.C index bdbea0cb43cfc04858064af1363c2c53d17eda69..aea3d5770808935587d72bcfaa7407a1da7a94cf 100644 --- a/applications/utilities/parallelProcessing/decomposePar/pointFieldDecomposerDecomposeFields.C +++ b/src/parallel/decompose/decompose/pointFieldDecomposerFields.C @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -46,7 +47,7 @@ Foam::pointFieldDecomposer::decomposeField // Create and map the patch field values forAll(boundaryAddressing_, patchi) { - if (patchFieldDecomposerPtrs_[patchi]) + if (patchFieldDecomposerPtrs_.set(patchi)) { patchFields.set ( @@ -56,7 +57,7 @@ Foam::pointFieldDecomposer::decomposeField field.boundaryField()[boundaryAddressing_[patchi]], procMesh_.boundary()[patchi], DimensionedField<Type, pointMesh>::null(), - *patchFieldDecomposerPtrs_[patchi] + patchFieldDecomposerPtrs_[patchi] ) ); } @@ -75,9 +76,8 @@ Foam::pointFieldDecomposer::decomposeField } // Create the field for the processor - return tmp<GeometricField<Type, pointPatchField, pointMesh>> - ( - new GeometricField<Type, pointPatchField, pointMesh> + return + tmp<GeometricField<Type, pointPatchField, pointMesh>>::New ( IOobject ( @@ -92,8 +92,7 @@ Foam::pointFieldDecomposer::decomposeField field.dimensions(), internalField, patchFields - ) - ); + ); } @@ -103,9 +102,9 @@ void Foam::pointFieldDecomposer::decomposeFields const PtrList<GeoField>& fields ) const { - forAll(fields, fieldi) + for (const auto& fld : fields) { - decomposeField(fields[fieldi])().write(); + decomposeField(fld)().write(); } } diff --git a/src/parallel/decompose/faDecompose/Make/files b/src/parallel/decompose/faDecompose/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..af2a87bf961960bbe653e2405ac209cb2f79a6fe --- /dev/null +++ b/src/parallel/decompose/faDecompose/Make/files @@ -0,0 +1,4 @@ +faFieldDecomposer.C +faMeshDecomposition.C + +LIB = $(FOAM_LIBBIN)/libfaDecompose diff --git a/src/parallel/decompose/faDecompose/Make/options b/src/parallel/decompose/faDecompose/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..b5d6f595dc9eb1057e7ddc89e0ed226d27e17007 --- /dev/null +++ b/src/parallel/decompose/faDecompose/Make/options @@ -0,0 +1,9 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/finiteArea/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ + +LIB_LIBS = \ + -lfiniteVolume \ + -lfiniteArea \ + -lmeshTools diff --git a/src/parallel/decompose/faDecompose/faFieldDecomposer.C b/src/parallel/decompose/faDecompose/faFieldDecomposer.C new file mode 100644 index 0000000000000000000000000000000000000000..f0966dfe47a7565a28b1a56cb6cec35798ead540 --- /dev/null +++ b/src/parallel/decompose/faDecompose/faFieldDecomposer.C @@ -0,0 +1,357 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2016-2017 Wikki Ltd + Copyright (C) 2021 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 "faFieldDecomposer.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::faFieldDecomposer::patchFieldDecomposer::patchFieldDecomposer +( + const label sizeBeforeMapping, + const labelUList& addressingSlice, + const label addressingOffset +) +: + sizeBeforeMapping_(sizeBeforeMapping), + directAddressing_(addressingSlice) +{ + forAll(directAddressing_, i) + { + // Subtract one to align addressing. + // directAddressing_[i] -= addressingOffset + 1; + // ZT, 12/Nov/2010 + directAddressing_[i] -= addressingOffset; + } +} + + +Foam::faFieldDecomposer::processorAreaPatchFieldDecomposer:: +processorAreaPatchFieldDecomposer +( + const label nTotalFaces, + const labelUList& owner, // == mesh.edgeOwner() + const labelUList& neigh, // == mesh.edgeNeighbour() + const labelUList& addressingSlice, + const scalarField& weights +) +: + sizeBeforeMapping_(nTotalFaces), + addressing_(addressingSlice.size()), + weights_(addressingSlice.size()) +{ + forAll(addressing_, i) + { + // Subtract one to align addressing. + label ai = addressingSlice[i]; +// label ai = mag(addressingSlice[i]) - 1; + + if (ai < neigh.size()) + { + // This is a regular edge. it has been an internal edge + // of the original mesh and now it has become a edge + // on the parallel boundary + addressing_[i].resize(2); + weights_[i].resize(2); + + addressing_[i][0] = owner[ai]; + addressing_[i][1] = neigh[ai]; + + if (ai < weights.size()) + { + // Edge weights exist/are usable + weights_[i][0] = weights[ai]; + weights_[i][1] = 1.0 - weights[ai]; + } + else + { + // No edge weights. use equal weighting + weights_[i][0] = 0.5; + weights_[i][1] = 0.5; + } + } + else + { + // This is a edge that used to be on a cyclic boundary + // but has now become a parallel patch edge. I cannot + // do the interpolation properly (I would need to look + // up the different (edge) list of data), so I will + // just grab the value from the owner face + + addressing_[i].resize(1); + weights_[i].resize(1); + + addressing_[i][0] = owner[ai]; + + weights_[i][0] = 1.0; + } + } +} + + +Foam::faFieldDecomposer::processorAreaPatchFieldDecomposer:: +processorAreaPatchFieldDecomposer +( + const faMesh& mesh, + const labelUList& addressingSlice +) +: + processorAreaPatchFieldDecomposer + ( + mesh.nFaces(), + mesh.edgeOwner(), + mesh.edgeNeighbour(), + addressingSlice, + mesh.weights().internalField() + ) +{} + + +Foam::faFieldDecomposer::processorEdgePatchFieldDecomposer:: +processorEdgePatchFieldDecomposer +( + label sizeBeforeMapping, + const labelUList& addressingSlice +) +: + sizeBeforeMapping_(sizeBeforeMapping), + addressing_(addressingSlice.size()), + weights_(addressingSlice.size()) +{ + forAll(addressing_, i) + { + addressing_[i].resize(1); + weights_[i].resize(1); + + addressing_[i][0] = mag(addressingSlice[i]) - 1; + weights_[i][0] = sign(addressingSlice[i]); + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::faFieldDecomposer::faFieldDecomposer +( + const Foam::zero, + const faMesh& procMesh, + const labelList& edgeAddressing, + const labelList& faceAddressing, + const labelList& boundaryAddressing +) +: + procMesh_(procMesh), + edgeAddressing_(edgeAddressing), + faceAddressing_(faceAddressing), + boundaryAddressing_(boundaryAddressing), + // Mappers + patchFieldDecomposerPtrs_(), + processorAreaPatchFieldDecomposerPtrs_(), + processorEdgePatchFieldDecomposerPtrs_() +{} + + +Foam::faFieldDecomposer::faFieldDecomposer +( + const faMesh& completeMesh, + const faMesh& procMesh, + const labelList& edgeAddressing, + const labelList& faceAddressing, + const labelList& boundaryAddressing +) +: + faFieldDecomposer + ( + zero{}, + procMesh, + edgeAddressing, + faceAddressing, + boundaryAddressing + ) +{ + reset(completeMesh); +} + + +Foam::faFieldDecomposer::faFieldDecomposer +( + const label nTotalFaces, + const List<labelRange>& boundaryRanges, + const labelUList& edgeOwner, + const labelUList& edgeNeigbour, + + const faMesh& procMesh, + const labelList& edgeAddressing, + const labelList& faceAddressing, + const labelList& boundaryAddressing +) +: + faFieldDecomposer + ( + zero{}, + procMesh, + edgeAddressing, + faceAddressing, + boundaryAddressing + ) +{ + reset(nTotalFaces, boundaryRanges, edgeOwner, edgeNeigbour); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::faFieldDecomposer::empty() const +{ + return patchFieldDecomposerPtrs_.empty(); +} + + +void Foam::faFieldDecomposer::clear() +{ + patchFieldDecomposerPtrs_.clear(); + processorAreaPatchFieldDecomposerPtrs_.clear(); + processorEdgePatchFieldDecomposerPtrs_.clear(); +} + + +void Foam::faFieldDecomposer::reset +( + const label nTotalFaces, + const List<labelRange>& boundaryRanges, + const labelUList& edgeOwner, + const labelUList& edgeNeigbour +) +{ + clear(); + const label nMappers = procMesh_.boundary().size(); + + patchFieldDecomposerPtrs_.resize(nMappers); + processorAreaPatchFieldDecomposerPtrs_.resize(nMappers); + processorEdgePatchFieldDecomposerPtrs_.resize(nMappers); + + forAll(boundaryAddressing_, patchi) + { + const label oldPatchi = boundaryAddressing_[patchi]; + const faPatch& fap = procMesh_.boundary()[patchi]; + const labelSubList localPatchSlice(fap.patchSlice(edgeAddressing_)); + + if (oldPatchi >= 0) + { + patchFieldDecomposerPtrs_.set + ( + patchi, + new patchFieldDecomposer + ( + boundaryRanges[oldPatchi].size(), + localPatchSlice, + boundaryRanges[oldPatchi].start() + ) + ); + } + else + { + processorAreaPatchFieldDecomposerPtrs_.set + ( + patchi, + new processorAreaPatchFieldDecomposer + ( + nTotalFaces, + edgeOwner, + edgeNeigbour, + localPatchSlice + ) + ); + + processorEdgePatchFieldDecomposerPtrs_.set + ( + patchi, + new processorEdgePatchFieldDecomposer + ( + procMesh_.boundary()[patchi].size(), + static_cast<const labelUList&>(localPatchSlice) + ) + ); + } + } +} + + +void Foam::faFieldDecomposer::reset(const faMesh& completeMesh) +{ + clear(); + const label nMappers = procMesh_.boundary().size(); + patchFieldDecomposerPtrs_.resize(nMappers); + processorAreaPatchFieldDecomposerPtrs_.resize(nMappers); + processorEdgePatchFieldDecomposerPtrs_.resize(nMappers); + + forAll(boundaryAddressing_, patchi) + { + const label oldPatchi = boundaryAddressing_[patchi]; + const faPatch& fap = procMesh_.boundary()[patchi]; + const labelSubList localPatchSlice(fap.patchSlice(edgeAddressing_)); + + if (oldPatchi >= 0) + { + patchFieldDecomposerPtrs_.set + ( + patchi, + new patchFieldDecomposer + ( + completeMesh.boundary()[oldPatchi].size(), + localPatchSlice, + completeMesh.boundary()[oldPatchi].start() + ) + ); + } + else + { + processorAreaPatchFieldDecomposerPtrs_.set + ( + patchi, + new processorAreaPatchFieldDecomposer + ( + completeMesh, + localPatchSlice + ) + ); + + processorEdgePatchFieldDecomposerPtrs_.set + ( + patchi, + new processorEdgePatchFieldDecomposer + ( + procMesh_.boundary()[patchi].size(), + static_cast<const labelUList&>(localPatchSlice) + ) + ); + } + } +} + + +// ************************************************************************* // diff --git a/applications/utilities/parallelProcessing/decomposePar/faFieldDecomposer.H b/src/parallel/decompose/faDecompose/faFieldDecomposer.H similarity index 70% rename from applications/utilities/parallelProcessing/decomposePar/faFieldDecomposer.H rename to src/parallel/decompose/faDecompose/faFieldDecomposer.H index 16928957bb5730f1bb129b60c07e8f6201b08c6d..a6ff53cb474e6d498dd0edc234066754b5ad1ee2 100644 --- a/applications/utilities/parallelProcessing/decomposePar/faFieldDecomposer.H +++ b/src/parallel/decompose/faDecompose/faFieldDecomposer.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -35,7 +36,7 @@ Author SourceFiles faFieldDecomposer.C - faFieldDecomposerDecomposeFields.C + faFieldDecomposerFields.C \*---------------------------------------------------------------------------*/ @@ -51,6 +52,7 @@ SourceFiles namespace Foam { +// Forward Declarations class IOobjectList; /*---------------------------------------------------------------------------*\ @@ -66,7 +68,7 @@ public: : public faPatchFieldMapper { - // Private data + // Private Data label sizeBeforeMapping_; labelList directAddressing_; @@ -118,7 +120,7 @@ public: : public faPatchFieldMapper { - // Private data + // Private Data label sizeBeforeMapping_; labelListList addressing_; @@ -126,7 +128,17 @@ public: public: - //- Construct given addressing + //- Construct addressing from details + processorAreaPatchFieldDecomposer + ( + const label nTotalFaces, + const labelUList& edgeOwner, + const labelUList& edgeNeigbour, + const labelUList& addressingSlice, + const scalarField& edgeWeights = scalarField::null() + ); + + //- Construct given addressing from complete mesh processorAreaPatchFieldDecomposer ( const faMesh& mesh, @@ -134,7 +146,7 @@ public: ); - // Member functions + // Member Functions label size() const { @@ -187,7 +199,7 @@ public: ); - // Member functions + // Member Functions label size() const { @@ -223,10 +235,7 @@ public: private: - // Private data - - //- Reference to complete mesh - const faMesh& completeMesh_; + // Private Data //- Reference to processor mesh const faMesh& procMesh_; @@ -241,12 +250,12 @@ private: const labelList& boundaryAddressing_; //- List of patch field decomposers - List<patchFieldDecomposer*> patchFieldDecomposerPtrs_; + PtrList<patchFieldDecomposer> patchFieldDecomposerPtrs_; - List<processorAreaPatchFieldDecomposer*> + PtrList<processorAreaPatchFieldDecomposer> processorAreaPatchFieldDecomposerPtrs_; - List<processorEdgePatchFieldDecomposer*> + PtrList<processorEdgePatchFieldDecomposer> processorEdgePatchFieldDecomposerPtrs_; @@ -263,7 +272,17 @@ public: // Constructors - //- Construct from components + //- Construct without mappers, added later with reset() + faFieldDecomposer + ( + const Foam::zero, + const faMesh& procMesh, + const labelList& edgeAddressing, + const labelList& faceAddressing, + const labelList& boundaryAddressing + ); + + //- Construct from components using information from the complete mesh faFieldDecomposer ( const faMesh& completeMesh, @@ -273,14 +292,50 @@ public: const labelList& boundaryAddressing ); + //- Construct from components without the complete mesh + faFieldDecomposer + ( + // Information about the complete mesh + const label nTotalFaces, + const List<labelRange>& boundaryRanges, + const labelUList& edgeOwner, + const labelUList& edgeNeigbour, + + // Addressing for processor mesh + const faMesh& procMesh, + const labelList& edgeAddressing, + const labelList& faceAddressing, + const labelList& boundaryAddressing + ); - // Destructor - ~faFieldDecomposer(); + //- Destructor + ~faFieldDecomposer() = default; // Member Functions + //- True if no mappers have been allocated + bool empty() const; + + //- Remove all mappers + void clear(); + + //- Reset mappers using information from the complete mesh + void reset(const faMesh& completeMesh); + + //- Reset mapper using information about the complete mesh + void reset + ( + const label nTotalFaces, + const List<labelRange>& boundaryRanges, + const labelUList& edgeOwner, + const labelUList& edgeNeigbour + ); + + + // Mapping + //- Decompose area field template<class Type> tmp<GeometricField<Type, faPatchField, areaMesh>> @@ -299,6 +354,33 @@ public: template<class GeoField> void decomposeFields(const PtrList<GeoField>& fields) const; + + + // Reading helpers + + //- Read the fields and hold on the pointer list + template + < + class Type, + template<class> class PatchField, + class GeoMesh + > + static void readFields + ( + const typename GeoMesh::Mesh& mesh, + const IOobjectList& objects, + PtrList<GeometricField<Type, PatchField, GeoMesh>>& fields, + const bool readOldTime + ); + + //- Read fields and hold on the pointer list + template<class Mesh, class GeoField> + static void readFields + ( + const Mesh& mesh, + const IOobjectList& objects, + PtrList<GeoField>& fields + ); }; @@ -309,7 +391,8 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository -# include "faFieldDecomposerDecomposeFields.C" + #include "faFieldDecomposerFields.C" + #include "faFieldDecomposerReadFields.C" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/applications/utilities/parallelProcessing/decomposePar/faFieldDecomposerDecomposeFields.C b/src/parallel/decompose/faDecompose/faFieldDecomposerFields.C similarity index 81% rename from applications/utilities/parallelProcessing/decomposePar/faFieldDecomposerDecomposeFields.C rename to src/parallel/decompose/faDecompose/faFieldDecomposerFields.C index ad0bebd67d83c03212d12631566de0d9ed020325..1b7eaea40f260387e5584a03cceab28d0af9af35 100644 --- a/applications/utilities/parallelProcessing/decomposePar/faFieldDecomposerDecomposeFields.C +++ b/src/parallel/decompose/faDecompose/faFieldDecomposerFields.C @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -29,16 +30,11 @@ License #include "processorFaPatchField.H" #include "processorFaePatchField.H" -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template<class Type> -tmp<GeometricField<Type, faPatchField, areaMesh>> -faFieldDecomposer::decomposeField +Foam::tmp<Foam::GeometricField<Type, Foam::faPatchField, Foam::areaMesh>> +Foam::faFieldDecomposer::decomposeField ( const GeometricField<Type, faPatchField, areaMesh>& field ) const @@ -51,17 +47,19 @@ faFieldDecomposer::decomposeField forAll(boundaryAddressing_, patchi) { - if (boundaryAddressing_[patchi] >= 0) + const label oldPatchi = boundaryAddressing_[patchi]; + + if (oldPatchi >= 0) { patchFields.set ( patchi, faPatchField<Type>::New ( - field.boundaryField()[boundaryAddressing_[patchi]], + field.boundaryField()[oldPatchi], procMesh_.boundary()[patchi], DimensionedField<Type, areaMesh>::null(), - *patchFieldDecomposerPtrs_[patchi] + patchFieldDecomposerPtrs_[patchi] ) ); } @@ -77,7 +75,7 @@ faFieldDecomposer::decomposeField Field<Type> ( field.internalField(), - *processorAreaPatchFieldDecomposerPtrs_[patchi] + processorAreaPatchFieldDecomposerPtrs_[patchi] ) ) ); @@ -85,9 +83,8 @@ faFieldDecomposer::decomposeField } // Create the field for the processor - return tmp<GeometricField<Type, faPatchField, areaMesh>> - ( - new GeometricField<Type, faPatchField, areaMesh> + return + tmp<GeometricField<Type, faPatchField, areaMesh>>::New ( IOobject ( @@ -101,14 +98,13 @@ faFieldDecomposer::decomposeField field.dimensions(), internalField, patchFields - ) - ); + ); } template<class Type> -tmp<GeometricField<Type, faePatchField, edgeMesh>> -faFieldDecomposer::decomposeField +Foam::tmp<Foam::GeometricField<Type, Foam::faePatchField, Foam::edgeMesh>> +Foam::faFieldDecomposer::decomposeField ( const GeometricField<Type, faePatchField, edgeMesh>& field ) const @@ -147,7 +143,7 @@ faFieldDecomposer::decomposeField forAll(field.boundaryField(), patchi) { - const Field<Type> & p = field.boundaryField()[patchi]; + const Field<Type>& p = field.boundaryField()[patchi]; const label patchStart = field.mesh().boundary()[patchi].start(); @@ -162,17 +158,19 @@ faFieldDecomposer::decomposeField forAll(boundaryAddressing_, patchi) { - if (boundaryAddressing_[patchi] >= 0) + const label oldPatchi = boundaryAddressing_[patchi]; + + if (oldPatchi >= 0) { patchFields.set ( patchi, faePatchField<Type>::New ( - field.boundaryField()[boundaryAddressing_[patchi]], + field.boundaryField()[oldPatchi], procMesh_.boundary()[patchi], DimensionedField<Type, edgeMesh>::null(), - *patchFieldDecomposerPtrs_[patchi] + patchFieldDecomposerPtrs_[patchi] ) ); } @@ -188,7 +186,7 @@ faFieldDecomposer::decomposeField Field<Type> ( allEdgeField, - *processorEdgePatchFieldDecomposerPtrs_[patchi] + processorEdgePatchFieldDecomposerPtrs_[patchi] ) ) ); @@ -196,9 +194,8 @@ faFieldDecomposer::decomposeField } // Create the field for the processor - return tmp<GeometricField<Type, faePatchField, edgeMesh>> - ( - new GeometricField<Type, faePatchField, edgeMesh> + return + tmp<GeometricField<Type, faePatchField, edgeMesh>>::New ( IOobject ( @@ -212,13 +209,12 @@ faFieldDecomposer::decomposeField field.dimensions(), internalField, patchFields - ) - ); + ); } template<class GeoField> -void faFieldDecomposer::decomposeFields +void Foam::faFieldDecomposer::decomposeFields ( const PtrList<GeoField>& fields ) const @@ -230,8 +226,4 @@ void faFieldDecomposer::decomposeFields } -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - // ************************************************************************* // diff --git a/src/parallel/decompose/faDecompose/faFieldDecomposerReadFields.C b/src/parallel/decompose/faDecompose/faFieldDecomposerReadFields.C new file mode 100644 index 0000000000000000000000000000000000000000..43529e3172db2ebe147e0495abb615011d178ef0 --- /dev/null +++ b/src/parallel/decompose/faDecompose/faFieldDecomposerReadFields.C @@ -0,0 +1,99 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2011-2016 OpenFOAM Foundation + Copyright (C) 2021 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 "faFieldDecomposer.H" +#include "GeometricField.H" +#include "IOobjectList.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template<class Type, template<class> class PatchField, class GeoMesh> +void Foam::faFieldDecomposer::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 GeoField + IOobjectList fieldObjects(objects.lookupClass<GeoField>()); + + /// // Remove the cellDist field + /// auto iter = fieldObjects.find("cellDist"); + /// if (iter.found()) + /// { + /// fieldObjects.erase(iter); + /// } + + // Use sorted set of names + // (different processors might read objects in different order) + const wordList masterNames(fieldObjects.sortedNames()); + + // Construct the fields + fields.resize(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::faFieldDecomposer::readFields +( + const Mesh& mesh, + const IOobjectList& objects, + PtrList<GeoField>& fields +) +{ + // Search list of objects for fields of type GeomField + IOobjectList fieldObjects(objects.lookupClass<GeoField>()); + + // Use sorted set of names + // (different processors might read objects in different order) + const wordList masterNames(fieldObjects.sortedNames()); + + // Construct the fields + fields.resize(masterNames.size()); + + forAll(masterNames, i) + { + const IOobject& io = *fieldObjects[masterNames[i]]; + + fields.set(i, new GeoField(io, mesh)); + } +} + + +// ************************************************************************* // diff --git a/applications/utilities/parallelProcessing/decomposePar/faMeshDecomposition.C b/src/parallel/decompose/faDecompose/faMeshDecomposition.C similarity index 92% rename from applications/utilities/parallelProcessing/decomposePar/faMeshDecomposition.C rename to src/parallel/decompose/faDecompose/faMeshDecomposition.C index c08daf4b48b1a669451956f34e77aa48c05f10c3..aecad1c65e80567c08445ebc74405ba52ff073d0 100644 --- a/applications/utilities/parallelProcessing/decomposePar/faMeshDecomposition.C +++ b/src/parallel/decompose/faDecompose/faMeshDecomposition.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd - Copyright (C) 2018-2019 OpenCFD Ltd. + Copyright (C) 2018-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -34,14 +34,16 @@ License #include "faMesh.H" #include "OSspecific.H" #include "Map.H" +#include "SLList.H" #include "globalMeshData.H" -#include "decompositionModel.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // void Foam::faMeshDecomposition::distributeFaces() { - Info<< "\nCalculating distribution of faces" << endl; + const word& polyMeshRegionName = mesh().name(); + + Info<< "\nCalculating distribution of finiteArea faces" << endl; cpuTime decompositionTime; @@ -58,7 +60,7 @@ void Foam::faMeshDecomposition::distributeFaces() ( IOobject ( - GeoMesh<polyMesh>::mesh_.name(), + polyMeshRegionName, processorDb.timeName(), processorDb ) @@ -160,22 +162,12 @@ void Foam::faMeshDecomposition::distributeFaces() Foam::faMeshDecomposition::faMeshDecomposition ( const fvMesh& mesh, - const fileName& decompDictFile + const label nProcessors, + const dictionary& params ) : faMesh(mesh), - decompDictFile_(decompDictFile), - nProcs_ - ( - decompositionMethod::nDomains - ( - decompositionModel::New - ( - mesh, - decompDictFile - ) - ) - ), + nProcs_(nProcessors), distributed_(false), hasGlobalFaceZones_(false), faceToProc_(nFaces()), @@ -193,55 +185,75 @@ Foam::faMeshDecomposition::faMeshDecomposition procNeighbourProcessors_(nProcs_), procProcessorPatchSize_(nProcs_), procProcessorPatchStartIndex_(nProcs_), - globallySharedPoints_(0), + globallySharedPoints_(), cyclicParallel_(false) { - const decompositionModel& model = decompositionModel::New - ( - mesh, - decompDictFile - ); - - model.readIfPresent("distributed", distributed_); - hasGlobalFaceZones_ = model.found("globalFaceZones"); + updateParameters(params); } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +void Foam::faMeshDecomposition::updateParameters +( + const dictionary& params +) +{ + params.readIfPresent("distributed", distributed_); + if (params.found("globalFaceZones")) + { + hasGlobalFaceZones_ = true; + } +} + + void Foam::faMeshDecomposition::decomposeMesh() { // Decide which cell goes to which processor distributeFaces(); + const word& polyMeshRegionName = mesh().name(); + Info<< "\nDistributing faces to processors" << endl; - // Memory management + labelList nLocalFaces(nProcs_, Zero); + + // Pass 1: determine local sizes, sanity check + + forAll(faceToProc_, facei) { - List<SLList<label>> procFaceList(nProcs()); + const label proci = faceToProc_[facei]; - forAll(faceToProc_, faceI) + if (proci < 0 || proci >= nProcs_) { - if (faceToProc_[faceI] >= nProcs()) - { - FatalErrorIn("Finite area mesh decomposition") - << "Impossible processor label " << faceToProc_[faceI] - << "for face " << faceI - << abort(FatalError); - } - else - { - procFaceList[faceToProc_[faceI]].append(faceI); - } + FatalErrorInFunction + << "Invalid processor label " << proci + << " for face " << facei << nl + << abort(FatalError); } - - // Convert linked lists into normal lists - forAll(procFaceList, procI) + else { - procFaceAddressing_[procI] = procFaceList[procI]; + ++nLocalFaces[proci]; } } + // Adjust lengths + forAll(nLocalFaces, proci) + { + procFaceAddressing_[proci].resize(nLocalFaces[proci]); + nLocalFaces[proci] = 0; // restart list + } + + // Pass 2: fill in local lists + forAll(faceToProc_, facei) + { + const label proci = faceToProc_[facei]; + const label localFacei = nLocalFaces[proci]; + ++nLocalFaces[proci]; + + procFaceAddressing_[proci][localFacei] = facei; + } + // Find processor mesh faceLabels and ... @@ -258,7 +270,7 @@ void Foam::faMeshDecomposition::decomposeMesh() ( IOobject ( - GeoMesh<polyMesh>::mesh_.name(), + polyMeshRegionName, processorDb.timeName(), processorDb ) @@ -314,7 +326,7 @@ void Foam::faMeshDecomposition::decomposeMesh() fvFaceProcAddressingHash.find ( faceLabels()[curProcFaceAddressing[faceI]] + 1 - )(); + ).val(); } // create processor finite area mesh @@ -324,38 +336,35 @@ void Foam::faMeshDecomposition::decomposeMesh() procFaceLabels_[procI] ); - const indirectPrimitivePatch& patch = this->patch(); + const uindirectPrimitivePatch& patch = this->patch(); const Map<label>& map = patch.meshPointMap(); EdgeMap<label> edgesHash; - label edgeI = -1; - const label nIntEdges = patch.nInternalEdges(); - for (label curEdge = 0; curEdge < nIntEdges; curEdge++) + for (label edgei = 0; edgei < nIntEdges; ++edgei) { - edgesHash.insert(patch.edges()[curEdge], ++edgeI); + edgesHash.insert(patch.edges()[edgei], edgesHash.size()); } - forAll(boundary(), patchI) + forAll(boundary(), patchi) { // Include emptyFaPatch + const label size = boundary()[patchi].labelList::size(); - const label size = boundary()[patchI].labelList::size(); - - for(int eI=0; eI<size; eI++) + for (label edgei=0; edgei < size; ++edgei) { edgesHash.insert ( - patch.edges()[boundary()[patchI][eI]], - ++edgeI + patch.edges()[boundary()[patchi][edgei]], + edgesHash.size() ); } } - const indirectPrimitivePatch& procPatch = procMesh.patch(); + const uindirectPrimitivePatch& procPatch = procMesh.patch(); const vectorField& procPoints = procPatch.localPoints(); const labelList& procMeshPoints = procPatch.meshPoints(); const edgeList& procEdges = procPatch.edges(); @@ -370,21 +379,18 @@ void Foam::faMeshDecomposition::decomposeMesh() } labelList& curPatchEdgeAddressing = procPatchEdgeAddressing_[procI]; - curPatchEdgeAddressing.setSize(procEdges.size(), -1); + curPatchEdgeAddressing.resize(procEdges.size(), -1); + + Map<label>& curMap = procMeshEdgesMap_[procI]; + curMap.clear(); + curMap.resize(2*procEdges.size()); forAll(procEdges, edgeI) { - edge curGlobalEdge = procEdges[edgeI]; - curGlobalEdge[0] = curPatchPointAddressing[curGlobalEdge[0]]; - curGlobalEdge[1] = curPatchPointAddressing[curGlobalEdge[1]]; - - curPatchEdgeAddressing[edgeI] = edgesHash.find(curGlobalEdge)(); + edge curGlobalEdge(curPatchPointAddressing, procEdges[edgeI]); + curPatchEdgeAddressing[edgeI] = edgesHash.find(curGlobalEdge).val(); } - Map<label>& curMap = procMeshEdgesMap_[procI]; - - curMap = Map<label>(2*procEdges.size()); - forAll(curPatchEdgeAddressing, edgeI) { curMap.insert(curPatchEdgeAddressing[edgeI], edgeI); @@ -1057,7 +1063,7 @@ void Foam::faMeshDecomposition::decomposeMesh() ( IOobject ( - GeoMesh<polyMesh>::mesh_.name(), + polyMeshRegionName, processorDb.timeName(), processorDb ) @@ -1083,12 +1089,11 @@ void Foam::faMeshDecomposition::decomposeMesh() procProcessorPatchSize_[procI]; labelListList& curPatchEdgeLabels = procPatchEdgeLabels_[procI]; - curPatchEdgeLabels = - labelListList - ( - curPatchSize.size() - + curProcessorPatchSize.size() - ); + curPatchEdgeLabels.resize + ( + curPatchSize.size() + + curProcessorPatchSize.size() + ); forAll(curPatchSize, patchI) { @@ -1137,8 +1142,9 @@ void Foam::faMeshDecomposition::decomposeMesh() bool Foam::faMeshDecomposition::writeDecomposition() { - Info<< "\nConstructing processor FA meshes" << endl; + const word& polyMeshRegionName = mesh().name(); + Info<< "\nConstructing processor FA meshes" << endl; // Make a lookup map for globally shared points Map<label> sharedPointLookup(2*globallySharedPoints_.size()); @@ -1175,7 +1181,7 @@ bool Foam::faMeshDecomposition::writeDecomposition() ( IOobject ( - GeoMesh<polyMesh>::mesh_.name(), + polyMeshRegionName, processorDb.timeName(), processorDb ) @@ -1195,7 +1201,7 @@ bool Foam::faMeshDecomposition::writeDecomposition() ); - // create finite area mesh + // Create finite area mesh faMesh procMesh ( procFvMesh, @@ -1219,11 +1225,9 @@ bool Foam::faMeshDecomposition::writeDecomposition() const faPatchList& meshPatches = boundary(); - List<faPatch*> procPatches + PtrList<faPatch> procPatches ( - curPatchSizes.size() - + curProcessorPatchSizes.size(), - reinterpret_cast<faPatch*>(NULL) + curPatchSizes.size() + curProcessorPatchSizes.size() ); label nPatches = 0; @@ -1232,44 +1236,51 @@ bool Foam::faMeshDecomposition::writeDecomposition() { const labelList& curEdgeLabels = curPatchEdgeLabels[nPatches]; - const label ngbPolyPatchIndex = + const label neiPolyPatchId = fvBoundaryProcAddressing.find ( meshPatches[curBoundaryAddressing[patchi]] .ngbPolyPatchIndex() ); - procPatches[nPatches] = + procPatches.set + ( + nPatches, meshPatches[curBoundaryAddressing[patchi]].clone ( procMesh.boundary(), curEdgeLabels, nPatches, - ngbPolyPatchIndex - ).ptr(); - - nPatches++; + neiPolyPatchId + ) + ); + ++nPatches; } forAll(curProcessorPatchSizes, procPatchI) { const labelList& curEdgeLabels = curPatchEdgeLabels[nPatches]; - procPatches[nPatches] = + procPatches.set + ( + nPatches, new processorFaPatch ( - word("procBoundary") + Foam::name(procI) - + word("to") - + Foam::name(curNeighbourProcessors[procPatchI]), + processorPolyPatch::newName + ( + procI, + curNeighbourProcessors[procPatchI] + ), curEdgeLabels, nPatches, procMesh.boundary(), -1, procI, curNeighbourProcessors[procPatchI] - ); + ) + ); - nPatches++; + ++nPatches; } // Add boundary patches @@ -1291,23 +1302,19 @@ bool Foam::faMeshDecomposition::writeDecomposition() forAll(procMesh.boundary(), patchi) { - if - ( - procMesh.boundary()[patchi].type() - == processorFaPatch::typeName - ) + const auto* ppp = + isA<processorFaPatch>(procMesh.boundary()[patchi]); + + if (ppp) { - const processorFaPatch& ppp = - refCast<const processorFaPatch> - ( - procMesh.boundary()[patchi] - ); + const auto& procPatch = *ppp; Info<< " Number of edges shared with processor " - << ppp.neighbProcNo() << " = " << ppp.size() << endl; + << procPatch.neighbProcNo() << " = " + << procPatch.size() << endl; - nProcPatches++; - nProcEdges += ppp.size(); + nProcEdges += procPatch.size(); + ++nProcPatches; } else { diff --git a/applications/utilities/parallelProcessing/decomposePar/faMeshDecomposition.H b/src/parallel/decompose/faDecompose/faMeshDecomposition.H similarity index 78% rename from applications/utilities/parallelProcessing/decomposePar/faMeshDecomposition.H rename to src/parallel/decompose/faDecompose/faMeshDecomposition.H index 3c0526820c34c6106e61c81fd285e66b68ab2771..44a5323353aee7b6dba301bc2b3c18a2b800b857 100644 --- a/applications/utilities/parallelProcessing/decomposePar/faMeshDecomposition.H +++ b/src/parallel/decompose/faDecompose/faMeshDecomposition.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -44,7 +45,6 @@ SourceFiles #include "fvMesh.H" #include "faMesh.H" #include "labelList.H" -#include "SLList.H" #include "PtrList.H" #include "point.H" @@ -59,10 +59,7 @@ class faMeshDecomposition : public faMesh { - // Private data - - //- Optional non-standard file for decomposeParDict - const fileName decompDictFile_; + // Private Data //- Number of processors in decomposition label nProcs_; @@ -86,7 +83,7 @@ class faMeshDecomposition labelList procNInternalEdges_; //- Edge labels for patches of processor meshes - List<List<List<label>>> procPatchEdgeLabels_; + List<labelListList> procPatchEdgeLabels_; //- Labels of points for each processor labelListList procPatchPointAddressing_; @@ -131,18 +128,21 @@ class faMeshDecomposition void distributeFaces(); + public: // Constructors //- Construct from components. + //- Values will come from the volume decomposition // \param mesh the fvMesh - // \param decompDictFile optional non-standard location for the - // decomposeParDict file + // \param nProcessors the number of processors + // \param params additional parameters, sent to updateParameters faMeshDecomposition ( const fvMesh& mesh, - const fileName& decompDictFile = "" + const label nProcessors, + const dictionary& params = dictionary::null ); @@ -152,29 +152,63 @@ public: // Member Functions + // Settings + //- Number of processor in decomposition label nProcs() const { return nProcs_; } - //- Is the decomposition data to be distributed for each processor + //- Is decomposition data to be distributed for each processor bool distributed() const { return distributed_; } - //- Decompose mesh - void decomposeMesh(); + //- Change distributed flag + bool distributed(const bool on) + { + bool old(distributed_); + distributed_ = on; + return old; + } - //- Write decomposition - bool writeDecomposition(); + //- Are global face zones used + bool useGlobalFaceZones() const + { + return distributed_; + } - //- Cell-processor decomposition labels - const labelList& faceToProc() const + //- Change global face zones flag + bool useGlobalFaceZones(const bool on) + { + bool old(hasGlobalFaceZones_); + hasGlobalFaceZones_ = on; + return old; + } + + //- Update flags based on the decomposition model settings + // Sets "distributed", detects presence of "globalFaceZones" + void updateParameters(const dictionary& params); + + + // Mappings + + //- Face-processor decomposition labels + const labelList& faceToProc() const noexcept { return faceToProc_; } + + + // Decompose + + //- Decompose mesh + void decomposeMesh(); + + //- Write decomposition + bool writeDecomposition(); }; diff --git a/src/parallel/reconstruct/Allwmake b/src/parallel/reconstruct/Allwmake index 77b67cd1ecb9178eabe0d9bc2f17742789cad26a..583901ce7c03b955be7b5d53f9b64524d625cb32 100755 --- a/src/parallel/reconstruct/Allwmake +++ b/src/parallel/reconstruct/Allwmake @@ -5,5 +5,6 @@ cd "${0%/*}" || exit # Run from this directory #------------------------------------------------------------------------------ wmake $targetType reconstruct +wmake $targetType faReconstruct #------------------------------------------------------------------------------ diff --git a/src/parallel/reconstruct/faReconstruct/Make/files b/src/parallel/reconstruct/faReconstruct/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..c0f15e7ecda4e911f54ec257a4e0c8de5e3d6bff --- /dev/null +++ b/src/parallel/reconstruct/faReconstruct/Make/files @@ -0,0 +1,5 @@ +processorFaMeshes.C +faFieldReconstructor.C +faMeshReconstructor.C + +LIB = $(FOAM_LIBBIN)/libfaReconstruct diff --git a/src/parallel/reconstruct/faReconstruct/Make/options b/src/parallel/reconstruct/faReconstruct/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..2526f4eb0e6970a6cc43123f2c5c752687ceb3e9 --- /dev/null +++ b/src/parallel/reconstruct/faReconstruct/Make/options @@ -0,0 +1,9 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteArea/lnInclude \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude + +EXE_LIBS = \ + -lfiniteArea \ + -lfiniteVolume \ + -lmeshTools diff --git a/applications/utilities/parallelProcessing/reconstructPar/faFieldReconstructor.C b/src/parallel/reconstruct/faReconstruct/faFieldReconstructor.C similarity index 100% rename from applications/utilities/parallelProcessing/reconstructPar/faFieldReconstructor.C rename to src/parallel/reconstruct/faReconstruct/faFieldReconstructor.C diff --git a/applications/utilities/parallelProcessing/reconstructPar/faFieldReconstructor.H b/src/parallel/reconstruct/faReconstruct/faFieldReconstructor.H similarity index 98% rename from applications/utilities/parallelProcessing/reconstructPar/faFieldReconstructor.H rename to src/parallel/reconstruct/faReconstruct/faFieldReconstructor.H index 77f312191dadecc20198d8ca09970af92a7a4820..0c1e0005732b959b7caacba2b8e695842a5fb635 100644 --- a/applications/utilities/parallelProcessing/reconstructPar/faFieldReconstructor.H +++ b/src/parallel/reconstruct/faReconstruct/faFieldReconstructor.H @@ -35,7 +35,7 @@ Author SourceFiles faFieldReconstructor.C - faFieldReconstructorReconstructFields.C + faFieldReconstructorFields.C \*---------------------------------------------------------------------------*/ @@ -194,7 +194,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository -# include "faFieldReconstructorReconstructFields.C" +# include "faFieldReconstructorFields.C" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/applications/utilities/parallelProcessing/reconstructPar/faFieldReconstructorReconstructFields.C b/src/parallel/reconstruct/faReconstruct/faFieldReconstructorFields.C similarity index 100% rename from applications/utilities/parallelProcessing/reconstructPar/faFieldReconstructorReconstructFields.C rename to src/parallel/reconstruct/faReconstruct/faFieldReconstructorFields.C diff --git a/src/parallel/reconstruct/faReconstruct/faMeshReconstructor.C b/src/parallel/reconstruct/faReconstruct/faMeshReconstructor.C new file mode 100644 index 0000000000000000000000000000000000000000..0f85a81d5e23c22c07c812eda60677631957deb2 --- /dev/null +++ b/src/parallel/reconstruct/faReconstruct/faMeshReconstructor.C @@ -0,0 +1,637 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 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 "faMeshReconstructor.H" +#include "globalIndex.H" +#include "globalMeshData.H" +#include "edgeHashes.H" +#include "Time.H" +#include "PstreamCombineReduceOps.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +int Foam::faMeshReconstructor::debug = 0; + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::faMeshReconstructor::calcAddressing +( + const labelUList& fvFaceProcAddr +) +{ + const globalIndex globalFaceNum(procMesh_.nFaces()); + + // ---------------------- + // boundaryProcAddressing + // + // Trivial since non-processor boundary ordering is identical + + const label nPatches = procMesh_.boundary().size(); + + faBoundaryProcAddr_ = identity(nPatches); + + // Mark processor patches + for + ( + label patchi = procMesh_.boundary().nNonProcessor(); + patchi < nPatches; + ++patchi + ) + { + faBoundaryProcAddr_[patchi] = -1; + } + + + // ------------------ + // faceProcAddressing + // + // Transcribe/rewrite based on finiteVolume faceProcAddressing + + faFaceProcAddr_ = procMesh_.faceLabels(); + + // From local faceLabels to proc values + for (label& facei : faFaceProcAddr_) + { + // Use finiteVolume info, ignoring face flips + facei = mag(fvFaceProcAddr[facei] - 1); + } + + + // Make global consistent. + // Starting at '0', without gaps in numbering etc. + // - the sorted order is the obvious solution + { + globalFaceNum.gather(faFaceProcAddr_, singlePatchFaceLabels_); + + labelList order(Foam::sortedOrder(singlePatchFaceLabels_)); + + singlePatchFaceLabels_ = labelList(singlePatchFaceLabels_, order); + + globalFaceNum.scatter(order, faFaceProcAddr_); + } + + // Broadcast the same information everywhere + Pstream::scatter(singlePatchFaceLabels_); + + + // ------------------ + // edgeProcAddressing + // + // This is more complicated. + + // Create a single (serial) patch of the finiteArea mesh without a + // corresponding volume mesh, otherwise it would be the same as + // reconstructPar on the volume mesh (big, slow, etc). + // + // Do manual point-merge and relabeling to avoid dependency on + // finiteVolume pointProcAddressing + + faPointProcAddr_.clear(); // Final size == procMesh_.nPoints() + + // 1. + // - Topological point merge of the area meshes + // - use the local patch faces and points + + // 2. + // - build a single (serial) patch of the finiteArea mesh only + // without any point support from the volume mesh + // - it may be possible to skip this step, but not obvious how + + // The collected faces are contiguous per processor, which gives us + // the possibility to easily identify their source by using the + // global face indexing (if needed). + // The ultimate face locations are handled with a separate ordering + // list. + + const uindirectPrimitivePatch& procPatch = procMesh_.patch(); + + + { + faceList singlePatchProcFaces; // [proc0faces, proc1faces ...] + labelList uniqueMeshPointLabels; + + // Local face points to compact merged point index + labelList pointToGlobal; + + autoPtr<globalIndex> globalPointsPtr = + procMesh_.mesh().globalData().mergePoints + ( + procPatch.meshPoints(), + procPatch.meshPointMap(), // unused + pointToGlobal, + uniqueMeshPointLabels + ); + + // Gather faces, renumbered for the *merged* points + faceList tmpFaces(globalFaceNum.localSize()); + + forAll(tmpFaces, facei) + { + tmpFaces[facei] = + face(pointToGlobal, procPatch.localFaces()[facei]); + } + + globalFaceNum.gather + ( + tmpFaces, + singlePatchProcFaces, + UPstream::msgType(), + Pstream::commsTypes::scheduled + ); + + globalPointsPtr().gather + ( + UIndirectList<point> + ( + procPatch.points(), // NB: mesh points (non-local) + uniqueMeshPointLabels + ), + singlePatchPoints_ + ); + + // Transcribe into final assembled order + singlePatchFaces_.resize(singlePatchProcFaces.size()); + + // Target face ordering + labelList singlePatchProcAddr; + globalFaceNum.gather(faFaceProcAddr_, singlePatchProcAddr); + + forAll(singlePatchProcAddr, facei) + { + const label targetFacei = singlePatchProcAddr[facei]; + singlePatchFaces_[targetFacei] = singlePatchProcFaces[facei]; + } + + // Use initial equivalent "global" (serial) patch + // to establish the correct point and face walking order + // + // - only meaningful on master + const primitivePatch initialPatch + ( + SubList<face>(singlePatchFaces_), + singlePatchPoints_ + ); + + // Grab the faces/points in local point ordering + tmpFaces = initialPatch.localFaces(); + pointField tmpPoints(initialPatch.localPoints()); + + // The meshPointMap is contiguous, so flatten as linear list + /// Map<label> mpm(initialPatch.meshPointMap()); + labelList mpm(initialPatch.nPoints()); + forAllConstIters(initialPatch.meshPointMap(), iter) + { + mpm[iter.key()] = iter.val(); + } + Pstream::scatter(mpm); + + // Rewrite pointToGlobal according to the correct point order + for (label& pointi : pointToGlobal) + { + pointi = mpm[pointi]; + } + + // Finalize. overwrite + faPointProcAddr_ = std::move(pointToGlobal); + + singlePatchFaces_ = std::move(tmpFaces); + singlePatchPoints_ = std::move(tmpPoints); + } + + // Broadcast the same information everywhere + Pstream::scatter(singlePatchFaces_); + Pstream::scatter(singlePatchPoints_); + + // Now have enough global information to determine global edge mappings + + // Equivalent "global" (serial) patch + const primitivePatch onePatch + ( + SubList<face>(singlePatchFaces_), + singlePatchPoints_ + ); + + faEdgeProcAddr_.clear(); + faEdgeProcAddr_.resize(procMesh_.nEdges(), -1); + + { + EdgeMap<label> globalEdgeMapping(2*onePatch.nEdges()); + + // Pass 1: edge-hash lookup with edges in "natural" patch order + + // Can use local edges() directly without remap via meshPoints() + // since the previous sorting means that we are already working + // with faces that are in the local point order and even + // the points themselves are also in the local point order + for (const edge& e : onePatch.edges()) + { + globalEdgeMapping.insert(e, globalEdgeMapping.size()); + } + + // Lookup proc local edges (in natural order) to global equivalent + for (label edgei = 0; edgei < procPatch.nEdges(); ++edgei) + { + const edge globalEdge(faPointProcAddr_, procPatch.edges()[edgei]); + + const auto fnd = globalEdgeMapping.cfind(globalEdge); + + if (fnd.found()) + { + faEdgeProcAddr_[edgei] = fnd.val(); + } + else + { + FatalErrorInFunction + << "Failed to find edge " << globalEdge + << " this indicates a programming error" << nl + << exit(FatalError); + } + } + } + + // Now have consistent global edge + // This of course would all be too easy. + // The finiteArea edge lists have been defined as their own sorted + // order with sublists etc. + + // Gather edge ids for nonProcessor boundaries. + // These will also be in the serial geometry + + Map<label> remapGlobal(2*onePatch.nEdges()); + for (label edgei = 0; edgei < onePatch.nInternalEdges(); ++edgei) + { + remapGlobal.insert(edgei, remapGlobal.size()); + } + + // + singlePatchEdgeLabels_.clear(); + singlePatchEdgeLabels_.resize(procMesh_.boundary().nNonProcessor()); + + forAll(singlePatchEdgeLabels_, patchi) + { + const faPatch& fap = procMesh_.boundary()[patchi]; + + labelList& patchEdgeLabels = singlePatchEdgeLabels_[patchi]; + patchEdgeLabels = fap.edgeLabels(); + + // Renumber from local edges to global edges (natural order) + for (label& edgeId : patchEdgeLabels) + { + edgeId = faEdgeProcAddr_[edgeId]; + } + + // OR patchEdgeLabels = + // UIndirectList<label>(faEdgeProcAddr_, fap.edgeLabels()); + + + // Collect from all processors + combineReduce + ( + patchEdgeLabels, + ListOps::appendEqOp<label>() + ); + + // Sorted order will be the original non-decomposed order + Foam::sort(patchEdgeLabels); + + for (const label sortedEdgei : patchEdgeLabels) + { + remapGlobal.insert(sortedEdgei, remapGlobal.size()); + } + } + + { + // Use the map to rewrite the local faEdgeProcAddr_ + + labelList newEdgeProcAddr(faEdgeProcAddr_); + + label edgei = procMesh_.nInternalEdges(); + + for (const faPatch& fap : procMesh_.boundary()) + { + for (const label patchEdgei : fap.edgeLabels()) + { + const label globalEdgei = faEdgeProcAddr_[patchEdgei]; + + const auto fnd = remapGlobal.cfind(globalEdgei); + if (fnd.found()) + { + newEdgeProcAddr[edgei] = fnd.val(); + ++edgei; + } + else + { + FatalErrorInFunction + << "Failed to find edge " << globalEdgei + << " this indicates a programming error" << nl + << exit(FatalError); + } + } + } + + faEdgeProcAddr_ = std::move(newEdgeProcAddr); + } +} + + +void Foam::faMeshReconstructor::initPatch() const +{ + serialPatchPtr_.reset + ( + new primitivePatch + ( + SubList<face>(singlePatchFaces_), + singlePatchPoints_ + ) + ); +} + + +void Foam::faMeshReconstructor::createMesh() +{ + const Time& runTime = procMesh_.mesh().time(); + + // Time for non-parallel case (w/o functionObjects or libs) + serialRunTime_ = Time::New(runTime.globalPath().toAbsolute()); + + + // Trivial polyMesh only containing points and faces. + // This is valid, provided we don't use it for anything complicated. + + serialVolMesh_.reset + ( + new polyMesh + ( + IOobject + ( + procMesh_.mesh().name(), // Volume region name + procMesh_.mesh().facesInstance(), + + *serialRunTime_, + + IOobject::NO_READ, + IOobject::NO_WRITE, + false // not registered + ), + pointField(singlePatchPoints_), // copy + faceList(singlePatchFaces_), // copy + labelList(singlePatchFaces_.size(), Zero), // faceOwner + labelList(), // faceNeighbour + false // no syncPar! + ) + ); + + // A simple area-mesh with one-to-one mapping of faceLabels + serialAreaMesh_.reset + ( + new faMesh + ( + *serialVolMesh_, + identity(singlePatchFaces_.size()) // faceLabels + ) + ); + + auto& completeMesh = *serialAreaMesh_; + + // Add in non-processor boundary patches + PtrList<faPatch> completePatches(singlePatchEdgeLabels_.size()); + forAll(completePatches, patchi) + { + const labelList& patchEdgeLabels = singlePatchEdgeLabels_[patchi]; + + const faPatch& fap = procMesh_.boundary()[patchi]; + + const label neiPolyPatchId = fap.ngbPolyPatchIndex(); + + completePatches.set + ( + patchi, + fap.clone + ( + completeMesh.boundary(), + patchEdgeLabels, + patchi, // index + neiPolyPatchId + ) + ); + } + + completeMesh.addFaPatches(completePatches); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::faMeshReconstructor::faMeshReconstructor +( + const faMesh& procMesh +) +: + procMesh_(procMesh) +{ + if (!Pstream::parRun()) + { + FatalErrorInFunction + << "Can only be called in parallel!!" << nl + << exit(FatalError); + } + + // Require faceProcAddressing from finiteVolume decomposition + labelIOList fvFaceProcAddressing + ( + IOobject + ( + "faceProcAddressing", + procMesh_.mesh().facesInstance(), + + // Or search? + // procMesh_.time().findInstance + // ( + // // Search for polyMesh face instance + // // mesh.facesInstance() + // procMesh_.mesh().meshDir(), + // "faceProcAddressing" + // ), + + polyMesh::meshSubDir, + procMesh_.mesh(), // The polyMesh db + IOobject::MUST_READ, + IOobject::NO_WRITE, + false // not registered + ) + ); + + calcAddressing(fvFaceProcAddressing); +} + + +Foam::faMeshReconstructor::faMeshReconstructor +( + const faMesh& procMesh, + const labelUList& fvFaceProcAddressing +) +: + procMesh_(procMesh) +{ + if (!Pstream::parRun()) + { + FatalErrorInFunction + << "Can only be called in parallel!!" << nl + << exit(FatalError); + } + + calcAddressing(fvFaceProcAddressing); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::faMeshReconstructor::~faMeshReconstructor() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::faMeshReconstructor::clearGeom() +{ + serialAreaMesh_.reset(nullptr); + serialVolMesh_.reset(nullptr); + serialRunTime_.reset(nullptr); +} + + +const Foam::primitivePatch& Foam::faMeshReconstructor::patch() const +{ + if (!serialPatchPtr_) + { + initPatch(); + } + + return *serialPatchPtr_; +} + + +Foam::primitivePatch& Foam::faMeshReconstructor::patch() +{ + if (!serialPatchPtr_) + { + initPatch(); + } + + return *serialPatchPtr_; +} + + +const Foam::faMesh& Foam::faMeshReconstructor::mesh() const +{ + if (!serialAreaMesh_) + { + const_cast<faMeshReconstructor&>(*this).createMesh(); + } + + return *serialAreaMesh_; +} + + +void Foam::faMeshReconstructor::writeAddressing() const +{ + writeAddressing(procMesh_.mesh().facesInstance()); +} + + +void Foam::faMeshReconstructor::writeAddressing(const word& timeName) const +{ + // Write copies + + IOobject ioAddr + ( + "procAddressing", + timeName, + faMesh::meshSubDir, + procMesh_.mesh(), // The polyMesh + IOobject::NO_READ, + IOobject::NO_WRITE, + false // not registered + ); + + // boundaryProcAddressing + ioAddr.rename("boundaryProcAddressing"); + labelIOList(ioAddr, faBoundaryProcAddr_).write(); + + // faceProcAddressing + ioAddr.rename("faceProcAddressing"); + labelIOList(ioAddr, faFaceProcAddr_).write(); + + // pointProcAddressing + ioAddr.rename("pointProcAddressing"); + labelIOList(ioAddr, faPointProcAddr_).write(); + + // edgeProcAddressing + ioAddr.rename("edgeProcAddressing"); + labelIOList(ioAddr, faEdgeProcAddr_).write(); +} + + +void Foam::faMeshReconstructor::writeMesh() const +{ + writeMesh(procMesh_.mesh().facesInstance()); +} + + +void Foam::faMeshReconstructor::writeMesh(const word& timeName) const +{ + const faMesh& fullMesh = this->mesh(); + + const bool oldDistributed = fileHandler().distributed(); + auto oldHandler = fileHandler(fileOperation::NewUncollated()); + fileHandler().distributed(true); + + if (Pstream::master()) + { + const bool oldParRun = Pstream::parRun(false); + + IOobject io(fullMesh.boundary()); + + io.rename("faceLabels"); + labelIOList(io, singlePatchFaceLabels_).write(); + + fullMesh.boundary().write(); + + Pstream::parRun(oldParRun); + } + + // Restore old settings + if (oldHandler) + { + fileHandler(std::move(oldHandler)); + } + fileHandler().distributed(oldDistributed); +} + + +// ************************************************************************* // diff --git a/src/parallel/reconstruct/faReconstruct/faMeshReconstructor.H b/src/parallel/reconstruct/faReconstruct/faMeshReconstructor.H new file mode 100644 index 0000000000000000000000000000000000000000..8cf5154f448e0730de47c9cf05c38c5ac57633e2 --- /dev/null +++ b/src/parallel/reconstruct/faReconstruct/faMeshReconstructor.H @@ -0,0 +1,222 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 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::faMeshReconstructor + +Description + A bare-bones reconstructor for finiteArea meshes when processor + meshes are available (in parallel) but an equivalent serial faMesh + is needed for reconstruction or decomposition. + In these situations, a serial version of the faMesh is needed, + but preferably without reconstructing the entire volume mesh. + + It uses the finiteVolume faceProcAddressing in addition to + the geometric information available from the underlying polyMesh. + + The resulting equivalent faMesh can be used for basic operations, + but caution should be exercised before attempting large operations. + +SourceFiles + faMeshReconstructor.C + +\*---------------------------------------------------------------------------*/ + +#ifndef faMeshReconstructor_H +#define faMeshReconstructor_H + +#include "faMesh.H" +#include "primitivePatch.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward Declarations +class Time; + +/*---------------------------------------------------------------------------*\ + Class faMeshReconstructor Declaration +\*---------------------------------------------------------------------------*/ + +class faMeshReconstructor +{ + // Private Data + + //- The processor-specific faMesh + const faMesh& procMesh_; + + + // Addressing + + //- Processor face addressing, derived from finite volume information + labelList faFaceProcAddr_; + + //- Processor boundary addressing + labelList faBoundaryProcAddr_; + + //- Processor point addressing + labelList faPointProcAddr_; + + //- Processor edge addressing + labelList faEdgeProcAddr_; + + + // Equivalent surface information + + //- Faces labels for a single patch + labelList singlePatchFaceLabels_; + + //- Faces for a single patch + faceList singlePatchFaces_; + + //- Support points for a single patch + pointField singlePatchPoints_; + + //- Lists of edge-labels (per edge patch) for the single patch + labelListList singlePatchEdgeLabels_; + + + // Demand-driven data + + //- Primitive patch + mutable autoPtr<primitivePatch> serialPatchPtr_; + + //- Time database for serial meshes + autoPtr<Time> serialRunTime_; + + //- Dummy volume mesh, used for serial area mesh + autoPtr<polyMesh> serialVolMesh_; + + //- Equivalent serial area mesh + autoPtr<faMesh> serialAreaMesh_; + + + // Private Member Functions + + //- Calculate all addressing, using finiteVolume faceProcAddressing + void calcAddressing(const labelUList& fvFaceProcAddr); + + //- Set primitive patch, removing any old one + void initPatch() const; + + //- Create the serial geometry + void createMesh(); + + //- No copy construct + faMeshReconstructor(const faMeshReconstructor&) = delete; + + //- No copy assignment + void operator=(const faMeshReconstructor&) = delete; + + +public: + + //- Debug flag + static int debug; + + + // Constructors + + //- Construct from components + explicit faMeshReconstructor(const faMesh& procMesh); + + //- Construct from components + faMeshReconstructor + ( + const faMesh& procMesh, + const labelUList& fvFaceProcAddressing + ); + + + //- Destructor + ~faMeshReconstructor(); + + void clearGeom(); + + + // Member Functions + + //- Processor point addressing + const labelList& pointProcAddressing() const noexcept + { + return faPointProcAddr_; + } + + //- Processor edge addressing + const labelList& edgeProcAddressing() const noexcept + { + return faEdgeProcAddr_; + } + + //- Processor face addressing + const labelList& faceProcAddressing() const noexcept + { + return faFaceProcAddr_; + } + + //- Processor boundary addressing + const labelList& boundaryProcAddressing() const noexcept + { + return faBoundaryProcAddr_; + } + + + //- Serial equivalent patch + const primitivePatch& patch() const; + + //- Serial equivalent patch + primitivePatch& patch(); + + //- Serial equivalent faMesh + const faMesh& mesh() const; + + + // Write + + //- Write proc addressing at the polyMesh faceInstances time + void writeAddressing() const; + + //- Write proc addressing at the given time + void writeAddressing(const word& timeName) const; + + //- Write equivalent mesh information at the polyMesh faceInstances time + void writeMesh() const; + + //- Write equivalent mesh information at the given time + void writeMesh(const word& timeName) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/parallelProcessing/reconstructPar/processorFaMeshes.C b/src/parallel/reconstruct/faReconstruct/processorFaMeshes.C similarity index 57% rename from applications/utilities/parallelProcessing/reconstructPar/processorFaMeshes.C rename to src/parallel/reconstruct/faReconstruct/processorFaMeshes.C index 980d652ce41314994e75adde175e5c952e3a9812..645a166900b11935d542edb335a010a70393254c 100644 --- a/applications/utilities/parallelProcessing/reconstructPar/processorFaMeshes.C +++ b/src/parallel/reconstruct/faReconstruct/processorFaMeshes.C @@ -145,116 +145,4 @@ Foam::processorFaMeshes::processorFaMeshes } -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -// Foam::fvMesh::readUpdateState Foam::processorFaMeshes::readUpdate() -// { -// fvMesh::readUpdateState stat = fvMesh::UNCHANGED; - -// forAll(databases_, procI) -// { -// // Check if any new meshes need to be read. -// fvMesh::readUpdateState procStat = meshes_[procI].readUpdate(); - -// /* -// if (procStat != fvMesh::UNCHANGED) -// { -// Info<< "Processor " << procI -// << " at time " << databases_[procI].timeName() -// << " detected mesh change " << procStat -// << endl; -// } -// */ - -// // Combine into overall mesh change status -// if (stat == fvMesh::UNCHANGED) -// { -// stat = procStat; -// } -// else -// { -// if (stat != procStat) -// { -// FatalErrorIn("processorFaMeshes::readUpdate()") -// << "Processor " << procI -// << " has a different polyMesh at time " -// << databases_[procI].timeName() -// << " compared to any previous processors." << nl -// << "Please check time " << databases_[procI].timeName() -// << " directories on all processors for consistent" -// << " mesh files." -// << exit(FatalError); -// } -// } -// } - -// if -// ( -// stat == fvMesh::TOPO_CHANGE -// || stat == fvMesh::TOPO_PATCH_CHANGE -// ) -// { -// // Reread all meshes and addressing -// read(); -// } -// return stat; -// } - - -// void Foam::processorFaMeshes::reconstructPoints(fvMesh& mesh) -// { -// // Read the field for all the processors -// PtrList<pointIOField> procsPoints(meshes_.size()); - -// forAll(meshes_, procI) -// { -// procsPoints.set -// ( -// procI, -// new pointIOField -// ( -// IOobject -// ( -// "points", -// meshes_[procI].time().timeName(), -// polyMesh::meshSubDir, -// meshes_[procI], -// IOobject::MUST_READ, -// IOobject::NO_WRITE -// ) -// ) -// ); -// } - -// // Create the new points -// vectorField newPoints(mesh.nPoints()); - -// forAll(meshes_, procI) -// { -// const vectorField& procPoints = procsPoints[procI]; - -// // Set the cell values in the reconstructed field - -// const labelList& pointProcAddressingI = pointProcAddressing_[procI]; - -// if (pointProcAddressingI.size() != procPoints.size()) -// { -// FatalErrorIn("processorFaMeshes") -// << "problem :" -// << " pointProcAddressingI:" << pointProcAddressingI.size() -// << " procPoints:" << procPoints.size() -// << abort(FatalError); -// } - -// forAll(pointProcAddressingI, pointI) -// { -// newPoints[pointProcAddressingI[pointI]] = procPoints[pointI]; -// } -// } - -// mesh.movePoints(newPoints); -// mesh.write(); -// } - - // ************************************************************************* // diff --git a/applications/utilities/parallelProcessing/reconstructPar/processorFaMeshes.H b/src/parallel/reconstruct/faReconstruct/processorFaMeshes.H similarity index 92% rename from applications/utilities/parallelProcessing/reconstructPar/processorFaMeshes.H rename to src/parallel/reconstruct/faReconstruct/processorFaMeshes.H index b302a287d76259831fd16f1bf9c2a9f0227206e5..342beb837515d189f756e671b6a43f904b41f1f3 100644 --- a/applications/utilities/parallelProcessing/reconstructPar/processorFaMeshes.H +++ b/src/parallel/reconstruct/faReconstruct/processorFaMeshes.H @@ -27,7 +27,7 @@ Class Foam::processorFaMeshes Description - Container for processor mesh addressing. + Container for finite-area processor mesh addressing. Author Zeljko Tukovic, FSB Zagreb @@ -41,8 +41,8 @@ SourceFiles #define processorFaMeshes_H #include "PtrList.H" -#include "fvMesh.H" #include "faMesh.H" +#include "fvMesh.H" #include "IOobjectList.H" #include "labelIOList.H" @@ -100,29 +100,31 @@ public: // Member Functions - //- Update the meshes based on the mesh files saved in - // time directories -// fvMesh::readUpdateState readUpdate(); - - //- Reconstruct point position after motion in parallel -// void reconstructPoints(faMesh& mesh); + const PtrList<faMesh>& meshes() const + { + return meshes_; + } PtrList<faMesh>& meshes() { return meshes_; } + const PtrList<labelIOList>& pointProcAddressing() const { return pointProcAddressing_; } + PtrList<labelIOList>& edgeProcAddressing() { return edgeProcAddressing_; } + const PtrList<labelIOList>& faceProcAddressing() const { return faceProcAddressing_; } + const PtrList<labelIOList>& boundaryProcAddressing() const { return boundaryProcAddressing_; diff --git a/src/thermophysicalModels/radiation/fvOptions/radiation/radiation.H b/src/thermophysicalModels/radiation/fvOptions/radiation/radiation.H index 723b53b2e4305c3fc3b24e6ab6b02d41923599d5..f70449ab59ad3dcabe51b243f6c4be9ec96988ec 100644 --- a/src/thermophysicalModels/radiation/fvOptions/radiation/radiation.H +++ b/src/thermophysicalModels/radiation/fvOptions/radiation/radiation.H @@ -80,7 +80,7 @@ namespace fv class radiation : - public option + public fv::option { // Private Data diff --git a/src/waveModels/fvOptions/multiphaseMangrovesSource/multiphaseMangrovesSource.H b/src/waveModels/fvOptions/multiphaseMangrovesSource/multiphaseMangrovesSource.H index 6d040ba0963a2017935b6c7cf5e32042fe5f8779..5c5cc232ebb2c7353775cb6879646e489f02e222 100644 --- a/src/waveModels/fvOptions/multiphaseMangrovesSource/multiphaseMangrovesSource.H +++ b/src/waveModels/fvOptions/multiphaseMangrovesSource/multiphaseMangrovesSource.H @@ -50,7 +50,7 @@ SourceFiles namespace Foam { -// Forward declarations +// Forward Declarations class MangrovesModel; namespace fv @@ -62,7 +62,7 @@ namespace fv class multiphaseMangrovesSource : - public option + public fv::option { // Private Member Functions diff --git a/src/waveModels/fvOptions/multiphaseMangrovesTurbulenceModel/multiphaseMangrovesTurbulenceModel.H b/src/waveModels/fvOptions/multiphaseMangrovesTurbulenceModel/multiphaseMangrovesTurbulenceModel.H index 3be8a42214fd0bccd6d53355b1da4588cc8a0943..ae9c4911565ddcfb260805c2a0567cbb4c10a0fd 100644 --- a/src/waveModels/fvOptions/multiphaseMangrovesTurbulenceModel/multiphaseMangrovesTurbulenceModel.H +++ b/src/waveModels/fvOptions/multiphaseMangrovesTurbulenceModel/multiphaseMangrovesTurbulenceModel.H @@ -59,7 +59,7 @@ namespace fv class multiphaseMangrovesTurbulenceModel : - public option + public fv::option { // Private Member Functions diff --git a/tutorials/compressible/acousticFoam/obliqueAirJet/main/constant/faMesh/faMeshDefinition b/tutorials/compressible/acousticFoam/obliqueAirJet/main/system/faMeshDefinition similarity index 97% rename from tutorials/compressible/acousticFoam/obliqueAirJet/main/constant/faMesh/faMeshDefinition rename to tutorials/compressible/acousticFoam/obliqueAirJet/main/system/faMeshDefinition index 1c7878defd4144f254e88dac980e7b48f0f44fc6..7bc2d201acae0c3aaa85e4cb1d2d3507a24b1c29 100644 --- a/tutorials/compressible/acousticFoam/obliqueAirJet/main/constant/faMesh/faMeshDefinition +++ b/tutorials/compressible/acousticFoam/obliqueAirJet/main/system/faMeshDefinition @@ -14,7 +14,7 @@ FoamFile } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -polyMeshPatches 1(window); +polyMeshPatches ( window ); boundary { diff --git a/tutorials/finiteArea/liquidFilmFoam/cylinder/Allrun-parallel b/tutorials/finiteArea/liquidFilmFoam/cylinder/Allrun-parallel new file mode 100755 index 0000000000000000000000000000000000000000..3f019bcaa246a8435ee97246f38fb9fe96f11b24 --- /dev/null +++ b/tutorials/finiteArea/liquidFilmFoam/cylinder/Allrun-parallel @@ -0,0 +1,14 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory +. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions +#------------------------------------------------------------------------------ + +runApplication blockMesh + +runApplication decomposePar + +runParallel makeFaMesh + +runParallel $(getApplication) + +#------------------------------------------------------------------------------ diff --git a/tutorials/finiteArea/liquidFilmFoam/cylinder/constant/faMesh/faMeshDefinition b/tutorials/finiteArea/liquidFilmFoam/cylinder/system/faMeshDefinition similarity index 94% rename from tutorials/finiteArea/liquidFilmFoam/cylinder/constant/faMesh/faMeshDefinition rename to tutorials/finiteArea/liquidFilmFoam/cylinder/system/faMeshDefinition index 12c4767c8d128cad7fa7b3a50171d1bd251fb1ec..66da6e5c0e5d3e14aa40e0ead8b8599737b034f2 100644 --- a/tutorials/finiteArea/liquidFilmFoam/cylinder/constant/faMesh/faMeshDefinition +++ b/tutorials/finiteArea/liquidFilmFoam/cylinder/system/faMeshDefinition @@ -10,12 +10,11 @@ FoamFile version 2.0; format ascii; class dictionary; - location "constant/faMesh"; object faMeshDefinition; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -polyMeshPatches 1( film ); +polyMeshPatches ( film ); boundary { @@ -56,4 +55,11 @@ boundary } +defaultPatch +{ + name empty; + type empty; +} + + // ************************************************************************** // diff --git a/tutorials/finiteArea/sphereSurfactantFoam/sphereTransport/constant/faMesh/faMeshDefinition b/tutorials/finiteArea/sphereSurfactantFoam/sphereTransport/system/faMeshDefinition similarity index 96% rename from tutorials/finiteArea/sphereSurfactantFoam/sphereTransport/constant/faMesh/faMeshDefinition rename to tutorials/finiteArea/sphereSurfactantFoam/sphereTransport/system/faMeshDefinition index a9d4ea6d56081363cebae691a205237c534a5246..ce76df0f704fea266824e10d19cdb6a7bf8a32d5 100644 --- a/tutorials/finiteArea/sphereSurfactantFoam/sphereTransport/constant/faMesh/faMeshDefinition +++ b/tutorials/finiteArea/sphereSurfactantFoam/sphereTransport/system/faMeshDefinition @@ -14,7 +14,7 @@ FoamFile } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -polyMeshPatches 1( outer ); +polyMeshPatches ( outer ); boundary { diff --git a/tutorials/finiteArea/surfactantFoam/planeTransport/Allrun-parallel b/tutorials/finiteArea/surfactantFoam/planeTransport/Allrun-parallel new file mode 100755 index 0000000000000000000000000000000000000000..93e66772a9e4956484ce22728b18bbafb7209795 --- /dev/null +++ b/tutorials/finiteArea/surfactantFoam/planeTransport/Allrun-parallel @@ -0,0 +1,19 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory +. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions +#------------------------------------------------------------------------------ + +runApplication blockMesh + +decompDict="-decomposeParDict system/decomposeParDict-procBoundary8" +fileHandler="-fileHandler collated" + +runApplication $decompDict decomposePar $fileHandler + +runParallel $decompDict makeFaMesh $fileHandler + +runParallel $decompDict $(getApplication) $fileHandler + +runApplication reconstructPar $fileHandler + +#------------------------------------------------------------------------------ diff --git a/tutorials/finiteArea/surfactantFoam/planeTransport/system/blockMeshDict b/tutorials/finiteArea/surfactantFoam/planeTransport/system/blockMeshDict index fabc18b264b1d93d6cfab4843e64d6cfd2b5d547..6f5e501b6bef578d56b41dc59fdb81b7912171e5 100644 --- a/tutorials/finiteArea/surfactantFoam/planeTransport/system/blockMeshDict +++ b/tutorials/finiteArea/surfactantFoam/planeTransport/system/blockMeshDict @@ -14,27 +14,44 @@ FoamFile } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// A flat plate that is only partial covered by the finiteArea mesh. +// Depending on the decomposition, the outflow boundary may +// coincide with a processor patch. + scale 0.1; +height 0.1; +width 1; +len 3; +out 1; +out #eval{ $out + $len }; + +nx 60; +ny 20; +nz 1; +nout 20; + vertices ( - (0 0 0) - (3 0 0) - (3 1 0) - (0 1 0) - (0 0 0.1) - (3 0 0.1) - (3 1 0.1) - (0 1 0.1) -); + /* 0*/ (0 0 0) + /* 1*/ ($len 0 0) + /* 2*/ ($len $width 0) + /* 3*/ (0 $width 0) + /* 4*/ (0 0 $height) + /* 5*/ ($len 0 $height) + /* 6*/ ($len $width $height) + /* 7*/ (0 $width $height) -blocks -( - hex (0 1 2 3 4 5 6 7) (60 20 1) simpleGrading (1 1 1) + /* 8*/ ($out 0 0) + /* 9*/ ($out 1 0) + /*10*/ ($out 0 $height) + /*11*/ ($out 1 $height) ); -edges +blocks ( + hex (0 1 2 3 4 5 6 7) ($nx $ny $nz) grading (1 1 1) + hex (1 8 9 2 5 10 11 6) ($nout $ny $nz) grading (1 1 1) ); boundary @@ -44,7 +61,7 @@ boundary type patch; faces ( - (0 4 7 3) + (0 4 7 3) ); } @@ -53,8 +70,12 @@ boundary type wall; faces ( - (3 7 6 2) - (1 5 4 0) + (3 7 6 2) + (1 5 4 0) + + // outflow + (1 8 10 5) + (2 6 11 9) ); } @@ -63,7 +84,7 @@ boundary type patch; faces ( - (2 6 5 1) + (8 9 10 11) ); } @@ -73,6 +94,7 @@ boundary faces ( (0 3 2 1) + (1 8 9 2) ); } @@ -84,10 +106,15 @@ boundary (4 5 6 7) ); } -); -mergePatchPairs -( + outflow + { + type patch; + faces + ( + (5 10 11 6) + ); + } ); diff --git a/tutorials/finiteArea/surfactantFoam/planeTransport/system/decomposeParDict b/tutorials/finiteArea/surfactantFoam/planeTransport/system/decomposeParDict index 792ca5965b6bd6145d7980fd2566eaa59204925c..bf5148c5d808cde097b94291c40d8f1e0da6d567 100644 --- a/tutorials/finiteArea/surfactantFoam/planeTransport/system/decomposeParDict +++ b/tutorials/finiteArea/surfactantFoam/planeTransport/system/decomposeParDict @@ -10,7 +10,6 @@ FoamFile version 2.0; format ascii; class dictionary; - location "system"; object decomposeParDict; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/tutorials/finiteArea/surfactantFoam/planeTransport/system/decomposeParDict-procBoundary4 b/tutorials/finiteArea/surfactantFoam/planeTransport/system/decomposeParDict-procBoundary4 new file mode 100644 index 0000000000000000000000000000000000000000..30e0dbd4ae6ea8e3763dbbc1cdee23298e270d3b --- /dev/null +++ b/tutorials/finiteArea/surfactantFoam/planeTransport/system/decomposeParDict-procBoundary4 @@ -0,0 +1,28 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2012 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object decomposeParDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// With 4 divisions in x-direction (coincides with finiteArea boundary) + +numberOfSubdomains 4; + +method simple; + +coeffs +{ + n ( 4 1 1 ); +} + + +// ************************************************************************* // diff --git a/tutorials/finiteArea/surfactantFoam/planeTransport/system/decomposeParDict-procBoundary8 b/tutorials/finiteArea/surfactantFoam/planeTransport/system/decomposeParDict-procBoundary8 new file mode 100644 index 0000000000000000000000000000000000000000..bc6a1ae7b79de5cb9a2c03b3d430b01314ade512 --- /dev/null +++ b/tutorials/finiteArea/surfactantFoam/planeTransport/system/decomposeParDict-procBoundary8 @@ -0,0 +1,28 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2012 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object decomposeParDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// With 4 divisions in x-direction (coincides with finiteArea boundary) + +numberOfSubdomains 8; + +method simple; + +coeffs +{ + n ( 4 2 1 ); +} + + +// ************************************************************************* // diff --git a/tutorials/finiteArea/surfactantFoam/planeTransport/constant/faMesh/faMeshDefinition b/tutorials/finiteArea/surfactantFoam/planeTransport/system/faMeshDefinition similarity index 91% rename from tutorials/finiteArea/surfactantFoam/planeTransport/constant/faMesh/faMeshDefinition rename to tutorials/finiteArea/surfactantFoam/planeTransport/system/faMeshDefinition index de49f774744e4c64c66527ebd7369d53e2392a9e..9558287443a608ef2b1dda567ea742e6b8b84291 100644 --- a/tutorials/finiteArea/surfactantFoam/planeTransport/constant/faMesh/faMeshDefinition +++ b/tutorials/finiteArea/surfactantFoam/planeTransport/system/faMeshDefinition @@ -14,7 +14,7 @@ FoamFile } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -polyMeshPatches 1( top ); +polyMeshPatches ( top ); boundary { @@ -28,7 +28,8 @@ boundary { type patch; ownerPolyPatch top; - neighbourPolyPatch outlet; + // neighbourPolyPatch outlet; + neighbourPolyPatch outflow; } bound { diff --git a/tutorials/incompressible/pimpleFoam/laminar/contactAngleCavity/constant/faMesh/faMeshDefinition b/tutorials/incompressible/pimpleFoam/laminar/contactAngleCavity/system/faMeshDefinition similarity index 100% rename from tutorials/incompressible/pimpleFoam/laminar/contactAngleCavity/constant/faMesh/faMeshDefinition rename to tutorials/incompressible/pimpleFoam/laminar/contactAngleCavity/system/faMeshDefinition diff --git a/tutorials/incompressible/pimpleFoam/laminar/contaminatedDroplet2D/constant/faMesh/faMeshDefinition b/tutorials/incompressible/pimpleFoam/laminar/contaminatedDroplet2D/system/faMeshDefinition similarity index 100% rename from tutorials/incompressible/pimpleFoam/laminar/contaminatedDroplet2D/constant/faMesh/faMeshDefinition rename to tutorials/incompressible/pimpleFoam/laminar/contaminatedDroplet2D/system/faMeshDefinition diff --git a/tutorials/incompressible/pimpleFoam/laminar/sloshing2D/constant/faMesh/faMeshDefinition b/tutorials/incompressible/pimpleFoam/laminar/sloshing2D/system/faMeshDefinition similarity index 100% rename from tutorials/incompressible/pimpleFoam/laminar/sloshing2D/constant/faMesh/faMeshDefinition rename to tutorials/incompressible/pimpleFoam/laminar/sloshing2D/system/faMeshDefinition