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 "SundanceMap.hpp"
00043 #include "PlayaTabs.hpp"
00044 #include "SundanceOut.hpp"
00045 #include "SundanceOrderedTuple.hpp"
00046 #include "SundanceNodalDOFMapHN.hpp"
00047 #include "SundanceLagrange.hpp"
00048 #include "PlayaMPIContainerComm.hpp"
00049 #include "Teuchos_TimeMonitor.hpp"
00050
00051
00052 using namespace Sundance;
00053 using namespace Teuchos;
00054 using Playa::MPIComm;
00055 using Playa::MPIContainerComm;
00056
00057 NodalDOFMapHN::NodalDOFMapHN(const Mesh& mesh,
00058 int nFuncs,
00059 const CellFilter& maxCellFilter,
00060 int setupVerb)
00061 : HNDoFMapBaseHomogeneous(mesh, nFuncs, setupVerb),
00062 maxCellFilter_(maxCellFilter),
00063 dim_(mesh.spatialDim()),
00064 nFuncs_(nFuncs),
00065 nElems_(mesh.numCells(mesh.spatialDim())),
00066 nNodes_(mesh.numCells(0)),
00067 nNodesPerElem_(mesh.numFacets(mesh.spatialDim(),0,0)),
00068 elemDofs_(nElems_ * nFuncs * nNodesPerElem_),
00069 nodeDofs_(mesh.numCells(0)*nFuncs_, -2),
00070 structure_(rcp(new MapStructure(nFuncs_, rcp(new Lagrange(1))))),
00071 hasCellHanging_(nElems_),
00072 nodeIsHanging_(nElems_ * nFuncs * nNodesPerElem_),
00073 cellsWithHangingDoF_globalDoFs_(),
00074 cells_To_NodeLIDs_(),
00075 hangingNodeLID_to_NodesLIDs_(),
00076 hangindNodeLID_to_Coefs_(),
00077 matrixStore_(),
00078 facetLID_()
00079 {
00080
00081 matrixStore_.init(1);
00082 init();
00083 }
00084
00085 void NodalDOFMapHN::init()
00086 {
00087 Tabs tab;
00088
00089 SUNDANCE_MSG2(setupVerb(), tab << "NodalDOFMapHN initializing nodal DOF map nrFunc:"
00090 << nFuncs_ << " nNodes_:" << nNodes_ << " nElems_:" <<nElems_);
00091
00092 Array<Array<int> > remoteNodes(mesh().comm().getNProc());
00093 Array<int> hasProcessedCell(nNodes_, 0);
00094
00095
00096 int nextDOF = 0;
00097 int owner;
00098
00099 nFacets_ = mesh().numFacets(dim_, 0, 0);
00100 Array<int> elemLID(nElems_);
00101 Array<int> facetOrientations(nFacets_*nElems_);
00102
00103
00104 CellSet maxCells = maxCellFilter_.getCells(mesh());
00105
00106 int cc = 0;
00107 for (CellIterator iter=maxCells.begin(); iter != maxCells.end(); iter++, cc++)
00108 {
00109 int c = *iter;
00110 elemLID[cc] = c;
00111 }
00112
00113
00114 mesh().getFacetLIDs(dim_, elemLID, 0, facetLID_, facetOrientations);
00115
00116 for (int c=0; c<nElems_; c++) {
00117 hasCellHanging_[c] = false;
00118
00119 for (int f=0; f<nFacets_; f++) {
00120
00121
00122 int fLID = facetLID_[c*nFacets_+f];
00123 SUNDANCE_MSG2(setupVerb(), "NodalDOFMapHN::init() CellLID:"<< c <<"Try point LID:" << fLID << " facet:" << f);
00124 if (hasProcessedCell[fLID] == 0) {
00125
00126
00127 if ( isRemote(0, fLID, owner) && (!mesh().isElementHangingNode(0,fLID)) ) {
00128 int facetGID
00129 = mesh().mapLIDToGID(0, fLID);
00130 remoteNodes[owner].append(facetGID);
00131 }
00132 else {
00133 SUNDANCE_MSG2(setupVerb(), "NodalDOFMapHN::init() Doing point LID:" << fLID << " facet:" << f);
00134
00135 if ( mesh().isElementHangingNode(0,fLID) == false ){
00136
00137 for (int i=0; i<nFuncs_; i++){
00138 nodeDofs_[fLID*nFuncs_ + i] = nextDOF;
00139 nextDOF++;
00140 }
00141 } else {
00142 SUNDANCE_MSG2(setupVerb(), "NodalDOFMapHN::init() Hanging node found LID:" << fLID);
00143 hasCellHanging_[c] = true;
00144 for (int i=0; i<nFuncs_; i++){
00145 nodeDofs_[fLID*nFuncs_ + i] = -1;
00146 }
00147 Array<int> pointsLIDs;
00148 Array<int> facetIndex;
00149 Array<double> coefs;
00150
00151 getPointLIDsForHN( fLID, f, c , pointsLIDs, coefs , facetIndex);
00152
00153
00154 hangingNodeLID_to_NodesLIDs_.put( fLID , pointsLIDs );
00155 hangindNodeLID_to_Coefs_.put(fLID,coefs);
00156 }
00157 }
00158 hasProcessedCell[fLID] = 1;
00159 }
00160
00161 if (mesh().isElementHangingNode(0,fLID) == true) {
00162 hasCellHanging_[c] = true;
00163 }
00164 }
00165 }
00166
00167
00168
00169
00170 int localCount = nextDOF;
00171 computeOffsets(localCount);
00172
00173
00174 shareRemoteDOFs(remoteNodes);
00175
00176
00177
00178
00179 for (int c=0; c<nElems_; c++)
00180 {
00181 if (hasCellHanging_[c]){
00182 Array<int> HNDoFs(nFacets_);
00183 Array<double> transMatrix;
00184 Array<double> coefs;
00185
00186 transMatrix.resize(nFacets_*nFacets_);
00187 for (int ii = 0 ; ii < nFacets_*nFacets_ ; ii++) transMatrix[ii] = 0.0;
00188
00189 for (int f=0; f<nFacets_; f++)
00190 {
00191 int fLID = facetLID_[c*nFacets_+f];
00192 SUNDANCE_MSG2(setupVerb(), tab << "NodalDOFMapHN cell:" << c << " facetLID:" << fLID
00193 << " hanging:"<< nodeDofs_[fLID*nFuncs_] << " array:" << HNDoFs);
00194 if (nodeDofs_[fLID*nFuncs_] < 0)
00195 {
00196 Array<int> pointsLIDs;
00197 Array<int> facetIndex;
00198 Array<double> coefs;
00199
00200 getPointLIDsForHN( fLID, f, c , pointsLIDs, coefs , facetIndex);
00201
00202 for (int j=0 ; j < pointsLIDs.size() ; j++){
00203
00204 HNDoFs[facetIndex[j]] = pointsLIDs[j];
00205 transMatrix[f*nFacets_ + facetIndex[j]] = coefs[j];
00206 }
00207 }
00208 else
00209 {
00210
00211 HNDoFs[f] = fLID;
00212 transMatrix[f*nFacets_ + f] = 1.0;
00213 }
00214 }
00215
00216 int matrixIndex = matrixStore_.addMatrix(0,transMatrix);
00217 maxCellLIDwithHN_to_TrafoMatrix_.put( c , matrixIndex );
00218
00219
00220 cellsWithHangingDoF_globalDoFs_.put( c , HNDoFs );
00221
00222 SUNDANCE_MSG2(setupVerb(), tab << "NodalDOFMapHN initializing cellLID:" << c << " array:" << HNDoFs);
00223 SUNDANCE_MSG2(setupVerb(), tab << "NodalDOFMapHN initializing cellLID:" << c << " Trafo array:" << transMatrix);
00224
00225
00226 for (int f=0; f<nFacets_; f++)
00227 {
00228 int fLID = HNDoFs[f];
00229 for (int i=0; i<nFuncs_; i++) {
00230 elemDofs_[(c*nFuncs_+i)*nFacets_ + f] = nodeDofs_[fLID*nFuncs_ + i];
00231 }
00232
00233 }
00234 SUNDANCE_MSG2(setupVerb(),tab << "NodalDOFMapHN HN initializing cellLID:" << c << " elemDofs_:" << elemDofs_);
00235 }
00236 else {
00237
00238 for (int f=0; f<nFacets_; f++)
00239 {
00240 int fLID = facetLID_[c*nFacets_+f];
00241 for (int i=0; i<nFuncs_; i++)
00242 {
00243 elemDofs_[(c*nFuncs_+i)*nFacets_ + f] = nodeDofs_[fLID*nFuncs_ + i];
00244 }
00245 }
00246 SUNDANCE_MSG2(setupVerb(),tab << "NodalDOFMapHN initializing cellLID:" << c << " elemDofs_:" << elemDofs_);
00247 }
00248 }
00249 SUNDANCE_MSG2(setupVerb(),tab << "NodalDOFMapHN initializing DONE");
00250
00251 }
00252
00253 RCP<const MapStructure>
00254 NodalDOFMapHN::getDOFsForCellBatch(int cellDim,
00255 const Array<int>& cellLID,
00256 const Set<int>& requestedFuncSet,
00257 Array<Array<int> >& dofs,
00258 Array<int>& nNodes,
00259 int verbosity) const
00260 {
00261 TimeMonitor timer(batchedDofLookupTimer());
00262
00263 Tabs tab;
00264 SUNDANCE_MSG2(verbosity,
00265 tab << "NodalDOFMapHN::getDOFsForCellBatch(): cellDim=" << cellDim
00266 << " requestedFuncSet:" << requestedFuncSet
00267 << " cellLID=" << cellLID);
00268
00269
00270 dofs.resize(1);
00271 nNodes.resize(1);
00272
00273 int nCells = cellLID.size();
00274
00275
00276 if (cellDim == dim_)
00277 {
00278 int dofsPerElem = nFuncs_ * nNodesPerElem_;
00279 nNodes[0] = nNodesPerElem_;
00280 dofs[0].resize(nCells * dofsPerElem);
00281 Array<int>& dof0 = dofs[0];
00282 Array<int> tmpArray;
00283
00284 tmpArray.resize(dofsPerElem);
00285
00286 for (int c=0; c<nCells; c++)
00287 {
00288
00289 for (int i=0; i<dofsPerElem; i++) {
00290 dof0[c*dofsPerElem + i] = elemDofs_[cellLID[c]*dofsPerElem+i];
00291 tmpArray[i] = elemDofs_[cellLID[c]*dofsPerElem+i];
00292 }
00293 SUNDANCE_MSG2(verbosity,tab << "NodalDOFMapHN::getDOFsForCellBatch cellDim:" <<
00294 cellDim << " cellLID:" << c << " array:" << tmpArray);
00295 }
00296 }
00297 else if (cellDim == 0)
00298 {
00299 nNodes[0] = 1;
00300 dofs[0].resize(nCells * nFuncs_);
00301 Array<int>& dof0 = dofs[0];
00302 Array<int> tmpArray;
00303 tmpArray.resize(nFuncs_);
00304
00305 for (int c=0; c<nCells; c++)
00306 {
00307 for (int i=0; i<nFuncs_; i++)
00308 {
00309 dof0[c*nFuncs_ + i] = nodeDofs_[cellLID[c]*nFuncs_+i];
00310 tmpArray[i] = nodeDofs_[cellLID[c]*nFuncs_+i];
00311 }
00312 SUNDANCE_MSG2(verbosity,tab << "NodalDOFMapHN::getDOFsForCellBatch cellDim:" <<
00313 cellDim << " pointLID:" << cellLID[c] << " array:" << tmpArray);
00314 }
00315 }
00316 else
00317 {
00318
00319 int nFacets = mesh().numFacets(cellDim, cellLID[0], 0);
00320 nNodes[0] = nFacets;
00321 int dofsPerCell = nFuncs_ * nNodes[0];
00322 dofs[0].resize(nCells * dofsPerCell);
00323 Array<int>& dof0 = dofs[0];
00324 Array<int> facetLIDs(nCells * nNodes[0]);
00325 Array<int> dummy(nCells * nNodes[0]);
00326 Array<int> tmpArray;
00327 tmpArray.resize(nFuncs_*nFacets);
00328
00329 mesh().getFacetLIDs(cellDim, cellLID, 0, facetLIDs, dummy);
00330
00331 for (int c=0; c<nCells; c++)
00332 {
00333 for (int f=0; f<nFacets; f++)
00334 {
00335 int facetCellLID = facetLIDs[c*nFacets+f];
00336 for (int i=0; i<nFuncs_; i++)
00337 {
00338 dof0[(c*nFuncs_+i)*nFacets + f]
00339 = nodeDofs_[facetCellLID*nFuncs_+i];
00340
00341 if ( nodeDofs_[facetCellLID*nFuncs_+i] < 0){
00342 int tmp = 1;
00343
00344 int maxCell = mesh().maxCofacetLID( cellDim , cellLID[c] , 0 , tmp);
00345 Array<int> facetsLIDs;
00346 mesh().returnParentFacets( maxCell , 0 , facetsLIDs , tmp );
00347
00348 Array<int> childFacets(mesh().numFacets(mesh().spatialDim(),0,0));
00349 for (int jk = 0 ; jk < childFacets.size() ; jk++)
00350 childFacets[jk] = mesh().facetLID( mesh().spatialDim() , maxCell, 0 , jk , tmp);
00351 int fIndex = 0;
00352
00353 for (int jk = 0 ; jk < childFacets.size() ; jk++)
00354 if ( childFacets[jk] == facetCellLID) { fIndex = jk; break;}
00355 dof0[(c*nFuncs_+i)*nFacets + f] = nodeDofs_[facetsLIDs[fIndex]*nFuncs_ + i];
00356 }
00357 tmpArray[f*nFuncs_+i] = dof0[(c*nFuncs_+i)*nFacets + f];
00358 }
00359 }
00360 SUNDANCE_MSG2(verbosity,tab << "NodalDOFMapHN::getDOFsForCellBatch cellDim:" <<
00361 cellDim << " edge or face LID:" << cellLID[c] << " array:" << tmpArray);
00362 }
00363 }
00364 SUNDANCE_MSG2(verbosity,
00365 tab << "NodalDOFMapHN::getDOFsForCellBatch(): DONE");
00366 return structure_;
00367 }
00368
00369
00370 void NodalDOFMapHN::getTrafoMatrixForCell(
00371 int cellLID,
00372 int funcID,
00373 int& trafoMatrixSize,
00374 bool& doTransform,
00375 Array<double>& transfMatrix ) const {
00376
00377 trafoMatrixSize = nFacets_;
00378
00379 if (cellsWithHangingDoF_globalDoFs_.containsKey(cellLID))
00380 {
00381
00382 int matrixIndex = maxCellLIDwithHN_to_TrafoMatrix_.get( cellLID );
00383 matrixStore_.getMatrix( 0 , matrixIndex , transfMatrix );
00384 doTransform = true;
00385 }
00386 else
00387 {
00388 doTransform = false;
00389 }
00390 }
00391
00392 void NodalDOFMapHN::getTrafoMatrixForFacet(
00393 int cellDim,
00394 int cellLID,
00395 int facetIndex,
00396 int funcID,
00397 int& trafoMatrixSize,
00398 bool& doTransform,
00399 Array<double>& transfMatrix ) const {
00400
00401 int fIndex;
00402 int maxCellLID;
00403
00404 SUNDANCE_MSG2(setupVerb() , "NodalDOFMapHN::getTrafoMatrixForFacet() cellDim :" << cellDim << ", cellLID:" << cellLID);
00405 maxCellLID = mesh().maxCofacetLID( cellDim, cellLID, 0 , fIndex);
00406 SUNDANCE_MSG2(setupVerb() , "NodalDOFMapHN::getTrafoMatrixForFacet() testing :" << maxCellLID);
00407
00408
00409
00410 if (cellsWithHangingDoF_globalDoFs_.containsKey(maxCellLID))
00411 {
00412 int matrixIndex = maxCellLIDwithHN_to_TrafoMatrix_.get( maxCellLID );
00413 matrixStore_.getMatrix( 0 , matrixIndex , transfMatrix );
00414 doTransform = true;
00415 }
00416 else
00417 {
00418 doTransform = false;
00419 }
00420 }
00421
00422
00423 void NodalDOFMapHN::getDOFsForHNCell(
00424 int cellDim,
00425 int cellLID,
00426 int funcID,
00427 Array<int>& dofs ,
00428 Array<double>& coefs ) const {
00429
00430
00431 if ( (cellDim == 0) && (hangingNodeLID_to_NodesLIDs_.containsKey(cellLID)) )
00432 {
00433 Array<int> pointLIDs;
00434 Array<int> pointCoefs;
00435 pointLIDs = hangingNodeLID_to_NodesLIDs_.get( cellLID );
00436 dofs.resize(pointLIDs.size());
00437
00438 for (int ind = 0 ; ind < pointLIDs.size() ; ind++){
00439 dofs[ind] = nodeDofs_[ pointLIDs[ind] *nFuncs_ + funcID ];
00440 }
00441
00442 coefs = hangindNodeLID_to_Coefs_.get( cellLID );
00443 }
00444 }
00445
00446
00447
00448 void NodalDOFMapHN::getPointLIDsForHN( int pointLID , int facetIndex ,
00449 int maxCellIndex ,Array<int>& glbLIDs, Array<double>& coefsArray , Array<int>& nodeIndex){
00450
00451 Array<int> facets;
00452 int indexInParent , parentLID , facetCase = 0;
00453 double divRatio = 0.5;
00454 switch (dim_){
00455 case 2:
00456
00457 glbLIDs.resize(2);
00458 nodeIndex.resize(2);
00459 indexInParent = mesh().indexInParent(maxCellIndex);
00460 mesh().returnParentFacets(maxCellIndex , 0 ,facets , parentLID );
00461 switch( mesh().maxChildren()) {
00462
00463 case 9: {
00464 switch (indexInParent){
00465 case 0: {facetCase = (facetIndex == 1)? 0 : 1;
00466 divRatio = (1.0/3.0); break;}
00467 case 1: {facetCase = 0;
00468 divRatio = (facetIndex == 0)? (1.0/3.0) : (2.0/3.0); break;}
00469 case 2: {facetCase = (facetIndex == 0)? 0 : 2;
00470 divRatio = (facetIndex == 0)? (2.0/3.0) : (1.0/3.0); break;}
00471 case 5: {facetCase = 1;
00472 divRatio = (facetIndex == 0)? (1.0/3.0) : (2.0/3.0); break;}
00473 case 3: {facetCase = 2;
00474 divRatio = (facetIndex == 1)? (1.0/3.0) : (2.0/3.0); break;}
00475 case 6: {facetCase = (facetIndex == 0)? 1 : 3;
00476 divRatio = (facetIndex == 0)? (2.0/3.0) : (1.0/3.0); break;}
00477 case 7: {facetCase = 3;
00478 divRatio = (facetIndex == 2)? (1.0/3.0) : (2.0/3.0); break;}
00479 case 8: {facetCase = (facetIndex == 1)? 2 : 3;
00480 divRatio = (2.0/3.0); break;}
00481 }
00482 break;
00483 }
00484
00485 case 4:{
00486 divRatio = 0.5;
00487 switch (indexInParent){
00488 case 0: {facetCase = (facetIndex == 1)? 0 : 1; break;}
00489 case 1: {facetCase = (facetIndex == 0)? 0 : 2; break;}
00490 case 2: {facetCase = (facetIndex == 0)? 1 : 3; break;}
00491 case 3: {facetCase = (facetIndex == 1)? 2 : 3; break;}
00492 }
00493 break;
00494 }
00495 default: {}
00496 }
00497
00498 switch (facetCase){
00499 case 0: {glbLIDs[0] = facets[0]; glbLIDs[1] = facets[1];
00500 nodeIndex[0] = 0; nodeIndex[1] = 1; break;}
00501 case 1: {glbLIDs[0] = facets[0]; glbLIDs[1] = facets[2];
00502 nodeIndex[0] = 0; nodeIndex[1] = 2; break;}
00503 case 2: {glbLIDs[0] = facets[1]; glbLIDs[1] = facets[3];
00504 nodeIndex[0] = 1; nodeIndex[1] = 3; break;}
00505 case 3: {glbLIDs[0] = facets[2]; glbLIDs[1] = facets[3];
00506 nodeIndex[0] = 2; nodeIndex[1] = 3; break;}
00507 }
00508 coefsArray.resize(2); coefsArray[0] = 1 - divRatio; coefsArray[1] = divRatio;
00509 SUNDANCE_MSG2(setupVerb(),"NodalDOFMapHN::getPointLIDsForHN() fc=" << facetCase << " R=" << divRatio
00510 << " facetIndex:" << facetIndex << " indexInParent:" << indexInParent <<" glbLIDs:"
00511 << glbLIDs << " maxCellIndex:" << maxCellIndex << " nodeIndex:" << nodeIndex);
00512 break;
00513 case 3:{
00514
00515 double ind_x = 0 , ind_y = 0 , ind_z = 0;
00516 double f_x = 0.0 , f_y = 0.0 , f_z = 0.0;
00517 double xx = 0.0 , yy = 0.0 , zz = 0.0;
00518 double values[8];
00519 indexInParent = mesh().indexInParent(maxCellIndex);
00520 mesh().returnParentFacets(maxCellIndex , 0 ,facets , parentLID );
00521
00522 switch( mesh().maxChildren()) {
00523
00524 case 27:{
00525 switch (indexInParent){
00526 case 0: { ind_x = 0.0; ind_y = 0.0; ind_z = 0.0; break;}
00527 case 1: { ind_x = 1.0; ind_y = 0.0; ind_z = 0.0; break;}
00528 case 2: { ind_x = 2.0; ind_y = 0.0; ind_z = 0.0; break;}
00529 case 3: { ind_x = 0.0; ind_y = 1.0; ind_z = 0.0; break;}
00530 case 4: { ind_x = 1.0; ind_y = 1.0; ind_z = 0.0; break;}
00531 case 5: { ind_x = 2.0; ind_y = 1.0; ind_z = 0.0; break;}
00532 case 6: { ind_x = 0.0; ind_y = 2.0; ind_z = 0.0; break;}
00533 case 7: { ind_x = 1.0; ind_y = 2.0; ind_z = 0.0; break;}
00534 case 8: { ind_x = 2.0; ind_y = 2.0; ind_z = 0.0; break;}
00535 case 9: { ind_x = 0.0; ind_y = 0.0; ind_z = 1.0; break;}
00536 case 10: { ind_x = 1.0; ind_y = 0.0; ind_z = 1.0; break;}
00537 case 11: { ind_x = 2.0; ind_y = 0.0; ind_z = 1.0; break;}
00538 case 12: { ind_x = 0.0; ind_y = 1.0; ind_z = 1.0; break;}
00539 case 14: { ind_x = 2.0; ind_y = 1.0; ind_z = 1.0; break;}
00540 case 15: { ind_x = 0.0; ind_y = 2.0; ind_z = 1.0; break;}
00541 case 16: { ind_x = 1.0; ind_y = 2.0; ind_z = 1.0; break;}
00542 case 17: { ind_x = 2.0; ind_y = 2.0; ind_z = 1.0; break;}
00543 case 18: { ind_x = 0.0; ind_y = 0.0; ind_z = 2.0; break;}
00544 case 19: { ind_x = 1.0; ind_y = 0.0; ind_z = 2.0; break;}
00545 case 20: { ind_x = 2.0; ind_y = 0.0; ind_z = 2.0; break;}
00546 case 21: { ind_x = 0.0; ind_y = 1.0; ind_z = 2.0; break;}
00547 case 22: { ind_x = 1.0; ind_y = 1.0; ind_z = 2.0; break;}
00548 case 23: { ind_x = 2.0; ind_y = 1.0; ind_z = 2.0; break;}
00549 case 24: { ind_x = 0.0; ind_y = 2.0; ind_z = 2.0; break;}
00550 case 25: { ind_x = 1.0; ind_y = 2.0; ind_z = 2.0; break;}
00551 case 26: { ind_x = 2.0; ind_y = 2.0; ind_z = 2.0; break;}
00552 default: {}
00553 }
00554
00555 switch (facetIndex){
00556 case 0: { f_x = 0.0 , f_y = 0.0 , f_z = 0.0; break;}
00557 case 1: { f_x = 1.0 , f_y = 0.0 , f_z = 0.0; break;}
00558 case 2: { f_x = 0.0 , f_y = 1.0 , f_z = 0.0; break;}
00559 case 3: { f_x = 1.0 , f_y = 1.0 , f_z = 0.0; break;}
00560 case 4: { f_x = 0.0 , f_y = 0.0 , f_z = 1.0; break;}
00561 case 5: { f_x = 1.0 , f_y = 0.0 , f_z = 1.0; break;}
00562 case 6: { f_x = 0.0 , f_y = 1.0 , f_z = 1.0; break;}
00563 case 7: { f_x = 1.0 , f_y = 1.0 , f_z = 1.0; break;}
00564 default: {}
00565 }
00566 break;
00567 }
00568
00569 case 8:{
00570
00571 switch (indexInParent){
00572 case 0: { ind_x = 0.0; ind_y = 0.0; ind_z = 0.0; break;}
00573 case 1: { ind_x = 1.5; ind_y = 0.0; ind_z = 0.0; break;}
00574 case 2: { ind_x = 0.0; ind_y = 1.5; ind_z = 0.0; break;}
00575 case 3: { ind_x = 1.5; ind_y = 1.5; ind_z = 0.0; break;}
00576 case 4: { ind_x = 0.0; ind_y = 0.0; ind_z = 1.5; break;}
00577 case 5: { ind_x = 1.5; ind_y = 0.0; ind_z = 1.5; break;}
00578 case 6: { ind_x = 0.0; ind_y = 1.5; ind_z = 1.5; break;}
00579 case 7: { ind_x = 1.5; ind_y = 1.5; ind_z = 1.5; break;}
00580 default: {}
00581 }
00582
00583 switch (facetIndex){
00584 case 0: { f_x = 0.0 , f_y = 0.0 , f_z = 0.0; break;}
00585 case 1: { f_x = 1.5 , f_y = 0.0 , f_z = 0.0; break;}
00586 case 2: { f_x = 0.0 , f_y = 1.5 , f_z = 0.0; break;}
00587 case 3: { f_x = 1.5 , f_y = 1.5 , f_z = 0.0; break;}
00588 case 4: { f_x = 0.0 , f_y = 0.0 , f_z = 1.5; break;}
00589 case 5: { f_x = 1.5 , f_y = 0.0 , f_z = 1.5; break;}
00590 case 6: { f_x = 0.0 , f_y = 1.5 , f_z = 1.5; break;}
00591 case 7: { f_x = 1.5 , f_y = 1.5 , f_z = 1.5; break;}
00592 default: {}
00593 }
00594 break;
00595 }
00596 default: {}
00597 }
00598
00599 xx = (ind_x + f_x)/3.0;
00600 yy = (ind_y + f_y)/3.0;
00601 zz = (ind_z + f_z)/3.0;
00602 values[0] = (1.0 - xx)*(1.0 - yy)*(1.0 - zz);
00603 values[1] = (xx)*(1.0 - yy)*(1.0 - zz);
00604 values[2] = (1.0 - xx)*(yy)*(1.0 - zz);
00605 values[3] = (xx)*(yy)*(1.0 - zz);
00606 values[4] = (1.0 - xx)*(1.0 - yy)*(zz);
00607 values[5] = (xx)*(1.0 - yy)*(zz);
00608 values[6] = (1.0 - xx)*(yy)*(zz);
00609 values[7] = (xx)*(yy)*(zz);
00610
00611 glbLIDs.resize(0);
00612 nodeIndex.resize(0);
00613 coefsArray.resize(0);
00614 for (int ii = 0 ; ii < 8 ; ii++ ){
00615
00616 if (fabs(values[ii]) > 1e-5){
00617 glbLIDs.append(facets[ii]);
00618 nodeIndex.append(ii);
00619 coefsArray.append(values[ii]);
00620 }
00621 }
00622 SUNDANCE_MSG2(setupVerb(),"NodalDOFMapHN::getPointLIDsForHN()" << " facetIndex:" << facetIndex << " indexInParent:"
00623 << indexInParent <<" glbLIDs:" << glbLIDs << " maxCellIndex:" << maxCellIndex << " nodeIndex:" << nodeIndex);
00624 break;
00625 }
00626 }
00627
00628 }
00629
00630
00631
00632 void NodalDOFMapHN::computeOffsets(int localCount)
00633 {
00634 Array<int> dofOffsets;
00635 int totalDOFCount;
00636 int myOffset = 0;
00637 int np = mesh().comm().getNProc();
00638 if (np > 1)
00639 {
00640 SUNDANCE_MSG2(setupVerb(),"NodalDOFMapHN::computeOffsets, localCount:" << localCount);
00641 MPIContainerComm<int>::accumulate(localCount, dofOffsets, totalDOFCount,
00642 mesh().comm());
00643 myOffset = dofOffsets[mesh().comm().getRank()];
00644
00645 SUNDANCE_MSG2(setupVerb(),"NodalDOFMapHN::computeOffsets, offset:" << myOffset);
00646 int nDofs = nNodes_ * nFuncs_;
00647 for (int i=0; i<nDofs; i++)
00648 {
00649 if (nodeDofs_[i] >= 0) nodeDofs_[i] += myOffset;
00650 }
00651 }
00652 else
00653 {
00654 totalDOFCount = localCount;
00655 }
00656
00657 setLowestLocalDOF(myOffset);
00658 setNumLocalDOFs(localCount);
00659 setTotalNumDOFs(totalDOFCount);
00660 }
00661
00662
00663 void NodalDOFMapHN::shareRemoteDOFs(const Array<Array<int> >& outgoingCellRequests)
00664 {
00665 int np = mesh().comm().getNProc();
00666 if (np==1) return;
00667 int rank = mesh().comm().getRank();
00668
00669 Array<Array<int> > incomingCellRequests;
00670 Array<Array<int> > outgoingDOFs(np);
00671 Array<Array<int> > incomingDOFs;
00672
00673 SUNDANCE_MSG2(setupVerb(),
00674 "p=" << mesh().comm().getRank()
00675 << "synchronizing DOFs for cells of dimension 0");
00676 SUNDANCE_MSG2(setupVerb(),
00677 "p=" << mesh().comm().getRank()
00678 << " sending cell reqs d=0, GID="
00679 << outgoingCellRequests);
00680
00681
00682 MPIContainerComm<int>::allToAll(outgoingCellRequests,
00683 incomingCellRequests,
00684 mesh().comm());
00685
00686
00687
00688 for (int p=0; p<np; p++)
00689 {
00690 if (p==rank) continue;
00691 const Array<int>& requestsFromProc = incomingCellRequests[p];
00692 int nReq = requestsFromProc.size();
00693
00694 SUNDANCE_MSG3(setupVerb(),"p=" << mesh().comm().getRank()
00695 << " recv'd from proc=" << p
00696 << " reqs for DOFs for cells "
00697 << requestsFromProc);
00698
00699 outgoingDOFs[p].resize(nReq);
00700
00701 for (int c=0; c<nReq; c++)
00702 {
00703 int GID = requestsFromProc[c];
00704 SUNDANCE_MSG2(setupVerb(),
00705 "p=" << rank
00706 << " processing zero-cell with GID=" << GID);
00707 int LID = mesh().mapGIDToLID(0, GID);
00708 SUNDANCE_MSG2(setupVerb(),
00709 "p=" << rank
00710 << " LID=" << LID << " dofs="
00711 << nodeDofs_[LID*nFuncs_]);
00712 outgoingDOFs[p][c] = nodeDofs_[LID*nFuncs_];
00713 SUNDANCE_MSG2(setupVerb(),
00714 "p=" << rank
00715 << " done processing cell with GID=" << GID);
00716 }
00717 }
00718
00719 SUNDANCE_MSG2(setupVerb(),
00720 "p=" << mesh().comm().getRank()
00721 << "answering DOF requests for cells of dimension 0");
00722
00723
00724 MPIContainerComm<int>::allToAll(outgoingDOFs,
00725 incomingDOFs,
00726 mesh().comm());
00727
00728 SUNDANCE_MSG2(setupVerb(),
00729 "p=" << mesh().comm().getRank()
00730 << "communicated DOF answers for cells of dimension 0" );
00731
00732
00733
00734
00735 for (int p=0; p<mesh().comm().getNProc(); p++)
00736 {
00737 if (p==mesh().comm().getRank()) continue;
00738 const Array<int>& dofsFromProc = incomingDOFs[p];
00739 int numCells = dofsFromProc.size();
00740 for (int c=0; c<numCells; c++)
00741 {
00742 int cellGID = outgoingCellRequests[p][c];
00743 int cellLID = mesh().mapGIDToLID(0, cellGID);
00744 int dof = dofsFromProc[c];
00745 for (int i=0; i<nFuncs_; i++)
00746 {
00747 nodeDofs_[cellLID*nFuncs_ + i] = dof+i;
00748 addGhostIndex(dof+i);
00749 }
00750 }
00751 }
00752 }