Ejemplo n.º 1
0
/** Fill the node to element adjacency table for both 
    this element and its corresponding ghosts
 */
void FEM_Node::setElemAdjacency(int type, const FEM_Elem &elem){
	int nodesPerElem = elem.getNodesPer();
	FEM_VarIndexAttribute *adjacencyAttr = elemAdjacency;
	CkVec<CkVec<ElemID> > &adjacencyTable = elemAdjacency->get();
	FEM_VarIndexAttribute *ghostAdjacencyAttr = ((FEM_Node *)getGhost())->elemAdjacency;
	CkVec<CkVec<ElemID> > &ghostAdjacencyTable = ghostAdjacencyAttr->get();

	// Scan through elements
	for(int i=0;i<elem.size();i++){
	  const int *conn = elem.connFor(i);
	  for(int j=0;j<nodesPerElem;j++){
		int node = conn[j];
		if (node!=-1){
		  if(FEM_Is_ghost_index(node)){
			int idx = ghostAdjacencyAttr->findInRow(FEM_To_ghost_index(node),var_id(type,i));
			if(idx == -1) {// If not currently in the adjacency list, push onto list
			  ghostAdjacencyTable[FEM_To_ghost_index(node)].push_back(var_id(type,i));
			}
		  }
		  else{
			int idx = adjacencyAttr->findInRow(node,var_id(type,i));
			if(idx == -1) {// If not currently in the adjacency list, push onto list
			  adjacencyTable[node].push_back(var_id(type,i));
			}
		  }
		}
	  }
	}
	
	// Scan through ghost elements
	if(elem.getGhost()){
	  for(int i=0;i<((FEM_Elem*)elem.getGhost())->size();i++){
		const int *conn = ((FEM_Elem*)elem.getGhost())->connFor(i);
		for(int j=0;j<nodesPerElem;j++){
		  int node = conn[j];
		  if (node!=-1){
			if(FEM_Is_ghost_index(node)){
			  int idx = ghostAdjacencyAttr->findInRow(FEM_To_ghost_index(node),var_id(type,FEM_From_ghost_index(i)));
			  if(idx == -1){ // If not currently in the adjacency list, push onto list
				ghostAdjacencyTable[FEM_To_ghost_index(node)].push_back(var_id(type,FEM_From_ghost_index(i)));
			  }
			}
			
			else{
			  int idx = adjacencyAttr->findInRow(node,var_id(type,FEM_From_ghost_index(i)));
			  if(idx == -1){// If not currently in the adjacency list, push onto list
				adjacencyTable[node].push_back(var_id(type,FEM_From_ghost_index(i)));
			  }
			}
		  }
		}
	  }
	}
}
Ejemplo n.º 2
0
/** Finds oldElem in n's element adjacency list, and replaces it with newElem
 */
void FEM_Mesh::n2e_replace(int n, int oldElem, int newElem) 
{
  if (n == -1) return;
  if(FEM_Is_ghost_index(n)){
	FEM_VarIndexAttribute *eAdj = (FEM_VarIndexAttribute *)node.getGhost()->lookup(FEM_NODE_ELEM_ADJACENCY,"n2e_replace");
	CkVec<CkVec<ElemID> > &eVec = eAdj->get();
	CkVec<ElemID> &nsVec = eVec[FEM_To_ghost_index(n)];
	for (int i=0; i<nsVec.length(); i++) {
	  if (nsVec[i].getSignedId() == oldElem) {
		nsVec[i] = ElemID(0,newElem);
		break;
	  }
	}
	int *testn2e, testn2ec;
	n2e_getAll(n,testn2e,testn2ec);
	for(int i=0; i<testn2ec; i++) {
	  if(FEM_Is_ghost_index(testn2e[i]))
	    CkAssert(elem[0].ghost->is_valid(FEM_From_ghost_index(testn2e[i])));
	  else 
	    CkAssert(elem[0].is_valid(testn2e[i]));
	}
	if(testn2ec!=0) delete[] testn2e;
  }
  else{
	FEM_VarIndexAttribute *eAdj = (FEM_VarIndexAttribute *)node.lookup(FEM_NODE_ELEM_ADJACENCY,"n2e_replace");
	CkVec<CkVec<ElemID> > &eVec = eAdj->get();
	CkVec<ElemID> &nsVec = eVec[n];
	for (int i=0; i<nsVec.length(); i++) {
	  if (nsVec[i].getSignedId() == oldElem) {
		nsVec[i] = ElemID(0,newElem);
		break;
	  }
	}
  }
}
Ejemplo n.º 3
0
/** Adds newElem to node n's element adjacency list
 */
