ParMooN
 All Classes Functions Variables Friends Pages
cancer_exp_3d_nd.h
1 // #define __UREA__
2 // #define __SIMPATURS__
3 //
4 // #include <Urea_3d4d.h>
5 // #include <MacroCell.h>
6 
7 void ExampleFile()
8 {
9 
10  OutPut("Example: cancer_exp_3d.h" << endl); //OutPut("GRID_TYPE set to " << TDatabase::ParamDB->GRID_TYPE << endl);
11 }
12 
13 // ========================================================================
14 // definitions for the temperature
15 // ========================================================================
16 
17 void Exact(double x, double y, double z, double *values)
18 {
19 
20  values[0] = 0;
21 }
22 
23 void V_Exact(double x, double y, double z, double *values)
24 {
25  values[0] = 0;
26 }
27 
28 void W_Exact(double x, double y, double z, double *values)
29 {
30  values[0] = 0;
31 }
32 
33 // =================initial conditon=============================================================================
34 void InitialCondition(double x, double y, double z, double *values)
35 {
36 //===============cube=============================================================================================
37 // double temp;
38 // temp = ((x-0.5)*(x-0.5)+(y-0.5)*(y-0.5)+(z-0.5)*(z-0.5));
39 //
40 // if (temp >0.1)
41 // { values[0] = 0.; }
42 // else
43 // { values[0] = exp(-temp/0.01);}
44 
45 //===============cube-1D-Test Case==================================================================================
46 // double temp;
47 // temp = ((x)*(x)+(y)*(y)+(z)*(z));
48 //
49 // if (temp >0.25)
50 // { values[0] = 0.; }
51 // else
52 // { values[0] = exp(-temp/0.01);}
53 
54 
55 //==============Breast Geometry=====================================================================================
56  //values[0] = exp(-((x-286.530470)*(x-286.530470)+(y-34.297560)*(y-34.297560)+(z-162.509553)*(z-162.509553))/20);
57  /* values[0] = exp(-((x-239)*(x-239)+(y-24)*(y-24)+(z-167)*(z-167))/20); */
58 
59  values[0] = exp(-((x-240)*(x-240)+(y-50)*(y-50)+(z-147)*(z-147))/20);
60 
61 // values[0] = exp(-((x-225)*(x-225)+(y-5)*(y-5)+(z-150)*(z-150))/100); //near boundary
62 // values[0] = exp(-((x-230)*(x-230)+(y+30)*(y+30)+(z-177)*(z-177))/100); //on boundary
63 
64 
65 //==============Breast Geometry - breast2.mesh========================================================================
66 // values[0] = exp(-((x-264.792889)*(x-264.792889)+(y-144.038695)*(y-144.038695)+(z+10.472588)*(z+10.472588))/100);
67 
68 }
69 
70 void V_InitialCondition(double x, double y, double z, double *values)
71 {
72 //===============cube====================================================================================================
73 // double temp;
74 // temp = ((x-0.5)*(x-0.5)+(y-0.5)*(y-0.5)+(z-0.5)*(z-0.5));
75 //
76 // if (temp >0.1)
77 // { values[0] = 1.; }
78 // else
79 // { values[0] = 1- 0.5 * exp(-temp/0.01);}
80 
81 //===============cube-1D-Test Case=========================================================================================
82 // double temp;
83 // temp = ((x)*(x)+(y)*(y)+(z)*(z));
84 //
85 // if (temp >0.25)
86 // { values[0] = 1.; }
87 // else
88 // { values[0] = 1- 0.5 * exp(-temp/0.01);}
89 
90 //==============Breast Geometry=============================================================================================
91  // values[0] = 1 - exp(-((x-286.530470)*(x-286.530470)+(y-34.297560)*(y-34.297560)+(z-162.509553)*(z-162.509553))/20);
92  // values[0] = 1- exp(-((x-239)*(x-239)+(y-24)*(y-24)+(z-167)*(z-167))/20);
93 
94 
95  values[0] = 1 - 0.5 * exp(-((x-240)*(x-240)+(y-50)*(y-50)+(z-147)*(z-147))/20);
96 
97 //==============Breast Geometry - breast2.mesh===============================================================================
98 // values[0] = 1- 0.5* exp(-((x-264.792889)*(x-264.792889)+(y-144.038695)*(y-144.038695)+(z+10.472588)*(z+10.472588))/100);
99 // values[0] = 1- 0.5 * exp(-((x-268)*(x-268)+(y-165)*(y-165)+(z+10.)*(z+10.))/20);
100 
101 }
102 
103 void W_InitialCondition(double x, double y, double z, double *values)
104 {
105 //===============cube========================================================================================================
106 // double temp;
107 // temp = ((x-0.5)*(x-0.5)+(y-0.5)*(y-0.5)+(z-0.5)*(z-0.5));
108 //
109 // if (temp >0.1)
110 // { values[0] = 0.; }
111 // else
112 // { values[0] = 0.5 * exp(-temp/0.01);}
113 
114 //===============cube-1D-Test Case=============================================================================================
115 // double temp;
116 // temp = ((x)*(x)+(y)*(y)+(z)*(z));
117 //
118 // if (temp >0.25)
119 // { values[0] = 0.; }
120 // else
121 // { values[0] = 0.5 * exp(-temp/0.01);}
122 
123 
124 //==============Breast Geometry=================================================================================================
125  // values[0] = 5 * exp(-((x-286.530470)*(x-286.530470)+(y-34.297560)*(y-34.297560)+(z-162.509553)*(z-162.509553))/20);
126  // values[0] = 0.5 * exp(-((x-239)*(x-239)+(y-24)*(y-24)+(z-167)*(z-167))/20);
127 
128 
129  values[0] = 0.5 * exp(-((x-240)*(x-240)+(y-50)*(y-50)+(z-147)*(z-147))/20);
130 
131 //==============Breast Geometry - breast2.mesh==================================================================================
132 // values[0] = 0.5 * exp(-((x-264.792889)*(x-264.792889)+(y-144.038695)*(y-144.038695)+(z+10.472588)*(z+10.472588))/100);
133 
134 
135 }
136 
137 
138 void BoundCondition(double x, double y, double z, BoundCond &cond)
139 {
140  cond = NEUMANN;
141 }
142 
143 void V_BoundCondition(double x, double y, double z, BoundCond &cond)
144 {
145  cond = NEUMANN;
146 }
147 
148 
149 void W_BoundCondition(double x, double y, double z, BoundCond &cond)
150 {
151  cond = NEUMANN;
152 }
153 
154 // value of boundary condition
155 void BoundValue(double x, double y, double z, double &value)
156 {
157  value = 0;
158 }
159 
160 void V_BoundValue(double x, double y, double z, double &value)
161 {
162  value = 0;
163 }
164 
165 void W_BoundValue(double x, double y, double z, double &value)
166 {
167  value = 0;
168 }
169 // ========================================================================
170 // BilinearCoeffs for Heat
171 // ========================================================================
172 void BilinearCoeffs(int n_points, double *X, double *Y, double *Z,
173  double **parameters, double **coeffs)
174 {
175  double eps= 0.0/TDatabase::ParamDB->RE_NR;
176  int i;
177  double *coeff; // *param;
178  double x, y, z, c, a[3], b[3], s[3], h;
179  double t = TDatabase::TimeDB->CURRENTTIME;
180 
181  b[0] = 0;
182  b[1] = 0;
183  b[2] = 0;
184  c = 0;
185  for(i=0;i<n_points;i++)
186  {
187  coeff = coeffs[i];
188  // param = parameters[i];
189 
190 // x = X[i];
191 // y = Y[i];
192 // z = Z[i];
193 
194  // diffusion
195  coeff[0] = eps;
196  // convection in x direction
197  coeff[1] = b[0];
198  // convection in y direction
199  coeff[2] = b[1];
200  // convection in z direction
201  coeff[3] = b[2];
202  // reaction
203  coeff[4] = c;
204  // rhs
205  coeff[5] = 0;
206 
207 
208  coeff[6] = 0;
209 
210  }
211 }
212 
213 void V_BilinearCoeffs(int n_points, double *X, double *Y, double *Z,
214  double **parameters, double **coeffs)
215 {
216  double eps= 0.0/TDatabase::ParamDB->RE_NR;
217  int i;
218  double *coeff; // *param;
219  double x, y, z, c, a[3], b[3], s[3], h;
220  double t = TDatabase::TimeDB->CURRENTTIME;
221  b[0] = 0;
222  b[1] = 0;
223  b[2] = 0;
224  c = 0;
225  for(i=0;i<n_points;i++)
226  {
227  coeff = coeffs[i];
228  // param = parameters[i];
229 
230 // x = X[i];
231 // y = Y[i];
232 // z = Z[i];
233 
234  // diffusion
235  coeff[0] = eps;
236  // convection in x direction
237  coeff[1] = b[0];
238  // convection in y direction
239  coeff[2] = b[1];
240  // convection in z direction
241  coeff[3] = b[2];
242  // reaction
243  coeff[4] = c;
244  // rhs
245  coeff[5] = 0;
246  coeff[6] = 0;
247 
248  }
249 }
250 
251 void W_BilinearCoeffs(int n_points, double *X, double *Y, double *Z,
252  double **parameters, double **coeffs)
253 {
254  double eps= 5./TDatabase::ParamDB->RE_NR;
255  int i;
256  double *coeff; // *param;
257  double x, y, z, c, a[3], b[3], s[3], h;
258  double t = TDatabase::TimeDB->CURRENTTIME;
259 
260  b[0] = 0;
261  b[1] = 0;
262  b[2] = 0;
263  c = 0;
264 
265  for(i=0;i<n_points;i++)
266  {
267  coeff = coeffs[i];
268  // param = parameters[i];
269 
270 // x = X[i];
271 // y = Y[i];
272 // z = Z[i];
273 
274  // diffusion
275  coeff[0] = eps;
276  // convection in x direction
277  coeff[1] = b[0];
278  // convection in y direction
279  coeff[2] = b[1];
280  // convection in z direction
281  coeff[3] = b[2];
282  // reaction
283  coeff[4] = c;
284  // rhs
285  coeff[5] = 0 ;
286  coeff[6] = 0;
287 
288  }
289 }
290 void ReadAdditionalNModes(char *NODE, tetgenio &InAddPts)
291 {
292  int i, N_Vertices, index, N_Atribude, BDMarker;
293  char line[100];
294  std::ifstream dat(NODE);
295 
296  if (!dat)
297  {
298  cerr << "cannot open '" << NODE << "' for input" << endl;
299  exit(-1);
300  }
301 
302  dat.getline (line, 99); // first line is command line
303  dat >> N_Vertices >> N_Atribude >> BDMarker;
304  dat.getline (line, 99);
305 
306  InAddPts.numberofpoints = N_Vertices;
307  InAddPts.pointlist = new double[3*N_Vertices];
308 
309  //read from file
310  for(i=0;i<N_Vertices; i++)
311  {
312  dat.getline (line, 99);
313  dat >> index >> InAddPts.pointlist[3*i] >> InAddPts.pointlist[3*i+1] >> InAddPts.pointlist[3*i+2];
314  cout<< i << " vert X: " <<InAddPts.pointlist[3*i] << " vert Y: " <<InAddPts.pointlist[3*i+1] <<" vert Z: " <<InAddPts.pointlist[3*i+2] <<endl;
315 
316  }
317 
318  dat.close();
319 
320 // cout << "N_Vertices " <<N_Vertices <<endl;
321 //
322 // exit(0);
323 
324 } // ReadAdditionalNModes
325 
326 
327 
328 void ReadMeditMeshWithCells(char *SMESH, tetgenio &In)
329 {
330  int i, j, k, dimension, N_FVert, N_Faces, N_Vertices, N_CVert, N_Cells;
331  int BDComp_Min=10000000;
332  int *plist;
333 
334  double x;
335 
336  char line[100];
337  tetgenio::facet *F;
338  tetgenio::polygon *P;
339 
340  std::ifstream dat(SMESH);
341 
342  if (!dat)
343  {
344  cerr << "cannot open '" << SMESH << "' for input" << endl;
345  exit(-1);
346  }
347 
348  // check the dimension
349  while (!dat.eof())
350  {
351  dat >> line;
352 
353  if ( (!strcmp(line, "Dimension")) || (!strcmp(line, "dimension")) || (!strcmp(line, "DIMENSION")))
354  {
355  dat.getline (line, 99);
356  dat >> dimension;
357  break;
358  }
359  // read until end of line
360  dat.getline (line, 99);
361  }
362 
363  if(dimension!=3)
364  {
365  cerr << "dimension: " << dimension << endl;
366  exit(-1);
367  }
368 
369  // find the N_Vertices
370  while (!dat.eof())
371  {
372  dat >> line;
373 
374  if ( (!strcmp(line, "Vertices")) || (!strcmp(line, "vertices")) || (!strcmp(line, "VERTICES")) )
375  {
376  dat.getline (line, 99);
377  dat >> N_Vertices;
378  break;
379  }
380  // read until end of line
381  dat.getline (line, 99);
382  }
383 
384  In.numberofpoints = N_Vertices;
385  In.pointlist = new double[3*N_Vertices];
386 
387  //read from file
388  for(i=0;i<N_Vertices; i++)
389  {
390  dat.getline (line, 99);
391  dat >> x >> In.pointlist[3*i+1] >> In.pointlist[3*i+2];
392 
393  In.pointlist[3*i] = x - 3.606596999999999830777142; //center point
394 
395 // if(i==1063 || i==1061 || i==1062 || i==162 || i==1175 || i==517 || i==1064 || i==518 ) // i==1063 as center
396  if(i==1062 || i==916 || i==341 || i==914 || i==162 || i==1063 || i==1061) // i==1062 as center
397  cout<< i << " vert X: " <<In.pointlist[3*i] << " vert Y: " <<In.pointlist[3*i+1] <<" vert Z: " <<In.pointlist[3*i+2] <<endl;
398  }
399 
400  // find the N_Triangles
401  // find the N_Vertices
402  while (!dat.eof())
403  {
404  dat >> line;
405 
406  if ( (!strcmp(line, "Triangles")) || (!strcmp(line, "triangles")) || (!strcmp(line, "TRIANGLES")) )
407  {
408  N_FVert = 3;
409  dat.getline (line, 99);
410  dat >> N_Faces;
411  break;
412  }
413  else if ( (!strcmp(line, "Quadrilaterals")) || (!strcmp(line, "quadrilaterals")) || (!strcmp(line, "QUADRILATERALS")) )
414  {
415  N_FVert = 4;
416  dat.getline (line, 99);
417  dat >> N_Faces;
418  break;
419  }
420 
421  // read until end of line
422  dat.getline (line, 99);
423  }
424 
425  In.numberoffacets = N_Faces;
426  In.facetlist = new tetgenio::facet[In.numberoffacets];
427  In.facetmarkerlist = new int[In.numberoffacets];
428 
429  for(i=0;i<N_Faces; i++)
430  {
431  dat.getline (line, 99);
432 
433  F = &In.facetlist[i];
434  tetgenio::init(F);
435  F->numberofpolygons = 1;
436  F->polygonlist = new tetgenio::polygon[F->numberofpolygons];
437  F->numberofholes = 0;
438  F->holelist = NULL;
439  P = &F->polygonlist[0];
440  tetgenio::init(P);
441  P->numberofvertices = N_FVert;
442  P->vertexlist = new int[P->numberofvertices];
443 
444  for(j=0;j<N_FVert;j++)
445  {
446  dat >> k;
447  P->vertexlist[j] = k-1; // c numbering
448  }
449 
450  dat >> In.facetmarkerlist[i];
451 
452  if(BDComp_Min > In.facetmarkerlist[i])
453  BDComp_Min=In.facetmarkerlist[i];
454 
455  // cout << i<< " P->vertexlist[j]: " << In.facetmarkerlist[i] << endl;
456  } // for(i=0;i<N_Faces; i++)
457 
458  BDComp_Min--;
459 
460  for(i=0;i<N_Faces; i++)
461  In.facetmarkerlist[i] -= BDComp_Min;
462 
463 
465  while (!dat.eof())
466  {
467  dat >> line;
468 
469  if ( (!strcmp(line, "Tetrahedron")) || (!strcmp(line, "tetrahedron")) || (!strcmp(line, "TETRAHEDRON")) )
470  {
471  N_CVert = 4;
472  dat.getline (line, 99);
473  dat >> N_Cells;
474  break;
475  }
476  // read until end of line
477  dat.getline (line, 99);
478  }
479 
480  In.numberoftetrahedra = N_Cells;
481  In.numberofcorners = N_CVert;
482  In.numberoftetrahedronattributes = 1;
483  In.tetrahedronlist = new int[N_Cells * 4];
484  In.tetrahedronattributelist = new REAL[N_Cells];
485  In.tetrahedronvolumelist = new REAL[N_Cells];
486 
487  for(i=0; i<N_Cells; i++)
488  {
489  dat.getline (line, 99);
490  plist = &(In.tetrahedronlist[i * 4]);
491 
492  for(j=0;j<N_CVert;j++)
493  {
494  dat >> k;
495  plist[j] = k -1;
496  }// for(j=0;j<N_CV
497 
498 
499  dat >> In.tetrahedronattributelist[i];
500 // In.tetrahedronvolumelist [i] = 100.;
501  } // for(i=0; i<N_
502 
503 
504 
505 // cout << i<< " N_Cells : " << N_Cells << endl;
506 // exit(0);
507 
508  dat.close();
509 // exit(0);
510 } // ReadMeditMeshWithCells
511 
512 
513 void ReadMeditMesh(char *SMESH, tetgenio &In)
514 {
515  int i, j, k, dimension, N_FVert, N_Faces, N_Vertices;
516  int BDComp_Min=10000000;
517 
518  char line[100];
519  tetgenio::facet *F;
520  tetgenio::polygon *P;
521 
522  std::ifstream dat(SMESH);
523 
524  if (!dat)
525  {
526  cerr << "cannot open '" << SMESH << "' for input" << endl;
527  exit(-1);
528  }
529 
530  // check the dimension
531  while (!dat.eof())
532  {
533  dat >> line;
534 
535  if ( (!strcmp(line, "Dimension")) || (!strcmp(line, "dimension")) || (!strcmp(line, "DIMENSION")))
536  {
537  dat.getline (line, 99);
538  dat >> dimension;
539  break;
540  }
541  // read until end of line
542  dat.getline (line, 99);
543  }
544 
545  if(dimension!=3)
546  {
547  cerr << "dimension: " << dimension << endl;
548  exit(-1);
549  }
550 
551  // find the N_Vertices
552  while (!dat.eof())
553  {
554  dat >> line;
555 
556  if ( (!strcmp(line, "Vertices")) || (!strcmp(line, "vertices")) || (!strcmp(line, "VERTICES")) )
557  {
558  dat.getline (line, 99);
559  dat >> N_Vertices;
560  break;
561  }
562  // read until end of line
563  dat.getline (line, 99);
564  }
565 
566  In.numberofpoints = N_Vertices;
567  In.pointlist = new double[3*N_Vertices];
568 
569  //read from file
570  for(i=0;i<N_Vertices; i++)
571  {
572  dat.getline (line, 99);
573  dat >> In.pointlist[3*i] >> In.pointlist[3*i+1] >> In.pointlist[3*i+2];
574  //cout<< i << " vert X: " <<In.pointlist[3*i] << " vert Y: " <<In.pointlist[3*i+1] <<endl;
575  }
576 
577  // find the N_Triangles
578  // find the N_Vertices
579  while (!dat.eof())
580  {
581  dat >> line;
582 
583  if ( (!strcmp(line, "Triangles")) || (!strcmp(line, "triangles")) || (!strcmp(line, "TRIANGLES")) )
584  {
585  N_FVert = 3;
586  dat.getline (line, 99);
587  dat >> N_Faces;
588  break;
589  }
590  else if ( (!strcmp(line, "Quadrilaterals")) || (!strcmp(line, "quadrilaterals")) || (!strcmp(line, "QUADRILATERALS")) )
591  {
592  N_FVert = 4;
593  dat.getline (line, 99);
594  dat >> N_Faces;
595  break;
596  }
597 
598  // read until end of line
599  dat.getline (line, 99);
600  }
601 
602  In.numberoffacets = N_Faces;
603  In.facetlist = new tetgenio::facet[In.numberoffacets];
604  In.facetmarkerlist = new int[In.numberoffacets];
605 
606  for(i=0;i<N_Faces; i++)
607  {
608  dat.getline (line, 99);
609 
610  F = &In.facetlist[i];
611  tetgenio::init(F);
612  F->numberofpolygons = 1;
613  F->polygonlist = new tetgenio::polygon[F->numberofpolygons];
614  F->numberofholes = 0;
615  F->holelist = NULL;
616  P = &F->polygonlist[0];
617  tetgenio::init(P);
618  P->numberofvertices = N_FVert;
619  P->vertexlist = new int[P->numberofvertices];
620 
621  for(j=0;j<N_FVert;j++)
622  {
623  dat >> k;
624  P->vertexlist[j] = k-1; // c numbering
625  }
626 
627  dat >> In.facetmarkerlist[i];
628 
629  if(BDComp_Min > In.facetmarkerlist[i])
630  BDComp_Min=In.facetmarkerlist[i];
631 
632  // cout << i<< " P->vertexlist[j]: " << In.facetmarkerlist[i] << endl;
633  } // for(i=0;i<N_Faces; i++)
634 
635  BDComp_Min--;
636 
637  for(i=0;i<N_Faces; i++)
638  In.facetmarkerlist[i] -= BDComp_Min;
639 
640 // cout << i<< " P->vertexlist[j]: " << BDComp_Min << endl;
641 
642 
643  dat.close();
644 // exit(0);
645 } // ReadMeditMesh
646 
647 
648 void DeleteDomain(TDomain *&Domain)
649 {
650  int i, j, k, N_Cells, N_RootCells;
651  int CurrVertex, N_Faces, N_Vertices, ID;
652 
653  TBaseCell **CellTree, **SurfCellTree, *cell;
654  TGridCell **DelCell;
655  TVertex **VertexDel;
656  TCollection *coll;
657 
658 
659  Domain->GetTreeInfo(CellTree,N_RootCells);
660  coll = Domain->GetCollection(It_Finest, 0);
661  N_Cells = coll->GetN_Cells();
662 
663 
664  // cout<<"N_RootCells: "<<N_RootCells<<endl;
665  // remove all existing vertices and joints
666  VertexDel = new TVertex*[8*N_RootCells];
667  CurrVertex = 0;
668 
669  for(i=0;i<N_Cells;i++)
670  {
671  cell = coll->GetCell(i);
672  N_Faces = cell->GetN_Faces();
673  N_Vertices = cell->GetN_Vertices();
674  for(j=0;j<N_Faces;j++)
675  {
676  if(CurrVertex==0)
677  {
678  VertexDel[CurrVertex++] = cell->GetVertex(j);
679  }
680  else
681  {
682  ID = 0;
683  for(k=0;k<CurrVertex;k++)
684  if(VertexDel[k]==cell->GetVertex(j))
685  {
686  ID = 1; break;
687  }
688  if(ID!=1)
689  {
690  VertexDel[CurrVertex++] = cell->GetVertex(j);
691  }
692  } // else if(CurrVertex==0)
693 
694  ID = 0;
695  for(k=0;k<CurrVertex;k++)
696  if(VertexDel[k]==cell->GetVertex((j+1)%N_Vertices))
697  {
698  ID = 1; break;
699  }
700  if(ID!=1)
701  {
702  VertexDel[CurrVertex++] = cell->GetVertex((j+1)%N_Vertices);
703  }
704 
705  ID = 0;
706  for(k=0;k<CurrVertex;k++)
707  if(VertexDel[k]==cell->GetVertex((j+2)%N_Vertices))
708  {
709  ID = 1; break;
710  }
711  if(ID!=1)
712  {
713  VertexDel[CurrVertex++] = cell->GetVertex((j+2)%N_Vertices);
714  }
715  if(N_Faces==6) // If old cell is hexahedrol
716  {
717  ID = 0;
718  for(k=0;k<CurrVertex;k++)
719  if(VertexDel[k]==cell->GetVertex((j+4)%N_Vertices))
720  {
721  ID = 1; break;
722  }
723  if(ID!=1)
724  {
725  VertexDel[CurrVertex++] = cell->GetVertex((j+4)%N_Vertices);
726  }
727  }
728  } // for j
729  } // for i
730 
731  for(i=0;i<CurrVertex;i++)
732  delete VertexDel[i];
733  delete [] VertexDel;
734  OutPut(CurrVertex<<" vertices were deleted"<<endl);
735 
736  // remove all existing cells and joints
737 
738  for(i=0;i<N_RootCells;i++)
739  delete (TGridCell*)CellTree[i];
740  delete [] CellTree;
741  OutPut(N_RootCells<<" cells were deleted"<<endl);
742 
743 
744 /*
745  cout << "DeleteDomain" <<endl;
746  exit(0);
747  */
748 }
749 
750 
751 void TetrameshCreate(TDomain *&Domain)
752 {
753  int i, j, k, l, dimension, N_Vertices;
754  int N_FVert, N_Faces, *Facemarkerlist, *Facelist, N_RootCells;
755  int v1, v2, v3, v4, CellMarker, RefLevel=0, *Tetrahedrals, *PointNeighb, maxEpV, *Tetrahedrals_loc;
756  int a, b, c, Neib[2], Neighb_tmp, CurrNeib, len1, len2, len3, CurrComp, N_Points ;
757  int N_Cells, MaxLen, jj, N_SourcePts;
758  const int *EdgeVertex, *TmpFV, *TmpLen;
759 
760  double X, Y, Z, DispX, DispY, DispZ;
761  double Xmin = 1e10, Xmax = -1e10, Ymin = 1e10, Ymax = -1e10;
762  double Zmin = 1e10, Zmax = -1e10, T[4]={0,0,0,0}, S[4]={0,0,0,0};
763  double StartX, StartY, StartZ, BoundX, BoundY, BoundZ;
764 
765  char *MESH, line[100];
766  MESH = TDatabase::ParamDB->SMESHFILE;
767 
768  TVertex **NewVertices;
769  TBaseCell **CellTree, *cell;
770  TJoint *Joint;
771  TBoundComp3D *bdcomp;
772  TShapeDesc *ShapeDesc;
773  TCollection *coll;
774 
775 #ifdef _MPI
776  int rank, size;
777  MPI_Comm Comm = TDatabase::ParamDB->Comm;
778 
779  MPI_Comm_rank(Comm, &rank);
780  MPI_Comm_size(Comm, &size);
781 
782 #endif
783 
785  DeleteDomain(Domain);
786 
787  // cout << " SMESHFILE is " << SMESH << endl;
789  std::ifstream dat(MESH);
790 
791  if (!dat)
792  {
793  cerr << "cannot open '" << MESH << "' for input" << endl;
794  exit(-1);
795  }
796 
797 
798  // check the dimension
799  while (!dat.eof())
800  {
801  dat >> line;
802 
803  if ( (!strcmp(line, "Dimension")) || (!strcmp(line, "dimension")) || (!strcmp(line, "DIMENSION")))
804  {
805  dat.getline (line, 99);
806  dat >> dimension;
807  break;
808  }
809  // read until end of line
810  dat.getline (line, 99);
811  }
812 
813  if(dimension!=3)
814  {
815  cerr << "dimension: " << dimension << endl;
816  exit(-1);
817  }
818 
819  // find the N_Vertices
820  while (!dat.eof())
821  {
822  dat >> line;
823 
824  if ( (!strcmp(line, "Vertices")) || (!strcmp(line, "vertices")) || (!strcmp(line, "VERTICES")) )
825  {
826  dat.getline (line, 99);
827  dat >> N_Vertices;
828  break;
829  }
830  // read until end of line
831  dat.getline (line, 99);
832  }
833 
834  // generate new vertices
835  NewVertices = new TVertex*[N_Vertices];
836 
837  //read from file
838  for(i=0;i<N_Vertices; i++)
839  {
840  dat.getline (line, 99);
841  dat >> X >> Y >> Z;
842 
843  if(TDatabase::ParamDB->P13==0)
844  { //Lside
845  //center point is (291.977 -1.8733333333333333 159.89 ) //old, wrong
846  // 2.922130000000000e+02 -1.8733333333333333e+00 1.583800000000000e+02 1
847  DispX = 0.;
848  DispY = -1.8733333333333333;
849  DispZ = 0.;
850 
851 
852  }
853  else // default
854  {
855  //Front side
856  //center point is side 300.565, 69.66666666666666, 157.038
857  DispX = 0.;
858  DispY = 69.66666666666666;
859  DispZ = 0.;
860  }
861 // if( sqrt((X -2.922130000000000e+02)*(X -291.977) + (Y+1.8733333333333333)*(Y+-1.8733333333333333) + (Z-1.583800000000000e+02)*(Z-1.583800000000000e+02) ) < 1.e-5)
862 // cout<< i << " vert X: " <<X << " vert Y: " <<Y <<" vert Z: " <<Z <<endl;
863 // 98 vert X: 292.213 vert Y: -1.87333 vert Z: 158.38
864 
865 
866 
867  NewVertices[i] = new TVertex( (X - DispX), (Y - DispY), (Z- DispZ));
868 
869 // // Pt source is at (291.977 -1.87333 159.89 )
870 // if(i==98 || i==123 || i==122 )
871 // cout<< i << " vert X: " <<X << " vert Y: " <<Y <<" vert Z: " <<Z <<endl;
872 //
873 
874  // set bounding box
875  if (X > Xmax) Xmax = X;
876  if (X < Xmin) Xmin = X;
877  if (Y > Ymax) Ymax = Y;
878  if (Y < Ymin) Ymin = Y;
879  if (Z > Zmax) Zmax = Z;
880  if (Z < Zmin) Zmin = Z;
881 
882  //cout<< i << " vert X: " <<X << " vert Y: " <<Y <<" vert Z: " <<Z <<endl;
883  } // for(i=0;i<N_Vertices; i++)
884 
885 // exit(0);
886 
887 
888  // set bounding box
889  StartX = Xmin;
890  StartY = Ymin;
891  StartZ = Zmin;
892  BoundX = Xmax - Xmin;
893  BoundY = Ymax - Ymin;
894  BoundZ = Zmax - Zmin;
895 
896 
897  Domain->SetBoundBox(StartX, StartY, StartZ, BoundX, BoundY, BoundZ);
898 // cout<<Xmin <<" "<<Ymin <<" "<<Zmin<<endl;
899 // cout<<Xmax <<" "<<Ymax <<" "<<Zmax<<endl;
900 
901 // cout<<" N_Vertices "<<N_Vertices <<endl;
902 
903 
904 
905 
906  // find the N_RootCells
907  while (!dat.eof())
908  {
909  dat >> line;
910 
911  if ( (!strcmp(line, "Tetrahedron")) || (!strcmp(line, "tetrahedron")) || (!strcmp(line, "TETRAHEDRON")) )
912  {
913  dat.getline (line, 99);
914  dat >> N_RootCells;
915  break;
916  }
917  // read until end of line
918  dat.getline (line, 99);
919  }
920 
921  // generate new cells
922  CellTree = new TBaseCell*[N_RootCells];
923  Tetrahedrals = new int[4*N_RootCells];
924 
925  for (i=0;i<N_RootCells;i++)
926  {
927  dat.getline (line, 99);
928  dat >> v1 >> v2 >> v3 >> v4 >> CellMarker;
929  Tetrahedrals[4*i ] = v1 -1;
930  Tetrahedrals[4*i + 1] = v2 -1;
931  Tetrahedrals[4*i + 2] = v3 -1;
932  Tetrahedrals[4*i + 3] = v4 -1;
933 
934 
935  CellTree[i] = new TMacroCell(TDatabase::RefDescDB[Tetrahedron], RefLevel);
936  CellTree[i]->SetRegionID(CellMarker);
937  CellTree[i]->SetAsLayerCell(1);
938 
939  CellTree[i]->SetVertex(0, NewVertices[Tetrahedrals[4*i ]]);
940  CellTree[i]->SetVertex(1, NewVertices[Tetrahedrals[4*i + 1]]);
941  CellTree[i]->SetVertex(2, NewVertices[Tetrahedrals[4*i + 2]]);
942  CellTree[i]->SetVertex(3, NewVertices[Tetrahedrals[4*i + 3]]);
943 
944  CellTree[i]->SetClipBoard(i);
945  ((TMacroCell *) CellTree[i])->SetSubGridID(0);
946  }
947 
948  dat.close();
949 
950 
951  Domain->SetTreeInfo(CellTree, N_RootCells);
952 
953  // initialize iterators
954  TDatabase::IteratorDB[It_EQ]->SetParam(Domain);
955  TDatabase::IteratorDB[It_LE]->SetParam(Domain);
956  TDatabase::IteratorDB[It_Finest]->SetParam(Domain);
957  TDatabase::IteratorDB[It_Between]->SetParam(Domain);
958  TDatabase::IteratorDB[It_OCAF]->SetParam(Domain);
959 
960  // search neighbours
961  PointNeighb = new int[N_Vertices];
962 #ifdef _MPI
963  if(rank==0)
964 #endif
965  cout<<"Numberofpoints "<<N_Vertices<<endl;
966  memset(PointNeighb, 0, N_Vertices*SizeOfInt);
967 
968  for (i=0;i<4*N_RootCells;i++)
969  PointNeighb[Tetrahedrals[i]]++;
970 
971  maxEpV = 0;
972  for (i=0;i<N_Vertices;i++)
973  if (PointNeighb[i] > maxEpV) maxEpV = PointNeighb[i];
974  delete [] PointNeighb;
975 
976 #ifdef _MPI
977  if(rank==0)
978 #endif
979  cout<<"maxEpV "<< maxEpV<<endl;
980 
981  PointNeighb = new int[++maxEpV * N_Vertices];
982 
983  memset(PointNeighb, 0, maxEpV*N_Vertices*SizeOfInt);
984 
985  // every vertex contains "maxEpV" columns
986  // for every vertex at first colomn contains the number of cells containing this vertex
987  // at further columns we set the index of corresponding cells containing this vertex
988  // cout<<"maxEpV*N_Vertices "<<maxEpV*N_Vertices<<endl;
989  for(i=0;i<4*N_RootCells;i++)
990  {
991  j = Tetrahedrals[i]*maxEpV;
992  PointNeighb[j]++;
993  //cout<<"j + PointNeighb[j] " << j <<endl;
994  PointNeighb[j + PointNeighb[j]] = i / 4;
995  }
996 
997 
999  coll=Domain->GetCollection(It_Finest, 0);
1000  N_Cells = coll->GetN_Cells();
1001 
1002  for(i=0;i<N_Cells;i++)
1003  {
1004  cell = coll->GetCell(i);
1005  ShapeDesc= cell->GetShapeDesc();
1006  ShapeDesc->GetFaceVertex(TmpFV, TmpLen, MaxLen);
1007  N_Faces = cell->GetN_Faces();
1008  Tetrahedrals_loc = Tetrahedrals+4*i;
1009 
1010 
1011  for(jj=0;jj<N_Faces;jj++)
1012  if(cell->GetJoint(jj) == NULL)
1013  {
1014  N_Points = TmpLen[jj];
1015 
1016  if(N_Points!=3)
1017  {
1018  cerr << "Only Tria faces are allowed!!! N_FVert: " << N_Points << endl;
1019  exit(-1);
1020  }
1021 
1022  //printf(" TetrameshGen Null joint \n" );
1023  a = Tetrahedrals_loc[TmpFV[jj*MaxLen]];
1024  b = Tetrahedrals_loc[TmpFV[jj*MaxLen + 1]];
1025  c = Tetrahedrals_loc[TmpFV[jj*MaxLen + 2]];
1026 
1027  //cout<<" "<< a<<" "<< b<<" "<< c<<endl;
1028 
1029  Neib[0] = -1;
1030  Neib[1] = -1;
1031  CurrNeib = 0;
1032 
1033  len1 = PointNeighb[a*maxEpV];
1034  len2 = PointNeighb[b*maxEpV];
1035  len3 = PointNeighb[c*maxEpV];
1036 
1037  // find the index of the cells containing current face with point indices a,b,c
1038  for (j=1;j<=len1;j++)
1039  {
1040  Neighb_tmp = PointNeighb[a*maxEpV + j];
1041  for (k=1;k<=len2;k++)
1042  {
1043  if(Neighb_tmp == PointNeighb[b*maxEpV + k])
1044  {
1045  for(l=1;l<=len3;l++)
1046  if(Neighb_tmp == PointNeighb[c*maxEpV + l])
1047  {
1048  Neib[CurrNeib++] = Neighb_tmp;
1049  break;
1050  }
1051  }
1052  }
1053  if (CurrNeib == 2) break;
1054  } // for (j=1;j<=len1;j++)
1055 
1056  if(CurrNeib==1)
1057  {
1058 
1059  bdcomp = Domain->GetBdPart(0)->GetBdComp(CurrComp);
1060 
1061 
1062  if(bdcomp->GetTSofXYZ(NewVertices[a]->GetX(), NewVertices[a]->GetY(),
1063  NewVertices[a]->GetY(), T[1], S[1]) ||
1064  bdcomp->GetTSofXYZ(NewVertices[b]->GetX(), NewVertices[b]->GetY(),
1065  NewVertices[b]->GetY(), T[2], S[2]) ||
1066  bdcomp->GetTSofXYZ(NewVertices[c]->GetX(), NewVertices[c]->GetY(),
1067  NewVertices[c]->GetY(), T[3], S[3]) )
1068  {
1069  cerr<<"Error: could not set parameter values"<<endl;
1070  OutPut(NewVertices[a]<<endl);
1071  OutPut(NewVertices[b]<<endl);
1072  OutPut(NewVertices[c]<<endl);
1073  exit(0);
1074  }
1075 
1076 // if (CurrNeib == 2)
1077 // {
1078 // if(bdcomp->IsFreeBoundary())
1079 // Joint = new TIsoInterfaceJoint3D(bdcomp, T, S,
1080 // CellTree[Neib[0]], CellTree[Neib[1]] );
1081 // else
1082 // Joint = new TInterfaceJoint3D(bdcomp, T, S,
1083 // CellTree[Neib[0]], CellTree[Neib[1]] );
1084 // }
1085 // else
1086 // {
1087 // if(bdcomp->IsFreeBoundary())
1088 // Joint = new TIsoBoundFace(bdcomp, T, S);
1089 // else
1090  Joint = new TBoundFace(bdcomp, T, S);
1091 // }
1092  }
1093  else
1094  {
1095  // cout<<"Inner face"<<endl;
1096  if (CurrNeib != 2)
1097  cerr << "Error !!!!!!!! not enough neighbours!" << endl;
1098 
1099  Joint = new TJointEqN(CellTree[Neib[0]], CellTree[Neib[1]]);
1100  }
1101 
1102  // First element containing the current face
1103  // find the local index for the point 'a' on the cell
1104  for (j=0;j<4;j++)
1105  if (Tetrahedrals[4*Neib[0]+j] == a) break;
1106 
1107  // find the local index for the point 'b' on the cell
1108  for (k=0;k<4;k++)
1109  if (Tetrahedrals[4*Neib[0]+k] == b) break;
1110 
1111  // find the local index for the point 'c' on the cell
1112  for (l=0;l<4;l++)
1113  if (Tetrahedrals[4*Neib[0]+l] == c) break;
1114 
1115  l = l*100 + k*10 + j;
1116 
1117  //cout<<" l "<< l <<endl;
1118 
1119  switch (l) // j will contain the local index for the current face
1120  {
1121  case 210: case 21: case 102:
1122  case 120: case 12: case 201:
1123  j = 0;
1124  break;
1125  case 310: case 31: case 103:
1126  case 130: case 13: case 301:
1127  j = 1;
1128  break;
1129  case 321: case 132: case 213:
1130  case 231: case 123: case 312:
1131  j = 2;
1132  break;
1133  case 230: case 23: case 302:
1134  case 320: case 32: case 203:
1135  j = 3;
1136  break;
1137 
1138  default:
1139  Error("Unable to set the face !!!!!!!!!!!!" << endl);
1140  exit(0);
1141  } // switch (l)
1142 
1143  CellTree[Neib[0]]->SetJoint(j, Joint);
1144 
1145  // second cell containing the current face
1146  if (Neib[1] != -1) // second element containing the current face
1147  {
1148  // find the local index for the point 'a' on the cell
1149  for (j=0;j<4;j++)
1150  if (Tetrahedrals[4*Neib[1]+j] == a) break;
1151 
1152  // find the local index for the point 'b' on the cell
1153  for (k=0;k<4;k++)
1154  if (Tetrahedrals[4*Neib[1]+k] == b) break;
1155 
1156  // find the local index for the point 'c' on the cell
1157  for (l=0;l<4;l++)
1158  if (Tetrahedrals[4*Neib[1]+l] == c) break;
1159 
1160  l = l*100 + k*10 + j;
1161 
1162  //cout<<" l "<< l <<endl;
1163 
1164  switch (l) // j will contain the local index for the current face
1165  {
1166  case 210: case 21: case 102:
1167  case 120: case 12: case 201:
1168  j = 0;
1169  break;
1170  case 310: case 31: case 103:
1171  case 130: case 13: case 301:
1172  j = 1;
1173  break;
1174  case 321: case 132: case 213:
1175  case 231: case 123: case 312:
1176  j = 2;
1177  break;
1178  case 230: case 23: case 302:
1179  case 320: case 32: case 203:
1180  j = 3;
1181  break;
1182 
1183  default:
1184  Error("Unable to set the face !!!!!!!!!!!!" << endl);
1185  exit(0);
1186  }
1187  CellTree[Neib[1]]->SetJoint(j, Joint);
1188  } // if (Neib[1] != -1)
1189 
1190 
1191  if (Joint->GetType() == InterfaceJoint3D ||
1192  Joint->GetType() == IsoInterfaceJoint3D)
1193  {
1194  ((TInterfaceJoint3D*)Joint)->SetMapType();
1195  ((TInterfaceJoint3D*)(Joint))->CheckOrientation();
1196  }
1197  else
1198  if (Joint->GetType() == JointEqN)
1199  Joint->SetMapType();
1200 
1201  } // if(cell->GetJoint(j)
1202  } // for(i=0;i<N_Cells;i++)
1203 
1204 delete [] PointNeighb;
1205 
1206 // #ifdef _MPI
1207 // if(rank==1)
1208 // printf(" TetrameshGen complete \n" );
1209 // MPI_Finalize();
1210 // #endif
1211 // exit(0);
1212 // //
1213 
1214 }
1215 
1216 
1217 void TetrameshGen(TDomain *&Domain)
1218 {
1219  //======================================================================
1220  // Tetgen for grid generation begin
1221  //======================================================================
1222  int i, j, k, l, N_Coord, *N_FVerts, N_Faces, *Facets;
1223  int N, N_RootCells, N_Cells, CurrVertex, N_Vertices, ID, N_G, RefLevel=0;
1224  int CurrNeib, len1, len2, len3, maxEpV = 0, a, b, c, Neib[2], Neighb_tmp, CurrComp;
1225  int *Tetrahedrals, *PointNeighb, dimension;
1226  int *Facelist, *Facemarkerlist;
1227 
1228  double *Coordinates, N_x, N_y, N_z;
1229  double *Vertices;
1230  double Xmin = 1e10, Xmax = -1e10, Ymin = 1e10, Ymax = -1e10;
1231  double Zmin = 1e10, Zmax = -1e10, T[4]={0,0,0,0}, S[4]={0,0,0,0};
1232  double StartX, StartY, StartZ, BoundX, BoundY, BoundZ;
1233 
1234  tetgenio In, Out;
1235 
1236  TBaseCell **CellTree, **SurfCellTree;
1237  TGridCell **DelCell;
1238  TVertex **VertexDel, **NewVertices, **NewSurfVertices;
1239  TBoundPart *BoundPart;
1240  TBdPlane **UpdateFaceParams;
1241  TJoint *Joint;
1242  TBoundComp3D *bdcomp;
1243  TCollection *coll, *SurfColl;
1244  TBaseCell *cell;
1245  TBdSphere *UpdateParam;
1246 
1247  char *SMESH, line[100];
1248  SMESH = TDatabase::ParamDB->SMESHFILE;
1249 
1250 #ifdef _MPI
1251  int rank, size;
1252  MPI_Comm Comm = TDatabase::ParamDB->Comm;
1253 
1254  MPI_Comm_rank(Comm, &rank);
1255  MPI_Comm_size(Comm, &size);
1256 
1257 #endif
1258 
1259 
1260 
1262 #ifdef _MPI
1263  if(rank==0)
1264 #endif
1265  {
1266 
1267 // In.initialize();
1268 // Out.initialize();
1269 
1270  std::ostringstream opts;
1271  opts << " ";
1272 
1273  opts.seekp(std::ios::beg);
1274  opts<<'p'; // Tetrahedralize the PLC. Switches are chosen to read a PLC (p)
1275 // opts<<'r'; // -r Reconstructs a previously generated mesh
1276 // opts<<"q"<<1.49; // quality mesh generation(q) with a specified quality bound
1277 // opts<<"a"<<0.1; // maximum volume constraint
1278 // opts<<'i'; // Inserts a list of additional points into mesh.
1279  opts<<'z'; // numbers all output items starting from zero
1280 // opts<<'d'; // Detect intersections of PLC facets.
1281  opts<<'f'; // Outputs all faces (including non-boundary)
1282  opts<<'e'; // Outputs a list of edges of the triangulation
1283 // opts<<'I'; // Suppresses mesh iteration numbers.
1284  opts<<'C'; // Checks the consistency of the final mesh.
1285 // opts<<'Q'; // Quiet: No terminal output except errors.
1286 // opts<<'g'; // Outputs mesh to .mesh file for viewing by Medit
1287  opts<<'Y'; // Suppresses boundary facets/segments splitting
1288 // opts<<'V'; //verbose mode
1289  opts<<ends;
1290 
1291 
1292 // cout << " SMESHFILE is " << SMESH << endl;
1294  ReadMeditMesh(SMESH, In);
1295 
1296 
1297 // for(i=0;i<In.numberofpoints;i++)
1298 // OutPut(i<<" (x, y, z) = "<<
1299 // In.pointlist[3*i]<<' '<<In.pointlist[3*i+1]<<' '<<In.pointlist[3*i+2]<<endl);
1300 
1301  // Calling tetrahedralize function of 3dtetgen mesh generator
1302  tetrahedralize((char*)opts.str().c_str(), &In, &Out);
1303 
1304  } // if(rank==0)
1305 
1306  exit(0);
1307  // output: coordinates of all vertices
1308 // for(i=0;i<Out.numberofpoints;i++)
1309 // OutPut(" (x, y, z) = "<< Out.pointlist[3*i]<<' '<<Out.pointlist[3*i+1]<<' '<<Out.pointlist[3*i+2]<<endl);
1310 
1311  Domain->GetTreeInfo(CellTree,N_RootCells);
1312  coll = Domain->GetCollection(It_Finest, 0);
1313  N_Cells = coll->GetN_Cells();
1314 
1315 // cout<<"N_RootCells: "<<N_RootCells<<endl;
1316  // remove all existing vertices and joints
1317  VertexDel = new TVertex*[8*N_RootCells];
1318  CurrVertex = 0;
1319 
1320  for(i=0;i<N_Cells;i++)
1321  {
1322  cell = coll->GetCell(i);
1323  N_Faces = cell->GetN_Faces();
1324  N_Vertices = cell->GetN_Vertices();
1325  for(j=0;j<N_Faces;j++)
1326  {
1327  if(CurrVertex==0)
1328  {
1329  VertexDel[CurrVertex++] = cell->GetVertex(j);
1330  }
1331  else
1332  {
1333  ID = 0;
1334  for(k=0;k<CurrVertex;k++)
1335  if(VertexDel[k]==cell->GetVertex(j))
1336  {
1337  ID = 1; break;
1338  }
1339  if(ID!=1)
1340  {
1341  VertexDel[CurrVertex++] = cell->GetVertex(j);
1342  }
1343  } // else if(CurrVertex==0)
1344 
1345  ID = 0;
1346  for(k=0;k<CurrVertex;k++)
1347  if(VertexDel[k]==cell->GetVertex((j+1)%N_Vertices))
1348  {
1349  ID = 1; break;
1350  }
1351  if(ID!=1)
1352  {
1353  VertexDel[CurrVertex++] = cell->GetVertex((j+1)%N_Vertices);
1354  }
1355 
1356  ID = 0;
1357  for(k=0;k<CurrVertex;k++)
1358  if(VertexDel[k]==cell->GetVertex((j+2)%N_Vertices))
1359  {
1360  ID = 1; break;
1361  }
1362  if(ID!=1)
1363  {
1364  VertexDel[CurrVertex++] = cell->GetVertex((j+2)%N_Vertices);
1365  }
1366  if(N_Faces==6) // If old cell is hexahedrol
1367  {
1368  ID = 0;
1369  for(k=0;k<CurrVertex;k++)
1370  if(VertexDel[k]==cell->GetVertex((j+4)%N_Vertices))
1371  {
1372  ID = 1; break;
1373  }
1374  if(ID!=1)
1375  {
1376  VertexDel[CurrVertex++] = cell->GetVertex((j+4)%N_Vertices);
1377  }
1378  }
1379  } // for j
1380  } // for i
1381 
1382  for(i=0;i<CurrVertex;i++)
1383  delete VertexDel[i];
1384  delete [] VertexDel;
1385  OutPut(CurrVertex<<" vertices were deleted"<<endl);
1386 
1387  // remove all existing cells and joints
1388 
1389  for(i=0;i<N_RootCells;i++)
1390  delete (TGridCell*)CellTree[i];
1391  delete [] CellTree;
1392  OutPut(N_RootCells<<" cells were deleted"<<endl);
1393 
1394 
1395 #ifdef _MPI
1396  if(rank==0)
1397 #endif
1398  {
1399  N_RootCells = Out.numberoftetrahedra;
1400  N_G = Out.numberofpoints;
1401 
1402  // allocate auxillary fields
1403  Coordinates = Out.pointlist;
1404  Tetrahedrals = Out.tetrahedronlist;
1405  }
1406 
1407 
1408 
1409 #ifdef _MPI
1410  MPI_Bcast(&N_RootCells, 1, MPI_INT, 0, Comm);
1411  MPI_Bcast(&N_G, 1, MPI_INT, 0, Comm);
1412 
1413 
1414  if(rank!=0)
1415  {
1416  Coordinates = new double [3*N_G];
1417  Tetrahedrals = new int[4*N_RootCells];
1418  }
1419 
1420  MPI_Bcast(Coordinates, 3*N_G, MPI_DOUBLE, 0, Comm);
1421  MPI_Bcast(Tetrahedrals, 4*N_RootCells, MPI_INT, 0, Comm);
1422 #endif
1423 
1424  // generate new vertices
1425  NewVertices = new TVertex*[N_G];
1426 
1427  for (i=0;i<N_G;i++)
1428  {
1429  NewVertices[i] = new TVertex(Coordinates[3*i], Coordinates[3*i+1], Coordinates[3*i+2]);
1430 
1431  // set bounding box
1432  if (Coordinates[3*i] > Xmax) Xmax = Coordinates[3*i];
1433  if (Coordinates[3*i] < Xmin) Xmin = Coordinates[3*i];
1434  if (Coordinates[3*i+1] > Ymax) Ymax = Coordinates[3*i+1];
1435  if (Coordinates[3*i+1] < Ymin) Ymin = Coordinates[3*i+1];
1436  if (Coordinates[3*i+2] > Zmax) Zmax = Coordinates[3*i+2];
1437  if (Coordinates[3*i+2] < Zmin) Zmin = Coordinates[3*i+2];
1438  }
1439 
1440  // set bounding box
1441  StartX = Xmin;
1442  StartY = Ymin;
1443  StartZ = Zmin;
1444  BoundX = Xmax - Xmin;
1445  BoundY = Ymax - Ymin;
1446  BoundZ = Zmax - Zmin;
1447 
1448 
1449  Domain->SetBoundBox(StartX, StartY, StartZ, BoundX, BoundY, BoundZ);
1450 // cout<<Xmin <<" "<<Ymin <<" "<<Zmin<<endl;
1451 // cout<<Xmax <<" "<<Ymax <<" "<<Zmax<<endl;
1452 
1453  CellTree = new TBaseCell*[N_RootCells];
1454  // output of each tetraheron vertex indices (four vertices for each)
1455 // for (i=0;i<N_RootCells;i++)
1456 // cout<< Tetrahedrals[4*i]<<" "<<Tetrahedrals[4*i + 1]<<" "
1457 // <<Tetrahedrals[4*i + 2]<<" "<<Tetrahedrals[4*i + 3]<<endl;
1458 
1459 
1460  for (i=0;i<N_RootCells;i++)
1461  {
1462  CellTree[i] = new TMacroCell(TDatabase::RefDescDB[Tetrahedron],
1463  RefLevel);
1464 
1465  CellTree[i]->SetVertex(0, NewVertices[Tetrahedrals[4*i ]]);
1466  CellTree[i]->SetVertex(1, NewVertices[Tetrahedrals[4*i + 1]]);
1467  CellTree[i]->SetVertex(2, NewVertices[Tetrahedrals[4*i + 2]]);
1468  CellTree[i]->SetVertex(3, NewVertices[Tetrahedrals[4*i + 3]]);
1469 
1470  CellTree[i]->SetClipBoard(i);
1471  ((TMacroCell *) CellTree[i])->SetSubGridID(0);
1472  }
1473 
1474  Domain->SetTreeInfo(CellTree, N_RootCells);
1475 
1476 
1477  // initialize iterators
1478  TDatabase::IteratorDB[It_EQ]->SetParam(Domain);
1479  TDatabase::IteratorDB[It_LE]->SetParam(Domain);
1480  TDatabase::IteratorDB[It_Finest]->SetParam(Domain);
1481  TDatabase::IteratorDB[It_Between]->SetParam(Domain);
1482  TDatabase::IteratorDB[It_OCAF]->SetParam(Domain);
1483 
1484 
1485  // search neighbours
1486  PointNeighb = new int[N_G];
1487 #ifdef _MPI
1488  if(rank==0)
1489 #endif
1490  cout<<"numberofpoints "<<N_G<<endl;
1491  memset(PointNeighb, 0, N_G *SizeOfInt);
1492 
1493  for (i=0;i<4*N_RootCells;i++)
1494  PointNeighb[Tetrahedrals[i]]++;
1495 
1496  for (i=0;i<N_G;i++)
1497  if (PointNeighb[i] > maxEpV) maxEpV = PointNeighb[i];
1498  delete [] PointNeighb;
1499 
1500 #ifdef _MPI
1501  if(rank==0)
1502 #endif
1503  cout<<"maxEpV "<< maxEpV<<endl;
1504 
1505  PointNeighb = new int[++maxEpV * N_G];
1506 
1507  memset(PointNeighb, 0, maxEpV*N_G*SizeOfInt);
1508 
1509  // every vertex contains "maxEpV" columns
1510  // for every vertex at first colomn contains the number of cells containing this vertex
1511  // at further columns we set the index of corresponding cells containing this vertex
1512  // cout<<"maxEpV*N_G "<<maxEpV*N_G<<endl;
1513 
1514  for(i=0;i<4*N_RootCells;i++)
1515  {
1516  j = Tetrahedrals[i]*maxEpV;
1517  PointNeighb[j]++;
1518  //cout<<"j + PointNeighb[j] " << j <<endl;
1519  PointNeighb[j + PointNeighb[j]] = i / 4;
1520  }
1521  // output of PointNeighb columns for each point
1522 // for (i=0;i<N_G;i++)
1523 // {
1524 // for (j=0;j<maxEpV;j++)
1525 // cout<<" "<< PointNeighb[i*maxEpV+j];
1526 // cout<<endl;
1527 // }
1528 
1529 
1530 
1531  // generate new faces
1532 
1533 #ifdef _MPI
1534  if(rank==0)
1535 #endif
1536  {
1537  N_G = Out.numberoftrifaces;
1538  Facelist = Out.trifacelist;
1539  Facemarkerlist = Out.trifacemarkerlist;
1540  }
1541 
1542 #ifdef _MPI
1543  MPI_Bcast(&N_G, 1, MPI_INT, 0, Comm);
1544 
1545  if(rank!=0)
1546  {
1547  Facelist = new int [3*N_G];
1548  Facemarkerlist = new int[N_G];
1549  }
1550 
1551 
1552  MPI_Bcast(Facelist, 3*N_G, MPI_INT, 0, Comm);
1553  MPI_Bcast(Facemarkerlist, N_G, MPI_INT, 0, Comm);
1554 
1555  if(rank==0)
1556 #endif
1557  cout<<"numberoftrifaces "<<N_G<<endl;
1558 
1559  for (i=0;i<N_G;i++)
1560  {
1561  a = Facelist[3*i];
1562  b = Facelist[3*i+1];
1563  c = Facelist[3*i+2];
1564 
1565 // cout<<" "<< a<<" "<< b<<" "<< c<<endl;
1566 
1567  Neib[0] = -1;
1568  Neib[1] = -1;
1569  CurrNeib = 0;
1570 
1571  len1 = PointNeighb[a*maxEpV];
1572  len2 = PointNeighb[b*maxEpV];
1573  len3 = PointNeighb[c*maxEpV];
1574 
1575  // find the index of the cells containing current face with point indices a,b,c
1576  for (j=1;j<=len1;j++)
1577  {
1578  Neighb_tmp = PointNeighb[a*maxEpV + j];
1579  for (k=1;k<=len2;k++)
1580  {
1581  if (Neighb_tmp == PointNeighb[b*maxEpV + k])
1582  {
1583  for (l=1;l<=len3;l++)
1584  if (Neighb_tmp == PointNeighb[c*maxEpV + l])
1585  {
1586  Neib[CurrNeib++] = Neighb_tmp;
1587  break;
1588  }
1589  }
1590  }
1591  if (CurrNeib == 2) break;
1592  }
1593  // cout<<"CurrNeib " << CurrNeib <<endl;
1594 // cout<<"Facemarkerlist[i] : "<<Facemarkerlist[i]<<endl;
1595  if (Facemarkerlist[i]) // 0 for inner edges and Boundcomp+1 for Boundedge respect
1596  {
1597 
1598  CurrComp = Facemarkerlist[i] - 1;
1599 // cout<<"Boundary face CurrComp: "<<CurrComp<<endl;
1600 // exit(0);
1601  CurrComp = 0; // not yet implemented fully
1602 
1603 
1604 
1605  bdcomp = Domain->GetBdPart(0)->GetBdComp(CurrComp);
1606 
1607 
1608  if(bdcomp->GetTSofXYZ(NewVertices[a]->GetX(), NewVertices[a]->GetY(),
1609  NewVertices[a]->GetY(), T[1], S[1]) ||
1610  bdcomp->GetTSofXYZ(NewVertices[b]->GetX(), NewVertices[b]->GetY(),
1611  NewVertices[b]->GetY(), T[2], S[2]) ||
1612  bdcomp->GetTSofXYZ(NewVertices[c]->GetX(), NewVertices[c]->GetY(),
1613  NewVertices[c]->GetY(), T[3], S[3]) )
1614  {
1615  cerr<<"Error: could not set parameter values"<<endl;
1616  OutPut(NewVertices[a]<<endl);
1617  OutPut(NewVertices[b]<<endl);
1618  OutPut(NewVertices[c]<<endl);
1619  exit(0);
1620  }
1621 
1622  if (CurrNeib == 2)
1623  {
1624  if(bdcomp->IsFreeBoundary())
1625  Joint = new TIsoInterfaceJoint3D(bdcomp, T, S,
1626  CellTree[Neib[0]], CellTree[Neib[1]] );
1627  else
1628  Joint = new TInterfaceJoint3D(bdcomp, T, S,
1629  CellTree[Neib[0]], CellTree[Neib[1]] );
1630  }
1631  else
1632  {
1633  if(bdcomp->IsFreeBoundary())
1634  Joint = new TIsoBoundFace(bdcomp, T, S);
1635  else
1636  Joint = new TBoundFace(bdcomp, T, S);
1637  }
1638  }
1639  else
1640  {
1641 // // cout<<"Inner face"<<endl;
1642  if (CurrNeib != 2)
1643  cerr << "Error !!!!!!!! not enough neighbours!" << endl;
1644 
1645  Joint = new TJointEqN(CellTree[Neib[0]], CellTree[Neib[1]]);
1646 
1647  }
1648 
1649  // First element containing the current face
1650  // find the local index for the point 'a' on the cell
1651  for (j=0;j<4;j++)
1652  if (Tetrahedrals[4*Neib[0]+j] == a) break;
1653 
1654  // find the local index for the point 'b' on the cell
1655  for (k=0;k<4;k++)
1656  if (Tetrahedrals[4*Neib[0]+k] == b) break;
1657 
1658  // find the local index for the point 'c' on the cell
1659  for (l=0;l<4;l++)
1660  if (Tetrahedrals[4*Neib[0]+l] == c) break;
1661 
1662  l = l*100 + k*10 + j;
1663 
1664 // cout<<""<< l <<endl;
1665 
1666  switch (l) // j will contain the local index for the current face
1667  {
1668  case 210: case 21: case 102:
1669  case 120: case 12: case 201:
1670  j = 0;
1671  break;
1672  case 310: case 31: case 103:
1673  case 130: case 13: case 301:
1674  j = 1;
1675  break;
1676  case 321: case 132: case 213:
1677  case 231: case 123: case 312:
1678  j = 2;
1679  break;
1680  case 230: case 23: case 302:
1681  case 320: case 32: case 203:
1682  j = 3;
1683  break;
1684 
1685  default:
1686  Error("Unable to set the face !!!!!!!!!!!!" << endl);
1687  exit(0);
1688  }
1689  CellTree[Neib[0]]->SetJoint(j, Joint);
1690 
1691  if (Neib[1] != -1) // second element containing the current face
1692  {
1693  // find the local index for the point 'a' on the cell
1694  for (j=0;j<4;j++)
1695  if (Tetrahedrals[4*Neib[1]+j] == a) break;
1696 
1697  // find the local index for the point 'b' on the cell
1698  for (k=0;k<4;k++)
1699  if (Tetrahedrals[4*Neib[1]+k] == b) break;
1700 
1701  // find the local index for the point 'c' on the cell
1702  for (l=0;l<4;l++)
1703  if (Tetrahedrals[4*Neib[1]+l] == c) break;
1704 
1705  l = l*100 + k*10 + j;
1706 
1707 // cout<<""<< l <<endl;
1708 
1709  switch (l) // j will contain the local index for the current face
1710  {
1711  case 210: case 21: case 102:
1712  case 120: case 12: case 201:
1713  j = 0;
1714  break;
1715  case 310: case 31: case 103:
1716  case 130: case 13: case 301:
1717  j = 1;
1718  break;
1719  case 321: case 132: case 213:
1720  case 231: case 123: case 312:
1721  j = 2;
1722  break;
1723  case 230: case 23: case 302:
1724  case 320: case 32: case 203:
1725  j = 3;
1726  break;
1727 
1728  default:
1729  Error("Unable to set the face !!!!!!!!!!!!" << endl);
1730  exit(0);
1731  }
1732  CellTree[Neib[1]]->SetJoint(j, Joint);
1733  }
1734 
1735  if (Joint->GetType() == InterfaceJoint3D ||
1736  Joint->GetType() == IsoInterfaceJoint3D)
1737  {
1738  ((TInterfaceJoint3D*)Joint)->SetMapType();
1739  ((TInterfaceJoint3D*)(Joint))->CheckOrientation();
1740  }
1741  else
1742  if (Joint->GetType() == JointEqN)
1743  Joint->SetMapType();
1744 
1745  }
1746 
1747 #ifdef _MPI
1748  if(rank==0)
1749 #endif
1750  {
1751 // In.deinitialize();
1752 // Out.deinitialize();
1753  }
1754 
1755 
1756 
1757 
1758 #ifdef _MPI
1759  if(rank!=0)
1760  {
1761  delete [] Tetrahedrals ;
1762  delete [] Coordinates;
1763  delete [] Facelist;
1764  delete [] Facemarkerlist;
1765  }
1766 #endif
1767 
1768  delete [] PointNeighb;
1769 
1770 // #ifdef _MPI
1771 // if(rank==3)
1772 // printf(" TetrameshGen %d \n", N_G );
1773 // MPI_Finalize();
1774 // #endif
1775 // exit(0);
1776 //
1777 
1778 }
1779 
1780 
1782 void TetraGen(TDomain *&Domain)
1783 {
1784  //======================================================================
1785  // Tetgen for grid generation begin
1786  //======================================================================
1787  int i, j, k, l, N_Coord, *N_FVerts, N_Faces, *Facets;
1788  int N, N_RootCells, N_Cells, CurrVertex, N_Vertices, ID, N_G, RefLevel=0;
1789  int CurrNeib, len1, len2, len3, maxEpV = 0, a, b, c, Neib[2], Neighb_tmp, CurrComp;
1790  int *Tetrahedrals, *PointNeighb, dimension;
1791  int jj, N_Points, MaxLen, *Tetrahedrals_loc;
1792  const int *EdgeVertex, *TmpFV, *TmpLen;
1793 
1794  double *Coordinates, N_x, N_y, N_z;
1795  double *Vertices;
1796  double Xmin = 1e10, Xmax = -1e10, Ymin = 1e10, Ymax = -1e10;
1797  double Zmin = 1e10, Zmax = -1e10, T[4]={0,0,0,0}, S[4]={0,0,0,0};
1798  double StartX, StartY, StartZ, BoundX, BoundY, BoundZ;
1799 
1800  tetgenio In, Out;
1801 
1802  TBaseCell **CellTree, **SurfCellTree;
1803  TGridCell **DelCell;
1804  TVertex **VertexDel, **NewVertices, **NewSurfVertices;
1805  TBoundPart *BoundPart;
1806  TBdPlane **UpdateFaceParams;
1807  TJoint *Joint;
1808  TBoundComp3D *bdcomp;
1809  TCollection *coll, *SurfColl;
1810  TBaseCell *cell;
1811  TBdSphere *UpdateParam;
1812  TShapeDesc *ShapeDesc;
1813 
1814  char *SMESH, line[100];
1815  SMESH = TDatabase::ParamDB->SMESHFILE;
1816 
1817 #ifdef _MPI
1818  int rank, size;
1819  MPI_Comm Comm = TDatabase::ParamDB->Comm;
1820 
1821  MPI_Comm_rank(Comm, &rank);
1822  MPI_Comm_size(Comm, &size);
1823 
1824 #endif
1825 
1827 #ifdef _MPI
1828  if(rank==0)
1829 #endif
1830  {
1831 
1832 // In.initialize();
1833 // Out.initialize();
1834 
1835  std::ostringstream opts;
1836  opts << " ";
1837 
1838  opts.seekp(std::ios::beg);
1839  opts<<'p'; // Tetrahedralize the PLC. Switches are chosen to read a PLC (p)
1840 // opts<<'r'; // -r Reconstructs a previously generated mesh
1841  opts<<"q"<<1.20; // quality mesh generation(q) with a specified quality bound
1842 // opts<<"a"<<0.1; // maximum volume constraint
1843 // opts<<'i'; // Inserts a list of additional points into mesh.
1844  opts<<'z'; // numbers all output items starting from zero
1845 // opts<<'d'; // Detect intersections of PLC facets.
1846  opts<<'f'; // Outputs all faces (including non-boundary)
1847  opts<<'e'; // Outputs a list of edges of the triangulation
1848 // opts<<'I'; // Suppresses mesh iteration numbers.
1849  opts<<'C'; // Checks the consistency of the final mesh.
1850 // opts<<'Q'; // Quiet: No terminal output except errors.
1851 // opts<<'g'; // Outputs mesh to .mesh file for viewing by Medit
1852  opts<<'Y'; // Suppresses boundary facets/segments splitting
1853 // opts<<'V'; //verbose mode
1854  opts<<ends;
1855 
1856 
1857 // cout << " SMESHFILE is " << SMESH << endl;
1859  ReadMeditMesh(SMESH, In);
1860 
1861 
1862 // for(i=0;i<In.numberofpoints;i++)
1863 // OutPut(i<<" (x, y, z) = "<<
1864 // In.pointlist[3*i]<<' '<<In.pointlist[3*i+1]<<' '<<In.pointlist[3*i+2]<<endl);
1865 
1866  // Calling tetrahedralize function of 3dtetgen mesh generator
1867  tetrahedralize((char*)opts.str().c_str(), &In, &Out);
1868 
1869  // output: coordinates of all vertices
1870 // for(i=0;i<Out.numberofpoints;i++)
1871 // OutPut(" (x, y, z) = "<< Out.pointlist[3*i]<<' '<<Out.pointlist[3*i+1]<<' '<<Out.pointlist[3*i+2]<<endl);
1872 
1873  } // if(rank==0)
1874 
1876  DeleteDomain(Domain);
1877 
1878 
1879 #ifdef _MPI
1880  if(rank==0)
1881 #endif
1882  {
1883  N_RootCells = Out.numberoftetrahedra;
1884  N_G = Out.numberofpoints;
1885 
1886  // allocate auxillary fields
1887  Coordinates = Out.pointlist;
1888  Tetrahedrals = Out.tetrahedronlist;
1889  }
1890 
1891 #ifdef _MPI
1892  MPI_Bcast(&N_RootCells, 1, MPI_INT, 0, Comm);
1893  MPI_Bcast(&N_G, 1, MPI_INT, 0, Comm);
1894 
1895 
1896  if(rank!=0)
1897  {
1898  Coordinates = new double [3*N_G];
1899  Tetrahedrals = new int[4*N_RootCells];
1900  }
1901 
1902  MPI_Bcast(Coordinates, 3*N_G, MPI_DOUBLE, 0, Comm);
1903  MPI_Bcast(Tetrahedrals, 4*N_RootCells, MPI_INT, 0, Comm);
1904 #endif
1905 
1906  // generate new vertices
1907  NewVertices = new TVertex*[N_G];
1908 
1909  for (i=0;i<N_G;i++)
1910  {
1911  NewVertices[i] = new TVertex(Coordinates[3*i], Coordinates[3*i+1], Coordinates[3*i+2]);
1912 
1913  // set bounding box
1914  if (Coordinates[3*i] > Xmax) Xmax = Coordinates[3*i];
1915  if (Coordinates[3*i] < Xmin) Xmin = Coordinates[3*i];
1916  if (Coordinates[3*i+1] > Ymax) Ymax = Coordinates[3*i+1];
1917  if (Coordinates[3*i+1] < Ymin) Ymin = Coordinates[3*i+1];
1918  if (Coordinates[3*i+2] > Zmax) Zmax = Coordinates[3*i+2];
1919  if (Coordinates[3*i+2] < Zmin) Zmin = Coordinates[3*i+2];
1920  }
1921 
1922  // set bounding box
1923  StartX = Xmin;
1924  StartY = Ymin;
1925  StartZ = Zmin;
1926  BoundX = Xmax - Xmin;
1927  BoundY = Ymax - Ymin;
1928  BoundZ = Zmax - Zmin;
1929 
1930 
1931  Domain->SetBoundBox(StartX, StartY, StartZ, BoundX, BoundY, BoundZ);
1932 // cout<<Xmin <<" "<<Ymin <<" "<<Zmin<<endl;
1933 // cout<<Xmax <<" "<<Ymax <<" "<<Zmax<<endl;
1934 
1935  CellTree = new TBaseCell*[N_RootCells];
1936  // output of each tetraheron vertex indices (four vertices for each)
1937 // for (i=0;i<N_RootCells;i++)
1938 // cout<< Tetrahedrals[4*i]<<" "<<Tetrahedrals[4*i + 1]<<" "
1939 // <<Tetrahedrals[4*i + 2]<<" "<<Tetrahedrals[4*i + 3]<<endl;
1940 
1941 
1942  for (i=0;i<N_RootCells;i++)
1943  {
1944  CellTree[i] = new TMacroCell(TDatabase::RefDescDB[Tetrahedron],
1945  RefLevel);
1946 
1947  CellTree[i]->SetVertex(0, NewVertices[Tetrahedrals[4*i ]]);
1948  CellTree[i]->SetVertex(1, NewVertices[Tetrahedrals[4*i + 1]]);
1949  CellTree[i]->SetVertex(2, NewVertices[Tetrahedrals[4*i + 2]]);
1950  CellTree[i]->SetVertex(3, NewVertices[Tetrahedrals[4*i + 3]]);
1951 
1952  CellTree[i]->SetClipBoard(i);
1953  ((TMacroCell *) CellTree[i])->SetSubGridID(0);
1954  }
1955 
1956  Domain->SetTreeInfo(CellTree, N_RootCells);
1957 
1958 
1959  // initialize iterators
1960  TDatabase::IteratorDB[It_EQ]->SetParam(Domain);
1961  TDatabase::IteratorDB[It_LE]->SetParam(Domain);
1962  TDatabase::IteratorDB[It_Finest]->SetParam(Domain);
1963  TDatabase::IteratorDB[It_Between]->SetParam(Domain);
1964  TDatabase::IteratorDB[It_OCAF]->SetParam(Domain);
1965 
1966 
1967  // search neighbours
1968  PointNeighb = new int[N_G];
1969 #ifdef _MPI
1970  if(rank==0)
1971 #endif
1972  cout<<"numberofpoints "<<N_G<<endl;
1973  memset(PointNeighb, 0, N_G *SizeOfInt);
1974 
1975  for (i=0;i<4*N_RootCells;i++)
1976  PointNeighb[Tetrahedrals[i]]++;
1977 
1978  for (i=0;i<N_G;i++)
1979  if (PointNeighb[i] > maxEpV) maxEpV = PointNeighb[i];
1980  delete [] PointNeighb;
1981 
1982 #ifdef _MPI
1983  if(rank==0)
1984 #endif
1985  cout<<"maxEpV "<< maxEpV<<endl;
1986 
1987  PointNeighb = new int[++maxEpV * N_G];
1988 
1989  memset(PointNeighb, 0, maxEpV*N_G*SizeOfInt);
1990 
1991  // every vertex contains "maxEpV" columns
1992  // for every vertex at first colomn contains the number of cells containing this vertex
1993  // at further columns we set the index of corresponding cells containing this vertex
1994  // cout<<"maxEpV*N_G "<<maxEpV*N_G<<endl;
1995 
1996  for(i=0;i<4*N_RootCells;i++)
1997  {
1998  j = Tetrahedrals[i]*maxEpV;
1999  PointNeighb[j]++;
2000  //cout<<"j + PointNeighb[j] " << j <<endl;
2001  PointNeighb[j + PointNeighb[j]] = i / 4;
2002  }
2003 
2004 
2005  // generate new faces
2006  coll=Domain->GetCollection(It_Finest, 0);
2007  N_Cells = coll->GetN_Cells();
2008  N_G = 0;
2009  for (i=0;i<N_Cells;i++)
2010  {
2011  cell = coll->GetCell(i);
2012  ShapeDesc= cell->GetShapeDesc();
2013  ShapeDesc->GetFaceVertex(TmpFV, TmpLen, MaxLen);
2014  N_Faces = cell->GetN_Faces();
2015  Tetrahedrals_loc = Tetrahedrals+4*i;
2016 
2017  for(jj=0;jj<N_Faces;jj++)
2018  if(cell->GetJoint(jj) == NULL)
2019  {
2020  N_G++;
2021  N_Points = TmpLen[jj];
2022 
2023  if(N_Points!=3)
2024  {
2025  cerr << "Only Tria faces are allowed!!! N_FVert: " << N_Points << endl;
2026  exit(-1);
2027  }
2028 
2029 
2030  //printf(" TetrameshGen Null joint \n" );
2031  a = Tetrahedrals_loc[TmpFV[jj*MaxLen]];
2032  b = Tetrahedrals_loc[TmpFV[jj*MaxLen + 1]];
2033  c = Tetrahedrals_loc[TmpFV[jj*MaxLen + 2]];
2034 
2035 // cout<<" "<< a<<" "<< b<<" "<< c<<endl;
2036 
2037  Neib[0] = -1;
2038  Neib[1] = -1;
2039  CurrNeib = 0;
2040 
2041  len1 = PointNeighb[a*maxEpV];
2042  len2 = PointNeighb[b*maxEpV];
2043  len3 = PointNeighb[c*maxEpV];
2044 
2045  // find the index of the cells containing current face with point indices a,b,c
2046  for (j=1;j<=len1;j++)
2047  {
2048  Neighb_tmp = PointNeighb[a*maxEpV + j];
2049  for (k=1;k<=len2;k++)
2050  {
2051  if (Neighb_tmp == PointNeighb[b*maxEpV + k])
2052  {
2053  for (l=1;l<=len3;l++)
2054  if (Neighb_tmp == PointNeighb[c*maxEpV + l])
2055  {
2056  Neib[CurrNeib++] = Neighb_tmp;
2057  break;
2058  }
2059  }
2060  }
2061  if (CurrNeib == 2) break;
2062  }// for (j=1;j<=len1;j++)
2063 
2064  // cout<<"CurrNeib " << CurrNeib <<endl;
2065  // cout<<"Facemarkerlist[i] : "<<Facemarkerlist[i]<<endl;
2066  if (CurrNeib == 1) // 0 for inner edges and Boundcomp+1 for Boundedge respect
2067  {
2068  CurrComp = 0; // not yet implemented fully
2069 
2070 
2071 
2072  bdcomp = Domain->GetBdPart(0)->GetBdComp(CurrComp);
2073 
2074 
2075  if(bdcomp->GetTSofXYZ(NewVertices[a]->GetX(), NewVertices[a]->GetY(),
2076  NewVertices[a]->GetY(), T[1], S[1]) ||
2077  bdcomp->GetTSofXYZ(NewVertices[b]->GetX(), NewVertices[b]->GetY(),
2078  NewVertices[b]->GetY(), T[2], S[2]) ||
2079  bdcomp->GetTSofXYZ(NewVertices[c]->GetX(), NewVertices[c]->GetY(),
2080  NewVertices[c]->GetY(), T[3], S[3]) )
2081  {
2082  cerr<<"Error: could not set parameter values"<<endl;
2083  OutPut(NewVertices[a]<<endl);
2084  OutPut(NewVertices[b]<<endl);
2085  OutPut(NewVertices[c]<<endl);
2086  exit(0);
2087  }
2088 
2089  if (CurrNeib == 2)
2090  {
2091  if(bdcomp->IsFreeBoundary())
2092  Joint = new TIsoInterfaceJoint3D(bdcomp, T, S,
2093  CellTree[Neib[0]], CellTree[Neib[1]] );
2094  else
2095  Joint = new TInterfaceJoint3D(bdcomp, T, S,
2096  CellTree[Neib[0]], CellTree[Neib[1]] );
2097  }
2098  else
2099  {
2100  if(bdcomp->IsFreeBoundary())
2101  Joint = new TIsoBoundFace(bdcomp, T, S);
2102  else
2103  Joint = new TBoundFace(bdcomp, T, S);
2104  }
2105  }
2106  else
2107  {
2108  // cout<<"Inner face"<<endl;
2109  if (CurrNeib != 2)
2110  cerr << "Error !!!!!!!! not enough neighbours!" << endl;
2111 
2112  Joint = new TJointEqN(CellTree[Neib[0]], CellTree[Neib[1]]);
2113  }
2114 
2115  // First element containing the current face
2116  // find the local index for the point 'a' on the cell
2117  for (j=0;j<4;j++)
2118  if (Tetrahedrals[4*Neib[0]+j] == a) break;
2119 
2120  // find the local index for the point 'b' on the cell
2121  for (k=0;k<4;k++)
2122  if (Tetrahedrals[4*Neib[0]+k] == b) break;
2123 
2124  // find the local index for the point 'c' on the cell
2125  for (l=0;l<4;l++)
2126  if (Tetrahedrals[4*Neib[0]+l] == c) break;
2127 
2128  l = l*100 + k*10 + j;
2129 
2130 // cout<<""<< l <<endl;
2131 
2132  switch (l) // j will contain the local index for the current face
2133  {
2134  case 210: case 21: case 102:
2135  case 120: case 12: case 201:
2136  j = 0;
2137  break;
2138  case 310: case 31: case 103:
2139  case 130: case 13: case 301:
2140  j = 1;
2141  break;
2142  case 321: case 132: case 213:
2143  case 231: case 123: case 312:
2144  j = 2;
2145  break;
2146  case 230: case 23: case 302:
2147  case 320: case 32: case 203:
2148  j = 3;
2149  break;
2150 
2151  default:
2152  Error("Unable to set the face !!!!!!!!!!!!" << endl);
2153  exit(0);
2154  }
2155  CellTree[Neib[0]]->SetJoint(j, Joint);
2156 
2157  if (Neib[1] != -1) // second element containing the current face
2158  {
2159  // find the local index for the point 'a' on the cell
2160  for (j=0;j<4;j++)
2161  if (Tetrahedrals[4*Neib[1]+j] == a) break;
2162 
2163  // find the local index for the point 'b' on the cell
2164  for (k=0;k<4;k++)
2165  if (Tetrahedrals[4*Neib[1]+k] == b) break;
2166 
2167  // find the local index for the point 'c' on the cell
2168  for (l=0;l<4;l++)
2169  if (Tetrahedrals[4*Neib[1]+l] == c) break;
2170 
2171  l = l*100 + k*10 + j;
2172 
2173 // cout<<""<< l <<endl;
2174 
2175  switch (l) // j will contain the local index for the current face
2176  {
2177  case 210: case 21: case 102:
2178  case 120: case 12: case 201:
2179  j = 0;
2180  break;
2181  case 310: case 31: case 103:
2182  case 130: case 13: case 301:
2183  j = 1;
2184  break;
2185  case 321: case 132: case 213:
2186  case 231: case 123: case 312:
2187  j = 2;
2188  break;
2189  case 230: case 23: case 302:
2190  case 320: case 32: case 203:
2191  j = 3;
2192  break;
2193 
2194  default:
2195  Error("Unable to set the face !!!!!!!!!!!!" << endl);
2196  exit(0);
2197  }
2198  CellTree[Neib[1]]->SetJoint(j, Joint);
2199  } // if (Neib[1] != -1)
2200 
2201  if (Joint->GetType() == InterfaceJoint3D ||
2202  Joint->GetType() == IsoInterfaceJoint3D)
2203  {
2204  ((TInterfaceJoint3D*)Joint)->SetMapType();
2205  ((TInterfaceJoint3D*)(Joint))->CheckOrientation();
2206  }
2207  else
2208  if (Joint->GetType() == JointEqN)
2209  Joint->SetMapType();
2210  } // if(cell->GetJoint(jj) == NULL)
2211  } // for (i=0;i<N_Cells;i++)
2212 
2213 
2214 #ifdef _MPI
2215  if(rank==0)
2216 #endif
2217  cout<<"numberoftrifaces after "<<N_G<<endl;
2218 
2219 #ifdef _MPI
2220  if(rank==0)
2221 #endif
2222  {
2223 // In.deinitialize();
2224 // Out.deinitialize();
2225  }
2226 
2227 
2228 
2229 
2230 #ifdef _MPI
2231  if(rank!=0)
2232  {
2233  delete [] Tetrahedrals ;
2234  delete [] Coordinates;
2235 // delete [] Facelist;
2236 // delete [] Facemarkerlist;
2237  }
2238 #endif
2239 
2240  delete [] PointNeighb;
2241 
2242 // #ifdef _MPI
2243 // if(rank==3)
2244 // printf(" TetrameshGen %d \n", N_G );
2245 // MPI_Finalize();
2246 // #endif
2247 // exit(0);
2248 //
2249 
2250 }
2251 
2252 
2254 void TetraGenWithInputCells(TDomain *&Domain)
2255 {
2256  //======================================================================
2257  // Tetgen for grid generation begin
2258  //======================================================================
2259  int i, j, k, l, N_Coord, *N_FVerts, N_Faces, *Facets;
2260  int N, N_RootCells, N_Cells, CurrVertex, N_Vertices, ID, N_G, RefLevel=0;
2261  int CurrNeib, len1, len2, len3, maxEpV = 0, a, b, c, Neib[2], Neighb_tmp, CurrComp;
2262  int *Tetrahedrals, *PointNeighb, dimension;
2263  int jj, N_Points, MaxLen, *Tetrahedrals_loc;
2264  const int *EdgeVertex, *TmpFV, *TmpLen;
2265  double *TetRegionlist;
2266 
2267  double *Coordinates, N_x, N_y, N_z;
2268  double *Vertices;
2269  double Xmin = 1e10, Xmax = -1e10, Ymin = 1e10, Ymax = -1e10;
2270  double Zmin = 1e10, Zmax = -1e10, T[4]={0,0,0,0}, S[4]={0,0,0,0};
2271  double StartX, StartY, StartZ, BoundX, BoundY, BoundZ;
2272 
2273  tetgenio In, Out, InAddPts;
2274 
2275  TBaseCell **CellTree, **SurfCellTree;
2276  TGridCell **DelCell;
2277  TVertex **VertexDel, **NewVertices, **NewSurfVertices;
2278  TBoundPart *BoundPart;
2279  TBdPlane **UpdateFaceParams;
2280  TJoint *Joint;
2281  TBoundComp3D *bdcomp;
2282  TCollection *coll, *SurfColl;
2283  TBaseCell *cell;
2284  TBdSphere *UpdateParam;
2285  TShapeDesc *ShapeDesc;
2286 
2287  char *SMESH, line[100];
2288  SMESH = TDatabase::ParamDB->SMESHFILE;
2289 // NODE = TDatabase::ParamDB->GRAPEBASENAME;
2290 
2291 #ifdef _MPI
2292  int rank, size;
2293  MPI_Comm Comm = TDatabase::ParamDB->Comm;
2294 
2295  MPI_Comm_rank(Comm, &rank);
2296  MPI_Comm_size(Comm, &size);
2297 
2298 #endif
2299 
2301 #ifdef _MPI
2302  if(rank==0)
2303 #endif
2304  {
2305 
2306 // In.initialize();
2307 // Out.initialize();
2308 
2309  std::ostringstream opts;
2310  opts << " ";
2311 
2312  opts.seekp(std::ios::beg);
2313 // opts<<'p'; // Tetrahedralize the PLC. Switches are chosen to read a PLC (p)
2314  opts<<'r'; // -r Reconstructs a previously generated mesh
2315 // opts<<'q'<<1.2; // quality mesh generation(q) with a specified quality bound
2316 // opts<<'a'<<100; // maximum volume constraint
2317 // opts<<'a'; // maximum volume constraint
2318 // opts<<'i'; // Inserts a list of additional points into mesh.
2319  opts<<'z'; // numbers all output items starting from zero
2320 // opts<<'d'; // Detect intersections of PLC facets.
2321  opts<<'f'; // Outputs all faces (including non-boundary)
2322  opts<<'e'; // Outputs a list of edges of the triangulation
2323 // opts<<'I'; // Suppresses mesh iteration numbers.
2324  opts<<'C'; // Checks the consistency of the final mesh.
2325 // opts<<'Q'; // Quiet: No terminal output except errors.
2326 // opts<<'g'; // Outputs mesh to .mesh file for viewing by Medit
2327  opts<<'Y'; // Suppresses boundary facets/segments splitting
2328 // opts<<'A'; // output region attribute list
2329 // opts<<'V'; //verbose mode
2330 // opts<<'V';
2331 // opts<<'V';
2332 // opts<<'V';
2333 // opts<<'V';
2334  opts<<ends;
2335 
2336  In.initialize();
2337  Out.initialize();
2338 // InAddPts.initialize();
2339 // cout << " SMESHFILE is " << SMESH << endl;
2341  ReadMeditMeshWithCells(SMESH, In);
2342 // ReadAdditionalNModes(NODE, InAddPts);
2343 // In.load_medit(SMESH, 1);
2344 
2345 
2346 // InAddPts.load_node(NODE);
2347 // cout<< " InAddPts.numberofpoints " << InAddPts.numberofpoints <<endl;
2348 // exit(0);
2349 // for(i=0;i<In.numberofpoints;i++)
2350 // OutPut(i<<" (x, y, z) = "<<
2351 // In.pointlist[3*i]<<' '<<In.pointlist[3*i+1]<<' '<<In.pointlist[3*i+2]<<endl);
2352 // exit(0);
2353  // Calling tetrahedralize function of 3dtetgen mesh generator
2354 
2355 
2356  tetrahedralize((char*)opts.str().c_str(), &In, &Out);
2357 // tetrahedralize((char*)opts.str().c_str(), &In, &Out, &InAddPts);
2358 // exit(0);
2359  // output: coordinates of all vertices
2360 // for(i=0;i<Out.numberofpoints;i++)
2361 // OutPut(" (x, y, z) = "<< Out.pointlist[3*i]<<' '<<Out.pointlist[3*i+1]<<' '<<Out.pointlist[3*i+2]<<endl);
2362 
2363  } // if(rank==0)
2364 
2366  DeleteDomain(Domain);
2367 
2368 
2369 #ifdef _MPI
2370  if(rank==0)
2371 #endif
2372  {
2373  N_RootCells = Out.numberoftetrahedra;
2374  N_G = Out.numberofpoints;
2375 
2376  // allocate auxillary fields
2377  Coordinates = Out.pointlist;
2378  Tetrahedrals = Out.tetrahedronlist;
2379 
2380  TetRegionlist = Out.tetrahedronattributelist;
2381  }
2382 
2383 #ifdef _MPI
2384  MPI_Bcast(&N_RootCells, 1, MPI_INT, 0, Comm);
2385  MPI_Bcast(&N_G, 1, MPI_INT, 0, Comm);
2386 
2387 
2388  if(rank!=0)
2389  {
2390  Coordinates = new double [3*N_G];
2391  Tetrahedrals = new int[4*N_RootCells];
2392  TetRegionlist = new double [N_RootCells];
2393  }
2394 
2395  MPI_Bcast(Coordinates, 3*N_G, MPI_DOUBLE, 0, Comm);
2396  MPI_Bcast(Tetrahedrals, 4*N_RootCells, MPI_INT, 0, Comm);
2397  MPI_Bcast(TetRegionlist, N_RootCells, MPI_DOUBLE, 0, Comm);
2398 #endif
2399 
2400  // generate new vertices
2401  NewVertices = new TVertex*[N_G];
2402 
2403  for (i=0;i<N_G;i++)
2404  {
2405  NewVertices[i] = new TVertex(Coordinates[3*i], Coordinates[3*i+1], Coordinates[3*i+2]);
2406 
2407  // set bounding box
2408  if (Coordinates[3*i] > Xmax) Xmax = Coordinates[3*i];
2409  if (Coordinates[3*i] < Xmin) Xmin = Coordinates[3*i];
2410  if (Coordinates[3*i+1] > Ymax) Ymax = Coordinates[3*i+1];
2411  if (Coordinates[3*i+1] < Ymin) Ymin = Coordinates[3*i+1];
2412  if (Coordinates[3*i+2] > Zmax) Zmax = Coordinates[3*i+2];
2413  if (Coordinates[3*i+2] < Zmin) Zmin = Coordinates[3*i+2];
2414  }
2415 
2416  // set bounding box
2417  StartX = Xmin;
2418  StartY = Ymin;
2419  StartZ = Zmin;
2420  BoundX = Xmax - Xmin;
2421  BoundY = Ymax - Ymin;
2422  BoundZ = Zmax - Zmin;
2423 
2424 
2425  Domain->SetBoundBox(StartX, StartY, StartZ, BoundX, BoundY, BoundZ);
2426 // cout<<Xmin <<" "<<Ymin <<" "<<Zmin<<endl;
2427 // cout<<Xmax <<" "<<Ymax <<" "<<Zmax<<endl;
2428 
2429  CellTree = new TBaseCell*[N_RootCells];
2430  // output of each tetraheron vertex indices (four vertices for each)
2431 // for (i=0;i<N_RootCells;i++)
2432 // cout<< Tetrahedrals[4*i]<<" "<<Tetrahedrals[4*i + 1]<<" "
2433 // <<Tetrahedrals[4*i + 2]<<" "<<Tetrahedrals[4*i + 3]<<endl;
2434 
2435 
2436  for (i=0;i<N_RootCells;i++)
2437  {
2438  CellTree[i] = new TMacroCell(TDatabase::RefDescDB[Tetrahedron],
2439  RefLevel);
2440 
2441  CellTree[i]->SetVertex(0, NewVertices[Tetrahedrals[4*i ]]);
2442  CellTree[i]->SetVertex(1, NewVertices[Tetrahedrals[4*i + 1]]);
2443  CellTree[i]->SetVertex(2, NewVertices[Tetrahedrals[4*i + 2]]);
2444  CellTree[i]->SetVertex(3, NewVertices[Tetrahedrals[4*i + 3]]);
2445 
2446  CellTree[i]->SetClipBoard(i);
2447  ((TMacroCell *) CellTree[i])->SetSubGridID(0);
2448 
2449 // cout << i<< " TetRegionlist : " << TetRegionlist[i] << endl;
2450  CellTree[i]->SetRegionID((int)TetRegionlist[i]);
2451  }
2452 // exit(0);
2453  Domain->SetTreeInfo(CellTree, N_RootCells);
2454 
2455 
2456  // initialize iterators
2457  TDatabase::IteratorDB[It_EQ]->SetParam(Domain);
2458  TDatabase::IteratorDB[It_LE]->SetParam(Domain);
2459  TDatabase::IteratorDB[It_Finest]->SetParam(Domain);
2460  TDatabase::IteratorDB[It_Between]->SetParam(Domain);
2461  TDatabase::IteratorDB[It_OCAF]->SetParam(Domain);
2462 
2463 
2464  // search neighbours
2465  PointNeighb = new int[N_G];
2466 #ifdef _MPI
2467  if(rank==0)
2468 #endif
2469  cout<<"numberofpoints "<<N_G<<endl;
2470  memset(PointNeighb, 0, N_G *SizeOfInt);
2471 
2472  for (i=0;i<4*N_RootCells;i++)
2473  PointNeighb[Tetrahedrals[i]]++;
2474 
2475  for (i=0;i<N_G;i++)
2476  if (PointNeighb[i] > maxEpV) maxEpV = PointNeighb[i];
2477  delete [] PointNeighb;
2478 
2479 #ifdef _MPI
2480  if(rank==0)
2481 #endif
2482  cout<<"maxEpV "<< maxEpV<<endl;
2483 
2484  PointNeighb = new int[++maxEpV * N_G];
2485 
2486  memset(PointNeighb, 0, maxEpV*N_G*SizeOfInt);
2487 
2488  // every vertex contains "maxEpV" columns
2489  // for every vertex at first colomn contains the number of cells containing this vertex
2490  // at further columns we set the index of corresponding cells containing this vertex
2491  // cout<<"maxEpV*N_G "<<maxEpV*N_G<<endl;
2492 
2493  for(i=0;i<4*N_RootCells;i++)
2494  {
2495  j = Tetrahedrals[i]*maxEpV;
2496  PointNeighb[j]++;
2497  //cout<<"j + PointNeighb[j] " << j <<endl;
2498  PointNeighb[j + PointNeighb[j]] = i / 4;
2499  }
2500 
2501 
2502  // generate new faces
2503  coll=Domain->GetCollection(It_Finest, 0);
2504  N_Cells = coll->GetN_Cells();
2505  N_G = 0;
2506  for (i=0;i<N_Cells;i++)
2507  {
2508  cell = coll->GetCell(i);
2509  ShapeDesc= cell->GetShapeDesc();
2510  ShapeDesc->GetFaceVertex(TmpFV, TmpLen, MaxLen);
2511  N_Faces = cell->GetN_Faces();
2512  Tetrahedrals_loc = Tetrahedrals+4*i;
2513 
2514  for(jj=0;jj<N_Faces;jj++)
2515  if(cell->GetJoint(jj) == NULL)
2516  {
2517  N_G++;
2518  N_Points = TmpLen[jj];
2519 
2520  if(N_Points!=3)
2521  {
2522  cerr << "Only Tria faces are allowed!!! N_FVert: " << N_Points << endl;
2523  exit(-1);
2524  }
2525 
2526 
2527  //printf(" TetrameshGen Null joint \n" );
2528  a = Tetrahedrals_loc[TmpFV[jj*MaxLen]];
2529  b = Tetrahedrals_loc[TmpFV[jj*MaxLen + 1]];
2530  c = Tetrahedrals_loc[TmpFV[jj*MaxLen + 2]];
2531 
2532 // cout<<" "<< a<<" "<< b<<" "<< c<<endl;
2533 
2534  Neib[0] = -1;
2535  Neib[1] = -1;
2536  CurrNeib = 0;
2537 
2538  len1 = PointNeighb[a*maxEpV];
2539  len2 = PointNeighb[b*maxEpV];
2540  len3 = PointNeighb[c*maxEpV];
2541 
2542  // find the index of the cells containing current face with point indices a,b,c
2543  for (j=1;j<=len1;j++)
2544  {
2545  Neighb_tmp = PointNeighb[a*maxEpV + j];
2546  for (k=1;k<=len2;k++)
2547  {
2548  if (Neighb_tmp == PointNeighb[b*maxEpV + k])
2549  {
2550  for (l=1;l<=len3;l++)
2551  if (Neighb_tmp == PointNeighb[c*maxEpV + l])
2552  {
2553  Neib[CurrNeib++] = Neighb_tmp;
2554  break;
2555  }
2556  }
2557  }
2558  if (CurrNeib == 2) break;
2559  }// for (j=1;j<=len1;j++)
2560 
2561  // cout<<"CurrNeib " << CurrNeib <<endl;
2562  // cout<<"Facemarkerlist[i] : "<<Facemarkerlist[i]<<endl;
2563  if (CurrNeib == 1) // 0 for inner edges and Boundcomp+1 for Boundedge respect
2564  {
2565  CurrComp = 0; // not yet implemented fully
2566 
2567 
2568 
2569  bdcomp = Domain->GetBdPart(0)->GetBdComp(CurrComp);
2570 
2571 
2572  if(bdcomp->GetTSofXYZ(NewVertices[a]->GetX(), NewVertices[a]->GetY(),
2573  NewVertices[a]->GetY(), T[1], S[1]) ||
2574  bdcomp->GetTSofXYZ(NewVertices[b]->GetX(), NewVertices[b]->GetY(),
2575  NewVertices[b]->GetY(), T[2], S[2]) ||
2576  bdcomp->GetTSofXYZ(NewVertices[c]->GetX(), NewVertices[c]->GetY(),
2577  NewVertices[c]->GetY(), T[3], S[3]) )
2578  {
2579  cerr<<"Error: could not set parameter values"<<endl;
2580  OutPut(NewVertices[a]<<endl);
2581  OutPut(NewVertices[b]<<endl);
2582  OutPut(NewVertices[c]<<endl);
2583  exit(0);
2584  }
2585 
2586  if (CurrNeib == 2)
2587  {
2588  if(bdcomp->IsFreeBoundary())
2589  Joint = new TIsoInterfaceJoint3D(bdcomp, T, S,
2590  CellTree[Neib[0]], CellTree[Neib[1]] );
2591  else
2592  Joint = new TInterfaceJoint3D(bdcomp, T, S,
2593  CellTree[Neib[0]], CellTree[Neib[1]] );
2594  }
2595  else
2596  {
2597  if(bdcomp->IsFreeBoundary())
2598  Joint = new TIsoBoundFace(bdcomp, T, S);
2599  else
2600  Joint = new TBoundFace(bdcomp, T, S);
2601  }
2602  }
2603  else
2604  {
2605  // cout<<"Inner face"<<endl;
2606  if (CurrNeib != 2)
2607  cerr << "Error !!!!!!!! not enough neighbours!" << endl;
2608 
2609  Joint = new TJointEqN(CellTree[Neib[0]], CellTree[Neib[1]]);
2610  }
2611 
2612  // First element containing the current face
2613  // find the local index for the point 'a' on the cell
2614  for (j=0;j<4;j++)
2615  if (Tetrahedrals[4*Neib[0]+j] == a) break;
2616 
2617  // find the local index for the point 'b' on the cell
2618  for (k=0;k<4;k++)
2619  if (Tetrahedrals[4*Neib[0]+k] == b) break;
2620 
2621  // find the local index for the point 'c' on the cell
2622  for (l=0;l<4;l++)
2623  if (Tetrahedrals[4*Neib[0]+l] == c) break;
2624 
2625  l = l*100 + k*10 + j;
2626 
2627 // cout<<""<< l <<endl;
2628 
2629  switch (l) // j will contain the local index for the current face
2630  {
2631  case 210: case 21: case 102:
2632  case 120: case 12: case 201:
2633  j = 0;
2634  break;
2635  case 310: case 31: case 103:
2636  case 130: case 13: case 301:
2637  j = 1;
2638  break;
2639  case 321: case 132: case 213:
2640  case 231: case 123: case 312:
2641  j = 2;
2642  break;
2643  case 230: case 23: case 302:
2644  case 320: case 32: case 203:
2645  j = 3;
2646  break;
2647 
2648  default:
2649  Error("Unable to set the face !!!!!!!!!!!!" << endl);
2650  exit(0);
2651  }
2652  CellTree[Neib[0]]->SetJoint(j, Joint);
2653 
2654  if (Neib[1] != -1) // second element containing the current face
2655  {
2656  // find the local index for the point 'a' on the cell
2657  for (j=0;j<4;j++)
2658  if (Tetrahedrals[4*Neib[1]+j] == a) break;
2659 
2660  // find the local index for the point 'b' on the cell
2661  for (k=0;k<4;k++)
2662  if (Tetrahedrals[4*Neib[1]+k] == b) break;
2663 
2664  // find the local index for the point 'c' on the cell
2665  for (l=0;l<4;l++)
2666  if (Tetrahedrals[4*Neib[1]+l] == c) break;
2667 
2668  l = l*100 + k*10 + j;
2669 
2670 // cout<<""<< l <<endl;
2671 
2672  switch (l) // j will contain the local index for the current face
2673  {
2674  case 210: case 21: case 102:
2675  case 120: case 12: case 201:
2676  j = 0;
2677  break;
2678  case 310: case 31: case 103:
2679  case 130: case 13: case 301:
2680  j = 1;
2681  break;
2682  case 321: case 132: case 213:
2683  case 231: case 123: case 312:
2684  j = 2;
2685  break;
2686  case 230: case 23: case 302:
2687  case 320: case 32: case 203:
2688  j = 3;
2689  break;
2690 
2691  default:
2692  Error("Unable to set the face !!!!!!!!!!!!" << endl);
2693  exit(0);
2694  }
2695  CellTree[Neib[1]]->SetJoint(j, Joint);
2696  } // if (Neib[1] != -1)
2697 
2698  if (Joint->GetType() == InterfaceJoint3D ||
2699  Joint->GetType() == IsoInterfaceJoint3D)
2700  {
2701  ((TInterfaceJoint3D*)Joint)->SetMapType();
2702  ((TInterfaceJoint3D*)(Joint))->CheckOrientation();
2703  }
2704  else
2705  if (Joint->GetType() == JointEqN)
2706  Joint->SetMapType();
2707  } // if(cell->GetJoint(jj) == NULL)
2708  } // for (i=0;i<N_Cells;i++)
2709 
2710 
2711 #ifdef _MPI
2712  if(rank==0)
2713 #endif
2714  cout<<"numberoftrifaces after "<<N_G<<endl;
2715 
2716 #ifdef _MPI
2717  if(rank==0)
2718 #endif
2719  {
2720 // In.deinitialize();
2721 // Out.deinitialize();
2722  }
2723 
2724 
2725 
2726 
2727 #ifdef _MPI
2728  if(rank!=0)
2729  {
2730  delete [] Tetrahedrals ;
2731  delete [] Coordinates;
2732  delete [] TetRegionlist;
2733 // delete [] Facemarkerlist;
2734  }
2735 #endif
2736 
2737  delete [] PointNeighb;
2738 
2739 // #ifdef _MPI
2740 // if(rank==3)
2741 // printf(" TetrameshGen %d \n", N_G );
2742 // MPI_Finalize();
2743 // #endif
2744 // exit(0);
2745 //
2746 
2747 }
2748 
2749 
2750 
2751 
void SetMapType()
Definition: Joint.C:107
Definition: BdPlane.h:18
void GetTreeInfo(TBaseCell **&celltree, int &N_rootcells)
get tree of cells
Definition: Domain.h:176
virtual int GetTSofXYZ(double X, double Y, double Z, double &T, double &S)=0
JointType GetType()
Definition: Joint.h:75
TBaseCell * GetCell(int i) const
return Cell with index i in Cells-array
Definition: Collection.h:50
int GetN_Faces()
return the number of faces of the cell
Definition: BaseCell.h:190
TBoundComp2D * GetBdComp(int i)
Definition: BoundPart.h:49
int SetJoint(int J_i, TJoint *J)
set the pointer to face J_i to J
Definition: BaseCell.h:168
int GetFaceVertex(const int *&TmpFV, const int *&TmpLen, int &MaxLen)
Definition: ShapeDesc.h:124
static TTimeDB * TimeDB
Definition: Database.h:1137
contains the boundary description, the virtual cell tree and macro grid
Definition: Domain.h:36
void SetClipBoard(int value)
set value in ClipBoard
Definition: BaseCell.h:263
double RE_NR
Definition: Database.h:313
int SetParam(TDomain *domain)
Definition: Iterator.C:17
static TIterator ** IteratorDB
Definition: Database.h:1131
Definition: IsoBoundFace.h:18
TShapeDesc * GetShapeDesc() const
return shape descriptor of refinement descriptor
Definition: BaseCell.h:134
store cells in an array, used by cell iterators
Definition: Collection.h:18
virtual TVertex * GetVertex(int Vert_i)=0
return the pointer to vertex with number i
represent a unit of the macro grid
Definition: MacroCell.h:15
Definition: JointEqN.h:20
int GetN_Cells() const
return number of cells
Definition: Collection.h:46
Definition: ShapeDesc.h:29
TJoint * GetJoint(int J_i)
return the pointer to face with number i
Definition: BaseCell.h:175
MPI_Comm Comm
Definition: Database.h:978
Definition: Joint.h:48
TBoundPart * GetBdPart(int i)
get i-th boundary part
Definition: Domain.h:172
Definition: BoundComp3D.h:17
double GetY() const
Definition: Vertex.h:99
int GetN_Vertices()
return the number of vertices of the cell
Definition: BaseCell.h:179
Definition: BoundPart.h:21
void SetTreeInfo(TBaseCell **celltree, int N_rootcells)
set tree of cells
Definition: Domain.h:183
bool IsFreeBoundary() const
Definition: BoundComp.h:57
TCollection * GetCollection(Iterators it, int level)
produce a collection with all cells returned by iterator it
Definition: Domain.C:1982
Definition: IsoInterfaceJoint3D.h:19
information for finite element data structure
Definition: BaseCell.h:25
Definition: Vertex.h:19
static TRefDesc ** RefDescDB
Definition: Database.h:1125
void SetRegionID(int val)
set region number to this cell
Definition: BaseCell.h:347
Definition: BoundFace.h:18
double GetX() const
Definition: Vertex.h:96
virtual int SetVertex(int Vert_i, TVertex *Vert)=0
set the pointer of vertex Vert_i to Vert
represent geometric information of the cell
Definition: GridCell.h:15
void SetAsLayerCell(int val)
set as LayerCell cell
Definition: BaseCell.h:355
Definition: BdSphere.h:18
static TParamDB * ParamDB
Definition: Database.h:1134
Definition: InterfaceJoint3D.h:18