00001 #ifndef DUNE_PRISMSHAPEFUNCTIONS_HH
00002 #define DUNE_PRISMSHAPEFUNCTIONS_HH
00003
00004 #include<iostream>
00005 #include<dune/common/fvector.hh>
00006 #include<dune/common/exceptions.hh>
00007 #include<dune/common/geometrytype.hh>
00008
00015 namespace Dune
00016 {
00017
00024
00025
00026
00027
00032 template<typename C,typename T>
00033 class P0PrismShapeFunction
00034 {
00035 public:
00036
00037
00038 enum { dim=3 };
00039 enum { comps=1 };
00040
00041 enum { m=1 };
00042
00043
00044 typedef C CoordType;
00045 typedef T ResultType;
00046 typedef P0PrismShapeFunction ImplementationType;
00047
00049 P0PrismShapeFunction ()
00050 {
00051 pos[0] = 1/3.0;
00052 pos[1] = 1/3.0;
00053 pos[2] = 1/2.0;
00054
00055 }
00056
00058 ResultType evaluateFunction (int comp, const FieldVector<CoordType,3>& x) const
00059 {
00060 return 1;
00061 }
00062
00064 ResultType evaluateDerivative (int comp, int dir, const FieldVector<CoordType,3>& x) const
00065 {
00066 return 0;
00067 }
00068
00070 int localindex (int comp) const
00071 {
00072 return 0;
00073 }
00074
00076 int codim () const
00077 {
00078 return 0;
00079 }
00080
00082 int entity () const
00083 {
00084 return 0;
00085 }
00086
00088 int entityindex () const
00089 {
00090 return 0;
00091 }
00092
00094 const FieldVector<CoordType,dim>& position () const
00095 {
00096 return pos;
00097 }
00098
00099 private:
00100 FieldVector<CoordType,3> pos;
00101 };
00102
00103
00104
00105
00106
00107
00108
00115
00116
00117
00118
00119
00120 template<typename C,typename T>
00121 class P1PrismShapeFunction
00122 {
00123 public:
00124
00125 enum {dim=3};
00126 enum{comps=1};
00127 enum {m=6};
00128
00129 typedef C CoordType;
00130 typedef T ResultType;
00131 typedef P1PrismShapeFunction ImplementationType;
00132
00133
00134 P1PrismShapeFunction(int i)
00135 {
00136 number=i;
00137 switch(i)
00138 {
00139
00140 case 0:
00141
00142 pos[0]=0.0;
00143 pos[1]=0.0;
00144 pos[2]=0.0;
00145
00146 a[0]=1.0;
00147 a[1]=1.0;
00148 b[0]=-1.0;
00149 b[1]=-1.0;
00150 b[2]=0.0;
00151 c[0]=0.0;
00152 c[1]=0.0;
00153 c[2]=-1.0;
00154
00155 aa[0][0]=-1.0;
00156 bb[0][0]=0.0;
00157 bb[1][0]=0.0;
00158 bb[2][0]=1.0;
00159
00160 aa[0][1]=-1.0;
00161 bb[0][1]=0.0;
00162 bb[1][1]=0.0;
00163 bb[2][1]=1.0;
00164
00165 aa[0][2]=-1.0;
00166 bb[0][2]=1.0;
00167 bb[1][2]=1.0;
00168 bb[2][2]=0.0;
00169 break;
00170 case 1:
00171
00172 pos[0]=1.0;
00173 pos[1]=0.0;
00174 pos[2]=0.0;
00175
00176 a[0]=0.0;
00177 a[1]=1.0;
00178 b[0]=1.0;
00179 b[1]=0.0;
00180 b[2]=0.0;
00181 c[0]=0.0;
00182 c[1]=0.0;
00183 c[2]=-1.0;
00184
00185 aa[0][0]=1.0;
00186 bb[0][0]=0.0;
00187 bb[1][0]=0.0;
00188 bb[2][0]=-1.0;
00189
00190 aa[0][1]=0.0;
00191 bb[0][1]=0.0;
00192 bb[1][1]=0.0;
00193 bb[2][1]=0.0;
00194
00195 aa[0][2]=0.0;
00196 bb[0][2]=-1.0;
00197 bb[1][2]=0.0;
00198 bb[2][2]=0.0;
00199 break;
00200 case 2:
00201
00202 pos[0]=0.0;
00203 pos[1]=1.0;
00204 pos[2]=0.0;
00205
00206 a[0]=0.0;
00207 a[1]=1.0;
00208 b[0]=0.0;
00209 b[1]=1.0;
00210 b[2]=0.0;
00211 c[0]=0.0;
00212 c[1]=0.0;
00213 c[2]=-1.0;
00214
00215 aa[0][0]=0.0;
00216 bb[0][0]=0.0;
00217 bb[1][0]=0.0;
00218 bb[2][0]=0.0;
00219
00220 aa[0][1]=1.0;
00221 bb[0][1]=0.0;
00222 bb[1][1]=0.0;
00223 bb[2][1]=-1.0;
00224
00225 aa[0][2]=0.0;
00226 bb[0][2]=0.0;
00227 bb[1][2]=-1.0;
00228 bb[2][2]=0.0;
00229 break;
00230 case 3:
00231
00232 pos[0]=0.0;
00233 pos[1]=0.0;
00234 pos[2]=1.0;
00235
00236 a[0]=1.0;
00237 a[1]=0.0;
00238 b[0]=-1.0;
00239 b[1]=-1.0;
00240 b[2]=0.0;
00241 c[0]=0.0;
00242 c[1]=0.0;
00243 c[2]=1.0;
00244
00245 aa[0][0]=0.0;
00246 bb[0][0]=0.0;
00247 bb[1][0]=0.0;
00248 bb[2][0]=-1.0;
00249
00250 aa[0][1]=0.0;
00251 bb[0][1]=0.0;
00252 bb[1][1]=0.0;
00253 bb[2][1]=-1.0;
00254
00255 aa[0][2]=1.0;
00256 bb[0][2]=-1.0;
00257 bb[1][2]=-1.0;
00258 bb[2][2]=0.0;
00259 break;
00260 case 4:
00261
00262 pos[0]=1.0;
00263 pos[1]=0.0;
00264 pos[2]=1.0;
00265
00266 a[0]=0.0;
00267 a[1]=0.0;
00268 b[0]=1.0;
00269 b[1]=0.0;
00270 b[2]=0.0;
00271 c[0]=0.0;
00272 c[1]=0.0;
00273 c[2]=1.0;
00274
00275 aa[0][0]=0.0;
00276 bb[0][0]=0.0;
00277 bb[1][0]=0.0;
00278 bb[2][0]=1.0;
00279
00280 aa[0][1]=0.0;
00281 bb[0][1]=0.0;
00282 bb[1][1]=0.0;
00283 bb[2][1]=0.0;
00284
00285 aa[0][2]=0.0;
00286 bb[0][2]=1.0;
00287 bb[1][2]=0.0;
00288 bb[2][2]=0.0;
00289 break;
00290 case 5:
00291
00292 pos[0]=0.0;
00293 pos[1]=1.0;
00294 pos[2]=1.0;
00295
00296 a[0]=0.0;
00297 a[1]=0.0;
00298 b[0]=0.0;
00299 b[1]=1.0;
00300 b[2]=0.0;
00301 c[0]=0.0;
00302 c[1]=0.0;
00303 c[2]=1.0;
00304
00305 aa[0][0]=0.0;
00306 bb[0][0]=0.0;
00307 bb[1][0]=0.0;
00308 bb[2][0]=0.0;
00309
00310 aa[0][1]=0.0;
00311 bb[0][1]=0.0;
00312 bb[1][1]=0.0;
00313 bb[2][1]=1.0;
00314
00315 aa[0][2]=0.0;
00316 bb[0][2]=0.0;
00317 bb[1][2]=1.0;
00318 bb[2][2]=0.0;
00319 break;
00320 default:
00321 DUNE_THROW(RangeError, "wrong no of shape fns in Prism?");
00322 break;
00323 }
00324 }
00326 P1PrismShapeFunction ()
00327 {}
00328
00330 ResultType evaluateFunction (int comp, const FieldVector<CoordType,3>& x) const
00331 {
00332
00333 ResultType phi1=a[0];
00334 ResultType phi2=a[1];
00335
00336 for (int j=0;j<3;++j)
00337 {
00338 phi1 +=b[j]*x[j];
00339 phi2 +=c[j]*x[j];
00340 }
00341 ResultType phi=phi1*phi2;
00342 return phi;
00343
00344
00345 }
00346
00347
00348 ResultType evaluateDerivative (int comp, int dir, const FieldVector<CoordType,3>& x) const
00349
00350 {
00351 ResultType deriv=aa[0][dir];
00352
00353 for (int j=0;j<3;++j)
00354 {
00355 deriv +=bb[j][dir]*x[j];
00356 }
00357
00358 return deriv;
00359
00360 }
00361
00362
00363
00365 int localindex (int comp) const
00366 {
00367 return number;
00368 }
00369
00371 int codim () const
00372 {
00373 return dim;
00374 }
00375
00377 int entity () const
00378 {
00379 return number;
00380 }
00381
00383 int entityindex () const
00384 {
00385 return 0;
00386 }
00387
00389 const FieldVector<CoordType,dim>& position () const
00390 {
00391 return pos;
00392 }
00393
00394 private:
00395 int number;
00396 ResultType a[3], b[3], c[3],aa[3][3], bb[3][3], cc[3][3];
00397 FieldVector<CoordType,3> pos;
00398
00399
00400 };
00401
00402
00403
00404
00405
00406
00407
00414
00415
00416
00417
00418
00419 template<typename C,typename T>
00420 class P2PrismShapeFunction
00421 {
00422 public:
00423
00424 enum {dim=3};
00425 enum {comps=1};
00426 enum {m=18};
00427
00428 typedef C CoordType;
00429 typedef T ResultType;
00430 typedef P2PrismShapeFunction ImplementationType;
00431
00432
00433 P2PrismShapeFunction(int i)
00434 {
00435 number=i;
00436
00437
00438
00439 if (i<3 || (i>=12 && i<15))
00440 codim_=3;
00441 else if (i>=9 && i<12)
00442 codim_=1;
00443 else
00444 codim_=2;
00445
00446 static const int entities[] = {0,1,2,
00447 1,2,0,
00448 3, 4, 5,
00449 2,3,1,
00450 3,4,5,
00451 7,8,6};
00452
00453 entity_ = entities[i];
00454
00455 if (i<6) {
00456
00457 a1d = 1.0;
00458 b1d = -3.0;
00459 c1d = 2.0;
00460 pos[2] = 0;
00461
00462 } else if (i<12) {
00463
00464 a1d = 0.0;
00465 b1d = 4.0;
00466 c1d = -4.0;
00467 pos[2] = 0.5;
00468
00469 } else {
00470 a1d = 0.0;
00471 b1d = -1.0;
00472 c1d = 2.0;
00473 pos[2] = 1.0;
00474 }
00475
00476 switch(i) {
00477
00478 case 0:
00479 case 6:
00480 case 12:
00481
00482
00483 pos[0]=0.0;
00484 pos[1]=0.0;
00485
00486 coeff=2;
00487 a[0]=1.0;
00488 a[1]=0.5;
00489 b[0]=-1.0;
00490 b[1]=-1.0;
00491 c[0]=-1.0;
00492 c[1]=-1.0;
00493
00494 aa[0][0]=-3;
00495 bb[0][0]=4;
00496 bb[1][0]=4;
00497
00498 aa[0][1]=-3;
00499 bb[0][1]=4;
00500 bb[1][1]=4;
00501 break;
00502 case 1:
00503 case 7:
00504 case 13:
00505
00506
00507 pos[0]=1.0;
00508 pos[1]=0.0;
00509
00510 coeff=2;
00511 a[0]=0.0;
00512 a[1]=-0.5;
00513 b[0]=1.0;
00514 b[1]=0.0;
00515 c[0]=1.0;
00516 c[1]=0.0;
00517
00518 aa[0][0]=-1;
00519 bb[0][0]=4;
00520 bb[1][0]=0;
00521
00522 aa[0][1]=0;
00523 bb[0][1]=0;
00524 bb[1][1]=0;
00525 break;
00526 case 2:
00527 case 8:
00528 case 14:
00529
00530 pos[0]=0.0;
00531 pos[1]=1.0;
00532
00533 coeff=2;
00534 a[0]=0.0;
00535 a[1]=-0.5;
00536 b[0]=0.0;
00537 b[1]=1.0;
00538 c[0]=0.0;
00539 c[1]=1.0;
00540
00541 aa[0][0]=0;
00542 bb[0][0]=0;
00543 bb[1][0]=0;
00544
00545 aa[0][1]=-1;
00546 bb[0][1]=0;
00547 bb[1][1]=4;
00548 break;
00549 case 3:
00550 case 9:
00551 case 15:
00552
00553 pos[0]=0.5;
00554 pos[1]=0.5;
00555
00556 coeff=4;
00557 a[0]=0.0;
00558 a[1]=0.0;
00559 b[0]=1.0;
00560 b[1]=0.0;
00561 c[0]=0.0;
00562 c[1]=1.0;
00563
00564 aa[0][0]=0;
00565 bb[0][0]=0;
00566 bb[1][0]=4;
00567
00568 aa[0][1]=0;
00569 bb[0][1]=4;
00570 bb[1][1]=0;
00571 break;
00572 case 4:
00573 case 10:
00574 case 16:
00575
00576 pos[0]=0.0;
00577 pos[1]=0.5;
00578
00579 coeff=4;
00580 a[0]=0.0;
00581 a[1]=1.0;
00582 b[0]=0.0;
00583 b[1]=1.0;
00584 c[0]=-1.0;
00585 c[1]=-1.0;
00586
00587 aa[0][0]=0;
00588 bb[0][0]=0;
00589 bb[1][0]=-4;
00590
00591 aa[0][1]=4;
00592 bb[0][1]=-4;
00593 bb[1][1]=-8;
00594 break;
00595 case 5:
00596 case 11:
00597 case 17:
00598
00599 pos[0]=0.5;
00600 pos[1]=0.0;
00601
00602 coeff=4;
00603 a[0]=0.0;
00604 a[1]=1.0;
00605 b[0]=1.0;
00606 b[1]=0.0;
00607 c[0]=-1.0;
00608 c[1]=-1.0;
00609
00610 aa[0][0]=4;
00611 bb[0][0]=-8;
00612 bb[1][0]=-4;
00613
00614 aa[0][1]=0;
00615 bb[0][1]=-4;
00616 bb[1][1]=0;
00617 break;
00618 default:
00619 DUNE_THROW(RangeError, "wrong no of shape fns in Prism?");
00620 break;
00621 }
00622 }
00624 P2PrismShapeFunction ()
00625 {}
00626
00628 ResultType evaluateFunction (int comp, const FieldVector<CoordType,3>& x) const
00629 {
00630
00631 ResultType phi1=a[0];
00632 ResultType phi2=a[1];
00633
00634 for (int j=0;j<2;++j)
00635 {
00636 phi1 +=b[j]*x[j];
00637 phi2 +=c[j]*x[j];
00638 }
00639
00640
00641 ResultType phi3 = a1d + x[2]*b1d + x[2]*x[2]*c1d;
00642
00643 return coeff * phi1*phi2*phi3;
00644
00645
00646 }
00647
00648
00649 ResultType evaluateDerivative (int comp, int dir, const FieldVector<CoordType,3>& x) const
00650
00651 {
00652 if (dir==2) {
00653 ResultType phi1=a[0];
00654 ResultType phi2=a[1];
00655
00656 for (int j=0;j<2;++j) {
00657 phi1 +=b[j]*x[j];
00658 phi2 +=c[j]*x[j];
00659 }
00660
00661 ResultType phi = coeff * phi1 * phi2;
00662 return phi * (b1d + 2*c1d*x[2]);
00663
00664 }
00665
00666 ResultType deriv=aa[0][dir];
00667
00668 for (int j=0;j<2;++j)
00669 deriv +=bb[j][dir]*x[j];
00670
00671 return deriv * (a1d + x[2]*b1d + x[2]*x[2]*c1d);
00672
00673 }
00674
00675
00676
00678 int localindex (int comp) const
00679 {
00680 return number;
00681 }
00682
00684 int codim () const
00685 {
00686 return codim_;
00687 }
00688
00690 int entity () const
00691 {
00692 return entity_;
00693 }
00694
00696 int entityindex () const
00697 {
00698 return 0;
00699 }
00700
00702 const FieldVector<CoordType,dim>& position () const
00703 {
00704 return pos;
00705 }
00706
00707 private:
00708 int number,coeff,entity_,codim_;
00709 ResultType a[2], b[2], c[2],aa[2][2], bb[2][2];
00710
00711
00712 ResultType a1d, b1d, c1d;
00713 FieldVector<CoordType,3> pos;
00714
00715
00716 };
00717
00718
00719
00720 template<typename C, typename T, typename S>
00721 class P0PrismShapeFunctionSet
00722 {
00723 public:
00724
00725
00726 enum { dim=3 };
00727 enum { comps=1 };
00728
00729 enum { m=1 };
00730
00731
00732 typedef C CoordType;
00733 typedef T ResultType;
00734 typedef S value_type;
00735 typedef typename S::ImplementationType Imp;
00736
00738 P0PrismShapeFunctionSet ()
00739 {
00740 sf = Imp();
00741 }
00742
00744 int size () const
00745 {
00746 return 1;
00747 }
00748
00750 int size (int entity, int codim) const
00751 {
00752 if (codim==0) return 1; else return 0;
00753 }
00754
00756 const value_type& operator[] (int i) const
00757 {
00758 return sf;
00759 }
00760
00762 int order () const
00763 {
00764 return 0;
00765 }
00766
00768 GeometryType type () const
00769 {
00770 static GeometryType prism(GeometryType::prism, dim);
00771 return prism;
00772 }
00773
00774 private:
00775 S sf;
00776 };
00777
00778
00779
00780 template<typename C, typename T, typename S>
00781 class P1PrismShapeFunctionSet
00782 {
00783 public:
00784
00785
00786 enum { dim=3 };
00787 enum { comps=1 };
00788
00789 enum { m=6 };
00790
00791
00792 typedef C CoordType;
00793 typedef T ResultType;
00794 typedef S value_type;
00795 typedef typename S::ImplementationType Imp;
00796
00798 P1PrismShapeFunctionSet ()
00799 {
00800 for (int i=0; i<m; i++)
00801 sf[i] = Imp(i);
00802 }
00803
00805 int size () const
00806 {
00807 return m;
00808 }
00809
00811 int size (int entity, int codim) const
00812 {
00813 if (codim==dim) return m; else return 0;
00814 }
00815
00817 const value_type& operator[] (int i) const
00818 {
00819 return sf[i];
00820 }
00821
00823 int order () const
00824 {
00825 return 1;
00826 }
00827
00829 GeometryType type () const
00830 {
00831 static GeometryType prism(GeometryType::prism, dim);
00832 return prism;
00833 }
00834
00835 private:
00836 S sf[m];
00837 };
00838
00839
00840
00841 template<typename C, typename T, typename S>
00842 class P2PrismShapeFunctionSet
00843 {
00844 public:
00845
00846
00847 enum { dim=3 };
00848 enum { comps=1 };
00849
00850 enum { m=18 };
00851
00852
00853 typedef C CoordType;
00854 typedef T ResultType;
00855 typedef S value_type;
00856 typedef typename S::ImplementationType Imp;
00857
00859 P2PrismShapeFunctionSet ()
00860 {
00861 for (int i=0; i<m; i++)
00862 sf[i] = Imp(i);
00863
00864 }
00865
00867 int size () const
00868 {
00869 return m;
00870 }
00871
00873 int size (int entity, int codim) const
00874 {
00875 if (codim==dim)
00876 return 6;
00877 else if (codim==2)
00878 return 9;
00879 else if (codim==1)
00880 return 3;
00881
00882 return 0;
00883 }
00884
00886 const value_type& operator[] (int i) const
00887 {
00888 return sf[i];
00889 }
00890
00892 int order () const
00893 {
00894 return 2;
00895 }
00896
00898 GeometryType type () const
00899 {
00900 static GeometryType prism(GeometryType::prism, dim);
00901 return prism;
00902 }
00903
00904 private:
00905 S sf[m];
00906 };
00907
00908
00910 template<typename C, typename T>
00911 class P0PrismShapeFunctionSetContainer
00912 {
00913 public:
00914
00915 enum { dim=3 };
00916 enum { comps=1 };
00917 enum { maxsize=1 };
00918
00919
00920 typedef C CoordType;
00921 typedef T ResultType;
00922 typedef P0PrismShapeFunctionSet<C,T,P0PrismShapeFunction<C,T> > value_type;
00923
00924 const value_type& operator() (GeometryType type, int order) const
00925 {
00926 if(type.isPrism()) return p0prism;
00927 DUNE_THROW(NotImplemented, "type not implemented yet");
00928 }
00929
00930 private:
00931 value_type p0prism;
00932 };
00933
00935 template<typename C, typename T>
00936 class P1PrismShapeFunctionSetContainer
00937 {
00938 public:
00939
00940 enum { dim=3 };
00941 enum { comps=1 };
00942 enum { maxsize=6 };
00943
00944
00945 typedef C CoordType;
00946 typedef T ResultType;
00947 typedef P1PrismShapeFunctionSet<C,T,P1PrismShapeFunction<C,T> > value_type;
00948
00949 const value_type& operator() (GeometryType type, int order) const
00950 {
00951 if(type.isPrism()) return p1prism;
00952 DUNE_THROW(NotImplemented, "type not implemented yet");
00953 }
00954
00955 private:
00956 value_type p1prism;
00957 };
00958
00960 template<typename C, typename T>
00961 class P2PrismShapeFunctionSetContainer
00962 {
00963 public:
00964
00965 enum { dim=3 };
00966 enum { comps=1 };
00967 enum { maxsize=18 };
00968
00969
00970 typedef C CoordType;
00971 typedef T ResultType;
00972 typedef P2PrismShapeFunctionSet<C,T,P2PrismShapeFunction<C,T> > value_type;
00973
00974 const value_type& operator() (GeometryType type, int order) const
00975 {
00976 if(type.isPrism()) return p2prism;
00977 DUNE_THROW(NotImplemented, "type not implemented yet");
00978 }
00979
00980 private:
00981 value_type p2prism;
00982 };
00983
00986 }
00987 #endif