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 <iostream>
00027 #include <limits>
00028
00029 #include <BLassert.H>
00030 #include <BoxLib.H>
00031 #include <Box.H>
00032
00033 const Box&
00034 Box::TheUnitBox ()
00035 {
00036 static const Box Unit(IntVect::TheZeroVector(), IntVect::TheZeroVector());
00037 return Unit;
00038 }
00039
00040 Box::Box ()
00041 :
00042 smallend(IntVect::TheUnitVector()),
00043 bigend(IntVect::TheZeroVector()),
00044 btype()
00045 {}
00046
00047 Box::Box (const IntVect& small,
00048 const int* vec_len)
00049 :
00050 smallend(small),
00051 bigend(D_DECL(small[0]+vec_len[0]-1,
00052 small[1]+vec_len[1]-1,
00053 small[2]+vec_len[2]-1))
00054 {}
00055
00056 Box::Box (const IntVect& small,
00057 const IntVect& big,
00058 const IndexType& t)
00059 :
00060 smallend(small),
00061 bigend(big),
00062 btype(t)
00063 {}
00064
00065 Box::Box (const IntVect& small,
00066 const IntVect& big)
00067 :
00068 smallend(small),
00069 bigend(big)
00070 {}
00071
00072 Box::Box (const IntVect& small,
00073 const IntVect& big,
00074 const IntVect& typ)
00075 :
00076 smallend(small),
00077 bigend(big),
00078 btype(typ)
00079 {
00080 BL_ASSERT(typ >= IntVect::TheZeroVector() && typ <= IntVect::TheUnitVector());
00081 }
00082
00083 bool
00084 Box::volumeOK () const
00085 {
00086 long ignore;
00087 return volumeOK(ignore);
00088 }
00089
00090 long
00091 Box::index (const IntVect& v) const
00092 {
00093 long result = v[0]-smallend[0];
00094 #if BL_SPACEDIM==2
00095 result += length(0)*(v[1]-smallend[1]);
00096 #elif BL_SPACEDIM==3
00097 result += length(0)*(v[1]-smallend[1]
00098 +(v[2]-smallend[2])*length(1));
00099 #endif
00100 return result;
00101 }
00102
00103 Box&
00104 Box::setSmall (const IntVect& sm)
00105 {
00106 smallend = sm;
00107 return *this;
00108 }
00109
00110 Box&
00111 Box::setSmall (int dir,
00112 int sm_index)
00113 {
00114 smallend.setVal(dir,sm_index);
00115 return *this;
00116 }
00117
00118 Box&
00119 Box::setBig (const IntVect& bg)
00120 {
00121 bigend = bg;
00122 return *this;
00123 }
00124
00125 Box&
00126 Box::setBig (int dir,
00127 int bg_index)
00128 {
00129 bigend.setVal(dir,bg_index);
00130 return *this;
00131 }
00132
00133 Box&
00134 Box::setRange (int dir,
00135 int sm_index,
00136 int n_cells)
00137 {
00138 smallend.setVal(dir,sm_index);
00139 bigend.setVal(dir,sm_index+n_cells-1);
00140 return *this;
00141 }
00142
00143 Box&
00144 Box::shift (int dir,
00145 int nzones)
00146 {
00147 smallend.shift(dir,nzones);
00148 bigend.shift(dir,nzones);
00149 return *this;
00150 }
00151
00152 Box&
00153 Box::shift (const IntVect& iv)
00154 {
00155 smallend.shift(iv);
00156 bigend.shift(iv);
00157 return *this;
00158 }
00159
00160 Box&
00161 Box::convert (const IntVect& typ)
00162 {
00163 BL_ASSERT(typ >= IntVect::TheZeroVector() && typ <= IntVect::TheUnitVector());
00164 IntVect shft(typ - btype.ixType());
00165 bigend += shft;
00166 btype = IndexType(typ);
00167 return *this;
00168 }
00169
00170 Box&
00171 Box::convert (IndexType t)
00172 {
00173 for (int dir = 0; dir < BL_SPACEDIM; dir++)
00174 {
00175 unsigned int typ = t[dir];
00176 unsigned int bitval = btype[dir];
00177 int off = typ - bitval;
00178 bigend.shift(dir,off);
00179 btype.setType(dir, (IndexType::CellIndex) typ);
00180 }
00181 return *this;
00182 }
00183
00184 Box
00185 BoxLib::surroundingNodes (const Box& b,
00186 int dir)
00187 {
00188 Box bx(b);
00189 return bx.surroundingNodes(dir);
00190 }
00191
00192 Box&
00193 Box::surroundingNodes (int dir)
00194 {
00195 if (!(btype[dir]))
00196 {
00197 bigend.shift(dir,1);
00198
00199
00200
00201 btype.set(dir);
00202 }
00203 return *this;
00204 }
00205
00206 Box
00207 BoxLib::surroundingNodes (const Box& b)
00208 {
00209 Box bx(b);
00210 return bx.surroundingNodes();
00211 }
00212
00213 Box&
00214 Box::surroundingNodes ()
00215 {
00216 for (int i = 0; i < BL_SPACEDIM; ++i)
00217 if ((btype[i] == 0))
00218 bigend.shift(i,1);
00219 btype.setall();
00220 return *this;
00221 }
00222
00223 Box
00224 BoxLib::enclosedCells (const Box& b,
00225 int dir)
00226 {
00227 Box bx(b);
00228 return bx.enclosedCells(dir);
00229 }
00230
00231 Box&
00232 Box::enclosedCells (int dir)
00233 {
00234 if (btype[dir])
00235 {
00236 bigend.shift(dir,-1);
00237
00238
00239
00240 btype.unset(dir);
00241 }
00242 return *this;
00243 }
00244
00245 Box
00246 BoxLib::enclosedCells (const Box& b)
00247 {
00248 Box bx(b);
00249 return bx.enclosedCells();
00250 }
00251
00252 Box&
00253 Box::enclosedCells ()
00254 {
00255 for (int i = 0 ; i < BL_SPACEDIM; ++i)
00256 if (btype[i])
00257 bigend.shift(i,-1);
00258 btype.clear();
00259 return *this;
00260 }
00261
00262 Box&
00263 Box::operator+= (const IntVect& v)
00264 {
00265 smallend += v;
00266 bigend += v;
00267 return *this;
00268 }
00269
00270 Box
00271 Box::operator+ (const IntVect& v) const
00272 {
00273 Box result = *this;
00274 return result += v;
00275 }
00276
00277 Box&
00278 Box::operator-= (const IntVect& v)
00279 {
00280 smallend -= v;
00281 bigend -= v;
00282 return *this;
00283 }
00284
00285 Box
00286 Box::operator- (const IntVect& v) const
00287 {
00288 Box result = *this;
00289 return result -= v;
00290 }
00291
00292 Box&
00293 Box::grow (int i)
00294 {
00295 smallend.diagShift(-i);
00296 bigend.diagShift(i);
00297 return *this;
00298 }
00299
00300 Box
00301 BoxLib::grow (const Box& b,
00302 int i)
00303 {
00304 Box result = b;
00305 return result.grow(i);
00306 }
00307
00308 Box&
00309 Box::grow (const IntVect& v)
00310 {
00311 smallend -= v;
00312 bigend += v;
00313 return *this;
00314 }
00315
00316 Box
00317 BoxLib::grow (const Box& b,
00318 const IntVect& v)
00319 {
00320 Box result = b;
00321 return result.grow(v);
00322 }
00323
00324 Box&
00325 Box::grow (int idir,
00326 int n_cell)
00327 {
00328 smallend.shift(idir, -n_cell);
00329 bigend.shift(idir, n_cell);
00330 return *this;
00331 }
00332
00333 Box&
00334 Box::grow (const Orientation& face,
00335 int n_cell)
00336 {
00337 int idir = face.coordDir();
00338 if (face.isLow())
00339 smallend.shift(idir, -n_cell);
00340 else
00341 bigend.shift(idir,n_cell);
00342 return *this;
00343 }
00344
00345 Box&
00346 Box::growLo (int idir,
00347 int n_cell)
00348 {
00349 smallend.shift(idir, -n_cell);
00350 return *this;
00351 }
00352
00353 Box&
00354 Box::growHi (int idir,
00355 int n_cell)
00356 {
00357 bigend.shift(idir,n_cell);
00358 return *this;
00359 }
00360
00361 Box
00362 Box::operator& (const Box& rhs) const
00363 {
00364 Box lhs = *this;
00365 return lhs &= rhs;
00366 }
00367
00368 bool
00369 Box::numPtsOK (long& N) const
00370 {
00371 BL_ASSERT(ok());
00372
00373 N = length(0);
00374
00375 for (int i = 1; i < BL_SPACEDIM; i++)
00376 {
00377 if (length(i) == 0)
00378 {
00379 N = 0;
00380 return true;
00381 }
00382 else if (N <= std::numeric_limits<long>::max()/length(i))
00383 {
00384 N *= length(i);
00385 }
00386 else
00387 {
00388
00389
00390
00391 std::cout << "length0,length1,N " <<
00392 length(0) << ' ' << length(1) << ' ' << N << '\n';
00393 if (BL_SPACEDIM==3)
00394 std::cout << "length2 " << length(2) << '\n';
00395
00396 return false;
00397 }
00398 }
00399
00400 return true;
00401 }
00402
00403 long
00404 Box::numPts () const
00405 {
00406 long result;
00407 if (!numPtsOK(result))
00408 BoxLib::Error("Arithmetic overflow in Box::numPts()");
00409 return result;
00410 }
00411
00412 bool
00413 Box::volumeOK (long& N) const
00414 {
00415 BL_ASSERT(ok());
00416
00417 N = length(0)-btype[0];
00418
00419 for (int i = 1; i < BL_SPACEDIM; i++)
00420 {
00421 long diff = (length(i)-btype[i]);
00422
00423 if (diff == 0)
00424 {
00425 N = 0;
00426 return true;
00427 }
00428 else if (N <= std::numeric_limits<long>::max()/diff)
00429 {
00430 N *= diff;
00431 }
00432 else
00433 {
00434
00435
00436
00437 return false;
00438 }
00439 }
00440
00441 return true;
00442 }
00443
00444 long
00445 Box::volume () const
00446 {
00447 long result;
00448 if (!volumeOK(result))
00449 BoxLib::Error("Arithmetic overflow in Box::volume()");
00450 return result;
00451 }
00452
00453 Box&
00454 Box::shiftHalf (int dir,
00455 int nzones)
00456 {
00457 int nbit = (nzones<0 ? -nzones : nzones)%2;
00458 int nshift = nzones/2;
00459
00460
00461
00462 unsigned int bit_dir = btype[dir];
00463 if (nbit)
00464 btype.flip(dir);
00465 if (nzones < 0)
00466 nshift -= (bit_dir ? nbit : 0);
00467 else
00468 nshift += (bit_dir ? 0 : nbit);
00469 smallend.shift(dir,nshift);
00470 bigend.shift(dir,nshift);
00471 return *this;
00472 }
00473
00474 Box&
00475 Box::shiftHalf (const IntVect& nz)
00476 {
00477 for (int dir = 0; dir < BL_SPACEDIM; dir++)
00478 {
00479 shiftHalf(dir,nz[dir]);
00480 }
00481 return *this;
00482 }
00483
00484 bool
00485 Box::intersects (const Box& b) const
00486 {
00487 Box isect = *this & b;
00488 return isect.ok();
00489 }
00490
00491 Box&
00492 Box::operator&= (const Box& b)
00493 {
00494 if (! sameType(b)) {
00495 std::cout << "sameType(b) error b= " << b << '\n';
00496 std::cout << "b.btype= " << b.btype << '\n';
00497 std::cout << "this = " << *this << '\n';
00498 std::cout << "btype= " << btype << '\n';
00499 BL_ASSERT(sameType(b));
00500 }
00501
00502 smallend.max(b.smallend);
00503 bigend.min(b.bigend);
00504 return *this;
00505 }
00506
00507 void
00508 Box::next (IntVect& p) const
00509 {
00510 BL_ASSERT(contains(p));
00511
00512 p.shift(0,1);
00513 #if BL_SPACEDIM==2
00514 if (!(p <= bigend))
00515 {
00516 p.setVal(0,smallend[0]);
00517 p.shift(1,1);
00518 }
00519 #elif BL_SPACEDIM==3
00520 if (!(p <= bigend))
00521 {
00522 p.setVal(0,smallend[0]);
00523 p.shift(1,1);
00524 if (!(p <= bigend))
00525 {
00526 p.setVal(1,smallend[1]);
00527 p.shift(2,1);
00528 }
00529 }
00530 #endif
00531 }
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544 void
00545 Box::next (IntVect& p,
00546 const int* shv) const
00547 {
00548 BL_ASSERT(contains(p));
00549
00550 #if BL_SPACEDIM==1
00551 p.shift(0,shv[0]);
00552 #elif BL_SPACEDIM==2
00553 p.shift(0,shv[0]);
00554 if (!(p <= bigend))
00555 {
00556
00557
00558
00559 p.setVal(0,smallend[0]);
00560 p.shift(1,shv[1]);
00561 }
00562 #elif BL_SPACEDIM==3
00563 p.shift(0,shv[0]);
00564 if (!(p <= bigend))
00565 {
00566
00567
00568
00569 p.setVal(0,smallend[0]);
00570 p.shift(1,shv[1]);
00571 if(!(p <= bigend))
00572 {
00573 p.setVal(1,smallend[1]);
00574 p.shift(2,shv[2]);
00575 }
00576 }
00577 #endif
00578 }
00579
00580 Box
00581 BoxLib::refine (const Box& b,
00582 int refinement_ratio)
00583 {
00584 Box result = b;
00585 return result.refine(refinement_ratio);
00586 }
00587
00588 Box&
00589 Box::refine (int refinement_ratio)
00590 {
00591 IntVect shft(IntVect::TheUnitVector());
00592 shft -= btype.ixType();
00593 smallend.scale(refinement_ratio);
00594 bigend += shft;
00595 bigend.scale(refinement_ratio);
00596 bigend -= shft;
00597 return *this;
00598 }
00599
00600 Box
00601 BoxLib::refine (const Box& b,
00602 const IntVect& refinement_ratio)
00603 {
00604 Box result = b;
00605 return result.refine(refinement_ratio);
00606 }
00607
00608 Box&
00609 Box::refine (const IntVect& refinement_ratio)
00610 {
00611 IntVect shft(IntVect::TheUnitVector());
00612 shft -= btype.ixType();
00613 smallend *= refinement_ratio;
00614 bigend += shft;
00615 bigend *= refinement_ratio;
00616 bigend -= shft;
00617 return *this;
00618 }
00619
00620
00621
00622
00623
00624
00625 int
00626 Box::longside () const
00627 {
00628 int ignore = 0;
00629 return longside(ignore);
00630 }
00631
00632 int
00633 Box::longside (int& dir) const
00634 {
00635 int maxlen = length(0);
00636 dir = 0;
00637 for (int i = 1; i < BL_SPACEDIM; i++)
00638 {
00639 if (length(i) > maxlen)
00640 {
00641 maxlen = length(i);
00642 dir = i;
00643 }
00644 }
00645 return maxlen;
00646 }
00647
00648 int
00649 Box::shortside () const
00650 {
00651 int ignore = 0;
00652 return shortside(ignore);
00653 }
00654
00655 int
00656 Box::shortside (int& dir) const
00657 {
00658 int minlen = length(0);
00659 dir = 0;
00660 for (int i = 1; i < BL_SPACEDIM; i++)
00661 {
00662 if (length(i) < minlen)
00663 {
00664 minlen = length(i);
00665 dir = i;
00666 }
00667 }
00668 return minlen;
00669 }
00670
00671
00672
00673
00674
00675
00676
00677 Box
00678 Box::chop (int dir,
00679 int chop_pnt)
00680 {
00681
00682
00683
00684 IntVect sm(smallend);
00685 IntVect bg(bigend);
00686 sm.setVal(dir,chop_pnt);
00687 if (btype[dir])
00688 {
00689
00690
00691
00692 BL_ASSERT(chop_pnt > smallend[dir] && chop_pnt < bigend[dir]);
00693
00694
00695
00696 bigend.setVal(dir,chop_pnt);
00697 }
00698 else
00699 {
00700
00701
00702
00703 BL_ASSERT(chop_pnt > smallend[dir] && chop_pnt <= bigend[dir]);
00704
00705
00706
00707 bigend.setVal(dir,chop_pnt-1);
00708 }
00709 return Box(sm,bg,btype);
00710 }
00711
00712 Box
00713 BoxLib::coarsen (const Box& b,
00714 int refinement_ratio)
00715 {
00716 Box result = b;
00717 return result.coarsen(refinement_ratio);
00718 }
00719
00720 Box&
00721 Box::coarsen (int refinement_ratio)
00722 {
00723 smallend.coarsen(refinement_ratio);
00724 if (btype.any())
00725 {
00726 IntVect off(IntVect::TheZeroVector());
00727 for (int dir = 0; dir < BL_SPACEDIM; dir++)
00728 {
00729 if (btype[dir])
00730 if (bigend[dir]%refinement_ratio)
00731 off.setVal(dir,1);
00732 }
00733 bigend.coarsen(refinement_ratio);
00734 bigend += off;
00735 }
00736 else
00737 {
00738 bigend.coarsen(refinement_ratio);
00739 }
00740
00741 return *this;
00742 }
00743 Box
00744 BoxLib::coarsen (const Box& b,
00745 const IntVect& refinement_ratio)
00746 {
00747 Box result = b;
00748 return result.coarsen(refinement_ratio);
00749 }
00750
00751 Box&
00752 Box::coarsen (const IntVect& refinement_ratio)
00753 {
00754 smallend.coarsen(refinement_ratio);
00755
00756 if (btype.any())
00757 {
00758 IntVect off(IntVect::TheZeroVector());
00759 for (int dir = 0; dir < BL_SPACEDIM; dir++)
00760 {
00761 if (btype[dir])
00762 {
00763 int b = bigend[dir];
00764 int r = refinement_ratio[dir];
00765 if (b%r)
00766 off.setVal(dir,1);
00767 }
00768 }
00769 bigend.coarsen(refinement_ratio);
00770 bigend += off;
00771 }
00772 else
00773 {
00774 bigend.coarsen(refinement_ratio);
00775 }
00776
00777 return *this;
00778 }
00779
00780
00781
00782
00783
00784 std::ostream&
00785 operator<< (std::ostream& os,
00786 const Box& b)
00787 {
00788 os << '('
00789 << b.smallEnd() << ' '
00790 << b.bigEnd() << ' '
00791 << b.type()
00792 << ')';
00793
00794 if (os.fail())
00795 BoxLib::Error("operator<<(ostream&,Box&) failed");
00796
00797 return os;
00798 }
00799
00800
00801
00802
00803 #define BL_IGNORE_MAX 100000
00804
00805 std::istream&
00806 operator>> (std::istream& is,
00807 Box& b)
00808 {
00809 IntVect lo, hi, typ;
00810
00811 is >> std::ws;
00812 char c;
00813 is >> c;
00814
00815 if (c == '(')
00816 {
00817 is >> lo >> hi;
00818 is >> c;
00819
00820 is.putback(c);
00821 if ( c == '(' )
00822 {
00823 is >> typ;
00824 }
00825 is.ignore(BL_IGNORE_MAX,')');
00826 }
00827 else
00828 {
00829 BoxLib::Error("operator>>(istream&,Box&): expected \'(\'");
00830 }
00831
00832 b = Box(lo,hi,typ);
00833
00834 if (is.fail())
00835 BoxLib::Error("operator>>(istream&,Box&) failed");
00836
00837 return is;
00838 }
00839
00840 Box
00841 BoxLib::minBox (const Box& b,
00842 const Box& o)
00843 {
00844 Box result = b;
00845 return result.minBox(o);
00846 }
00847
00848 Box&
00849 Box::minBox (const Box &b)
00850 {
00851 BL_ASSERT(b.ok() && ok());
00852 BL_ASSERT(sameType(b));
00853 smallend.min(b.smallend);
00854 bigend.max(b.bigend);
00855 return *this;
00856 }
00857
00858 Box
00859 BoxLib::bdryLo (const Box& b,
00860 int dir,
00861 int len)
00862 {
00863 IntVect low(b.smallEnd());
00864 IntVect hi(b.bigEnd());
00865 int sm = low[dir];
00866 hi.setVal(dir,sm+len-1);
00867
00868
00869
00870 IndexType typ(b.ixType());
00871 typ.set(dir);
00872 return Box(low,hi,typ);
00873 }
00874
00875 Box
00876 BoxLib::bdryHi (const Box& b,
00877 int dir,
00878 int len)
00879 {
00880 IntVect low(b.smallEnd());
00881 IntVect hi(b.bigEnd());
00882 unsigned int bitval = b.type()[dir];
00883 int bg = hi[dir] + 1 - bitval%2;
00884 low.setVal(dir,bg);
00885 hi.setVal(dir,bg+len-1);
00886
00887
00888
00889 IndexType typ(b.ixType());
00890 typ.set(dir);
00891 return Box(low,hi,typ);
00892 }
00893
00894 Box
00895 BoxLib::bdryNode (const Box& b,
00896 const Orientation& face,
00897 int len)
00898 {
00899 int dir = face.coordDir();
00900 IntVect low(b.smallEnd());
00901 IntVect hi(b.bigEnd());
00902 if (face.isLow())
00903 {
00904 int sm = low[dir];
00905 hi.setVal(dir,sm+len-1);
00906 }
00907 else
00908 {
00909 unsigned int bitval = b.type()[dir];
00910 int bg = hi[dir] + 1 - bitval%2;
00911 low.setVal(dir,bg);
00912 hi.setVal(dir,bg+len-1);
00913 }
00914
00915
00916
00917 IndexType typ(b.ixType());
00918 typ.set(dir);
00919 return Box(low,hi,typ);
00920 }
00921
00922 Box
00923 BoxLib::adjCellLo (const Box& b,
00924 int dir,
00925 int len)
00926 {
00927 BL_ASSERT(len > 0);
00928 IntVect low(b.smallEnd());
00929 IntVect hi(b.bigEnd());
00930 int sm = low[dir];
00931 low.setVal(dir,sm - len);
00932 hi.setVal(dir,sm - 1);
00933
00934
00935
00936 IndexType typ(b.ixType());
00937 typ.unset(dir);
00938 return Box(low,hi,typ);
00939 }
00940
00941 Box
00942 BoxLib::adjCellHi (const Box& b,
00943 int dir,
00944 int len)
00945 {
00946 BL_ASSERT(len > 0);
00947 IntVect low(b.smallEnd());
00948 IntVect hi(b.bigEnd());
00949 unsigned int bitval = b.type()[dir];
00950 int bg = hi[dir] + 1 - bitval%2;
00951 low.setVal(dir,bg);
00952 hi.setVal(dir,bg + len - 1);
00953
00954
00955
00956 IndexType typ(b.ixType());
00957 typ.unset(dir);
00958 return Box(low,hi,typ);
00959 }
00960
00961 Box
00962 BoxLib::adjCell (const Box& b,
00963 const Orientation& face,
00964 int len)
00965 {
00966 BL_ASSERT(len > 0);
00967 IntVect low(b.smallEnd());
00968 IntVect hi(b.bigEnd());
00969 int dir = face.coordDir();
00970 if (face.isLow())
00971 {
00972 int sm = low[dir];
00973 low.setVal(dir,sm - len);
00974 hi.setVal(dir,sm - 1);
00975 }
00976 else
00977 {
00978 unsigned int bitval = b.type()[dir];
00979 int bg = hi[dir] + 1 - bitval%2;
00980 low.setVal(dir,bg);
00981 hi.setVal(dir,bg + len - 1);
00982 }
00983
00984
00985
00986 IndexType typ(b.ixType());
00987 typ.unset(dir);
00988 return Box(low,hi,typ);
00989 }