void FEM_mesh_smooth(int mesh, int *nodes, int nNodes, int attrNo) { vector2d newPos, *coords, *ghostCoords,theCoord; int nNod, nGn, *boundVals, nodesInChunk; int neighbors[3], *adjnodes; int gIdxN; FEM_Mesh *meshP = FEM_Mesh_lookup(mesh, "driver"); nodesInChunk = FEM_Mesh_get_length(mesh,FEM_NODE); boundVals = new int[nodesInChunk]; nGn = FEM_Mesh_get_length(mesh, FEM_GHOST + FEM_NODE); coords = new vector2d[nodesInChunk+nGn]; FEM_Mesh_data(mesh, FEM_NODE, FEM_BOUNDARY, (int*) boundVals, 0, nodesInChunk, FEM_INT, 1); FEM_Mesh_data(mesh, FEM_NODE, attrNo, (double*)coords, 0, nodesInChunk, FEM_DOUBLE, 2); IDXL_Layout_t coord_layout = IDXL_Layout_create(IDXL_DOUBLE, 2); FEM_Update_ghost_field(coord_layout,-1, coords); ghostCoords = &(coords[nodesInChunk]); // FEM_Mesh_data(FEM_Mesh_default_write(), FEM_GHOST+FEM_NODE, attrNo, (double*)ghostCoords, 0, nGn, FEM_DOUBLE, 2); for (int i=0; i<nNodes; i++) { newPos.x=0; newPos.y=0; CkAssert(nodes[i]<nodesInChunk); if (FEM_is_valid(mesh, FEM_NODE, i) && boundVals[i]>-1) //node must be internal { meshP->n2n_getAll(i, &adjnodes, &nNod); // for (int j=0; j<nNod; j++) CkPrintf("node[%d]: %d\n", i,adjnodes[j]); for (int j=0; j<nNod; j++) { //for all adjacent nodes, find coords if (adjnodes[j]<-1) { gIdxN = FEM_From_ghost_index(adjnodes[j]); newPos.x += theCoord.x=ghostCoords[gIdxN].x; newPos.y += theCoord.y=ghostCoords[gIdxN].y; } else { newPos.x += theCoord.x=coords[adjnodes[j]].x; newPos.y += theCoord.y=coords[adjnodes[j]].y; } int rank=FEM_My_partition(); if (rank==0 && i==3 || rank==1 && i==17) { CkPrintf("node[%d]: %d\n", i,adjnodes[j]); CkPrintf("%d: (%f, %f)\n", j, theCoord.x, theCoord.y); } } newPos.x/=nNod; newPos.y/=nNod; FEM_set_entity_coord2(mesh, FEM_NODE, nodes[i], newPos.x, newPos.y); delete [] adjnodes; } } // FEM_Update_field(coord_layout, coords); // FEM_Mesh_data(FEM_Mesh_default_write(), FEM_NODE, attrNo, (double*)coords, 0, nodesInChunk, FEM_DOUBLE, 2); if (coords) delete [] coords; delete [] boundVals; }
/** Based on shared node communication list, compute FEM_NODE FEM_GLOBALNO and FEM_NODE_PRIMARY */ CDECL void FEM_Make_node_globalno(int fem_mesh,FEM_Comm_t comm_context) { const char *caller="FEM_Make_node_globalno"; FEMAPI(caller); FEM_Mesh *m=FEM_Mesh_lookup(fem_mesh,caller); int n, nNo=m->node.size(); const IDXL_Side &shared=m->node.shared; CkVec<int> globalNo(nNo); CkVec<char> nodePrimary(nNo); // Figure out how each of our nodes is shared int nLocal=0; for (n=0;n<nNo;n++) { switch (commState(n,shared)) { case comm_unshared: nodePrimary[n]=0; globalNo[n]=nLocal++; break; case comm_shared: nodePrimary[n]=0; globalNo[n]=-1; // will be filled in during sendsum, below break; case comm_primary: nodePrimary[n]=1; globalNo[n]=nLocal++; break; }; } // Compute global numbers across processors // as the sum of local (unshared and primary) nodes: MPI_Comm comm=(MPI_Comm)comm_context; int firstGlobal=0; // global number of first local element MPI_Scan(&nLocal,&firstGlobal, 1,MPI_INT, MPI_SUM,comm); firstGlobal-=nLocal; /* sum of all locals before me, but *not* including */ for (n=0;n<nNo;n++) { if (globalNo[n]==-1) globalNo[n]=0; else globalNo[n]+=firstGlobal; } // Get globalNo for shared nodes, by copying from primary. IDXL_Layout_t l=IDXL_Layout_create(IDXL_INT,1); IDXL_Comm_t c=IDXL_Comm_begin(72173841,comm_context); IDXL_Comm_sendsum(c,FEM_Comm_shared(fem_mesh,FEM_NODE),l,&globalNo[0]); IDXL_Comm_wait(c); IDXL_Layout_destroy(l); // Copy globalNo and primary into fem FEM_Mesh_set_data(fem_mesh,FEM_NODE, FEM_GLOBALNO, &globalNo[0], 0,nNo, FEM_INDEX_0,1); FEM_Mesh_set_data(fem_mesh,FEM_NODE, FEM_NODE_PRIMARY, &nodePrimary[0], 0,nNo, FEM_BYTE,1); }
void FEM_mesh_smooth(int mesh, int *nodes, int nNodes, int attrNo) { vector3d *centroids, newPos, *coords, *ghostCoords, *vGcoords; int nEle, nGn, *boundVals, nodesInChunk, nVg; int neighbors[3], *adjelems; int gIdxN; int j=0; double x[3], y[3]; FEM_Mesh *meshP = FEM_Mesh_lookup(mesh, "driver"); nodesInChunk = FEM_Mesh_get_length(mesh,FEM_NODE); boundVals = new int[nodesInChunk]; nGn = FEM_Mesh_get_length(mesh, FEM_GHOST + FEM_NODE); coords = new vector3d[nodesInChunk+nGn]; FEM_Mesh_data(mesh, FEM_NODE, FEM_BOUNDARY, (int*) boundVals, 0, nodesInChunk, FEM_INT, 1); FEM_Mesh_data(mesh, FEM_NODE, attrNo, (double*)coords, 0, nodesInChunk, FEM_DOUBLE, 2); for (int i=0; i<(nodesInChunk); i++) { //CkPrintf(" coords[%d]: (%f, %f)\n", i, coords[i].x, coords[i].y); } IDXL_Layout_t coord_layout = IDXL_Layout_create(IDXL_DOUBLE, 2); FEM_Update_ghost_field(coord_layout,-1, coords); ghostCoords = &(coords[nodesInChunk]); /* for (int i=0; i<nGn;i++) { if (FEM_is_valid(mesh, FEM_GHOST+FEM_NODE, i)) { CkPrintf("ghost %d is valid \n", i); // vGcoords[j]=ghostCoords[i]; //j++; } else CkPrintf("ghost %d is invalid \n", i); } */ for (int i=0; i<(nodesInChunk+nGn); i++) { //CkPrintf(" coords[%d]: (%f, %f)\n", i, coords[i].x, coords[i].y); } // FEM_Mesh_data(FEM_Mesh_default_write(), FEM_GHOST+FEM_NODE, attrNo, (double*)ghostCoords, 0, nGn, FEM_DOUBLE, 2); for (int i=0; i<nNodes; i++) { newPos.x=0; newPos.y=0; CkAssert(nodes[i]<nodesInChunk); if (FEM_is_valid(mesh, FEM_NODE, i) && boundVals[i]>-1) //node must be internal { meshP->n2e_getAll(i, &adjelems, &nEle); centroids = new vector3d[nEle]; for (int j=0; j<nEle; j++) { //for all adjacent elements, find centroids meshP->e2n_getAll(adjelems[j], neighbors); for (int k=0; k<3; k++) { if (neighbors[k]<-1) { gIdxN = FEM_From_ghost_index(neighbors[k]); x[k] = ghostCoords[gIdxN].x; y[k] = ghostCoords[gIdxN].y; } else { x[k] = coords[neighbors[k]].x; y[k] = coords[neighbors[k]].y; } } centroids[j].x=(x[0]+x[1]+x[2])/3.0; centroids[j].y=(y[0]+y[1]+y[2])/3.0; newPos.x += centroids[j].x; newPos.y += centroids[j].y; } newPos.x/=nEle; newPos.y/=nEle; FEM_set_entity_coord2(mesh, FEM_NODE, nodes[i], newPos.x, newPos.y); delete [] centroids; delete [] adjelems; } } delete [] coords; delete [] boundVals; }
CDECL int FEM_Create_simple_field(int base_type, int vec_len) { return IDXL_Layout_create(base_type,vec_len); }