00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef BOUNDY_H_
00024 #define BOUNDY_H_
00025
00026 class Bo_description;
00027
00029
00030
00031
00032
00033
00034
00036
00037
00039
00041
00042
00043 class Tetraeder_storage {
00044 public:
00045
00046 inline Tetraeder_storage(Bo_description* desc,
00047 int P0, int P1, int P2, int P3,
00048 Tetraeder_storage* Next);
00049
00050 Tetraeder_storage(Tetraeder_storage* Next) {
00051 next = Next;
00052 var = NULL;
00053 }
00054
00055
00056 void Put_Next(Tetraeder_storage* Next) {
00057 next = Next;
00058 }
00059 Tetraeder_storage* Next() { return next; }
00060
00061
00062 inline void Put_det(double deter) { det = deter; }
00063 inline double Det() { return det; }
00064
00065
00066 int N0() { return num0; }
00067 int N1() { return num1; }
00068 int N2() { return num2; }
00069 int N3() { return num3; }
00070
00071
00072 double Xm0, Ym0, Zm0;
00073 double Xm1, Ym1, Zm1;
00074 double Xm2, Ym2, Zm2;
00075 double Xm3, Ym3, Zm3;
00076
00077
00078 virtual bool Boundary_tet() { return false; }
00079 virtual double Give_det_surface() { return 0.0; }
00080 virtual void Put_det_surface(double value) { };
00081
00082
00083 inline bool Check_angles(Bo_description* desc);
00084
00085
00086 double *Give_variable() { return var; };
00087 void Set_var(double *v) { var = v; };
00088
00089 virtual ~Tetraeder_storage() {
00090 delete next;
00091 if(var!=NULL) delete var;
00092 }
00093
00094 protected:
00095 int num0; int num1; int num2; int num3;
00096 double det;
00097 Tetraeder_storage* next;
00098
00099
00100 double *var;
00101 };
00102
00103
00104 class Boundary_tetraeder_storage : public Tetraeder_storage {
00105 public:
00106 Boundary_tetraeder_storage(Bo_description* desc,
00107 int P0, int P1, int P2, int P3,
00108 Tetraeder_storage* Next) :
00109 Tetraeder_storage(Next) {
00110 num0 = P0; num1 = P1; num2 = P2; num3 = P3;
00111 };
00112
00113 bool Boundary_tet() { return true; }
00114 double Give_det_surface() { return det_surface; }
00115 void Put_det_surface(double value) { det_surface = value; }
00116
00117 ~Boundary_tetraeder_storage() {
00118 delete next;
00119 if(var!=NULL) delete var;
00120 }
00121 private:
00122 double det_surface;
00123 };
00124
00125
00127
00128
00129
00131
00132 class BoCeData;
00133
00134 class Bo_description {
00135 public:
00136 Bo_description();
00137 void Put_zero();
00138
00139
00140 bool corner_point(dir_sons e);
00141 bool edge_point(dir_sons e,dir_3D d);
00142
00143
00144 bool edge_point(Edge_Corner_point poi);
00145 double h(dir_sons e,dir_3D d);
00146
00147
00148 bool Edge(Edges_cell ed);
00149 double Meshsize();
00150 int edge_info();
00151
00152
00153
00154 D3vector coord(dir_sons e);
00155 D3vector coord(dir_sons e,dir_3D);
00156 D3vector coord(Edge_Corner_point poi);
00157
00158
00159 void Put_corner_point(dir_sons e);
00160 void Put_edge_point(dir_sons e,dir_3D d,double h);
00161 void Put_Meshsize(double H);
00162 void Put_edge(Edges_cell ed);
00163
00164
00165 void Test_Initialisierung();
00166
00167
00168 void Set_num_corner(dir_sons e, int num);
00169 void Set_num_edge_poi(dir_sons e, dir_3D d, int num);
00170 void Set_num_cellpoi(int num);
00171 int Num_corner(dir_sons e);
00172 int Num_edge_poi(dir_sons e,dir_3D d);
00173 int Num(Edge_Corner_point poi);
00174
00175
00176 void Put_bocedata(BoCeData* boce) { bocedat=boce; };
00177 BoCeData* Give_bocedata() { return bocedat; };
00178
00179
00180 double * Give_dis() { return dis; }
00181
00182 private:
00183 bool corner[8];
00184 bool edge_poi[24];
00185 double dis[24];
00186 int edge;
00187 double H;
00188
00189
00190 int num_corner[8];
00191 int num_edge_poi[24];
00192 int num_cellpoi;
00193
00194 BoCeData* bocedat;
00195 };
00196
00197
00199
00200
00201
00202
00204 class Bocellpoint {
00205 public:
00206 Bocellpoint(D3vector l_coord) {
00207 local_coord=l_coord;
00208 label_level=NULL;
00209 };
00210 D3vector Give_local_coord() { return local_coord; };
00211 void Set_number_avs(int avs_num) { number_avs = avs_num; };
00212 int Number_avs() { return number_avs; };
00213
00214 int *label_level;
00215 private:
00216 D3vector local_coord;
00217 int number_avs;
00218 };
00219
00220
00221
00222
00224
00225
00226
00227
00229
00230
00231 class BoCeData {
00232 public:
00233 BoCeData() { bocellpoint=NULL;
00234 Tets_boundary=NULL;
00235 Tets=NULL;
00236 vars = NULL;
00237 info = NULL;
00238 hhh = NULL;
00239 };
00240
00241
00242
00243 int Give_total_number_points() const;
00244 bool Is_point_clipped_point(int num) const;
00245
00246 void Set_h(double *h, Bo_description& desc);
00247
00248
00249
00250 void Calc_FE_elements(Bo_description& desc);
00251 int Give_number_points() const;
00252
00253
00254
00255 void Add_Tetraeder(Bo_description* desc, int P0, int P1, int P2, int P3);
00256 void Add_Tetraeder_bo(Bo_description* desc, int P0, int P1, int P2, int P3);
00257
00258
00259 D3vector coord(int num, double* h);
00260 double *hhh;
00261
00262
00263 inline dir_sons corner(int num) const;
00264 inline Cell_type_points edge_point(int num) const;
00265
00266
00267 inline dir_3D edge_dir(int num);
00268
00269 bool Edge(Edges_cell ed);
00270
00271 inline double Meshsize();
00272
00273
00274 bool boundary_EW(int num);
00275 bool boundary_NS(int num);
00276 bool boundary_TD(int num);
00277
00278
00279 Tetraeder_storage* Give_tets() const { return Tets; }
00280 Boundary_tetraeder_storage* Give_boundary_tets() const
00281 { return Tets_boundary; }
00282
00283
00284 bool Exists_bocellpoint() const { return bocellpoint!=NULL; }
00285 int* Give_label_level() const { return bocellpoint->label_level; }
00286 void Set_label_level(int* ll) { bocellpoint->label_level = ll; }
00287 void Set_Dirichlet(int num) { bocellpoint->label_level[num-1]=true; }
00288 bool Is_Dirichlet(int num) const { return bocellpoint->label_level[num-1]; }
00289
00290 void Set_number_avs(int avs_num);
00291 int Number_avs();
00292 void Add_Bo_freedom(D3vector local_coord);
00293 D3vector Local_coord_bocellpoint();
00294 inline D3vector Coord_bocellpoint();
00295 inline D3vector Coord_bocellpoint_normal() const;
00296
00297
00298
00299 void Set_variable_pointer(int num, double* poi);
00300
00301 double** vars;
00302
00303
00304 void Print();
00305 void Analyse_angles(Bo_description& desc);
00306
00307 ~BoCeData() {
00308 if(bocellpoint!=NULL)
00309 delete bocellpoint;
00310 if(Tets!=NULL)
00311 delete Tets;
00312 if(vars!=NULL)
00313 delete vars;
00314 if(info!=NULL)
00315 delete info;
00316 };
00317
00318 private:
00319
00320 void Initialize(Bo_description& desc);
00321
00322
00323 void Put_corner_point(int num, dir_sons c);
00324 void Put_edge_point(int num,dir_sons c,dir_3D d);
00325 void Allocate(int n_points);
00326
00327 void Put_edge_info(int ed);
00328 void Put_Meshsize(double h);
00329
00330 int number_points;
00331 int* info;
00332
00333 int edge;
00334 double H;
00335
00336
00337
00338
00339 Tetraeder_storage* Tets;
00340 Boundary_tetraeder_storage* Tets_boundary;
00341
00342
00343 Bocellpoint* bocellpoint;
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 void Print(dir_3D d);
00355 void Print(dir_sons d);
00356 void Print(Edges_cell ed);
00357 };
00358
00359
00361
00363
00364
00365 inline Bo_description::Bo_description() {
00366 static int i;
00367 for(i=0;i<8;++i) corner[i] = false;
00368 for(i=0;i<24;++i) edge_poi[i] = false;
00369 for(i=0;i<24;++i) dis[i] = 0.0;
00370 edge = 0;
00371 }
00372
00373 inline void Bo_description::Put_zero() {
00374 static int i;
00375 for(i=0;i<8;++i) corner[i] = false;
00376 for(i=0;i<24;++i) edge_poi[i] = false;
00377 for(i=0;i<24;++i) dis[i] = 0.0;
00378 edge = 0;
00379 }
00380
00381 inline bool Bo_description::corner_point(dir_sons e) {
00382 return corner[e];
00383 };
00384
00385 inline bool Bo_description::edge_point(dir_sons e,dir_3D d) {
00386 return edge_poi[3*e + (d>>1)];
00387 }
00388
00389 inline void Bo_description::Set_num_corner(dir_sons e, int num) {
00390 num_corner[e]=num;
00391 }
00392 inline void Bo_description::Set_num_edge_poi(dir_sons e, dir_3D d, int num) {
00393 num_edge_poi[3*e + (d>>1)] = num;
00394 };
00395 inline void Bo_description::Set_num_cellpoi(int num) {
00396 num_cellpoi = num;
00397 };
00398
00399 inline int Bo_description::Num_corner(dir_sons e) {
00400
00401
00402
00403
00404
00405
00406
00407
00408 return num_corner[e];
00409 }
00410 inline int Bo_description::Num_edge_poi(dir_sons e, dir_3D d) {
00411 return num_edge_poi[3*e + (d>>1)];
00412 };
00413
00414 inline int Bo_description::Num(Edge_Corner_point poi) {
00415 if(poi.edge_point == edge_poi_typ) return Num_edge_poi(poi.corner,poi.d);
00416 if(poi.edge_point == corner_poi_typ) return Num_corner(poi.corner);
00417 return num_cellpoi;
00418 }
00419
00420
00421 inline bool Bo_description::edge_point(Edge_Corner_point poi) {
00422 return edge_point(poi.corner,poi.d);
00423 };
00424
00425 inline double Bo_description::h(dir_sons e,dir_3D d) {
00426 return dis[3*e + (d>>1)];
00427 }
00428
00429 inline double Bo_description::Meshsize() {
00430 return H;
00431 }
00432
00433 inline void Bo_description::Put_Meshsize(double h) {
00434 H=h;
00435 }
00436
00437 inline void Bo_description::Put_corner_point(dir_sons e) {
00438 corner[e]=true;
00439 }
00440
00441 inline void Bo_description::Put_edge_point(dir_sons e,dir_3D d,double h) {
00442 edge_poi[3*e + (d>>1)] = true;
00443 dis[3*e + (d>>1)] = h;
00444
00445 Put_corner_point(e);
00446 }
00447
00448 inline bool Bo_description::Edge(Edges_cell ed) {
00449 return (bool)((edge>>ed)&1);
00450 }
00451
00452 inline int Bo_description::edge_info() { return edge; };
00453
00454 inline void Bo_description::Put_edge(Edges_cell ed) {
00455 edge = edge|(1<<ed);
00456
00457 Put_corner_point(Transform(ed,Ld));
00458 Put_corner_point(Transform(ed,Rd));
00459 }
00460
00461 inline D3vector Bo_description::coord(dir_sons e) {
00462 return D3vector((e&1)*H,((e>>1)&1)*H,(e>>2)*H);
00463 };
00464
00465 inline D3vector Bo_description::coord(dir_sons e,dir_3D d) {
00466 if(d < Sdir)
00467 return D3vector((e&1)*H + h(e,d) *(2*d-1),
00468 ((e>>1)&1)*H,(e>>2)*H);
00469 if(d > Ndir)
00470 return D3vector((e&1)*H,((e>>1)&1)*H,
00471 (e>>2)*H + h(e,d) * (2*d-9));
00472 return D3vector((e&1)*H,
00473 ((e>>1)&1)*H + h(e,d) * (2*d-5),(e>>2)*H);
00474
00475 };
00476
00477 inline D3vector Bo_description::coord(Edge_Corner_point poi) {
00478 if(poi.edge_point == edge_poi_typ) return coord(poi.corner,poi.d);
00479 if(poi.edge_point == corner_poi_typ) return coord(poi.corner);
00480 return Give_bocedata()->Coord_bocellpoint();
00481 }
00482
00484
00485 inline D3vector BoCeData::Local_coord_bocellpoint() {
00486 if(developer_version) {
00487 if(bocellpoint == NULL)
00488 cout << " \n Fehler in BoCeData::Local_coord_bocellpoint!" << endl;
00489 }
00490 return bocellpoint->Give_local_coord();
00491 }
00492
00493 inline D3vector BoCeData::Coord_bocellpoint() {
00494 if(developer_version) {
00495 if(bocellpoint == NULL)
00496 cout << " \n Fehler in BoCeData::Local_coord_bocellpoint!" << endl;
00497 }
00498 return bocellpoint->Give_local_coord() + D3vector(0.5,0.5,0.5)*H;
00499 }
00500
00501 inline D3vector BoCeData::Coord_bocellpoint_normal() const {
00502 return bocellpoint->Give_local_coord() / H + D3vector(0.5,0.5,0.5);
00503 }
00504
00505 inline int BoCeData::Number_avs() {
00506 if(developer_version) {
00507 if(bocellpoint == NULL)
00508 cout << " \n Fehler in BoCeData::Number_avs!" << endl;
00509 }
00510 return bocellpoint->Number_avs();
00511 }
00512
00513 inline void BoCeData::Set_number_avs(int avs_num) {
00514 if(developer_version) {
00515 if(bocellpoint == NULL)
00516 cout << " \n Fehler in BoCeData::Set_number_avs!" << endl;
00517 }
00518 bocellpoint->Set_number_avs(avs_num);
00519 }
00520
00521 inline void BoCeData::Add_Bo_freedom(D3vector local_coord) {
00522 if(developer_version) {
00523 if(bocellpoint != NULL)
00524 cout << " \n Randzellfreiheitsgrad existiert schon! " << endl;
00525 }
00526 bocellpoint = new Bocellpoint(local_coord);
00527 }
00528
00529
00530 inline void BoCeData::Add_Tetraeder(Bo_description* desc,
00531 int P0, int P1, int P2, int P3) {
00532 Tets = new Tetraeder_storage(desc,P0,P1,P2,P3,Tets);
00533 }
00534
00535 inline void BoCeData::Add_Tetraeder_bo(Bo_description* desc,
00536 int P0, int P1, int P2, int P3) {
00537 Tets_boundary =
00538 new Boundary_tetraeder_storage(desc,P0,P1,P2,P3,Tets_boundary);
00539 }
00540
00541
00542 inline D3vector BoCeData::coord(int num, double *h) {
00543 dir_sons e;
00544 dir_3D d;
00545 if(developer_version) {
00546 if(num<0 || num > number_points) {
00547 cout << " \n Fehler in BoCeData::coord " << endl;
00548 return D3vector(0,0,0);
00549 }
00550 }
00551 if(num == number_points) {
00552 return bocellpoint->Give_local_coord() + D3vector(0.5,0.5,0.5)*H;
00553 }
00554 e = corner(num);
00555 if(edge_point(num)) {
00556 d = edge_dir(num);
00557 if(d < Sdir)
00558 return D3vector((e&1)*H + h[num] *(2*d-1),
00559 ((e>>1)&1)*H,(e>>2)*H);
00560 if(d > Ndir)
00561 return D3vector((e&1)*H,((e>>1)&1)*H,
00562 (e>>2)*H + h[num] * (2*d-9));
00563 return D3vector((e&1)*H,
00564 ((e>>1)&1)*H + h[num] * (2*d-5),(e>>2)*H);
00565 }
00566 else {
00567 return D3vector((e&1)*H,((e>>1)&1)*H,(e>>2)*H);
00568 }
00569 }
00570
00571
00572
00573 inline bool BoCeData::Edge(Edges_cell ed) {
00574 return (bool)((edge>>ed)&1);
00575 }
00576
00577 inline void BoCeData::Put_edge_info(int ed) { edge=ed; };
00578
00579 inline double BoCeData::Meshsize() {
00580 return H;
00581 }
00582
00583 inline void BoCeData::Put_Meshsize(double h) {
00584 H=h;
00585 }
00586
00587
00588
00589 inline int BoCeData::Give_number_points() const {
00590 return number_points;
00591 };
00592
00593
00594 inline dir_sons BoCeData::corner(int num) const {
00595 if(developer_version) {
00596 if(num<0 || num >= number_points) {
00597 cout << " \n Fehler in BoCeData::corner " << endl;
00598 return WSDd;
00599 }
00600 }
00601 return (dir_sons)(info[num]&7);
00602 };
00603
00604 inline Cell_type_points BoCeData::edge_point(int num) const {
00605 if(developer_version) {
00606 if(num<0 || num > number_points) {
00607 cout << " \n Fehler in BoCeData::edge_point " << endl;
00608 return corner_poi_typ;
00609 }
00610 }
00611 if( num == number_points) return cell_poi_typ;
00612 else return (Cell_type_points)((info[num]>>3)&1);
00613 };
00614
00615
00616 inline dir_3D BoCeData::edge_dir(int num) {
00617 if(developer_version) {
00618 if(num<0 || num >= number_points) {
00619 cout << " \n Fehler in BoCeData::edge_dir " << endl;
00620 return Wdir;
00621 }
00622 }
00623 return (dir_3D)((info[num]>>4)&7);
00624 }
00625
00626
00627 inline bool BoCeData::boundary_EW(int num) {
00628 if(developer_version) {
00629 if(num<0 || num >= number_points) {
00630 cout << " \n Fehler in BoCeData::boundary_EW " << endl;
00631 return false;
00632 }
00633 }
00634 return (bool)((info[num]>>7)&1);
00635 };
00636
00637
00638 inline bool BoCeData::boundary_NS(int num) {
00639 if(developer_version) {
00640 if(num<0 || num >= number_points) {
00641 cout << " \n Fehler in BoCeData::boundary_NS " << endl;
00642 return false;
00643 }
00644 }
00645 return (bool)((info[num]>>8)&1);
00646 };
00647
00648
00649 inline bool BoCeData::boundary_TD(int num) {
00650 if(developer_version) {
00651 if(num<0 || num >= number_points) {
00652 cout << " \n Fehler in BoCeData::boundary_TD " << endl;
00653 return false;
00654 }
00655 }
00656 return (bool)((info[num]>>9)&1);
00657 };
00658
00659
00660 inline void BoCeData::Put_corner_point(int num, dir_sons c) {
00661 if(developer_version) {
00662 if(num<0 || num >= number_points) {
00663 cout << " \n Fehler in BoCeData::Put_corner " << endl;
00664 return;
00665 }
00666 }
00667 info[num] = c;
00668 }
00669
00670 inline void BoCeData::Put_edge_point(int num,dir_sons c, dir_3D d) {
00671 if(developer_version) {
00672 if(num<0 || num >= number_points) {
00673 cout << " \n Fehler in BoCeData::Put_edge_point " << endl;
00674 return;
00675 }
00676 }
00677 info[num] = c;
00678 info[num] = info[num] | (1<<3);
00679 info[num] = (info[num] & (~(7<<4))) | (d<<4);
00680 }
00681
00682 inline void BoCeData::Allocate(int n_points) {
00683 static int i;
00684 number_points = n_points;
00685 info = new int[number_points];
00686 for(i=0;i<number_points;i++) info[i]=0;
00687 Tets = NULL;
00688 }
00689
00690 inline void BoCeData::Set_variable_pointer(int num, double* poi) {
00691 vars[num]=poi;
00692 };
00694
00695 inline Tetraeder_storage::Tetraeder_storage(Bo_description* desc,
00696 int P0, int P1, int P2, int P3,
00697 Tetraeder_storage* Next) {
00698 next = Next; num0 = P0; num1 = P1; num2 = P2; num3 = P3;
00699 var= NULL;
00700
00701 if(developer_version) {
00702 Check_angles(desc);
00703 }
00704 };
00705
00706 inline bool Tetraeder_storage::Check_angles(Bo_description* desc) {
00707 bool oh_key;
00708
00709 oh_key = true;
00710
00711 Edge_Corner_point ec0;
00712 Edge_Corner_point ec1;
00713 Edge_Corner_point ec2;
00714 Edge_Corner_point ec3;
00715
00716 ec0.edge_point=desc->Give_bocedata()->edge_point(num0);
00717 if(ec0.edge_point!=cell_poi_typ)
00718 ec0.corner =desc->Give_bocedata()->corner(num0);
00719 if(ec0.edge_point==edge_poi_typ)
00720 ec0.d = desc->Give_bocedata()->edge_dir(num0);
00721
00722
00723 ec1.edge_point=desc->Give_bocedata()->edge_point(num1);
00724 if(ec1.edge_point!=cell_poi_typ)
00725 ec1.corner =desc->Give_bocedata()->corner(num1);
00726 if(ec1.edge_point==edge_poi_typ)
00727 ec1.d = desc->Give_bocedata()->edge_dir(num1);
00728
00729
00730 ec2.edge_point=desc->Give_bocedata()->edge_point(num2);
00731 if(ec2.edge_point!=cell_poi_typ)
00732 ec2.corner =desc->Give_bocedata()->corner(num2);
00733 if(ec2.edge_point==edge_poi_typ)
00734 ec2.d = desc->Give_bocedata()->edge_dir(num2);
00735
00736 ec3.edge_point=desc->Give_bocedata()->edge_point(num3);
00737 if(ec3.edge_point!=cell_poi_typ)
00738 ec3.corner =desc->Give_bocedata()->corner(num3);
00739 if(ec3.edge_point==edge_poi_typ)
00740 ec3.d = desc->Give_bocedata()->edge_dir(num3);
00741
00742
00743 double max_face_ang;
00744 double max_edge_ang;
00745 max_face_ang = calc_maximal_face_angle(desc->coord(ec0),
00746 desc->coord(ec1),
00747 desc->coord(ec2),
00748 desc->coord(ec3));
00749 if(max_face_ang > 163) {
00750 cout << "\n Error: Too large interior angle!" <<
00751 " Tell Christoph Pflaum this error! ";
00752 cout << "\n Maximal interior face angle: " << max_face_ang << endl;
00753 desc->coord(ec0).Print(); cout << endl;
00754 desc->coord(ec1).Print(); cout << endl;
00755 desc->coord(ec2).Print(); cout << endl;
00756 desc->coord(ec3).Print(); cout << endl;
00757 oh_key = false;
00758 }
00759 max_edge_ang = calc_maximal_edge_angle(desc->coord(ec0),
00760 desc->coord(ec1),
00761 desc->coord(ec2),
00762 desc->coord(ec3));
00763 if(max_edge_ang > 144) {
00764 cout << "\n Error: Too large interior angle!" <<
00765 " Tell Christoph Pflaum this error! ";
00766 cout << "\n Maximal interior edge angle: " << max_edge_ang << endl;
00767 desc->coord(ec0).Print(); cout << endl;
00768 desc->coord(ec1).Print(); cout << endl;
00769 desc->coord(ec2).Print(); cout << endl;
00770 desc->coord(ec3).Print(); cout << endl;
00771 oh_key = false;
00772 }
00773 return oh_key;
00774 };
00775
00776
00777
00778
00779 inline int BoCeData::Give_total_number_points() const {
00780 if(Exists_bocellpoint()) return number_points+1;
00781 else return number_points;
00782 }
00783
00784 inline bool BoCeData::Is_point_clipped_point(int num) const {
00785 if(num<number_points) return true;
00786 return false;
00787 }
00788
00789 #endif