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

elasticityJac.C

Go to the documentation of this file.
00001 
00007 #include "petscmat.h"
00008 #include "omg.h"
00009 #include "oda.h"
00010 #include "odaUtils.h"
00011 #include "elasticityJac.h"
00012 
00013 #ifdef PETSC_USE_LOG
00014 extern int elasticityDiagEvent;
00015 extern int elasticityMultEvent;
00016 extern int elasticityFinestDiagEvent;
00017 extern int elasticityFinestMultEvent;
00018 #endif
00019 
00020 extern double**** LaplacianType2Stencil; 
00021 extern double**** GradDivType2Stencil; 
00022 
00023 void getActiveStateAndActiveCommForKSP_Shell_Elas(Mat mat,
00024     bool & activeState, MPI_Comm & activeComm) {
00025   PetscTruth isshell;
00026   PetscTypeCompare((PetscObject)mat, MATSHELL, &isshell);
00027   assert(isshell);
00028   ot::DAMG damg;
00029   MatShellGetContext(mat, (void**)(&damg));
00030   ot::DA* da = damg->da;
00031   activeState = da->iAmActive();
00032   activeComm = da->getCommActive();
00033 }
00034 
00035 void getPrivateMatricesForKSP_Shell_Elas(Mat mat,
00036     Mat *AmatPrivate, Mat *PmatPrivate, MatStructure* pFlag) {
00037   PetscTruth isshell;
00038   PetscTypeCompare((PetscObject)mat, MATSHELL, &isshell);
00039   assert(isshell);
00040   ot::DAMG damg;
00041   MatShellGetContext(mat, (void**)(&damg));
00042   ElasticityData* data = (static_cast<ElasticityData*>(damg->user));
00043   *AmatPrivate = data->Jmat_private;
00044   *PmatPrivate = data->Jmat_private;
00045   *pFlag = DIFFERENT_NONZERO_PATTERN;
00046 }
00047 
00048 #define ELASTICITY_ELEM_DIAG_BLOCK {\
00049   unsigned int idx = da->curr();\
00050   unsigned int lev = da->getLevel(idx);\
00051   double h = hFac*(1u << (maxD - lev));\
00052   double fac = h/2.0;\
00053   unsigned int indices[8];\
00054   da->getNodeIndices(indices);\
00055   unsigned char childNum = da->getChildNumber();\
00056   unsigned char hnMask = da->getHangingNodeIndex(idx);\
00057   unsigned char elemType = 0;\
00058   GET_ETYPE_BLOCK(elemType,hnMask,childNum)\
00059   for(int k = 0; k < 8; k++) {\
00060     if(bdyArr[indices[k]]) {\
00061       /*Dirichlet Node*/\
00062       for(int dof = 0; dof < 3; dof++) {\
00063         diagArr[(3*indices[k])+dof] = 1.0;\
00064       } /*end dof*/\
00065     } else { \
00066       for(int dof = 0; dof < 3; dof++) {\
00067         diagArr[(3*indices[k])+dof] += (fac*(\
00068               (mu*LaplacianType2Stencil[childNum][elemType][k][k])\
00069               + ((mu+lambda)*GradDivType2Stencil[childNum][elemType][(3*k) + dof][(3*k) + dof])));\
00070       } /*end dof*/\
00071     }\
00072   } /*end k*/\
00073 }
00074 
00075 #define ELASTICITY_DIAG_BLOCK {\
00076   ot::DA* da = damg->da;\
00077   ElasticityData* data = (static_cast<ElasticityData*>(damg->user));\
00078   iC(VecZeroEntries(diag));\
00079   PetscScalar *diagArr = NULL;\
00080   unsigned char* bdyArr = data->bdyArr;\
00081   double mu = data->mu;\
00082   double lambda = data->lambda;\
00083   unsigned int maxD;\
00084   double hFac;\
00085   /*Nodal,Non-Ghosted,Write,3 dof*/\
00086   da->vecGetBuffer(diag,diagArr,false,false,false,3);\
00087   if(da->iAmActive()) {\
00088     maxD = (da->getMaxDepth());\
00089     hFac = 1.0/((double)(1u << (maxD-1)));\
00090     /*Loop through All Elements including ghosted*/\
00091     for(da->init<ot::DA_FLAGS::ALL>();\
00092         da->curr() < da->end<ot::DA_FLAGS::ALL>();\
00093         da->next<ot::DA_FLAGS::ALL>()) {\
00094  ELASTICITY_ELEM_DIAG_BLOCK \
00095     } /*end i*/\
00096   } /*end if active*/\
00097   da->vecRestoreBuffer(diag,diagArr,false,false,false,3);\
00098   /*2 IOP = 1 FLOP. Loop counters are included too.*/\
00099   PetscLogFlops(235*(da->getGhostedElementSize()));\
00100 }
00101 
00102 PetscErrorCode ElasticityMatGetDiagonal(Mat J, Vec diag) {
00103   PetscFunctionBegin;
00104 
00105   PetscLogEventBegin(elasticityDiagEvent,diag,0,0,0);
00106 
00107   ot::DAMG damg;
00108   iC(MatShellGetContext(J, (void**)(&damg)));
00109 
00110   bool isFinestLevel = (damg->nlevels == 1);
00111 
00112   if(isFinestLevel) {
00113     PetscLogEventBegin(elasticityFinestDiagEvent,diag,0,0,0);
00114   }
00115 
00116   ELASTICITY_DIAG_BLOCK  
00117 
00118     if(isFinestLevel) {
00119       PetscLogEventEnd(elasticityFinestDiagEvent,diag,0,0,0);
00120     }
00121 
00122   PetscLogEventEnd(elasticityDiagEvent,diag,0,0,0);
00123 
00124   PetscFunctionReturn(0);
00125 }
00126 
00127 #undef ELASTICITY_DIAG_BLOCK 
00128 #undef ELASTICITY_ELEM_DIAG_BLOCK 
00129 
00130 #define ELASTICITY_ELEM_MULT_BLOCK {\
00131   unsigned int idx = da->curr();\
00132   unsigned int lev = da->getLevel(idx);\
00133   double h = hFac*(1u << (maxD - lev));\
00134   double fac = h/2.0;\
00135   unsigned int indices[8];\
00136   da->getNodeIndices(indices);\
00137   unsigned char childNum = da->getChildNumber();\
00138   unsigned char hnMask = da->getHangingNodeIndex(idx);\
00139   unsigned char elemType = 0;\
00140   GET_ETYPE_BLOCK(elemType,hnMask,childNum)\
00141   for(int k = 0;k < 8;k++) {\
00142     if(bdyArr[indices[k]]) {\
00143       /*Dirichlet Node Row*/\
00144       for(int dof = 0; dof < 3; dof++) {\
00145         outArr[(3*indices[k]) + dof] =  inArr[(3*indices[k]) + dof];\
00146       }/*end for dof*/\
00147     } else {\
00148       for(int j=0;j<8;j++) {\
00149         /*Avoid Dirichlet Node Columns*/\
00150         if(!(bdyArr[indices[j]])) {\
00151           for(int dof = 0; dof < 3; dof++) {\
00152             outArr[(3*indices[k]) + dof] += (mu*fac*LaplacianType2Stencil[childNum][elemType][k][j]\
00153                 *inArr[(3*indices[j]) + dof]);\
00154           }/*end for dof*/\
00155           for(int dofOut = 0; dofOut < 3; dofOut++) {\
00156             for(int dofIn = 0; dofIn < 3; dofIn++) {\
00157               outArr[(3*indices[k]) + dofOut] += ((mu+lambda)*fac*\
00158                   (GradDivType2Stencil[childNum][elemType][(3*k) + dofOut][(3*j) + dofIn])\
00159                   *inArr[(3*indices[j]) + dofIn]);\
00160             }/*end for dofIn*/\
00161           }/*end for dofOut*/\
00162         }\
00163       }/*end for j*/\
00164     }\
00165   }/*end for k*/\
00166 }
00167 
00168 #define ELASTICITY_MULT_BLOCK {\
00169   ot::DA* da = damg->da;\
00170   ElasticityData* data = (static_cast<ElasticityData*>(damg->user));\
00171   iC(VecZeroEntries(out));\
00172   unsigned int maxD;\
00173   double hFac;\
00174   if(da->iAmActive()) {\
00175     maxD = da->getMaxDepth();\
00176     hFac = 1.0/((double)(1u << (maxD-1)));\
00177   }\
00178   PetscScalar *outArr=NULL;\
00179   PetscScalar *inArr=NULL;\
00180   unsigned char* bdyArr = data->bdyArr;\
00181   double mu = data->mu;\
00182   double lambda = data->lambda;\
00183   /*Nodal,Non-Ghosted,Read,3 dof*/\
00184   da->vecGetBuffer(in,inArr,false,false,true,3);\
00185   /*Nodal,Non-Ghosted,Write,3 dof*/\
00186   da->vecGetBuffer(out,outArr,false,false,false,3);\
00187   if(da->iAmActive()) {\
00188     da->ReadFromGhostsBegin<PetscScalar>(inArr,3);\
00189     /*Loop through All Independent Elements*/\
00190     for(da->init<ot::DA_FLAGS::INDEPENDENT>();\
00191         da->curr() < da->end<ot::DA_FLAGS::INDEPENDENT>();\
00192         da->next<ot::DA_FLAGS::INDEPENDENT>() ) {\
00193  ELASTICITY_ELEM_MULT_BLOCK \
00194     } /*end independent*/\
00195     da->ReadFromGhostsEnd<PetscScalar>(inArr);\
00196     /*Loop through All Dependent Elements,*/\
00197     /*i.e. Elements which have atleast one*/\
00198     /*vertex owned by this processor and at least one*/\
00199     /*vertex not owned by this processor.*/\
00200     for(da->init<ot::DA_FLAGS::DEPENDENT>();\
00201         da->curr() < da->end<ot::DA_FLAGS::DEPENDENT>();\
00202         da->next<ot::DA_FLAGS::DEPENDENT>() ) {\
00203  ELASTICITY_ELEM_MULT_BLOCK \
00204     } /*end loop for dependent elems*/\
00205   } /*end if active*/\
00206   da->vecRestoreBuffer(in,inArr,false,false,true,3);\
00207   da->vecRestoreBuffer(out,outArr,false,false,false,3);\
00208   /*2 IOP = 1 FLOP. Loop counters are included too.*/\
00209   PetscLogFlops(6855*(da->getGhostedElementSize()));\
00210 }
00211 
00212 PetscErrorCode ElasticityMatMult(Mat J, Vec in, Vec out)
00213 {
00214   PetscFunctionBegin;
00215 
00216   PetscLogEventBegin(elasticityMultEvent,in,out,0,0);
00217 
00218   ot::DAMG damg;
00219   iC(MatShellGetContext(J, (void**)(&damg)));
00220 
00221   bool isFinestLevel = (damg->nlevels == 1);
00222 
00223   if(isFinestLevel) {
00224     PetscLogEventBegin(elasticityFinestMultEvent,in,out,0,0);
00225   }
00226 
00227   ELASTICITY_MULT_BLOCK 
00228 
00229     if(isFinestLevel) {
00230       PetscLogEventEnd(elasticityFinestMultEvent,in,out,0,0);
00231     }
00232 
00233   PetscLogEventEnd(elasticityMultEvent,in,out,0,0);
00234 
00235   PetscFunctionReturn(0);
00236 }
00237 
00238 #undef ELASTICITY_ELEM_MULT_BLOCK 
00239 #undef ELASTICITY_MULT_BLOCK 
00240 
00241 #define BUILD_FULL_ELASTICITY_ELEM_ADD_BLOCK {\
00242   unsigned int idx = da->curr();\
00243   unsigned int lev = da->getLevel(idx);\
00244   double h = hFac*(1u << (maxD - lev));\
00245   double fac = h/2.0;\
00246   unsigned int indices[8];\
00247   da->getNodeIndices(indices);\
00248   unsigned char childNum = da->getChildNumber();\
00249   unsigned char hnMask = da->getHangingNodeIndex(idx);\
00250   unsigned char elemType = 0;\
00251   GET_ETYPE_BLOCK(elemType,hnMask,childNum)\
00252   for(int k = 0;k < 8;k++) {\
00253     /*Avoid Dirichlet Node Rows during ADD_VALUES loop.*/\
00254     /*Need a separate INSERT_VALUES loop for those*/\
00255     if(!(bdyArr[indices[k]])) {\
00256       for(int j=0;j<8;j++) {\
00257         if(!(bdyArr[indices[j]])) {\
00258           for(int dof = 0; dof < 3; dof++) {\
00259             ot::MatRecord currRec;\
00260             currRec.rowIdx = indices[k];\
00261             currRec.colIdx = indices[j];\
00262             currRec.rowDim = dof;\
00263             currRec.colDim = dof;\
00264             currRec.val = (mu*fac*\
00265                 LaplacianType2Stencil[childNum][elemType][k][j]);\
00266             records.push_back(currRec);\
00267           } /*end for dof*/\
00268           for(int dofOut = 0; dofOut < 3; dofOut++) {\
00269             for(int dofIn = 0; dofIn < 3; dofIn++) {\
00270               ot::MatRecord currRec;\
00271               currRec.rowIdx = indices[k];\
00272               currRec.colIdx = indices[j];\
00273               currRec.rowDim = dofOut;\
00274               currRec.colDim = dofIn;\
00275               currRec.val = ((mu+lambda)*fac*\
00276                   GradDivType2Stencil[childNum][elemType][(3*k)+dofOut][(3*j)+dofIn]);\
00277               records.push_back(currRec);\
00278             } /*end for dofIn*/\
00279           } /*end for dofOut*/\
00280         }\
00281       } /*end for j*/\
00282     }\
00283   } /*end for k*/\
00284   if(records.size() > 1000) {\
00285     /*records will be cleared inside the function*/\
00286     da->setValuesInMatrix(B, records, 3, ADD_VALUES);\
00287   }\
00288 }
00289 
00290 #define BUILD_FULL_ELASTICITY_ELEM_INSERT_BLOCK {\
00291   unsigned int idx = da->curr();\
00292   unsigned int lev = da->getLevel(idx);\
00293   double h = hFac*(1u << (maxD - lev));\
00294   double fac = h/2.0;\
00295   unsigned int indices[8];\
00296   da->getNodeIndices(indices);\
00297   unsigned char childNum = da->getChildNumber();\
00298   unsigned char hnMask = da->getHangingNodeIndex(idx);\
00299   unsigned char elemType = 0;\
00300   GET_ETYPE_BLOCK(elemType,hnMask,childNum)\
00301   for(int k = 0;k < 8;k++) {\
00302     /*Insert values for Dirichlet Node Rows only.*/\
00303     if(bdyArr[indices[k]]) {\
00304       for(int dof = 0; dof < 3; dof++) {\
00305         ot::MatRecord currRec;\
00306         currRec.rowIdx = indices[k];\
00307         currRec.colIdx = indices[k];\
00308         currRec.rowDim = dof;\
00309         currRec.colDim = dof;\
00310         currRec.val = 1.0;\
00311         records.push_back(currRec);\
00312       } /*end for dof*/\
00313     }\
00314   } /*end for k*/\
00315   if(records.size() > 1000) {\
00316     /*records will be cleared inside the function*/\
00317     da->setValuesInMatrix(B, records, 3, INSERT_VALUES);\
00318   }\
00319 }
00320 
00321 #define BUILD_FULL_ELASTICITY_BLOCK {\
00322   ot::DA* da = damg->da;\
00323   MatZeroEntries(B);\
00324   std::vector<ot::MatRecord> records;\
00325   unsigned int maxD;\
00326   double hFac;\
00327   if(da->iAmActive()) {\
00328     maxD = da->getMaxDepth();\
00329     hFac = 1.0/((double)(1u << (maxD-1)));\
00330   }\
00331   unsigned char* bdyArr = data->bdyArr;\
00332   double mu = data->mu;\
00333   double lambda = data->lambda;\
00334   if(da->iAmActive()) {\
00335     for(da->init<ot::DA_FLAGS::WRITABLE>();\
00336         da->curr() < da->end<ot::DA_FLAGS::WRITABLE>();\
00337         da->next<ot::DA_FLAGS::WRITABLE>()) {\
00338  BUILD_FULL_ELASTICITY_ELEM_ADD_BLOCK \
00339     } /*end writable*/\
00340   } /*end if active*/\
00341   da->setValuesInMatrix(B, records, 3, ADD_VALUES);\
00342   MatAssemblyBegin(B, MAT_FLUSH_ASSEMBLY);\
00343   MatAssemblyEnd(B, MAT_FLUSH_ASSEMBLY);\
00344   if(da->iAmActive()) {\
00345     for(da->init<ot::DA_FLAGS::WRITABLE>();\
00346         da->curr() < da->end<ot::DA_FLAGS::WRITABLE>();\
00347         da->next<ot::DA_FLAGS::WRITABLE>()) {\
00348  BUILD_FULL_ELASTICITY_ELEM_INSERT_BLOCK \
00349     } /*end writable*/\
00350   } /*end if active*/\
00351   da->setValuesInMatrix(B, records, 3, INSERT_VALUES);\
00352   MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY);\
00353   MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY);\
00354   if(data->bdyArr) {\
00355     delete [] (data->bdyArr);\
00356     data->bdyArr = NULL;\
00357   }\
00358 }
00359 
00360 PetscErrorCode ComputeElasticityMat(ot::DAMG damg, Mat J, Mat B) {
00361   //For matShells nothing to be done here.
00362   PetscFunctionBegin;
00363 
00364   ElasticityData* data = (static_cast<ElasticityData*>(damg->user));
00365 
00366   PetscTruth isshell;
00367   PetscTypeCompare((PetscObject)B, MATSHELL, &isshell);
00368 
00369   assert(J == B);
00370 
00371   if(isshell) {
00372     if( data->Jmat_private == NULL ) {
00373       //inactive processors will return
00374       PetscFunctionReturn(0);
00375     } else {
00376       J = data->Jmat_private;
00377       B = data->Jmat_private;
00378     }
00379   }
00380 
00381   PetscTypeCompare((PetscObject)B, MATSHELL, &isshell);
00382 
00383   if(isshell) {
00384     PetscFunctionReturn(0);
00385   }
00386 
00387   BUILD_FULL_ELASTICITY_BLOCK
00388 
00389     PetscFunctionReturn(0);
00390 }
00391 
00392 #undef BUILD_FULL_ELASTICITY_ELEM_ADD_BLOCK 
00393 #undef BUILD_FULL_ELASTICITY_ELEM_INSERT_BLOCK 
00394 #undef BUILD_FULL_ELASTICITY_BLOCK 
00395 
00396 void SetElasticityContexts(ot::DAMG* damg) {
00397   int       nlevels = damg[0]->nlevels; //number of multigrid levels
00398   PetscReal muVal = 1.0;
00399   PetscReal lambdaVal = 1.0;
00400   PetscTruth optFound;
00401   PetscOptionsGetReal("elasticity","-_mu", &muVal, &optFound);
00402   PetscOptionsGetReal("elasticity","-_lambda", &lambdaVal, &optFound);
00403   for(int i = 0; i < nlevels; i++) {
00404     ElasticityData* ctx= new ElasticityData;
00405     ctx->mu = muVal;
00406     ctx->lambda = lambdaVal;
00407     ctx->bdyArr = NULL;
00408     ctx->Jmat_private = NULL;
00409     ctx->inTmp = NULL;
00410     ctx->outTmp = NULL;
00411 
00412     std::vector<unsigned char> tmpBdyFlags;
00413     std::vector<unsigned char> tmpBdyFlagsAux;
00414     unsigned char* bdyArrAux = NULL;
00415 
00416     //This will create a nodal, non-ghosted, 1 dof array
00417     assignBoundaryFlags(damg[i]->da, tmpBdyFlags);
00418     ((damg[i])->da)->vecGetBuffer<unsigned char>(tmpBdyFlags, ctx->bdyArr, false, false, true, 1);
00419     if(damg[i]->da->iAmActive()) {
00420       ((damg[i])->da)->ReadFromGhostsBegin<unsigned char>(ctx->bdyArr, 1);
00421     }
00422 
00423     if(damg[i]->da_aux) {
00424       assignBoundaryFlags( damg[i]->da_aux, tmpBdyFlagsAux);
00425       ((damg[i])->da_aux)->vecGetBuffer<unsigned char>(tmpBdyFlagsAux, bdyArrAux,
00426         false, false, true, 1);
00427       if(damg[i]->da_aux->iAmActive()) {
00428         ((damg[i])->da_aux)->ReadFromGhostsBegin<unsigned char>(bdyArrAux, 1);
00429       }
00430     }
00431 
00432     tmpBdyFlags.clear();
00433     tmpBdyFlagsAux.clear();
00434 
00435     if(damg[i]->da->iAmActive()) {
00436       ((damg[i])->da)->ReadFromGhostsEnd<unsigned char>(ctx->bdyArr);
00437     }
00438 
00439     if((damg[i])->da_aux) {
00440       if(damg[i]->da_aux->iAmActive()) {
00441         ((damg[i])->da_aux)->ReadFromGhostsEnd<unsigned char>(bdyArrAux);
00442       }
00443     }
00444 
00445     for(int loopCtr = 0; loopCtr < 2; loopCtr++) {
00446       ot::DA* da = NULL;
00447       unsigned char* suppressedDOFptr = NULL;
00448       unsigned char* bdyArrPtr = NULL;
00449       if(loopCtr == 0) {
00450         da = damg[i]->da;
00451         suppressedDOFptr = damg[i]->suppressedDOF;
00452         bdyArrPtr = ctx->bdyArr;
00453       } else {
00454         da = damg[i]->da_aux;
00455         suppressedDOFptr = damg[i]->suppressedDOFaux;
00456         bdyArrPtr = bdyArrAux;
00457       }
00458       if(da) {
00459         if(da->iAmActive()) {
00460           for(da->init<ot::DA_FLAGS::ALL>(); 
00461               da->curr() < da->end<ot::DA_FLAGS::ALL>();
00462               da->next<ot::DA_FLAGS::ALL>()) {
00463             unsigned int indices[8];
00464             da->getNodeIndices(indices);
00465             for(unsigned int k = 0; k < 8; k++) {
00466               for(unsigned int d = 0; d < 3; d++) {
00467                 suppressedDOFptr[(3*indices[k]) + d] = bdyArrPtr[indices[k]];
00468               }
00469             }
00470           }
00471         }
00472       }
00473     }
00474 
00475     if(bdyArrAux) {
00476       delete [] bdyArrAux;
00477       bdyArrAux = NULL;
00478     }
00479 
00480     (damg[i])->user = ctx;
00481   }//end for i
00482 
00483 }//end fn.
00484 
00485 void DestroyElasticityContexts(ot::DAMG* damg) {
00486   int       nlevels = damg[0]->nlevels; //number of multigrid levels
00487   for(int i = 0; i < nlevels; i++) {
00488     ElasticityData* ctx = (static_cast<ElasticityData*>(damg[i]->user));
00489     if(ctx->bdyArr) {
00490       delete [] (ctx->bdyArr);
00491       ctx->bdyArr = NULL;
00492     }
00493     if(ctx->Jmat_private) {
00494       MatDestroy(ctx->Jmat_private);
00495       ctx->Jmat_private = NULL;
00496     }
00497     if(ctx->inTmp) {
00498       VecDestroy(ctx->inTmp);
00499       ctx->inTmp = NULL;
00500     }
00501     if(ctx->outTmp) {
00502       VecDestroy(ctx->outTmp);
00503       ctx->outTmp = NULL;
00504     }
00505     delete ctx;
00506     ctx = NULL;
00507   }
00508 }//end fn.
00509 
00510 PetscErrorCode ElasticityShellMatMult(Mat J, Vec in, Vec out)
00511 {
00512   PetscFunctionBegin;
00513 
00514   ot::DAMG damg;
00515   iC(MatShellGetContext(J, (void**)(&damg)));
00516 
00517   ElasticityData* ctx = (static_cast<ElasticityData*>(damg->user));
00518 
00519   if(damg->da->iAmActive()) {      
00520     PetscScalar* inArray;
00521     PetscScalar* outArray;
00522 
00523     VecGetArray(in, &inArray);
00524     VecGetArray(out, &outArray);
00525 
00526     VecPlaceArray(ctx->inTmp, inArray);
00527     VecPlaceArray(ctx->outTmp, outArray);
00528 
00529     MatMult(ctx->Jmat_private, ctx->inTmp, ctx->outTmp);
00530 
00531     VecResetArray(ctx->inTmp);
00532     VecResetArray(ctx->outTmp);
00533 
00534     VecRestoreArray(in, &inArray);
00535     VecRestoreArray(out, &outArray);
00536   }
00537 
00538   PetscFunctionReturn(0);
00539 }
00540 
00541 PetscErrorCode CreateElasticityMat(ot::DAMG damg, Mat *jac) {
00542   PetscFunctionBegin;
00543   PetscInt buildFullCoarseMat;
00544   PetscInt buildFullMatAll;
00545   int totalLevels;
00546   PetscTruth flg;
00547   PetscOptionsGetInt(PETSC_NULL,"-buildFullCoarseMat",&buildFullCoarseMat,&flg);
00548   PetscOptionsGetInt(PETSC_NULL,"-buildFullMatAll",&buildFullMatAll,&flg);
00549   if(buildFullMatAll) {
00550     buildFullCoarseMat = 1;
00551   }
00552   totalLevels = damg->totalLevels;
00553   ot::DA* da = damg->da;
00554   int myRank;
00555   MPI_Comm_rank(da->getComm(), &myRank);
00556   if( totalLevels == damg->nlevels ) {
00557     //This is the coarsest.
00558     if( (!myRank) && (buildFullCoarseMat) ) {
00559       std::cout<<"Building Full elasticity Mat at the coarsest level."<<std::endl;
00560     }
00561     char matType[30];
00562     if(buildFullCoarseMat) {
00563       if(!(da->computedLocalToGlobal())) {
00564         da->computeLocalToGlobalMappings();
00565       }
00566       PetscTruth typeFound;
00567       PetscOptionsGetString(PETSC_NULL,"-fullJacMatType",matType,30,&typeFound);
00568       if(!typeFound) {
00569         std::cout<<"I need a MatType for the full matrix!"<<std::endl;
00570         assert(false);
00571       }
00572     }
00573     bool requirePrivateMats = (da->getNpesActive() != da->getNpesAll());    
00574     if(requirePrivateMats) {
00575       unsigned int  m,n;
00576       m=n=(3*(da->getNodeSize()));
00577       ElasticityData* ctx = (static_cast<ElasticityData*>(damg->user));
00578       if(da->iAmActive()) {
00579         if(buildFullCoarseMat) {
00580           da->createActiveMatrix(ctx->Jmat_private, matType, 3);
00581         } else {
00582           MatCreateShell(da->getCommActive(), m ,n, PETSC_DETERMINE,
00583               PETSC_DETERMINE, damg, (&(ctx->Jmat_private)));
00584 
00585           MatShellSetOperation(ctx->Jmat_private, MATOP_MULT,
00586               (void (*)(void)) ElasticityMatMult);
00587 
00588           MatShellSetOperation(ctx->Jmat_private, MATOP_GET_DIAGONAL,
00589               (void (*)(void)) ElasticityMatGetDiagonal);
00590 
00591           MatShellSetOperation(ctx->Jmat_private, MATOP_DESTROY,
00592               (void (*)(void)) ElasticityMatDestroy);
00593         }
00594         MatGetVecs(ctx->Jmat_private, &(ctx->inTmp), &(ctx->outTmp));
00595       } else {
00596         ctx->Jmat_private = NULL;
00597       }
00598       //Need a MATShell wrapper anyway. But, the matvecs are not implemented for
00599       //this matrix. However, a matmult function is required for compute
00600       //residuals
00601       MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE, PETSC_DETERMINE, damg, jac);
00602       MatShellSetOperation(*jac ,MATOP_DESTROY, (void (*)(void)) ElasticityMatDestroy);
00603       MatShellSetOperation(*jac, MATOP_MULT, (void (*)(void)) ElasticityShellMatMult);
00604     } else {
00605       if(buildFullCoarseMat) {
00606         da->createMatrix(*jac, matType, 3);
00607       } else {
00608         unsigned int  m,n;
00609         m=n=(3*(da->getNodeSize()));
00610         MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE, PETSC_DETERMINE, damg, jac);
00611         MatShellSetOperation(*jac ,MATOP_MULT, (void (*)(void)) ElasticityMatMult);
00612         MatShellSetOperation(*jac ,MATOP_GET_DIAGONAL, (void (*)(void)) ElasticityMatGetDiagonal);
00613         MatShellSetOperation(*jac ,MATOP_DESTROY, (void (*)(void)) ElasticityMatDestroy);
00614       }
00615     }
00616     if( (!myRank) && (buildFullCoarseMat) ) {
00617       std::cout<<"Finished Building Full elasticity Mat at the coarsest level."<<std::endl;
00618     }
00619   }else {  
00620     //This is not the coarsest level. No need to bother with KSP_Shell
00621     if(buildFullMatAll) {
00622       if( !myRank ) {
00623         std::cout<<"Building Full elasticity Mat at level: "<<(damg->nlevels)<<std::endl;
00624       }
00625       if(!(da->computedLocalToGlobal())) {
00626         da->computeLocalToGlobalMappings();
00627       }
00628       char matType[30];
00629       PetscTruth typeFound;
00630       PetscOptionsGetString(PETSC_NULL,"-fullJacMatType",matType,30,&typeFound);
00631       if(!typeFound) {
00632         std::cout<<"I need a MatType for the full matrix!"<<std::endl;
00633         assert(false);
00634       }
00635       da->createMatrix(*jac, matType, 3);
00636       if(!myRank) {
00637         std::cout<<"Finished Building Full elasticity Mat at level: "<<(damg->nlevels)<<std::endl;
00638       }
00639     } else {
00640       //Create a MATShell
00641       //The size this processor owns ( without ghosts).
00642       unsigned int  m,n;
00643       m=n=(3*(da->getNodeSize()));
00644       MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE, PETSC_DETERMINE, damg, jac);
00645       MatShellSetOperation(*jac ,MATOP_MULT, (void (*)(void)) ElasticityMatMult);
00646       MatShellSetOperation(*jac ,MATOP_GET_DIAGONAL, (void (*)(void)) ElasticityMatGetDiagonal);
00647       MatShellSetOperation(*jac ,MATOP_DESTROY, (void (*)(void)) ElasticityMatDestroy);
00648     }
00649   }
00650   PetscFunctionReturn(0);
00651 }//end fn.
00652 
00653 PetscErrorCode ElasticityMatDestroy(Mat J) {
00654   PetscFunctionBegin;
00655   //Nothing to be done here. No new pointers were created during creation. 
00656   PetscFunctionReturn(0);
00657 }
00658 
00659 //Functions required in order to use BlockDiag PC
00660 
00661 void computeInvBlockDiagEntriesForElasticityMat(Mat J, double **invBlockDiagEntries) {
00662   ot::DAMG damg;
00663   MatShellGetContext(J, (void**)(&damg));
00664   ElasticityData* data = (static_cast<ElasticityData*>(damg->user));
00665   ot::DA* da = damg->da;
00666   unsigned int dof = 3;
00667   unsigned int nodeSize = damg->da->getNodeSize();
00668 
00669   //Initialize
00670   for(int i = 0; i < (dof*nodeSize); i++ ) {
00671     for(int j = 0; j < dof; j++) {
00672       invBlockDiagEntries[i][j] = 0.0;
00673     }//end for j
00674   }//end for i
00675 
00676   unsigned char* bdyArr = data->bdyArr;
00677   double mu = data->mu;
00678   double lambda = data->lambda;
00679   unsigned int maxD;
00680   double hFac;
00681 
00682   std::vector<double> blockDiagVec;
00683   da->createVector<double>(blockDiagVec, false, false, 9);
00684   for(unsigned int i = 0; i < blockDiagVec.size(); i++) {
00685     blockDiagVec[i] = 0.0;
00686   }
00687 
00688   double *blockDiagArr;
00689   /*Nodal,Non-Ghosted,Write,9 dof*/
00690   da->vecGetBuffer<double>(blockDiagVec, blockDiagArr, false, false, false, 9);
00691 
00692   if(da->iAmActive()) {
00693     maxD = (da->getMaxDepth());
00694     hFac = 1.0/((double)(1u << (maxD-1)));
00695     /*Loop through All Elements including ghosted*/
00696     for(da->init<ot::DA_FLAGS::ALL>();
00697         da->curr() < da->end<ot::DA_FLAGS::ALL>();
00698         da->next<ot::DA_FLAGS::ALL>()) {
00699       unsigned int idx = da->curr();
00700       unsigned int lev = da->getLevel(idx);
00701       double h = hFac*(1u << (maxD - lev));
00702       double fac = h/2.0;
00703       unsigned int indices[8];
00704       da->getNodeIndices(indices);
00705       unsigned char childNum = da->getChildNumber();
00706       unsigned char hnMask = da->getHangingNodeIndex(idx);
00707       unsigned char elemType = 0;
00708       GET_ETYPE_BLOCK(elemType,hnMask,childNum)
00709         for(int k = 0; k < 8; k++) {
00710           if(bdyArr[indices[k]]) {
00711             /*Dirichlet Node*/
00712             for(int dof = 0; dof < 3; dof++) {
00713               blockDiagArr[(9*indices[k]) + (3*dof) + dof] = 1.0;
00714             } /*end dof*/
00715           } else { 
00716             for(int dof = 0; dof < 3; dof++) {
00717               blockDiagArr[(9*indices[k])+(3*dof) + dof] += (mu*fac*
00718                   LaplacianType2Stencil[childNum][elemType][k][k]);
00719             } /*end dof*/
00720             for(int dofOut = 0; dofOut < 3; dofOut++) {
00721               for(int dofIn = 0; dofIn < 3; dofIn++) {
00722                 blockDiagArr[(9*indices[k]) + (3*dofOut) + dofIn] +=
00723                   ((mu+lambda)*fac*
00724                    GradDivType2Stencil[childNum][elemType][(3*k) + dofOut][(3*k) + dofIn]);
00725               }/*end dofIn*/
00726             } /*end dofOut*/
00727           }
00728         } /*end k*/
00729     } /*end i*/
00730   } /*end if active*/
00731 
00732   da->vecRestoreBuffer<double>(blockDiagVec,blockDiagArr,false,false,false,9);
00733 
00734   for(unsigned int i = 0; i < nodeSize; i++) {
00735     double a11 = blockDiagVec[(9*i)];
00736     double a12 = blockDiagVec[(9*i)+1];
00737     double a13 = blockDiagVec[(9*i)+2];
00738     double a21 = blockDiagVec[(9*i)+3];
00739     double a22 = blockDiagVec[(9*i)+4];
00740     double a23 = blockDiagVec[(9*i)+5];
00741     double a31 = blockDiagVec[(9*i)+6];
00742     double a32 = blockDiagVec[(9*i)+7];
00743     double a33 = blockDiagVec[(9*i)+8];
00744 
00745     double detA = ((a11*a22*a33)-(a11*a23*a32)-(a21*a12*a33)
00746         +(a21*a13*a32)+(a31*a12*a23)-(a31*a13*a22));
00747 
00748     invBlockDiagEntries[3*i][0] = (a22*a33-a23*a32)/detA;
00749 
00750     invBlockDiagEntries[3*i][1] = -(a12*a33-a13*a32)/detA;
00751 
00752     invBlockDiagEntries[3*i][2] = (a12*a23-a13*a22)/detA;
00753 
00754     invBlockDiagEntries[(3*i)+1][0] = -(a21*a33-a23*a31)/detA;
00755 
00756     invBlockDiagEntries[(3*i)+1][1] = (a11*a33-a13*a31)/detA;
00757 
00758     invBlockDiagEntries[(3*i)+1][2] = -(a11*a23-a13*a21)/detA;
00759 
00760     invBlockDiagEntries[(3*i)+2][0] = (a21*a32-a22*a31)/detA;
00761 
00762     invBlockDiagEntries[(3*i)+2][1] = -(a11*a32-a12*a31)/detA;
00763 
00764     invBlockDiagEntries[(3*i)+2][2] = (a11*a22-a12*a21)/detA;
00765   }//end for i
00766 
00767   blockDiagVec.clear();
00768 }
00769 
00770 
00771 void getDofAndNodeSizeForElasticityMat(Mat J, unsigned int & dof, unsigned int & nodeSize) {
00772   ot::DAMG damg;
00773   MatShellGetContext(J, (void**)(&damg));
00774 
00775   dof = 3;
00776   nodeSize = damg->da->getNodeSize();
00777 }
00778 

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