tetMeshOptimisation.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | cfMesh: A library for mesh generation
4  \\ / O peration |
5  \\ / A nd | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6  \\/ M anipulation | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
8 License
9  This file is part of cfMesh.
10 
11  cfMesh is free software; you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by the
13  Free Software Foundation; either version 3 of the License, or (at your
14  option) any later version.
15 
16  cfMesh 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
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with cfMesh. If not, see <http://www.gnu.org/licenses/>.
23 
24 Description
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "demandDrivenData.H"
29 #include "tetMeshOptimisation.H"
30 #include "partTetMesh.H"
31 #include "meshSurfaceEngine.H"
33 
34 #include "partTetMeshSimplex.H"
35 #include "meshUntangler.H"
36 #include "volumeOptimizer.H"
37 #include "knuppMetric.H"
38 
39 #include <map>
40 
41 # ifdef USE_OMP
42 #include <omp.h>
43 # endif
44 
45 // #define DEBUGSearch
46 
47 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
48 
49 namespace Foam
50 {
51 
52 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
53 
54 // Construct from mesh
56 :
57  tetMesh_(mesh)
58 {}
59 
60 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
61 
63 {}
64 
65 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
66 
68 {
70  const LongList<partTet>& tets = tetMesh_.tets();
71  const LongList<direction>& smoothVertex = tetMesh_.smoothVertex();
72 
73  boolList negativeNode(smoothVertex.size()), invertedTets(tets.size());
74 
75  //- try getting rid of negative volume using the Patrik Knupp's metric
76  //- which gets non-negative contributions from invertex tets, only
77  # ifdef USE_OMP
78  # pragma omp parallel for if( tets.size() > 100 ) \
79  schedule(dynamic, 10)
80  # endif
81  forAll(tets, tetI)
82  {
83  invertedTets[tetI] = false;
84 
85  if( tets[tetI].mag(points) < VSMALL )
86  invertedTets[tetI] = true;
87  }
88 
89  label nIter(0), nNegative, nNegativeBefore;
90 
91  do
92  {
93  //- find the number of inverted tets
94  nNegative = 0;
95  negativeNode = false;
96  # ifdef USE_OMP
97  # pragma omp parallel for if( tets.size() > 100 ) \
98  schedule(dynamic, 10) reduction(+ : nNegative)
99  # endif
100  forAll(invertedTets, tetI)
101  {
102  if( invertedTets[tetI] )
103  {
104  ++nNegative;
105  const partTet& tet = tets[tetI];
106 
107  for(label i=0;i<4;++i)
108  negativeNode[tet[i]] = true;
109  }
110  }
111 
112  reduce(nNegative, sumOp<label>());
113  if( nNegative == 0 )
114  return;
115 
116  //- make sure that the points at procesor boundaries are selected
117  //- at all processors
118  if( Pstream::parRun() )
119  unifyNegativePoints(negativeNode);
120 
121  //- smooth the mesh
122  List<LongList<labelledPoint> > newPositions;
123  # ifdef USE_OMP
124  # pragma omp parallel if( smoothVertex.size() > 100 )
125  # endif
126  {
127  # ifdef USE_OMP
128  # pragma omp master
129  {
130  newPositions.setSize(omp_get_num_threads());
131  }
132 
133  # pragma omp barrier
134 
135  LongList<labelledPoint>& np = newPositions[omp_get_thread_num()];
136  # else
137  newPositions.setSize(1);
138  LongList<labelledPoint>& np = newPositions[0];
139  # endif
140 
141  # ifdef USE_OMP
142  # pragma omp for schedule(dynamic, 10)
143  # endif
144  forAll(smoothVertex, nodeI)
145  {
146  if
147  (
148  !negativeNode[nodeI] ||
149  (smoothVertex[nodeI] & partTetMesh::LOCKED)
150  )
151  continue;
152 
153  if( smoothVertex[nodeI] & partTetMesh::SMOOTH )
154  {
155  partTetMeshSimplex simplex(tetMesh_, nodeI);
157  np.append(labelledPoint(nodeI, simplex.centrePoint()));
158  }
159  }
160  }
161 
162  //- update mesh vertices
163  tetMesh_.updateVerticesSMP(newPositions);
164  newPositions.clear();
165 
166  if( Pstream::parRun() )
167  {
169  unifyCoordinatesParallel(&negativeNode);
170  }
171 
172  //- check which tets have been repaired
173  boolList helper(invertedTets.size());
174  nNegativeBefore = nNegative;
175  nNegative = 0;
176 
177  # ifdef USE_OMP
178  # pragma omp parallel for if( tets.size() > 100 ) \
179  schedule(dynamic, 10) reduction(+ : nNegative)
180  # endif
181  forAll(tets, tetI)
182  {
183  helper[tetI] = false;
184 
185  if( invertedTets[tetI] && (tets[tetI].mag(points) < VSMALL) )
186  {
187  helper[tetI] = true;
188 
189  const partTet& tet = tets[tetI];
190 
191  for(label i=0;i<4;++i)
192  negativeNode[tet[i]] = true;
193  }
194  }
195  invertedTets.transfer(helper);
196 
197  reduce(nNegative, sumOp<label>());
198  if( nNegative == 0 )
199  return;
200 
201  } while( (nNegative < nNegativeBefore) || (++nIter < nIterations) );
202 }
203 
205 {
207  const LongList<partTet>& tets = tetMesh_.tets();
208  const LongList<direction>& smoothVertex = tetMesh_.smoothVertex();
209 
210  boolList negativeNode(smoothVertex.size()), invertedTets(tets.size());
211 
212  //- try getting rid of negative volume using the untangler
213  # ifdef USE_OMP
214  # pragma omp parallel for if( tets.size() > 100 ) \
215  schedule(dynamic, 10)
216  # endif
217  forAll(tets, tetI)
218  {
219  invertedTets[tetI] = false;
220 
221  if( tets[tetI].mag(points) < VSMALL )
222  invertedTets[tetI] = true;
223  }
224 
225  label nIter(0), nNegative, nNegativeBefore;
226 
227  do
228  {
229  //- find the number of inverted tets
230  nNegative = 0;
231  negativeNode = false;
232  # ifdef USE_OMP
233  # pragma omp parallel for if( tets.size() > 100 ) \
234  schedule(dynamic, 10) reduction(+ : nNegative)
235  # endif
236  forAll(invertedTets, tetI)
237  {
238  if( invertedTets[tetI] )
239  {
240  ++nNegative;
241  const partTet& tet = tets[tetI];
242 
243  for(label i=0;i<4;++i)
244  negativeNode[tet[i]] = true;
245  }
246  }
247 
248  reduce(nNegative, sumOp<label>());
249  if( nNegative == 0 )
250  return;
251 
252  //- make sure that the points at procesor boundaries are selected
253  //- at all processors
254  if( Pstream::parRun() )
255  unifyNegativePoints(negativeNode);
256 
257  //- smooth the mesh
258  List<LongList<labelledPoint> > newPositions;
259  # ifdef USE_OMP
260  # pragma omp parallel if( smoothVertex.size() > 100 )
261  # endif
262  {
263  # ifdef USE_OMP
264  # pragma omp master
265  {
266  newPositions.setSize(omp_get_num_threads());
267  }
268 
269  # pragma omp barrier
270 
271  LongList<labelledPoint>& np = newPositions[omp_get_thread_num()];
272  # else
273  newPositions.setSize(1);
274  LongList<labelledPoint>& np = newPositions[0];
275  # endif
276 
277  # ifdef USE_OMP
278  # pragma omp for schedule(dynamic, 10)
279  # endif
280  forAll(smoothVertex, nodeI)
281  {
282  if( !negativeNode[nodeI] )
283  continue;
284 
285  if( smoothVertex[nodeI] & partTetMesh::LOCKED )
286  continue;
287 
288  if( smoothVertex[nodeI] & partTetMesh::SMOOTH )
289  {
290  partTetMeshSimplex simplex(tetMesh_, nodeI);
292  np.append(labelledPoint(nodeI, simplex.centrePoint()));
293  }
294  }
295  }
296 
297  //- update mesh vertices
298  tetMesh_.updateVerticesSMP(newPositions);
299  newPositions.clear();
300 
301  if( Pstream::parRun() )
302  {
304  unifyCoordinatesParallel(&negativeNode);
305  }
306 
307  //- check which tets have been repaired
308  boolList helper(invertedTets.size());
309  nNegativeBefore = nNegative;
310  nNegative = 0;
311  # ifdef USE_OMP
312  # pragma omp parallel for if( tets.size() > 100 ) \
313  schedule(dynamic, 10) reduction(+ : nNegative)
314  # endif
315  forAll(tets, tetI)
316  {
317  helper[tetI] = false;
318 
319  if( invertedTets[tetI] && (tets[tetI].mag(points) < VSMALL) )
320  {
321  ++nNegative;
322  const partTet& tet = tets[tetI];
323 
324  for(label i=0;i<4;++i)
325  negativeNode[tet[i]] = true;
326  }
327  }
328 
329  reduce(nNegative, sumOp<label>());
330  if( nNegative == 0 )
331  return;
332  invertedTets.transfer(helper);
333 
334  } while( (nNegative < nNegativeBefore) || (++nIter < nIterations) );
335 }
336 
338 {
339  const LongList<direction>& smoothVertex = tetMesh_.smoothVertex();
340 
341  //- use mesh optimizer to improve the result
342  for(label i=0;i<nIterations;++i)
343  {
344  List<LongList<labelledPoint> > newPositions;
345 
346  # ifdef USE_OMP
347  # pragma omp parallel if( smoothVertex.size() > 100 )
348  # endif
349  {
350  # ifdef USE_OMP
351  # pragma omp master
352  {
353  newPositions.setSize(omp_get_num_threads());
354  }
355 
356  # pragma omp barrier
357 
358  LongList<labelledPoint>& np = newPositions[omp_get_thread_num()];
359  # else
360  newPositions.setSize(1);
361  LongList<labelledPoint>& np = newPositions[0];
362  # endif
363 
364  # ifdef USE_OMP
365  # pragma omp for schedule(dynamic, 10)
366  # endif
367  forAll(smoothVertex, nodeI)
368  {
369  if( smoothVertex[nodeI] & partTetMesh::LOCKED )
370  continue;
371 
372  if( smoothVertex[nodeI] & partTetMesh::SMOOTH )
373  {
374  partTetMeshSimplex simplex(tetMesh_, nodeI);
375 
376  volumeOptimizer vOpt(simplex);
377  vOpt.optimizeNodePosition(1e-5);
378 
379  np.append(labelledPoint(nodeI, simplex.centrePoint()));
380  }
381  }
382  }
383 
384  //- update mesh vertices
385  tetMesh_.updateVerticesSMP(newPositions);
386  newPositions.clear();
387 
388  if( Pstream::parRun() )
389  {
392  }
393  }
394 }
395 
397 (
398  const label nIterations,
399  const bool nonShrinking
400 )
401 {
402  const LongList<point>& points = tetMesh_.points();
403  const LongList<direction>& smoothVertex = tetMesh_.smoothVertex();
404 
405  # ifdef USE_OMP
406  label nThreads = omp_get_num_procs();
407  if( smoothVertex.size() < 100 )
408  nThreads = 1;
409  # else
410  const label nThreads(1);
411  # endif
412 
413  for(label i=0;i<nIterations;++i)
414  {
415  List<LongList<labelledPoint> > newPositions(nThreads);
416 
417  # ifdef USE_OMP
418  # pragma omp parallel num_threads(nThreads)
419  # endif
420  {
421  # ifdef USE_OMP
422  LongList<labelledPoint>& np = newPositions[omp_get_thread_num()];
423  # else
424  LongList<labelledPoint>& np = newPositions[0];
425  # endif
426 
427  # ifdef USE_OMP
428  # pragma omp for schedule(dynamic, 5)
429  # endif
430  forAll(smoothVertex, nodeI)
431  {
432  if( smoothVertex[nodeI] & partTetMesh::LOCKED )
433  continue;
434 
435  if( smoothVertex[nodeI] & partTetMesh::BOUNDARY )
436  {
437  partTetMeshSimplex simplex(tetMesh_, nodeI);
438 
439  volumeOptimizer vOpt(simplex);
440  vOpt.optimizeNodePosition(1e-5);
441 
442  if( nonShrinking )
443  {
444  //- find boundary faces of the simplex
445  const DynList<point, 128>& pts = simplex.pts();
446  const DynList<partTet, 128>& tets = simplex.tets();
447  DynList<edge, 64> bEdges;
448  DynList<label, 64> numAppearances;
449 
450  forAll(tets, tetI)
451  {
452  const partTet& tet = tets[tetI];
453  for(label i=0;i<3;++i)
454  {
455  edge e(tet[i], tet[(i+1)%3]);
456 
457  const label pos = bEdges.containsAtPosition(e);
458  if( pos < 0 )
459  {
460  bEdges.append(e);
461  numAppearances.append(1);
462  }
463  else
464  {
465  ++numAppearances(pos);
466  }
467  }
468  }
469 
470  //- create normal tensor of the simplex
472  forAll(bEdges, beI)
473  {
474  if( numAppearances[beI] != 1 )
475  continue;
476 
478  (
479  pts[bEdges[beI].start()],
480  pts[bEdges[beI].end()],
481  points[nodeI]
482  );
483 
484  vector n = tri.normal();
485  n /= (mag(n) + VSMALL);
486 
487  nt += symm(n * n);
488  }
489 
490  const vector ev = eigenValues(nt);
491 
492  //- make sure the point stays on the surface
493  vector disp = simplex.centrePoint() - points[nodeI];
494 
495  if( mag(ev[2]) > (mag(ev[1]) + mag(ev[0])) )
496  {
497  //- ordinary surface vertex
498  vector normal = eigenVector(nt, ev[2]);
499  normal /= (mag(normal)+VSMALL);
500  disp -= (disp & normal) * normal;
501  }
502  else if( mag(ev[1]) > 0.5 * (mag(ev[2]) + mag(ev[0])) )
503  {
504  //- this vertex is on an edge
505  vector normal1 = eigenVector(nt, ev[1]);
506  normal1 /= (mag(normal1)+VSMALL);
507  vector normal2 = eigenVector(nt, ev[2]);
508  normal2 /= (mag(normal2)+VSMALL);
509 
510  vector eVec = normal1 ^ normal2;
511  eVec /= (mag(eVec) + VSMALL);
512 
513  disp = (disp & eVec) * eVec;
514  }
515  else
516  {
517  //- this vertex is a corner. do not move it
518  continue;
519  }
520 
521  const point newP = points[nodeI] + disp;
522  np.append(labelledPoint(nodeI, newP));
523  }
524  else
525  {
526  //- move the vertex without constraining it
527  np.append(labelledPoint(nodeI, simplex.centrePoint()));
528  }
529  }
530  }
531  }
532 
533  //- update tetMesh
534  tetMesh_.updateVerticesSMP(newPositions);
535  newPositions.clear();
536 
537  if( Pstream::parRun() )
538  {
539  updateBufferLayerPoints();
540  unifyCoordinatesParallel();
541  }
542  }
543 }
544 
546 (
547  const label nIterations
548 )
549 {
550  const LongList<direction>& smoothVertex = tetMesh_.smoothVertex();
551 
552  # ifdef USE_OMP
553  label nThreads = omp_get_num_procs();
554  if( smoothVertex.size() < 1000 )
555  nThreads = 1;
556  # else
557  const label nThreads(1);
558  # endif
559 
560  for(label i=0;i<nIterations;++i)
561  {
562  List<LongList<labelledPoint> > newPositions(nThreads);
563 
564  # ifdef USE_OMP
565  # pragma omp parallel num_threads(nThreads)
566  # endif
567  {
568  # ifdef USE_OMP
570  newPositions[omp_get_thread_num()];
571  # else
572  LongList<labelledPoint>& np = newPositions[0];
573  # endif
574 
575  # ifdef USE_OMP
576  # pragma omp for schedule(dynamic, 5)
577  # endif
578  forAll(smoothVertex, nodeI)
579  {
580  if( smoothVertex[nodeI] & partTetMesh::LOCKED )
581  continue;
582 
583  if( smoothVertex[nodeI] & partTetMesh::BOUNDARY )
584  {
585  partTetMeshSimplex simplex(tetMesh_, nodeI);
586 
587  //- find boundary faces of the simplex
588  const DynList<point, 128>& pts = simplex.pts();
589  const DynList<partTet, 128>& tets = simplex.tets();
590  DynList<edge, 64> bndEdges;
591  DynList<label, 64> numAppearances;
592 
593  //- find boundary edges of the simplex
594  forAll(tets, tetI)
595  {
596  const partTet& tet = tets[tetI];
597  for(label i=0;i<3;++i)
598  {
599  const edge e(tet[i], tet[(i+1)%3]);
600  const label pos = bndEdges.containsAtPosition(e);
601 
602  if( pos < 0 )
603  {
604  bndEdges.append(e);
605  numAppearances.append(1);
606  }
607  else
608  {
609  ++numAppearances(pos);
610  }
611  }
612  }
613 
614  point newP(vector::zero);
615  label counter(0);
616  forAll(bndEdges, beI)
617  {
618  if( numAppearances[beI] != 1 )
619  continue;
620 
622  (
623  pts[bndEdges[beI].start()],
624  pts[bndEdges[beI].end()],
625  simplex.centrePoint()
626  );
627 
628  newP += tri.centre();
629  ++counter;
630  }
631 
632  if( counter != 0 )
633  {
634  newP /= counter;
635  np.append(labelledPoint(nodeI, newP));
636  }
637  }
638  }
639  }
640 
641  //- update tetMesh with new vertex positions
642  tetMesh_.updateVerticesSMP(newPositions);
643  newPositions.clear();
644 
645  if( Pstream::parRun() )
646  {
647  updateBufferLayerPoints();
648  unifyCoordinatesParallel();
649  }
650  }
651 }
652 
653 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
654 
655 } // End namespace Foam
656 
657 // ************************************************************************* //
Foam::tetMeshOptimisation::optimiseUsingKnuppMetric
void optimiseUsingKnuppMetric(const label nInterations=5)
untangle mesh by using Patrik Knupp's simple metric
Definition: tetMeshOptimisation.C:67
Foam::symm
dimensionedSymmTensor symm(const dimensionedSymmTensor &dt)
Definition: dimensionedSymmTensor.C:82
Foam::SymmTensor< scalar >
Foam::LongList::append
void append(const T &e)
Append an element at the end of the list.
Definition: LongListI.H:265
Foam::Vector< scalar >::zero
static const Vector zero
Definition: Vector.H:80
Foam::partTetMeshSimplex
Definition: partTetMeshSimplex.H:52
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::tetMeshOptimisation::optimiseBoundaryVolumeOptimizer
void optimiseBoundaryVolumeOptimizer(const label nIterations=3, const bool nonShrinking=false)
smooth boundary using the volume optimizer
Definition: tetMeshOptimisation.C:397
demandDrivenData.H
Template functions to aid in the implementation of demand driven data.
tetMeshOptimisation.H
Foam::UPstream::parRun
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:377
Foam::edge
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
Foam::partTet
Definition: partTet.H:53
Foam::List::transfer
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Foam::tetMeshOptimisation::~tetMeshOptimisation
~tetMeshOptimisation()
Definition: tetMeshOptimisation.C:62
Foam::meshUntangler::optimizeNodePosition
void optimizeNodePosition(const scalar tol=0.001)
Definition: meshUntangler.C:60
Foam::LongList::size
label size() const
Size of the active part of the list.
Definition: LongListI.H:203
Foam::tetMeshOptimisation::optimiseUsingMeshUntangler
void optimiseUsingMeshUntangler(const label nIerations=5)
smooth using mesh untangler
Definition: tetMeshOptimisation.C:204
Foam::mag
dimensioned< scalar > mag(const dimensioned< Type > &)
Foam::knuppMetric
class for mesh untangler
Definition: knuppMetric.H:53
Foam::tetMeshOptimisation::tetMeshOptimisation
tetMeshOptimisation(partTetMesh &mesh)
Construct from tet mesh.
Definition: tetMeshOptimisation.C:55
Foam::partTetMeshSimplex::tets
const DynList< partTet, 128 > & tets() const
return tets
Definition: partTetMeshSimplex.H:100
Foam::triangle::centre
Point centre() const
Return centre (centroid)
Definition: triangleI.H:102
Foam::LongList
Definition: LongList.H:55
Foam::tetMeshOptimisation::tetMesh_
partTetMesh & tetMesh_
reference to the tet mesh
Definition: tetMeshOptimisation.H:62
Foam::triangle
A triangle primitive used to calculate face normals and swept volumes.
Definition: triangle.H:59
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:43
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::triangle::normal
vector normal() const
Return vector normal.
Definition: triangleI.H:116
Foam::eigenVector
vector eigenVector(const tensor &, const scalar lambda)
Definition: tensor.C:207
Foam::eigenValues
dimensionedVector eigenValues(const dimensionedTensor &dt)
Definition: dimensionedTensor.C:146
partTetMeshSimplex.H
volumeOptimizer.H
Foam::meshUntangler
Definition: meshUntangler.H:54
Foam::tetMeshOptimisation::optimiseBoundarySurfaceLaplace
void optimiseBoundarySurfaceLaplace(const label nIterations=3)
smooth boundary using shrinking surface laplace
Definition: tetMeshOptimisation.C:546
Foam::partTetMesh::tets
const LongList< partTet > & tets() const
Definition: partTetMesh.H:179
partTetMesh.H
Foam::volumeOptimizer
class for volume optimizer
Definition: volumeOptimizer.H:53
Foam::partTetMeshSimplex::centrePoint
const point & centrePoint() const
return centre point coordinates
Definition: partTetMeshSimplex.H:106
Foam::volumeOptimizer::optimizeNodePosition
void optimizeNodePosition(const scalar tol=0.001)
find the best position for the node
Definition: volumeOptimizer.C:67
Foam::partTetMesh::SMOOTH
@ SMOOTH
Definition: partTetMesh.H:161
meshUntangler.H
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
Foam::SymmTensor< scalar >::zero
static const SymmTensor zero
Definition: SymmTensor.H:77
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
meshSurfaceEngine.H
Foam::e
const double e
Elementary charge.
Definition: doubleFloat.H:94
Foam::DynList
Definition: DynList.H:53
Foam::partTetMesh
Definition: partTetMesh.H:59
Foam::knuppMetric::optimizeNodePosition
void optimizeNodePosition(const scalar tol=0.001)
Definition: knuppMetric.C:124
Foam::partTetMesh::BOUNDARY
@ BOUNDARY
Definition: partTetMesh.H:165
Foam::List::setSize
void setSize(const label)
Reset size of List.
Foam::tetMeshOptimisation::updateBufferLayerPoints
void updateBufferLayerPoints()
update buffer layer points
Definition: tetMeshOptimisationParallel.C:209
Foam::DynList::containsAtPosition
label containsAtPosition(const T &e) const
Definition: DynListI.H:356
Foam::sumOp
Definition: ops.H:162
Foam::labelledPoint
Definition: labelledPoint.H:50
Foam::Vector< scalar >
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::List::clear
void clear()
Clear the list, i.e. set size to zero.
Definition: List.C:379
meshSurfaceEngineModifier.H
Foam::tetMeshOptimisation::optimiseUsingVolumeOptimizer
void optimiseUsingVolumeOptimizer(const label nIterations=10)
smooth using volume optimizer
Definition: tetMeshOptimisation.C:337
Foam::tetMeshOptimisation::unifyNegativePoints
void unifyNegativePoints(boolList &negativeNode) const
Definition: tetMeshOptimisationParallel.C:43
knuppMetric.H
Foam::partTetMesh::updateVerticesSMP
void updateVerticesSMP(const List< LongList< labelledPoint > > &)
Definition: partTetMesh.C:454
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::partTetMesh::points
const LongList< point > & points() const
access to points, tets and other data
Definition: partTetMesh.H:174
Foam::partTetMesh::LOCKED
@ LOCKED
Definition: partTetMesh.H:166
Foam::partTetMesh::smoothVertex
const LongList< direction > & smoothVertex() const
Definition: partTetMesh.H:189
Foam::partTetMeshSimplex::pts
DynList< point, 128 > & pts()
return points
Definition: partTetMeshSimplex.H:88
Foam::tetMeshOptimisation::unifyCoordinatesParallel
void unifyCoordinatesParallel(const boolList *negativeNodePtr=NULL)
Definition: tetMeshOptimisationParallel.C:261
normal
A normal distribution model.
Foam::DynList::append
void append(const T &e)
Append an element at the end of the list.
Definition: DynListI.H:304
Foam::pos
dimensionedScalar pos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:190