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