diff --git a/applications/utilities/finiteArea/makeFaMesh/Make/options b/applications/utilities/finiteArea/makeFaMesh/Make/options index 98ba4f7225..7a28b2c4b6 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 0000000000..5c38c9b4f1 --- /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 areaScalarFields; + PtrList areaVectorFields; + PtrList areaSphTensorFields; + PtrList areaSymmTensorFields; + PtrList 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 0000000000..a50d18df3c --- /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 0000000000..8a678fdcc8 --- /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 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(true)) + { + FatalErrorInFunction + << meshDictIO.objectPath() << nl + << exit(FatalError); + } + + Info<< "Creating faMesh from definition: " + << runTime.relativePath(meshDictIO.objectPath()) << endl; + + meshDictPtr = autoPtr::New(meshDictIO); +} + +IOdictionary& meshDefDict = *meshDictPtr; + + +// ************************************************************************* // diff --git a/applications/utilities/finiteArea/makeFaMesh/makeFaMesh.C b/applications/utilities/finiteArea/makeFaMesh/makeFaMesh.C index 0010be3dab..e80ed303d9 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,36 +38,20 @@ 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" + +#include "areaFields.H" +#include "faFieldDecomposer.H" +#include "faMeshReconstructor.H" +#include "OBJstream.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) - {} -}; - - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int main(int argc, char *argv[]) @@ -73,286 +60,64 @@ int main(int argc, char *argv[]) ( "A mesh generator for finiteArea mesh" ); + argList::addOption + ( + "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"); + + argList::addBoolOption + ( + "write-edges-obj", + "Write mesh edges as obj files and exit", + false // could make an advanced option + ); #include "addRegionOption.H" - argList::noParallel(); - #include "setRootCase.H" #include "createTime.H" - #include "createNamedMesh.H" + #include "createNamedPolyMesh.H" // Reading faMeshDefinition dictionary - IOdictionary faMeshDefinition - ( - IOobject - ( - "faMeshDefinition", - runTime.constant(), - "faMesh", - mesh, - IOobject::MUST_READ, - IOobject::NO_WRITE - ) - ); + #include "findMeshDefinitionDict.H" - wordList polyMeshPatches - ( - faMeshDefinition.get("polyMeshPatches") - ); - - const dictionary& bndDict = faMeshDefinition.subDict("boundary"); - - const wordList faPatchNames(bndDict.toc()); - - List faPatches(faPatchNames.size()+1); - - forAll(faPatchNames, patchI) + // Inject/overwrite name for optional 'empty' patch + word patchName; + if (args.readIfPresent("empty-patch", patchName)) { - const dictionary& curPatchDict = bndDict.subDict(faPatchNames[patchI]); - - faPatches[patchI].name_ = faPatchNames[patchI]; - - faPatches[patchI].type_ = curPatchDict.get("type"); - - const word ownName(curPatchDict.get("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("neighbourPolyPatch")); - - faPatches[patchI].ngbPolyPatchID_ = - mesh.boundaryMesh().findPatchID(neiName); - - if (faPatches[patchI].ngbPolyPatchID_ < 0) - { - FatalErrorIn("makeFaMesh:") - << "neighbourPolyPatch " << neiName << " does not exist" - << exit(FatalError); - } + meshDefDict.add("emptyPatch", patchName, true); } - // Setting faceLabels list size - label size = 0; + // Create + faMesh areaMesh(mesh, meshDefDict); - labelList patchIDs(polyMeshPatches.size(), -1); + bool quickExit = false; - forAll(polyMeshPatches, patchI) + if (args.found("write-edges-obj")) { - 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(); + quickExit = true; + #include "faMeshWriteEdgesOBJ.H" } - labelList faceLabels(size, -1); - - sort(patchIDs); - - - // Filling of faceLabels list - label faceI = -1; - - forAll(polyMeshPatches, patchI) + if (quickExit) { - 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; - } + Info<< "\nEnd\n" << endl; + return 0; } - // Creating faMesh - Info << "Create faMesh ... "; + // Set the precision of the points data to 10 + IOstream::defaultPrecision(10); - faMesh areaMesh - ( - mesh, - faceLabels - ); - 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