Memosa-FVM  0.2
Mesh.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 <set>
6 #include "Mesh.h"
7 #include "StorageSite.h"
8 #include "CRConnectivity.h"
9 #include "Cell.h"
10 #include <cassert>
11 #include "KSearchTree.h"
12 #include "GeomFields.h"
13 #include <fstream>
14 
15 
16 
17 #define epsilon 1e-6
18 
19 int Mesh::_lastID = 0;
20 
21 Mesh::Mesh(const int dimension):
22  _dimension(dimension),
23  _id(_lastID++),
24  _cellZoneID(-1),
25  _cells(0),
26  _faces(0),
27  _nodes(0),
28  _ibFaces(0),
29  _boundaryNodes(0),
30  _interiorFaceGroup(),
31  _faceGroups(),
32  _boundaryGroups(),
33  _interfaceGroups(),
34  _connectivityMap(),
35  _coordinates(),
36  _boundaryNodeGlobalToLocalPtr(),
37  _ibFaceList(),
38  _numOfAssembleMesh(1),
39  _isAssembleMesh(false),
40  _isShell(false),
41  _isDoubleShell(false),
42  _isConnectedShell(false),
43  _parentFaceGroupSite(0),
44  _otherFaceGroupSite(0),
45  _parentMeshID(0),
46  _otherMeshID(0)
47 {
48  _cells.setMesh(this);
49  logCtor();
50 }
51 
52 Mesh::Mesh( const int dimension,
53  const Array<VecD3>& faceNodesCoord ):
54  _dimension(dimension),
55  _id(_lastID++),
56  _cellZoneID(-1),
57  _cells(0),
58  _faces(0),
59  _nodes(0),
60  _ibFaces(0),
61  _boundaryNodes(0),
62  _interiorFaceGroup(),
63  _faceGroups(),
64  _boundaryGroups(),
65  _interfaceGroups(),
66  _connectivityMap(),
67  _coordinates(),
68  _boundaryNodeGlobalToLocalPtr(),
69  _ibFaceList(),
70  _numOfAssembleMesh(1),
71  _isAssembleMesh(false),
72  _isShell(false),
73  _isDoubleShell(false),
74  _isConnectedShell(false),
75  _parentFaceGroupSite(0),
76  _otherFaceGroupSite(0),
77  _parentMeshID(0),
78  _otherMeshID(0)
79 {
80  int faceNodeCount = _dimension == 2 ? 2 :4;
81  int totNodes = faceNodesCoord.getLength();
82 
83  // counting duplicate nodes as well for 3d
84  int totFaces = totNodes / faceNodeCount;
85 
86  //check if this is corect integer division
87  assert( (faceNodeCount*totFaces) == totNodes );
88  //set sites
89  StorageSite& faceSite = getFaces();
90  StorageSite& nodeSite = getNodes();
91  faceSite.setCount( totFaces );
92  nodeSite.setCount( totNodes );
93  //interior face group (we have only one interface for this
94  createBoundaryFaceGroup(totFaces,0,0,"wall");
95 
96  //setting coordinates
97  shared_ptr< Array<VecD3> > coord( new Array< VecD3 > ( totNodes ) );
98  *coord = faceNodesCoord;
99  setCoordinates( coord );
100 
101  //faceNodes constructor
102  shared_ptr<CRConnectivity> faceNodes( new CRConnectivity(faceSite,
103  nodeSite) );
104 
105  faceNodes->initCount();
106  //addCount
107  for ( int i = 0; i < totFaces; i++ )
108  faceNodes->addCount(i, faceNodeCount);
109  //finish count
110  faceNodes->finishCount();
111  //add operation
112  int face = 0;
113  int nodeIndx = 0;
114  for( int i = 0; i < totFaces; i++ )
115  {
116  for( int j =0; j < faceNodeCount; j++ )
117  {
118  faceNodes->add(face, nodeIndx++);
119  }
120  face++;
121  }
122  //finish add
123  faceNodes->finishAdd();
124 
125  //setting faceNodes
126  SSPair key(&faceSite,&nodeSite);
127  _connectivityMap[key] = faceNodes;
128 
129  logCtor();
130 }
131 
132 Mesh::Mesh( const int dimension,
133  const int nCells,
134  const Array<VecD3>& nodesCoord,
135  const Array<int>& faceCellIndices,
136  const Array<int>& faceNodeIndices,
137  const Array<int>& faceNodeCount,
138  const Array<int>& faceGroupSize
139  ):
140  _dimension(dimension),
141  _id(_lastID++),
142  _cellZoneID(-1),
143  _cells(0),
144  _faces(0),
145  _nodes(0),
146  _ibFaces(0),
147  _boundaryNodes(0),
148  _interiorFaceGroup(),
149  _faceGroups(),
150  _boundaryGroups(),
151  _interfaceGroups(),
152  _connectivityMap(),
153  _coordinates(),
154  _boundaryNodeGlobalToLocalPtr(),
155  _ibFaceList(),
156  _numOfAssembleMesh(1),
157  _isAssembleMesh(false),
158  _isShell(false),
159  _isDoubleShell(false),
160  _isConnectedShell(false),
161  _parentFaceGroupSite(0),
162  _otherFaceGroupSite(0),
163  _parentMeshID(0),
164  _otherMeshID(0)
165 {
166  int nFaces = faceNodeCount.getLength();
167  int nNodes = nodesCoord.getLength();
168 
169  StorageSite& faceSite = getFaces();
170  StorageSite& nodeSite = getNodes();
171  StorageSite& cellSite = getCells();
172  faceSite.setCount( nFaces );
173  nodeSite.setCount( nNodes );
174 
175  //interior face group (we have only one interface for this
176  createInteriorFaceGroup(faceGroupSize[0]);
177 
178  int nFaceGroups = faceGroupSize.getLength();
179 
180  int offset = faceGroupSize[0];
181  int nBoundaryFaces =0;
182  for(int nfg=1; nfg<nFaceGroups; nfg++)
183  {
184  createBoundaryFaceGroup(faceGroupSize[nfg], offset, nfg, "wall");
185  offset += faceGroupSize[nfg];
186  nBoundaryFaces += faceGroupSize[nfg];
187  }
188 
189  cellSite.setCount( nCells, nBoundaryFaces );
190 
191  //setting coordinates
192  shared_ptr< Array<VecD3> > coord( new Array< VecD3 > ( nNodes ) );
193  *coord = nodesCoord;
194  setCoordinates( coord );
195 
196 
197  //faceNodes constructor
198  shared_ptr<CRConnectivity> faceNodes( new CRConnectivity(faceSite,
199  nodeSite) );
200 
201  faceNodes->initCount();
202 
203  shared_ptr<CRConnectivity> faceCells( new CRConnectivity(faceSite,
204  cellSite) );
205 
206  faceCells->initCount();
207 
208 
209  //addCount
210  for ( int f = 0; f < nFaces; f++ )
211  {
212  faceNodes->addCount(f, faceNodeCount[f]);
213  faceCells->addCount(f, 2);
214  }
215 
216  //finish count
217  faceNodes->finishCount();
218  faceCells->finishCount();
219 
220  //add operation
221  int nfn=0;
222  int nfc=0;
223 
224  for( int f = 0; f < nFaces; f++ )
225  {
226  for( int j =0; j < faceNodeCount[f]; j++ )
227  {
228  faceNodes->add(f, faceNodeIndices[nfn++]);
229  }
230  faceCells->add(f,faceCellIndices[nfc++]);
231  faceCells->add(f,faceCellIndices[nfc++]);
232  }
233  //finish add
234  faceNodes->finishAdd();
235  faceCells->finishAdd();
236 
237  //setting faceNodes
238  SSPair key(&faceSite,&nodeSite);
239  _connectivityMap[key] = faceNodes;
240 
241  SSPair key2(&faceSite,&cellSite);
242  _connectivityMap[key2] = faceCells;
243 
244 
245 
246  logCtor();
247 }
248 
249 
251 {
252  logDtor();
253 }
254 
255 
256 
257 
258 const StorageSite&
260 {
261  _interiorFaceGroup = shared_ptr<FaceGroup>(new FaceGroup(size,0,_faces,0,"interior"));
262  _faceGroups.push_back(_interiorFaceGroup);
263  return _interiorFaceGroup->site;
264 }
265 
266 
267 const StorageSite&
268 Mesh::createInterfaceGroup(const int size, const int offset, const int id)
269 {
270  shared_ptr<FaceGroup> fg(new FaceGroup(size,offset,_faces,id,"interface"));
271  _faceGroups.push_back(fg);
272  _interfaceGroups.push_back(fg);
273  return fg->site;
274 }
275 
276 
277 const StorageSite&
278 Mesh::createBoundaryFaceGroup(const int size, const int offset, const int id, const string& boundaryType)
279 {
280  shared_ptr<FaceGroup> fg(new FaceGroup(size,offset,_faces,id,boundaryType));
281  _faceGroups.push_back(fg);
282  _boundaryGroups.push_back(fg);
283  return fg->site;
284 }
285 
286 
287 shared_ptr<Array<int> >
289 {
291  {
292  const int nNodes = _nodes.getCount();
293  _boundaryNodeGlobalToLocalPtr = shared_ptr<Array<int> >(new Array<int>(nNodes));
294  Array<int>& globalToLocal = *_boundaryNodeGlobalToLocalPtr;
295  globalToLocal = -1;
296  int BoundaryNodeCount=0;
297  int nLocal=0;
298  foreach(const FaceGroupPtr fgPtr, getAllFaceGroups())
299  {
300  const FaceGroup& fg = *fgPtr;
301  if (fg.groupType != "interior")
302  {
303  const StorageSite& BoundaryFaces = fg.site;
304  const CRConnectivity& BoundaryFaceNodes = getFaceNodes(BoundaryFaces);
305  const Array<int>& BFArray = BoundaryFaceNodes.getRow();
306  const Array<int>& BNArray = BoundaryFaceNodes.getCol();
307  const int nBFaces = BoundaryFaceNodes.getRowDim();
308  for(int i=0;i<nBFaces;i++)
309  {
310  for(int ip=BFArray[i];ip<BFArray[i+1];ip++)
311  {
312  const int j = BNArray[ip];
313  if (globalToLocal[j] == -1)
314  globalToLocal[j] = nLocal++;
315  }
316  }
317  }
318  }
319  BoundaryNodeCount = nLocal;
320  }
322 }
323 
324 
326 {
327  if(!_boundaryNodes)
328  {
329  const int nNodes = _nodes.getCount();
330  shared_ptr<Array<int> > GlobalToLocalPtr = createAndGetBNglobalToLocal();
331  Array<int>& GlobalToLocal = *GlobalToLocalPtr;
332  int BoundaryNodeCount = 0;
333  int nLocal = 0;
334  for(int i=0;i<nNodes;i++)
335  {
336  if(GlobalToLocal[i] != -1)
337  nLocal++;
338  }
339  BoundaryNodeCount = nLocal;
340  _boundaryNodes = new StorageSite(BoundaryNodeCount,0,0,0);
341  }
342  return *_boundaryNodes;
343 }
344 
345 
347 {
348  return *(createAndGetBNglobalToLocal());
349 }
350 
351 
352 void Mesh::setConnectivity(const StorageSite& rowSite, const StorageSite& colSite,
353  shared_ptr<CRConnectivity> conn)
354 {
355  SSPair key(&rowSite,&colSite);
356  _connectivityMap[key] = conn;
357 }
358 
360  const StorageSite& colSite) const
361 {
362  SSPair key(&rowSite,&colSite);
363  _connectivityMap.erase(key);
364 }
365 
366 
367 const CRConnectivity&
369 {
370  SSPair key(&_faces,&_nodes);
371  ConnectivityMap::const_iterator pos = _connectivityMap.find(key);
372  if (pos != _connectivityMap.end())
373  return *pos->second;
374  throw CException("face nodes not defined");
375 }
376 
377 const CRConnectivity&
379 {
380  SSPair key(&_faces,&_cells);
381  ConnectivityMap::const_iterator pos = _connectivityMap.find(key);
382  if (pos != _connectivityMap.end())
383  return *pos->second;
384  throw CException("face cells not defined");
385 }
386 
387 const CRConnectivity&
388 Mesh::getFaceCells(const StorageSite& faces) const
389 {
390  SSPair key(&faces,&_cells);
391  ConnectivityMap::const_iterator pos = _connectivityMap.find(key);
392  if (pos != _connectivityMap.end())
393  return *pos->second;
394 
395  shared_ptr<CRConnectivity> thisFaceCells =
396  getAllFaceCells().createOffset(faces,faces.getOffset(),faces.getCount());
397  _connectivityMap[key] = thisFaceCells;
398  return *thisFaceCells;
399 }
400 
401 const CRConnectivity&
402 Mesh::getFaceNodes(const StorageSite& faces) const
403 {
404  SSPair key(&faces,&_nodes);
405  ConnectivityMap::const_iterator pos = _connectivityMap.find(key);
406  if (pos != _connectivityMap.end())
407  return *pos->second;
408 
409  shared_ptr<CRConnectivity> thisFaceNodes =
410  getAllFaceNodes().createOffset(faces,faces.getOffset(),faces.getCount());
411  _connectivityMap[key] = thisFaceNodes;
412  return *thisFaceNodes;
413 }
414 
415 const CRConnectivity&
416 Mesh::getConnectivity(const StorageSite& from, const StorageSite& to) const
417 {
418  SSPair key(&from,&to);
419  ConnectivityMap::const_iterator pos = _connectivityMap.find(key);
420  if (pos != _connectivityMap.end())
421  return *pos->second;
422  throw CException("connectivity not defined");
423 }
424 
425 const CRConnectivity&
427 {
428  SSPair key(&_cells,&_nodes);
429 
430 
431 
432  ConnectivityMap::const_iterator pos = _connectivityMap.find(key);
433 
434  if (pos != _connectivityMap.end())
435  return *pos->second;
436 
437 
438  const CRConnectivity& faceCells = getAllFaceCells();
439  const CRConnectivity& faceNodes = getAllFaceNodes();
440 
441  SSPair keycf(&_cells,&_faces);
442  shared_ptr<CRConnectivity> cellFaces = faceCells.getTranspose();
443  shared_ptr<CRConnectivity> cellNodes = cellFaces->multiply(faceNodes,false);
444 
445  _connectivityMap[keycf] = cellFaces;
446  _connectivityMap[key] = cellNodes;
447 
448  orderCellFacesAndNodes(*cellFaces, *cellNodes, faceNodes,
449  faceCells, *_coordinates);
450  return *cellNodes;
451 }
452 
453 const CRConnectivity&
455 {
456  SSPair key(&_cells,&_faces);
457  ConnectivityMap::const_iterator pos = _connectivityMap.find(key);
458  if (pos != _connectivityMap.end())
459  return *pos->second;
460 
461  const CRConnectivity& faceCells = getAllFaceCells();
462  shared_ptr<CRConnectivity> cellFaces = faceCells.getTranspose();
463 
464  _connectivityMap[key] = cellFaces;
465  return *cellFaces;
466 }
467 
470 {
471  SSPair key(&_faces,&_cells);
472  ConnectivityMap::const_iterator pos = _connectivityMap.find(key);
473  if (pos != _connectivityMap.end())
474  return *pos->second;
475  throw CException("face cells not defined");
476 }
477 
478 
479 const CRConnectivity&
481 {
482  SSPair key(&_cells,&_cells);
483  ConnectivityMap::const_iterator pos = _connectivityMap.find(key);
484  if (pos != _connectivityMap.end())
485  return *pos->second;
486 
487  const CRConnectivity& faceCells = getAllFaceCells();
488  const CRConnectivity& cellFaces = getCellFaces();
489  shared_ptr<CRConnectivity> cellCells = cellFaces.multiply(faceCells,true);
490  _connectivityMap[key] = cellCells;
491  return *cellCells;
492 }
493 
494 const CRConnectivity&
496 {
497  if (!_cellCells2)
498  {
499 #ifdef FVM_PARALLEL
500  if ( MPI::COMM_WORLD.Get_size() > 1 ) {
501  //CRConnectivity constructor
502  _cellCells2 = shared_ptr<CRConnectivity> ( new CRConnectivity(this->getCells(), this->getCells()) );
503  //initCount
504  _cellCells2->initCount();
505 
506  const int ncells = this->getCells().getCountLevel1();
507  const int selfCount = this->getCells().getSelfCount();
508 
509  const CRConnectivity& cellCells = this->getCellCells();
510  multimap<int,int>::const_iterator it0;
511  multimap<int,int>::const_iterator it1;
512  //loop over cells
513  for ( int n = 0; n < ncells; n++ ){
514  set<int> setCells;
515  for ( int k = 0; k < cellCells.getCount(n); k++ ){
516  const int cellID1 = cellCells(n,k);
517  setCells.insert( cellID1 );
518  if ( cellID1 < selfCount ){ //it means inner cells use cellCells
519  for ( int i = 0; i < cellCells.getCount(cellID1); i++ ){
520  const int cellID2 = cellCells(cellID1,i);
521  setCells.insert(cellID2);
522  }
523  } else {
524  for ( it1 = _cellCellsGlobal.equal_range(cellID1).first; it1 != _cellCellsGlobal.equal_range(cellID1).second; it1++ ){
525  const int globalCellID2 = it1->second;
526  const int localID2 = _globalToLocal.find(globalCellID2)->second;
527  if ( _globalToLocal.count(globalCellID2) > 0 )
528  setCells.insert(localID2);
529  }
530  }
531  }
532  //erase itself
533  setCells.erase(n);
534  _cellCells2->addCount(n,setCells.size());
535  }
536  //finish count
537  _cellCells2->finishCount();
538  //add cellcells2
539  //loop over cells
540  for ( int n = 0; n < ncells; n++ ){
541  set<int> setCells;
542  for ( int k = 0; k < cellCells.getCount(n); k++ ){
543  const int cellID1 = cellCells(n,k);
544  setCells.insert( cellID1 );
545  if ( cellID1 < selfCount ){ //it means inner cells use cellCells
546  for ( int i = 0; i < cellCells.getCount(cellID1); i++ ){
547  const int cellID2 = cellCells(cellID1,i);
548  setCells.insert(cellID2);
549  }
550  } else {
551  for ( it1 = _cellCellsGlobal.equal_range(cellID1).first; it1 != _cellCellsGlobal.equal_range(cellID1).second; it1++ ){
552  const int globalCellID2 = it1->second;
553  const int localID2 = _globalToLocal.find(globalCellID2)->second;
554  if ( _globalToLocal.count(globalCellID2) > 0 )
555  setCells.insert(localID2);
556  }
557  }
558  }
559  //erase itself
560  setCells.erase(n);
561  foreach ( const set<int>::value_type cellID, setCells ){
562  _cellCells2->add(n, cellID);
563  }
564  }
565  //finish add
566  _cellCells2->finishAdd();
567 
568  //unique numbering for cells to
569  {
570  const int ncount = _cellCells2->getRowSite().getCountLevel1();
571  const Array<int>& row = _cellCells2->getRow();
572  Array<int>& col = _cellCells2->getCol();
573  for( int i = 0; i < ncount; i++ ){
574  for ( int j = row[i]; j < row[i+1]; j++ ){
575  const int globalID = (*_localToGlobal)[ col[j] ];
576  col[j] = _globalToLocal[globalID];
577  }
578  }
579  }
580  //uniqing numberinf for face cells
581  {
582  CRConnectivity& faceCells = (const_cast<Mesh *>(this))->getAllFaceCells();
583  const int nfaces = faceCells.getRowSite().getCount();
584  const Array<int>& row = faceCells.getRow();
585  Array<int>& col = faceCells.getCol();
586  for( int i = 0; i < nfaces; i++ ){
587  for ( int j = row[i]; j < row[i+1]; j++ ){
588  const int globalID = (*_localToGlobal)[ col[j] ];
589  col[j] = _globalToLocal[globalID];
590  }
591  }
592  const StorageSite& cellSite = this->getCells();
593  this->eraseConnectivity(cellSite,cellSite);
594  }
595 
596 
597  //get mappers to update cellCell2 localToGlobalMap and globalToLocalMapper
598  map<int,int>& globalToLocalMapper = _cellCells2->getGlobalToLocalMapper();
599  foreach( const mapInt::value_type& mpos, _globalToLocal ){
600  globalToLocalMapper[mpos.first] = mpos.second;
601  }
602 
603  //localToGlobal need to be first created
604  _cellCells2->resizeLocalToGlobalMap( this->getCells().getCountLevel1() );
605  Array<int>& localToGlobal = *(_cellCells2->getLocalToGlobalMapPtr());
606  for ( int i = 0; i < localToGlobal.getLength(); i++ ){
607  localToGlobal[i] = (*_localToGlobal)[i];
608  }
609 
610  } else { //if it is a one processor, we want to call this version, otherwise, couplingplate has trouble
611  const CRConnectivity& cellCells = getCellCells();
612  _cellCells2 = cellCells.multiply(cellCells, true);
613  }
614 
615  //set enum as CELLCELL2
617 
618 #endif
619 
620 #ifndef FVM_PARALLEL
621  const CRConnectivity& cellCells = getCellCells();
622  _cellCells2 = cellCells.multiply(cellCells, true);
623 #endif
624 
625 
626 
627  }
628 
629  return *_cellCells2;
630 }
631 
632 const CRConnectivity&
634 {
635  if (!_faceCells2)
636  {
637  const CRConnectivity& cellCells = getCellCells();
638  const CRConnectivity& faceCells = getAllFaceCells();
639  _faceCells2 = faceCells.multiply(cellCells, false);
640  }
641  return *_faceCells2;
642 }
643 
644 
645 void
646 Mesh::setFaceNodes(shared_ptr<CRConnectivity> faceNodes)
647 {
648  SSPair key(&_faces,&_nodes);
649  _connectivityMap[key] = faceNodes;
650 }
651 
652 
653 void
654 Mesh::setFaceCells(shared_ptr<CRConnectivity> faceCells)
655 {
656 
657 
658  SSPair key(&_faces,&_cells);
659  _connectivityMap[key] = faceCells;
660 
661 
662 }
663 
664 
665 void
667 {
668  //uniqing numberinf for face cells
669  {
670  CRConnectivity& faceCells = (const_cast<Mesh *>(this))->getAllFaceCells();
671  const int nfaces = faceCells.getRowSite().getCount();
672  const Array<int>& row = faceCells.getRow();
673  Array<int>& col = faceCells.getCol();
674  for( int i = 0; i < nfaces; i++ ){
675  for ( int j = row[i]; j < row[i+1]; j++ ){
676  const int globalID = (*_localToGlobal)[ col[j] ];
677  col[j] = _globalToLocal[globalID];
678  }
679  }
680  const StorageSite& cellSite = this->getCells();
681  this->eraseConnectivity(cellSite,cellSite);
682  }
683 }
684 
685 const Array<int>&
687 {
688  if (_ibFaceList) return (*_ibFaceList);
689  throw CException("ib face list not defined");
690 }
691 
692 
693 void
694 Mesh::createGhostCellSiteScatter( const PartIDMeshIDPair& id, shared_ptr<StorageSite> site )
695 {
696  _ghostCellSiteScatterMap.insert( pair<PartIDMeshIDPair, shared_ptr<StorageSite> >( id, site ) );
697 
698 }
699 
700 void
701 Mesh::createGhostCellSiteGather( const PartIDMeshIDPair& id, shared_ptr<StorageSite> site )
702 {
703  _ghostCellSiteGatherMap.insert( pair<PartIDMeshIDPair, shared_ptr<StorageSite> >( id, site ) );
704 
705 }
706 
707 void
708 Mesh::createGhostCellSiteScatterLevel1( const PartIDMeshIDPair& id, shared_ptr<StorageSite> site )
709 {
710  _ghostCellSiteScatterMapLevel1.insert( pair<PartIDMeshIDPair, shared_ptr<StorageSite> >( id, site ) );
711 
712 }
713 
714 void
715 Mesh::createGhostCellSiteGatherLevel1( const PartIDMeshIDPair& id, shared_ptr<StorageSite> site )
716 {
717  _ghostCellSiteGatherMapLevel1.insert( pair<PartIDMeshIDPair, shared_ptr<StorageSite> >( id, site ) );
718 
719 }
720 
721 
722 //this
723 void
725 {
726  //cellColor color ghost cells respect to self-inner cells
727  _cellColor = shared_ptr< Array<int> > ( new Array<int>( _cells.getCount() ) );
728  //cellColorOther color ghost cells in respect to other partition,
729  //if partition interface has aligned with mesh interface this will be different than _cellColor
730  _cellColorOther = shared_ptr< Array<int> > ( new Array<int>( _cells.getCount() ) );
731 
732  *_cellColor = -1;
733  *_cellColorOther = -1;
734  _isAssembleMesh = true;
735 }
736 
737 void
739 {
740  _localToGlobal = shared_ptr< Array<int> > ( new Array<int>( _cells.getCountLevel1() ) );
741  *_localToGlobal = -1;
742 }
743 
744 void
746 {
747  _localToGlobalNodes = shared_ptr< Array<int> > ( new Array<int>( _nodes.getCount() ) );
748  *_localToGlobalNodes = -1;
749 }
750 
751 
752 void
754 {
755  const StorageSite& nodes = this->getNodes();
756  const StorageSite& boundaryNodes = bMesh.getNodes();
757  const map<int,int>& globalToLocal = nodes.getScatterIndex().find(&boundaryNodes)->second;
758  //create repeatNodes array
759  _repeatNodes = shared_ptr< Array<int> > ( new Array<int> ( boundaryNodes.getCount() ) );
760  *_repeatNodes = 0;
761  foreach( const set<int>::value_type& node, _boundaryNodesSet ){
762  const int globalNodeID = (*_localToGlobalNodes)[node]; //from local parition mesh to global number
763  const int localNodeID = globalToLocal.find(globalNodeID)->second; //from global node id to local id in boundary mesh
764  (*_repeatNodes)[localNodeID] = 1; //this fill local partitionin mesh
765  }
766 
767  //global reduction to find repeating nodes
768 #ifdef FVM_PARALLEL
769  MPI::COMM_WORLD.Allreduce(MPI::IN_PLACE, _repeatNodes->getData(),_repeatNodes->getLength(), MPI::INT, MPI::SUM);
770 #endif
771 
772 // if ( MPI::COMM_WORLD.Get_rank() == 0 )
773 // for( int i = 0; i < _repeatNodes->getLength(); i++ ){
774 // if ( (*_repeatNodes)[i] > 1 )
775 // cout << "repeatNodes[" << i << "] = " << (*_repeatNodes)[i] << endl;
776 // }
777 
778 
779 
780 
781 }
782 
783 shared_ptr< ArrayBase >
784 Mesh::getUpdatedNodesCoordCoupling(const GeomFields& geomField, const Mesh& bMesh)
785 {
786  const StorageSite& nodes = this->getNodes();
787  const StorageSite& boundaryNodes = bMesh.getNodes();
788  const map<int,int>& globalToLocal = nodes.getScatterIndex().find(&boundaryNodes)->second;
789  const Array<VecD3>& fieldCoord = dynamic_cast< const Array<VecD3>& > (geomField.coordinate[nodes]);
790  shared_ptr< ArrayBase> returnCoord = geomField.coordinate[nodes].newSizedClone( boundaryNodes.getCount() );
791  Array<VecD3>& coord = dynamic_cast< Array<VecD3>& > ( *returnCoord );
792  coord.zero();
793 
794  foreach( const set<int>::value_type node, _boundaryNodesSet ){
795  const int globalNodeID = (*_localToGlobalNodes)[node];
796  const int localNodeID = globalToLocal.find(globalNodeID)->second;
797  coord[localNodeID] = fieldCoord[node] / double( (*_repeatNodes)[localNodeID] ); //this fill local partitionin mesh
798  }
799  //global reduction to find repeating nodes
800 // #ifdef FVM_PARALLEL
801 // const int count = coord.getLength() * 3;
802 // MPI::COMM_WORLD.Allreduce(MPI::IN_PLACE, coord.getData(), count, MPI::DOUBLE, MPI::SUM);
803 // #endif
804  return returnCoord;
805 }
806 
807 
808 //getting map from this mesh to given mesh
809 void
811 {
812  //loop over local faces
813  const StorageSite& nodes = this->getNodes();
814  const StorageSite& boundaryNodes = bMesh.getNodes();
815  const map<int,int>& globalToLocal = nodes.getScatterIndex().find(&boundaryNodes)->second;
816 
817  const CRConnectivity& faceNodes = this->getAllFaceNodes();
818  const CRConnectivity& faceNodesBMesh = bMesh.getAllFaceNodes();
819  shared_ptr<CRConnectivity> nodeFacesBMeshPtr = faceNodesBMesh.getTranspose();
820  const CRConnectivity& nodeFacesBMesh = *nodeFacesBMeshPtr;
821 
822  foreach(const FaceGroupPtr fgPtr, this->getBoundaryFaceGroups()){
823  const FaceGroup& fg = *fgPtr;
824  const StorageSite& faces = fg.site;
825  const int nFaces = faces.getCount();
826 
827  for(int f=0; f<nFaces; f++){
828  const int faceID = f + faces.getOffset();
829  const int nFaceNodes = faceNodes.getCount(faceID);
830  set<int> comp; //vector to store localIds of bMesh
831  vector<int> nodeList(nFaceNodes,0);
832  for(int nn=0; nn<nFaceNodes; nn++){
833  //get local node number
834  const int n=faceNodes(faceID,nn);
835  const int globalNodeID = (*_localToGlobalNodes)[n];
836  const int localNodeID = globalToLocal.find(globalNodeID)->second; //localID boundary mesh
837  comp.insert(localNodeID);
838  nodeList[nn] = localNodeID;
839  }
840  //now get corresponding faceID to boundaryMeshFaceID
841  //loop over nodeFaces on boundaryMesh
842  for( int i = 0; i < nFaceNodes; i++ ){
843  bool breakUpperLoop = false;
844  const int nfaces = nodeFacesBMesh.getCount(nodeList[i]);
845  //loop over faces around nodes of boundary mesh
846  for ( int j = 0; j < nfaces; j++ ){
847  const int localFaceID = nodeFacesBMesh(nodeList[i],j); //localFaceID boundary mesh
848  //check if this face is connected to our comp vector
849  const int nnodes = faceNodesBMesh.getCount(localFaceID);
850  vector<bool> matchingNodes(nFaceNodes,false);
851  for ( int k = 0; k < nnodes; k++ ){
852  const int nodeID = faceNodesBMesh(localFaceID,j);
853  if ( comp.count(nodeID) == 1 ){ //this means if this node is in search sets
854  matchingNodes[k] = true;
855  }
856  }
857  //checking if matchinNodes bools are all true
858  if ( find(matchingNodes.begin(), matchingNodes.end(), false) == matchingNodes.end() ){
859  _commonFacesMap[faceID] = localFaceID;
860  _commonFacesMapOther[localFaceID] = faceID;
861  breakUpperLoop = true;
862  break;
863  }
864  }
865  if ( breakUpperLoop ){
866  break;
867  }
868  }
869  }
870  }
871 
872 
873 }
874 
875 
876 void
878 {
879  StorageSite& nodes = _nodes;
880  StorageSite& otherNodes = other._nodes;
881  const int nNodes = nodes.getCount();
882  const int nOtherNodes = otherNodes.getCount();
883 
884  const Array<VecD3>& coords = getNodeCoordinates();
885  const Array<VecD3>& otherCoords = other.getNodeCoordinates();
886 
887 
888  KSearchTree bNodeTree;
889 
890  // add all boundary nodes of this mesh to the tree
891  {
892  Array<bool> nodeMark(nNodes);
893  nodeMark = false;
894  foreach(const FaceGroupPtr fgPtr, getAllFaceGroups())
895  {
896  const FaceGroup& fg = *fgPtr;
897  const StorageSite& faces = fg.site;
898  if (fg.groupType!="interior")
899  {
900  const int nFaces = faces.getCount();
901  const CRConnectivity& faceNodes = getFaceNodes(faces);
902  for(int f=0; f<nFaces; f++)
903  {
904  const int nFaceNodes = faceNodes.getCount(f);
905  for(int nn=0; nn<nFaceNodes; nn++)
906  {
907  const int n=faceNodes(f,nn);
908  if (!nodeMark[n])
909  {
910  nodeMark[n] = true;
911  bNodeTree.insert(coords[n],n);
912  }
913  }
914  }
915  }
916  }
917  }
918 
919 
920  // loop over all the boundary nodes of the other mesh to find possible common ones
921  Array<bool> nodeMark(nOtherNodes);
922 
923  typedef map<int,int> CommonNodesMap;
924  CommonNodesMap commonNodesMap;
925 
926  Array<int> closest(2);
927 
928  nodeMark = false;
929 
930 
931  foreach(const FaceGroupPtr fgPtr, other.getAllFaceGroups())
932  {
933  const FaceGroup& fg = *fgPtr;
934  const StorageSite& faces = fg.site;
935  if (fg.groupType!="interior")
936  {
937  const int nFaces = faces.getCount();
938  const CRConnectivity& faceNodes = other.getFaceNodes(faces);
939 
940  for(int f=0; f<nFaces; f++)
941  {
942  const int nFaceNodes = faceNodes.getCount(f);
943  for(int nn=0; nn<nFaceNodes; nn++)
944  {
945  const int n=faceNodes(f,nn);
946  if (!nodeMark[n])
947  {
948  bNodeTree.findNeighbors(otherCoords[n],2,closest);
949 
950  double dist0 = mag(otherCoords[n] - coords[closest[0]]);
951 
952  // distance between the two closest point used as scale
953 
954  double distScale = mag(coords[closest[0]] - coords[closest[1]]);
955 
956  if (dist0 < distScale*epsilon)
957  {
958  // if another node has already been found as the
959  // closest for this one we have something wrong
960  if (commonNodesMap.find(closest[0]) != commonNodesMap.end())
961  {
962  throw CException("duplicate nodes on the mesh ?");
963  }
964  commonNodesMap.insert(make_pair(closest[0], n));
965  }
966  nodeMark[n] = true;
967  }
968  }
969  }
970  }
971  }
972 
973  const int nCommon = commonNodesMap.size();
974 
975  if (nCommon == 0)
976  return;
977  cout << "found " << nCommon << " common nodes " << endl;
978 
979  shared_ptr<IntArray> myCommonNodes(new IntArray(nCommon));
980  shared_ptr<IntArray> otherCommonNodes(new IntArray(nCommon));
981 
982  int nc=0;
983  foreach(CommonNodesMap::value_type& pos, commonNodesMap)
984  {
985  (*myCommonNodes)[nc] = pos.first;
986  (*otherCommonNodes)[nc] = pos.second;
987  nc++;
988  }
989 
990  nodes.getCommonMap()[&otherNodes] = myCommonNodes;
991  otherNodes.getCommonMap()[&nodes] = otherCommonNodes;
992 
993 }
994 
995 void
997  const GeomFields& geomFields)
998 {
999  const int count(faces.getCount());
1000  if (count != otherFaces.getCount())
1001  throw CException("face groups are not of the same length");
1002 
1003  const Array<VecD3>& coords =
1004  dynamic_cast<const Array<VecD3>& >(geomFields.coordinate[faces]);
1005 
1006  const Array<VecD3>& otherCoords =
1007  dynamic_cast<const Array<VecD3>& >(geomFields.coordinate[otherFaces]);
1008 
1009  const Array<VecD3>& area =
1010  dynamic_cast<const Array<VecD3>& >(geomFields.area[faces]);
1011 
1012  const Array<VecD3>& otherArea =
1013  dynamic_cast<const Array<VecD3>& >(geomFields.area[otherFaces]);
1014 
1015  KSearchTree thisFacesTree(coords);
1016 
1017  Array<int> closest(2);
1018 
1019  shared_ptr<IntArray> myCommonFaces(new IntArray(count));
1020  shared_ptr<IntArray> otherCommonFaces(new IntArray(count));
1021 
1022  for(int f=0; f<count; f++)
1023  {
1024  thisFacesTree.findNeighbors(otherCoords[f],2,closest);
1025 
1026  const int closestFace = closest[0];
1027  double dist0 = mag(otherCoords[f] - coords[closestFace]);
1028 
1029  // distance between the two closest point used as scale
1030 
1031  double distScale = mag(coords[closest[0]] - coords[closest[1]]);
1032 
1033  if (dist0 < distScale*epsilon)
1034  {
1035  double crossProductMag(mag2(cross(otherArea[f],area[closestFace])));
1036  if (crossProductMag > mag2(otherArea[f])*epsilon)
1037  throw CException("cross product is not small");
1038 
1039  (*otherCommonFaces)[f] = closestFace;
1040  (*myCommonFaces)[closestFace] = f;
1041  }
1042  else
1043  throw CException("Not a match");
1044 
1045  }
1046 
1047  faces.getCommonMap()[&otherFaces] = myCommonFaces;
1048  otherFaces.getCommonMap()[&faces] = otherCommonFaces;
1049 
1050 }
1051 
1052 bool
1054  const GeomFields& geomFields)
1055 {
1056  const int count(faces.getCount());
1057  if (count != otherFaces.getCount())
1058  return false;
1059 
1060  const Array<VecD3>& coords =
1061  dynamic_cast<const Array<VecD3>& >(geomFields.coordinate[faces]);
1062 
1063  const Array<VecD3>& otherCoords =
1064  dynamic_cast<const Array<VecD3>& >(geomFields.coordinate[otherFaces]);
1065 
1066  const Array<VecD3>& area =
1067  dynamic_cast<const Array<VecD3>& >(geomFields.area[faces]);
1068 
1069  const Array<VecD3>& otherArea =
1070  dynamic_cast<const Array<VecD3>& >(geomFields.area[otherFaces]);
1071 
1072  KSearchTree thisFacesTree(coords);
1073 
1074  int neibs;
1075  if(otherCoords.getLength()>1)
1076  neibs=2;
1077  else
1078  neibs=1;
1079 
1080  Array<int> closest(neibs);
1081 
1082  shared_ptr<IntArray> myCommonFaces(new IntArray(count));
1083  shared_ptr<IntArray> otherCommonFaces(new IntArray(count));
1084 
1085  for(int f=0; f<count; f++)
1086  {
1087  thisFacesTree.findNeighbors(otherCoords[f],neibs,closest);
1088 
1089  const int closestFace = closest[0];
1090  double dist0 = mag(otherCoords[f] - coords[closestFace]);
1091 
1092  // distance between the two closest point used as scale
1093 
1094  double distScale;
1095  if(neibs==2)
1096  distScale=mag(coords[closest[0]] - coords[closest[1]])*epsilon;
1097  else
1098  distScale=sqrt(sqrt((area[f].mag2())))*0.00001;
1099 
1100  if (dist0 < distScale)
1101  {
1102  double crossProductMag(mag2(cross(otherArea[f],area[closestFace])));
1103  if (crossProductMag > mag2(otherArea[f])*epsilon)
1104  return false;
1105 
1106  (*otherCommonFaces)[f] = closestFace;
1107  (*myCommonFaces)[closestFace] = f;
1108  }
1109  else
1110  return false;
1111 
1112  }
1113 
1114  faces.getCommonMap()[&otherFaces] = myCommonFaces;
1115  otherFaces.getCommonMap()[&faces] = otherCommonFaces;
1116 
1117  return true;
1118 
1119 }
1120 
1121 Mesh*
1123 {
1124  StorageSite& nodes = _nodes;
1125  const Array<VecD3>& coords = getNodeCoordinates();
1126 
1127  const int nodeCount = nodes.getCount();
1128  Array<int> globalToLocalNodes(nodeCount);
1129 
1130  globalToLocalNodes = -1;
1131  int bMeshNodeCount=0;
1132  int bMeshFaceCount=0;
1133  foreach(const FaceGroupPtr fgPtr, getAllFaceGroups())
1134  {
1135  const FaceGroup& fg = *fgPtr;
1136  const StorageSite& faces = fg.site;
1137  if (fg.groupType!="interior")
1138  {
1139  const int nFaces = faces.getCount();
1140  const CRConnectivity& faceNodes = getFaceNodes(faces);
1141  for(int f=0; f<nFaces; f++)
1142  {
1143  const int nFaceNodes = faceNodes.getCount(f);
1144  for(int nn=0; nn<nFaceNodes; nn++)
1145  {
1146  const int n=faceNodes(f,nn);
1147  if (globalToLocalNodes[n] == -1)
1148  {
1149  globalToLocalNodes[n] = bMeshNodeCount++;
1150  }
1151  }
1152  }
1153  bMeshFaceCount += nFaces;
1154  }
1155  }
1156 
1157 
1158  Mesh *bMesh = new Mesh(_dimension);
1159 
1160 
1161  StorageSite& bMeshFaces = bMesh->getFaces();
1162  StorageSite& bMeshNodes = bMesh->getNodes();
1163  bMeshFaces.setCount( bMeshFaceCount );
1164  bMeshNodes.setCount( bMeshNodeCount );
1165 
1166  bMesh->createBoundaryFaceGroup(bMeshFaceCount,0,0,"wall");
1167 
1168  //setting coordinates
1169  shared_ptr< Array<VecD3> > bMeshCoordPtr( new Array< VecD3 > ( bMeshNodeCount ) );
1170 
1171  shared_ptr<IntArray> myCommonNodes(new IntArray(bMeshNodeCount));
1172  shared_ptr<IntArray> otherCommonNodes(new IntArray(bMeshNodeCount));
1173 
1174  for(int n=0; n<nodeCount; n++)
1175  {
1176  const int nLocal = globalToLocalNodes[n];
1177  if (nLocal >=0)
1178  {
1179  (*bMeshCoordPtr)[nLocal] = coords[n];
1180  (*myCommonNodes)[nLocal] = nLocal;
1181  (*otherCommonNodes)[nLocal] = n;
1182  }
1183  }
1184  nodes.getCommonMap()[&bMeshNodes] = myCommonNodes;
1185  bMeshNodes.getCommonMap()[&nodes] = otherCommonNodes;
1186 
1187  bMesh->setCoordinates( bMeshCoordPtr );
1188 
1189  //faceNodes constructor
1190  shared_ptr<CRConnectivity> bFaceNodes( new CRConnectivity(bMeshFaces,
1191  bMeshNodes) );
1192 
1193  bFaceNodes->initCount();
1194 
1195  bMeshFaceCount=0;
1196 
1197  foreach(FaceGroupPtr fgPtr, getAllFaceGroups())
1198  {
1199  FaceGroup& fg = *fgPtr;
1200  StorageSite& faces = const_cast<StorageSite&>(fg.site);
1201  if (fg.groupType!="interior")
1202  {
1203  const int nFaces = faces.getCount();
1204  const CRConnectivity& faceNodes = getFaceNodes(faces);
1205 
1206  shared_ptr<IntArray> myCommonFaces(new IntArray(nFaces));
1207  shared_ptr<IntArray> otherCommonFaces(new IntArray(nFaces));
1208 
1209  for(int f=0; f<nFaces; f++)
1210  {
1211  const int nFaceNodes = faceNodes.getCount(f);
1212  bFaceNodes->addCount(bMeshFaceCount,nFaceNodes);
1213  (*myCommonFaces)[f] = bMeshFaceCount;
1214  (*otherCommonFaces)[f] = f;
1215  bMeshFaceCount++;
1216  }
1217 
1218  faces.getCommonMap()[&bMeshFaces] = myCommonFaces;
1219  bMeshFaces.getCommonMap()[&faces] = otherCommonFaces;
1220  }
1221  }
1222 
1223  bFaceNodes->finishCount();
1224  bMeshFaceCount=0;
1225 
1226  foreach(const FaceGroupPtr fgPtr, getAllFaceGroups())
1227  {
1228  const FaceGroup& fg = *fgPtr;
1229  const StorageSite& faces = fg.site;
1230  if (fg.groupType!="interior")
1231  {
1232  const int nFaces = faces.getCount();
1233  const CRConnectivity& faceNodes = getFaceNodes(faces);
1234  for(int f=0; f<nFaces; f++)
1235  {
1236  const int nFaceNodes = faceNodes.getCount(f);
1237  for(int nn=0; nn<nFaceNodes; nn++)
1238  {
1239  const int n=faceNodes(f,nn);
1240  const int nLocal = globalToLocalNodes[n];
1241  bFaceNodes->add(bMeshFaceCount,nLocal);
1242  }
1243  bMeshFaceCount++;
1244  }
1245  }
1246  }
1247 
1248  bFaceNodes->finishAdd();
1249  //setting faceNodes
1250  SSPair key(&bMeshFaces,&bMeshNodes);
1251  bMesh->_connectivityMap[key] = bFaceNodes;
1252 
1253  return bMesh;
1254 
1255 }
1256 
1257 Mesh*
1258 Mesh::extrude(int nz, double zmax, bool boundaryOnly)
1259 {
1260  if (boundaryOnly)
1261  nz = 1;
1262 
1263  if (_dimension != 2)
1264  throw CException("can only extrude two dimensional mesh");
1265 
1266  const int myNCells = _cells.getSelfCount();
1267  const int myNFaces = _faces.getSelfCount();
1268  const int myNInteriorFaces = _interiorFaceGroup->site.getCount();
1269  const int myNBoundaryFaces = myNFaces - myNInteriorFaces;
1270  const int myNNodes = _nodes.getSelfCount();
1271  const CRConnectivity& myCellNodes = getCellNodes();
1272 
1273  const int eNInteriorFaces_rib = boundaryOnly ? 0 : nz*myNInteriorFaces;
1274  const int eNInteriorFaces_cap = (nz-1)*myNCells;
1275 
1276  const int eNInteriorFaces = eNInteriorFaces_rib + eNInteriorFaces_cap;
1277  const int eNBoundaryFaces = nz*myNBoundaryFaces + 2*myNCells;
1278  const int eNFaces = eNInteriorFaces + eNBoundaryFaces;
1279  const int eNInteriorCells = boundaryOnly ? 0 : nz*myNCells;
1280  const int eNBoundaryCells = boundaryOnly ? 0 : eNBoundaryFaces;
1281 
1282  const int eNNodes = (nz+1)*myNNodes;
1283 
1284  Mesh *eMesh = new Mesh(3);
1285 
1286  // set nodes
1287  StorageSite& eMeshNodes = eMesh->getNodes();
1288  eMeshNodes.setCount( eNNodes );
1289 
1290  const Array<VecD3>& myCoords = getNodeCoordinates();
1291  shared_ptr< Array<VecD3> > eMeshCoordPtr( new Array< VecD3 > ( eNNodes ) );
1292  Array<VecD3>& eCoords = *eMeshCoordPtr;
1293  const double dz = zmax/nz;
1294 
1295  const double z0 = -zmax/2.0;
1296  for(int k=0, en=0; k<=nz; k++)
1297  {
1298  const double z = z0 + dz*k;
1299  for(int n=0; n<myNNodes; n++)
1300  {
1301  eCoords[en][0] = myCoords[n][0];
1302  eCoords[en][1] = myCoords[n][1];
1303  eCoords[en][2] = z;
1304  en++;
1305  }
1306  }
1307 
1308  eMesh->setCoordinates( eMeshCoordPtr );
1309 
1310 
1311  // set cells
1312 
1313  StorageSite& eMeshCells = eMesh->getCells();
1314  eMeshCells.setCount( eNInteriorCells, eNBoundaryCells);
1315 
1316 
1317  // set faces
1318 
1319  StorageSite& eMeshFaces = eMesh->getFaces();
1320  eMeshFaces.setCount(eNFaces);
1321 
1322 
1323  shared_ptr<CRConnectivity> eFaceNodes( new CRConnectivity(eMeshFaces,
1324  eMeshNodes) );
1325 
1326  shared_ptr<CRConnectivity> eFaceCells( new CRConnectivity(eMeshFaces,
1327  eMeshCells) );
1328 
1329  // set counts for face cells and face nodes
1330 
1331 
1332  eFaceNodes->initCount();
1333  eFaceCells->initCount();
1334 
1335  int f = 0;
1336 
1337  if (!boundaryOnly)
1338  {
1339  // rib faces first
1340  for(; f<eNInteriorFaces_rib; f++)
1341  {
1342  eFaceNodes->addCount(f,4);
1343  eFaceCells->addCount(f,2);
1344  }
1345 
1346  // interior cap faces
1347  for(int k=1; k<nz; k++)
1348  {
1349  for(int c=0; c<myNCells; c++)
1350  {
1351  eFaceNodes->addCount(f, myCellNodes.getCount(c));
1352  eFaceCells->addCount(f, 2);
1353  f++;
1354  }
1355  }
1356 
1357  eMesh->createInteriorFaceGroup(eNInteriorFaces);
1358  }
1359 
1360 
1361  // z = 0 faces
1362  eMesh->createBoundaryFaceGroup(myNCells, f, 10000, "wall");
1363  for(int c=0; c<myNCells; c++)
1364  {
1365  eFaceNodes->addCount(f, myCellNodes.getCount(c));
1366  eFaceCells->addCount(f, 2);
1367  f++;
1368  }
1369 
1370  // z = zmax faces
1371  eMesh->createBoundaryFaceGroup(myNCells, f, 10001, "wall");
1372  for(int c=0; c<myNCells; c++)
1373  {
1374  eFaceNodes->addCount(f, myCellNodes.getCount(c));
1375  eFaceCells->addCount(f, 2);
1376  f++;
1377  }
1378 
1379  foreach(const FaceGroupPtr fgPtr, getAllFaceGroups())
1380  {
1381  const FaceGroup& fg = *fgPtr;
1382  const StorageSite& faces = fg.site;
1383  if (fg.groupType!="interior")
1384  {
1385  const int nBFaces = faces.getCount();
1386 
1387  eMesh->createBoundaryFaceGroup(nBFaces*nz, f, fg.id, fg.groupType);
1388 
1389  for(int k=0; k<nz; k++)
1390  for(int bf=0; bf<nBFaces; bf++)
1391  {
1392  eFaceNodes->addCount(f,4);
1393  eFaceCells->addCount(f,2);
1394  f++;
1395  }
1396  }
1397  }
1398 
1399  eFaceNodes->finishCount();
1400  eFaceCells->finishCount();
1401 
1402 
1403  // now set the indices of face cells and nodes
1404 
1405 
1406  f = 0;
1407 
1408 
1409  // rib faces first
1410 
1411  const CRConnectivity& myFaceNodes = getAllFaceNodes();
1412  const CRConnectivity& myFaceCells = getAllFaceCells();
1413 
1414  if (!boundaryOnly)
1415  {
1416  for(int k=0; k<nz; k++)
1417  {
1418  const int eCellOffset = k*myNCells;
1419  const int eNodeOffset = k*myNNodes;
1420 
1421  for(int myf=0; myf<myNInteriorFaces; myf++)
1422  {
1423  const int myNode0 = myFaceNodes(myf,0);
1424  const int myNode1 = myFaceNodes(myf,1);
1425 
1426  const int myCell0 = myFaceCells(myf,0);
1427  const int myCell1 = myFaceCells(myf,1);
1428 
1429 
1430  eFaceNodes->add(f, myNode0 + eNodeOffset);
1431  eFaceNodes->add(f, myNode1 + eNodeOffset );
1432  eFaceNodes->add(f, myNode1 + eNodeOffset + myNNodes);
1433  eFaceNodes->add(f, myNode0 + eNodeOffset + myNNodes);
1434 
1435  eFaceCells->add(f, myCell0 + eCellOffset);
1436  eFaceCells->add(f, myCell1 + eCellOffset);
1437 
1438  f++;
1439  }
1440  }
1441 
1442  // interior cap faces
1443  for(int k=1; k<nz; k++)
1444  {
1445  const int eCellOffset = k*myNCells;
1446  const int eNodeOffset = k*myNNodes;
1447 
1448  for(int c=0; c<myNCells; c++)
1449  {
1450  const int nCellNodes = myCellNodes.getCount(c);
1451  for(int nnc=0; nnc<nCellNodes; nnc++)
1452  {
1453  eFaceNodes->add(f, myCellNodes(c,nnc) + eNodeOffset);
1454  }
1455 
1456  eFaceCells->add(f, c + eCellOffset - myNCells);
1457  eFaceCells->add(f, c + eCellOffset);
1458  f++;
1459  }
1460  }
1461  }
1462 
1463  // counter for boundary faces
1464  int ebf = 0;
1465 
1466 
1467  // z = 0 faces
1468  {
1469  const int eCellOffset = 0;
1470  const int eNodeOffset = 0;
1471 
1472  for(int c=0; c<myNCells; c++)
1473  {
1474  const int nCellNodes = myCellNodes.getCount(c);
1475 
1476  // reverse order of face nodes
1477  for(int nnc=nCellNodes-1; nnc>=0; nnc--)
1478  {
1479  eFaceNodes->add(f, myCellNodes(c,nnc) + eNodeOffset);
1480  }
1481 
1482  eFaceCells->add(f, c + eCellOffset);
1483  eFaceCells->add(f, ebf + eNInteriorCells);
1484  f++;
1485  ebf++;
1486  }
1487 
1488  }
1489 
1490  // z = zmax faces
1491  {
1492  const int eCellOffset = (nz-1)*myNCells;
1493  const int eNodeOffset = nz*myNNodes;
1494 
1495  for(int c=0; c<myNCells; c++)
1496  {
1497  const int nCellNodes = myCellNodes.getCount(c);
1498 
1499  // reverse order of face nodes
1500  for(int nnc=0; nnc<nCellNodes; nnc++)
1501  {
1502  eFaceNodes->add(f, myCellNodes(c,nnc) + eNodeOffset);
1503  }
1504 
1505  eFaceCells->add(f, c + eCellOffset);
1506  eFaceCells->add(f, ebf + eNInteriorCells);
1507  f++;
1508  ebf++;
1509  }
1510  }
1511 
1512 
1513  // rib boundary faces
1514  foreach(const FaceGroupPtr fgPtr, getAllFaceGroups())
1515  {
1516  const FaceGroup& fg = *fgPtr;
1517  const StorageSite& faces = fg.site;
1518  if (fg.groupType!="interior")
1519  {
1520  const int nBFaces = faces.getCount();
1521 
1522  const CRConnectivity& bFaceNodes = getFaceNodes(faces);
1523  const CRConnectivity& bFaceCells = getFaceCells(faces);
1524 
1525  for(int k=0; k<nz; k++)
1526  {
1527  const int eCellOffset = k*myNCells;
1528  const int eNodeOffset = k*myNNodes;
1529  for(int bf=0; bf<nBFaces; bf++)
1530  {
1531  const int myNode0 = bFaceNodes(bf,0);
1532  const int myNode1 = bFaceNodes(bf,1);
1533 
1534  const int myCell0 = bFaceCells(bf,0);
1535 
1536 
1537  eFaceNodes->add(f, myNode0 + eNodeOffset);
1538  eFaceNodes->add(f, myNode1 + eNodeOffset);
1539  eFaceNodes->add(f, myNode1 + eNodeOffset + myNNodes);
1540  eFaceNodes->add(f, myNode0 + eNodeOffset + myNNodes);
1541 
1542  eFaceCells->add(f, myCell0 + eCellOffset);
1543  eFaceCells->add(f, ebf + eNInteriorCells);
1544 
1545  f++;
1546  ebf++;
1547  }
1548  }
1549  }
1550 
1551  }
1552 
1553  eFaceNodes->finishAdd();
1554  eFaceCells->finishAdd();
1555 
1556  //setting faceNodes
1557  SSPair key1(&eMeshFaces,&eMeshNodes);
1558  eMesh->_connectivityMap[key1] = eFaceNodes;
1559 
1560  if (!boundaryOnly)
1561  {
1562  SSPair key2(&eMeshFaces,&eMeshCells);
1563  eMesh->_connectivityMap[key2] = eFaceCells;
1564  }
1565 
1566  return eMesh;
1567 }
1568 
1569 const FaceGroup&
1570 Mesh::getFaceGroup(const int fgId) const
1571 {
1572  foreach(const FaceGroupPtr fgPtr, getAllFaceGroups())
1573  {
1574  const FaceGroup& fg = *fgPtr;
1575  if (fg.id == fgId)
1576  return fg;
1577  }
1578  throw CException("no face group with given id");
1579 }
1580 
1581 Mesh*
1582 Mesh::createShell(const int fgId, Mesh& otherMesh, const int otherFgId)
1583 {
1584  typedef Array<int> IntArray;
1585 
1586  const FaceGroup& fg = getFaceGroup(fgId);
1587  const StorageSite& fgSite = fg.site;
1588 
1589  const FaceGroup& otherfg = otherMesh.getFaceGroup(otherFgId);
1590  const StorageSite& otherfgSite = otherfg.site;
1591 
1592  StorageSite& cells = getCells();
1593 
1594 
1595  StorageSite& otherCells = otherMesh.getCells();
1596 
1597  const CRConnectivity& faceCells = getFaceCells(fgSite);
1598  const CRConnectivity& otherFaceCells = otherMesh.getFaceCells(otherfgSite);
1599 
1600  const int count = fgSite.getSelfCount();
1601 
1602  Mesh* shellMesh = new Mesh(_dimension);
1603 
1604  shellMesh->_isShell = true;
1605  shellMesh->_parentFaceGroupSite = &fgSite;
1606 
1607  StorageSite& sMeshCells = shellMesh->getCells();
1608 
1609  // as many cells as there are faces, plus twice the number of ghost cells
1610  sMeshCells.setCount( count, 2*count);
1611 
1612 
1613  // we will number the cells in the shell mesh in the same order as
1614  // the faces on the left mesh
1615 
1616  // create a mapping from the cells in the left mesh to the smesh
1617  // cells using the faceCell connectivity
1618  map<int, int> leftCellsToSCells;
1619  map<int, int> rightCellsToSCells;
1620  for(int f=0; f<count; f++)
1621  {
1622  const int lc1 = faceCells(f,1);
1623  const int rc1 = otherFaceCells(f,1);
1624  leftCellsToSCells[lc1] = f;
1625  rightCellsToSCells[rc1] = f;
1626  }
1627 
1628  // since there can be more than one face group in common between the
1629  // two meshes, we need to split up the existing gather scatter index
1630  // arrays into two sets, one for the cells that are connected
1631  // through the faces in the current face group and one for the rest.
1632 
1633 
1634  StorageSite::ScatterMap& lScatterMap = cells.getScatterMap();
1635  StorageSite::ScatterMap& rScatterMap = otherCells.getScatterMap();
1636 
1637  shared_ptr<IntArray> L2RScatterOrigPtr = lScatterMap[&otherCells];
1638  shared_ptr<IntArray> R2LScatterOrigPtr = rScatterMap[&cells];
1639 
1640 
1641  StorageSite::GatherMap& lGatherMap = cells.getGatherMap();
1642  StorageSite::GatherMap& rGatherMap = otherCells.getGatherMap();
1643 
1644  shared_ptr<IntArray> R2LGatherOrigPtr = lGatherMap[&otherCells];
1645  shared_ptr<IntArray> L2RGatherOrigPtr = rGatherMap[&cells];
1646 
1647 
1648  vector<int> L2SScatterVector;
1649  vector<int> R2SScatterVector;
1650  vector<int> S2LScatterVector;
1651  vector<int> S2RScatterVector;
1652 
1653  vector<int> L2SGatherVector;
1654  vector<int> R2SGatherVector;
1655  vector<int> S2LGatherVector;
1656  vector<int> S2RGatherVector;
1657 
1658  vector<int> L2RScatterNewVector;
1659  vector<int> R2LScatterNewVector;
1660  vector<int> L2RGatherNewVector;
1661  vector<int> R2LGatherNewVector;
1662 
1663  for(int i=0; i<L2RScatterOrigPtr->getLength(); i++)
1664  {
1665  const int lcs = (*L2RScatterOrigPtr)[i];
1666  const int rcg = (*L2RGatherOrigPtr)[i];
1667  // if the left cell is in the current face groups neighbours it goes into the new1
1668  if (rightCellsToSCells.find(rcg) != rightCellsToSCells.end())
1669  {
1670 
1671  const int sCell = rightCellsToSCells[rcg];
1672 
1673  L2SScatterVector.push_back(lcs);
1674  L2SGatherVector.push_back(sCell+count);
1675 
1676  S2RScatterVector.push_back(sCell);
1677  S2RGatherVector.push_back(rcg);
1678  }
1679  else
1680  {
1681  L2RScatterNewVector.push_back(lcs);
1682  L2RGatherNewVector.push_back(rcg);
1683  }
1684  }
1685 
1686  for(int i=0; i<R2LGatherOrigPtr->getLength(); i++)
1687  {
1688  const int lcg = (*R2LGatherOrigPtr)[i];
1689  const int rcs = (*R2LScatterOrigPtr)[i];
1690  // if the left cell is in the current face groups neighbours it goes into the new1
1691  if (leftCellsToSCells.find(lcg) != leftCellsToSCells.end())
1692  {
1693  const int sCell = leftCellsToSCells[lcg];
1694 
1695  S2LGatherVector.push_back(lcg);
1696  S2LScatterVector.push_back(sCell);
1697 
1698  R2SGatherVector.push_back(sCell+2*count);
1699  R2SScatterVector.push_back(rcs);
1700 
1701  }
1702  else
1703  {
1704  R2LGatherNewVector.push_back(lcg);
1705  R2LScatterNewVector.push_back(rcs);
1706  }
1707  }
1708 
1709 
1710  // set the gather scatter arrays in the smesh cells
1711  sMeshCells.getScatterMap()[&cells] = arrayFromVector(S2LScatterVector);
1712  sMeshCells.getScatterMap()[&otherCells] = arrayFromVector(S2RScatterVector);
1713  sMeshCells.getGatherMap()[&cells] = arrayFromVector(L2SGatherVector);
1714  sMeshCells.getGatherMap()[&otherCells] = arrayFromVector(R2SGatherVector);
1715 
1716  // replace the existing arrays in left and right maps and add the
1717  // new ones
1718 
1719  lScatterMap.erase(&otherCells);
1720  if (L2RScatterNewVector.size() > 0)
1721  lScatterMap[&otherCells] = arrayFromVector(L2RScatterNewVector);
1722  lScatterMap[&sMeshCells] = arrayFromVector(L2SScatterVector);
1723 
1724  lGatherMap.erase(&otherCells);
1725  if (R2LGatherNewVector.size() > 0)
1726  lGatherMap[&otherCells] = arrayFromVector(R2LGatherNewVector);
1727  lGatherMap[&sMeshCells] = arrayFromVector(S2LGatherVector);
1728 
1729  rScatterMap.erase(&cells);
1730  if (R2LScatterNewVector.size() > 0)
1731  rScatterMap[&cells] = arrayFromVector(R2LScatterNewVector);
1732  rScatterMap[&sMeshCells] = arrayFromVector(R2SScatterVector);
1733 
1734  rGatherMap.erase(&cells);
1735  if (L2RGatherNewVector.size() > 0)
1736  rGatherMap[&cells] = arrayFromVector(L2RGatherNewVector);
1737  rGatherMap[&sMeshCells] = arrayFromVector(S2RGatherVector);
1738 
1739  // create the cell cell connectivity for the shell mesh
1740  shared_ptr<CRConnectivity> sCellCells(new CRConnectivity(sMeshCells,sMeshCells));
1741  sCellCells->initCount();
1742 
1743  // two neighbours for the first count cells, one for the rest
1744  for(int i=0; i<count; i++)
1745  {
1746  sCellCells->addCount(i,2);
1747  sCellCells->addCount(i+count,1);
1748  sCellCells->addCount(i+2*count,1);
1749  }
1750 
1751  sCellCells->finishCount();
1752 
1753  for(int i=0; i<count; i++)
1754  {
1755  sCellCells->add(i,i+count);
1756  sCellCells->add(i,i+2*count);
1757 
1758  sCellCells->add(i+count,i);
1759  sCellCells->add(i+2*count,i);
1760  }
1761 
1762  sCellCells->finishAdd();
1763 
1764  SSPair key(&sMeshCells,&sMeshCells);
1765 
1766  shellMesh->_connectivityMap[key] = sCellCells;
1767 
1768  return shellMesh;
1769 }
1770 
1771 Mesh*
1772 Mesh::createDoubleShell(const int fgId, Mesh& otherMesh, const int otherFgId, const bool connectedShell)
1773 {
1774  typedef Array<int> IntArray;
1775 
1776  const FaceGroup& fg = getFaceGroup(fgId);
1777  const StorageSite& fgSite = fg.site;
1778  StorageSite& cells = getCells();
1779 
1780  const FaceGroup& fgOther = otherMesh.getFaceGroup(otherFgId);
1781  const StorageSite& fgSiteOther = fgOther.site;
1782 
1783  StorageSite& otherCells = otherMesh.getCells();
1784 
1785  const CRConnectivity& faceCells = getFaceCells(fgSite);
1786  const CRConnectivity& otherFaceCells = otherMesh.getFaceCells(fgSiteOther);
1787 
1788  const int count = fgSite.getSelfCount();
1789 
1790  Mesh* shellMesh = new Mesh(_dimension);
1791 
1792  shellMesh->_isShell = true;
1793  shellMesh->_isDoubleShell = true;
1794  shellMesh->_parentFaceGroupSite = &fgSite;
1795  shellMesh->_parentMeshID = getID();
1796  shellMesh->_otherMeshID = otherMesh.getID();
1797  shellMesh->_otherFaceGroupSite = &fgSiteOther;
1798 
1799  if (connectedShell)
1800  shellMesh->_isConnectedShell = true;
1801 
1802  StorageSite& sMeshCells = shellMesh->getCells();
1803 
1804  // twice as many cells as there are faces, plus twice the number of ghost cells
1805  sMeshCells.setCount( 2*count, 2*count);
1806 
1807 
1808  // we will number the left cells in the shell mesh in the same order as
1809  // the faces on the left mesh
1810 
1811  // create a mapping from the cells in the left mesh to the smesh
1812  // cells using the faceCell connectivity
1813  map<int, int> leftCellsToSCells;
1814  map<int, int> rightCellsToSCells;
1815 
1816  // If we are splitting an interior face, one mesh will have correct
1817  // (f,0) and (f,1) orientations and one will not, meaning that
1818  // faceCells(f,1) will return the interior cell instead of the
1819  // ghost cell. Here we check for orientation and switch if needed.
1820  int lDirection = 1;
1821  int rDirection = 1;
1822  if (faceCells(0,1) < cells.getSelfCount())
1823  {
1824  lDirection = 0;
1825  }
1826  if (otherFaceCells(0,1) < otherCells.getSelfCount())
1827  {
1828  rDirection = 0;
1829  }
1830 
1831  for(int f=0; f<count; f++)
1832  {
1833  // add ghost(gather) cells to map
1834  const int lc1 = faceCells(f,lDirection);
1835  const int rc1 = otherFaceCells(f,rDirection);
1836  leftCellsToSCells[lc1] = f;
1837  rightCellsToSCells[rc1] = f;
1838  }
1839 
1840  // since there can be more than one face group in common between the
1841  // two meshes, we need to split up the existing gather scatter index
1842  // arrays into two sets, one for the cells that are connected
1843  // through the faces in the current face group and one for the rest.
1844 
1845  if (connectedShell)
1846  {
1847  StorageSite::ScatterMap& lScatterMap = cells.getScatterMap();
1848  StorageSite::ScatterMap& rScatterMap = otherCells.getScatterMap();
1849 
1850  shared_ptr<IntArray> L2RScatterOrigPtr = lScatterMap[&otherCells];
1851  shared_ptr<IntArray> R2LScatterOrigPtr = rScatterMap[&cells];
1852 
1853 
1854  StorageSite::GatherMap& lGatherMap = cells.getGatherMap();
1855  StorageSite::GatherMap& rGatherMap = otherCells.getGatherMap();
1856 
1857  shared_ptr<IntArray> R2LGatherOrigPtr = lGatherMap[&otherCells];
1858  shared_ptr<IntArray> L2RGatherOrigPtr = rGatherMap[&cells];
1859 
1860 
1861  vector<int> L2SScatterVector;
1862  vector<int> R2SScatterVector;
1863  vector<int> S2LScatterVector;
1864  vector<int> S2RScatterVector;
1865 
1866  vector<int> L2SGatherVector;
1867  vector<int> R2SGatherVector;
1868  vector<int> S2LGatherVector;
1869  vector<int> S2RGatherVector;
1870 
1871  vector<int> L2RScatterNewVector;
1872  vector<int> R2LScatterNewVector;
1873  vector<int> L2RGatherNewVector;
1874  vector<int> R2LGatherNewVector;
1875 
1876  for(int i=0; i<L2RScatterOrigPtr->getLength(); i++)
1877  {
1878  const int lcs = (*L2RScatterOrigPtr)[i];
1879  const int rcg = (*L2RGatherOrigPtr)[i];
1880 
1881  if (rightCellsToSCells.find(rcg) != rightCellsToSCells.end())
1882  {
1883  //left shell cell is sCell
1884  const int sCell = rightCellsToSCells[rcg];
1885 
1886  L2SScatterVector.push_back(lcs);
1887  L2SGatherVector.push_back(sCell+3*count);
1888 
1889  S2RScatterVector.push_back(sCell+count);
1890  S2RGatherVector.push_back(rcg);
1891  }
1892  else
1893  {
1894  L2RScatterNewVector.push_back(lcs);
1895  L2RGatherNewVector.push_back(rcg);
1896  }
1897  }
1898 
1899  for(int i=0; i<R2LGatherOrigPtr->getLength(); i++)
1900  {
1901  const int lcg = (*R2LGatherOrigPtr)[i];
1902  const int rcs = (*R2LScatterOrigPtr)[i];
1903  // if the left cell is in the current face groups neighbours it goes into the new1
1904  if (leftCellsToSCells.find(lcg) != leftCellsToSCells.end())
1905  {
1906  const int sCell = leftCellsToSCells[lcg];
1907 
1908  S2LGatherVector.push_back(lcg);
1909  S2LScatterVector.push_back(sCell);
1910 
1911  R2SGatherVector.push_back(sCell+2*count);
1912  R2SScatterVector.push_back(rcs);
1913 
1914  }
1915  else
1916  {
1917  R2LGatherNewVector.push_back(lcg);
1918  R2LScatterNewVector.push_back(rcs);
1919  }
1920  }
1921 
1922 
1923  // set the gather scatter arrays in the smesh cells
1924  sMeshCells.getScatterMap()[&cells] = arrayFromVector(S2LScatterVector);
1925  sMeshCells.getScatterMap()[&otherCells] = arrayFromVector(S2RScatterVector);
1926  sMeshCells.getGatherMap()[&cells] = arrayFromVector(L2SGatherVector);
1927  sMeshCells.getGatherMap()[&otherCells] = arrayFromVector(R2SGatherVector);
1928 
1929  // replace the existing arrays in left and right maps and add the
1930  // new ones
1931 
1932  lScatterMap.erase(&otherCells);
1933  if (L2RScatterNewVector.size() > 0)
1934  lScatterMap[&otherCells] = arrayFromVector(L2RScatterNewVector);
1935  lScatterMap[&sMeshCells] = arrayFromVector(L2SScatterVector);
1936 
1937  lGatherMap.erase(&otherCells);
1938  if (R2LGatherNewVector.size() > 0)
1939  lGatherMap[&otherCells] = arrayFromVector(R2LGatherNewVector);
1940  lGatherMap[&sMeshCells] = arrayFromVector(S2LGatherVector);
1941 
1942  rScatterMap.erase(&cells);
1943  if (R2LScatterNewVector.size() > 0)
1944  rScatterMap[&cells] = arrayFromVector(R2LScatterNewVector);
1945  rScatterMap[&sMeshCells] = arrayFromVector(R2SScatterVector);
1946 
1947  rGatherMap.erase(&cells);
1948  if (L2RGatherNewVector.size() > 0)
1949  rGatherMap[&cells] = arrayFromVector(L2RGatherNewVector);
1950  rGatherMap[&sMeshCells] = arrayFromVector(S2RGatherVector);
1951  }
1952  // create the cell cell connectivity for the shell mesh
1953  shared_ptr<CRConnectivity> sCellCells(new CRConnectivity(sMeshCells,sMeshCells));
1954  sCellCells->initCount();
1955 
1956  // three neighbours for interior cells, two for ghost, due to
1957  // potentially abnormal interface conditions
1958  for(int i=0; i<count; i++)
1959  {
1960  sCellCells->addCount(i,3);
1961  sCellCells->addCount(i+count,3);
1962  sCellCells->addCount(i+2*count,2);
1963  sCellCells->addCount(i+3*count,2);
1964  }
1965 
1966  sCellCells->finishCount();
1967 
1968  for(int i=0; i<count; i++)
1969  {
1970  // left shell cells
1971  sCellCells->add(i,i+count);
1972  sCellCells->add(i,i+2*count);
1973  sCellCells->add(i,i+3*count);
1974 
1975  // right shell cells
1976  sCellCells->add(i+count,i);
1977  sCellCells->add(i+count,i+2*count);
1978  sCellCells->add(i+count,i+3*count);
1979 
1980  // right ghost cells
1981  sCellCells->add(i+2*count,i);
1982  sCellCells->add(i+2*count,i+count);
1983 
1984  // left ghost cells
1985  sCellCells->add(i+3*count,i);
1986  sCellCells->add(i+3*count,i+count);
1987  }
1988 
1989  sCellCells->finishAdd();
1990 
1991  SSPair key(&sMeshCells,&sMeshCells);
1992 
1993  shellMesh->_connectivityMap[key] = sCellCells;
1994 
1995  return shellMesh;
1996 }
1997 
1998 void
2000 {
2001 #ifdef FVM_PARALLEL
2003  countCRConn();
2004  addCRConn();
2005  //CRConnectivityPrint(this->getCellCellsGhostExt(), 0, "cellCells");
2006 #endif
2007 }
2008 
2009 //fill countArray (both mesh and partition) and only gatherArray for mesh
2010 void
2012 {
2013 #ifdef FVM_PARALLEL
2014  //SENDING allocation and filling
2015  const StorageSite& site = this->getCells();
2016  const CRConnectivity& cellCells = this->getCellCells();
2017  const StorageSite::ScatterMap& scatterMap = site.getScatterMap();
2018  foreach(const StorageSite::ScatterMap::value_type& mpos, scatterMap){
2019  const StorageSite& oSite = *mpos.first;
2020  //checking if storage site is only site or ghost site, we only communicate ghost site ( oSite.getCount() == -1 )
2021  const Array<int>& scatterArray = *mpos.second;
2022  //key site
2023  EntryIndex e(&site,&oSite);
2024  //allocate array
2025  _sendCounts[e] = shared_ptr< Array<int> > ( new Array<int> (scatterArray.getLength()) );
2026  //fill send array
2027  Array<int>& sendArray = dynamic_cast< Array<int>& > ( *_sendCounts[e] );
2028  for( int i = 0; i < scatterArray.getLength(); i++ ){
2029  const int cellID = scatterArray[i];
2030  sendArray[i] = cellCells.getCount(cellID);
2031  }
2032  }
2033 
2034 
2035  //RECIEVING allocation (filling will be done by MPI Communication)
2036  const StorageSite::GatherMap& gatherMap = site.getGatherMap();
2037  foreach(const StorageSite::GatherMap::value_type& mpos, gatherMap){
2038  const StorageSite& oSite = *mpos.first;
2039  const Array<int>& gatherArray = *mpos.second;
2040  //checking if storage site is only site or ghost site, we only communicate ghost site ( oSite.getCount() == -1 )
2041  EntryIndex e(&oSite,&site);
2042  //allocate array
2043  _recvCounts[e] = shared_ptr< Array<int> > ( new Array<int> (gatherArray.getLength()) );
2044  }
2045 #endif
2046  }
2047 
2048 //fill countArray (both mesh and partition) and only gatherArray for mesh
2049 void
2051 {
2052 #ifdef FVM_PARALLEL
2053  const StorageSite& site = this->getCells();
2054  const StorageSite::GatherMap& gatherMap = site.getGatherMap();
2055  foreach(const StorageSite::GatherMap::value_type& mpos, gatherMap){
2056  const StorageSite& oSite = *mpos.first;
2057  //checking if storage site is only site or ghost site, we only communicate ghost site ( oSite.getCount() == -1 )
2058  EntryIndex e(&oSite,&site);
2059  //allocate array
2060  //mesh interface can be done know
2061  if ( oSite.getGatherProcID() == - 1) {
2062  const Mesh& otherMesh = oSite.getMesh();
2063  *_recvCounts[e] = otherMesh.getSendCounts(e);
2064  }
2065  }
2066 #endif
2067 }
2068 
2069 
2070 
2071 void
2073 {
2074 #ifdef FVM_PARALLEL
2075  //SENDING
2076  const int request_size = get_request_size();
2077  MPI::Request request_send[ request_size ];
2078  MPI::Request request_recv[ request_size ];
2079  int indxSend = 0;
2080  int indxRecv = 0;
2081  const StorageSite& site = this->getCells();
2082  const StorageSite::ScatterMap& scatterMap = site.getScatterMap();
2083  foreach(const StorageSite::ScatterMap::value_type& mpos, scatterMap){
2084  const StorageSite& oSite = *mpos.first;
2085  EntryIndex e(&site,&oSite);
2086  //checking if storage site is only site or ghost site, we only communicate ghost site ( oSite.getCount() == -1 )
2087  ArrayBase& sendArray = *_sendCounts[e];
2088 
2089  //loop over surround indices and itself
2090  int to_where = oSite.getGatherProcID();
2091  if ( to_where != -1 ){
2092  int mpi_tag = oSite.getTag();
2093  request_send[indxSend++] =
2094  MPI::COMM_WORLD.Isend( sendArray.getData(), sendArray.getDataSize(), MPI::BYTE, to_where, mpi_tag );
2095  }
2096  }
2097  //RECIEVING
2098  //getting values from other meshes to fill g
2099  const StorageSite::GatherMap& gatherMap = site.getGatherMap();
2100  foreach(const StorageSite::GatherMap::value_type& mpos, gatherMap){
2101  const StorageSite& oSite = *mpos.first;
2102  //checking if storage site is only site or ghost site, we only communicate ghost site ( oSite.getCount() == -1 )
2103  EntryIndex e(&oSite,&site);
2104  ArrayBase& recvArray = *_recvCounts[e];
2105  int from_where = oSite.getGatherProcID();
2106  if ( from_where != -1 ){
2107  int mpi_tag = oSite.getTag();
2108  request_recv[indxRecv++] =
2109  MPI::COMM_WORLD.Irecv( recvArray.getData(), recvArray.getDataSize(), MPI::BYTE, from_where, mpi_tag );
2110  }
2111  }
2112 
2113  int count = get_request_size();
2114  MPI::Request::Waitall( count, request_recv );
2115  MPI::Request::Waitall( count, request_send );
2116 
2117 #endif
2118 
2119 }
2120 
2121 
2122 //fill scatterArray (both mesh and partition) and only gatherArray for mesh
2123 void
2125 {
2126 #ifdef FVM_PARALLEL
2127  //SENDING allocation and filling
2128  const StorageSite& site = this->getCells();
2129  const CRConnectivity& cellCells = this->getCellCells();
2130  const Array<int>& localToGlobal = this->getLocalToGlobal();
2131  const StorageSite::ScatterMap& scatterMap = site.getScatterMap();
2132  foreach(const StorageSite::ScatterMap::value_type& mpos, scatterMap){
2133  const StorageSite& oSite = *mpos.first;
2134  const Array<int>& scatterArray = *mpos.second;
2135  //loop over surround indices and itself for sizing
2136  EntryIndex e(&site,&oSite);
2137  //allocate array
2138  int sendSize = 0;
2139  for ( int i = 0; i < scatterArray.getLength(); i++ ){
2140  sendSize += cellCells.getCount( scatterArray[i] );
2141  }
2142  _sendIndices[e] = shared_ptr< Array<int> > ( new Array<int> (sendSize) );
2143  //fill send array
2144  Array<int>& sendArray = dynamic_cast< Array<int>& > ( *_sendIndices[e] );
2145  int indx = 0;
2146  for( int i = 0; i < scatterArray.getLength(); i++ ){
2147  const int cellID = scatterArray[i];
2148  for ( int j = 0; j < cellCells.getCount(cellID); j++ ){
2149  sendArray[indx] = localToGlobal[ cellCells(cellID,j) ];
2150  indx++;
2151  }
2152  }
2153  }
2154  //RECIEVING allocation (filling will be done by MPI Communication)
2155  const StorageSite::GatherMap& gatherMap = site.getGatherMap();
2156  foreach(const StorageSite::GatherMap::value_type& mpos, gatherMap){
2157  const StorageSite& oSite = *mpos.first;
2158  EntryIndex e(&oSite,&site);
2159  const Array<int>& recvCounts = dynamic_cast< const Array<int>& > (*_recvCounts[e]);
2160  int recvSize = 0;
2161  for ( int i = 0; i < recvCounts.getLength(); i++ ){
2162  recvSize += recvCounts[i];
2163  }
2164  //allocate array
2165  _recvIndices[e] = shared_ptr< Array<int> > ( new Array<int> (recvSize) );
2166  }
2167 #endif
2168 }
2169 
2170 //fill scatterArray (both mesh and partition) and only gatherArray for mesh
2171 void
2173 {
2174 #ifdef FVM_PARALLEL
2175  //RECIEVING allocation (filling will be done by MPI Communication)
2176  const StorageSite& site = this->getCells();
2177  const StorageSite::GatherMap& gatherMap = site.getGatherMap();
2178  foreach(const StorageSite::GatherMap::value_type& mpos, gatherMap){
2179  const StorageSite& oSite = *mpos.first;
2180  EntryIndex e(&oSite,&site);
2181  //mesh interface can be done know
2182  if ( oSite.getGatherProcID() == - 1) {
2183  const Mesh& otherMesh = oSite.getMesh();
2184  *_recvIndices[e] = otherMesh.getSendIndices(e);
2185  }
2186  }
2187 #endif
2188 }
2189 
2190 void
2192 {
2193 #ifdef FVM_PARALLEL
2194  //SENDING
2195  const int request_size = get_request_size();
2196  MPI::Request request_send[ request_size ];
2197  MPI::Request request_recv[ request_size ];
2198  int indxSend = 0;
2199  int indxRecv = 0;
2200  const StorageSite& site = this->getCells();
2201  const StorageSite::ScatterMap& scatterMap = site.getScatterMap();
2202  foreach(const StorageSite::ScatterMap::value_type& mpos, scatterMap){
2203  const StorageSite& oSite = *mpos.first;
2204  EntryIndex e(&site,&oSite);
2205  //checking if storage site is only site or ghost site, we only communicate ghost site ( oSite.getCount() == -1 )
2206  ArrayBase& sendArray = *_sendIndices[e];
2207  //loop over surround indices and itself
2208  int to_where = oSite.getGatherProcID();
2209  if ( to_where != -1 ){
2210  int mpi_tag = oSite.getTag();
2211  request_send[indxSend++] =
2212  MPI::COMM_WORLD.Isend( sendArray.getData(), sendArray.getDataSize(), MPI::BYTE, to_where, mpi_tag );
2213  }
2214  }
2215  //RECIEVING
2216  //getting values from other meshes to fill g
2217  const StorageSite::GatherMap& gatherMap = site.getGatherMap();
2218  foreach(const StorageSite::GatherMap::value_type& mpos, gatherMap){
2219  const StorageSite& oSite = *mpos.first;
2220  EntryIndex e(&oSite,&site);
2221  ArrayBase& recvArray = *_recvIndices[e];
2222  int from_where = oSite.getGatherProcID();
2223  if ( from_where != -1 ){
2224  int mpi_tag = oSite.getTag();
2225  request_recv[indxRecv++] =
2226  MPI::COMM_WORLD.Irecv( recvArray.getData(), recvArray.getDataSize(), MPI::BYTE, from_where, mpi_tag );
2227  }
2228  }
2229 
2230  int count = get_request_size();
2231  MPI::Request::Waitall( count, request_recv );
2232  MPI::Request::Waitall( count, request_send );
2233 #endif
2234 
2235 }
2236 
2238 void
2240 {
2241  //counting interface counts
2242  //counting interfaces
2243  set<int> interfaceCells;
2244  //const Array<int>& localToGlobal = this->getLocalToGlobal();
2245  const map<int,int>& globalToLocal = this->getGlobalToLocal();
2246  const StorageSite& site = this->getCells();
2247  const int originalCount = site.getCount();
2248  const StorageSite::GatherMap& gatherMap = site.getGatherMap();
2249  int countLevel0 = 0;
2250  foreach(const StorageSite::GatherMap::value_type& mpos, gatherMap){
2251  const StorageSite& oSite = *mpos.first;
2252  const Array<int>& gatherArray = dynamic_cast< const Array<int>& > (*mpos.second);
2253  countLevel0 += gatherArray.getLength();
2254  EntryIndex e(&oSite,&site);
2255  const Array<int> & recv_indices = dynamic_cast< const Array<int>& > (*_recvIndices[e]);
2256  const Array<int> & recv_counts = dynamic_cast< const Array<int>& > (*_recvCounts [e]);
2257  //loop over gatherArray
2258  int indx = 0;
2259  for ( int i = 0; i < gatherArray.getLength(); i++ ){
2260  const int nnb = recv_counts[i]; //give getCount()
2261  for ( int nb = 0; nb < nnb; nb++ ){
2262  const int localID = globalToLocal.find( recv_indices[indx] )->second;
2263  if ( localID >= originalCount ){
2264  interfaceCells.insert( recv_indices[indx] );
2265  }
2266  indx++;
2267  }
2268  }
2269  }
2270  const int selfCount = site.getSelfCount();
2271  const int countLevel1 = int(interfaceCells.size());
2272  //ghost cells = sum of boundary and interfaces
2273  const int nghost = getNumBounCells() + countLevel0 + countLevel1;
2274  _cellSiteGhostExt = shared_ptr<StorageSite> ( new StorageSite(selfCount, nghost) );
2275  //constructing new CRConnecitvity;
2276  _cellCellsGhostExt = shared_ptr< CRConnectivity> ( new CRConnectivity( *_cellSiteGhostExt, *_cellSiteGhostExt) );
2277 }
2278 
2279 
2280 void
2282 {
2284  conn.initCount();
2285  const StorageSite& site = this->getCells();
2286  const CRConnectivity& cellCells = this->getCellCells();
2287  int ncount = site.getSelfCount() + getNumBounCells();
2288  //loop over old connectivity (inner + boundary)
2289  for ( int i = 0; i < ncount; i++ ){
2290  conn.addCount(i, cellCells.getCount(i) );
2291  }
2292  // now interfaces
2293  const StorageSite::GatherMap& gatherMap = site.getGatherMap();
2294  foreach(const StorageSite::GatherMap::value_type& mpos, gatherMap){
2295  const StorageSite& oSite = *mpos.first;
2296  const Array<int>& gatherArray = dynamic_cast< const Array<int>& > (*mpos.second);
2297  EntryIndex e(&oSite,&site);
2298  const Array<int>& recv_counts = dynamic_cast< const Array<int>& > (*_recvCounts [e]);
2299  //loop over gatherArray
2300  for ( int i = 0; i < gatherArray.getLength(); i++ ){
2301  conn.addCount(gatherArray[i], recv_counts[i] );
2302  }
2303  }
2304  //finishCount
2305  conn.finishCount();
2306 }
2307 
2308 void
2310 {
2312  const StorageSite& site = this->getCells();
2313  const CRConnectivity& cellCells =this->getCellCells();
2314  int ncount = site.getSelfCount() + getNumBounCells();
2315  //first inner
2316  //loop over olde connectivity (inner + boundary)
2317  for ( int i = 0; i < ncount; i++ ){
2318  for ( int j = 0; j < cellCells.getCount(i); j++ ){
2319  conn.add(i, cellCells(i,j));
2320  }
2321  }
2322 
2323  //CRConnectivityPrint( cellCells, 0, "cellCellsBeforeGhostExt");
2324 
2325  // now interfaces
2326  const map<int,int>& globalToLocal = this->getGlobalToLocal();
2327  const StorageSite::GatherMap& gatherMap = site.getGatherMap();
2328  foreach(const StorageSite::GatherMap::value_type& mpos, gatherMap){
2329  const StorageSite& oSite = *mpos.first;
2330  const Array<int>& gatherArray = dynamic_cast< const Array<int>& > (*mpos.second);
2331  EntryIndex e(&oSite,&site);
2332  const Array<int>& recv_counts = dynamic_cast< const Array<int>& > (*_recvCounts [e]);
2333  const Array<int>& recv_indices = dynamic_cast< const Array<int>& > (*_recvIndices[e]);
2334  //loop over gatherArray
2335  int indx = 0;
2336  for ( int i = 0; i < gatherArray.getLength(); i++ ){
2337  const int ncount = recv_counts[i];
2338  for ( int j = 0; j < ncount; j++ ){
2339  const int addCell = globalToLocal.find( recv_indices[indx] )->second;
2340  conn.add(gatherArray[i], addCell);
2341  indx++;
2342  }
2343  }
2344  }
2345  //finish add
2346  conn.finishAdd();
2347 }
2348 
2349 int
2351 {
2352  //boundary information has been stored
2353  const FaceGroupList& boundaryFaceGroups = this->getBoundaryFaceGroups();
2354  int nBounElm = 0;
2355  for ( int bounID = 0; bounID < int(boundaryFaceGroups.size()); bounID++){
2356  nBounElm += boundaryFaceGroups.at(bounID)->site.getCount();
2357  }
2358  return nBounElm;
2359 }
2360 
2361 
2362 int
2364 {
2365  int indx = 0;
2366  const StorageSite& site = this->getCells();
2367  const StorageSite::ScatterMap& scatterMap = site.getScatterMap();
2368  foreach(const StorageSite::ScatterMap::value_type& mpos, scatterMap){
2369  const StorageSite& oSite = *mpos.first;
2370  //checking if storage site is only site or ghost site, we only communicate ghost site ( oSite.getCount() == -1 )
2371  if ( oSite.getGatherProcID() != -1 )
2372  indx++;
2373  }
2374  return indx;
2375 }
2376 
2377 
2378 void
2379 Mesh::CRConnectivityPrint( const CRConnectivity& conn, int procID, const string& name )
2380 {
2381 #ifdef FVM_PARALLEL
2382  if ( MPI::COMM_WORLD.Get_rank() == procID ){
2383  cout << name << " :" << endl;
2384  const Array<int>& row = conn.getRow();
2385  const Array<int>& col = conn.getCol();
2386  for ( int i = 0; i < row.getLength()-1; i++ ){
2387  cout << " i = " << i << ", ";
2388  for ( int j = row[i]; j < row[i+1]; j++ )
2389  cout << col[j] << " ";
2390  cout << endl;
2391  }
2392  }
2393 #endif
2394 }
2395 
2396 void
2397 Mesh::CRConnectivityPrintFile(const CRConnectivity& conn, const string& name, const int procID) const
2398 {
2399 #ifdef FVM_PARALLEL
2400  if ( MPI::COMM_WORLD.Get_rank() == procID ){
2401  ofstream debugFile;
2402  stringstream ss(stringstream::in | stringstream::out);
2403  ss << procID;
2404  string fname = name + ss.str() + ".dat";
2405  debugFile.open( fname.c_str() );
2406  ss.str("");
2407 
2408  debugFile << name << " :" << endl;
2409  debugFile << endl;
2410  const Array<int>& row = conn.getRow();
2411  const Array<int>& col = conn.getCol();
2412  for ( int i = 0; i < row.getLength()-1; i++ ){
2413  debugFile << " i = " << i << ", ";
2414  for ( int j = row[i]; j < row[i+1]; j++ )
2415  debugFile << col[j] << " ";
2416  debugFile << endl;
2417  }
2418  debugFile << endl;
2419  debugFile.close();
2420  }
2421 #endif
2422 }
2423 
2425 {
2426  foreach(FaceGroupPtr fgPtr, _interfaceGroups)
2427  {
2428  _boundaryGroups.push_back(fgPtr);
2429  }
2430  _interfaceGroups.clear();
2431 }
const CRConnectivity & getAllFaceNodes() const
Definition: Mesh.cpp:368
const FaceGroupList & getBoundaryFaceGroups() const
Definition: Mesh.h:187
#define epsilon
Definition: Mesh.cpp:17
void setNodeRepeationArrayCoupling(const Mesh &bMesh)
Definition: Mesh.cpp:753
const Array< int > & getCol() const
int getCount(const int i) const
virtual void zero()
Definition: Array.h:281
virtual int getDataSize() const =0
const Array< int > & getRow() const
const ArrayBase & getSendCounts(const EntryIndex &e) const
Definition: Mesh.h:277
shared_ptr< FaceGroup > FaceGroupPtr
Definition: Mesh.h:46
int getSelfCount() const
Definition: StorageSite.h:40
void setFaceNodes(shared_ptr< CRConnectivity > faceNodes)
Definition: Mesh.cpp:646
Field coordinate
Definition: GeomFields.h:19
const CRConnectivity & getConnectivity(const StorageSite &from, const StorageSite &to) const
Definition: Mesh.cpp:416
void findCommonFaces(StorageSite &faces, StorageSite &otherFaces, const GeomFields &geomFields)
Definition: Mesh.cpp:996
int get_request_size()
Definition: Mesh.cpp:2363
bool _isShell
Definition: Mesh.h:408
map< int, int > _globalToLocal
Definition: Mesh.h:398
const int _dimension
Definition: Mesh.h:346
void eraseConnectivity(const StorageSite &rowSite, const StorageSite &colSite) const
Definition: Mesh.cpp:359
Definition: Mesh.h:28
void createGhostCellSiteScatter(const PartIDMeshIDPair &id, shared_ptr< StorageSite > site)
Definition: Mesh.cpp:694
const FaceGroupList & getAllFaceGroups() const
Definition: Mesh.h:193
shared_ptr< Array< int > > _ibFaceList
Definition: Mesh.h:369
void CRConnectivityPrint(const CRConnectivity &conn, int procID, const string &name)
Definition: Mesh.cpp:2379
bool COMETfindCommonFaces(StorageSite &faces, StorageSite &otherFaces, const GeomFields &geomFields)
Definition: Mesh.cpp:1053
StorageSite _faces
Definition: Mesh.h:355
const StorageSite & getNodes() const
Definition: Mesh.h:110
FaceGroupList _interfaceGroups
Definition: Mesh.h:364
map< int, int > _commonFacesMapOther
Definition: Mesh.h:393
const StorageSite & createInteriorFaceGroup(const int size)
Definition: Mesh.cpp:259
const ScatterIndex & getScatterIndex() const
Definition: StorageSite.h:61
Array< int > IntArray
Definition: Mesh.h:54
void createGhostCellSiteGatherLevel1(const PartIDMeshIDPair &id, shared_ptr< StorageSite > site)
Definition: Mesh.cpp:715
map< int, int > _commonFacesMap
Definition: Mesh.h:392
const Array< int > & getIBFaceList() const
Definition: Mesh.cpp:686
void setCoordinates(shared_ptr< Array< VecD3 > > x)
Definition: Mesh.h:204
GhostArrayMap _sendCounts
Definition: Mesh.h:383
bool _isConnectedShell
Definition: Mesh.h:410
const FaceGroup & getFaceGroup(const int fgId) const
Definition: Mesh.cpp:1570
Definition: Mesh.h:49
ConnectivityMap _connectivityMap
Definition: Mesh.h:365
const CRConnectivity & getFaceNodes(const StorageSite &site) const
Definition: Mesh.cpp:402
const CommonMap & getCommonMap() const
Definition: StorageSite.h:60
T mag(const Vector< T, 3 > &a)
Definition: Vector.h:260
void setFaceCells(shared_ptr< CRConnectivity > faceCells)
Definition: Mesh.cpp:654
void setCount(const int selfCount, const int nGhost=0)
Definition: StorageSite.h:42
shared_ptr< CRConnectivity > _cellCellsGhostExt
Definition: Mesh.h:389
Mesh * createShell(const int fgId, Mesh &otherMesh, const int otherFgId)
Definition: Mesh.cpp:1582
void createRowColSiteCRConn()
Definition: Mesh.cpp:2239
void setConnectivity(const StorageSite &rowSite, const StorageSite &colSite, shared_ptr< CRConnectivity > conn)
Definition: Mesh.cpp:352
map< int, int > & getGlobalToLocal()
Definition: Mesh.h:243
#define logCtor()
Definition: RLogInterface.h:26
GhostCellSiteMap _ghostCellSiteScatterMapLevel1
Definition: Mesh.h:380
Mesh * extrude(int nz, double zmax, bool boundaryOnly=false)
Definition: Mesh.cpp:1258
const StorageSite & createBoundaryFaceGroup(const int size, const int offset, const int id, const string &boundaryType)
Definition: Mesh.cpp:278
string groupType
Definition: Mesh.h:42
void recvScatterGatherCountsBufferLocal()
Definition: Mesh.cpp:2050
GhostCellSiteMap _ghostCellSiteGatherMapLevel1
Definition: Mesh.h:381
const ArrayBase & getSendIndices(const EntryIndex &e) const
Definition: Mesh.h:278
GhostArrayMap _recvIndices
Definition: Mesh.h:386
void setMesh(const Mesh *mesh)
Definition: StorageSite.h:55
bool _isDoubleShell
Definition: Mesh.h:409
const StorageSite * _otherFaceGroupSite
Definition: Mesh.h:417
Mesh(const int dimension)
Definition: Mesh.cpp:21
Tangent sqrt(const Tangent &a)
Definition: Tangent.h:317
void orderCellFacesAndNodes(CRConnectivity &cellFaces, CRConnectivity &cellNodes, const CRConnectivity &faceNodes, const CRConnectivity &faceCells, const Array< Vector< double, 3 > > &nodeCoordinates)
Definition: Cell.cpp:241
pair< const StorageSite *, const StorageSite * > EntryIndex
Definition: Mesh.h:64
const CRConnectivity & getAllFaceCells() const
Definition: Mesh.cpp:378
const CRConnectivity & getCellFaces() const
Definition: Mesh.cpp:454
shared_ptr< CRConnectivity > _cellCells2
Definition: Mesh.h:405
const int id
Definition: Mesh.h:41
void countCRConn()
Definition: Mesh.cpp:2281
void createGhostCellSiteGather(const PartIDMeshIDPair &id, shared_ptr< StorageSite > site)
Definition: Mesh.cpp:701
int _otherMeshID
Definition: Mesh.h:419
const StorageSite & getBoundaryNodes() const
Definition: Mesh.cpp:325
set< int > _boundaryNodesSet
Definition: Mesh.h:394
shared_ptr< Array< int > > _boundaryNodeGlobalToLocalPtr
Definition: Mesh.h:367
static int _lastID
Definition: Mesh.h:421
GhostCellSiteMap _ghostCellSiteScatterMap
Definition: Mesh.h:377
void syncCounts()
Definition: Mesh.cpp:2072
const Array< VecD3 > & getNodeCoordinates() const
Definition: Mesh.h:218
const StorageSite & createInterfaceGroup(const int size, const int offset, const int id)
Definition: Mesh.cpp:268
Array< int > & getLocalToGlobal()
Definition: Mesh.h:240
Mesh * createDoubleShell(const int fgId, Mesh &otherMesh, const int otherFgId, const bool connectedShell)
Definition: Mesh.cpp:1772
int getTag() const
Definition: StorageSite.h:84
Mesh * extractBoundaryMesh()
Definition: Mesh.cpp:1122
shared_ptr< Array< int > > _cellColorOther
Definition: Mesh.h:372
GhostArrayMap _recvCounts
Definition: Mesh.h:384
void uniqueFaceCells()
Definition: Mesh.cpp:666
int getGatherProcID() const
Definition: StorageSite.h:83
void createScatterGatherIndicesBuffer()
Definition: Mesh.cpp:2124
GhostCellSiteMap _ghostCellSiteGatherMap
Definition: Mesh.h:378
void findCommonNodes(Mesh &other)
Definition: Mesh.cpp:877
void CRConnectivityPrintFile(const CRConnectivity &conn, const string &name, const int procID) const
Definition: Mesh.cpp:2397
vector< FaceGroupPtr > FaceGroupList
Definition: Mesh.h:47
pair< const StorageSite *, const StorageSite * > SSPair
Definition: Mesh.h:60
void findNeighbors(const Vec3D &p, const int k, Array< int > &neighbors)
Definition: KSearchTree.cpp:30
multiMap _cellCellsGlobal
Definition: Mesh.h:400
const Mesh & getMesh() const
Definition: StorageSite.h:56
shared_ptr< StorageSite > _cellSiteGhostExt
Definition: Mesh.h:388
pair< int, int > PartIDMeshIDPair
Definition: Mesh.h:62
const StorageSite & getFaces() const
Definition: Mesh.h:108
void recvScatterGatherIndicesBufferLocal()
Definition: Mesh.cpp:2172
shared_ptr< FaceGroup > _interiorFaceGroup
Definition: Mesh.h:361
FaceGroupList _boundaryGroups
Definition: Mesh.h:363
const CRConnectivity & getCellCells() const
Definition: Mesh.cpp:480
const StorageSite & getCells() const
Definition: Mesh.h:109
Vector< T, 3 > cross(const Vector< T, 3 > &a, const Vector< T, 3 > &b)
Definition: Vector.h:242
void createLocalGlobalArray()
Definition: Mesh.cpp:738
StorageSite _nodes
Definition: Mesh.h:356
#define logDtor()
Definition: RLogInterface.h:33
int getCountLevel1() const
Definition: StorageSite.h:72
shared_ptr< CRConnectivity > _faceCells2
Definition: Mesh.h:406
const ScatterMap & getScatterMap() const
Definition: StorageSite.h:58
void InterfaceToBoundary()
Definition: Mesh.cpp:2424
const CRConnectivity & getFaceCells(const StorageSite &site) const
Definition: Mesh.cpp:388
map< const StorageSite *, shared_ptr< Array< int > > > ScatterMap
Definition: StorageSite.h:23
const CRConnectivity & getFaceCells2() const
Definition: Mesh.cpp:633
Definition: Array.h:14
int getOffset() const
Definition: StorageSite.h:87
shared_ptr< CRConnectivity > multiply(const CRConnectivity &b, const bool implicitDiagonal) const
void createCellColor()
Definition: Mesh.cpp:724
shared_ptr< Array< int > > _repeatNodes
Definition: Mesh.h:395
const GatherMap & getGatherMap() const
Definition: StorageSite.h:59
shared_ptr< Array< int > > _localToGlobal
Definition: Mesh.h:397
shared_ptr< Array< int > > _cellColor
Definition: Mesh.h:371
void createGhostCellSiteScatterLevel1(const PartIDMeshIDPair &id, shared_ptr< StorageSite > site)
Definition: Mesh.cpp:708
shared_ptr< CRConnectivity > getTranspose() const
int add(const int index, const int val)
shared_ptr< CRConnectivity > createOffset(const StorageSite &newRowSite, const int offset, const int size) const
const CRConnectivity & getCellCells2() const
Definition: Mesh.cpp:495
virtual void * getData() const =0
shared_ptr< Array< int > > createAndGetBNglobalToLocal() const
Definition: Mesh.cpp:288
void createScatterGatherCountsBuffer()
Definition: Mesh.cpp:2011
int getCount() const
Definition: StorageSite.h:39
void addCRConn()
Definition: Mesh.cpp:2309
StorageSite _cells
Definition: Mesh.h:354
int getNumBounCells()
Definition: Mesh.cpp:2350
Field area
Definition: GeomFields.h:23
map< const StorageSite *, shared_ptr< Array< int > > > GatherMap
Definition: StorageSite.h:24
GhostArrayMap _sendIndices
Definition: Mesh.h:385
int _parentMeshID
Definition: Mesh.h:418
bool _isAssembleMesh
Definition: Mesh.h:374
shared_ptr< Array< VecD3 > > _coordinates
Definition: Mesh.h:366
shared_ptr< ArrayBase > getUpdatedNodesCoordCoupling(const GeomFields &geomField, const Mesh &bMesh)
Definition: Mesh.cpp:784
void createCellCellsGhostExt()
Definition: Mesh.cpp:1999
StorageSite * _boundaryNodes
Definition: Mesh.h:359
void setCommonFacesMap(const Mesh &bMesh)
Definition: Mesh.cpp:810
const StorageSite * _parentFaceGroupSite
Definition: Mesh.h:416
const StorageSite & getRowSite() const
FaceGroupList _faceGroups
Definition: Mesh.h:362
int getRowDim() const
int getID() const
Definition: Mesh.h:106
void addCount(const int index, const int count)
const CRConnectivity & getCellNodes() const
Definition: Mesh.cpp:426
const ArrayBase & getBNglobalToLocal() const
Definition: Mesh.cpp:346
void syncIndices()
Definition: Mesh.cpp:2191
void createLocalToGlobalNodesArray()
Definition: Mesh.cpp:745
shared_ptr< Array< T > > arrayFromVector(const vector< T > &v)
Definition: Array.h:523
StorageSite site
Definition: Mesh.h:40
shared_ptr< Array< int > > _localToGlobalNodes
Definition: Mesh.h:396
void insert(const Vec3D &v, const int n)
Definition: KSearchTree.cpp:23
int getLength() const
Definition: Array.h:87
~Mesh()
Definition: Mesh.cpp:250
T mag2(const Vector< T, 3 > &a)
Definition: Vector.h:267