void BulkAdapt::remote_edgeAdj_replace(int remotePartID, adaptAdj elem, adaptAdj oldElem, adaptAdj newElem, int n1_idxl, int n2_idxl) { int n1 = get_node_from_idxl(n1_idxl, remotePartID), n2 = get_node_from_idxl(n2_idxl, remotePartID); // Find the relative nodes on the edge to be bisected int relNodes[4]; FEM_Elem &elems = meshPtr->elem[elem.elemType]; // elems is all local elements int *conn = elems.connFor(elem.localID); // conn points at elemID's ACTUAL data! fillNodes(relNodes, n1, n2, conn); // find which edgeID is bisected int edgeID = getEdgeID(relNodes[0], relNodes[1], 4, 3); replaceAdaptAdjOnEdge(meshPtr, elem, oldElem, newElem, edgeID); }
void BulkAdapt::remote_edgeAdj_add(int remotePartID, adaptAdj adj, adaptAdj splitElem, int n1_idxl, int n2_idxl) { int n1 = get_node_from_idxl(n1_idxl, remotePartID), n2 = get_node_from_idxl(n2_idxl, remotePartID); // Find the relative nodes on the edge to be bisected int relNodes[4]; FEM_Elem &elems = meshPtr->elem[adj.elemType]; // elems is all local elements int *conn = elems.connFor(adj.localID); // conn points at elemID's ACTUAL data! fillNodes(relNodes, n1, n2, conn); // find which edgeID is bisected int edgeID = getEdgeID(relNodes[0], relNodes[1], 4, 3); addToAdaptAdj(meshPtr, adj, edgeID, splitElem); }
//------------------------------------------------------------------------------ void NiceGraph::removeEdge (int from, int to) { bool okflag; if (isDirected) okflag = testFromToConnected(from,to); else okflag = testConnected(from,to); // test connected first to make sure the connection exists if (okflag) { int edgeID = getEdgeID(from,to); removeEdge(edgeID); if (!isDirected) removeEdge(to,from); } }
int computeFID( int* bb ) { int count = 0; for( int i = 0; i < 6; i++ ) { count += bb[i]; } if( count == 0 ) { return -1; } else if( count == 1 ) { for( int i = 0; i < 6; i++ ) { if( bb[i] == 1 ) { return BoundsToFace[i]; } } } else if( count == 2 ) { int edgeID = getEdgeID( bb ); return 14+edgeID; } else if( count == 3 ) { int pointID = 0; pointID += ( ( bb[0] ) ? 1 : 0 ); pointID += ( ( bb[2] ) ? 2 : 0 ); pointID += ( ( bb[4] ) ? 4 : 0 ); return 6+pointID; } else { cerr << "computeFID: Error: cannot have this case. Touching too many boundaries" << endl; } return -1; }
/* * The bend has become straight, remove bend */ void BendConstraint::satisfy() { COLA_ASSERT((scanDim==vpsc::XDIM)||(scanDim==vpsc::YDIM)); FILE_LOG(logDEBUG) << "BendConstraint::satisfy()... edge id=" << getEdgeID() << " node id=" << bendPoint->node->id; // XXX: Note that the call to prune() deletes the bendPoint and the // BendConstraint (this instance itself), so it is not safe to // access any member variables after that. Hence the local copy // of scanDim. The code really needs to be reworked to be // written much more cleanly, only this kind of restructuring // has the potential to introduce many bugs, so I will leave it // for now. -- mjwybrow vpsc::Dim dim = scanDim; Node* node=bendPoint->node; double pos=bendPoint->pos(vpsc::conjugate(scanDim)); Segment* s=bendPoint->prune(scanDim); // create a new StraightConstraint to replace the BendConstraint s->createStraightConstraint(dim, node, pos); FILE_LOG(logDEBUG)<<"BendConstraint::satisfy()...done."; }
adaptAdj BulkAdapt::remote_edge_bisect_2D(adaptAdj nbrElem, adaptAdj splitElem, int new_idxl, int n1_idxl, int n2_idxl, int remotePartID) { int node1idx, node2idx, newNodeID; node1idx = get_node_from_idxl(n1_idxl, remotePartID); node2idx = get_node_from_idxl(n2_idxl, remotePartID); FEM_Elem &elem = meshPtr->elem[nbrElem.elemType]; // elem is local elements int *nbrConn = elem.connFor(nbrElem.localID); int relNode1 = getRelNode(node1idx, nbrConn, 3); int relNode2 = getRelNode(node2idx, nbrConn, 3); int nbrEdgeID = getEdgeID(relNode1, relNode2, 3, 2); FEM_DataAttribute *coord = meshPtr->node.getCoord(); // entire local coords double *node1coords = (coord->getDouble()).getRow(node1idx); // ptrs to ACTUAL coords! double *node2coords = (coord->getDouble()).getRow(node2idx); // ptrs to ACTUAL coords! double bisectCoords[2]; midpoint(node1coords, node2coords, 2, &bisectCoords[0]); newNodeID = add_node(2, &bisectCoords[0]); int chunks[2] = {nbrElem.partID, remotePartID}; make_node_shared(newNodeID, 2, chunks); int local_new_idxl = get_idxl_for_node(newNodeID, remotePartID); if (new_idxl != local_new_idxl) printf("ERROR: Partition %d added shared node at different idxl index %d than other copy at %d on partition %d!", nbrElem.partID, local_new_idxl, new_idxl, remotePartID); int nbrNode1, nbrNode2; adaptAdj nbrSplitElem; // split the local neighbor element, i.e. the second "side" one_side_split_2D(nbrElem, nbrSplitElem, nbrEdgeID, &nbrNode1, &nbrNode2, &newNodeID, false); adaptAdj *nbrSplitElemAdaptAdj = getAdaptAdj(meshPtr, nbrSplitElem.localID, nbrSplitElem.elemType, 0); nbrSplitElemAdaptAdj[nbrEdgeID] = splitElem; //BULK_DEBUG(printf("[%d] For nbrSplitElem %d set adjacency to %d across splitEdge\n",partitionID,nbrSplitElem.localID,splitElem.localID);) return nbrSplitElem; }
void IsoSurfaceThread::run() { int numThreads = GLFunctions::idealThreadCount; int chunkSize = m_scalarField->size() / numThreads; int begin = m_id * chunkSize; int end = m_id * chunkSize + chunkSize; if ( m_id == numThreads - 1 ) { end = m_scalarField->size() - ( ( m_nX + 1 ) * ( m_nY + 1 ) ); } int x; int y; int z; // Generate isosurface. for ( int k = begin; k < end; ++k ) { getXYZ( k, x, y, z ); if ( x == m_nX ) continue; if ( y == m_nY ) continue; // Calculate table lookup index from those // vertices which are below the isolevel. unsigned int tableIndex = 0; if ( m_scalarField->at( z * m_nPointsInSlice + y * m_nPointsInXDirection + x ) < m_isoLevel ) tableIndex |= 1; if ( m_scalarField->at( z * m_nPointsInSlice + ( y + 1 ) * m_nPointsInXDirection + x ) < m_isoLevel ) tableIndex |= 2; if ( m_scalarField->at( z * m_nPointsInSlice + ( y + 1 ) * m_nPointsInXDirection + ( x + 1 ) ) < m_isoLevel ) tableIndex |= 4; if ( m_scalarField->at( z * m_nPointsInSlice + y * m_nPointsInXDirection + ( x + 1 ) ) < m_isoLevel ) tableIndex |= 8; if ( m_scalarField->at( ( z + 1 ) * m_nPointsInSlice + y * m_nPointsInXDirection + x ) < m_isoLevel ) tableIndex |= 16; if ( m_scalarField->at( ( z + 1 ) * m_nPointsInSlice + ( y + 1 ) * m_nPointsInXDirection + x ) < m_isoLevel ) tableIndex |= 32; if ( m_scalarField->at( ( z + 1 ) * m_nPointsInSlice + ( y + 1 ) * m_nPointsInXDirection + ( x + 1 ) ) < m_isoLevel ) tableIndex |= 64; if ( m_scalarField->at( ( z + 1 ) * m_nPointsInSlice + y * m_nPointsInXDirection + ( x + 1 ) ) < m_isoLevel ) tableIndex |= 128; // Now create a triangulation of the isosurface in this // cell. if ( edgeTable[ tableIndex ] != 0 ) { if ( edgeTable[ tableIndex ] & 8 ) { POINT3DID pt = calculateIntersection( x, y, z, 3 ); unsigned int id = getEdgeID( x, y, z, 3 ); QMutexLocker locker( m_mutex ); m_i2pt3idVertices->insert( id, pt ); locker.unlock(); } if ( edgeTable[ tableIndex ] & 1 ) { POINT3DID pt = calculateIntersection( x, y, z, 0 ); unsigned int id = getEdgeID( x, y, z, 0 ); QMutexLocker locker( m_mutex ); m_i2pt3idVertices->insert( id, pt ); locker.unlock(); } if ( edgeTable[ tableIndex ] & 256 ) { POINT3DID pt = calculateIntersection( x, y, z, 8 ); unsigned int id = getEdgeID( x, y, z, 8 ); QMutexLocker locker( m_mutex ); m_i2pt3idVertices->insert( id, pt ); locker.unlock(); } if ( x == m_nX - 1 ) { if ( edgeTable[ tableIndex ] & 4 ) { POINT3DID pt = calculateIntersection( x, y, z, 2 ); unsigned int id = getEdgeID( x, y, z, 2 ); QMutexLocker locker( m_mutex ); m_i2pt3idVertices->insert( id, pt ); locker.unlock(); } if ( edgeTable[ tableIndex ] & 2048 ) { POINT3DID pt = calculateIntersection( x, y, z, 11 ); unsigned int id = getEdgeID( x, y, z, 11 ); QMutexLocker locker( m_mutex ); m_i2pt3idVertices->insert( id, pt ); locker.unlock(); } } if ( y == m_nY - 1 ) { if ( edgeTable[ tableIndex ] & 2 ) { POINT3DID pt = calculateIntersection( x, y, z, 1 ); unsigned int id = getEdgeID( x, y, z, 1 ); QMutexLocker locker( m_mutex ); m_i2pt3idVertices->insert( id, pt ); locker.unlock(); } if ( edgeTable[ tableIndex ] & 512 ) { POINT3DID pt = calculateIntersection( x, y, z, 9 ); unsigned int id = getEdgeID( x, y, z, 9 ); QMutexLocker locker( m_mutex ); m_i2pt3idVertices->insert( id, pt ); locker.unlock(); } } if ( z == m_nZ - 1 ) { if ( edgeTable[ tableIndex ] & 16 ) { POINT3DID pt = calculateIntersection( x, y, z, 4 ); unsigned int id = getEdgeID( x, y, z, 4 ); QMutexLocker locker( m_mutex ); m_i2pt3idVertices->insert( id, pt ); locker.unlock(); } if ( edgeTable[ tableIndex ] & 128 ) { POINT3DID pt = calculateIntersection( x, y, z, 7 ); unsigned int id = getEdgeID( x, y, z, 7 ); QMutexLocker locker( m_mutex ); m_i2pt3idVertices->insert( id, pt ); locker.unlock(); } } if ( ( x == m_nX - 1 ) && ( y == m_nY - 1 ) ) if ( edgeTable[ tableIndex ] & 1024 ) { POINT3DID pt = calculateIntersection( x, y, z, 10 ); unsigned int id = getEdgeID( x, y, z, 10 ); QMutexLocker locker( m_mutex ); m_i2pt3idVertices->insert( id, pt ); locker.unlock(); } if ( ( x == m_nX - 1 ) && ( z == m_nZ - 1 ) ) if ( edgeTable[ tableIndex ] & 64 ) { POINT3DID pt = calculateIntersection( x, y, z, 6 ); unsigned int id = getEdgeID( x, y, z, 6 ); QMutexLocker locker( m_mutex ); m_i2pt3idVertices->insert( id, pt ); locker.unlock(); } if ( ( y == m_nY - 1 ) && ( z == m_nZ - 1 ) ) if ( edgeTable[ tableIndex ] & 32 ) { POINT3DID pt = calculateIntersection( x, y, z, 5 ); unsigned int id = getEdgeID( x, y, z, 5 ); QMutexLocker locker( m_mutex ); m_i2pt3idVertices->insert( id, pt ); locker.unlock(); } for ( int i = 0; triTable[ tableIndex ][ i ] != -1; i += 3 ) { TRIANGLE triangle; unsigned int pointID0, pointID1, pointID2; pointID0 = getEdgeID( x, y, z, triTable[ tableIndex ][ i ] ); pointID1 = getEdgeID( x, y, z, triTable[ tableIndex ][ i + 1 ] ); pointID2 = getEdgeID( x, y, z, triTable[ tableIndex ][ i + 2 ] ); triangle.pointID[ 0 ] = pointID0; triangle.pointID[ 1 ] = pointID1; triangle.pointID[ 2 ] = pointID2; QMutexLocker locker( m_mutex ); m_trivecTriangles->push_back( triangle ); locker.unlock(); } } } }
void BulkAdapt::local_update_asterisk_3D(int i, adaptAdj elem, int numElemPairs, adaptAdj *elemPairs, int n1, int n2, int n5) { FEM_Elem &elems = meshPtr->elem[elem.elemType]; int *conn = elems.connFor(elem.localID); int n3=-1, n4=-1; for (int i=0; i<4; i++) { if ((conn[i] != n1) && (conn[i] != n5) && (n3 == -1)) n3 = conn[i]; else if ((conn[i] != n1) && (conn[i] != n5)) n4 = conn[i]; } // derive relative nodes int relNode[4]; relNode[0] = getRelNode(n1, conn, 4); relNode[1] = getRelNode(n5, conn, 4); relNode[2] = getRelNode(n3, conn, 4); relNode[3] = getRelNode(n4, conn, 4); int face[4]; // face[0] and [1] are split; others are not face[0] = (relNode[0] + relNode[1] + relNode[2]) - 3; face[1] = (relNode[0] + relNode[1] + relNode[3]) - 3; face[2] = (relNode[0] + relNode[3] + relNode[2]) - 3; face[3] = (relNode[1] + relNode[3] + relNode[2]) - 3; adaptAdj neighbors[4]; // elem's neighbors neighbors[0] = *getFaceAdaptAdj(meshPtr, elem.localID, elem.elemType, face[0]); neighbors[1] = *getFaceAdaptAdj(meshPtr, elem.localID, elem.elemType, face[1]); neighbors[2] = *getFaceAdaptAdj(meshPtr, elem.localID, elem.elemType, face[2]); neighbors[3] = *getFaceAdaptAdj(meshPtr, elem.localID, elem.elemType, face[3]); adaptAdj splitElem = neighbors[3], nbr1 = neighbors[0], nbr2 = neighbors[1]; adaptAdj nbr1split(-1,-1,0), nbr2split(-1,-1,0); int found=0; if (nbr1.localID != -1) found++; if (nbr2.localID != -1) found++; for (int i=0; i<numElemPairs; i++) { if (elemPairs[2*i] == nbr1) { nbr1split = elemPairs[2*i+1]; found--; } else if (elemPairs[2*i] == nbr2) { nbr2split = elemPairs[2*i+1]; found--; } if (found == 0) break; } int *splitConn = elems.connFor(splitElem.localID); int splitRelNode[4]; splitRelNode[0] = getRelNode(n5, splitConn, 4); splitRelNode[1] = getRelNode(n2, splitConn, 4); splitRelNode[2] = getRelNode(n3, splitConn, 4); splitRelNode[3] = getRelNode(n4, splitConn, 4); int splitFace[4]; // splitFace[0] and [1] are split; others are not splitFace[0] = (splitRelNode[0] + splitRelNode[1] + splitRelNode[2]) - 3; splitFace[1] = (splitRelNode[0] + splitRelNode[1] + splitRelNode[3]) - 3; splitFace[2] = (splitRelNode[0] + splitRelNode[3] + splitRelNode[2]) - 3; splitFace[3] = (splitRelNode[1] + splitRelNode[3] + splitRelNode[2]) - 3; // Update faces first replaceAdaptAdj(meshPtr, splitElem, nbr1, nbr1split); replaceAdaptAdj(meshPtr, splitElem, nbr2, nbr2split); // Now, update edges // Here are the edges to update for elem: int n3_n5, n4_n5; // Here are the edges to update for splitElem: int n5_n2, n5_n3, n5_n4, n2_n3, n2_n4; // set the edge IDs n3_n5 = getEdgeID(relNode[2], relNode[1], 4, 3); n4_n5 = getEdgeID(relNode[3], relNode[1], 4, 3); n5_n2 = getEdgeID(splitRelNode[0], splitRelNode[1], 4, 3); n5_n3 = getEdgeID(splitRelNode[0], splitRelNode[2], 4, 3); n5_n4 = getEdgeID(splitRelNode[0], splitRelNode[3], 4, 3); n2_n3 = getEdgeID(splitRelNode[1], splitRelNode[2], 4, 3); n2_n4 = getEdgeID(splitRelNode[1], splitRelNode[3], 4, 3); clearEdgeAdjacency(meshPtr, elem.localID, elem.elemType, n3_n5); clearEdgeAdjacency(meshPtr, elem.localID, elem.elemType, n4_n5); clearEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n2); clearEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n3); clearEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n4); addEdgeAdjacency(meshPtr, elem.localID, elem.elemType, n3_n5, splitElem); if (nbr1.localID != -1) { addEdgeAdjacency(meshPtr, elem.localID, elem.elemType, n3_n5, nbr1); addEdgeAdjacency(meshPtr, elem.localID, elem.elemType, n3_n5, nbr1split); } addEdgeAdjacency(meshPtr, elem.localID, elem.elemType, n4_n5, splitElem); if (nbr2.localID != -1) { addEdgeAdjacency(meshPtr, elem.localID, elem.elemType, n4_n5, nbr2); addEdgeAdjacency(meshPtr, elem.localID, elem.elemType, n4_n5, nbr2split); } addEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n3, elem); if (nbr1.localID != -1) { addEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n3, nbr1); addEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n3, nbr1split); } addEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n4, elem); if (nbr2.localID != -1) { addEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n4, nbr2); addEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n4, nbr2split); } for (int i=0; i<numElemPairs; i++) { if (splitElem != elemPairs[2*i+1]) { addEdgeAdjacency(meshPtr, splitElem.localID, splitElem.elemType, n5_n2, elemPairs[2*i+1]); } } if(nbr1.localID != -1) replaceAdaptAdjOnEdge(meshPtr, splitElem, nbr1, nbr1split, n2_n3); if(nbr2.localID != -1) replaceAdaptAdjOnEdge(meshPtr, splitElem, nbr2, nbr2split, n2_n4); }
/* o o /|\ /|\ startElem / | \ nbrElem startElem / | \ nbrElem / | \ / | \ / | \ / | \ / | \ / | \ o | o o-----o-----o \ | / \ | / \ | / \ | / \ | / splitElem \ | / nbrSplitElem \ | / \ | / \|/ \|/ o o */ bool BulkAdapt::edge_bisect_2D(int elemID, int elemType, int edgeID) { //BULK_DEBUG(CkPrintf("[%d] BulkAdapt::edge_bisect_2D starts elemID %d \n",partitionID,elemID)); // lock partitions for the two involved elements adaptAdj elemsToLock[2]; adaptAdj startElem(partitionID, elemID, elemType); adaptAdj nbrElem = *getAdaptAdj(meshID, elemID, elemType, edgeID); //BULK_DEBUG(printf("[%d] neighbor of elem %d is elem (%d,%d) \n",partitionID,elemID,nbrElem.partID,nbrElem.localID);) elemsToLock[0] = startElem; elemsToLock[1] = nbrElem; RegionID lockRegionID; if (localShadow->lockRegion(2, elemsToLock, &lockRegionID,0.0)) { //BULK_DEBUG(CkPrintf("[%d] Lock obtained.\n",partitionID);); } else { //BULK_DEBUG(CkPrintf("[%d] Lock not obtained.\n",partitionID);); return false; } // ******** LOCAL OPS ********* int node1idx, node2idx, newNodeID; adaptAdj splitElem; // split the local element, i.e. the first "side" one_side_split_2D(startElem, splitElem, edgeID, &node1idx, &node2idx, &newNodeID, true); if ((nbrElem.partID > -1) && (nbrElem.partID == partitionID)) { // if nbrElem exists and is local... // PRE: neighbor-side operations FEM_Elem &elem = meshPtr->elem[elemType]; // elem is local elements int *nbrConn = elem.connFor(nbrElem.localID); int relNode1 = getRelNode(node1idx, nbrConn, 3); int relNode2 = getRelNode(node2idx, nbrConn, 3); int nbrEdgeID = getEdgeID(relNode1, relNode2, 3, 2); int nbrNode1, nbrNode2; adaptAdj nbrSplitElem; // split the local neighbor element, i.e. the second "side" one_side_split_2D(nbrElem, nbrSplitElem, nbrEdgeID, &nbrNode1, &nbrNode2, &newNodeID, false); // now fix the adjacencies across the new edge to the two new elements adaptAdj *splitElemAdaptAdj = getAdaptAdj(meshID, splitElem.localID, splitElem.elemType, 0); adaptAdj *nbrSplitElemAdaptAdj = getAdaptAdj(meshID, nbrSplitElem.localID, nbrSplitElem.elemType, 0); nbrSplitElemAdaptAdj[nbrEdgeID] = splitElem; //BULK_DEBUG(printf("[%d] For nbrSplitElem %d set adjacency to %d across splitEdge\n",partitionID,nbrSplitElem.localID,splitElem.localID);) // POST: start-side operations splitElemAdaptAdj[edgeID] = nbrSplitElem; //BULK_DEBUG(printf("[%d] For splitElem %d set adjacency to %d across splitEdge\n",partitionID,splitElem.localID,nbrSplitElem.localID);) } else if (nbrElem.partID == -1) { // startElem's edgeID is on domain boundary adaptAdj *splitElemAdaptAdj = getAdaptAdj(meshID, splitElem.localID, splitElem.elemType, 0); splitElemAdaptAdj[edgeID] = adaptAdj(-1, -1, 0); //BULK_DEBUG(printf("[%d] For splitElem %d splitEdge is on the domain boundary.\n",partitionID,splitElem.localID);) } else { // nbrElem exists and is remote int chunks[1] = {nbrElem.partID}; make_node_shared(newNodeID, 1, &chunks[0]); int new_idxl, n1_idxl, n2_idxl; new_idxl = get_idxl_for_node(newNodeID, nbrElem.partID); n1_idxl = get_idxl_for_node(node1idx, nbrElem.partID); n2_idxl = get_idxl_for_node(node2idx, nbrElem.partID); // make sync call on partition nbrElem.partID // SEND: nbrElem, splitElem, new_idxl, n1_idxl, n2_idxl, partitionID // RETURNS: nbrSplitElem adaptAdjMsg *am = shadowProxy[nbrElem.partID].remote_bulk_edge_bisect_2D(nbrElem, splitElem, new_idxl, n1_idxl, n2_idxl, partitionID); adaptAdj nbrSplitElem = am->elem; // now fix the adjacencies across the new edge to remote new element adaptAdj *splitElemAdaptAdj = getAdaptAdj(meshID, splitElem.localID, splitElem.elemType, 0); splitElemAdaptAdj[edgeID] = nbrSplitElem; //BULK_DEBUG(printf("[%d] For splitElem %d set adjacency to %d across splitEdge\n",partitionID,splitElem.localID,nbrSplitElem.localID);) } // unlock the two partitions localShadow->unlockRegion(lockRegionID); getAndDumpAdaptAdjacencies(meshID, meshPtr->nElems(), elemType, partitionID); return true; }
void BulkAdapt::handle_split_3D(int remotePartID, int pos, int tableID, adaptAdj elem, RegionID lockRegionID, int n1_idxl, int n2_idxl, int n5_idxl) { int n1 = get_node_from_idxl(n1_idxl, remotePartID), n2 = get_node_from_idxl(n2_idxl, remotePartID), n5; if (is_node_in_idxl(n5_idxl, remotePartID)) { n5 = get_node_from_idxl(n5_idxl, remotePartID); } else { FEM_DataAttribute *coord = meshPtr->node.getCoord(); // all local coords double *n0co = (coord->getDouble()).getRow(n1); double *n1co = (coord->getDouble()).getRow(n2); double nodeCoords[9]; nodeCoords[0] = n0co[0]; nodeCoords[1] = n0co[1]; nodeCoords[2] = n0co[2]; nodeCoords[3] = n1co[0]; nodeCoords[4] = n1co[1]; nodeCoords[5] = n1co[2]; midpoint(&(nodeCoords[0]), &(nodeCoords[3]), 3, &(nodeCoords[6])); n5 = add_node(3, &(nodeCoords[6])); // Find the relative nodes on the edge to be bisected int relNodes[4]; FEM_Elem &elems = meshPtr->elem[elem.elemType]; // elems is all local elements int *conn = elems.connFor(elem.localID); // conn points at elemID's ACTUAL data! fillNodes(relNodes, n1, n2, conn); // find which edgeID is bisected int edgeID = getEdgeID(relNodes[0], relNodes[1], 4, 3); // find elements on edge to be bisected int numElemsToLock = 0; adaptAdj *elemsToLock; get_elemsToLock(elem, &elemsToLock, edgeID, &numElemsToLock); // find chunks that share the edge to be bisected int *chunks = (int *)malloc(numElemsToLock*sizeof(int)); int numParts=0; for (int i=0; i<numElemsToLock; i++) { chunks[i] = -1; int j; for (j=0; j<numParts; j++) { if (chunks[j] == elemsToLock[i].partID) { break; } } chunks[j] = elemsToLock[i].partID; if (j==numParts) numParts++; } if (numParts > 1) make_node_shared(n5, numParts, &chunks[0]); free(chunks); free(elemsToLock); } adaptAdj *splitElem = local_split_3D(elem, n1, n2, n5); shadowProxy[remotePartID].recv_split_3D(pos, tableID, elem, *splitElem); delete splitElem; }
/** Perform local edge adjacency updates associated with a split */ void BulkAdapt::update_local_edge_adj(adaptAdj elem, adaptAdj splitElem, int n1, int n2, int n5) { copyEdgeAdaptAdj(meshPtr, &elem, &splitElem); // first, extract the modifiable data structures in question CkVec<adaptAdj> *elemEdgeAdj[6]; CkVec<adaptAdj> *splitElemEdgeAdj[6]; for (int i=0; i<6; i++) { elemEdgeAdj[i] = getEdgeAdaptAdj(meshPtr, elem.localID, elem.elemType, i); splitElemEdgeAdj[i] = getEdgeAdaptAdj(meshPtr, splitElem.localID, splitElem.elemType, i); } // the edges modified in this operation are the old edges of elem, // now on splitElem: (n2,n3) and (n2,n4), the old edge (n3,n4) which // was on elem, but is now on both elem and splitElem, and the new // edges that get added incident on n5: (n3,n5) and (n4,n5). The // new edge (n2,n5) must be updated in a different context. // Here's how each of these needs to be modified: // (n2,n3): originally on elem, for splitElem, it will be identical, but we // need to replace elem with splitElem on all the other elements along that // edge. // (n2,n4): identical to (n2,n3) // (n3,n4): elem needs to take it's original list and add splitElem to it; // splitElem takes elem's original list and adds element to it; then // all the elements in that original list need to add splitElem. // (n3,n5): start with an empty list on both elem and splitElem. // elem adds splitElem, splitElem adds elem. Other elements // surrounding the split edge (n1,n2) must be added outside of this // operation // (n4,n5): identical to (n3,n5) // Start with splitElem: get relNodes and edgeIDs FEM_Elem &elems = meshPtr->elem[splitElem.elemType]; int *conn = elems.connFor(splitElem.localID); int n3=-1, n4=-1; for (int i=0; i<4; i++) { if ((conn[i] != n5) && (conn[i] != n2) && (n3 == -1)) n3 = conn[i]; else if ((conn[i] != n5) && (conn[i] != n2)) n4 = conn[i]; } // derive relative nodes int relNode[4]; relNode[0] = getRelNode(n5, conn, 4); relNode[1] = getRelNode(n2, conn, 4); relNode[2] = getRelNode(n3, conn, 4); relNode[3] = getRelNode(n4, conn, 4); // edgeIDs on splitElem int n2_n3 = getEdgeID(relNode[1], relNode[2], 4, 3); int n2_n4 = getEdgeID(relNode[1], relNode[3], 4, 3); int n3_n4 = getEdgeID(relNode[2], relNode[3], 4, 3); int n3_n5 = getEdgeID(relNode[2], relNode[0], 4, 3); int n4_n5 = getEdgeID(relNode[3], relNode[0], 4, 3); // Get similar info for elem int *elemConn = elems.connFor(elem.localID); // derive relative nodes int elem_relNode[4]; elem_relNode[0] = getRelNode(n1, elemConn, 4); elem_relNode[1] = getRelNode(n5, elemConn, 4); elem_relNode[2] = getRelNode(n3, elemConn, 4); elem_relNode[3] = getRelNode(n4, elemConn, 4); // edgeIDs on elem int elem_n3_n4 = getEdgeID(relNode[2], relNode[3], 4, 3); int elem_n3_n5 = getEdgeID(relNode[2], relNode[1], 4, 3); int elem_n4_n5 = getEdgeID(relNode[3], relNode[1], 4, 3); // split face IDs on elem int face[4]; // face[0] and [1] are split; others are not face[0] = (elem_relNode[0] + elem_relNode[1] + elem_relNode[2]) - 3; face[1] = (elem_relNode[0] + elem_relNode[1] + elem_relNode[3]) - 3; // split neighbors on elem adaptAdj elem_neighbors[4]; // elem's neighbors elem_neighbors[0] = *getFaceAdaptAdj(meshPtr,elem.localID, elem.elemType, face[0]); elem_neighbors[1] = *getFaceAdaptAdj(meshPtr,elem.localID, elem.elemType, face[1]); // Now we're ready to go to town // n2_n3 for (int i=0; i<elemEdgeAdj[elem_n3_n5]->size(); i++) { adaptAdj adj = (*elemEdgeAdj[elem_n3_n5])[i]; if ((adj != elem_neighbors[0]) && (adj != elem_neighbors[1])) { if (adj.partID == splitElem.partID) { // do the local replace on adj int *adjConn = elems.connFor(adj.localID); // derive relative nodes int r2, r3; r2 = getRelNode(n2, adjConn, 4); r3 = getRelNode(n3, adjConn, 4); // edgeID on adj int edgeID = getEdgeID(r2, r3, 4, 3); replaceAdaptAdjOnEdge(meshPtr, adj, elem, splitElem, edgeID); } else if (adj.partID != -1) { // call remote replacement int n2_idxl = get_idxl_for_node(n2, adj.partID); int n3_idxl = get_idxl_for_node(n3, adj.partID); //printf("[%d] A:calling remote edgeAdj replace on %don%d, to replace %don%d with %don%d, with edge at %d,%d thinking elem's forbidden face neighbors are %don%d and %don%d\n", partitionID, adj.localID, adj.partID, elem.localID, elem.partID, splitElem.localID, splitElem.partID, n2, n3, elem_neighbors[0].localID, elem_neighbors[0].partID, elem_neighbors[1].localID, elem_neighbors[1].partID); shadowProxy[adj.partID].remote_edgeAdj_replace(partitionID, adj, elem, splitElem, n2_idxl, n3_idxl); } } } // wow! all that was just for the (n2,n3) edge! This sucks! // n2_n4 -- easy, just like the previous one for (int i=0; i<elemEdgeAdj[elem_n4_n5]->size(); i++) { adaptAdj adj = (*elemEdgeAdj[elem_n4_n5])[i]; if ((adj != elem_neighbors[0]) && (adj != elem_neighbors[1])) { if (adj.partID == splitElem.partID) { // do the local replace on adj int *adjConn = elems.connFor(adj.localID); // derive relative nodes int r2, r4; r2 = getRelNode(n2, adjConn, 4); r4 = getRelNode(n4, adjConn, 4); // edgeID on adj int edgeID = getEdgeID(r2, r4, 4, 3); replaceAdaptAdjOnEdge(meshPtr, adj, elem, splitElem, edgeID); } else if (adj.partID != -1) { // call remote replacement int n2_idxl = get_idxl_for_node(n2, adj.partID); int n4_idxl = get_idxl_for_node(n4, adj.partID); //printf("[%d] B:calling remote edgeAdj replace on %don%d, to replace %don%d with %don%d, with edge at %d,%d, thinking elem's forbidden face neighbors are %don%d and %don%d\n", partitionID, adj.localID, adj.partID, elem.localID, elem.partID, splitElem.localID, splitElem.partID, n2, n4, elem_neighbors[0].localID, elem_neighbors[0].partID, elem_neighbors[1].localID, elem_neighbors[1].partID); shadowProxy[adj.partID].remote_edgeAdj_replace(partitionID, adj, elem, splitElem, n2_idxl, n4_idxl); } } } // n3_n4: elem needs to take it's original list and add splitElem to it; // splitElem takes elem's original list and adds element to it; then // all the elements in that original list need to add splitElem. // This is *similar* to the previous case, with the exceptions that // we are *adding* instead of replacing on the other elems on the // edge, and the addition of elem and splitElem to each other's edgeAdj. for (int i=0; i<elemEdgeAdj[elem_n3_n4]->size(); i++) { adaptAdj adj = (*elemEdgeAdj[elem_n3_n4])[i]; if (adj.partID == splitElem.partID) { // do the local replace on adj int *adjConn = elems.connFor(adj.localID); // derive relative nodes int r3, r4; r3 = getRelNode(n3, adjConn, 4); r4 = getRelNode(n4, adjConn, 4); // edgeID on adj int edgeID = getEdgeID(r3, r4, 4, 3); addToAdaptAdj(meshPtr, adj, edgeID, splitElem); } else if (adj.partID != -1) { // call remote replacement int n3_idxl = get_idxl_for_node(n3, adj.partID); int n4_idxl = get_idxl_for_node(n4, adj.partID); shadowProxy[adj.partID].remote_edgeAdj_add(partitionID, adj, splitElem, n3_idxl, n4_idxl); } } addToAdaptAdj(meshPtr, splitElem, n3_n4, elem); addToAdaptAdj(meshPtr, elem, elem_n3_n4, splitElem); // The last two cases are performed elsewhere }
//------------------------------------------------------------------------------ float NiceGraph::getWeight(int from, int to) { int eID = getEdgeID(from,to); return edgeList[eID]->weight; }