Skip to content
Snippets Groups Projects
distanceSurface.H 12.4 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-2022 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::distanceSurface
    
    Description
    
        A surface defined by a distance from an input searchable surface.
    
        Uses an iso-surface algorithm (cell, topo, point) for constructing the
    
        For a zero-distance surface, it performs additional checks and supports
        filtering to handle the surface boundaries.
    
    
        Example of function object partial specification:
        \verbatim
        surfaces
        {
            surface1
            {
                type        distanceSurface;
                surfaceType triSurfaceMesh;
                surfaceName something.obj;
    
            }
    
            surface2
            {
                type        distanceSurface;
                surfaceType triSurfaceMesh;
                surfaceName other.obj;
    
                topology    nearestPoints;
                nearestPoints
                (
                    (0 0 0)
                    (10 10 0)
                );
    
                // Max search distance for nearestPoints
                maxDistance 0.005;
            }
        }
        \endverbatim
    
    
        Dictionary controls:
        \table
    
            Property | Description                              | Required | Default
    
            distance | distance from surface                    | no  | 0
            signed   | Use sign when distance is positive       | no  | true
            isoMethod | Iso-algorithm (cell/topo/point)         | no  | default
    
            regularise | Face simplification (enum or bool)     | no  | true
    
            bounds   | Limit with bounding box                  | no  |
            surfaceType | Type of surface                       | yes |
            surfaceName | Name of surface in \c triSurface/     | no  | dict name
    
            topology    | Topology filter name                  | no  | none
    
            nearestPoints | Points for point-based segmentation | no  |
            maxDistance | Max search distance for nearestPoints | no  | GREAT
            absProximity | Max proximity of face centres        | no  | 1e-5
    
    mattijs's avatar
    mattijs committed
    
    
        Topology/Filtering (for zero-distance only).
        These represent different ways to tackle the "ragged edge" problem.
    
        - \c none :
            No filtering
    
        - \c proximityFaces or \c proximity (post-filter):
            Checks the resulting faces against the original search surface
            and rejects faces with a distance greater than \c absProximity.
    
    
        - \c proximityRegions (post-filter):
    
            Checks the distance of the resulting faces against the original
            search surface. Filters based on the area-weighted distance
            of each topologically connected region.
            If the area-weighted distance of a region is greater than
            \c absProximity, the entire region is rejected.
    
    
        - \c largestRegion (pre-filter):
            The cut cells are checked for topological connectivity and the
            region with the most number of cut cells is retained.
    
        - \c nearestPoints (pre-filter):
            The cut cells split into regions, the regions closest to the
            user-defined points are retained.
            Uses \c maxDistance for additional control.
        .
    
    
        For distance = 0, some special adjustments.
        - Always signed (ignoring the input value).
        - Use normal distance from surface (for better treatment of open edges).
    
        - Additional checks for open surfaces edges are used to limit the extend
          of resulting distance surface.
          The resulting surface elements will, however, contain partial cell
          coverage. NB: Not applicable if the \c point isoMethod is used.
    
    Mark OLESEN's avatar
    Mark OLESEN committed
    The keyword \c cell (bool value) which was use in 1906 and earlier to switch
    between point/cell algorithms is now ignored (2020-12).
    
    Changed default algorithm from cell to topo (2020-12).
    
    
    mattijs's avatar
    mattijs committed
    SourceFiles
        distanceSurface.C
    
    mattijs's avatar
    mattijs committed
    
    \*---------------------------------------------------------------------------*/
    
    
    #ifndef Foam_distanceSurface_H
    #define Foam_distanceSurface_H
    
    mattijs's avatar
    mattijs committed
    
    #include "sampledSurface.H"
    #include "searchableSurface.H"
    
    #include "isoSurfaceBase.H"
    
    #include "pointIndexHit.H"
    
    mattijs's avatar
    mattijs committed
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    namespace Foam
    {
    
    /*---------------------------------------------------------------------------*\
                           Class distanceSurface Declaration
    \*---------------------------------------------------------------------------*/
    
    class distanceSurface
    {
    
        // Data Types
    
            //- The type of pre/post face-filtering
            enum class topologyFilterType : uint8_t
            {
                NONE,               //!< No additional filtering
                LARGEST_REGION,     //!< Retain largest region
                NEAREST_POINTS,     //!< Retain regions nearest to the points
    
                PROXIMITY_REGIONS,  //!< Retain regions with good surface proximity
                PROXIMITY_FACES,    //!< Retain faces with good surface proximity
                PROXIMITY = PROXIMITY_FACES
    
            };
    
            //- Names for the topology filter
            static const Enum<topologyFilterType> topoFilterNames_;
    
    
    
    mattijs's avatar
    mattijs committed
    
    
            //- Reference to mesh
            const polyMesh& mesh_;
    
    
            //- Searchable surface
            const autoPtr<searchableSurface> geometryPtr_;
    
    mattijs's avatar
    mattijs committed
    
    
    mattijs's avatar
    mattijs committed
            const scalar distance_;
    
    
            //- Distance is zero. Implies signed and additional optimizations
            const bool withZeroDistance_;
    
            //- Use signed distance
            const bool withSignDistance_;
    
    mattijs's avatar
    mattijs committed
    
    
    Mark OLESEN's avatar
    Mark OLESEN committed
            //- Parameters for iso-surface (algorithm, filter, mergeTol, etc)
            isoSurfaceParams isoParams_;
    
            //- Optional topology face-filtering
            topologyFilterType topoFilter_;
    
            //- Points for nearest-points segmentation
            pointField nearestPoints_;
    
            //- Max search distance squared (for nearestPoints)
            scalar maxDistanceSqr_;
    
            //- Max distance for proximity check (post-filtering)
            scalar absProximity_;
    
    
            //- Distance to cell centres
            autoPtr<volScalarField> cellDistancePtr_;
    
    mattijs's avatar
    mattijs committed
    
    
            //- Distance to points
            scalarField pointDistance_;
    
    mattijs's avatar
    mattijs committed
    
    
        // Sampling geometry. Directly stored or via an iso-surface (ALGO_POINT)
    
            //- The extracted surface (direct storage)
            mutable meshedSurface surface_;
    
            //- For every face the original cell in mesh (direct storage)
            mutable labelList meshCells_;
    
            //- Extracted iso-surface, for interpolators
    
            mutable autoPtr<isoSurfaceBase> isoSurfacePtr_;
    
        // Private Member Functions
    
            //- Absolute distances from hit points
            //  Hit/miss checks have been done elsewhere.
            static inline void calcAbsoluteDistance
            (
                scalarField& distance,
                const pointField& points,
                const List<pointIndexHit>& nearest
            )
            {
                forAll(nearest, i)
                {
                    distance[i] = Foam::mag(points[i] - nearest[i].point());
                }
            }
    
    
    
    protected:
    
        // Protected Member Functions
    
            //- Is currently backed by an isoSurfacePtr_
            bool hasIsoSurface() const
            {
                return bool(isoSurfacePtr_);
            }
    
            //- Interpolate volume field onto surface points
            template<class Type>
            tmp<Field<Type>> isoSurfaceInterpolate
            (
    
                const VolumeField<Type>& cellValues,
    
                const Field<Type>& pointValues
            ) const
            {
                if (isoSurfacePtr_)
                {
                    return isoSurfacePtr_->interpolate(cellValues, pointValues);
                }
    
                return nullptr;
            }
    
    mattijs's avatar
    mattijs committed
    
    
        // Private Member Functions
    
            //- Re-filter the blocked cells based on the anticipated cuts
            //  Uses a lightweight variant of cutting.
            bool refineBlockedCells
            (
                bitSet& ignoreCells,
                const isoSurfaceBase& isoContext
            ) const;
    
            //- Prepare blockedFaces for region split
            bitSet filterPrepareRegionSplit(const bitSet& ignoreCells) const;
    
            //- Keep region with the most cuts (after region split)
            void filterKeepLargestRegion(bitSet& ignoreCells) const;
    
            //- Keep region(s) closest to the nearest points
            void filterKeepNearestRegions(bitSet& ignoreCells) const;
    
    
            //- Remove region(s) that have far faces
            void filterRegionProximity(bitSet& ignoreCells) const;
    
            //- Adjust extracted iso-surface to remove far faces
            void filterFaceProximity();
    
    
    mattijs's avatar
    mattijs committed
    public:
    
        //- Runtime type information
        TypeName("distanceSurface");
    
    
        // Constructors
    
            //- Construct from dictionary
            distanceSurface
            (
    
                const word& defaultSurfaceName,
    
    mattijs's avatar
    mattijs committed
                const polyMesh& mesh,
                const dictionary& dict
            );
    
    
            //- Construct from components with zero-distanced
            distanceSurface
            (
                const polyMesh& mesh,
                const word& surfaceType,
                const word& surfaceName,
                const isoSurfaceParams& params = isoSurfaceParams(),
                const bool interpolate = false
            );
    
    
            //- Construct from components
            distanceSurface
            (
                const polyMesh& mesh,
                const bool interpolate,
                const word& surfaceType,
                const word& surfaceName,
                const scalar distance,
    
    Mark OLESEN's avatar
    Mark OLESEN committed
                const bool useSignedDistance,
                const isoSurfaceParams& params = isoSurfaceParams()
    
            distanceSurface
            (
                const polyMesh& mesh,
                const bool interpolate,
                autoPtr<searchableSurface>&& surface,
                const scalar distance,
                const bool useSignedDistance,
                const isoSurfaceParams& params = isoSurfaceParams()
            );
    
    
    mattijs's avatar
    mattijs committed
    
    
        virtual ~distanceSurface() = default;
    
    mattijs's avatar
    mattijs committed
    
    
        // Member Functions
    
    
            //- Create/recreate the distance surface
            void createGeometry();
    
    mattijs's avatar
    mattijs committed
    
    
            //- The name of the underlying searchableSurface
            const word& surfaceName() const
    
                return geometryPtr_->name();
    
            //- The distance to the underlying searchableSurface
    
            scalar distance() const noexcept
    
            //- The underlying surface
            const meshedSurface& surface() const
    
            //- The underlying surface
    
            meshedSurface& surface()
    
    mattijs's avatar
    mattijs committed
    
    
            //- For each face, the original cell in mesh
            const labelList& meshCells() const
            {
    
                    return isoSurfacePtr_->meshCells();
    
            //- For each face, the original cell in mesh
            labelList& meshCells()
            {
    
                    return isoSurfacePtr_->meshCells();
    
    mattijs's avatar
    mattijs committed
    
    
    
    mattijs's avatar
    mattijs committed
    
    
            void print(Ostream& os, int level=0) const;
    
    mattijs's avatar
    mattijs committed
    };
    
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    } // End namespace Foam
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    #endif
    
    // ************************************************************************* //