00001
00007 #include "petsc.h"
00008 #include "parUtils.h"
00009 #include "seqUtils.h"
00010 #include "omg.h"
00011 #include "oda.h"
00012 #include "odaJac.h"
00013 #include "omgJac.h"
00014 #include "nodeAndValues.h"
00015
00016 extern double****** ShapeFnStencil;
00017
00018 namespace ot {
00019 extern double**** ShapeFnCoeffs;
00020 }
00021
00022 #define square(x) ((x)*(x))
00023
00024 #define EVAL_FN(x,y,z,result) {\
00025 result = 0.0;\
00026 if( ((x) >= 0.0) && ((y) >= 0.0) && ((z) >= 0.0) && \
00027 ((x) < 0.2) && ((y) < 0.2) && ((z) < 0.2) ) {\
00028 double dx = ((x) - 0.1);\
00029 double dy = ((y) - 0.1);\
00030 double dz = ((z) - 0.1);\
00031 result += exp(-((square(dx) + square(dy) + square(dz))/0.005));\
00032 }\
00033 if( ((x) >= 0.2) && ((y) >= 0.2) && ((z) >= 0.2) && \
00034 ((x) <= 0.4) && ((y) <= 0.4) && ((z) <= 0.4) ) {\
00035 double dx = ((x) - 0.3);\
00036 double dy = ((y) - 0.3);\
00037 double dz = ((z) - 0.3);\
00038 result += exp(-((square(dx) + square(dy) + square(dz))/0.005));\
00039 }\
00040 if( ((x) >= 0.5) && ((y) >= 0.5) && ((z) >= 0.5) && \
00041 ((x) <= 0.7) && ((y) <= 0.7) && ((z) <= 0.7) ) {\
00042 double dx = ((x) - 0.6);\
00043 double dy = ((y) - 0.6);\
00044 double dz = ((z) - 0.6);\
00045 result += exp(-((square(dx) + square(dy) + square(dz))/0.005));\
00046 }\
00047 }
00048
00049 PetscErrorCode EnforceZeroFBM2(ot::DAMG damg, Vec tmp) {
00050 PetscFunctionBegin;
00051
00052 PetscScalar *inarray;
00053
00054 ot::DA* da = damg->da;
00055 da->vecGetBuffer(tmp, inarray, false, false, false, 1);
00056
00057 PetscReal gamma = 0;
00058 PetscOptionsGetReal(0, "-gamma", &gamma, 0);
00059
00060 unsigned int maxD;
00061 unsigned int balOctmaxD;
00062
00063 if(da->iAmActive()) {
00064 maxD = da->getMaxDepth();
00065 balOctmaxD = maxD - 1;
00066 for(da->init<ot::DA_FLAGS::ALL>();
00067 da->curr() < da->end<ot::DA_FLAGS::ALL>();
00068 da->next<ot::DA_FLAGS::ALL>())
00069 {
00070 Point pt;
00071 pt = da->getCurrentOffset();
00072 unsigned levelhere = da->getLevel(da->curr()) - 1;
00073 double hxOct = (double)((double)(1u << (balOctmaxD - levelhere))/(double)(1u << balOctmaxD));
00074 double x = (double)(pt.xint())/((double)(1u << (maxD-1)));
00075 double y = (double)(pt.yint())/((double)(1u << (maxD-1)));
00076 double z = (double)(pt.zint())/((double)(1u << (maxD-1)));
00077
00078 unsigned int indices[8];
00079 da->getNodeIndices(indices);
00080 double coord[8][3] = {
00081 {0.0,0.0,0.0},
00082 {1.0,0.0,0.0},
00083 {0.0,1.0,0.0},
00084 {1.0,1.0,0.0},
00085 {0.0,0.0,1.0},
00086 {1.0,0.0,1.0},
00087 {0.0,1.0,1.0},
00088 {1.0,1.0,1.0}
00089 };
00090 unsigned char hn = da->getHangingNodeIndex(da->curr());
00091
00092 for(int i = 0; i < 8; i++)
00093 {
00094 if (!(hn & (1 << i))){
00095 double xPt;
00096 xPt = x + (coord[i][0]*hxOct);
00097 if( xPt >= (0.9*gamma) ) {
00098 inarray[indices[i]] = 0.0;
00099 }
00100 }
00101 }
00102 }
00103 }
00104
00105 da->vecRestoreBuffer(tmp, inarray, false, false, false, 1);
00106
00107 PetscFunctionReturn(0);
00108 }
00109
00110 PetscErrorCode EnforceZeroFBM(ot::DAMG damg, Vec tmp) {
00111 PetscFunctionBegin;
00112
00113 PetscScalar *inarray;
00114
00115 ot::DA* da = damg->da;
00116 da->vecGetBuffer(tmp, inarray, false, false, false, 1);
00117
00118 PetscReal fbmR = 0;
00119 PetscOptionsGetReal(0, "-fbmR", &fbmR, 0);
00120
00121 unsigned int maxD;
00122 unsigned int balOctmaxD;
00123
00124 if(da->iAmActive()) {
00125 maxD = da->getMaxDepth();
00126 balOctmaxD = maxD - 1;
00127 for(da->init<ot::DA_FLAGS::ALL>();
00128 da->curr() < da->end<ot::DA_FLAGS::ALL>();
00129 da->next<ot::DA_FLAGS::ALL>())
00130 {
00131 Point pt;
00132 pt = da->getCurrentOffset();
00133 unsigned levelhere = da->getLevel(da->curr()) - 1;
00134 double hxOct = (double)((double)(1u << (balOctmaxD - levelhere))/(double)(1u << balOctmaxD));
00135 double x = (double)(pt.xint())/((double)(1u << (maxD-1)));
00136 double y = (double)(pt.yint())/((double)(1u << (maxD-1)));
00137 double z = (double)(pt.zint())/((double)(1u << (maxD-1)));
00138
00139 unsigned int indices[8];
00140 da->getNodeIndices(indices);
00141 double coord[8][3] = {
00142 {0.0,0.0,0.0},
00143 {1.0,0.0,0.0},
00144 {0.0,1.0,0.0},
00145 {1.0,1.0,0.0},
00146 {0.0,0.0,1.0},
00147 {1.0,0.0,1.0},
00148 {0.0,1.0,1.0},
00149 {1.0,1.0,1.0}
00150 };
00151 unsigned char hn = da->getHangingNodeIndex(da->curr());
00152
00153 for(int i = 0; i < 8; i++)
00154 {
00155 if (!(hn & (1 << i))){
00156 double xPt, yPt, zPt;
00157 xPt = x + (coord[i][0]*hxOct);
00158 yPt = y + (coord[i][1]*hxOct);
00159 zPt = z + (coord[i][2]*hxOct);
00160 double distSqr = (square(xPt - 0.5)) + (square(yPt - 0.5)) + (square(zPt - 0.5));
00161 if( distSqr <= square(1.5*fbmR) ) {
00162 inarray[indices[i]] = 0.0;
00163 }
00164 }
00165 }
00166 }
00167 }
00168
00169 da->vecRestoreBuffer(tmp, inarray, false, false, false, 1);
00170
00171 PetscFunctionReturn(0);
00172 }
00173
00174 PetscErrorCode SetSolutionFBM2(ot::DAMG damg, Vec tmp) {
00175 PetscFunctionBegin;
00176
00177 PetscScalar *inarray;
00178 VecZeroEntries(tmp);
00179
00180 ot::DA* da = damg->da;
00181 da->vecGetBuffer(tmp, inarray, false, false, false, 1);
00182
00183 PetscReal gamma = 0;
00184 PetscOptionsGetReal(0, "-gamma", &gamma, 0);
00185
00186 unsigned int maxD;
00187 unsigned int balOctmaxD;
00188
00189 if(da->iAmActive()) {
00190 maxD = da->getMaxDepth();
00191 balOctmaxD = maxD - 1;
00192 for(da->init<ot::DA_FLAGS::ALL>();
00193 da->curr() < da->end<ot::DA_FLAGS::ALL>();
00194 da->next<ot::DA_FLAGS::ALL>())
00195 {
00196 Point pt;
00197 pt = da->getCurrentOffset();
00198 unsigned levelhere = da->getLevel(da->curr()) - 1;
00199 double hxOct = (double)((double)(1u << (balOctmaxD - levelhere))/(double)(1u << balOctmaxD));
00200 double x = (double)(pt.xint())/((double)(1u << (maxD-1)));
00201 double y = (double)(pt.yint())/((double)(1u << (maxD-1)));
00202 double z = (double)(pt.zint())/((double)(1u << (maxD-1)));
00203
00204 unsigned int indices[8];
00205 da->getNodeIndices(indices);
00206 double coord[8][3] = {
00207 {0.0,0.0,0.0},
00208 {1.0,0.0,0.0},
00209 {0.0,1.0,0.0},
00210 {1.0,1.0,0.0},
00211 {0.0,0.0,1.0},
00212 {1.0,0.0,1.0},
00213 {0.0,1.0,1.0},
00214 {1.0,1.0,1.0}
00215 };
00216 unsigned char hn = da->getHangingNodeIndex(da->curr());
00217
00218 for(int i = 0; i < 8; i++)
00219 {
00220 if (!(hn & (1 << i))){
00221 double xPt;
00222 xPt = x + (coord[i][0]*hxOct);
00223 if( xPt < (0.9*gamma) ) {
00224 double solVal = gamma - xPt;
00225 inarray[indices[i]] = solVal;
00226 }
00227 }
00228 }
00229 }
00230 }
00231
00232 da->vecRestoreBuffer(tmp, inarray, false, false, false, 1);
00233
00234 PetscFunctionReturn(0);
00235 }
00236
00237 PetscErrorCode SetSolutionFBM(ot::DAMG damg, Vec tmp) {
00238 PetscFunctionBegin;
00239
00240 PetscScalar *inarray;
00241 VecZeroEntries(tmp);
00242
00243 ot::DA* da = damg->da;
00244 da->vecGetBuffer(tmp, inarray, false, false, false, 1);
00245
00246 PetscReal fbmR = 0;
00247 PetscOptionsGetReal(0, "-fbmR", &fbmR, 0);
00248
00249 unsigned int maxD;
00250 unsigned int balOctmaxD;
00251
00252 if(da->iAmActive()) {
00253 maxD = da->getMaxDepth();
00254 balOctmaxD = maxD - 1;
00255 for(da->init<ot::DA_FLAGS::ALL>(); da->curr() < da->end<ot::DA_FLAGS::ALL>(); da->next<ot::DA_FLAGS::ALL>())
00256 {
00257 Point pt;
00258 pt = da->getCurrentOffset();
00259 unsigned levelhere = da->getLevel(da->curr()) - 1;
00260 double hxOct = (double)((double)(1u << (balOctmaxD - levelhere))/(double)(1u << balOctmaxD));
00261 double x = (double)(pt.xint())/((double)(1u << (maxD-1)));
00262 double y = (double)(pt.yint())/((double)(1u << (maxD-1)));
00263 double z = (double)(pt.zint())/((double)(1u << (maxD-1)));
00264
00265 unsigned int indices[8];
00266 da->getNodeIndices(indices);
00267 double coord[8][3] = {
00268 {0.0,0.0,0.0},
00269 {1.0,0.0,0.0},
00270 {0.0,1.0,0.0},
00271 {1.0,1.0,0.0},
00272 {0.0,0.0,1.0},
00273 {1.0,0.0,1.0},
00274 {0.0,1.0,1.0},
00275 {1.0,1.0,1.0}
00276 };
00277 unsigned char hn = da->getHangingNodeIndex(da->curr());
00278
00279 for(int i = 0; i < 8; i++)
00280 {
00281 if (!(hn & (1 << i))){
00282 double xPt, yPt, zPt;
00283 xPt = x + (coord[i][0]*hxOct);
00284 yPt = y + (coord[i][1]*hxOct);
00285 zPt = z + (coord[i][2]*hxOct);
00286 double distSqr = (square(xPt - 0.5)) + (square(yPt - 0.5)) + (square(zPt - 0.5));
00287 if( distSqr > square(1.5*fbmR) ) {
00288 double solVal = (square(xPt - 0.5)) + (square(yPt - 0.5))
00289 + (square(zPt - 0.5)) - (square(fbmR));
00290 inarray[indices[i]] = solVal;
00291 }
00292 }
00293 }
00294 }
00295 }
00296
00297 da->vecRestoreBuffer(tmp, inarray, false, false, false, 1);
00298
00299 PetscFunctionReturn(0);
00300 }
00301
00302 PetscErrorCode ComputeTestFBM_RHS(ot::DAMG damg, Vec in) {
00303 PetscFunctionBegin;
00304
00305 Vec dirichletVals;
00306 Vec bcCorrections;
00307 VecDuplicate(in, &dirichletVals);
00308 VecDuplicate(in, &bcCorrections);
00309
00310 ComputeFBM_RHS_Part1(damg, in);
00311 ComputeFBM_RHS_Part3(damg, dirichletVals);
00312
00313 Mat tmpMat;
00314 CreateTmpDirichletJacobian(damg, &tmpMat);
00315 MatMult(tmpMat, dirichletVals, bcCorrections);
00316 MatDestroy(tmpMat);
00317
00318 VecAXPY(in, 1.0, dirichletVals);
00319 VecAXPY(in, -1.0, bcCorrections);
00320
00321 VecDestroy(dirichletVals);
00322 VecDestroy(bcCorrections);
00323
00324 int rank;
00325 MPI_Comm_rank(damg->comm, &rank);
00326 if(!rank) {
00327 std::cout<<"Done building RHS"<<std::endl;
00328 }
00329
00330 PetscFunctionReturn(0);
00331 }
00332
00333 PetscErrorCode ComputeFBM2_RHS(ot::DAMG damg, Vec in) {
00334 PetscFunctionBegin;
00335
00336 Vec deltaRhs;
00337 Vec dirichletVals;
00338 Vec bcCorrections;
00339 VecDuplicate(in, &deltaRhs);
00340 VecDuplicate(in, &dirichletVals);
00341 VecDuplicate(in, &bcCorrections);
00342
00343 VecZeroEntries(in);
00344 ComputeFBM2_RHS_Part1(damg, deltaRhs);
00345 ComputeFBM2_RHS_Part2(damg, dirichletVals);
00346
00347 Mat tmpMat;
00348 CreateTmpDirichletLaplacian(damg, &tmpMat);
00349 MatMult(tmpMat, dirichletVals, bcCorrections);
00350 MatDestroy(tmpMat);
00351
00352 PetscReal gamma = 0;
00353 PetscOptionsGetReal(0, "-gamma", &gamma, 0);
00354
00355 VecAXPY(in, -1.0, deltaRhs);
00356 VecAXPY(in, 1.0, dirichletVals);
00357 VecAXPY(in, -1.0, bcCorrections);
00358
00359 VecDestroy(deltaRhs);
00360 VecDestroy(dirichletVals);
00361 VecDestroy(bcCorrections);
00362
00363 int rank;
00364 MPI_Comm_rank(damg->comm, &rank);
00365 if(!rank) {
00366 std::cout<<"Done building RHS"<<std::endl;
00367 }
00368
00369 PetscFunctionReturn(0);
00370 }
00371
00372
00373 PetscErrorCode ComputeFBM2_RHS_Part1(ot::DAMG damg, Vec in) {
00374 PetscFunctionBegin;
00375
00376 ot::DA* da = damg->da;
00377
00378 DirichletJacData* data = (static_cast<DirichletJacData*>(damg->user));
00379 unsigned char* bdyArr = data->bdyArr;
00380
00381 MPI_Comm commAll = da->getComm();
00382
00383 int rankAll = da->getRankAll();
00384 int npesAll = da->getNpesAll();
00385
00386 unsigned int dim = da->getDimension();
00387 unsigned int maxDepth = da->getMaxDepth();
00388 int npesActive = da->getNpesActive();
00389
00390 if( npesActive < npesAll ) {
00391 unsigned int tmpArr[3];
00392 tmpArr[0] = dim;
00393 tmpArr[1] = maxDepth;
00394 tmpArr[2] = npesActive;
00395
00396 par::Mpi_Bcast<unsigned int>(tmpArr, 3, 0, commAll);
00397
00398 dim = tmpArr[0];
00399 maxDepth = tmpArr[1];
00400 npesActive = static_cast<int>(tmpArr[2]);
00401 }
00402
00403 unsigned int balOctMaxD = (maxDepth - 1);
00404
00405 PetscReal gamma = 0;
00406 PetscOptionsGetReal(0, "-gamma", &gamma, 0);
00407
00408 PetscInt Nsample = 100;
00409 PetscOptionsGetInt(0, "-Nsample", &Nsample, 0);
00410
00411 double hSample = 1.0/static_cast<double>(Nsample);
00412 std::vector<double> pts;
00413 if(!rankAll) {
00414 for(double z = 0; z < 1.0; z += hSample) {
00415 for(double y = 0; y < 1.0; y += hSample) {
00416 pts.push_back(gamma);
00417 pts.push_back(y);
00418 pts.push_back(z);
00419 }
00420 }
00421 }
00422
00423 unsigned int numLocalDelta = pts.size()/3;
00424
00425 std::vector<ot::NodeAndValues<double, 4> > tnAndVal(numLocalDelta);
00426
00427 for(unsigned int i = 0; i < numLocalDelta; i++) {
00428 double x = pts[3*i];
00429 double y = pts[(3*i) + 1];
00430 double z = pts[(3*i) + 2];
00431
00432 unsigned int xint = static_cast<unsigned int>(x*static_cast<double>(1u << balOctMaxD));
00433 unsigned int yint = static_cast<unsigned int>(y*static_cast<double>(1u << balOctMaxD));
00434 unsigned int zint = static_cast<unsigned int>(z*static_cast<double>(1u << balOctMaxD));
00435
00436 tnAndVal[i].node = ot::TreeNode(xint, yint, zint, maxDepth, dim, maxDepth);
00437
00438 tnAndVal[i].values[0] = x;
00439 tnAndVal[i].values[1] = y;
00440 tnAndVal[i].values[2] = z;
00441 tnAndVal[i].values[3] = square(hSample);
00442 }
00443
00444 pts.clear();
00445
00446 std::vector<ot::TreeNode> minBlocks = da->getMinAllBlocks();
00447
00448 if(npesActive < npesAll) {
00449 bool* activeStates = new bool[npesAll];
00450
00451 activeStates[0] = true;
00452 for(int i = 1; i < npesActive; i++) {
00453 activeStates[i] = false;
00454 }
00455 for(int i = npesActive; i < npesAll; i++) {
00456 activeStates[i] = true;
00457 }
00458
00459 MPI_Comm tmpComm;
00460
00461 par::splitComm2way(activeStates, &tmpComm, commAll);
00462
00463 if(rankAll == 0) {
00464 par::Mpi_Bcast<ot::TreeNode>(&(*(minBlocks.begin())) , npesActive, 0, tmpComm);
00465 }
00466 if(rankAll >= npesActive) {
00467 minBlocks.resize(npesActive);
00468 par::Mpi_Bcast<ot::TreeNode>(&(*(minBlocks.begin())) , npesActive, 0, tmpComm);
00469 }
00470
00471 delete [] activeStates;
00472 }
00473
00474 unsigned int* part = new unsigned int[tnAndVal.size()];
00475
00476 int *sendCnt = new int[npesAll];
00477 for(int i = 0; i < npesAll; i++) {
00478 sendCnt[i] = 0;
00479 }
00480
00481 for(int i = 0; i < tnAndVal.size(); i++) {
00482 seq::maxLowerBound<ot::TreeNode>(minBlocks, tnAndVal[i].node, part[i], NULL, NULL);
00483 sendCnt[part[i]]++;
00484 }
00485
00486 int *recvCnt = new int[npesAll];
00487
00488 par::Mpi_Alltoall<int>( sendCnt, recvCnt, 1, commAll);
00489
00490 int *sendOffsets = new int[npesAll];
00491 int *recvOffsets = new int[npesAll];
00492
00493 sendOffsets[0] = 0;
00494 recvOffsets[0] = 0;
00495 for(int i = 1; i < npesAll; i++) {
00496 sendOffsets[i] = sendOffsets[i - 1] + sendCnt[i - 1];
00497 recvOffsets[i] = recvOffsets[i - 1] + recvCnt[i - 1];
00498 }
00499
00500
00501
00502 std::vector<ot::NodeAndValues<double, 4> > sendList(sendOffsets[npesAll - 1] + sendCnt[npesAll - 1]);
00503 std::vector<ot::NodeAndValues<double, 4> > recvList(recvOffsets[npesAll - 1] + recvCnt[npesAll - 1]);
00504
00505 int* tmpSendCnt = new int[npesAll];
00506 for(int i = 0; i < npesAll; i++) {
00507 tmpSendCnt[i] = 0;
00508 }
00509
00510 for(int i = 0; i < tnAndVal.size(); i++) {
00511 sendList[sendOffsets[part[i]] + tmpSendCnt[part[i]]] = tnAndVal[i];
00512 tmpSendCnt[part[i]]++;
00513 }
00514 delete [] tmpSendCnt;
00515 tnAndVal.clear();
00516
00517 par::Mpi_Alltoallv_sparse<ot::NodeAndValues<double, 4> >( &(*(sendList.begin())), sendCnt,
00518 sendOffsets, &(*(recvList.begin())), recvCnt, recvOffsets, commAll);
00519
00520 sendList.clear();
00521
00522 delete [] part;
00523 delete [] sendCnt;
00524 delete [] recvCnt;
00525 delete [] sendOffsets;
00526 delete [] recvOffsets;
00527
00528 sort(recvList.begin(), recvList.end());
00529
00530
00531
00532 VecZeroEntries(in);
00533
00534 if(!(da->iAmActive())) {
00535 assert(recvList.empty());
00536 } else {
00537 PetscScalar *inarray;
00538 da->vecGetBuffer(in, inarray, false, false, false, 1);
00539
00540 unsigned int ptsCtr = 0;
00541
00542 for(da->init<ot::DA_FLAGS::WRITABLE>();
00543 da->curr() < da->end<ot::DA_FLAGS::WRITABLE>();
00544 da->next<ot::DA_FLAGS::WRITABLE>())
00545 {
00546 Point pt;
00547 pt = da->getCurrentOffset();
00548 unsigned int idx = da->curr();
00549 unsigned levelhere = da->getLevel(idx);
00550 unsigned int xint = pt.xint();
00551 unsigned int yint = pt.yint();
00552 unsigned int zint = pt.zint();
00553 ot::TreeNode currOct(xint, yint, zint, levelhere, dim, maxDepth);
00554 while( (ptsCtr < recvList.size()) &&
00555 (recvList[ptsCtr].node < currOct) ) {
00556 ptsCtr++;
00557 }
00558 double hxOct = (double)((double)(1u << (maxDepth - levelhere))/(double)(1u << balOctMaxD));
00559 double x = static_cast<double>(xint)/((double)(1u << balOctMaxD));
00560 double y = static_cast<double>(yint)/((double)(1u << balOctMaxD));
00561 double z = static_cast<double>(zint)/((double)(1u << balOctMaxD));
00562 unsigned int indices[8];
00563 da->getNodeIndices(indices);
00564 unsigned char childNum = da->getChildNumber();
00565 unsigned char hnMask = da->getHangingNodeIndex(idx);
00566 unsigned char elemType = 0;
00567 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
00568 while( (ptsCtr < recvList.size()) &&
00569 ( currOct.isAncestor(recvList[ptsCtr].node) ||
00570 ( currOct == (recvList[ptsCtr].node) ) ) ) {
00571 for(unsigned int j = 0; j < 8; j++) {
00572 if(!(bdyArr[indices[j]])) {
00573 double xLoc = (((2.0/hxOct)*(recvList[ptsCtr].values[0] - x)) - 1.0);
00574 double yLoc = (((2.0/hxOct)*(recvList[ptsCtr].values[1] - y)) - 1.0);
00575 double zLoc = (((2.0/hxOct)*(recvList[ptsCtr].values[2] - z)) - 1.0);
00576 double ShFnVal = ( ot::ShapeFnCoeffs[childNum][elemType][j][0] +
00577 (ot::ShapeFnCoeffs[childNum][elemType][j][1]*xLoc) +
00578 (ot::ShapeFnCoeffs[childNum][elemType][j][2]*yLoc) +
00579 (ot::ShapeFnCoeffs[childNum][elemType][j][3]*zLoc) +
00580 (ot::ShapeFnCoeffs[childNum][elemType][j][4]*xLoc*yLoc) +
00581 (ot::ShapeFnCoeffs[childNum][elemType][j][5]*yLoc*zLoc) +
00582 (ot::ShapeFnCoeffs[childNum][elemType][j][6]*zLoc*xLoc) +
00583 (ot::ShapeFnCoeffs[childNum][elemType][j][7]*xLoc*yLoc*zLoc) );
00584 inarray[indices[j]] += ((recvList[ptsCtr].values[3])*ShFnVal);
00585 }
00586 }
00587 ptsCtr++;
00588 }
00589 }
00590
00591 da->WriteToGhostsBegin<PetscScalar>(inarray, 1);
00592 da->WriteToGhostsEnd<PetscScalar>(inarray, 1);
00593
00594 da->vecRestoreBuffer(in, inarray, false, false, false, 1);
00595
00596 }
00597
00598 PetscFunctionReturn(0);
00599
00600 }
00601
00602 PetscErrorCode ComputeFBM2_RHS_Part2(ot::DAMG damg, Vec in) {
00603 PetscFunctionBegin;
00604
00605 ot::DA* da = damg->da;
00606 PetscScalar *inarray;
00607
00608 DirichletJacData* data = (static_cast<DirichletJacData*>(damg->user));
00609 unsigned char* bdyArr = data->bdyArr;
00610
00611 PetscReal gamma = 0;
00612 PetscOptionsGetReal(0, "-gamma", &gamma, 0);
00613
00614 VecZeroEntries(in);
00615 da->vecGetBuffer(in, inarray, false, false, false, 1);
00616
00617 unsigned int maxD;
00618 unsigned int balOctmaxD;
00619
00620 if(da->iAmActive()) {
00621 maxD = da->getMaxDepth();
00622 balOctmaxD = maxD - 1;
00623 for(da->init<ot::DA_FLAGS::ALL>();
00624 da->curr() < da->end<ot::DA_FLAGS::ALL>();
00625 da->next<ot::DA_FLAGS::ALL>())
00626 {
00627 Point pt;
00628 pt = da->getCurrentOffset();
00629 unsigned int idx = da->curr();
00630 unsigned levelhere = (da->getLevel(idx) - 1);
00631 double hxOct = (double)((double)(1u << (balOctmaxD - levelhere))/(double)(1u << balOctmaxD));
00632 double x = (double)(pt.xint())/((double)(1u << (maxD-1)));
00633 double y = (double)(pt.yint())/((double)(1u << (maxD-1)));
00634 double z = (double)(pt.zint())/((double)(1u << (maxD-1)));
00635 double coord[8][3] = {
00636 {0.0,0.0,0.0},
00637 {1.0,0.0,0.0},
00638 {0.0,1.0,0.0},
00639 {1.0,1.0,0.0},
00640 {0.0,0.0,1.0},
00641 {1.0,0.0,1.0},
00642 {0.0,1.0,1.0},
00643 {1.0,1.0,1.0}
00644 };
00645 unsigned int indices[8];
00646 da->getNodeIndices(indices);
00647 unsigned char hnMask = da->getHangingNodeIndex(idx);
00648 for(unsigned int j = 0; j < 8; j++) {
00649 if(!(hnMask & (1 << j))) {
00650 if(bdyArr[indices[j]]) {
00651 double xPt = x + (coord[j][0]*hxOct);
00652 if(xPt < gamma) {
00653 inarray[indices[j]] = gamma - xPt;
00654 }
00655 }
00656 }
00657 }
00658 }
00659 }
00660
00661 da->vecRestoreBuffer(in,inarray,false,false,false,1);
00662
00663 PetscFunctionReturn(0);
00664 }
00665
00666 PetscErrorCode ComputeFBM_RHS(ot::DAMG damg, Vec in) {
00667 PetscFunctionBegin;
00668
00669 Vec deltaRhs;
00670 Vec dirichletVals;
00671 Vec bcCorrections;
00672 VecDuplicate(in, &deltaRhs);
00673 VecDuplicate(in, &dirichletVals);
00674 VecDuplicate(in, &bcCorrections);
00675
00676 ComputeFBM_RHS_Part1(damg, in);
00677 ComputeFBM_RHS_Part2(damg, deltaRhs);
00678 ComputeFBM_RHS_Part3(damg, dirichletVals);
00679
00680 Mat tmpMat;
00681 CreateTmpDirichletJacobian(damg, &tmpMat);
00682 MatMult(tmpMat, dirichletVals, bcCorrections);
00683 MatDestroy(tmpMat);
00684
00685 PetscReal fbmR = 0;
00686 PetscOptionsGetReal(0, "-fbmR", &fbmR, 0);
00687
00688 VecAXPY(in, -2.0*fbmR, deltaRhs);
00689 VecAXPY(in, 1.0, dirichletVals);
00690 VecAXPY(in, -1.0, bcCorrections);
00691
00692 VecDestroy(deltaRhs);
00693 VecDestroy(dirichletVals);
00694 VecDestroy(bcCorrections);
00695
00696 int rank;
00697 MPI_Comm_rank(damg->comm, &rank);
00698 if(!rank) {
00699 std::cout<<"Done building RHS"<<std::endl;
00700 }
00701
00702 PetscFunctionReturn(0);
00703 }
00704
00705 PetscErrorCode ComputeFBM_RHS_Part3(ot::DAMG damg, Vec in) {
00706 PetscFunctionBegin;
00707
00708 ot::DA* da = damg->da;
00709 PetscScalar *inarray;
00710
00711 DirichletJacData* data = (static_cast<DirichletJacData*>(damg->user));
00712 unsigned char* bdyArr = data->bdyArr;
00713
00714 PetscReal fbmR = 0;
00715 PetscOptionsGetReal(0, "-fbmR", &fbmR, 0);
00716
00717 VecZeroEntries(in);
00718 da->vecGetBuffer(in,inarray,false,false,false,1);
00719
00720 unsigned int maxD;
00721 unsigned int balOctmaxD;
00722
00723 if(da->iAmActive()) {
00724 maxD = da->getMaxDepth();
00725 balOctmaxD = maxD - 1;
00726 for(da->init<ot::DA_FLAGS::ALL>();
00727 da->curr() < da->end<ot::DA_FLAGS::ALL>();
00728 da->next<ot::DA_FLAGS::ALL>())
00729 {
00730 Point pt;
00731 pt = da->getCurrentOffset();
00732 unsigned int idx = da->curr();
00733 unsigned levelhere = (da->getLevel(idx) - 1);
00734 double hxOct = (double)((double)(1u << (balOctmaxD - levelhere))/(double)(1u << balOctmaxD));
00735 double x = (double)(pt.xint())/((double)(1u << (maxD-1)));
00736 double y = (double)(pt.yint())/((double)(1u << (maxD-1)));
00737 double z = (double)(pt.zint())/((double)(1u << (maxD-1)));
00738 double coord[8][3] = {
00739 {0.0,0.0,0.0},
00740 {1.0,0.0,0.0},
00741 {0.0,1.0,0.0},
00742 {1.0,1.0,0.0},
00743 {0.0,0.0,1.0},
00744 {1.0,0.0,1.0},
00745 {0.0,1.0,1.0},
00746 {1.0,1.0,1.0}
00747 };
00748 unsigned int indices[8];
00749 da->getNodeIndices(indices);
00750 unsigned char hnMask = da->getHangingNodeIndex(idx);
00751 for(unsigned int j = 0; j < 8; j++) {
00752 if(!(hnMask & (1 << j))) {
00753 if(bdyArr[indices[j]]) {
00754 double xPt = x + (coord[j][0]*hxOct);
00755 double yPt = y + (coord[j][1]*hxOct);
00756 double zPt = z + (coord[j][2]*hxOct);
00757 inarray[indices[j]] = (square(xPt - 0.5)) + (square(yPt - 0.5))
00758 + (square(zPt - 0.5)) - (square(fbmR));
00759 }
00760 }
00761 }
00762 }
00763 }
00764
00765 da->vecRestoreBuffer(in,inarray,false,false,false,1);
00766
00767 PetscFunctionReturn(0);
00768 }
00769
00770
00771
00772
00773 PetscErrorCode ComputeFBM_RHS_Part2(ot::DAMG damg, Vec in) {
00774 PetscFunctionBegin;
00775
00776 ot::DA* da = damg->da;
00777
00778 DirichletJacData* data = (static_cast<DirichletJacData*>(damg->user));
00779 unsigned char* bdyArr = data->bdyArr;
00780
00781 MPI_Comm commAll = da->getComm();
00782
00783 int rankAll = da->getRankAll();
00784 int npesAll = da->getNpesAll();
00785
00786 unsigned int dim = da->getDimension();
00787 unsigned int maxDepth = da->getMaxDepth();
00788 int npesActive = da->getNpesActive();
00789
00790 if( npesActive < npesAll ) {
00791 unsigned int tmpArr[3];
00792 tmpArr[0] = dim;
00793 tmpArr[1] = maxDepth;
00794 tmpArr[2] = npesActive;
00795
00796 par::Mpi_Bcast<unsigned int>(tmpArr, 3, 0, commAll);
00797
00798 dim = tmpArr[0];
00799 maxDepth = tmpArr[1];
00800 npesActive = static_cast<int>(tmpArr[2]);
00801 }
00802
00803 unsigned int balOctMaxD = (maxDepth - 1);
00804
00805 char pFile[250];
00806 sprintf(pFile,"fbmInp%d_%d.pts", rankAll, npesAll);
00807
00808 std::vector<double> pts;
00809 ot::readPtsFromFile(pFile, pts);
00810
00811 unsigned int numLocalDelta = pts.size()/3;
00812
00813 std::vector<ot::NodeAndValues<double, 4> > tnAndVal(numLocalDelta);
00814
00815 for(unsigned int i = 0; i < numLocalDelta; i++) {
00816 double x = pts[3*i];
00817 double y = pts[(3*i) + 1];
00818 double z = pts[(3*i) + 2];
00819
00820 unsigned int xint = static_cast<unsigned int>(x*static_cast<double>(1u << balOctMaxD));
00821 unsigned int yint = static_cast<unsigned int>(y*static_cast<double>(1u << balOctMaxD));
00822 unsigned int zint = static_cast<unsigned int>(z*static_cast<double>(1u << balOctMaxD));
00823
00824 tnAndVal[i].node = ot::TreeNode(xint, yint, zint, maxDepth, dim, maxDepth);
00825
00826 tnAndVal[i].values[0] = x;
00827 tnAndVal[i].values[1] = y;
00828 tnAndVal[i].values[2] = z;
00829 tnAndVal[i].values[3] = 1.0;
00830 }
00831
00832 pts.clear();
00833
00834 std::vector<ot::TreeNode> minBlocks = da->getMinAllBlocks();
00835
00836 if(npesActive < npesAll) {
00837 bool* activeStates = new bool[npesAll];
00838
00839 activeStates[0] = true;
00840 for(int i = 1; i < npesActive; i++) {
00841 activeStates[i] = false;
00842 }
00843 for(int i = npesActive; i < npesAll; i++) {
00844 activeStates[i] = true;
00845 }
00846
00847 MPI_Comm tmpComm;
00848
00849 par::splitComm2way(activeStates, &tmpComm, commAll);
00850
00851 if(rankAll == 0) {
00852 par::Mpi_Bcast<ot::TreeNode>(&(*(minBlocks.begin())) , npesActive, 0, tmpComm);
00853 }
00854 if(rankAll >= npesActive) {
00855 minBlocks.resize(npesActive);
00856 par::Mpi_Bcast<ot::TreeNode>(&(*(minBlocks.begin())) , npesActive, 0, tmpComm);
00857 }
00858
00859 delete [] activeStates;
00860 }
00861
00862 unsigned int* part = new unsigned int[tnAndVal.size()];
00863
00864 int *sendCnt = new int[npesAll];
00865 for(int i = 0; i < npesAll; i++) {
00866 sendCnt[i] = 0;
00867 }
00868
00869 for(int i = 0; i < tnAndVal.size(); i++) {
00870 seq::maxLowerBound<ot::TreeNode>(minBlocks, tnAndVal[i].node, part[i], NULL, NULL);
00871 sendCnt[part[i]]++;
00872 }
00873
00874 int *recvCnt = new int[npesAll];
00875
00876 par::Mpi_Alltoall<int>( sendCnt, recvCnt, 1, commAll);
00877
00878 int *sendOffsets = new int[npesAll];
00879 int *recvOffsets = new int[npesAll];
00880
00881 sendOffsets[0] = 0;
00882 recvOffsets[0] = 0;
00883 for(int i = 1; i < npesAll; i++) {
00884 sendOffsets[i] = sendOffsets[i - 1] + sendCnt[i - 1];
00885 recvOffsets[i] = recvOffsets[i - 1] + recvCnt[i - 1];
00886 }
00887
00888
00889
00890 std::vector<ot::NodeAndValues<double, 4> > sendList(sendOffsets[npesAll - 1] + sendCnt[npesAll - 1]);
00891 std::vector<ot::NodeAndValues<double, 4> > recvList(recvOffsets[npesAll - 1] + recvCnt[npesAll - 1]);
00892
00893 int* tmpSendCnt = new int[npesAll];
00894 for(int i = 0; i < npesAll; i++) {
00895 tmpSendCnt[i] = 0;
00896 }
00897
00898 for(int i = 0; i < tnAndVal.size(); i++) {
00899 sendList[sendOffsets[part[i]] + tmpSendCnt[part[i]]] = tnAndVal[i];
00900 tmpSendCnt[part[i]]++;
00901 }
00902 delete [] tmpSendCnt;
00903 tnAndVal.clear();
00904
00905 par::Mpi_Alltoallv_sparse<ot::NodeAndValues<double, 4> >( &(*(sendList.begin())), sendCnt,
00906 sendOffsets, &(*(recvList.begin())), recvCnt, recvOffsets, commAll);
00907
00908 sendList.clear();
00909
00910 delete [] part;
00911 delete [] sendCnt;
00912 delete [] recvCnt;
00913 delete [] sendOffsets;
00914 delete [] recvOffsets;
00915
00916 sort(recvList.begin(), recvList.end());
00917
00918
00919
00920 VecZeroEntries(in);
00921
00922 if(!(da->iAmActive())) {
00923 assert(recvList.empty());
00924 } else {
00925 PetscScalar *inarray;
00926 da->vecGetBuffer(in, inarray, false, false, false, 1);
00927
00928 unsigned int ptsCtr = 0;
00929
00930 for(da->init<ot::DA_FLAGS::WRITABLE>();
00931 da->curr() < da->end<ot::DA_FLAGS::WRITABLE>();
00932 da->next<ot::DA_FLAGS::WRITABLE>())
00933 {
00934 Point pt;
00935 pt = da->getCurrentOffset();
00936 unsigned int idx = da->curr();
00937 unsigned levelhere = da->getLevel(idx);
00938 unsigned int xint = pt.xint();
00939 unsigned int yint = pt.yint();
00940 unsigned int zint = pt.zint();
00941 ot::TreeNode currOct(xint, yint, zint, levelhere, dim, maxDepth);
00942 while( (ptsCtr < recvList.size()) &&
00943 (recvList[ptsCtr].node < currOct) ) {
00944 ptsCtr++;
00945 }
00946 double hxOct = (double)((double)(1u << (maxDepth - levelhere))/(double)(1u << balOctMaxD));
00947 double x = static_cast<double>(xint)/((double)(1u << balOctMaxD));
00948 double y = static_cast<double>(yint)/((double)(1u << balOctMaxD));
00949 double z = static_cast<double>(zint)/((double)(1u << balOctMaxD));
00950 unsigned int indices[8];
00951 da->getNodeIndices(indices);
00952 unsigned char childNum = da->getChildNumber();
00953 unsigned char hnMask = da->getHangingNodeIndex(idx);
00954 unsigned char elemType = 0;
00955 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
00956 while( (ptsCtr < recvList.size()) &&
00957 ( currOct.isAncestor(recvList[ptsCtr].node) ||
00958 ( currOct == (recvList[ptsCtr].node) ) ) ) {
00959 for(unsigned int j = 0; j < 8; j++) {
00960 if(!(bdyArr[indices[j]])) {
00961 double xLoc = (((2.0/hxOct)*(recvList[ptsCtr].values[0] - x)) - 1.0);
00962 double yLoc = (((2.0/hxOct)*(recvList[ptsCtr].values[1] - y)) - 1.0);
00963 double zLoc = (((2.0/hxOct)*(recvList[ptsCtr].values[2] - z)) - 1.0);
00964 double ShFnVal = ( ot::ShapeFnCoeffs[childNum][elemType][j][0] +
00965 (ot::ShapeFnCoeffs[childNum][elemType][j][1]*xLoc) +
00966 (ot::ShapeFnCoeffs[childNum][elemType][j][2]*yLoc) +
00967 (ot::ShapeFnCoeffs[childNum][elemType][j][3]*zLoc) +
00968 (ot::ShapeFnCoeffs[childNum][elemType][j][4]*xLoc*yLoc) +
00969 (ot::ShapeFnCoeffs[childNum][elemType][j][5]*yLoc*zLoc) +
00970 (ot::ShapeFnCoeffs[childNum][elemType][j][6]*zLoc*xLoc) +
00971 (ot::ShapeFnCoeffs[childNum][elemType][j][7]*xLoc*yLoc*zLoc) );
00972 inarray[indices[j]] += ((recvList[ptsCtr].values[3])*ShFnVal);
00973 }
00974 }
00975 ptsCtr++;
00976 }
00977 }
00978
00979 da->WriteToGhostsBegin<PetscScalar>(inarray, 1);
00980 da->WriteToGhostsEnd<PetscScalar>(inarray, 1);
00981
00982 da->vecRestoreBuffer(in, inarray, false, false, false, 1);
00983
00984 }
00985
00986 PetscFunctionReturn(0);
00987
00988 }
00989
00990 PetscErrorCode ComputeFBM_RHS_Part1(ot::DAMG damg, Vec in) {
00991 PetscFunctionBegin;
00992
00993 ot::DA* da = damg->da;
00994 PetscScalar *inarray;
00995
00996 DirichletJacData* data = (static_cast<DirichletJacData*>(damg->user));
00997 unsigned char* bdyArr = data->bdyArr;
00998
00999 VecZeroEntries(in);
01000 da->vecGetBuffer(in,inarray,false,false,false,1);
01001
01002 unsigned int maxD;
01003 unsigned int balOctmaxD;
01004
01005 PetscInt numGaussPts = 0;
01006 PetscOptionsGetInt(0,"-numGaussPts",&numGaussPts,0);
01007
01008 PetscReal fbmR = 0;
01009 PetscOptionsGetReal(0,"-fbmR",&fbmR,0);
01010
01011 assert(numGaussPts <= 7);
01012 assert(numGaussPts >= 2);
01013
01014 std::vector<std::vector<double> > wts(6);
01015 std::vector<std::vector<double> > gPts(6);
01016
01017 for(int k = 0; k < 6; k++) {
01018 wts[k].resize(k+2);
01019 gPts[k].resize(k+2);
01020 }
01021
01022
01023 wts[0][0] = 1.0; wts[0][1] = 1.0;
01024 gPts[0][0] = sqrt(1.0/3.0); gPts[0][1] = -sqrt(1.0/3.0);
01025
01026
01027 wts[1][0] = 0.88888889; wts[1][1] = 0.555555556; wts[1][2] = 0.555555556;
01028 gPts[1][0] = 0.0; gPts[1][1] = 0.77459667; gPts[1][2] = -0.77459667;
01029
01030
01031 wts[2][0] = 0.65214515; wts[2][1] = 0.65214515;
01032 wts[2][2] = 0.34785485; wts[2][3] = 0.34785485;
01033 gPts[2][0] = 0.33998104; gPts[2][1] = -0.33998104;
01034 gPts[2][2] = 0.86113631; gPts[2][3] = -0.86113631;
01035
01036
01037 wts[3][0] = 0.568888889; wts[3][1] = 0.47862867; wts[3][2] = 0.47862867;
01038 wts[3][3] = 0.23692689; wts[3][4] = 0.23692689;
01039 gPts[3][0] = 0.0; gPts[3][1] = 0.53846931; gPts[3][2] = -0.53846931;
01040 gPts[3][3] = 0.90617985; gPts[3][4] = -0.90617985;
01041
01042
01043 wts[4][0] = 0.46791393; wts[4][1] = 0.46791393; wts[4][2] = 0.36076157;
01044 wts[4][3] = 0.36076157; wts[4][4] = 0.17132449; wts[4][5] = 0.17132449;
01045 gPts[4][0] = 0.23861918; gPts[4][1] = -0.23861918; gPts[4][2] = 0.66120939;
01046 gPts[4][3] = -0.66120939; gPts[4][4] = 0.93246951; gPts[4][5] = -0.93246951;
01047
01048
01049 wts[5][0] = 0.41795918; wts[5][1] = 0.38183005; wts[5][2] = 0.38183005;
01050 wts[5][3] = 0.27970539; wts[5][4] = 0.27970539;
01051 wts[5][5] = 0.12948497; wts[5][6] = 0.12948497;
01052 gPts[5][0] = 0.0; gPts[5][1] = 0.40584515; gPts[5][2] = -0.40584515;
01053 gPts[5][3] = 0.74153119; gPts[5][4] = -0.74153119;
01054 gPts[5][5] = 0.94910791; gPts[5][6] = -0.94910791;
01055
01056 if(da->iAmActive()) {
01057 maxD = da->getMaxDepth();
01058 balOctmaxD = maxD - 1;
01059 for(da->init<ot::DA_FLAGS::ALL>();
01060 da->curr() < da->end<ot::DA_FLAGS::ALL>();
01061 da->next<ot::DA_FLAGS::ALL>())
01062 {
01063 Point pt;
01064 pt = da->getCurrentOffset();
01065 unsigned int idx = da->curr();
01066 unsigned levelhere = (da->getLevel(idx) - 1);
01067 double hxOct = (double)((double)(1u << (balOctmaxD - levelhere))/(double)(1u << balOctmaxD));
01068 double x = (double)(pt.xint())/((double)(1u << (maxD-1)));
01069 double y = (double)(pt.yint())/((double)(1u << (maxD-1)));
01070 double z = (double)(pt.zint())/((double)(1u << (maxD-1)));
01071 double fac = ((hxOct*hxOct*hxOct)/8.0);
01072 unsigned int indices[8];
01073 da->getNodeIndices(indices);
01074 unsigned char childNum = da->getChildNumber();
01075 unsigned char hnMask = da->getHangingNodeIndex(idx);
01076 unsigned char elemType = 0;
01077 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
01078 for(unsigned int j = 0; j < 8; j++) {
01079 if(!(bdyArr[indices[j]])) {
01080 double integral = 0.0;
01081
01082 for(int m = 0; m < numGaussPts; m++) {
01083 for(int n = 0; n < numGaussPts; n++) {
01084 for(int p = 0; p < numGaussPts; p++) {
01085 double xPt = ( (hxOct*(1.0 + gPts[numGaussPts-2][m])*0.5) + x );
01086 double yPt = ( (hxOct*(1.0 + gPts[numGaussPts-2][n])*0.5) + y );
01087 double zPt = ( (hxOct*(1.0 + gPts[numGaussPts-2][p])*0.5) + z );
01088 double distSqr = (square(xPt - 0.5)) + (square(yPt - 0.5)) + (square(zPt - 0.5));
01089 double rhsVal = 0.0;
01090 if( distSqr >= (square(fbmR)) ) {
01091 rhsVal = -6.0 -(square(fbmR)) + (square(xPt - 0.5)) +
01092 (square(yPt - 0.5)) + (square(zPt - 0.5));
01093 }
01094 double ShFnVal = ( ot::ShapeFnCoeffs[childNum][elemType][j][0] +
01095 (ot::ShapeFnCoeffs[childNum][elemType][j][1]*gPts[numGaussPts-2][m]) +
01096 (ot::ShapeFnCoeffs[childNum][elemType][j][2]*gPts[numGaussPts-2][n]) +
01097 (ot::ShapeFnCoeffs[childNum][elemType][j][3]*gPts[numGaussPts-2][p]) +
01098 (ot::ShapeFnCoeffs[childNum][elemType][j][4]*gPts[numGaussPts-2][m]*
01099 gPts[numGaussPts-2][n]) +
01100 (ot::ShapeFnCoeffs[childNum][elemType][j][5]*gPts[numGaussPts-2][n]*
01101 gPts[numGaussPts-2][p]) +
01102 (ot::ShapeFnCoeffs[childNum][elemType][j][6]*gPts[numGaussPts-2][p]*
01103 gPts[numGaussPts-2][m]) +
01104 (ot::ShapeFnCoeffs[childNum][elemType][j][7]*gPts[numGaussPts-2][m]*
01105 gPts[numGaussPts-2][n]*gPts[numGaussPts-2][p]) );
01106 integral += (wts[numGaussPts-2][m]*wts[numGaussPts-2][n]
01107 *wts[numGaussPts-2][p]*rhsVal*ShFnVal);
01108 }
01109 }
01110 }
01111 inarray[indices[j]] += (fac*integral);
01112 }
01113 }
01114 }
01115 }
01116
01117 da->vecRestoreBuffer(in,inarray,false,false,false,1);
01118
01119 PetscFunctionReturn(0);
01120 }
01121
01122
01123
01124
01125
01126
01127 PetscErrorCode ComputeRHS2(ot::DAMG damg,Vec in) {
01128 PetscFunctionBegin;
01129 ot::DA* da = damg->da;
01130 PetscScalar *inarray;
01131
01132
01133
01134
01135 VecZeroEntries(in);
01136 da->vecGetBuffer(in,inarray,false,false,false,1);
01137
01138 unsigned int maxD;
01139 unsigned int balOctmaxD;
01140
01141 double wts[3] = { (8.0/9.0), (5.0/9.0), (5.0/9.0) };
01142 double gPts[3] = { 0.0, sqrt((3.0/5.0)), -sqrt((3.0/5.0)) };
01143
01144 if(da->iAmActive()) {
01145 maxD = da->getMaxDepth();
01146 balOctmaxD = maxD - 1;
01147 for(da->init<ot::DA_FLAGS::ALL>();
01148 da->curr() < da->end<ot::DA_FLAGS::ALL>();
01149 da->next<ot::DA_FLAGS::ALL>())
01150 {
01151 Point pt;
01152 pt = da->getCurrentOffset();
01153 unsigned int idx = da->curr();
01154 unsigned levelhere = (da->getLevel(idx) - 1);
01155 double hxOct = (double)((double)(1u << (balOctmaxD - levelhere))/(double)(1u << balOctmaxD));
01156 double x = (double)(pt.xint())/((double)(1u << (maxD-1)));
01157 double y = (double)(pt.yint())/((double)(1u << (maxD-1)));
01158 double z = (double)(pt.zint())/((double)(1u << (maxD-1)));
01159 double fac = ((hxOct*hxOct*hxOct)/8.0);
01160 unsigned int indices[8];
01161 da->getNodeIndices(indices);
01162 unsigned char childNum = da->getChildNumber();
01163 unsigned char hnMask = da->getHangingNodeIndex(idx);
01164 unsigned char elemType = 0;
01165 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
01166 for(unsigned int j = 0; j < 8; j++) {
01167 double integral = 0.0;
01168
01169 for(int m = 0; m < 3; m++) {
01170 for(int n = 0; n < 3; n++) {
01171 for(int p = 0; p < 3; p++) {
01172 double fnVal = 0.0;
01173 double xPt = ( (hxOct*(1.0 +gPts[m])*0.5) + x );
01174 double yPt = ( (hxOct*(1.0 + gPts[n])*0.5) + y );
01175 double zPt = ( (hxOct*(1.0 + gPts[p])*0.5) + z );
01176 EVAL_FN(xPt,yPt,zPt,fnVal)
01177 integral +=
01178 (wts[m]*wts[n]*wts[p]*fnVal*
01179 ShapeFnStencil[childNum][elemType][j][m][n][p]);
01180 }
01181 }
01182 }
01183 inarray[indices[j]] += (fac*integral);
01184 }
01185 }
01186 }
01187
01188 da->vecRestoreBuffer(in,inarray,false,false,false,1);
01189
01190 PetscFunctionReturn(0);
01191 }
01192
01193 #undef square
01194 #undef EVAL_FN
01195
01196 PetscErrorCode ComputeSol(ot::DAMG damg,Vec expectedSol) {
01197 PetscFunctionBegin;
01198 ot::DA* da = damg->da;
01199 PetscScalar *solArray;
01200 VecZeroEntries(expectedSol);
01201 da->vecGetBuffer(expectedSol,solArray,false,false,false,1);
01202
01203 unsigned int maxD;
01204 unsigned int balOctmaxD;
01205
01206 if(da->iAmActive()) {
01207 maxD = da->getMaxDepth();
01208 balOctmaxD = maxD - 1;
01209 for(da->init<ot::DA_FLAGS::ALL>();
01210 da->curr() < da->end<ot::DA_FLAGS::ALL>();
01211 da->next<ot::DA_FLAGS::ALL>())
01212 {
01213 Point pt;
01214 pt = da->getCurrentOffset();
01215 unsigned levelhere = da->getLevel(da->curr()) - 1;
01216 double hxOct = (double)((double)(1u << (balOctmaxD - levelhere))/(double)(1u << balOctmaxD));
01217 double x = (double)(pt.xint())/((double)(1u << (maxD-1)));
01218 double y = (double)(pt.yint())/((double)(1u << (maxD-1)));
01219 double z = (double)(pt.zint())/((double)(1u << (maxD-1)));
01220
01221 unsigned int indices[8];
01222 da->getNodeIndices(indices);
01223 double coord[8][3] = {
01224 {0.0,0.0,0.0},
01225 {1.0,0.0,0.0},
01226 {0.0,1.0,0.0},
01227 {1.0,1.0,0.0},
01228 {0.0,0.0,1.0},
01229 {1.0,0.0,1.0},
01230 {0.0,1.0,1.0},
01231 {1.0,1.0,1.0}
01232 };
01233 unsigned char hn = da->getHangingNodeIndex(da->curr());
01234
01235 for(int i = 0; i < 8; i++)
01236 {
01237 if (!(hn & (1 << i))){
01238 double xhere, yhere, zhere;
01239 xhere = x + coord[i][0]*hxOct ; yhere = y + coord[i][1]*hxOct; zhere = z + coord[i][2]*hxOct;
01240 double solSum = 0.0;
01241 for(int freqCnt = 1; freqCnt < 10; freqCnt++) {
01242 double facsol = freqCnt;
01243 solSum += cos(facsol*M_PI*xhere)*cos(facsol*M_PI*yhere)*cos(facsol*M_PI*zhere);
01244 }
01245 solArray[indices[i]] = solSum;
01246 }
01247 }
01248 }
01249 }
01250
01251 da->vecRestoreBuffer(expectedSol,solArray,false,false,false,1);
01252
01253 PetscFunctionReturn(0);
01254 }
01255
01256 PetscErrorCode ComputeRHS0(ot::DAMG damg,Vec in) {
01257 PetscFunctionBegin;
01258 VecZeroEntries(in);
01259 PetscFunctionReturn(0);
01260 }
01261
01262 PetscErrorCode ComputeRandomRHS(ot::DAMG damg,Vec in) {
01263 PetscFunctionBegin;
01264 PetscRandom rctx;
01265 PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
01266 PetscRandomSetType(rctx,PETSCRAND48);
01267 PetscInt randomSeed = 12345;
01268 PetscOptionsGetInt(0,"-randomSeed",&randomSeed,0);
01269 int rank;
01270 MPI_Comm_rank(damg->comm,&rank);
01271 if(!rank) {
01272 std::cout<<"Using Random Seed: "<<randomSeed<<std::endl;
01273 }
01274 PetscRandomSetSeed(rctx,randomSeed);
01275 PetscRandomSeed(rctx);
01276 PetscRandomSetFromOptions(rctx);
01277 VecSetRandom(in,rctx);
01278 PetscRandomDestroy(rctx);
01279
01280 PetscReal norm2;
01281 PetscReal normInf;
01282 VecNorm(in, NORM_INFINITY, &normInf);
01283 VecNorm(in, NORM_2, &norm2);
01284 if(!rank) {
01285 std::cout<<"Random Rhs norm-2: "<<norm2<<" normInf: "<<normInf<<std::endl;
01286 }
01287
01288 PetscFunctionReturn(0);
01289 }
01290
01291
01292 PetscErrorCode ComputeRHS3(ot::DAMG damg,Vec in) {
01293 PetscFunctionBegin;
01294
01295 int rank;
01296 MPI_Comm_rank(damg->comm,&rank);
01297 Vec tmp;
01298 VecDuplicate(in,&tmp);
01299 ComputeRandomRHS(damg,tmp);
01300 Mat massMat;
01301 CreateAndComputeMassMatrix(damg->da,&massMat);
01302 MatMult(massMat,tmp,in);
01303 MatDestroy(massMat);
01304 VecDestroy(tmp);
01305
01306 PetscReal norm2;
01307 PetscReal normInf;
01308 VecNorm(in, NORM_INFINITY, &normInf);
01309 VecNorm(in, NORM_2, &norm2);
01310 if(!rank) {
01311 std::cout<<"End of RHS-3: Rhs norm-2: "<<norm2<<" normInf: "<<normInf<<std::endl;
01312 }
01313 PetscFunctionReturn(0);
01314 }
01315
01316
01317 PetscErrorCode ComputeRHS4(ot::DAMG damg, Vec in) {
01318 PetscFunctionBegin;
01319 int rank;
01320 MPI_Comm_rank(damg->comm, &rank);
01321 Vec tmp;
01322 VecDuplicate(in, &tmp);
01323 ComputeRandomRHS(damg, tmp);
01324
01325 MatMult(damg->J, tmp, in);
01326 VecDestroy(tmp);
01327
01328 PetscReal norm2;
01329 PetscReal normInf;
01330 VecNorm(in, NORM_INFINITY, &normInf);
01331 VecNorm(in, NORM_2, &norm2);
01332
01333 if(!rank) {
01334 std::cout<<" End of RHS-4: Rhs norm-2: "<<norm2<<" normInf: "<<normInf<<std::endl;
01335 }
01336
01337 PetscFunctionReturn(0);
01338 }
01339
01340 PetscErrorCode ComputeRHS1(ot::DAMG damg,Vec in) {
01341 PetscFunctionBegin;
01342 ot::DA* da = damg->da;
01343 Vec tmp;
01344 VecDuplicate(in,&tmp);
01345 PetscScalar *inarray;
01346 VecZeroEntries(tmp);
01347 da->vecGetBuffer(tmp,inarray,false,false,false,1);
01348
01349 int rank;
01350 MPI_Comm_rank(damg->comm,&rank);
01351 unsigned int maxD;
01352 unsigned int balOctmaxD;
01353
01354 if(da->iAmActive()) {
01355 maxD = da->getMaxDepth();
01356 balOctmaxD = maxD - 1;
01357 for(da->init<ot::DA_FLAGS::ALL>(); da->curr() < da->end<ot::DA_FLAGS::ALL>(); da->next<ot::DA_FLAGS::ALL>())
01358 {
01359 Point pt;
01360 pt = da->getCurrentOffset();
01361 unsigned levelhere = da->getLevel(da->curr()) - 1;
01362 double hxOct = (double)((double)(1u << (balOctmaxD - levelhere))/(double)(1u << balOctmaxD));
01363 double x = (double)(pt.xint())/((double)(1u << (maxD-1)));
01364 double y = (double)(pt.yint())/((double)(1u << (maxD-1)));
01365 double z = (double)(pt.zint())/((double)(1u << (maxD-1)));
01366
01367 unsigned int indices[8];
01368 da->getNodeIndices(indices);
01369 double coord[8][3] = {
01370 {0.0,0.0,0.0},
01371 {1.0,0.0,0.0},
01372 {0.0,1.0,0.0},
01373 {1.0,1.0,0.0},
01374 {0.0,0.0,1.0},
01375 {1.0,0.0,1.0},
01376 {0.0,1.0,1.0},
01377 {1.0,1.0,1.0}
01378 };
01379 unsigned char hn = da->getHangingNodeIndex(da->curr());
01380
01381 for(int i = 0; i < 8; i++)
01382 {
01383 if (!(hn & (1 << i))){
01384 double xhere, yhere, zhere;
01385 xhere = x + coord[i][0]*hxOct ; yhere = y + coord[i][1]*hxOct; zhere = z + coord[i][2]*hxOct;
01386 double rhsSum = 0.0;
01387 for(int freqCnt = 1; freqCnt < 10; freqCnt++) {
01388 double facsol = freqCnt;
01389 rhsSum += (1.0 + 3*facsol*facsol*M_PI*M_PI)*cos(facsol*M_PI*xhere)*
01390 cos(facsol*M_PI*yhere)*cos(facsol*M_PI*zhere);
01391 }
01392 inarray[indices[i]] = rhsSum;
01393 }
01394 }
01395 }
01396 }
01397
01398 da->vecRestoreBuffer(tmp,inarray,false,false,false,1);
01399
01400 PetscReal norm2;
01401 PetscReal normInf;
01402
01403 VecNorm(tmp, NORM_INFINITY, &normInf);
01404 VecNorm(tmp, NORM_2, &norm2);
01405 if(!rank) {
01406 std::cout<<"tmpRhs norm-2: "<<norm2<<" normInf: "<<normInf<<std::endl;
01407 }
01408
01409 Mat massMat;
01410 CreateAndComputeMassMatrix(da,&massMat);
01411 MatMult(massMat,tmp,in);
01412 MatDestroy(massMat);
01413 VecDestroy(tmp);
01414
01415 VecNorm(in, NORM_INFINITY, &normInf);
01416 VecNorm(in, NORM_2, &norm2);
01417 if(!rank) {
01418 std::cout<<"End of RHS-1: Rhs norm-2: "<<norm2<<" normInf: "<<normInf<<std::endl;
01419 }
01420
01421 PetscFunctionReturn(0);
01422 }
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432 PetscErrorCode ComputeRHS5(ot::DAMG damg,Vec in) {
01433 PetscFunctionBegin;
01434 ot::DA* da = damg->da;
01435 Vec tmp;
01436 VecDuplicate(in, &tmp);
01437 PetscScalar *inarray;
01438 VecZeroEntries(tmp);
01439 da->vecGetBuffer(tmp, inarray, false, false, false, 1);
01440
01441 PetscReal lapFac = 0.0;
01442 PetscTruth optFound;
01443 PetscOptionsGetReal("lap","-MatPropFac",&lapFac,&optFound);
01444 int rank;
01445 MPI_Comm_rank(damg->comm,&rank);
01446 unsigned int maxD;
01447 unsigned int balOctmaxD;
01448
01449 if(da->iAmActive()) {
01450 maxD = da->getMaxDepth();
01451 balOctmaxD = maxD - 1;
01452 for(da->init<ot::DA_FLAGS::ALL>(); da->curr() < da->end<ot::DA_FLAGS::ALL>(); da->next<ot::DA_FLAGS::ALL>())
01453 {
01454 Point pt;
01455 pt = da->getCurrentOffset();
01456 unsigned levelhere = da->getLevel(da->curr()) - 1;
01457 double hxOct = (double)((double)(1u << (balOctmaxD - levelhere))/(double)(1u << balOctmaxD));
01458 double x = (double)(pt.xint())/((double)(1u << (maxD-1)));
01459 double y = (double)(pt.yint())/((double)(1u << (maxD-1)));
01460 double z = (double)(pt.zint())/((double)(1u << (maxD-1)));
01461
01462 unsigned int indices[8];
01463 da->getNodeIndices(indices);
01464 double coord[8][3] = {
01465 {0.0,0.0,0.0},
01466 {1.0,0.0,0.0},
01467 {0.0,1.0,0.0},
01468 {1.0,1.0,0.0},
01469 {0.0,0.0,1.0},
01470 {1.0,0.0,1.0},
01471 {0.0,1.0,1.0},
01472 {1.0,1.0,1.0}
01473 };
01474 unsigned char hn = da->getHangingNodeIndex(da->curr());
01475
01476 for(int i = 0; i < 8; i++)
01477 {
01478 if (!(hn & (1 << i))){
01479 double xhere, yhere, zhere;
01480 xhere = x + (coord[i][0]*hxOct);
01481 yhere = y + (coord[i][1]*hxOct);
01482 zhere = z + (coord[i][2]*hxOct);
01483 double solVal = cos(2.0*M_PI*xhere)*cos(2.0*M_PI*yhere)*cos(2.0*M_PI*zhere);
01484 double epVal = (1.0 + (lapFac*(
01485 (cos(2.0*M_PI*xhere)*cos(2.0*M_PI*xhere)) +
01486 (cos(2.0*M_PI*yhere)*cos(2.0*M_PI*yhere)) +
01487 (cos(2.0*M_PI*zhere)*cos(2.0*M_PI*zhere))
01488 )));
01489 double rhsVal = (solVal + (12.0*(M_PI*M_PI)*solVal*epVal)
01490 - (8.0*(M_PI*M_PI)*lapFac*solVal*(
01491 (sin(2.0*M_PI*xhere)*sin(2.0*M_PI*xhere)) +
01492 (sin(2.0*M_PI*yhere)*sin(2.0*M_PI*yhere)) +
01493 (sin(2.0*M_PI*zhere)*sin(2.0*M_PI*zhere))
01494 )));
01495 inarray[indices[i]] = rhsVal;
01496 }
01497 }
01498 }
01499 }
01500
01501 da->vecRestoreBuffer(tmp, inarray, false, false, false, 1);
01502
01503 PetscReal norm2;
01504 PetscReal normInf;
01505
01506 VecNorm(tmp, NORM_INFINITY, &normInf);
01507 VecNorm(tmp, NORM_2, &norm2);
01508 if(!rank) {
01509 std::cout<<"tmpRhs-5 norm-2: "<<norm2<<" normInf: "<<normInf<<std::endl;
01510 }
01511
01512 Mat massMat;
01513 CreateAndComputeMassMatrix(da,&massMat);
01514 MatMult(massMat,tmp,in);
01515 MatDestroy(massMat);
01516 VecDestroy(tmp);
01517
01518 VecNorm(in, NORM_INFINITY, &normInf);
01519 VecNorm(in, NORM_2, &norm2);
01520 if(!rank) {
01521 std::cout<<"End of RHS-5: Rhs norm-2: "<<norm2<<" normInf: "<<normInf<<std::endl;
01522 }
01523
01524 PetscFunctionReturn(0);
01525 }
01526
01530 PetscErrorCode ComputeRHS6(ot::DAMG damg,Vec in) {
01531 PetscFunctionBegin;
01532 ot::DA* da = damg->da;
01533 Vec tmp;
01534 VecDuplicate(in, &tmp);
01535 SetSolution5(da,tmp);
01536 MatMult(damg->J, tmp, in);
01537 VecDestroy(tmp);
01538 PetscFunctionReturn(0);
01539 }
01540
01552 PetscErrorCode ComputeRHS7(ot::DAMG damg,Vec in) {
01553 PetscFunctionBegin;
01554 ot::DA* da = damg->da;
01555 PetscScalar *inarray;
01556 VecZeroEntries(in);
01557 da->vecGetBuffer(in,inarray,false,false,false,1);
01558
01559 PetscReal lapFac = 0.0;
01560 PetscTruth optFound;
01561 PetscOptionsGetReal("lap","-MatPropFac",&lapFac,&optFound);
01562
01563 unsigned int maxD;
01564 unsigned int balOctmaxD;
01565
01566 double wts[3] = { (8.0/9.0), (5.0/9.0), (5.0/9.0) };
01567 double gPts[3] = { 0.0, sqrt((3.0/5.0)), -sqrt((3.0/5.0)) };
01568
01569 if(da->iAmActive()) {
01570 maxD = da->getMaxDepth();
01571 balOctmaxD = maxD - 1;
01572 for(da->init<ot::DA_FLAGS::ALL>();
01573 da->curr() < da->end<ot::DA_FLAGS::ALL>();
01574 da->next<ot::DA_FLAGS::ALL>())
01575 {
01576 Point pt;
01577 pt = da->getCurrentOffset();
01578 unsigned int idx = da->curr();
01579 unsigned levelhere = (da->getLevel(idx) - 1);
01580 double hxOct = (double)((double)(1u << (balOctmaxD - levelhere))/(double)(1u << balOctmaxD));
01581 double x = (double)(pt.xint())/((double)(1u << (maxD-1)));
01582 double y = (double)(pt.yint())/((double)(1u << (maxD-1)));
01583 double z = (double)(pt.zint())/((double)(1u << (maxD-1)));
01584 double fac = ((hxOct*hxOct*hxOct)/8.0);
01585 unsigned int indices[8];
01586 da->getNodeIndices(indices);
01587 unsigned char childNum = da->getChildNumber();
01588 unsigned char hnMask = da->getHangingNodeIndex(idx);
01589 unsigned char elemType = 0;
01590 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
01591 for(unsigned int j = 0; j < 8; j++) {
01592 double integral = 0.0;
01593
01594 for(int m = 0; m < 3; m++) {
01595 for(int n = 0; n < 3; n++) {
01596 for(int p = 0; p < 3; p++) {
01597 double xPt = ( (hxOct*(1.0 +gPts[m])*0.5) + x );
01598 double yPt = ( (hxOct*(1.0 + gPts[n])*0.5) + y );
01599 double zPt = ( (hxOct*(1.0 + gPts[p])*0.5) + z );
01600 double solVal = cos(2.0*M_PI*xPt)*cos(2.0*M_PI*yPt)*cos(2.0*M_PI*zPt);
01601 double epVal = (1.0 + (lapFac*(
01602 (cos(2.0*M_PI*xPt)*cos(2.0*M_PI*xPt)) +
01603 (cos(2.0*M_PI*yPt)*cos(2.0*M_PI*yPt)) +
01604 (cos(2.0*M_PI*zPt)*cos(2.0*M_PI*zPt))
01605 )));
01606 double rhsVal = (solVal + (12.0*(M_PI*M_PI)*solVal*epVal)
01607 - (8.0*(M_PI*M_PI)*lapFac*solVal*(
01608 (sin(2.0*M_PI*xPt)*sin(2.0*M_PI*xPt)) +
01609 (sin(2.0*M_PI*yPt)*sin(2.0*M_PI*yPt)) +
01610 (sin(2.0*M_PI*zPt)*sin(2.0*M_PI*zPt))
01611 )));
01612 integral += (wts[m]*wts[n]*wts[p]*rhsVal*
01613 ShapeFnStencil[childNum][elemType][j][m][n][p]);
01614 }
01615 }
01616 }
01617 inarray[indices[j]] += (fac*integral);
01618 }
01619 }
01620 }
01621
01622 da->vecRestoreBuffer(in,inarray,false,false,false,1);
01623
01624 PetscFunctionReturn(0);
01625 }
01626
01638 PetscErrorCode ComputeRHS8(ot::DAMG damg,Vec in) {
01639 PetscFunctionBegin;
01640 ot::DA* da = damg->da;
01641 PetscScalar *inarray;
01642 VecZeroEntries(in);
01643 da->vecGetBuffer(in,inarray,false,false,false,1);
01644
01645 PetscReal lapFac = 0.0;
01646 PetscTruth optFound;
01647 PetscOptionsGetReal("lap","-MatPropFac",&lapFac,&optFound);
01648
01649 PetscInt numGaussPts = 0;
01650 PetscOptionsGetInt(0,"-numGaussPts",&numGaussPts,0);
01651
01652 assert(numGaussPts <= 7);
01653 assert(numGaussPts >= 2);
01654
01655 unsigned int maxD;
01656 unsigned int balOctmaxD;
01657
01658 std::vector<std::vector<double> > wts(6);
01659 std::vector<std::vector<double> > gPts(6);
01660
01661 for(int k = 0; k < 6; k++) {
01662 wts[k].resize(k+2);
01663 gPts[k].resize(k+2);
01664 }
01665
01666
01667 wts[0][0] = 1.0; wts[0][1] = 1.0;
01668 gPts[0][0] = sqrt(1.0/3.0); gPts[0][1] = -sqrt(1.0/3.0);
01669
01670
01671 wts[1][0] = 0.88888889; wts[1][1] = 0.555555556; wts[1][2] = 0.555555556;
01672 gPts[1][0] = 0.0; gPts[1][1] = 0.77459667; gPts[1][2] = -0.77459667;
01673
01674
01675 wts[2][0] = 0.65214515; wts[2][1] = 0.65214515;
01676 wts[2][2] = 0.34785485; wts[2][3] = 0.34785485;
01677 gPts[2][0] = 0.33998104; gPts[2][1] = -0.33998104;
01678 gPts[2][2] = 0.86113631; gPts[2][3] = -0.86113631;
01679
01680
01681 wts[3][0] = 0.568888889; wts[3][1] = 0.47862867; wts[3][2] = 0.47862867;
01682 wts[3][3] = 0.23692689; wts[3][4] = 0.23692689;
01683 gPts[3][0] = 0.0; gPts[3][1] = 0.53846931; gPts[3][2] = -0.53846931;
01684 gPts[3][3] = 0.90617985; gPts[3][4] = -0.90617985;
01685
01686
01687 wts[4][0] = 0.46791393; wts[4][1] = 0.46791393; wts[4][2] = 0.36076157;
01688 wts[4][3] = 0.36076157; wts[4][4] = 0.17132449; wts[4][5] = 0.17132449;
01689 gPts[4][0] = 0.23861918; gPts[4][1] = -0.23861918; gPts[4][2] = 0.66120939;
01690 gPts[4][3] = -0.66120939; gPts[4][4] = 0.93246951; gPts[4][5] = -0.93246951;
01691
01692
01693 wts[5][0] = 0.41795918; wts[5][1] = 0.38183005; wts[5][2] = 0.38183005;
01694 wts[5][3] = 0.27970539; wts[5][4] = 0.27970539;
01695 wts[5][5] = 0.12948497; wts[5][6] = 0.12948497;
01696 gPts[5][0] = 0.0; gPts[5][1] = 0.40584515; gPts[5][2] = -0.40584515;
01697 gPts[5][3] = 0.74153119; gPts[5][4] = -0.74153119;
01698 gPts[5][5] = 0.94910791; gPts[5][6] = -0.94910791;
01699
01700 if(da->iAmActive()) {
01701 maxD = da->getMaxDepth();
01702 balOctmaxD = maxD - 1;
01703 for(da->init<ot::DA_FLAGS::ALL>();
01704 da->curr() < da->end<ot::DA_FLAGS::ALL>();
01705 da->next<ot::DA_FLAGS::ALL>())
01706 {
01707 Point pt;
01708 pt = da->getCurrentOffset();
01709 unsigned int idx = da->curr();
01710 unsigned levelhere = (da->getLevel(idx) - 1);
01711 double hxOct = (double)((double)(1u << (balOctmaxD - levelhere))/(double)(1u << balOctmaxD));
01712 double x = (double)(pt.xint())/((double)(1u << (maxD-1)));
01713 double y = (double)(pt.yint())/((double)(1u << (maxD-1)));
01714 double z = (double)(pt.zint())/((double)(1u << (maxD-1)));
01715 double fac = ((hxOct*hxOct*hxOct)/8.0);
01716 unsigned int indices[8];
01717 da->getNodeIndices(indices);
01718 unsigned char childNum = da->getChildNumber();
01719 unsigned char hnMask = da->getHangingNodeIndex(idx);
01720 unsigned char elemType = 0;
01721 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
01722 for(unsigned int j = 0; j < 8; j++) {
01723 double integral = 0.0;
01724
01725 for(int m = 0; m < numGaussPts; m++) {
01726 for(int n = 0; n < numGaussPts; n++) {
01727 for(int p = 0; p < numGaussPts; p++) {
01728 double xPt = ( (hxOct*(1.0 +gPts[numGaussPts-2][m])*0.5) + x );
01729 double yPt = ( (hxOct*(1.0 + gPts[numGaussPts-2][n])*0.5) + y );
01730 double zPt = ( (hxOct*(1.0 + gPts[numGaussPts-2][p])*0.5) + z );
01731 double solVal = cos(2.0*M_PI*xPt)*cos(2.0*M_PI*yPt)*cos(2.0*M_PI*zPt);
01732 double epVal = (1.0 + (lapFac*(
01733 (cos(2.0*M_PI*xPt)*cos(2.0*M_PI*xPt)) +
01734 (cos(2.0*M_PI*yPt)*cos(2.0*M_PI*yPt)) +
01735 (cos(2.0*M_PI*zPt)*cos(2.0*M_PI*zPt))
01736 )));
01737 double rhsVal = (solVal + (12.0*(M_PI*M_PI)*solVal*epVal)
01738 - (8.0*(M_PI*M_PI)*lapFac*solVal*(
01739 (sin(2.0*M_PI*xPt)*sin(2.0*M_PI*xPt)) +
01740 (sin(2.0*M_PI*yPt)*sin(2.0*M_PI*yPt)) +
01741 (sin(2.0*M_PI*zPt)*sin(2.0*M_PI*zPt))
01742 )));
01743 double ShFnVal = ( ot::ShapeFnCoeffs[childNum][elemType][j][0] +
01744 (ot::ShapeFnCoeffs[childNum][elemType][j][1]*gPts[numGaussPts-2][m]) +
01745 (ot::ShapeFnCoeffs[childNum][elemType][j][2]*gPts[numGaussPts-2][n]) +
01746 (ot::ShapeFnCoeffs[childNum][elemType][j][3]*gPts[numGaussPts-2][p]) +
01747 (ot::ShapeFnCoeffs[childNum][elemType][j][4]*gPts[numGaussPts-2][m]*
01748 gPts[numGaussPts-2][n]) +
01749 (ot::ShapeFnCoeffs[childNum][elemType][j][5]*gPts[numGaussPts-2][n]*
01750 gPts[numGaussPts-2][p]) +
01751 (ot::ShapeFnCoeffs[childNum][elemType][j][6]*gPts[numGaussPts-2][p]*
01752 gPts[numGaussPts-2][m]) +
01753 (ot::ShapeFnCoeffs[childNum][elemType][j][7]*gPts[numGaussPts-2][m]*
01754 gPts[numGaussPts-2][n]*gPts[numGaussPts-2][p]) );
01755 integral += (wts[numGaussPts-2][m]*wts[numGaussPts-2][n]
01756 *wts[numGaussPts-2][p]*rhsVal*ShFnVal);
01757 }
01758 }
01759 }
01760 inarray[indices[j]] += (fac*integral);
01761 }
01762 }
01763 }
01764
01765 da->vecRestoreBuffer(in,inarray,false,false,false,1);
01766
01767 PetscFunctionReturn(0);
01768 }
01769
01773 PetscErrorCode SetSolution5(ot::DA* da , Vec tmp) {
01774 PetscFunctionBegin;
01775 PetscScalar *inarray;
01776 VecZeroEntries(tmp);
01777 da->vecGetBuffer(tmp, inarray, false, false, false, 1);
01778
01779 unsigned int maxD;
01780 unsigned int balOctmaxD;
01781
01782 if(da->iAmActive()) {
01783 maxD = da->getMaxDepth();
01784 balOctmaxD = maxD - 1;
01785 for(da->init<ot::DA_FLAGS::ALL>(); da->curr() < da->end<ot::DA_FLAGS::ALL>(); da->next<ot::DA_FLAGS::ALL>())
01786 {
01787 Point pt;
01788 pt = da->getCurrentOffset();
01789 unsigned levelhere = da->getLevel(da->curr()) - 1;
01790 double hxOct = (double)((double)(1u << (balOctmaxD - levelhere))/(double)(1u << balOctmaxD));
01791 double x = (double)(pt.xint())/((double)(1u << (maxD-1)));
01792 double y = (double)(pt.yint())/((double)(1u << (maxD-1)));
01793 double z = (double)(pt.zint())/((double)(1u << (maxD-1)));
01794
01795 unsigned int indices[8];
01796 da->getNodeIndices(indices);
01797 double coord[8][3] = {
01798 {0.0,0.0,0.0},
01799 {1.0,0.0,0.0},
01800 {0.0,1.0,0.0},
01801 {1.0,1.0,0.0},
01802 {0.0,0.0,1.0},
01803 {1.0,0.0,1.0},
01804 {0.0,1.0,1.0},
01805 {1.0,1.0,1.0}
01806 };
01807 unsigned char hn = da->getHangingNodeIndex(da->curr());
01808
01809 for(int i = 0; i < 8; i++)
01810 {
01811 if (!(hn & (1 << i))){
01812 double xhere, yhere, zhere;
01813 xhere = x + (coord[i][0]*hxOct);
01814 yhere = y + (coord[i][1]*hxOct);
01815 zhere = z + (coord[i][2]*hxOct);
01816 double solVal = cos(2.0*M_PI*xhere)*cos(2.0*M_PI*yhere)*cos(2.0*M_PI*zhere);
01817 inarray[indices[i]] = solVal;
01818 }
01819 }
01820 }
01821 }
01822
01823 da->vecRestoreBuffer(tmp, inarray, false, false, false, 1);
01824
01825 PetscFunctionReturn(0);
01826 }
01827
01828
01829
01830
01831
01832 double ComputeError5(ot::DA* da, Vec in)
01833 {
01834
01835 if(da->iAmActive()) {
01836 double wts[3] = { (8.0/9.0), (5.0/9.0), (5.0/9.0) };
01837 double gPts[3] = { 0.0, sqrt((3.0/5.0)), -sqrt((3.0/5.0)) };
01838 unsigned int maxD = da->getMaxDepth();
01839 unsigned int balOctmaxD = (maxD - 1);
01840 double error = 0.0;
01841 PetscScalar *inarray;
01842 da->vecGetBuffer(in, inarray, false, false, true, 1);
01843 da->ReadFromGhostsBegin<PetscScalar>(inarray, 1);
01844 da->ReadFromGhostsEnd<PetscScalar>(inarray);
01845 for(da->init<ot::DA_FLAGS::WRITABLE>();
01846 da->curr() < da->end<ot::DA_FLAGS::WRITABLE>();
01847 da->next<ot::DA_FLAGS::WRITABLE>())
01848 {
01849 Point pt;
01850 pt = da->getCurrentOffset();
01851 unsigned int idx = da->curr();
01852 unsigned int levelhere = (da->getLevel(idx) - 1);
01853 double hxOct = (double)((double)(1u << (balOctmaxD - levelhere))/(double)(1u << balOctmaxD));
01854 double x = (double)(pt.xint())/((double)(1u << (maxD-1)));
01855 double y = (double)(pt.yint())/((double)(1u << (maxD-1)));
01856 double z = (double)(pt.zint())/((double)(1u << (maxD-1)));
01857 double fac = ((hxOct*hxOct*hxOct)/8.0);
01858 unsigned int indices[8];
01859 da->getNodeIndices(indices);
01860 unsigned char childNum = da->getChildNumber();
01861 unsigned char hnMask = da->getHangingNodeIndex(idx);
01862 unsigned char elemType = 0;
01863 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
01864 double integral = 0.0;
01865
01866 for(int m = 0; m < 3; m++) {
01867 for(int n = 0; n < 3; n++) {
01868 for(int p = 0; p < 3; p++) {
01869 double xPt = ( (hxOct*(1.0 +gPts[m])*0.5) + x );
01870 double yPt = ( (hxOct*(1.0 + gPts[n])*0.5) + y );
01871 double zPt = ( (hxOct*(1.0 + gPts[p])*0.5) + z );
01872 double fnVal = cos(2.0*M_PI*xPt)*cos(2.0*M_PI*yPt)*cos(2.0*M_PI*zPt);
01873 double uhval= 0.0;
01874 for(unsigned int j = 0; j < 8; j++) {
01875 uhval += (inarray[indices[j]]*ShapeFnStencil[childNum][elemType][j][m][n][p]);
01876 }
01877 integral += (wts[m]*wts[n]*wts[p]*(fnVal - uhval)*(fnVal - uhval));
01878 }
01879 }
01880 }
01881 error += integral*fac;
01882 }
01883 da->vecRestoreBuffer(in, inarray, false, false, true, 1);
01884 double totalError = 0.0;
01885 par::Mpi_Reduce<double>(&error, &totalError, 1, MPI_SUM, 0, da->getCommActive());
01886 return(sqrt(totalError));
01887 } else {
01888 return(0.0);
01889 }
01890 }
01891
01892 double TestError5(ot::DA* da) {
01893 Vec tmp;
01894 da->createVector(tmp, false, false, 1);
01895 SetSolution5(da, tmp);
01896 double error = ComputeError5(da, tmp);
01897 VecDestroy(tmp);
01898 return error;
01899 }
01900
01901
01902
01903
01904 PetscErrorCode ComputeRHS9(ot::DAMG damg, Vec in) {
01905 PetscFunctionBegin;
01906
01907 ot::DA* da = damg->da;
01908
01909 MPI_Comm commAll = da->getComm();
01910
01911 int rankAll = da->getRankAll();
01912 int npesAll = da->getNpesAll();
01913
01914 unsigned int dim = da->getDimension();
01915 unsigned int maxDepth = da->getMaxDepth();
01916 int npesActive = da->getNpesActive();
01917
01918 if( npesActive < npesAll ) {
01919 unsigned int tmpArr[3];
01920 tmpArr[0] = dim;
01921 tmpArr[1] = maxDepth;
01922 tmpArr[2] = npesActive;
01923
01924 par::Mpi_Bcast<unsigned int>(tmpArr, 3, 0, commAll);
01925
01926 dim = tmpArr[0];
01927 maxDepth = tmpArr[1];
01928 npesActive = static_cast<int>(tmpArr[2]);
01929 }
01930
01931 unsigned int balOctMaxD = (maxDepth - 1);
01932
01933 char fname[250];
01934 sprintf(fname,"deltaSources_%d_%d.txt", rankAll, npesAll);
01935
01936 FILE* inFile = fopen(fname,"r");
01937 if(!inFile) {
01938 std::cout<<"Unable to open "<<fname<<" for reading."<<std::endl;
01939 }
01940
01941 unsigned int numLocalDelta;
01942 fscanf(inFile,"%u",&numLocalDelta);
01943
01944 std::vector<ot::NodeAndValues<double, 4> > tnAndVal(numLocalDelta);
01945
01946 for(unsigned int i = 0; i < numLocalDelta; i++) {
01947 double x, y, z, v;
01948 fscanf(inFile,"%lf",&x);
01949 fscanf(inFile,"%lf",&y);
01950 fscanf(inFile,"%lf",&z);
01951 fscanf(inFile,"%lf",&v);
01952
01953 assert(x >= 0.0);
01954 assert(y >= 0.0);
01955 assert(z >= 0.0);
01956 assert(x <= 1.0);
01957 assert(y <= 1.0);
01958 assert(z <= 1.0);
01959
01960 unsigned int xint = static_cast<unsigned int>(x*static_cast<double>(1u << balOctMaxD));
01961 unsigned int yint = static_cast<unsigned int>(y*static_cast<double>(1u << balOctMaxD));
01962 unsigned int zint = static_cast<unsigned int>(z*static_cast<double>(1u << balOctMaxD));
01963
01964 tnAndVal[i].node = ot::TreeNode(xint, yint, zint, maxDepth, dim, maxDepth);
01965
01966 tnAndVal[i].values[0] = x;
01967 tnAndVal[i].values[1] = y;
01968 tnAndVal[i].values[2] = z;
01969 tnAndVal[i].values[3] = v;
01970 }
01971
01972 fclose(inFile);
01973
01974 std::vector<ot::TreeNode> minBlocks = da->getMinAllBlocks();
01975
01976 if(npesActive < npesAll) {
01977 bool* activeStates = new bool[npesAll];
01978
01979 activeStates[0] = true;
01980 for(int i = 1; i < npesActive; i++) {
01981 activeStates[i] = false;
01982 }
01983 for(int i = npesActive; i < npesAll; i++) {
01984 activeStates[i] = true;
01985 }
01986
01987 MPI_Comm tmpComm;
01988
01989 par::splitComm2way(activeStates, &tmpComm, commAll);
01990
01991 if(rankAll == 0) {
01992 par::Mpi_Bcast<ot::TreeNode>(&(*(minBlocks.begin())) , npesActive, 0, tmpComm);
01993 }
01994 if(rankAll >= npesActive) {
01995 minBlocks.resize(npesActive);
01996 par::Mpi_Bcast<ot::TreeNode>(&(*(minBlocks.begin())) , npesActive, 0, tmpComm);
01997 }
01998
01999 delete [] activeStates;
02000 }
02001
02002 unsigned int* part = new unsigned int[tnAndVal.size()];
02003
02004 int *sendCnt = new int[npesAll];
02005 for(int i = 0; i < npesAll; i++) {
02006 sendCnt[i] = 0;
02007 }
02008
02009 for(int i = 0; i < tnAndVal.size(); i++) {
02010 seq::maxLowerBound<ot::TreeNode>(minBlocks, tnAndVal[i].node, part[i], NULL, NULL);
02011 sendCnt[part[i]]++;
02012 }
02013
02014 int *recvCnt = new int[npesAll];
02015
02016 par::Mpi_Alltoall<int>( sendCnt, recvCnt, 1, commAll);
02017
02018 int *sendOffsets = new int[npesAll];
02019 int *recvOffsets = new int[npesAll];
02020
02021 sendOffsets[0] = 0;
02022 recvOffsets[0] = 0;
02023 for(int i = 1; i < npesAll; i++) {
02024 sendOffsets[i] = sendOffsets[i - 1] + sendCnt[i - 1];
02025 recvOffsets[i] = recvOffsets[i - 1] + recvCnt[i - 1];
02026 }
02027
02028
02029
02030 std::vector<ot::NodeAndValues<double, 4> > sendList(sendOffsets[npesAll - 1] + sendCnt[npesAll - 1]);
02031 std::vector<ot::NodeAndValues<double, 4> > recvList(recvOffsets[npesAll - 1] + recvCnt[npesAll - 1]);
02032
02033 int* tmpSendCnt = new int[npesAll];
02034 for(int i = 0; i < npesAll; i++) {
02035 tmpSendCnt[i] = 0;
02036 }
02037
02038 for(int i = 0; i < tnAndVal.size(); i++) {
02039 sendList[sendOffsets[part[i]] + tmpSendCnt[part[i]]] = tnAndVal[i];
02040 tmpSendCnt[part[i]]++;
02041 }
02042 delete [] tmpSendCnt;
02043 tnAndVal.clear();
02044
02045 par::Mpi_Alltoallv_sparse<ot::NodeAndValues<double, 4> >( &(*(sendList.begin())), sendCnt,
02046 sendOffsets, &(*(recvList.begin())), recvCnt, recvOffsets, commAll);
02047
02048 sendList.clear();
02049
02050 delete [] part;
02051 delete [] sendCnt;
02052 delete [] recvCnt;
02053 delete [] sendOffsets;
02054 delete [] recvOffsets;
02055
02056 sort(recvList.begin(), recvList.end());
02057
02058
02059
02060 VecZeroEntries(in);
02061
02062 if(!(da->iAmActive())) {
02063 assert(recvList.empty());
02064 } else {
02065 PetscScalar *inarray;
02066 da->vecGetBuffer(in, inarray, false, false, false, 1);
02067
02068 unsigned int ptsCtr = 0;
02069
02070 for(da->init<ot::DA_FLAGS::WRITABLE>();
02071 da->curr() < da->end<ot::DA_FLAGS::WRITABLE>();
02072 da->next<ot::DA_FLAGS::WRITABLE>())
02073 {
02074 Point pt;
02075 pt = da->getCurrentOffset();
02076 unsigned int idx = da->curr();
02077 unsigned levelhere = da->getLevel(idx);
02078 unsigned int xint = pt.xint();
02079 unsigned int yint = pt.yint();
02080 unsigned int zint = pt.zint();
02081 ot::TreeNode currOct(xint, yint, zint, levelhere, dim, maxDepth);
02082 while( (ptsCtr < recvList.size()) &&
02083 (recvList[ptsCtr].node < currOct) ) {
02084 ptsCtr++;
02085 }
02086 double hxOct = (double)((double)(1u << (maxDepth - levelhere))/(double)(1u << balOctMaxD));
02087 double x = static_cast<double>(xint)/((double)(1u << balOctMaxD));
02088 double y = static_cast<double>(yint)/((double)(1u << balOctMaxD));
02089 double z = static_cast<double>(zint)/((double)(1u << balOctMaxD));
02090 unsigned int indices[8];
02091 da->getNodeIndices(indices);
02092 unsigned char childNum = da->getChildNumber();
02093 unsigned char hnMask = da->getHangingNodeIndex(idx);
02094 unsigned char elemType = 0;
02095 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
02096 while( (ptsCtr < recvList.size()) &&
02097 ( currOct.isAncestor(recvList[ptsCtr].node) ||
02098 ( currOct == (recvList[ptsCtr].node) ) ) ) {
02099 for(unsigned int j = 0; j < 8; j++) {
02100 double xLoc = (((2.0/hxOct)*(recvList[ptsCtr].values[0] - x)) - 1.0);
02101 double yLoc = (((2.0/hxOct)*(recvList[ptsCtr].values[1] - y)) - 1.0);
02102 double zLoc = (((2.0/hxOct)*(recvList[ptsCtr].values[2] - z)) - 1.0);
02103 double ShFnVal = ( ot::ShapeFnCoeffs[childNum][elemType][j][0] +
02104 (ot::ShapeFnCoeffs[childNum][elemType][j][1]*xLoc) +
02105 (ot::ShapeFnCoeffs[childNum][elemType][j][2]*yLoc) +
02106 (ot::ShapeFnCoeffs[childNum][elemType][j][3]*zLoc) +
02107 (ot::ShapeFnCoeffs[childNum][elemType][j][4]*xLoc*yLoc) +
02108 (ot::ShapeFnCoeffs[childNum][elemType][j][5]*yLoc*zLoc) +
02109 (ot::ShapeFnCoeffs[childNum][elemType][j][6]*zLoc*xLoc) +
02110 (ot::ShapeFnCoeffs[childNum][elemType][j][7]*xLoc*yLoc*zLoc) );
02111 inarray[indices[j]] += ((recvList[ptsCtr].values[3])*ShFnVal);
02112 }
02113 ptsCtr++;
02114 }
02115 }
02116
02117 da->WriteToGhostsBegin<PetscScalar>(inarray, 1);
02118 da->WriteToGhostsEnd<PetscScalar>(inarray, 1);
02119
02120 da->vecRestoreBuffer(in, inarray, false, false, false, 1);
02121
02122 }
02123
02124 PetscFunctionReturn(0);
02125
02126 }
02127
02128