Geophysical Inversion and Modelling Library v1.5.4
Loading...
Searching...
No Matches
shape.h
1/******************************************************************************
2 * Copyright (C) 2006-2024 by the GIMLi development team *
3 * Carsten Rücker carsten@resistivity.net *
4 * *
5 * Licensed under the Apache License, Version 2.0 (the "License"); *
6 * you may not use this file except in compliance with the License. *
7 * You may obtain a copy of the License at *
8 * *
9 * http://www.apache.org/licenses/LICENSE-2.0 *
10 * *
11 * Unless required by applicable law or agreed to in writing, software *
12 * distributed under the License is distributed on an "AS IS" BASIS, *
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
14 * See the License for the specific language governing permissions and *
15 * limitations under the License. *
16 * *
17 ******************************************************************************/
18
19#ifndef _GIMLI_Shape__H
20#define _GIMLI_Shape__H
21
22#include "gimli.h"
23#include "polynomial.h"
24#include "curvefitting.h"
25
26#ifndef PYGIMLI_CAST // fails because of boost threads and clang problems
27 #if USE_BOOST_THREAD
28 #include <boost/thread.hpp>
29 extern boost::mutex ShapeFunctionWriteCacheMutex__;
30 //#error AVOID BOOST
31 #else
32 #include <mutex>
33 extern std::mutex ShapeFunctionWriteCacheMutex__;
34 #endif
35#endif
36
37namespace GIMLI{
38
40DLLEXPORT double tetVolume(const RVector3 & p0, const RVector3 & p1,
41 const RVector3 & p2, const RVector3 & p3);
42
44DLLEXPORT double triSize(const RVector3 & p0, const RVector3 & p1,
45 const RVector3 & p2);
46
47
48DLLEXPORT std::vector < PolynomialFunction < double > >
49createPolynomialShapeFunctions(const std::vector < RVector3 > & pnts,
50 uint dim, uint nCoeff,
51 bool pascale, bool serendipity,
52 const RVector & startVector);
53
54
55template < class Ent > std::vector < PolynomialFunction < double > >
56 createPolynomialShapeFunctions(const Ent & ent, uint nCoeff,
57 bool pascale, bool serendipity,
58 const RVector & startVector){
59// __MS(ent)
60 std::vector < RVector3 > pnts;
61 for (Index i = 0; i < ent.nodeCount(); i ++){
62 pnts.push_back(ent.rst(i));
63 }
64
65 return createPolynomialShapeFunctions(pnts, ent.dim(), nCoeff, pascale,
66 serendipity, startVector);
67}
68
69// no default arg here .. pygimli@win64 linker bug
70template < class Ent > std::vector < PolynomialFunction < double > >
71 createPolynomialShapeFunctions(const Ent & ent, uint nCoeff,
72 bool pascale, bool serendipity){
73 RVector start(0);
74 return createPolynomialShapeFunctions(ent, nCoeff, pascale, serendipity, start);
75}
76
77class DLLEXPORT ShapeFunctionCache : public Singleton< ShapeFunctionCache > {
78public:
79 friend class Singleton< ShapeFunctionCache >;
80
81 template < class Ent > const std::vector < PolynomialFunction < double > > &
82 shapeFunctions(const Ent & e) const {
83
84 std::map < uint8, std::vector < PolynomialFunction < double > > >::const_iterator it = shapeFunctions_.find(e.rtti());
85
86 if (it == shapeFunctions_.end()){
87 this->createShapeFunctions_(e);
88 it = shapeFunctions_.find(e.rtti());
89 }
90
91 return (*it).second;
92 }
93
94 template < class Ent > const std::vector < PolynomialFunction < double > > &
95 deriveShapeFunctions(const Ent & e , uint dim) const {
96 std::map < uint8, std::vector < std::vector < PolynomialFunction < double > > > >::const_iterator it = dShapeFunctions_.find(e.rtti());
97
98 if (it == dShapeFunctions_.end()) {
99 this->createShapeFunctions_(e);
100 it = dShapeFunctions_.find(e.rtti());
101 }
102 return (*it).second[dim];
103 }
104
106 void clear() {
107 shapeFunctions_.clear();
108 dShapeFunctions_.clear();
109 }
110
111 std::vector< RMatrix3 > & RMatrix3Cache();
112 std::vector< RMatrix > & RMatrixCache(uint rtti);
113
114 RMatrix3 & cachedRMatrix3(uint i);
115 RMatrix & cachedRMatrix(uint rtti, uint i);
116private:
117
119 template < class Ent > void createShapeFunctions_(const Ent & e) const {
120 std::vector < PolynomialFunction < double > > N = e.createShapeFunctions();
121
122 #if USE_BOOST_THREAD
123 //#ifdef WIN32_LEAN_AND_MEAN
124 // __MS("pls check missing mutex")
125 //boost::mutex::scoped_lock lock(ShapeFunctionWriteCacheMutex__);
126 //#else
127 #ifndef PYGIMLI_CAST // fails because of boost threads and clang problems
128 boost::mutex::scoped_lock lock(ShapeFunctionWriteCacheMutex__);
129 #endif
130 //#endif
131
132 #else
133 // __MS("lock deactiated " << ShapeFunctionWriteCacheMutex__)
134
135 std::unique_lock < std::mutex > lock(ShapeFunctionWriteCacheMutex__);
136 #endif
137
138
139 shapeFunctions_[e.rtti()] = N;
140 dShapeFunctions_[e.rtti()] = std::vector < std::vector < PolynomialFunction < double > > >();
141
142 dShapeFunctions_[e.rtti()].push_back(std::vector < PolynomialFunction < double > >());
143 dShapeFunctions_[e.rtti()].push_back(std::vector < PolynomialFunction < double > >());
144 dShapeFunctions_[e.rtti()].push_back(std::vector < PolynomialFunction < double > >());
145
146 for (uint i = 0; i < N.size(); i ++){
147 dShapeFunctions_[e.rtti()][0].push_back(N[i].derive(0));
148 dShapeFunctions_[e.rtti()][1].push_back(N[i].derive(1));
149 dShapeFunctions_[e.rtti()][2].push_back(N[i].derive(2));
150 }
151 }
152
154 ShapeFunctionCache(){}
156 virtual ~ShapeFunctionCache(){}
158 ShapeFunctionCache(const ShapeFunctionCache &){};
160 void operator = (const ShapeFunctionCache &){};
161
162protected:
163
165 mutable std::map < uint8, std::vector < PolynomialFunction < double > > > shapeFunctions_;
166
168 mutable std::map < uint8, std::vector< std::vector < PolynomialFunction < double > > > > dShapeFunctions_;
169
170 mutable std::vector< RMatrix3 > _rMatrix3Cache;
171 mutable std::map< uint, std::vector< RMatrix > > _rMatrixCache;
172
173};
174
175static const double NodeCoordinates[1][3] = {
176 {0.0, 0.0, 0.0}
177};
178
180
181class DLLEXPORT Shape {
182public:
184 Shape(MeshEntity * ent);
185
187 virtual ~Shape();
188
190 virtual int rtti() const = 0;
191
192 virtual int dim() const = 0;
193
195 virtual std::string name() const { return "Shape"; }
196
198 Index nodeCount() const { return this->nodeCount_; }
199
201 Node & node(Index i) const;
202
203 // /*! Return a reference to the i-th \ref Node of this shape. */
204 // Node & node(Index i);
205
207 void setNodesPtr(const std::vector< Node * > & n) {
208 this->nodeVector_ = &n;
209 }
210
212 const std::vector< Node * > & nodes() const { return * this->nodeVector_; }
213
215 // std::vector < Node * > & nodes() { return nodeVector_ ; }
216
217 virtual std::vector < PolynomialFunction < double > > createShapeFunctions() const ;
218
239 void createJacobian(RMatrix3 & J) const;
240
241 RMatrix3 createJacobian() const;
242
246 const RMatrix3 & invJacobian() const;
247
250 virtual RVector N(const RVector3 & L) const;
251
255 virtual void N(const RVector3 & L, RVector & ret) const;
256
260 virtual void dNdrst(const RVector3 & rst, RMatrix & MdNdrst) const;
261
262 virtual RMatrix dNdrst(const RVector3 & L) const;
263
274 virtual void rst2xyz(const RVector3 & rst, RVector3 & xyz) const;
275
277 virtual RVector3 xyz(const RVector3 & rst) const;
278
284 virtual void xyz2rst(const RVector3 & xyz, RVector3 & rst) const;
285
287 virtual RVector3 rst(const RVector3 & xyz) const;
288
290 virtual RVector3 rst(Index i) const;
291
295 inline double drstdxyz(uint rstI, uint xyzJ) const {
296// return invJacobian()[rstI][xyzJ];}
297 return invJacobian()[rstI * 3 + xyzJ];}
298
303 virtual bool isInside(const RVector3 & xyz, bool verbose=false) const;
304
310 virtual bool isInside(const RVector3 & xyz, RVector & sf,
311 bool verbose=false) const;
312
316 virtual bool touch(const RVector3 & pos, double tol=1e-6, bool verbose=false) const;
317
318 /*!* Return true if the ray intersects the shape.
319 * On boundary means inside too. The intersection position is stored in pos.
320 * */
321 virtual bool intersectRay(const RVector3 & start, const RVector3 & dir,
322 RVector3 & pos){
323 __MS(rtti() << " " << name())
324 THROW_TO_IMPL
325 return false;
326 };
327
329 double domainSize() const;
330
332 RVector3 center() const;
333
335 virtual RVector3 norm() const;
336
338 double h() const;
339
341 virtual Plane plane() const;
342
344 void changed();
345
346 double jacobianDeterminant() const { return det(this->createJacobian()); }
347
348 inline void resizeNodeSize_(Index n) { this->nodeCount_ = n; }
349
350
351protected:
352
354 virtual double domainSize_() const { return 0.0; }
355
356 Index nodeCount_;
357
358 mutable double domSize_;
359 mutable bool hasDomSize_;
360 mutable double _h;
361
362 mutable RMatrix3 invJacobian_;
363
364 // const std::vector< Node * > & nodes()
365 const std::vector < Node * > * nodeVector_;
366};
367
368DLLEXPORT std::ostream & operator << (std::ostream & str, const Shape & c);
369
370class DLLEXPORT NodeShape : public Shape{
371public:
372 NodeShape(MeshEntity * ent) : Shape(ent) { resizeNodeSize_(1); }
373
374 virtual ~NodeShape(){ }
375
376 virtual int rtti() const { return MESH_SHAPE_NODE_RTTI; }
377
378 virtual int dim() const { return 0; }
379
380 virtual std::string name() const { return "NodeShape"; }
381
382 virtual RVector3 rst(Index i) const;
383
384 virtual double domainSize_() const { return 1.0; }
385
386 virtual RVector3 norm() const;
387
388protected:
389 //virtual double jacobianDeterminant_() const { return 0.0; }
390};
391
392static const double EdgeCoordinates[2][3] = {
393 {0.0, 0.0, 0.0},
394 {1.0, 0.0, 0.0}
395};
396
397class DLLEXPORT EdgeShape : public Shape {
398public:
399 EdgeShape(MeshEntity * ent) : Shape(ent) { resizeNodeSize_(2); }
400
401 virtual ~EdgeShape(){ }
402
403 virtual int rtti() const { return MESH_SHAPE_EDGE_RTTI; }
404
405 virtual int dim() const { return 1; }
406
407 virtual std::string name() const { return "EdgeShape"; }
408
410 virtual RVector3 rst(Index i) const;
411
412 /*!* Return true if the ray intersects the shape.
413 * On boundary means inside too. The intersection position is stored in pos.
414 * */
415 virtual bool intersectRay(const RVector3 & start, const RVector3 & dir,
416 RVector3 & pos);
417
421 virtual bool touch(const RVector3 & pos, double tol=1e-6, bool verbose=false) const;
422
423 double length() const;
424
425 virtual RVector3 norm() const;
426
427protected:
428
429 virtual double domainSize_() const { return length(); }
430};
431
432static const double TriCoordinates[3][3] = {
433 {0.0, 0.0, 0.0},
434 {1.0, 0.0, 0.0},
435 {0.0, 1.0, 0.0}
436};
437
448class DLLEXPORT TriangleShape : public Shape {
449public:
450
451 TriangleShape(MeshEntity * ent) : Shape(ent) { resizeNodeSize_(3); }
452
453 virtual ~TriangleShape(){ }
454
455 virtual int rtti() const { return MESH_SHAPE_TRIANGLE_RTTI; }
456
457 virtual int dim() const { return 2; }
458
459 virtual std::string name() const { return "TriangleShape"; }
460
462 virtual RVector3 rst(Index i) const;
463
465 virtual void xyz2rst(const RVector3 & pos, RVector3 & rst) const;
466
467 double area() const;
468
469 virtual RVector3 norm() const;
470
471 /*!* Return true if the ray intersects the shape.
472 * On boundary means inside too. The intersection position is stored in pos.
473 * */
474 virtual bool intersectRay(const RVector3 & start, const RVector3 & dir,
475 RVector3 & pos);
476
477protected:
478
480 virtual double domainSize_() const { return area(); }
481};
482
483
484static const double QuadCoordinates[4][3] = {
485 {0.0, 0.0, 0.0},
486 {1.0, 0.0, 0.0},
487 {1.0, 1.0, 0.0},
488 {0.0, 1.0, 0.0}
489};
490
492
503class DLLEXPORT QuadrangleShape : public Shape {
504public:
505
506 QuadrangleShape(MeshEntity * ent) : Shape(ent) { resizeNodeSize_(4); }
507
508 virtual ~QuadrangleShape(){ }
509
510 virtual int rtti() const { return MESH_SHAPE_QUADRANGLE_RTTI; }
511
512 virtual int dim() const { return 2; }
513
514 virtual std::string name() const { return "QuadrangleShape"; }
515
517 virtual RVector3 rst(Index i) const;
518
519 double area() const;
520
521// virtual std::vector < PolynomialFunction < double > > createShapeFunctions() const;
522
523// /*! See Shape::N. */
524// virtual void N(const RVector3 & L, RVector & n) const;
525
526// /*! See Shape::dNdrst. */
527// virtual RMatrix dNdrst(const RVector3 & rst) const;
528//
529 virtual RVector3 norm() const;
530
531 virtual bool intersectRay(const RVector3 & start, const RVector3 & dir,
532 RVector3 & pos);
533
534protected:
535 virtual double domainSize_() const { return area(); }
536};
537
538
539class DLLEXPORT PolygonShape : public Shape {
540public:
541 PolygonShape(MeshEntity * ent);
542
543 virtual ~PolygonShape();
544
545 virtual int rtti() const { return MESH_SHAPE_POLYGON_FACE_RTTI; }
546
547 virtual int dim() const { return 3; }
548
549 virtual std::string name() const { return "PolygonFaceShape"; }
550
551 virtual RVector3 norm() const;
552
553 virtual RVector3 rst(Index i) const;
554
555 virtual bool isInside(const RVector3 & xyz, bool verbose) const;
556
557protected:
558};
559
560
561static const double TetCoordinates[4][3] = {
562 {0.0, 0.0, 0.0},
563 {1.0, 0.0, 0.0},
564 {0.0, 1.0, 0.0},
565 {0.0, 0.0, 1.0}
566};
567
569
572class DLLEXPORT TetrahedronShape : public Shape {
573public:
574 TetrahedronShape(MeshEntity * ent) : Shape(ent) { resizeNodeSize_(4); }
575
576 virtual ~TetrahedronShape(){ }
577
578 virtual int rtti() const { return MESH_SHAPE_TETRAHEDRON_RTTI; }
579
580 virtual int dim() const { return 3; }
581
582 virtual std::string name() const { return "TetrahedronShape"; }
583
585 virtual RVector3 rst(Index i) const;
586
588 void xyz2rst(const RVector3 & pos, RVector3 & rst) const;
589
590// /*! See Shape::N. */
591// virtual void N(const RVector3 & L, RVector & n) const;
592//
593// /*! See Shape::dNdrst. */
594// virtual RMatrix dNdrst(const RVector3 & rst) const;
595
596 double volume() const;
597
598protected:
599
600 virtual double domainSize_() const { return volume(); }
601};
602
603static const int HexahedronSplit5TetID[5][4] = {
604 {1, 4, 5, 6},
605 {3, 6, 7, 4},
606 {1, 0, 4, 3},
607 {1, 2, 3, 6},
608 {1, 4, 6, 3}
609};
610
611static const int HexahedronSplit6TetID[6][4] = {
612 {0, 1, 2, 6},
613 {0, 2, 3, 6},
614 {0, 1, 6, 5},
615 {0, 4, 5, 6},
616 {0, 3, 7, 6},
617 {0, 4, 6, 7}
618};
619
620static const double HexCoordinates[8][3] = {
621 {0.0, 0.0, 0.0},
622 {1.0, 0.0, 0.0},
623 {1.0, 1.0, 0.0},
624 {0.0, 1.0, 0.0},
625 {0.0, 0.0, 1.0},
626 {1.0, 0.0, 1.0},
627 {1.0, 1.0, 1.0},
628 {0.0, 1.0, 1.0}
629};
630
632
644
645class DLLEXPORT HexahedronShape : public Shape {
646public:
647 HexahedronShape(MeshEntity * ent) : Shape(ent){ resizeNodeSize_(8); }
648
649 virtual ~HexahedronShape(){ }
650
651 virtual int rtti() const { return MESH_SHAPE_HEXAHEDRON_RTTI; }
652
653 virtual int dim() const { return 3; }
654
656 virtual RVector3 rst(Index i) const;
657
658 virtual std::string name() const { return "HexahedronShape"; }
659
660 double volume() const;
661
664 virtual bool enforcePositiveDirection();
665
666// /*! See Shape::N. */
667// virtual void N(const RVector3 & L, RVector & n) const;
668//
669// /*! See Shape::dNdrst. */
670// virtual RMatrix dNdrst(const RVector3 & rst) const;
671
672protected:
673
674 virtual double domainSize_() const { return volume(); }
675};
676
677static const uint8 TriPrimSplit3TetID[3][4] = {
678 {0, 5, 1, 2},
679 {3, 1, 5, 4},
680 {3, 5, 1, 0}
681};
682
683static const double PrismCoordinates[6][3] = {
684 {0.0, 0.0, 0.0},
685 {1.0, 0.0, 0.0},
686 {0.0, 1.0, 0.0},
687 {0.0, 0.0, 1.0},
688 {1.0, 0.0, 1.0},
689 {0.0, 1.0, 1.0}
690};
691
693
703
704class DLLEXPORT TriPrismShape : public Shape {
705public:
706 TriPrismShape(MeshEntity * ent) : Shape(ent){ resizeNodeSize_(6); }
707
708 virtual ~TriPrismShape(){ }
709
710 virtual int rtti() const { return MESH_SHAPE_TRIPRISM_RTTI; }
711
712 virtual int dim() const { return 3; }
713
714 virtual std::string name() const { return "TriagonalPrismShape"; }
715
717 virtual RVector3 rst(Index i) const;
718
719 virtual std::vector < PolynomialFunction < double > > createShapeFunctions() const;
720
721 double volume() const;
722
723protected:
724
725 virtual double domainSize_() const { return volume(); }
726};
727
728static const double PyramidCoordinates[5][3] = {
729 {0.0, 0.0, 0.0},
730 {1.0, 0.0, 0.0},
731 {1.0, 1.0, 0.0},
732 {0.0, 1.0, 0.0},
733 {0.0, 0.0, 0.1}
734};
735
737
744class DLLEXPORT PyramidShape : public Shape {
745public:
746 PyramidShape(MeshEntity * ent) : Shape(ent){ resizeNodeSize_(5); }
747
748 virtual ~PyramidShape(){ }
749
750 virtual int rtti() const { return MESH_SHAPE_PYRAMID_RTTI; }
751
752 virtual int dim() const { return 3; }
753
755 virtual RVector3 rst(Index i) const;
756
757// /*! See Shape::N. */
758// virtual void N(const RVector3 & L, RVector & n) const;
759//
760// /*! See Shape::dNdrst. */
761// virtual RMatrix dNdrst(const RVector3 & rst) const;
762
763};
764
765} // namespace GIMLI
766
767#endif // _GIMLI_SHAPE__H
768
virtual std::string name() const
Definition shape.h:407
virtual double domainSize_() const
Definition shape.h:429
virtual int rtti() const
Definition shape.h:403
virtual double domainSize_() const
Definition shape.h:674
virtual std::string name() const
Definition shape.h:658
virtual int rtti() const
Definition shape.h:651
Definition meshentities.h:103
virtual double domainSize_() const
Definition shape.h:384
virtual int rtti() const
Definition shape.h:376
virtual std::string name() const
Definition shape.h:380
3D Node
Definition node.h:39
A plane.
Definition plane.h:30
virtual int rtti() const
Definition shape.h:545
virtual std::string name() const
Definition shape.h:549
virtual int rtti() const
Definition shape.h:750
virtual std::string name() const
Definition shape.h:514
virtual double domainSize_() const
Definition shape.h:535
virtual int rtti() const
Definition shape.h:510
std::map< uint8, std::vector< std::vector< PolynomialFunction< double > > > > dShapeFunctions_
Definition shape.h:168
void clear()
Definition shape.h:106
std::map< uint8, std::vector< PolynomialFunction< double > > > shapeFunctions_
Definition shape.h:165
virtual std::string name() const
Definition shape.h:195
double drstdxyz(uint rstI, uint xyzJ) const
Definition shape.h:295
virtual double domainSize_() const
Definition shape.h:354
const RMatrix3 & invJacobian() const
Definition shape.cpp:311
void setNodesPtr(const std::vector< Node * > &n)
Definition shape.h:207
virtual int rtti() const =0
const std::vector< Node * > & nodes() const
Definition shape.h:212
Shape(MeshEntity *ent)
Definition shape.cpp:114
virtual bool intersectRay(const RVector3 &start, const RVector3 &dir, RVector3 &pos)
Definition shape.h:321
Index nodeCount() const
Definition shape.h:198
Singleton()
Definition gimli.h:634
virtual double domainSize_() const
Definition shape.h:600
virtual int rtti() const
Definition shape.h:578
virtual std::string name() const
Definition shape.h:582
double volume() const
Definition shape.cpp:718
virtual double domainSize_() const
Definition shape.h:725
virtual int rtti() const
Definition shape.h:710
virtual std::string name() const
Definition shape.h:714
virtual int rtti() const
Definition shape.h:455
virtual double domainSize_() const
Definition shape.h:480
virtual std::string name() const
Definition shape.h:459
GIMLi main namespace for the Geophyiscal Inversion and Modelling Library.
Definition baseentity.h:24
T det(const T &a, const T &b, const T &c, const T &d)
Definition matrix.h:1016
double triSize(const RVector3 &p0, const RVector3 &p1, const RVector3 &p2)
Definition shape.cpp:525
double tetVolume(const RVector3 &p0, const RVector3 &p1, const RVector3 &p2, const RVector3 &p3)
Definition shape.cpp:714