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