00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "SundanceHomogeneousDOFMap.hpp"
00043 #include "SundanceCellFilter.hpp"
00044 #include "SundanceMaximalCellFilter.hpp"
00045 #include "PlayaMPIContainerComm.hpp"
00046 #include "SundanceOut.hpp"
00047 #include "PlayaTabs.hpp"
00048 #include "Teuchos_Time.hpp"
00049 #include "Teuchos_TimeMonitor.hpp"
00050
00051 using namespace Sundance;
00052 using namespace Teuchos;
00053 using Playa::MPIComm;
00054 using Playa::MPIContainerComm;
00055
00056
00057 static Time& dofLookupTimer()
00058 {
00059 static RCP<Time> rtn
00060 = TimeMonitor::getNewTimer("unbatched dof lookup");
00061 return *rtn;
00062 }
00063
00064 static Time& dofBatchLookupTimer()
00065 {
00066 static RCP<Time> rtn
00067 = TimeMonitor::getNewTimer("batched dof lookup");
00068 return *rtn;
00069 }
00070
00071 HomogeneousDOFMap::HomogeneousDOFMap(const Mesh& mesh,
00072 const BasisFamily& basis,
00073 int numFuncs,
00074 int setupVerb)
00075 : DOFMapBase(mesh, setupVerb),
00076 dim_(mesh.spatialDim()),
00077 dofs_(mesh.spatialDim()+1),
00078 maximalDofs_(),
00079 haveMaximalDofs_(false),
00080 localNodePtrs_(mesh.spatialDim()+1),
00081 nNodesPerCell_(mesh.spatialDim()+1),
00082 totalNNodesPerCell_(mesh.spatialDim()+1, 0),
00083 numFacets_(mesh.spatialDim()+1),
00084 originalFacetOrientation_(2),
00085 basisIsContinuous_(false)
00086 {
00087 verbosity() = DOFMapBase::classVerbosity();
00088
00089 CellFilter maximalCells = new MaximalCellFilter();
00090 cellSets().append(maximalCells.getCells(mesh));
00091 cellDimOnCellSets().append(mesh.spatialDim());
00092
00093 allocate(mesh, basis, numFuncs);
00094 initMap();
00095 }
00096
00097
00098 HomogeneousDOFMap::HomogeneousDOFMap(const Mesh& mesh,
00099 const BasisFamily& basis,
00100 const Array<CellFilter>& subregions,
00101 int numFuncs)
00102 : DOFMapBase(mesh),
00103 dim_(mesh.spatialDim()),
00104 dofs_(mesh.spatialDim()+1),
00105 maximalDofs_(),
00106 haveMaximalDofs_(false),
00107 localNodePtrs_(mesh.spatialDim()+1),
00108 nNodesPerCell_(mesh.spatialDim()+1),
00109 totalNNodesPerCell_(mesh.spatialDim()+1, 0),
00110 numFacets_(mesh.spatialDim()+1),
00111 originalFacetOrientation_(2),
00112 basisIsContinuous_(false)
00113 {
00114 verbosity() = DOFMapBase::classVerbosity();
00115
00116 for (int r=0; r<subregions.size(); r++)
00117 {
00118 cellSets().append(subregions[r].getCells(mesh));
00119 cellDimOnCellSets().append(subregions[r].dimension(mesh));
00120 }
00121
00122 allocate(mesh, basis, numFuncs);
00123 initMap();
00124 }
00125
00126
00127 void HomogeneousDOFMap::allocate(const Mesh& mesh,
00128 const BasisFamily& basis,
00129 int numFuncs)
00130 {
00131 Tabs tab;
00132 SUNDANCE_MSG1(setupVerb(), tab << "allocating DOF map for nFuncs=" << numFuncs);
00133 Array<int> fid(numFuncs);
00134 for (int f=0; f<numFuncs; f++) fid[f] = f;
00135 funcIDOnCellSets().append(fid);
00136
00137
00138
00139 for (int d=0; d<=dim_; d++)
00140 {
00141 Tabs tab1;
00142 SUNDANCE_MSG2(setupVerb(), tab1 << "allocating d=" << d);
00143
00144
00145 numFacets_[d].resize(d);
00146 for (int fd=0; fd<d; fd++) numFacets_[d][fd]=mesh.numFacets(d, 0, fd);
00147 SUNDANCE_MSG3(setupVerb(), tab1 << "num facets for dimension " << d << " is "
00148 << numFacets_[d]);
00149
00150
00151
00152 basis.ptr()->getLocalDOFs(mesh.cellType(d), localNodePtrs_[d]);
00153
00154
00155 SUNDANCE_MSG3(setupVerb(), tab1 << "node ptrs for dimension " << d << " are "
00156 << localNodePtrs_[d]);
00157
00158
00159
00160 if (localNodePtrs_[d][d].size() > 0)
00161 {
00162 nNodesPerCell_[d] = localNodePtrs_[d][d][0].size();
00163 }
00164 else
00165 {
00166 nNodesPerCell_[d] = 0;
00167 }
00168 SUNDANCE_MSG3(setupVerb(), tab1 <<
00169 "num nodes for dimension " << d << " is "
00170 << nNodesPerCell_[d]);
00171
00172 totalNNodesPerCell_[d] = nNodesPerCell_[d];
00173 for (int dd=0; dd<d; dd++)
00174 {
00175 totalNNodesPerCell_[d] += numFacets_[d][dd]*nNodesPerCell_[dd];
00176 }
00177
00178
00179 if (nNodesPerCell_[d] > 0)
00180 {
00181 dofs_[d].resize(mesh.numCells(d));
00182 }
00183 else
00184 {
00185 dofs_[d].resize(0);
00186 }
00187
00188 if (d > 0 && d < dim_) originalFacetOrientation_[d-1].resize(mesh.numCells(d));
00189
00190
00191
00192 if (d < dim_ && nNodesPerCell_[d] > 0) basisIsContinuous_ = true;
00193
00194
00195
00196
00197 int numCells = dofs_[d].size();
00198 for (int c=0; c<numCells; c++)
00199 {
00200 dofs_[d][c].resize(funcIDList().size() * nNodesPerCell_[d]);
00201
00202 for (int i=0; i<dofs_[d][c].size(); i++)
00203 {
00204 dofs_[d][c][i] = uninitializedVal();
00205 }
00206 }
00207 }
00208 SUNDANCE_MSG1(setupVerb(), tab << "done allocating DOF map");
00209 }
00210
00211 void HomogeneousDOFMap::initMap()
00212 {
00213 Tabs tab;
00214 SUNDANCE_MSG1(setupVerb(), tab << "initializing DOF map");
00215
00216 int nextDOF = 0;
00217
00218
00219
00220
00221 Array<Array<Array<int> > > remoteCells(mesh().spatialDim()+1,
00222 mesh().comm().getNProc());
00223
00224 for (int r=0; r<numCellSets(); r++)
00225 {
00226
00227
00228
00229
00230
00231
00232
00233
00234 CellSet cells = cellSet(r);
00235 CellIterator iter;
00236 for (iter=cells.begin(); iter != cells.end(); iter++)
00237 {
00238
00239 int cellLID = *iter;
00240 int owner;
00241
00242 if (nNodesPerCell_[dim_] > 0)
00243 {
00244
00245
00246
00247 if (isRemote(dim_, cellLID, owner))
00248 {
00249 int dummy=0;
00250 int cellGID = mesh().mapLIDToGID(dim_, cellLID);
00251 remoteCells[dim_][owner].append(cellGID);
00252 setDOFs(dim_, cellLID, dummy);
00253 }
00254 else
00255
00256 {
00257 setDOFs(dim_, cellLID, nextDOF);
00258 }
00259 }
00260
00261
00262
00263
00264 if (basisIsContinuous_)
00265 {
00266 for (int d=0; d<dim_; d++)
00267 {
00268 if (nNodesPerCell_[d] > 0)
00269 {
00270 int nf = numFacets_[dim_][d];
00271 Array<int> facetLID(nf);
00272 Array<int> facetOrientations(nf);
00273
00274 mesh().getFacetArray(dim_, cellLID, d,
00275 facetLID, facetOrientations);
00276
00277 for (int f=0; f<nf; f++)
00278 {
00279
00280
00281 if (!hasBeenAssigned(d, facetLID[f]))
00282 {
00283
00284 if (isRemote(d, facetLID[f], owner))
00285 {
00286 int dummy=0;
00287 int facetGID = mesh().mapLIDToGID(d, facetLID[f]);
00288 remoteCells[d][owner].append(facetGID);
00289 setDOFs(d, facetLID[f], dummy);
00290 }
00291 else
00292 {
00293
00294 setDOFs(d, facetLID[f], nextDOF);
00295
00296 if (d > 0)
00297 {
00298 originalFacetOrientation_[d-1][facetLID[f]]
00299 = facetOrientations[f];
00300 }
00301 }
00302 }
00303 }
00304 }
00305 }
00306 }
00307 }
00308 }
00309
00310
00311
00312
00313 if (mesh().comm().getNProc() > 1)
00314 {
00315 for (int d=0; d<=dim_; d++)
00316 {
00317 if (nNodesPerCell_[d] > 0)
00318 {
00319 computeOffsets(d, nextDOF);
00320 shareDOFs(d, remoteCells[d]);
00321 }
00322 }
00323 }
00324 else
00325 {
00326 setLowestLocalDOF(0);
00327 setNumLocalDOFs(nextDOF);
00328 setTotalNumDOFs(nextDOF);
00329 }
00330 SUNDANCE_MSG1(setupVerb(), tab << "done initializing DOF map");
00331 }
00332
00333 void HomogeneousDOFMap::shareDOFs(int cellDim,
00334 const Array<Array<int> >& outgoingCellRequests)
00335 {
00336 int np = mesh().comm().getNProc();
00337 int rank = mesh().comm().getRank();
00338
00339 if (np == 1) return;
00340
00341 TEUCHOS_TEST_FOR_EXCEPTION(np != outgoingCellRequests.size(), std::runtime_error,
00342 "incorrect size of outgoingCellRequests array. Size is "
00343 << outgoingCellRequests.size() << ", should be np=" << np);
00344
00345
00346
00347 Array<Array<int> > incomingCellRequests;
00348 Array<Array<int> > outgoingDOFs(np);
00349 Array<Array<int> > incomingDOFs;
00350
00351 SUNDANCE_MSG2(setupVerb(),
00352 "p=" << mesh().comm().getRank()
00353 << "synchronizing DOFs for cells of dimension " << cellDim);
00354 SUNDANCE_MSG2(setupVerb(),
00355 "p=" << mesh().comm().getRank()
00356 << " sending cell reqs d=" << cellDim << " GID=" << outgoingCellRequests);
00357
00358
00359 MPIContainerComm<int>::allToAll(outgoingCellRequests,
00360 incomingCellRequests,
00361 mesh().comm());
00362
00363
00364
00365 SUNDANCE_MSG2(setupVerb(),
00366 "p=" << rank
00367 << "recvd DOF requests for cells of dimension " << cellDim
00368 << " GID=" << incomingCellRequests);
00369
00370
00371
00372 for (int p=0; p<np; p++)
00373 {
00374 if (p==rank) continue;
00375 const Array<int>& requestsFromProc = incomingCellRequests[p];
00376 int nReq = requestsFromProc.size();
00377 int blockSize = 1;
00378 if (cellDim > 0 && cellDim < dim_)
00379 {
00380 outgoingDOFs[p].resize(2 * nReq);
00381 blockSize = 2;
00382 }
00383 else
00384 {
00385 outgoingDOFs[p].resize(nReq);
00386 }
00387 SUNDANCE_MSG3(setupVerb(),
00388 "p=" << mesh().comm().getRank() << " recv'd from proc=" << p
00389 << " reqs for DOFs for cells " << requestsFromProc);
00390 for (int c=0; c<nReq; c++)
00391 {
00392 int GID = requestsFromProc[c];
00393 SUNDANCE_MSG3(setupVerb(),
00394 "p=" << rank
00395 << " processing cell with d=" << cellDim
00396 << " GID=" << GID);
00397 int LID = mesh().mapGIDToLID(cellDim, GID);
00398 SUNDANCE_MSG3(setupVerb(),
00399 "p=" << rank
00400 << " LID=" << LID << " dofs=" << dofs_[cellDim]);
00401 outgoingDOFs[p][blockSize*c] = dofs_[cellDim][LID][0];
00402 if (cellDim > 0 && cellDim < dim_)
00403 {
00404 outgoingDOFs[p][blockSize*c+1] = originalFacetOrientation_[cellDim-1][LID];
00405 }
00406 SUNDANCE_MSG3(setupVerb(),
00407 "p=" << rank
00408 << " done processing cell with GID=" << GID);
00409 }
00410 }
00411
00412
00413
00414 SUNDANCE_MSG2(setupVerb(),
00415 "p=" << mesh().comm().getRank()
00416 << "answering DOF requests for cells of dimension " << cellDim);
00417
00418
00419 MPIContainerComm<int>::allToAll(outgoingDOFs,
00420 incomingDOFs,
00421 mesh().comm());
00422
00423 SUNDANCE_MSG2(setupVerb(),
00424 "p=" << mesh().comm().getRank()
00425 << "communicated DOF answers for cells of dimension " << cellDim);
00426
00427
00428
00429 for (int p=0; p<mesh().comm().getNProc(); p++)
00430 {
00431 if (p==mesh().comm().getRank()) continue;
00432 const Array<int>& dofsFromProc = incomingDOFs[p];
00433 int blockSize = 1;
00434 if (cellDim > 0 && cellDim < dim_)
00435 {
00436 blockSize = 2;
00437 }
00438
00439 for (int c=0; c<dofsFromProc.size()/blockSize; c++)
00440 {
00441 int cellGID = outgoingCellRequests[p][c];
00442 int cellLID = mesh().mapGIDToLID(cellDim, cellGID);
00443 int dof = dofsFromProc[blockSize*c];
00444 setDOFs(cellDim, cellLID, dof, true);
00445 if (cellDim > 0 && cellDim < dim_)
00446 {
00447 originalFacetOrientation_[cellDim-1][cellLID] = dofsFromProc[blockSize*c+1];
00448 }
00449 }
00450 }
00451
00452 }
00453
00454
00455
00456 void HomogeneousDOFMap::setDOFs(int cellDim, int cellLID,
00457 int& nextDOF,
00458 bool isRemote)
00459 {
00460 Tabs tab;
00461 SUNDANCE_MSG3(setupVerb(), tab << "setting DOFs for " << cellDim << "-cell " << cellLID);
00462 Array<int>& cellDOFs = dofs_[cellDim][cellLID];
00463
00464 int nn = nNodesPerCell_[cellDim];
00465 int nf = funcIDList().size();
00466
00467 for (int i=0; i<nn; i++)
00468 {
00469 for (int f=0; f<nf; f++)
00470 {
00471 int k = nextDOF++;
00472 cellDOFs[funcIDList()[f] + nf*i] = k;
00473 if (isRemote) addGhostIndex(k);
00474 }
00475 }
00476 }
00477
00478
00479
00480 void HomogeneousDOFMap::getDOFsForCellBatch(int cellDim,
00481 const Array<int>& cellLID,
00482 Array<int>& dofs,
00483 int& nNodes) const
00484 {
00485 TimeMonitor timer(dofBatchLookupTimer());
00486
00487 Tabs tab;
00488 SUNDANCE_MSG3(setupVerb(),
00489 tab << "getDOFsForCellBatch(): cellDim=" << cellDim
00490 << " cellLID=" << cellLID);
00491
00492 if (cellLID.size()==0) return;
00493
00494 if (cellDim == dim_)
00495 {
00496 if (!haveMaximalDofs_)
00497 {
00498 buildMaximalDofTable();
00499 }
00500
00501 SUNDANCE_MSG4(setupVerb(), tab << "getting dofs for maximal cells");
00502
00503 nNodes = totalNNodesPerCell_[cellDim];
00504 int nCells = cellLID.size();
00505 int nTotalCells = mesh().numCells(cellDim);
00506 int nf = funcIDList().size();
00507 dofs.resize(totalNNodesPerCell_[cellDim] * cellLID.size() * nf);
00508
00509 for (int c=0; c<cellLID.size(); c++)
00510 {
00511 Tabs tab1;
00512 SUNDANCE_MSG4(setupVerb(), tab1 << "cell=" << c);
00513 for (int fid=0; fid<nf; fid++)
00514 {
00515 Tabs tab2;
00516 SUNDANCE_MSG4(setupVerb(), tab2 << "f= " << fid);
00517 for (int n=0; n<nNodes; n++)
00518 {
00519 Tabs tab3;
00520 dofs[(fid*nCells + c)*nNodes + n]
00521 = maximalDofs_[(fid*nTotalCells + cellLID[c])*nNodes + n];
00522 SUNDANCE_MSG4(setupVerb(), tab3 << "n=" << n << " dof="
00523 << dofs[(fid*nCells + c)*nNodes + n]);
00524 }
00525
00526 }
00527 }
00528 }
00529 else
00530 {
00531 int nf = funcIDList().size();
00532 int nCells = cellLID.size();
00533 dofs.resize(totalNNodesPerCell_[cellDim] * cellLID.size() * nf);
00534
00535 Tabs tab1;
00536 SUNDANCE_MSG4(setupVerb(), tab1 << "getting dofs for non-maximal cells");
00537
00538 static Array<Array<int> > facetLID(3);
00539 static Array<Array<int> > facetOrientations(3);
00540 static Array<int> numFacets(3);
00541
00542 for (int d=0; d<cellDim; d++)
00543 {
00544 numFacets[d] = mesh().numFacets(cellDim, cellLID[0], d);
00545 mesh().getFacetLIDs(cellDim, cellLID, d, facetLID[d],
00546 facetOrientations[d]);
00547 }
00548
00549
00550 int nInteriorNodes = localNodePtrs_[cellDim][cellDim][0].size();
00551
00552 nNodes = totalNNodesPerCell_[cellDim];
00553
00554 for (int c=0; c<cellLID.size(); c++)
00555 {
00556 Tabs tab2;
00557 SUNDANCE_MSG4(setupVerb(), tab2 << "cell=" << c);
00558 SUNDANCE_MSG4(setupVerb(), tab2 << "doing interior nodes");
00559
00560
00561
00562 if (cellDim==0 || nInteriorNodes <= 1)
00563 {
00564 for (int m=0; m<nInteriorNodes; m++)
00565 {
00566 Tabs tab3;
00567 int ptr = localNodePtrs_[cellDim][cellDim][0][m];
00568 for (int f=0; f<nf; f++)
00569 {
00570 dofs[(f*nCells + c)*nNodes+ptr]
00571 = dofs_[cellDim][cellLID[c]][f + nf*m];
00572 SUNDANCE_MSG4(setupVerb(), tab3 << "n=" << m << " f=" << f
00573 << " dof="
00574 << dofs[(f*nCells + c)*nNodes+ptr]);
00575 }
00576 }
00577 }
00578 else
00579 {
00580 int sign = originalFacetOrientation_[cellDim-1][cellLID[c]];
00581 for (int m=0; m<nInteriorNodes; m++)
00582 {
00583 int n = m;
00584 if (sign < 0) n = nInteriorNodes - 1 - m;
00585 Tabs tab3;
00586 int ptr = localNodePtrs_[cellDim][cellDim][0][m];
00587 for (int f=0; f<nf; f++)
00588 {
00589 dofs[(f*nCells + c)*nNodes+ptr]
00590 = dofs_[cellDim][cellLID[c]][f + nf*n];
00591 SUNDANCE_MSG4(setupVerb(), tab3 << "n=" << m << " f=" << f
00592 << " dof="
00593 << dofs[(f*nCells + c)*nNodes+ptr]);
00594 }
00595 }
00596 }
00597
00598 SUNDANCE_MSG4(setupVerb(), tab1 << "doing facet nodes");
00599
00600 for (int d=0; d<cellDim; d++)
00601 {
00602 Tabs tab3;
00603 SUNDANCE_MSG4(setupVerb(), tab3 << "d= " << d);
00604 for (int f=0; f<numFacets[d]; f++)
00605 {
00606 Tabs tab4;
00607 int facetID = facetLID[d][c*numFacets[d]+f];
00608
00609 SUNDANCE_MSG4(setupVerb(), tab4 << "f= " << f << " facetLID = " << facetID);
00610 int nFacetNodes = localNodePtrs_[cellDim][d][f].size();
00611 if (d==0 || nFacetNodes <= 1)
00612 {
00613 Tabs tab5;
00614 for (int n=0; n<nFacetNodes; n++)
00615 {
00616 SUNDANCE_MSG3(setupVerb(),
00617 tab5 << "n=" << n);
00618 int ptr = localNodePtrs_[cellDim][d][f][n];
00619 SUNDANCE_MSG3(setupVerb(),
00620 tab5 << "local ptr=" << ptr);
00621 for (int funcID=0; funcID<nf; funcID++)
00622 {
00623 SUNDANCE_MSG3(setupVerb(),
00624 tab5 << "found dof="
00625 << dofs_[d][facetID][funcID + nf*n]);
00626 dofs[(funcID*nCells + c)*nNodes+ptr]
00627 = dofs_[d][facetID][funcID + nf*n];
00628 }
00629 }
00630 }
00631 else
00632 {
00633 Tabs tab5;
00634 int facetOrientation
00635 = facetOrientations[d][c*numFacets[d]+f]
00636 * originalFacetOrientation_[d-1][facetID];
00637 for (int m=0; m<nFacetNodes; m++)
00638 {
00639 int n = m;
00640 if (facetOrientation<0) n = nFacetNodes-1-m;
00641 SUNDANCE_MSG3(setupVerb(),
00642 tab5 << "n=" << n);
00643 int ptr = localNodePtrs_[cellDim][d][f][m];
00644 SUNDANCE_MSG3(setupVerb(),
00645 tab5 << "local ptr=" << ptr);
00646 for (int funcID=0; funcID<nf; funcID++)
00647 {
00648 SUNDANCE_MSG3(setupVerb(),
00649 tab5 << "found dof="
00650 << dofs_[d][facetID][funcID + nf*n]);
00651 dofs[(funcID*nCells + c)*nNodes+ptr]
00652 = dofs_[d][facetID][funcID + nf*n];
00653 }
00654 }
00655 }
00656 }
00657 }
00658 }
00659 }
00660 }
00661
00662 void HomogeneousDOFMap::buildMaximalDofTable() const
00663 {
00664 Tabs tab;
00665 int cellDim = dim_;
00666 int nf = funcIDList().size();
00667 int nCells = mesh().numCells(dim_);
00668
00669 SUNDANCE_MSG2(setupVerb(), tab << "building dofs for maximal cells");
00670
00671 SUNDANCE_MSG3(setupVerb(), tab << "nf=" << nf
00672 << " total nNodes=" << totalNNodesPerCell_[cellDim]);
00673
00674 static Array<Array<int> > facetLID(3);
00675 static Array<Array<int> > facetOrientations(3);
00676 static Array<int> numFacets(3);
00677
00678 Array<int> cellLID(nCells);
00679
00680 for (int c=0; c<cellLID.size(); c++) cellLID[c]=c;
00681
00682 for (int d=0; d<cellDim; d++)
00683 {
00684 numFacets[d] = mesh().numFacets(cellDim, cellLID[0], d);
00685 mesh().getFacetLIDs(cellDim, cellLID, d, facetLID[d], facetOrientations[d]);
00686 }
00687
00688
00689 int nInteriorNodes = localNodePtrs_[cellDim][cellDim][0].size();
00690
00691
00692 int nNodes = totalNNodesPerCell_[cellDim];
00693
00694 maximalDofs_.resize(nCells*nf*nNodes);
00695
00696 for (int c=0; c<nCells; c++)
00697 {
00698 Tabs tab1;
00699 SUNDANCE_MSG4(setupVerb(), tab1 << "working on cell=" << c << " LID=" << cellLID[c]);
00700
00701
00702 SUNDANCE_MSG4(setupVerb(), tab1 << "doing interior nodes");
00703 for (int n=0; n<nInteriorNodes; n++)
00704 {
00705 int ptr = localNodePtrs_[cellDim][cellDim][0][n];
00706 for (int f=0; f<nf; f++)
00707 {
00708 maximalDofs_[(f*nCells + c)*nNodes+ptr]
00709 = dofs_[cellDim][c][f + nf*n];
00710 }
00711 }
00712
00713 SUNDANCE_MSG4(setupVerb(), tab1 << "doing facet nodes");
00714
00715 for (int d=0; d<cellDim; d++)
00716 {
00717 Tabs tab2;
00718 SUNDANCE_MSG4(setupVerb(), tab2 << "facet dim=" << d);
00719 for (int f=0; f<numFacets[d]; f++)
00720 {
00721 Tabs tab3;
00722 int facetID = facetLID[d][c*numFacets[d]+f];
00723 SUNDANCE_MSG4(setupVerb(), tab2 << "f=" << f << " facetLID=" << facetID);
00724 int nFacetNodes = localNodePtrs_[cellDim][d][f].size();
00725 if (d == 0 || nFacetNodes <= 1)
00726 {
00727 for (int n=0; n<nFacetNodes; n++)
00728 {
00729 Tabs tab4;
00730 SUNDANCE_MSG3(setupVerb(),
00731 tab4 << "n=" << n);
00732 int ptr = localNodePtrs_[cellDim][d][f][n];
00733 for (int funcID=0; funcID<nf; funcID++)
00734 {
00735 SUNDANCE_MSG3(setupVerb(),
00736 tab4 << "found dof="
00737 << dofs_[d][facetID][funcID + nf*n])
00738 maximalDofs_[(funcID*nCells + c)*nNodes+ptr]
00739 = dofs_[d][facetID][funcID + nf*n];
00740 }
00741 }
00742 }
00743 else
00744 {
00745 Tabs tab4;
00746 int facetOrientation = facetOrientations[d][c*numFacets[d]+f]
00747 * originalFacetOrientation_[d-1][facetID];
00748 for (int m=0; m<nFacetNodes; m++)
00749 {
00750 Tabs tab4;
00751 int n = m;
00752 if (facetOrientation<0) n = nFacetNodes-1-m;
00753 SUNDANCE_MSG3(setupVerb(),
00754 tab4 << "n=" << n);
00755 int ptr = localNodePtrs_[cellDim][d][f][m];
00756 for (int funcID=0; funcID<nf; funcID++)
00757 {
00758 SUNDANCE_MSG3(setupVerb(),
00759 tab4 << "found dof="
00760 << dofs_[d][facetID][funcID + nf*n])
00761 maximalDofs_[(funcID*nCells + c)*nNodes+ptr]
00762 = dofs_[d][facetID][funcID + nf*n];
00763 }
00764 }
00765 }
00766 }
00767 }
00768 }
00769 haveMaximalDofs_ = true;
00770 }
00771
00772
00773
00774
00775
00776 void HomogeneousDOFMap::computeOffsets(int dim, int localCount)
00777 {
00778 if (verbosity() > 2)
00779 {
00780 comm().synchronize();
00781 comm().synchronize();
00782 comm().synchronize();
00783 comm().synchronize();
00784 }
00785 SUNDANCE_MSG2(setupVerb(),
00786 "p=" << mesh().comm().getRank()
00787 << " sharing offsets for DOF numbering for dim=" << dim);
00788
00789 SUNDANCE_MSG2(setupVerb(),
00790 "p=" << mesh().comm().getRank()
00791 << " I have " << localCount << " cells");
00792
00793 Array<int> dofOffsets;
00794 int totalDOFCount;
00795 MPIContainerComm<int>::accumulate(localCount, dofOffsets, totalDOFCount,
00796 mesh().comm());
00797 int myOffset = dofOffsets[mesh().comm().getRank()];
00798
00799 SUNDANCE_MSG2(setupVerb(),
00800 "p=" << mesh().comm().getRank()
00801 << " back from MPI accumulate");
00802
00803 if (verbosity() > 2)
00804 {
00805 comm().synchronize();
00806 comm().synchronize();
00807 comm().synchronize();
00808 comm().synchronize();
00809 }
00810
00811 for (int c=0; c<dofs_[dim].size(); c++)
00812 {
00813 if (hasBeenAssigned(dim, c))
00814 {
00815 for (int n=0; n<dofs_[dim][c].size(); n++)
00816 {
00817 dofs_[dim][c][n] += myOffset;
00818 }
00819 }
00820 }
00821
00822 setLowestLocalDOF(myOffset);
00823 setNumLocalDOFs(localCount);
00824 setTotalNumDOFs(totalDOFCount);
00825
00826 SUNDANCE_MSG2(setupVerb(),
00827 "p=" << mesh().comm().getRank()
00828 << " done sharing offsets for DOF numbering for dim=" << dim);
00829 if (verbosity() > 2)
00830 {
00831 comm().synchronize();
00832 comm().synchronize();
00833 comm().synchronize();
00834 comm().synchronize();
00835 }
00836
00837 }
00838
00839
00840
00841 void HomogeneousDOFMap::print(std::ostream& os) const
00842 {
00843 int myRank = mesh().comm().getRank();
00844
00845 Tabs tabs;
00846
00847 os << "DOFS = " << dofs_ << std::endl;
00848
00849 for (int p=0; p<mesh().comm().getNProc(); p++)
00850 {
00851 mesh().comm().synchronize();
00852 mesh().comm().synchronize();
00853 if (p == myRank)
00854 {
00855 os << tabs <<
00856 "========= DOFMap on proc p=" << p << " =============" << std::endl;
00857 for (int d=dim_; d>=0; d--)
00858 {
00859 Tabs tabs1;
00860 os << tabs1 << "dimension = " << d << std::endl;
00861 for (int c=0; c<mesh().numCells(d); c++)
00862 {
00863 Tabs tabs2;
00864 os << tabs2 << "Cell LID=" << c << " GID="
00865 << mesh().mapLIDToGID(d, c) << std::endl;
00866 for (int f=0; f<funcIDList().size(); f++)
00867 {
00868 Tabs tabs3;
00869 Array<int> dofs;
00870 getDOFsForCell(d, c, funcIDList()[f], dofs);
00871 os << tabs3 << "f=" << funcIDList()[f] << " "
00872 << dofs << std::endl;
00873 if (false)
00874 {
00875 os << tabs3 << "{";
00876 for (int i=0; i<dofs.size(); i++)
00877 {
00878 if (i != 0) os << ", ";
00879 if (isLocalDOF(dofs[i])) os << "L";
00880 else os << "R";
00881 }
00882 os << "}" << std::endl;
00883 }
00884 }
00885 }
00886 }
00887 }
00888 mesh().comm().synchronize();
00889 mesh().comm().synchronize();
00890 }
00891 }
00892
00893