#include #include #include "AmrUcdGridHierarchy.hh" void AmrUcdGridHierarchy::AmrUcdGrid::copyFromAmrGrid(AmrGrid &g){ level = g.level; dataveclen=g.dataveclen; rank = g.rank; datatype = IObase::Int2DataType(g.datatype); // Perhaps should do floating point only vdata = g.data; // copy to float datatype printf("AmrUcdGridHierarchy:: dataveclen=%u\n",dataveclen); if(g.data){ int nelements = IObase::nElements(g.rank,g.dims); register int i; //if(datatype!=IObase::Float32) data = new float[nelements]; switch(datatype){ case IObase::Float32: printf("AmrUcdGridHierarchy:: Original data is float use directly\n"); printf("\tpointerbase=%lu last=%lu\n",data,(data+nelements)); //data=(float*)g.data; for(i=0;i=dims[i] && i<2;i++){ mindex[i]=0; (mindex[i+1])++; } // assign using correct type (could put outside of loop to optimize) n->data = data+dataindex; n->level = level; // semiredunant, but necessary for AVS /* if(datatype==IObase::Float32) n->fdata=fdata+dataindex; else if(IObase::Float64) n->ddata=ddata+dataindex; else if(IObase::Int32 || IObase::uInt32) n->idata=idata+dataindex; else if(IObase::Int16 || IObase::uInt16) n->sdata=sdata+dataindex; else if(IObase::Int8 || IObase::uInt8) n->cdata=cdata+dataindex; */ n->child=n->parent=0; // for now (will fix this up later) n->index=-1; // nil index for now n->gridID = gridID; for(i=0;i<3;i++) n->location.array[i] = origin[i] + delta[i]*(double)(mindex[i]); // assumes f77 order for arrays } } AmrUcdGridHierarchy::~AmrUcdGridHierarchy() { purge(); } void AmrUcdGridHierarchy::purge(){ for(int l=0;l0){ // make grid hierarchy (eg. assign parents) (perhaps doubly-link) // compare the bounding box to all grids in parent level FOREACH(parent,grids[g.level-1]){ // OrderedList needs copy constructor if(parent->bounds.contains(grid->bounds)){ // compared grid->parent=parent; parent->children.append(grid);// do forward ref break; } } } grids[g.level].add(grid); } void AmrUcdGridHierarchy::buildNodeHierarchy(){ int i; levelinfo.setSize(grids.getSize()); for(i=0;idelta); else{ double fakedelta[5]={1,1,1,1,1}; printf("AmrUcdGridHierarchy::buildNodeHierarchy(): Using Fake delta for level %u (shouldn't do that)\n",i); levelinfo[i].setDelta(fakedelta); } } for(i=0;i<(levelinfo.getSize()-1);i++) levelinfo[i].setStride(levelinfo[i+1].delta); // cycle through each level and find parent nodes for each node //-------------Node Parenting Cycle---------------------------- puts("node parenting cycle"); for(i=1;iparent; if(!parent) continue; // failsafe for NULL parent // stride through the parent doing replacement // first compute the strides through the parent grid // as well as the origin in parent coordinates for(int j=0;j<3;j++){ register double dp=parent->origin[j]; register double dc=grid->origin[j]; register double dx=dc-dp; // difference between origins dx /= parent->delta[j]; // if diff > .5 then use it? if(j==0) printf("dparent=%lf dchild=%lf dx=%lf\n",dp,dc,dx); // (no just need to round it) origin[j]=(int)(dx+0.5); // this is a marginally bogus way to round up. stride[j]=levelinfo[i-1].childstride[j]; } printf("NodeParenting L%u: origin=%u:%u:%u stride=%u\n",i,origin[0],origin[1],origin[2],stride[0]); int px,x,py,y,pz,z; // typedef DATATYPE AmrNode; FlexArray *pnodes=&(parent->points); FlexArray *nodes=&(grid->points); for(z=0,pz=origin[2];zdims[2];z+=stride[2],pz++){ int zi=grid->dims[1]*z; int pzi=parent->dims[1]*pz; for(y=0,py=origin[1];ydims[1];y+=stride[1],py++){ int yi=(zi+y)*grid->dims[0]; int pyi=(pzi+py)*parent->dims[0]; for(x=0,px=origin[0];xdims[0];x+=stride[0],px++){ register int pindex=px+pyi; register int cindex=x+yi; // ugh! finally we get to assign parents to the nodes (*pnodes)[pindex].child=&((*nodes)[cindex]); (*nodes)[cindex].parent=&((*pnodes)[pindex]); } } } } } } void AmrUcdGridHierarchy::print(){ // ************Print Some Results*********************** for(int i=0;igridID); int x,y,index; printf("=====: "); for(x=0;xdims[0];x++){ // print a row printf("%5u ",x); } //puts("-----------------------------") for(y=0,index=0;ydims[1];y++,index+=grid->dims[0]){ printf("\n[%3u]X: ",y); for(x=0;xdims[0];x++){ // print a row printf("%5.3f ",grid->points[index+x].location.cartesian.x); } printf("\n Y: "); for(x=0;xdims[0];x++){ // print a row printf("%5.3f ",grid->points[index+x].location.cartesian.y); } printf("\n Z: "); for(x=0;xdims[0];x++){ // print a row printf("%5.3f ",grid->points[index+x].location.cartesian.z); } printf("\n P: "); for(x=0;xdims[0];x++){ if(grid->points[index+x].parent) printf("%5u ",grid->points[index+x].parent->gridID); else printf("None "); } printf("\n C: "); for(x=0;xdims[0];x++){ if(grid->points[index+x].child) printf("%5u ",grid->points[index+x].child->gridID); else printf(" None "); } } printf("\n"); } } } void AmrUcdGridHierarchy::buildUCD(FlexArray &nodes,FlexArray &cells){ // OK, first build pointlist by adding only cells without children // for each one added to list, set its index member // also set index for all parents recursively. (have recursive setindex in // as a static member function of each node) int ctr,i; // **** Init all node indexes to -1 printf("AmrUcdGridHierarchy::buildUCD(): Initialize UCD\n"); for(i=0;ipoints.getData(); for(long idx=0;idxnelements;idx++) points[i].index=-1; } } // print(); // **** Top-down assignment of indices for each node without child // If a node has a child, then the child will be superceding it // for indices printf("\ttop-down assign indices\n"); for(i=levelinfo.getSize()-1;i>=0;--i){ printf("\tLevel[%u]\n",i); AmrUcdGrid *grid; FOREACH(grid,grids[i]){ AmrNode *points=grid->points.getData(); for(long idx=0;idxnelements;idx++){ if(!points[idx].child){ // if no child // then assign unique index points[idx].setIndex(nodes.getSize()); nodes.append(points+idx); // append to nodelist } } } } printf("Number of nodes in all = %u\n",nodes.getSize()); // OK, nows the time in schprockets when we dance... // **** Top-down building of Hexahedral cells //printf("now build hexahedral cells\n"); for(i=levelinfo.getSize()-1;i>=0;i--){ printf("\tL%u\n",i); AmrUcdGrid *grid; int nodeindices[8],mapped[8]; FOREACH(grid,grids[i]){ AmrNode *points=grid->points.getData(); // verify that at least one point doesn't have a child // if all have children then continue int x,y,z; int *dims=grid->dims; int zstep=dims[1]*dims[0]; int ystep=dims[0]; // xstep=1 int idx; // setup the cell indices for(idx=0;idx<8;idx++){ nodeindices[idx]=0; } for(idx=0;idx<4;idx++) { nodeindices[idx]+=zstep; } for(idx=0;idx<=4;idx+=4){ nodeindices[idx+2]+=1; nodeindices[idx+3]+=1; nodeindices[idx]+=ystep; nodeindices[idx+3]+=ystep; } // ***** Build the Cell list for(z=0;z<(dims[2]-1);z++){ //printf("\t\tZ%u\n",z); for(y=0;y<(dims[1]-1);y++){ for(x=0;x<(dims[0]-1);x++){ // OK, now we find the real indices and for(idx=0;idx<8;idx++){ mapped[idx]=points[nodeindices[idx]].index; if(mapped[idx]>nodes.getSize()){ printf("indexing error at grid %u, position %u,%u,%u idx[%u]=%u\n", grid->gridID,x,y,z,idx,mapped[idx]); } } // append to cells list cells.append(mapped,8); // copies the mapped array? // now we save this sequence; for(idx=0;idx<8;idx++) (nodeindices[idx])++; } for(idx=0;idx<8;idx++) (nodeindices[idx])++; } for(idx=0;idx<8;idx++) (nodeindices[idx])+=ystep; } } } }