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 "SundanceMixedDOFMapHN.hpp"
00043 #include "SundanceBasisDOFTopologyBase.hpp"
00044 #include "SundanceCellFilter.hpp"
00045 #include "SundanceMaximalCellFilter.hpp"
00046 #include "PlayaMPIContainerComm.hpp"
00047 #include "SundanceOut.hpp"
00048 #include "PlayaTabs.hpp"
00049 #include "Teuchos_Time.hpp"
00050 #include "Teuchos_TimeMonitor.hpp"
00051
00052 using namespace Sundance;
00053 using namespace Teuchos;
00054 using Playa::MPIComm;
00055 using Playa::MPIContainerComm;
00056 using Playa::MPIDataType;
00057 using Playa::MPIOp;
00058
00059 static Time& mixedHNDOFCtorTimer()
00060 {
00061 static RCP<Time> rtn
00062 = TimeMonitor::getNewTimer("mixed hanging-node DOF map init");
00063 return *rtn;
00064 }
00065 static Time& maxDOFBuildTimer()
00066 {
00067 static RCP<Time> rtn
00068 = TimeMonitor::getNewTimer("max-cell dof table init");
00069 return *rtn;
00070 }
00071
00072 MixedDOFMapHN::MixedDOFMapHN(const Mesh& mesh,
00073 const Array<RCP<BasisDOFTopologyBase> >& basis,
00074 const CellFilter& maxCells,
00075 int setupVerb)
00076 : HNDoFMapBaseHomogeneous(mesh, basis.size(), setupVerb),
00077 maxCells_(maxCells),
00078 dim_(mesh.spatialDim()),
00079 dofs_(mesh.spatialDim()+1),
00080 maximalDofs_(),
00081 haveMaximalDofs_(false),
00082 localNodePtrs_(),
00083 hasCellHanging_(),
00084 isElementHanging_(mesh.spatialDim()+1),
00085 HN_To_globalFacetsLID_(),
00086 HN_To_globalFacetsDim_(),
00087 HN_To_coeffs_(),
00088 maxCellLIDwithHN_to_TrafoMatrix_(),
00089 matrixStore_(),
00090 nNodesPerCell_(),
00091 totalNNodesPerCell_(),
00092 cellHasAnyDOFs_(dim_+1),
00093 numFacets_(mesh.spatialDim()+1),
00094 originalFacetOrientation_(2),
00095 hasBeenAssigned_(mesh.spatialDim()+1),
00096 structure_(),
00097 nFuncs_()
00098 {
00099 TimeMonitor timer(mixedHNDOFCtorTimer());
00100 Tabs tab;
00101
00102 SUNDANCE_MSG1(setupVerb, tab << "building mixed hanging node DOF map");
00103
00104 Sundance::Map<OrderedHandle<BasisDOFTopologyBase>, int> basisToChunkMap;
00105 Array<RCP<BasisDOFTopologyBase> > chunkBases;
00106 Array<Array<int> > chunkFuncs;
00107
00108 int chunk = 0;
00109 int nBasis = basis.size();
00110 basis_.resize(nBasis);
00111
00112 nPoints_ = mesh.numCells(0);
00113
00114 for (int i=0; i<nBasis; i++)
00115 {
00116 OrderedHandle<BasisDOFTopologyBase> bh = basis[i];
00117 if (!basisToChunkMap.containsKey(bh))
00118 {
00119 chunkBases.append(basis[i]);
00120 basisToChunkMap.put(bh, chunk);
00121 chunkFuncs.append(tuple(i));
00122 basis_[chunk] = rcp_dynamic_cast<BasisFamilyBase>(basis[i]);
00123 chunk++;
00124 }
00125 else
00126 {
00127 int b = basisToChunkMap.get(bh);
00128 chunkFuncs[b].append(i);
00129 }
00130 }
00131 basis_.resize(chunk);
00132
00133
00134 matrixStore_.init(chunk);
00135
00136 Tabs tab1;
00137 SUNDANCE_MSG1(setupVerb, tab1 << "basis to chunk map = " << basisToChunkMap);
00138
00139
00140 structure_ = rcp(new MapStructure(basis.size(), chunkBases, chunkFuncs));
00141
00142 nFuncs_.resize(chunkBases.size());
00143 for (int i=0; i<nFuncs_.size(); i++)
00144 nFuncs_[i] = chunkFuncs[i].size();
00145
00146 allocate(mesh);
00147
00148 initMap();
00149
00150 buildMaximalDofTable();
00151
00152
00153
00154
00155 SUNDANCE_MSG1(setupVerb, tab << "done building mixed HN DOF map");
00156
00157 }
00158
00159
00160 void MixedDOFMapHN::allocate(const Mesh& mesh)
00161 {
00162 Tabs tab;
00163
00164
00165 SUNDANCE_MSG1(setupVerb(),tab << "grouping like basis functions");
00166
00167
00168 localNodePtrs_.resize(nBasisChunks());
00169 nNodesPerCell_.resize(nBasisChunks());
00170 totalNNodesPerCell_.resize(nBasisChunks());
00171 nDofsPerCell_.resize(nBasisChunks());
00172 totalNDofsPerCell_.resize(nBasisChunks());
00173 maximalDofs_.resize(nBasisChunks());
00174
00175 for (int b=0; b<nBasisChunks(); b++)
00176 {
00177 localNodePtrs_[b].resize(mesh.spatialDim()+1);
00178 nNodesPerCell_[b].resize(mesh.spatialDim()+1);
00179 totalNNodesPerCell_[b].resize(mesh.spatialDim()+1);
00180 nDofsPerCell_[b].resize(mesh.spatialDim()+1);
00181 totalNDofsPerCell_[b].resize(mesh.spatialDim()+1);
00182 }
00183
00184
00185 SUNDANCE_MSG1(setupVerb(),tab << "working out DOF map node counts");
00186
00187 numFacets_.resize(dim_+1);
00188 isElementHanging_.resize(dim_+1);
00189 hasCellHanging_.resize(mesh.numCells(dim_),false);
00190
00191 for (int d=0; d<=dim_; d++)
00192 {
00193 Tabs tab1;
00194 SUNDANCE_MSG1(setupVerb(),tab << "allocating maps for cell dim=" << d);
00195
00196
00197 numFacets_[d].resize(d);
00198
00199 for (int fd=0; fd<d; fd++) numFacets_[d][fd]=mesh.numFacets(d, 0, fd);
00200 SUNDANCE_MSG1(setupVerb(),tab1 << "num facets for dimension " << d << " is "
00201 << numFacets_[d]);
00202
00203 cellHasAnyDOFs_[d] = false;
00204 dofs_[d].resize(nBasisChunks());
00205
00206 int numCells = mesh.numCells(d);
00207 hasBeenAssigned_[d].resize(numCells);
00208
00209
00210 isElementHanging_[d].resize(numCells,false);
00211 for (int c=0; c<numCells; c++) { isElementHanging_[d][c] = false; }
00212 if (d == dim_){
00213 for (int c=0; c<numCells; c++) { hasCellHanging_[c] = false; }
00214 }
00215
00216 for (int b=0; b<nBasisChunks(); b++)
00217 {
00218 Tabs tab2;
00219 SUNDANCE_MSG2(setupVerb(),tab1 << "basis chunk=" << b);
00220 SUNDANCE_MSG2(setupVerb(),tab2 << "basis=" << basis(b)->description());
00221 int nNodes = basis(b).ptr()->nReferenceDOFsWithFacets(mesh.cellType(dim_), mesh.cellType(d));
00222 SUNDANCE_MSG2(setupVerb(),tab2 << "nNodes per cell=" << nNodes);
00223 if (nNodes == 0)
00224 {
00225 nNodesPerCell_[b][d] = 0;
00226 nDofsPerCell_[b][d] = 0;
00227 }
00228 else
00229 {
00230
00231
00232 basis(b).ptr()->getReferenceDOFs(mesh.cellType(dim_),
00233 mesh.cellType(d),
00234 localNodePtrs_[b][d]);
00235
00236
00237 SUNDANCE_MSG3(setupVerb(),tab2 << "node ptrs are "
00238 << localNodePtrs_[b][d]);
00239
00240
00241
00242 if (localNodePtrs_[b][d][d].size() > 0)
00243 {
00244 nNodesPerCell_[b][d] = localNodePtrs_[b][d][d][0].size();
00245 if (nNodesPerCell_[b][d] > 0) cellHasAnyDOFs_[d] = true;
00246 }
00247 else
00248 {
00249 nNodesPerCell_[b][d] = 0;
00250 }
00251 nDofsPerCell_[b][d] = nNodesPerCell_[b][d] * nFuncs(b);
00252 }
00253
00254
00255
00256
00257
00258 if (nDofsPerCell_[b][d] > 0 && d > 0 && d < mesh.spatialDim())
00259 {
00260 Mesh& tmpMesh = const_cast<Mesh&>(mesh);
00261 tmpMesh.assignIntermediateCellGIDs(d);
00262 }
00263
00264 SUNDANCE_MSG3(setupVerb(),tab2 <<
00265 "num nodes is "
00266 << nNodesPerCell_[b][d]);
00267
00268 totalNNodesPerCell_[b][d] = nNodesPerCell_[b][d];
00269 for (int dd=0; dd<d; dd++)
00270 {
00271 totalNNodesPerCell_[b][d]
00272 += numFacets_[d][dd]*nNodesPerCell_[b][dd];
00273 }
00274 totalNDofsPerCell_[b][d] = totalNNodesPerCell_[b][d] * nFuncs(b);
00275 SUNDANCE_MSG3(setupVerb(),tab2 << "totalNDofsPerCell " << totalNDofsPerCell_[b][d]);
00276
00277 if (nNodes > 0)
00278 {
00279
00280 dofs_[d][b].resize(nDofsPerCell_[b][d] * numCells);
00281
00282
00283 int nDof = dofs_[d][b].size();
00284 Array<int>& dofs = dofs_[d][b];
00285 int marker = uninitializedVal();
00286 for (int i=0; i<nDof; i++)
00287 {
00288 dofs[i] = marker;
00289 }
00290 }
00291
00292 if (d==dim_)
00293 {
00294 maximalDofs_[b].resize(totalNDofsPerCell_[b][d]*numCells);
00295 }
00296 }
00297
00298
00299 if (d > 0 && d < dim_)
00300 {
00301 originalFacetOrientation_[d-1].resize(numCells);
00302 }
00303
00304 }
00305 SUNDANCE_MSG1(setupVerb(),tab << "done allocating DOF map");
00306 }
00307
00308 void MixedDOFMapHN::initMap()
00309 {
00310 Tabs tab;
00311 SUNDANCE_MSG1(setupVerb(),tab << "initializing DOF map");
00312
00313 int nextDOF = 0;
00314
00315
00316
00317
00318 Array<Array<Array<int> > > remoteCells(mesh().spatialDim()+1);
00319
00320 for (int d=0; d<remoteCells.size(); d++)
00321 remoteCells[d].resize(mesh().comm().getNProc());
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 CellSet cells = maxCells_.getCells(mesh());
00332 CellIterator iter;
00333 for (iter=cells.begin(); iter != cells.end(); iter++)
00334 {
00335
00336 int cellLID = *iter;
00337 int owner;
00338
00339 if (cellHasAnyDOFs_[dim_])
00340 {
00341
00342
00343
00344 if (isRemote(dim_, cellLID, owner))
00345 {
00346
00347 int cellGID = mesh().mapLIDToGID(dim_, cellLID);
00348 SUNDANCE_MSG4(setupVerb(),"proc=" << comm().getRank()
00349 << " thinks d-" << dim_
00350 << " cell GID=" << cellGID
00351 << " is owned remotely by p="
00352 << owner);
00353 remoteCells[dim_][owner].append(cellGID);
00354 }
00355 else
00356
00357 {
00358 for (int b=0; b<nBasisChunks(); b++)
00359 {
00360 setDOFs(b, dim_, cellLID, nextDOF);
00361 }
00362 }
00363 }
00364
00365
00366 for (int d=0; d<dim_; d++)
00367 {
00368 if (cellHasAnyDOFs_[d])
00369 {
00370 int nf = numFacets_[dim_][d];
00371 Array<int> facetLID(nf);
00372 Array<int> facetOrientations(nf);
00373
00374
00375 mesh().getFacetArray(dim_, cellLID, d,
00376 facetLID, facetOrientations);
00377
00378 for (int f=0; f<nf; f++)
00379 {
00380
00381
00382 if (!hasBeenAssigned(d, facetLID[f]))
00383 {
00384 markAsAssigned(d, facetLID[f]);
00385
00386 if ( isRemote(d, facetLID[f], owner) && (!mesh().isElementHangingNode(d,facetLID[f])))
00387 {
00388 int facetGID
00389 = mesh().mapLIDToGID(d, facetLID[f]);
00390 SUNDANCE_MSG4(setupVerb(),"proc=" << comm().getRank()
00391 << " thinks d-" << d
00392 << " cell GID=" << facetGID
00393 << " is owned remotely by p=" << owner);
00394 remoteCells[d][owner].append(facetGID);
00395 }
00396 else
00397 {
00398
00399 for (int b=0; b<nBasisChunks(); b++)
00400 {
00401 setDOFs(b, d, facetLID[f], nextDOF);
00402 }
00403
00404 if (d > 0)
00405 {
00406 originalFacetOrientation_[d-1][facetLID[f]]
00407 = facetOrientations[f];
00408 }
00409 }
00410 }
00411 }
00412 }
00413 }
00414 }
00415
00416
00417
00418
00419
00420
00421 int numLocalDOFs = nextDOF;
00422 if (mesh().comm().getNProc() > 1)
00423 {
00424 for (int d=0; d<=dim_; d++)
00425 {
00426 if (cellHasAnyDOFs_[d])
00427 {
00428 computeOffsets(d, numLocalDOFs);
00429 shareDOFs(d, remoteCells[d]);
00430 }
00431 }
00432 }
00433 else
00434 {
00435 setLowestLocalDOF(0);
00436 setNumLocalDOFs(numLocalDOFs);
00437 setTotalNumDOFs(numLocalDOFs);
00438 }
00439 SUNDANCE_MSG1(setupVerb(),tab << "done initializing DOF map , numLocalDOFs:" << numLocalDOFs);
00440 }
00441
00442
00443 void MixedDOFMapHN::setDOFs(int basisChunk, int cellDim, int cellLID,
00444 int& nextDOF, bool isRemote)
00445 {
00446 int nDofs = nDofsPerCell_[basisChunk][cellDim];
00447 if (nDofs==0) return;
00448 Tabs tab;
00449 SUNDANCE_MSG4(setupVerb(),tab << "setting DOFs for " << cellDim
00450 << "-cell " << cellLID << " , basisChunk:" << basisChunk <<" , nDofs:" <<nDofs << " , nextDOF:" << nextDOF );
00451
00452 int* ptr = getInitialDOFPtrForCell(cellDim, cellLID, basisChunk);
00453
00454
00455
00456
00457
00458 if (isRemote)
00459 {
00460 if (mesh().isElementHangingNode(cellDim, cellLID)){
00461 isElementHanging_[cellDim][cellLID] = true;
00462 for (int i=0; i<nDofs; i++) {
00463 ptr[i] = -1;
00464
00465 }
00466 }
00467 else
00468 {
00469 for (int i=0; i<nDofs; i++, nextDOF++){
00470 ptr[i] = nextDOF;
00471 addGhostIndex(nextDOF);
00472 }
00473 }
00474 }
00475 else
00476 {
00477 if (mesh().isElementHangingNode(cellDim, cellLID)){
00478 isElementHanging_[cellDim][cellLID] = true;
00479 for (int i=0; i<nDofs; i++) {
00480
00481
00482
00483
00484 ptr[i] = -1;
00485 }
00486 }
00487 else
00488 {
00489 for (int i=0; i<nDofs; i++,nextDOF++) {
00490
00491
00492
00493 ptr[i] = nextDOF;
00494 }
00495 }
00496 }
00497 }
00498
00499
00500
00501
00502
00503 void MixedDOFMapHN::shareDOFs(int cellDim,
00504 const Array<Array<int> >& outgoingCellRequests)
00505 {
00506 int np = mesh().comm().getNProc();
00507 int rank = mesh().comm().getRank();
00508
00509 Array<Array<int> > incomingCellRequests;
00510 Array<Array<int> > outgoingDOFs(np);
00511 Array<Array<int> > incomingDOFs;
00512
00513 SUNDANCE_MSG2(setupVerb(),
00514 "p=" << mesh().comm().getRank()
00515 << "synchronizing DOFs for cells of dimension " << cellDim);
00516 SUNDANCE_MSG2(setupVerb(),
00517 "p=" << mesh().comm().getRank()
00518 << " sending cell reqs d=" << cellDim << " GID=" << outgoingCellRequests);
00519
00520
00521 MPIContainerComm<int>::allToAll(outgoingCellRequests,
00522 incomingCellRequests,
00523 mesh().comm());
00524
00525
00526
00527
00528
00529 int blockSize = 0;
00530 bool sendOrientation = false;
00531 for (int b=0; b<nBasisChunks(); b++)
00532 {
00533 int nDofs = nDofsPerCell_[b][cellDim];
00534 if (nDofs > 0) blockSize++;
00535 if (nDofs > 1 && cellDim > 0 && cellDim < dim_) sendOrientation = true;
00536 }
00537 blockSize += sendOrientation;
00538
00539 SUNDANCE_MSG2(setupVerb(),
00540 "p=" << rank
00541 << "recvd DOF requests for cells of dimension " << cellDim
00542 << " GID=" << incomingCellRequests);
00543
00544
00545
00546 for (int p=0; p<np; p++)
00547 {
00548 if (p==rank) continue;
00549 const Array<int>& requestsFromProc = incomingCellRequests[p];
00550 int nReq = requestsFromProc.size();
00551
00552 SUNDANCE_MSG4(setupVerb(),"p=" << mesh().comm().getRank()
00553 << " recv'd from proc=" << p
00554 << " reqs for DOFs for cells "
00555 << requestsFromProc);
00556
00557 outgoingDOFs[p].resize(nReq * blockSize);
00558
00559 for (int c=0; c<nReq; c++)
00560 {
00561 int GID = requestsFromProc[c];
00562 SUNDANCE_MSG3(setupVerb(),
00563 "p=" << rank
00564 << " processing cell with d=" << cellDim
00565 << " GID=" << GID);
00566 int LID = mesh().mapGIDToLID(cellDim, GID);
00567 SUNDANCE_MSG3(setupVerb(),
00568 "p=" << rank
00569 << " LID=" << LID << " dofs=" << dofs_[cellDim]);
00570 int blockOffset = 0;
00571 for (int b=0; b<nBasisChunks(); b++)
00572 {
00573 if (nDofsPerCell_[b][cellDim] == 0) continue;
00574 outgoingDOFs[p][blockSize*c+blockOffset]
00575 = getInitialDOFForCell(cellDim, LID, b);
00576 blockOffset++;
00577 }
00578 if (sendOrientation)
00579 {
00580 outgoingDOFs[p][blockSize*(c+1) - 1]
00581 = originalFacetOrientation_[cellDim-1][LID];
00582 }
00583 SUNDANCE_MSG3(setupVerb(),
00584 "p=" << rank
00585 << " done processing cell with GID=" << GID);
00586 }
00587 }
00588
00589
00590 SUNDANCE_MSG2(setupVerb(),
00591 "p=" << mesh().comm().getRank()
00592 << "answering DOF requests for cells of dimension " << cellDim);
00593
00594
00595 MPIContainerComm<int>::allToAll(outgoingDOFs,
00596 incomingDOFs,
00597 mesh().comm());
00598
00599 SUNDANCE_MSG2(setupVerb(),
00600 "p=" << mesh().comm().getRank()
00601 << "communicated DOF answers for cells of dimension " << cellDim);
00602
00603
00604
00605
00606 for (int p=0; p<mesh().comm().getNProc(); p++)
00607 {
00608 if (p==mesh().comm().getRank()) continue;
00609 const Array<int>& dofsFromProc = incomingDOFs[p];
00610 int numCells = dofsFromProc.size()/blockSize;
00611 for (int c=0; c<numCells; c++)
00612 {
00613 int cellGID = outgoingCellRequests[p][c];
00614 int cellLID = mesh().mapGIDToLID(cellDim, cellGID);
00615 int blockOffset = 0;
00616 for (int b=0; b<nBasisChunks(); b++)
00617 {
00618 if (nDofsPerCell_[b][cellDim] == 0) continue;
00619 int dof = dofsFromProc[blockSize*c+blockOffset];
00620 setDOFs(b, cellDim, cellLID, dof, true);
00621 blockOffset++;
00622 }
00623 if (sendOrientation)
00624 {
00625 originalFacetOrientation_[cellDim-1][cellLID]
00626 = dofsFromProc[blockSize*(c+1)-1];
00627 }
00628 }
00629 }
00630
00631 }
00632
00633
00634 RCP<const MapStructure> MixedDOFMapHN
00635 ::getDOFsForCellBatch(int cellDim,
00636 const Array<int>& cellLID,
00637 const Set<int>& requestedFuncSet,
00638 Array<Array<int> >& dofs,
00639 Array<int>& nNodes,
00640 int verbosity) const
00641 {
00642 TimeMonitor timer(batchedDofLookupTimer());
00643
00644 Tabs tab;
00645
00646 SUNDANCE_MSG2(verbosity,
00647 tab << "getDOFsForCellBatch(): cellDim=" << cellDim
00648 << " cellLID=" << cellLID);
00649
00650 dofs.resize(nBasisChunks());
00651 nNodes.resize(nBasisChunks());
00652
00653 int nCells = cellLID.size();
00654
00655 if (cellDim == dim_)
00656 {
00657 Tabs tab1;
00658
00659 SUNDANCE_MSG4(verbosity,tab1 << "getting dofs for maximal cells : " << cellLID );
00660
00661 for (int b=0; b<nBasisChunks(); b++)
00662 {
00663 nNodes[b] = totalNNodesPerCell_[b][cellDim];
00664 dofs[b].resize(nNodes[b]*nFuncs(b)*nCells);
00665 int dofsPerCell = nFuncs(b)*nNodes[b];
00666 Array<int>& chunkDofs = dofs[b];
00667
00668
00669
00670 for (int c=0; c<nCells; c++)
00671 {
00672 for (int i=0; i<dofsPerCell; i++)
00673 {
00674 chunkDofs[c*dofsPerCell + i]
00675 = maximalDofs_[b][cellLID[c]*dofsPerCell+i];
00676 }
00677 }
00678 SUNDANCE_MSG3(verbosity,tab1 << "dofs for chunk-" << b << " :" << chunkDofs);
00679 }
00680 }
00681 else
00682 {
00683 Tabs tab1;
00684 SUNDANCE_MSG3(verbosity,tab1 << "getting dofs for non-maximal cells");
00685
00686 static Array<Array<int> > facetLID(3);
00687 static Array<Array<int> > facetOrientations(3);
00688 static Array<int> numFacets(3);
00689
00690 for (int d=0; d<cellDim; d++)
00691 {
00692 numFacets[d] = mesh().numFacets(cellDim, cellLID[0], d);
00693 mesh().getFacetLIDs(cellDim, cellLID, d, facetLID[d],
00694 facetOrientations[d]);
00695 }
00696
00697 for (int b=0; b<nBasisChunks(); b++)
00698 {
00699 nNodes[b] = totalNNodesPerCell_[b][cellDim];
00700 dofs[b].resize(nNodes[b]*nFuncs(b)*nCells);
00701 int dofsPerCell = nFuncs(b)*nNodes[b];
00702
00703 Array<int>& toPtr = dofs[b];
00704 int nf = nFuncs(b);
00705
00706 for (int c=0; c<nCells; c++)
00707 {
00708 Tabs tab2;
00709 SUNDANCE_MSG3(verbosity,tab2 << "cell=" << c << " ,cellLID[c]:" << cellLID[c]);
00710 int offset = dofsPerCell*c;
00711
00712
00713
00714
00715 SUNDANCE_MSG3(verbosity,tab2 << "doing interior nodes");
00716 int nInteriorNodes = nNodesPerCell_[b][cellDim];
00717
00718 if (nInteriorNodes > 0)
00719 {
00720 if (cellDim==0 || nInteriorNodes <= 1)
00721 {
00722
00723 for (int func=0; func<nf; func++)
00724 {
00725 for (int n=0; n<nInteriorNodes; n++)
00726 {
00727 int ptr = localNodePtrs_[b][cellDim][cellDim][0][n];
00728 toPtr[offset + func*nNodes[b] + ptr]
00729 = dofs_[cellDim][b][cellLID[c]*nDofsPerCell_[b][cellDim]+func*nNodesPerCell_[b][cellDim]+n];
00730
00731 }
00732 }
00733 }
00734 else
00735 {
00736 int sign = originalFacetOrientation_[cellDim-1][cellLID[c]];
00737 int nInteriorNodes = localNodePtrs_[b][cellDim][cellDim][0].size();
00738
00739 for (int func=0; func<nf; func++)
00740 {
00741 for (int m=0; m<nInteriorNodes; m++)
00742 {
00743 int n = m;
00744 if (sign<0) n = nInteriorNodes-1-m;
00745 int ptr = localNodePtrs_[b][cellDim][cellDim][0][m];
00746 toPtr[offset + func*nNodes[b] + ptr] = dofs_[cellDim][b][cellLID[c]*nDofsPerCell_[b][cellDim]+func*nNodesPerCell_[b][cellDim]+n];
00747
00748 }
00749 }
00750 }
00751 }
00752
00753
00754 for (int d=0; d<cellDim; d++)
00755 {
00756 Tabs tab2;
00757 SUNDANCE_MSG3(verbosity,tab2 << "facet dim=" << d);
00758 if (nNodesPerCell_[b][d] == 0) continue;
00759 for (int f=0; f<numFacets[d]; f++)
00760 {
00761 Tabs tab3;
00762 int facetID = facetLID[d][c*numFacets[d]+f];
00763 SUNDANCE_MSG3(verbosity,tab2 << "f=" << f << " facetLID=" << facetID);
00764 if (localNodePtrs_[b][cellDim].size()==0) continue;
00765 int nFacetNodes = localNodePtrs_[b][cellDim][d][f].size();
00766
00767 int* toPtr1 = &(dofs[b][dofsPerCell*c]);
00768 const int* nodePtr = &(localNodePtrs_[b][cellDim][d][f][0]);
00769
00770
00771
00772 for (int func=0; func<nf; func++)
00773 {
00774 if (d == 0 || nFacetNodes <= 1)
00775 {
00776 for (int n=0; n<nFacetNodes; n++)
00777 {
00778 int ptr = nodePtr[n];
00779 toPtr1[func*nNodes[b] + ptr]
00780 = dofs_[d][b][facetID*nDofsPerCell_[b][d]+func*nNodesPerCell_[b][d]+n];
00781
00782
00783
00784 if (toPtr1[func*nNodes[b] + ptr] < 0 )
00785 {
00786 int fIndex = 1 , tmp1 = 1;
00787
00788
00789
00790 int maxCell = mesh().maxCofacetLID( d , facetID , 0 , fIndex);
00791
00792
00793
00794
00795
00796 Array<int> facetsLIDs;
00797 mesh().returnParentFacets( maxCell , d , facetsLIDs , tmp1 );
00798
00799
00800
00801
00802
00803 toPtr1[func*nNodes[b] + ptr]
00804 = dofs_[d][b][facetsLIDs[fIndex]*nDofsPerCell_[b][d]+func*nNodesPerCell_[b][d]+n];
00805 }
00806 }
00807 }
00808 else
00809 {
00810 int facetOrientation = facetOrientations[d][c*numFacets[d]+f]
00811 * originalFacetOrientation_[d-1][facetID];
00812 for (int m=0; m<nFacetNodes; m++)
00813 {
00814 int n = m;
00815 if (facetOrientation<0) n = nFacetNodes-1-m;
00816 int ptr = nodePtr[n];
00817 toPtr1[func*nNodes[b]+ptr]
00818 = dofs_[d][b][facetID*nDofsPerCell_[b][d]+func*nNodesPerCell_[b][d]+n];
00819
00820
00821 if (toPtr1[func*nNodes[b]+ptr] < 0)
00822 {
00823 int fIndex = 1 , tmp1 = 1;
00824
00825
00826
00827 int maxCell = mesh().maxCofacetLID( d , facetID , 0 , fIndex);
00828 Array<int> facetsLIDs;
00829 mesh().returnParentFacets( maxCell , d , facetsLIDs , tmp1 );
00830
00831
00832
00833 toPtr1[func*nNodes[b] + ptr]
00834 = dofs_[d][b][facetsLIDs[fIndex]*nDofsPerCell_[b][d]+func*nNodesPerCell_[b][d]+n];
00835 }
00836 }
00837 }
00838 }
00839 }
00840 }
00841 }
00842 }
00843
00844 }
00845 return structure_;
00846 }
00847
00848 void MixedDOFMapHN::buildMaximalDofTable()
00849 {
00850 TimeMonitor timer(maxDOFBuildTimer());
00851 Tabs tab;
00852 int cellDim = dim_;
00853 int nCells = mesh().numCells(dim_);
00854
00855 SUNDANCE_MSG1(setupVerb(),tab << "building dofs for maximal cells");
00856
00857 Array<Array<int> > facetLID(3);
00858 Array<Array<int> > facetOrientations(3);
00859 Array<int> numFacets(3);
00860
00861 Array<int> cellLID(nCells);
00862
00863 for (int c=0; c<nCells; c++) cellLID[c]=c;
00864
00865 for (int d=0; d<cellDim; d++)
00866 {
00867 numFacets[d] = mesh().numFacets(cellDim, cellLID[0], d);
00868 mesh().getFacetLIDs(cellDim, cellLID, d,
00869 facetLID[d], facetOrientations[d]);
00870 }
00871
00872 Array<int> nInteriorNodes(nBasisChunks());
00873 Array<int> nNodes(nBasisChunks());
00874 for (int b = 0; b<nBasisChunks(); b++)
00875 {
00876
00877 if (localNodePtrs_[b][cellDim].size() != 0)
00878 {
00879 nInteriorNodes[b] = localNodePtrs_[b][cellDim][cellDim][0].size();
00880 }
00881 else
00882 {
00883 nInteriorNodes[b] = 0;
00884 }
00885 nNodes[b] = totalNNodesPerCell_[b][cellDim];
00886 }
00887
00888
00889
00890
00891 Array< Array<Array<int> > >globalDoFs_Cell(nBasisChunks());
00892
00893 Array<Array<double> > trafoMatrix(nBasisChunks());
00894
00895 Array<int> localDoFs;
00896 Array<int> parentFacetDim;
00897 Array<int> parentFacetIndex;
00898 Array<int> parentFacetNode;
00899 Array<int> retFacets;
00900 Array<double> coefs;
00901
00902
00903 for (int c=0; c<nCells; c++)
00904 {
00905
00906
00907 for (int jj = 0 ; jj < numFacets[0] ; jj++){
00908 if (mesh().isElementHangingNode(0,facetLID[0][ c*numFacets[0] + jj])){
00909
00910
00911 hasCellHanging_[cellLID[c]] = true;
00912 break;
00913 }
00914 }
00915
00916 Tabs tab1;
00917 SUNDANCE_MSG3(setupVerb(),tab1 << "working on cell=" << c
00918 << " LID=" << cellLID[c]);
00919
00920
00921 SUNDANCE_MSG3(setupVerb(),tab1 << "doing interior nodes");
00922 for (int b=0; b<nBasisChunks(); b++)
00923 {
00924
00925 if (hasCellHanging_[cellLID[c]]){
00926
00927 globalDoFs_Cell[b].resize( nFuncs(b));
00928 trafoMatrix[b].resize(nNodes[b]*nNodes[b], 0.0);
00929 for (int jj = 0; jj < nNodes[b]*nNodes[b] ; jj++) trafoMatrix[b][jj] = 0.0;
00930 for (int func=0; func<nFuncs(b); func++)
00931 {
00932 globalDoFs_Cell[b][func].resize(nNodes[b]);
00933 for (int kk = 0 ; kk < nNodes[b] ; kk++ ){
00934 globalDoFs_Cell[b][func][kk] = -1;
00935 }
00936 }
00937 }
00938
00939 SUNDANCE_MSG3(setupVerb(),tab1 << "basis chunk=" << b);
00940 if (nInteriorNodes[b]>0)
00941 {
00942 SUNDANCE_MSG3(setupVerb(),tab1<< "nInteriorNodes = " <<nInteriorNodes[b]);
00943 int* toPtr = &(maximalDofs_[b][nNodes[b]*nFuncs(b)*cellLID[c]]);
00944 int nf = nFuncs(b);
00945 for (int func=0; func<nf; func++)
00946 {
00947 for (int n=0; n<nInteriorNodes[b]; n++)
00948 {
00949
00950
00951
00952
00953
00954
00955 int ptr = localNodePtrs_[b][cellDim][cellDim][0][n];
00956
00957 if (hasCellHanging_[cellLID[c]])
00958 {
00959 SUNDANCE_MSG1(setupVerb(), tab1 << "Cell has HDoF cellLID[c]=" << cellLID[c] );
00960 int dof_tmp = dofs_[cellDim][b][cellLID[c]*nDofsPerCell_[b][cellDim]+func*nNodesPerCell_[b][cellDim]+n];
00961
00962 SUNDANCE_MSG1(setupVerb(), tab1 << "Cell has HDoF cellLID[c] , globalDoFs_Cell[b][func]:"<<globalDoFs_Cell[b][func]<<" dof=" << dof_tmp);
00963 globalDoFs_Cell[b][func][ptr] = dof_tmp;
00964 SUNDANCE_MSG1(setupVerb(), tab1 << "Cell has HDoF cellLID[c] , ptr=" << ptr <<" dof=" << dof_tmp);
00965 if (func == 0){
00966 trafoMatrix[b][nNodes[b]*ptr + ptr] = 1.0;
00967 }
00968 }
00969
00970 toPtr[func*nNodes[b] + ptr] =
00971 dofs_[cellDim][b][cellLID[c]*nDofsPerCell_[b][cellDim]+func*nNodesPerCell_[b][cellDim]+n];
00972 SUNDANCE_MSG1(setupVerb(), tab1 << " dof=" << dofs_[cellDim][b][cellLID[c]*nDofsPerCell_[b][cellDim]+func*nNodesPerCell_[b][cellDim]+n]);
00973 }
00974 }
00975 }
00976 }
00977
00978 SUNDANCE_MSG3(setupVerb(),tab1 << "doing facet nodes");
00979
00980 for (int d=0; d<cellDim; d++)
00981 {
00982 Tabs tab2;
00983 SUNDANCE_MSG3(setupVerb(),tab2 << "facet dim=" << d);
00984
00985 for (int f=0; f<numFacets[d]; f++)
00986 {
00987 Tabs tab3;
00988 int facetID = facetLID[d][c*numFacets[d]+f];
00989 SUNDANCE_MSG3(setupVerb(),tab2 << "f=" << f << " facetLID=" << facetID);
00990
00991 for (int b=0; b<nBasisChunks(); b++)
00992 {
00993 Tabs tab4;
00994 SUNDANCE_MSG3(setupVerb(),tab4 << "basis chunk=" << b);
00995 SUNDANCE_MSG3(setupVerb(),tab4 << "num nodes per cell=" << nNodesPerCell_[b][d]);
00996 int nf = nFuncs(b);
00997 if (nDofsPerCell_[b][d]==0) continue;
00998 int nFacetNodes = 0;
00999 if (localNodePtrs_[b][cellDim].size()!=0)
01000 nFacetNodes = localNodePtrs_[b][cellDim][d][f].size();
01001 if (nFacetNodes == 0) continue;
01002
01003 SUNDANCE_MSG3(setupVerb(),tab4 << "dof table size=" << maximalDofs_[b].size());
01004
01005 int* toPtr = &(maximalDofs_[b][nNodes[b]*nFuncs(b)*cellLID[c]]);
01006
01007 const int* nodePtr = &(localNodePtrs_[b][cellDim][d][f][0]);
01008
01009 for (int func=0; func<nf; func++)
01010 {
01011 Tabs tab5;
01012 SUNDANCE_MSG3(setupVerb(),tab5 << "func=" << func);
01013 if (d == 0 || nFacetNodes <= 1)
01014 {
01015 Tabs tab6;
01016 for (int n=0; n<nFacetNodes; n++)
01017 {
01018 SUNDANCE_MSG3(setupVerb(),tab5 << "n=" << n);
01019 int ptr = nodePtr[n];
01020 SUNDANCE_MSG3(setupVerb(),tab6 << "ptr=" << ptr);
01021
01022
01023
01024
01025 if (hasCellHanging_[cellLID[c]]){
01026 int parentCellLID = 0;
01027 int dof_tmp = dofs_[d][b][facetID*nDofsPerCell_[b][d]+func*nNodesPerCell_[b][d]+n];
01028 SUNDANCE_MSG3(setupVerb(), tab1 << "Cell has HDoF cellLID[c] , d="<<d<<", f="<<f<<", n="<<n<<", dof=" << dof_tmp);
01029 if (dof_tmp < 0){
01030 Array<int> constFacetLID;
01031 Array<int> constFacetDim;
01032
01033 basis_[b]->getConstrainsForHNDoF(
01034 mesh().indexInParent(cellLID[c]), cellDim ,
01035 mesh().maxChildren(), d , f , n,
01036 localDoFs, parentFacetDim,
01037 parentFacetIndex, parentFacetNode, coefs );
01038 SUNDANCE_MSG3(setupVerb(), tab1 << " After basis_[b]->getConstrainsForHNDoF:");
01039 constFacetLID.resize(localDoFs.size());
01040 constFacetDim.resize(localDoFs.size());
01041 for (int indexi = 0 ; indexi < localDoFs.size() ; indexi++)
01042 {
01043
01044 int ptr1 = localNodePtrs_[b][cellDim][parentFacetDim[indexi]]
01045 [parentFacetIndex[indexi]][parentFacetNode[indexi]];
01046
01047 mesh().returnParentFacets(cellLID[c] , parentFacetDim[indexi], retFacets , parentCellLID );
01048 int parFacetLID = retFacets[parentFacetIndex[indexi]];
01049 int parFacetNode = parentFacetNode[indexi];
01050 SUNDANCE_MSG3(setupVerb(), tab1 << "returnParentFacets , parFacetLID=" << parFacetLID <<" parFacetNode=" << parFacetNode );
01051 SUNDANCE_MSG3(setupVerb(), tab1 << "returnParentFacets , retFacets=" << retFacets );
01052
01053 constFacetDim[indexi] = parentFacetDim[indexi];
01054 constFacetLID[indexi] = parFacetLID;
01055
01056 dof_tmp = dofs_[parentFacetDim[indexi]][b]
01057 [parFacetLID * nDofsPerCell_[b][parentFacetDim[indexi]]+func*nNodesPerCell_[b][parentFacetDim[indexi]]+parFacetNode];
01058
01059 globalDoFs_Cell[b][func][ptr1] = dof_tmp;
01060
01061 SUNDANCE_MSG3(setupVerb(), tab1 << "Cell has HDoF cellLID[c] , ptr=" << ptr << "ptr1=" << ptr1 <<" dof=" << dof_tmp);
01062 if (func == 0){
01063 trafoMatrix[b][nNodes[b]*ptr + ptr1] = coefs[indexi];
01064 }
01065 SUNDANCE_MSG3(setupVerb(), tab1 << "Cell has HDoF cellLID[c] , DONE Fill");
01066 }
01067
01068 if ( (d == 0) && (func == 0)) {
01069 HN_To_globalFacetsLID_.put( nPoints_*b + facetID , constFacetLID);
01070 HN_To_globalFacetsDim_.put( nPoints_*b + facetID , constFacetDim);
01071 HN_To_coeffs_.put( nPoints_*b + facetID , coefs);
01072 }
01073 }else {
01074
01075 SUNDANCE_MSG3(setupVerb(), tab1 << "Cell has HDoF cellLID[c] , ptr=" << ptr <<" dof=" << dof_tmp);
01076
01077
01078
01079
01080 globalDoFs_Cell[b][func][ptr] = dof_tmp;
01081 if (func == 0){
01082 trafoMatrix[b][nNodes[b]*ptr + ptr] = 1.0;
01083 }
01084 }
01085 } else {
01086 toPtr[func*nNodes[b] + ptr]
01087 = dofs_[d][b][facetID*nDofsPerCell_[b][d]+func*nNodesPerCell_[b][d]+n];
01088 SUNDANCE_MSG3(setupVerb(), tab1 << " dof=" << dofs_[d][b][facetID*nDofsPerCell_[b][d]+func*nNodesPerCell_[b][d]+n]);
01089 }
01090 }
01091 }
01092 else
01093 {
01094 int facetOrientation = facetOrientations[d][c*numFacets[d]+f]
01095 * originalFacetOrientation_[d-1][facetID];
01096 for (int m=0; m<nFacetNodes; m++)
01097 {
01098 int n = m;
01099 if (facetOrientation<0) n = nFacetNodes-1-m;
01100 int ptr = nodePtr[m];
01101
01102
01103
01104
01105
01106 if (hasCellHanging_[cellLID[c]])
01107 {
01108 int parentCellLID = 0;
01109 int dof_tmp = dofs_[d][b][facetID*nDofsPerCell_[b][d]+func*nNodesPerCell_[b][d]+n];
01110 SUNDANCE_MSG3(setupVerb(), tab1 << "Cell has HDoF cellLID[c] , d="<<d<<", f="<<f<<", n="<<n<<", dof=" << dof_tmp);
01111 if (dof_tmp < 0){
01112 Array<int> constFacetLID;
01113 Array<int> constFacetDim;
01114
01115 basis_[b]->getConstrainsForHNDoF(
01116 mesh().indexInParent(cellLID[c]), cellDim ,
01117 mesh().maxChildren(), d , f , n,
01118 localDoFs, parentFacetDim,
01119 parentFacetIndex, parentFacetNode, coefs );
01120 SUNDANCE_MSG3(setupVerb(), tab1 << " After basis_[b]->getConstrainsForHNDoF:");
01121 constFacetLID.resize(localDoFs.size());
01122 constFacetDim.resize(localDoFs.size());
01123 for (int indexi = 0 ; indexi < localDoFs.size() ; indexi++)
01124 {
01125
01126 int ptr1 = localNodePtrs_[b][cellDim][parentFacetDim[indexi]]
01127 [parentFacetIndex[indexi]][parentFacetNode[indexi]];
01128
01129 mesh().returnParentFacets(cellLID[c] , parentFacetDim[indexi], retFacets , parentCellLID );
01130 int parFacetLID = retFacets[parentFacetIndex[indexi]];
01131 int parFacetNode = parentFacetNode[indexi];
01132 SUNDANCE_MSG3(setupVerb(), tab1 << "returnParentFacets , parFacetLID=" << parFacetLID <<" parFacetNode=" << parFacetNode );
01133 SUNDANCE_MSG3(setupVerb(), tab1 << "returnParentFacets , retFacets=" << retFacets );
01134
01135 constFacetDim[indexi] = parentFacetDim[indexi];
01136 constFacetLID[indexi] = parFacetLID;
01137
01138 dof_tmp = dofs_[parentFacetDim[indexi]][b]
01139 [parFacetLID * nDofsPerCell_[b][parentFacetDim[indexi]]+func*nNodesPerCell_[b][parentFacetDim[indexi]]+parFacetNode];
01140
01141 globalDoFs_Cell[b][func][ptr1] = dof_tmp;
01142
01143 SUNDANCE_MSG3(setupVerb(), tab1 << "Cell has HDoF cellLID[c] , ptr=" << ptr1 <<" dof=" << dof_tmp);
01144 if (func == 0){
01145 trafoMatrix[b][nNodes[b]*ptr + ptr1] = coefs[indexi];
01146 }
01147 }
01148
01149 if ( (d == 0) && (func == 0)) {
01150 HN_To_globalFacetsLID_.put( nPoints_*b + facetID , constFacetLID);
01151 HN_To_globalFacetsDim_.put( nPoints_*b + facetID , constFacetDim);
01152 HN_To_coeffs_.put( nPoints_*b + facetID , coefs);
01153 }
01154 }else{
01155
01156
01157 SUNDANCE_MSG3(setupVerb(), tab1 << "Cell has HDoF cellLID[c] , ptr=" << ptr <<" dof=" << dof_tmp);
01158 globalDoFs_Cell[b][func][ptr] = dof_tmp;
01159 if (func == 0){
01160 trafoMatrix[b][nNodes[b]*ptr + ptr] = 1.0;
01161 }
01162 }
01163 } else {
01164 toPtr[func*nNodes[b]+ptr]
01165 = dofs_[d][b][facetID*nDofsPerCell_[b][d]+func*nNodesPerCell_[b][d]+n];
01166 SUNDANCE_MSG3(setupVerb(), tab1 << " dof=" << dofs_[d][b][facetID*nDofsPerCell_[b][d]+func*nNodesPerCell_[b][d]+n]);
01167 }
01168 }
01169 }
01170 }
01171 }
01172 }
01173 }
01174
01175
01176 if (hasCellHanging_[cellLID[c]]){
01177
01178 Array<int> matrixIndexes(nBasisChunks());
01179 for (int b=0; b<nBasisChunks(); b++){
01180 matrixIndexes[b] = matrixStore_.addMatrix( b , trafoMatrix[b] );
01181 }
01182 maxCellLIDwithHN_to_TrafoMatrix_.put( cellLID[c] , matrixIndexes );
01183
01184 for (int b=0; b<nBasisChunks(); b++)
01185 {
01186
01187 SUNDANCE_MSG3(setupVerb(), "trafoMatrix[b]=" << trafoMatrix[b]);
01188 for (int func=0; func<nFuncs(b); func++)
01189 {
01190
01191 SUNDANCE_MSG1(setupVerb(), "globalDoFs_Cell[b][func]=" << globalDoFs_Cell[b][func]);
01192 for (int jj=0 ; jj < nNodes[b] ; jj++){
01193
01194 maximalDofs_[b][(cellLID[c]*nFuncs(b) + func)*nNodes[b] + jj] = globalDoFs_Cell[b][func][jj];
01195 }
01196 }
01197 }
01198 }
01199 }
01200
01201 haveMaximalDofs_ = true;
01202
01203 SUNDANCE_MSG1(setupVerb(),tab << "done building dofs for maximal cells");
01204 }
01205
01206
01207 void MixedDOFMapHN::getTrafoMatrixForCell(
01208 int cellLID,
01209 int funcID,
01210 int& trafoMatrixSize,
01211 bool& doTransform,
01212 Array<double>& transfMatrix ) const {
01213
01214 trafoMatrixSize = 0;
01215
01216 if (maxCellLIDwithHN_to_TrafoMatrix_.containsKey(cellLID))
01217 {
01218
01219 const Array<int> &matrixIndexes = maxCellLIDwithHN_to_TrafoMatrix_.get( cellLID );
01220 matrixStore_.getMatrix( chunkForFuncID(funcID) , matrixIndexes[chunkForFuncID(funcID)] , transfMatrix );
01221
01222
01223
01224 trafoMatrixSize = sqrt((double) transfMatrix.size());
01225 SUNDANCE_MSG1(setupVerb(), "getTrafoMatrixForCell() cellLID:" << cellLID << ",funcID:" <<
01226 funcID << ",chunkForFuncID(funcID):" << chunkForFuncID(funcID) << ", trafoMatrixSize:" << trafoMatrixSize);
01227
01228 doTransform = true;
01229 }
01230 else
01231 {
01232 doTransform = false;
01233 }
01234 }
01235
01236 void MixedDOFMapHN::getTrafoMatrixForFacet(
01237 int cellDim,
01238 int cellLID,
01239 int facetIndex,
01240 int funcID,
01241 int& trafoMatrixSize,
01242 bool& doTransform,
01243 Array<double>& transfMatrix ) const {
01244
01245 int fIndex;
01246 int maxCellLID;
01247
01248 SUNDANCE_MSG2(setupVerb() , "NodalDOFMapHN::getTrafoMatrixForFacet() cellDim :" << cellDim << ", cellLID:" << cellLID);
01249 maxCellLID = mesh().maxCofacetLID( cellDim, cellLID, 0 , fIndex);
01250 SUNDANCE_MSG2(setupVerb() , "NodalDOFMapHN::getTrafoMatrixForFacet() testing :" << maxCellLID);
01251
01252
01253
01254 if (maxCellLIDwithHN_to_TrafoMatrix_.containsKey(maxCellLID))
01255 {
01256 const Array<int> &matrixIndexes = maxCellLIDwithHN_to_TrafoMatrix_.get( maxCellLID );
01257 matrixStore_.getMatrix( chunkForFuncID(funcID) , matrixIndexes[chunkForFuncID(funcID)] , transfMatrix );
01258 doTransform = true;
01259 }
01260 else
01261 {
01262 doTransform = false;
01263 }
01264 }
01265
01266
01267 void MixedDOFMapHN::getDOFsForHNCell(
01268 int cellDim,
01269 int cellLID,
01270 int funcID,
01271 Array<int>& dofs ,
01272 Array<double>& coefs ) const {
01273
01274
01275
01276
01277
01278 if ( (cellDim == 0) && ( HN_To_globalFacetsLID_.containsKey(nPoints_*chunkForFuncID(funcID) + cellLID)) )
01279 {
01280 Array<int> facetLIDs;
01281 Array<int> facetDim;
01282 SUNDANCE_MSG1(setupVerb(), "getDOFsForHNCell() cellDim:"<<cellDim<<" cellLID:"<<
01283 cellLID<<"funcID:" << funcID <<",chunkForFuncID(funcID)" << chunkForFuncID(funcID));
01284 facetLIDs = HN_To_globalFacetsLID_.get( nPoints_*chunkForFuncID(funcID) + cellLID );
01285 facetDim = HN_To_globalFacetsDim_.get( nPoints_*chunkForFuncID(funcID) + cellLID );
01286 dofs.resize(facetLIDs.size());
01287 int b = chunkForFuncID(funcID);
01288 int func = indexForFuncID(funcID);
01289
01290 for (int ind = 0 ; ind < facetLIDs.size() ; ind++){
01291
01292 dofs[ind] = dofs_[facetDim[ind]][b]
01293 [facetLIDs[ind]*nDofsPerCell_[b][facetDim[ind]]+func*nNodesPerCell_[b][facetDim[ind]] + 0 ];
01294 }
01295
01296 coefs = HN_To_coeffs_.get( nPoints_*chunkForFuncID(funcID) + cellLID );
01297 SUNDANCE_MSG1(setupVerb(), "b=" << b);
01298 SUNDANCE_MSG1(setupVerb(), "func=" << func);
01299 SUNDANCE_MSG1(setupVerb(), "facetLIDs=" << facetLIDs);
01300 SUNDANCE_MSG1(setupVerb(), "facetDim = " << facetDim);
01301 SUNDANCE_MSG1(setupVerb(), "dofs=" << dofs);
01302 SUNDANCE_MSG1(setupVerb(), "coefs = " << coefs);
01303 }
01304 }
01305
01306
01307 void MixedDOFMapHN::computeOffsets(int dim, int localCount)
01308 {
01309 if (setupVerb() > 2)
01310 {
01311 comm().synchronize();
01312 comm().synchronize();
01313 comm().synchronize();
01314 comm().synchronize();
01315 }
01316 SUNDANCE_MSG2(setupVerb(),
01317 "p=" << mesh().comm().getRank()
01318 << " sharing offsets for DOF numbering for dim=" << dim);
01319
01320 SUNDANCE_MSG2(setupVerb(),
01321 "p=" << mesh().comm().getRank()
01322 << " I have " << localCount << " cells");
01323
01324 Array<int> dofOffsets;
01325 int totalDOFCount;
01326 MPIContainerComm<int>::accumulate(localCount, dofOffsets, totalDOFCount,
01327 mesh().comm());
01328 int myOffset = dofOffsets[mesh().comm().getRank()];
01329
01330 SUNDANCE_MSG2(setupVerb(),
01331 "p=" << mesh().comm().getRank()
01332 << " back from MPI accumulate");
01333
01334 if (setupVerb() > 2)
01335 {
01336 comm().synchronize();
01337 comm().synchronize();
01338 comm().synchronize();
01339 comm().synchronize();
01340 }
01341
01342 for (int chunk=0; chunk<dofs_[dim].size(); chunk++)
01343 {
01344 for (int n=0; n<dofs_[dim][chunk].size(); n++)
01345 {
01346
01347 if (dofs_[dim][chunk][n] >= 0) {
01348 dofs_[dim][chunk][n] += myOffset;
01349 }
01350 }
01351 }
01352
01353 setLowestLocalDOF(myOffset);
01354 setNumLocalDOFs(localCount);
01355 setTotalNumDOFs(totalDOFCount);
01356
01357 SUNDANCE_MSG2(setupVerb(),
01358 "p=" << mesh().comm().getRank()
01359 << " done sharing offsets for DOF numbering for dim=" << dim);
01360 if (setupVerb() > 2)
01361 {
01362 comm().synchronize();
01363 comm().synchronize();
01364 comm().synchronize();
01365 comm().synchronize();
01366 }
01367
01368 }
01369
01370
01371
01372 void MixedDOFMapHN::checkTable() const
01373 {
01374 int bad = 0;
01375 for (int d=0; d<dofs_.size(); d++)
01376 {
01377 for (int chunk=0; chunk<dofs_[d].size(); chunk++)
01378 {
01379 const Array<int>& dofs = dofs_[d][chunk];
01380 for (int n=0; n<dofs.size(); n++)
01381 {
01382 if (dofs[n] < 0) bad = 1;
01383 }
01384 }
01385 }
01386
01387 int anyBad = bad;
01388 comm().allReduce((void*) &bad, (void*) &anyBad, 1,
01389 MPIDataType::intType(), MPIOp::sumOp());
01390 TEUCHOS_TEST_FOR_EXCEPTION(anyBad > 0, std::runtime_error, "invalid DOF map");
01391 }