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
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 }
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 }
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
00125 if(!records.empty()) {
00126
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 }
00147 PetscInt rowId = static_cast<PetscInt>(
00148 (dof*m_dilpLocalToGlobal[records[currRecord].rowIdx]) +
00149 records[currRecord].rowDim);
00150 if(values.empty()) {
00151
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
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 }
00173
00174
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 }
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 }
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
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 }
00288
00289 return p2;
00290 }
00291
00292 void DA::incrementCurrentOffset() {
00293 #ifdef __DEBUG_DA_PUBLIC__
00294 assert(m_bIamActive);
00295 #endif
00296
00297
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 }
00363
00364 m_ptCurrentOffset = p2;
00365 }
00366
00367
00368
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 }
00397
00398
00399 int DA::createMatrix(Mat &M, MatType mtype, unsigned int dof) {
00400
00401 unsigned int sz = 0;
00402 if(m_bIamActive) {
00403 sz = dof*(m_uiNodeSize + m_uiBoundaryNodeSize);
00404 }
00405
00406
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 }
00428
00429 int DA::createActiveMatrix(Mat &M, MatType mtype, unsigned int dof) {
00430
00431 unsigned int sz = 0;
00432 if(m_bIamActive) {
00433 sz = dof*(m_uiNodeSize + m_uiBoundaryNodeSize);
00434
00435
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 }
00455
00456 return 0;
00457 }
00458
00459 int DA::createVector(Vec &arr, bool isElemental, bool isGhosted, unsigned int dof) {
00460
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
00475 sz *= dof;
00476 }
00477
00478
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
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
00505 sz *= dof;
00506
00507
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 }
00516
00517 return 0;
00518 }
00519
00520
00521 int DA::vecGetBuffer(Vec in, PetscScalar* &out, bool isElemental, bool isGhosted,
00522 bool isReadOnly, unsigned int dof) {
00523
00524
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
00539 sz *= dof;
00540 }
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
00561 PetscScalar *array = NULL;
00562 VecGetArray(in, &array);
00563
00564
00565 if(isGhosted && isElemental) {
00566
00567
00568
00569 out = array;
00570 }else {
00571
00572
00573 sz = dof*m_uiLocalBufferSize;
00574
00575 if(sz) {
00576 out = new PetscScalar[sz];
00577 }else {
00578 out = NULL;
00579 }
00580
00581
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
00591
00592 if (isGhosted) {
00593 if (isElemental) {
00594
00595 } else {
00596
00597 for (unsigned int i=0; i<m_uiLocalBufferSize; i++) {
00598
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 }
00607 }
00608 } else {
00609 if (isElemental) {
00610
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 }
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 }
00627 for (unsigned int i = m_uiElementEnd; i < m_uiPostGhostBegin; i++) {
00628
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 }
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
00650
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
00665 sz *= dof;
00666 }
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
00690
00691
00692 VecRestoreArray(in, &out);
00693 out = NULL;
00694 } else if ( isReadOnly ) {
00695
00696
00697
00698 if(out) {
00699 delete [] out;
00700 out = NULL;
00701 }
00702 } else {
00703
00704
00705
00706
00707 PetscScalar *array;
00708 VecGetArray(in, &array);
00709
00710 if ( isElemental ) {
00711
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
00720 for (unsigned int i=0; i<sz; i++) {
00721
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
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
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
00756
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
00771 unsigned char _mask = m_ucpLutMasksPtr[2*m_uiCurrent];
00772
00773
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
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 }
00857
00858 }
00859
00860