void FEM_Mesh::n2e_add(int n, int newElem) 
{
  if (n == -1) return;
  if(FEM_Is_ghost_index(n)){
	FEM_VarIndexAttribute *eAdj = (FEM_VarIndexAttribute *)node.getGhost()->lookup(FEM_NODE_ELEM_ADJACENCY,"n2e_add");     
	CkVec<CkVec<ElemID> > &eVec = eAdj->get();
	CkVec<ElemID> &nsVec = eVec[FEM_To_ghost_index(n)];
	ElemID ne(0, newElem);
	nsVec.push_back(ne);
	int *testn2e, testn2ec;
	n2e_getAll(n,testn2e,testn2ec);
	for(int i=0; i<testn2ec; i++) {
	  if(FEM_Is_ghost_index(testn2e[i]))
	    CkAssert(elem[0].ghost->is_valid(FEM_From_ghost_index(testn2e[i])));
	  else 
	    CkAssert(elem[0].is_valid(testn2e[i]));
	}
	if(testn2ec!=0) delete[] testn2e;
  }
  else {
	FEM_VarIndexAttribute *eAdj = (FEM_VarIndexAttribute *)node.lookup(FEM_NODE_ELEM_ADJACENCY,"n2e_add");     
	CkVec<CkVec<ElemID> > &eVec = eAdj->get();
	CkVec<ElemID> &nsVec = eVec[n];
	ElemID ne(0, newElem);
	nsVec.push_back(ne);
  }
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
/** createElemElemAdj() is similar to splitter::addTuple()
 * It will scan through all tuples/faces for each element
 * and register them with a tupleTable which will find 
 * matching tuples between different elements. The matches  
 * are then extracted from the table and the resulting
 * adjacencies are marked in the FEM_ELEM_ELEM_ADJACENCY
 * and FEM_ELEM_ELEM_ADJ_TYPES attribute fields. The attributes
 * store the adjacent element's local id and type respectively.
 * The ordering in the attribute tables is by local element id,
 * as usual, and is then ordered by the tuple ordering specified
 * in the last parameter to FEM_Add_elem2face_tuples, which 
 * gets stored in the FEM_ElemAdj_Layer data structure
 * created/returned by getElemAdjLayer().
 *
 * The element id's are NOT indices into the conn array in 
 * the case of ghost elements. Ghost elements will have the
 * same element type as their corresponding real elements.
 * Their id, which gets stored in FEM_ELEM_ELEM_ADJACENCY
 * will be a negative number which can be converted to an index
 * with FEM_To_ghost_index(). Thus the user MUST use 
 * FEM_Is_ghost_index(i) on the values, before accessing 
 * them in the conn array, especially since the ghosts
 * will have a negative id.
 *
 * The function assumes that the FEM_ELEM_ELEM_ADJACENCY
 * and FEM_ELEM_ELEM_ADJ_TYPES attribute fields already exist.
 *
 * TODO:
 *  
 *   Verify the tuple table does not need to be 
 *   explicitly deleted.
 */
void FEM_Mesh::createElemElemAdj()
{
    //CkPrintf("createElemElemAdj()\n");
	
  FEM_ElemAdj_Layer *g = getElemAdjLayer();
  if(! g->initialized)
	CkAbort("FEM> Cannot call FEM_Mesh_create_elem_elem_adjacency() before registering tuples with FEM_Add_elem2face_tuples()\n");

  
  int nodesPerTuple = g->nodesPerTuple;
  tupleTable table(nodesPerTuple);

  // Put tuples into table
  for (int t=0;t<elem.size();t++){ // for each element type
	  if(elem.hasNonEmpty(t)) {
		  const int tuplesPerElem = g->elem[t].tuplesPerElem;
		  const int numElements = elem[t].size();
		  // for every element of  type t:
		  for (int elemIndex=0;elemIndex<numElements;elemIndex++)	{
			  // insert element into the tuple table
			  const int *conn=elem[t].connFor(elemIndex);
			  int tuple[tupleTable::MAX_TUPLE];
			  FEM_Symmetries_t allSym;
			  // copy node numbers into tuple
			  for (int u=0;u<tuplesPerElem;u++) {
				  for (int i=0;i<nodesPerTuple;i++) {
					  int eidx=g->elem[t].elem2tuple[i+u*g->nodesPerTuple];
					  if (eidx==-1)    // "not-there" node
						  tuple[i]=-1;   // Don't map via connectivity
					  else             // Ordinary node
						  tuple[i]=conn[eidx]; 
				  }
				  // add tuple to table
				  table.addTuple(tuple,new elemList(0,elemIndex,t,allSym,u)); 
			  }
		  }

		  // Put corresponding ghost elements into tuple table
		  if(elem[t].getGhost() != NULL){
			  FEM_Elem *ghostElem = (FEM_Elem *)elem[t].getGhost();
			  const int numElements = ghostElem->size();
			  // for every element of  type t:
			  for (int elemIndex=0;elemIndex<numElements;elemIndex++)	{
				  // insert element into the tuple table
				  const int *conn=ghostElem->connFor(elemIndex);
				  int tuple[tupleTable::MAX_TUPLE];
				  FEM_Symmetries_t allSym;
				  // copy node numbers into tuple
				  for (int u=0;u<tuplesPerElem;u++) {
					  for (int i=0;i<nodesPerTuple;i++) {

						  int eidx=g->elem[t].elem2tuple[i+u*g->nodesPerTuple];
						  if (eidx==-1) { //"not-there" node--
							  tuple[i]=-1; //Don't map via connectivity
						  } else { //Ordinary node
							  int n=conn[eidx];
							  tuple[i]=n; 
						  }
					  }
					  // add tuple to table
					  table.addTuple(tuple,new elemList(0,FEM_From_ghost_index(elemIndex),t,allSym,u)); 
				  }
			  }
		  }
	  }
  }

  /* Extract adjacencies from table and store into 
   * FEM_ELEM_ELEM_ADJACENCY and FEM_ELEM_ELEM_ADJ_TYPES 
   * attribute fields
   */
  for (int t=0;t<elem.size();t++) { // for each element type t
	  if (elem.hasNonEmpty(t)) {
		  elemList *l;
		  const int tuplesPerElem = g->elem[t].tuplesPerElem;
		  const int numElements = elem[t].size();
		  const int numGhostElements = ((FEM_Elem*)(elem[t].getGhost()))->size();

		  // directly modify the element adjacency table for element type t
		  FEM_IndexAttribute *elemAdjTypesAttr = (FEM_IndexAttribute *)elem[t].lookup(FEM_ELEM_ELEM_ADJ_TYPES,"createElemElemAdj");
		  FEM_IndexAttribute *elemAdjAttr = (FEM_IndexAttribute *)elem[t].lookup(FEM_ELEM_ELEM_ADJACENCY,"createElemElemAdj");
		  FEM_IndexAttribute *elemAdjTypesAttrGhost = (FEM_IndexAttribute *)elem[t].getGhost()->lookup(FEM_ELEM_ELEM_ADJ_TYPES,"createElemElemAdj");
		  FEM_IndexAttribute *elemAdjAttrGhost = (FEM_IndexAttribute *)elem[t].getGhost()->lookup(FEM_ELEM_ELEM_ADJACENCY,"createElemElemAdj");
		  CkAssert(elemAdjTypesAttr && elemAdjAttr);

		  AllocTable2d<int> &adjTable = elemAdjAttr->get();
		  int *adjs = adjTable.getData();
		  AllocTable2d<int> &adjTypesTable = elemAdjTypesAttr->get();
		  int *adjTypes = adjTypesTable.getData();

		  AllocTable2d<int> &adjTableGhost = elemAdjAttrGhost->get();
		  int *adjsGhost = adjTableGhost.getData();
		  AllocTable2d<int> &adjTypesTableGhost = elemAdjTypesAttrGhost->get();
		  int *adjTypesGhost = adjTypesTableGhost.getData();

		  // initialize tables
		  for(int i=0;i<numElements*tuplesPerElem;i++){
			  adjs[i]=-1;
			  adjTypes[i]=-1;
		  }
		  for(int i=0;i<numGhostElements*tuplesPerElem;i++){
			  adjsGhost[i]=-1;
			  adjTypesGhost[i]=-1;
		  }

		  // look through each elemList that is returned by the tuple table
		  table.beginLookup();
		  while (NULL!=(l=table.lookupNext())) {
			  if (l->next==NULL) { 
				  // One-entry list: must be a symmetry
				  // UNHANDLED CASE: not sure exactly what this means
			  }
			  else { /* Several elements in list: normal case */
				  //CkPrintf("Found in table list: ");
				  //for(const elemList *c=l;c!=NULL;c=c->next){
                                  //	  CkPrintf("     %d,%d", c->type, c->localNo);
				  //}
				  //CkPrintf("\n");
				  
				  // for each a,b from the list
				  for (const elemList *a=l;a!=NULL;a=a->next){
					  for (const elemList *b=l;b!=NULL;b=b->next){
						  // if a and b are different elements
						  if((a->localNo != b->localNo) || (a->type != b->type)){
							  int j;
							  
							  if(a->type == t){ // only update the entries for element type t
								  if(FEM_Is_ghost_index(a->localNo)){
									  j = FEM_To_ghost_index(a->localNo)*tuplesPerElem + a->tupleNo;
									  CkAssert(j<numGhostElements*tuplesPerElem);
									  adjsGhost[j] = b->localNo;
									  adjTypesGhost[j] = b->type;
								  }
								  else {
									  j = a->localNo*tuplesPerElem + a->tupleNo;
									  CkAssert(j<numElements*tuplesPerElem);
									  //CkPrintf("Recording that %d,%d at position %d has neighbor %d,%d \n", a->type,a->localNo, a->tupleNo, b->type, b->localNo);
									  adjs[j] = b->localNo;
									  adjTypes[j] = b->type;
								  }
							  }
						  }
					  }
				  }
			  }
		  }
	  }
  }
}
Ejemplo n.º 6
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;
}