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