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

omgRhs.C

Go to the documentation of this file.
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 //Force is a sum of delta functions.
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   }//end for i
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   //We can simply communicate the doubles instead, but then we will need to
00501   //recreate octants from doubles to do further processing.
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   //Now the points are sorted and aligned with the DA partition
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             }//end if bdy
00586           }//end for j
00587           ptsCtr++;
00588         }
00589     }//end for WRITABLE
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   }//end if active
00597 
00598   PetscFunctionReturn(0);
00599 
00600 }//end fn.
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           }//end if bdy
00656         }//end if hanging
00657       }//end for j
00658     }//end for ALL
00659   }//end if active
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           }//end if bdy
00760         }//end if hanging
00761       }//end for j
00762     }//end for ALL
00763   }//end if active
00764 
00765   da->vecRestoreBuffer(in,inarray,false,false,false,1);
00766 
00767   PetscFunctionReturn(0);
00768 }
00769 
00770 //Force is a sum of delta functions.
00771 //The location of the delta
00772 //functions is given in the file "fbmInp<rank>_<npes>.pts"
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   }//end for i
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   //We can simply communicate the doubles instead, but then we will need to
00889   //recreate octants from doubles to do further processing.
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   //Now the points are sorted and aligned with the DA partition
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             }//end if bdy
00974           }//end for j
00975           ptsCtr++;
00976         }
00977     }//end for i
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   }//end if active
00985 
00986   PetscFunctionReturn(0);
00987 
00988 }//end fn.
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   //2-pt rule
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   //3-pt rule
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   //4-pt rule
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   //5-pt rule
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   //6-pt rule
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   //7-pt rule
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             //Quadrature Rule
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           }//end if bdy
01113         }//end for j
01114     }//end for i
01115   }//end if active
01116 
01117   da->vecRestoreBuffer(in,inarray,false,false,false,1);
01118 
01119   PetscFunctionReturn(0);
01120 }
01121 
01122 //Rhs = sum of 3 gaussian functions centered at different points.
01123 //Rhs is assembled using 3-pt gauss-quadrature integration per dimension. This is exact to
01124 //polynomials of degree 5 or less
01125 //w1 =8/9, x1 =0, w2=w3 =5/9, x2 = +sqrt(3/5), x3 = -sqrt(3/5)
01126 //int_a_to_b(f) = ((b-a)/2)*sum(wi*f((((b-a)/2)*xi) + ((b+a)/2)))
01127 PetscErrorCode ComputeRHS2(ot::DAMG damg,Vec in) {
01128   PetscFunctionBegin;            
01129   ot::DA* da = damg->da;
01130   PetscScalar *inarray;
01131 
01132   //In PETSc's debug mode they use an Allreduce where all processors (active
01133   //and inactive) participate. Hence, VecZeroEntries must be called by active
01134   //and inactive processors.
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           //Quadrature Rule
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         }//end for j
01185     }//end for i
01186   }//end if active
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 //Consistent Random RHS
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 //Random Solution Consistent RHS
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    RHS corresponding to the homogeneous neumann, variable coefficient, scalar, poisson problem
01428    with solution = cos(2*pi*x)cos(2*pi*y)cos(2*pi*z) and
01429    epsilon = 1 + 10^6[cos^2(2*pi*x) + cos^2(2*pi*y) + cos^2(2*pi*z)] and
01430    alpha  = 1
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           //Quadrature Rule
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         }//end for j
01619     }//end for i
01620   }//end if active
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   //2-pt rule
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   //3-pt rule
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   //4-pt rule
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   //5-pt rule
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   //6-pt rule
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   //7-pt rule
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           //Quadrature Rule
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         }//end for j
01762     }//end for i
01763   }//end if active
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    Measure L-2 error for the variable coefficient scalar
01830    elliptic homogeneous neumann problem  with RHS given by RHS5
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       //Quadrature Rule
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           }// end for p
01879         } // end for n
01880       }//end for m
01881       error += integral*fac;
01882     }//end for i
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   }//end if-else active
01890 }//end fn.
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 //Force is a sum of delta functions.
01902 //The location and the magnitude of the delta
01903 //functions is given in the file "deltaSources_<rank>_<npes>.txt"
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);//Can be equal to 1.0 for domain boundaries
01957     assert(y <= 1.0);//Can be equal to 1.0 for domain boundaries
01958     assert(z <= 1.0);//Can be equal to 1.0 for domain boundaries
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   }//end for i
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   //We can simply communicate the doubles instead, but then we will need to
02029   //recreate octants from doubles to do further processing.
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   //Now the points are sorted and aligned with the DA partition
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           }//end for j
02113           ptsCtr++;
02114         }
02115     }//end for i
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   }//end if active
02123 
02124   PetscFunctionReturn(0);
02125 
02126 }//end fn.
02127 
02128 

Generated on Tue Mar 24 16:13:58 2009 for DENDRO by  doxygen 1.3.9.1