1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-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 //- Take value at local point patchPointI and assign it to its
153 // correct place in patchValues (for transferral) and sharedValues
157 const processorPolyPatch& pp,
158 const Map<label>& meshToShared,
159 const pointField& pointValues,
160 const label patchPointI,
161 pointField& patchValues,
162 pointField& sharedValues
165 //- Synchonise points on all non-separated coupled patches
166 void syncUnseparatedPoints
168 pointField& collapsedPoint,
169 const point& nullValue
173 //- Get location of iso value as fraction inbetween s0,s1
180 //- Check if any edge of a face is cut
183 const scalarField& pVals,
191 const labelList& boundaryRegion,
192 const volVectorField& meshC,
193 const volScalarField& cVals,
200 //- Set faceCutType,cellCutType.
203 const labelList& boundaryRegion,
204 const volVectorField& meshC,
205 const volScalarField& cVals,
206 const scalarField& pVals
209 static labelPair findCommonPoints
215 static point calcCentre(const triSurface&);
217 static pointIndexHit collapseSurface
219 pointField& localPoints,
220 DynamicList<labelledTri, 64>& localTris
223 //- Determine per cc whether all near cuts can be snapped to single
227 const labelList& boundaryRegion,
228 const volVectorField& meshC,
229 const volScalarField& cVals,
230 const scalarField& pVals,
231 DynamicList<point>& snappedPoints,
235 //- Determine per point whether all near cuts can be snapped to single
237 void calcSnappedPoint
239 const PackedBoolList& isBoundaryPoint,
240 const labelList& boundaryRegion,
241 const volVectorField& meshC,
242 const volScalarField& cVals,
243 const scalarField& pVals,
244 DynamicList<point>& snappedPoints,
245 labelList& snappedPoint
249 //- Return input field with coupled (and empty) patch values rewritten
251 tmp<SlicedGeometricField
252 <Type, fvPatchField, slicedFvPatchField, volMesh> >
255 const GeometricField<Type, fvPatchField, volMesh>& fld
258 //- Generate single point by interpolation or snapping
274 void generateTriPoints
296 DynamicList<Type>& points
300 label generateFaceTriPoints
302 const volScalarField& cVals,
303 const scalarField& pVals,
305 const GeometricField<Type, fvPatchField, volMesh>& cCoords,
306 const Field<Type>& pCoords,
308 const DynamicList<Type>& snappedPoints,
309 const labelList& snappedCc,
310 const labelList& snappedPoint,
315 const bool hasNeiSnap,
316 const Type& neiSnapPt,
318 DynamicList<Type>& triPoints,
319 DynamicList<label>& triMeshCells
323 void generateTriPoints
325 const volScalarField& cVals,
326 const scalarField& pVals,
328 const GeometricField<Type, fvPatchField, volMesh>& cCoords,
329 const Field<Type>& pCoords,
331 const DynamicList<Type>& snappedPoints,
332 const labelList& snappedCc,
333 const labelList& snappedPoint,
335 DynamicList<Type>& triPoints,
336 DynamicList<label>& triMeshCells
339 triSurface stitchTriPoints
341 const bool checkDuplicates,
342 const List<point>& triPoints,
343 labelList& triPointReverseMap, // unmerged to merged point
344 labelList& triMap // merged to unmerged triangle
347 //- Check single triangle for (topological) validity
348 static bool validTri(const triSurface&, const label);
350 //- Determine edge-face addressing
353 const triSurface& surf,
354 List<FixedList<label, 3> >& faceEdges,
355 labelList& edgeFace0,
356 labelList& edgeFace1,
357 Map<labelList>& edgeFacesRest
360 //- Determine orientation
361 static void walkOrientation
363 const triSurface& surf,
364 const List<FixedList<label, 3> >& faceEdges,
365 const labelList& edgeFace0,
366 const labelList& edgeFace1,
367 const label seedTriI,
372 static void orientSurface
375 const List<FixedList<label, 3> >& faceEdges,
376 const labelList& edgeFace0,
377 const labelList& edgeFace1,
378 const Map<labelList>& edgeFacesRest
381 //- Is triangle (given by 3 edges) not fully connected?
382 static bool danglingTriangle
384 const FixedList<label, 3>& fEdges,
385 const labelList& edgeFace1
388 //- Mark all non-fully connected triangles
389 static label markDanglingTriangles
391 const List<FixedList<label, 3> >& faceEdges,
392 const labelList& edgeFace0,
393 const labelList& edgeFace1,
394 const Map<labelList>& edgeFacesRest,
395 boolList& keepTriangles
398 static triSurface subsetMesh
401 const labelList& newToOldFaces,
402 labelList& oldToNewPoints,
403 labelList& newToOldPoints
408 //- Runtime type information
409 TypeName("isoSurface");
414 //- Construct from cell values and point values. Uses boundaryField
415 // for boundary values. Holds reference to cellIsoVals and
419 const volScalarField& cellIsoVals,
420 const scalarField& pointIsoVals,
422 const bool regularise,
423 const scalar mergeTol = 1E-6 // fraction of bounding box
429 //- For every face original cell in mesh
430 const labelList& meshCells() const
435 //- For every unmerged triangle point the point in the triSurface
436 const labelList& triPointMergeMap() const
438 return triPointMergeMap_;
441 //- Interpolates cCoords,pCoords. Uses the references to the original
442 // fields used to create the iso surface.
443 template <class Type>
444 tmp<Field<Type> > interpolate
446 const GeometricField<Type, fvPatchField, volMesh>& cCoords,
447 const Field<Type>& pCoords
453 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
455 } // End namespace Foam
457 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
460 # include "isoSurfaceTemplates.C"
463 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
467 // ************************************************************************* //