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

vecMass.C

Go to the documentation of this file.
00001 
00007 #include "petsc.h"
00008 #include "omg.h"
00009 #include "oda.h"
00010 #include "vecMass.h"
00011 #include "elasticityJac.h"
00012 
00013 #ifdef PETSC_USE_LOG
00014 extern int vecMassDiagEvent;
00015 extern int vecMassMultEvent;
00016 extern int vecMassFinestDiagEvent;
00017 extern int vecMassFinestMultEvent;
00018 #endif
00019 
00020 extern double**** MassType2Stencil; 
00021 
00022 PetscErrorCode CreateConstVecMass(ot::DAMG damg, Mat *jac) {
00023   PetscFunctionBegin;
00024   PetscInt buildFullCoarseMat;
00025   int totalLevels;
00026   PetscTruth flg;
00027   PetscOptionsGetInt(PETSC_NULL,"-buildFullCoarseMat",&buildFullCoarseMat,&flg);
00028   totalLevels = damg->nlevels;
00029   ot::DA* da = damg->da;
00030   if((totalLevels == damg->nlevels) && buildFullCoarseMat) {
00031     //This is the coarsest.
00032     int myRank;
00033     MPI_Comm_rank(MPI_COMM_WORLD,&myRank);
00034     if(!myRank) {
00035       std::cout<<"Building Full vecMass Mat."<<std::endl;
00036     }
00037     if(!(da->computedLocalToGlobal())) {
00038       da->computeLocalToGlobalMappings();
00039     }
00040     char matType[30];
00041     PetscTruth typeFound;
00042     PetscOptionsGetString(PETSC_NULL,"-fullJacMatType",matType,30,&typeFound);
00043     if(!typeFound) {
00044       std::cout<<"I need a MatType for the full matrix!"<<std::endl;
00045       assert(false);
00046     } 
00047     da->createMatrix(*jac, matType, 3);
00048     if(!myRank) {
00049       std::cout<<"Finished Building Full vecMass Mat."<<std::endl;
00050     }
00051   }else {  
00052     //The size this processor owns ( without ghosts).
00053     unsigned int  m,n;
00054     m=n=(3*(da->getNodeSize()));
00055     MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE, PETSC_DETERMINE, damg, jac);
00056     MatShellSetOperation(*jac ,MATOP_MULT, (void (*)(void)) ConstVecMassMatMult);
00057     MatShellSetOperation(*jac ,MATOP_GET_DIAGONAL, (void (*)(void)) ConstVecMassMatGetDiagonal);
00058     MatShellSetOperation(*jac ,MATOP_DESTROY, (void (*)(void)) ConstVecMassMatDestroy);
00059   }
00060   PetscFunctionReturn(0);
00061 }//end fn.
00062 
00063 PetscErrorCode ConstVecMassMatDestroy(Mat J) {
00064   PetscFunctionBegin;
00065   //Nothing to be done here. No new pointers were created during creation. 
00066   PetscFunctionReturn(0);
00067 }
00068 
00069 #define VEC_MASS_ELEM_DIAG_BLOCK {\
00070   unsigned int idx = da->curr();\
00071   unsigned int lev = da->getLevel(idx);\
00072   double h = hFac*(1u << (maxD - lev));\
00073   double fac = h*h*h/8.0;\
00074   unsigned int indices[8];\
00075   da->getNodeIndices(indices);\
00076   unsigned char childNum = da->getChildNumber();\
00077   unsigned char hnMask = da->getHangingNodeIndex(idx);\
00078   unsigned char elemType = 0;\
00079   GET_ETYPE_BLOCK(elemType,hnMask,childNum)\
00080   for(int k = 0; k < 8; k++) {\
00081     if(bdyArr[indices[k]]) {\
00082       /*Dirichlet Node*/\
00083       for(int dof = 0; dof < 3; dof++) {\
00084         diagArr[(3*indices[k])+dof] = 1.0;\
00085       } /*end dof*/\
00086     } else { \
00087       for(int dof = 0; dof < 3; dof++) {\
00088         diagArr[(3*indices[k])+dof] += (fac*(MassType2Stencil[childNum][elemType][k][k]));\
00089       } /*end dof*/\
00090     }\
00091   } /*end k*/\
00092 }
00093 
00094 #define VEC_MASS_DIAG_BLOCK {\
00095   ot::DA* da = damg->da;\
00096   iC(VecZeroEntries(diag));\
00097   PetscScalar *diagArr;\
00098   unsigned char* bdyArr = data->bdyArr;\
00099   /*Nodal,Non-Ghosted,Write,3 dof*/\
00100   da->vecGetBuffer(diag, diagArr, false, false, false, 3);\
00101   unsigned int maxD;\
00102   double hFac;\
00103   if(da->iAmActive()) {\
00104     maxD = (da->getMaxDepth());\
00105     hFac = 1.0/((double)(1u << (maxD-1)));\
00106     /*Loop through All Elements including ghosted*/\
00107     for(da->init<ot::DA_FLAGS::ALL>(); da->curr() < da->end<ot::DA_FLAGS::ALL>(); da->next<ot::DA_FLAGS::ALL>()) {\
00108       VEC_MASS_ELEM_DIAG_BLOCK\
00109     } /*end i*/\
00110   } /*end if active*/\
00111   da->vecRestoreBuffer(diag, diagArr, false, false, false, 3);\
00112   /*2 IOP = 1 FLOP. Loop counters are included too.*/\
00113   PetscLogFlops(93*(da->getGhostedElementSize()));\
00114 }
00115 
00116 PetscErrorCode ConstVecMassMatGetDiagonal(Mat J, Vec diag) {
00117   PetscFunctionBegin;
00118 
00119   PetscLogEventBegin(vecMassDiagEvent,diag,0,0,0);
00120 
00121   ot::DAMG damg;
00122   iC(MatShellGetContext(J, (void**)(&damg)));
00123 
00124   ElasticityData* data = (static_cast<ElasticityData*>(damg->user));
00125 
00126   bool isFinestLevel = (damg->nlevels == 1);
00127 
00128   if(isFinestLevel) {
00129     PetscLogEventBegin(vecMassFinestDiagEvent,diag,0,0,0);
00130   }
00131 
00132   VEC_MASS_DIAG_BLOCK 
00133 
00134     if(isFinestLevel) {
00135       PetscLogEventEnd(vecMassFinestDiagEvent,diag,0,0,0);
00136     }
00137 
00138   PetscLogEventEnd(vecMassDiagEvent,diag,0,0,0);
00139 
00140   PetscFunctionReturn(0);
00141 }
00142 
00143 #define VEC_MASS_ELEM_MULT_BLOCK {\
00144   unsigned int idx = da->curr();\
00145   unsigned int lev = da->getLevel(idx);\
00146   double h = hFac*(1u << (maxD - lev));\
00147   double fac = h*h*h/8.0;\
00148   unsigned int indices[8];\
00149   da->getNodeIndices(indices);\
00150   unsigned char childNum = da->getChildNumber();\
00151   unsigned char hnMask = da->getHangingNodeIndex(idx);\
00152   unsigned char elemType = 0;\
00153   GET_ETYPE_BLOCK(elemType, hnMask, childNum)\
00154   for(int k = 0;k < 8;k++) {\
00155     if(bdyArr[indices[k]]) {\
00156       /*Dirichlet Node Row*/\
00157       for(int dof = 0; dof < 3; dof++) {\
00158         outArr[(3*indices[k]) + dof] =  inArr[(3*indices[k]) + dof];\
00159       }/*end for dof*/\
00160     } else {\
00161       for(int j=0;j<8;j++) {\
00162         /*Avoid Dirichlet Node Columns*/\
00163         if(!(bdyArr[indices[j]])) {\
00164           for(int dof = 0; dof < 3; dof++) {\
00165             outArr[(3*indices[k]) + dof] += (fac*(MassType2Stencil[childNum][elemType][k][j])\
00166                 *inArr[(3*indices[j]) + dof]);\
00167           }/*end for dof*/\
00168         }\
00169       }/*end for j*/\
00170     }\
00171   }/*end for k*/\
00172 }
00173 
00174 #define VEC_MASS_MULT_BLOCK {\
00175   ot::DA* da = damg->da;\
00176   iC(VecZeroEntries(out));\
00177   unsigned int maxD;\
00178   double hFac;\
00179   if(da->iAmActive()) {\
00180     maxD = da->getMaxDepth();\
00181     hFac = 1.0/((double)(1u << (maxD-1)));\
00182   }\
00183   PetscScalar *outArr=NULL;\
00184   PetscScalar *inArr=NULL;\
00185   unsigned char* bdyArr = data->bdyArr;\
00186   /*Nodal,Non-Ghosted,Read,3 dof*/\
00187   da->vecGetBuffer(in, inArr, false, false, true, 3);\
00188   if(da->iAmActive()) {\
00189     da->ReadFromGhostsBegin<PetscScalar>(inArr, 3);\
00190   }\
00191   /*Nodal,Non-Ghosted,Write,3 dof*/\
00192   da->vecGetBuffer(out, outArr, false, false, false, 3);\
00193   /*Loop through All Independent Elements*/\
00194   if(da->iAmActive()) {\
00195     for(da->init<ot::DA_FLAGS::INDEPENDENT>();\
00196         da->curr() < da->end<ot::DA_FLAGS::INDEPENDENT>(); da->next<ot::DA_FLAGS::INDEPENDENT>() ) {\
00197       VEC_MASS_ELEM_MULT_BLOCK\
00198     } /*end independent*/\
00199   } /*end if active*/\
00200   if(da->iAmActive()) {\
00201     da->ReadFromGhostsEnd<PetscScalar>(inArr);\
00202   }\
00203   /*Loop through All Dependent Elements,*/\
00204   /*i.e. Elements which have atleast one*/\
00205   /*vertex owned by this processor and at least one*/\
00206   /*vertex not owned by this processor.*/\
00207   if(da->iAmActive()) {\
00208     for(da->init<ot::DA_FLAGS::DEPENDENT>();\
00209         da->curr() < da->end<ot::DA_FLAGS::DEPENDENT>();  da->next<ot::DA_FLAGS::DEPENDENT>() ) {\
00210       VEC_MASS_ELEM_MULT_BLOCK\
00211     } /*end loop for dependent elems*/\
00212   } /*end if active*/\
00213   da->vecRestoreBuffer(in, inArr, false, false, true, 3);\
00214   da->vecRestoreBuffer(out, outArr, false, false, false, 3);\
00215   /*2 IOP = 1 FLOP. Loop counters are included too.*/\
00216   PetscLogFlops(1095*(da->getGhostedElementSize()));\
00217 }
00218 
00219 PetscErrorCode ConstVecMassMatMult(Mat J, Vec in, Vec out)
00220 {
00221   PetscFunctionBegin;
00222 
00223   PetscLogEventBegin(vecMassMultEvent,in,out,0,0);
00224 
00225   ot::DAMG damg;
00226   iC(MatShellGetContext(J, (void**)(&damg)));
00227 
00228   ElasticityData* data = (static_cast<ElasticityData*>(damg->user));
00229 
00230   bool isFinestLevel = (damg->nlevels == 1);
00231 
00232   if(isFinestLevel) {
00233     PetscLogEventBegin(vecMassFinestMultEvent,in,out,0,0);
00234   }
00235 
00236   VEC_MASS_MULT_BLOCK 
00237 
00238     if(isFinestLevel) {
00239       PetscLogEventEnd(vecMassFinestMultEvent,in,out,0,0);
00240     }
00241 
00242   PetscLogEventEnd(vecMassMultEvent,in,out,0,0);
00243 
00244   PetscFunctionReturn(0);
00245 }
00246 
00247 #define BUILD_FULL_VEC_MASS_BLOCK {\
00248   ot::DA* da = damg->da;\
00249   MatZeroEntries(B);\
00250   std::vector<ot::MatRecord> records;\
00251   unsigned int maxD;\
00252   double hFac;\
00253   if(da->iAmActive()) {\
00254     maxD = da->getMaxDepth();\
00255     hFac = 1.0/((double)(1u << (maxD-1)));\
00256   }\
00257   unsigned char* bdyArr = data->bdyArr;\
00258   if(da->iAmActive()) {\
00259     for(da->init<ot::DA_FLAGS::WRITABLE>();\
00260         da->curr() < da->end<ot::DA_FLAGS::WRITABLE>();  da->next<ot::DA_FLAGS::WRITABLE>()) {\
00261       unsigned int idx = da->curr();\
00262       unsigned int lev = da->getLevel(idx);\
00263       double h = hFac*(1u << (maxD - lev));\
00264       double fac = h/2.0;\
00265       unsigned int indices[8];\
00266       da->getNodeIndices(indices);\
00267       unsigned char childNum = da->getChildNumber();\
00268       unsigned char hnMask = da->getHangingNodeIndex(idx);\
00269       unsigned char elemType = 0;\
00270       GET_ETYPE_BLOCK(elemType, hnMask, childNum)\
00271       for(int k = 0;k < 8;k++) {\
00272         /*Avoid Dirichlet Node Rows during ADD_VALUES loop.*/\
00273         /*Need a separate INSERT_VALUES loop for those*/\
00274         if(!(bdyArr[indices[k]])) {\
00275           for(int j=0;j<8;j++) {\
00276             if(!(bdyArr[indices[j]])) {\
00277               for(int dof = 0; dof < 3; dof++) {\
00278                 ot::MatRecord currRec;\
00279                 currRec.rowIdx = indices[k];\
00280                 currRec.colIdx = indices[j];\
00281                 currRec.rowDim = dof;\
00282                 currRec.colDim = dof;\
00283                 currRec.val = (fac*(MassType2Stencil[childNum][elemType][k][j]));\
00284                 records.push_back(currRec);\
00285               } /*end for dof*/\
00286             }\
00287           } /*end for j*/\
00288         }\
00289       } /*end for k*/\
00290       if(records.size() > 1000) {\
00291         /*records will be cleared inside the function*/\
00292         da->setValuesInMatrix(B, records, 3, ADD_VALUES);\
00293       }\
00294     } /*end writable*/\
00295   } /*end if active*/\
00296   da->setValuesInMatrix(B, records, 3, ADD_VALUES);\
00297   MatAssemblyBegin(B, MAT_FLUSH_ASSEMBLY);\
00298   MatAssemblyEnd(B, MAT_FLUSH_ASSEMBLY);\
00299   if(da->iAmActive()) {\
00300     for(da->init<ot::DA_FLAGS::WRITABLE>();\
00301         da->curr() < da->end<ot::DA_FLAGS::WRITABLE>();  da->next<ot::DA_FLAGS::WRITABLE>()) {\
00302       unsigned int idx = da->curr();\
00303       unsigned int lev = da->getLevel(idx);\
00304       double h = hFac*(1u << (maxD - lev));\
00305       double fac = h/2.0;\
00306       unsigned int indices[8];\
00307       da->getNodeIndices(indices);\
00308       unsigned char childNum = da->getChildNumber();\
00309       unsigned char hnMask = da->getHangingNodeIndex(idx);\
00310       unsigned char elemType = 0;\
00311       GET_ETYPE_BLOCK(elemType, hnMask, childNum)\
00312       for(int k = 0; k < 8; k++) {\
00313         /*Insert values for Dirichlet Node Rows only.*/\
00314         if(bdyArr[indices[k]]) {\
00315           for(int dof = 0; dof < 3; dof++) {\
00316             ot::MatRecord currRec;\
00317             currRec.rowIdx = indices[k];\
00318             currRec.colIdx = indices[k];\
00319             currRec.rowDim = dof;\
00320             currRec.colDim = dof;\
00321             currRec.val = 1.0;\
00322             records.push_back(currRec);\
00323           } /*end for dof*/\
00324         }\
00325       } /*end for k*/\
00326       if(records.size() > 1000) {\
00327         /*records will be cleared inside the function*/\
00328         da->setValuesInMatrix(B, records, 3, INSERT_VALUES);\
00329       }\
00330     } /*end writable*/\
00331   } /*end if active*/\
00332   da->setValuesInMatrix(B, records, 3, INSERT_VALUES);\
00333   MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY);\
00334   MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY);\
00335 }
00336 
00337 PetscErrorCode ComputeConstVecMass(ot::DAMG damg, Mat J, Mat B) {
00338   //For matShells nothing to be done here.
00339   PetscFunctionBegin;
00340 
00341   PetscTruth isshell;
00342   PetscTypeCompare((PetscObject)B, MATSHELL, &isshell);
00343   if(isshell) {
00344     PetscFunctionReturn(0);
00345   }
00346 
00347   ElasticityData* data = (static_cast<ElasticityData*>(damg->user));
00348 
00349   //Assuming that B and J are the same.
00350 
00351   BUILD_FULL_VEC_MASS_BLOCK 
00352 
00353     PetscFunctionReturn(0);
00354 }
00355 
00356 #undef BUILD_FULL_VEC_MASS_BLOCK 
00357 #undef VEC_MASS_MULT_BLOCK 
00358 #undef VEC_MASS_DIAG_BLOCK 
00359 #undef VEC_MASS_ELEM_DIAG_BLOCK 
00360 #undef VEC_MASS_ELEM_MULT_BLOCK 
00361 
00362 

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