Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/meshing/meshclass.hpp
3206 views
1
#ifndef MESHCLASS
2
#define MESHCLASS
3
4
/**************************************************************************/
5
/* File: meshclass.hpp */
6
/* Author: Joachim Schoeberl */
7
/* Date: 20. Nov. 99 */
8
/**************************************************************************/
9
10
/*
11
The mesh class
12
*/
13
14
15
16
enum resthtype { RESTRICTH_FACE, RESTRICTH_EDGE,
17
RESTRICTH_SURFACEELEMENT, RESTRICTH_POINT, RESTRICTH_SEGMENT };
18
19
class HPRefElement;
20
21
22
/// 2d/3d mesh
23
class Mesh
24
{
25
public:
26
typedef MoveableArray<MeshPoint,PointIndex::BASE> T_POINTS;
27
typedef MoveableArray<Element> T_VOLELEMENTS;
28
typedef MoveableArray<Element2d> T_SURFELEMENTS;
29
30
// typedef ARRAY<MeshPoint,PointIndex::BASE> T_POINTS;
31
// typedef ARRAY<Element> T_VOLELEMENTS;
32
// typedef ARRAY<Element2d> T_SURFELEMENTS;
33
34
35
private:
36
/// point coordinates
37
T_POINTS points;
38
39
/// type of element, set in calcsurfacesofnode
40
// ARRAY<ELEMENTTYPE> eltyps;
41
42
/// line-segments at edges
43
ARRAY<Segment> segments;
44
/// surface elements, 2d-inner elements
45
T_SURFELEMENTS surfelements;
46
/// volume elements
47
T_VOLELEMENTS volelements;
48
/// points will be fixed forever
49
ARRAY<PointIndex> lockedpoints;
50
51
52
/// surface indices at boundary nodes
53
TABLE<int,PointIndex::BASE> surfacesonnode;
54
/// boundary edges (1..normal bedge, 2..segment)
55
INDEX_2_CLOSED_HASHTABLE<int> * boundaryedges;
56
///
57
INDEX_2_CLOSED_HASHTABLE<int> * segmentht;
58
///
59
INDEX_3_CLOSED_HASHTABLE<int> * surfelementht;
60
61
/// faces of rest-solid
62
ARRAY<Element2d> openelements;
63
/// open segmenets for surface meshing
64
ARRAY<Segment> opensegments;
65
66
67
68
/**
69
Representation of local mesh-size h
70
*/
71
LocalH * lochfunc;
72
///
73
double hglob;
74
///
75
double hmin;
76
///
77
ARRAY<double> maxhdomain;
78
79
/**
80
the face-index of the surface element maps into
81
this table.
82
*/
83
ARRAY<FaceDescriptor> facedecoding;
84
85
/// sub-domain materials
86
ARRAY<char*> materials;
87
88
ARRAY<string*, 0> bcnames;
89
90
/// Periodic surface, close surface, etc. identifications
91
Identifications * ident;
92
93
94
/// number of vertices (if < 0, use np)
95
int numvertices;
96
97
/// geometric search tree for interval intersection search
98
Box3dTree * elementsearchtree;
99
/// time stamp for tree
100
int elementsearchtreets;
101
102
/// element -> face, element -> edge etc ...
103
class MeshTopology * topology;
104
/// methods for high order elements
105
class CurvedElements * curvedelems;
106
107
/// nodes identified by close points
108
class AnisotropicClusters * clusters;
109
110
/// space dimension (2 or 3)
111
int dimension;
112
113
/// changed by every minor modification (addpoint, ...)
114
int timestamp;
115
/// changed after finishing global algorithm (improve, ...)
116
int majortimestamp;
117
118
/// mesh access semaphors.
119
NgMutex mutex;
120
/// mesh access semaphors.
121
NgMutex majormutex;
122
123
SYMBOLTABLE< ARRAY<int>* > userdata_int;
124
SYMBOLTABLE< ARRAY<double>* > userdata_double;
125
126
127
mutable ARRAY< Point3d > pointcurves;
128
mutable ARRAY<int> pointcurves_startpoint;
129
mutable ARRAY<double> pointcurves_red,pointcurves_green,pointcurves_blue;
130
131
132
/// start element for point search (GetElementOfPoint)
133
mutable int ps_startelement;
134
135
136
#ifdef PARALLEL
137
/// connection to parallel meshes
138
class ParallelMeshTopology * paralleltop;
139
140
#endif
141
142
143
private:
144
void BuildBoundaryEdges(void);
145
146
public:
147
bool PointContainedIn2DElement(const Point3d & p,
148
double lami[3],
149
const int element,
150
bool consider3D = false) const;
151
bool PointContainedIn3DElement(const Point3d & p,
152
double lami[3],
153
const int element) const;
154
bool PointContainedIn3DElementOld(const Point3d & p,
155
double lami[3],
156
const int element) const;
157
158
public:
159
160
// store coarse mesh before hp-refinement
161
ARRAY<HPRefElement> * hpelements;
162
Mesh * coarsemesh;
163
164
165
/// number of refinement levels
166
int mglevels;
167
/// refinement hierarchy
168
ARRAY<INDEX_2,PointIndex::BASE> mlbetweennodes;
169
/// parent element of volume element
170
ARRAY<int> mlparentelement;
171
/// parent element of surface element
172
ARRAY<int> mlparentsurfaceelement;
173
174
175
176
///
177
Mesh();
178
///
179
~Mesh();
180
181
Mesh & operator= (const Mesh & mesh2);
182
183
///
184
void DeleteMesh();
185
186
///
187
void ClearSurfaceElements()
188
{
189
surfelements.SetSize(0);
190
timestamp = NextTimeStamp();
191
}
192
193
///
194
void ClearVolumeElements()
195
{
196
volelements.SetSize(0);
197
// eltyps.SetSize(0);
198
timestamp = NextTimeStamp();
199
}
200
201
///
202
void ClearSegments()
203
{
204
segments.SetSize(0);
205
timestamp = NextTimeStamp();
206
}
207
208
///
209
bool TestOk () const;
210
211
void SetAllocSize(int nnodes, int nsegs, int nsel, int nel);
212
213
214
PointIndex AddPoint (const Point3d & p, int layer = 1);
215
PointIndex AddPoint (const Point3d & p, int layer, POINTTYPE type);
216
#ifdef PARALLEL
217
PointIndex AddPoint (const Point3d & p, bool aisghost, int layer = 1);
218
PointIndex AddPoint (const Point3d & p, bool aisghost, int layer, POINTTYPE type);
219
#endif
220
int GetNP () const { return points.Size(); }
221
222
MeshPoint & Point(int i) { return points.Elem(i); }
223
MeshPoint & Point(PointIndex pi) { return points[pi]; }
224
const MeshPoint & Point(int i) const { return points.Get(i); }
225
const MeshPoint & Point(PointIndex pi) const { return points[pi]; }
226
227
const MeshPoint & operator[] (PointIndex pi) const { return points[pi]; }
228
MeshPoint & operator[] (PointIndex pi) { return points[pi]; }
229
230
const T_POINTS & Points() const { return points; }
231
T_POINTS & Points() { return points; }
232
233
234
SegmentIndex AddSegment (const Segment & s);
235
void DeleteSegment (int segnr)
236
{
237
segments.Elem(segnr).p1 = PointIndex::BASE-1;
238
segments.Elem(segnr).p2 = PointIndex::BASE-1;
239
}
240
void FullDeleteSegment (int segnr)
241
{
242
segments.Delete(segnr-PointIndex::BASE);
243
}
244
245
int GetNSeg () const { return segments.Size(); }
246
Segment & LineSegment(int i) { return segments.Elem(i); }
247
const Segment & LineSegment(int i) const { return segments.Get(i); }
248
249
Segment & LineSegment(SegmentIndex si) { return segments[si]; }
250
const Segment & LineSegment(SegmentIndex si) const { return segments[si]; }
251
const Segment & operator[] (SegmentIndex si) const { return segments[si]; }
252
Segment & operator[] (SegmentIndex si) { return segments[si]; }
253
254
255
256
257
SurfaceElementIndex AddSurfaceElement (const Element2d & el);
258
void DeleteSurfaceElement (int eli)
259
{
260
surfelements.Elem(eli).Delete();
261
surfelements.Elem(eli).PNum(1) = -1;
262
surfelements.Elem(eli).PNum(2) = -1;
263
surfelements.Elem(eli).PNum(3) = -1;
264
timestamp = NextTimeStamp();
265
}
266
267
void DeleteSurfaceElement (SurfaceElementIndex eli)
268
{
269
DeleteSurfaceElement (int(eli)+1);
270
}
271
272
int GetNSE () const { return surfelements.Size(); }
273
Element2d & SurfaceElement(int i) { return surfelements.Elem(i); }
274
const Element2d & SurfaceElement(int i) const { return surfelements.Get(i); }
275
276
Element2d & SurfaceElement(SurfaceElementIndex i)
277
{ return surfelements[i]; }
278
const Element2d & SurfaceElement(SurfaceElementIndex i) const
279
{ return surfelements[i]; }
280
281
const Element2d & operator[] (SurfaceElementIndex ei) const
282
{ return surfelements[ei]; }
283
Element2d & operator[] (SurfaceElementIndex ei)
284
{ return surfelements[ei]; }
285
286
287
void GetSurfaceElementsOfFace (int facenr, ARRAY<SurfaceElementIndex> & sei) const;
288
289
ElementIndex AddVolumeElement (const Element & el);
290
291
int GetNE () const { return volelements.Size(); }
292
293
Element & VolumeElement(int i) { return volelements.Elem(i); }
294
const Element & VolumeElement(int i) const { return volelements.Get(i); }
295
Element & VolumeElement(ElementIndex i) { return volelements[i]; }
296
const Element & VolumeElement(ElementIndex i) const { return volelements[i]; }
297
298
const Element & operator[] (ElementIndex ei) const
299
{ return volelements[ei]; }
300
Element & operator[] (ElementIndex ei)
301
{ return volelements[ei]; }
302
303
304
305
306
// ELEMENTTYPE ElementType (int i) const { return eltyps.Get(i); }
307
308
309
// ELEMENTTYPE ElementType (int i) const
310
// { return (volelements.Get(i).fixed) ? FIXEDELEMENT : FREEELEMENT; }
311
312
ELEMENTTYPE ElementType (ElementIndex i) const
313
{ return (volelements[i].flags.fixed) ? FIXEDELEMENT : FREEELEMENT; }
314
315
/*
316
ELEMENTTYPE ElementType (int i) const { return eltyps.Get(i); }
317
ELEMENTTYPE ElementType (ElementIndex i) const { return eltyps[i]; }
318
*/
319
320
const T_VOLELEMENTS & VolumeElements() const { return volelements; }
321
T_VOLELEMENTS & VolumeElements() { return volelements; }
322
323
324
///
325
double ElementError (int eli) const;
326
327
///
328
void AddLockedPoint (PointIndex pi);
329
///
330
void ClearLockedPoints ();
331
332
const ARRAY<PointIndex> & LockedPoints() const
333
{ return lockedpoints; }
334
335
/// Returns number of domains
336
int GetNDomains() const;
337
338
339
///
340
int GetDimension() const
341
{ return dimension; }
342
void SetDimension(int dim)
343
{ dimension = dim; }
344
345
/// sets internal tables
346
void CalcSurfacesOfNode ();
347
348
/// additional (temporarily) fix points
349
void FixPoints (const BitArray & fixpoints);
350
351
/**
352
finds elements without neighbour and
353
boundary elements without inner element.
354
Results are stored in openelements.
355
if dom == 0, all sub-domains, else subdomain dom */
356
void FindOpenElements (int dom = 0);
357
358
359
/**
360
finds segments without surface element,
361
and surface elements without neighbours.
362
store in opensegmentsy
363
*/
364
void FindOpenSegments (int surfnr = 0);
365
/**
366
remove one layer of surface elements
367
*/
368
void RemoveOneLayerSurfaceElements ();
369
370
371
int GetNOpenSegments () { return opensegments.Size(); }
372
const Segment & GetOpenSegment (int nr) { return opensegments.Get(nr); }
373
374
/**
375
Checks overlap of boundary
376
return == 1, iff overlap
377
*/
378
int CheckOverlappingBoundary ();
379
/**
380
Checks consistent boundary
381
return == 0, everything ok
382
*/
383
int CheckConsistentBoundary () const;
384
385
/*
386
checks element orientation
387
*/
388
int CheckVolumeMesh () const;
389
390
391
/**
392
finds average h of surface surfnr if surfnr > 0,
393
else of all surfaces.
394
*/
395
double AverageH (int surfnr = 0) const;
396
/// Calculates localh
397
void CalcLocalH ();
398
///
399
void SetLocalH (const Point3d & pmin, const Point3d & pmax, double grading);
400
///
401
void RestrictLocalH (const Point3d & p, double hloc);
402
///
403
void RestrictLocalHLine (const Point3d & p1, const Point3d & p2,
404
double hloc);
405
/// number of elements per radius
406
void CalcLocalHFromSurfaceCurvature(double elperr);
407
///
408
void CalcLocalHFromPointDistances(void);
409
///
410
void RestrictLocalH (resthtype rht, int nr, double loch);
411
///
412
void LoadLocalMeshSize (const char * meshsizefilename);
413
///
414
void SetGlobalH (double h);
415
///
416
void SetMinimalH (double h);
417
///
418
double MaxHDomain (int dom) const;
419
///
420
void SetMaxHDomain (const ARRAY<double> & mhd);
421
///
422
double GetH (const Point3d & p) const;
423
///
424
double GetMinH (const Point3d & pmin, const Point3d & pmax);
425
///
426
LocalH & LocalHFunction () { return * lochfunc; }
427
///
428
bool LocalHFunctionGenerated(void) const { return (lochfunc != NULL); }
429
430
/// Find bounding box
431
void GetBox (Point3d & pmin, Point3d & pmax, int dom = -1) const;
432
433
/// Find bounding box of points of typ ptyp or less
434
void GetBox (Point3d & pmin, Point3d & pmax, POINTTYPE ptyp ) const;
435
436
///
437
int GetNOpenElements() const
438
{ return openelements.Size(); }
439
///
440
const Element2d & OpenElement(int i) const
441
{ return openelements.Get(i); }
442
443
444
/// are also quads open elements
445
bool HasOpenQuads () const;
446
447
/// split into connected pieces
448
void SplitIntoParts ();
449
450
///
451
void SplitSeparatedFaces ();
452
453
/// Refines mesh and projects points to true surface
454
// void Refine (int levels, const CSGeometry * geom);
455
456
457
bool BoundaryEdge (PointIndex pi1, PointIndex pi2) const
458
{
459
if(!boundaryedges)
460
const_cast<Mesh *>(this)->BuildBoundaryEdges();
461
462
INDEX_2 i2 (pi1, pi2);
463
i2.Sort();
464
return boundaryedges->Used (i2);
465
}
466
467
bool IsSegment (PointIndex pi1, PointIndex pi2) const
468
{
469
INDEX_2 i2 (pi1, pi2);
470
i2.Sort();
471
return segmentht->Used (i2);
472
}
473
474
SegmentIndex SegmentNr (PointIndex pi1, PointIndex pi2) const
475
{
476
INDEX_2 i2 (pi1, pi2);
477
i2.Sort();
478
return segmentht->Get (i2);
479
}
480
481
482
/**
483
Remove unused points. etc.
484
*/
485
void Compress ();
486
487
///
488
void Save (ostream & outfile) const;
489
///
490
void Load (istream & infile);
491
///
492
void Merge (istream & infile, const int surfindex_offset = 0);
493
///
494
void Save (const string & filename) const;
495
///
496
void Load (const string & filename);
497
///
498
void Merge (const string & filename, const int surfindex_offset = 0);
499
500
501
///
502
void ImproveMesh (OPTIMIZEGOAL goal = OPT_QUALITY);
503
504
///
505
void ImproveMeshJacobian (OPTIMIZEGOAL goal = OPT_QUALITY, const BitArray * usepoint = NULL);
506
///
507
void ImproveMeshJacobianOnSurface (const BitArray & usepoint,
508
const ARRAY< Vec<3>* > & nv,
509
OPTIMIZEGOAL goal = OPT_QUALITY,
510
const ARRAY< ARRAY<int,PointIndex::BASE>* > * idmaps = NULL);
511
/*
512
#ifdef SOLIDGEOM
513
/// old
514
void ImproveMesh (const CSGeometry & surfaces,
515
OPTIMIZEGOAL goal = OPT_QUALITY);
516
#endif
517
*/
518
519
/**
520
free nodes in environment of openelements
521
for optimiztion
522
*/
523
void FreeOpenElementsEnvironment (int layers);
524
525
///
526
bool LegalTet (Element & el) const
527
{
528
if (el.IllegalValid())
529
return !el.Illegal();
530
return LegalTet2 (el);
531
}
532
///
533
bool LegalTet2 (Element & el) const;
534
535
536
///
537
bool LegalTrig (const Element2d & el) const;
538
/**
539
if values non-null, return values in 4-double array:
540
triangle angles min/max, tetangles min/max
541
if null, output results on cout
542
*/
543
void CalcMinMaxAngle (double badellimit, double * retvalues = NULL);
544
545
/*
546
Marks elements which are dangerous to refine
547
return: number of illegal elements
548
*/
549
int MarkIllegalElements ();
550
551
/// orient surface mesh, for one sub-domain only
552
void SurfaceMeshOrientation ();
553
554
/// convert mixed element mesh to tet-mesh
555
void Split2Tets();
556
557
558
/// build box-search tree
559
void BuildElementSearchTree ();
560
561
void SetPointSearchStartElement(const int el) const {ps_startelement = el;}
562
563
/// gives element of point, barycentric coordinates
564
int GetElementOfPoint (const Point3d & p,
565
double * lami,
566
bool build_searchtree = 0,
567
const int index = -1,
568
const bool allowindex = true) const;
569
int GetElementOfPoint (const Point3d & p,
570
double * lami,
571
const ARRAY<int> * const indices,
572
bool build_searchtree = 0,
573
const bool allowindex = true) const;
574
int GetSurfaceElementOfPoint (const Point3d & p,
575
double * lami,
576
bool build_searchtree = 0,
577
const int index = -1,
578
const bool allowindex = true) const;
579
int GetSurfaceElementOfPoint (const Point3d & p,
580
double * lami,
581
const ARRAY<int> * const indices,
582
bool build_searchtree = 0,
583
const bool allowindex = true) const;
584
585
/// give list of vol elements which are int the box(p1,p2)
586
void GetIntersectingVolEls(const Point3d& p1, const Point3d& p2,
587
ARRAY<int> & locels) const;
588
589
///
590
int AddFaceDescriptor(const FaceDescriptor& fd)
591
{ return facedecoding.Append(fd); }
592
593
594
///
595
void SetMaterial (int domnr, const char * mat);
596
///
597
const char * GetMaterial (int domnr) const;
598
599
void SetNBCNames ( int nbcn );
600
601
void SetBCName ( int bcnr, const string & abcname );
602
603
string GetBCName ( int bcnr ) const;
604
605
string * GetBCNamePtr ( int bcnr )
606
{ return bcnames[bcnr]; }
607
608
///
609
void ClearFaceDescriptors()
610
{ facedecoding.SetSize(0); }
611
612
///
613
int GetNFD () const
614
{ return facedecoding.Size(); }
615
616
const FaceDescriptor & GetFaceDescriptor (int i) const
617
{ return facedecoding.Get(i); }
618
619
///
620
FaceDescriptor & GetFaceDescriptor (int i)
621
{ return facedecoding.Elem(i); }
622
623
// #ifdef NONE
624
// /*
625
// Identify points pi1 and pi2, due to
626
// identification nr identnr
627
// */
628
// void AddIdentification (int pi1, int pi2, int identnr);
629
630
// int GetIdentification (int pi1, int pi2) const;
631
// int GetIdentificationSym (int pi1, int pi2) const;
632
// ///
633
// INDEX_2_HASHTABLE<int> & GetIdentifiedPoints ()
634
// {
635
// return *identifiedpoints;
636
// }
637
638
// ///
639
// void GetIdentificationMap (int identnr, ARRAY<int> & identmap) const;
640
// ///
641
// void GetIdentificationPairs (int identnr, ARRAY<INDEX_2> & identpairs) const;
642
// ///
643
// int GetMaxIdentificationNr () const
644
// {
645
// return maxidentnr;
646
// }
647
// #endif
648
649
/// return periodic, close surface etc. identifications
650
Identifications & GetIdentifications () { return *ident; }
651
/// return periodic, close surface etc. identifications
652
const Identifications & GetIdentifications () const { return *ident; }
653
654
655
void InitPointCurve(double red = 1, double green = 0, double blue = 0) const;
656
void AddPointCurvePoint(const Point3d & pt) const;
657
int GetNumPointCurves(void) const;
658
int GetNumPointsOfPointCurve(int curve) const;
659
Point3d & GetPointCurvePoint(int curve, int n) const;
660
void GetPointCurveColor(int curve, double & red, double & green, double & blue) const;
661
662
663
664
665
/// find number of vertices
666
void ComputeNVertices ();
667
/// number of vertices (no edge-midpoints)
668
int GetNV () const;
669
/// remove edge points
670
void SetNP (int np);
671
672
673
674
675
/*
676
/// build connected nodes along prism stack
677
void BuildConnectedNodes ();
678
void ConnectToNodeRec (int node, int tonode,
679
const TABLE<int> & conto);
680
*/
681
682
bool PureTrigMesh (int faceindex = 0) const;
683
bool PureTetMesh () const;
684
685
686
const class MeshTopology & GetTopology () const
687
{ return *topology; }
688
689
void UpdateTopology();
690
691
class CurvedElements & GetCurvedElements () const
692
{ return *curvedelems; }
693
694
const class AnisotropicClusters & GetClusters () const
695
{ return *clusters; }
696
697
int GetTimeStamp() const { return timestamp; }
698
void SetNextTimeStamp()
699
{ timestamp = NextTimeStamp(); }
700
701
int GetMajorTimeStamp() const { return majortimestamp; }
702
void SetNextMajorTimeStamp()
703
{ majortimestamp = timestamp = NextTimeStamp(); }
704
705
706
/// return mutex
707
NgMutex & Mutex () { return mutex; }
708
NgMutex & MajorMutex () { return majormutex; }
709
710
711
///
712
void SetUserData(const char * id, ARRAY<int> & data);
713
///
714
bool GetUserData(const char * id, ARRAY<int> & data, int shift = 0) const;
715
///
716
void SetUserData(const char * id, ARRAY<double> & data);
717
///
718
bool GetUserData(const char * id, ARRAY<double> & data, int shift = 0) const;
719
720
///
721
friend void OptimizeRestart (Mesh & mesh3d);
722
///
723
void PrintMemInfo (ostream & ost) const;
724
///
725
friend class Meshing3;
726
727
728
enum GEOM_TYPE { NO_GEOM = 0, GEOM_2D = 1, GEOM_CSG = 10, GEOM_STL = 11, GEOM_OCC = 12, GEOM_ACIS = 13 };
729
GEOM_TYPE geomtype;
730
731
732
733
#ifdef PARALLEL
734
/// returns parallel topology
735
class ParallelMeshTopology & GetParallelTopology () const
736
{ return *paralleltop; }
737
738
739
/// distributes the master-mesh to local meshes
740
void Distribute ();
741
742
/// loads a mesh sent from master processor
743
void ReceiveParallelMesh ();
744
745
/// find connection to parallel meshes
746
// void FindExchangePoints () ;
747
748
// void FindExchangeEdges ();
749
// void FindExchangeFaces ();
750
751
/// use metis to decompose master mesh
752
void ParallelMetis (); // ARRAY<int> & neloc );
753
void PartHybridMesh (); // ARRAY<int> & neloc );
754
void PartDualHybridMesh (); // ARRAY<int> & neloc );
755
void PartDualHybridMesh2D (); // ( ARRAY<int> & neloc );
756
757
/// send mesh to parallel machine, keep global mesh at master
758
void SendMesh ( ) const; // Mesh * mastermesh, ARRAY<int> & neloc) const;
759
760
void UpdateOverlap ();
761
762
#endif
763
764
765
};
766
767
inline ostream& operator<<(ostream& ost, const Mesh& mesh)
768
{
769
ost << "mesh: " << endl;
770
mesh.Save(ost);
771
return ost;
772
}
773
774
775
#endif
776
777
778
779