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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "SundanceBasicSimplicialMesh.hpp"
00043 #include "SundanceMeshType.hpp"
00044 #include "SundanceCellJacobianBatch.hpp"
00045 #include "SundanceMaximalCofacetBatch.hpp"
00046 #include "SundanceMeshSource.hpp"
00047 #include "SundanceDebug.hpp"
00048 #include "SundanceOut.hpp"
00049 #include "PlayaMPIContainerComm.hpp"
00050 #include "Teuchos_Time.hpp"
00051 #include "Teuchos_TimeMonitor.hpp"
00052 #include "SundanceObjectWithVerbosity.hpp"
00053 #include "SundanceCollectiveExceptionCheck.hpp"
00054
00055 #include <algorithm>
00056 #include <unistd.h>
00057
00058 using namespace Sundance;
00059 using namespace Teuchos;
00060 using Playa::MPIComm;
00061 using Playa::MPIContainerComm;
00062
00063 using std::endl;
00064
00065
00066 #ifdef BSM_LOW_LEVEL_TIMER
00067
00068 static Time& getAddElementTimer()
00069 {
00070 static RCP<Time> rtn
00071 = TimeMonitor::getNewTimer("BSM addElement");
00072 return *rtn;
00073 }
00074
00075 static Time& getFacetRegistrationTimer()
00076 {
00077 static RCP<Time> rtn
00078 = TimeMonitor::getNewTimer("BSM element facet registration");
00079 return *rtn;
00080 }
00081
00082
00083 static Time& getAddVertexTimer()
00084 {
00085 static RCP<Time> rtn
00086 = TimeMonitor::getNewTimer("BSM addVertex");
00087 return *rtn;
00088 }
00089
00090
00091 static Time& getAddEdgeTimer()
00092 {
00093 static RCP<Time> rtn
00094 = TimeMonitor::getNewTimer("BSM addEdge");
00095 return *rtn;
00096 }
00097
00098 static Time& getAddFaceTimer()
00099 {
00100 static RCP<Time> rtn
00101 = TimeMonitor::getNewTimer("BSM addFace");
00102 return *rtn;
00103 }
00104
00105 static Time& getLookupLIDTimer()
00106 {
00107 static RCP<Time> rtn
00108 = TimeMonitor::getNewTimer("BSM lookup LID");
00109 return *rtn;
00110 }
00111
00112 #endif
00113
00114 static Time& batchedFacetGrabTimer()
00115 {
00116 static RCP<Time> rtn
00117 = TimeMonitor::getNewTimer("batched facet grabbing");
00118 return *rtn;
00119 }
00120
00121 void sort(const Array<int>& in, Array<int>& rtn)
00122 {
00123 rtn.resize(in.size());
00124 const int* pIn = &(in[0]);
00125 int* pRtn = &(rtn[0]);
00126 for (int i=0; i<in.size(); i++) pRtn[i] = pIn[i];
00127
00128 for (int j=1; j<in.size(); j++)
00129 {
00130 int key = pRtn[j];
00131 int i=j-1;
00132 while (i>=0 && pRtn[i]>key)
00133 {
00134 pRtn[i+1]=pRtn[i];
00135 i--;
00136 }
00137 pRtn[i+1]=key;
00138 }
00139
00140 }
00141
00142
00143 static Time& getJacobianTimer()
00144 {
00145 static RCP<Time> rtn
00146 = TimeMonitor::getNewTimer("cell Jacobian grabbing");
00147 return *rtn;
00148 }
00149
00150
00151
00152
00153 BasicSimplicialMesh::BasicSimplicialMesh(int dim, const MPIComm& comm,
00154 const MeshEntityOrder& order)
00155 : IncrementallyCreatableMesh(dim, comm, order),
00156 numCells_(dim+1),
00157 points_(),
00158 edgeVerts_(2),
00159 faceVertLIDs_(dim),
00160 faceVertGIDs_(dim),
00161 faceEdges_(dim),
00162 faceEdgeSigns_(dim),
00163 elemVerts_(dim+1),
00164 elemEdges_(),
00165 elemEdgeSigns_(),
00166 elemFaces_(dim+1),
00167 elemFaceRotations_(dim+1),
00168 vertexSetToFaceIndexMap_(),
00169 edgeFaces_(),
00170 edgeCofacets_(),
00171 faceCofacets_(),
00172 vertEdges_(),
00173 vertFaces_(),
00174 vertCofacets_(),
00175 vertEdgePartners_(),
00176 LIDToGIDMap_(dim+1),
00177 GIDToLIDMap_(dim+1),
00178 labels_(dim+1),
00179 ownerProcID_(dim+1),
00180 faceVertGIDBase_(1),
00181 hasEdgeGIDs_(false),
00182 hasFaceGIDs_(false),
00183 neighbors_(),
00184 neighborsAreSynchronized_(false)
00185 {
00186 estimateNumVertices(1000);
00187 estimateNumElements(1000);
00188
00189
00190
00191
00192 faceVertGIDs_.resize(1);
00193 faceVertGIDBase_[0] = &(faceVertGIDs_.value(0,0));
00194 faceVertGIDs_.resize(0);
00195
00196
00197 if (spatialDim()==2)
00198 {
00199 elemEdges_.setTupleSize(3);
00200 elemEdgeSigns_.setTupleSize(3);
00201 }
00202 if (spatialDim()==3)
00203 {
00204 elemEdges_.setTupleSize(6);
00205 elemEdgeSigns_.setTupleSize(6);
00206 }
00207
00208 neighbors_.put(comm.getRank());
00209 }
00210
00211
00212 void BasicSimplicialMesh::getJacobians(int cellDim, const Array<int>& cellLID,
00213 CellJacobianBatch& jBatch) const
00214 {
00215 TimeMonitor timer(getJacobianTimer());
00216
00217 int flops = 0 ;
00218 int nCells = cellLID.size();
00219
00220 TEUCHOS_TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), std::logic_error,
00221 "cellDim=" << cellDim
00222 << " is not in expected range [0, " << spatialDim()
00223 << "]");
00224
00225 jBatch.resize(cellLID.size(), spatialDim(), cellDim);
00226
00227 if (cellDim < spatialDim())
00228 {
00229 switch(cellDim)
00230 {
00231 case 1:
00232 flops += 3*nCells;
00233 break;
00234 case 2:
00235
00236 flops += (4 + 10)*nCells;
00237 break;
00238 default:
00239 break;
00240 }
00241
00242 for (int i=0; i<nCells; i++)
00243 {
00244 int lid = cellLID[i];
00245 double* detJ = jBatch.detJ(i);
00246 switch(cellDim)
00247 {
00248 case 0:
00249 *detJ = 1.0;
00250 break;
00251 case 1:
00252 {
00253 int a = edgeVerts_.value(lid, 0);
00254 int b = edgeVerts_.value(lid, 1);
00255 const Point& pa = points_[a];
00256 const Point& pb = points_[b];
00257 Point dx = pb-pa;
00258 *detJ = sqrt(dx*dx);
00259 }
00260 break;
00261 case 2:
00262 {
00263 int a = faceVertLIDs_.value(lid, 0);
00264 int b = faceVertLIDs_.value(lid, 1);
00265 int c = faceVertLIDs_.value(lid, 2);
00266 const Point& pa = points_[a];
00267 const Point& pb = points_[b];
00268 const Point& pc = points_[c];
00269 Point directedArea = cross(pc-pa, pb-pa);
00270 *detJ = sqrt(directedArea*directedArea);
00271 }
00272 break;
00273 default:
00274 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value "
00275 "cellDim=" << cellDim
00276 << " in BasicSimplicialMesh::getJacobians()");
00277 }
00278 }
00279 }
00280 else
00281 {
00282 Array<double> J(cellDim*cellDim);
00283
00284 flops += cellDim*cellDim*nCells;
00285
00286 for (int i=0; i<cellLID.size(); i++)
00287 {
00288 int lid = cellLID[i];
00289 double* J = jBatch.jVals(i);
00290 switch(cellDim)
00291 {
00292 case 0:
00293 J[0] = 1.0;
00294 break;
00295 case 1:
00296 {
00297 int a = elemVerts_.value(lid, 0);
00298 int b = elemVerts_.value(lid, 1);
00299 const Point& pa = points_[a];
00300 const Point& pb = points_[b];
00301 J[0] = fabs(pa[0]-pb[0]);
00302 }
00303 break;
00304 case 2:
00305 {
00306 int a = elemVerts_.value(lid, 0);
00307 int b = elemVerts_.value(lid, 1);
00308 int c = elemVerts_.value(lid, 2);
00309 const Point& pa = points_[a];
00310 const Point& pb = points_[b];
00311 const Point& pc = points_[c];
00312 J[0] = pb[0] - pa[0];
00313 J[1] = pc[0] - pa[0];
00314 J[2] = pb[1] - pa[1];
00315 J[3] = pc[1] - pa[1];
00316
00317 }
00318 break;
00319 case 3:
00320 {
00321 int a = elemVerts_.value(lid, 0);
00322 int b = elemVerts_.value(lid, 1);
00323 int c = elemVerts_.value(lid, 2);
00324 int d = elemVerts_.value(lid, 3);
00325 const Point& pa = points_[a];
00326 const Point& pb = points_[b];
00327 const Point& pc = points_[c];
00328 const Point& pd = points_[d];
00329 J[0] = pb[0] - pa[0];
00330 J[1] = pc[0] - pa[0];
00331 J[2] = pd[0] - pa[0];
00332 J[3] = pb[1] - pa[1];
00333 J[4] = pc[1] - pa[1];
00334 J[5] = pd[1] - pa[1];
00335 J[6] = pb[2] - pa[2];
00336 J[7] = pc[2] - pa[2];
00337 J[8] = pd[2] - pa[2];
00338 }
00339 break;
00340 default:
00341 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value "
00342 "cellDim=" << cellDim
00343 << " in BasicSimplicialMesh::getJacobians()");
00344 }
00345 }
00346 }
00347 CellJacobianBatch::addFlops(flops);
00348 }
00349
00350
00351
00352 void BasicSimplicialMesh::getCellDiameters(int cellDim, const Array<int>& cellLID,
00353 Array<double>& cellDiameters) const
00354 {
00355 TEUCHOS_TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), std::logic_error,
00356 "cellDim=" << cellDim
00357 << " is not in expected range [0, " << spatialDim()
00358 << "]");
00359
00360 cellDiameters.resize(cellLID.size());
00361
00362 if (cellDim < spatialDim())
00363 {
00364 for (int i=0; i<cellLID.size(); i++)
00365 {
00366 int lid = cellLID[i];
00367 switch(cellDim)
00368 {
00369 case 0:
00370 cellDiameters[i] = 1.0;
00371 break;
00372 case 1:
00373 {
00374 int a = edgeVerts_.value(lid, 0);
00375 int b = edgeVerts_.value(lid, 1);
00376 const Point& pa = points_[a];
00377 const Point& pb = points_[b];
00378 Point dx = pb-pa;
00379 cellDiameters[i] = sqrt(dx*dx);
00380 }
00381 break;
00382 case 2:
00383 {
00384 int a = faceVertLIDs_.value(lid, 0);
00385 int b = faceVertLIDs_.value(lid, 1);
00386 int c = faceVertLIDs_.value(lid, 2);
00387 const Point& pa = points_[a];
00388 const Point& pb = points_[b];
00389 const Point& pc = points_[c];
00390 Point directedArea = cross(pc-pa, pb-pa);
00391 cellDiameters[i] = sqrt(directedArea*directedArea);
00392 }
00393 break;
00394 default:
00395 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value "
00396 "cellDim=" << cellDim
00397 << " in BasicSimplicialMesh::getCellDiameters()");
00398 }
00399 }
00400 }
00401 else
00402 {
00403 for (int i=0; i<cellLID.size(); i++)
00404 {
00405 int lid = cellLID[i];
00406 switch(cellDim)
00407 {
00408 case 0:
00409 cellDiameters[i] = 1.0;
00410 break;
00411 case 1:
00412 {
00413 int a = elemVerts_.value(lid, 0);
00414 int b = elemVerts_.value(lid, 1);
00415 const Point& pa = points_[a];
00416 const Point& pb = points_[b];
00417 cellDiameters[i] = fabs(pa[0]-pb[0]);
00418 }
00419 break;
00420 case 2:
00421 {
00422 int a = elemVerts_.value(lid, 0);
00423 int b = elemVerts_.value(lid, 1);
00424 int c = elemVerts_.value(lid, 2);
00425 const Point& pa = points_[a];
00426 const Point& pb = points_[b];
00427 const Point& pc = points_[c];
00428 cellDiameters[i]
00429 = (pa.distance(pb) + pb.distance(pc) + pa.distance(pc))/3.0;
00430 }
00431 break;
00432 case 3:
00433 {
00434 int a = elemVerts_.value(lid, 0);
00435 int b = elemVerts_.value(lid, 1);
00436 int c = elemVerts_.value(lid, 2);
00437 int d = elemVerts_.value(lid, 3);
00438 const Point& pa = points_[a];
00439 const Point& pb = points_[b];
00440 const Point& pc = points_[c];
00441 const Point& pd = points_[d];
00442
00443 cellDiameters[i]
00444 = (pa.distance(pb) + pa.distance(pc) + pa.distance(pd)
00445 + pb.distance(pc) + pb.distance(pd)
00446 + pc.distance(pd))/6.0;
00447 }
00448 break;
00449 default:
00450 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value "
00451 "cellDim=" << cellDim
00452 << " in BasicSimplicialMesh::getCellDiameters()");
00453 }
00454 }
00455 }
00456 }
00457
00458
00459 void BasicSimplicialMesh::pushForward(int cellDim, const Array<int>& cellLID,
00460 const Array<Point>& refQuadPts,
00461 Array<Point>& physQuadPts) const
00462 {
00463 TEUCHOS_TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), std::logic_error,
00464 "cellDim=" << cellDim
00465 << " is not in expected range [0, " << spatialDim()
00466 << "]");
00467 int flops = 0;
00468 int nQuad = refQuadPts.size();
00469 int nCells = cellLID.size();
00470 Array<double> J(cellDim*cellDim);
00471
00472 if (physQuadPts.size() > 0) physQuadPts.resize(0);
00473 physQuadPts.reserve(cellLID.size() * refQuadPts.size());
00474
00475 switch(cellDim)
00476 {
00477 case 1:
00478 flops += nCells * (1 + 2*nQuad);
00479 break;
00480 case 2:
00481 if (spatialDim()==2)
00482 {
00483 flops += nCells*(4 + 8*nQuad);
00484 }
00485 else
00486 {
00487 flops += 18*nCells*nQuad;
00488 }
00489 break;
00490 case 3:
00491 flops += 27*nCells*nQuad;
00492 break;
00493 default:
00494 break;
00495 }
00496
00497
00498 for (int i=0; i<cellLID.size(); i++)
00499 {
00500 int lid = cellLID[i];
00501 switch(cellDim)
00502 {
00503 case 0:
00504 physQuadPts.append(points_[lid]);
00505 break;
00506 case 1:
00507 {
00508 int a, b;
00509 if (spatialDim()==1)
00510 {
00511 a = elemVerts_.value(lid, 0);
00512 b = elemVerts_.value(lid, 1);
00513 }
00514 else
00515 {
00516 a = edgeVerts_.value(lid, 0);
00517 b = edgeVerts_.value(lid, 1);
00518 }
00519 const Point& pa = points_[a];
00520 const Point& pb = points_[b];
00521 Point dx = pb-pa;
00522 for (int q=0; q<nQuad; q++)
00523 {
00524 physQuadPts.append(pa + refQuadPts[q][0]*dx);
00525 }
00526 }
00527 break;
00528 case 2:
00529 {
00530 int a,b,c;
00531 if (spatialDim()==2)
00532 {
00533 a = elemVerts_.value(lid, 0);
00534 b = elemVerts_.value(lid, 1);
00535 c = elemVerts_.value(lid, 2);
00536 }
00537 else
00538 {
00539 a = faceVertLIDs_.value(lid, 0);
00540 b = faceVertLIDs_.value(lid, 1);
00541 c = faceVertLIDs_.value(lid, 2);
00542 }
00543 const Point& pa = points_[a];
00544 const Point& pb = points_[b];
00545 const Point& pc = points_[c];
00546
00547 if (spatialDim()==2)
00548 {
00549 J[0] = pb[0] - pa[0];
00550 J[1] = pc[0] - pa[0];
00551 J[2] = pb[1] - pa[1];
00552 J[3] = pc[1] - pa[1];
00553 for (int q=0; q<nQuad; q++)
00554 {
00555 physQuadPts.append(pa
00556 + Point(J[0]*refQuadPts[q][0] +J[1]*refQuadPts[q][1],
00557 J[2]*refQuadPts[q][0] +J[3]*refQuadPts[q][1]) );
00558 }
00559 }
00560 else
00561 {
00562 for (int q=0; q<nQuad; q++)
00563 {
00564 physQuadPts.append(pa
00565 + (pb-pa)*refQuadPts[q][0]
00566 + (pc-pa)*refQuadPts[q][1]);
00567 }
00568 }
00569
00570 }
00571 break;
00572 case 3:
00573 {
00574 int a = elemVerts_.value(lid, 0);
00575 int b = elemVerts_.value(lid, 1);
00576 int c = elemVerts_.value(lid, 2);
00577 int d = elemVerts_.value(lid, 3);
00578 const Point& pa = points_[a];
00579 const Point& pb = points_[b];
00580 const Point& pc = points_[c];
00581 const Point& pd = points_[d];
00582 J[0] = pb[0] - pa[0];
00583 J[1] = pc[0] - pa[0];
00584 J[2] = pd[0] - pa[0];
00585 J[3] = pb[1] - pa[1];
00586 J[4] = pc[1] - pa[1];
00587 J[5] = pd[1] - pa[1];
00588 J[6] = pb[2] - pa[2];
00589 J[7] = pc[2] - pa[2];
00590 J[8] = pd[2] - pa[2];
00591
00592 for (int q=0; q<nQuad; q++)
00593 {
00594 physQuadPts.append(pa
00595 + Point(J[0]*refQuadPts[q][0]
00596 + J[1]*refQuadPts[q][1]
00597 + J[2]*refQuadPts[q][2],
00598 J[3]*refQuadPts[q][0]
00599 + J[4]*refQuadPts[q][1]
00600 + J[5]*refQuadPts[q][2],
00601 J[6]*refQuadPts[q][0]
00602 + J[7]*refQuadPts[q][1]
00603 + J[8]*refQuadPts[q][2]));
00604
00605 }
00606
00607 }
00608 break;
00609 default:
00610 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible switch value "
00611 "in BasicSimplicialMesh::getJacobians()");
00612 }
00613 }
00614
00615 CellJacobianBatch::addFlops(flops);
00616 }
00617
00618 void BasicSimplicialMesh::estimateNumVertices(int nPts)
00619 {
00620 points_.reserve(nPts);
00621 vertCofacets_.reserve(nPts);
00622 vertEdges_.reserve(nPts);
00623 vertEdgePartners_.reserve(nPts);
00624
00625 ownerProcID_[0].reserve(nPts);
00626 LIDToGIDMap_[0].reserve(nPts);
00627 GIDToLIDMap_[0] = Hashtable<int,int>(nPts, 0.6);
00628 labels_[0].reserve(nPts);
00629 }
00630
00631 void BasicSimplicialMesh::estimateNumElements(int nElems)
00632 {
00633 int nEdges = 0;
00634 int nFaces = 0;
00635
00636 if (spatialDim()==3)
00637 {
00638 nFaces = 5*nElems;
00639 nEdges = 5*nElems;
00640 labels_[2].reserve(nFaces);
00641 }
00642 else if (spatialDim()==2)
00643 {
00644 nEdges = 3*nElems;
00645 }
00646
00647 labels_[1].reserve(nEdges);
00648 vertexSetToFaceIndexMap_ = Hashtable<VertexView, int>(nFaces);
00649
00650 edgeVerts_.reserve(nEdges);
00651 faceVertLIDs_.reserve(nFaces);
00652 faceVertGIDs_.reserve(nFaces);
00653 faceEdges_.reserve(nFaces);
00654 elemVerts_.reserve(nElems);
00655 elemEdges_.reserve(nElems);
00656 elemEdgeSigns_.reserve(nElems);
00657 elemFaces_.reserve(nElems);
00658 edgeCofacets_.reserve(nEdges);
00659 faceCofacets_.reserve(nFaces);
00660
00661 ownerProcID_[spatialDim()].reserve(nElems);
00662 LIDToGIDMap_[spatialDim()].reserve(nElems);
00663 GIDToLIDMap_[spatialDim()] = Hashtable<int,int>(nElems, 0.6);
00664 labels_[spatialDim()].reserve(nElems);
00665
00666
00667
00668 faceVertGIDs_.resize(1);
00669 faceVertGIDBase_[0] = &(faceVertGIDs_.value(0,0));
00670 faceVertGIDs_.resize(0);
00671 }
00672
00673
00674
00675 int BasicSimplicialMesh::numCells(int cellDim) const
00676 {
00677 return numCells_[cellDim];
00678 }
00679
00680 int BasicSimplicialMesh::ownerProcID(int cellDim, int cellLID) const
00681 {
00682 return ownerProcID_[cellDim][cellLID];
00683 }
00684
00685 int BasicSimplicialMesh::numFacets(int cellDim, int cellLID,
00686 int facetDim) const
00687 {
00688 if (cellDim==1)
00689 {
00690 return 2;
00691 }
00692 else if (cellDim==2)
00693 {
00694 return 3;
00695 }
00696 else
00697 {
00698 if (facetDim==0) return 4;
00699 if (facetDim==1) return 6;
00700 return 4;
00701 }
00702 }
00703
00704 void BasicSimplicialMesh::getFacetLIDs(int cellDim,
00705 const Array<int>& cellLID,
00706 int facetDim,
00707 Array<int>& facetLID,
00708 Array<int>& facetSign) const
00709 {
00710 TimeMonitor timer(batchedFacetGrabTimer());
00711
00712 int nf = numFacets(cellDim, cellLID[0], facetDim);
00713 facetLID.resize(cellLID.size() * nf);
00714 if (facetDim > 0) facetSign.resize(cellLID.size() * nf);
00715
00716
00717 if (facetDim==0)
00718 {
00719 if (cellDim == spatialDim())
00720 {
00721 int ptr=0;
00722 for (int c=0; c<cellLID.size(); c++)
00723 {
00724 const int* fPtr = &(elemVerts_.value(cellLID[c], 0));
00725 for (int f=0; f<nf; f++, ptr++)
00726 {
00727 facetLID[ptr] = fPtr[f];
00728 }
00729 }
00730 }
00731 else if (cellDim==1)
00732 {
00733 int ptr=0;
00734 for (int c=0; c<cellLID.size(); c++)
00735 {
00736 const int* fPtr = &(edgeVerts_.value(cellLID[c], 0));
00737 for (int f=0; f<nf; f++, ptr++)
00738 {
00739 facetLID[ptr] = fPtr[f];
00740 }
00741 }
00742 }
00743 else if (cellDim==2)
00744 {
00745 int ptr=0;
00746 for (int c=0; c<cellLID.size(); c++)
00747 {
00748 const int* fPtr = &(faceVertLIDs_.value(cellLID[c], 0));
00749 for (int f=0; f<nf; f++, ptr++)
00750 {
00751 facetLID[ptr] = fPtr[f];
00752 }
00753 }
00754 }
00755 }
00756 else if (facetDim==1)
00757 {
00758 int ptr=0;
00759 if (cellDim == spatialDim())
00760 {
00761 for (int c=0; c<cellLID.size(); c++)
00762 {
00763 const int* fPtr = &(elemEdges_.value(cellLID[c], 0));
00764
00765 for (int f=0; f<nf; f++, ptr++)
00766 {
00767 facetLID[ptr] = fPtr[f];
00768 facetSign[ptr] = 1;
00769 }
00770 }
00771 }
00772 else
00773 {
00774 for (int c=0; c<cellLID.size(); c++)
00775 {
00776 const int* fPtr = &(faceEdges_.value(cellLID[c], 0));
00777
00778 for (int f=0; f<nf; f++, ptr++)
00779 {
00780 facetLID[ptr] = fPtr[f];
00781
00782 }
00783 }
00784 }
00785 }
00786 else
00787 {
00788 int ptr=0;
00789 for (int c=0; c<cellLID.size(); c++)
00790 {
00791 const int* fPtr = &(elemFaces_.value(cellLID[c], 0));
00792
00793 for (int f=0; f<nf; f++, ptr++)
00794 {
00795 facetLID[ptr] = fPtr[f];
00796 facetSign[ptr] = 1;
00797 }
00798 }
00799 }
00800 }
00801
00802 int BasicSimplicialMesh::facetLID(int cellDim, int cellLID,
00803 int facetDim, int facetIndex, int& facetSign) const
00804 {
00805
00806 if (facetDim==0)
00807 {
00808 if (cellDim == spatialDim())
00809 {
00810 return elemVerts_.value(cellLID, facetIndex);
00811 }
00812 else if (cellDim==1) return edgeVerts_.value(cellLID, facetIndex);
00813 else if (cellDim==2) return faceVertLIDs_.value(cellLID, facetIndex);
00814 }
00815 if (facetDim==1)
00816 {
00817 if (cellDim==spatialDim())
00818 {
00819 facetSign = 1;
00820 return elemEdges_.value(cellLID, facetIndex);
00821 }
00822 else
00823 {
00824
00825 return faceEdges_.value(cellLID, facetIndex);
00826 }
00827 }
00828 else
00829 {
00830 facetSign = 1;
00831 return elemFaces_.value(cellLID, facetIndex);
00832 }
00833 }
00834
00835
00836 int BasicSimplicialMesh::numMaxCofacets(int cellDim, int cellLID) const
00837 {
00838
00839 if (cellDim==0)
00840 {
00841 return vertCofacets_[cellLID].length();
00842 }
00843 if (cellDim==1)
00844 {
00845 return edgeCofacets_[cellLID].length();
00846 }
00847 if (cellDim==2)
00848 {
00849 return faceCofacets_[cellLID].length();
00850 }
00851 return -1;
00852 }
00853
00854
00855
00856 int BasicSimplicialMesh::maxCofacetLID(int cellDim, int cellLID,
00857 int cofacetIndex,
00858 int& facetIndex) const
00859 {
00860 int rtn = -1;
00861 if (cellDim==0)
00862 {
00863 rtn = vertCofacets_[cellLID][cofacetIndex];
00864 }
00865 else if (cellDim==1)
00866 {
00867 rtn = edgeCofacets_[cellLID][cofacetIndex];
00868 }
00869 else if (cellDim==2)
00870 {
00871 rtn = faceCofacets_[cellLID][cofacetIndex];
00872 }
00873 else
00874 {
00875 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00876 "invalid cell dimension " << cellDim
00877 << " in request for cofacet");
00878 }
00879
00880
00881
00882 int dummy;
00883 for (int f=0; f<numFacets(spatialDim(), rtn, cellDim); f++)
00884 {
00885
00886 int c = facetLID(spatialDim(), rtn, cellDim, f, dummy);
00887
00888 if (cellLID==c)
00889 {
00890 facetIndex = f;
00891 return rtn;
00892 }
00893 }
00894 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "reverse pointer to facet not found"
00895 " in request for cofacet");
00896 return -1;
00897 }
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927 void BasicSimplicialMesh::getCofacets(int cellDim, int cellLID,
00928 int cofacetDim, Array<int>& cofacetLIDs) const
00929 {
00930
00931 TEUCHOS_TEST_FOR_EXCEPTION(cofacetDim > spatialDim() || cofacetDim < 0, std::runtime_error,
00932 "invalid cofacet dimension=" << cofacetDim);
00933 TEUCHOS_TEST_FOR_EXCEPTION( cofacetDim <= cellDim, std::runtime_error,
00934 "invalid cofacet dimension=" << cofacetDim
00935 << " for cell dim=" << cellDim);
00936 if (cofacetDim==spatialDim())
00937 {
00938 cofacetLIDs.resize(numMaxCofacets(cellDim, cellLID));
00939 int dum=0;
00940 for (int f=0; f<cofacetLIDs.size(); f++)
00941 {
00942 cofacetLIDs[f] = maxCofacetLID(cellDim, cellLID, f, dum);
00943 }
00944 }
00945 else
00946 {
00947 if (cellDim==0)
00948 {
00949 if (cofacetDim==1) cofacetLIDs = vertEdges_[cellLID];
00950 else if (cofacetDim==2) cofacetLIDs = vertFaces_[cellLID];
00951 else TEUCHOS_TEST_FOR_EXCEPT(true);
00952 }
00953 else if (cellDim==1)
00954 {
00955 if (cofacetDim==2) cofacetLIDs = edgeFaces_[cellLID];
00956 else TEUCHOS_TEST_FOR_EXCEPT(true);
00957 }
00958 else if (cellDim==2)
00959 {
00960
00961
00962 TEUCHOS_TEST_FOR_EXCEPT(true);
00963 }
00964 else
00965 {
00966 TEUCHOS_TEST_FOR_EXCEPT(true);
00967 }
00968 }
00969 }
00970
00971 int BasicSimplicialMesh::mapGIDToLID(int cellDim, int globalIndex) const
00972 {
00973 return GIDToLIDMap_[cellDim].get(globalIndex);
00974 }
00975
00976 bool BasicSimplicialMesh::hasGID(int cellDim, int globalIndex) const
00977 {
00978 return GIDToLIDMap_[cellDim].containsKey(globalIndex);
00979 }
00980
00981 int BasicSimplicialMesh::mapLIDToGID(int cellDim, int localIndex) const
00982 {
00983 return LIDToGIDMap_[cellDim][localIndex];
00984 }
00985
00986 CellType BasicSimplicialMesh::cellType(int cellDim) const
00987 {
00988
00989 switch(cellDim)
00990 {
00991 case 0:
00992 return PointCell;
00993 case 1:
00994 return LineCell;
00995 case 2:
00996 return TriangleCell;
00997 case 3:
00998 return TetCell;
00999 default:
01000 return NullCell;
01001 }
01002 }
01003
01004 int BasicSimplicialMesh::label(int cellDim,
01005 int cellLID) const
01006 {
01007 return labels_[cellDim][cellLID];
01008 }
01009
01010 void BasicSimplicialMesh::getLabels(int cellDim, const Array<int>& cellLID,
01011 Array<int>& labels) const
01012 {
01013 labels.resize(cellLID.size());
01014 const Array<int>& ld = labels_[cellDim];
01015 for (int i=0; i<cellLID.size(); i++)
01016 {
01017 labels[i] = ld[cellLID[i]];
01018 }
01019 }
01020
01021
01022 Set<int> BasicSimplicialMesh::getAllLabelsForDimension(int cellDim) const
01023 {
01024 Set<int> rtn;
01025
01026 const Array<int>& ld = labels_[cellDim];
01027 for (int i=0; i<ld.size(); i++)
01028 {
01029 rtn.put(ld[i]);
01030 }
01031
01032 return rtn;
01033 }
01034
01035 void BasicSimplicialMesh::getLIDsForLabel(int cellDim, int label, Array<int>& cellLIDs) const
01036 {
01037 cellLIDs.resize(0);
01038 const Array<int>& ld = labels_[cellDim];
01039 for (int i=0; i<ld.size(); i++)
01040 {
01041 if (ld[i] == label) cellLIDs.append(i);
01042 }
01043 }
01044
01045
01046
01047
01048 int BasicSimplicialMesh::addVertex(int globalIndex, const Point& x,
01049 int ownerProcID, int label)
01050 {
01051 #ifdef BSM_LOW_LEVEL_TIMER
01052 TimeMonitor timer(getAddVertexTimer());
01053 #endif
01054 int lid = points_.length();
01055 points_.append(x);
01056
01057 SUNDANCE_OUT(this->verb() > 4,
01058 "BSM added point " << x << " lid = " << lid);
01059
01060 numCells_[0]++;
01061
01062 LIDToGIDMap_[0].append(globalIndex);
01063 GIDToLIDMap_[0].put(globalIndex, lid);
01064
01065 if (comm().getRank() != ownerProcID) neighbors_.put(ownerProcID);
01066 ownerProcID_[0].append(ownerProcID);
01067 labels_[0].append(label);
01068
01069 vertCofacets_.resize(points_.length());
01070 vertEdges_.resize(points_.length());
01071 if (spatialDim() > 2) vertFaces_.resize(points_.length());
01072 vertEdgePartners_.resize(points_.length());
01073
01074 return lid;
01075 }
01076
01077 int BasicSimplicialMesh::addElement(int globalIndex,
01078 const Array<int>& vertGID,
01079 int ownerProcID, int label)
01080 {
01081 #ifdef BSM_LOW_LEVEL_TIMER
01082 TimeMonitor timer(getAddElementTimer());
01083 #endif
01084 SUNDANCE_VERB_HIGH("p=" << comm().getRank() << "adding element " << globalIndex
01085 << " with vertices:" << vertGID);
01086
01087 static Array<int> sortedVertGID;
01088 sort(vertGID, sortedVertGID);
01089
01090
01091
01092
01093
01094 int lid = elemVerts_.length();
01095 elemEdgeSigns_.resize(lid+1);
01096
01097 numCells_[spatialDim()]++;
01098
01099 LIDToGIDMap_[spatialDim()].append(globalIndex);
01100 GIDToLIDMap_[spatialDim()].put(globalIndex, lid);
01101 labels_[spatialDim()].append(label);
01102 ownerProcID_[spatialDim()].append(ownerProcID);
01103 if (comm().getRank() != ownerProcID) neighbors_.put(ownerProcID);
01104
01105
01106
01107 static Array<int> edges;
01108 static Array<int> faces;
01109 static Array<int> faceRotations;
01110 static Array<int> vertLID;
01111
01112
01113 {
01114 #ifdef BSM_LOW_LEVEL_TIMER
01115 TimeMonitor timer(getLookupLIDTimer());
01116 #endif
01117 vertLID.resize(vertGID.size());
01118 for (int i=0; i<vertGID.size(); i++)
01119 {
01120 vertLID[i] = GIDToLIDMap_[0].get(sortedVertGID[i]);
01121 }
01122 }
01123
01124
01125
01126
01127
01128
01129
01130
01131 if (spatialDim()==1)
01132 {
01133
01134 edges.resize(0);
01135 faces.resize(0);
01136
01137 vertCofacets_[vertLID[0]].append(lid);
01138 vertCofacets_[vertLID[1]].append(lid);
01139 }
01140 if (spatialDim()==2)
01141 {
01142
01143 edges.resize(3);
01144 faces.resize(0);
01145
01146
01147 edges[0] = addEdge(vertLID[1], vertLID[2], lid, globalIndex, 0);
01148 edges[1] = addEdge(vertLID[0], vertLID[2], lid, globalIndex, 1);
01149 edges[2] = addEdge(vertLID[0], vertLID[1], lid, globalIndex, 2);
01150
01151
01152 vertCofacets_[vertLID[0]].append(lid);
01153 vertCofacets_[vertLID[1]].append(lid);
01154 vertCofacets_[vertLID[2]].append(lid);
01155
01156 }
01157 else if (spatialDim()==3)
01158 {
01159
01160 edges.resize(6);
01161 faces.resize(4);
01162
01163
01164 edges[0] = addEdge(vertLID[2], vertLID[3], lid, globalIndex, 0);
01165 edges[1] = addEdge(vertLID[1], vertLID[3], lid, globalIndex, 1);
01166 edges[2] = addEdge(vertLID[1], vertLID[2], lid, globalIndex, 2);
01167 edges[3] = addEdge(vertLID[0], vertLID[3], lid, globalIndex, 3);
01168 edges[4] = addEdge(vertLID[0], vertLID[2], lid, globalIndex, 4);
01169 edges[5] = addEdge(vertLID[0], vertLID[1], lid, globalIndex, 5);
01170
01171
01172 vertCofacets_[vertLID[0]].append(lid);
01173 vertCofacets_[vertLID[1]].append(lid);
01174 vertCofacets_[vertLID[2]].append(lid);
01175 vertCofacets_[vertLID[3]].append(lid);
01176
01177
01178 static Array<int> tmpVertLID(3);
01179 static Array<int> tmpSortedVertGID(3);
01180 static Array<int> tmpEdges(4);
01181 #define BSM_OPT_CODE
01182 #ifndef BSM_OPT_CODE
01183 faces[0] = addFace(tuple(vertLID[1], vertLID[2], vertLID[3]),
01184 tuple(sortedVertGID[1], sortedVertGID[2], sortedVertGID[3]),
01185 tuple(edges[2], edges[0], edges[1]), lid, globalIndex);
01186
01187 faces[1] = addFace(tuple(vertLID[0], vertLID[2], vertLID[3]),
01188 tuple(sortedVertGID[0], sortedVertGID[2], sortedVertGID[3]),
01189 tuple(edges[3], edges[4], edges[0]), lid, globalIndex);
01190
01191 faces[2] = addFace(tuple(vertLID[0], vertLID[1], vertLID[3]),
01192 tuple(sortedVertGID[0], sortedVertGID[1], sortedVertGID[3]),
01193 tuple(edges[5], edges[1], edges[3]), lid, globalIndex);
01194
01195 faces[3] = addFace(tuple(vertLID[0], vertLID[1], vertLID[2]),
01196 tuple(sortedVertGID[0], sortedVertGID[1], sortedVertGID[2]),
01197 tuple(edges[5], edges[2], edges[4]), lid, globalIndex);
01198 #else
01199 tmpVertLID[0] = vertLID[1];
01200 tmpVertLID[1] = vertLID[2];
01201 tmpVertLID[2] = vertLID[3];
01202 tmpSortedVertGID[0] = sortedVertGID[1];
01203 tmpSortedVertGID[1] = sortedVertGID[2];
01204 tmpSortedVertGID[2] = sortedVertGID[3];
01205 tmpEdges[0] = edges[2];
01206 tmpEdges[1] = edges[0];
01207 tmpEdges[2] = edges[1];
01208 faces[0] = addFace(tmpVertLID, tmpSortedVertGID,
01209 tmpEdges, lid, globalIndex);
01210
01211 tmpVertLID[0] = vertLID[0];
01212 tmpVertLID[1] = vertLID[2];
01213 tmpVertLID[2] = vertLID[3];
01214 tmpSortedVertGID[0] = sortedVertGID[0];
01215 tmpSortedVertGID[1] = sortedVertGID[2];
01216 tmpSortedVertGID[2] = sortedVertGID[3];
01217 tmpEdges[0] = edges[3];
01218 tmpEdges[1] = edges[4];
01219 tmpEdges[2] = edges[0];
01220 faces[1] = addFace(tmpVertLID, tmpSortedVertGID,
01221 tmpEdges, lid, globalIndex);
01222
01223 tmpVertLID[0] = vertLID[0];
01224 tmpVertLID[1] = vertLID[1];
01225 tmpVertLID[2] = vertLID[3];
01226 tmpSortedVertGID[0] = sortedVertGID[0];
01227 tmpSortedVertGID[1] = sortedVertGID[1];
01228 tmpSortedVertGID[2] = sortedVertGID[3];
01229 tmpEdges[0] = edges[5];
01230 tmpEdges[1] = edges[1];
01231 tmpEdges[2] = edges[3];
01232 faces[2] = addFace(tmpVertLID, tmpSortedVertGID,
01233 tmpEdges, lid, globalIndex);
01234
01235 tmpVertLID[0] = vertLID[0];
01236 tmpVertLID[1] = vertLID[1];
01237 tmpVertLID[2] = vertLID[2];
01238 tmpSortedVertGID[0] = sortedVertGID[0];
01239 tmpSortedVertGID[1] = sortedVertGID[1];
01240 tmpSortedVertGID[2] = sortedVertGID[2];
01241 tmpEdges[0] = edges[5];
01242 tmpEdges[1] = edges[2];
01243 tmpEdges[2] = edges[4];
01244 faces[3] = addFace(tmpVertLID, tmpSortedVertGID,
01245 tmpEdges, lid, globalIndex);
01246
01247
01248 #endif
01249 }
01250
01251 {
01252 #ifdef BSM_LOW_LEVEL_TIMER
01253 TimeMonitor timer(getFacetRegistrationTimer());
01254 #endif
01255 elemVerts_.append(vertLID);
01256 if (edges.length() > 0) elemEdges_.append(edges);
01257
01258 if (faces.length() > 0)
01259 {
01260 elemFaces_.append(faces);
01261 elemFaceRotations_.append(faceRotations);
01262 }
01263
01264 }
01265
01266 for (int i=0; i<edges.length(); i++) edgeCofacets_[edges[i]].append(lid);
01267
01268
01269 for (int i=0; i<faces.length(); i++) faceCofacets_[faces[i]].append(lid);
01270
01271 return lid;
01272 }
01273
01274 int BasicSimplicialMesh::addFace(
01275 const Array<int>& vertLID,
01276 const Array<int>& vertGID,
01277 const Array<int>& edgeLID,
01278 int elemLID,
01279 int elemGID)
01280 {
01281 #ifdef BSM_LOW_LEVEL_TIMER
01282 TimeMonitor timer(getAddFaceTimer());
01283 #endif
01284
01285
01286 int lid = lookupFace(vertGID);
01287
01288 if (lid >= 0)
01289 {
01290 return lid;
01291 }
01292 else
01293 {
01294
01295 lid = faceVertLIDs_.length();
01296
01297
01298
01299 faceVertGIDs_.append(&(vertGID[0]), 3);
01300 faceVertLIDs_.append(&(vertLID[0]), 3);
01301 faceEdges_.append(&(edgeLID[0]), 3);
01302
01303 SUNDANCE_VERB_EXTREME("p=" << comm().getRank() << " adding face "
01304 << vertGID);
01305
01306
01307
01308
01309 int vert1Owner = ownerProcID_[0][vertLID[0]];
01310 int vert2Owner = ownerProcID_[0][vertLID[1]];
01311 int vert3Owner = ownerProcID_[0][vertLID[2]];
01312 int myRank = comm().getRank();
01313 if (vert1Owner==myRank && vert2Owner==myRank && vert3Owner==myRank)
01314 {
01315 ownerProcID_[2].append(myRank);
01316 }
01317 else ownerProcID_[2].append(-1);
01318
01319
01320 labels_[2].append(0);
01321
01322
01323
01324 faceVertGIDBase_[0] = &(faceVertGIDs_.value(0,0));
01325
01326
01327
01328
01329
01330 VertexView face(&(faceVertGIDBase_[0]), lid, 3);
01331
01332
01333
01334 vertexSetToFaceIndexMap_.put(face, lid);
01335
01336
01337 faceCofacets_.resize(lid+1);
01338
01339
01340 numCells_[spatialDim()-1]++;
01341
01342
01343 edgeFaces_[edgeLID[0]].append(lid);
01344 edgeFaces_[edgeLID[1]].append(lid);
01345 edgeFaces_[edgeLID[2]].append(lid);
01346
01347
01348 vertFaces_[vertLID[0]].append(lid);
01349 vertFaces_[vertLID[1]].append(lid);
01350 vertFaces_[vertLID[2]].append(lid);
01351
01352
01353 return lid;
01354 }
01355
01356 }
01357
01358
01359 int BasicSimplicialMesh::checkForExistingEdge(int vertLID1, int vertLID2)
01360 {
01361 const Array<int>& edgePartners = vertEdgePartners_[vertLID1];
01362 for (int i=0; i<edgePartners.length(); i++)
01363 {
01364 if (edgePartners[i] == vertLID2)
01365 {
01366 return vertEdges_[vertLID1][i];
01367 }
01368 }
01369 return -1;
01370 }
01371
01372 int BasicSimplicialMesh::lookupFace(const Array<int>& vertGID)
01373 {
01374
01375
01376 int* base = const_cast<int*>(&(vertGID[0]));
01377 int** basePtr = &base;
01378 VertexView inputFaceView(basePtr, 0, 3);
01379
01380 if (vertexSetToFaceIndexMap_.containsKey(inputFaceView))
01381 {
01382
01383 return vertexSetToFaceIndexMap_.get(inputFaceView);
01384 }
01385 else
01386 {
01387
01388 return -1;
01389 }
01390 }
01391
01392 int BasicSimplicialMesh::addEdge(int v1, int v2,
01393 int elemLID, int elemGID,
01394 int myFacetNumber)
01395 {
01396 #ifdef BSM_LOW_LEVEL_TIMER
01397 TimeMonitor timer(getAddEdgeTimer());
01398 #endif
01399
01400
01401
01402
01403 int lid = checkForExistingEdge(v1, v2);
01404
01405 if (lid >= 0)
01406 {
01407
01408 int g1 = LIDToGIDMap_[0][v1];
01409 int g2 = LIDToGIDMap_[0][v2];
01410 TEUCHOS_TEST_FOR_EXCEPT(g2 <= g1);
01411
01412
01413 return lid;
01414 }
01415 else
01416 {
01417
01418 lid = edgeVerts_.length();
01419
01420 edgeVerts_.append(tuple(v1,v2));
01421
01422
01423
01424 int vert1Owner = ownerProcID_[0][v1];
01425 int vert2Owner = ownerProcID_[0][v2];
01426 if (vert2Owner==comm().getRank() && vert1Owner==comm().getRank())
01427 ownerProcID_[1].append(vert1Owner);
01428 else ownerProcID_[1].append(-1);
01429
01430
01431 vertEdges_[v1].append(lid);
01432 vertEdgePartners_[v1].append(v2);
01433 vertEdges_[v2].append(lid);
01434 vertEdgePartners_[v2].append(v1);
01435
01436 edgeCofacets_.resize(lid+1);
01437 if (spatialDim() > 2) edgeFaces_.resize(lid+1);
01438
01439
01440
01441 labels_[1].append(0);
01442
01443
01444 numCells_[1]++;
01445 }
01446
01447 return lid;
01448 }
01449
01450
01451 void BasicSimplicialMesh::synchronizeGIDNumbering(int dim, int localCount)
01452 {
01453
01454 SUNDANCE_OUT(this->verb() > 4,
01455 "sharing offsets for GID numbering for dim=" << dim);
01456 SUNDANCE_OUT(this->verb() > 4,
01457 "I have " << localCount << " cells");
01458 Array<int> gidOffsets;
01459 int total;
01460 MPIContainerComm<int>::accumulate(localCount, gidOffsets, total, comm());
01461 int myOffset = gidOffsets[comm().getRank()];
01462
01463 SUNDANCE_OUT(this->verb() > 4,
01464 "back from MPI accumulate: offset for d=" << dim
01465 << " on p=" << comm().getRank() << " is " << myOffset);
01466
01467 for (int i=0; i<numCells(dim); i++)
01468 {
01469 if (LIDToGIDMap_[dim][i] == -1) continue;
01470 LIDToGIDMap_[dim][i] += myOffset;
01471 GIDToLIDMap_[dim].put(LIDToGIDMap_[dim][i], i);
01472 }
01473 SUNDANCE_OUT(this->verb() > 4,
01474 "done sharing offsets for GID numbering for dim=" << dim);
01475 }
01476
01477
01478 void BasicSimplicialMesh::assignIntermediateCellGIDs(int cellDim)
01479 {
01480 int myRank = comm().getRank();
01481
01482 SUNDANCE_VERB_MEDIUM("p=" << myRank << " assigning " << cellDim
01483 << "-cell owners");
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494 int numWaits = 1;
01495 if (staggerOutput())
01496 {
01497 SUNDANCE_VERB_LOW("p=" << myRank << " doing staggered output in "
01498 "assignIntermediateCellOwners()");
01499 numWaits = comm().getNProc();
01500 }
01501
01502
01503
01504
01505 Array<Array<int> > outgoingRequests(comm().getNProc());
01506 Array<Array<int> > incomingRequests(comm().getNProc());
01507
01508
01509 Array<Array<int> > outgoingRequestLIDs(comm().getNProc());
01510
01511
01512 Array<Array<int> > outgoingGIDs(comm().getNProc());
01513 Array<Array<int> > incomingGIDs(comm().getNProc());
01514
01515
01516 Array<int>& cellOwners = ownerProcID_[cellDim];
01517
01518
01519
01520 int localCount = 0;
01521 ArrayOfTuples<int>* cellVerts;
01522 if (cellDim==2) cellVerts = &(faceVertLIDs_);
01523 else cellVerts = &(edgeVerts_);
01524
01525 LIDToGIDMap_[cellDim].resize(numCells(cellDim));
01526
01527 SUNDANCE_OUT(this->verb() > 3,
01528 "starting loop over cells");
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549 try
01550 {
01551 resolveEdgeOwnership(cellDim);
01552 }
01553 catch(std::exception& e0)
01554 {
01555 SUNDANCE_TRACE_MSG(e0, "while resolving edge ownership");
01556 }
01557
01558
01559 for (int q=0; q<numWaits; q++)
01560 {
01561 if (numWaits > 1 && q != myRank)
01562 {
01563 TEUCHOS_TEST_FOR_EXCEPTION(checkForFailures(comm()), std::runtime_error,
01564 "off-proc error detected on proc=" << myRank
01565 << " while computing GID resolution requests");
01566 continue;
01567 }
01568 try
01569 {
01570 for (int i=0; i<numCells(cellDim); i++)
01571 {
01572 SUNDANCE_OUT(this->verb() > 4,
01573 "p=" << myRank
01574 <<" cell " << i);
01575
01576
01577
01578
01579
01580
01581 int owner = cellOwners[i];
01582 if (owner==myRank)
01583 {
01584 SUNDANCE_VERB_EXTREME("p=" << myRank
01585 << " assigning GID=" << localCount
01586 << " to cell "
01587 << cellToStr(cellDim, i));
01588 LIDToGIDMap_[cellDim][i] = localCount++;
01589 }
01590 else
01591
01592
01593
01594
01595
01596
01597
01598
01599 {
01600 LIDToGIDMap_[cellDim][i] = -1;
01601 SUNDANCE_OUT(this->verb() > 4,
01602 "p=" << myRank << " adding cell LID=" << i
01603 << " to req list");
01604 outgoingRequestLIDs[owner].append(i);
01605 for (int v=0; v<=cellDim; v++)
01606 {
01607 int ptLID = cellVerts->value(i, v);
01608 int ptGID = LIDToGIDMap_[0][ptLID];
01609 SUNDANCE_OUT(this->verb() > 4,
01610 "p=" << myRank << " adding pt LID=" << ptLID
01611 << " GID=" << ptGID
01612 << " to req list");
01613 outgoingRequests[owner].append(ptGID);
01614 }
01615 SUNDANCE_VERB_EXTREME("p=" << myRank
01616 << " deferring GID assignment for cell "
01617 << cellToStr(cellDim, i));
01618 }
01619 }
01620 }
01621 catch(std::exception& e0)
01622 {
01623 reportFailure(comm());
01624 SUNDANCE_TRACE_MSG(e0, "while computing GID resolution requests");
01625 }
01626 TEUCHOS_TEST_FOR_EXCEPTION(checkForFailures(comm()), std::runtime_error,
01627 "off-proc error detected on proc=" << myRank
01628 << " while computing GID resolution requests");
01629 }
01630
01631
01632
01633 try
01634 {
01635 synchronizeGIDNumbering(cellDim, localCount);
01636 }
01637 catch(std::exception& e0)
01638 {
01639 reportFailure(comm());
01640 SUNDANCE_TRACE_MSG(e0, "while computing GID offsets");
01641 }
01642 TEUCHOS_TEST_FOR_EXCEPTION(checkForFailures(comm()), std::runtime_error,
01643 "off-proc error detected on proc=" << myRank
01644 << " while computing GID offsets");
01645
01646
01647 for (int q=0; q<numWaits; q++)
01648 {
01649 if (numWaits > 1) comm().synchronize();
01650 if (numWaits > 1 && q!=myRank) continue;
01651 SUNDANCE_OUT(this->verb() > 4,
01652 "p=" << myRank << "sending requests: "
01653 << outgoingRequests);
01654 }
01655
01656 try
01657 {
01658 MPIContainerComm<int>::allToAll(outgoingRequests,
01659 incomingRequests,
01660 comm());
01661 }
01662 catch(std::exception& e0)
01663 {
01664 reportFailure(comm());
01665 SUNDANCE_TRACE_MSG(e0, "while distributing GID resolution requests");
01666 }
01667 TEUCHOS_TEST_FOR_EXCEPTION(checkForFailures(comm()), std::runtime_error,
01668 "off-proc error detected on proc=" << myRank
01669 << " while distributing GID resolution requests");
01670
01671
01672 for (int q=0; q<numWaits; q++)
01673 {
01674 if (numWaits > 1) comm().synchronize();
01675 if (numWaits > 1 && q!=myRank) continue;
01676 SUNDANCE_OUT(this->verb() > 4,
01677 "p=" << myRank << "recv'd requests: " << incomingRequests);
01678 }
01679
01680
01681 for (int q=0; q<numWaits; q++)
01682 {
01683 if (numWaits>1 && q != myRank)
01684 {
01685 TEUCHOS_TEST_FOR_EXCEPTION(checkForFailures(comm()), std::runtime_error,
01686 "off-proc error detected on proc=" << myRank
01687 << " while computing edge/face GID responses");
01688 continue;
01689 }
01690 try
01691 {
01692
01693 for (int p=0; p<comm().getNProc(); p++)
01694 {
01695 const Array<int>& requestsFromProc = incomingRequests[p];
01696
01697 for (int c=0; c<requestsFromProc.size(); c+=(cellDim+1))
01698 {
01699 SUNDANCE_OUT(this->verb() > 4,
01700 "p=" << myRank << "processing request c="
01701 << c/(cellDim+1));
01702
01703
01704 int cellLID;
01705 if (cellDim==1)
01706 {
01707 int vertLID1 = mapGIDToLID(0, requestsFromProc[c]);
01708 int vertLID2 = mapGIDToLID(0, requestsFromProc[c+1]);
01709 SUNDANCE_VERB_HIGH("p=" << myRank
01710 << " edge vertex GIDs are "
01711 << requestsFromProc[c+1]
01712 << ", " << requestsFromProc[c]);
01713 cellLID = checkForExistingEdge(vertLID1, vertLID2);
01714 }
01715 else
01716 {
01717
01718 SUNDANCE_VERB_HIGH("p=" << myRank
01719 << " face vertex GIDs are "
01720 << requestsFromProc[c]
01721 << ", " << requestsFromProc[c+1]
01722 << ", " << requestsFromProc[c+2]);
01723 cellLID = lookupFace(tuple(requestsFromProc[c],
01724 requestsFromProc[c+1],
01725 requestsFromProc[c+2]));
01726 }
01727 SUNDANCE_VERB_HIGH("p=" << myRank << "cell LID is "
01728 << cellLID);
01729
01730 TEUCHOS_TEST_FOR_EXCEPTION(cellLID < 0, std::runtime_error,
01731 "unable to find requested cell "
01732 << cellStr(cellDim+1, &(requestsFromProc[c])));
01733
01734
01735
01736 int cellGID = mapLIDToGID(cellDim, cellLID);
01737 TEUCHOS_TEST_FOR_EXCEPTION(cellGID < 0, std::runtime_error,
01738 "proc " << myRank
01739 << " was asked by proc " << p
01740 << " to provide a GID for cell "
01741 << cellStr(cellDim+1, &(requestsFromProc[c]))
01742 << " with LID=" << cellLID
01743 << " but its GID is undefined");
01744
01745 outgoingGIDs[p].append(mapLIDToGID(cellDim, cellLID));
01746 }
01747 }
01748 }
01749 catch(std::exception& e0)
01750 {
01751 reportFailure(comm());
01752 SUNDANCE_TRACE_MSG(e0, "while computing edge/face GID responses");
01753 }
01754 TEUCHOS_TEST_FOR_EXCEPTION(checkForFailures(comm()), std::runtime_error,
01755 "off-proc error detected "
01756 "on proc=" << myRank
01757 << " while computing edge/face GID responses");
01758 }
01759
01760
01761
01762 for (int q=0; q<numWaits; q++)
01763 {
01764 if (numWaits>1) comm().synchronize();
01765 if (numWaits>1 && q!=myRank) continue;
01766 SUNDANCE_OUT(this->verb() > 4,
01767 "p=" << myRank << "sending GIDs: " << outgoingGIDs);
01768 }
01769
01770
01771 try
01772 {
01773 MPIContainerComm<int>::allToAll(outgoingGIDs,
01774 incomingGIDs,
01775 comm());
01776 }
01777 catch(std::exception& e0)
01778 {
01779 reportFailure(comm());
01780 SUNDANCE_TRACE_MSG(e0, "while distributing edge/face GIDs");
01781 }
01782 TEUCHOS_TEST_FOR_EXCEPTION(checkForFailures(comm()), std::runtime_error,
01783 "off-proc error detected on proc=" << myRank
01784 << " while distributing edge/face GIDs");
01785
01786
01787
01788
01789 for (int q=0; q<numWaits; q++)
01790 {
01791 if (numWaits > 1 && q != myRank)
01792 {
01793 TEUCHOS_TEST_FOR_EXCEPTION(checkForFailures(comm()), std::runtime_error,
01794 "off-proc error detected on proc=" << myRank
01795 << " while setting remote edge/face GIDs");
01796 continue;
01797 }
01798 try
01799 {
01800 SUNDANCE_OUT(this->verb() > 4,
01801 "p=" << myRank << "recv'ing GIDs: " << incomingGIDs);
01802
01803
01804 for (int p=0; p<comm().getNProc(); p++)
01805 {
01806 const Array<int>& gidsFromProc = incomingGIDs[p];
01807 for (int c=0; c<gidsFromProc.size(); c++)
01808 {
01809 int cellLID = outgoingRequestLIDs[p][c];
01810 int cellGID = incomingGIDs[p][c];
01811 SUNDANCE_OUT(this->verb() > 4,
01812 "p=" << myRank <<
01813 " assigning GID=" << cellGID << " to LID="
01814 << cellLID);
01815 LIDToGIDMap_[cellDim][cellLID] = cellGID;
01816 GIDToLIDMap_[cellDim].put(cellGID, cellLID);
01817 }
01818 }
01819
01820
01821 SUNDANCE_OUT(this->verb() > 3,
01822 "p=" << myRank
01823 << "done synchronizing cells of dimension "
01824 << cellDim);
01825 }
01826 catch(std::exception& e0)
01827 {
01828 reportFailure(comm());
01829 SUNDANCE_TRACE_MSG(e0, " while setting remote edge/face GIDs");
01830 }
01831 TEUCHOS_TEST_FOR_EXCEPTION(checkForFailures(comm()), std::runtime_error,
01832 "off-proc error detected on proc=" << myRank
01833 << " while setting remote edge/face GIDs");
01834 }
01835 if (cellDim==1) hasEdgeGIDs_ = true;
01836 else hasFaceGIDs_ = true;
01837 }
01838
01839
01840
01841
01842
01843
01844
01845 void BasicSimplicialMesh::synchronizeNeighborLists()
01846 {
01847 if (neighborsAreSynchronized_) return ;
01848
01849 Array<Array<int> > outgoingNeighborFlags(comm().getNProc());
01850 Array<Array<int> > incomingNeighborFlags(comm().getNProc());
01851
01852 int myRank = comm().getRank();
01853
01854 for (int p=0; p<comm().getNProc(); p++)
01855 {
01856 if (neighbors_.contains(p)) outgoingNeighborFlags[p].append(myRank);
01857 }
01858
01859 try
01860 {
01861 MPIContainerComm<int>::allToAll(outgoingNeighborFlags,
01862 incomingNeighborFlags,
01863 comm());
01864 }
01865 catch(std::exception& e0)
01866 {
01867 reportFailure(comm());
01868 SUNDANCE_TRACE_MSG(e0, "while distributing neighbor information");
01869 }
01870 TEUCHOS_TEST_FOR_EXCEPTION(checkForFailures(comm()), std::runtime_error,
01871 "off-proc error detected on proc=" << myRank
01872 << " while distributing neighbor information");
01873
01874
01875
01876 for (int p=0; p<comm().getNProc(); p++)
01877 {
01878 if (incomingNeighborFlags[p].size() > 0) neighbors_.put(p);
01879 }
01880
01881 neighborsAreSynchronized_ = true;
01882 }
01883
01884
01885
01886
01887 void BasicSimplicialMesh::resolveEdgeOwnership(int cellDim)
01888 {
01889 int myRank = comm().getRank();
01890 SUNDANCE_VERB_LOW("p=" << myRank << " finding "
01891 << cellDim << "-cell owners");
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903 int numWaits = 1;
01904 if (staggerOutput())
01905 {
01906 SUNDANCE_VERB_LOW("p=" << myRank << " doing staggered output in "
01907 "assignIntermediateCellOwners()");
01908 numWaits = comm().getNProc();
01909 }
01910
01911 synchronizeNeighborLists();
01912
01913
01914 Array<int>& cellOwners = ownerProcID_[cellDim];
01915 ArrayOfTuples<int>* cellVerts;
01916 if (cellDim==2) cellVerts = &(faceVertLIDs_);
01917 else cellVerts = &(edgeVerts_);
01918
01919
01920 Array<int> neighbors = neighbors_.elements();
01921 SUNDANCE_VERB_LOW("p=" << myRank << " neighbors are " << neighbors);
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944 Array<int> reqIndexToEdgeLIDMap;
01945
01946
01947 Array<Array<int> > outgoingEdgeSpecifiers(comm().getNProc());
01948 Array<int> vertLID(cellDim+1);
01949 Array<int> vertGID(cellDim+1);
01950
01951 for (int q=0; q<numWaits; q++)
01952 {
01953 if (numWaits > 1 && q != myRank)
01954 {
01955 TEUCHOS_TEST_FOR_EXCEPTION(checkForFailures(comm()), std::runtime_error,
01956 "off-proc error detected on proc=" << myRank
01957 << " while determining edges to be resolved");
01958 continue;
01959 }
01960 try
01961 {
01962 for (int i=0; i<numCells(cellDim); i++)
01963 {
01964 int owner = cellOwners[i];
01965
01966
01967
01968
01969 if (owner==-1)
01970 {
01971
01972
01973 for (int v=0; v<=cellDim; v++)
01974 {
01975 vertLID[v] = cellVerts->value(i, v);
01976 vertGID[v] = LIDToGIDMap_[0][vertLID[v]];
01977 }
01978
01979 for (int n=0; n<neighbors.size(); n++)
01980 {
01981 for (int v=0; v<=cellDim; v++)
01982 {
01983 outgoingEdgeSpecifiers[neighbors[n]].append(vertGID[v]);
01984 }
01985 }
01986 SUNDANCE_VERB_HIGH("p=" << myRank
01987 << " is asking all neighbors to resolve edge "
01988 << cellToStr(cellDim, i));
01989
01990
01991
01992 reqIndexToEdgeLIDMap.append(i);
01993 }
01994 }
01995
01996 SUNDANCE_VERB_MEDIUM("p=" << myRank
01997 << " initially unresolved edge LIDs are "
01998 << reqIndexToEdgeLIDMap);
01999
02000 SUNDANCE_VERB_HIGH("p=" << myRank
02001 << " sending outgoing edge specs:") ;
02002 for (int p=0; p<comm().getNProc(); p++)
02003 {
02004 SUNDANCE_VERB_HIGH(outgoingEdgeSpecifiers[p].size()/(cellDim+1)
02005 << " edge reqs to proc "<< p) ;
02006 }
02007 SUNDANCE_VERB_HIGH("p=" << myRank << " outgoing edge specs are "
02008 << outgoingEdgeSpecifiers);
02009 }
02010 catch(std::exception& e0)
02011 {
02012 reportFailure(comm());
02013 SUNDANCE_TRACE_MSG(e0, "while determining edges to be resolved");
02014 }
02015 TEUCHOS_TEST_FOR_EXCEPTION(checkForFailures(comm()), std::runtime_error,
02016 "off-proc error detected on proc=" << myRank
02017 << " while determining edges to be resolved");
02018 }
02019
02020
02021
02022
02023 Array<Array<int> > incomingEdgeSpecifiers(comm().getNProc());
02024
02025
02026 try
02027 {
02028 MPIContainerComm<int>::allToAll(outgoingEdgeSpecifiers,
02029 incomingEdgeSpecifiers,
02030 comm());
02031 }
02032 catch(std::exception& e0)
02033 {
02034 reportFailure(comm());
02035 SUNDANCE_TRACE_MSG(e0, "while distributing edge resolution reqs");
02036 }
02037 TEUCHOS_TEST_FOR_EXCEPTION(checkForFailures(comm()), std::runtime_error,
02038 "off-proc error detected on proc=" << myRank
02039 << " while distributing edge resolution reqs");
02040
02041
02042 Array<Array<int> > outgoingEdgeContainers(comm().getNProc());
02043 for (int q=0; q<numWaits; q++)
02044 {
02045
02046 if (numWaits > 1 && q != myRank)
02047 {
02048 TEUCHOS_TEST_FOR_EXCEPTION(checkForFailures(comm()), std::runtime_error,
02049 "off-proc error detected on proc=" << myRank
02050 << " while resolving edge ownership results");
02051 continue;
02052 }
02053
02054 try
02055 {
02056 SUNDANCE_VERB_HIGH("p=" << myRank << " incoming edge specs are "
02057 << incomingEdgeSpecifiers);
02058
02059
02060
02061
02062
02063
02064 for (int p=0; p<comm().getNProc(); p++)
02065 {
02066 const Array<int>& edgesFromProc = incomingEdgeSpecifiers[p];
02067
02068 int numVerts = cellDim+1;
02069 for (int c=0; c<edgesFromProc.size(); c+=numVerts)
02070 {
02071 SUNDANCE_VERB_LOW("p=" << myRank << " doing c=" << c/numVerts
02072 << " of " << edgesFromProc.size()/numVerts
02073 << " reqs from proc=" << p);
02074
02075
02076
02077
02078
02079
02080
02081
02082 int cellLID;
02083 SUNDANCE_VERB_LOW("p=" << myRank << " looking at "
02084 << cellStr(numVerts, &(edgesFromProc[c])));
02085
02086
02087
02088
02089
02090 int response = 0;
02091
02092 for (int v=0; v<numVerts; v++)
02093 {
02094 vertGID[v] = edgesFromProc[c+v];
02095 if (!GIDToLIDMap_[0].containsKey(vertGID[v]))
02096 {
02097 response = -1;
02098 break;
02099 }
02100 else
02101 {
02102 vertLID[v] = GIDToLIDMap_[0].get(vertGID[v]);
02103 }
02104 }
02105 if (response != -1)
02106 {
02107
02108
02109 if (cellDim==1)
02110 {
02111 cellLID = checkForExistingEdge(vertLID[0], vertLID[1]);
02112 }
02113 else
02114 {
02115 cellLID = lookupFace(tuple(vertGID[0], vertGID[1], vertGID[2]));
02116 }
02117
02118 if (cellLID==-1)
02119 {
02120 response = -1;
02121 }
02122 }
02123
02124 if (response == -1)
02125 {
02126 SUNDANCE_VERB_HIGH("p=" << myRank << " is unaware of cell "
02127 << cellStr(numVerts, &(vertGID[0])));
02128 }
02129 else
02130 {
02131 SUNDANCE_VERB_HIGH("p=" << myRank << " knows about cell "
02132 << cellStr(numVerts, &(vertGID[0])));
02133 if (ownerProcID_[cellDim][cellLID] != -1) response = 1;
02134 }
02135
02136 outgoingEdgeContainers[p].append(response);
02137 SUNDANCE_VERB_LOW("p=" << myRank << " did c=" << c/numVerts
02138 << " of " << edgesFromProc.size()/numVerts
02139 << " reqs from proc=" << p);
02140 }
02141 SUNDANCE_VERB_LOW("p=" << myRank << " done all reqs from proc "
02142 << p);
02143
02144 }
02145 SUNDANCE_VERB_LOW("p=" << myRank << " done processing edge reqs");
02146 SUNDANCE_VERB_HIGH("p=" << myRank
02147 << " outgoing edge containers are "
02148 << outgoingEdgeContainers);
02149 }
02150 catch(std::exception& e0)
02151 {
02152 reportFailure(comm());
02153 SUNDANCE_TRACE_MSG(e0, "while resolving edge ownership results");
02154 }
02155 TEUCHOS_TEST_FOR_EXCEPTION(checkForFailures(comm()), std::runtime_error,
02156 "off-proc error detected on proc=" << myRank
02157 << " while resolving edge ownership results");
02158 }
02159
02160
02161
02162
02163
02164 Array<Array<int> > incomingEdgeContainers(comm().getNProc());
02165 try
02166 {
02167 MPIContainerComm<int>::allToAll(outgoingEdgeContainers,
02168 incomingEdgeContainers,
02169 comm());
02170 }
02171 catch(std::exception& e0)
02172 {
02173 reportFailure(comm());
02174 SUNDANCE_TRACE_MSG(e0, "while distributing edge resolution results");
02175 }
02176 TEUCHOS_TEST_FOR_EXCEPTION(checkForFailures(comm()), std::runtime_error,
02177 "off-proc error detected on proc=" << myRank
02178 << " while distributing edge ownership results");
02179
02180
02181
02182
02183
02184
02185 for (int q=0; q<numWaits; q++)
02186 {
02187 if (numWaits > 1 && q != myRank)
02188 {
02189 TEUCHOS_TEST_FOR_EXCEPTION(checkForFailures(comm()), std::runtime_error,
02190 "off-proc error detected on proc=" << myRank
02191 << " while finalizing edge ownership");
02192 continue;
02193 }
02194
02195 try
02196 {
02197 SUNDANCE_VERB_HIGH("p=" << myRank
02198 << " incoming edge containers are "
02199 << incomingEdgeContainers);
02200 Set<int> resolved;
02201 for (int p=0; p<comm().getNProc(); p++)
02202 {
02203 const Array<int>& edgeContainers = incomingEdgeContainers[p];
02204
02205 for (int c=0; c<edgeContainers.size(); c++)
02206 {
02207 int edgeLID = reqIndexToEdgeLIDMap[c];
02208
02209
02210
02211 if (edgeContainers[c] == 0 && !resolved.contains(edgeLID))
02212 {
02213
02214
02215 cellOwners[edgeLID] = p;
02216 }
02217
02218
02219
02220 else if (edgeContainers[c]==1)
02221 {
02222 cellOwners[edgeLID] = p;
02223 resolved.put(edgeLID);
02224 }
02225 }
02226 }
02227
02228
02229 for (int c=0; c<reqIndexToEdgeLIDMap.size(); c++)
02230 {
02231 int edgeLID = reqIndexToEdgeLIDMap[c];
02232 if (cellOwners[edgeLID] < 0) cellOwners[edgeLID] = myRank;
02233 SUNDANCE_VERB_EXTREME("p=" << myRank
02234 << " has decided cell "
02235 << cellToStr(cellDim, edgeLID)
02236 << " is owned by proc="
02237 << cellOwners[edgeLID]);
02238 }
02239 SUNDANCE_VERB_LOW("p=" << myRank << " done finalizing ownership");
02240 }
02241 catch(std::exception& e0)
02242 {
02243 reportFailure(comm());
02244 SUNDANCE_TRACE_MSG(e0, "while finalizing edge ownership");
02245 }
02246 TEUCHOS_TEST_FOR_EXCEPTION(checkForFailures(comm()), std::runtime_error,
02247 "off-proc error detected on proc=" << myRank
02248 << " while finalizing edge ownership");
02249 }
02250 }
02251
02252 string BasicSimplicialMesh::cellStr(int dim, const int* verts) const
02253 {
02254 std::string rtn="(";
02255 for (int i=0; i<dim; i++)
02256 {
02257 if (i!=0) rtn += ", ";
02258 rtn += Teuchos::toString(verts[i]);
02259 }
02260 rtn += ")";
02261 return rtn;
02262 }
02263
02264 string BasicSimplicialMesh::cellToStr(int cellDim, int cellLID) const
02265 {
02266 TeuchosOStringStream os;
02267
02268 if (cellDim > 0)
02269 {
02270 const ArrayOfTuples<int>* cellVerts;
02271 if (cellDim==spatialDim())
02272 {
02273 cellVerts = &(elemVerts_);
02274 }
02275 else
02276 {
02277 if (cellDim==2) cellVerts = &(faceVertLIDs_);
02278 else cellVerts = &(edgeVerts_);
02279 }
02280 os << "(";
02281 for (int j=0; j<cellVerts->tupleSize(); j++)
02282 {
02283 if (j!=0) os << ", ";
02284 os << mapLIDToGID(0, cellVerts->value(cellLID,j));
02285 }
02286 os << ")" << std::endl;
02287 }
02288 else
02289 {
02290 os << LIDToGIDMap_[0][cellLID] << std::endl;
02291 }
02292 return os.str();
02293 }
02294
02295 string BasicSimplicialMesh::printCells(int cellDim) const
02296 {
02297 TeuchosOStringStream os;
02298
02299 if (cellDim > 0)
02300 {
02301 const ArrayOfTuples<int>* cellVerts;
02302 if (cellDim==spatialDim())
02303 {
02304 cellVerts = &(elemVerts_);
02305 }
02306 else
02307 {
02308 if (cellDim==2) cellVerts = &(faceVertLIDs_);
02309 else cellVerts = &(edgeVerts_);
02310 }
02311
02312 os << "printing cells for processor " << comm().getRank() << std::endl;
02313 for (int i=0; i<cellVerts->length(); i++)
02314 {
02315 os << i << " (";
02316 for (int j=0; j<cellVerts->tupleSize(); j++)
02317 {
02318 if (j!=0) os << ", ";
02319 os << mapLIDToGID(0, cellVerts->value(i,j));
02320 }
02321 os << ")" << std::endl;
02322 }
02323 }
02324 else
02325 {
02326 os << LIDToGIDMap_[0] << std::endl;
02327 }
02328
02329 return os.str();
02330 }
02331
02332
02333