21 Mesh& solidBoundaryMesh,
23 fluidNeighborsPerIBFace(50),
24 fluidNeighborsPerSolidFace(50),
25 solidNeighborsPerIBFace(50),
26 IBNeighborsPerSolidFace(50),
27 _geomFields(geomFields),
28 _solidBoundaryMesh(solidBoundaryMesh),
29 _fluidMeshes(fluidMeshes)
45 for (
int n=0; n<numFluidMeshes; n++)
61 for (
int n=0; n<numFluidMeshes; n++)
68 MPI::COMM_WORLD.Allreduce( MPI::IN_PLACE, &nFound, 1, MPI::INT, MPI::SUM );
69 if ( MPI::COMM_WORLD.Get_rank() == 0 )
70 cout <<
"iteration " << nIter <<
": found " << nFound <<
" fluid cells " << endl;
74 cout <<
"iteration " << nIter <<
": found " << nFound <<
" fluid cells " << endl;
82 for (
int n=0; n<numFluidMeshes; n++)
90 for (
int n=0; n<numFluidMeshes; n++)
97 for (
int n=0; n<numFluidMeshes; n++)
104 vector<NearestCell> solidFacesNearestCell(solidMeshFaces.
getCount());
107 for (
int n=0; n<numFluidMeshes; n++) {
123 for(
int c=0; c<numCells; c++)
126 fluidCellsTree.
insert(cellCoords[c],c);
141 vector<doubleIntStruct> solidFacesNearestCellMPI(solidMeshFaces.
getCount());
142 const int procID = MPI::COMM_WORLD.Get_rank();
143 const int faceCount = solidMeshFaces.
getCount();
144 for(
int i = 0; i < faceCount; i++ ){
145 const Mesh* mesh = solidFacesNearestCell[i].mesh;
147 const int meshID = mesh->
getID();
148 const int tag = (
std::max(procID, meshID) << 16 ) | (
std::min(procID,meshID) );
149 const double val = solidFacesNearestCell[i].distanceSquared;
150 solidFacesNearestCellMPI[i].VALUE = val;
151 solidFacesNearestCellMPI[i].TAG = tag;
153 const double LARGE_VALUE = 1.0e+15;
154 solidFacesNearestCellMPI[i].VALUE = LARGE_VALUE;
155 solidFacesNearestCellMPI[i].TAG = -1;
160 MPI::COMM_WORLD.Allreduce(MPI::IN_PLACE, &solidFacesNearestCellMPI[0], faceCount, MPI::DOUBLE_INT, MPI::MINLOC);
162 for (
int i = 0; i < faceCount; i++ ){
163 const Mesh* meshThis = solidFacesNearestCell[i].mesh;
164 if ( meshThis != NULL ){
165 const int meshIDThis = meshThis->
getID();
166 const int tagThis = (
std::max(procID, meshIDThis) << 16 ) | (
std::min(procID,meshIDThis) );
167 if ( tagThis != solidFacesNearestCellMPI[i].TAG ){
168 solidFacesNearestCell[i].mesh = NULL;
176 for (
int n=0; n<numFluidMeshes; n++)
184 const int nIBFaces = ibFaces.
getCount();
187 for(
int c=0; c<nIBFaces; c++)
189 const int gf=ibFaceIndices[c];
190 IBFacesTree.
insert(faceCoords[gf],c);
224 const int nFaces = faces.
getCount();
226 int nIntersections = 0;
233 for(
int n=0; n<nCells; n++)
235 const Vec3D& a = meshCoords[cellNodes(n,0)];
236 const Vec3D& b = meshCoords[cellNodes(n,1)];
237 const Vec3D& c = meshCoords[cellNodes(n,2)];
245 else if (cellNodes.
getCount(n) == 4)
248 const Vec3D& d = meshCoords[cellNodes(n,3)];
263 for(
int f=0; f<nFaces; f++)
265 const int c0 = faceCells(f,0);
266 const int c1 = faceCells(f,1);
268 const Vec3D& a = meshCoords[faceNodes(f,0)];
269 const Vec3D& b = meshCoords[faceNodes(f,1)];
270 const Vec3D& c = meshCoords[faceNodes(f,2)];
280 else if (faceNodes.
getCount(f) == 4)
283 const Vec3D& d = meshCoords[faceNodes(f,3)];
304 const int nFaces = faces.
getCount();
305 for(
int f=0; f<nFaces; f++)
307 const int c0 = faceCells(f,0);
308 const int c1 = faceCells(f,1);
335 const int nCellsTotal = cells.
getCount();
347 for(
int c=0; c<nCellsTotal; c++)
352 stack<int> cellsToCheck;
353 cellsToCheck.push(c);
356 while(!cellsToCheck.empty())
358 int c_nb = cellsToCheck.top();
360 const int nNeighbors = cellCells.
getCount(c_nb);
361 for(
int nn=0; nn<nNeighbors; nn++)
363 const int neighbor = cellCells(c_nb,nn);
368 cellsToCheck.push(neighbor);
393 for(
int c=0; c<nCellsTotal; c++)
420 cout <<
" found " << nFluid <<
" fluid, "
421 << nSolid <<
" solid and "
422 << nBoundary <<
" boundary cells " << endl;
432 int nBoundaryGlobal=0;
433 vector<int> ibTypeCells;
436 for(
int c=0; c<nCellsInner; c++)
444 ibTypeCells.push_back(localToGlobal[c]);
451 MPI::COMM_WORLD.Allreduce( &nFluid, &nFluidGlobal , 1, MPI::INT, MPI::SUM);
452 MPI::COMM_WORLD.Allreduce( &nSolid, &nSolidGlobal , 1, MPI::INT, MPI::SUM);
453 MPI::COMM_WORLD.Allreduce( &nBoundary, &nBoundaryGlobal, 1, MPI::INT, MPI::SUM);
454 vector<int> ibTypeCellsGlobal(nBoundaryGlobal);
455 const int nsize = MPI::COMM_WORLD.Get_size();
456 const int rank = MPI::COMM_WORLD.Get_rank();
459 MPI::COMM_WORLD.Allgather(&nBoundary, 1, MPI::INT, &counts[0], 1, MPI::INT);
462 for (
int p=1; p < nsize; p++){
463 offsets[p] = counts[p-1] + offsets[p-1];
467 MPI::COMM_WORLD.Gatherv(&ibTypeCells[0],counts[rank], MPI::INT,
468 &ibTypeCellsGlobal[0], counts, offsets, MPI::INT, 0);
471 if ( MPI::COMM_WORLD.Get_rank() == 0 ){
472 set<int> ibTypeCellSet;
473 for(
int i = 0; i < int(ibTypeCellsGlobal.size()); i++ ){
474 ibTypeCellSet.insert( ibTypeCellsGlobal[i] );
479 debugFile.open(
"IBManagerDEBUG.dat");
480 debugFile <<
" found (global) " << nFluidGlobal <<
" fluid, " << nSolidGlobal <<
" solid and "
481 << nBoundaryGlobal <<
" boundary cells " << endl;
482 debugFile <<
"IBTYPE_BOUNDARY CELLS (GLOBAL NUMBERING)" << endl;
483 foreach (
const set<int>::value_type cellID, ibTypeCellSet){
484 debugFile << cellID << endl;
511 const int nFaces = faces.
getCount();
518 for(
int f=0; f<nFaces; f++)
520 const int c0 = faceCells(f,0);
521 const int c1 = faceCells(f,1);
523 const int ibType0 = cellIBType[c0];
524 const int ibType1 = cellIBType[c1];
529 ibFaceIndex[f]=nIBFaces++;
535 throw CException(
"found face between solid and fluid cells");
543 shared_ptr<IntArray > ibFaceListPtr(
new IntArray(nIBFaces));
545 IntArray& ibFaceList = *ibFaceListPtr;
548 for(
int f=0; f<nFaces; f++)
550 const int c0 = faceCells(f,0);
551 const int c1 = faceCells(f,1);
553 const int ibType0 = cellIBType[c0];
554 const int ibType1 = cellIBType[c1];
559 ibFaceList[nIBFaces++] = f;
564 cout <<
" found " << nIBFaces <<
" ib Faces " << endl;
579 set<int> newNeighbors;
580 foreach(
int c, neighbors)
582 const int neighborCount = cellCells.
getCount(c);
583 for(
int nnb=0; nnb<neighborCount; nnb++)
585 const int c_nb = cellCells(c,nnb);
587 newNeighbors.insert(c_nb);
590 neighbors.insert(newNeighbors.begin(),newNeighbors.end());
601 const int nIBFaces = ibFaces.
getCount();
613 shared_ptr<CRConnectivity> ibFaceToCells
616 shared_ptr<CRConnectivity> ibFaceToSolid
624 vector<NearestCell> nearestCellForIBFace(nIBFaces);
634 ibFaceToCells->initCount();
635 ibFaceToSolid->initCount();
637 for(
int f=0; f<nIBFaces; f++)
642 ibFaceToSolid->finishCount();
645 for(
int f=0; f<nIBFaces; f++)
648 const int gf = ibFaceIndices[f];
649 const Vec3D& xf = faceCentroid[gf];
653 fluidNeighbors[0] = -9999;
656 if ( fluidNeighbors[0] != -9999 ){
657 nc.
neighbors.push_back(fluidNeighbors[0]);
658 const int c = fluidNeighbors[0];
659 const int neighborCount = cellCells2.
getCount(c);
660 for(
int nnb=0; nnb<neighborCount; nnb++) {
661 const int c_nb = cellCells2(c,nnb);
675 dtree.
insert( cellCoords[nb], nb);
678 while (swap ==
true){
680 for (
int i=1; i<=(nc.
neighbors.size()-1); i++){
683 const double distanceLeft =
mag2(cellCoords[nbLeft]-solidMeshCoords[f]);
684 const double distanceRight =
mag2(cellCoords[nbRight]-solidMeshCoords[f]);
685 if (distanceLeft > distanceRight){
700 nc.
neighbors.push_back(desiredNeighbors[i]);
715 throw CException(
"not enough fluid cells for IB face interpolation");
718 ibFaceToCells->addCount(f,nc.
neighbors.size());
724 ibFaceToSolid->add(f,solidNeighbors[n]);
727 ibFaceToCells->finishCount();
728 ibFaceToSolid->finishAdd();
730 for(
int f=0; f<nIBFaces; f++)
735 ibFaceToCells->add(f,nb);
745 ibFaceToCells->finishAdd();
761 vector<NearestCell>& nearest)
767 const int nSolidFaces = solidMeshFaces.
getCount();
776 for(
int f=0; f<nSolidFaces; f++)
779 fluidNeighbors[0] = -9999;
780 const Vec3D& xf = solidFaceCentroid[f];
782 if ( fluidNeighbors[0] != -9999 ){
783 const int c = fluidNeighbors[0];
784 const Vec3D& xc = cellCentroid[c];
785 const double distanceSquared =
mag2(xf-xc);
846 vector<NearestCell>& nearest)
852 const int nFaces = faces.
getCount();
862 const int nSolidFaces = solidMeshFaces.
getCount();
868 shared_ptr<CRConnectivity> solidFacesToCells
870 shared_ptr<CRConnectivity> solidToIBFaces
872 solidFacesToCells->initCount();
873 solidToIBFaces->initCount();
876 for(
int f=0; f<nSolidFaces; f++)
881 solidToIBFaces->finishCount();
883 for(
int f=0; f<nSolidFaces; f++)
886 if (nc.
mesh == &mesh)
888 const int c = nc.
cell;
891 const int neighborCount = cellCells2.
getCount(c);
892 for(
int nnb=0; nnb<neighborCount; nnb++) {
893 const int c_nb = cellCells2(c,nnb);
906 dtree.
insert( cellCoords[nb], nb);
910 while (swap ==
true){
912 for (
int i=1; i<=(nc.
neighbors.size()-1); i++){
915 const double distanceLeft =
mag2(cellCoords[nbLeft]-solidMeshCoords[f]);
916 const double distanceRight =
mag2(cellCoords[nbRight]-solidMeshCoords[f]);
917 if (distanceLeft > distanceRight){
933 nc.
neighbors.push_back(desiredNeighbors[i]);
949 solidFacesToCells->addCount(f,nc.
neighbors.size());
955 solidFacesToCells->finishCount();
958 for(
int f=0; f<nSolidFaces; f++)
961 if (nc.
mesh == &mesh)
965 solidFacesToCells->add(f,nb);
975 solidFacesToCells->finishAdd();
978 for(
int f=0; f<nSolidFaces; f++)
981 const Vec3D& xf = solidMeshCoords[f];
985 solidToIBFaces->add(f, desiredNeighborsforIBFaces[n]);
994 solidToIBFaces->finishAdd();
1009 if ( MPI::COMM_WORLD.Get_rank() == procID ){
1011 stringstream ss(stringstream::in | stringstream::out);
1013 string fname = name + ss.str() +
".dat";
1014 debugFile.open( fname.c_str() );
1017 debugFile << name <<
" :" << endl;
1021 for (
int i = 0; i < row.
getLength()-1; i++ ){
1022 debugFile <<
" i = " << i <<
", ";
1023 for (
int j = row[i]; j < row[i+1]; j++ )
1024 debugFile << col[j] <<
" ";
void markIntersections(Mesh &fluidMesh, AABB &sMeshesAABB)
const CRConnectivity & getAllFaceNodes() const
const FaceGroupList & getBoundaryFaceGroups() const
const Array< int > & getCol() const
int getCount(const int i) const
const Array< int > & getRow() const
shared_ptr< FaceGroup > FaceGroupPtr
const StorageSite & getIBFaces() const
void addFluidNeighbors(set< int > &neighbors, const CRConnectivity &cellCells, const Array< int > &ibType)
void CRConnectivityPrintFile(const CRConnectivity &conn, const string &name, const int procID) const
void createSolidInterpolationStencil(Mesh &mesh, KSearchTree &IBFacesTree, vector< NearestCell > &nearest)
int fluidNeighborsPerIBFace
int markSolid(Mesh &fluidMesh)
bool hasIntersectionWithTriangle(Vec3D a, Vec3D b, Vec3D c)
const Array< int > & getIBFaceList() const
double max(double x, double y)
int markFluid(Mesh &fluidMesh)
void setCount(const int selfCount, const int nGhost=0)
void setConnectivity(const StorageSite &rowSite, const StorageSite &colSite, shared_ptr< CRConnectivity > conn)
void createIBInterpolationStencil(Mesh &mesh, KSearchTree &fluidCellsTree, KSearchTree &solidFacesTree)
const CRConnectivity & getAllFaceCells() const
const Array< VecD3 > & getNodeCoordinates() const
Array< int > & getLocalToGlobal()
IBManager(GeomFields &geomFields, Mesh &solidBoundaryMesh, const MeshList &fluidMeshes)
void markIBTypePlus(Mesh &fluidMesh)
void setIBFaces(shared_ptr< Array< int > > faceList)
void findNeighbors(const Vec3D &p, const int k, Array< int > &neighbors)
const StorageSite & getFaces() const
void createIBFaces(Mesh &fluidMesh)
const CRConnectivity & getCellCells() const
const StorageSite & getCells() const
static void clearGradientMatrix(const Mesh &mesh)
int solidNeighborsPerIBFace
Mesh & _solidBoundaryMesh
int getCountLevel1() const
int IBNeighborsPerSolidFace
const CRConnectivity & getFaceCells(const StorageSite &site) const
const MeshList _fluidMeshes
void findNearestCellForSolidFaces(Mesh &mesh, KSearchTree &fluidCellsTree, vector< NearestCell > &nearest)
const CRConnectivity & getCellCells2() const
double min(double x, double y)
int fluidNeighborsPerSolidFace
const CRConnectivity & getCellNodes() const
vector< Mesh * > MeshList
void insert(const Vec3D &v, const int n)
T mag2(const Vector< T, 3 > &a)