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 \
00062 for(int dof = 0; dof < 3; dof++) {\
00063 diagArr[(3*indices[k])+dof] = 1.0;\
00064 } \
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 } \
00071 }\
00072 } \
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 \
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 \
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 } \
00096 } \
00097 da->vecRestoreBuffer(diag,diagArr,false,false,false,3);\
00098 \
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 \
00144 for(int dof = 0; dof < 3; dof++) {\
00145 outArr[(3*indices[k]) + dof] = inArr[(3*indices[k]) + dof];\
00146 }\
00147 } else {\
00148 for(int j=0;j<8;j++) {\
00149 \
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 }\
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 }\
00161 }\
00162 }\
00163 }\
00164 }\
00165 }\
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 \
00184 da->vecGetBuffer(in,inArr,false,false,true,3);\
00185 \
00186 da->vecGetBuffer(out,outArr,false,false,false,3);\
00187 if(da->iAmActive()) {\
00188 da->ReadFromGhostsBegin<PetscScalar>(inArr,3);\
00189 \
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 } \
00195 da->ReadFromGhostsEnd<PetscScalar>(inArr);\
00196 \
00197 \
00198 \
00199 \
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 } \
00205 } \
00206 da->vecRestoreBuffer(in,inArr,false,false,true,3);\
00207 da->vecRestoreBuffer(out,outArr,false,false,false,3);\
00208 \
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 \
00254 \
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 } \
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 } \
00279 } \
00280 }\
00281 } \
00282 }\
00283 } \
00284 if(records.size() > 1000) {\
00285 \
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 \
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 } \
00313 }\
00314 } \
00315 if(records.size() > 1000) {\
00316 \
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 } \
00340 } \
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 } \
00350 } \
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
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
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;
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
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 }
00482
00483 }
00484
00485 void DestroyElasticityContexts(ot::DAMG* damg) {
00486 int nlevels = damg[0]->nlevels;
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 }
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
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
00599
00600
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
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
00641
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 }
00652
00653 PetscErrorCode ElasticityMatDestroy(Mat J) {
00654 PetscFunctionBegin;
00655
00656 PetscFunctionReturn(0);
00657 }
00658
00659
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
00670 for(int i = 0; i < (dof*nodeSize); i++ ) {
00671 for(int j = 0; j < dof; j++) {
00672 invBlockDiagEntries[i][j] = 0.0;
00673 }
00674 }
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
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
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
00712 for(int dof = 0; dof < 3; dof++) {
00713 blockDiagArr[(9*indices[k]) + (3*dof) + dof] = 1.0;
00714 }
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 }
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 }
00726 }
00727 }
00728 }
00729 }
00730 }
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 }
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