Loading...
Searching...
No Matches
smoothTriSurfaceMesh.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2016-2018 OpenFOAM Foundation
9 Copyright (C) 2025 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
33// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34
35namespace Foam
36{
37
40
41}
42
43
44// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
45
46void Foam::smoothTriSurfaceMesh::calcFeatureEdges(const scalar featureAngle)
47{
48 if (featureAngle <= -180)
49 {
50 return;
51 }
52
53 const triSurface& s = *this;
54
55 scalar cosAngle = Foam::cos(degToRad(featureAngle));
56
57 const labelListList& edgeFaces = s.edgeFaces();
58 const edgeList& edges = s.edges();
59
60 forAll(edgeFaces, edgei)
61 {
62 const labelList& eFaces = edgeFaces[edgei];
63
64 if (eFaces.size() > 2)
65 {
66 isBorderEdge_[edgei] = true;
67 }
68 else if (eFaces.size() == 2)
69 {
70 const vector n0(s[eFaces[0]].unitNormal(points()));
71 const vector n1(s[eFaces[1]].unitNormal(points()));
72 if ((n0&n1) < cosAngle)
73 {
74 isBorderEdge_[edgei] = true;
75 }
76 }
77 }
78
79 forAll(isBorderEdge_, edgei)
80 {
81 if (isBorderEdge_[edgei])
82 {
83 const edge& e = edges[edgei];
84 isPointOnBorderEdge_[e[0]] = true;
85 isPointOnBorderEdge_[e[1]] = true;
86 }
87 }
88}
89
90
91Foam::vector Foam::smoothTriSurfaceMesh::pointNormal
92(
93 const label startFacei,
94 const label localPointi
95) const
96{
97 const triSurface& s = *this;
98
99 if (!isPointOnBorderEdge_[localPointi])
100 {
101 const labelList& pFaces = pointFaces()[localPointi];
102 vector pn(Zero);
103 forAll(pFaces, i)
104 {
105 label facei = pFaces[i];
106 pn += s[facei].unitNormal(points());
107 }
108 return pn.normalise();
109 }
110
111
112 // Calculate the local point normal on the face. This routine
113 // only gets called if the point is on a border edge so we can
114 // walk and always hit a border edge.
115
116 const edgeList& edges = triSurface::edges();
117 const labelList& fEdges = faceEdges()[startFacei];
118
119 // Get the two edges on the point
120 label e0 = -1;
121 label e1 = -1;
122 forAll(fEdges, i)
123 {
124 const edge& e = edges[fEdges[i]];
125 if (e.otherVertex(localPointi) == -1)
126 {
127 e0 = fEdges[fEdges.rcIndex(i)];
128 e1 = fEdges[fEdges.fcIndex(i)];
129 break;
130 }
131 }
132
133 label facei = startFacei;
134 label edgei = e0;
135
136 // Initialise normal
137 vector n(s[facei].unitNormal(points()));
138
139 while (!isBorderEdge_[edgei])
140 {
141 // Cross edge to next face
142 const labelList& eFaces = edgeFaces()[edgei];
143 if (eFaces.size() != 2)
144 {
145 break;
146 }
147
148 forAll(eFaces, i)
149 {
150 if (eFaces[i] != facei)
151 {
152 facei = eFaces[i];
153 break;
154 }
155 }
156
157 if (facei == startFacei)
158 {
159 break;
160 }
161
162 n += s[facei].unitNormal(points());
163
164 // Cross face to next edge
165 const labelList& fEdges = faceEdges()[facei];
166
167 forAll(fEdges, i)
168 {
169 label ei = fEdges[i];
170 if (ei != edgei && edges[ei].otherVertex(localPointi) != -1)
171 {
172 edgei = ei;
173 break;
174 }
175 }
176 }
177
178
179 // Walk in other direction
180 {
181
182 facei = startFacei;
183 edgei = e1;
184
185 while (!isBorderEdge_[edgei])
186 {
187 // Cross edge to next face
188 const labelList& eFaces = edgeFaces()[edgei];
189 if (eFaces.size() != 2)
190 {
191 break;
192 }
193
194 forAll(eFaces, i)
195 {
196 if (eFaces[i] != facei)
197 {
198 facei = eFaces[i];
199 break;
200 }
201 }
202
203 if (facei == startFacei)
204 {
205 break;
206 }
207
208 n += s[facei].unitNormal(points());
209
210 // Cross face to next edge
211 const labelList& fEdges = faceEdges()[facei];
212
213 forAll(fEdges, i)
214 {
215 label ei = fEdges[i];
216 if (ei != edgei && edges[ei].otherVertex(localPointi) != -1)
217 {
218 edgei = ei;
219 break;
220 }
221 }
222 }
223 }
225 return n.normalise();
226}
227
228
229// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
230
231Foam::smoothTriSurfaceMesh::smoothTriSurfaceMesh
232(
233 const IOobject& io,
234 const scalar featureAngle
235)
236:
238 isBorderEdge_(nEdges()),
239 isPointOnBorderEdge_(nPoints())
240{
241 calcFeatureEdges(featureAngle);
242}
243
244
245Foam::smoothTriSurfaceMesh::smoothTriSurfaceMesh
246(
247 const IOobject& io,
248 const dictionary& dict
249)
250:
252 isBorderEdge_(nEdges()),
253 isPointOnBorderEdge_(nPoints())
254{
255 if (dict.found("featureAngle"))
256 {
257 calcFeatureEdges(readScalar(dict.lookup("featureAngle")));
258 }
259}
260
261
262// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
265{}
266
267
268// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
269
271(
272 const List<pointIndexHit>& info,
273 vectorField& normal
274) const
275{
276 const triSurface& s = static_cast<const triSurface&>(*this);
277 const pointField& pts = s.points();
278
279 DebugPout<< "smoothTriSurfaceMesh::getNormal :"
280 << " surface:" << this->searchableSurface::name()
281 << " tris:" << s.size()
282 << " feat edges:" << isBorderEdge_.count()
283 << endl;
284
285 normal.setSize(info.size());
286
287 forAll(info, i)
288 {
289 if (info[i].hit())
290 {
291 label facei = info[i].index();
292
293 // Get local coordinates in triangle
295 (
296 s[facei].tri(pts).pointToBarycentric(info[i].hitPoint())
297 );
298
299 // Average point normals
300 const triFace& localTri = s.localFaces()[facei];
301
302 vector n(Zero);
303 forAll(localTri, fp)
304 {
305 n += coordinates[fp]*pointNormal(facei, localTri[fp]);
306 }
307 normal[i] = n.normalise();
308 }
309 else
310 {
311 // Set to what?
312 normal[i] = Zero;
313 }
314 }
315}
316
317
318// ************************************************************************* //
label n
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition IOobject.H:191
const word & name() const noexcept
Return the object name.
Definition IOobjectI.H:205
InfoProxy< IOobject > info() const noexcept
Return info proxy, for printing information to a stream.
Definition IOobject.H:1041
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
void setSize(label n)
Alias for resize().
Definition List.H:536
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
An edge is a list of two vertex labels. This can correspond to a directed graph edge or an edge on a ...
Definition edge.H:62
Base class of (analytical or triangulated) surface. Encapsulates all the search routines....
Variant of triSurfaceMesh that interpolates face-normals to obtain point normals.
virtual ~smoothTriSurfaceMesh()
Destructor.
virtual void getNormal(const List< pointIndexHit > &, vectorField &normal) const
From a set of points and indices get the normal.
A triangular face using a FixedList of labels corresponding to mesh vertices.
Definition triFace.H:68
IOoject and searching on triSurface.
triSurfaceMesh(const triSurfaceMesh &)=delete
No copy construct.
virtual tmp< pointField > coordinates() const
Get representative set of element coordinates.
virtual tmp< pointField > points() const
Get the points that define the surface.
Triangulated surface description with patch information.
Definition triSurface.H:74
triSurface()
Default construct.
Definition triSurface.C:426
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
PtrList< coordinateSystem > coordinates(solidRegions.size())
const auto & io
const pointField & points
label nPoints
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
#define DebugPout
Report an information message using Foam::Pout.
Namespace for OpenFOAM.
List< edge > edgeList
List of edge.
Definition edgeList.H:32
List< labelList > labelListList
List of labelList.
Definition labelList.H:38
List< label > labelList
A List of labels.
Definition List.H:62
Barycentric2D< scalar > barycentric2D
A scalar version of the templated Barycentric2D.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
constexpr scalar degToRad() noexcept
Multiplication factor for degrees to radians conversion.
Field< vector > vectorField
Specialisation of Field<T> for vector.
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
vectorField pointField
pointField is a vectorField.
Vector< scalar > vector
Definition vector.H:57
dimensionedScalar cos(const dimensionedScalar &ds)
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=cellModel::ref(cellModel::HEX);labelList hexLabels(8);label activeCells=0;labelList pointMap(nPoints);forAll(pointMap, i){ pointMap[i]=i;}for(label i=0;i< nPoints;i++){ if(f[i] > 0.0) { hexLabels[0]=i;hexLabels[1]=i1tab[i];hexLabels[2]=i3tab[i1tab[i]];hexLabels[3]=i3tab[i];hexLabels[4]=i8tab[i];hexLabels[5]=i1tab[i8tab[i]];hexLabels[6]=i3tab[i1tab[i8tab[i]]];hexLabels[7]=i3tab[i8tab[i]];cellShapes[activeCells].reset(hex, hexLabels);edgeList edges=cellShapes[activeCells].edges();forAll(edges, ei) { if(edges[ei].mag(points)< SMALL) { label start=pointMap[edges[ei].start()];while(start !=pointMap[start]) { start=pointMap[start];} label end=pointMap[edges[ei].end()];while(end !=pointMap[end]) { end=pointMap[end];} pointMap[start]=pointMap[end]=Foam::min(start, end);} } cellZoning[activeCells]=idreg[i];activeCells++;}}cellShapes.setSize(activeCells);cellZoning.setSize(activeCells);forAll(cellShapes, celli){ cellShape &cs=cellShapes[celli];forAll(cs, i) { cs[i]=pointMap[cs[i]];} cs.collapse();}label bcIDs[11]={-1, 0, 2, 4, -1, 5, -1, 6, 7, 8, 9};constexpr label nBCs=12;const word *kivaPatchTypes[nBCs]={ &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &symmetryPolyPatch::typeName, &wedgePolyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &symmetryPolyPatch::typeName, &oldCyclicPolyPatch::typeName};enum patchTypeNames{ PISTON, VALVE, LINER, CYLINDERHEAD, AXIS, WEDGE, INFLOW, OUTFLOW, PRESIN, PRESOUT, SYMMETRYPLANE, CYCLIC};const char *kivaPatchNames[nBCs]={ "piston", "valve", "liner", "cylinderHead", "axis", "wedge", "inflow", "outflow", "presin", "presout", "symmetryPlane", "cyclic"};List< DynamicList< face > > pFaces[nBCs]
dictionary dict
const pointField & pts
volScalarField & e
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299
Unit conversion functions.