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

massMatrix.h

Go to the documentation of this file.
00001 
00016 #ifndef _MASSMATRIX_H_
00017 #define _MASSMATRIX_H_
00018 
00031 #include "feMatrix.h"
00032 
00033 class massMatrix : public ot::fem::feMatrix<massMatrix>
00034 {
00035   public:
00036   massMatrix(daType da);
00047     inline bool ElementalMatVec(int i, int j, int k, PetscScalar ***in, PetscScalar ***out, double scale);
00048     inline bool ElementalMatVec(unsigned int idx, PetscScalar *in, PetscScalar *out, double scale);
00049 
00050     inline bool ElementalMatGetDiagonal(int i, int j, int k, PetscScalar ***diag, double scale);
00051     inline bool ElementalMatGetDiagonal(unsigned int idx, PetscScalar *diag, double scale);
00052 
00053     inline bool initStencils();
00054 
00055     bool preMatVec();
00056     bool postMatVec();
00057 
00058     void setNuVec(Vec nv) {
00059       nuvec = nv;
00060     }
00061 
00062    private:
00063     PetscScalar***      nuarray; /* Diffusion coefficient array*/
00064     Vec                 nuvec;     
00065 
00066     double              m_dHx;
00067     
00068     double xFac, yFac, zFac;
00069     unsigned int maxD;
00070 };
00071 
00072 
00073 massMatrix::massMatrix(daType da) {
00074 #ifdef __DEBUG__
00075   assert ( ( da == PETSC ) || ( da == OCT ) );
00076 #endif
00077   m_daType = da;
00078   m_DA          = NULL;
00079   m_octDA       = NULL;
00080   m_stencil     = NULL;
00081 
00082   // initialize the stencils ...
00083   initStencils();
00084   if (da == OCT)
00085     initOctLut();
00086 }
00087 
00088 bool massMatrix::initStencils() {
00089   typedef int* int1Ptr;
00090   typedef int** int2Ptr;
00091  
00092   if (m_daType == PETSC) {
00093     int Bjk[8][8] =    {
00094       { 64, 32, 32, 16, 32, 16, 16,  8},
00095       { 32, 64, 16, 32, 16, 32,  8, 16},
00096       { 32, 16, 64, 32, 16,  8, 32, 16},
00097       { 16, 32, 32, 64,  8, 16, 16, 32},
00098       { 32, 16, 16,  8, 64, 32, 32, 16},
00099       { 16, 32,  8, 16, 32, 64, 16, 32},
00100       { 16,  8, 32, 16, 32, 16, 64, 32},
00101       {  8, 16, 16, 32, 16, 32, 32, 64}
00102     };
00103 
00104     int** Ajk = new int1Ptr[8];
00105     for (int j=0;j<8;j++) {
00106       Ajk[j] = new int[8];
00107       for (int k=0;k<8;k++) {
00108         Ajk[j][k] = Bjk[j][k];
00109       }//end k
00110     }//end j
00111     m_stencil = Ajk;
00112   } else {
00113     int Bijk[8][8][8] = {
00114       //Type-0:No Hanging
00115       {{ 64, 32, 32, 16, 32, 16, 16,  8},
00116         { 32, 64, 16, 32, 16, 32,  8, 16},
00117         { 32, 16, 64, 32, 16,  8, 32, 16},
00118         { 16, 32, 32, 64,  8, 16, 16, 32},
00119         { 32, 16, 16,  8, 64, 32, 32, 16},
00120         { 16, 32,  8, 16, 32, 64, 16, 32},
00121         { 16,  8, 32, 16, 32, 16, 64, 32},
00122         {  8, 16, 16, 32, 16, 32, 32, 64}},
00123 
00124       //Type-1: Y Hanging
00125       {{ 112,  40,  32,  32,  40,  20,  32,  16},
00126         {  40,  64,   8,  32,  16,  32,   8,  16},
00127         {  32,   8,  16,  16,   8,   4,  16,   8},
00128         {  32,  32,  16,  64,   8,  16,  16,  32},
00129         {  40,  16,   8,   8,  64,  32,  32,  16},
00130         {  20,  32,   4,  16,  32,  64,  16,  32},
00131         {  32,   8,  16,  16,  32,  16,  64,  32},
00132         {  16,  16,   8,  32,  16,  32,  32,  64}},
00133 
00134       //Type-2: X and Y Hanging
00135       {{ 168,  36,  36,  48,  48,  36,  36,  24},
00136         {  36,  16,   4,  16,   8,  16,   4,   8},
00137         {  36,   4,  16,  16,   8,   4,  16,   8},
00138         {  48,  16,  16,  64,   8,  16,  16,  32},
00139         {  48,   8,   8,   8,  64,  32,  32,  16},
00140         {  36,  16,   4,  16,  32,  64,  16,  32},
00141         {  36,   4,  16,  16,  32,  16,  64,  32},
00142         {  24,   8,   8,  32,  16,  32,  32,  64}},
00143 
00144       //Type-3: X and Y and Z Hanging
00145       {{ 232,  40,  40,  52,  40,  52,  52,  32},
00146         {  40,  16,   4,  16,   4,  16,   4,   8},
00147         {  40,   4,  16,  16,   4,   4,  16,   8},
00148         {  52,  16,  16,  64,   4,  16,  16,  32},
00149         {  40,   4,   4,   4,  16,  16,  16,   8},
00150         {  52,  16,   4,  16,  16,  64,  16,  32},
00151         {  52,   4,  16,  16,  16,  16,  64,  32},
00152         {  32,   8,   8,  32,   8,  32,  32,  64}},
00153 
00154       //Type-4:XY and X and Y Hanging
00155       {{ 196,  56,  56,  16,  50,  40,  40,  32},
00156         {  56,  28,  16,   8,  10,  20,   8,  16},
00157         {  56,  16,  28,   8,  10,   8,  20,  16},
00158         {  16,   8,   8,   4,   2,   4,   4,   8},
00159         {  50,  10,  10,   2,  64,  32,  32,  16},
00160         {  40,  20,   8,   4,  32,  64,  16,  32},
00161         {  40,   8,  20,   4,  32,  16,  64,  32},
00162         {  32,  16,  16,   8,  16,  32,  32,  64}},
00163 
00164       //Type-5:XY and X and Y and Z Hanging
00165       {{ 262,  61,  61,  17,  41,  56,  56,  40},
00166         {  61,  28,  16,   8,   5,  20,   8,  16},
00167         {  61,  16,  28,   8,   5,   8,  20,  16},
00168         {  17,   8,   8,   4,   1,   4,   4,   8},
00169         {  41,   5,   5,   1,  16,  16,  16,   8},
00170         {  56,  20,   8,   4,  16,  64,  16,  32},
00171         {  56,   8,  20,   4,  16,  16,  64,  32},
00172         {  40,  16,  16,   8,   8,  32,  32,  64}},
00173 
00174       //Type-6:XY and YZ and X and Y and Z Hanging
00175       {{ 294,  63,  84,  18,  63,  60,  18,  48},
00176         {  63,  28,  18,   8,   7,  20,   2,  16},
00177         {  84,  18,  42,   9,  18,  12,   9,  24},
00178         {  18,   8,   9,   4,   2,   4,   1,   8},
00179         {  63,   7,  18,   2,  28,  20,   8,  16},
00180         {  60,  20,  12,   4,  20,  64,   4,  32},
00181         {  18,   2,   9,   1,   8,   4,   4,   8},
00182         {  48,  16,  24,   8,  16,  32,   8,  64}},
00183 
00184       //Type-7: All 6 Hanging
00185       {{ 328,  87,  87,  19,  87,  19,  19,  56},
00186         {  87,  42,  21,   9,  21,   9,   3,  24},
00187         {  87,  21,  42,   9,  21,   3,   9,  24},
00188         {  19,   9,   9,   4,   3,   1,   1,   8},
00189         {  87,  21,  21,   3,  42,   9,   9,  24},
00190         {  19,   9,   3,   1,   9,   4,   1,   8},
00191         {  19,   3,   9,   1,   9,   1,   4,   8},
00192         {  56,  24,  24,   8,  24,   8,   8,  64}}
00193     };
00194 
00195     int ***Aijk = new int2Ptr[8];
00196     for (int i=0;i<8;i++) {
00197       Aijk[i] = new int1Ptr[8];
00198       for (int j=0;j<8;j++) {
00199         Aijk[i][j] = new int[8];
00200         for (int k=0;k<8;k++) {
00201           Aijk[i][j][k] = Bijk[i][j][k];
00202         }//end k
00203       }//end j
00204     }//end i
00205     m_stencil = Aijk;
00206   }
00207   return true;
00208 }
00209 
00210 bool massMatrix::preMatVec() {
00211   if (m_daType == PETSC) {
00212     // compute Hx
00213     int ierr;
00214     PetscInt mx,my,mz;
00215     ierr = DAGetInfo(m_DA,0, &mx, &my, &mz, 0,0,0,0,0,0,0); CHKERRQ(ierr); 
00216 
00217     m_dHx = m_dLx/(mx -1);
00218     m_dHx = m_dHx*m_dHx*m_dHx;
00219     m_dHx /= 1728.0;
00220     CHKERRQ(ierr);
00221   } else {
00222     maxD = m_octDA->getMaxDepth();
00223 
00224     
00225     // Get the  x,y,z factors 
00226     xFac = 1.0/((double)(1u << (maxD-1)));
00227     if (m_octDA->getDimension() > 1) {
00228       yFac = 1.0/((double)(1u << (maxD-1)));
00229       if (m_octDA->getDimension() > 2) {
00230         zFac = 1.0/((double)(1u << (maxD-1)));
00231       }
00232     }
00233   }
00234 
00235   return true;
00236 }
00237 
00238 bool massMatrix::ElementalMatVec(unsigned int i, PetscScalar *in, PetscScalar *out, double scale) {
00239   unsigned int lev = m_octDA->getLevel(i);
00240   double hx = xFac*(1u << (maxD - lev));
00241   double hy = yFac*(1u << (maxD - lev));
00242   double hz = zFac*(1u << (maxD - lev));
00243 
00244   double fac = scale*hx*hy*hz/1728.0;
00245   
00246   stdElemType elemType;
00247   unsigned int idx[8];
00248   
00249   int ***Aijk = (int ***)m_stencil;
00250   
00251   alignElementAndVertices(m_octDA, elemType, idx);       
00252   
00253 
00254   for (int k = 0;k < 8;k++) {
00255     for (int j=0;j<8;j++) {
00256       out[m_uiDof*idx[k]] += fac*(Aijk[elemType][k][j])*in[m_uiDof*idx[j]];
00257                 //              std::cout << Aijk[elemType][k][j] << ";" << fac << " ; " << in[m_uiDof*idx[j]] << std::endl;
00258                 //std::cout << xFac << "; " << hx << std::endl;
00259     }//end for j
00260   }//end for k
00261   
00262   return true;
00263 }
00264 bool massMatrix::ElementalMatVec(int i, int j, int k, PetscScalar ***in, PetscScalar ***out, double scale){
00265   int dof= m_uiDof;
00266   int idx[8][3]={
00267     {k, j, dof*i},
00268     {k,j,dof*(i+1)},
00269     {k,j+1,dof*i},
00270     {k,j+1,dof*(i+1)},
00271     {k+1, j, dof*i},
00272     {k+1,j,dof*(i+1)},
00273     {k+1,j+1,dof*i},
00274     {k+1,j+1,dof*(i+1)}               
00275   };             
00276 
00277   double stencilScale =  m_dHx*scale;
00278   int **Ajk = (int **)m_stencil;
00279   
00280   for (int q = 0; q < 8; q++) {
00281     for (int r = 0; r < 8; r++) {
00282       out[idx[q][0]][idx[q][1]][idx[q][2]] += stencilScale*Ajk[q][r]*in[idx[r][0]][idx[r][1]][idx[r][2]];
00283                 if(dof > 1)  out[idx[q][0]][idx[q][1]][idx[q][2]+1] += 0.0;
00284     }
00285   }
00286   return true;
00287   // std::cout << "Stencil scale is " << stencilScale << std::endl;
00288 }
00289 
00290 bool massMatrix::postMatVec() {
00291 
00292   return true;
00293 }
00294 
00295 bool massMatrix::ElementalMatGetDiagonal(unsigned int i, PetscScalar *diag, double scale) {
00296   unsigned int lev = m_octDA->getLevel(i);
00297   double hx = xFac*(1u << (maxD - lev));
00298   double hy = yFac*(1u << (maxD - lev));
00299   double hz = zFac*(1u << (maxD - lev));
00300 
00301   double fac = scale*hx*hy*hz/1728.0;
00302   
00303   stdElemType elemType;
00304   unsigned int idx[8];
00305   
00306   int ***Aijk = (int ***)m_stencil;
00307   
00308   alignElementAndVertices(m_octDA, elemType, idx);       
00309   
00310   for (int k = 0;k < 8;k++) {
00311       diag[m_uiDof*idx[k]] += fac*(Aijk[elemType][k][k]);
00312         }//end for k
00313   
00314   return true;
00315 }
00316 
00317 bool massMatrix::ElementalMatGetDiagonal(int i, int j, int k, PetscScalar ***diag, double scale){
00318   int dof= m_uiDof;
00319   int idx[8][3]={
00320     {k, j, dof*i},
00321     {k,j,dof*(i+1)},
00322     {k,j+1,dof*i},
00323     {k,j+1,dof*(i+1)},
00324     {k+1, j, dof*i},
00325     {k+1,j,dof*(i+1)},
00326     {k+1,j+1,dof*i},
00327     {k+1,j+1,dof*(i+1)}               
00328   };             
00329 
00330   double stencilScale =  m_dHx*scale;
00331   int **Ajk = (int **)m_stencil;
00332   
00333   for (int q = 0; q < 8; q++) {
00334     diag[idx[q][0]][idx[q][1]][idx[q][2]] += stencilScale*Ajk[q][q];
00335                 if(dof > 1)  diag[idx[q][0]][idx[q][1]][idx[q][2]+1] += 0.0;
00336   }
00337   return true;
00338 }
00339 
00340 
00341 #endif /*_MASSMATRIX_H_*/
00342 

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