Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

oda.C

Go to the documentation of this file.
00001 
00008 #include "oda.h"
00009 #include "parUtils.h"
00010 #include "colors.h"
00011 #include "testUtils.h"
00012 #include "dendro.h"
00013 
00014 #ifdef __DEBUG__
00015 #ifndef __DEBUG_DA__
00016 #define __DEBUG_DA__
00017 #endif
00018 #endif
00019 
00020 #ifdef __DEBUG_DA__
00021 #ifndef __DEBUG_DA_PUBLIC__
00022 #define __DEBUG_DA_PUBLIC__
00023 #endif
00024 #endif
00025 
00026 #ifdef __DEBUG_DA_PUBLIC__
00027 #ifndef __MEASURE_DA__
00028 #define __MEASURE_DA__
00029 #endif
00030 #endif
00031 
00032 namespace ot {
00033 
00034   int DA::computeLocalToGlobalElemMappings() {
00035     DendroIntL localElemSize = getElementSize();
00036     DendroIntL off1, globalOffset;
00037     MPI_Request sendRequest;
00038     MPI_Status status;
00039     if(m_bIamActive) {
00040       par::Mpi_Scan<DendroIntL>(&localElemSize, &off1, 1, MPI_SUM, m_mpiCommActive); 
00041       if(m_iRankActive < (m_iNpesActive - 1)) {
00042         par::Mpi_Issend<DendroIntL>(&off1, 1, m_iRankActive+1, 0, m_mpiCommActive, &sendRequest);
00043       }
00044 
00045       if(m_iRankActive) {
00046         par::Mpi_Recv<DendroIntL>(&globalOffset, 1, m_iRankActive-1, 0, m_mpiCommActive, &status );
00047       }else {
00048         globalOffset = 0;
00049       }
00050     }
00051 
00052     //Equivalent to createVector: elemental, non-ghosted, 1 dof
00053     std::vector<DendroIntL> gNumNonGhostElems(localElemSize); 
00054 
00055     for(DendroIntL i = 0; i < localElemSize; i++) {
00056       gNumNonGhostElems[i] = (i+globalOffset);   
00057     }
00058 
00059     vecGetBuffer<DendroIntL>(gNumNonGhostElems,
00060         m_dilpLocalToGlobalElems, true, false, true, 1);
00061 
00062     if( m_bIamActive && (m_iRankActive < (m_iNpesActive-1)) ) {
00063       MPI_Status statusWait;
00064       MPI_Wait(&sendRequest, &statusWait);
00065     }
00066 
00067     ReadFromGhostElemsBegin<DendroIntL>(m_dilpLocalToGlobalElems,1);
00068     ReadFromGhostElemsEnd<DendroIntL>(m_dilpLocalToGlobalElems);
00069 
00070     gNumNonGhostElems.clear();
00071     m_bComputedLocalToGlobalElems = true;
00072 
00073     return 0;
00074   }//end function
00075 
00076   int DA::computeLocalToGlobalMappings() {
00077     DendroIntL localNodeSize = getNodeSize();
00078     DendroIntL off1, globalOffset;
00079     MPI_Request sendRequest;
00080     MPI_Status status;
00081     if(m_bIamActive) {
00082       par::Mpi_Scan<DendroIntL>(&localNodeSize, &off1, 1, MPI_SUM, m_mpiCommActive); 
00083       if(m_iRankActive < (m_iNpesActive-1)) {
00084         par::Mpi_Issend<DendroIntL>(&off1, 1, m_iRankActive+1, 0, m_mpiCommActive, &sendRequest);
00085       }
00086 
00087       if(m_iRankActive) {
00088         par::Mpi_Recv<DendroIntL>(&globalOffset, 1, m_iRankActive-1, 0, m_mpiCommActive, &status);
00089       }else {
00090         globalOffset = 0;
00091       }
00092     }
00093 
00094     std::vector<DendroIntL> gNumNonGhostNodes(localNodeSize); 
00095     for(DendroIntL i = 0; i < localNodeSize; i++) {
00096       gNumNonGhostNodes[i] = (i+globalOffset);   
00097     }
00098 
00099     vecGetBuffer<DendroIntL>(gNumNonGhostNodes, m_dilpLocalToGlobal,
00100         false, false, true, 1);
00101 
00102     if(m_bIamActive && (m_iRankActive < (m_iNpesActive-1))) {
00103       MPI_Status statusWait;
00104       MPI_Wait(&sendRequest, &statusWait);
00105     }
00106 
00107     ReadFromGhostsBegin<DendroIntL>(m_dilpLocalToGlobal,1);
00108     ReadFromGhostsEnd<DendroIntL>(m_dilpLocalToGlobal);
00109 
00110     gNumNonGhostNodes.clear();
00111     m_bComputedLocalToGlobal = true;
00112 
00113     return 0;
00114   }//end function
00115 
00116   int DA::setValuesInMatrix(Mat mat, std::vector<ot::MatRecord>& records, unsigned int dof, InsertMode mode) {
00117 
00118     PROF_SET_MAT_VALUES_BEGIN 
00119 
00120       assert(m_bComputedLocalToGlobal);
00121     std::vector<PetscScalar> values;
00122     std::vector<PetscInt> colIndices;
00123 
00124     //Can make it more efficient later.
00125     if(!records.empty()) {
00126       //Sort Order: row first, col next, val last
00127       std::sort(records.begin(), records.end());
00128 
00129       unsigned int currRecord = 0;
00130       while(currRecord < (records.size()-1)) {
00131         values.push_back(records[currRecord].val);
00132         colIndices.push_back( static_cast<PetscInt>(
00133               (dof*m_dilpLocalToGlobal[records[currRecord].colIdx]) +
00134               records[currRecord].colDim) );
00135         if( (records[currRecord].rowIdx != records[currRecord+1].rowIdx) ||
00136             (records[currRecord].rowDim != records[currRecord+1].rowDim) ) {
00137           PetscInt rowId = static_cast<PetscInt>(
00138               (dof*m_dilpLocalToGlobal[records[currRecord].rowIdx]) + 
00139               records[currRecord].rowDim);
00140           MatSetValues(mat,1,&rowId,colIndices.size(),(&(*colIndices.begin())),
00141               (&(*values.begin())),mode);
00142           colIndices.clear();
00143           values.clear();
00144         }
00145         currRecord++;
00146       }//end while
00147       PetscInt rowId = static_cast<PetscInt>(
00148           (dof*m_dilpLocalToGlobal[records[currRecord].rowIdx]) +
00149           records[currRecord].rowDim);
00150       if(values.empty()) {
00151         //Last row is different from the previous row
00152         PetscInt colId = static_cast<PetscInt>(
00153             (dof*m_dilpLocalToGlobal[records[currRecord].colIdx]) + 
00154             records[currRecord].colDim);
00155         PetscScalar value = records[currRecord].val;
00156         MatSetValues(mat,1,&rowId,1,&colId,&value,mode);
00157       }else {
00158         //Last row is same as the previous row
00159         values.push_back(records[currRecord].val);
00160         colIndices.push_back( static_cast<PetscInt>(
00161               (dof*m_dilpLocalToGlobal[records[currRecord].colIdx]) + 
00162               records[currRecord].colDim) );
00163         MatSetValues(mat,1,&rowId,colIndices.size(),(&(*colIndices.begin())),
00164             (&(*values.begin())),mode);
00165         colIndices.clear();
00166         values.clear();
00167       }
00168       records.clear();
00169     }
00170 
00171     PROF_SET_MAT_VALUES_END
00172   }//end function
00173 
00174   //***************Constructor*****************//
00175   DA::DA(std::vector<ot::TreeNode> &in, MPI_Comm comm, MPI_Comm activeInputComm,
00176       bool compressLut, const std::vector<ot::TreeNode>* blocksPtr, bool* iAmActive ) {
00177 
00178 #ifdef __PROF_WITH_BARRIER__
00179     MPI_Barrier(comm);
00180 #endif
00181     PROF_BUILD_DA_BEGIN 
00182 
00183       DA_FactoryPart0(in, comm, activeInputComm, compressLut, iAmActive);
00184 
00185     if(m_bIamActive) {
00186       DA_FactoryPart1(in);
00187 
00188       DA_FactoryPart2(in);
00189 
00190       DA_FactoryPart3(in, comm, compressLut, blocksPtr, iAmActive);
00191     }
00192 
00193     PROF_BUILD_DA_END
00194   }//end constructor
00195 
00196   DA::DA(unsigned int dummy, std::vector<ot::TreeNode> &in, MPI_Comm comm,
00197       MPI_Comm activeInputComm, bool compressLut, 
00198       const std::vector<ot::TreeNode> * blocksPtr, bool* iAmActive ) {
00199 
00200 #ifdef __PROF_WITH_BARRIER__
00201     MPI_Barrier(comm);
00202 #endif
00203     PROF_BUILD_DA_BEGIN 
00204 
00205       DA_FactoryPart0(in, comm, activeInputComm, compressLut, iAmActive);
00206 
00207     if(m_bIamActive) {
00208       DA_FactoryPart3(in, comm, compressLut, blocksPtr, iAmActive);
00209     }
00210 
00211     PROF_BUILD_DA_END
00212   }//end constructor
00213 
00214   DA::~DA() {
00215     if (m_ucpOctLevels != NULL) {
00216       delete [] m_ucpOctLevels;
00217       m_ucpOctLevels = NULL;
00218     }
00219 
00220     if(m_dilpLocalToGlobal != NULL) {
00221       delete [] m_dilpLocalToGlobal;
00222       m_dilpLocalToGlobal = NULL;
00223     }
00224 
00225     if(m_dilpLocalToGlobalElems != NULL) {
00226       delete [] m_dilpLocalToGlobalElems;
00227       m_dilpLocalToGlobalElems = NULL;
00228     }
00229 
00230     m_ucpLutRemainders.clear();
00231     m_uspLutQuotients.clear();
00232     m_ucpLutMasks.clear();
00233     m_ucpSortOrders.clear();
00234     m_uiNlist.clear();
00235   }
00236 
00237   /************** Domain Access ****************/
00238   Point DA::getNextOffset(Point p, unsigned char d) {
00239 #ifdef __DEBUG_DA_PUBLIC__
00240     assert(m_bIamActive);
00241 #endif
00242 
00243     unsigned int len = (unsigned int)(1u<<( m_uiMaxDepth - d ) );
00244     unsigned int len_par = (unsigned int)(1u<<( m_uiMaxDepth - d +1 ) );
00245 
00246     unsigned int i,j,k;
00247 
00248     i = p.xint(); i %= len_par;
00249     j = p.yint(); j %= len_par;
00250     k = p.zint(); k %= len_par;
00251     i /= len;
00252     j /= len;
00253     k /= len;
00254 
00255     unsigned int childNum = 4*k + 2*j + i;
00256 
00257     Point p2;
00258     switch (childNum) {
00259       case 7:
00260         p2.x() = p.x() -len; p2.y() = p.y() - len; p2.z() = p.z() -len;
00261         return getNextOffset(p2, d-1);
00262       case 0:
00263         p2.x() = p.x() +len; p2.y() = p.y(); p2.z() = p.z();
00264         break;
00265       case 1:
00266         p2.x() = p.x() -len; p2.y() = p.y() +len; p2.z() = p.z();
00267         break;
00268       case 2:
00269         p2.x() = p.x() +len; p2.y() = p.y(); p2.z() = p.z();
00270         break;
00271       case 3:
00272         p2.x() = p.x() -len; p2.y() = p.y() - len; p2.z() = p.z() +len;
00273         break;
00274       case 4:
00275         p2.x() = p.x() +len; p2.y() = p.y(); p2.z() = p.z();
00276         break;
00277       case 5:
00278         p2.x() = p.x() -len; p2.y() = p.y()+len; p2.z() = p.z();
00279         break;
00280       case 6:
00281         p2.x() = p.x() +len; p2.y() = p.y(); p2.z() = p.z();
00282         break;
00283       default:
00284         std::cerr << "Wrong child number in " << __func__ << std::endl;
00285         assert(false);
00286         break;
00287     } // switch (childNum)
00288 
00289     return p2;
00290   }
00291 
00292   void DA::incrementCurrentOffset() {
00293 #ifdef __DEBUG_DA_PUBLIC__
00294     assert(m_bIamActive);
00295 #endif
00296 
00297     // if it is the first element, simply return the stored offset ...
00298     if ( m_uiCurrent == (m_uiElementBegin-1)) {
00299       m_ptCurrentOffset = m_ptOffset;
00300       return; 
00301     }
00302 
00303 #ifdef __DEBUG_DA_PUBLIC__
00304     if ( m_ucpOctLevels[m_uiCurrent] & ot::TreeNode::BOUNDARY ) {
00305       std::cerr << RED"ERROR, Boundary eleme in incre Curr offset"NRM << std::endl;
00306       assert(false);
00307     }
00308 #endif
00309 
00310     unsigned char d = (m_ucpOctLevels[m_uiCurrent] & ot::TreeNode::MAX_LEVEL );
00311     unsigned int len = (unsigned int)(1u<<( m_uiMaxDepth - d ) );
00312     unsigned int len_par = (unsigned int)(1u<<( m_uiMaxDepth - d +1 ) );
00313 
00314     unsigned int i,j,k;
00315 
00316     i = m_ptCurrentOffset.xint(); 
00317     j = m_ptCurrentOffset.yint(); 
00318     k = m_ptCurrentOffset.zint(); 
00319 
00320     i %= len_par;
00321     j %= len_par;
00322     k %= len_par;
00323 
00324     i /= len;
00325     j /= len;
00326     k /= len;
00327 
00328     unsigned int childNum = 4*k + 2*j + i;
00329 
00330     Point p = m_ptCurrentOffset;
00331     Point p2;
00332     switch (childNum) {
00333       case 7:
00334         p2.x() = p.x() -len; p2.y() = p.y() - len; p2.z() = p.z() -len;
00335         p2 = getNextOffset(p2, d-1);
00336         break;
00337       case 0:
00338         p2.x() = p.x() +len; p2.y() = p.y(); p2.z() = p.z();
00339         break;
00340       case 1:
00341         p2.x() = p.x() -len; p2.y() = p.y() +len; p2.z() = p.z();
00342         break;
00343       case 2:
00344         p2.x() = p.x() +len; p2.y() = p.y(); p2.z() = p.z();
00345         break;
00346       case 3:
00347         p2.x() = p.x() -len; p2.y() = p.y() - len; p2.z() = p.z() +len;
00348         break;
00349       case 4:
00350         p2.x() = p.x() +len; p2.y() = p.y(); p2.z() = p.z();
00351         break;
00352       case 5:
00353         p2.x() = p.x() -len; p2.y() = p.y()+len; p2.z() = p.z();
00354         break;
00355       case 6:
00356         p2.x() = p.x() +len; p2.y() = p.y(); p2.z() = p.z();
00357         break;
00358       default:
00359         std::cerr << "Wrong child number in " << __func__ << std::endl;
00360         assert(false);
00361         break;
00362     } // switch (childNum)
00363 
00364     m_ptCurrentOffset = p2;
00365   }
00366 
00367   //This is for real octants only, pseudo-boundary octants can not be tested
00368   //using this. 
00369   bool DA::isBoundaryOctant(unsigned char *flags) {
00370 #ifdef __DEBUG_DA_PUBLIC__
00371     assert(m_bIamActive);
00372 #endif
00373 
00374     unsigned char _flags = 0;
00375     Point pt = getCurrentOffset();
00376     unsigned int x = pt.xint();
00377     unsigned int y = pt.yint();
00378     unsigned int z = pt.zint();
00379     unsigned int d = getLevel(curr())-1;
00380     unsigned int maxD = getMaxDepth()-1;
00381     unsigned int len  = (unsigned int)(1u<<(maxD - d) );
00382     unsigned int blen = (unsigned int)(1u << maxD);
00383 
00384     if (!x) _flags |= ot::TreeNode::X_NEG_BDY;  
00385     if (!y) _flags |=  ot::TreeNode::Y_NEG_BDY; 
00386     if (!z) _flags |=   ot::TreeNode::Z_NEG_BDY;
00387 
00388     if ( (x+len) == blen )  _flags |= ot::TreeNode::X_POS_BDY;
00389     if ( (y+len) == blen )  _flags |= ot::TreeNode::Y_POS_BDY;
00390     if ( (z+len) == blen )  _flags |= ot::TreeNode::Z_POS_BDY;
00391 
00392     if(flags) {
00393       *flags = _flags;
00394     }
00395     return _flags;
00396   }//end function
00397 
00398   /***************** Array Access ********************/
00399   int DA::createMatrix(Mat &M, MatType mtype, unsigned int dof) {
00400     // first determine the size ...
00401     unsigned int sz = 0;
00402     if(m_bIamActive) {
00403       sz = dof*(m_uiNodeSize + m_uiBoundaryNodeSize);
00404     }//end if active
00405 
00406     // now create the PETSc Mat
00407     PetscTruth isAij, isAijSeq, isAijPrl, isSuperLU, isSuperLU_Dist;
00408     PetscStrcmp(mtype,MATAIJ,&isAij);
00409     PetscStrcmp(mtype,MATSEQAIJ,&isAijSeq);
00410     PetscStrcmp(mtype,MATMPIAIJ,&isAijPrl);
00411     PetscStrcmp(mtype,MATSUPERLU,&isSuperLU);
00412     PetscStrcmp(mtype,MATSUPERLU_DIST,&isSuperLU_Dist);
00413 
00414     MatCreate(m_mpiCommAll, &M);
00415     MatSetSizes(M, sz,sz, PETSC_DECIDE, PETSC_DECIDE);
00416     MatSetType(M,mtype);
00417 
00418     if(isAij || isAijSeq || isAijPrl || isSuperLU || isSuperLU_Dist) {
00419       if(m_iNpesAll > 1) {
00420         MatMPIAIJSetPreallocation(M, 53*dof , PETSC_NULL, 53*dof , PETSC_NULL);
00421       }else {
00422         MatSeqAIJSetPreallocation(M, 53*dof , PETSC_NULL);
00423       }
00424     }
00425 
00426     return 0;
00427   }//end function
00428 
00429   int DA::createActiveMatrix(Mat &M, MatType mtype, unsigned int dof) {
00430     // first determine the size ...
00431     unsigned int sz = 0;
00432     if(m_bIamActive) {
00433       sz = dof*(m_uiNodeSize + m_uiBoundaryNodeSize);
00434 
00435       // now create the PETSc Mat
00436       PetscTruth isAij, isAijSeq, isAijPrl, isSuperLU, isSuperLU_Dist;
00437       PetscStrcmp(mtype,MATAIJ,&isAij);
00438       PetscStrcmp(mtype,MATSEQAIJ,&isAijSeq);
00439       PetscStrcmp(mtype,MATMPIAIJ,&isAijPrl);
00440       PetscStrcmp(mtype,MATSUPERLU,&isSuperLU);
00441       PetscStrcmp(mtype,MATSUPERLU_DIST,&isSuperLU_Dist);
00442 
00443       MatCreate(m_mpiCommActive, &M);
00444       MatSetSizes(M, sz,sz, PETSC_DECIDE, PETSC_DECIDE);
00445       MatSetType(M,mtype);
00446 
00447       if(isAij || isAijSeq || isAijPrl || isSuperLU || isSuperLU_Dist) {
00448         if(m_iNpesActive > 1) {
00449           MatMPIAIJSetPreallocation(M, 53*dof , PETSC_NULL, 53*dof , PETSC_NULL);
00450         }else {
00451           MatSeqAIJSetPreallocation(M, 53*dof , PETSC_NULL);
00452         }
00453       }
00454     }//end if active
00455 
00456     return 0;
00457   }//end function
00458 
00459   int DA::createVector(Vec &arr, bool isElemental, bool isGhosted, unsigned int dof) {
00460     // first determine the length of the vector ...
00461     unsigned int sz = 0;
00462     if(m_bIamActive) {
00463       if (isElemental) {
00464         sz = m_uiElementSize;
00465         if (isGhosted) {
00466           sz += (m_uiPreGhostElementSize);
00467         }
00468       } else {
00469         sz = m_uiNodeSize + m_uiBoundaryNodeSize;
00470         if (isGhosted) {
00471           sz += (m_uiPreGhostNodeSize + m_uiPreGhostBoundaryNodeSize + m_uiPostGhostNodeSize);
00472         }
00473       }
00474       // now for dof ...
00475       sz *= dof;
00476     }//end if active
00477 
00478     // now create the PETSc Vector
00479     VecCreate(m_mpiCommAll, &arr);
00480     VecSetSizes(arr, sz, PETSC_DECIDE);
00481     if (m_iNpesAll > 1) {
00482       VecSetType(arr,VECMPI);
00483     } else {
00484       VecSetType(arr,VECSEQ);
00485     }    
00486     return 0;
00487   }
00488 
00489   int DA::createActiveVector(Vec &arr, bool isElemental, bool isGhosted, unsigned int dof) {
00490     // first determine the length of the vector ...
00491     unsigned int sz = 0;
00492     if(m_bIamActive) {
00493       if (isElemental) {
00494         sz = m_uiElementSize;
00495         if (isGhosted) {
00496           sz += (m_uiPreGhostElementSize);
00497         }
00498       } else {
00499         sz = m_uiNodeSize + m_uiBoundaryNodeSize;
00500         if (isGhosted) {
00501           sz += (m_uiPreGhostNodeSize + m_uiPreGhostBoundaryNodeSize + m_uiPostGhostNodeSize);
00502         }
00503       }
00504       // now for dof ...
00505       sz *= dof;
00506 
00507       // now create the PETSc Vector
00508       VecCreate(m_mpiCommActive, &arr);
00509       VecSetSizes(arr, sz, PETSC_DECIDE);
00510       if (m_iNpesActive > 1) {
00511         VecSetType(arr, VECMPI);
00512       } else {
00513         VecSetType(arr, VECSEQ);
00514       }    
00515     }//end if active
00516 
00517     return 0;
00518   }
00519 
00520   // Obtains a ot::index aligned buffer of the Vector
00521   int DA::vecGetBuffer(Vec in, PetscScalar* &out, bool isElemental, bool isGhosted,
00522       bool isReadOnly, unsigned int dof) {
00523     // Some error checks ... make sure the size of Vec in matches those implied
00524     // by the other params ...
00525     unsigned int sz = 0;
00526     if(m_bIamActive) {
00527       if (isElemental) {
00528         sz = m_uiElementSize;
00529         if (isGhosted) {
00530           sz += m_uiPreGhostElementSize;
00531         }
00532       } else {
00533         sz = m_uiNodeSize + m_uiBoundaryNodeSize;
00534         if (isGhosted) {
00535           sz += (m_uiPreGhostNodeSize + m_uiPreGhostBoundaryNodeSize + m_uiPostGhostNodeSize);
00536         }
00537       }
00538       // now for dof ...
00539       sz *= dof;
00540     }//end if active
00541 
00542     PetscInt vecSz=0;
00543     VecGetLocalSize(in, &vecSz);
00544 
00545     if ( sz != vecSz) {
00546       std::cerr  << m_iRankAll << ": In function " << __func__ << " sizes are unequal, sz is  " 
00547         << sz << " and vecSz is " << vecSz << std::endl;
00548       std::cerr << "Params are: isElem " << isElemental << " isGhosted " << isGhosted << std::endl;
00549       assert(false);
00550       return -1;; 
00551     };
00552 
00553     if(!m_bIamActive) {
00554       assert(m_uiLocalBufferSize == 0);
00555       assert(m_uiElementBegin == 0);
00556       assert(m_uiElementEnd == 0);
00557       assert(m_uiPostGhostBegin == 0);
00558     }
00559 
00560     // get the local Petsc Arrray,
00561     PetscScalar *array = NULL;
00562     VecGetArray(in, &array);
00563 
00564     // allocate except for the case of ghosted-elemental vectors...
00565     if(isGhosted && isElemental) {
00566       //simply copy the pointer
00567       //This is the only case where the buffer will not be the size of the
00568       //fullLocalBufferSize. 
00569       out = array;
00570     }else {
00571       // First let us allocate for the buffer ... the local buffer will be of full
00572       // length.
00573       sz = dof*m_uiLocalBufferSize;
00574 
00575       if(sz) {
00576         out = new PetscScalar[sz];
00577       }else {
00578         out = NULL;
00579       }
00580 
00581       //Zero Entries first if you plan to modify the buffer 
00582       if(!isReadOnly) {
00583         for(unsigned int i = 0; i < sz; i++) {
00584           out[i] = 0.0;
00585         }
00586       }
00587     }
00588 
00589     unsigned int vecCnt=0;
00590     // Now we can populate the out buffer ... and that needs a loop through the
00591     // elements ...
00592     if (isGhosted) {
00593       if (isElemental) {
00594         //Nothing to be done here.
00595       } else {
00596         // now copy ...
00597         for (unsigned int i=0; i<m_uiLocalBufferSize; i++) {
00598           // skip the ones that are not nodes ...
00599           if ( ! (m_ucpOctLevels[i] & ot::TreeNode::NODE ) ) {
00600             continue;
00601           }
00602           for (unsigned int j=0; j<dof; j++) {
00603             out[dof*i+j] = array[dof*vecCnt + j];
00604           }
00605           vecCnt++;
00606         }//end for i
00607       }//end if elemental
00608     } else {
00609       if (isElemental) {
00610         // is a simple copy ...
00611         for (unsigned int i = m_uiElementBegin; i < m_uiElementEnd; i++) {
00612           for (unsigned int j = 0; j < dof; j++) {
00613             out[dof*i+j] = array[dof*vecCnt + j];
00614           }
00615           vecCnt++;
00616         }//end for i
00617       } else {
00618         for (unsigned int i = m_uiElementBegin; i < m_uiElementEnd; i++) {
00619           if ( ! (m_ucpOctLevels[i] & ot::TreeNode::NODE ) ) {
00620             continue;
00621           }
00622           for (unsigned int j=0; j<dof; j++) {
00623             out[dof*i+j] = array[dof*vecCnt + j];
00624           }
00625           vecCnt++;
00626         }//end for i
00627         for (unsigned int i = m_uiElementEnd; i < m_uiPostGhostBegin; i++) {
00628           // add the remaining boundary nodes ...
00629           if ( ! ( (m_ucpOctLevels[i] & ot::TreeNode::NODE ) &&
00630                 (m_ucpOctLevels[i] & ot::TreeNode::BOUNDARY ) ) ) {
00631             continue;
00632           }
00633           for (unsigned int j=0; j<dof; j++) {
00634             out[dof*i+j] = array[dof*vecCnt + j];
00635           }
00636           vecCnt++;
00637         }//end for i
00638       }
00639     }
00640 
00641     if(!(isGhosted && isElemental)) {
00642       VecRestoreArray(in, &array);
00643     }
00644 
00645     return 0;
00646   }
00647 
00648   int DA::vecRestoreBuffer(Vec in, PetscScalar* out, bool isElemental, bool isGhosted, bool isReadOnly, unsigned int dof) {
00649     // Some error checks ... make sure the size of Vec in matches those implied
00650     // by the other params ...
00651     unsigned int sz = 0;
00652     if(m_bIamActive) {
00653       if (isElemental) {
00654         sz = m_uiElementSize;
00655         if (isGhosted) {
00656           sz += m_uiPreGhostElementSize;
00657         }
00658       } else {
00659         sz = m_uiNodeSize + m_uiBoundaryNodeSize;
00660         if (isGhosted) {
00661           sz += (m_uiPreGhostNodeSize + m_uiPreGhostBoundaryNodeSize + m_uiPostGhostNodeSize);
00662         }
00663       }
00664       // now for dof ...
00665       sz *= dof;
00666     }//end if active
00667 
00668     PetscInt vecSz=0;
00669     VecGetLocalSize(in, &vecSz);
00670 
00671     if ( sz != vecSz) {
00672       std::cerr  << RED<<"In function PETSc::" << __func__ <<
00673         NRM<<" sizes are unequal, sz is  " << sz << " and vecSz is " << vecSz << std::endl;
00674       std::cerr << "Params are: isElem " << isElemental << " isGhosted " << isGhosted << std::endl;
00675       assert(false);
00676       return -1;;
00677     }
00678 
00679     if(!m_bIamActive) {
00680       assert(m_uiLocalBufferSize == 0);
00681       assert(m_uiElementBegin == 0);
00682       assert(m_uiElementEnd == 0);
00683       assert(m_uiPostGhostBegin == 0);
00684     }
00685 
00686     unsigned int vecCnt=0;
00687 
00688     if(isGhosted && isElemental) {
00689       //If it is ghosted and elemental, simply restore the array.
00690       //out was not allocated expicitly in this case. It was just a copy of the
00691       //array's pointer. The readOnly flag is immaterial for this case.
00692       VecRestoreArray(in, &out);
00693       out = NULL;
00694     }  else if ( isReadOnly ) {
00695       // no need to write back ... simply clean up and return
00696       //Since this is not an elemental and ghosted vector, out was allocated
00697       //explicitly 
00698       if(out) {
00699         delete [] out;
00700         out = NULL;
00701       }
00702     } else {
00703       //ghosted and elemental is already taken care of. So only need to tackle
00704       //the other 3 cases.
00705       // need to write back ...
00706       // get the local Petsc Arrray,
00707       PetscScalar *array;
00708       VecGetArray(in, &array);
00709 
00710       if ( isElemental ) {
00711         //non-ghosted, elemental
00712         for (unsigned int i = m_uiElementBegin; i < m_uiElementEnd; i++) {
00713           for (unsigned int j=0; j<dof; j++) {
00714             array[dof*vecCnt + j] = out[dof*i+j];
00715           }
00716           vecCnt++;
00717         }
00718       } else if ( isGhosted ) {
00719         // nodal and ghosted ...
00720         for (unsigned int i=0; i<sz; i++) {
00721           // skip the ones that are not nodes ...
00722           if ( ! (m_ucpOctLevels[i] & ot::TreeNode::NODE ) ) {
00723             continue;
00724           }
00725           for (unsigned int j=0; j<dof; j++) {
00726             array[dof*vecCnt + j] = out[dof*i+j];
00727           }
00728           vecCnt++;
00729         }
00730       } else {
00731         // nodal non ghosted ...
00732         for (unsigned int i = m_uiElementBegin; i < m_uiElementEnd; i++) {
00733           if ( ! (m_ucpOctLevels[i] & ot::TreeNode::NODE ) ) {
00734             continue;
00735           }
00736           for (unsigned int j=0; j<dof; j++) {
00737             array[dof*vecCnt + j] = out[dof*i+j];
00738           }
00739           vecCnt++;
00740         }
00741         for (unsigned int i = m_uiElementEnd; i < m_uiPostGhostBegin; i++) {
00742           // add the remaining boundary nodes ...
00743           if ( ! ( (m_ucpOctLevels[i] & ot::TreeNode::NODE ) &&
00744                 (m_ucpOctLevels[i] & ot::TreeNode::BOUNDARY ) ) ) {
00745             continue;
00746           }
00747           for (unsigned int j=0; j<dof; j++) {
00748             array[dof*vecCnt + j] = out[dof*i+j];
00749           }
00750           vecCnt++;
00751         }
00752       }
00753 
00754       VecRestoreArray(in, &array);
00755       //Since this is not an elemental and ghosted vector, out was allocated
00756       //explicitly 
00757       if(out) {
00758         delete [] out;
00759         out = NULL;
00760       }
00761     }
00762     return 0;
00763   }
00764 
00765   void DA::updateQuotientCounter() {
00766 #ifdef __DEBUG_DA_PUBLIC__
00767     assert(m_bIamActive);
00768 #endif
00769 
00770     // m_ucpLutRemainders, m_uspLutQuotients.
00771     unsigned char _mask = m_ucpLutMasksPtr[2*m_uiCurrent];
00772 
00773     // first let us get the offsets ..
00774     for (int j=0; j < 8; j++) {
00775       if ( _mask & (1 << j ) ) {
00776         m_uiQuotientCounter++;
00777       }
00778     }
00779   }
00780 
00781   unsigned char DA::getHangingNodeIndex(unsigned int i) {
00782 #ifdef __DEBUG_DA_PUBLIC__
00783     assert(m_bIamActive);
00784 #endif
00785     return m_ucpLutMasks[2*i + 1];
00786   }
00787 
00788   void DA::incrementPreGhostOffset() {
00789 #ifdef __DEBUG_DA_PUBLIC__
00790     assert(m_bIamActive);
00791 #endif
00792 
00793     unsigned char c = m_ucpPreGhostConnectivity[m_uiCurrent];
00794     if ( c ) {
00795       unsigned char nd = m_ucpOctLevels[m_uiCurrent+1];
00796       unsigned char cd = m_ucpOctLevels[m_uiCurrent];
00797       unsigned int ns = (unsigned int)(1u << ( m_uiMaxDepth - nd ) );
00798       unsigned int cs = (unsigned int)(1u << ( m_uiMaxDepth - cd ) );
00799 
00800       Point curr = m_ptCurrentOffset;
00801 
00802       unsigned int cx = curr.xint();
00803       unsigned int cy = curr.yint();
00804       unsigned int cz = curr.zint();
00805       unsigned int nx = cx;
00806       unsigned int ny = cy;
00807       unsigned int nz = cz;
00808 
00809       //_zzyyxxT
00810       unsigned char xFlag = ((c & (3<<1) ) >> 1);
00811       unsigned char yFlag = ((c & (3<<3) ) >> 3);
00812       unsigned char zFlag = ((c & (3<<5) ) >> 5);
00813 
00814       switch (xFlag) {
00815         case 0: nx = cx;
00816                 break;
00817         case 1: nx = (cx - ns);
00818                 break;
00819         case 2: nx = (cx + cs); 
00820                 break;
00821         case 3: nx = (cx + cs - ns);
00822                 break;
00823         default: assert(false);
00824       }
00825 
00826       switch (yFlag) {
00827         case 0: ny = cy;
00828                 break;
00829         case 1: ny = (cy - ns);
00830                 break;
00831         case 2: ny = (cy + cs); 
00832                 break;
00833         case 3: ny = (cy + cs - ns); 
00834                 break;
00835         default: assert(false);
00836       }
00837 
00838       switch (zFlag) {
00839         case 0: nz = cz;
00840                 break;
00841         case 1: nz = (cz - ns); 
00842                 break;
00843         case 2: nz = (cz + cs); 
00844                 break;
00845         case 3: nz = (cz + cs - ns); 
00846                 break;
00847         default: assert(false);
00848       }
00849 
00850       m_ptCurrentOffset = Point(nx,ny,nz);    
00851 
00852     } else {
00853       m_ptCurrentOffset = m_ptsPreGhostOffsets[m_uiPreGhostQuotientCnt++];     
00854     }
00855 
00856   }//end function
00857 
00858 } // end namespace ot
00859 
00860 

Generated on Tue Mar 24 16:14:05 2009 for DENDRO by  doxygen 1.3.9.1