1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
28 A surface formed by the iso value.
29 After "Regularised Marching Tetrahedra: improved iso-surface extraction",
30 G.M. Treece, R.W. Prager and A.H. Gee.
33 - does tets without using cell centres/cell values. Not tested.
34 - regularisation can create duplicate triangles/non-manifold surfaces.
35 Current handling of those is bit ad-hoc for now and not perfect.
36 - regularisation does not do boundary points so as to preserve the
38 - uses geometric merge with fraction of bounding box as distance.
39 - triangles can be between two cell centres so constant sampling
41 - on empty patches behaves like zero gradient.
42 - does not do 2D correctly, creates non-flat iso surface.
43 - on processor boundaries might two overlapping (identical) triangles
44 (one from either side)
46 The handling on coupled patches is a bit complex. All fields
47 (values and coordinates) get rewritten so
48 - empty patches get zerogradient (value) and facecentre (coordinates)
49 - separated processor patch faces get interpolate (value) and facecentre
50 (coordinates). (this is already the default for cyclics)
51 - non-separated processor patch faces keep opposite value and cell centre
53 Now the triangle generation on non-separated processor patch faces
54 can use the neighbouring value. Any separated processor face or cyclic
55 face gets handled just like any boundary face.
61 \*---------------------------------------------------------------------------*/
66 #include "triSurface.H"
67 #include "labelPair.H"
68 #include "pointIndexHit.H"
69 #include "PackedBoolList.H"
70 #include "volFields.H"
71 #include "slicedVolFields.H"
73 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
80 /*---------------------------------------------------------------------------*\
81 Class isoSurface Declaration
82 \*---------------------------------------------------------------------------*/
92 NEARFIRST, // intersection close to e.first()
93 NEARSECOND, // ,, e.second()
94 NOTNEAR // no intersection
100 SPHERE, // all edges to cell centre cut
105 //- Reference to mesh
108 const scalarField& pVals_;
110 //- Input volScalarField with separated coupled patches rewritten
111 autoPtr<slicedVolScalarField> cValsPtr_;
117 const Switch regularise_;
119 //- When to merge points
120 const scalar mergeDistance_;
123 //- Whether face might be cut
124 List<cellCutType> faceCutType_;
126 //- Whether cell might be cut
127 List<cellCutType> cellCutType_;
129 //- Estimated number of cut cells
132 //- For every triangle the original cell in mesh
133 labelList meshCells_;
135 //- For every unmerged triangle point the point in the triSurface
136 labelList triPointMergeMap_;
139 // Private Member Functions
141 // Point synchronisation
143 //- Does tensor differ (to within mergeTolerance) from identity
144 bool noTransform(const tensor& tt) const;
146 //- Is patch a collocated (i.e. non-separated) coupled patch?
147 static bool collocatedPatch(const polyPatch&);
149 //- Per face whether is collocated
150 PackedBoolList collocatedFaces(const coupledPolyPatch&) const;
152 //- Synchonise points on all non-separated coupled patches
153 void syncUnseparatedPoints
155 pointField& collapsedPoint,
156 const point& nullValue
160 //- Get location of iso value as fraction inbetween s0,s1
167 //- Check if any edge of a face is cut
170 const scalarField& pVals,
178 const labelList& boundaryRegion,
179 const volVectorField& meshC,
180 const volScalarField& cVals,
187 //- Set faceCutType,cellCutType.
190 const labelList& boundaryRegion,
191 const volVectorField& meshC,
192 const volScalarField& cVals,
193 const scalarField& pVals
196 static labelPair findCommonPoints
202 static point calcCentre(const triSurface&);
204 static pointIndexHit collapseSurface
206 pointField& localPoints,
207 DynamicList<labelledTri, 64>& localTris
210 //- Determine per cc whether all near cuts can be snapped to single
214 const labelList& boundaryRegion,
215 const volVectorField& meshC,
216 const volScalarField& cVals,
217 const scalarField& pVals,
218 DynamicList<point>& snappedPoints,
222 //- Determine per point whether all near cuts can be snapped to single
224 void calcSnappedPoint
226 const PackedBoolList& isBoundaryPoint,
227 const labelList& boundaryRegion,
228 const volVectorField& meshC,
229 const volScalarField& cVals,
230 const scalarField& pVals,
231 DynamicList<point>& snappedPoints,
232 labelList& snappedPoint
236 //- Return input field with coupled (and empty) patch values rewritten
238 tmp<SlicedGeometricField
239 <Type, fvPatchField, slicedFvPatchField, volMesh> >
242 const GeometricField<Type, fvPatchField, volMesh>& fld
245 //- Generate single point by interpolation or snapping
261 void generateTriPoints
283 DynamicList<Type>& points
287 label generateFaceTriPoints
289 const volScalarField& cVals,
290 const scalarField& pVals,
292 const GeometricField<Type, fvPatchField, volMesh>& cCoords,
293 const Field<Type>& pCoords,
295 const DynamicList<Type>& snappedPoints,
296 const labelList& snappedCc,
297 const labelList& snappedPoint,
302 const bool hasNeiSnap,
303 const Type& neiSnapPt,
305 DynamicList<Type>& triPoints,
306 DynamicList<label>& triMeshCells
310 void generateTriPoints
312 const volScalarField& cVals,
313 const scalarField& pVals,
315 const GeometricField<Type, fvPatchField, volMesh>& cCoords,
316 const Field<Type>& pCoords,
318 const DynamicList<Type>& snappedPoints,
319 const labelList& snappedCc,
320 const labelList& snappedPoint,
322 DynamicList<Type>& triPoints,
323 DynamicList<label>& triMeshCells
326 triSurface stitchTriPoints
328 const bool checkDuplicates,
329 const List<point>& triPoints,
330 labelList& triPointReverseMap, // unmerged to merged point
331 labelList& triMap // merged to unmerged triangle
334 //- Check single triangle for (topological) validity
335 static bool validTri(const triSurface&, const label);
337 //- Determine edge-face addressing
340 const triSurface& surf,
341 List<FixedList<label, 3> >& faceEdges,
342 labelList& edgeFace0,
343 labelList& edgeFace1,
344 Map<labelList>& edgeFacesRest
347 //- Determine orientation
348 static void walkOrientation
350 const triSurface& surf,
351 const List<FixedList<label, 3> >& faceEdges,
352 const labelList& edgeFace0,
353 const labelList& edgeFace1,
354 const label seedTriI,
359 static void orientSurface
362 const List<FixedList<label, 3> >& faceEdges,
363 const labelList& edgeFace0,
364 const labelList& edgeFace1,
365 const Map<labelList>& edgeFacesRest
368 //- Is triangle (given by 3 edges) not fully connected?
369 static bool danglingTriangle
371 const FixedList<label, 3>& fEdges,
372 const labelList& edgeFace1
375 //- Mark all non-fully connected triangles
376 static label markDanglingTriangles
378 const List<FixedList<label, 3> >& faceEdges,
379 const labelList& edgeFace0,
380 const labelList& edgeFace1,
381 const Map<labelList>& edgeFacesRest,
382 boolList& keepTriangles
385 static triSurface subsetMesh
388 const labelList& newToOldFaces,
389 labelList& oldToNewPoints,
390 labelList& newToOldPoints
395 //- Runtime type information
396 TypeName("isoSurface");
401 //- Construct from cell values and point values. Uses boundaryField
402 // for boundary values. Holds reference to cellIsoVals and
406 const volScalarField& cellIsoVals,
407 const scalarField& pointIsoVals,
409 const bool regularise,
410 const scalar mergeTol = 1E-6 // fraction of bounding box
416 //- For every face original cell in mesh
417 const labelList& meshCells() const
422 //- For every unmerged triangle point the point in the triSurface
423 const labelList& triPointMergeMap() const
425 return triPointMergeMap_;
428 //- Interpolates cCoords,pCoords. Uses the references to the original
429 // fields used to create the iso surface.
430 template <class Type>
431 tmp<Field<Type> > interpolate
433 const GeometricField<Type, fvPatchField, volMesh>& cCoords,
434 const Field<Type>& pCoords
440 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
442 } // End namespace Foam
444 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
447 # include "isoSurfaceTemplates.C"
450 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
454 // ************************************************************************* //