Blockstructured Adaptive Mesh Refinement in object-oriented C++
00001 00007 #include "DAGH.h" 00008 #include "values.h" 00009 00010 #ifdef __KCC 00011 template class GridData(2)<short>; 00012 template class GridData(3)<short>; 00013 template class GridData(1)<int>; 00014 #endif 00015 00016 #define MAXPOINTS (10000) 00017 #define MAXPOINTS2 (100000000) 00018 #define MIN_EFFICIENCY (0.4) 00019 #define MINOFF (4) 00020 #define ITHRES (2) 00021 00028 void Cluster_Prune(GridData(1)<int> &sig, int& pl, int& pu, int bw) { 00029 BeginFastIndex1(sig, sig.bbox(), sig.data(), int); 00030 pl = sig.bbox().lower(0); 00031 pu = sig.bbox().upper(0); 00032 if (pu - pl < bw) { 00033 return; 00034 } 00035 while (FastIndex1(sig,pl) == 0 && pl < sig.bbox().upper(0)) 00036 pl += sig.bbox().stepsize(0); 00037 while (FastIndex1(sig,pu) == 0 && pu > sig.bbox().lower(0)) 00038 pu -= sig.bbox().stepsize(0); 00039 if (pu+sig.bbox().stepsize(0)-pl < bw) { 00040 int diff = bw - (pu+sig.bbox().stepsize(0)-pl); 00041 int addl, addu; 00042 int udist = sig.bbox().upper(0) - pu; 00043 int ldist = pl - sig.bbox().lower(0); 00044 00045 addl = ((diff/sig.bbox().stepsize(0))/2) * sig.bbox().stepsize(0); 00046 addu = diff - addl; 00047 if (addu > udist) { 00048 addu = udist; 00049 addl = diff - addu; 00050 } 00051 if (addl > ldist) { 00052 addl = ldist; 00053 addu = diff - addu; 00054 } 00055 00056 pu += addu; 00057 pl -= addl; 00058 } 00059 EndFastIndex1(sig); 00060 } 00061 00069 void Cluster_Slice(GridData(1)<int> &sig, int& slice, int& str, int bw) { 00070 int i, l, u, s, t, a; // ctr, low, up, step, str, answer 00071 l = sig.bbox().lower(0); 00072 u = sig.bbox().upper(0); 00073 s = sig.bbox().stepsize(0); 00074 00075 /* Since this box is already pruned, we don't want to split it if 00076 it is less than 2 the min width */ 00077 if (u+s-l < 2*bw) { 00078 str = -1; 00079 slice = -1; 00080 return; 00081 } 00082 00083 GridData(1)<int> lap(l,u,s); 00084 00085 BeginFastIndex1(sig, sig.bbox(), sig.data(), int); 00086 BeginFastIndex1(lap, lap.bbox(), lap.data(), int); 00087 00088 t = -1; 00089 a = -1; 00090 00091 /* Look for a zero near the center */ 00092 for (i=l+bw-s;i<=u-bw;i+=s) { 00093 if (FastIndex1(sig,i) == 0) { 00094 int di = (i-l < u-i ? i-l : u-i); 00095 if (di > t) { 00096 a = i; 00097 t = di; 00098 } 00099 } 00100 } 00101 if (a != -1) { 00102 slice = a; 00103 str = 2*MAXPOINTS2+t; 00104 return; 00105 } 00106 00107 /* Evaluate the laplacian etc */ 00108 int malap = 0; 00109 for (i=l+s; i<=u-s; i+=s) { 00110 lap(i) = FastIndex1(sig,i+s) + FastIndex1(sig,i-s) - 2*FastIndex1(sig,i); 00111 int alap = (FastIndex1(lap,i)>0 ? FastIndex1(lap,i) : -FastIndex1(lap,i)); 00112 if (alap > malap) malap = alap; 00113 } 00114 00115 t = -1; 00116 a = -1; 00117 00118 /* And find the strongest second derivative */ 00119 int tts = -1; 00120 if (malap > 0) { 00121 int ms = Max(MINOFF*s,bw); 00122 for (i=l+ms-s; i<=u-ms; i+=s) 00123 if (FastIndex1(lap,i-s)*FastIndex1(lap,i) < 0) { 00124 int ts = ((FastIndex1(lap,i-s)-FastIndex1(lap,i))>0 ? 00125 FastIndex1(lap,i-s)-FastIndex1(lap,i) : 00126 -(FastIndex1(lap,i-s)-FastIndex1(lap,i))); 00127 int di = (i-l < u-i ? i-l : u-i); 00128 if (ts==tts && di>t) { 00129 a = i; 00130 t = di; 00131 } 00132 if (ts>tts) { 00133 tts = ts; 00134 a = i; 00135 t = di; 00136 } 00137 } 00138 if (a!=-1 && tts>=ITHRES) 00139 t = MAXPOINTS2+tts*MAXPOINTS+t; 00140 } 00141 00142 /* Use bisection if no slice has been found */ 00143 if (a==-1 || tts<ITHRES) { 00144 t = (sig.size()/2)*s-s; 00145 a = l+t; 00146 } 00147 EndFastIndex1(sig); 00148 EndFastIndex1(lap); 00149 00150 slice = a; 00151 str = t; 00152 } 00153 00166 void Cluster3R(GridData(3)<short> &flag, 00167 const BBox& flagbbox, 00168 double Efficiency, 00169 int MinWidth, 00170 int MaxWidth, 00171 BBoxList &recurseOnThis) { 00172 BBoxList result, tmpresult; 00173 int l[3], u[3], s[3]; 00174 int i; 00175 for (i=0;i<3;i++) s[i] = flagbbox.stepsize(i); 00176 if (MaxWidth<2*MinWidth) MaxWidth=MAXINT; 00177 00178 //cout << "Clustering " << flagbbox <<"\n"; 00179 //cout.flush(); 00180 00181 /* Declare and fill in Signature Planes in each direction */ 00182 Array(1)<int> i_sig(flagbbox.lower(0), 00183 flagbbox.upper(0), 00184 flagbbox.stepsize(0)); 00185 Array(1)<int> j_sig(flagbbox.lower(1), 00186 flagbbox.upper(1), 00187 flagbbox.stepsize(1)); 00188 Array(1)<int> k_sig(flagbbox.lower(2), 00189 flagbbox.upper(2), 00190 flagbbox.stepsize(2)); 00191 i_sig = 0; 00192 j_sig = 0; 00193 k_sig = 0; 00194 BeginFastIndex3(flag, flag.bbox(), flag.data(), short); 00195 BeginFastIndex1(i_sig, i_sig.bbox(), i_sig.data(), int); 00196 BeginFastIndex1(j_sig, j_sig.bbox(), j_sig.data(), int); 00197 BeginFastIndex1(k_sig, k_sig.bbox(), k_sig.data(), int); 00198 00199 int flagged = 0; 00200 for_3(ii, jj, kk, flagbbox, flagbbox.stepsize()) 00201 if (FastIndex3(flag,ii,jj,kk)>0) { 00202 FastIndex1(i_sig,ii)++; 00203 FastIndex1(j_sig,jj)++; 00204 FastIndex1(k_sig,kk)++; 00205 flagged++; 00206 } 00207 end_for; 00208 00209 /* Check for pruning */ 00210 int ipl, ipu, jpl, jpu, kpl, kpu; 00211 Cluster_Prune(i_sig,ipl,ipu,MinWidth*s[0]); 00212 Cluster_Prune(j_sig,jpl,jpu,MinWidth*s[1]); 00213 Cluster_Prune(k_sig,kpl,kpu,MinWidth*s[2]); 00214 00215 Coords pl(3,ipl,jpl,kpl); 00216 Coords pu(3,ipu,jpu,kpu); 00217 00218 if (! ((pl == flagbbox.lower()) && 00219 (pu == flagbbox.upper()))) { 00220 Coords ps = Coords(3,s); 00221 BBox newB(pl,pu,ps); 00222 // cout <<" PRUNE :" << newB <<"\n"; 00223 // cout.flush(); 00224 /* Check my efficiency! */ 00225 flagged = 0; 00226 for_3(ii, jj, kk, newB, newB.stepsize()) 00227 if (FastIndex3(flag,ii,jj,kk)>0) flagged++; 00228 end_for 00229 if (((double)flagged / (double)newB.size()) >= Efficiency && 00230 Max(Max(newB.extents(0),newB.extents(1)),newB.extents(2)) <= MaxWidth) { 00231 recurseOnThis.add(newB); 00232 return; 00233 } else { 00234 Cluster3R(flag,newB,Efficiency,MinWidth,MaxWidth,recurseOnThis); 00235 return; 00236 } 00237 } 00238 00239 /* Find the slice positions */ 00240 int istr=-1, jstr=-1, kstr=-1; 00241 int islice=-1, jslice=-1, kslice=-1; 00242 Cluster_Slice(i_sig,islice,istr,MinWidth*s[0]); 00243 Cluster_Slice(j_sig,jslice,jstr,MinWidth*s[1]); 00244 Cluster_Slice(k_sig,kslice,kstr,MinWidth*s[2]); 00245 00246 // cout << "SLICE:"<<islice<<" "<<jslice<<" "<<kslice<<"\n"; 00247 // cout << "STR :"<<istr<<" "<<jstr<<" "<<kstr<<"\n"; 00248 // cout.flush(); 00249 00250 /* Don't split small grids. */ 00251 /* Bisectioning down to the minimum can occur, if a grid does not have any */ 00252 /* zero signature and the strength of its laplacian is lower than ITHRES. */ 00253 /* We accept this grid, if its efficiency is greater than MIN_EFFICIENCY. */ 00254 if ((islice+jslice+kslice==-3) || 00255 (istr<MAXPOINTS2 && jstr<MAXPOINTS2 && kstr<MAXPOINTS2 && 00256 (double)flagged/(double)flagbbox.size()>MIN_EFFICIENCY && 00257 Max(Max(flagbbox.extents(0),flagbbox.extents(1)),flagbbox.extents(2)) 00258 <= MaxWidth)) { 00259 // cout << "RETURNING " << flagbbox << endl << flush; 00260 recurseOnThis.add(flagbbox); 00261 return; 00262 } 00263 00264 /* Split along the line with the biggest strength */ 00265 BBox divme = flagbbox; 00266 if (istr > jstr && istr > kstr) { 00267 l[0] = divme.lower(0); l[1]= divme.lower(1); l[2] = divme.lower(2); 00268 u[0] = islice; u[1]= divme.upper(1); u[2] = divme.upper(2); 00269 tmpresult.add(BBox(3,l,u,s)); 00270 l[0] = islice+s[0]; l[1]= divme.lower(1); l[2] = divme.lower(2); 00271 u[0] = divme.upper(0); u[1]= divme.upper(1); u[2] = divme.upper(2); 00272 tmpresult.add(BBox(3,l,u,s)); 00273 } else if (jstr > kstr) { 00274 l[0] = divme.lower(0); l[1]= divme.lower(1); l[2] = divme.lower(2); 00275 u[0] = divme.upper(0); u[1]= jslice; u[2] = divme.upper(2); 00276 tmpresult.add(BBox(3,l,u,s)); 00277 l[0] = divme.lower(0); l[1]= jslice+s[1]; l[2] = divme.lower(2); 00278 u[0] = divme.upper(0); u[1]= divme.upper(1); u[2] = divme.upper(2); 00279 tmpresult.add(BBox(3,l,u,s)); 00280 } else { 00281 l[0] = divme.lower(0); l[1]= divme.lower(1); l[2] = divme.lower(2); 00282 u[0] = divme.upper(0); u[1]= divme.upper(1); u[2] = kslice; 00283 tmpresult.add(BBox(3,l,u,s)); 00284 l[0] = divme.lower(0); l[1]= divme.lower(1); l[2] = kslice+s[2]; 00285 u[0] = divme.upper(0); u[1]= divme.upper(1); u[2] = divme.upper(2); 00286 tmpresult.add(BBox(3,l,u,s)); 00287 } 00288 00289 /* foreach New bbox */ 00290 for (BBox* newB = tmpresult.first(); newB; newB = tmpresult.next()) { 00291 /* Figure out how many points are flagged */ 00292 // cout << "Handling "<< *newB <<"\n"; 00293 flagged = 0; 00294 double myEff; 00295 for_3(ii, jj, kk, *newB, newB->stepsize()) 00296 //cout << "SGF: "<<ii<<" "<<jj<<" "<<kk<<" "<<subgridflag(ii,jj,kk)<<"\n"; 00297 //cout.flush(); 00298 if (FastIndex3(flag,ii,jj,kk)>0) flagged++; 00299 end_for 00300 myEff = (double)flagged/(double)((*newB).size()); 00301 /* Do we have ANY? */ 00302 if (flagged) { 00303 // cout <<"Flagged " << flagged << " "<< *newB << "\n"; 00304 // cout <<"Efficiency "<<myEff<<" of " << (*newB).size() <<"\n"; 00305 // cout.flush(); 00306 /* Stopping Condition */ 00307 if ((myEff >= Efficiency && 00308 Max(Max(newB->extents(0),newB->extents(1)),newB->extents(2)) <= MaxWidth) || 00309 (newB->size() < MinWidth*MinWidth*MinWidth) || 00310 (islice+jslice+kslice==-3)) { 00311 /* No. This one stays = the list if it contains flagged points */ 00312 /* Don't add a degenerate grid! */ 00313 int add = 1; 00314 for (BBox *tmp = recurseOnThis.first(); tmp; 00315 tmp = recurseOnThis.next()) { 00316 if ((*tmp).inside((*newB).lower()) && 00317 (*tmp).inside((*newB).upper())) add = 0; 00318 } 00319 if (add) { 00320 // cout << " Adding "<< *newB <<"\n"; 00321 // cout.flush(); 00322 recurseOnThis.add(*newB); 00323 } 00324 } else { 00325 /* Yes: Recluster this sub-box */ 00326 // cout <<"FALL: Flagged " << flagged << " "<< *newB << "\n"; 00327 // cout <<"FALL: Efficiency "<<myEff<<" of " << (*newB).size() <<"\n"; 00328 // cout.flush(); 00329 BBoxList subcluster; 00330 Cluster3R(flag,*newB,Efficiency,MinWidth,MaxWidth,subcluster); 00331 for (BBox *me = subcluster.first(); me; me = subcluster.next()) 00332 recurseOnThis.add(*me); 00333 } 00334 } 00335 } 00336 EndFastIndex1(i_sig); 00337 EndFastIndex1(j_sig); 00338 EndFastIndex1(k_sig); 00339 EndFastIndex3(flag); 00340 return; 00341 } 00342 00355 void Cluster2(GridData(2)<short> &flag, 00356 BBoxList& bblexclude, 00357 double Efficiency, 00358 int MinWidth, 00359 int MaxWidth, 00360 int BufferWidth, 00361 BBoxList &Result) { 00362 BBoxList Result3D; 00363 GridData(2)<short> newflag(flag.bbox()); 00364 BBox flat_3d(3,flag.bbox().lower(0),flag.bbox().lower(1),0, 00365 flag.bbox().upper(0),flag.bbox().upper(1),0, 00366 flag.bbox().stepsize(0),flag.bbox().stepsize(1),1); 00367 GridData(3)<short> clust_this(flat_3d); 00368 int flagged_points = 0; 00369 newflag = 0; clust_this = 0; 00370 00371 for_2(i, j, flag.bbox(), flag.stepsize()) 00372 if (flag(i,j)) { 00373 flagged_points ++; 00374 BBox where(2,i,j,i,j, 00375 flag.bbox().stepsize(0), 00376 flag.bbox().stepsize(1)); 00377 where.grow(BufferWidth); 00378 newflag.equals(1,where); 00379 } 00380 end_for 00381 00382 for (BBox *bbex=bblexclude.first();bbex;bbex=bblexclude.next()) 00383 newflag.equals(0,*bbex); 00384 00385 if (flagged_points) { 00386 for_2(i,j,flag.bbox(),flag.stepsize()) 00387 clust_this(i,j,0) = newflag(i,j); 00388 end_for; 00389 Cluster3R(clust_this, clust_this.bbox(), Efficiency, 00390 MinWidth, MaxWidth, Result3D); 00391 } 00392 00393 /* 00394 Make sure that rank is appropriately set for the bboxes in 00395 Result!! 00396 00397 Manish Parashar Thu May 9 07:54:32 CDT 1996 00398 */ 00399 for (BBox* tmpbb=Result3D.first();tmpbb;tmpbb=Result3D.next()) { 00400 BBox tmp2d(2,tmpbb->lower(),tmpbb->upper(), tmpbb->stepsize()); 00401 Result.add(tmp2d); 00402 } 00403 } 00404 00417 void Cluster3(GridData(3)<short> &flag, 00418 BBoxList& bblexclude, 00419 double Efficiency, 00420 int MinWidth, 00421 int MaxWidth, 00422 int BufferWidth, 00423 BBoxList &Result) { 00424 BBoxList tmpresult, result; 00425 GridData(3)<short> newflag(flag.bbox()); 00426 int flagged_points = 0; 00427 newflag = 0; 00428 00429 for_3(i, j, k, flag.bbox(), flag.stepsize()) 00430 if (flag(i,j,k)) { 00431 flagged_points ++; 00432 BBox where(3,i,j,k,i,j,k, 00433 flag.bbox().stepsize(0), 00434 flag.bbox().stepsize(1), 00435 flag.bbox().stepsize(2)); 00436 where.grow(BufferWidth); 00437 newflag.equals(1,where); 00438 } 00439 end_for 00440 00441 for (BBox *bbex=bblexclude.first();bbex;bbex=bblexclude.next()) 00442 newflag.equals(0,*bbex); 00443 00444 if (flagged_points) { 00445 Cluster3R(newflag, newflag.bbox(), Efficiency, 00446 MinWidth, MaxWidth, Result); 00447 } 00448 }
Quickstart Users Guide Programmers Reference Installation Examples Download
AMROC Main Home Contactlast update: 06/01/04