Skip to content
Snippets Groups Projects
cartesianMeshGenerator.C 10.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • franjo's avatar
    franjo committed
    /*---------------------------------------------------------------------------*\
      =========                 |
    
    Tomislav Lugaric's avatar
    Tomislav Lugaric committed
      \\      /  F ield         | cfMesh: A library for mesh generation
    
    franjo's avatar
    franjo committed
       \\    /   O peration     |
    
    Tomislav Lugaric's avatar
    Tomislav Lugaric committed
        \\  /    A nd           | Author: Franjo Juretic (franjo.juretic@c-fields.com)
         \\/     M anipulation  | Copyright (C) Creative Fields, Ltd.
    
    franjo's avatar
    franjo committed
    -------------------------------------------------------------------------------
    License
    
    Tomislav Lugaric's avatar
    Tomislav Lugaric committed
        This file is part of cfMesh.
    
    franjo's avatar
    franjo committed
    
    
    Tomislav Lugaric's avatar
    Tomislav Lugaric committed
        cfMesh is free software; you can redistribute it and/or modify it
    
    franjo's avatar
    franjo committed
        under the terms of the GNU General Public License as published by the
    
    Tomislav Lugaric's avatar
    Tomislav Lugaric committed
        Free Software Foundation; either version 3 of the License, or (at your
    
    franjo's avatar
    franjo committed
        option) any later version.
    
    
    Tomislav Lugaric's avatar
    Tomislav Lugaric committed
        cfMesh is distributed in the hope that it will be useful, but WITHOUT
    
    franjo's avatar
    franjo committed
        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
    
    Tomislav Lugaric's avatar
    Tomislav Lugaric committed
        along with cfMesh.  If not, see <http://www.gnu.org/licenses/>.
    
    franjo's avatar
    franjo committed
    
    Description
    
    \*---------------------------------------------------------------------------*/
    
    #include "cartesianMeshGenerator.H"
    #include "triSurf.H"
    
    #include "triSurfacePatchManipulator.H"
    
    franjo's avatar
    franjo committed
    #include "demandDrivenData.H"
    #include "Time.H"
    #include "meshOctreeCreator.H"
    #include "cartesianMeshExtractor.H"
    #include "meshSurfaceEngine.H"
    #include "meshSurfaceMapper.H"
    
    #include "edgeExtractor.H"
    
    franjo's avatar
    franjo committed
    #include "meshSurfaceEdgeExtractorNonTopo.H"
    #include "meshOptimizer.H"
    #include "meshSurfaceOptimizer.H"
    #include "topologicalCleaner.H"
    #include "boundaryLayers.H"
    
    franjo's avatar
    franjo committed
    #include "renameBoundaryPatches.H"
    #include "checkMeshDict.H"
    #include "checkCellConnectionsOverFaces.H"
    #include "checkIrregularSurfaceConnections.H"
    #include "checkNonMappableCellConnections.H"
    #include "checkBoundaryFacesSharingTwoEdges.H"
    
    Franjo's avatar
    Franjo committed
    #include "triSurfaceMetaData.H"
    
    #include "polyMeshGenGeometryModification.H"
    #include "surfaceMeshGeometryModification.H"
    
    franjo's avatar
    franjo committed
    
    
    franjo's avatar
    franjo committed
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    namespace Foam
    {
    
    // * * * * * * * * * * * * Private member functions  * * * * * * * * * * * * //
    
    franjo's avatar
    franjo committed
    void cartesianMeshGenerator::createCartesianMesh()
    {
    
        //- create polyMesh from octree boxes
        cartesianMeshExtractor cme(*octreePtr_, meshDict_, mesh_);
    
    franjo's avatar
    franjo committed
        if( meshDict_.found("decomposePolyhedraIntoTetsAndPyrs") )
        {
            if( readBool(meshDict_.lookup("decomposePolyhedraIntoTetsAndPyrs")) )
                cme.decomposeSplitHexes();
        }
    
        cme.createMesh();
    
    franjo's avatar
    franjo committed
    }
    
    franjo's avatar
    franjo committed
    void cartesianMeshGenerator::surfacePreparation()
    {
    
        //- removes unnecessary cells and morph the boundary
    
    franjo's avatar
    franjo committed
        //- such that there is only one boundary face per cell
    
        //- It also checks topology of cells after morphing is performed
    
    franjo's avatar
    franjo committed
        bool changed;
    
    franjo's avatar
    franjo committed
        do
        {
            changed = false;
    
            checkIrregularSurfaceConnections checkConnections(mesh_);
            if( checkConnections.checkAndFixIrregularConnections() )
                changed = true;
    
    franjo's avatar
    franjo committed
            if( checkNonMappableCellConnections(mesh_).removeCells() )
                changed = true;
    
    franjo's avatar
    franjo committed
            if( checkCellConnectionsOverFaces(mesh_).checkCellGroups() )
                changed = true;
    
        } while( changed );
    
    franjo's avatar
    franjo committed
        checkBoundaryFacesSharingTwoEdges(mesh_).improveTopology();
    }
    
    franjo's avatar
    franjo committed
    void cartesianMeshGenerator::mapMeshToSurface()
    {
    
        //- calculate mesh surface
    
        meshSurfaceEngine mse(mesh_);
    
    franjo's avatar
    franjo committed
        //- pre-map mesh surface
    
        meshSurfaceMapper mapper(mse, *octreePtr_);
    
    franjo's avatar
    franjo committed
        mapper.preMapVertices();
    
    
        //- map mesh surface on the geometry surface
    
        mapper.mapVerticesOntoSurface();
    
        //- untangle surface faces
    
        meshSurfaceOptimizer(mse, *octreePtr_).untangleSurface();
    
    franjo's avatar
    franjo committed
    }
    
    
    void cartesianMeshGenerator::extractPatches()
    {
        edgeExtractor extractor(mesh_, *octreePtr_);
    
        Info << "Extracting edges" << endl;
        extractor.extractEdges();
    
        extractor.updateMeshPatches();
    }
    
    
    franjo's avatar
    franjo committed
    void cartesianMeshGenerator::mapEdgesAndCorners()
    {
    
        meshSurfaceEdgeExtractorNonTopo(mesh_, *octreePtr_);
    
    franjo's avatar
    franjo committed
    }
    
    void cartesianMeshGenerator::optimiseMeshSurface()
    {
    
        meshSurfaceEngine mse(mesh_);
        meshSurfaceOptimizer(mse, *octreePtr_).optimizeSurface();
    
    franjo's avatar
    franjo committed
    }
    
    void cartesianMeshGenerator::generateBoundaryLayers()
    
    franjo's avatar
    franjo committed
    {
    
        boundaryLayers bl(mesh_);
    
    franjo's avatar
    franjo committed
    }
    
    void cartesianMeshGenerator::refBoundaryLayers()
    {
    
        if( meshDict_.isDict("boundaryLayers") )
        {
            refineBoundaryLayers refLayers(mesh_);
    
            refineBoundaryLayers::readSettings(meshDict_, refLayers);
    
            labelLongList pointsInLayer;
            refLayers.pointsInBndLayer(pointsInLayer);
    
            meshOptimizer mOpt(mesh_);
            mOpt.lockPoints(pointsInLayer);
            mOpt.untangleBoundaryLayer();
    
    franjo's avatar
    franjo committed
    void cartesianMeshGenerator::optimiseFinalMesh()
    {
    
        bool enforceConstraints(false);
        if( meshDict_.found("enforceGeometryConstraints") )
        {
            enforceConstraints =
                readBool(meshDict_.lookup("enforceGeometryConstraints"));
        }
    
        if( true )
        {
            meshSurfaceEngine mse(mesh_);
            meshSurfaceOptimizer surfOpt(mse, *octreePtr_);
    
            if( enforceConstraints )
                surfOpt.enforceConstraints();
    
            surfOpt.optimizeSurface();
        }
    
    
    franjo's avatar
    franjo committed
        deleteDemandDrivenData(octreePtr_);
    
        //- final optimisation
        meshOptimizer optimizer(mesh_);
    
        if( enforceConstraints )
            optimizer.enforceConstraints();
    
        optimizer.optimizeMeshFV();
    
        optimizer.optimizeLowQualityFaces();
    
        optimizer.optimizeBoundaryLayer(modSurfacePtr_==NULL);
    
        mesh_.clearAddressingData();
    
    
        if( modSurfacePtr_ )
        {
            polyMeshGenGeometryModification meshMod(mesh_, meshDict_);
    
            //- revert the mesh into the original space
            meshMod.revertGeometryModification();
    
            //- delete modified surface mesh
            deleteDemandDrivenData(modSurfacePtr_);
        }
    
    franjo's avatar
    franjo committed
    }
    
    
    void cartesianMeshGenerator::projectSurfaceAfterBackScaling()
    {
        if( !meshDict_.found("anisotropicSources") )
            return;
    
        deleteDemandDrivenData(octreePtr_);
        octreePtr_ = new meshOctree(*surfacePtr_);
    
        meshOctreeCreator
        (
            *octreePtr_,
            meshDict_
        ).createOctreeWithRefinedBoundary(20, 30);
    
        //- calculate mesh surface
        meshSurfaceEngine mse(mesh_);
    
        //- pre-map mesh surface
        meshSurfaceMapper mapper(mse, *octreePtr_);
    
        //- map mesh surface on the geometry surface
        mapper.mapVerticesOntoSurface();
    
        optimiseFinalMesh();
    }
    
    
    franjo's avatar
    franjo committed
    void cartesianMeshGenerator::replaceBoundaries()
    {
        renameBoundaryPatches rbp(mesh_, meshDict_);
    }
    
    void cartesianMeshGenerator::renumberMesh()
    {
    
        polyMeshGenModifier(mesh_).renumberMesh();
    
    franjo's avatar
    franjo committed
    }
    
    franjo's avatar
    franjo committed
    void cartesianMeshGenerator::generateMesh()
    {
    
            if( controller_.runCurrentStep("templateGeneration") )
    
            {
                createCartesianMesh();
            }
    
            if( controller_.runCurrentStep("surfaceTopology") )
    
            {
                surfacePreparation();
            }
    
    
            if( controller_.runCurrentStep("surfaceProjection") )
    
            {
                mapMeshToSurface();
    
            if( controller_.runCurrentStep("patchAssignment") )
            {
                extractPatches();
    
            if( controller_.runCurrentStep("edgeExtraction") )
    
            {
                mapEdgesAndCorners();
    
                optimiseMeshSurface();
    
            if( controller_.runCurrentStep("boundaryLayerGeneration") )
            {
    
                generateBoundaryLayers();
            }
    
            if( controller_.runCurrentStep("meshOptimisation") )
    
            {
                optimiseFinalMesh();
    
    
                projectSurfaceAfterBackScaling();
    
            if( controller_.runCurrentStep("boundaryLayerRefinement") )
    
            {
                refBoundaryLayers();
            }
    
    
            controller_.workflowCompleted();
    
    Franjo's avatar
    Franjo committed
        catch(const std::string& message)
        {
            Info << message << endl;
        }
    
        catch(...)
        {
            WarningIn
            (
                "void cartesianMeshGenerator::generateMesh()"
            ) << "Meshing process terminated!" << endl;
        }
    
    franjo's avatar
    franjo committed
    }
    
    // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
    
    cartesianMeshGenerator::cartesianMeshGenerator(const Time& time)
    :
        db_(time),
        surfacePtr_(NULL),
    
    franjo's avatar
    franjo committed
        meshDict_
        (
            IOobject
            (
                "meshDict",
                db_.system(),
                db_,
                IOobject::MUST_READ,
                IOobject::NO_WRITE
            )
        ),
        octreePtr_(NULL),
    
        mesh_(time),
        controller_(mesh_)
    
    franjo's avatar
    franjo committed
    {
        if( true )
        {
            checkMeshDict cmd(meshDict_);
        }
    
    franjo's avatar
    franjo committed
        fileName surfaceFile = meshDict_.lookup("surfaceFile");
        if( Pstream::parRun() )
    
            surfaceFile = ".."/surfaceFile;
    
    franjo's avatar
    franjo committed
    
        surfacePtr_ = new triSurf(db_.path()/surfaceFile);
    
    Franjo's avatar
    Franjo committed
        if( true )
        {
            //- save meta data with the mesh (surface mesh + its topology info)
            triSurfaceMetaData sMetaData(*surfacePtr_);
            const dictionary& surfMetaDict = sMetaData.metaData();
    
    
            mesh_.metaData().add("surfaceFile", surfaceFile, true);
            mesh_.metaData().add("surfaceMeta", surfMetaDict, true);
    
        if( surfacePtr_->featureEdges().size() != 0 )
        {
            //- create surface patches based on the feature edges
            //- and update the meshDict based on the given data
            triSurfacePatchManipulator manipulator(*surfacePtr_);
    
            const triSurf* surfaceWithPatches =
                manipulator.surfaceWithPatches(&meshDict_);
    
            //- delete the old surface and assign the new one
            deleteDemandDrivenData(surfacePtr_);
            surfacePtr_ = surfaceWithPatches;
        }
    
    franjo's avatar
    franjo committed
    
    
        if( meshDict_.found("anisotropicSources") )
        {
            surfaceMeshGeometryModification surfMod(*surfacePtr_, meshDict_);
    
            modSurfacePtr_ = surfMod.modifyGeometry();
    
            octreePtr_ = new meshOctree(*modSurfacePtr_);
        }
        else
        {
            octreePtr_ = new meshOctree(*surfacePtr_);
        }
    
        meshOctreeCreator(*octreePtr_, meshDict_).createOctreeBoxes();
    
    franjo's avatar
    franjo committed
    
        generateMesh();
    }
    
    // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
    
    cartesianMeshGenerator::~cartesianMeshGenerator()
    {
        deleteDemandDrivenData(surfacePtr_);
    
        deleteDemandDrivenData(modSurfacePtr_);
    
    franjo's avatar
    franjo committed
        deleteDemandDrivenData(octreePtr_);
    }
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    void cartesianMeshGenerator::writeMesh() const
    
        mesh_.write();
    
    franjo's avatar
    franjo committed
    }
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    } // End namespace Foam
    
    // ************************************************************************* //