00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _IFDATAIMPLEM_H_
00012 #define _IFDATAIMPLEM_H_
00013
00014 #if defined(CH_Darwin) && defined(__GNUC__) && ( __GNUC__ == 3 )
00015
00016 #include <unistd.h>
00017 #define _GLIBCPP_USE_C99 1
00018 #endif
00019
00020 #include <iostream>
00021
00022
00023 template <int dim> inline IFData<dim>::IFData()
00024 {
00025 m_function = NULL;
00026 }
00027
00028
00029 inline IFData<1>::IFData()
00030 :m_dx(0.0)
00031 {
00032 }
00033
00034 template <int dim> inline IFData<dim>::IFData(const IFData<dim>& a_iFData)
00035 :m_cornerSigns(a_iFData.m_cornerSigns),
00036 m_intersections(a_iFData.m_intersections),
00037 m_dx(a_iFData.m_dx),
00038 m_globalCellCenter(a_iFData.m_globalCellCenter),
00039 m_normalDir(a_iFData.m_normalDir),
00040 m_changingDir(a_iFData.m_changingDir),
00041 m_normal(a_iFData.m_normal),
00042 m_gradNormal(a_iFData.m_gradNormal),
00043 m_allVerticesIn(a_iFData.m_allVerticesIn),
00044 m_allVerticesOut(a_iFData.m_allVerticesOut),
00045 m_allVerticesOn(a_iFData.m_allVerticesOn)
00046 {
00047
00048
00049 if (a_iFData.m_function != NULL)
00050 {
00051 m_function = a_iFData.m_function->newImplicitFunction();
00052 }
00053 else
00054 {
00055 m_function = NULL;
00056 }
00057 }
00058
00059 inline IFData<1>::IFData(const IFData<1>& a_iFData)
00060 :m_cornerSigns(a_iFData.m_cornerSigns),
00061 m_intersection(a_iFData.m_intersection),
00062 m_dx(a_iFData.m_dx),
00063 m_allVerticesIn(a_iFData.m_allVerticesIn),
00064 m_allVerticesOut(a_iFData.m_allVerticesOut),
00065 m_allVerticesOn(a_iFData.m_allVerticesOn)
00066 {
00067 }
00068
00069
00070 template <int dim> inline IFData<dim>::IFData(const BaseIF & a_function,
00071 const Rvect & a_dx,
00072 const RvgDim & a_globalCellCenter,
00073 const Vector<int> & a_normalDir)
00074 :m_dx(a_dx),
00075 m_globalCellCenter(a_globalCellCenter)
00076 {
00077
00078 m_normalDir = a_normalDir;
00079 setChangingDirection();
00080
00081
00082 m_function = a_function.newImplicitFunction();
00083
00084
00085 setNormal();
00086
00087
00088 Vector< IndexTM<Real,GLOBALDIM> > globalGradNormal = m_function->gradNormal(m_globalCellCenter);
00089
00090 if (GLOBALDIM==dim)
00091 {
00092 for (int i = 0; i < dim; i++)
00093 {
00094 m_gradNormal.push_back(IndexTM<Real,dim>::Zero);
00095 for (int j = 0; j < dim; j++)
00096 {
00097 m_gradNormal[i][j] = globalGradNormal[i][j];
00098 }
00099 }
00100 }
00101 else if (GLOBALDIM > dim)
00102 {
00103 reduceGradNormal(globalGradNormal,m_function->normal(m_globalCellCenter));
00104 }
00105 else
00106 {
00107 MayDay::Abort("Current dimension is higher than GLOBALDIM");
00108 }
00109
00110
00111
00112 makeCornerSigns();
00113
00114
00115 findIntersectionPts();
00116 }
00117
00118 template <int dim> inline IFData<dim>::IFData(const IFData<dim+1> & a_hIFData,
00119 const int & a_idir,
00120 const int & a_hilo)
00121 {
00122 CH_TIME("IFData::ConstructorReduceInfo");
00123
00124 typedef IndexTM<int,dim+1>HDEdgeIndex;
00125 typedef map<HDEdgeIndex,Real,LexLT<HDEdgeIndex> > HDEdgeIntersections;
00126 typedef IndexTM<int,dim+1>HDVertex;
00127 typedef map<HDVertex,int,LexLT<HDVertex> > HDCornerSigns;
00128
00129
00130 m_function = a_hIFData.m_function->newImplicitFunction();
00131
00132
00133 m_globalCellCenter = a_hIFData.m_globalCellCenter;
00134
00135
00136 int pm = a_hilo;
00137 pm *= 2;
00138 pm -= 1;
00139
00140
00141 m_globalCellCenter[a_idir] += pm*0.5*a_hIFData.m_dx[a_idir];
00142
00143
00144 m_normalDir.push_back(a_idir);
00145 setChangingDirection();
00146
00147 m_allVerticesIn = true;
00148 m_allVerticesOut = true;
00149 m_allVerticesOn = true;
00150 for (typename HDCornerSigns::const_iterator it = a_hIFData.m_cornerSigns.begin();
00151 it != a_hIFData.m_cornerSigns.end(); ++it)
00152 {
00153 const HDVertex& hVertex = it->first;
00154 if (hVertex[a_idir] == a_hilo)
00155 {
00156 Vertex vertex;
00157 for (int j = 0; j < dim; ++j)
00158 {
00159 if (j < a_idir)
00160 {
00161 vertex[j] = hVertex[j];
00162 }
00163 else
00164 {
00165 vertex[j] = hVertex[j+1];
00166 }
00167 }
00168
00169 m_cornerSigns[vertex] = it->second;
00170 if (m_cornerSigns[vertex] == IN)
00171 {
00172 m_allVerticesOut = false;
00173 m_allVerticesOn = false;
00174 }
00175 else if (m_cornerSigns[vertex] == OUT)
00176 {
00177 m_allVerticesIn = false;
00178 m_allVerticesOn = false;
00179 }
00180 }
00181 }
00182
00183 for (typename HDEdgeIntersections::const_iterator it = a_hIFData.m_intersections.begin();
00184 it != a_hIFData.m_intersections.end(); ++it)
00185 {
00186 const HDEdgeIndex& hEdgeIndex = it->first;
00187 EdgeIndex edgeIndex;
00188 int hEdgeDir = hEdgeIndex[0];
00189
00190
00191
00192
00193
00194
00195
00196 if (hEdgeDir < a_idir)
00197 {
00198 if (hEdgeIndex[a_idir] == a_hilo)
00199 {
00200 edgeIndex[0] = hEdgeDir;
00201
00202 for (int j = 1; j < dim; ++j)
00203 {
00204 if (j < a_idir)
00205 {
00206 edgeIndex[j] = hEdgeIndex[j];
00207 }
00208 else
00209 {
00210 edgeIndex[j] = hEdgeIndex[j+1];
00211 }
00212 }
00213 m_intersections[edgeIndex] = it->second;
00214 }
00215 }
00216 else if (hEdgeDir > a_idir)
00217 {
00218 if (hEdgeIndex[a_idir+1] == a_hilo)
00219 {
00220 edgeIndex[0] = hEdgeDir - 1;
00221
00222 for (int j = 1; j < dim; ++j)
00223 {
00224 if (j < a_idir+1)
00225 {
00226 edgeIndex[j] = hEdgeIndex[j];
00227 }
00228 else
00229 {
00230 edgeIndex[j] = hEdgeIndex[j+1];
00231 }
00232 }
00233 m_intersections[edgeIndex] = it->second;
00234 }
00235 }
00236 }
00237
00238
00239
00240 Real mag = 0.0;
00241
00242 IndexTM<Real,GLOBALDIM> localNormal = m_function->normal(m_globalCellCenter);
00243 Vector< IndexTM<Real,GLOBALDIM> > localGradNormal = m_function->gradNormal(m_globalCellCenter);
00244
00245 if (!m_allVerticesOut)
00246 {
00247 for (int jdir = 0; jdir < dim+1; ++jdir)
00248 {
00249 if (jdir < a_idir)
00250 {
00251 m_dx[jdir] = a_hIFData.m_dx[jdir];
00252 m_normal[jdir] = localNormal[jdir];
00253
00254 mag += m_normal[jdir]*m_normal[jdir];
00255 }
00256 else if (jdir > a_idir)
00257 {
00258 m_dx[jdir-1] = a_hIFData.m_dx[jdir];
00259 m_normal[jdir-1] = localNormal[jdir];
00260
00261 mag += m_normal[jdir-1]*m_normal[jdir-1];
00262 }
00263 }
00264
00265 if (mag > 0.0)
00266 {
00267 m_normal /= sqrt(mag);
00268 }
00269 reduceGradNormal(localGradNormal,localNormal);
00270 }
00271 }
00272
00273 inline IFData<1>::IFData(const IFData<2> & a_2DIFData,
00274 const int & a_idir,
00275 const int & a_hilo)
00276 {
00277
00278
00279
00280
00281 m_dx = a_2DIFData.m_dx[(a_idir + 1)%2];
00282
00283 IFData<2>localInfo = a_2DIFData;
00284
00285
00286 IndexTM<int,2>twoDEdge;
00287 twoDEdge[0] = (a_idir + 1)%2;
00288 twoDEdge[1] = a_hilo;
00289
00290 m_intersection = LARGEREALVAL;
00291 if (localInfo.m_intersections.find(twoDEdge) != localInfo.m_intersections.end())
00292 {
00293 m_intersection = localInfo.m_intersections[twoDEdge];
00294 }
00295
00296
00297
00298 IndexTM<int,2>loPt2D;
00299 loPt2D[(a_idir + 1)%2] = 0;
00300 loPt2D[a_idir] = a_hilo;
00301
00302 IndexTM<int,2>hiPt2D;
00303 hiPt2D[(a_idir+ 1)%2] = 1;
00304 hiPt2D[a_idir] = a_hilo;
00305
00306 if (localInfo.m_cornerSigns.find(loPt2D) != localInfo.m_cornerSigns.end())
00307 {
00308 m_cornerSigns[0] = localInfo.m_cornerSigns[loPt2D];
00309 }
00310 else
00311 {
00312 MayDay::Abort("Lo endpoint not in Map");
00313 }
00314
00315 if (localInfo.m_cornerSigns.find(hiPt2D) != localInfo.m_cornerSigns.end())
00316 {
00317 m_cornerSigns[1] = localInfo.m_cornerSigns[hiPt2D];
00318 }
00319 else
00320 {
00321 MayDay::Abort("Hi endpoint not in Map");
00322 }
00323
00324
00325 m_allVerticesIn = true;
00326 m_allVerticesOut = true;
00327 m_allVerticesOn = true;
00328
00329 if (m_cornerSigns[0] != ON || m_cornerSigns[1] != ON)
00330 {
00331 m_allVerticesOn = false;
00332 }
00333
00334 if (m_cornerSigns[0] == IN || m_cornerSigns[1] == IN)
00335 {
00336 m_allVerticesOut = false;
00337 }
00338
00339 if (m_cornerSigns[0] == OUT || m_cornerSigns[1] == OUT)
00340 {
00341 m_allVerticesIn = false;
00342 }
00343 }
00344
00345
00346 template <int dim> inline IFData<dim>::~IFData()
00347 {
00348 if (m_function != NULL)
00349 {
00350 delete m_function;
00351 }
00352 }
00353
00354
00355 inline IFData<1>::~IFData()
00356 {
00357 }
00358
00359 template <int dim> inline void IFData<dim>::reduceGradNormal(const Vector< IndexTM<Real,GLOBALDIM> > & a_gradNormal,
00360 const IndexTM<Real,GLOBALDIM> & a_normal)
00361 {
00362
00363
00364
00365
00366
00367 Real norm = 0.0;
00368 for (int idir = 0; idir < dim; idir++)
00369 {
00370 m_gradNormal.push_back(IndexTM<Real,dim>::Zero);
00371 norm += a_normal[m_changingDir[idir]] * a_normal[m_changingDir[idir]];
00372 }
00373
00374 Real sumNormSquared = norm;
00375 norm = pow(norm,(Real)1.5);
00376
00377 for (int j = 0; j < dim; j++)
00378 {
00379 for (int k = 0; k < dim; k++)
00380 {
00381 if (norm!=0.0)
00382 {
00383 for (int i = 0; i < dim; i++)
00384 {
00385 m_gradNormal[j][k] += a_normal[m_changingDir[i]]
00386 * a_gradNormal[m_changingDir[i]][m_changingDir[k]];
00387 }
00388
00389 m_gradNormal[j][k] *= -a_normal[m_changingDir[j]];
00390 m_gradNormal[j][k] += a_gradNormal[m_changingDir[j]][m_changingDir[k]]
00391 * sumNormSquared;
00392
00393 m_gradNormal[j][k] /= norm;
00394 }
00395 else
00396 {
00397 m_gradNormal[j][k] = a_gradNormal[m_changingDir[j]][m_changingDir[k]];
00398 }
00399 }
00400 }
00401 }
00402
00403 template <int dim> inline void IFData<dim>::setNormal()
00404 {
00405 IndexTM<Real,GLOBALDIM> globalNormal = m_function->normal(m_globalCellCenter);
00406
00407 Real norm = 0.0;
00408 for (int idir = 0; idir < dim; idir++)
00409 {
00410
00411 m_normal[idir] = globalNormal[m_changingDir[idir]];
00412 norm += m_normal[idir] * m_normal[idir];
00413 }
00414
00415 if (norm!=0.0)
00416 {
00417 m_normal /= sqrt(norm);
00418 }
00419 }
00420
00421 template <int dim> inline void IFData<dim>::makeCornerSigns()
00422 {
00423 m_allVerticesIn = true;
00424 m_allVerticesOut = true;
00425 m_allVerticesOn = true;
00426
00427 Vertex vertex;
00428
00429
00430 int numVertices = 1 << dim;
00431 for (int i = 0; i < numVertices; ++i)
00432 {
00433 int ii = i;
00434 for (int j = 0; j < dim; ++j)
00435 {
00436 vertex[j] = (ii & 1);
00437 ii = ii >> 1;
00438 }
00439
00440 RvgDim offset = relCoord(vertex);
00441 Real val = m_function->value(m_globalCellCenter + offset);
00442
00443
00444 if (val == 0)
00445 {
00446 m_cornerSigns[vertex] = ON;
00447 }
00448 else if (val + MACHINEPRECISION < 0)
00449 {
00450 m_cornerSigns[vertex] = IN;
00451 m_allVerticesOut = false;
00452 m_allVerticesOn = false;
00453 }
00454 else if (val - MACHINEPRECISION > 0)
00455 {
00456 m_cornerSigns[vertex] = OUT;
00457 m_allVerticesIn = false;
00458 m_allVerticesOn = false;
00459 }
00460 else
00461 {
00462 m_cornerSigns[vertex] = ON;
00463 }
00464 }
00465 }
00466
00467 template <int dim> inline void IFData<dim>::findIntersectionPts()
00468 {
00469
00470 for (typename CornerSigns::const_iterator it0 = m_cornerSigns.begin();
00471 it0 != m_cornerSigns.end(); ++it0)
00472 {
00473 for (typename CornerSigns::const_iterator it1 = m_cornerSigns.begin();
00474 it1 != m_cornerSigns.end(); ++it1)
00475 {
00476 int edgeDir = LARGEINTVAL;
00477 if (isConnected(edgeDir,it0->first,it1->first))
00478 {
00479
00480 makeEdgeKey(edgeDir,it0->first,it1->first);
00481 }
00482 }
00483 }
00484 }
00485
00486 template <int dim> inline bool IFData<dim>::isConnected(int & a_edgeDir,
00487 const Vertex & a_vertex1,
00488 const Vertex & a_vertex2)
00489 {
00490 bool connected = true;
00491 int numDif = 0;
00492
00493
00494
00495 for (int idir = 0; idir < dim; ++idir)
00496 {
00497 if (a_vertex1[idir] != a_vertex2[idir])
00498 {
00499
00500 a_edgeDir = idir;
00501 numDif += 1;
00502 }
00503 }
00504
00505 if (numDif == 1)
00506 {
00507 connected = true;
00508 }
00509 else
00510 {
00511 connected = false;
00512 a_edgeDir = LARGEINTVAL;
00513 }
00514
00515 return connected;
00516 }
00517
00518 template <int dim> inline void IFData<dim>::makeEdgeKey(const int & a_edgeDir,
00519 const Vertex & a_vertex0,
00520 const Vertex & a_vertex1)
00521 {
00522 EdgeIndex thisEdge;
00523 thisEdge[0] = a_edgeDir;
00524 for (int idir = 0; idir < dim; ++idir)
00525 {
00526 if (idir < a_edgeDir)
00527 {
00528 thisEdge[idir + 1] = a_vertex0[idir];
00529 }
00530 else if (idir > a_edgeDir)
00531 {
00532 thisEdge[idir] = a_vertex0[idir];
00533 }
00534 }
00535
00536 int lo = LARGEINTVAL;
00537 int hi = LARGEINTVAL;
00538 if (m_cornerSigns.find(a_vertex0)!= m_cornerSigns.end())
00539 {
00540 lo = m_cornerSigns.find(a_vertex0)->second;
00541 }
00542 else
00543 {
00544 MayDay::Abort("Vertex not well defined in makeEdgeKey");
00545 }
00546
00547 if (m_cornerSigns.find(a_vertex1)!= m_cornerSigns.end())
00548 {
00549 hi = m_cornerSigns.find(a_vertex1)->second;
00550 }
00551 else
00552 {
00553 MayDay::Abort("Vertex not well defined in makeEdgeKey");
00554 }
00555
00556 if ((lo==OUT && hi==IN)||(lo==IN && hi==OUT))
00557 {
00558
00559 Real pt = rootFinder(thisEdge);
00560
00561
00562 bool hiOn;
00563 bool loOn;
00564 checkIntersection(hiOn,loOn,pt);
00565 if (hiOn || loOn)
00566 {
00567 if (hiOn)
00568 {
00569 m_cornerSigns[a_vertex1] = ON;
00570 }
00571 else if (loOn)
00572 {
00573 m_cornerSigns[a_vertex0] = ON;
00574 }
00575
00576 remakeCornerSigns();
00577 }
00578 else
00579 {
00580 m_intersections[thisEdge] = pt;
00581 }
00582 }
00583 }
00584
00585 template <int dim> inline Real IFData<dim>::rootFinder(const EdgeIndex& a_thisEdge)
00586 {
00587
00588 Real pt = LARGEREALVAL;
00589
00590 int edgeDir = a_thisEdge[0];
00591
00592 Vertex loEnd;
00593 loEnd[edgeDir] = 0;
00594
00595 Vertex hiEnd;
00596 hiEnd[edgeDir] = 1;
00597
00598 for (int idir = 0; idir < dim; ++idir)
00599 {
00600 if (idir < edgeDir)
00601 {
00602 loEnd[idir] = a_thisEdge[idir + 1];
00603 hiEnd[idir] = a_thisEdge[idir + 1];
00604 }
00605 else if (idir > edgeDir)
00606 {
00607 loEnd[idir] = a_thisEdge[idir];
00608 hiEnd[idir] = a_thisEdge[idir];
00609 }
00610 }
00611
00612
00613 RvgDim loOffset = relCoord(loEnd);
00614 RvgDim hiOffset = relCoord(hiEnd);
00615
00616
00617 RvgDim loPt = loOffset + m_globalCellCenter;
00618 RvgDim hiPt = hiOffset + m_globalCellCenter;
00619
00620
00621 int globalEdgeDir = m_changingDir[edgeDir];
00622
00623
00624
00625 pt = BrentRootFinder(loPt,hiPt,globalEdgeDir);
00626
00627
00628
00629
00630
00631
00632 return pt;
00633 }
00634
00635 template <int dim> inline Real IFData<dim>::midPtRootFinder(const Rvect & loPt,
00636 const Rvect & hiPt) const
00637 {
00638 Real dist = LARGEREALVAL;
00639
00640
00641 const unsigned int MAXITER = 100;
00642
00643 #if defined(CH_USE_DOUBLE)
00644 const Real EPS = 3.0e-15;
00645 #elif defined(CH_USE_FLOAT)
00646 const Real EPS = 3.0e-7;
00647 #else
00648 #error Unknown Chombo precision
00649 #endif
00650
00651 const Real tol = 10.0*EPS;
00652 Rvect aPt;
00653 Rvect bPt;
00654 Rvect xMid;
00655
00656 Real phi_aPt = m_function->value(loPt);
00657 Real phi_bPt = m_function->value(hiPt);
00658 Real phi_xMid = LARGEREALVAL;
00659
00660 aPt = loPt;
00661 bPt = hiPt;
00662
00663 int iter;
00664 if (phi_aPt*phi_bPt > 0)
00665 {
00666 MayDay::Abort("root must be bracketed");
00667 }
00668 else
00669 {
00670 for (iter = 0; iter < MAXITER; iter++)
00671 {
00672 xMid = 0.5*(aPt + bPt);
00673
00674 phi_xMid = m_function->value(xMid);
00675 if (Abs(phi_xMid) > tol)
00676 {
00677 if (phi_bPt*phi_xMid > 0)
00678 {
00679 bPt = xMid;
00680 }
00681 else
00682 {
00683 aPt = xMid;
00684 }
00685 }
00686 else
00687 {
00688 break;
00689 }
00690 }
00691
00692 if (iter >= MAXITER)
00693 {
00694 cerr << "rootFinder: exceeding maximum iterations: "
00695 << MAXITER << "\n";
00696 }
00697 else
00698 {
00699 dist = 0.0;
00700 for (int idir = 0; idir < SpaceDim; ++idir)
00701 {
00702 dist += (xMid[idir] - loPt[idir])*(xMid[idir] - loPt[idir]);
00703 }
00704 dist = sqrt(dist);
00705 }
00706 }
00707
00708 return dist;
00709 }
00710
00711 template <int dim> inline Real IFData<dim>::BrentRootFinder(const RvgDim & a_loPt,
00712 const RvgDim & a_hiPt,
00713 const int & a_edgeDir) const
00714 {
00715
00716 const unsigned int MAXITER = 100;
00717 const Real EPS = 3.0e-15;
00718
00719 unsigned int i;
00720 Real aPt;
00721 Real bPt;
00722 Real c, fa, fb, fc;
00723 Real d, e;
00724 Real tol1, xm;
00725 Real p, q, r, s;
00726
00727 aPt = -1.0;
00728 bPt = 1.0;
00729
00730 RvgDim physCoordAPt = a_loPt;
00731 RvgDim physCoordBPt = a_hiPt;
00732
00733 fa = -m_function->value(physCoordAPt);
00734 fb = -m_function->value(physCoordBPt);
00735
00736
00737 c = d = e = 0.0;
00738
00739 if (fb*fa > 0)
00740 {
00741 MayDay::Error("root must be bracketed");
00742 }
00743
00744 fc = fb;
00745
00746 for (i = 0; i < MAXITER; i++)
00747 {
00748 if (fb*fc > 0)
00749 {
00750
00751 c = aPt;
00752 fc = fa;
00753 d = bPt - aPt;
00754 e = d;
00755 }
00756
00757 if (Abs(fc) < Abs(fb))
00758 {
00759 aPt = bPt;
00760 bPt = c;
00761 c = aPt;
00762 fa = fb;
00763 fb = fc;
00764 fc = fa;
00765 }
00766
00767
00768 tol1 = 2.0 * EPS * Abs(bPt) + 0.5 * TOLERANCE;
00769 xm = 0.5 * (c - bPt);
00770
00771 if (Abs(xm) <= tol1 || fb == 0.0)
00772 {
00773 break;
00774 }
00775
00776 if (Abs(e) >= tol1 && Abs(fa) > Abs(fb))
00777 {
00778
00779 s = fb / fa;
00780 if (aPt == c)
00781 {
00782 p = 2.0 * xm * s;
00783 q = 1.0 - s;
00784 }
00785 else
00786 {
00787 q = fa / fc;
00788 r = fb / fc;
00789 p = s * (2.0 * xm * q * (q-r) - (bPt-aPt) * (r-1.0));
00790 q = (q-1.0) * (r-1.0) * (s-1.0);
00791 }
00792
00793
00794 if (p > 0) q = -q;
00795
00796 p = Abs(p);
00797
00798 if (2.0 * p < Min(((Real)3.0)*xm*q-Abs(tol1*q), Abs(e*q)))
00799 {
00800
00801 e = d;
00802 d = p / q;
00803 }
00804 else
00805 {
00806
00807 d = xm;
00808 e = d;
00809 }
00810 }
00811 else
00812 {
00813
00814 d = xm;
00815 e = d;
00816 }
00817
00818
00819 aPt = bPt;
00820 fa = fb;
00821
00822
00823 if (Abs(d) > tol1)
00824 {
00825 bPt = bPt + d;
00826 }
00827 else
00828 {
00829 if (xm < 0) bPt = bPt - tol1;
00830 else bPt = bPt + tol1;
00831 }
00832
00833 physCoordBPt[a_edgeDir] = ((1.0 - bPt)/2.0) * a_loPt[a_edgeDir] + ((1.0 + bPt)/2.0) * a_hiPt[a_edgeDir];
00834 fb = -m_function->value(physCoordBPt);
00835 }
00836
00837 if (i >= MAXITER)
00838 {
00839 cerr << "BrentRootFinder: exceeding maximum iterations: "
00840 << MAXITER << "\n";
00841 }
00842
00843 return bPt;
00844 }
00845
00846 template <int dim> inline void IFData<dim>::checkIntersection(bool & a_hiOn,
00847 bool & a_loOn,
00848 const Real & a_pt) const
00849 {
00850 a_hiOn = false;
00851 a_loOn = false;
00852
00853 if (a_pt >= 1.0 - MACHINEPRECISION)
00854 {
00855 a_hiOn = true;
00856 }
00857 else if (a_pt <= -1.0 + MACHINEPRECISION)
00858 {
00859 a_loOn = true;
00860 }
00861 }
00862
00863 template <int dim> inline void IFData<dim>::remakeCornerSigns()
00864 {
00865 m_allVerticesIn = true;
00866 m_allVerticesOut = true;
00867 m_allVerticesOn = true;
00868
00869 for (typename CornerSigns::const_iterator it = m_cornerSigns.begin();
00870 it != m_cornerSigns.end(); ++it)
00871 {
00872 if (it->second == IN)
00873 {
00874 m_allVerticesOut = false;
00875 }
00876
00877 if (it->second == OUT)
00878 {
00879 m_allVerticesIn = false;
00880 }
00881
00882 if (it->second != ON)
00883 {
00884 m_allVerticesOn = false;
00885 }
00886 }
00887 }
00888
00889 template <int dim> inline void IFData<dim>::print(ostream& a_out) const
00890 {
00891 for (typename CornerSigns::const_iterator it = m_cornerSigns.begin();
00892 it != m_cornerSigns.end(); ++it)
00893 {
00894 a_out << "Vertex " << "(" << it->first << ") = " << it->second << "\n";
00895 }
00896
00897 for (typename EdgeIntersections::const_iterator it = m_intersections.begin();
00898 it != m_intersections.end(); ++it)
00899 {
00900 a_out << "EdgeIndex " << it->first << " = " << it->second << "\n";
00901 }
00902
00903 a_out << "allVerticesIn = " << m_allVerticesIn << "\n";
00904 a_out << "allVerticesOut = " << m_allVerticesOut << "\n";
00905 a_out << "allVerticesOn = " << m_allVerticesOn << "\n";
00906
00907 if (!m_allVerticesOut)
00908 {
00909 a_out << "m_dx = " << m_dx << "\n";
00910 a_out << "m_normalDir" << m_normalDir << "\n";
00911 a_out << "m_normal = " << m_normal << "\n";
00912 a_out << "m_gradNormal = " << m_gradNormal << "\n";
00913 a_out << "m_globalCellCenter = " << m_globalCellCenter << "\n";
00914 }
00915 else
00916 {
00917 a_out << "normal and dx not defined : all Vertices Out";
00918 }
00919 }
00920
00921 inline void IFData<1>::print(ostream& a_out) const
00922 {
00923 typedef map<int,int> oneDCornerSigns;
00924 for (oneDCornerSigns::const_iterator it = m_cornerSigns.begin();
00925 it != m_cornerSigns.end(); ++it)
00926 {
00927 a_out << "Vertex " << "(" << it->first << ") = " << it->second << "\n";
00928 }
00929
00930 a_out << "m_allVerticesIn = " << m_allVerticesIn << "\n";
00931 a_out << "m_allVerticesOut = " << m_allVerticesOut << "\n";
00932 a_out << "m_allVerticesOn = " << m_allVerticesOn << "\n";
00933
00934 if (!m_allVerticesOut)
00935 {
00936 a_out << "m_dx = " << m_dx << "\n";
00937 }
00938
00939 int lo = LARGEINTVAL;
00940 int hi = LARGEINTVAL;
00941 if (m_cornerSigns.find(0)!= m_cornerSigns.end())
00942 {
00943 lo = m_cornerSigns.find(0)->second;
00944 }
00945 else
00946 {
00947 MayDay::Abort("no lo in cornerSigns");
00948 }
00949
00950 if (m_cornerSigns.find(1)!= m_cornerSigns.end())
00951 {
00952 hi = m_cornerSigns.find(1)->second;
00953 }
00954 else
00955 {
00956 MayDay::Abort("no hi in cornerSigns");
00957 }
00958
00959 if (lo == OUT && hi == OUT)
00960 {
00961 a_out << "Edge Covered" << "\n";
00962 }
00963 else if (lo==IN && hi==IN)
00964 {
00965 a_out << "Edge Uncovered" << "\n";
00966 }
00967 else if (lo==ON || hi==ON)
00968 {
00969 a_out << "Edge has vertex on the interface" << "\n";
00970 }
00971 else
00972 {
00973 if (m_intersection == LARGEREALVAL)
00974 {
00975 MayDay::Warning("no intersection pt");
00976 }
00977 else
00978 {
00979 a_out << "Intersection pt is " << m_intersection << "\n";
00980 }
00981 }
00982 }
00983
00984 template <int dim> inline void IFData<dim>::dump() const
00985 {
00986 print(pout());
00987 }
00988
00989 template <int dim> inline ostream& operator<<(ostream & a_out,
00990 const IFData<dim> & a_iFData)
00991 {
00992 a_iFData.print(a_out);
00993 return a_out;
00994 }
00995
00996
00997 template <int dim> inline void IFData<dim>::operator=(const IFData & a_iFData)
00998 {
00999 m_cornerSigns = a_iFData.m_cornerSigns;
01000 m_intersections = a_iFData.m_intersections;
01001
01002
01003 if (a_iFData.m_function != NULL)
01004 {
01005 m_function = a_iFData.m_function->newImplicitFunction();
01006 }
01007 else
01008 {
01009 m_function = NULL;
01010 }
01011
01012 m_dx = a_iFData.m_dx;
01013 m_globalCellCenter = a_iFData.m_globalCellCenter;
01014
01015 m_normalDir = a_iFData.m_normalDir;
01016 m_changingDir = a_iFData.m_changingDir;
01017 m_normal = a_iFData.m_normal;
01018
01019 m_gradNormal = a_iFData.m_gradNormal;
01020
01021 m_allVerticesIn = a_iFData.m_allVerticesIn;
01022 m_allVerticesOut = a_iFData.m_allVerticesOut;
01023 m_allVerticesOn = a_iFData.m_allVerticesOn;
01024 }
01025
01026
01027 inline void IFData<1>::operator=(const IFData & a_iFData)
01028 {
01029 m_cornerSigns = a_iFData.m_cornerSigns;
01030 m_intersection = a_iFData.m_intersection;
01031
01032 m_dx = a_iFData.m_dx;
01033
01034 m_allVerticesIn = a_iFData.m_allVerticesIn;
01035 m_allVerticesOut = a_iFData.m_allVerticesOut;
01036 m_allVerticesOn = a_iFData.m_allVerticesOn;
01037 }
01038
01039
01040 template <int dim> inline IndexTM<Real,GLOBALDIM> IFData<dim>::relCoord(const Vertex & a_vertex)
01041 {
01042 RvgDim retval=IndexTM<Real,GLOBALDIM>::Zero;
01043 Rvect hilo;
01044
01045 for (int idir = 0; idir < dim; ++idir)
01046 {
01047 hilo[idir] = a_vertex[idir] - 0.5;
01048 retval[m_changingDir[idir]] = hilo[idir]*m_dx[idir];
01049 }
01050
01051 return retval;
01052 }
01053
01054 template <int dim> inline void IFData<dim>::setChangingDirection()
01055 {
01056 if (m_normalDir.size()==0)
01057 {
01058 for (int i = 0 ; i < GLOBALDIM ; ++i)
01059 {
01060 m_changingDir.push_back(i);
01061 }
01062 }
01063 else
01064 {
01065 for (int i = 0 ; i < GLOBALDIM ; ++i)
01066 {
01067 if (searchNormalDir(i) == false)
01068 {
01069 m_changingDir.push_back(i);
01070 }
01071 }
01072 }
01073 }
01074
01075
01076 template <int dim> inline bool IFData<dim>::searchNormalDir(const int i) const
01077 {
01078 int size = m_normalDir.size();
01079
01080 for (int j = 0; j < size; j++)
01081 {
01082 if (m_normalDir[j] == i)
01083 {
01084 return true;
01085 }
01086 }
01087
01088 return false;
01089 }
01090
01091 #endif