aboutsummaryrefslogtreecommitdiff
path: root/src/AmrUcdGridHierarchy.cc
blob: 479e9ef1e36c76d58334f61cd033793128e17a1b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
#include <stdio.h>
#include <stdlib.h>
#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<nelements;i++) data[i]=(float)((float*)(g.data))[i];
      break;
    case IObase::Float64:
      printf("AmrUcdGridHierarchy:: Original data is double... copy\n");
      for(i=0;i<nelements;i++) data[i]=(float)((double*)(g.data))[i];
      break;
    case IObase::Int32: 
    case IObase::uInt32:
      for(i=0;i<nelements;i++) data[i]=(float)((int*)(g.data))[i];
      break;
    case IObase::Int16:
    case IObase::uInt16:
      for(i=0;i<nelements;i++) data[i]=(float)((short*)(g.data))[i];
      break;
    case IObase::Int8:
    case IObase::uInt8:
    default:
      for(i=0;i<nelements;i++) data[i]=(float)((char*)(g.data))[i];
      break;
    };
  }
  else
    data=0; // danger
  register int i;
  for(i=0;i<3;i++){
    dims[i]=g.dims[i];
    origin[i]=g.origin[i];
    delta[i]=g.delta[i];
  }
  bounds.setFromExtents(g.minext,g.maxext);
  for(i=0,nelements=1;i<rank;i++) nelements*=dims[i];
}

void AmrUcdGridHierarchy::AmrUcdGrid::regenPoints(){
  int i;
  //bounds.setFromOriginDx(origin,delta,dims); // already set from ext
  // should set from extents
  // create points
  points.setSize(nelements);
  points.setSize(nelements);
  // for each point, lets initialize
  long index,dataindex;
  int mindex[3]={0,0,0};
  //----------Node Initialization Cycle-----------------
  printf("AmrUcdGridHierarchy:: dataveclen=%u\n",dataveclen);
  for(index=0,dataindex=0;index<nelements;index++,dataindex+=dataveclen,(mindex[0])++){
    AmrNode *n = points.getData()+index;
    for(i=0;mindex[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;l<grids.getSize();l++){
    AmrUcdGrid *grid;
    FOREACH(grid,grids[l]){
      delete grid;
    }
  }
  grids.purge();
  levelinfo.purge();
}

void AmrUcdGridHierarchy::addGrid(AmrGrid &g){
  if(grids.getSize()<g.level+1)
    grids.setSize(g.level+1);
  AmrUcdGrid *grid,*parent;
  grid = new AmrUcdGrid(g);
  //--------------Grid Parenting Cycle----------------
  if(g.level>0){ // 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;i<levelinfo.getSize();i++){
    grids[i].reset();  // restart
    AmrUcdGrid *g = grids[i].getNext();
    if(g)
      levelinfo[i].setDelta(g->delta);
    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;i<levelinfo.getSize();i++){
    AmrUcdGrid *grid;
    printf("\tL%u\n",i);
    FOREACH(grid,grids[i]){ // level 2 grids should not be here!!!
      // First find offset
      int offset[3]; // we'll skip that for now and assume aligned
      int origin[3]; // origin with respect to parent
      int stride[3]; // just here for convenience
      // now stride through the parent grid doing parenting replacement
      AmrUcdGrid *parent=grid->parent;
      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<AmrNode> *pnodes=&(parent->points);
      FlexArray<AmrNode> *nodes=&(grid->points);
      for(z=0,pz=origin[2];z<grid->dims[2];z+=stride[2],pz++){
	int zi=grid->dims[1]*z;
	int pzi=parent->dims[1]*pz;
	for(y=0,py=origin[1];y<grid->dims[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];x<grid->dims[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;i<levelinfo.getSize();i++){
    AmrUcdGrid *grid;
    printf("Level %u\n",i);
    FOREACH(grid,grids[i]){ // level 2 grids should not be here!!!
      printf("-------------Slice grid %lu ID=%u---------\n",(unsigned long)grid,grid->gridID);
      int x,y,index;
      
      printf("=====: ");
      for(x=0;x<grid->dims[0];x++){
	// print a row
	printf("%5u ",x);
      }
      
      //puts("-----------------------------")
      for(y=0,index=0;y<grid->dims[1];y++,index+=grid->dims[0]){
	printf("\n[%3u]X: ",y);
	for(x=0;x<grid->dims[0];x++){
	  // print a row
	  printf("%5.3f ",grid->points[index+x].location.cartesian.x);
	}
	printf("\n     Y: ");
	for(x=0;x<grid->dims[0];x++){
	  // print a row
	  printf("%5.3f ",grid->points[index+x].location.cartesian.y);
	}	
	printf("\n     Z: ");
	for(x=0;x<grid->dims[0];x++){
	  // print a row
	  printf("%5.3f ",grid->points[index+x].location.cartesian.z);
	}
	printf("\n     P: ");
	for(x=0;x<grid->dims[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;x<grid->dims[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<AmrNode*> &nodes,FlexArray<int> &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;i<levelinfo.getSize();i++){
    AmrUcdGrid *grid;
    FOREACH(grid,grids[i]){
      AmrNode *points=grid->points.getData();
      for(long idx=0;idx<grid->nelements;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;idx<grid->nelements;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;
      }
    }
  }
}