Пример #1
0
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;
}
Пример #2
0
/**
    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);
}
Пример #3
0
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;
}
Пример #4
0
CDECL int 
FEM_Create_simple_field(int base_type, int vec_len)
{
  return IDXL_Layout_create(base_type,vec_len);
}