Memosa-FVM  0.2
MeshPartitioner.cpp
Go to the documentation of this file.
1 // This file os part of FVM
2 // Copyright (c) 2012 FVM Authors
3 // See LICENSE file for terms.
4 
5 #include<iostream>
6 #include <cassert>
7 #include <fstream>
8 #include <string>
9 #include <sstream>
10 #include <iomanip>
11 #include <algorithm>
12 #include "MeshPartitioner.h"
13 #include "Mesh.h"
14 #include "Array.h"
15 #include "CRConnectivity.h"
16 #include "StorageSite.h"
17 #include "Vector.h"
18 #include "OneToOneIndexMap.h"
19 #include <parmetis.h>
20 #include <utility>
21 #include <list>
22 #include "Field.h"
23 #include "MultiField.h"
24 
25 
26 
27 MeshPartitioner::MeshPartitioner( const MeshList &mesh_list, vector<int> nPart, vector<int> eType ):
28 _meshList(mesh_list), _nPart(nPart), _eType(eType), _options(0), _bMesh(NULL)
29 {
30  if ( !MPI::Is_initialized() ) MPI::Init();
31  init();
32  assert( _meshList.size() == 1 );
33 }
34 
35 
37 {
38 
39  MPI::COMM_WORLD.Barrier();
40  //releae memory of vector elements dynamically allocated memory
41  vector< Array<int>* > ::iterator it_array;
42  for ( it_array = _elemDist.begin(); it_array != _elemDist.end(); it_array++)
43  delete *it_array;
44 
45  for ( it_array = _globalIndx.begin(); it_array != _globalIndx.end(); it_array++)
46  delete *it_array;
47 
48  if ( !_cleanup ){
49  vector< int* > ::iterator it_int;
50  for ( it_int = _ePtr.begin(); it_int != _ePtr.end(); it_int++)
51  delete [] *it_int;
52 
53  for ( it_int = _eInd.begin(); it_int != _eInd.end(); it_int++)
54  delete [] *it_int;
55 
56  for ( it_int = _eElm.begin(); it_int != _eElm.end(); it_int++)
57  delete [] *it_int;
58 
59  for ( it_int = _elmWght.begin(); it_int != _elmWght.end(); it_int++)
60  delete [] *it_int;
61 
62  for ( it_int = _row.begin(); it_int != _row.end(); it_int++)
63  delete [] *it_int;
64 
65  for ( it_int = _col.begin(); it_int != _col.end(); it_int++)
66  delete [] *it_int;
67 
68  for ( it_int = _elem.begin(); it_int != _elem.end(); it_int++)
69  delete [] *it_int;
70  }
71 
72  vector< float* > ::iterator it_float;
73  for ( it_float = _tpwgts.begin(); it_float != _tpwgts.end(); it_float++)
74  delete [] *it_float;
75 
76  for ( it_float = _ubvec.begin(); it_float != _ubvec.end(); it_float++)
77  delete [] *it_float;
78  vector< int* > ::iterator it_int;
79  for ( it_int = _part.begin(); it_int != _part.end(); it_int++)
80  delete [] *it_int;
81 
82 
83  for ( it_int = _elemWithGhosts.begin(); it_int != _elemWithGhosts.end(); it_int++)
84  delete [] *it_int;
85 
86 
87 
88  vector< Mesh* >::iterator it_mesh;
89  for ( it_mesh = _meshListLocal.begin(); it_mesh != _meshListLocal.end(); it_mesh++)
90  delete *it_mesh;
91 
92  if ( _bMesh ) delete _bMesh;
93 }
94 
95 
96 void
98 {
99 
101  if ( _partTYPE == FIEDLER )
104  if ( _partTYPE == PARMETIS )
105  parmetis_mesh();
106  map_part_elms();
109  //dumpTecplot();
110 
111 }
112 
113 
114 
115 void
117 {
120  interfaces();
124  coordinates();
126  mesh_setup();
127  mappers();
134  if ( _meshList.at(0)->isMergedMesh() ){
135  setMeshColors();
136  }
137 
138 }
139 
140 #if 0
141 void
142 MeshPartitioner::dumpTecplot()
143 {
144 
145  //just for mesh 0;
146  MPI::COMM_WORLD.Barrier();
147 
148  const Mesh& mesh = *(_meshList.at(0));
149  const Array<Mesh::VecD3>& coord = mesh.getNodeCoordinates();
150 
151  const StorageSite& cellSite = _meshList.at(0)->getCells();
152  int tot_elems = cellSite.getSelfCount();
153  const CRConnectivity& cellNodes = _meshList.at(0)->getCellNodes();
154  //connectivity
155  if ( _procID == 0 )
156  for ( int n = 0; n < tot_elems; n++ ){
157  int nnodes = cellNodes.getCount(n);
158  cout << " elem = " << n << ", ";
159  for ( int node = 0; node < nnodes; node++ )
160  cout << cellNodes(n,node) << " ";
161  cout << endl;
162  }
163 
164  int tot_nodes = coord.getLength();
165 
166  if ( _procID == 0 )
167  for ( int node = 0; node < tot_nodes; node++)
168  cout << " nodeID = " << node << " x = " << coord[node][0] << " y = " << coord[node][1] << " z = " << coord[node][2] << endl;
169 
170 
171 
172 
173  if ( _procID == 0 ) {
174  MPI::Status status_row;
175  MPI::Status status_col;
176  int tag_row = 9;
177  int tag_col = 99;
178  int tot_elems = _totElems.at(0);
179  ofstream part_file( "partiton.dat" );
180 
181  int *row = new int[tot_elems]; //open big array
182  int *col = new int[8*tot_elems]; //maximum hexa
183 
184 
185  part_file << "title = \" tecplot file for partionoing \" " << endl;
186  part_file << "variables = \"x\", \"y\", \"z\", \"partID\" " << endl;
187  part_file << "zone N = " << tot_nodes << " E = " << tot_elems <<
188  " DATAPACKING = BLOCK, VARLOCATION = ([4]=CELLCENTERED), ZONETYPE=FETRIANGLE " << endl;
189 
190  //x
191  for ( int n = 0; n < tot_nodes; n++){
192  part_file << scientific << coord[n][0] << " " ;
193  if ( n % 5 == 0 ) part_file << endl;
194  }
195  part_file << endl;
196  //y
197  for ( int n= 0; n < tot_nodes; n++){
198  part_file << scientific << coord[n][1] << " ";
199  if ( n % 5 == 0 ) part_file << endl;
200  }
201  part_file << endl;
202  //z
203  for ( int n = 0; n < tot_nodes; n++){
204  part_file << scientific << coord[n][2] << " ";
205  if ( n % 5 == 0) part_file << endl;
206  }
207  part_file << endl;
208 
209  for ( int elem = 0; elem < _nelems.at(0); elem++){
210  part_file << 0 << " ";
211  if ( elem % 10 == 0 ) part_file << endl;
212  }
213 
214  vector< shared_ptr< Array<int> > > row_root;
215  vector< shared_ptr< Array<int> > > col_root;
216 
217  //copy row and col values from root
218  row_root.push_back( shared_ptr< Array<int> > (new Array<int> (_nelems.at(0)+1) ) );
219  col_root.push_back( shared_ptr< Array<int> > (new Array<int> (_colDim.at(0) ) ) );
220 
221  for ( int r = 0; r < _nelems.at(0)+1; r++)
222  (*row_root.at(0))[r] = _row.at(0)[r];
223 
224  for ( int c = 0; c < _colDim.at(0); c++)
225  (*col_root.at(0))[c] = _col.at(0)[c];
226 
227 
228  for ( int p = 1; p < _nPart.at(0); p++){
229  MPI::COMM_WORLD.Recv( row, tot_elems, MPI::INT, p, tag_row, status_row);
230  MPI::COMM_WORLD.Recv( col, 8*tot_elems, MPI::INT, p, tag_col, status_col);
231 
232  int nelems = status_row.Get_count(MPI::INT) - 1;
233  int col_dim = status_col.Get_count(MPI::INT);
234  row_root.push_back( shared_ptr< Array<int> > (new Array<int> (nelems+1) ) );
235  col_root.push_back( shared_ptr< Array<int> > (new Array<int> (col_dim) ) );
236  //fill row_root
237  for ( int r = 0; r < nelems+1; r++)
238  (*row_root.at(p))[r] = row[r];
239  //fill col_root
240  for ( int c = 0; c < col_dim; c++)
241  (*col_root.at(p))[c] = col[c];
242 
243  for ( int elem = 0; elem < nelems; elem++){
244  part_file << p << " ";
245  if ( elem % 10 == 0 ) part_file << endl;
246  }
247  }
248  part_file << endl;
249 
250 
251  for ( int p = 0; p < _nPart.at(0); p++){
252  //connectivity
253  int nelems = row_root.at(p)->getLength() - 1;
254  for ( int elem = 0; elem < nelems; elem++){
255  int node_start = (*row_root.at(p))[elem];
256  int node_end = (*row_root.at(p))[elem+1];
257  for ( int node = node_start; node < node_end; node++)
258  part_file << setw(6) << (*col_root.at(p))[node]+1 << " ";
259  part_file <<endl;
260  }
261  }
262 
263  part_file.close();
264  delete [] row;
265  delete [] col;
266 
267  } else {
268  int tag_row = 9;
269  int tag_col = 99;
270 
271  MPI::COMM_WORLD.Send(_row.at(0), _nelems.at(0)+1, MPI::INT, 0, tag_row);
272  MPI::COMM_WORLD.Send(_col.at(0), _colDim.at(0) , MPI::INT, 0, tag_col);
273 
274  }
275 
276 }
277 
278 #endif
279  //SET PROPERTIES METHODS
280 void
282 {
283  for ( int id = 0; id < _nmesh; id++)
284  _wghtFlag.at(id) = weight_type;
285 
286 }
287 
288 void
290 {
291  for ( int id = 0; id < _nmesh; id++)
292  _numFlag.at(id) = num_flag;
293 
294 }
295 
296  // PRIVATE METHODS
297 
298 void
300 {
302  _procID = MPI::COMM_WORLD.Get_rank();
303  _nmesh = _meshList.size();
304 
305  _totElems.resize ( _nmesh );
306  _totElemsAndGhosts.resize( _nmesh );
307  _wghtFlag.resize( _nmesh );
308  _numFlag.resize ( _nmesh );
309  _ncon.resize ( _nmesh );
310  _ncommonNodes.resize( _nmesh );
311  _mapPartAndElms.resize( _nmesh );
312  _boundarySet.resize( _nmesh );
313  _interfaceSet.resize( _nmesh );
314  _mapBounIDAndCell.resize( _nmesh );
315  _mapBounIDAndBounType.resize( _nmesh );
316  _nelems.resize( _nmesh );
317  _nelemsWithGhosts.resize( _nmesh );
318  _colDim.resize( _nmesh );
319  _edgecut.resize( _nmesh );
320  _elemSet.resize(_nmesh);
321  _nonInteriorCells.resize(_nmesh ); //local numbering
322  _bndryOffsets.resize( _nmesh );
323  _interfaceOffsets.resize( _nmesh );
324  _cellToOrderedCell.resize( _nmesh );
325  _globalToLocalMappers.resize( _nmesh );
326  _localToGlobalMappers.resize( _nmesh );
327  _windowSize.resize( _nmesh );
328  _fromIndices.resize( _nmesh );
329  _toIndices.resize( _nmesh );
330  _cleanup = false;
331  _debugMode = false;
332  for ( int id = 0; id < _nmesh; id++){
333  StorageSite& site = _meshList[id]->getCells();
334  _totElems.at(id) = site.getSelfCount();
335  _totElemsAndGhosts.at(id) = site.getCount();
336  _wghtFlag.at(id) = int( NOWEIGHTS ); //No Weights : default value
337  _numFlag.at(id) = int( C_STYLE ); //C Style numbering :: default_value
338  _ncon.at(id) = 2; //number of specified weights : default value for contigous domain ncon > 1
339  //if it is assemble mesh ncon will be equal to num of assembled mesh
340  if ( _meshList.at(id)->isMergedMesh() )
341  _ncon.at(id) = _meshList.at(id)->getNumOfAssembleMesh();
342 
343  //assign ubvec
344  _ubvec.push_back( new float[_ncon.at(id) ] );
345  for ( int n = 0; n < _ncon.at(id); n++)
346  _ubvec.at(id)[n] = 1.05f; //1.05 suggested value from parMetis manual
347 
348 
349  //assign elementy type
350  switch (_eType.at(id) ){
351  case TRI :
352  _ncommonNodes.at(id) = 2;
353  break;
354  case TETRA :
355  _ncommonNodes.at(id) = 3;
356  break;
357  case HEXA :
358  _ncommonNodes.at(id) = 4;
359  break;
360  case QUAD :
361  _ncommonNodes.at(id) = 2;
362  break;
363  default :
364  cout << " ONLY TRIANGLE, TETRAHEDRAL, HEXAHEDRAL and QUADRILATERAL elements must be chose " <<
365  endl; abort();
366  }
367 
368  //get tpwgts
369  int ncon_by_nparts = _ncon.at(id) * _nPart.at(id);
370  _tpwgts.push_back( new float[ ncon_by_nparts ] );
371  for (int n = 0; n < ncon_by_nparts; n++){
372  _tpwgts.at(id)[n] = 1.0f / float( ncon_by_nparts );
373  }
374 
375  //edgecut
376  _edgecut.at(id) = -1;
377 
378  _interfaceMeshCounts.push_back ( ArrayIntPtr( new Array<int>(_nPart.at(id)) ) );
379  _procTotalInterfaces.push_back ( ArrayIntPtr( new Array<int>(_nPart.at(id)) ) );
380 
381  }
382 
383 
384 }
385 
386 
387 
388 void
390 {
391 
392  for (int id = 0; id < _nmesh; id++){
393  int nelems = _totElems[id];
394  int npart = _nPart[id];
395  int nremainder = nelems % npart;
396  int init_dist = (nelems - nremainder) / npart;
397  _elemDist.push_back( new Array<int>( npart) );
398  _globalIndx.push_back( new Array<int>(npart+1) );
399  *_elemDist.at(id) = init_dist;
400 
401  int p = 0;
402  while ( nremainder != 0 ){
403  (*_elemDist.at(id))[p % npart]++;
404  nremainder--;
405  p++;
406  }
407 
408  (*_globalIndx[id]) = 0;
409  int sum_elem = 0;
410  for ( int n = 1; n <= npart; n++){
411  sum_elem += (*_elemDist.at(id))[n-1];
412  ((*_globalIndx.at(id))[n]) = sum_elem;
413  }
414  }
415 
416  for (int id = 0; id < _nmesh; id++){
417  int mesh_nlocal = (*_elemDist.at(id))[_procID];
418  _part.push_back( new int[mesh_nlocal] );
419  for ( int n = 0; n < mesh_nlocal; n++)
420  _part.at(id)[n] = -1;
421  }
422 
423  if ( _debugMode )
425 
426 }
427 
428 
429 //debug compute_elem_dist() function
430 void
432 {
433  //open file
434  debug_file_open("compute_elem_dist");
435  //_totElms
436  _debugFile << "_totElems = " << _totElems[0] << endl;
437  _debugFile << endl;
438  //_npart
439  _debugFile << "_npart = " << _nPart[0] << endl;
440  _debugFile << endl;
441  //_elemDist
442  _debugFile << "_elemDist : " << endl;
443  _debugFile << endl;
444  for( int n = 0; n < _nPart[0]; n++ )
445  _debugFile << "_elemDist[" << n << "] = " << (*_elemDist[0])[n] << endl;
446  _debugFile << endl;
447  //_globalIndx
448  _debugFile << "_globalIndx : " << endl;
449  for( int n = 0; n < _nPart[0]+1; n++ )
450  _debugFile << "_globalIndx[" << n << "] = " << (*_globalIndx[0])[n] << endl;
451  _debugFile << endl;
452  //close file
454 
455 }
456 
457 
458 
459 
460 void
462 {
463 
464  for (int id = 0; id < _nmesh; id++){
465  //allocate local ePtr for parMetis
466  int mesh_nlocal = (*_elemDist.at(id))[_procID];
467  _ePtr.push_back( new int[mesh_nlocal+1] );
468  _eElm.push_back( new int[mesh_nlocal+1] );
469  //element weights
470  _elmWght.push_back( new int[_ncon.at(id)*mesh_nlocal] );
471  if ( !_meshList.at(id)->isMergedMesh() ){
472  _wghtFlag.at(id) = int( NOWEIGHTS ); //No Weights : default value
473  for ( int n = 0; n < _ncon.at(id)*mesh_nlocal; n++)
474  _elmWght.at(id)[n] = 1;
475  } else {
476  _wghtFlag.at(id) = int( WEIGTHS_ONLY_VERTICES );
477  const Array<int>& cellColors = _meshList.at(id)->getCellColors();
478  int indx = 0 ;
479  for ( int n =0; n < mesh_nlocal; n++ ){
480  for ( int i = 0; i < _meshList.at(id)->getNumOfAssembleMesh(); i++ ){
481  _elmWght.at(id)[indx] = 0;
482  if ( cellColors[ (*_globalIndx[id])[_procID] + n ] == i )
483  _elmWght.at(id)[indx] = 1;
484  indx++;
485  }
486  }
487  }
488  //allocate local eInd for ParMETIS
489  _eInd.push_back( new int[get_local_nodes(id)] );
490 
491 // //setting ePtr and eInd for ParMETIS
492  set_eptr_eind(id);
493  }
494 
495  if ( _debugMode )
497 
498 }
499 
500 int
502 {
503  const Mesh* mesh = _meshList[id];
504  const CRConnectivity& cellNodes = mesh->getCellNodes();
505 
506  //get local nodes
507  int local_nodes = 0;
508  int nstart = (*_globalIndx.at(id))[_procID];
509  int npart = nstart + (*_elemDist[id])[_procID];
510  for ( int n = nstart; n < npart; n++)
511  local_nodes += cellNodes.getCount(n);
512 
513  return local_nodes;
514 }
515 
516 void
518 {
519  const Mesh* mesh = _meshList[id];
520  const CRConnectivity& cellNodes = mesh->getCellNodes();
521 
522  int elem_start = (*_globalIndx.at(id))[_procID];
523  int elem_finish = elem_start + (*_elemDist[id])[_procID];
524  int indxInd = 0;
525  int indxPtr = 0;
526  _ePtr.at(id)[indxPtr] = 0;
527  for ( int elem = elem_start; elem < elem_finish; elem++ ){
528  _eElm.at(id)[indxPtr] = elem; //mapping local to global Index
529  indxPtr++;
530  _ePtr.at(id)[indxPtr] = _ePtr.at(id)[indxPtr-1] + cellNodes.getCount(elem);
531  if ( _eType.at(id) == TRI || _eType.at(id) == TETRA || _eType.at(id) == HEXA ){ // connectivity orientation is not important
532  for ( int node = 0; node < cellNodes.getCount(elem); node++ )
533  _eInd.at(id)[indxInd++] = cellNodes(elem,node);
534  }
535 
536  if ( _eType.at(id) == QUAD ) { //connectivity orientation is reversed for QUADs since Parmetis require clockwise orientation
537  for ( int node = cellNodes.getCount(elem)-1; node >=0; node-- )
538  _eInd.at(id)[indxInd++] = cellNodes(elem,node);
539  }
540 
541  }
542 
543 }
544 
545 void
547 {
548  debug_file_open("elem_connectivity");
549  //ePtr
550  _debugFile << " _ePtr :" << endl;
551  _debugFile << endl;
552  int mesh_nlocal = (*_elemDist.at(0))[_procID];
553  for ( int i = 0; i <= mesh_nlocal; i++ ){
554  _debugFile << " _ePtr[" << i << "] = " << _ePtr[0][i] << endl;
555  }
556  _debugFile << endl;
557  //eInd
558  _debugFile << "_eInd : " << endl;
559  _debugFile << endl;
560  for ( int i = 0; i < mesh_nlocal; i++ ){
561  _debugFile << "_eInd[" << i << "], glblCellID = " << setw(3) << _eElm.at(0)[i] << ", ";
562  for ( int j = _ePtr[0][i]; j < _ePtr[0][i+1]; j++ ){
563  _debugFile << setw(5) << _eInd.at(0)[j] << " ";
564  }
565  _debugFile << endl;
566  }
567  _debugFile << endl;
569 }
570 
571 
572 void
574 {
575  MPI_Comm comm_world = MPI::COMM_WORLD;
576  for ( int id = 0; id < _nmesh; id++){
577  ParMETIS_V3_PartMeshKway( &(*_globalIndx.at(id))[0], _ePtr.at(id), _eInd.at(id),
578  _elmWght.at(id), &_wghtFlag.at(id), &_numFlag.at(id), &_ncon.at(id), &_ncommonNodes.at(id),
579  &_nPart.at(id), _tpwgts.at(id), _ubvec.at(id), &_options, &_edgecut.at(id), _part.at(id), &comm_world );
580 
581  }
582 
583  if ( _debugMode )
585 
586 }
587 
588 //debuggin parmetis_mesh
589 void
591 {
592 
593  debug_file_open("parmetis_mesh");
594  //_part
595  _debugFile << "_part :" << endl;
596  _debugFile << endl;
597  int elem_start = (*_globalIndx.at(0))[_procID];
598  int elem_finish = elem_start + (*_elemDist[0])[_procID];
599  int indx = 0;
600  for ( int i = elem_start; i < elem_finish; i++ ){
601  _debugFile << "_part[" << indx << "] = " << _part.at(0)[indx] << endl;
602  indx++;
603  }
604  _debugFile << endl;
606 
607 }
608 
609 
610 void
611 MeshPartitioner::fiedler_order( const string& fname )
612 {
613  _partTYPE = FIEDLER;
614  //read permutation file
615  int totElms = _totElems[0];
616  int totElmsAndGhost = _totElemsAndGhosts[0];
617  _fiedlerMap = ArrayIntPtr( new Array<int>(totElmsAndGhost) );
618  ifstream permutation_file( fname.c_str() );
619  int cellID = -1;
620  for ( int i = 0; i < totElms; i++ ){
621  permutation_file >> cellID;
622  (*_fiedlerMap)[i] = cellID - 1; //permutation
623  }
624  for ( int i = totElms; i < totElmsAndGhost; i++ ){
625  (*_fiedlerMap)[i] = i; //permutation
626  }
627 
628  permutation_file.close();
629 }
630 
631 void
633 {
634  MPI::COMM_WORLD.Barrier();
635 
636  //copy to part
637  int elem_start = (*_globalIndx.at(0))[_procID];
638  int elem_finish = elem_start + (*_elemDist[0])[_procID];
639 
640  int indx = 0;
641  for ( int i = elem_start; i < elem_finish; i++ ){
642  _part.at(0)[indx] = _procID;
643  indx++;
644  }
645 
646  CRConnectivity& faceCells = _meshList[0]->getAllFaceCells();
647  faceCells.reorder( *_fiedlerMap );
648 
649  MPI::COMM_WORLD.Barrier();
650 
651  if ( _debugMode )
653 
654 }
655 
656 //debuggin fiedler partition
657 void
659 {
660  debug_file_open("fiedler_partition");
661  //_fieldermap
662  _debugFile << "Fiedler Map :" << endl;
663  _debugFile << endl;
664  int totElms = _totElems[0];
665  for ( int n = 0; n < totElms; n++ )
666  _debugFile << "_fiedlerMap[" << n << "] = " << (*_fiedlerMap)[n] << endl;
667  _debugFile << endl;
668  //_part
669  _debugFile << "_part :" << endl;
670  _debugFile << endl;
671  int elem_start = (*_globalIndx.at(0))[_procID];
672  int elem_finish = elem_start + (*_elemDist[0])[_procID];
673  int indx = 0;
674  for ( int i = elem_start; i < elem_finish; i++ ){
675  _debugFile << "_part[" << indx << "] = " << _part.at(0)[indx] << endl;
676  indx++;
677  }
678  _debugFile << endl;
679  //faceCells after Fiedler
680  CRConnectivity& faceCells = _meshList[0]->getAllFaceCells();
681  CRConnectivityPrintFile( faceCells, "faceCells" );
683 
684 }
685 
686 //this store local partID and local elm number mappings (global elem number can be deduct from _eElm data structure(eElem[local] = globalID])
687 void
689 {
690  for (int id = 0; id < _nmesh; id++){
691  int nlocal_elem = (*_elemDist.at(id))[_procID];
692  for ( int elm = 0; elm < nlocal_elem; elm++){
693  int partID = _part[id][elm];
694  _mapPartAndElms.at(id).insert(pair<int,int>(partID,elm));
695  }
696 
697  }
698 
699  if ( _debugMode )
701 }
702 
703 void
705 {
706  //open file
707  debug_file_open("map_part_elms");
708  //header
709  _debugFile << " _mapPartAndElms : " << endl;
710  _debugFile << endl;
711  for ( int p = 0; p < _nPart[0]; p++){
712  multimap<int,int>::iterator it, itlow, itup;
713  itlow = _mapPartAndElms.at(0).lower_bound(p);
714  itup = _mapPartAndElms.at(0).upper_bound(p);
715  for( it = itlow; it != itup; it++)
716  _debugFile << " partID = " << it->first << " elemID = " << it->second << endl;
717  }
718  _debugFile << endl;
719  //close file
721 
722 }
723 //compute _nelems and _colDim for each partition
724 void
726 {
727  for ( int id = 0; id < _nmesh; id++){
728  for ( int partID = 0; partID < _nPart.at(id); partID++){
729  int nelems_local = _mapPartAndElms.at(id).count(partID);
730 
731  //sum to find size of ncol
732  multimap<int,int>::const_iterator it = _mapPartAndElms.at(id).find(partID);
733  multimap<int,int>::const_iterator itlow = _mapPartAndElms.at(id).lower_bound(partID);
734  multimap<int,int>::const_iterator itup = _mapPartAndElms.at(id).upper_bound(partID);
735  int ncol_local = 0;
736  for ( it = itlow; it != itup; it++){
737  int pos = it->second; // element number
738  ncol_local += _ePtr.at(id)[pos+1] - _ePtr.at(id)[pos];
739  }
740 
741  MPI::COMM_WORLD.Reduce(&nelems_local, &_nelems.at(id), 1, MPI::INT, MPI::SUM, partID);
742  MPI::COMM_WORLD.Reduce(&ncol_local, &_colDim.at(id), 1, MPI::INT, MPI::SUM, partID);
743 
744  }
745  //now each processor now how many elements and nodes
746  _row.push_back ( new int[_nelems.at(id)+1] );
747  _elem.push_back( new int[_nelems.at(id) ] );
748  _col.push_back ( new int[_colDim.at(id)] );
749  for ( int n = 0; n < _nelems.at(id)+1; n++ )
750  _row.at(id)[n] = -1;
751  for ( int n = 0; n < _colDim.at(id); n++)
752  _col.at(id)[n] = -1;
753  for ( int n = 0; n < _nelems.at(id); n++)
754  _elem.at(id)[n] = -1;
755 
756  }
757 
758  if ( _debugMode )
760 
761 }
762 
763 //debug count_elems_part
764 void
766 {
767  //open debug file
768  debug_file_open("count_elems_part");
769  //_nelems
770  _debugFile << "_nelems = " << _nelems.at(0) << endl;
771  _debugFile << endl;
772  //_colDim
773  _debugFile << "_colDim = " << _colDim.at(0) << endl;
774  //close debug file
776 
777 
778 
779 }
780 
781 
782 
783 void
785 {
786 
787  for ( int id = 0; id < _nmesh; id++){
788 
789  int *countsRow = new int[_nPart.at(id)];
790  int *countsCol = new int[_nPart.at(id)];
791  int *offsetsRow = new int[_nPart.at(id)];
792  int *offsetsCol = new int[_nPart.at(id)];
793 
794 
795  for ( int partID = 0; partID < _nPart.at(id); partID++){
796  int nelems_local = _mapPartAndElms.at(id).count(partID);
797  int *row_local = new int[nelems_local];
798  int *elem_local = new int[nelems_local];
799 
800  multimap<int,int>::const_iterator it = _mapPartAndElms.at(id).find(partID);
801  multimap<int,int>::const_iterator itlow = _mapPartAndElms.at(id).lower_bound(partID);
802  multimap<int,int>::const_iterator itup = _mapPartAndElms.at(id).upper_bound(partID);
803 
804  //fill row array
805  int indx = 0;
806  int ncol_local = 0;
807  for ( it = itlow; it != itup; it++){
808  int pos = it->second; // element number
809  ncol_local += _ePtr.at(id)[pos+1] - _ePtr.at(id)[pos];
810  row_local[indx] = _ePtr.at(id)[pos+1]-_ePtr.at(id)[pos]; //aggregation before shipping
811  elem_local[indx] = _eElm.at(id)[pos]; //globalID stored in _eElm
812  indx++;
813  }
814 
815  //fill col array
816  int *col_local = new int[ncol_local];
817  indx = 0;
818  for ( it = itlow; it != itup; it++ ){
819  int elID = it->second;
820  int node_start = _ePtr.at(id)[elID];
821  int node_end = _ePtr.at(id)[elID+1];
822  for ( int node = node_start; node < node_end; node++){
823  col_local[indx++] = _eInd.at(id)[node];
824  }
825  }
826 
827  //forming counts
828  int nrow_local = nelems_local;
829  MPI::COMM_WORLD.Allgather(&nrow_local, 1, MPI::INT, countsRow, 1, MPI::INT);
830  MPI::COMM_WORLD.Allgather(&ncol_local, 1, MPI::INT, countsCol, 1, MPI::INT);
831 
832 
833  //form offsets
834  offsetsRow[0] = 0;
835  offsetsCol[0] = 0;
836  for ( int p = 1; p < int(_nPart.at(id)); p++ ){
837  offsetsRow[p] = countsRow[p-1] + offsetsRow[p-1];
838  offsetsCol[p] = countsCol[p-1] + offsetsCol[p-1];
839  }
840 
841  //gathering partial partions for _row and _col
842  MPI::COMM_WORLD.Gatherv(row_local, countsRow[_procID], MPI::INT, _row.at(id),
843  countsRow, offsetsRow, MPI::INT, partID);
844 
845  MPI::COMM_WORLD.Gatherv(col_local, countsCol[_procID], MPI::INT, _col.at(id),
846  countsCol, offsetsCol, MPI::INT, partID);
847 
848  MPI::COMM_WORLD.Gatherv(elem_local, countsRow[_procID], MPI::INT, _elem.at(id),
849  countsRow, offsetsRow, MPI::INT, partID);
850 
851 
852  delete [] row_local;
853  delete [] col_local;
854  delete [] elem_local;
855 
856  } // for::partID
857 
858  delete [] countsRow ;
859  delete [] countsCol ;
860  delete [] offsetsRow;
861  delete [] offsetsCol;
862 
863  } // for::meshID
864 
865 
866  shift_sum_row();
867 
868  //clean up
869  if ( _cleanup )
871 
872  if ( _debugMode )
874 
875 }
876 
877 void
879 {
880  for ( int id = 0; id < _nmesh; id++){
881  //shift [0,n] to [1,n+1]
882  for ( int n = _nelems.at(id); n > 0; n--)
883  _row.at(id)[n] = _row.at(id)[n-1];
884  _row.at(id)[0] = 0;
885  //summing row ex: row = {0,3,6,9,...} for triangle (three nodes)
886  for ( int n = 1; n < _nelems.at(id)+1; n++ )
887  _row.at(id)[n] += _row.at(id)[n-1];
888 
889  }
890 
891 
892 }
893 
894 
895 void
897 {
898  //dont release memory until all process reach this point
899  MPI::COMM_WORLD.Barrier();
900  vector< int* > ::iterator it_int;
901  for ( it_int = _ePtr.begin(); it_int != _ePtr.end(); it_int++)
902  delete [] *it_int;
903 
904  for ( it_int = _eInd.begin(); it_int != _eInd.end(); it_int++)
905  delete [] *it_int;
906 
907  for ( it_int = _eElm.begin(); it_int != _eElm.end(); it_int++)
908  delete [] *it_int;
909 
910  for ( it_int = _elmWght.begin(); it_int != _elmWght.end(); it_int++)
911  delete [] *it_int;
912 
913  for ( it_int = _row.begin(); it_int != _row.end(); it_int++)
914  delete [] *it_int;
915 
916  for ( it_int = _col.begin(); it_int != _col.end(); it_int++)
917  delete [] *it_int;
918 
919 
920 }
921 
922 void
924 {
925  debug_file_open("exchange_part_elems");
926  //_row
927  for ( int n = 0; n < _nelems.at(0)+1; n++){
928  _debugFile << " _row[" << n << "] = " << _row.at(0)[n] << endl;
929  }
930  _debugFile << endl;
931  //_col
932  for ( int n = 0; n < _colDim.at(0); n++){
933  _debugFile << " _col[" << n << "] = " << _col.at(0)[n] << endl;
934  }
935  _debugFile << endl;
936  //elem
937  for ( int n = 0; n < _nelems.at(0); n++){
938  _debugFile << " _elem[" << n << "] = " << _elem.at(0)[n] << endl;
939  }
940  _debugFile << endl;
942 
943 }
944 
945 
946 
947 void
949 {
950  for ( int id = 0; id < _nmesh; id++){
951  //interior faces
952  _meshListLocal.at(id)->createInteriorFaceGroup( count_interior_faces(id) );
953 
954  //boundary faces
955  set<int>::const_iterator it_set;
956  for ( it_set = _boundarySet.at(id).begin(); it_set != _boundarySet.at(id).end(); it_set++){
957  int bndryID = *it_set;
958  int size = _mapBounIDAndCell.at(id).count(bndryID);
959  if ( size > 0 ){
960  int offset = _bndryOffsets.at(id)[ bndryID ] ;
961  string boundaryType = _mapBounIDAndBounType.at(id)[bndryID];
962  _meshListLocal.at(id)->createBoundaryFaceGroup(size, offset, bndryID, boundaryType);
963  }
964  }
965 
966  //then interface faces
967  for ( it_set = _interfaceSet.at(id).begin(); it_set != _interfaceSet.at(id).end(); it_set++){
968  int interfaceID = *it_set;
969  int size = int(_interfaceMap.at(id).count( interfaceID ) );
970  int offset = _interfaceOffsets.at(id)[ interfaceID ];
971 // _meshListLocal.at(id)->createInterfaceGroup( size, offset, interfaceID );
972 // structural solver complained and thought that it is boundayr so we assign as -
973 // but this interface id might be used in meshassembly and meshdismantler
974  _meshListLocal.at(id)->createInterfaceGroup( size, offset, -interfaceID );
975  shared_ptr<StorageSite> siteGather ( new StorageSite(size) );
976  shared_ptr<StorageSite> siteScatter( new StorageSite(size) );
977  siteGather->setScatterProcID( _procID );
978  siteGather->setGatherProcID ( interfaceID );
979  siteScatter->setScatterProcID( _procID );
980  siteScatter->setGatherProcID ( interfaceID );
981  int packed_info = (std::max(_procID,interfaceID) << 16 ) | ( std::min(_procID,interfaceID) );
982  siteScatter->setTag( packed_info );
983 
984 
985  Mesh::PartIDMeshIDPair pairID = make_pair<int,int>(interfaceID, id);
986  _meshListLocal.at(id)->createGhostCellSiteScatter( pairID, siteScatter );
987  _meshListLocal.at(id)->createGhostCellSiteGather ( pairID, siteScatter );
988 
989  }
990 
991  _meshListLocal.at(id)->setCoordinates( _coord.at(id) );
992  _meshListLocal.at(id)->setFaceNodes ( _faceNodesOrdered.at(id) );
993  _meshListLocal.at(id)->setFaceCells ( _faceCellsOrdered.at(id) );
994  }
995 
996 }
997 
998 //if it is merged, we want to fill color array in Mesh class for further usage
999 void
1001 {
1002  //get number of meshes assembled from meshList
1003  int nmesh = _meshList.at(0)->getNumOfAssembleMesh();
1004  //assing nmesh and make Mesh::_isAssembledMesh == true
1005  _meshListLocal.at(0)->setNumOfAssembleMesh( nmesh );
1006  _meshListLocal.at(0)->createCellColor();
1007  //get cellsite storagesite
1008  const StorageSite& cellSite = _meshListLocal.at(0)->getCells();
1009  Array<int>& colorGlbl = _meshList.at(0)->getCellColors();
1010  Array<int>& colorLocal = _meshListLocal.at(0)->getCellColors();
1011  Array<int>& colorOtherLocal = _meshListLocal.at(0)->getCellColorsOther();
1012  const map<int,int>& localToGlobalMappers = _localToGlobalMappers.at(0);
1013  //loop first over inner cells to color them
1014  for ( int i = 0; i < cellSite.getSelfCount(); i++ ){
1015  int glblID = localToGlobalMappers.find(i)->second;
1016  colorLocal[i] = colorGlbl[ glblID ];
1017  }
1018  //coloring other cells (boundary+ghostcells)
1019  //we check across cell's color, they should have the same color.
1020  const CRConnectivity& cellCells = _meshListLocal.at(0)->getCellCells();
1021  for ( int i = cellSite.getSelfCount(); i < cellSite.getCount(); i++ ){
1022  int acrossCellID = cellCells(i,0); //ghost or boundary has only one cell connected
1023  colorLocal[i] = colorLocal[ acrossCellID ];
1024  }
1025 
1026  //colorOtherLocal loop first over inner cells to color them, this color ghost cell according to their real location
1027  colorOtherLocal.resize( cellSite.getCountLevel1() );
1028  const Array<int>& localToGlobal = _meshListLocal.at(0)->getLocalToGlobal();
1029  for ( int i = 0; i < cellSite.getCountLevel1(); i++ ){
1030  int glblID = localToGlobal[i];
1031  colorOtherLocal[i] = colorGlbl[ glblID ];
1032  }
1033 
1034 
1035 }
1036 
1037 
1038 
1039 //get boundary information for process
1040 void
1042 {
1043 
1044  //mapBounIDAndCell store global information
1045  //_mapBounIDAndCell store local (process) information
1046  multimap<int,int> mapBounIDAndCell;
1047 
1048  //boundary information has been stored
1049  const FaceGroupList& boundaryFaceGroups = _meshList.at(id)->getBoundaryFaceGroups();
1050  int indx = _totElems.at(id);
1051 
1052  for ( int bounID = 0; bounID < int(boundaryFaceGroups.size()); bounID++){
1053  int group_id = boundaryFaceGroups.at(bounID)->id;
1054  _boundarySet.at(id).insert( group_id );
1055  string boun_type( boundaryFaceGroups.at(bounID)->groupType );
1056 
1057  _mapBounIDAndBounType.at(id).insert( pair<int,string>(group_id, boun_type) );
1058 
1059  int nBounElm = boundaryFaceGroups.at(bounID)->site.getCount();
1060 
1061  for ( int n = 0; n < nBounElm; n++){
1062  mapBounIDAndCell.insert( pair<int,int>(group_id, indx) );
1063  indx++;
1064  }
1065  }
1066 
1067  //putting local elements in set to check fast way
1068  for ( int n = 0; n < _nelems.at(id); n++ )
1069  _elemSet.at(id).insert( _elem.at(id)[n] );
1070 
1071  multimap<int,int>::const_iterator it;
1072  const CRConnectivity& cellCells = _meshList.at(id)->getCellCells();
1073  for ( it = mapBounIDAndCell.begin(); it != mapBounIDAndCell.end(); it++ ){
1074  int boun_cell_id = it->second;
1075  int neigh_id = cellCells(boun_cell_id,0); //assuming just one neighbour for boundary
1076  if ( _elemSet.at(id).count( neigh_id ) > 0 )
1077  _mapBounIDAndCell.at(id).insert( pair<int,int>(it->first, it->second) );
1078  }
1079 
1080  if ( _debugMode )
1082 
1083 }
1084 
1085 void
1087 {
1088  //open file
1089  debug_file_open("mapBounIDAndCell");
1090  //_elemset
1091  _debugFile << "_boundarySet : " << endl;
1092  _debugFile << endl;
1093  foreach( const set<int>::value_type id ,_boundarySet.at(0) ){
1094  _debugFile << id << endl;
1095  }
1096  _debugFile << endl;
1097  //dump boundary names
1098  _debugFile << "_mapBounIDAndBounType : " << endl;
1099  _debugFile << endl;
1100  multimap<int,string>::iterator it_multimapS;
1101  for ( it_multimapS = _mapBounIDAndBounType.at(0).begin();
1102  it_multimapS != _mapBounIDAndBounType.at(0).end(); it_multimapS++)
1103  _debugFile << "Boundary multimap = " << it_multimapS->first << " " << it_multimapS->second << endl;
1104  _debugFile << endl;
1105  //_elemset
1106  _debugFile << "_elemSet : " << endl;
1107  _debugFile << endl;
1108  foreach( const set<int>::value_type cellID ,_elemSet.at(0) ){
1109  _debugFile << cellID << endl;
1110  }
1111  _debugFile << endl;
1112  //boundaryID to Cell
1113  multimap<int,int>::iterator it_multimap;
1114  for ( it_multimap = _mapBounIDAndCell.at(0).begin();
1115  it_multimap != _mapBounIDAndCell.at(0).end(); it_multimap++)
1116  _debugFile << "Boundary multimap = " << it_multimap->first << " " << it_multimap->second << endl;
1117  _debugFile << endl;
1118 
1119  debug_file_close();
1120 }
1121 
1122 //adding ghost cell elements to local elements
1123 void
1125 {
1126  int tot_cells = _mapBounIDAndCell.at(id).size() + _nelems.at(id);
1127  _nelemsWithGhosts.at(id) = tot_cells;
1128  _elemWithGhosts.push_back( new int[ tot_cells] );
1129 
1130  //assign old values
1131  for ( int n = 0; n < _nelems.at(id); n++)
1132  _elemWithGhosts.at(id)[n] = _elem.at(id)[n];
1133  //ghost part assigned
1134  multimap<int,int>::const_iterator it;
1135  int indx = _nelems.at(id);
1136  for ( it = _mapBounIDAndCell.at(id).begin(); it != _mapBounIDAndCell.at(id).end(); it++){
1137  _elemWithGhosts.at(id)[indx] = it->second;
1138  indx++;
1139  }
1140 
1141  if ( _debugMode )
1143 
1144 }
1145 
1146 void
1148 {
1149  //open file
1150  debug_file_open("resize_elem");
1151  //_nelemsWithGhosts
1152  _debugFile << "_nelemsWithGhosts : " << _nelemsWithGhosts.at(0) << endl;
1153  _debugFile << endl;
1154  //_elemWithGhosts
1155  _debugFile << "_elemWithGhosts : " << endl;
1156  _debugFile << endl;
1157  for ( int n = 0; n < _nelemsWithGhosts.at(0); n++ )
1158  _debugFile << _elemWithGhosts.at(0)[n] << endl;
1159  //close file
1160  debug_file_close();
1161 
1162 }
1163 
1164 
1165 //construct CRConnectivity cellParts
1166 void
1168 {
1169  vector< int* > elemGlobal;
1170  vector< int* > distGlobal; //total partition + 1 suche that 0, 5, 10, 15
1171 
1172  for ( int id = 0; id < _nmesh; id++){
1173  mapBounIDAndCell(id);
1174  resize_elem(id);
1175 
1176  elemGlobal.push_back( new int [_totElemsAndGhosts.at(id) ] ); //global array to aggregation
1177  distGlobal.push_back( new int [ _nPart.at(id) + 1 ] );
1178  int *offsets = new int [ _nPart.at(id) ];
1179 
1180 
1181  MPI::COMM_WORLD.Allgather(&_nelemsWithGhosts.at(id), 1, MPI::INT, distGlobal.at(id), 1, MPI::INT);
1182  //form offsets
1183  offsets[0] = 0;
1184  for ( int p = 1; p < int(_nPart.at(id)); p++ ){
1185  offsets[p] = distGlobal.at(id)[p-1] + offsets[p-1];
1186  }
1187 
1188  //gathering partial partions for _row and _col
1189  MPI::COMM_WORLD.Allgatherv(_elemWithGhosts.at(id), _nelemsWithGhosts.at(id), MPI::INT, elemGlobal.at(id),
1190  distGlobal.at(id), offsets, MPI::INT);
1191 
1192 
1193  //shift distGlobal to one right
1194  for ( int i = int(_nPart.at(id)); i > 0; i--)
1195  distGlobal.at(id)[i] = distGlobal.at(id)[i-1];
1196 
1197  distGlobal.at(id)[0] = 0;
1198 
1199  //summing distGlobal
1200  for ( int i = 1; i < _nPart.at(id)+1; i++ ){
1201  distGlobal.at(id)[i] += distGlobal.at(id)[i-1];
1202  }
1203  delete [] offsets;
1204 
1205 
1206  //forming CRConnectivity for cellPart
1207  int nghost = _totElemsAndGhosts.at(id) - _totElems.at(id);
1208  _cellSiteGlobal.push_back( StorageSitePtr(new StorageSite(_totElems.at(id), nghost )) );
1209  _partSite.push_back( StorageSitePtr(new StorageSite(_nPart.at(id)) ) );
1210 
1211  _cellParts.push_back( CRConnectivityPtr(new CRConnectivity( *_cellSiteGlobal.at(id), *_partSite.at(id)) ) );
1212 
1213  _cellParts.at(id)->initCount();
1214 
1215  for ( int indx = 0; indx < _totElemsAndGhosts.at(id); indx++)
1216  _cellParts.at(id)->addCount(indx,1);
1217 
1218  _cellParts.at(id)->finishCount();
1219 
1220  int index = 0;
1221  while ( index < _nPart.at(id) ){
1222  for ( int n = distGlobal.at(id)[index]; n < distGlobal.at(id)[index+1]; n++){
1223 
1224  _cellParts.at(id)->add(elemGlobal.at(id)[n],index);
1225  }
1226  index++;
1227  }
1228 
1229  _cellParts.at(id)->finishAdd();
1230  _partCells.push_back( _cellParts.at(id)->getTranspose() );
1231  }
1232 
1233 
1234  //deleting allocated arrays in this method
1235  vector< int* > ::iterator it_int;
1236  for ( it_int = elemGlobal.begin(); it_int != elemGlobal.end(); it_int++)
1237  delete [] *it_int;
1238 
1239  for ( it_int = distGlobal.begin(); it_int != distGlobal.end(); it_int++)
1240  delete [] *it_int;
1241 
1242  if ( _debugMode )
1244 
1245 }
1246 
1247 //debug
1248 void
1250 {
1251  //open file
1252  debug_file_open("CRConnectivity_cellParts");
1253  //_cellParts
1254  _debugFile << " _cellParts : " << endl;
1255  _debugFile << endl;
1256  _debugFile << " _cellParts->getRowDim() = " << _cellParts.at(0)->getRowDim() << endl;
1257  _debugFile << " _cellParts->getColDim() = " << _cellParts.at(0)->getColDim() << endl;
1258  _debugFile << endl;
1259  const Array<int>& rowCellParts = _cellParts.at(0)->getRow();
1260  const Array<int>& colCellParts = _cellParts.at(0)->getCol();
1261  for ( int n = 0;n < _cellParts.at(0)->getRowDim(); n++){
1262  _debugFile << " row[" << n << "] = " << rowCellParts[n] << " ";
1263  int nnodes = rowCellParts[n+1] - rowCellParts[n];
1264  for ( int node = 0; node < nnodes; node++){
1265  _debugFile << colCellParts[ rowCellParts[n] + node ] << " ";
1266  }
1267  _debugFile << endl;
1268  }
1269  //close file
1270  debug_file_close();
1271 
1272 }
1273 
1274 //construct CRConnectivity faceParts
1275 void
1277 {
1278  for ( int id = 0; id < _nmesh; id++){
1279  _faceCellsGlobal.push_back( &_meshList.at(id)->getAllFaceCells() );
1280  _faceNodesGlobal.push_back( &_meshList.at(id)->getAllFaceNodes() );
1281 
1282  _faceParts.push_back( _faceCellsGlobal.at(id)->multiply( *_cellParts.at(id), false) );
1283  _partFaces.push_back( _faceParts.at(id)->getTranspose() );
1284  _partNodes.push_back( _partFaces.at(id)->multiply( *_faceNodesGlobal.at(id), false) );
1285  }
1286 
1287  if ( _debugMode )
1289 }
1290 
1291 //debug
1292 void
1294 {
1295  //open file
1296  debug_file_open("CRConnectivity_faceParts");
1297  //faceParts
1298  _debugFile << " _faceParts : " << endl;
1299  _debugFile << endl;
1300  _debugFile << " _faceParts->getRowDim() = " << _faceParts.at(0)->getRowDim() << endl;
1301  _debugFile << " _faceParts->getColDim() = " << _faceParts.at(0)->getColDim() << endl;
1302  const Array<int>& rowFaceParts = _faceParts.at(0)->getRow();
1303  const Array<int>& colFaceParts = _faceParts.at(0)->getCol();
1304  for ( int n = 0; n < _faceParts.at(0)->getRowDim();n++){
1305  _debugFile << " row[" << n <<"] = " ;
1306  int nnodes = rowFaceParts[n+1] - rowFaceParts[n];
1307  for ( int node = 0; node < nnodes; node++){
1308  _debugFile << colFaceParts[ rowFaceParts[n] + node ] << " ";
1309  }
1310  _debugFile << endl;
1311  }
1312 
1313  _debugFile << endl;
1314  //close file
1315  debug_file_close();
1316 
1317 
1318 }
1319 
1320 
1321 
1322 //forming faceCells and faceNodes on each local mesh
1323 void
1325 {
1326  vector< ArrayIntPtr > indices;
1327 
1328  for ( int id = 0; id < _nmesh; id++){
1329  //form site
1330  int face_count = _partFaces.at(id)->getCount( _procID );
1331  int node_count = _partNodes.at(id)->getCount( _procID );
1332 
1333  _faceSite.push_back( StorageSitePtr(new StorageSite(face_count)) );
1334  _nodeSite.push_back( StorageSitePtr(new StorageSite(node_count)) );
1335 
1336  const Array<int>& row = _partFaces.at(id)->getRow();
1337  const Array<int>& col = _partFaces.at(id)->getCol();
1338  //forming indices
1339  indices.push_back( ArrayIntPtr(new Array<int>( face_count )) );
1340  int n_start = row[_procID];
1341  int indx = 0;
1342  for ( int n = n_start; n < n_start + face_count; n++){
1343  (*indices.at(id))[indx] = col[n];
1344  indx++;
1345  }
1346  //getting subset from global _faceCellsGlobal and _faceNodesGlobal
1347  int cell_count = _nelems.at(id);
1348  int ghost_count = _nelemsWithGhosts.at(id) - _nelems.at(id) + _interfaceMap.at(id).size();
1349  _cellSite.push_back( StorageSitePtr(new StorageSite( cell_count, ghost_count)) );
1350 
1351  _faceCells.push_back( _faceCellsGlobal.at(id)->getLocalizedSubsetOfFaceCells( *_faceSite.at(id), *_cellSite.at(id), *indices.at(id), *_cellParts.at(id), _procID ) );
1352  _faceNodes.push_back( _faceNodesGlobal.at(id)->getLocalizedSubset( *_faceSite.at(id), *_nodeSite.at(id), *indices.at(id) ) );
1353  _cellCells.push_back( (_faceCells.at(id)->getTranspose())->multiply(*_faceCells.at(id), true) );
1354  _cellNodes.push_back( (_faceCells.at(id)->getTranspose())->multiply(*_faceNodes.at(id), false) );
1355 
1356  }
1357 
1358  if ( _cleanup )
1360 
1361  if ( _debugMode )
1363 }
1364 
1365 
1366 void
1368 {
1369  //open file
1370  debug_file_open("faceCells_faceNodes");
1371  _debugFile << "faceCells_faceNodes : " << endl;
1372  _debugFile << endl;
1373 
1374  const Array<int>& globalToLocalMap = _faceCells.at(0)->getGlobalToLocalMap();
1375  const Array<int>& localToGlobalMap = _faceCells.at(0)->getLocalToGlobalMap();
1376  _debugFile << " globalToLocalMap.length() = " << globalToLocalMap.getLength() << endl;
1377  for ( int n = 0; n < globalToLocalMap.getLength(); n++)
1378  _debugFile << " globalToLocalMap[" << n << "] = " << globalToLocalMap[n] << endl;
1379  _debugFile << endl;
1380  _debugFile << " localToGlobalMap.length() = " << localToGlobalMap.getLength() << endl;
1381  for ( int n = 0; n < _nelems.at(0); n++)
1382  _debugFile << " localToGlobalMap[" << n << "] = " << localToGlobalMap[n] << endl;
1383  _debugFile << endl;
1384 
1385  //faceCells
1386  _debugFile << " _faceCells : " << endl;
1387  _debugFile << " _faceCells->getRowDim() = " << _faceCells.at(0)->getRowDim() << endl;
1388  _debugFile << " _faceCells->getColDim() = " << _faceCells.at(0)->getColDim() << endl;
1389  const Array<int>& rowFaceCells = _faceCells.at(0)->getRow();
1390  const Array<int>& colFaceCells = _faceCells.at(0)->getCol();
1391  for ( int face = 0; face < _faceCells.at(0)->getRowDim(); face++){
1392  _debugFile << " row[" << face <<"] = " << (*_partFaces.at(0))(_procID,face) << " ";
1393  int ncells = _faceCells.at(0)->getCount(face);
1394  for ( int cell = 0; cell < ncells; cell++){
1395  _debugFile << colFaceCells[ rowFaceCells[face] + cell ] << " ";
1396  }
1397  _debugFile << endl;
1398  }
1399  _debugFile << endl;
1400  //faceNodes
1401  _debugFile << " _faceNodes : " << endl;
1402  _debugFile << " _faceNodes->getRowDim() = " << _faceNodes.at(0)->getRowDim() << endl;
1403  _debugFile << " _faceNodes->getColDim() = " << _faceNodes.at(0)->getColDim() << endl;
1404  const Array<int>& rowFaceNodes = _faceNodes.at(0)->getRow();
1405  const Array<int>& colFaceNodes = _faceNodes.at(0)->getCol();
1406 
1407  for ( int face = 0; face < _faceNodes.at(0)->getRowDim(); face++){
1408  _debugFile << " row[" << face <<"] = " << (*_partFaces.at(0))(_procID,face) << " ";
1409  int nnodes = _faceNodes.at(0)->getCount(face);
1410  for ( int node = 0; node < nnodes; node++){
1411  _debugFile << colFaceNodes[ rowFaceNodes[face] + node ] << " ";
1412  }
1413  _debugFile << endl;
1414  }
1415  _debugFile << endl;
1416  //faceNodes
1417  _debugFile << " _cellNodes(Local Numbering) : " << endl;
1418  _debugFile << " _cellNodes->getRowDim() = " << _cellNodes.at(0)->getRowDim() << endl;
1419  _debugFile << " _cellNodes->getColDim() = " << _cellNodes.at(0)->getColDim() << endl;
1420  const Array<int>& rowCellNodes = _cellNodes.at(0)->getRow();
1421  const Array<int>& colCellNodes = _cellNodes.at(0)->getCol();
1422 
1423  for ( int cell = 0; cell < _cellNodes.at(0)->getRowDim(); cell++){
1424  _debugFile << " row[" << cell << "] = " ;
1425  int nnodes = _cellNodes.at(0)->getCount(cell);
1426  for ( int node = 0; node < nnodes; node++){
1427  _debugFile << colCellNodes[ rowCellNodes[cell] + node ] << " ";
1428  }
1429  _debugFile << endl;
1430  }
1431  _debugFile << endl;
1432  //cellCells
1433  _debugFile << " _cellCells : " << endl;
1434  _debugFile << " _cellCells->getRowDim() = " << _cellCells.at(0)->getRowDim() << endl;
1435  _debugFile << " _cellCells->getColDim() = " << _cellCells.at(0)->getColDim() << endl;
1436  const Array<int>& rowCellCells = _cellCells.at(0)->getRow();
1437  const Array<int>& colCellCells = _cellCells.at(0)->getCol();
1438 
1439  for ( int cell = 0; cell < _cellCells.at(0)->getRowDim(); cell++){
1440  _debugFile << " row[" << cell <<"] = " << " ";
1441  int nnodes = _cellCells.at(0)->getCount(cell);
1442  for ( int node = 0; node < nnodes; node++){
1443  _debugFile << colCellCells[ rowCellCells[cell] + node ] << " ";
1444  }
1445  _debugFile << endl;
1446  }
1447  _debugFile << endl;
1448  //close file
1449  debug_file_close();
1450 
1451 }
1452 
1453 
1454 void
1456 {
1457  MPI::COMM_WORLD.Barrier();
1458  _faceCellsGlobal.clear();
1459  _faceNodesGlobal.clear();
1460  vector< int* > ::iterator it_int;
1461  for ( it_int = _elem.begin(); it_int != _elem.end(); it_int++)
1462  delete [] *it_int;
1463 
1464 
1465 }
1466 
1467 //form interfaces
1468 void
1470 {
1471  _interfaceMap.resize( _nmesh );
1472  for ( int id = 0; id < _nmesh; id++){
1473  int nface = _partFaces.at(id)->getCount( _procID );
1474  for ( int face = 0; face < nface; face++ ){
1475  int face_globalID = (*_partFaces.at(id))(_procID,face);
1476  if (_faceParts.at(id)->getCount(face_globalID) == 2 ){ // ==2 means sharing interface
1477  int neighPart = (*_faceParts.at(id))(face_globalID,0) +
1478  (*_faceParts.at(id))(face_globalID,1) - _procID;
1479  _interfaceSet.at(id).insert( neighPart );
1480  _interfaceMap.at(id).insert( pair<int,int>(neighPart,face) );
1481  }
1482  }
1483  }
1484 
1485  if ( _debugMode )
1486  DEBUG_interfaces();
1487 }
1488 
1489 void
1491 {
1492  //open file
1493  debug_file_open("interfaces");
1494  //interfaceMap
1495  pair<multimap<int,int>::iterator,multimap<int,int>::iterator> ret;
1496  _debugFile << "_InterfaceMap : " << endl;
1497  _debugFile << endl;
1498  _debugFile << "_interfaceMap.size() = " << _interfaceMap.at(0).size() << endl;
1499  _debugFile << endl;
1500  multimap<int,int>::iterator it_multimap;
1501  for ( int part = 0; part < _nPart.at(0); part++ ){
1502  ret = _interfaceMap.at(0).equal_range(part);
1503  _debugFile << " interface ID = " << part << " => ";
1504  for (it_multimap=ret.first; it_multimap!=ret.second; ++it_multimap)
1505  _debugFile << (*_partFaces.at(0))(_procID, (*it_multimap).second) << " ";
1506  _debugFile << endl;
1507  }
1508  _debugFile << endl;
1509  //close file
1510  debug_file_close();
1511 
1512 }
1513 
1514 //form coordinates
1515 void
1517 {
1518 
1519  for ( int id = 0; id < _nmesh; id++){
1520  const Mesh& mesh = *(_meshList.at(id));
1521  const Array<Mesh::VecD3>& global_coord = mesh.getNodeCoordinates();
1522  int node_count = _partNodes.at(id)->getCount( _procID );
1523  _coord.push_back( ArrayVecD3Ptr(new Array<Mesh::VecD3>(node_count)) );
1524  const Array<int>& rowPartNodes = _partNodes.at(id)->getRow();
1525  const Array<int>& colPartNodes = _partNodes.at(id)->getCol();
1526 
1527  for ( int node = 0; node < node_count; node++)
1528  (*_coord.at(id))[node] = global_coord[ colPartNodes[rowPartNodes[_procID]+node] ];
1529  }
1530 
1531  if ( _debugMode )
1533 
1534 }
1535 
1536 void
1538 {
1539  debug_file_open("coordinates");
1540  //node coordinates
1541  _debugFile << "coordinates : " << endl;
1542  _debugFile << endl;
1543  int node_count = _partNodes.at(0)->getCount( _procID );
1544  for ( int node = 0; node < node_count; node++){
1545  _debugFile << fixed;
1546  _debugFile << " node ID = " <<setw(10)<< node << setprecision(7) << ", x = " << (*_coord.at(0))[node][0] <<
1547  setprecision(7) << ", y = " << (*_coord.at(0))[node][1] <<
1548  setprecision(7) << ", z = " << (*_coord.at(0))[node][2] << endl;
1549  }
1550  _debugFile << endl;
1551  debug_file_close();
1552 }
1553 
1554 int
1556 {
1557  return _partFaces.at(id)->getCount(_procID) - (_nelemsWithGhosts.at(id) - _nelems.at(id))
1558  - _interfaceMap.at(id).size();
1559 
1560 }
1561 
1562 
1563 //this is expensive way, lets keep it
1564 void
1566 {
1567  for ( int id = 0; id < _nmesh; id++ ){
1568  int nface_local = _partFaces.at(id)->getCount( _procID );
1569  for ( int face = 0; face < nface_local; face++){
1570  int cell_0 = (*_faceCells.at(id))(face,0);
1571  int cell_1 = (*_faceCells.at(id))(face,1);
1572  if ( cell_0 >= _nelems.at(id) )
1573  _nonInteriorCells.at(id).insert(cell_0);
1574  if ( cell_1 >= _nelems.at(id) )
1575  _nonInteriorCells.at(id).insert(cell_1);
1576 
1577  }
1578  }
1579 
1580  if ( _debugMode )
1582 }
1583 
1584 void
1586 {
1587  //open
1588  debug_file_open("non_interior_cells");
1589  set<int>::const_iterator it_set;
1590  //non-interior cells (only for last mesh)
1591  _debugFile << "_nonInteriorCells : " << endl;
1592  _debugFile << endl;
1593  _debugFile << "total non-interior cells = " << _nonInteriorCells.at(0).size() << endl;
1594  _debugFile << endl;
1595  for ( it_set = _nonInteriorCells.at(0).begin(); it_set != _nonInteriorCells.at(0).end(); it_set++ )
1596  _debugFile << " " << *it_set << endl;
1597 
1598  _debugFile << endl;
1599  //close
1600  debug_file_close();
1601 
1602 }
1603 
1604 
1605 
1606 void
1608 {
1609 
1610  const CRConnectivity& faceCells = *_faceCells.at(0);
1611  const Array<int>& globalToLocalList = faceCells.getGlobalToLocalMap();
1612  const Array<int>& localToGlobalList = faceCells.getLocalToGlobalMap();
1613  set<int> globalCellList;
1614  //first copy _faceCells.GlobalTocell to some set which will be ordered from smallest integer to largest one
1615  for ( int i = 0; i < globalToLocalList.getLength(); i++){
1616  if ( globalToLocalList[i] != -1 ){
1617  globalCellList.insert( i );
1618  }
1619  }
1620  //now use ordered set
1621  int indx = 0;
1622  foreach( const set<int>::value_type globalID, globalCellList ){
1623  int localID = globalToLocalList[globalID];
1624  _cellToPreservedOrderCell[localID] = indx++;
1625  }
1626  //use global to Local
1627  for ( int i = 0; i < localToGlobalList.getLength(); i++ ){
1628  const int glblID = localToGlobalList[i];
1629  _globalToLocal[glblID] = i;
1630  }
1631 
1632  if ( _debugMode )
1634 
1635 }
1636 
1637 void
1639 {
1640  //file open
1641  debug_file_open("preserve_cell_order");
1642  _debugFile << "_cellToPreservedOrderCell : " << endl;
1643  _debugFile << endl;
1644  foreach ( const IntMap::value_type& pos, _cellToPreservedOrderCell )
1645  _debugFile << pos.first << " " << pos.second << endl;
1646 
1647  _debugFile << endl;
1648  _debugFile << " _globalToLocal : " << endl;
1649  _debugFile << endl;
1650 
1651  foreach ( const IntMap::value_type& pos, _globalToLocal ){
1652  _debugFile << "glblID = " << pos.first << ", localID = " << pos.second << endl;
1653  }
1654 
1655  //close
1656  debug_file_close();
1657 
1658 }
1659 
1660 
1661 //faceCells and faceNodes are order such that interior face come first and
1662 //then boundary faces or interfaces follows after that
1663 //interface and boundary cells which are always stored as second element
1664 //faceCellsOrdered(face,0) => interior cells, faceCellsOrdered(face,1)=>boundary or interface cells
1665 void
1667 {
1668 
1669  for ( int id = 0; id < _nmesh; id++ ){
1670  int tot_cells = _nelemsWithGhosts.at(id) + _interfaceMap.at(id).size();
1671  construct_mesh( id );
1672 
1673  _faceCellsOrdered.push_back( CRConnectivityPtr( new CRConnectivity(_meshListLocal.at(id)->getFaces(), _meshListLocal.at(id)->getCells() ) ) );
1674  _faceNodesOrdered.push_back( CRConnectivityPtr( new CRConnectivity(_meshListLocal.at(id)->getFaces(), _meshListLocal.at(id)->getNodes() ) ) );
1675  _cellToOrderedCell[id].assign(tot_cells, -1);
1676  //first preserve order cells (stick with global numbering)
1678  //faceCells
1679  _faceCellsOrdered.at(id)->initCount();
1680  _faceNodesOrdered.at(id)->initCount();
1681 
1682  int nface = _partFaces.at(id)->getCount(_procID);
1683  int count_node = _faceNodes.at(id)->getRow()[1] - _faceNodes.at(id)->getRow()[0];
1684  int count_cell = _faceCells.at(id)->getRow()[1] - _faceCells.at(id)->getRow()[0];
1685  for ( int face = 0; face < nface; face++){
1686  _faceCellsOrdered.at(id)->addCount(face,count_cell); //two cells (always)
1687  _faceNodesOrdered.at(id)->addCount(face,count_node); //two, three or four nodes
1688  }
1689 
1690  _faceCellsOrdered.at(id)->finishCount();
1691  _faceNodesOrdered.at(id)->finishCount();
1692 
1693  //start with interior faces
1694  int array_length = _faceCells.at(id)->getLocalToGlobalMap().getLength();
1695  assert( array_length == tot_cells );
1696 
1697  int face_track = 0;
1698  int nface_local = _partFaces.at(id)->getCount( _procID );
1699  for ( int face = 0; face < nface_local; face++){
1700  int cell_0 = (*_faceCells.at(id))(face,0);
1701  int cell_1 = (*_faceCells.at(id))(face,1);
1702  //find if this face is interior or not
1703  bool is_interior = _nonInteriorCells.at(id).count(cell_0) == 0 &&
1704  _nonInteriorCells.at(id).count(cell_1) == 0;
1705 
1706  if ( is_interior ) {
1707  int cellID0 = _cellToPreservedOrderCell[cell_0];
1708  int cellID1 = _cellToPreservedOrderCell[cell_1];
1709  //map to cell number to preserved ordering mapping
1710  _cellToOrderedCell[id][cell_0] = cellID0;
1711  _cellToOrderedCell[id][cell_1] = cellID1;
1712  //add operation to faceCells
1713  _faceCellsOrdered.at(id)->add(face_track,cellID0);
1714  _faceCellsOrdered.at(id)->add(face_track,cellID1);
1715  //storing things as mappers
1716  int globalID0 = _faceCells.at(id)->getLocalToGlobalMap()[cell_0];
1717  int globalID1 = _faceCells.at(id)->getLocalToGlobalMap()[cell_1];
1718  _globalToLocalMappers.at(id).insert( pair<int,int>(globalID0,cellID0 ) );
1719  _globalToLocalMappers.at(id).insert( pair<int,int>(globalID1,cellID1 ) );
1720  _localToGlobalMappers.at(id).insert( pair<int,int>(cellID0, globalID0) );
1721  _localToGlobalMappers.at(id).insert( pair<int,int>(cellID1, globalID1) );
1722  //faceNodesOrdered
1723  for ( int node = 0; node < count_node; node++ )
1724  _faceNodesOrdered.at(id)->add( face_track, (*_faceNodes.at(id))( face, node ) );
1725  face_track++;
1726  }
1727  }
1728 
1729  //check if any inner cells are not visited from above search (it might be inner cell
1730  //surrounded by interface/boundary faces,so,the above loop fail to catch inner cells)
1731  foreach(const IntMap::value_type& mpos, _cellToPreservedOrderCell){
1732  int cellID = mpos.first;
1733  int global_id = _faceCells.at(id)->getLocalToGlobalMap()[cellID];
1734  if ( _cellToOrderedCell[0][cellID] == -1 ){ //means not visited
1735  int orderedCellID = mpos.second;
1736  _cellToOrderedCell[0][cellID] = orderedCellID;
1737  _globalToLocalMappers.at(id).insert( pair<int,int>(global_id,orderedCellID) );
1738  _localToGlobalMappers.at(id).insert( pair<int,int>(orderedCellID, global_id) );
1739  }
1740  }
1741 
1742  int cellID = _cellToPreservedOrderCell.size();
1743  //then boundary faces
1744  multimap<int,int>::const_iterator it_cell;
1745  pair<multimap<int,int>::const_iterator,multimap<int,int>::const_iterator> it;
1746  set<int> ::const_iterator it_set;
1747  int offset = face_track;
1748  //loop over boundaries
1749  for ( it_set = _boundarySet.at(id).begin(); it_set != _boundarySet.at(id).end(); it_set++){
1750  int bndryID = *it_set;
1751  it = _mapBounIDAndCell.at(id).equal_range(bndryID);
1752  //if it is not empty
1753  if ( _mapBounIDAndCell.at(id).count( bndryID ) > 0 )
1754  _bndryOffsets.at(id).insert( pair<int,int>(bndryID, offset) );
1755 
1756  for ( it_cell = it.first; it_cell != it.second; it_cell++ ){
1757  int elem_0 = _globalToLocal[it_cell->second];
1758  int elem_1 = (*_cellCells.at(id))(elem_0, 0);
1759  assert( elem_0 != elem_1 );
1760  int inner_elem = _cellToOrderedCell[id][elem_1];
1761  int outer_elem = cellID;
1762 
1763  //update globalToLocal and localToGlobalMaps
1764  _globalToLocalMappers.at(id).insert( pair<int,int>(it_cell->second,cellID ) );
1765  _localToGlobalMappers.at(id).insert( pair<int,int>(cellID, it_cell->second) );
1766  _cellToOrderedCell[id][elem_0] = cellID;
1767 
1768  _faceCellsOrdered.at(id)->add(face_track, inner_elem);
1769  _faceCellsOrdered.at(id)->add(face_track, outer_elem);
1770 
1771  int count_node = _faceNodes.at(id)->getRow()[1] - _faceNodes.at(id)->getRow()[0];
1772  for ( int node = 0; node < count_node; node++)
1773  _faceNodesOrdered.at(id)->add( face_track, (*_cellNodes.at(id))(elem_0,node) );
1774 
1775  face_track++;
1776  offset++;
1777  cellID++;
1778  }
1779  }
1780 
1781 
1782  //then interface faces
1783  multimap<int,int>::const_iterator it_face;
1784  for ( it_set = _interfaceSet.at(id).begin(); it_set != _interfaceSet.at(id).end(); it_set++){
1785  int interfaceID = *it_set;
1786  it = _interfaceMap.at(id).equal_range( interfaceID );
1787  _interfaceOffsets.at(id).insert( pair<int,int>(interfaceID,offset) ) ;
1788  for ( it_face = it.first; it_face != it.second; it_face++ ){
1789  int face_id = it_face->second;
1790  int elem_0 = (*_faceCells.at(id))(face_id,0);
1791  int elem_1 = (*_faceCells.at(id))(face_id,1);
1792  int outer_elem_id = -1;
1793 
1794  if ( _nonInteriorCells.at(id).count( elem_1 ) > 0 ){ //if elem_1 is non-interior cell
1795  _faceCellsOrdered.at(id)->add(face_track,_cellToOrderedCell[id][elem_0]);
1796  outer_elem_id = elem_1;
1797  } else {
1798  _faceCellsOrdered.at(id)->add(face_track,_cellToOrderedCell[id][elem_1]);
1799  outer_elem_id = elem_0;
1800  }
1801  _faceCellsOrdered.at(id)->add(face_track,cellID);
1802 
1803  //update maps
1804  int global_id = _faceCells.at(id)->getLocalToGlobalMap()[outer_elem_id];
1805  assert( cellID >=0 && cellID < array_length );
1806  _globalToLocalMappers.at(id).insert( pair<int,int>(global_id, cellID) );
1807  _localToGlobalMappers.at(id).insert( pair<int,int>(cellID, global_id) );
1808  _cellToOrderedCell[id][outer_elem_id] = cellID;
1809 
1810  int count_node = _faceNodes.at(id)->getRow()[1] - _faceNodes.at(id)->getRow()[0];
1811 
1812  if ( outer_elem_id == elem_1 ) {
1813  for ( int node = 0; node < count_node; node++)
1814  _faceNodesOrdered.at(id)->add( face_track, (*_faceNodes.at(id))( face_id, node ) );
1815  } else {
1816  for ( int node = count_node-1; node >= 0; node--)
1817  _faceNodesOrdered.at(id)->add( face_track, (*_faceNodes.at(id))( face_id, node ) );
1818  }
1819 
1820  face_track++;
1821  offset++;
1822  cellID++;
1823  }
1824 
1825  }
1826 
1827  _faceCellsOrdered.at(id)->finishAdd();
1828  _faceNodesOrdered.at(id)->finishAdd();
1829  assert( cellID == tot_cells );
1830  }
1831 
1832 
1833  if ( _debugMode )
1835 
1836 }
1837 
1838 void
1840 {
1841  //openfile
1842  debug_file_open("order_faceCells_faceNodes");
1843  //faceCellsOrdered
1844  _debugFile << " _faceCellsOrdered : " << endl;
1845  _debugFile << " _faceCellsOrdered->getRowDim() = " << _faceCellsOrdered.at(0)->getRowDim() << endl;
1846  _debugFile << " _faceCellsOrdered->getColDim() = " << _faceCellsOrdered.at(0)->getColDim() << endl;
1847  const Array<int>& rowFaceCellsOrdered = _faceCellsOrdered.at(0)->getRow();
1848  const Array<int>& colFaceCellsOrdered = _faceCellsOrdered.at(0)->getCol();
1849  for ( int face = 0; face < _faceCellsOrdered.at(0)->getRowDim(); face++){
1850  _debugFile << " row[" << face <<"] = " ;
1851  int ncells = _faceCellsOrdered.at(0)->getCount(face);
1852  for ( int cell = 0; cell < ncells; cell++){
1853  _debugFile << colFaceCellsOrdered[ rowFaceCellsOrdered[face] + cell ] << " ";
1854  }
1855  _debugFile << endl;
1856  }
1857  _debugFile << endl;
1858 
1859  //faceNodes
1860  _debugFile << " _faceNodesOrdered : " << endl;
1861  _debugFile << " _faceNodesOrdered->getRowDim() = " << _faceNodesOrdered.at(0)->getRowDim() << endl;
1862  _debugFile << " _faceNodesOrdered->getColDim() = " << _faceNodesOrdered.at(0)->getColDim() << endl;
1863  const Array<int>& rowFaceNodesOrdered = _faceNodesOrdered.at(0)->getRow();
1864  const Array<int>& colFaceNodesOrdered = _faceNodesOrdered.at(0)->getCol();
1865 
1866  for ( int face = 0; face < _faceNodesOrdered.at(0)->getRowDim(); face++){
1867  _debugFile << " row[" << face<<"] = " ;
1868  int nnodes = _faceNodesOrdered.at(0)->getCount(face);
1869  for ( int node = 0; node < nnodes; node++){
1870  _debugFile << colFaceNodesOrdered[ rowFaceNodesOrdered[face] + node ]+1 << " ";
1871  }
1872  _debugFile << endl;
1873  }
1874  _debugFile << endl;
1875 
1876  //close
1877  debug_file_close();
1878 }
1879 
1880 void
1882 {
1883  int dim = _meshList.at(id)->getDimension();
1884  int cellZoneId = _meshList.at(id)->getCellZoneID();
1885  Mesh *pmesh = new Mesh(dim);
1886  pmesh->setID(_meshList.at(id)->getID());
1887  pmesh->setCellZoneID(cellZoneId);
1888  _meshListLocal.push_back( pmesh );
1889 
1890  StorageSite& faceSite = _meshListLocal.at(id)->getFaces();
1891  StorageSite& cellSite = _meshListLocal.at(id)->getCells();
1892  StorageSite& nodeSite = _meshListLocal.at(id)->getNodes();
1893  int nface_local = _partFaces.at(id)->getCount( _procID );
1894  int tot_cells = _nelemsWithGhosts.at(id) + _interfaceMap.at(id).size();
1895  int nGhostCell_local = tot_cells - _nelems.at(id);
1896  int nnode_local =_partNodes.at(id)->getCount( _procID );
1897 
1898  //Storage sites
1899  faceSite.setCount( nface_local );
1900  cellSite.setCount( _nelems.at(id), nGhostCell_local );
1901  nodeSite.setCount( nnode_local );
1902 }
1903 
1904 //collect each mesh neightbourhood interface cells, ...
1905 void
1907 {
1908 
1909  vector<int> offset;
1910  vector<int> interfaceMeshIDs;
1911  int *recv_counts = NULL;
1912  int *displ = NULL;
1913  for ( int id = 0; id < _nmesh; id++){
1914  recv_counts = new int[ _nPart.at(id) ];
1915  displ = new int[ _nPart.at(id) ];
1916 
1917  int total_interface_mesh = int( _interfaceSet.at(id).size() );
1918  int total_faces = int( _interfaceMap.at(id).size() );
1919 
1920  MPI::COMM_WORLD.Allgather(&total_interface_mesh, 1, MPI::INT, _interfaceMeshCounts.at(id)->getData(), 1, MPI::INT);
1921  MPI::COMM_WORLD.Allgather(&total_faces, 1, MPI::INT, _procTotalInterfaces.at(id)->getData(), 1, MPI::INT);
1922 
1923  //now find offsets for ghostCells
1924  int total_interface_local = _interfaceSet.at(id).size();
1925  int total_interface_global = -1;
1926 
1927  MPI::COMM_WORLD.Allreduce( &total_interface_local, &total_interface_global, 1, MPI::INT, MPI::SUM );
1928  MPI::COMM_WORLD.Allgather( &total_interface_local, 1, MPI::INT, recv_counts, 1, MPI::INT );
1929  MPI::COMM_WORLD.Allreduce( &total_faces, &_windowSize.at(id), 1, MPI::INT, MPI::MAX);
1930 
1931  //enough space for gathering
1932  _offsetInterfaceCells.push_back( ArrayIntPtr( new Array<int>(total_interface_global) ) );
1933  _interfaceMeshIDs.push_back ( ArrayIntPtr( new Array<int>(total_interface_global) ) );
1934 
1935  _ghostCellsGlobal.push_back ( ArrayIntPtr( new Array<int>(total_faces ) ) );
1936  _ghostCellsLocal.push_back ( ArrayIntPtr( new Array<int>(total_faces ) ) );
1937 
1938  //local offset and interfaceMeshID are stored in contigous memory
1939  int index = 0;
1940  set<int>::const_iterator it_set;
1941  for ( it_set = _interfaceSet.at(id).begin(); it_set != _interfaceSet.at(id).end(); it_set++ ){
1942  int neighMeshID = *it_set;
1943  interfaceMeshIDs.push_back( neighMeshID );
1944  //loop over interface
1945  int nstart = _interfaceOffsets.at(id)[neighMeshID];
1946  offset.push_back( nstart );
1947 
1948  int nend = nstart + _interfaceMap.at(id).count( neighMeshID );
1949  for ( int n = nstart; n < nend; n++){
1950  int elem_local_id = (*_faceCellsOrdered.at(id))(n,0);
1951  int elem_global_id = _localToGlobalMappers.at(id)[ elem_local_id ];
1952 
1953  (*_ghostCellsLocal.at(id))[index] = elem_local_id;
1954  (*_ghostCellsGlobal.at(id))[index] = elem_global_id;
1955  index++;
1956  }
1957 
1958  }
1959 
1960  displ[0] = 0;
1961  for ( int i = 1; i < _nPart.at(id); i++)
1962  displ[i] = recv_counts[i-1] + displ[i-1];
1963 
1964 
1965  //now gather for _interface...
1966  MPI::COMM_WORLD.Allgatherv( &offset[0], total_interface_local, MPI::INT,
1967  _offsetInterfaceCells.at(id)->getData(), recv_counts, displ, MPI::INT);
1968 
1969  MPI::COMM_WORLD.Allgatherv( &interfaceMeshIDs[0], total_interface_local, MPI::INT,
1970  _interfaceMeshIDs.at(id)->getData(), recv_counts, displ, MPI::INT);
1971 
1972  offset.clear();
1973  interfaceMeshIDs.clear();
1974 
1975  delete [] recv_counts;
1976  delete [] displ;
1977 
1978  }
1979 
1980  if ( _debugMode )
1982 
1983 }
1984 
1985 void
1987 {
1988  debug_file_open("exchange_interface_meshes");
1989  //interfaceMesheCounts
1990  for ( int proc = 0; proc < _nPart.at(0); proc++)
1991  _debugFile << " total mesh surrounding = " << (*_interfaceMeshCounts.at(0))[proc] << endl;
1992  _debugFile << endl;
1993 
1994  //ofsest
1995  _debugFile << " offset for ghost Cells from adjacent meshes to read data from _ghostCellsGlobal : " << endl;
1996  for ( int n = 0; n < _offsetInterfaceCells.at(0)->getLength(); n++ )
1997  _debugFile << " n = " << n << " offsetInterfaceCells = " << (*_offsetInterfaceCells.at(0))[n] << endl;
1998  _debugFile << endl;
1999  //interfaceMeshIDs
2000  _debugFile << " neightboorhood cell IDs : " << endl;
2001  for ( int n = 0; n < _interfaceMeshIDs.at(0)->getLength(); n++ )
2002  _debugFile << " n = " << n << " interfaced Mesh ID = " << (*_interfaceMeshIDs.at(0))[n] << endl;
2003  _debugFile << endl;
2004 
2005  //global Interface cells (interior ones, global numbering)
2006  _debugFile << "interface cells looking interior domain (global numbering) : " << endl;
2007  for ( int n = 0; n < _ghostCellsGlobal.at(0)->getLength(); n++ )
2008  _debugFile << " n = " << n << " cell ID = " << (*_ghostCellsGlobal.at(0))[n] << endl;
2009 
2010  //global Interface cells (interior ones, global numbering)
2011  _debugFile << "interface cells looking interior domain (local numbering) : " << endl;
2012  for ( int n = 0; n < _ghostCellsLocal.at(0)->getLength(); n++ )
2013  _debugFile << " n = " << n << " interfaced Mesh ID = " << (*_ghostCellsLocal.at(0))[n] << endl;
2014  debug_file_close();
2015 
2016 }
2017 
2018 void
2020 {
2021 
2022  for ( int id = 0; id < _nmesh; id++){
2023  create_window( id );
2024  fence_window();
2025 
2026  StorageSite::ScatterMap & cellScatterMap = _meshListLocal.at(id)->getCells().getScatterMap();
2027  StorageSite::GatherMap & cellGatherMap = _meshListLocal.at(id)->getCells().getGatherMap();
2028 
2029  //getting data
2030  set<int>::const_iterator it_set;
2031  int interfaceIndx = 0;
2032  for ( it_set = _interfaceSet.at(id).begin(); it_set != _interfaceSet.at(id).end(); it_set++){
2033 
2034  int neighMeshID = *it_set;
2035  int size = int(_interfaceMap.at(id).count(neighMeshID) );
2036  _fromIndices.at(id).push_back( ArrayIntPtr( new Array<int>(size) ) );
2037  _toIndices.at(id).push_back( ArrayIntPtr( new Array<int>(size) ) );
2038  *_fromIndices.at(id).at(interfaceIndx) = -1;
2039  *_toIndices.at(id).at(interfaceIndx) = -1;
2040 
2041  int window_displ = -1;
2042  window_displ = get_window_displ( id, neighMeshID );
2043  _winLocal.Get ( _fromIndices.at(id).at(interfaceIndx)->getData(), size, MPI::INT, neighMeshID, window_displ, size, MPI::INT );
2044  _winGlobal.Get( _toIndices.at(id).at(interfaceIndx)->getData() , size, MPI::INT, neighMeshID, window_displ, size, MPI::INT );
2045  interfaceIndx++;
2046 
2047  }
2048 
2049  fence_window();
2050  free_window();
2051 
2052 
2053  interfaceIndx = 0;
2054  for ( it_set = _interfaceSet.at(id).begin(); it_set != _interfaceSet.at(id).end(); it_set++ ){
2055 
2056  int neighMeshID = *it_set;
2057  int size = int(_interfaceMap.at(id).count(neighMeshID) );
2058  map<int, int> mapKeyCount; //map between key and count of that key
2059  for ( int n = 0; n < size; n++){
2060 
2061  int key = (*_toIndices.at(id).at(interfaceIndx))[n];
2062 // int count = _globalToLocalMappers.at(id).count( key );
2063 
2064  if ( mapKeyCount.count( key ) > 0 ) { //it has elements
2065  mapKeyCount[key] = mapKeyCount[key] + 1; //increase one
2066  } else { //if it is empty
2067  mapKeyCount.insert(pair<int,int>(key,0));
2068  }
2069 
2070  multimap<int,int>::const_iterator it;
2071  it = _globalToLocalMappers.at(id).lower_bound( key );
2072  for ( int n_iter = 0; n_iter < mapKeyCount[key]; n_iter++)
2073  it++;
2074 
2075  int elem_id = it->second;
2076  (*_toIndices.at(id).at(interfaceIndx))[n] = elem_id;
2077 
2078 
2079  }
2080  //from indices seems useless for now but we need to find scatterCells = cellCells(toIndices) and
2081  //use fromindices as storage Array
2082  for ( int i = 0; i < _fromIndices.at(id).at(interfaceIndx)->getLength(); i++){
2083  int elem_id = (*_toIndices.at(id).at(interfaceIndx))[i];
2084  (*_fromIndices.at(id).at(interfaceIndx))[i] = _meshListLocal.at(id)->getCellCells()(elem_id,0);
2085  }
2086  Mesh::PartIDMeshIDPair pairID = make_pair<int,int>(neighMeshID,0); //no multiple meshees so second index zero
2087  cellScatterMap[ _meshListLocal.at(id)->getGhostCellSiteScatter( pairID ) ] = _fromIndices.at(id).at(interfaceIndx);
2088  cellGatherMap [ _meshListLocal.at(id)->getGhostCellSiteGather ( pairID ) ] = _toIndices.at(id).at(interfaceIndx);
2089 
2090  interfaceIndx++;
2091 
2092  }
2093 
2094  }
2095 
2096  if ( _cleanup )
2098 
2099  if ( _debugMode )
2100  DEBUG_mesh();
2101 
2102 }
2103 
2104 //get offset value for global numbering for each partition
2105 int
2107 {
2108  const int nmesh = int( _meshListLocal.size() );
2109  int count = 0;
2110  //get offsets for
2111  for ( int id = 0; id < nmesh; id++ ){
2112  const Mesh& mesh = *_meshListLocal.at(id);
2113  const StorageSite& cellSite = mesh.getCells();
2114  const FaceGroupList& bounGroupList = mesh.getBoundaryFaceGroups();
2115  int bounCount = 0;
2116  for ( int i = 0; i < mesh.getBoundaryGroupCount(); i++ )
2117  bounCount += bounGroupList[i]->site.getCount();
2118  const int selfCount = cellSite.getSelfCount();
2119  count += selfCount + bounCount;
2120  }
2121 
2122  //allocation holding each partiton offset
2123  int *counts = new int[ _nPart[0] ];
2124  //MPI calls allgather to know offsets
2125  MPI::COMM_WORLD.Allgather( &count, 1, MPI::INT, counts, 1, MPI::INT);
2126 
2127  //compute offsets for each partition
2128  int offset = 0;
2129  for ( int i = 0; i < _procID; i++ )
2130  offset += counts[i];
2131 
2132  //delete allocation counts
2133  delete [] counts;
2134  return offset;
2135 
2136 }
2137 
2138 //this function might be called to sync global number of level0 and level1.
2139 //Since MeshListLocal might have level0 or level1 cells, users are responsible to specify correct value of level
2140 void
2142 {
2143  const int nmesh = int( _meshListLocal.size() );
2144  //creating cellID MultiField to use sync() operation
2145  shared_ptr<MultiField> cellMultiField = shared_ptr<MultiField>( new MultiField() );
2146  shared_ptr<Field> cellField = shared_ptr<Field> ( new Field("globalcellID") );
2147 
2148  for ( int id = 0; id < nmesh; id++ ){
2149  const StorageSite* site = &_meshListLocal[id]->getCells();
2150  MultiField::ArrayIndex ai( cellField.get(), site );
2151  shared_ptr<Array<int> > cIndex(new Array<int>(site->getCountLevel1()));
2152  *cIndex = -1;
2153  cellMultiField->addArray(ai,cIndex);
2154  }
2155 
2156  //global numbering
2157  const int globalOffset = global_offset();
2158  int offset = globalOffset;
2159  for ( int id = 0; id < nmesh; id++ ){
2160  const Mesh& mesh = *_meshListLocal.at(id);
2161  const StorageSite* site = &_meshListLocal[id]->getCells();
2162  MultiField::ArrayIndex ai( cellField.get(), site );
2163  Array<int>& localCell = dynamic_cast< Array<int>& >( (*cellMultiField)[ai] );
2164  //global numbering inner cells
2165  const int selfCount = site->getSelfCount();
2166  const map<int,int>& localToGlobalMappers = _localToGlobalMappers.at(0);
2167  for ( int i = 0; i < selfCount; i++ ){
2168  localCell[i] = offset + i;
2169  localCell[i] = localToGlobalMappers.find(i)->second;
2170  }
2171  //update offset
2172  offset += selfCount;
2173  //loop over boundaries and global number boundary cells
2174  const FaceGroupList& bounGroupList = mesh.getBoundaryFaceGroups();
2175  const CRConnectivity& faceCells = mesh.getAllFaceCells();
2176  for ( int i = 0; i < mesh.getBoundaryGroupCount(); i++ ){
2177  const int ibeg = bounGroupList[i]->site.getOffset();
2178  const int iend = ibeg + bounGroupList[i]->site.getCount();
2179  int indx=0;
2180  for ( int ii = ibeg; ii < iend; ii++ ){
2181  const int cellID = faceCells(ii,1);
2182  localCell[ cellID] =localToGlobalMappers.find(cellID)->second ;
2183  indx++;
2184  }
2185  //update offset
2186  offset += iend-ibeg;
2187  }
2188  }
2189 
2190  //sync opeartion
2191  cellMultiField->sync();
2192 
2193  //create localToGlobal array and assign it in Mesh
2194  for ( int id = 0; id < nmesh; id++ ){
2195  Mesh& mesh = *_meshListLocal.at(id);
2196  mesh.createLocalGlobalArray();
2197  const StorageSite* site = &_meshListLocal[id]->getCells();
2198  MultiField::ArrayIndex ai( cellField.get(), site );
2199  const Array<int>& localCell = dynamic_cast< const Array<int>& >( (*cellMultiField)[ai] );
2200  Array<int>& localToGlobal = mesh.getLocalToGlobal();
2201  for ( int i = 0; i < localCell.getLength(); i++ ){
2202  localToGlobal[i] = localCell[i];
2203  assert( localCell[i] != -1 );
2204  }
2205 
2206  //copying GlobalToLocal
2207  map<int,int>& globalToLocal = mesh.getGlobalToLocal();
2208  for ( int i = 0; i < localCell.getLength(); i++ ){
2209  globalToLocal[ localToGlobal[i] ] = i;
2210  }
2211  }
2212 
2213  if ( _debugMode )
2215 
2216 }
2217 
2218 
2219 //debug Mesh::localToGlobal
2220 void
2222 {
2223  //open file
2224  debug_file_open("local_to_global");
2225  //print offsets
2226  _debugFile << " offset = " << global_offset() << endl;
2227  //print Mesh::localToGlobal array
2228  const int nmesh = int( _meshListLocal.size() );
2229  //loop over meshes
2230  for ( int id = 0; id < nmesh; id++ ){
2231  const Mesh& mesh = *_meshListLocal.at(id);
2232  const Array<int>& localToGlobal = mesh.getLocalToGlobal();
2233  _debugFile << "Mesh ID = " << id << endl;
2234  for ( int i = 0; i < localToGlobal.getLength(); i++ ){
2235  _debugFile << " localToGlobal[" << i << "] = " << localToGlobal[i] << endl;
2236  }
2237  }
2238  for ( int id = 0; id < nmesh; id++ ){
2239  const Mesh& mesh = *_meshListLocal.at(id);
2240  const map<int,int>& globalToLocal = mesh.getGlobalToLocal();
2241  _debugFile << "Mesh ID = " << id << endl;
2242  foreach ( const IntMap::value_type& mpos, globalToLocal ){
2243  _debugFile << " globalToLocal[" << mpos.first << "] = " << mpos.second << endl;
2244  }
2245  }
2246 
2247  debug_file_close();
2248 }
2249 
2250 //filling Mesh::cellCellsGlobal such that
2251 void
2253 {
2254  const int nmesh = int( _meshListLocal.size() );
2255  //get offsets for
2256  for ( int id = 0; id < nmesh; id++ ){
2257  Mesh& mesh = *_meshListLocal.at(id);
2258  Mesh::multiMap& cellCellsGlobal = mesh.getCellCellsGlobal();
2259  const Array<int>& localToGlobal = mesh.getLocalToGlobal();
2260  const StorageSite& cellSite = mesh.getCells();
2261  const CRConnectivity& cellCells = mesh.getCellCells();
2262  //loop over
2263  const int ncells = cellSite.getCount();
2264  for ( int n = 0; n < ncells; n++ ){
2265  const int iend = cellCells.getCount(n);
2266  //cellCellsGlobal.insert( pair<int,int>(n, localToGlobal[n]) );
2267  for ( int i = 0; i < iend; i++ ){
2268  const int localCellID = cellCells(n,i);
2269  cellCellsGlobal.insert( pair<int,int>(n, localToGlobal[localCellID] ) );
2270  }
2271  }
2272  }
2273 
2275 
2276  if ( _debugMode )
2278 
2279 }
2280 
2281 //creating cellCells global to fill ghost cell connections (previous routine cellcells_global has
2282 //not yet include surrounding cells on other processors)
2283 void
2285 {
2286  for ( int id = 0; id < _nmesh; id++ ){
2287  Mesh& mesh = *_meshListLocal.at(id);
2288  StorageSite& cellSite = mesh.getCells();
2289  const int ndim = mesh.getDimension();
2290  const int selfCount = cellSite.getSelfCount();
2291  //estimated sizes for buffers
2292  const int scatterSize = 6 * int( (ndim == 2) ? pow(selfCount,0.5) : pow(selfCount,2.0/3.0) ); //6 is maximum face count in hexa
2293  //array to hold local processors scatterBuffer (it might repeat several cells, it is ok)
2294  vector<int> scatterBuffer;
2295  //local array to hold cellCells for scattercells
2296  vector<int> cellCellsBuffer;
2297  //local array to hold count of cells around scatter cells
2298  vector<int> cellCellsCountBuffer;
2299  //scatterSize is not fill in capacity of scatterSize!!!!!!!!!!!!!, you have to call vector::size() method
2300  scatterBuffer.reserve ( scatterSize );
2301  cellCellsCountBuffer.reserve( scatterSize );
2302  cellCellsBuffer.reserve ( 6*scatterSize);
2303 
2304 
2305  const Array<int>& localToGlobal = mesh.getLocalToGlobal();
2306  const CRConnectivity& cellCells = mesh.getCellCells();
2307  const CRConnectivity& faceCells = mesh.getAllFaceCells();
2308  const FaceGroupList& faceGroupList = mesh.getInterfaceGroups();
2309  //loop over interfaces
2310  for ( int i = 0; i < mesh.getInterfaceGroupCount(); i++ ){
2311  const int ibeg = faceGroupList[i]->site.getOffset();
2312  const int iend = ibeg + faceGroupList[i]->site.getCount();
2313  for ( int i = ibeg; i < iend; i++ ){
2314  const int localCellID = faceCells(i,0);
2315  const int globalCellID = localToGlobal[ localCellID ];
2316  scatterBuffer.push_back(globalCellID);
2317  int indx = 0;
2318  for ( int j = 0; j < cellCells.getCount(localCellID); j++ ){
2319  const int nextcellID = localToGlobal[ cellCells(localCellID,j) ];
2320  cellCellsBuffer.push_back(nextcellID);
2321  indx++;
2322  }
2323  cellCellsCountBuffer.push_back(indx);
2324  }
2325  }
2326 
2327  //MPI collective operations
2328 
2329  //first decide global buffer sizes
2330  int scatterGlobalSize;
2331  int cellCellsGlobalSize;
2332  int cellCellsCountGlobalSize;
2333  int sendbuffer = int( scatterBuffer.size() );
2334  MPI::COMM_WORLD.Allreduce( &sendbuffer, &scatterGlobalSize, 1, MPI::INT, MPI::SUM );
2335  sendbuffer = int( cellCellsBuffer.size() );
2336  MPI::COMM_WORLD.Allreduce( &sendbuffer, &cellCellsGlobalSize, 1, MPI::INT, MPI::SUM );
2337  sendbuffer = int( cellCellsCountBuffer.size() );
2338  MPI::COMM_WORLD.Allreduce( &sendbuffer, &cellCellsCountGlobalSize, 1, MPI::INT, MPI::SUM );
2339 
2340  //create array for
2341  //scatterCellsGlobal
2342  shared_ptr< Array<int> > scatterCellsGlobal = ArrayIntPtr( new Array<int>(scatterGlobalSize ) );
2343  int *recv_counts = new int[ _nPart.at(id) ];
2344  int sendcount = int( scatterBuffer.size() );
2345  MPI::COMM_WORLD.Allgather( &sendcount, 1, MPI::INT, recv_counts, 1, MPI::INT );
2346 
2347  int *displ = new int[ _nPart.at(id) ];
2348  displ[0] = 0;
2349  for ( int i = 1; i < _nPart.at(id); i++)
2350  displ[i] = recv_counts[i-1] + displ[i-1];
2351  //now gather for scatterBuffer
2352  MPI::COMM_WORLD.Allgatherv( &scatterBuffer[0], sendcount , MPI::INT,
2353  scatterCellsGlobal->getData(), recv_counts, displ, MPI::INT);
2354 
2355  // cellCellsCountGlobal
2356  shared_ptr< Array<int> > cellCellsCountGlobal = ArrayIntPtr( new Array<int>(cellCellsCountGlobalSize ) );
2357  sendcount = int( cellCellsCountBuffer.size() );
2358  MPI::COMM_WORLD.Allgather( &sendcount, 1, MPI::INT, recv_counts, 1, MPI::INT );
2359 
2360  displ[0] = 0;
2361  for ( int i = 1; i < _nPart.at(id); i++)
2362  displ[i] = recv_counts[i-1] + displ[i-1];
2363  //now gather for scatterBuffer
2364  MPI::COMM_WORLD.Allgatherv( &cellCellsCountBuffer[0], sendcount , MPI::INT,
2365  cellCellsCountGlobal->getData(), recv_counts, displ, MPI::INT);
2366 
2367  // cellCellsGlobal
2368  shared_ptr< Array<int> > cellCellsGlobal = ArrayIntPtr( new Array<int>(cellCellsGlobalSize ) );
2369  sendcount = int( cellCellsBuffer.size() );
2370  MPI::COMM_WORLD.Allgather( &sendcount, 1, MPI::INT, recv_counts, 1, MPI::INT );
2371 
2372  displ[0] = 0;
2373  for ( int i = 1; i < _nPart.at(id); i++)
2374  displ[i] = recv_counts[i-1] + displ[i-1];
2375  //now gather for scatterBuffer
2376  MPI::COMM_WORLD.Allgatherv( &cellCellsBuffer[0], sendcount , MPI::INT,
2377  cellCellsGlobal->getData(), recv_counts, displ, MPI::INT);
2378 
2379 
2380  //create mapping index location where connectivity starts
2381  //and map index show index location, {12,82,23}, I want to know what is 82 index = 1
2382  map<int,int> cellPointer;
2383  map<int,int> locaterIndx;
2384  int pointerIndx = 0;
2385  for ( int i = 0; i < scatterGlobalSize; i++ ){
2386  const int cellID = (*scatterCellsGlobal )[i];
2387  const int count = (*cellCellsCountGlobal)[i];
2388  cellPointer[cellID] = pointerIndx;
2389  pointerIndx += count;
2390  locaterIndx[cellID] = i;
2391  }
2392 
2393  Mesh::multiMap& cellCellsMap = mesh.getCellCellsGlobal();
2394  //loop over interface, and get ghost cells(globalid), then go to scatterCells,
2395  //loop over interfaces for gather
2396  for ( int i = 0; i < mesh.getInterfaceGroupCount(); i++ ){
2397  const int ibeg = faceGroupList[i]->site.getOffset();
2398  const int iend = ibeg + faceGroupList[i]->site.getCount();
2399  for ( int i = ibeg; i < iend; i++ ){
2400  const int localCellID = faceCells(i,1); //gather cellID(local)
2401  const int globalCellID = localToGlobal[localCellID ];
2402  const int count = (*cellCellsCountGlobal)[ locaterIndx[globalCellID] ];
2403  const int offset = cellPointer[globalCellID];
2404  //erase ghost cell to not duplicate
2405  cellCellsMap.erase( localCellID );
2406  //add itself
2407 // cellCellsMap.insert( pair<int,int>( localCellID,globalCellID) );
2408  for ( int j = 0; j < count; j++ ){
2409  const int cellID = (*cellCellsGlobal)[offset+j];
2410 
2411  cellCellsMap.insert( pair<int,int>(localCellID,cellID) );
2412  }
2413  }
2414  }
2415  delete [] recv_counts;
2416  delete [] displ;
2417  }
2418 
2419  }
2420 
2421 //debug Mesh:cellCellsGlobal
2422 void
2424 {
2425  //open file
2426  debug_file_open("cellcells_global");
2427  //loop over meshes
2428  for ( int id = 0 ; id < _nmesh ; id++ ){
2429  Mesh& mesh = *_meshListLocal.at(id);
2430  const multimap<int,int>& cellCellsGlobal = mesh.getCellCellsGlobal();
2431  const StorageSite& cellSite = mesh.getCells();
2432  const int ncells = cellSite.getCount();
2433  _debugFile << "Mesh ID = " << id << endl;
2434  //loop over all meshinterfaces (key = all other meshes)
2435  for ( int n = 0; n < ncells; n++ ){
2436  _debugFile << " localCellID = " << n << " itself and cells around (global number) = ";
2437  multimap<int,int>::const_iterator it;
2438  for ( it = cellCellsGlobal.equal_range(n).first; it != cellCellsGlobal.equal_range(n).second; it++ ){
2439  _debugFile << it->second << " ";
2440  }
2441  _debugFile << endl;
2442  }
2443  }
2444  //close file
2445  debug_file_close();
2446 }
2447 
2448 //create globalCellIDs (only scatter cells and its around) to processor map
2449 //creating scatter cells (second layer)
2450 void
2452 {
2453  for ( int id = 0; id < _nmesh; id++ ){
2454  set<int> cellsLevel1;
2455  const Mesh& mesh = *_meshListLocal.at(id);
2456  const Array<int>& localToGlobal = mesh.getLocalToGlobal();
2457  const CRConnectivity& cellCells = mesh.getCellCells();
2458  const StorageSite& cellSite = mesh.getCells();
2459  const int selfCount = cellSite.getSelfCount();
2460  const StorageSite::ScatterMap& cellScatterMap = cellSite.getScatterMap();
2461  //count boundary cells
2462  const FaceGroupList& bounGroupList = mesh.getBoundaryFaceGroups();
2463  int nboun = 0;
2464  for ( int n = 0; n < mesh.getBoundaryGroupCount(); n++ ){
2465  nboun += bounGroupList[n]->site.getCount();
2466  }
2467  //compute innercells + boundary cells
2468  const int countNonGhostCells = selfCount + nboun;
2469  //get scatter map key ={neight part id, mesh id}, value = scatter storage site
2470  const Mesh::GhostCellSiteMap& ghostCellSiteScatterMap = mesh.getGhostCellSiteScatterMap();
2471  //loop over scatter mappers
2472  foreach ( const Mesh::GhostCellSiteMap::value_type& mpos, ghostCellSiteScatterMap ){
2473  const StorageSite& siteScatter = *(mpos.second);
2474  const Array<int>& scatterArray = *(cellScatterMap.find( &siteScatter )->second);
2475  //loop over scatter cells
2476  for ( int i = 0; i < siteScatter.getCount(); i++){
2477  const int cellID0 = scatterArray[i];
2478  cellsLevel1.insert( localToGlobal[cellID0] );
2479  const int jj = cellCells.getCount(cellID0);
2480  //around cells
2481  for ( int j = 0; j < jj; j++ ){
2482  //now this cell arounds
2483  //check if this is not ghost cell since we are only including inner+boundary cells
2484  const int cellID1 = cellCells(cellID0,j);
2485  if ( cellID1 < countNonGhostCells ){ //since we order first local then boundary
2486  cellsLevel1.insert(localToGlobal[cellID1]);
2487  }
2488  }
2489  }
2490  }
2491  //allocate send buffer and copy local values in it
2492  shared_ptr< Array<int> > cellsLevel1Array = ArrayIntPtr( new Array<int>(cellsLevel1.size()) );
2493  set <int>::const_iterator it = cellsLevel1.begin();
2494  for ( int i = 0; i < cellsLevel1Array->getLength(); i++){
2495  (*cellsLevel1Array)[i] = *it;
2496  it++;
2497  }
2498 
2499  int cellsLevel1GlobalSize = 0;
2500  int sendbuffer = int( cellsLevel1.size() );
2501  MPI::COMM_WORLD.Allreduce( &sendbuffer, &cellsLevel1GlobalSize, 1, MPI::INT, MPI::SUM );
2502 
2503  //create array for cellsLevel1Global
2504  shared_ptr< Array<int> > cellsLevel1Global = ArrayIntPtr( new Array<int>(cellsLevel1GlobalSize ) );
2505  int *recv_counts = new int[ _nPart.at(id) ];
2506  int sendcount = int( cellsLevel1.size() );
2507  MPI::COMM_WORLD.Allgather( &sendcount, 1, MPI::INT, recv_counts, 1, MPI::INT );
2508 
2509  int *displ = new int[ _nPart.at(id) ];
2510  displ[0] = 0;
2511  for ( int i = 1; i < _nPart.at(id); i++)
2512  displ[i] = recv_counts[i-1] + displ[i-1];
2513  //now gather for cellsLevel1Global
2514  MPI::COMM_WORLD.Allgatherv( cellsLevel1Array->getData(), sendcount , MPI::INT,
2515  cellsLevel1Global->getData(), recv_counts, displ, MPI::INT);
2516 
2517  //now fill following arrays
2518  int procid = 0;
2519  int indx = recv_counts[0];
2520  for ( int i = 0; i < cellsLevel1Global->getLength(); i++ ){
2521  _cellsLevel1PartID[ (*cellsLevel1Global)[i] ] = procid;
2522  if ( (i == indx-1) && (procid <_nPart.at(id)-1) ){
2523  //procid++;
2524  indx += recv_counts[++procid];
2525  }
2526  }
2527 
2528  delete [] recv_counts;
2529  delete [] displ;
2530 
2531  }
2532 
2533 //write this debug function
2534 
2535  if ( _debugMode )
2537  }
2538 
2539 //debug cells involving Level1 scatterings
2540 void
2542 {
2543  //open file
2544  debug_file_open("globalCellID_procID_map");
2545  foreach ( const IntMap::value_type& mpos, _cellsLevel1PartID){
2546  const int globalID = mpos.first;
2547  const int partID = mpos.second;
2548  _debugFile << " global CellID = " << globalID << " partition ID = " << partID << endl;
2549  }
2550  //close file
2551  debug_file_close();
2552 }
2553 
2554 //creaate a data structure map<cell, partID> but only on gatherCellCells
2555 void
2557 {
2558  for ( int id = 0; id < _nmesh; id++ ){
2559  const Mesh& mesh = *_meshListLocal.at(id);
2560  const CRConnectivity& faceCells = mesh.getAllFaceCells();
2561  const Mesh::multiMap& cellCellsMap = mesh.getCellCellsGlobal();
2562  const FaceGroupList& faceGroupList = mesh.getInterfaceGroups();
2563  const Array<int>& localToGlobal = mesh.getLocalToGlobal();
2564  //loop over interface, and get ghost cells(globalid), then go to scatterCells,
2565  //loop over interfaces for gather
2566  for ( int i = 0; i < mesh.getInterfaceGroupCount(); i++ ){
2567  const int ibeg = faceGroupList[i]->site.getOffset();
2568  const int iend = ibeg + faceGroupList[i]->site.getCount();
2569  for ( int i = ibeg; i < iend; i++ ){
2570  const int localCellID = faceCells(i,1); //gather cellID(local)
2571  multimap<int,int>::const_iterator it;
2572  for ( it = cellCellsMap.equal_range(localCellID).first; it != cellCellsMap.equal_range(localCellID).second; it++){
2573  _gatherCellsLevel1PartIDMap[it->second] = _cellsLevel1PartID[it->second];
2574  }
2575  }
2576 
2577  }
2578 
2579  for ( int i = 0; i < mesh.getInterfaceGroupCount(); i++ ){
2580  const int ibeg = faceGroupList[i]->site.getOffset();
2581  const int iend = ibeg + faceGroupList[i]->site.getCount();
2582  for ( int i = ibeg; i < iend; i++ ){
2583  //delete zero level gather cells
2584  _gatherCellsLevel1PartIDMap.erase( localToGlobal[ faceCells(i,1) ] );
2585  //delete scatter cells
2586  _gatherCellsLevel1PartIDMap.erase( localToGlobal[ faceCells(i,0) ] );
2587  }
2588 
2589  }
2590 
2591  }
2592 
2593 
2594  if( _debugMode )
2596 
2597 }
2598 
2599 //debug cells involving Level1 scatterings
2600 void
2602 {
2603  //open file
2604  debug_file_open("gatherCellsLevel1_partID_map");
2605  foreach ( const IntMap::value_type& mpos, _gatherCellsLevel1PartIDMap){
2606  const int globalID = mpos.first;
2607  const int partID = mpos.second;
2608  _debugFile << " global CellID = " << globalID << " partition ID = " << partID << endl;
2609  }
2610  //close file
2611  debug_file_close();
2612 }
2613 
2614 
2615 //creating scatter and gather cells (second layer)
2616 void
2618 {
2619 
2620  for ( int id = 0; id < _nmesh; id++ ){
2621 
2622  //we prepare gatherArrays to other processor
2623  map<int, vector<int> > gatherArrays; //key=sending procs, value = scatter cells on other cells to this processor
2624  foreach( const IntMap::value_type& mpos, _gatherCellsLevel1PartIDMap ){
2625  const int globalID = mpos.first;
2626  const int partID = mpos.second; //this is where is going to be sent
2627  gatherArrays[partID].push_back( globalID );
2628  }
2629 
2630  vector<int> gatherProcs;
2631  //create a vector holding receiver processor
2632  foreach( const VectorMap::value_type& pos, gatherArrays){
2633  gatherProcs.push_back( pos.first);
2634  }
2635 
2636  //globalSendProcess is holding number of sending processro for each processor
2637  Array<int> globalGatherProcsCount( _nPart.at(id) );
2638  int gatherProcsCount = gatherArrays.size();
2639  MPI::COMM_WORLD.Allgather(&gatherProcsCount, 1, MPI::INT, globalGatherProcsCount.getData(), 1, MPI::INT);
2640 
2641  Array<int> offsets( _nPart.at(id) );
2642  //form offsets
2643  offsets[0] = 0;
2644  for ( int p = 1; p < int(_nPart.at(id)); p++ ){
2645  offsets[p] = globalGatherProcsCount[p-1] + offsets[p-1];
2646  }
2647  //get global buffer size
2648  int globalBufferSize = 0;
2649  for ( int i = 0; i < globalGatherProcsCount.getLength(); i++ ){
2650  globalBufferSize += globalGatherProcsCount[i];
2651  }
2652  Array<int> globalGatherProcs( globalBufferSize );
2653  //gathering partial partions for _row and _col
2654  MPI::COMM_WORLD.Allgatherv(&gatherProcs[0], gatherProcs.size(), MPI::INT, globalGatherProcs.getData(),
2655  (const int *) globalGatherProcsCount.getData(), (const int *)offsets.getData(), MPI::INT);
2656 
2657  //now preparing scatterProcs
2658  list<int> scatterProcs;
2659  for ( int i = 0; i < _nPart.at(id); i++ ){
2660  for ( int j = 0; j < globalGatherProcsCount[i]; j++ ){
2661  const int gatherProcID = globalGatherProcs[ offsets[i]+j];
2662  if ( _procID == gatherProcID ) //if it is sending me then this is included in recvProcs
2663  scatterProcs.push_back( i );
2664  }
2665  }
2666 
2667 
2668  //MPI SENDING
2669  MPI::Request request_send[ gatherArrays.size() ];
2670  int indxSend = 0;
2671  int indxRecv = 0;
2672  foreach(const VectorMap::value_type pos, gatherArrays){
2673  int to_where = pos.first;
2674  int count = int( gatherArrays[to_where].size() );
2675  int send_tag = 112233;
2676  request_send[indxSend++] =
2677  MPI::COMM_WORLD.Isend( &gatherArrays[to_where][0], count, MPI::INT, to_where, send_tag );
2678  }
2679 
2680 
2681  map<int, vector<int> > scatterArrays; //key=recv procs, value = gather cells
2682  list<int>::iterator it;
2683  while ( !scatterProcs.empty() ){
2684  for( it = scatterProcs.begin(); it != scatterProcs.end(); ++it ){
2685  int from_where = *it; //whereever it sends data has to get another data from there
2686  int recv_tag = 112233;
2687  MPI::Status recv_status;
2688  if( MPI::COMM_WORLD.Iprobe(from_where, recv_tag, recv_status) ){
2689  //find receive buffer size
2690  int scatter_count = recv_status.Get_count( MPI::INT );
2691  //recv arrays allocation
2692  scatterArrays[from_where].resize( scatter_count);
2693  scatterProcs.remove(from_where);
2694  break;
2695  }
2696  }
2697  }
2698 
2699 
2700  //RECIEVING
2701  //getting values from other meshes to fill g
2702  MPI::Request request_recv[ scatterArrays.size() ];
2703  foreach( const VectorMap::value_type& pos, scatterArrays){
2704  int from_where = pos.first; //whereever it sends data has to get another data from there
2705  int recv_count = int(scatterArrays[from_where].size());
2706  int recv_tag = 112233;
2707  request_recv[indxRecv++] =
2708  MPI::COMM_WORLD.Irecv( &scatterArrays[from_where][0], recv_count, MPI::INT, from_where, recv_tag );
2709  }
2710 
2711  int countScatter = scatterArrays.size();
2712  int countGather = gatherArrays.size();
2713  MPI::Request::Waitall( countScatter, request_recv );
2714  MPI::Request::Waitall( countGather, request_send );
2715 
2716 
2717  StorageSite::ScatterMap & cellScatterMapLevel1 = _meshListLocal.at(id)->getCells().getScatterMapLevel1();
2718  StorageSite::GatherMap & cellGatherMapLevel1 = _meshListLocal.at(id)->getCells().getGatherMapLevel1();
2719  map<int,int>& globalToLocal = _meshListLocal.at(id)->getGlobalToLocal();
2720  StorageSite& cellSite = _meshListLocal.at(id)->getCells();
2721  //create scatter ghost sites level1
2722  foreach ( const VectorMap::value_type& pos, scatterArrays ){
2723  const int toProcID = pos.first;
2724  const vector<int>& scatter_array = pos.second;
2725  const int scatterSize = int( scatter_array.size() );
2726  //scatter Arrays
2727  ArrayIntPtr from_indices = ArrayIntPtr( new Array<int>( scatterSize ) );
2728  //copy scatter_array to from_indices
2729  for ( int i = 0; i < scatterSize; i++ ){
2730  (*from_indices)[i] = globalToLocal[ scatter_array[i] ];
2731  }
2732 
2733  //create scatter sites
2734  shared_ptr<StorageSite> siteScatter( new StorageSite(scatterSize) );
2735 
2736  siteScatter->setScatterProcID( _procID );
2737  siteScatter->setGatherProcID ( toProcID );
2738 
2739 
2740  int packed_info = (std::max(_procID,toProcID) << 16 ) | ( std::min(_procID,toProcID) );
2741  siteScatter->setTag( packed_info );
2742  Mesh::PartIDMeshIDPair pairID = make_pair<int,int>(toProcID, id);
2743  _meshListLocal.at(id)->createGhostCellSiteScatterLevel1( pairID, siteScatter );
2744  cellScatterMapLevel1[ siteScatter.get() ] = from_indices;
2745  }
2746 
2747  int gatherIndx = cellSite.getCount();
2748  //create gather ghost sites level1
2749  foreach ( const VectorMap::value_type& pos, gatherArrays ){
2750  const int fromProcID = pos.first;
2751  const vector<int>& gather_array = pos.second;
2752  const int gatherSize = int( gather_array.size() );
2753  //gather Arrays
2754  ArrayIntPtr to_indices = ArrayIntPtr( new Array<int>( gatherSize ) );
2755  //copy gather_array to to_indices
2756  for ( int i = 0; i < gatherSize; i++ ){
2757  (*to_indices)[i] = gatherIndx;
2758  globalToLocal[gather_array[i]] = gatherIndx;
2759  gatherIndx++;
2760  }
2761 
2762  //create gather and ghost sites
2763  shared_ptr<StorageSite> siteGather ( new StorageSite(gatherSize ) );
2764 
2765  siteGather->setScatterProcID( _procID );
2766  siteGather->setGatherProcID ( fromProcID );
2767 
2768  int packed_info = (std::max(fromProcID, _procID) << 16 ) | ( std::min(fromProcID, _procID) );
2769  siteGather->setTag( packed_info );
2770  Mesh::PartIDMeshIDPair pairID = make_pair<int,int>(fromProcID, id);
2771  _meshListLocal.at(id)->createGhostCellSiteGatherLevel1 ( pairID, siteGather );
2772  cellGatherMapLevel1 [ siteGather.get() ] = to_indices;
2773  }
2774 
2775  //create storage sites
2776  cellSite.setCountLevel1(gatherIndx);
2777 
2778  const StorageSite& faceSite = _meshListLocal.at(id)->getFaces();
2779  _meshListLocal.at(id)->eraseConnectivity(cellSite, cellSite);
2780  _meshListLocal.at(id)->eraseConnectivity(cellSite, faceSite);
2781 
2782  //uniquie
2783  if ( !_meshList.at(0)->isMergedMesh() )
2784  _meshListLocal.at(id)->uniqueFaceCells();
2785 
2786  _meshListLocal.at(id)->createScatterGatherCountsBuffer();
2787  _meshListLocal.at(id)->syncCounts();
2788  _meshListLocal.at(id)->recvScatterGatherCountsBufferLocal();
2789 
2790  _meshListLocal.at(id)->createScatterGatherIndicesBuffer();
2791  _meshListLocal.at(id)->syncIndices();
2792  _meshListLocal.at(id)->recvScatterGatherIndicesBufferLocal();
2793 
2794  _meshListLocal.at(id)->createCellCellsGhostExt();
2795 
2796  //adding Mesh classes new data structure to keep track of globalID nodes (consisten with fluent case file)
2797  _meshListLocal.at(id)->createLocalToGlobalNodesArray();
2798  const StorageSite& nodes = _meshListLocal.at(id)->getNodes();
2799  Array<int>& localToGlobalNodes = *_meshListLocal.at(id)->getLocalToGlobalNodesPtr();
2800  //map<int,int>& globalToLocalNodes = _meshListLocal.at(id)->getGlobalToLocalNodes();
2801 
2802  //updating localToGlobal
2803  for ( int i = 0; i < nodes.getCount(); i++ ){
2804  const int globalID = (*_partNodes.at(id))(_procID,i);
2805  localToGlobalNodes[i] = globalID;
2806  //globalToLocalNodes[globalID] = i;
2807  }
2808  //find boundary nodes
2809  set<int>& boundaryNodeSet = _meshListLocal.at(id)->getBoundaryNodesSet();
2810  foreach(const FaceGroupPtr fgPtr, _meshListLocal.at(id)->getBoundaryFaceGroups() ){
2811  const FaceGroup& fg = *fgPtr;
2812  const StorageSite& faces = fg.site;
2813  const int nFaces = faces.getCount();
2814  const CRConnectivity& faceNodes = _meshListLocal.at(id)->getFaceNodes(faces);
2815  for(int f=0; f<nFaces; f++){
2816  const int nFaceNodes = faceNodes.getCount(f);
2817  for(int nn=0; nn<nFaceNodes; nn++){
2818  const int n=faceNodes(f,nn);
2819  boundaryNodeSet.insert(n);
2820  }
2821  }
2822  }
2823 
2824 
2825 // const Array<Mesh::VecD3>& coordFluent = _meshList.at(0)->getNodeCoordinates();
2826 // const Array<Mesh::VecD3>& coordPart = _meshListLocal.at(0)->getNodeCoordinates();
2827 // if ( _procID == 0 )
2828 // coordFluent.print(cout);
2829 // cout << endl;
2830 // cout << endl;
2831 // if ( _procID == 1 ){
2832 // coordPart.print(cout);
2833 // localToGlobalNodes.print(cout);
2834 // cout << endl;
2835 // CRConnectivityPrint(*_partNodes.at(0),_procID,"partNodes");
2836 // }
2837 
2838 /* const Array<int>& localToGlobalNodes = _faceNodesGlobal.at(0)->getLocalToGlobalMap();
2839  localToGlobalNodes.print(cout);*/
2840 
2841  }
2842 
2843 
2844 
2845  if ( _debugMode )
2847  }
2848 
2849 
2850 
2851 void
2853 {
2854  const Mesh& mesh = *_meshList.at(0);
2855  Mesh& meshLocal = *_meshListLocal.at(0);
2856  const StorageSite& nodes = mesh.getNodes();
2857  StorageSite& nodesLocal = meshLocal.getNodes();
2858  const Array<Mesh::VecD3>& coords = mesh.getNodeCoordinates();
2859 // map<int,int>& globalToLocalNodesFromLocalMesh= meshLocal.getGlobalToLocalNodes();
2860 // map<int,int>& g
2861 
2862  const int nodeCount = nodes.getCount();
2863  Array<int> globalToLocalNodes(nodeCount);
2864 
2865  globalToLocalNodes = -1;
2866  int bMeshNodeCount=0;
2867  int bMeshFaceCount=0;
2868  foreach(const FaceGroupPtr fgPtr, mesh.getBoundaryFaceGroups()){
2869  const FaceGroup& fg = *fgPtr;
2870  const StorageSite& faces = fg.site;
2871  const int nFaces = faces.getCount();
2872  const CRConnectivity& faceNodes = mesh.getFaceNodes(faces);
2873  for(int f=0; f<nFaces; f++){
2874  const int nFaceNodes = faceNodes.getCount(f);
2875  for(int nn=0; nn<nFaceNodes; nn++){
2876  const int n=faceNodes(f,nn);
2877  if (globalToLocalNodes[n] == -1){
2878  globalToLocalNodes[n] = bMeshNodeCount++;
2879  }
2880  }
2881  }
2882  bMeshFaceCount += nFaces;
2883  }
2884 
2885  _bMesh = new Mesh(mesh.getDimension());
2886 
2887  StorageSite& bMeshFaces = _bMesh->getFaces();
2888  StorageSite& bMeshNodes = _bMesh->getNodes();
2889  bMeshFaces.setCount( bMeshFaceCount );
2890  bMeshNodes.setCount( bMeshNodeCount );
2891 
2892  _bMesh->createBoundaryFaceGroup(bMeshFaceCount,0,0,"wall");
2893 
2894  //setting coordinates
2895  shared_ptr< Array<Mesh::VecD3> > bMeshCoordPtr( new Array< Mesh::VecD3 > ( bMeshNodeCount ) );
2896 
2897  shared_ptr<Mesh::IntArray> myCommonNodes(new Mesh::IntArray(bMeshNodeCount));
2898  shared_ptr<Mesh::IntArray> otherCommonNodes(new Mesh::IntArray(bMeshNodeCount));
2899  for(int n=0; n<nodeCount; n++)
2900  {
2901  const int nLocal = globalToLocalNodes[n];
2902  if (nLocal >=0)
2903  {
2904  (*bMeshCoordPtr)[nLocal] = coords[n];
2905  (*myCommonNodes)[nLocal] = nLocal;
2906  (*otherCommonNodes)[nLocal] = n;
2907  }
2908  }
2909  nodesLocal.getCommonMap()[&bMeshNodes] = myCommonNodes;
2910  bMeshNodes.getCommonMap()[&nodesLocal] = otherCommonNodes;
2911  //filling scatter index (global to local)
2912  map<int,int>& scatterIndex = nodesLocal.getScatterIndex()[&bMeshNodes];
2913  for ( int n = 0; n < bMeshNodeCount; n++ ){
2914  const int nodeID = (*otherCommonNodes)[n];
2915  scatterIndex[nodeID] = n;
2916  }
2917 
2918 
2919 
2920  _bMesh->setCoordinates( bMeshCoordPtr );
2921 
2922  //faceNodes constructor
2923  shared_ptr<CRConnectivity> bFaceNodes( new CRConnectivity(bMeshFaces,
2924  bMeshNodes) );
2925 
2926  bFaceNodes->initCount();
2927 
2928  bMeshFaceCount=0;
2929 
2930  foreach(FaceGroupPtr fgPtr, mesh.getBoundaryFaceGroups()){
2931  FaceGroup& fg = *fgPtr;
2932  StorageSite& faces = const_cast<StorageSite&>(fg.site);
2933  const int nFaces = faces.getCount();
2934  const CRConnectivity& faceNodes = mesh.getFaceNodes(faces);
2935 
2936  shared_ptr<Mesh::IntArray> myCommonFaces(new Mesh::IntArray(nFaces));
2937  shared_ptr<Mesh::IntArray> otherCommonFaces(new Mesh::IntArray(nFaces));
2938 
2939  for(int f=0; f<nFaces; f++){
2940  const int nFaceNodes = faceNodes.getCount(f);
2941  bFaceNodes->addCount(bMeshFaceCount,nFaceNodes);
2942  (*myCommonFaces)[f] = bMeshFaceCount;
2943  (*otherCommonFaces)[f] = f;
2944  bMeshFaceCount++;
2945  }
2946 
2947  faces.getCommonMap()[&bMeshFaces] = myCommonFaces;
2948  bMeshFaces.getCommonMap()[&faces] = otherCommonFaces;
2949  }
2950 
2951  bFaceNodes->finishCount();
2952  bMeshFaceCount=0;
2953 
2954  foreach(const FaceGroupPtr fgPtr, mesh.getBoundaryFaceGroups()){
2955  const FaceGroup& fg = *fgPtr;
2956  const StorageSite& faces = fg.site;
2957  const int nFaces = faces.getCount();
2958  const CRConnectivity& faceNodes = mesh.getFaceNodes(faces);
2959  for(int f=0; f<nFaces; f++){
2960  const int nFaceNodes = faceNodes.getCount(f);
2961  for(int nn=0; nn<nFaceNodes; nn++){
2962  const int n=faceNodes(f,nn);
2963  const int nLocal = globalToLocalNodes[n];
2964  bFaceNodes->add(bMeshFaceCount,nLocal);
2965  }
2966  bMeshFaceCount++;
2967  }
2968  }
2969 
2970  bFaceNodes->finishAdd();
2971  //setting faceNodes
2972  Mesh::SSPair key(&bMeshFaces,&bMeshNodes);
2973  Mesh::ConnectivityMap& connectivityMap = _bMesh->getConnectivityMap();
2974  connectivityMap[key] = bFaceNodes;
2975  //_bMesh->_connectivityMap[key] = bFaceNodes;
2976 
2977 }
2978 
2979 
2980 
2981 //scatter levels debugger
2982 void
2984 {
2985  //open file
2986  debug_file_open("level1_scatter_gather_cells");
2987  //scatter cells
2988  for ( int id = 0; id < _nmesh; id++ ){
2989  const Mesh& mesh = *_meshListLocal.at(id);
2990  const StorageSite& cellSite = mesh.getCells();
2991  const StorageSite::ScatterMap& cellSiteScatterMapLevel1 = cellSite.getScatterMapLevel1();
2992  //get scatter map key ={neight part id, mesh id}, value = scatter storage site
2993  const Mesh::GhostCellSiteMap& ghostSiteScatterMapLevel1 = mesh.getGhostCellSiteScatterMapLevel1();
2994  _debugFile << "This Mesh ID (Scatter Cells) = " << id << endl;
2995  //loop over scatter mappers
2996  foreach ( const Mesh::GhostCellSiteMap::value_type& mpos, ghostSiteScatterMapLevel1 ){
2997  const Mesh::PartIDMeshIDPair& pairID = mpos.first;
2998  const StorageSite& siteScatter = *(mpos.second);
2999  const Array<int>& scatterArray = *(cellSiteScatterMapLevel1.find( &siteScatter )->second);
3000  const int neighProcID = pairID.first;
3001  const int neighMeshID = pairID.second;
3002  _debugFile << " neighProcID = " << neighProcID << " neighMeshID = " << neighMeshID << endl;
3003  for ( int i = 0; i < scatterArray.getLength(); i++ ){
3004  _debugFile << " " << scatterArray[i] << endl;
3005  }
3006  }
3007  }
3008 
3009  //gather cells
3010  for ( int id = 0; id < _nmesh; id++ ){
3011  const Mesh& mesh = *_meshListLocal.at(id);
3012  const StorageSite& cellSite = mesh.getCells();
3013  const StorageSite::GatherMap& cellSiteGatherMapLevel1 = cellSite.getGatherMapLevel1();
3014  //get scatter map key ={neight part id, mesh id}, value = scatter storage site
3015  const Mesh::GhostCellSiteMap& ghostSiteGatherMapLevel1 = mesh.getGhostCellSiteGatherMapLevel1();
3016  _debugFile << "This Mesh ID (Gather Cells) = " << id << endl;
3017  //loop over scatter mappers
3018  foreach ( const Mesh::GhostCellSiteMap::value_type& mpos, ghostSiteGatherMapLevel1 ){
3019  const Mesh::PartIDMeshIDPair& pairID = mpos.first;
3020  const StorageSite& siteGather = *(mpos.second);
3021  const Array<int>& gatherArray = *(cellSiteGatherMapLevel1.find( &siteGather )->second);
3022  const int neighProcID = pairID.first;
3023  const int neighMeshID = pairID.second;
3024  _debugFile << " neighProcID = " << neighProcID << " neighMeshID = " << neighMeshID << endl;
3025  for ( int i = 0; i < gatherArray.getLength(); i++ ){
3026  _debugFile << " " << gatherArray[i] << endl;
3027  }
3028  }
3029  }
3030 
3031  //close file
3032  debug_file_close();
3033 
3034 }
3035 
3036 
3037 void
3039 {
3040  const CRConnectivity& cellCells2 = _meshListLocal[0]->getCellCells2();
3041  //openfile
3042  debug_file_open("CRConnectivity_cellCells2");
3043  //print connectivity
3044  CRConnectivityPrintFile( cellCells2, "CellCells2" );
3045  //close file
3046  debug_file_close();
3047 }
3048 
3049 
3050 
3051 
3052 
3053 
3054 void
3056 {
3057  MPI::COMM_WORLD.Barrier();
3058  _localToGlobalMappers.clear();
3059  _globalToLocalMappers.clear();
3060 }
3061 
3062 int
3063 MeshPartitioner::get_window_displ( int id, int neigh_mesh_id )
3064 {
3065  int loc = 0;
3066  int window_displ = 0;
3067  for ( int i = 0; i < neigh_mesh_id; i++)
3068  loc += (*_interfaceMeshCounts.at(id))[i];
3069 
3070  while ( (*_interfaceMeshIDs.at(id))[loc] != _procID){
3071  window_displ += (*_offsetInterfaceCells.at(id))[loc+1] - (*_offsetInterfaceCells.at(id))[loc];
3072  loc++;
3073  }
3074 
3075 
3076  return window_displ;
3077 }
3078 
3079 void
3081 {
3082  int int_size = MPI::INT.Get_size();
3083  MPI::Aint lb, sizeofAint;
3084  MPI::INT.Get_extent(lb,sizeofAint);
3085 
3086  int window_size = _windowSize.at(id); //already MPI::MAX has taken maximum size
3087  _winLocal = MPI::Win::Create(_ghostCellsLocal.at(id)->getData(), window_size*sizeofAint, int_size,
3088  MPI_INFO_NULL, MPI::COMM_WORLD);
3089  _winGlobal = MPI::Win::Create(_ghostCellsGlobal.at(id)->getData(), window_size*sizeofAint, int_size,
3090  MPI_INFO_NULL, MPI::COMM_WORLD);
3091 
3092 }
3093 
3094 void
3096 {
3097  _winLocal.Free();
3098  _winGlobal.Free();
3099 }
3100 
3101 void
3103 {
3104 
3105 // _winLocal.Fence ( 0 );
3106 // _winGlobal.Fence( 0 );
3107 
3108  _winLocal.Fence(MPI::MODE_NOPUT);
3109  _winGlobal.Fence(MPI::MODE_NOPUT);
3110 
3111 }
3112 
3113 //dump all mesh information
3114 void
3116 {
3117  mesh_file();
3118  mesh_tecplot();
3119 
3120 
3121 }
3122 
3123 void
3125 {
3126  stringstream ss;
3127  ss << "mesh_proc" << _procID << "_info.dat";
3128  ofstream mesh_file( (ss.str()).c_str() );
3129  for ( int id = 0; id < _nmesh; id++ ){
3130 
3131  const StorageSite::ScatterMap& cellScatterMap = _meshListLocal.at(id)->getCells().getScatterMap();
3132  const StorageSite::GatherMap& cellGatherMap = _meshListLocal.at(id)->getCells().getGatherMap();
3133  const Mesh::GhostCellSiteMap& ghostCellSiteScatterMap = _meshListLocal.at(id)->getGhostCellSiteScatterMap();
3134  const Mesh::GhostCellSiteMap& ghostCellSiteGatherMap = _meshListLocal.at(id)->getGhostCellSiteGatherMap();
3135 
3136  Mesh::GhostCellSiteMap::const_iterator it_ghostScatter;
3137  //loop over interfaces
3138  for ( it_ghostScatter = ghostCellSiteScatterMap.begin(); it_ghostScatter != ghostCellSiteScatterMap.end(); it_ghostScatter++ ){
3139  const Mesh::PartIDMeshIDPair pairID = it_ghostScatter->first;
3140  int neighID = pairID.first;
3141 
3142  const StorageSite& siteScatter = *( ghostCellSiteScatterMap.find( pairID )->second );
3143  const StorageSite& siteGather = *( ghostCellSiteGatherMap.find ( pairID )->second );
3144 
3145 
3146  const Array<int>& scatterArray = *(cellScatterMap.find( &siteScatter )->second);
3147  const Array<int>& gatherArray = *(cellGatherMap.find ( &siteGather )->second);
3148  for ( int i = 0; i < siteScatter.getCount(); i++){
3149  mesh_file << " neightMeshID = " << neighID << " "
3150  << gatherArray[i] + 1 << " ===> "
3151  << scatterArray[i] + 1 << endl;
3152  }
3153  }
3154 
3155  }
3156 
3157  mesh_file.close();
3158 
3159 }
3160 
3161 
3162 //need modification for quad, hexa, tetra
3163 void
3165 {
3166  stringstream ss;
3167  ss << "mesh_proc" << _procID << ".dat";
3168  ofstream mesh_file( (ss.str()).c_str() );
3169 
3170  const Mesh& mesh = *(_meshListLocal.at(0));
3171  const CRConnectivity& cellNodes = mesh.getCellNodes();
3172  const Array<Mesh::VecD3>& coord = mesh.getNodeCoordinates();
3173  int tot_elems = cellNodes.getRowDim();
3174  int tot_nodes = coord.getLength();
3175 
3176  mesh_file << "title = \" tecplot file for process Mesh \" " << endl;
3177  mesh_file << "variables = \"x\", \"y\", \"z\", \"cell_type\" " << endl;
3178 #if 0
3179  mesh_file << "variables = \"x\", \"y\", \"z\", \"cell_type\", \"color\" " << endl;
3180 #endif
3181 
3182  stringstream zone_info;
3183 
3184  if ( _eType.at(0) == TRI )
3185  zone_info << " DATAPACKING = BLOCK, VARLOCATION = ([4]=CELLCENTERED), ZONETYPE=FETRIANGLE ";
3186 
3187  if ( _eType.at(0) == QUAD )
3188  zone_info << " DATAPACKING = BLOCK, VARLOCATION = ([4]=CELLCENTERED), ZONETYPE=FEQUADRILATERAL ";
3189 
3190  if ( _eType.at(0) == HEXA )
3191  zone_info << " DATAPACKING = BLOCK, VARLOCATION = ([4]=CELLCENTERED), ZONETYPE=FEBRICK ";
3192 
3193  if ( _eType.at(0) == TETRA )
3194  zone_info << " DATAPACKING = BLOCK, VARLOCATION = ([4]=CELLCENTERED), ZONETYPE=FETETRAHEDRON ";
3195 
3196 
3197  mesh_file << "zone N = " << tot_nodes << " E = " << tot_elems << zone_info.str() << endl;
3198 
3199  //x
3200  for ( int n = 0; n < tot_nodes; n++){
3201  mesh_file << scientific << coord[n][0] << " " ;
3202  if ( n % 5 == 0 ) mesh_file << endl;
3203  }
3204  mesh_file << endl;
3205 
3206  //y
3207  for ( int n= 0; n < tot_nodes; n++){
3208  mesh_file << scientific << coord[n][1] << " ";
3209  if ( n % 5 == 0 ) mesh_file << endl;
3210  }
3211  mesh_file << endl;
3212 
3213  //z
3214  for ( int n = 0; n < tot_nodes; n++){
3215  mesh_file << scientific << coord[n][2] << " ";
3216  if ( n % 5 == 0) mesh_file << endl;
3217  }
3218 
3219  mesh_file << endl;
3220  mesh_file << endl;
3221  //cell type
3222  int cell_type = -1;
3223  for ( int n = 0; n < tot_elems; n++){
3224  int elem_id = _cellToOrderedCell[0][n];
3225  cell_type = 1;
3226  if ( _nonInteriorCells.at(0).count(elem_id) == 0 ){
3227  cell_type = 0;
3228  } else {
3229  cell_type = 1;
3230  }
3231 
3232  mesh_file << cell_type << " ";
3233  if ( n % 10 == 0 ) mesh_file << endl;
3234 
3235  }
3236  mesh_file << endl;
3237 #if 0
3238  mesh_file << endl;
3239  //mesh color is only
3240  const Array<int>& color = mesh.getCellColors();
3241  for ( int n = 0; n < tot_elems; n++ ){
3242  mesh_file << color[n] << " ";
3243  if ( n % 10 == 0 ) mesh_file << endl;
3244  }
3245 #endif
3246 
3247 
3248  mesh_file << endl;
3249  //connectivity
3250  for (int n = 0; n < tot_elems; n++){
3251  int nnodes = cellNodes.getCount(n);
3252  if ( n < _nelems.at(0) ){
3253  for ( int node = 0; node < nnodes; node++)
3254  mesh_file << cellNodes(n,node)+1 << " ";
3255  } else {
3256 
3257  if ( _eType.at(0) == TRI )
3258  mesh_file << cellNodes(n,0)+1 << " " << cellNodes(n,1)+1 <<
3259  " " << cellNodes(n,0)+1 << " ";
3260 
3261  if ( _eType.at(0) == QUAD )
3262  mesh_file << cellNodes(n,0)+1 << " " << cellNodes(n,0)+1 <<
3263  " " << cellNodes(n,1)+1 << " " << cellNodes(n,1)+1 << " ";
3264 
3265  if ( _eType.at(0) == HEXA )
3266  mesh_file << cellNodes(n,0)+1 << " " << cellNodes(n,1)+1 << " "
3267  << cellNodes(n,2)+1 << " " << cellNodes(n,3)+1 << " "
3268  << cellNodes(n,0)+1 << " " << cellNodes(n,1)+1 << " "
3269  << cellNodes(n,2)+1 << " " << cellNodes(n,3)+1 << " ";
3270 
3271  if ( _eType.at(0) == TETRA )
3272  mesh_file << cellNodes(n,0)+1 << " " << cellNodes(n,1)+1 <<
3273  " " << cellNodes(n,2)+1 << " " << cellNodes(n,0)+1 << " ";
3274 
3275 
3276  }
3277  mesh_file << endl;
3278  }
3279 
3280 
3281  mesh_file.close();
3282 
3283 }
3284 
3285 void
3287 {
3288  int nprocs = MPI::COMM_WORLD.Get_size();
3289  ofstream mesh_file("mesh.xmf");
3290  mesh_file << "<?xml version='1.0' ?>" << endl;
3291  mesh_file << "<!DOCTYPE Xdmf SYSTEM 'Xdmf.dtd' []>" << endl;
3292  mesh_file << "<Xdmf xmlns:xi='http://www.w3.org/2001/XInclude' Version='2.0'>" << endl;
3293  mesh_file << " <Domain>" << endl;
3294  for (int i=0; i < nprocs; i++)
3295  mesh_file << " <xi:include href='mesh_proc" << i << ".xmf' />" << endl;
3296  mesh_file << " </Domain>" << endl;
3297  mesh_file << "</Xdmf>" << endl;
3298  mesh_file.close();
3299 }
3300 
3301 
3302 // Dump the mesh in xdmf format.
3303 // We use ASCII for convenience with the values encoded in the XML,
3304 // rather that a seperate hdf5 file.
3305 void
3307 {
3308  if (_procID == 0)
3309  mesh_xdmf_header();
3310 
3311  stringstream ss;
3312  ss << "mesh_proc" << _procID << ".xmf";
3313  ofstream mesh_file( (ss.str()).c_str() );
3314 
3315  const Mesh& mesh = *(_meshListLocal.at(0));
3316  const CRConnectivity& cellNodes = mesh.getCellNodes();
3317  const Array<Mesh::VecD3>& coord = mesh.getNodeCoordinates();
3318  int tot_elems = _nelems.at(0);
3319  int tot_nodes = coord.getLength();
3320  int epn;
3321 
3322  mesh_file << "<Grid Name='Mesh-" << _procID << "' GridType='Uniform'>" << endl << " ";
3323 
3324  switch (_eType.at(0)) {
3325  case TRI:
3326  mesh_file << "<Topology TopologyType='Triangle'";
3327  epn = 3;
3328  break;
3329  case QUAD:
3330  mesh_file << "<Topology TopologyType='Quadrilateral'";
3331  epn = 4;
3332  break;
3333  case HEXA:
3334  mesh_file << "<Topology TopologyType='Hexahedron'";
3335  epn = 8;
3336  break;
3337  case TETRA:
3338  mesh_file << "<Topology TopologyType='Tetrahedron'";
3339  epn = 4;
3340  break;
3341  default:
3342  cout << "Unknown mesh type " << _eType.at(0) << endl;
3343  return;
3344  }
3345  mesh_file << " Dimensions='" << tot_elems << "'>" << endl;
3346  mesh_file << " <DataItem Dimensions='" << tot_elems << " " << epn << "'>" << endl;
3347 
3348  //connectivity (Topology)
3349  for (int n = 0; n < tot_elems; n++) {
3350  mesh_file << " ";
3351  for (int node = 0; node < cellNodes.getCount(n); node++)
3352  mesh_file << cellNodes(n,node) << " ";
3353  mesh_file << endl;
3354  }
3355  mesh_file << " </DataItem>" << endl;
3356  mesh_file << " </Topology>" << endl;
3357 
3358  // Geometry
3359  mesh_file << " <Geometry Type='XYZ'>" << endl;
3360  mesh_file << " <DataItem Dimensions='" << tot_nodes << " 3' NumberType='Float'>" << endl;
3361  for (int n = 0; n < tot_nodes; n++) {
3362  mesh_file << " ";
3363  mesh_file << coord[n][0] << " " ;
3364  mesh_file << coord[n][1] << " " ;
3365  mesh_file << coord[n][2] << endl;
3366  }
3367  mesh_file << " </DataItem>" << endl;
3368  mesh_file << " </Geometry>" << endl;
3369  mesh_file << "</Grid>" << endl;
3370  mesh_file.close();
3371 }
3372 
3373 
3374 
3375 void
3376 MeshPartitioner::CRConnectivityPrint( const CRConnectivity& conn, int procID, const string& name )
3377 {
3378 
3379  if ( MPI::COMM_WORLD.Get_rank() == procID ){
3380  cout << name << " :" << endl;
3381  const Array<int>& row = conn.getRow();
3382  const Array<int>& col = conn.getCol();
3383  for ( int i = 0; i < row.getLength()-1; i++ ){
3384  cout << " i = " << i << ", ";
3385  for ( int j = row[i]; j < row[i+1]; j++ )
3386  cout << col[j] << " ";
3387  cout << endl;
3388  }
3389  }
3390 
3391 }
3392 
3393 
3394 void
3396 {
3397  _debugFile << name << " :" << endl;
3398  _debugFile << endl;
3399  const Array<int>& row = conn.getRow();
3400  const Array<int>& col = conn.getCol();
3401  for ( int i = 0; i < row.getLength()-1; i++ ){
3402  _debugFile << " i = " << i << ", ";
3403  for ( int j = row[i]; j < row[i+1]; j++ )
3404  _debugFile << col[j] << " ";
3405  _debugFile << endl;
3406  }
3407  _debugFile << endl;
3408 }
3409 
3410 void
3411 MeshPartitioner::debug_file_open( const string& fname_ )
3412 {
3413  stringstream ss(stringstream::in | stringstream::out);
3414  ss << _procID;
3415 
3416  string fname = "MeshPartitioner_PROC" + ss.str() + "_" + fname_ + ".dat";
3417  _debugFile.open( fname.c_str() );
3418  ss.str("");
3419 }
3420 
3421 void
3423 {
3424  _debugFile.close();
3425 }
vector< int * > _ePtr
const FaceGroupList & getBoundaryFaceGroups() const
Definition: Mesh.h:187
const Array< int > & getCol() const
vector< int * > _eInd
int getCount(const int i) const
vector< StorageSitePtr > _faceSite
void debug_file_open(const string &fname)
const Array< int > & getRow() const
vector< map< int, int > > _bndryOffsets
void setID(const int id)
Definition: Mesh.h:321
int getBoundaryGroupCount() const
Definition: Mesh.h:184
shared_ptr< FaceGroup > FaceGroupPtr
Definition: Mesh.h:46
void CRConnectivityPrintFile(const CRConnectivity &conn, const string &name)
vector< CRConnectivityPtr > _cellCells
int getSelfCount() const
Definition: StorageSite.h:40
vector< multimap< int, int > > _globalToLocalMappers
const Array< int > & getGlobalToLocalMap() const
void setWeightType(int weight_type)
void set_eptr_eind(int id)
vector< int > _totElems
void DEBUG_faceCells_faceNodes()
vector< float * > _ubvec
vector< ArrayVecD3Ptr > _coord
vector< int > _ncommonNodes
vector< ArrayIntPtr > _interfaceMeshCounts
Definition: Mesh.h:28
vector< StorageSitePtr > _nodeSite
vector< CRConnectivityPtr > _partFaces
vector< CRConnectivityPtr > _faceParts
void mapBounIDAndCell(int id)
ArrayIntPtr _fiedlerMap
vector< ArrayIntPtr > _interfaceMeshIDs
vector< int * > _elemWithGhosts
const StorageSite & getNodes() const
Definition: Mesh.h:110
void DEBUG_exchange_interface_meshes()
void DEBUG_compute_elem_dist()
vector< set< int > > _elemSet
Definition: Field.h:14
void DEBUG_preserve_cell_order()
void reorder(const Array< int > &indices)
void DEBUG_elem_connectivity()
const ScatterIndex & getScatterIndex() const
Definition: StorageSite.h:61
multiMap & getCellCellsGlobal()
Definition: Mesh.h:247
shared_ptr< StorageSite > StorageSitePtr
ConnectivityMap & getConnectivityMap()
Definition: Mesh.h:335
const GatherMap & getGatherMapLevel1() const
Definition: StorageSite.h:74
vector< int * > _eElm
vector< int * > _elem
const ScatterMap & getScatterMapLevel1() const
Definition: StorageSite.h:73
void DEBUG_CRConnectivity_faceParts()
void setCoordinates(shared_ptr< Array< VecD3 > > x)
Definition: Mesh.h:204
Definition: Mesh.h:49
vector< int > _numFlag
double max(double x, double y)
Definition: Octree.cpp:18
const CRConnectivity & getFaceNodes(const StorageSite &site) const
Definition: Mesh.cpp:402
const CommonMap & getCommonMap() const
Definition: StorageSite.h:60
void order_faceCells_faceNodes()
int get_local_nodes(int id)
int count_interior_faces(int id)
vector< int * > _elmWght
void setCount(const int selfCount, const int nGhost=0)
Definition: StorageSite.h:42
vector< ArrayIntPtr > _procTotalInterfaces
vector< int > _nPart
vector< set< int > > _interfaceSet
void DEBUG_CRConnectivity_cellCells2()
vector< map< int, int > > _localToGlobalMappers
map< int, int > & getGlobalToLocal()
Definition: Mesh.h:243
vector< CRConnectivityPtr > _partCells
int getInterfaceGroupCount() const
Definition: Mesh.h:185
multimap< int, int > multiMap
Definition: Mesh.h:57
void cleanup_follow_exchange_part_elems()
void gatherCellsLevel1_partID_map()
const StorageSite & createBoundaryFaceGroup(const int size, const int offset, const int id, const string &boundaryType)
Definition: Mesh.cpp:278
vector< int > _wghtFlag
vector< Array< int > * > _globalIndx
shared_ptr< Array< Mesh::VecD3 > > ArrayVecD3Ptr
vector< StorageSitePtr > _cellSite
void CRConnectivityPrint(const CRConnectivity &conn, int procID, const string &name)
vector< int * > _part
const Array< int > & getLocalToGlobalMap() const
const CRConnectivity & getAllFaceCells() const
Definition: Mesh.cpp:378
map< SSPair, shared_ptr< CRConnectivity > > ConnectivityMap
Definition: Mesh.h:61
vector< CRConnectivityPtr > _faceNodes
vector< CRConnectivityPtr > _partNodes
void exchange_interface_meshes()
void DEBUG_CRConnectivity_cellParts()
const Array< VecD3 > & getNodeCoordinates() const
Definition: Mesh.h:218
Array< int > & getLocalToGlobal()
Definition: Mesh.h:240
virtual void * getData() const
Definition: Array.h:275
pair< const Field *, const StorageSite * > ArrayIndex
Definition: MultiField.h:21
void resize(const int newLength)
Definition: Array.h:56
void DEBUG_globalCellID_procID_map()
vector< StorageSitePtr > _partSite
vector< int > _eType
vector< StorageSitePtr > _cellSiteGlobal
vector< ArrayIntPtr > _offsetInterfaceCells
map< int, int > _cellToPreservedOrderCell
vector< FaceGroupPtr > FaceGroupList
Definition: Mesh.h:47
pair< const StorageSite *, const StorageSite * > SSPair
Definition: Mesh.h:60
map< PartIDMeshIDPair, shared_ptr< StorageSite > > GhostCellSiteMap
Definition: Mesh.h:63
void DEBUG_fiedler_partition()
shared_ptr< CRConnectivity > CRConnectivityPtr
void setCellZoneID(const int id)
Definition: Mesh.h:320
pair< int, int > PartIDMeshIDPair
Definition: Mesh.h:62
const StorageSite & getFaces() const
Definition: Mesh.h:108
vector< set< int > > _boundarySet
const CRConnectivity & getCellCells() const
Definition: Mesh.cpp:480
vector< map< int, int > > _interfaceOffsets
const StorageSite & getCells() const
Definition: Mesh.h:109
map< int, int > _globalToLocal
vector< Array< int > * > _elemDist
void createLocalGlobalArray()
Definition: Mesh.cpp:738
vector< const CRConnectivity * > _faceNodesGlobal
void resize_elem(int id)
vector< int > _ncon
void DEBUG_exchange_part_elems()
void DEBUG_gatherCellsLevel1_partID_map()
int getCountLevel1() const
Definition: StorageSite.h:72
void cellcells_global_extension()
const GhostCellSiteMap & getGhostCellSiteScatterMapLevel1() const
Definition: Mesh.h:139
const ScatterMap & getScatterMap() const
Definition: StorageSite.h:58
vector< int * > _col
map< const StorageSite *, shared_ptr< Array< int > > > ScatterMap
Definition: StorageSite.h:23
GhostCellSiteMap & getGhostCellSiteGatherMapLevel1()
Definition: Mesh.h:148
Definition: Array.h:14
vector< CRConnectivityPtr > _faceNodesOrdered
void DEBUG_level1_scatter_gather_cells()
MeshPartitioner(const MeshList &mesh_list, vector< int > npart, vector< int > eType)
vector< set< int > > _nonInteriorCells
vector< int > _nelems
vector< int > _windowSize
const MeshList _meshList
void DEBUG_order_faceCells_faceNodes()
vector< CRConnectivityPtr > _faceCellsOrdered
vector< multimap< int, int > > _mapPartAndElms
vector< int * > _row
int getCount() const
Definition: StorageSite.h:39
int get_window_displ(int id, int neigh_mesh_id)
shared_ptr< Array< int > > ArrayIntPtr
vector< vector< ArrayIntPtr > > _toIndices
vector< map< int, string > > _mapBounIDAndBounType
vector< int > _totElemsAndGhosts
vector< CRConnectivityPtr > _cellNodes
map< const StorageSite *, shared_ptr< Array< int > > > GatherMap
Definition: StorageSite.h:24
const FaceGroupList & getInterfaceGroups() const
Definition: Mesh.h:190
vector< Mesh * > _meshListLocal
vector< multimap< int, int > > _mapBounIDAndCell
map< int, int > _cellsLevel1PartID
void construct_mesh(int id)
double min(double x, double y)
Definition: Octree.cpp:23
void create_window(int id)
vector< vector< int > > _cellToOrderedCell
map< int, int > _gatherCellsLevel1PartIDMap
int getDimension() const
Definition: Mesh.h:105
void setCountLevel1(const int countLevel1)
Definition: StorageSite.h:69
void level1_scatter_gather_cells()
vector< ArrayIntPtr > _ghostCellsLocal
vector< CRConnectivityPtr > _faceCells
vector< CRConnectivityPtr > _cellParts
int getRowDim() const
vector< multimap< int, int > > _interfaceMap
vector< float * > _tpwgts
const CRConnectivity & getCellNodes() const
Definition: Mesh.cpp:426
const GhostCellSiteMap & getGhostCellSiteScatterMap() const
Definition: Mesh.h:116
void fiedler_order(const string &fname)
void cleanup_follow_faceCells_faceNodes()
void setNumFlag(int num_flag)
vector< int > _nelemsWithGhosts
vector< Mesh * > MeshList
Definition: Mesh.h:439
StorageSite site
Definition: Mesh.h:40
vector< int > _colDim
int getLength() const
Definition: Array.h:87
vector< vector< ArrayIntPtr > > _fromIndices
vector< int > _edgecut
vector< const CRConnectivity * > _faceCellsGlobal
vector< ArrayIntPtr > _ghostCellsGlobal