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

odaJac.C

Go to the documentation of this file.
00001 
00007 #include "petsc.h"
00008 #include "petscvec.h"
00009 #include "petscmat.h"
00010 #include "odaJac.h"
00011 
00012 #ifdef PETSC_USE_LOG
00013 extern int Jac1DiagEvent;
00014 extern int Jac1MultEvent;
00015 extern int Jac1FinestDiagEvent;
00016 extern int Jac1FinestMultEvent;
00017 #endif
00018 
00019 extern double**** LaplacianType2Stencil; 
00020 extern double**** MassType2Stencil; 
00021 
00022 PetscErrorCode Jacobian1ShellMatMult(Mat J, Vec in, Vec out) {
00023   PetscFunctionBegin;
00024 
00025   Jac1MFreeData* ctx;
00026 
00027   MatShellGetContext(J, (void**)(&ctx));
00028 
00029   assert(ctx != NULL);
00030   assert(ctx->da != NULL);  
00031 
00032   if(ctx->da->iAmActive()) {      
00033     PetscScalar* inArray;
00034     PetscScalar* outArray;
00035 
00036     VecGetArray(in, &inArray);
00037     VecGetArray(out, &outArray);
00038 
00039     VecPlaceArray(ctx->inTmp, inArray);
00040     VecPlaceArray(ctx->outTmp, outArray);
00041 
00042     MatMult(ctx->Jmat_private, ctx->inTmp, ctx->outTmp);
00043 
00044     VecResetArray(ctx->inTmp);
00045     VecResetArray(ctx->outTmp);
00046 
00047     VecRestoreArray(in, &inArray);
00048     VecRestoreArray(out, &outArray);
00049   }
00050 
00051   PetscFunctionReturn(0);
00052 }
00053 
00054 PetscErrorCode CreateJacobian1(ot::DA *da, Mat *jac)
00055 {
00056   PetscInt  m,n;
00057   PetscFunctionBegin;
00058   //The size this processor owns ( without ghosts).
00059   m=n=da->getNodeSize();
00060   Jac1MFreeData* data = new Jac1MFreeData;
00061   data->da = da;
00062   data->Jmat_private = NULL;
00063   data->inTmp = NULL;
00064   data->outTmp = NULL;
00065   data->isFinestLevel = true;//single grid is always the finest.
00066   iC(MatCreateShell(da->getComm(), m ,n,PETSC_DETERMINE,PETSC_DETERMINE,
00067         (void*)(data), jac));
00068   iC(MatShellSetOperation(*jac ,MATOP_MULT, (void(*)(void)) Jacobian1MatMult));
00069   iC(MatShellSetOperation(*jac ,MATOP_GET_DIAGONAL, (void(*)(void)) Jacobian1MatGetDiagonal));
00070   iC(MatShellSetOperation(*jac ,MATOP_DESTROY, (void(*)(void)) Jacobian1MatDestroy));
00071   PetscFunctionReturn(0);
00072 }
00073 
00074 PetscErrorCode CreateActiveJacobian1(ot::DA *da, Mat *jac)
00075 {
00076   PetscInt  m,n;
00077   PetscFunctionBegin;
00078   if(da->iAmActive()) {
00079     //The size this processor owns ( without ghosts).
00080     m=n=da->getNodeSize();
00081     Jac1MFreeData* data = new Jac1MFreeData;
00082     data->da = da;
00083     data->Jmat_private = NULL;
00084     data->inTmp = NULL;
00085     data->outTmp = NULL;
00086     data->isFinestLevel = true;//single grid is always the finest.
00087     iC(MatCreateShell(da->getCommActive(), m ,n,PETSC_DETERMINE,PETSC_DETERMINE,
00088           (void*)(data), jac));
00089     iC(MatShellSetOperation(*jac ,MATOP_MULT, (void(*)(void)) Jacobian1MatMult));
00090     iC(MatShellSetOperation(*jac ,MATOP_GET_DIAGONAL, (void(*)(void)) Jacobian1MatGetDiagonal));
00091     iC(MatShellSetOperation(*jac ,MATOP_DESTROY, (void(*)(void)) Jacobian1MatDestroy));
00092   }
00093   PetscFunctionReturn(0);
00094 }
00095 
00096 PetscErrorCode ComputeJacobian1(ot::DA* da, Mat J)
00097 {
00098   PetscFunctionBegin;
00099   //Do nothing
00100   PetscFunctionReturn(0);
00101 }
00102 
00103 PetscErrorCode CreateAndComputeMassMatrix(ot::DA* da, Mat* jac) {
00104   PetscInt  m,n;
00105   PetscFunctionBegin;
00106   //The size this processor owns ( without ghosts).
00107   m=n=da->getNodeSize();
00108   Jac1MFreeData* data = new Jac1MFreeData;
00109   data->da = da;
00110   data->Jmat_private = NULL;
00111   data->inTmp = NULL;
00112   data->outTmp = NULL;
00113   iC(MatCreateShell(da->getComm(), m ,n,PETSC_DETERMINE,PETSC_DETERMINE, (void*)(data), jac));
00114   iC(MatShellSetOperation(*jac ,MATOP_MULT, (void(*)(void)) MassMatMult));
00115   iC(MatShellSetOperation(*jac ,MATOP_GET_DIAGONAL, (void(*)(void)) MassMatGetDiagonal));
00116   iC(MatShellSetOperation(*jac ,MATOP_DESTROY, (void(*)(void)) MassMatDestroy));
00117   PetscFunctionReturn(0);
00118 }
00119 
00120 PetscErrorCode Jacobian1MatDestroy(Mat J) {
00121   PetscFunctionBegin;
00122   Jac1MFreeData *data;
00123   iC(MatShellGetContext( J, (void **)&data));
00124   if(data != NULL) {
00125     if(J != data->Jmat_private) {
00126       if(data->Jmat_private) {
00127         MatDestroy(data->Jmat_private);
00128         data->Jmat_private = NULL;
00129       }
00130     }
00131     if(data->inTmp) {
00132       VecDestroy(data->inTmp);
00133       data->inTmp = NULL;
00134     }
00135     if(data->outTmp) {
00136       VecDestroy(data->outTmp);
00137       data->outTmp = NULL;
00138     }
00139     delete data;
00140     data = NULL;
00141   }
00142   PetscFunctionReturn(0);
00143 }
00144 
00145 PetscErrorCode MassMatDestroy(Mat J) {
00146   PetscFunctionBegin;    
00147   Jac1MFreeData *data;
00148   iC(MatShellGetContext( J, (void **)&data));
00149   if(data) {
00150     if(data->Jmat_private) {
00151       MatDestroy(data->Jmat_private);
00152       data->Jmat_private = NULL;
00153     }
00154     delete data;
00155     data = NULL;
00156   }
00157   PetscFunctionReturn(0);
00158 }
00159 
00160 PetscErrorCode Jacobian1MatGetDiagonal(Mat J, Vec diag) {
00161   PetscFunctionBegin;
00162 
00163   PetscLogEventBegin(Jac1DiagEvent,diag,0,0,0);
00164   Jac1MFreeData *data;
00165   iC(MatShellGetContext(J, (void **)&data));
00166   if(data->isFinestLevel) {
00167     PetscLogEventBegin(Jac1FinestDiagEvent,diag,0,0,0);
00168   }
00169   iC(VecZeroEntries(diag));
00170 
00171   PetscScalar *diagArr;
00172   //Nodal,Non-Ghosted,Write,1 dof
00173   data->da->vecGetBuffer(diag,diagArr,false,false,false,1);
00174 
00175   //If Required Use Some Problem Specific information and set xFac, yFac, zFac.
00176   //Here, I'm simply assuming that the domain is of unit size.
00177   //To get the physical dimension of any element in a particular direction say
00178   //'x', xFac will be multiplied by (1u << (maxD-level)) of that element.
00179   unsigned int maxD;
00180   double hFac;
00181 
00182   PetscReal lapFac = 1.0;
00183   PetscReal massFac = 1.0;
00184   PetscTruth optFound;
00185   PetscOptionsGetReal("lap","-MatPropFac",&lapFac,&optFound);
00186   PetscOptionsGetReal("mass","-MatPropFac",&massFac,&optFound);
00187 
00188   if(data->da->iAmActive()) {
00189     maxD = (data->da->getMaxDepth());
00190     hFac = 1.0/((double)(1u << (maxD-1)));
00191 
00192     //Loop through All Elements including ghosted
00193     for(data->da->init<ot::DA_FLAGS::ALL>();
00194         data->da->curr() < data->da->end<ot::DA_FLAGS::ALL>(); 
00195         data->da->next<ot::DA_FLAGS::ALL>()) {
00196       //This returns the 8 vertices in the Morton order.
00197       unsigned int lev = data->da->getLevel(data->da->curr());
00198       double h = hFac*(1u << (maxD - lev));
00199       double fac1 = lapFac*h/2.0;
00200       double fac2 = massFac*h*h*h/8.0;
00201       unsigned int indices[8];
00202       data->da->getNodeIndices(indices); 
00203       unsigned char childNum = data->da->getChildNumber();
00204       unsigned char hnMask = data->da->getHangingNodeIndex(data->da->curr()); 
00205       unsigned char elemType = 0;
00206       GET_ETYPE_BLOCK(elemType,hnMask,childNum)
00207         for(int k = 0;k < 8;k++) {
00208           diagArr[indices[k]] +=  ((fac1*(LaplacianType2Stencil[childNum][elemType][k][k])) +  
00209               (fac2*(MassType2Stencil[childNum][elemType][k][k])));
00210         }//end k
00211     }//end i
00212   }
00213 
00214   data->da->vecRestoreBuffer(diag,diagArr,false,false,false,1);
00215 
00216   PetscLogFlops(44*(data->da->getGhostedElementSize()));
00217   PetscLogEventEnd(Jac1DiagEvent,diag,0,0,0);
00218   if(data->isFinestLevel) {
00219     PetscLogEventEnd(Jac1FinestDiagEvent,diag,0,0,0);
00220   }
00221 
00222   PetscFunctionReturn(0);
00223 }
00224 
00225 PetscErrorCode MassMatGetDiagonal(Mat J, Vec diag) {
00226   PetscFunctionBegin;  
00227   Jac1MFreeData *data;
00228   iC(MatShellGetContext(J, (void **)&data));
00229   iC(VecZeroEntries(diag));
00230 
00231   //If Required Use Some Problem Specific information and set xFac, yFac, zFac.
00232   //Here, I'm simply assuming that the domain is of unit size.
00233   //To get the physical dimension of any element in a particular direction say
00234   //'x', xFac will be multiplied by (1u << (maxD-level)) of that element.
00235   unsigned int maxD;
00236   double hFac;
00237   if(data->da->iAmActive()) {
00238     maxD = (data->da->getMaxDepth());
00239     hFac = 1.0/((double)(1u << (maxD-1)));
00240   }
00241 
00242   PetscScalar *diagArr;
00243   //Nodal,Non-Ghosted,Write,1 dof
00244   data->da->vecGetBuffer(diag,diagArr,false,false,false,1);
00245 
00246   if(data->da->iAmActive()) {
00247     //Loop through All Elements including ghosted
00248     for(data->da->init<ot::DA_FLAGS::ALL>();
00249         data->da->curr() < data->da->end<ot::DA_FLAGS::ALL>();
00250         data->da->next<ot::DA_FLAGS::ALL>()) {
00251       //This returns the 8 vertices in the Morton order.
00252       unsigned int lev = data->da->getLevel(data->da->curr());
00253       double h = hFac*(1u << (maxD - lev));
00254       double fac2 = h*h*h/8.0;
00255       unsigned int indices[8];
00256       data->da->getNodeIndices(indices); 
00257       unsigned char childNum = data->da->getChildNumber();
00258       unsigned char hnMask = data->da->getHangingNodeIndex(data->da->curr()); 
00259       unsigned char elemType = 0;
00260       GET_ETYPE_BLOCK(elemType,hnMask,childNum)
00261         for(int k = 0;k < 8;k++) {
00262           diagArr[indices[k]] +=  (fac2*(MassType2Stencil[childNum][elemType][k][k]));
00263         }//end k        
00264     }//end i
00265   }
00266 
00267   data->da->vecRestoreBuffer(diag,diagArr,false,false,false,1);  
00268   PetscFunctionReturn(0);
00269 }
00270 
00271 #define JACOBIAN_TYPE1_MULT_BLOCK {\
00272   unsigned int lev = data->da->getLevel(data->da->curr());\
00273   double h = hFac*(1u << (maxD - lev));\
00274   double fac1 = lapFac*h/2.0;\
00275   double fac2 = massFac*h*h*h/8.0;\
00276   unsigned int indices[8];\
00277   data->da->getNodeIndices(indices);\
00278   unsigned char childNum = data->da->getChildNumber();\
00279   unsigned char hnMask = data->da->getHangingNodeIndex(data->da->curr());\
00280   unsigned char elemType = 0;\
00281   GET_ETYPE_BLOCK(elemType,hnMask,childNum)\
00282   for(int k = 0;k < 8;k++) {\
00283     for(int j=0;j<8;j++) {\
00284       outArr[indices[k]] +=  (((fac1*(LaplacianType2Stencil[childNum][elemType][k][j])) +\
00285             (fac2*(MassType2Stencil[childNum][elemType][k][j])))*inArr[indices[j]]);\
00286     } /*end for j*/\
00287   } /*end for k*/\
00288 }
00289 
00290 PetscErrorCode Jacobian1MatMult(Mat J, Vec in, Vec out)
00291 {
00292   PetscFunctionBegin;
00293 
00294   Jac1MFreeData *data;
00295   PetscLogEventBegin(Jac1MultEvent,in,out,0,0);
00296   iC(MatShellGetContext( J, (void **)&data));  
00297   if(data->isFinestLevel) {
00298     PetscLogEventBegin(Jac1FinestMultEvent,in,out,0,0);
00299   }
00300   iC(VecZeroEntries(out));
00301 
00302   unsigned int maxD;
00303   double hFac;
00304   if(data->da->iAmActive()) {
00305     maxD = data->da->getMaxDepth(); 
00306     hFac = 1.0/((double)(1u << (maxD-1)));
00307   }
00308 
00309   PetscReal lapFac = 1.0;
00310   PetscReal massFac = 1.0;
00311   PetscTruth optFound;
00312   PetscOptionsGetReal("lap","-MatPropFac",&lapFac,&optFound);
00313   PetscOptionsGetReal("mass","-MatPropFac",&massFac,&optFound);
00314 
00315   PetscScalar *outArr=NULL;
00316   PetscScalar *inArr=NULL; 
00317   //Nodal,Non-Ghosted,Read,1 dof
00318   data->da->vecGetBuffer(in,inArr,false,false,true,1);
00319 
00320   //std::cout << __func__ << ": Updating Ghost..." << std::endl;
00321   if(data->da->iAmActive()) {
00322     data->da->ReadFromGhostsBegin<PetscScalar>(inArr,1);
00323   }
00324 
00325   //Nodal,Non-Ghosted,Write,1 dof
00326   data->da->vecGetBuffer(out,outArr,false,false,false,1);
00327 
00328   //Loop through All Independent Elements     
00329 
00330   if(data->da->iAmActive()) {
00331     for(data->da->init<ot::DA_FLAGS::INDEPENDENT>();
00332         data->da->curr() < data->da->end<ot::DA_FLAGS::INDEPENDENT>();
00333         data->da->next<ot::DA_FLAGS::INDEPENDENT>() ) {
00334       JACOBIAN_TYPE1_MULT_BLOCK
00335     }//end independent
00336   }
00337 
00338   if(data->da->iAmActive()) {
00339     data->da->ReadFromGhostsEnd<PetscScalar>(inArr);
00340   }
00341   //Loop through All Dependent Elements, i.e. Elements which have atleast one
00342   //vertex owned by this processor and at least one vertex not owned by this
00343   //processor. For simplicity, I may write to nodes that I do not own. These
00344   //can be discarded later. Every processor is only supposed to write to the
00345   //nodes it owns. An alternate strategy would require me to check if i own the
00346   //node before i write, I think this might be inefficient. So, if possible
00347   //allow me to write to nodes I do not own. You can discard them while
00348   //restoring the buffers.
00349   //Note: Whenever, I refer to nodes I refer to regular nodes only. If any of the
00350   //vertices are hanging then the regular node that will be used instead is used
00351   //to make the classifications such as ghost or non-ghost elem/node.
00352 
00353   if(data->da->iAmActive()) {
00354     for(data->da->init<ot::DA_FLAGS::DEPENDENT>();
00355         data->da->curr() < data->da->end<ot::DA_FLAGS::DEPENDENT>();
00356         data->da->next<ot::DA_FLAGS::DEPENDENT>() ) {
00357       JACOBIAN_TYPE1_MULT_BLOCK
00358     }//end loop for dependent elems
00359   }
00360 
00361   data->da->vecRestoreBuffer(in,inArr,false,false,true,1);
00362   data->da->vecRestoreBuffer(out,outArr,false,false,false,1);
00363 
00364   //Only useful flops, i.e. flops for the FEM calculation itself, are included.
00365   //The overhead due to looping through the octants and uncompressing the
00366   //nodelist and the transformations for the maps are not included. 
00367   PetscLogFlops(332*(data->da->getGhostedElementSize()));
00368   PetscLogEventEnd(Jac1MultEvent,in,out,0,0);
00369   if(data->isFinestLevel) {
00370     PetscLogEventEnd(Jac1FinestMultEvent,in,out,0,0);
00371   }
00372 
00373   PetscFunctionReturn(0);
00374 }
00375 
00376 #undef JACOBIAN_TYPE1_MULT_BLOCK
00377 
00378 #define MASS_MULT_BLOCK {\
00379   unsigned int lev = data->da->getLevel(data->da->curr());\
00380   double h = hFac*(1u << (maxD - lev));\
00381   double fac2 = h*h*h/8.0;\
00382   unsigned int indices[8];\
00383   data->da->getNodeIndices(indices);\
00384   unsigned char childNum = data->da->getChildNumber();\
00385   unsigned char hnMask = data->da->getHangingNodeIndex(data->da->curr());\
00386   unsigned char elemType = 0;\
00387   GET_ETYPE_BLOCK(elemType,hnMask,childNum)\
00388   for(int k = 0;k < 8;k++) {\
00389     for(int j=0;j<8;j++) {\
00390       outArr[indices[k]] +=  ((fac2*(MassType2Stencil[childNum][elemType][k][j]))*inArr[indices[j]]);\
00391     } /*end for j*/\
00392   } /*end for k*/\
00393 }
00394 
00395 PetscErrorCode MassMatMult(Mat J, Vec in, Vec out)
00396 {
00397   PetscFunctionBegin;
00398   Jac1MFreeData *data;
00399 
00400   iC(MatShellGetContext( J, (void **)&data));  
00401 
00402   iC (VecSet(out, 0));
00403 
00404   unsigned int maxD;
00405   double hFac;
00406 
00407   if(data->da->iAmActive()) {
00408     maxD = data->da->getMaxDepth(); 
00409     hFac = 1.0/((double)(1u << (maxD-1)));
00410   }
00411 
00412   PetscScalar *outArr=NULL;
00413   PetscScalar *inArr=NULL; 
00414   //Nodal,Non-Ghosted,Read,1 dof
00415   data->da->vecGetBuffer(in,inArr,false,false,true,1);
00416 
00417   if(data->da->iAmActive()) {
00418     data->da->ReadFromGhostsBegin<PetscScalar>(inArr,1);
00419   }
00420 
00421   //Nodal,Non-Ghosted,Write,1 dof
00422   data->da->vecGetBuffer(out,outArr,false,false,false,1);
00423 
00424   //Loop through All Independent Elements     
00425   if(data->da->iAmActive()) {
00426     for(data->da->init<ot::DA_FLAGS::INDEPENDENT>();
00427         data->da->curr() < data->da->end<ot::DA_FLAGS::INDEPENDENT>();
00428         data->da->next<ot::DA_FLAGS::INDEPENDENT>() ) {
00429       MASS_MULT_BLOCK
00430     }//end independent
00431   }
00432 
00433   // std::cout << "Finished Independent" << std::endl;
00434   if(data->da->iAmActive()) {
00435     data->da->ReadFromGhostsEnd<PetscScalar>(inArr);
00436   }
00437   //Loop through All Dependent Elements, i.e. Elements which have atleast one
00438   //vertex owned by this processor and at least one vertex not owned by this
00439   //processor. For simplicity, I may write to nodes that I do not own. These
00440   //can be discarded later. Every processor is only supposed to write to the
00441   //nodes it owns. An alternate strategy would require me to check if i own the
00442   //node before i write, I think this might be inefficient. So, if possible
00443   //allow me to write to nodes I do not own. You can discard them while
00444   //restoring the buffers.
00445   //Note: Whenever, I refer to nodes I refer to regular nodes only. If any of the
00446   //vertices are hanging then the regular node that will be used instead is used
00447   //to make the classifications such as ghost or non-ghost elem/node.
00448 
00449   if(data->da->iAmActive()) {
00450     for(data->da->init<ot::DA_FLAGS::DEPENDENT>();
00451         data->da->curr() < data->da->end<ot::DA_FLAGS::DEPENDENT>();
00452         data->da->next<ot::DA_FLAGS::DEPENDENT>() ) {
00453       MASS_MULT_BLOCK
00454     }//end loop for dependent elems
00455   }
00456 
00457   data->da->vecRestoreBuffer(in,inArr,false,false,true,1);
00458 
00459   data->da->vecRestoreBuffer(out,outArr,false,false,false,1);
00460 
00461   PetscFunctionReturn(0);
00462 }
00463 
00464 #undef MASS_MULT_BLOCK 
00465 
00466 PetscErrorCode CreateAndComputeFullJacobian1(ot::DA* da,Mat * J)
00467 {
00468   PetscFunctionBegin;
00469 
00470   assert(da->computedLocalToGlobal());
00471 
00472   char matType[30];
00473   PetscTruth typeFound;
00474   PetscOptionsGetString(PETSC_NULL,"-fullJacMatType",matType,30,&typeFound);
00475   if(!typeFound) {
00476     std::cout<<"I need a MatType for the full Jacobian matrix!"<<std::endl;
00477     MPI_Finalize();
00478     exit(0);            
00479   } 
00480   da->createMatrix(*J, matType, 1);
00481   MatZeroEntries(*J);
00482   std::vector<ot::MatRecord> records;
00483 
00484   unsigned int maxD;
00485   double hFac;
00486   if(da->iAmActive()) {
00487     maxD = da->getMaxDepth(); 
00488     hFac = 1.0/((double)(1u << (maxD-1)));
00489   }
00490 
00491 
00492   PetscReal lapFac = 1.0;
00493   PetscReal massFac = 1.0;
00494   PetscTruth optFound;
00495   PetscOptionsGetReal("lap","-MatPropFac",&lapFac,&optFound);
00496   PetscOptionsGetReal("mass","-MatPropFac",&massFac,&optFound);
00497 
00498   if(da->iAmActive()) {
00499     for(da->init<ot::DA_FLAGS::WRITABLE>();
00500         da->curr() < da->end<ot::DA_FLAGS::WRITABLE>();
00501         da->next<ot::DA_FLAGS::WRITABLE>()) {
00502       unsigned int lev = da->getLevel(da->curr());
00503       double h = hFac*(1u << (maxD - lev));
00504       double fac1 = lapFac*h/2.0;
00505       double fac2 = massFac*h*h*h/8.0;
00506       unsigned int indices[8];
00507       da->getNodeIndices(indices);
00508       unsigned char childNum = da->getChildNumber();
00509       unsigned char hnMask = da->getHangingNodeIndex(da->curr());
00510       unsigned char elemType = 0;
00511       GET_ETYPE_BLOCK(elemType,hnMask,childNum)
00512         for(int k = 0;k < 8;k++) {
00513           for(int j=0;j<8;j++) {
00514             ot::MatRecord currRec;
00515             currRec.rowIdx = indices[k];
00516             currRec.colIdx = indices[j];
00517             currRec.rowDim = 0;
00518             currRec.colDim = 0;
00519             currRec.val = ((fac1*(LaplacianType2Stencil[childNum][elemType][k][j])) +
00520                 (fac2*(MassType2Stencil[childNum][elemType][k][j])));
00521             records.push_back(currRec);
00522           }//end for j
00523         }//end for k
00524       if(records.size() > 1000) {
00525         da->setValuesInMatrix(*J, records, 1, ADD_VALUES);
00526       }
00527     }//end writable
00528   }//end if active
00529 
00530   da->setValuesInMatrix(*J, records, 1, ADD_VALUES);
00531 
00532   MatAssemblyBegin(*J, MAT_FINAL_ASSEMBLY);
00533   MatAssemblyEnd(*J, MAT_FINAL_ASSEMBLY);
00534 
00535   PetscFunctionReturn(0);
00536 }
00537 
00538 PetscErrorCode CreateAndComputeFullActiveJacobian1(ot::DA* da,Mat * J)
00539 {
00540   PetscFunctionBegin;
00541 
00542   assert(da->computedLocalToGlobal());
00543 
00544   if(da->iAmActive()) {
00545     char matType[30];
00546     PetscTruth typeFound;
00547     PetscOptionsGetString(PETSC_NULL,"-fullJacMatType",matType,30,&typeFound);
00548     if(!typeFound) {
00549       std::cout<<"I need a MatType for the full Jacobian matrix!"<<std::endl;
00550       MPI_Finalize();
00551       exit(0);          
00552     } 
00553     da->createActiveMatrix(*J, matType, 1);
00554     MatZeroEntries(*J);
00555     std::vector<ot::MatRecord> records;
00556 
00557     unsigned int maxD;
00558     double hFac;
00559     maxD = da->getMaxDepth(); 
00560     hFac = 1.0/((double)(1u << (maxD-1)));
00561 
00562     PetscReal lapFac = 1.0;
00563     PetscReal massFac = 1.0;
00564     PetscTruth optFound;
00565     PetscOptionsGetReal("lap","-MatPropFac",&lapFac,&optFound);
00566     PetscOptionsGetReal("mass","-MatPropFac",&massFac,&optFound);
00567 
00568     for(da->init<ot::DA_FLAGS::WRITABLE>();
00569         da->curr() < da->end<ot::DA_FLAGS::WRITABLE>();
00570         da->next<ot::DA_FLAGS::WRITABLE>()) {
00571       unsigned int lev = da->getLevel(da->curr());
00572       double h = hFac*(1u << (maxD - lev));
00573       double fac1 = lapFac*h/2.0;
00574       double fac2 = massFac*h*h*h/8.0;
00575       unsigned int indices[8];
00576       da->getNodeIndices(indices);
00577       unsigned char childNum = da->getChildNumber();
00578       unsigned char hnMask = da->getHangingNodeIndex(da->curr());
00579       unsigned char elemType = 0;
00580       GET_ETYPE_BLOCK(elemType,hnMask,childNum)
00581         for(int k = 0;k < 8;k++) {
00582           for(int j=0;j<8;j++) {
00583             ot::MatRecord currRec;
00584             currRec.rowIdx = indices[k];
00585             currRec.colIdx = indices[j];
00586             currRec.rowDim = 0;
00587             currRec.colDim = 0;
00588             currRec.val =
00589               ((fac1*(LaplacianType2Stencil[childNum][elemType][k][j])) +
00590                (fac2*(MassType2Stencil[childNum][elemType][k][j])));
00591             records.push_back(currRec);
00592           }//end for j
00593         }//end for k
00594       if(records.size() > 1000) {
00595         da->setValuesInMatrix(*J, records, 1, ADD_VALUES);
00596       }
00597     }//end writable
00598 
00599     da->setValuesInMatrix(*J, records, 1, ADD_VALUES);
00600 
00601     MatAssemblyBegin(*J, MAT_FINAL_ASSEMBLY);
00602     MatAssemblyEnd(*J, MAT_FINAL_ASSEMBLY);
00603 
00604   }//end if active
00605 
00606   PetscFunctionReturn(0);
00607 }
00608 
00609 
00610 

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