diff --git a/applications/utilities/mesh/generation/extrudeMesh/Make/options b/applications/utilities/mesh/generation/extrudeMesh/Make/options index ce0e27f401b48c65f68ffed57b4edb710b8401a7..1cdc68a2c7d9ca4dde6664f2a567caf945ee6660 100644 --- a/applications/utilities/mesh/generation/extrudeMesh/Make/options +++ b/applications/utilities/mesh/generation/extrudeMesh/Make/options @@ -1,10 +1,14 @@ EXE_INC = \ -IextrudedMesh \ -IextrudeModel/lnInclude \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/surfMesh/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude EXE_LIBS = \ + -lfiniteVolume \ + -lsurfMesh \ -lmeshTools \ -ldynamicMesh \ -lextrudeModel diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeMesh.C b/applications/utilities/mesh/generation/extrudeMesh/extrudeMesh.C index d149f85923cb03ebd38eadbbc3f0eafb8d4ccaf6..4d5bca0e8220e2c8691ea0e914e870c6581165ea 100644 --- a/applications/utilities/mesh/generation/extrudeMesh/extrudeMesh.C +++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeMesh.C @@ -36,13 +36,15 @@ Description #include "Time.H" #include "dimensionedTypes.H" #include "IFstream.H" -#include "faceMesh.H" #include "polyTopoChange.H" #include "polyTopoChanger.H" #include "edgeCollapser.H" #include "mathematicalConstants.H" #include "globalMeshData.H" #include "perfectInterface.H" +#include "addPatchCellLayer.H" +#include "fvMesh.H" +#include "MeshedSurfaces.H" #include "extrudedMesh.H" #include "extrudeModel.H" @@ -50,14 +52,148 @@ Description using namespace Foam; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +enum ExtrudeMode +{ + MESH, + PATCH, + SURFACE +}; + +template<> +const char* NamedEnum<ExtrudeMode, 3>::names[] = +{ + "mesh", + "patch", + "surface" +}; +static const NamedEnum<ExtrudeMode, 3> ExtrudeModeNames; + + +void createDummyFvMeshFiles(const polyMesh& mesh, const word& regionName) +{ + // Create dummy system/fv* + { + IOobject io + ( + "fvSchemes", + mesh.time().system(), + regionName, + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ); + + Info<< "Testing:" << io.objectPath() << endl; + + if (!io.headerOk()) + { + Info<< "Writing dummy " << regionName/io.name() << endl; + dictionary dummyDict; + dictionary divDict; + dummyDict.add("divSchemes", divDict); + dictionary gradDict; + dummyDict.add("gradSchemes", gradDict); + dictionary laplDict; + dummyDict.add("laplacianSchemes", laplDict); + + IOdictionary(io, dummyDict).regIOobject::write(); + } + } + { + IOobject io + ( + "fvSolution", + mesh.time().system(), + regionName, + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ); + + if (!io.headerOk()) + { + Info<< "Writing dummy " << regionName/io.name() << endl; + dictionary dummyDict; + IOdictionary(io, dummyDict).regIOobject::write(); + } + } +} + + +label findPatchID(const polyBoundaryMesh& patches, const word& name) +{ + label patchID = patches.findPatchID(name); + + if (patchID == -1) + { + FatalErrorIn("findPatchID(const polyBoundaryMesh&, const word&)") + << "Cannot find patch " << name + << " in the source mesh.\n" + << "Valid patch names are " << patches.names() + << exit(FatalError); + } + return patchID; +} + + +labelList patchFaces(const polyBoundaryMesh& patches, const word& name) +{ + label patchID = findPatchID(patches, name); + const polyPatch& pp = patches[patchID]; + + return identity(pp.size()) + pp.start(); +} + + +void updateFaceLabels(const mapPolyMesh& map, labelList& faceLabels) +{ + const labelList& reverseMap = map.reverseFaceMap(); + + labelList newFaceLabels(faceLabels.size()); + label newI = 0; + + forAll(faceLabels, i) + { + label oldFaceI = faceLabels[i]; + + if (reverseMap[oldFaceI] >= 0) + { + newFaceLabels[newI++] = reverseMap[oldFaceI]; + } + } + newFaceLabels.setSize(newI); + faceLabels.transfer(newFaceLabels); +} + + + // Main program: int main(int argc, char *argv[]) { + #include "addRegionOption.H" #include "setRootCase.H" #include "createTimeExtruded.H" - autoPtr<extrudedMesh> meshPtr(NULL); + // Get optional regionName + word regionName; + word regionDir; + if (args.optionReadIfPresent("region", regionName)) + { + regionDir = regionName; + Info<< "Create mesh " << regionName << " for time = " + << runTimeExtruded.timeName() << nl << endl; + } + else + { + regionName = fvMesh::defaultRegion; + Info<< "Create mesh for time = " + << runTimeExtruded.timeName() << nl << endl; + } + IOdictionary dict ( @@ -65,26 +201,44 @@ int main(int argc, char *argv[]) ( "extrudeProperties", runTimeExtruded.constant(), + regionDir, runTimeExtruded, IOobject::MUST_READ ) ); + // Point generator autoPtr<extrudeModel> model(extrudeModel::New(dict)); - const word sourceType(dict.lookup("constructFrom")); + // Whether to flip normals + const Switch flipNormals(dict.lookup("flipNormals")); + + // What to extrude + const ExtrudeMode mode = ExtrudeModeNames.read + ( + dict.lookup("constructFrom") + ); + - autoPtr<faceMesh> fMesh; + // Generated mesh (one of either) + autoPtr<fvMesh> meshFromMesh; + autoPtr<polyMesh> meshFromSurface; - if (sourceType == "patch") + // Faces on front and back for stitching (in case of mergeFaces) + word frontPatchName; + labelList frontPatchFaces; + word backPatchName; + labelList backPatchFaces; + + if (mode == PATCH || mode == MESH) { fileName sourceCasePath(dict.lookup("sourceCase")); sourceCasePath.expand(); fileName sourceRootDir = sourceCasePath.path(); fileName sourceCaseDir = sourceCasePath.name(); - word patchName(dict.lookup("sourcePatch")); + dict.lookup("sourcePatch") >> frontPatchName; - Info<< "Extruding patch " << patchName + Info<< "Extruding patch " << frontPatchName << " on mesh " << sourceCasePath << nl << endl; @@ -94,31 +248,183 @@ int main(int argc, char *argv[]) sourceRootDir, sourceCaseDir ); - #include "createPolyMesh.H" + #include "createMesh.H" + + const polyBoundaryMesh& patches = mesh.boundaryMesh(); - label patchID = mesh.boundaryMesh().findPatchID(patchName); - if (patchID == -1) + // Topo change container. Either copy an existing mesh or start + // with empty storage (number of patches only needed for checking) + autoPtr<polyTopoChange> meshMod + ( + ( + mode == MESH + ? new polyTopoChange(mesh) + : new polyTopoChange(patches.size()) + ) + ); + + // Extrusion engine. Either adding to existing mesh or + // creating separate mesh. + addPatchCellLayer layerExtrude(mesh, (mode == MESH)); + + indirectPrimitivePatch extrudePatch + ( + IndirectList<face> + ( + mesh.faces(), + patchFaces(patches, frontPatchName) + ), + mesh.points() + ); + + // Only used for addPatchCellLayer into new mesh + labelList exposedPatchIDs; + if (mode == PATCH) { - FatalErrorIn(args.executable()) - << "Cannot find patch " << patchName - << " in the source mesh.\n" - << "Valid patch names are " << mesh.boundaryMesh().names() - << exit(FatalError); + dict.lookup("exposedPatchName") >> backPatchName; + exposedPatchIDs.setSize + ( + extrudePatch.size(), + findPatchID(patches, backPatchName) + ); } - const polyPatch& pp = mesh.boundaryMesh()[patchID]; - fMesh.reset(new faceMesh(pp.localFaces(), pp.localPoints())); + pointField layer0Points(extrudePatch.nPoints()); + pointField displacement(extrudePatch.nPoints()); + forAll(displacement, pointI) { - fileName surfName(runTime.path()/patchName + ".sMesh"); - Info<< "Writing patch as surfaceMesh to " - << surfName << nl << endl; - OFstream os(surfName); - os << fMesh() << nl; + const vector& patchNormal = extrudePatch.pointNormals()[pointI]; + + // layer0 point + layer0Points[pointI] = model() + ( + extrudePatch.localPoints()[pointI], + patchNormal, + 0 + ); + // layerN point + point extrudePt = model() + ( + extrudePatch.localPoints()[pointI], + patchNormal, + model().nLayers() + ); + displacement[pointI] = extrudePt - layer0Points[pointI]; + } + + if (flipNormals) + { + Info<< "Flipping faces." << nl << endl; + displacement = -displacement; } + + // Check if wedge (has layer0 different from original patch points) + // If so move the mesh to starting position. + if (gMax(mag(layer0Points-extrudePatch.localPoints())) > SMALL) + { + Info<< "Moving mesh to layer0 points since differ from original" + << " points - this can happen for wedge extrusions." << nl + << endl; + + pointField newPoints(mesh.points()); + forAll(extrudePatch.meshPoints(), i) + { + newPoints[extrudePatch.meshPoints()[i]] = layer0Points[i]; + } + mesh.movePoints(newPoints); + } + + + // Layers per face + labelList nFaceLayers(extrudePatch.size(), model().nLayers()); + // Layers per point + labelList nPointLayers(extrudePatch.nPoints(), model().nLayers()); + // Displacement for first layer + vectorField firstLayerDisp = displacement*model().sumThickness(1); + // Expansion ratio not used. + scalarField ratio(extrudePatch.nPoints(), 1.0); + + layerExtrude.setRefinement + ( + ratio, // expansion ratio + extrudePatch, // patch faces to extrude + exposedPatchIDs, // if new mesh: patches for exposed faces + nFaceLayers, + nPointLayers, + firstLayerDisp, + meshMod() + ); + + // Reset points according to extrusion model + forAll(layerExtrude.addedPoints(), pointI) + { + const labelList& pPoints = layerExtrude.addedPoints()[pointI]; + forAll(pPoints, pPointI) + { + label meshPointI = pPoints[pPointI]; + + point modelPt + ( + model() + ( + extrudePatch.localPoints()[pointI], + extrudePatch.pointNormals()[pointI], + pPointI+1 // layer + ) + ); + + const_cast<DynamicList<point>&> + ( + meshMod().points() + )[meshPointI] = modelPt; + } + } + + // Store faces on front and exposed patch (if mode=patch there are + // only added faces so cannot used map to old faces) + const labelListList& layerFaces = layerExtrude.layerFaces(); + backPatchFaces.setSize(layerFaces.size()); + frontPatchFaces.setSize(layerFaces.size()); + forAll(backPatchFaces, i) + { + backPatchFaces[i] = layerFaces[i][0]; + frontPatchFaces[i] = layerFaces[i][layerFaces[i].size()-1]; + } + + // Create dummy fvSchemes, fvSolution + createDummyFvMeshFiles(mesh, regionDir); + + // Create actual mesh from polyTopoChange container + autoPtr<mapPolyMesh> map = meshMod().makeMesh + ( + meshFromMesh, + IOobject + ( + regionName, + runTimeExtruded.constant(), + runTimeExtruded, + IOobject::NO_READ, + IOobject::AUTO_WRITE, + false + ), + mesh + ); + + // Calculate face labels for front and back. + frontPatchFaces = renumber + ( + map().reverseFaceMap(), + frontPatchFaces + ); + backPatchFaces = renumber + ( + map().reverseFaceMap(), + backPatchFaces + ); } - else if (sourceType == "surface") + else { // Read from surface fileName surfName(dict.lookup("surface")); @@ -126,52 +432,62 @@ int main(int argc, char *argv[]) Info<< "Extruding surfaceMesh read from file " << surfName << nl << endl; - IFstream is(surfName); + MeshedSurface<face> fMesh(surfName); - fMesh.reset(new faceMesh(is)); + if (flipNormals) + { + Info<< "Flipping faces." << nl << endl; + faceList& faces = const_cast<faceList&>(fMesh.faces()); + forAll(faces, i) + { + faces[i] = fMesh[i].reverseFace(); + } + } - Info<< "Read patch from file " << surfName << nl - << endl; - } - else - { - FatalErrorIn(args.executable()) - << "Illegal 'constructFrom' specification. Should either be " - << "patch or surface." << exit(FatalError); - } + Info<< "Extruding surface with :" << nl + << " points : " << fMesh.points().size() << nl + << " faces : " << fMesh.size() << nl + << " normals[0] : " << fMesh.faceNormals()[0] + << nl + << endl; - Switch flipNormals(dict.lookup("flipNormals")); + meshFromSurface.reset + ( + new extrudedMesh + ( + IOobject + ( + extrudedMesh::defaultRegion, + runTimeExtruded.constant(), + runTimeExtruded + ), + fMesh, + model() + ) + ); - if (flipNormals) - { - Info<< "Flipping faces." << nl << endl; - faceList faces(fMesh().size()); - forAll(faces, i) - { - faces[i] = fMesh()[i].reverseFace(); - } - fMesh.reset(new faceMesh(faces, fMesh().localPoints())); + // Get the faces on front and back + frontPatchName = "originalPatch"; + frontPatchFaces = patchFaces + ( + meshFromSurface().boundaryMesh(), + frontPatchName + ); + backPatchName = "otherSide"; + backPatchFaces = patchFaces + ( + meshFromSurface().boundaryMesh(), + backPatchName + ); } - Info<< "Extruding patch with :" << nl - << " points : " << fMesh().points().size() << nl - << " faces : " << fMesh().size() << nl - << " normals[0] : " << fMesh().faceNormals()[0] - << nl - << endl; - - extrudedMesh mesh + polyMesh& mesh = ( - IOobject - ( - extrudedMesh::defaultRegion, - runTimeExtruded.constant(), - runTimeExtruded - ), - fMesh(), - model() + meshFromMesh.valid() + ? meshFromMesh() + : meshFromSurface() ); @@ -184,17 +500,6 @@ int main(int argc, char *argv[]) << "Merge distance : " << mergeDim << nl << endl; - const polyBoundaryMesh& patches = mesh.boundaryMesh(); - - const label origPatchID = patches.findPatchID("originalPatch"); - const label otherPatchID = patches.findPatchID("otherSide"); - - if (origPatchID == -1 || otherPatchID == -1) - { - FatalErrorIn(args.executable()) - << "Cannot find patch originalPatch or otherSide." << nl - << "Valid patches are " << patches.names() << exit(FatalError); - } // Collapse edges // ~~~~~~~~~~~~~~ @@ -237,6 +542,10 @@ int main(int argc, char *argv[]) // Update fields mesh.updateMesh(map); + // Update stored data + updateFaceLabels(map(), frontPatchFaces); + updateFaceLabels(map(), backPatchFaces); + // Move mesh (if inflation used) if (map().hasMotionPoints()) { @@ -252,22 +561,33 @@ int main(int argc, char *argv[]) Switch mergeFaces(dict.lookup("mergeFaces")); if (mergeFaces) { + if (mode == MESH) + { + FatalErrorIn(args.executable()) + << "Cannot stitch front and back of extrusion since" + << " in 'mesh' mode (extrusion appended to mesh)." + << exit(FatalError); + } + Info<< "Assuming full 360 degree axisymmetric case;" << " stitching faces on patches " - << patches[origPatchID].name() << " and " - << patches[otherPatchID].name() << " together ..." << nl << endl; - - polyTopoChanger stitcher(mesh); - stitcher.setSize(1); - - // Make list of masterPatch faces - labelList isf(patches[origPatchID].size()); + << frontPatchName << " and " + << backPatchName << " together ..." << nl << endl; - forAll (isf, i) + if (frontPatchFaces.size() != backPatchFaces.size()) { - isf[i] = patches[origPatchID].start() + i; + FatalErrorIn(args.executable()) + << "Differing number of faces on front (" + << frontPatchFaces.size() << ") and back (" + << backPatchFaces.size() << ")" + << exit(FatalError); } + + + polyTopoChanger stitcher(mesh); + stitcher.setSize(1); + const word cutZoneName("originalCutFaceZone"); List<faceZone*> fz @@ -276,8 +596,8 @@ int main(int argc, char *argv[]) new faceZone ( cutZoneName, - isf, - boolList(isf.size(), false), + frontPatchFaces, + boolList(frontPatchFaces.size(), false), 0, mesh.faceZones() ) @@ -286,26 +606,58 @@ int main(int argc, char *argv[]) mesh.addZones(List<pointZone*>(0), fz, List<cellZone*>(0)); // Add the perfect interface mesh modifier - stitcher.set + perfectInterface perfectStitcher ( + "couple", 0, - new perfectInterface + stitcher, + cutZoneName, + word::null, // dummy patch name + word::null // dummy patch name + ); + + // Topo change container + polyTopoChange meshMod(mesh); + + perfectStitcher.setRefinement + ( + indirectPrimitivePatch ( - "couple", - 0, - stitcher, - cutZoneName, - patches[origPatchID].name(), - patches[otherPatchID].name() - ) + IndirectList<face> + ( + mesh.faces(), + frontPatchFaces + ), + mesh.points() + ), + indirectPrimitivePatch + ( + IndirectList<face> + ( + mesh.faces(), + backPatchFaces + ), + mesh.points() + ), + meshMod ); - // Execute all polyMeshModifiers - autoPtr<mapPolyMesh> morphMap = stitcher.changeMesh(true); + // Construct new mesh from polyTopoChange. + autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false); + + // Update fields + mesh.updateMesh(map); - mesh.movePoints(morphMap->preMotionPoints()); + // Move mesh (if inflation used) + if (map().hasMotionPoints()) + { + mesh.movePoints(map().preMotionPoints()); + } } + mesh.setInstance(runTimeExtruded.constant()); + Info<< "Writing mesh to " << mesh.objectPath() << nl << endl; + if (!mesh.write()) { FatalErrorIn(args.executable()) << "Failed writing mesh" diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/extrudeModel/extrudeModel.C b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/extrudeModel/extrudeModel.C index 7305431b96971e591123ccaf5f7696528486db1f..5550c56b15249e78e55725d39914a3c6b1ea4fb8 100644 --- a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/extrudeModel/extrudeModel.C +++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/extrudeModel/extrudeModel.C @@ -43,6 +43,7 @@ Foam::extrudeModel::extrudeModel ) : nLayers_(readLabel(dict.lookup("nLayers"))), + expansionRatio_(readScalar(dict.lookup("expansionRatio"))), dict_(dict), coeffDict_(dict.subDict(modelType + "Coeffs")) {} @@ -62,5 +63,28 @@ Foam::label Foam::extrudeModel::nLayers() const } +Foam::scalar Foam::extrudeModel::expansionRatio() const +{ + return expansionRatio_; +} + + +Foam::scalar Foam::extrudeModel::sumThickness(const label layer) const +{ + // 1+r+r^2+ .. +r^(n-1) = (1-r^n)/(1-r) + + if (mag(1.0-expansionRatio_) < SMALL) + { + return scalar(layer)/nLayers_; + } + else + { + return + (1.0-pow(expansionRatio_, layer)) + / (1.0-pow(expansionRatio_, nLayers_)); + } +} + + // ************************************************************************* // diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/extrudeModel/extrudeModel.H b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/extrudeModel/extrudeModel.H index d8f3699fd5a2d0d3fd8334444b0a63d4ef981dd0..ac96bbeea6324e18d81a3ed42a7ebb161c03045a 100644 --- a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/extrudeModel/extrudeModel.H +++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/extrudeModel/extrudeModel.H @@ -58,6 +58,8 @@ protected: const label nLayers_; + const scalar expansionRatio_; + const dictionary& dict_; const dictionary& coeffDict_; @@ -113,9 +115,15 @@ public: label nLayers() const; + scalar expansionRatio() const; + // Member Operators + //- Helper: calculate cumulative relative thickness for layer. + // (layer=0 -> 0; layer=nLayers -> 1) + scalar sumThickness(const label layer) const; + virtual point operator() ( const point& surfacePoint, diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/linearNormal/linearNormal.C b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/linearNormal/linearNormal.C index c36098ab1e6a3cf10b748a84e7062524ad9e3fd9..cd42e918169e0431d3c35ac84deed960bccc7711 100644 --- a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/linearNormal/linearNormal.C +++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/linearNormal/linearNormal.C @@ -72,7 +72,8 @@ point linearNormal::operator() const label layer ) const { - scalar d = thickness_*layer/nLayers_; + //scalar d = thickness_*layer/nLayers_; + scalar d = thickness_*sumThickness(layer); return surfacePoint + d*surfaceNormal; } diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/linearNormal/linearNormal.H b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/linearNormal/linearNormal.H index 949547311b39d8c8cb191f69be04d0cf7c34e948..2dbcdccb162592ee75691124905b1d48bdb4c2a1 100644 --- a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/linearNormal/linearNormal.H +++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/linearNormal/linearNormal.H @@ -64,7 +64,7 @@ public: // Constructors - //- Construct from components + //- Construct from dictionary linearNormal(const dictionary& dict); diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/linearRadial/linearRadial.C b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/linearRadial/linearRadial.C index e8d406b110ad12350b00f733de5f0ad30ac40771..7d4fcff9ba02e8a348be0baa89787155dbcdb7fb 100644 --- a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/linearRadial/linearRadial.C +++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/linearRadial/linearRadial.C @@ -67,8 +67,7 @@ point linearRadial::operator() scalar rs = mag(surfacePoint); vector rsHat = surfacePoint/rs; - scalar delta = (R_ - rs)/nLayers_; - scalar r = rs + layer*delta; + scalar r = rs + (R_ - rs)*sumThickness(layer); return r*rsHat; } diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/linearRadial/linearRadial.H b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/linearRadial/linearRadial.H index 0fda12e1b14e8c49c18d7d24cfee56ff9ed5fd8c..66758c1b12897e64ebc01d4d98b519b4ed1c3262 100644 --- a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/linearRadial/linearRadial.H +++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/linearRadial/linearRadial.H @@ -61,7 +61,7 @@ public: // Constructors - //- Construct from components + //- Construct from dictionary linearRadial(const dictionary& dict); diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/sigmaRadial/sigmaRadial.C b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/sigmaRadial/sigmaRadial.C index fc6f04030504f04e57a14c7d5d447a0a3e754510..d35ad4e539447972ef603a8a9469a6276b140990 100644 --- a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/sigmaRadial/sigmaRadial.C +++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/sigmaRadial/sigmaRadial.C @@ -49,7 +49,13 @@ sigmaRadial::sigmaRadial(const dictionary& dict) RTbyg_(readScalar(coeffDict_.lookup("RTbyg"))), pRef_(readScalar(coeffDict_.lookup("pRef"))), pStrat_(readScalar(coeffDict_.lookup("pStrat"))) -{} +{ + if (mag(expansionRatio() - 1.0) > SMALL) + { + WarningIn("sigmaRadial::sigmaRadial(const dictionary&)") + << "Ignoring expansionRatio setting." << endl; + } +} // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/sigmaRadial/sigmaRadial.H b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/sigmaRadial/sigmaRadial.H index 525e89d11c94aa96a31ec11b65916b4c9ca06627..c74ad024575998d06364129abf3a1cf24e70c0c2 100644 --- a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/sigmaRadial/sigmaRadial.H +++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/sigmaRadial/sigmaRadial.H @@ -63,7 +63,7 @@ public: // Constructors - //- Construct from components + //- Construct from dictionary sigmaRadial(const dictionary& dict); diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.C b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.C index 3d2c883ea1901edb740f8afdd7de3c9b634858a2..5d0a3621b43c8752a1da56dfd950a41900f51e2f 100644 --- a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.C +++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.C @@ -88,8 +88,8 @@ point wedge::operator() } else { - //sliceAngle = angle_*(layer + 1)/nLayers_; - sliceAngle = angle_*layer/nLayers_; + //sliceAngle = angle_*layer/nLayers_; + sliceAngle = angle_*sumThickness(layer); } // Find projection onto axis (or rather decompose surfacePoint diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.H b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.H index 39c4b4a2d3073ade350e8c5db80f6faea29b5d5b..18707c32d11a560fde7ec582741318ec89bce799 100644 --- a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.H +++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.H @@ -77,7 +77,7 @@ public: // Constructors - //- Construct from components + //- Construct from dictionary wedge(const dictionary& dict); diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeProperties b/applications/utilities/mesh/generation/extrudeMesh/extrudeProperties index 45618034deb13b6a1e5c55bfc02e7bedd9928203..e1283ab8b59d0ba2220a815ee375f242d1e452f4 100644 --- a/applications/utilities/mesh/generation/extrudeMesh/extrudeProperties +++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeProperties @@ -14,24 +14,28 @@ FoamFile } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -// Where to get surface from: either from surface ('surface') or -// from (flipped) patch of existing case ('patch') -constructFrom patch; //surface; +// What to extrude: +// patch : from patch of another case ('sourceCase') +// mesh : as above but with original case included +// surface : from externally read surface -// If construct from (flipped) patch -sourceCase "$FOAM_RUN/icoFoam/cavity"; +//constructFrom mesh; +constructFrom patch; +//constructFrom surface; + +// If construct from patch/mesh: +sourceCase "../cavity"; sourcePatch movingWall; +// If construct from patch: patch to use for back (can be same as sourcePatch) +exposedPatchName movingWall; +// If construct from surface: +surface "movingWall.stl"; -// Flip surface normals before usage. -flipNormals false; -// If construct from surface -surface "movingWall.sMesh"; +// Flip surface normals before usage. +flipNormals false; -// Do front and back need to be merged? Usually only makes sense for 360 -// degree wedges. -mergeFaces true; //- Linear extrusion in point-normal direction @@ -46,11 +50,13 @@ extrudeModel wedge; //- Extrudes into sphere with grading according to pressure (atmospherics) //extrudeModel sigmaRadial; -nLayers 20; +nLayers 10; + +expansionRatio 1.0; //0.9; wedgeCoeffs { - axisPt (0 0.1 0); + axisPt (0 0.1 -0.05); axis (-1 0 0); angle 360; // For nLayers=1 assume symmetry so angle/2 on each side } @@ -73,5 +79,10 @@ sigmaRadialCoeffs } +// Do front and back need to be merged? Usually only makes sense for 360 +// degree wedges. +mergeFaces true; + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/applications/utilities/mesh/generation/extrudeMesh/faceMesh.H b/applications/utilities/mesh/generation/extrudeMesh/faceMesh.H deleted file mode 100644 index c8e1075f52e5f31ceba4f8930ad6be4dbab9158e..0000000000000000000000000000000000000000 --- a/applications/utilities/mesh/generation/extrudeMesh/faceMesh.H +++ /dev/null @@ -1,114 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -Class - Foam::faceMesh - -Description - Storage for surface mesh i.e. points and faces. - -SourceFiles - -\*---------------------------------------------------------------------------*/ - -#ifndef faceMesh_H -#define faceMesh_H - -#include "PrimitivePatch.H" -#include "faceList.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -/*---------------------------------------------------------------------------*\ - Class faceMesh Declaration -\*---------------------------------------------------------------------------*/ - -class faceMesh -: - public PrimitivePatch<face, List, pointField> -{ - // Private member functions - - PrimitivePatch<face, List, pointField> read(Istream& is) - { - pointField points(is); - faceList faces(is); - return PrimitivePatch<face, Foam::List, pointField>(faces, points); - } - - -public: - - // Constructors - - //- Construct from components - faceMesh(const faceList& faces, const pointField& points) - : - PrimitivePatch<face, Foam::List, pointField>(faces, points) - {} - - //- Construct from Istream - faceMesh(Istream& is) - : - PrimitivePatch<face, Foam::List, pointField>(read(is)) - {} - - - // Member Functions - - void flip() - { - forAll(*this, i) - { - face& f = operator[](i); - f = f.reverseFace(); - } - clearOut(); - } - - // IOstream Operators - - friend Ostream& operator<<(Ostream& os, const faceMesh& fm) - { - return os - << fm.points() - << token::NL - << static_cast<PrimitivePatch<face, Foam::List, pointField> > - (fm); - } -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/applications/utilities/mesh/manipulation/createPatch/createPatch.C b/applications/utilities/mesh/manipulation/createPatch/createPatch.C index 7d74e7208c2e552d4bf0cc3af9d05b19ec8c64ef..40ba0efadebc02dec26e5de383e6fef0634a6c93 100644 --- a/applications/utilities/mesh/manipulation/createPatch/createPatch.C +++ b/applications/utilities/mesh/manipulation/createPatch/createPatch.C @@ -208,8 +208,8 @@ void dumpCyclicMatch(const fileName& prefix, const polyMesh& mesh) // Dump halves { OFstream str(prefix+cycPatch.name()+"_half0.obj"); - Pout<< "Dumping cycPatch.name() half0 faces to " << str.name() - << endl; + Pout<< "Dumping " << cycPatch.name() + << " half0 faces to " << str.name() << endl; meshTools::writeOBJ ( str, @@ -226,8 +226,8 @@ void dumpCyclicMatch(const fileName& prefix, const polyMesh& mesh) } { OFstream str(prefix+cycPatch.name()+"_half1.obj"); - Pout<< "Dumping cycPatch.name() half1 faces to " << str.name() - << endl; + Pout<< "Dumping " << cycPatch.name() + << " half1 faces to " << str.name() << endl; meshTools::writeOBJ ( str, @@ -563,7 +563,7 @@ int main(int argc, char *argv[]) dumpCyclicMatch("initial_", mesh); // Read patch construct info from dictionary - PtrList<dictionary> patchSources(dict.lookup("patches")); + PtrList<dictionary> patchSources(dict.lookup("patchInfo")); diff --git a/applications/utilities/mesh/manipulation/createPatch/createPatchDict b/applications/utilities/mesh/manipulation/createPatch/createPatchDict index 9704392a10ea95e23f5afbe02a9c45bbbc736406..b8676f134d3798461fd5d0a7b8bed1af21151d4b 100644 --- a/applications/utilities/mesh/manipulation/createPatch/createPatchDict +++ b/applications/utilities/mesh/manipulation/createPatch/createPatchDict @@ -46,7 +46,7 @@ matchTolerance 1E-3; pointSync true; // Patches to create. -patches +patchInfo ( { // Name of new patch diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C index fea25e35eb8a6e64bfd01564cda14d42299d1403..716bdc6ddfacb967f4e97c2a2e7481327bb6af86 100644 --- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C +++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C @@ -2987,6 +2987,7 @@ void Foam::autoLayerDriver::addLayers ( invExpansionRatio, pp, + labelList(0), // exposed patchIDs, not used for adding layers nPatchFaceLayers, // layers per face nPatchPointLayers, // layers per point firstDisp, // thickness of layer nearest internal mesh diff --git a/src/dynamicMesh/perfectInterface/perfectInterface.C b/src/dynamicMesh/perfectInterface/perfectInterface.C index 80c9ed65836a807e8d87988cb6738d49320ad3dc..ee892b7e873dee29a6ee6fc89e7a9aad1c50cdfa 100644 --- a/src/dynamicMesh/perfectInterface/perfectInterface.C +++ b/src/dynamicMesh/perfectInterface/perfectInterface.C @@ -38,6 +38,7 @@ Description #include "polyModifyFace.H" #include "polyRemovePoint.H" #include "polyRemoveFace.H" +#include "indirectPrimitivePatch.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -61,7 +62,7 @@ const Foam::scalar Foam::perfectInterface::tol_ = 1E-3; Foam::pointField Foam::perfectInterface::calcFaceCentres ( - const primitivePatch& pp + const indirectPrimitivePatch& pp ) { const pointField& points = pp.points(); @@ -155,307 +156,335 @@ bool Foam::perfectInterface::changeTopology() const } -void Foam::perfectInterface::setRefinement(polyTopoChange& ref) const +void Foam::perfectInterface::setRefinement +( + const indirectPrimitivePatch& pp0, + const indirectPrimitivePatch& pp1, + polyTopoChange& ref +) const { - if (debug) + const polyMesh& mesh = topoChanger().mesh(); + + const polyBoundaryMesh& patches = mesh.boundaryMesh(); + + // Some aliases + const edgeList& edges0 = pp0.edges(); + const pointField& pts0 = pp0.localPoints(); + const pointField& pts1 = pp1.localPoints(); + const labelList& meshPts0 = pp0.meshPoints(); + const labelList& meshPts1 = pp1.meshPoints(); + + + // Get local dimension as fraction of minimum edge length + + scalar minLen = GREAT; + + forAll(edges0, edgeI) { - Pout<< "bool perfectInterface::setRefinement(polyTopoChange&) const : " - << "for object " << name() << " : " - << "masterPatchID_:" << masterPatchID_ - << " slavePatchID_:" << slavePatchID_ - << " faceZoneID_:" << faceZoneID_ << endl; + minLen = min(minLen, edges0[edgeI].mag(pts0)); } + scalar typDim = tol_*minLen; - if - ( - masterPatchID_.active() - && slavePatchID_.active() - && faceZoneID_.active() - ) + if (debug) { - const polyMesh& mesh = topoChanger().mesh(); - - const polyBoundaryMesh& patches = mesh.boundaryMesh(); + Pout<< "typDim:" << typDim << " edges0:" << edges0.size() + << " pts0:" << pts0.size() << " pts1:" << pts1.size() + << " pp0:" << pp0.size() << " pp1:" << pp1.size() << endl; + } - const polyPatch& pp0 = patches[masterPatchID_.index()]; - const polyPatch& pp1 = patches[slavePatchID_.index()]; - // Some aliases - const edgeList& edges0 = pp0.edges(); - const pointField& pts0 = pp0.localPoints(); - const pointField& pts1 = pp1.localPoints(); - const labelList& meshPts0 = pp0.meshPoints(); - const labelList& meshPts1 = pp1.meshPoints(); - + // Determine pointMapping in mesh point labels. Uses geometric + // comparison to find correspondence between patch points. - // Get local dimension as fraction of minimum edge length + labelList renumberPoints(mesh.points().size()); + forAll(renumberPoints, i) + { + renumberPoints[i] = i; + } + { + labelList from1To0Points(pts1.size()); - scalar minLen = GREAT; + bool matchOk = matchPoints + ( + pts1, + pts0, + scalarField(pts1.size(), typDim), // tolerance + true, // verbose + from1To0Points + ); - forAll(edges0, edgeI) + if (!matchOk) { - minLen = min(minLen, edges0[edgeI].mag(pts0)); + FatalErrorIn + ( + "perfectInterface::setRefinement(polyTopoChange& ref) const" + ) << "Points on patch sides do not match to within tolerance " + << typDim << exit(FatalError); } - scalar typDim = tol_*minLen; - if (debug) + forAll(pts1, i) { - Pout<< "typDim:" << typDim << " edges0:" << edges0.size() - << " pts0:" << pts0.size() << " pts1:" << pts1.size() - << " pp0:" << pp0.size() << " pp1:" << pp1.size() << endl; + renumberPoints[meshPts1[i]] = meshPts0[from1To0Points[i]]; } + } - // Determine pointMapping in mesh point labels. Uses geometric - // comparison to find correspondence between patch points. - labelList renumberPoints(mesh.points().size()); - forAll(renumberPoints, i) - { - renumberPoints[i] = i; - } - { - labelList from1To0Points(pts1.size()); + // Calculate correspondence between patch faces - bool matchOk = matchPoints - ( - pts1, - pts0, - scalarField(pts1.size(), typDim), // tolerance - true, // verbose - from1To0Points - ); + labelList from0To1Faces(pp1.size()); - if (!matchOk) - { - FatalErrorIn - ( - "perfectInterface::setRefinement(polyTopoChange& ref) const" - ) << "Points on patches " << pp0.name() << " and " - << pp1.name() << " do not match to within tolerance " - << typDim << exit(FatalError); - } + bool matchOk = matchPoints + ( + calcFaceCentres(pp0), + calcFaceCentres(pp1), + scalarField(pp0.size(), typDim), // tolerance + true, // verbose + from0To1Faces + ); - forAll(pts1, i) - { - renumberPoints[meshPts1[i]] = meshPts0[from1To0Points[i]]; - } - } + if (!matchOk) + { + FatalErrorIn + ( + "perfectInterface::setRefinement(polyTopoChange& ref) const" + ) << "Face centres of patch sides do not match to within tolerance " + << typDim << exit(FatalError); + } - // Calculate correspondence between patch faces + // Now + // - renumber faces using pts1 (except patch1 faces) + // - remove patch1 faces. Remember cell label on owner side. + // - modify patch0 faces to be internal. - labelList from0To1Faces(pp1.size()); + // 1. Get faces to be renumbered + labelHashSet affectedFaces(2*pp1.size()); + forAll(meshPts1, i) + { + label meshPointI = meshPts1[i]; - bool matchOk = matchPoints - ( - calcFaceCentres(pp0), - calcFaceCentres(pp1), - scalarField(pp0.size(), typDim), // tolerance - true, // verbose - from0To1Faces - ); + if (meshPointI != renumberPoints[meshPointI]) + { + const labelList& pFaces = mesh.pointFaces()[meshPointI]; - if (!matchOk) + forAll(pFaces, pFaceI) + { + affectedFaces.insert(pFaces[pFaceI]); + } + } + } + forAll(pp1, i) + { + affectedFaces.erase(pp1.addressing()[i]); + } + // Remove patch0 from renumbered faces. Should not be nessecary since + // patch0 and 1 should not share any point (if created by mergeMeshing) + // so affectedFaces should not contain any patch0 faces but you can + // never be sure what the user is doing. + forAll(pp0, i) + { + label faceI = pp0.addressing()[i]; + + if (affectedFaces.erase(faceI)) { - FatalErrorIn + WarningIn ( - "perfectInterface::setRefinement(polyTopoChange& ref) const" - ) << "Face centres of patches " << pp0.name() << " and " - << pp1.name() << " do not match to within tolerance " << typDim - << exit(FatalError); + "perfectInterface::setRefinement(polyTopoChange&) const" + ) << "Found face " << faceI << " vertices " + << mesh.faces()[faceI] << " whose points are" + << " used both by master patch and slave patch" << endl; } + } + // 2. Renumber (non patch0/1) faces. + for + ( + labelHashSet::const_iterator iter = affectedFaces.begin(); + iter != affectedFaces.end(); + ++iter + ) + { + label faceI = iter.key(); - // Now - // - renumber faces using pts1 (except patch1 faces) - // - remove patch1 faces. Remember cell label on owner side. - // - modify patch0 faces to be internal. + const face& f = mesh.faces()[faceI]; - // 1. Get faces to be renumbered - labelHashSet affectedFaces(2*pp1.size()); - forAll(meshPts1, i) + face newFace(f.size()); + + forAll(newFace, fp) { - label meshPointI = meshPts1[i]; + newFace[fp] = renumberPoints[f[fp]]; + } - if (meshPointI != renumberPoints[meshPointI]) - { - const labelList& pFaces = mesh.pointFaces()[meshPointI]; + label nbr = -1; - forAll(pFaces, pFaceI) - { - affectedFaces.insert(pFaces[pFaceI]); - } - } - } - forAll(pp1, i) + label patchI = -1; + + if (mesh.isInternalFace(faceI)) { - affectedFaces.erase(pp1.start() + i); + nbr = mesh.faceNeighbour()[faceI]; } - // Remove patch0 from renumbered faces. Should not be nessecary since - // patch0 and 1 should not share any point (if created by mergeMeshing) - // so affectedFaces should not contain any patch0 faces but you can - // never be sure what the user is doing. - forAll(pp0, i) + else { - if (affectedFaces.erase(pp0.start() + i)) - { - WarningIn - ( - "perfectInterface::setRefinement(polyTopoChange&) const" - ) << "Found face " << pp0.start() + i << " vertices " - << mesh.faces()[pp0.start() + i] << " whose points are" - << " used both by master patch " << pp0.name() - << " and slave patch " << pp1.name() - << endl; - } + patchI = patches.whichPatch(faceI); } + label zoneID = mesh.faceZones().whichZone(faceI); + + bool zoneFlip = false; - // 2. Renumber (non patch0/1) faces. - for + if (zoneID >= 0) + { + const faceZone& fZone = mesh.faceZones()[zoneID]; + + zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)]; + } + + ref.setAction ( - labelHashSet::const_iterator iter = affectedFaces.begin(); - iter != affectedFaces.end(); - ++iter - ) + polyModifyFace + ( + newFace, // modified face + faceI, // label of face being modified + mesh.faceOwner()[faceI], // owner + nbr, // neighbour + false, // face flip + patchI, // patch for face + false, // remove from zone + zoneID, // zone for face + zoneFlip // face flip in zone + ) + ); + } + + + // 3. Remove patch1 points + forAll(meshPts1, i) + { + label meshPointI = meshPts1[i]; + + if (meshPointI != renumberPoints[meshPointI]) { - label faceI = iter.key(); + ref.setAction(polyRemovePoint(meshPointI)); + } + } - const face& f = mesh.faces()[faceI]; - face newFace(f.size()); + // 4. Remove patch1 faces + forAll(pp1, i) + { + label faceI = pp1.addressing()[i]; + ref.setAction(polyRemoveFace(faceI)); + } - forAll(newFace, fp) - { - newFace[fp] = renumberPoints[f[fp]]; - } - label nbr = -1; + // 5. Modify patch0 faces for new points (not really nessecary; see + // comment above about patch1 and patch0 never sharing points) and + // becoming internal. + const boolList& mfFlip = + mesh.faceZones()[faceZoneID_.index()].flipMap(); + + forAll(pp0, i) + { + label faceI = pp0.addressing()[i]; - label patchI = -1; + const face& f = mesh.faces()[faceI]; - if (mesh.isInternalFace(faceI)) - { - nbr = mesh.faceNeighbour()[faceI]; - } - else - { - patchI = patches.whichPatch(faceI); - } + face newFace(f.size()); - label zoneID = mesh.faceZones().whichZone(faceI); + forAll(newFace, fp) + { + newFace[fp] = renumberPoints[f[fp]]; + } - bool zoneFlip = false; + label own = mesh.faceOwner()[faceI]; - if (zoneID >= 0) - { - const faceZone& fZone = mesh.faceZones()[zoneID]; + label pp1FaceI = pp1.addressing()[from0To1Faces[i]]; - zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)]; - } + label nbr = mesh.faceOwner()[pp1FaceI]; + if (own < nbr) + { ref.setAction ( polyModifyFace ( - newFace, // modified face - faceI, // label of face being modified - mesh.faceOwner()[faceI], // owner - nbr, // neighbour - false, // face flip - patchI, // patch for face - false, // remove from zone - zoneID, // zone for face - zoneFlip // face flip in zone + newFace, // modified face + faceI, // label of face being modified + own, // owner + nbr, // neighbour + false, // face flip + -1, // patch for face + false, // remove from zone + faceZoneID_.index(), // zone for face + mfFlip[i] // face flip in zone ) ); } - - - // 3. Remove patch1 points - forAll(meshPts1, i) - { - label meshPointI = meshPts1[i]; - - if (meshPointI != renumberPoints[meshPointI]) - { - ref.setAction(polyRemovePoint(meshPointI)); - } - } - - - // 4. Remove patch1 faces - forAll(pp1, i) + else { - ref.setAction(polyRemoveFace(pp1.start() + i)); + ref.setAction + ( + polyModifyFace + ( + newFace.reverseFace(), // modified face + faceI, // label of face being modified + nbr, // owner + own, // neighbour + true, // face flip + -1, // patch for face + false, // remove from zone + faceZoneID_.index(), // zone for face + !mfFlip[i] // face flip in zone + ) + ); } + } +} - // 5. Modify patch0 faces for new points (not really nessecary; see - // comment above about patch1 and patch0 never sharing points) and - // becoming internal. - const boolList& mfFlip = - mesh.faceZones()[faceZoneID_.index()].flipMap(); - - forAll(pp0, i) - { - label faceI = pp0.start() + i; - - const face& f = mesh.faces()[faceI]; +void Foam::perfectInterface::setRefinement(polyTopoChange& ref) const +{ + if (debug) + { + Pout<< "bool perfectInterface::setRefinement(polyTopoChange&) const : " + << "for object " << name() << " : " + << "masterPatchID_:" << masterPatchID_ + << " slavePatchID_:" << slavePatchID_ + << " faceZoneID_:" << faceZoneID_ << endl; + } - face newFace(f.size()); + if + ( + masterPatchID_.active() + && slavePatchID_.active() + && faceZoneID_.active() + ) + { + const polyMesh& mesh = topoChanger().mesh(); - forAll(newFace, fp) - { - newFace[fp] = renumberPoints[f[fp]]; - } + const polyBoundaryMesh& patches = mesh.boundaryMesh(); + const polyPatch& patch0 = patches[masterPatchID_.index()]; + const polyPatch& patch1 = patches[slavePatchID_.index()]; - label own = mesh.faceOwner()[faceI]; - label pp1FaceI = pp1.start() + from0To1Faces[i]; + labelList pp0Labels(identity(patch0.size())+patch0.start()); + indirectPrimitivePatch pp0 + ( + IndirectList<face>(mesh.faces(), pp0Labels), + mesh.points() + ); - label nbr = mesh.faceOwner()[pp1FaceI]; + labelList pp1Labels(identity(patch1.size())+patch1.start()); + indirectPrimitivePatch pp1 + ( + IndirectList<face>(mesh.faces(), pp1Labels), + mesh.points() + ); - if (own < nbr) - { - ref.setAction - ( - polyModifyFace - ( - newFace, // modified face - faceI, // label of face being modified - own, // owner - nbr, // neighbour - false, // face flip - -1, // patch for face - false, // remove from zone - faceZoneID_.index(), // zone for face - mfFlip[i] // face flip in zone - ) - ); - } - else - { - ref.setAction - ( - polyModifyFace - ( - newFace.reverseFace(), // modified face - faceI, // label of face being modified - nbr, // owner - own, // neighbour - false, // face flip - -1, // patch for face - false, // remove from zone - faceZoneID_.index(), // zone for face - !mfFlip[i] // face flip in zone - ) - ); - } - } + setRefinement(pp0, pp1, ref); } } diff --git a/src/dynamicMesh/perfectInterface/perfectInterface.H b/src/dynamicMesh/perfectInterface/perfectInterface.H index 3916bb3e74b6bfd647ddbb5a46a5b116a2d2910b..dec4f6a48d0448c894aff74d84410381acf0d78c 100644 --- a/src/dynamicMesh/perfectInterface/perfectInterface.H +++ b/src/dynamicMesh/perfectInterface/perfectInterface.H @@ -40,6 +40,7 @@ SourceFiles #include "polyMeshModifier.H" #include "polyPatchID.H" #include "ZoneIDs.H" +#include "indirectPrimitivePatch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -75,7 +76,7 @@ class perfectInterface // Private Member Functions //- Calculate face centres on patch - static pointField calcFaceCentres(const primitivePatch&); + static pointField calcFaceCentres(const indirectPrimitivePatch&); //- Disallow default bitwise copy construct @@ -128,6 +129,17 @@ public: // into the topological change virtual void setRefinement(polyTopoChange&) const; + //- Insert the layer addition/removal instructions + // into the topological change. Uses only mesh, not any of the + // patch and zone indices. Bit of a workaround - used in extruding + // a mesh. + virtual void setRefinement + ( + const indirectPrimitivePatch& pp0, + const indirectPrimitivePatch& pp1, + polyTopoChange& + ) const; + //- Modify motion points to comply with the topological change virtual void modifyMotionPoints(pointField& motionPoints) const; diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.C index 2f842e6d66127b62fb226d79899f1b2fd7876b3a..1a725f0ebfe6979252cc8b720f05feede1287e93 100644 --- a/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.C +++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.C @@ -335,17 +335,19 @@ Foam::label Foam::addPatchCellLayer::addSideFace label inflateEdgeI = -1; // Check mesh faces using edge - forAll(meshFaces, i) + if (addToMesh_) { - if (mesh_.isInternalFace(meshFaces[i])) + forAll(meshFaces, i) { - // meshEdge uses internal faces so ok to inflate from it - inflateEdgeI = meshEdgeI; - break; + if (mesh_.isInternalFace(meshFaces[i])) + { + // meshEdge uses internal faces so ok to inflate from it + inflateEdgeI = meshEdgeI; + break; + } } } - // Get my mesh face and its zone. label meshFaceI = pp.addressing()[ownFaceI]; label zoneI = mesh_.faceZones().whichZone(meshFaceI); @@ -504,9 +506,14 @@ Foam::label Foam::addPatchCellLayer::addSideFace // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from mesh -Foam::addPatchCellLayer::addPatchCellLayer(const polyMesh& mesh) +Foam::addPatchCellLayer::addPatchCellLayer +( + const polyMesh& mesh, + const bool addToMesh +) : mesh_(mesh), + addToMesh_(addToMesh), addedPoints_(0), layerFaces_(0) {} @@ -551,6 +558,7 @@ void Foam::addPatchCellLayer::setRefinement ( const scalarField& expansionRatio, const indirectPrimitivePatch& pp, + const labelList& exposedPatchID, const labelList& nFaceLayers, const labelList& nPointLayers, const vectorField& firstLayerDisp, @@ -827,6 +835,19 @@ void Foam::addPatchCellLayer::setRefinement } + const polyBoundaryMesh& patches = mesh_.boundaryMesh(); + + // Precalculated patchID for each patch face + labelList patchID(pp.size()); + + forAll(pp, patchFaceI) + { + label meshFaceI = pp.addressing()[patchFaceI]; + + patchID[patchFaceI] = patches.whichPatch(meshFaceI); + } + + // From master point (in patch point label) to added points (in mesh point // label) addedPoints_.setSize(pp.nPoints()); @@ -857,6 +878,33 @@ void Foam::addPatchCellLayer::setRefinement // Create new points // + // If creating new mesh: copy existing patch points + labelList copiedPatchPoints; + if (!addToMesh_) + { + copiedPatchPoints.setSize(firstLayerDisp.size()); + forAll(firstLayerDisp, patchPointI) + { + if (addedPoints_[patchPointI].size()) + { + label meshPointI = meshPoints[patchPointI]; + label zoneI = mesh_.pointZones().whichZone(meshPointI); + copiedPatchPoints[patchPointI] = meshMod.setAction + ( + polyAddPoint + ( + mesh_.points()[meshPointI], // point + -1, // master point + zoneI, // zone for point + true // supports a cell + ) + ); + } + } + } + + + // Create points for additional layers forAll(firstLayerDisp, patchPointI) { if (addedPoints_[patchPointI].size()) @@ -878,7 +926,7 @@ void Foam::addPatchCellLayer::setRefinement polyAddPoint ( pt, // point - meshPointI, // master point + (addToMesh_ ? meshPointI : -1), // master point zoneI, // zone for point true // supports a cell ) @@ -922,34 +970,15 @@ void Foam::addPatchCellLayer::setRefinement -1, // master point -1, // master edge -1, // master face - mesh_.faceOwner()[meshFaceI], // master cell id + (addToMesh_ ? mesh_.faceOwner()[meshFaceI] : -1),//master ownZoneI // zone for cell ) ); - - //Pout<< "For patchFace:" << patchFaceI - // << " meshFace:" << pp.addressing()[patchFaceI] - // << " layer:" << i << " added cell:" - // << addedCells[patchFaceI][i] - // << endl; } } } - const polyBoundaryMesh& patches = mesh_.boundaryMesh(); - - // Precalculated patchID for each patch face - labelList patchID(pp.size()); - - forAll(pp, patchFaceI) - { - label meshFaceI = pp.addressing()[patchFaceI]; - - patchID[patchFaceI] = patches.whichPatch(meshFaceI); - } - - // Create faces on top of the original patch faces. // These faces are created from original patch faces outwards so in order @@ -965,7 +994,6 @@ void Foam::addPatchCellLayer::setRefinement if (addedCells[patchFaceI].size()) { layerFaces_[patchFaceI].setSize(addedCells[patchFaceI].size() + 1); - layerFaces_[patchFaceI][0] = meshFaceI; label zoneI = mesh_.faceZones().whichZone(meshFaceI); @@ -981,7 +1009,12 @@ void Foam::addPatchCellLayer::setRefinement if (addedPoints_[f[fp]].empty()) { // Keep original point - newFace[fp] = meshPoints[f[fp]]; + newFace[fp] = + ( + addToMesh_ + ? meshPoints[f[fp]] + : copiedPatchPoints[f[fp]] + ); } else { @@ -1021,18 +1054,13 @@ void Foam::addPatchCellLayer::setRefinement nei, // neighbour -1, // master point -1, // master edge - meshFaceI, // master face for addition + (addToMesh_ ? meshFaceI : -1), // master face false, // flux flip patchI, // patch for face zoneI, // zone for face false // face zone flip ) ); - //Pout<< "Added inbetween face " << newFace - // << " own:" << addedCells[patchFaceI][i] - // << " nei:" << nei - // << " patch:" << patchI - // << endl; } } } @@ -1040,37 +1068,83 @@ void Foam::addPatchCellLayer::setRefinement // // Modify old patch faces to be on the inside // - forAll(pp, patchFaceI) + + if (addToMesh_) { - if (addedCells[patchFaceI].size()) + forAll(pp, patchFaceI) { - label meshFaceI = pp.addressing()[patchFaceI]; + if (addedCells[patchFaceI].size()) + { + label meshFaceI = pp.addressing()[patchFaceI]; - label zoneI = mesh_.faceZones().whichZone(meshFaceI); + layerFaces_[patchFaceI][0] = meshFaceI; - meshMod.setAction - ( - polyModifyFace + label zoneI = mesh_.faceZones().whichZone(meshFaceI); + + meshMod.setAction ( - pp[patchFaceI], // modified face - meshFaceI, // label of face - mesh_.faceOwner()[meshFaceI], // owner - addedCells[patchFaceI][0], // neighbour - false, // face flip - -1, // patch for face - false, // remove from zone - zoneI, // zone for face - false // face flip in zone - ) - ); - //Pout<< "Modified old patch face " << meshFaceI - // << " own:" << mesh_.faceOwner()[meshFaceI] - // << " nei:" << addedCells[patchFaceI][0] - // << endl; + polyModifyFace + ( + pp[patchFaceI], // modified face + meshFaceI, // label of face + mesh_.faceOwner()[meshFaceI], // owner + addedCells[patchFaceI][0], // neighbour + false, // face flip + -1, // patch for face + false, // remove from zone + zoneI, // zone for face + false // face flip in zone + ) + ); + } + } + } + else + { + // If creating new mesh: reverse original faces and put them + // in the exposed patch ID. + forAll(pp, patchFaceI) + { + if (nFaceLayers[patchFaceI] > 0) + { + label meshFaceI = pp.addressing()[patchFaceI]; + label zoneI = mesh_.faceZones().whichZone(meshFaceI); + bool zoneFlip = false; + if (zoneI != -1) + { + const faceZone& fz = mesh_.faceZones()[zoneI]; + zoneFlip = !fz.flipMap()[fz.whichFace(meshFaceI)]; + } + + // Reverse and renumber old patch face. + face f(pp.localFaces()[patchFaceI].reverseFace()); + forAll(f, fp) + { + f[fp] = copiedPatchPoints[f[fp]]; + } + + layerFaces_[patchFaceI][0] = meshMod.setAction + ( + polyAddFace + ( + f, // modified face + addedCells[patchFaceI][0], // owner + -1, // neighbour + -1, // masterPoint + -1, // masterEdge + -1, // masterFace + true, // face flip + exposedPatchID[patchFaceI], // patch for face + zoneI, // zone for face + zoneFlip // face flip in zone + ) + ); + } } } + // // Create 'side' faces, one per edge that is being extended. // @@ -1255,7 +1329,16 @@ void Foam::addPatchCellLayer::setRefinement forAll(stringedVerts, stringedI) { label v = stringedVerts[stringedI]; - addVertex(meshPoints[v], newFace, newFp); + addVertex + ( + ( + addToMesh_ + ? meshPoints[v] + : copiedPatchPoints[v] + ), + newFace, + newFp + ); } } else @@ -1276,7 +1359,16 @@ void Foam::addPatchCellLayer::setRefinement } else { - addVertex(meshPoints[v], newFace, newFp); + addVertex + ( + ( + addToMesh_ + ? meshPoints[v] + : copiedPatchPoints[v] + ), + newFace, + newFp + ); } } } @@ -1316,7 +1408,16 @@ void Foam::addPatchCellLayer::setRefinement } else { - addVertex(meshPoints[v], newFace, newFp); + addVertex + ( + ( + addToMesh_ + ? meshPoints[v] + : copiedPatchPoints[v] + ), + newFace, + newFp + ); } } diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.H b/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.H index f03d23e2144fb22c5a9f093f221ed5fd86dc4a42..f4b5bb2e79325c6c9023b3b417a053e41a573650 100644 --- a/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.H +++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.H @@ -26,7 +26,8 @@ Class Foam::addPatchCellLayer Description - Adds layers of cells to outside of polyPatch. + Adds layers of cells to outside of polyPatch. Can optionally create + stand-alone extruded mesh (addToMesh=false). Call setRefinement with offset vector for every patch point and number of layers per patch face and number of layers per patch point. @@ -164,6 +165,9 @@ class addPatchCellLayer //- Reference to mesh const polyMesh& mesh_; + //- Add layers to existing mesh or create new mesh + const bool addToMesh_; + //- For all patchpoints: list of added points (size 0 or nLayers) // First point in list is one nearest to original point in patch, // last one is the new point on the surface. @@ -253,7 +257,7 @@ public: // Constructors //- Construct from mesh. - addPatchCellLayer(const polyMesh& mesh); + addPatchCellLayer(const polyMesh& mesh, const bool addToMesh = true); // Member Functions @@ -291,8 +295,10 @@ public: //- Play commands into polyTopoChange to create layers on top // of indirectPrimitivePatch (have to be outside faces). // Gets displacement per patch point. - // - nPointLayers : number of layers per (patch)point - // - nFaceLayers : number of layers per (patch) face + // - exposedPatchID : only used if creating a new mesh (addToMesh=false) + // gives per pp face the patch the exposed face should get. + // - nPointLayers : number of layers per (patch)point. + // - nFaceLayers : number of layers per (patch) face. // - firstDisplacement : displacement per point for first // layer of points (i.e. nearest to original mesh). If zero // do not add point. @@ -305,14 +311,15 @@ public: // get a cell should firstDisplacement be <> 0 // Note: cells get added from owner cells of patch faces // (instead of e.g. from patch faces) - void setRefinement - ( - const scalarField& expansionRatio, - const indirectPrimitivePatch& pp, - const labelList& nFaceLayers, - const labelList& nPointLayers, - const vectorField& firstLayerDisp, - polyTopoChange& meshMod + void setRefinement + ( + const scalarField& expansionRatio, + const indirectPrimitivePatch& pp, + const labelList& exposedPatchID, + const labelList& nFaceLayers, + const labelList& nPointLayers, + const vectorField& firstLayerDisp, + polyTopoChange& meshMod ); @@ -329,6 +336,7 @@ public: ( scalarField(pp.nPoints(), 1.0), // expansion ration pp, + labelList(0), labelList(pp.size(), nLayers), labelList(pp.nPoints(), nLayers), overallDisplacement / nLayers, diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C index f6c397640fce9eb982b3bb125df349896a8582c4..6b1874dc4b846850035734e4a009c5f0b421eb9b 100644 --- a/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C +++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C @@ -749,6 +749,11 @@ void Foam::polyTopoChange::getFaceOrder " const" ) << "Did not determine new position" << " for face " << faceI + << " owner " << faceOwner_[faceI] + << " neighbour " << faceNeighbour_[faceI] + << " region " << region_[faceI] << endl + << "This is usually caused by not specifying a patch for" + << " a boundary face." << abort(FatalError); } } @@ -3176,7 +3181,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::makeMesh ( autoPtr<fvMesh>& newMeshPtr, const IOobject& io, - const fvMesh& mesh, + const polyMesh& mesh, const bool syncParallel, const bool orderCells, const bool orderPoints diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.H b/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.H index 77801e21f0dc33b703585f15ef3ffbd65a5c70ad..e7a0ba8fb380fd8a258cebf98baa1400440f134e 100644 --- a/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.H +++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.H @@ -585,7 +585,7 @@ public: ( autoPtr<fvMesh>& newMesh, const IOobject& io, - const fvMesh& mesh, + const polyMesh& mesh, const bool syncParallel = true, const bool orderCells = false, const bool orderPoints = false diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.C b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.C index 887fed0fd9caa67e0ab48929a2678beeb113e0a2..a089b502e34fb121c72d0e198e6dad5c075267ae 100644 --- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.C +++ b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.C @@ -48,7 +48,8 @@ int Foam::fileFormats::STLsurfaceFormatCore::detectBINARY { off_t dataFileSize = Foam::fileSize(filename); - istream& is = IFstream(filename, IOstream::BINARY)().stdStream(); + IFstream str(filename, IOstream::BINARY); + istream& is = str().stdStream(); // Read the STL header char header[headerSize];