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