Skip to content
Snippets Groups Projects
cartesianMeshGenerator.C 10.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • franjo's avatar
    franjo committed
    /*---------------------------------------------------------------------------*\
      =========                 |
      \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
       \\    /   O peration     |
        \\  /    A nd           | Copyright (C) 2005-2007 Franjo Juretic
         \\/     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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    
    Description
    
    \*---------------------------------------------------------------------------*/
    
    #include "cartesianMeshGenerator.H"
    #include "triSurf.H"
    
    #include "triSurfacePatchManipulator.H"
    
    franjo's avatar
    franjo committed
    #include "demandDrivenData.H"
    #include "objectRegistry.H"
    #include "Time.H"
    #include "meshOctreeCreator.H"
    #include "cartesianMeshExtractor.H"
    #include "meshSurfaceEngine.H"
    #include "meshSurfaceMapper.H"
    #include "meshSurfaceEdgeExtractorNonTopo.H"
    #include "surfaceMorpherCells.H"
    #include "meshOptimizer.H"
    #include "meshSurfaceOptimizer.H"
    #include "topologicalCleaner.H"
    #include "boundaryLayers.H"
    #include "renameBoundaryPatches.H"
    #include "checkMeshDict.H"
    #include "checkCellConnectionsOverFaces.H"
    #include "checkIrregularSurfaceConnections.H"
    #include "checkNonMappableCellConnections.H"
    #include "checkBoundaryFacesSharingTwoEdges.H"
    
    
    franjo's avatar
    franjo committed
    //#define DEBUGfpma
    
    franjo's avatar
    franjo committed
    
    # ifdef DEBUG
    #include "writeMeshEnsight.H"
    #include "writeMeshFPMA.H"
    # endif
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    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();
    
        # ifdef DEBUG
        mesh_.write();
        # ifdef DEBUGfpma
        writeMeshFPMA(mesh_, "cartesianMesh");
    
        writeMeshEnsight(mesh_, "cartesianMesh");
        # endif
        //::exit(EXIT_FAILURE);
        # endif
    
    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
    /*    do
        {
            surfaceMorpherCells* cmPtr = new surfaceMorpherCells(mesh_);
            cmPtr->morphMesh();
            deleteDemandDrivenData(cmPtr);
        } while( topologicalCleaner(mesh_).cleanTopology() );
    
    franjo's avatar
    franjo committed
        */
    
    franjo's avatar
    franjo committed
        bool changed;
        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();
    
        # ifdef DEBUG
        mesh_.write();
        # ifdef DEBUGfpma
        writeMeshFPMA(mesh_, "afterTopoCleaning");
    
        writeMeshEnsight(mesh_, "afterTopoCleaning");
        # endif
        //::exit(EXIT_FAILURE);
        # endif
    
    franjo's avatar
    franjo committed
    }
    
    franjo's avatar
    franjo committed
    void cartesianMeshGenerator::mapMeshToSurface()
    {
    
        //- calculate mesh surface
    
    franjo's avatar
    franjo committed
        meshSurfaceEngine* msePtr = new meshSurfaceEngine(mesh_);
    
    franjo's avatar
    franjo committed
        //- pre-map mesh surface
        meshSurfaceMapper mapper(*msePtr, *octreePtr_);
        mapper.preMapVertices();
    
    franjo's avatar
    franjo committed
        # ifdef DEBUG
    
        # ifdef DEBUGfpma
    
    franjo's avatar
    franjo committed
        writeMeshFPMA(mesh_, "preMappedMesh");
    
        writeMeshEnsight(mesh_, "preMappedMesh");
        # endif
        mesh_.write();
        //::exit(EXIT_FAILURE);
        # endif
    
    
        //- map mesh surface on the geometry surface
    
        mapper.mapVerticesOntoSurface();
    
        # ifdef DEBUG
        # ifdef DEBUGfpma
        writeMeshFPMA(mesh_, "afterMapping");
    
        writeMeshEnsight(mesh_, "afterMapping");
        # endif
        mesh_.write();
        //::exit(EXIT_FAILURE);
        # endif
    
        //- untangle surface faces
        meshSurfaceOptimizer(*msePtr, *octreePtr_).preOptimizeSurface();
    
        # ifdef DEBUG
        # ifdef DEBUGfpma
        writeMeshFPMA(mesh_, "afterSurfaceSmoothing");
    
        writeMeshEnsight(mesh_, "afterSurfaceSmoothing");
        # endif
        mesh_.write();
        //::exit(EXIT_FAILURE);
        # endif
    
    franjo's avatar
    franjo committed
        deleteDemandDrivenData(msePtr);
    }
    
    void cartesianMeshGenerator::mapEdgesAndCorners()
    {
    
        meshSurfaceEdgeExtractorNonTopo(mesh_, *octreePtr_);
    
        # ifdef DEBUG
    
        //mesh_.write();
        meshOptimizer(mesh_).optimizeSurface(*octreePtr_);
    
        mesh_.write();
    
        # ifdef DEBUGfpma
        writeMeshFPMA(mesh_, "withEdges");
    
        writeMeshEnsight(mesh_, "withEdges");
        #endif
        //::exit(EXIT_FAILURE);
        # endif
    
    franjo's avatar
    franjo committed
    }
    
    void cartesianMeshGenerator::optimiseMeshSurface()
    {
    
        meshSurfaceEngine mse(mesh_);
        meshSurfaceOptimizer(mse, *octreePtr_).optimizeSurface();
    
        # ifdef DEBUG
        mesh_.write();
        # ifdef DEBUGfpma
        writeMeshFPMA(mesh_, "optSurfaceWithEdges");
    
        writeMeshEnsight(mesh_, "optSurfaceWithEdges");
        #endif
        //::exit(EXIT_FAILURE);
        # endif
    
    franjo's avatar
    franjo committed
    }
    
    franjo's avatar
    franjo committed
    void cartesianMeshGenerator::generateBoudaryLayers()
    {
    
        boundaryLayers bl(mesh_);
    
    franjo's avatar
    franjo committed
        if( meshDict_.found("boundaryLayers") )
        {
    
            wordList createLayers;
    
            if( meshDict_.isDict("boundaryLayers") )
            {
                const dictionary& dict = meshDict_.subDict("boundaryLayers");
                createLayers = dict.toc();
            }
            else
            {
                wordList bndLayers(meshDict_.lookup("boundaryLayers"));
                createLayers.transfer(bndLayers);
            }
    
    franjo's avatar
    franjo committed
            forAll(createLayers, patchI)
                bl.addLayerForPatch(createLayers[patchI]);
        }
        else
        {
            //bl.createOTopologyLayers();
            bl.addLayerForAllPatches();
    
        # ifdef DEBUG
    
    franjo's avatar
    franjo committed
        # ifdef DEBUGfpma
        writeMeshFPMA(mesh_, "meshWithBndLayer");
    
        writeMeshEnsight(mesh_, "meshWithBndLayer");
        # endif
        mesh_.write();
        //::exit(EXIT_FAILURE);
    
    franjo's avatar
    franjo committed
        # endif
    }
    
    franjo's avatar
    franjo committed
    void cartesianMeshGenerator::optimiseFinalMesh()
    {
    
        //- final optimisation
        meshOptimizer optimizer(mesh_);
    
    franjo's avatar
    franjo committed
        optimizer.optimizeSurface(*octreePtr_);
    
    franjo's avatar
    franjo committed
        deleteDemandDrivenData(octreePtr_);
    
    franjo's avatar
    franjo committed
        optimizer.optimizeMeshFV();
    
        # ifdef DEBUG
        # ifdef DEBUGfpma
        writeMeshFPMA(mesh_,"optimisedMesh");
    
        writeMeshEnsight(mesh_, "optimisedMesh");
        #endif
        # endif
    
    franjo's avatar
    franjo committed
    }
    
    void cartesianMeshGenerator::replaceBoundaries()
    {
        renameBoundaryPatches rbp(mesh_, meshDict_);
    
    franjo's avatar
    franjo committed
        # ifdef DEBUG
    
        # ifdef DEBUGfpma
        writeMeshFPMA(mesh_,"renamedPatchesMesh");
    
        writeMeshEnsight(mesh_, "renamedPatchesMesh");
        #endif
        # endif
    
    franjo's avatar
    franjo committed
    }
    
    void cartesianMeshGenerator::renumberMesh()
    {
    
        polyMeshGenModifier(mesh_).renumberMesh();
    
        # ifdef DEBUG
        # ifdef DEBUGfpma
        writeMeshFPMA(mesh_,"renumberedMesh");
    
        writeMeshEnsight(mesh_, "renumberedMesh");
        #endif
        # endif
    
    franjo's avatar
    franjo committed
    }
    
    franjo's avatar
    franjo committed
    void cartesianMeshGenerator::generateMesh()
    {
    
        createCartesianMesh();
    
        surfacePreparation();
    
        mapMeshToSurface();
    
        mapEdgesAndCorners();
    
        optimiseMeshSurface();
    
        generateBoudaryLayers();
    
        optimiseFinalMesh();
    
        renumberMesh();
    
    franjo's avatar
    franjo committed
        replaceBoundaries();
    }
    
    // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
    
    // Construct from objectRegistry
    cartesianMeshGenerator::cartesianMeshGenerator(const Time& time)
    :
        db_(time),
        surfacePtr_(NULL),
        meshDict_
        (
            IOobject
            (
                "meshDict",
                db_.system(),
                db_,
                IOobject::MUST_READ,
                IOobject::NO_WRITE
            )
        ),
        octreePtr_(NULL),
    
        mesh_(time)
    
    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);
    
        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
    
        octreePtr_ = new meshOctree(*surfacePtr_);
    
        meshOctreeCreator(*octreePtr_, meshDict_).createOctreeBoxes();
    
    franjo's avatar
    franjo committed
    
        generateMesh();
    }
    
    /*
    cartesianMeshGenerator::cartesianMeshGenerator
    (
        const objectRegistry& time,
        const volScalarField& localCellSize
    )
    :
        db_(time),
        surfacePtr_(NULL),
        meshDict_
        (
            IOobject
            (
                "meshDict",
                db_.time().constant(),
                db_,
                IOobject::MUST_READ,
                IOobject::NO_WRITE
            )
        ),
        octreePtr_(NULL),
    
        mesh_(time)
    
    franjo's avatar
    franjo committed
    {
        fileName surfaceFile = meshDict_.lookup("surfaceFile");
    
        surfacePtr_ = new triSurface(db_.path()/surfaceFile);
    
        octreePtr_ = new meshOctree(*surfacePtr_);
    
        generateMesh();
    }
    */
    
    // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
    
    cartesianMeshGenerator::~cartesianMeshGenerator()
    {
        deleteDemandDrivenData(surfacePtr_);
        deleteDemandDrivenData(octreePtr_);
    }
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    void cartesianMeshGenerator::writeMesh() const
    
        mesh_.write();
    
    franjo's avatar
    franjo committed
    }
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    } // End namespace Foam
    
    // ************************************************************************* //