void _SnacRemesher_InterpolateNodes( void* _context ) { Snac_Context* context = (Snac_Context*)_context; SnacRemesher_Context* contextExt = ExtensionManager_Get( context->extensionMgr, context, SnacRemesher_ContextHandle ); Mesh* mesh = context->mesh; SnacRemesher_Mesh* meshExt = ExtensionManager_Get( context->meshExtensionMgr, mesh, SnacRemesher_MeshHandle ); NodeLayout* nLayout = mesh->layout->nodeLayout; Node_LocalIndex newNode_i; IndexSet* extNodes; void interpolateNode( void* _context, Node_LocalIndex newNodeInd, Element_DomainIndex dEltInd ); /* ** Free any owned arrays that may still exist from the last node interpolation. */ FreeArray( meshExt->externalNodes ); meshExt->nExternalNodes = 0; /* ** Scoot over all the new nodes and find the old element in which each one resides, then interpolate. */ /* Create an index set for storing any external nodes. */ extNodes = IndexSet_New( mesh->nodeLocalCount ); for( newNode_i = 0; newNode_i < mesh->nodeLocalCount; newNode_i++ ) { Node_LocalIndex dNodeInd; unsigned nElements; Element_DomainIndex* elements; Coord newPoint; unsigned elt_i; /* Extract the new node's coordinate. */ Vector_Set( newPoint, meshExt->newNodeCoords[newNode_i] ); /* Find the closest old node. */ dNodeInd = findClosestNode( context, newPoint, newNode_i ); /* Grab incident elements. */ { Node_GlobalIndex gNodeInd; gNodeInd = Mesh_NodeMapDomainToGlobal( mesh, dNodeInd ); nElements = nLayout->nodeElementCount( nLayout, gNodeInd ); if( nElements ) { elements = Memory_Alloc_Array( Element_DomainIndex, nElements, "SnacRemesher" ); nLayout->buildNodeElements( nLayout, gNodeInd, elements ); } else { elements = NULL; } } /* Convert global element indices to domain. */ for( elt_i = 0; elt_i < nElements; elt_i++ ) { elements[elt_i] = Mesh_ElementMapGlobalToDomain( mesh, elements[elt_i] ); } /* Which of the incident elements contains the node? */ for( elt_i = 0; elt_i < nElements; elt_i++ ) { if( elements[elt_i] >= mesh->elementDomainCount ) { continue; } if( pointInElement( context, newPoint, elements[elt_i] ) ) { break; } } /* Did we find the element? */ if( elt_i < nElements ) { /* If so, call a function to locate the tetrahedra and interpolate. */ interpolateNode( context, newNode_i, elements[elt_i] ); } else { /* If not, then the new node finds itself outside the old mesh. In this scenario, we cannot interpolate the nodal values with any accuracy (without knowing more about the physical problem). So, we will leave the node with its old values and mark this node as not being interpolated so the user may deal with it. */ /* Stash the node index. */ IndexSet_Add( extNodes, newNode_i ); /* Copy across the old value. Note that this should be done using some other provided copy method. */ memcpy( (unsigned char*)meshExt->newNodes + newNode_i * mesh->nodeExtensionMgr->finalSize, (unsigned char*)mesh->node + newNode_i * mesh->nodeExtensionMgr->finalSize, mesh->nodeExtensionMgr->finalSize ); /* assert(0); */ } /* Free element array. */ FreeArray( elements ); } /* Dump the external nodes and delete the set. */ IndexSet_GetMembers( extNodes, &meshExt->nExternalNodes, &meshExt->externalNodes ); Stg_Class_Delete( extNodes ); }
void FEM_Coarsen_Operation(FEM_Operation_Data *coarsen_data, coarsenData &operation){ double *coord = coarsen_data->coord; int tri,nodeToThrow,nodeToKeep,n1,n2; int *connData = coarsen_data->connData; int *validNodeData = coarsen_data->validNodeData; int *validElemData = coarsen_data->validElemData; int *nodeBoundaryData = coarsen_data->nodeBoundaryData; FEM_Attribute *sparseBoundaryAttr = coarsen_data->sparseBoundaryAttr; AllocTable2d<int> *sparseBoundaryTable; switch(operation.type){ case COLLAPSE: { tri = operation.data.cdata.elemID; nodeToKeep = operation.data.cdata.nodeToKeep; nodeToThrow = operation.data.cdata.nodeToDelete; int opNode = 0; for (int i=0; i<3; i++) { if ((connData[3*tri+i] != nodeToThrow) && (connData[3*tri+i] != nodeToKeep)) { opNode = connData[3*tri+i]; break; } } CkPrintf("Collapse %d, nodeToKeep %d, nodeToThrow %d, opNode %d\n", tri, nodeToKeep, nodeToThrow, opNode); sparseBoundaryTable = &(((FEM_DataAttribute *)sparseBoundaryAttr)->getInt()); int delEdgeIdx = coarsen_data->nodes2sparse->get(intdual(nodeToThrow,opNode))-1; int keepEdgeIdx = coarsen_data->nodes2sparse->get(intdual(nodeToKeep,opNode))-1; int delBC = ((*sparseBoundaryTable)[delEdgeIdx])[0]; int keepBC = ((*sparseBoundaryTable)[keepEdgeIdx])[0]; if (delBC > keepBC) { ((*sparseBoundaryTable)[keepEdgeIdx])[0] = delBC; } if(operation.data.cdata.flag & 0x1 || operation.data.cdata.flag & 0x2){ interpolateNode(coarsen_data->node,nodeToKeep,nodeToThrow,nodeToKeep,operation.data.cdata.frac); coord[2*nodeToKeep] = operation.data.cdata.newX; coord[2*nodeToKeep+1] = operation.data.cdata.newY; validNodeData[nodeToThrow] = 0; validNodeData[nodeToKeep] = 1; DEBUGINT(printf("---------Collapse <%d,%d> invalidating node %d and element %d \n",nodeToKeep,nodeToThrow,nodeToThrow,tri)); if(coarsen_data->validEdge){ int sidx = coarsen_data->nodes2sparse->get(intdual(nodeToKeep,nodeToThrow))-1; coarsen_data->nodes2sparse->remove(intdual(nodeToKeep,nodeToThrow)); (*(coarsen_data->validEdge))[sidx][0] = 0; DEBUGINT(printf("---- Deleting edge %d between nodes %d and %d \n",sidx,nodeToKeep,nodeToThrow)); if (delEdgeIdx >=0) { coarsen_data->nodes2sparse->remove(intdual(opNode,nodeToThrow)); (*(coarsen_data->validEdge))[delEdgeIdx][0] = 0; DEBUGINT(printf("---- Deleting edge %d between nodes %d and %d \n",delEdgeIdx,opNode,nodeToThrow)); } } } else { if (delEdgeIdx >=0) { coarsen_data->nodes2sparse->remove(intdual(opNode,nodeToThrow)); (*(coarsen_data->validEdge))[delEdgeIdx][0] = 0; DEBUGINT(printf("---- Deleting edge %d between nodes %d and %d \n",delEdgeIdx,opNode,nodeToThrow)); } } validElemData[tri] = 0; connData[3*tri] = connData[3*tri+1] = connData[3*tri+2] = -1; } break; case UPDATE: if(validNodeData[operation.data.udata.nodeID]){ coord[2*(operation.data.udata.nodeID)] = operation.data.udata.newX; coord[2*(operation.data.udata.nodeID)+1] = operation.data.udata.newY; if(nodeBoundaryData){ nodeBoundaryData[operation.data.udata.nodeID]=operation.data.udata.boundaryFlag; } }else{ DEBUGINT(printf("[%d] WEIRD -- update operation for invalid node %d \n",CkMyPe(),operation.data.udata.nodeID)); } break; case REPLACE: if(validElemData[operation.data.rddata.elemID]){ if(connData[3*operation.data.rddata.elemID+operation.data.rddata.relnodeID] == operation.data.rddata.oldNodeID){ connData[3*operation.data.rddata.elemID+operation.data.rddata.relnodeID] = operation.data.rddata.newNodeID; if(validNodeData[operation.data.rddata.oldNodeID]){ validNodeData[operation.data.rddata.oldNodeID]=0; } if(coarsen_data->validEdge){ //remove the edges containing oldNodeID and add edges containing newNodeID in the nodes2sparse hashtable //update the connectivity information of the edges for(int i=0;i<3;i++){ //find the two nodes apart from the one being replaced if(i != operation.data.rddata.relnodeID){ int otherNode = connData[3*operation.data.rddata.elemID+i]; int edgeIdx = coarsen_data->nodes2sparse->get(intdual(operation.data.rddata.oldNodeID,otherNode))-1; if(edgeIdx >= 0){ //The edge connectivity has not been updated on this processor coarsen_data->nodes2sparse->remove(intdual(operation.data.rddata.oldNodeID,otherNode)); DEBUGINT(printf("---- Deleting edge %d between nodes %d and %d \n",edgeIdx,operation.data.rddata.oldNodeID,otherNode)); coarsen_data->nodes2sparse->put(intdual(operation.data.rddata.newNodeID,otherNode)) = edgeIdx+1; DEBUGINT(printf("---- Adding edge %d between nodes %d and %d \n",edgeIdx,operation.data.rddata.newNodeID,otherNode)); (*(coarsen_data->sparseConnTable))[edgeIdx][0] = otherNode; (*(coarsen_data->sparseConnTable))[edgeIdx][1] = operation.data.rddata.newNodeID; } } } } }else{ DEBUGINT(printf("[%d] WEIRD -- REPLACE operation for element %d specifies different node number %d \n",CkMyPe(),operation.data.rddata.elemID,operation.data.rddata.oldNodeID)); } }else{ DEBUGINT(printf("[%d] WEIRD -- REPLACE operation for invalid element %d \n",CkMyPe(),operation.data.rddata.elemID)); } DEBUGINT(printf("---------Replace invalidating node %d with %d in element %d\n",operation.data.rddata.oldNodeID,operation.data.rddata.newNodeID,operation.data.rddata.elemID)); break; default: DEBUGINT(printf("[%d] WEIRD -- COARSENDATA type == invalid \n",CkMyPe())); CmiAbort("COARSENDATA type == invalid"); } };