00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <winstd.H>
00027
00028 #include <algorithm>
00029 #include <iostream>
00030
00031 #include <BoxArray.H>
00032 #include <BoxList.H>
00033
00034 void
00035 BoxList::join (const BoxList& blist)
00036 {
00037 BL_ASSERT(ixType() == blist.ixType());
00038 std::list<Box> lb = blist.lbox;
00039 lbox.splice(lbox.end(), lb);
00040 }
00041
00042 void
00043 BoxList::catenate (BoxList& blist)
00044 {
00045 BL_ASSERT(ixType() == blist.ixType());
00046 lbox.splice(lbox.end(), blist.lbox);
00047 BL_ASSERT(blist.isEmpty());
00048 }
00049
00050 bool
00051 BoxList::contains (const Box& b) const
00052 {
00053 BoxList bnew = BoxLib::complementIn(b,*this);
00054
00055 return bnew.isEmpty();
00056 }
00057
00058 BoxList&
00059 BoxList::remove (const Box& bx)
00060 {
00061 BL_ASSERT(ixType() == bx.ixType());
00062 lbox.remove(bx);
00063 return *this;
00064 }
00065
00066 BoxList&
00067 BoxList::remove (iterator bli)
00068 {
00069 BL_ASSERT(ixType() == bli->ixType());
00070 lbox.erase(bli);
00071 return *this;
00072 }
00073
00074 BoxList
00075 BoxLib::intersect (const BoxList& bl,
00076 const Box& b)
00077 {
00078 BoxList newbl(bl);
00079 return newbl.intersect(b);
00080 }
00081
00082 BoxList
00083 BoxLib::intersect (const BoxList& bl,
00084 const BoxList& br)
00085 {
00086 BoxList newbl(bl);
00087 return newbl.intersect(br);
00088 }
00089
00090 BoxList
00091 BoxLib::refine (const BoxList& bl,
00092 int ratio)
00093 {
00094 BoxList nbl(bl);
00095 return nbl.refine(ratio);
00096 }
00097
00098 BoxList
00099 BoxLib::coarsen (const BoxList& bl,
00100 int ratio)
00101 {
00102 BoxList nbl(bl);
00103 return nbl.coarsen(ratio);
00104 }
00105
00106 BoxList
00107 BoxLib::accrete (const BoxList& bl,
00108 int sz)
00109 {
00110 BoxList nbl(bl);
00111 return nbl.accrete(sz);
00112 }
00113
00114 bool
00115 BoxList::operator!= (const BoxList& rhs) const
00116 {
00117 return !operator==(rhs);
00118 }
00119
00120 BoxList::BoxList ()
00121 :
00122 lbox(),
00123 btype(IndexType::TheCellType())
00124 {}
00125
00126 BoxList::BoxList (const Box& bx)
00127 : btype(bx.ixType())
00128 {
00129 push_back(bx);
00130 }
00131
00132 BoxList::BoxList (IndexType _btype)
00133 :
00134 lbox(),
00135 btype(_btype)
00136 {}
00137
00138 BoxList::BoxList (const BoxArray &ba)
00139 :
00140 lbox(),
00141 btype()
00142 {
00143 if (ba.size() > 0)
00144 btype = ba[0].ixType();
00145 for (int i = 0; i < ba.size(); ++i)
00146 push_back(ba[i]);
00147 }
00148
00149 bool
00150 BoxList::ok () const
00151 {
00152 bool isok = true;
00153 const_iterator bli = begin();
00154 if ( bli != end() )
00155 {
00156 for (Box b(*bli); bli != end() && isok; ++bli)
00157 {
00158 isok = bli->ok() && bli->sameType(b);
00159 }
00160 }
00161 return isok;
00162 }
00163
00164 bool
00165 BoxList::isDisjoint () const
00166 {
00167 bool isdisjoint = true;
00168 for (const_iterator bli = begin(); bli != end() && isdisjoint; ++bli)
00169 {
00170 const_iterator bli2 = bli;
00171
00172
00173
00174 ++bli2;
00175 for (; bli2 != end() && isdisjoint; ++bli2)
00176 {
00177 if (bli->intersects(*bli2))
00178 {
00179 isdisjoint = false;
00180 }
00181 }
00182 }
00183 return isdisjoint;
00184 }
00185
00186 bool
00187 BoxList::contains (const IntVect& v) const
00188 {
00189 bool contained = false;
00190 for (const_iterator bli = begin(); bli != end() && !contained; ++bli)
00191 {
00192 if (bli->contains(v))
00193 {
00194 contained = true;
00195 }
00196 }
00197 return contained;
00198 }
00199
00200 bool
00201 BoxList::contains (const BoxList& bl) const
00202 {
00203 for (const_iterator bli = bl.begin(); bli != bl.end(); ++bli)
00204 {
00205 if ( !contains(*bli) )
00206 {
00207 return false;
00208 }
00209 }
00210 return true;
00211 }
00212
00213 bool
00214 BoxList::contains (const BoxArray& ba) const
00215 {
00216 for (int i = 0; i < ba.size(); i++)
00217 if (!contains(ba[i]))
00218 return false;
00219 return true;
00220 }
00221
00222 BoxList&
00223 BoxList::intersect (const Box& b)
00224 {
00225 for (iterator bli= begin(); bli != end(); )
00226 {
00227 if (bli->intersects(b))
00228 {
00229 *bli &= b;
00230 ++bli;
00231 }
00232 else
00233 {
00234 bli = lbox.erase(bli);
00235 }
00236 }
00237 return *this;
00238 }
00239
00240 BoxList&
00241 BoxList::intersect (const BoxList& b)
00242 {
00243 BoxList bl;
00244
00245 for (iterator lhs = begin(); lhs != end(); ++lhs)
00246 {
00247 for (const_iterator rhs = b.begin(); rhs != b.end(); ++rhs)
00248 {
00249 if ( lhs->intersects(*rhs) )
00250 {
00251 bl.push_back(*lhs & *rhs);
00252 }
00253 }
00254 }
00255
00256 *this = bl;
00257
00258 return *this;
00259 }
00260
00261 BoxList
00262 BoxLib::complementIn (const Box& b,
00263 const BoxList& bl)
00264 {
00265 BoxList newb(b.ixType());
00266 newb.push_back(b);
00267 for (BoxList::const_iterator bli = bl.begin(); bli != bl.end() && newb.isNotEmpty(); ++bli)
00268 {
00269 for (BoxList::iterator newbli = newb.begin(); newbli != newb.end(); )
00270 {
00271 if ( newbli->intersects(*bli))
00272 {
00273 BoxList tm = BoxLib::boxDiff(*newbli, *bli);
00274 newb.catenate(tm);
00275 newb.remove(newbli++);
00276 }
00277 else
00278 {
00279 ++newbli;
00280 }
00281 }
00282 }
00283 return newb;
00284 }
00285
00286 BoxList&
00287 BoxList::complementIn (const Box& b,
00288 const BoxList& bl)
00289 {
00290 clear();
00291 push_back(b);
00292 for (const_iterator bli = bl.begin(); bli != bl.end() && isNotEmpty(); ++bli)
00293 {
00294 for (iterator newbli = lbox.begin(); newbli != lbox.end(); )
00295 {
00296 if ( newbli->intersects(*bli) )
00297 {
00298 BoxList tm = BoxLib::boxDiff(*newbli, *bli);
00299 lbox.splice(lbox.end(), tm.lbox);
00300 lbox.erase(newbli++);
00301 }
00302 else
00303 {
00304 ++newbli;
00305 }
00306 }
00307 }
00308 return *this;
00309 }
00310
00311 BoxList&
00312 BoxList::refine (int ratio)
00313 {
00314 for (iterator bli = begin(); bli != end(); ++bli)
00315 {
00316 bli->refine(ratio);
00317 }
00318 return *this;
00319 }
00320
00321 BoxList&
00322 BoxList::refine (const IntVect& ratio)
00323 {
00324 for (iterator bli = begin(); bli != end(); ++bli)
00325 {
00326 bli->refine(ratio);
00327 }
00328 return *this;
00329 }
00330
00331 BoxList&
00332 BoxList::coarsen (int ratio)
00333 {
00334 for (iterator bli = begin(); bli != end(); ++bli)
00335 {
00336 bli->coarsen(ratio);
00337 }
00338 return *this;
00339 }
00340
00341 BoxList&
00342 BoxList::coarsen (const IntVect& ratio)
00343 {
00344 for (iterator bli = begin(); bli != end(); ++bli)
00345 {
00346 bli->coarsen(ratio);
00347 }
00348 return *this;
00349 }
00350
00351 BoxList&
00352 BoxList::accrete (int sz)
00353 {
00354 for (iterator bli = begin(); bli != end(); ++bli)
00355 {
00356 bli->grow(sz);
00357 }
00358 return *this;
00359 }
00360
00361 BoxList&
00362 BoxList::shift (int dir,
00363 int nzones)
00364 {
00365 for (iterator bli = begin(); bli != end(); ++bli)
00366 {
00367 bli->shift(dir, nzones);
00368 }
00369 return *this;
00370 }
00371
00372 BoxList&
00373 BoxList::shiftHalf (int dir,
00374 int num_halfs)
00375 {
00376 for (iterator bli = begin(); bli != end(); ++bli)
00377 {
00378 bli->shiftHalf(dir, num_halfs);
00379 }
00380 return *this;
00381 }
00382
00383 BoxList&
00384 BoxList::shiftHalf (const IntVect& iv)
00385 {
00386 for (iterator bli = begin(); bli != end(); ++bli)
00387 {
00388 bli->shiftHalf(iv);
00389 }
00390 return *this;
00391 }
00392
00393
00394
00395
00396
00397 BoxList
00398 BoxLib::boxDiff (const Box& b1in,
00399 const Box& b2)
00400 {
00401 Box b1(b1in);
00402 BoxList b_list(b1.ixType());
00403
00404 if ( !b2.contains(b1) )
00405 {
00406 if ( !b1.intersects(b2) )
00407 {
00408 b_list.push_back(b1);
00409 }
00410 else
00411 {
00412 const int* b2lo = b2.loVect();
00413 const int* b2hi = b2.hiVect();
00414
00415 for (int i = 0; i < BL_SPACEDIM; i++)
00416 {
00417 const int* b1lo = b1.loVect();
00418 const int* b1hi = b1.hiVect();
00419
00420 if ((b1lo[i] < b2lo[i]) && (b2lo[i] <= b1hi[i]))
00421 {
00422 Box bn(b1);
00423 bn.setSmall(i,b1lo[i]);
00424 bn.setBig(i,b2lo[i]-1);
00425 b_list.push_back(bn);
00426 b1.setSmall(i,b2lo[i]);
00427 }
00428 if ((b1lo[i] <= b2hi[i]) && (b2hi[i] < b1hi[i]))
00429 {
00430 Box bn(b1);
00431 bn.setSmall(i,b2hi[i]+1);
00432 bn.setBig(i,b1hi[i]);
00433 b_list.push_back(bn);
00434 b1.setBig(i,b2hi[i]);
00435 }
00436 }
00437 }
00438 }
00439 return b_list;
00440 }
00441
00442 int
00443 BoxList::simplify ()
00444 {
00445
00446
00447
00448 int count = 0;
00449 int lo[BL_SPACEDIM];
00450 int hi[BL_SPACEDIM];
00451
00452 for (iterator bla = begin(); bla != end(); )
00453 {
00454 const int* alo = bla->loVect();
00455 const int* ahi = bla->hiVect();
00456 bool match = false;
00457 iterator blb = bla;
00458 ++blb;
00459 while ( blb != end() )
00460 {
00461 const int* blo = blb->loVect();
00462 const int* bhi = blb->hiVect();
00463
00464
00465
00466
00467
00468 bool canjoin = true;
00469 int joincnt = 0;
00470 for (int i = 0; i < BL_SPACEDIM; i++)
00471 {
00472 if (alo[i]==blo[i] && ahi[i]==bhi[i])
00473 {
00474 lo[i] = alo[i];
00475 hi[i] = ahi[i];
00476 }
00477 else if (alo[i]<=blo[i] && blo[i]<=ahi[i]+1)
00478 {
00479 lo[i] = alo[i];
00480 hi[i] = std::max(ahi[i],bhi[i]);
00481 joincnt++;
00482 }
00483 else if (blo[i]<=alo[i] && alo[i]<=bhi[i]+1)
00484 {
00485 lo[i] = blo[i];
00486 hi[i] = std::max(ahi[i],bhi[i]);
00487 joincnt++;
00488 }
00489 else
00490 {
00491 canjoin = false;
00492 break;
00493 }
00494 }
00495 if (canjoin && (joincnt <= 1))
00496 {
00497
00498
00499
00500 blb->setSmall(IntVect(lo));
00501 blb->setBig(IntVect(hi));
00502 lbox.erase(bla++);
00503 count++;
00504 match = true;
00505 break;
00506 }
00507 else
00508 {
00509
00510
00511
00512 ++blb;
00513 }
00514 }
00515
00516
00517
00518 if (!match)
00519 ++bla;
00520 }
00521 return count;
00522 }
00523
00524 int
00525 BoxList::minimize ()
00526 {
00527 int cnt = 0;
00528 for (int n; (n=simplify()) > 0; )
00529 cnt += n;
00530 return cnt;
00531 }
00532
00533 Box
00534 BoxList::minimalBox () const
00535 {
00536 Box minbox;
00537 if ( !isEmpty() )
00538 {
00539 const_iterator bli = begin();
00540 minbox = *bli;
00541 while ( bli != end() )
00542 {
00543 minbox.minBox(*bli++);
00544 }
00545 }
00546 return minbox;
00547 }
00548
00549 BoxList&
00550 BoxList::maxSize (const IntVect& chunk)
00551 {
00552 for (iterator bli = begin(); bli != end(); ++bli)
00553 {
00554 const int* len = bli->length().getVect();
00555
00556 for (int i = 0; i < BL_SPACEDIM; i++)
00557 {
00558 if (len[i] > chunk[i])
00559 {
00560
00561
00562
00563 int ratio = 1;
00564 int bs = chunk[i];
00565 int nlen = len[i];
00566 while ((bs%2 == 0) && (nlen%2 == 0))
00567 {
00568 ratio *= 2;
00569 bs /= 2;
00570 nlen /= 2;
00571 }
00572
00573
00574
00575 const int numblk = nlen/bs + (nlen%bs ? 1 : 0);
00576 const int size = nlen/numblk;
00577 const int extra = nlen%numblk;
00578
00579
00580
00581 for (int k = 0; k < numblk-1; k++)
00582 {
00583
00584
00585
00586 const int ksize = (k < extra ? size+1 : size) * ratio;
00587
00588
00589
00590 const int pos = bli->bigEnd(i) - ksize + 1;
00591
00592 push_back(bli->chop(i,pos));
00593 }
00594 }
00595 }
00596
00597
00598
00599
00600
00601 }
00602 return *this;
00603 }
00604
00605 BoxList&
00606 BoxList::maxSize (int chunk)
00607 {
00608 return maxSize(IntVect(D_DECL(chunk,chunk,chunk)));
00609 }
00610
00611 BoxList&
00612 BoxList::surroundingNodes ()
00613 {
00614 for (iterator bli = begin(); bli != end(); ++bli)
00615 {
00616 bli->surroundingNodes();
00617 }
00618 return *this;
00619 }
00620
00621 BoxList&
00622 BoxList::surroundingNodes (int dir)
00623 {
00624 for (iterator bli = begin(); bli != end(); ++bli)
00625 {
00626 bli->surroundingNodes(dir);
00627 }
00628 return *this;
00629 }
00630
00631 BoxList&
00632 BoxList::enclosedCells ()
00633 {
00634 for (iterator bli = begin(); bli != end(); ++bli)
00635 {
00636 bli->enclosedCells();
00637 }
00638 return *this;
00639 }
00640
00641 BoxList&
00642 BoxList::enclosedCells (int dir)
00643 {
00644 for (iterator bli = begin(); bli != end(); ++bli)
00645 {
00646 bli->enclosedCells(dir);
00647 }
00648 return *this;
00649 }
00650
00651 BoxList&
00652 BoxList::convert (IndexType typ)
00653 {
00654 btype = typ;
00655 for (iterator bli = begin(); bli != end(); ++bli)
00656 {
00657 bli->convert(typ);
00658 }
00659 return *this;
00660 }
00661
00662 std::ostream&
00663 operator<< (std::ostream& os,
00664 const BoxList& blist)
00665 {
00666 BoxList::const_iterator bli = blist.begin();
00667 os << "(BoxList " << blist.size() << ' ' << blist.ixType() << '\n';
00668 for (int count = 1; bli != blist.end(); ++bli, ++count)
00669 {
00670 os << count << " : " << *bli << '\n';
00671 }
00672 os << ')' << '\n';
00673
00674 if (os.fail())
00675 BoxLib::Error("operator<<(ostream&,BoxList&) failed");
00676
00677 return os;
00678 }
00679
00680 bool
00681 BoxList::operator== (const BoxList& rhs) const
00682 {
00683 bool rc = true;
00684 if (size() != rhs.size())
00685 {
00686 rc = false;
00687 }
00688 else
00689 {
00690 BoxList::const_iterator liter = begin(), riter = rhs.begin();
00691 for (; liter != end() && rc; ++liter, ++riter)
00692 {
00693 if ( !( *liter == *riter) )
00694 {
00695 rc = false;
00696 }
00697 }
00698 }
00699 return rc;
00700 }