Newer
Older
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2019 OpenCFD Ltd.
-------------------------------------------------------------------------------
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.
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/>.
Class
Foam::isoSurface
Description
A surface formed by the iso value.
After "Regularised Marching Tetrahedra: improved iso-surface extraction",
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.
- uses geometric merge with fraction of bounding box as distance.
- triangles can be between two cell centres so constant sampling
does not make sense.
- 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.
isoSurfaceTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef isoSurface_H
#define isoSurface_H
#include "bitSet.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declarations
class plane;
class treeBoundBox;
class triSurface;
/*---------------------------------------------------------------------------*\
Class isoSurface Declaration
\*---------------------------------------------------------------------------*/
class isoSurface
:
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
};
const scalarField& pVals_;
//- Input volScalarField with separated coupled patches rewritten
autoPtr<slicedVolScalarField> cValsPtr_;
//- Whether face might be cut
List<cellCutType> faceCutType_;
//- Whether cell might be cut
List<cellCutType> cellCutType_;
//- Estimated number of cut cells
label nCutCells_;
//- 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_;
DynamicList<FixedList<scalar, 3>> interpolationWeights_;
// 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);
bitSet collocatedFaces(const coupledPolyPatch&) const;
//- Synchronise points on all non-separated coupled patches
void syncUnseparatedPoints
(
pointField& collapsedPoint,
const point& nullValue
) const;
//- Get location of iso value as fraction inbetween s0,s1
scalar isoFraction
//- Check if any edge of a face is cut
bool isEdgeOfFaceCut
(
const scalarField& pVals,
const face& f,
const bool ownLower,
const bool neiLower
) const;
Henry Weller
committed
//- Get neighbour value and position.
void getNeighbour
(
const labelList& boundaryRegion,
const label celli,
const label facei,
Henry Weller
committed
//- Determine for every face/cell whether it (possibly) generates
// triangles.
const volScalarField& cVals,
const scalarField& pVals
);
static point calcCentre(const triSurface&);
//- Determine per cc whether all near cuts can be snapped to single
// point.
void calcSnappedCc
labelList& snappedCc
) const;
//- Determine per point whether all near cuts can be snapped to single
// point.
void calcSnappedPoint
(
const bitSet& isBoundaryPoint,
//- Return input field with coupled (and empty) patch values rewritten
template<class Type>
tmp<SlicedGeometricField
Henry Weller
committed
<Type, fvPatchField, slicedFvPatchField, volMesh>>
adaptPatchFields
(
const GeometricField<Type, fvPatchField, volMesh>& fld
) const;
Henry Weller
committed
//- Note: cannot use simpler isoSurfaceCell::generateTriPoints since
// the need here to sometimes pass in remote 'snappedPoints'
DynamicList<Type>& pts
(
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
) 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
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
);
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
const PtrList<plane>& planes,
const triPointRef& tri,
DynamicList<point>& newTriPoints
//- Trim all triangles to box
static void trimToBox
const treeBoundBox& bb,
DynamicList<point>& triPoints,
DynamicList<label>& triMeshCells
//- Trim all triangles to box. Determine interpolation
// for existing and new points
static void trimToBox
const treeBoundBox& bb,
DynamicList<point>& triPoints,
DynamicList<label>& triMap,
labelList& triPointMap,
labelList& interpolatedPoints,
List<FixedList<label, 3>>& interpolatedOldPoints,
List<FixedList<scalar, 3>>& interpolationWeights
const triSurface&,
//- Declare friendship to share some functionality
friend class isoSurfaceTopo;
//- Filtering type
using isoSurfaceBase::filterType;
//- 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
const volScalarField& cellValues,
const scalarField& pointValues,
const boundBox& bounds = boundBox::invertedBox,
const scalar mergeTol = 1e-6
//- Interpolates cCoords, pCoords.
// Uses the references to the original fields used to create the
// iso surface.
Henry Weller
committed
tmp<Field<Type>> interpolate
(
const GeometricField<Type, fvPatchField, volMesh>& cCoords,
const Field<Type>& pCoords
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "isoSurfaceTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //