00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _CODIMBOXIMPLEM_H_
00012 #define _CODIMBOXIMPLEM_H_
00013
00014 #include "CodimBox.H"
00015
00016 #include "NamespaceHeader.H"
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 template<typename S> int CodimBox<S>::numOrient[CodimBox<S>::numCD] =
00032 {
00033 -1
00034 };
00035 template<typename S> int CodimBox<S>::totOrient[CodimBox<S>::numCD] =
00036 {
00037 -1
00038 };
00039 template<typename S> unsigned CodimBox<S>::bitOrient[CodimBox<S>::numAI] =
00040 {
00041 0
00042 };
00043 template<typename S> int CodimBox<S>::indexFAB[CodimBox<S>::numAI] =
00044 {
00045 -1
00046 };
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 template<typename S> CodimBox<S>::CodimBox()
00058 {
00059 initialize();
00060 }
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 template<typename S> CodimBox<S>::CodimBox(const int a_codim, const Box& a_box, const int a_nvar)
00071 :
00072 m_codim(a_codim)
00073 {
00074 initialize();
00075 define(a_box, a_nvar);
00076 }
00077
00078
00079
00080
00081
00082 template<typename S> CodimBox<S>::~CodimBox()
00083 {
00084 clear();
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 template<typename S> void CodimBox<S>::initialize()
00102 {
00103 if (indexFAB[0] == -1)
00104 {
00105 numOrient[0] = 1;
00106 indexFAB[0] = 0;
00107
00108 for (int i = 1; i != numCD; ++i) numOrient[i] = 0;
00109
00110
00111 int tmpCodim[numCD][numAI];
00112 tmpCodim[0][0] = 0;
00113
00114
00115
00116
00117 for (int i = 1; i != numAI; ++i)
00118 {
00119
00120
00121 unsigned k = i;
00122 int j = (k & 1);
00123 while (k >>= 1)
00124 if (k & 1) ++j;
00125
00126
00127
00128 indexFAB[i] = numOrient[j];
00129
00130 tmpCodim[j][numOrient[j]] = i;
00131 ++numOrient[j];
00132 }
00133
00134
00135
00136
00137
00138 int k = 0;
00139 int cOrient = 0;
00140 for (int iCodim = 0; iCodim != numCD; ++iCodim)
00141 {
00142 const int nOrient = numOrient[iCodim];
00143 totOrient[iCodim] = cOrient;
00144 cOrient += nOrient;
00145 for (int i = 0; i != nOrient; ++i)
00146 bitOrient[k++] = tmpCodim[iCodim][i];
00147 }
00148 }
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 template<typename S> void CodimBox<S>::define(const int a_codim, const Box& a_box, const int a_nvar)
00160 {
00161 CH_assert(a_codim >= 0);
00162 CH_assert(a_codim <= SpaceDim);
00163 m_codim = a_codim;
00164 define(a_box, a_nvar);
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174 template<typename S> void CodimBox<S>::define(const Box& a_box, const int a_nvar)
00175 {
00176 CH_assert(a_nvar > 0);
00177 m_box = a_box;
00178 m_nvar = a_nvar;
00179 clear();
00180 const int nOrient = numOrient[m_codim];
00181 m_S.resize(nOrient);
00182 for (int iOrient = 0; iOrient < nOrient; ++iOrient)
00183 {
00184 const Box cdbox = orientBox(iOrient);
00185 m_S[iOrient] = new S(cdbox, m_nvar);
00186 }
00187 }
00188
00189
00190
00191
00192
00193 template<typename S> void CodimBox<S>::clear()
00194 {
00195 if (m_S.size() != 0)
00196 {
00197 const int nOrient = numOrient[m_codim];
00198 for (int iOrient = 0; iOrient < nOrient; ++iOrient)
00199 {
00200 if (m_S[iOrient] != NULL)
00201 delete m_S[iOrient];
00202 }
00203 m_S.clear();
00204 }
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 template<typename S> int CodimBox<S>::getDirection(const int a_iOrient, int a_i) const
00223 {
00224 CH_assert(a_i < m_codim);
00225 unsigned bOrient = seq2bit(a_iOrient);
00226 int dir = 0;
00227 ++a_i;
00228 while (a_i)
00229 {
00230 if (bOrient & 1)
00231 --a_i;
00232 bOrient >>= 1;
00233 ++dir;
00234 }
00235 return dir - 1;
00236 }
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 template<typename S> const S& CodimBox<S>::operator()(const IndexType &a_ixType) const
00247 {
00248
00249
00250 int count = 0;
00251 unsigned bOrient = 0;
00252 for (int i = 0; i != SpaceDim; ++i)
00253 {
00254 if (a_ixType[i])
00255 {
00256 bOrient += (1 << i);
00257 ++count;
00258 }
00259 }
00260 CH_assert(count == m_codim);
00261 return getS(bOrient);
00262 }
00263
00264 template<typename S> S& CodimBox<S>::operator()(const IndexType &a_ixType)
00265 {
00266
00267
00268 int count = 0;
00269 unsigned bOrient = 0;
00270 for (int i = 0; i != SpaceDim; ++i)
00271 {
00272 if (a_ixType[i])
00273 {
00274 bOrient += (1 << i);
00275 ++count;
00276 }
00277 }
00278 CH_assert(count == m_codim);
00279 return getS(bOrient);
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 template<typename S> const S&CodimBox<S>::operator()() const
00304 {
00305 CH_assert(SpaceDim >= 0);
00306 CH_assert(m_codim == 0 || m_codim == SpaceDim);
00307 return getS((m_codim == 0) ? 0 : numAI - 1);
00308 }
00309
00310 template<typename S> S& CodimBox<S>::operator()()
00311 {
00312 CH_assert(SpaceDim >= 0);
00313 CH_assert(m_codim == 0 || m_codim == SpaceDim);
00314 return getS((m_codim == 0) ? 0 : numAI - 1);
00315 }
00316
00317
00318 template<typename S> const S&CodimBox<S>::operator()(const int a_dir0) const
00319 {
00320 CH_assert(SpaceDim >= 1);
00321 CH_assert(m_codim == 1);
00322 CH_assert(a_dir0 < SpaceDim);
00323 return getS((1 << a_dir0));
00324 }
00325
00326 template<typename S> S&CodimBox<S>::operator()(const int a_dir0)
00327 {
00328 CH_assert(SpaceDim >= 1);
00329 CH_assert(m_codim == 1);
00330 CH_assert(a_dir0 < SpaceDim);
00331 return getS((1 << a_dir0));
00332 }
00333
00334
00335 template<typename S> const S&CodimBox<S>::operator()(const int a_dir0,
00336 const int a_dir1) const
00337 {
00338 CH_assert(SpaceDim >= 2);
00339 CH_assert(m_codim == 2);
00340 CH_assert(a_dir0 < SpaceDim);
00341 CH_assert(a_dir1 < SpaceDim);
00342 CH_assert(a_dir0 != a_dir1);
00343 return getS((1 << a_dir0) +
00344 (1 << a_dir1));
00345 }
00346
00347 template<typename S> S& CodimBox<S>::operator()(const int a_dir0,
00348 const int a_dir1)
00349 {
00350 CH_assert(SpaceDim >= 2);
00351 CH_assert(m_codim == 2);
00352 CH_assert(a_dir0 < SpaceDim);
00353 CH_assert(a_dir1 < SpaceDim);
00354 CH_assert(a_dir0 != a_dir1);
00355 return getS((1 << a_dir0) +
00356 (1 << a_dir1));
00357 }
00358
00359
00360 template<typename S> const S&CodimBox<S>::operator()(const int a_dir0,
00361 const int a_dir1,
00362 const int a_dir2) const
00363 {
00364 CH_assert(SpaceDim >= 3);
00365 CH_assert(m_codim == 3);
00366 CH_assert(a_dir0 < SpaceDim);
00367 CH_assert(a_dir1 < SpaceDim);
00368 CH_assert(a_dir2 < SpaceDim);
00369 CH_assert(a_dir0 != a_dir1);
00370 CH_assert(a_dir1 != a_dir2);
00371 CH_assert(a_dir2 != a_dir0);
00372 return getS((1 << a_dir0) +
00373 (1 << a_dir1) +
00374 (1 << a_dir2));
00375 }
00376
00377 template<typename S> S& CodimBox<S>::operator()(const int a_dir0,
00378 const int a_dir1,
00379 const int a_dir2)
00380 {
00381 CH_assert(SpaceDim >= 3);
00382 CH_assert(m_codim == 3);
00383 CH_assert(a_dir0 < SpaceDim);
00384 CH_assert(a_dir1 < SpaceDim);
00385 CH_assert(a_dir2 < SpaceDim);
00386 CH_assert(a_dir0 != a_dir1);
00387 CH_assert(a_dir1 != a_dir2);
00388 CH_assert(a_dir2 != a_dir0);
00389 return getS((1 << a_dir0) +
00390 (1 << a_dir1) +
00391 (1 << a_dir2));
00392 }
00393
00394
00395 template<typename S> const S& CodimBox<S>::operator()(const int a_dir0,
00396 const int a_dir1,
00397 const int a_dir2,
00398 const int a_dir3) const
00399 {
00400 CH_assert(SpaceDim >= 4);
00401 CH_assert(m_codim == 4);
00402 CH_assert(a_dir0 < SpaceDim);
00403 CH_assert(a_dir1 < SpaceDim);
00404 CH_assert(a_dir2 < SpaceDim);
00405 CH_assert(a_dir3 < SpaceDim);
00406
00407 return getS((1 << a_dir0) +
00408 (1 << a_dir1) +
00409 (1 << a_dir2) +
00410 (1 << a_dir3));
00411 }
00412
00413 template<typename S> S&CodimBox<S>::operator()(const int a_dir0,
00414 const int a_dir1,
00415 const int a_dir2,
00416 const int a_dir3)
00417 {
00418 CH_assert(SpaceDim >= 4);
00419 CH_assert(m_codim == 4);
00420 CH_assert(a_dir0 < SpaceDim);
00421 CH_assert(a_dir1 < SpaceDim);
00422 CH_assert(a_dir2 < SpaceDim);
00423 CH_assert(a_dir3 < SpaceDim);
00424
00425 return getS((1 << a_dir0) +
00426 (1 << a_dir1) +
00427 (1 << a_dir2) +
00428 (1 << a_dir3));
00429 }
00430
00431
00432 template<typename S> const S& CodimBox<S>::operator()(const int a_dir0,
00433 const int a_dir1,
00434 const int a_dir2,
00435 const int a_dir3,
00436 const int a_dir4) const
00437 {
00438 CH_assert(SpaceDim >= 5);
00439 CH_assert(m_codim == 5);
00440 CH_assert(a_dir0 < SpaceDim);
00441 CH_assert(a_dir1 < SpaceDim);
00442 CH_assert(a_dir2 < SpaceDim);
00443 CH_assert(a_dir3 < SpaceDim);
00444 CH_assert(a_dir4 < SpaceDim);
00445
00446 return getS((1 << a_dir0) +
00447 (1 << a_dir1) +
00448 (1 << a_dir2) +
00449 (1 << a_dir3) +
00450 (1 << a_dir4));
00451 }
00452
00453 template<typename S> S& CodimBox<S>::operator()(const int a_dir0,
00454 const int a_dir1,
00455 const int a_dir2,
00456 const int a_dir3,
00457 const int a_dir4)
00458 {
00459 CH_assert(SpaceDim >= 5);
00460 CH_assert(m_codim == 5);
00461 CH_assert(a_dir0 < SpaceDim);
00462 CH_assert(a_dir1 < SpaceDim);
00463 CH_assert(a_dir2 < SpaceDim);
00464 CH_assert(a_dir3 < SpaceDim);
00465 CH_assert(a_dir4 < SpaceDim);
00466
00467 return getS((1 << a_dir0) +
00468 (1 << a_dir1) +
00469 (1 << a_dir2) +
00470 (1 << a_dir3) +
00471 (1 << a_dir4));
00472 }
00473
00474
00475 template<typename S> const S& CodimBox<S>::operator()(const int a_dir0,
00476 const int a_dir1,
00477 const int a_dir2,
00478 const int a_dir3,
00479 const int a_dir4,
00480 const int a_dir5) const
00481 {
00482 CH_assert(SpaceDim >= 6);
00483 CH_assert(m_codim == 6);
00484 CH_assert(a_dir0 < SpaceDim);
00485 CH_assert(a_dir1 < SpaceDim);
00486 CH_assert(a_dir2 < SpaceDim);
00487 CH_assert(a_dir3 < SpaceDim);
00488 CH_assert(a_dir4 < SpaceDim);
00489 CH_assert(a_dir5 < SpaceDim);
00490
00491 return getS((1 << a_dir0) +
00492 (1 << a_dir1) +
00493 (1 << a_dir2) +
00494 (1 << a_dir3) +
00495 (1 << a_dir4) +
00496 (1 << a_dir5));
00497 }
00498
00499 template<typename S> S& CodimBox<S>::operator()(const int a_dir0,
00500 const int a_dir1,
00501 const int a_dir2,
00502 const int a_dir3,
00503 const int a_dir4,
00504 const int a_dir5)
00505 {
00506 CH_assert(SpaceDim >= 6);
00507 CH_assert(m_codim == 6);
00508 CH_assert(a_dir0 < SpaceDim);
00509 CH_assert(a_dir1 < SpaceDim);
00510 CH_assert(a_dir2 < SpaceDim);
00511 CH_assert(a_dir3 < SpaceDim);
00512 CH_assert(a_dir4 < SpaceDim);
00513 CH_assert(a_dir5 < SpaceDim);
00514
00515 return getS((1 << a_dir0) +
00516 (1 << a_dir1) +
00517 (1 << a_dir2) +
00518 (1 << a_dir3) +
00519 (1 << a_dir4) +
00520 (1 << a_dir5));
00521 }
00522
00523
00524
00525
00526
00527
00528
00529 template<typename S> void CodimBox<S>::setVal(const Real a_x)
00530 {
00531 const int nOrient = numOrient[m_codim];
00532 for (int iOrient = 0; iOrient < nOrient; ++iOrient)
00533 {
00534 m_S[iOrient]->setVal(a_x);
00535 }
00536 }
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559 template<typename S> void CodimBox<S>::copy(const Box& a_R,
00560 const Interval& a_Cd,
00561 const CodimBox& a_src,
00562 const Interval& a_Cs)
00563 {
00564 CH_assert(m_codim == a_src.m_codim);
00565 const int nOrient = numOrient[m_codim];
00566 for (int iOrient = 0; iOrient != nOrient; ++iOrient)
00567 {
00568 CH_assert(m_S[iOrient] != NULL);
00569 const S& srcFab = *a_src.m_S[iOrient];
00570
00571 Box cdbox = orientBox(iOrient, a_R);
00572
00573 cdbox &= srcFab.box();
00574 cdbox &= m_S[iOrient]->box();
00575 if (!cdbox.isEmpty())
00576 {
00577 m_S[iOrient]->copy(cdbox, a_Cd, cdbox, srcFab, a_Cs);
00578 }
00579 }
00580 }
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607 template<typename S> void CodimBox<S>::copy(const Box& a_Rs,
00608 const Interval& a_Cd,
00609 const Box& a_Rd,
00610 const CodimBox<S>& a_src,
00611 const Interval& a_Cs)
00612 {
00613 CH_assert(m_codim == a_src.m_codim);
00614 CH_assert(a_Rs.sameSize(a_Rd));
00615 const int nOrient = numOrient[m_codim];
00616 for (int iOrient = 0; iOrient != nOrient; ++iOrient)
00617 {
00618 CH_assert(m_S[iOrient] != NULL);
00619
00620 Box cdboxd = orientBox(iOrient, a_Rd);
00621 cdboxd &= m_S[iOrient]->box();
00622
00623 Box cdboxs = cdboxd;
00624 if (a_Rs != a_Rd)
00625
00626 {
00627 IntVect shiftVect(a_Rs.smallEnd());
00628 shiftVect -= a_Rd.smallEnd();
00629 cdboxs.shift(shiftVect);
00630 }
00631 if (!cdboxd.isEmpty())
00632 {
00633 m_S[iOrient]->copy(cdboxs, a_Cd, cdboxd,
00634 *a_src.m_S[iOrient], a_Cs);
00635 }
00636 }
00637 }
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648 template<typename S> int CodimBox<S>::size(const Box& a_R, const Interval& a_comps) const
00649 {
00650 int totalSize = 0;
00651 S tempFab;
00652 const int nOrient = numOrient[m_codim];
00653 for (int iOrient = 0; iOrient != nOrient; ++iOrient)
00654 {
00655 const Box cdbox = orientBox(iOrient, a_R);
00656 totalSize += tempFab.size(cdbox, a_comps);
00657 }
00658 return totalSize;
00659 }
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672 template<typename S> void CodimBox<S>::linearOut(void* a_buf, const Box& a_R, const Interval& a_comps) const
00673 {
00674 Real* buffer = static_cast<Real*>(a_buf);
00675 const int nOrient = numOrient[m_codim];
00676 for (int iOrient = 0; iOrient != nOrient; ++iOrient)
00677 {
00678 CH_assert(m_S[iOrient] != NULL);
00679 const Box cdbox = orientBox(iOrient, a_R);
00680 const int orientSize = m_S[iOrient]->size(cdbox, a_comps);
00681 m_S[iOrient]->linearOut(buffer, cdbox, a_comps);
00682 buffer += orientSize/sizeof(Real);
00683 }
00684 }
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695 template<typename S> void CodimBox<S>::linearIn(void* a_buf, const Box& a_R, const Interval& a_comps)
00696 {
00697 Real* buffer = static_cast<Real*>(a_buf);
00698 const int nOrient = numOrient[m_codim];
00699 for (int iOrient = 0; iOrient != nOrient; ++iOrient)
00700 {
00701 CH_assert(m_S[iOrient] != NULL);
00702 const Box cdbox = orientBox(iOrient, a_R);
00703 const int orientSize = m_S[iOrient]->size(cdbox, a_comps);
00704 m_S[iOrient]->linearIn(buffer, cdbox, a_comps);
00705 buffer += orientSize/sizeof(Real);
00706 }
00707 }
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731 template<typename S> void CodimBox<S>::genGetDirections(const int a_codim,
00732 int a_bOrient,
00733 int *const a_dir)
00734 {
00735 for (int i = 0; i != a_codim; ++i)
00736 a_dir[i] = 0;
00737 int iStart = 0;
00738 while (a_bOrient)
00739 {
00740 if (a_bOrient & 1)
00741 ++iStart;
00742 a_bOrient >>= 1;
00743 for (int i = iStart; i < a_codim; ++i)
00744 ++a_dir[i];
00745 }
00746 }
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760 template<typename S> Box CodimBox<S>::genOrientBox(int a_bOrient, Box a_cbox)
00761 {
00762 int dir = 0;
00763 while (a_bOrient)
00764 {
00765 if (a_bOrient & 1)
00766 a_cbox.surroundingNodes(dir);
00767 a_bOrient >>= 1;
00768 ++dir;
00769 }
00770 return a_cbox;
00771 }
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797 #include "NamespaceFooter.H"
00798
00799 #endif