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