Skip to content
Snippets Groups Projects
isoSurface.H 14 KiB
Newer Older
  • Learn to ignore specific revisions
  • mattijs's avatar
    mattijs committed
    /*---------------------------------------------------------------------------*\
      =========                 |
      \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
       \\    /   O peration     |
    
    OpenFOAM bot's avatar
    OpenFOAM bot committed
        \\  /    A nd           | www.openfoam.com
    
         \\/     M anipulation  |
    -------------------------------------------------------------------------------
    
    OpenFOAM bot's avatar
    OpenFOAM bot committed
        Copyright (C) 2011-2016 OpenFOAM Foundation
    
        Copyright (C) 2016-2019 OpenCFD Ltd.
    
    mattijs's avatar
    mattijs committed
    -------------------------------------------------------------------------------
    License
        This file is part of OpenFOAM.
    
    
        OpenFOAM is free software: you can redistribute it and/or modify it
        under the terms of the GNU General Public License as published by
        the Free Software Foundation, either version 3 of the License, or
        (at your option) any later version.
    
    mattijs's avatar
    mattijs committed
    
        OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
        ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
        FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        for more details.
    
        You should have received a copy of the GNU General Public License
    
        along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
    
    mattijs's avatar
    mattijs committed
    
    Class
        Foam::isoSurface
    
    Description
        A surface formed by the iso value.
    
    mattijs's avatar
    mattijs committed
        After "Regularised Marching Tetrahedra: improved iso-surface extraction",
    
    mattijs's avatar
    mattijs committed
        G.M. Treece, R.W. Prager and A.H. Gee.
    
        Note:
        - does tets without using cell centres/cell values. Not tested.
        - regularisation can create duplicate triangles/non-manifold surfaces.
        Current handling of those is bit ad-hoc for now and not perfect.
    
        - regularisation does not do boundary points so as to preserve the
          boundary perfectly.
    
    mattijs's avatar
    mattijs committed
        - uses geometric merge with fraction of bounding box as distance.
        - triangles can be between two cell centres so constant sampling
          does not make sense.
    
    mattijs's avatar
    mattijs committed
        - on empty patches behaves like zero gradient.
    
    mattijs's avatar
    mattijs committed
        - does not do 2D correctly, creates non-flat iso surface.
    
        - on processor boundaries might two overlapping (identical) triangles
          (one from either side)
    
        The handling on coupled patches is a bit complex. All fields
        (values and coordinates) get rewritten so
        - empty patches get zerogradient (value) and facecentre (coordinates)
        - separated processor patch faces get interpolate (value) and facecentre
          (coordinates). (this is already the default for cyclics)
        - non-separated processor patch faces keep opposite value and cell centre
    
        Now the triangle generation on non-separated processor patch faces
        can use the neighbouring value. Any separated processor face or cyclic
        face gets handled just like any boundary face.
    
    
    mattijs's avatar
    mattijs committed
    SourceFiles
        isoSurface.C
    
    mattijs's avatar
    mattijs committed
    
    \*---------------------------------------------------------------------------*/
    
    #ifndef isoSurface_H
    #define isoSurface_H
    
    
    mattijs's avatar
    mattijs committed
    #include "volFields.H"
    
    mattijs's avatar
    mattijs committed
    #include "slicedVolFields.H"
    
    #include "isoSurfaceBase.H"
    
    mattijs's avatar
    mattijs committed
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    namespace Foam
    {
    
    
    mattijs's avatar
    mattijs committed
    class fvMesh;
    
    class plane;
    class treeBoundBox;
    
    mattijs's avatar
    mattijs committed
    
    /*---------------------------------------------------------------------------*\
                           Class isoSurface Declaration
    \*---------------------------------------------------------------------------*/
    
    class isoSurface
    :
    
        public isoSurfaceBase
    
    mattijs's avatar
    mattijs committed
    {
        // Private data
    
    
    mattijs's avatar
    mattijs committed
            enum segmentCutType
            {
                NEARFIRST,      // intersection close to e.first()
                NEARSECOND,     //  ,,                   e.second()
                NOTNEAR         // no intersection
            };
    
            enum cellCutType
            {
                NOTCUT,     // not cut
                SPHERE,     // all edges to cell centre cut
                CUT         // normal cut
            };
    
    mattijs's avatar
    mattijs committed
    
    
    
    mattijs's avatar
    mattijs committed
            //- Reference to mesh
    
    mattijs's avatar
    mattijs committed
            const fvMesh& mesh_;
    
    mattijs's avatar
    mattijs committed
    
    
    mattijs's avatar
    mattijs committed
            const scalarField& pVals_;
    
            //- Input volScalarField with separated coupled patches rewritten
            autoPtr<slicedVolScalarField> cValsPtr_;
    
    
            //- Regularise?
    
            const bool regularise_;
    
    mattijs's avatar
    mattijs committed
            //- When to merge points
            const scalar mergeDistance_;
    
    
    mattijs's avatar
    mattijs committed
            //- Whether face might be cut
            List<cellCutType> faceCutType_;
    
            //- Whether cell might be cut
            List<cellCutType> cellCutType_;
    
            //- Estimated number of cut cells
            label nCutCells_;
    
    
    mattijs's avatar
    mattijs committed
            //- For every unmerged triangle point the point in the triSurface
            labelList triPointMergeMap_;
    
    
            //- triSurface points that have weighted interpolation
            DynamicList<label> interpolatedPoints_;
    
            //- corresponding original, unmerged points
    
            DynamicList<FixedList<label, 3>> interpolatedOldPoints_;
    
    
            //- corresponding weights
    
            DynamicList<FixedList<scalar, 3>> interpolationWeights_;
    
    mattijs's avatar
    mattijs committed
    
        // Private Member Functions
    
    
    mattijs's avatar
    mattijs committed
            // Point synchronisation
    
                //- Does tensor differ (to within mergeTolerance) from identity
                bool noTransform(const tensor& tt) const;
    
                //- Is patch a collocated (i.e. non-separated) coupled patch?
    
                static bool collocatedPatch(const polyPatch& pp);
    
    mattijs's avatar
    mattijs committed
    
                //- Per face whether is collocated
    
                bitSet collocatedFaces(const coupledPolyPatch&) const;
    
                //- Synchronise points on all non-separated coupled patches
    
    mattijs's avatar
    mattijs committed
                void syncUnseparatedPoints
                (
                    pointField& collapsedPoint,
                    const point& nullValue
                ) const;
    
    
    
    mattijs's avatar
    mattijs committed
            //- Get location of iso value as fraction inbetween s0,s1
            scalar isoFraction
    
    mattijs's avatar
    mattijs committed
            (
                const scalar s0,
                const scalar s1
    
    mattijs's avatar
    mattijs committed
            ) const;
    
    
    mattijs's avatar
    mattijs committed
            //- Check if any edge of a face is cut
            bool isEdgeOfFaceCut
            (
                const scalarField& pVals,
                const face& f,
                const bool ownLower,
                const bool neiLower
            ) const;
    
    
    mattijs's avatar
    mattijs committed
            void getNeighbour
            (
                const labelList& boundaryRegion,
    
    mattijs's avatar
    mattijs committed
                const volVectorField& meshC,
    
    mattijs's avatar
    mattijs committed
                const volScalarField& cVals,
    
                const label celli,
                const label facei,
    
    mattijs's avatar
    mattijs committed
                scalar& nbrValue,
                point& nbrPoint
            ) const;
    
    
            //- Determine for every face/cell whether it (possibly) generates
            //  triangles.
    
    mattijs's avatar
    mattijs committed
            void calcCutTypes
    
    mattijs's avatar
    mattijs committed
            (
    
    mattijs's avatar
    mattijs committed
                const labelList& boundaryRegion,
    
    mattijs's avatar
    mattijs committed
                const volVectorField& meshC,
    
    mattijs's avatar
    mattijs committed
                const volScalarField& cVals,
                const scalarField& pVals
            );
    
    mattijs's avatar
    mattijs committed
    
            static point calcCentre(const triSurface&);
    
            //- Determine per cc whether all near cuts can be snapped to single
            //  point.
            void calcSnappedCc
    
    mattijs's avatar
    mattijs committed
            (
    
    mattijs's avatar
    mattijs committed
                const labelList& boundaryRegion,
    
    mattijs's avatar
    mattijs committed
                const volVectorField& meshC,
    
    mattijs's avatar
    mattijs committed
                const volScalarField& cVals,
    
    mattijs's avatar
    mattijs committed
                const scalarField& pVals,
    
    mattijs's avatar
    mattijs committed
                DynamicList<point>& snappedPoints,
    
    mattijs's avatar
    mattijs committed
                labelList& snappedCc
            ) const;
    
            //- Determine per point whether all near cuts can be snapped to single
            //  point.
            void calcSnappedPoint
            (
    
                const bitSet& isBoundaryPoint,
    
    mattijs's avatar
    mattijs committed
                const labelList& boundaryRegion,
    
    mattijs's avatar
    mattijs committed
                const volVectorField& meshC,
    
    mattijs's avatar
    mattijs committed
                const volScalarField& cVals,
    
    mattijs's avatar
    mattijs committed
                const scalarField& pVals,
    
    mattijs's avatar
    mattijs committed
                DynamicList<point>& snappedPoints,
    
    mattijs's avatar
    mattijs committed
                labelList& snappedPoint
            ) const;
    
    
    mattijs's avatar
    mattijs committed
    
            //- Return input field with coupled (and empty) patch values rewritten
            template<class Type>
            tmp<SlicedGeometricField
    
            <Type, fvPatchField, slicedFvPatchField, volMesh>>
    
    mattijs's avatar
    mattijs committed
            adaptPatchFields
            (
                const GeometricField<Type, fvPatchField, volMesh>& fld
            ) const;
    
    
    mattijs's avatar
    mattijs committed
            //- Generate single point by interpolation or snapping
    
    mattijs's avatar
    mattijs committed
            template<class Type>
            Type generatePoint
    
    mattijs's avatar
    mattijs committed
            (
    
    mattijs's avatar
    mattijs committed
                const scalar s0,
    
    mattijs's avatar
    mattijs committed
                const Type& p0,
    
    mattijs's avatar
    mattijs committed
                const bool hasSnap0,
                const Type& snapP0,
    
    mattijs's avatar
    mattijs committed
    
    
    mattijs's avatar
    mattijs committed
                const scalar s1,
    
    mattijs's avatar
    mattijs committed
                const Type& p1,
    
    mattijs's avatar
    mattijs committed
                const bool hasSnap1,
                const Type& snapP1
    
    mattijs's avatar
    mattijs committed
            ) const;
    
    
    
            //- Note: cannot use simpler isoSurfaceCell::generateTriPoints since
            //  the need here to sometimes pass in remote 'snappedPoints'
    
    mattijs's avatar
    mattijs committed
            template<class Type>
    
    mattijs's avatar
    mattijs committed
            void generateTriPoints
            (
                const scalar s0,
    
    mattijs's avatar
    mattijs committed
                const Type& p0,
    
    mattijs's avatar
    mattijs committed
                const bool hasSnap0,
                const Type& snapP0,
    
    mattijs's avatar
    mattijs committed
    
    
    mattijs's avatar
    mattijs committed
                const scalar s1,
    
    mattijs's avatar
    mattijs committed
                const Type& p1,
    
    mattijs's avatar
    mattijs committed
                const bool hasSnap1,
                const Type& snapP1,
    
    mattijs's avatar
    mattijs committed
    
    
    mattijs's avatar
    mattijs committed
                const scalar s2,
    
    mattijs's avatar
    mattijs committed
                const Type& p2,
    
    mattijs's avatar
    mattijs committed
                const bool hasSnap2,
                const Type& snapP2,
    
    mattijs's avatar
    mattijs committed
    
    
    mattijs's avatar
    mattijs committed
                const scalar s3,
    
    mattijs's avatar
    mattijs committed
                const Type& p3,
    
    mattijs's avatar
    mattijs committed
                const bool hasSnap3,
                const Type& snapP3,
    
    mattijs's avatar
    mattijs committed
    
    
    mattijs's avatar
    mattijs committed
            ) const;
    
            template<class Type>
    
    mattijs's avatar
    mattijs committed
            label generateFaceTriPoints
    
    mattijs's avatar
    mattijs committed
            (
                const volScalarField& cVals,
                const scalarField& pVals,
    
                const GeometricField<Type, fvPatchField, volMesh>& cCoords,
                const Field<Type>& pCoords,
    
                const DynamicList<Type>& snappedPoints,
                const labelList& snappedCc,
                const labelList& snappedPoint,
    
    mattijs's avatar
    mattijs committed
    
                const scalar neiVal,
                const Type& neiPt,
    
    mattijs's avatar
    mattijs committed
                const bool hasNeiSnap,
                const Type& neiSnapPt,
    
    mattijs's avatar
    mattijs committed
    
                DynamicList<Type>& triPoints,
                DynamicList<label>& triMeshCells
            ) const;
    
            template<class Type>
            void generateTriPoints
            (
                const volScalarField& cVals,
                const scalarField& pVals,
    
                const GeometricField<Type, fvPatchField, volMesh>& cCoords,
                const Field<Type>& pCoords,
    
                const DynamicList<Type>& snappedPoints,
                const labelList& snappedCc,
                const labelList& snappedPoint,
    
                DynamicList<Type>& triPoints,
                DynamicList<label>& triMeshCells
    
    mattijs's avatar
    mattijs committed
            ) const;
    
    
            template<class Type>
    
            static tmp<Field<Type>> interpolate
    
            (
                const label nPoints,
                const labelList& triPointMergeMap,
                const labelList& interpolatedPoints,
    
                const List<FixedList<label, 3>>& interpolatedOldPoints,
                const List<FixedList<scalar, 3>>& interpolationWeights,
    
                const DynamicList<Type>& unmergedValues
            );
    
    
    mattijs's avatar
    mattijs committed
            triSurface stitchTriPoints
            (
                const bool checkDuplicates,
                const List<point>& triPoints,
                labelList& triPointReverseMap,  // unmerged to merged point
                labelList& triMap               // merged to unmerged triangle
            ) const;
    
    
            //- Trim triangle to planes
            static void trimToPlanes
    
    mattijs's avatar
    mattijs committed
            (
    
                const PtrList<plane>& planes,
                const triPointRef& tri,
                DynamicList<point>& newTriPoints
    
    mattijs's avatar
    mattijs committed
            );
    
    
            //- Trim all triangles to box
            static void trimToBox
    
    mattijs's avatar
    mattijs committed
            (
    
                const treeBoundBox& bb,
                DynamicList<point>& triPoints,
                DynamicList<label>& triMeshCells
    
    mattijs's avatar
    mattijs committed
            );
    
    mattijs's avatar
    mattijs committed
    
    
            //- Trim all triangles to box. Determine interpolation
            //  for existing and new points
            static void trimToBox
    
    mattijs's avatar
    mattijs committed
            (
    
                const treeBoundBox& bb,
                DynamicList<point>& triPoints,
                DynamicList<label>& triMap,
                labelList& triPointMap,
                labelList& interpolatedPoints,
    
                List<FixedList<label, 3>>& interpolatedOldPoints,
                List<FixedList<scalar, 3>>& interpolationWeights
    
    mattijs's avatar
    mattijs committed
            );
    
            static triSurface subsetMesh
            (
    
    mattijs's avatar
    mattijs committed
                const labelList& newToOldFaces,
    
    mattijs's avatar
    mattijs committed
                labelList& oldToNewPoints,
    
    mattijs's avatar
    mattijs committed
                labelList& newToOldPoints
    
    mattijs's avatar
    mattijs committed
            );
    
    public:
    
    
        //- Declare friendship to share some functionality
    
        friend class isoSurfaceCell;
    
        friend class isoSurfaceTopo;
    
        //- Filtering type
        using isoSurfaceBase::filterType;
    
    
    mattijs's avatar
    mattijs committed
        //- Runtime type information
        TypeName("isoSurface");
    
    
        // Constructors
    
    
            //- Construct from cell values and point values.
            //  Uses boundaryField for boundary values.
            //  Holds reference to cellIsoVals and pointIsoVals.
            //
            //  \param bounds optional bounding box for trimming
            //  \param mergeTol fraction of mesh bounding box for merging points
            isoSurface
            (
                const volScalarField& cellValues,
                const scalarField& pointValues,
                const scalar iso,
                const isoSurfaceBase::filterType filter,
                const boundBox& bounds = boundBox::invertedBox,
                const scalar mergeTol = 1e-6
            );
    
    
    
            //- Construct from cell values and point values.
            //  Uses boundaryField for boundary values.
            //  Holds reference to cellIsoVals and pointIsoVals.
    
            //
            //  \param bounds optional bounding box for trimming
            //  \param mergeTol fraction of mesh bounding box for merging points
    
    mattijs's avatar
    mattijs committed
            isoSurface
            (
    
                const volScalarField& cellValues,
                const scalarField& pointValues,
    
    mattijs's avatar
    mattijs committed
                const scalar iso,
                const bool regularise,
    
                const boundBox& bounds = boundBox::invertedBox,
    
                const scalar mergeTol = 1e-6
    
    mattijs's avatar
    mattijs committed
            );
    
    
        // Member Functions
    
    
            //- Interpolates cCoords, pCoords.
            //  Uses the references to the original fields used to create the
            //  iso surface.
    
            template<class Type>
    
    mattijs's avatar
    mattijs committed
            (
                const GeometricField<Type, fvPatchField, volMesh>& cCoords,
                const Field<Type>& pCoords
            ) const;
    
    
    mattijs's avatar
    mattijs committed
    };
    
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    } // End namespace Foam
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    
    mattijs's avatar
    mattijs committed
    #ifdef NoRepository
    
        #include "isoSurfaceTemplates.C"
    
    mattijs's avatar
    mattijs committed
    #endif
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    
    mattijs's avatar
    mattijs committed
    #endif
    
    // ************************************************************************* //