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