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