00001
00007 #include "petsc.h"
00008 #include "petscmat.h"
00009 #include "petscvec.h"
00010 #include "omg.h"
00011 #include "oda.h"
00012 #include "omgJac.h"
00013 #include "odaJac.h"
00014
00015 #ifdef PETSC_USE_LOG
00016 extern int Jac2MultEvent;
00017 extern int Jac2DiagEvent;
00018 extern int Jac2FinestMultEvent;
00019 extern int Jac2FinestDiagEvent;
00020
00021 extern int Jac3MultEvent;
00022 extern int Jac3DiagEvent;
00023 extern int Jac3FinestMultEvent;
00024 extern int Jac3FinestDiagEvent;
00025 #endif
00026
00027 extern double***** LaplacianType1Stencil;
00028 extern double***** MassType1Stencil;
00029
00030 extern double**** LaplacianType2Stencil;
00031 extern double**** MassType2Stencil;
00032
00033 PetscErrorCode CreateTmpDirichletLaplacian(ot::DAMG damg, Mat *jac) {
00034 PetscFunctionBegin;
00035 ot::DA* da = damg->da;
00036
00037 unsigned int m,n;
00038 m=n=da->getNodeSize();
00039
00040 MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE, PETSC_DETERMINE, damg, jac);
00041 MatShellSetOperation(*jac ,MATOP_MULT, (void (*)(void)) TmpDirichletLaplacianMatMult);
00042 MatShellSetOperation(*jac ,MATOP_DESTROY, (void (*)(void)) DirichletLaplacianMatDestroy);
00043
00044 PetscFunctionReturn(0);
00045 }
00046
00047 PetscErrorCode CreateTmpDirichletJacobian(ot::DAMG damg, Mat *jac) {
00048 PetscFunctionBegin;
00049 ot::DA* da = damg->da;
00050
00051 unsigned int m,n;
00052 m=n=da->getNodeSize();
00053
00054 MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE, PETSC_DETERMINE, damg, jac);
00055 MatShellSetOperation(*jac ,MATOP_MULT, (void (*)(void)) TmpDirichletJacobianMatMult);
00056 MatShellSetOperation(*jac ,MATOP_DESTROY, (void (*)(void)) DirichletJacobianMatDestroy);
00057
00058 PetscFunctionReturn(0);
00059 }
00060
00061 PetscErrorCode CreateDirichletLaplacian(ot::DAMG damg, Mat *jac) {
00062 PetscFunctionBegin;
00063 int totalLevels;
00064 PetscTruth flg;
00065 PetscInt buildFullCoarseMat;
00066 PetscInt buildFullMatAll;
00067 PetscOptionsGetInt(PETSC_NULL,"-buildFullMatAll",&buildFullMatAll,&flg);
00068 PetscOptionsGetInt(PETSC_NULL,"-buildFullCoarseMat",&buildFullCoarseMat,&flg);
00069 if(buildFullMatAll) {
00070 buildFullCoarseMat = 1;
00071 }
00072 totalLevels = damg->totalLevels;
00073 ot::DA* da = damg->da;
00074 int myRank;
00075 MPI_Comm_rank(da->getComm(),&myRank);
00076
00077 unsigned int m,n;
00078 m=n=da->getNodeSize();
00079 if(totalLevels == damg->nlevels) {
00080
00081 if( (!myRank) && buildFullCoarseMat ) {
00082 std::cout<<"Building Full Coarse Mat."<<std::endl;
00083 }
00084 char matType[30];
00085 if(buildFullCoarseMat) {
00086 if(!(da->computedLocalToGlobal())) {
00087 da->computeLocalToGlobalMappings();
00088 }
00089 PetscTruth typeFound;
00090 PetscOptionsGetString(PETSC_NULL,"-fullJacMatType",matType,30,&typeFound);
00091 if(!typeFound) {
00092 std::cout<<"I need a MatType for the full Jacobian matrix!"<<std::endl;
00093 assert(false);
00094 }
00095 }
00096 bool requirePrivateMats = (da->getNpesActive() != da->getNpesAll());
00097 if(requirePrivateMats ) {
00098 DirichletJacData *data = (static_cast<DirichletJacData*>(damg->user));
00099 if(da->iAmActive()) {
00100 if(buildFullCoarseMat) {
00101 da->createActiveMatrix(data->Jmat_private, matType, 1);
00102 } else {
00103 MatCreateShell(da->getCommActive(), m, n, PETSC_DETERMINE,
00104 PETSC_DETERMINE, damg, &(data->Jmat_private));
00105 MatShellSetOperation(data->Jmat_private, MATOP_MULT,
00106 (void (*)(void)) DirichletLaplacianMatMult);
00107 MatShellSetOperation(data->Jmat_private, MATOP_GET_DIAGONAL,
00108 (void (*)(void)) DirichletLaplacianMatGetDiagonal);
00109 MatShellSetOperation(data->Jmat_private, MATOP_DESTROY,
00110 (void (*)(void)) DirichletLaplacianMatDestroy);
00111 }
00112 MatGetVecs(data->Jmat_private, &(data->inTmp), &(data->outTmp));
00113 } else {
00114 data->Jmat_private = NULL;
00115 data->inTmp = NULL;
00116 data->outTmp = NULL;
00117 }
00118 MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE, PETSC_DETERMINE, damg, jac);
00119 MatShellSetOperation(*jac ,MATOP_DESTROY, (void (*)(void)) DirichletLaplacianMatDestroy);
00120 MatShellSetOperation(*jac ,MATOP_MULT, (void(*)(void)) DirichletLaplacianShellMatMult);
00121 } else {
00122 if(buildFullCoarseMat) {
00123 da->createMatrix(*jac, matType, 1);
00124 } else {
00125 MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE, PETSC_DETERMINE, damg, jac);
00126 MatShellSetOperation(*jac ,MATOP_MULT, (void (*)(void)) DirichletLaplacianMatMult);
00127 MatShellSetOperation(*jac ,MATOP_GET_DIAGONAL, (void (*)(void)) DirichletLaplacianMatGetDiagonal);
00128 MatShellSetOperation(*jac ,MATOP_DESTROY, (void (*)(void)) DirichletLaplacianMatDestroy);
00129 }
00130 }
00131 if((!myRank) && buildFullCoarseMat) {
00132 std::cout<<"Finished Building Full Coarse Mat."<<std::endl;
00133 }
00134 } else {
00135
00136 if(buildFullMatAll) {
00137 if(!myRank) {
00138 std::cout<<"Building Full Mat for level: "<<(damg->nlevels)<<std::endl;
00139 }
00140 if(!(da->computedLocalToGlobal())) {
00141 da->computeLocalToGlobalMappings();
00142 }
00143 char matType[30];
00144 PetscTruth typeFound;
00145 PetscOptionsGetString(PETSC_NULL,"-fullJacMatType",matType,30,&typeFound);
00146 if(!typeFound) {
00147 std::cout<<"I need a MatType for the full Jacobian matrix!"<<std::endl;
00148 assert(false);
00149 }
00150 da->createMatrix(*jac, matType, 1);
00151 if(!myRank) {
00152 std::cout<<"Finished Building Full Mat for level: "<<(damg->nlevels)<<std::endl;
00153 }
00154 } else {
00155 MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE, PETSC_DETERMINE, damg, jac);
00156 MatShellSetOperation(*jac ,MATOP_MULT, (void (*)(void)) DirichletLaplacianMatMult);
00157 MatShellSetOperation(*jac ,MATOP_GET_DIAGONAL, (void (*)(void)) DirichletLaplacianMatGetDiagonal);
00158 MatShellSetOperation(*jac ,MATOP_DESTROY, (void (*)(void)) DirichletLaplacianMatDestroy);
00159 }
00160 }
00161
00162 PetscFunctionReturn(0);
00163 }
00164
00165
00166 PetscErrorCode CreateDirichletJacobian(ot::DAMG damg, Mat *jac) {
00167 PetscFunctionBegin;
00168 int totalLevels;
00169 PetscTruth flg;
00170 PetscInt buildFullCoarseMat;
00171 PetscInt buildFullMatAll;
00172 PetscOptionsGetInt(PETSC_NULL,"-buildFullMatAll",&buildFullMatAll,&flg);
00173 PetscOptionsGetInt(PETSC_NULL,"-buildFullCoarseMat",&buildFullCoarseMat,&flg);
00174 if(buildFullMatAll) {
00175 buildFullCoarseMat = 1;
00176 }
00177 totalLevels = damg->totalLevels;
00178 ot::DA* da = damg->da;
00179 int myRank;
00180 MPI_Comm_rank(da->getComm(),&myRank);
00181
00182 unsigned int m,n;
00183 m=n=da->getNodeSize();
00184 if(totalLevels == damg->nlevels) {
00185
00186 if( (!myRank) && buildFullCoarseMat ) {
00187 std::cout<<"Building Full Coarse Mat."<<std::endl;
00188 }
00189 char matType[30];
00190 if(buildFullCoarseMat) {
00191 if(!(da->computedLocalToGlobal())) {
00192 da->computeLocalToGlobalMappings();
00193 }
00194 PetscTruth typeFound;
00195 PetscOptionsGetString(PETSC_NULL,"-fullJacMatType",matType,30,&typeFound);
00196 if(!typeFound) {
00197 std::cout<<"I need a MatType for the full Jacobian matrix!"<<std::endl;
00198 assert(false);
00199 }
00200 }
00201 bool requirePrivateMats = (da->getNpesActive() != da->getNpesAll());
00202 if(requirePrivateMats ) {
00203 DirichletJacData *data = (static_cast<DirichletJacData*>(damg->user));
00204 if(da->iAmActive()) {
00205 if(buildFullCoarseMat) {
00206 da->createActiveMatrix(data->Jmat_private, matType, 1);
00207 } else {
00208 MatCreateShell(da->getCommActive(), m, n, PETSC_DETERMINE,
00209 PETSC_DETERMINE, damg, &(data->Jmat_private));
00210 MatShellSetOperation(data->Jmat_private, MATOP_MULT,
00211 (void (*)(void)) DirichletJacobianMatMult);
00212 MatShellSetOperation(data->Jmat_private, MATOP_GET_DIAGONAL,
00213 (void (*)(void)) DirichletJacobianMatGetDiagonal);
00214 MatShellSetOperation(data->Jmat_private, MATOP_DESTROY,
00215 (void (*)(void)) DirichletJacobianMatDestroy);
00216 }
00217 MatGetVecs(data->Jmat_private, &(data->inTmp), &(data->outTmp));
00218 } else {
00219 data->Jmat_private = NULL;
00220 data->inTmp = NULL;
00221 data->outTmp = NULL;
00222 }
00223 MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE, PETSC_DETERMINE, damg, jac);
00224 MatShellSetOperation(*jac ,MATOP_DESTROY, (void (*)(void)) DirichletJacobianMatDestroy);
00225 MatShellSetOperation(*jac ,MATOP_MULT, (void(*)(void)) DirichletJacobianShellMatMult);
00226 } else {
00227 if(buildFullCoarseMat) {
00228 da->createMatrix(*jac, matType, 1);
00229 } else {
00230 MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE, PETSC_DETERMINE, damg, jac);
00231 MatShellSetOperation(*jac ,MATOP_MULT, (void (*)(void)) DirichletJacobianMatMult);
00232 MatShellSetOperation(*jac ,MATOP_GET_DIAGONAL, (void (*)(void)) DirichletJacobianMatGetDiagonal);
00233 MatShellSetOperation(*jac ,MATOP_DESTROY, (void (*)(void)) DirichletJacobianMatDestroy);
00234 }
00235 }
00236 if((!myRank) && buildFullCoarseMat) {
00237 std::cout<<"Finished Building Full Coarse Mat."<<std::endl;
00238 }
00239 } else {
00240
00241 if(buildFullMatAll) {
00242 if(!myRank) {
00243 std::cout<<"Building Full Mat for level: "<<(damg->nlevels)<<std::endl;
00244 }
00245 if(!(da->computedLocalToGlobal())) {
00246 da->computeLocalToGlobalMappings();
00247 }
00248 char matType[30];
00249 PetscTruth typeFound;
00250 PetscOptionsGetString(PETSC_NULL,"-fullJacMatType",matType,30,&typeFound);
00251 if(!typeFound) {
00252 std::cout<<"I need a MatType for the full Jacobian matrix!"<<std::endl;
00253 assert(false);
00254 }
00255 da->createMatrix(*jac, matType, 1);
00256 if(!myRank) {
00257 std::cout<<"Finished Building Full Mat for level: "<<(damg->nlevels)<<std::endl;
00258 }
00259 } else {
00260 MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE, PETSC_DETERMINE, damg, jac);
00261 MatShellSetOperation(*jac ,MATOP_MULT, (void (*)(void)) DirichletJacobianMatMult);
00262 MatShellSetOperation(*jac ,MATOP_GET_DIAGONAL, (void (*)(void)) DirichletJacobianMatGetDiagonal);
00263 MatShellSetOperation(*jac ,MATOP_DESTROY, (void (*)(void)) DirichletJacobianMatDestroy);
00264 }
00265 }
00266
00267 PetscFunctionReturn(0);
00268 }
00269
00270 PetscErrorCode ComputeDirichletLaplacian(ot::DAMG damg, Mat J, Mat B) {
00271
00272 PetscFunctionBegin;
00273
00274 PetscTruth isshell;
00275 PetscTypeCompare((PetscObject)B, MATSHELL, &isshell);
00276
00277 DirichletJacData *data = (static_cast<DirichletJacData*>(damg->user));
00278
00279 assert(B == J);
00280
00281 if(isshell) {
00282 if( data->Jmat_private == NULL ) {
00283 PetscFunctionReturn(0);
00284 } else {
00285 J = data->Jmat_private;
00286 B = data->Jmat_private;
00287 }
00288 }
00289
00290
00291
00292 PetscTypeCompare((PetscObject)B, MATSHELL, &isshell);
00293 if(isshell) {
00294
00295 PetscFunctionReturn(0);
00296 }
00297
00298 ot::DA* da = damg->da;
00299
00300 MatZeroEntries(B);
00301
00302 std::vector<ot::MatRecord> records;
00303
00304 unsigned int maxD;
00305 double hFac;
00306 if(da->iAmActive()) {
00307 maxD = da->getMaxDepth();
00308 hFac = 1.0/((double)(1u << (maxD-1)));
00309 }
00310
00311 unsigned char* bdyArr = data->bdyArr;
00312
00313 if(da->iAmActive()) {
00314 for(da->init<ot::DA_FLAGS::WRITABLE>();
00315 da->curr() < da->end<ot::DA_FLAGS::WRITABLE>();
00316 da->next<ot::DA_FLAGS::WRITABLE>()) {
00317 unsigned int idx = da->curr();
00318 unsigned int lev = da->getLevel(idx);
00319 double h = hFac*(1u << (maxD - lev));
00320 double fac1 = h/2.0;
00321 unsigned int indices[8];
00322 da->getNodeIndices(indices);
00323 unsigned char childNum = da->getChildNumber();
00324 unsigned char hnMask = da->getHangingNodeIndex(idx);
00325 unsigned char elemType = 0;
00326 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
00327 for(int k = 0; k < 8; k++) {
00328 if(!(bdyArr[indices[k]])) {
00329 for(int j = 0; j < 8; j++) {
00330 if(!(bdyArr[indices[j]])) {
00331 ot::MatRecord currRec;
00332 currRec.rowIdx = indices[k];
00333 currRec.colIdx = indices[j];
00334 currRec.rowDim = 0;
00335 currRec.colDim = 0;
00336 currRec.val = (fac1*(LaplacianType2Stencil[childNum][elemType][k][j]));
00337 records.push_back(currRec);
00338 }
00339 }
00340 }
00341 }
00342 if(records.size() > 1000) {
00343
00344 da->setValuesInMatrix(B, records, 1, ADD_VALUES);
00345 }
00346 }
00347 }
00348 da->setValuesInMatrix(B, records, 1, ADD_VALUES);
00349 MatAssemblyBegin(B, MAT_FLUSH_ASSEMBLY);
00350 MatAssemblyEnd(B, MAT_FLUSH_ASSEMBLY);
00351
00352 if(da->iAmActive()) {
00353 for(da->init<ot::DA_FLAGS::WRITABLE>();
00354 da->curr() < da->end<ot::DA_FLAGS::WRITABLE>();
00355 da->next<ot::DA_FLAGS::WRITABLE>()) {
00356 unsigned int indices[8];
00357 da->getNodeIndices(indices);
00358 for(int k = 0; k < 8; k++) {
00359 if(bdyArr[indices[k]]) {
00360 ot::MatRecord currRec;
00361 currRec.rowIdx = indices[k];
00362 currRec.colIdx = indices[k];
00363 currRec.rowDim = 0;
00364 currRec.colDim = 0;
00365 currRec.val = 1.0;
00366 records.push_back(currRec);
00367 }
00368 }
00369 if(records.size() > 1000) {
00370
00371 da->setValuesInMatrix(B, records, 1, INSERT_VALUES);
00372 }
00373 }
00374 }
00375 da->setValuesInMatrix(B, records, 1, INSERT_VALUES);
00376 MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY);
00377 MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY);
00378
00379 PetscFunctionReturn(0);
00380 }
00381
00382 PetscErrorCode ComputeDirichletJacobian(ot::DAMG damg, Mat J, Mat B) {
00383
00384 PetscFunctionBegin;
00385
00386 PetscTruth isshell;
00387 PetscTypeCompare((PetscObject)B, MATSHELL, &isshell);
00388
00389 DirichletJacData *data = (static_cast<DirichletJacData*>(damg->user));
00390
00391 assert(B == J);
00392
00393 if(isshell) {
00394 if( data->Jmat_private == NULL ) {
00395 PetscFunctionReturn(0);
00396 } else {
00397 J = data->Jmat_private;
00398 B = data->Jmat_private;
00399 }
00400 }
00401
00402
00403
00404 PetscTypeCompare((PetscObject)B, MATSHELL, &isshell);
00405 if(isshell) {
00406
00407 PetscFunctionReturn(0);
00408 }
00409
00410 ot::DA* da = damg->da;
00411
00412 MatZeroEntries(B);
00413
00414 std::vector<ot::MatRecord> records;
00415
00416 unsigned int maxD;
00417 double hFac;
00418 if(da->iAmActive()) {
00419 maxD = da->getMaxDepth();
00420 hFac = 1.0/((double)(1u << (maxD-1)));
00421 }
00422
00423 unsigned char* bdyArr = data->bdyArr;
00424
00425 if(da->iAmActive()) {
00426 for(da->init<ot::DA_FLAGS::WRITABLE>();
00427 da->curr() < da->end<ot::DA_FLAGS::WRITABLE>();
00428 da->next<ot::DA_FLAGS::WRITABLE>()) {
00429 unsigned int idx = da->curr();
00430 unsigned int lev = da->getLevel(idx);
00431 double h = hFac*(1u << (maxD - lev));
00432 double fac1 = h/2.0;
00433 double fac2 = h*h*h/8.0;
00434 unsigned int indices[8];
00435 da->getNodeIndices(indices);
00436 unsigned char childNum = da->getChildNumber();
00437 unsigned char hnMask = da->getHangingNodeIndex(idx);
00438 unsigned char elemType = 0;
00439 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
00440 for(int k = 0; k < 8; k++) {
00441 if(!(bdyArr[indices[k]])) {
00442 for(int j = 0; j < 8; j++) {
00443 if(!(bdyArr[indices[j]])) {
00444 ot::MatRecord currRec;
00445 currRec.rowIdx = indices[k];
00446 currRec.colIdx = indices[j];
00447 currRec.rowDim = 0;
00448 currRec.colDim = 0;
00449 currRec.val = ((fac1*(LaplacianType2Stencil[childNum][elemType][k][j])) +
00450 (fac2*(MassType2Stencil[childNum][elemType][k][j])));
00451 records.push_back(currRec);
00452 }
00453 }
00454 }
00455 }
00456 if(records.size() > 1000) {
00457
00458 da->setValuesInMatrix(B, records, 1, ADD_VALUES);
00459 }
00460 }
00461 }
00462 da->setValuesInMatrix(B, records, 1, ADD_VALUES);
00463 MatAssemblyBegin(B, MAT_FLUSH_ASSEMBLY);
00464 MatAssemblyEnd(B, MAT_FLUSH_ASSEMBLY);
00465
00466 if(da->iAmActive()) {
00467 for(da->init<ot::DA_FLAGS::WRITABLE>();
00468 da->curr() < da->end<ot::DA_FLAGS::WRITABLE>();
00469 da->next<ot::DA_FLAGS::WRITABLE>()) {
00470 unsigned int indices[8];
00471 da->getNodeIndices(indices);
00472 for(int k = 0; k < 8; k++) {
00473 if(bdyArr[indices[k]]) {
00474 ot::MatRecord currRec;
00475 currRec.rowIdx = indices[k];
00476 currRec.colIdx = indices[k];
00477 currRec.rowDim = 0;
00478 currRec.colDim = 0;
00479 currRec.val = 1.0;
00480 records.push_back(currRec);
00481 }
00482 }
00483 if(records.size() > 1000) {
00484
00485 da->setValuesInMatrix(B, records, 1, INSERT_VALUES);
00486 }
00487 }
00488 }
00489 da->setValuesInMatrix(B, records, 1, INSERT_VALUES);
00490 MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY);
00491 MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY);
00492
00493 PetscFunctionReturn(0);
00494 }
00495
00496 PetscErrorCode DirichletLaplacianMatDestroy(Mat J) {
00497 PetscFunctionBegin;
00498
00499 PetscFunctionReturn(0);
00500 }
00501
00502 PetscErrorCode DirichletJacobianMatDestroy(Mat J) {
00503 PetscFunctionBegin;
00504
00505 PetscFunctionReturn(0);
00506 }
00507
00508 void SetDirichletJacContexts(ot::DAMG* damg) {
00509 int nlevels = damg[0]->nlevels;
00510 for(int i = 0; i < nlevels; i++) {
00511 DirichletJacData* ctx= new DirichletJacData;
00512 ctx->bdyArr = NULL;
00513 ctx->Jmat_private = NULL;
00514 ctx->inTmp = NULL;
00515 ctx->outTmp = NULL;
00516
00517 std::vector<unsigned char> tmpBdyFlags;
00518 std::vector<unsigned char> tmpBdyFlagsAux;
00519 unsigned char* bdyArrAux = NULL;
00520
00521
00522 assignBoundaryFlags(damg[i]->da, tmpBdyFlags);
00523 ((damg[i])->da)->vecGetBuffer<unsigned char>(tmpBdyFlags, ctx->bdyArr, false, false, true, 1);
00524 if(damg[i]->da->iAmActive()) {
00525 ((damg[i])->da)->ReadFromGhostsBegin<unsigned char>(ctx->bdyArr, 1);
00526 }
00527
00528 if(damg[i]->da_aux) {
00529 assignBoundaryFlags( damg[i]->da_aux, tmpBdyFlagsAux);
00530 ((damg[i])->da_aux)->vecGetBuffer<unsigned char>(tmpBdyFlagsAux, bdyArrAux,
00531 false, false, true, 1);
00532 if(damg[i]->da_aux->iAmActive()) {
00533 ((damg[i])->da_aux)->ReadFromGhostsBegin<unsigned char>(bdyArrAux, 1);
00534 }
00535 }
00536
00537 tmpBdyFlags.clear();
00538 tmpBdyFlagsAux.clear();
00539
00540 if(damg[i]->da->iAmActive()) {
00541 ((damg[i])->da)->ReadFromGhostsEnd<unsigned char>(ctx->bdyArr);
00542 }
00543
00544 if((damg[i])->da_aux) {
00545 if(damg[i]->da_aux->iAmActive()) {
00546 ((damg[i])->da_aux)->ReadFromGhostsEnd<unsigned char>(bdyArrAux);
00547 }
00548 }
00549
00550 for(int loopCtr = 0; loopCtr < 2; loopCtr++) {
00551 ot::DA* da = NULL;
00552 unsigned char* suppressedDOFptr = NULL;
00553 unsigned char* bdyArrPtr = NULL;
00554 if(loopCtr == 0) {
00555 da = damg[i]->da;
00556 suppressedDOFptr = damg[i]->suppressedDOF;
00557 bdyArrPtr = ctx->bdyArr;
00558 } else {
00559 da = damg[i]->da_aux;
00560 suppressedDOFptr = damg[i]->suppressedDOFaux;
00561 bdyArrPtr = bdyArrAux;
00562 }
00563 if(da) {
00564 if(da->iAmActive()) {
00565 for(da->init<ot::DA_FLAGS::ALL>();
00566 da->curr() < da->end<ot::DA_FLAGS::ALL>();
00567 da->next<ot::DA_FLAGS::ALL>()) {
00568 unsigned int indices[8];
00569 da->getNodeIndices(indices);
00570 for(unsigned int k = 0; k < 8; k++) {
00571 suppressedDOFptr[indices[k]] = bdyArrPtr[indices[k]];
00572 }
00573 }
00574 }
00575 }
00576 }
00577
00578 if(bdyArrAux) {
00579 delete [] bdyArrAux;
00580 bdyArrAux = NULL;
00581 }
00582
00583 (damg[i])->user = ctx;
00584 }
00585
00586 }
00587
00588 void DestroyDirichletJacContexts(ot::DAMG* damg) {
00589 int nlevels = damg[0]->nlevels;
00590 for(int i = 0; i < nlevels; i++) {
00591 DirichletJacData* ctx = (static_cast<DirichletJacData*>(damg[i]->user));
00592 if(ctx->bdyArr) {
00593 delete [] (ctx->bdyArr);
00594 ctx->bdyArr = NULL;
00595 }
00596 if(ctx->Jmat_private) {
00597 MatDestroy(ctx->Jmat_private);
00598 ctx->Jmat_private = NULL;
00599 }
00600 if(ctx->inTmp) {
00601 VecDestroy(ctx->inTmp);
00602 ctx->inTmp = NULL;
00603 }
00604 if(ctx->outTmp) {
00605 VecDestroy(ctx->outTmp);
00606 ctx->outTmp = NULL;
00607 }
00608 delete ctx;
00609 ctx = NULL;
00610 }
00611 }
00612
00613 PetscErrorCode DirichletLaplacianShellMatMult(Mat J, Vec in, Vec out) {
00614 PetscFunctionBegin;
00615
00616 ot::DAMG damg;
00617
00618 MatShellGetContext(J, (void**)(&damg));
00619
00620 DirichletJacData* ctx = static_cast<DirichletJacData*>(damg->user);
00621
00622 if(damg->da->iAmActive()) {
00623 PetscScalar* inArray;
00624 PetscScalar* outArray;
00625
00626 VecGetArray(in, &inArray);
00627 VecGetArray(out, &outArray);
00628
00629 VecPlaceArray(ctx->inTmp, inArray);
00630 VecPlaceArray(ctx->outTmp, outArray);
00631
00632 MatMult(ctx->Jmat_private, ctx->inTmp, ctx->outTmp);
00633
00634 VecResetArray(ctx->inTmp);
00635 VecResetArray(ctx->outTmp);
00636
00637 VecRestoreArray(in, &inArray);
00638 VecRestoreArray(out, &outArray);
00639 }
00640
00641 PetscFunctionReturn(0);
00642 }
00643
00644 PetscErrorCode DirichletJacobianShellMatMult(Mat J, Vec in, Vec out) {
00645 PetscFunctionBegin;
00646
00647 ot::DAMG damg;
00648
00649 MatShellGetContext(J, (void**)(&damg));
00650
00651 DirichletJacData* ctx = static_cast<DirichletJacData*>(damg->user);
00652
00653 if(damg->da->iAmActive()) {
00654 PetscScalar* inArray;
00655 PetscScalar* outArray;
00656
00657 VecGetArray(in, &inArray);
00658 VecGetArray(out, &outArray);
00659
00660 VecPlaceArray(ctx->inTmp, inArray);
00661 VecPlaceArray(ctx->outTmp, outArray);
00662
00663 MatMult(ctx->Jmat_private, ctx->inTmp, ctx->outTmp);
00664
00665 VecResetArray(ctx->inTmp);
00666 VecResetArray(ctx->outTmp);
00667
00668 VecRestoreArray(in, &inArray);
00669 VecRestoreArray(out, &outArray);
00670 }
00671
00672 PetscFunctionReturn(0);
00673 }
00674
00675 PetscErrorCode TmpDirichletLaplacianMatMult(Mat J, Vec in, Vec out) {
00676 PetscFunctionBegin;
00677
00678 ot::DAMG damg;
00679 iC(MatShellGetContext(J, (void**)(&damg)));
00680
00681 DirichletJacData *data = (static_cast<DirichletJacData*>(damg->user));
00682
00683 unsigned char* bdyArr = data->bdyArr;
00684
00685 ot::DA* da = damg->da;
00686
00687 iC(VecZeroEntries(out));
00688
00689 unsigned int maxD;
00690 double hFac;
00691 if(da->iAmActive()) {
00692 maxD = da->getMaxDepth();
00693 hFac = 1.0/((double)(1u << (maxD-1)));
00694 }
00695
00696 PetscScalar *outArr=NULL;
00697 PetscScalar *inArr=NULL;
00698
00699
00700 da->vecGetBuffer(in,inArr,false,false,true,1);
00701
00702
00703 da->vecGetBuffer(out,outArr,false,false,false,1);
00704
00705 if(da->iAmActive()) {
00706
00707 da->ReadFromGhostsBegin<PetscScalar>(inArr,1);
00708
00709 for(da->init<ot::DA_FLAGS::INDEPENDENT>();
00710 da->curr() < da->end<ot::DA_FLAGS::INDEPENDENT>();
00711 da->next<ot::DA_FLAGS::INDEPENDENT>() ) {
00712 unsigned int idx = da->curr();
00713 unsigned int lev = da->getLevel(idx);
00714 double h = hFac*(1u << (maxD - lev));
00715 double fac1 = h/2.0;
00716 unsigned int indices[8];
00717 da->getNodeIndices(indices);
00718 unsigned char childNum = da->getChildNumber();
00719 unsigned char hnMask = da->getHangingNodeIndex(idx);
00720 unsigned char elemType = 0;
00721 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
00722 for(int k = 0; k < 8; k++) {
00723 if(!bdyArr[indices[k]]) {
00724 for(int j = 0; j < 8; j++) {
00725 outArr[indices[k]] += (fac1*LaplacianType2Stencil[childNum][elemType][k][j]*inArr[indices[j]]);
00726 }
00727 }
00728 }
00729 }
00730
00731 da->ReadFromGhostsEnd<PetscScalar>(inArr);
00732
00733 for(da->init<ot::DA_FLAGS::DEPENDENT>();
00734 da->curr() < da->end<ot::DA_FLAGS::DEPENDENT>();
00735 da->next<ot::DA_FLAGS::DEPENDENT>() ) {
00736 unsigned int idx = da->curr();
00737 unsigned int lev = da->getLevel(idx);
00738 double h = hFac*(1u << (maxD - lev));
00739 double fac1 = h/2.0;
00740 double fac2 = h*h*h/8.0;
00741 unsigned int indices[8];
00742 da->getNodeIndices(indices);
00743 unsigned char childNum = da->getChildNumber();
00744 unsigned char hnMask = da->getHangingNodeIndex(idx);
00745 unsigned char elemType = 0;
00746 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
00747 for(int k = 0; k < 8; k++) {
00748 if(!bdyArr[indices[k]]) {
00749 for(int j = 0; j < 8; j++) {
00750 outArr[indices[k]] += (fac1*LaplacianType2Stencil[childNum][elemType][k][j]*inArr[indices[j]]);
00751 }
00752 }
00753 }
00754 }
00755
00756 }
00757
00758 da->vecRestoreBuffer(in,inArr,false,false,true,1);
00759
00760 da->vecRestoreBuffer(out,outArr,false,false,false,1);
00761
00762 PetscFunctionReturn(0);
00763 }
00764
00765
00766 PetscErrorCode TmpDirichletJacobianMatMult(Mat J, Vec in, Vec out) {
00767 PetscFunctionBegin;
00768
00769 ot::DAMG damg;
00770 iC(MatShellGetContext(J, (void**)(&damg)));
00771
00772 DirichletJacData *data = (static_cast<DirichletJacData*>(damg->user));
00773
00774 unsigned char* bdyArr = data->bdyArr;
00775
00776 ot::DA* da = damg->da;
00777
00778 iC(VecZeroEntries(out));
00779
00780 unsigned int maxD;
00781 double hFac;
00782 if(da->iAmActive()) {
00783 maxD = da->getMaxDepth();
00784 hFac = 1.0/((double)(1u << (maxD-1)));
00785 }
00786
00787 PetscScalar *outArr=NULL;
00788 PetscScalar *inArr=NULL;
00789
00790
00791 da->vecGetBuffer(in,inArr,false,false,true,1);
00792
00793
00794 da->vecGetBuffer(out,outArr,false,false,false,1);
00795
00796 if(da->iAmActive()) {
00797
00798 da->ReadFromGhostsBegin<PetscScalar>(inArr,1);
00799
00800 for(da->init<ot::DA_FLAGS::INDEPENDENT>();
00801 da->curr() < da->end<ot::DA_FLAGS::INDEPENDENT>();
00802 da->next<ot::DA_FLAGS::INDEPENDENT>() ) {
00803 unsigned int idx = da->curr();
00804 unsigned int lev = da->getLevel(idx);
00805 double h = hFac*(1u << (maxD - lev));
00806 double fac1 = h/2.0;
00807 double fac2 = h*h*h/8.0;
00808 unsigned int indices[8];
00809 da->getNodeIndices(indices);
00810 unsigned char childNum = da->getChildNumber();
00811 unsigned char hnMask = da->getHangingNodeIndex(idx);
00812 unsigned char elemType = 0;
00813 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
00814 for(int k = 0; k < 8; k++) {
00815 if(!bdyArr[indices[k]]) {
00816 for(int j = 0; j < 8; j++) {
00817 outArr[indices[k]] += (((fac1*(LaplacianType2Stencil[childNum][elemType][k][j])) +
00818 (fac2*(MassType2Stencil[childNum][elemType][k][j])))*inArr[indices[j]]);
00819 }
00820 }
00821 }
00822 }
00823
00824 da->ReadFromGhostsEnd<PetscScalar>(inArr);
00825
00826 for(da->init<ot::DA_FLAGS::DEPENDENT>();
00827 da->curr() < da->end<ot::DA_FLAGS::DEPENDENT>();
00828 da->next<ot::DA_FLAGS::DEPENDENT>() ) {
00829 unsigned int idx = da->curr();
00830 unsigned int lev = da->getLevel(idx);
00831 double h = hFac*(1u << (maxD - lev));
00832 double fac1 = h/2.0;
00833 double fac2 = h*h*h/8.0;
00834 unsigned int indices[8];
00835 da->getNodeIndices(indices);
00836 unsigned char childNum = da->getChildNumber();
00837 unsigned char hnMask = da->getHangingNodeIndex(idx);
00838 unsigned char elemType = 0;
00839 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
00840 for(int k = 0; k < 8; k++) {
00841 if(!bdyArr[indices[k]]) {
00842 for(int j = 0; j < 8; j++) {
00843 outArr[indices[k]] += (((fac1*(LaplacianType2Stencil[childNum][elemType][k][j])) +
00844 (fac2*(MassType2Stencil[childNum][elemType][k][j])))*inArr[indices[j]]);
00845 }
00846 }
00847 }
00848 }
00849
00850 }
00851
00852 da->vecRestoreBuffer(in,inArr,false,false,true,1);
00853
00854 da->vecRestoreBuffer(out,outArr,false,false,false,1);
00855
00856 PetscFunctionReturn(0);
00857 }
00858
00859 PetscErrorCode DirichletLaplacianMatMult(Mat J, Vec in, Vec out) {
00860 PetscFunctionBegin;
00861
00862 ot::DAMG damg;
00863 iC(MatShellGetContext(J, (void**)(&damg)));
00864
00865 DirichletJacData *data = (static_cast<DirichletJacData*>(damg->user));
00866
00867 unsigned char* bdyArr = data->bdyArr;
00868
00869 ot::DA* da = damg->da;
00870
00871 iC(VecZeroEntries(out));
00872
00873 unsigned int maxD;
00874 double hFac;
00875 if(da->iAmActive()) {
00876 maxD = da->getMaxDepth();
00877 hFac = 1.0/((double)(1u << (maxD-1)));
00878 }
00879
00880 PetscScalar *outArr=NULL;
00881 PetscScalar *inArr=NULL;
00882
00883
00884 da->vecGetBuffer(in,inArr,false,false,true,1);
00885
00886
00887 da->vecGetBuffer(out,outArr,false,false,false,1);
00888
00889 if(da->iAmActive()) {
00890
00891 da->ReadFromGhostsBegin<PetscScalar>(inArr,1);
00892
00893 for(da->init<ot::DA_FLAGS::INDEPENDENT>();
00894 da->curr() < da->end<ot::DA_FLAGS::INDEPENDENT>();
00895 da->next<ot::DA_FLAGS::INDEPENDENT>() ) {
00896 unsigned int idx = da->curr();
00897 unsigned int lev = da->getLevel(idx);
00898 double h = hFac*(1u << (maxD - lev));
00899 double fac1 = h/2.0;
00900 unsigned int indices[8];
00901 da->getNodeIndices(indices);
00902 unsigned char childNum = da->getChildNumber();
00903 unsigned char hnMask = da->getHangingNodeIndex(idx);
00904 unsigned char elemType = 0;
00905 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
00906 for(int k = 0; k < 8; k++) {
00907 if(bdyArr[indices[k]]) {
00908 outArr[indices[k]] = inArr[indices[k]];
00909 } else {
00910 for(int j = 0; j < 8; j++) {
00911 if(!bdyArr[indices[j]]) {
00912 outArr[indices[k]] += (fac1*LaplacianType2Stencil[childNum][elemType][k][j]*inArr[indices[j]]);
00913 }
00914 }
00915 }
00916 }
00917 }
00918
00919 da->ReadFromGhostsEnd<PetscScalar>(inArr);
00920
00921 for(da->init<ot::DA_FLAGS::DEPENDENT>();
00922 da->curr() < da->end<ot::DA_FLAGS::DEPENDENT>();
00923 da->next<ot::DA_FLAGS::DEPENDENT>() ) {
00924 unsigned int idx = da->curr();
00925 unsigned int lev = da->getLevel(idx);
00926 double h = hFac*(1u << (maxD - lev));
00927 double fac1 = h/2.0;
00928 double fac2 = h*h*h/8.0;
00929 unsigned int indices[8];
00930 da->getNodeIndices(indices);
00931 unsigned char childNum = da->getChildNumber();
00932 unsigned char hnMask = da->getHangingNodeIndex(idx);
00933 unsigned char elemType = 0;
00934 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
00935 for(int k = 0; k < 8; k++) {
00936 if(bdyArr[indices[k]]) {
00937 outArr[indices[k]] = inArr[indices[k]];
00938 } else {
00939 for(int j = 0; j < 8; j++) {
00940 if(!bdyArr[indices[j]]) {
00941 outArr[indices[k]] += (fac1*LaplacianType2Stencil[childNum][elemType][k][j]*inArr[indices[j]]);
00942 }
00943 }
00944 }
00945 }
00946 }
00947
00948 }
00949
00950 da->vecRestoreBuffer(in,inArr,false,false,true,1);
00951
00952 da->vecRestoreBuffer(out,outArr,false,false,false,1);
00953
00954 PetscFunctionReturn(0);
00955 }
00956
00957 PetscErrorCode DirichletJacobianMatMult(Mat J, Vec in, Vec out) {
00958 PetscFunctionBegin;
00959
00960 ot::DAMG damg;
00961 iC(MatShellGetContext(J, (void**)(&damg)));
00962
00963 DirichletJacData *data = (static_cast<DirichletJacData*>(damg->user));
00964
00965 unsigned char* bdyArr = data->bdyArr;
00966
00967 ot::DA* da = damg->da;
00968
00969 iC(VecZeroEntries(out));
00970
00971 unsigned int maxD;
00972 double hFac;
00973 if(da->iAmActive()) {
00974 maxD = da->getMaxDepth();
00975 hFac = 1.0/((double)(1u << (maxD-1)));
00976 }
00977
00978 PetscScalar *outArr=NULL;
00979 PetscScalar *inArr=NULL;
00980
00981
00982 da->vecGetBuffer(in,inArr,false,false,true,1);
00983
00984
00985 da->vecGetBuffer(out,outArr,false,false,false,1);
00986
00987 if(da->iAmActive()) {
00988
00989 da->ReadFromGhostsBegin<PetscScalar>(inArr,1);
00990
00991 for(da->init<ot::DA_FLAGS::INDEPENDENT>();
00992 da->curr() < da->end<ot::DA_FLAGS::INDEPENDENT>();
00993 da->next<ot::DA_FLAGS::INDEPENDENT>() ) {
00994 unsigned int idx = da->curr();
00995 unsigned int lev = da->getLevel(idx);
00996 double h = hFac*(1u << (maxD - lev));
00997 double fac1 = h/2.0;
00998 double fac2 = h*h*h/8.0;
00999 unsigned int indices[8];
01000 da->getNodeIndices(indices);
01001 unsigned char childNum = da->getChildNumber();
01002 unsigned char hnMask = da->getHangingNodeIndex(idx);
01003 unsigned char elemType = 0;
01004 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
01005 for(int k = 0; k < 8; k++) {
01006 if(bdyArr[indices[k]]) {
01007 outArr[indices[k]] = inArr[indices[k]];
01008 } else {
01009 for(int j = 0; j < 8; j++) {
01010 if(!bdyArr[indices[j]]) {
01011 outArr[indices[k]] += (((fac1*(LaplacianType2Stencil[childNum][elemType][k][j])) +
01012 (fac2*(MassType2Stencil[childNum][elemType][k][j])))*inArr[indices[j]]);
01013 }
01014 }
01015 }
01016 }
01017 }
01018
01019 da->ReadFromGhostsEnd<PetscScalar>(inArr);
01020
01021 for(da->init<ot::DA_FLAGS::DEPENDENT>();
01022 da->curr() < da->end<ot::DA_FLAGS::DEPENDENT>();
01023 da->next<ot::DA_FLAGS::DEPENDENT>() ) {
01024 unsigned int idx = da->curr();
01025 unsigned int lev = da->getLevel(idx);
01026 double h = hFac*(1u << (maxD - lev));
01027 double fac1 = h/2.0;
01028 double fac2 = h*h*h/8.0;
01029 unsigned int indices[8];
01030 da->getNodeIndices(indices);
01031 unsigned char childNum = da->getChildNumber();
01032 unsigned char hnMask = da->getHangingNodeIndex(idx);
01033 unsigned char elemType = 0;
01034 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
01035 for(int k = 0; k < 8; k++) {
01036 if(bdyArr[indices[k]]) {
01037 outArr[indices[k]] = inArr[indices[k]];
01038 } else {
01039 for(int j = 0; j < 8; j++) {
01040 if(!bdyArr[indices[j]]) {
01041 outArr[indices[k]] += (((fac1*(LaplacianType2Stencil[childNum][elemType][k][j])) +
01042 (fac2*(MassType2Stencil[childNum][elemType][k][j])))*inArr[indices[j]]);
01043 }
01044 }
01045 }
01046 }
01047 }
01048
01049 }
01050
01051 da->vecRestoreBuffer(in,inArr,false,false,true,1);
01052
01053 da->vecRestoreBuffer(out,outArr,false,false,false,1);
01054
01055 PetscFunctionReturn(0);
01056 }
01057
01058 PetscErrorCode DirichletLaplacianMatGetDiagonal(Mat J, Vec diag) {
01059 PetscFunctionBegin;
01060
01061 ot::DAMG damg;
01062 iC(MatShellGetContext(J, (void**)(&damg)));
01063
01064 DirichletJacData *data = (static_cast<DirichletJacData*>(damg->user));
01065
01066 ot::DA* da = damg->da;
01067
01068 iC(VecZeroEntries(diag));
01069
01070 unsigned char* bdyArr = data->bdyArr;
01071
01072 PetscScalar *diagArr;
01073
01074 da->vecGetBuffer(diag, diagArr, false, false, false, 1);
01075
01076 unsigned int maxD;
01077 double hFac;
01078 if(da->iAmActive()) {
01079 maxD = (da->getMaxDepth());
01080 hFac = 1.0/((double)(1u << (maxD-1)));
01081
01082 for(da->init<ot::DA_FLAGS::ALL>();
01083 da->curr() < da->end<ot::DA_FLAGS::ALL>();
01084 da->next<ot::DA_FLAGS::ALL>()) {
01085 unsigned int idx = da->curr();
01086 unsigned int lev = da->getLevel(idx);
01087 double h = hFac*(1u << (maxD - lev));
01088 double fac1 = h/2.0;
01089 unsigned int indices[8];
01090 da->getNodeIndices(indices);
01091 unsigned char childNum = da->getChildNumber();
01092 unsigned char hnMask = da->getHangingNodeIndex(idx);
01093 unsigned char elemType = 0;
01094 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
01095 for(int k = 0; k < 8; k++) {
01096 if(bdyArr[indices[k]]) {
01097 diagArr[indices[k]] = 1.0;
01098 } else {
01099 diagArr[indices[k]] += (fac1*LaplacianType2Stencil[childNum][elemType][k][k]);
01100 }
01101 }
01102 }
01103 }
01104
01105 da->vecRestoreBuffer(diag, diagArr, false, false, false, 1);
01106
01107 PetscFunctionReturn(0);
01108 }
01109
01110 PetscErrorCode DirichletJacobianMatGetDiagonal(Mat J, Vec diag) {
01111 PetscFunctionBegin;
01112
01113 ot::DAMG damg;
01114 iC(MatShellGetContext(J, (void**)(&damg)));
01115
01116 DirichletJacData *data = (static_cast<DirichletJacData*>(damg->user));
01117
01118 ot::DA* da = damg->da;
01119
01120 iC(VecZeroEntries(diag));
01121
01122 unsigned char* bdyArr = data->bdyArr;
01123
01124 PetscScalar *diagArr;
01125
01126 da->vecGetBuffer(diag, diagArr, false, false, false, 1);
01127
01128 unsigned int maxD;
01129 double hFac;
01130 if(da->iAmActive()) {
01131 maxD = (da->getMaxDepth());
01132 hFac = 1.0/((double)(1u << (maxD-1)));
01133
01134 for(da->init<ot::DA_FLAGS::ALL>();
01135 da->curr() < da->end<ot::DA_FLAGS::ALL>();
01136 da->next<ot::DA_FLAGS::ALL>()) {
01137 unsigned int idx = da->curr();
01138 unsigned int lev = da->getLevel(idx);
01139 double h = hFac*(1u << (maxD - lev));
01140 double fac1 = h/2.0;
01141 double fac2 = h*h*h/8.0;
01142 unsigned int indices[8];
01143 da->getNodeIndices(indices);
01144 unsigned char childNum = da->getChildNumber();
01145 unsigned char hnMask = da->getHangingNodeIndex(idx);
01146 unsigned char elemType = 0;
01147 GET_ETYPE_BLOCK(elemType,hnMask,childNum)
01148 for(int k = 0; k < 8; k++) {
01149 if(bdyArr[indices[k]]) {
01150 diagArr[indices[k]] = 1.0;
01151 } else {
01152 diagArr[indices[k]] += ((fac1*(LaplacianType2Stencil[childNum][elemType][k][k])) +
01153 (fac2*(MassType2Stencil[childNum][elemType][k][k])));
01154 }
01155 }
01156 }
01157 }
01158
01159 da->vecRestoreBuffer(diag, diagArr, false, false, false, 1);
01160
01161 PetscFunctionReturn(0);
01162 }
01163
01164 PetscErrorCode Jacobian2ShellMatMult(Mat J, Vec in, Vec out) {
01165 PetscFunctionBegin;
01166
01167 ot::DAMG damg;
01168
01169 MatShellGetContext(J, (void**)(&damg));
01170
01171 Jac2MFreeData* ctx = static_cast<Jac2MFreeData*>(damg->user);
01172
01173 if(damg->da->iAmActive()) {
01174 PetscScalar* inArray;
01175 PetscScalar* outArray;
01176
01177 VecGetArray(in, &inArray);
01178 VecGetArray(out, &outArray);
01179
01180 VecPlaceArray(ctx->inTmp, inArray);
01181 VecPlaceArray(ctx->outTmp, outArray);
01182
01183 MatMult(ctx->Jmat_private, ctx->inTmp, ctx->outTmp);
01184
01185 VecResetArray(ctx->inTmp);
01186 VecResetArray(ctx->outTmp);
01187
01188 VecRestoreArray(in, &inArray);
01189 VecRestoreArray(out, &outArray);
01190 }
01191
01192 PetscFunctionReturn(0);
01193 }
01194
01195 PetscErrorCode Jacobian3ShellMatMult(Mat J, Vec in, Vec out) {
01196 PetscFunctionBegin;
01197
01198 ot::DAMG damg;
01199
01200 MatShellGetContext(J, (void**)(&damg));
01201
01202 Jac3MFreeData* ctx = static_cast<Jac3MFreeData*>(damg->user);
01203
01204 if(damg->da->iAmActive()) {
01205 PetscScalar* inArray;
01206 PetscScalar* outArray;
01207
01208 VecGetArray(in, &inArray);
01209 VecGetArray(out, &outArray);
01210
01211 VecPlaceArray(ctx->inTmp, inArray);
01212 VecPlaceArray(ctx->outTmp, outArray);
01213
01214 MatMult(ctx->Jmat_private, ctx->inTmp, ctx->outTmp);
01215
01216 VecResetArray(ctx->inTmp);
01217 VecResetArray(ctx->outTmp);
01218
01219 VecRestoreArray(in, &inArray);
01220 VecRestoreArray(out, &outArray);
01221 }
01222
01223 PetscFunctionReturn(0);
01224 }
01225
01226 void getActiveStateAndActiveCommForKSP_Shell_DirichletJac(Mat mat,
01227 bool & activeState, MPI_Comm & activeComm) {
01228 PetscTruth isshell;
01229 PetscTypeCompare((PetscObject)mat, MATSHELL, &isshell);
01230 assert(isshell);
01231 ot::DAMG damg;
01232 MatShellGetContext(mat, (void**)(&damg));
01233 ot::DA* da = damg->da;
01234 activeState = da->iAmActive();
01235 activeComm = da->getCommActive();
01236 }
01237
01238 void getActiveStateAndActiveCommForKSP_Shell_Jac1(Mat mat,
01239 bool & activeState, MPI_Comm & activeComm) {
01240 PetscTruth isshell;
01241 PetscTypeCompare((PetscObject)mat, MATSHELL, &isshell);
01242 assert(isshell);
01243 Jac1MFreeData *data;
01244 MatShellGetContext(mat, (void**)(&data));
01245 ot::DA* da = data->da;
01246 activeState = da->iAmActive();
01247 activeComm = da->getCommActive();
01248 }
01249
01250 void getActiveStateAndActiveCommForKSP_Shell_Jac2or3(Mat mat,
01251 bool & activeState, MPI_Comm & activeComm) {
01252 PetscTruth isshell;
01253 PetscTypeCompare((PetscObject)mat, MATSHELL, &isshell);
01254 assert(isshell);
01255 ot::DAMG damg;
01256 MatShellGetContext(mat, (void**)(&damg));
01257 ot::DA* da = damg->da;
01258 activeState = da->iAmActive();
01259 activeComm = da->getCommActive();
01260 }
01261
01262 void getPrivateMatricesForKSP_Shell_DirichletJac(Mat mat,
01263 Mat *AmatPrivate, Mat *PmatPrivate, MatStructure* pFlag) {
01264 PetscTruth isshell;
01265 PetscTypeCompare((PetscObject)mat, MATSHELL, &isshell);
01266 assert(isshell);
01267 ot::DAMG damg;
01268 MatShellGetContext(mat, (void**)(&damg));
01269 DirichletJacData* data = (static_cast<DirichletJacData*>(damg->user));
01270 *AmatPrivate = data->Jmat_private;
01271 *PmatPrivate = data->Jmat_private;
01272 *pFlag = DIFFERENT_NONZERO_PATTERN;
01273 }
01274
01275 void getPrivateMatricesForKSP_Shell_Jac1(Mat mat,
01276 Mat *AmatPrivate, Mat *PmatPrivate, MatStructure* pFlag) {
01277 PetscTruth isshell;
01278 PetscTypeCompare((PetscObject)mat, MATSHELL, &isshell);
01279 assert(isshell);
01280 Jac1MFreeData* data;
01281 MatShellGetContext(mat, (void**)(&data));
01282 *AmatPrivate = data->Jmat_private;
01283 *PmatPrivate = data->Jmat_private;
01284 *pFlag = DIFFERENT_NONZERO_PATTERN;
01285 }
01286
01287 void getPrivateMatricesForKSP_Shell_Jac2(Mat mat,
01288 Mat *AmatPrivate, Mat *PmatPrivate, MatStructure* pFlag) {
01289 PetscTruth isshell;
01290 PetscTypeCompare((PetscObject)mat, MATSHELL, &isshell);
01291 assert(isshell);
01292 ot::DAMG damg;
01293 MatShellGetContext(mat, (void**)(&damg));
01294 Jac2MFreeData* data = (static_cast<Jac2MFreeData*>(damg->user));
01295 *AmatPrivate = data->Jmat_private;
01296 *PmatPrivate = data->Jmat_private;
01297 *pFlag = DIFFERENT_NONZERO_PATTERN;
01298 }
01299
01300 void getPrivateMatricesForKSP_Shell_Jac3(Mat mat,
01301 Mat *AmatPrivate, Mat *PmatPrivate, MatStructure* pFlag) {
01302 PetscTruth isshell;
01303 PetscTypeCompare((PetscObject)mat, MATSHELL, &isshell);
01304 assert(isshell);
01305 ot::DAMG damg;
01306 MatShellGetContext(mat, (void**)(&damg));
01307 Jac3MFreeData *data = (static_cast<Jac3MFreeData*>(damg->user));
01308 *AmatPrivate = data->Jmat_private;
01309 *PmatPrivate = data->Jmat_private;
01310 *pFlag = DIFFERENT_NONZERO_PATTERN;
01311 }
01312
01313 PetscErrorCode CreateAndComputeMassMatrix(ot::DAMG damg, Mat* jac) {
01314 unsigned int m,n;
01315 PetscFunctionBegin;
01316 ot::DA* da = damg->da;
01317
01318 m=n=da->getNodeSize();
01319 Jac1MFreeData* data = new Jac1MFreeData;
01320 data->da = da;
01321 data->inTmp = NULL;
01322 data->outTmp = NULL;
01323 data->Jmat_private = NULL;
01324 iC(MatCreateShell(da->getComm(), m ,n,PETSC_DETERMINE,PETSC_DETERMINE, (void*)(data), jac));
01325 iC(MatShellSetOperation(*jac ,MATOP_MULT, (void(*)(void)) MassMatMult));
01326 iC(MatShellSetOperation(*jac ,MATOP_GET_DIAGONAL, (void(*)(void)) MassMatGetDiagonal));
01327 iC(MatShellSetOperation(*jac ,MATOP_DESTROY, (void(*)(void)) MassMatDestroy));
01328 PetscFunctionReturn(0);
01329 }
01330
01331
01332 PetscErrorCode CreateJacobian1(ot::DAMG damg,Mat *jac) {
01333 PetscFunctionBegin;
01334 PetscInt buildFullCoarseMat;
01335 PetscInt buildFullMatAll;
01336 int totalLevels;
01337 PetscTruth flg;
01338 PetscOptionsGetInt(PETSC_NULL, "-buildFullMatAll", &buildFullMatAll, &flg);
01339 PetscOptionsGetInt(PETSC_NULL, "-buildFullCoarseMat", &buildFullCoarseMat, &flg);
01340 if(buildFullMatAll) {
01341 buildFullCoarseMat = 1;
01342 }
01343 totalLevels = damg->totalLevels;
01344 ot::DA* da = damg->da;
01345 int myRank;
01346 MPI_Comm_rank(da->getComm(), &myRank);
01347
01348 unsigned int m,n;
01349 m=n=da->getNodeSize();
01350 if(totalLevels == damg->nlevels) {
01351
01352 if( (!myRank) && buildFullCoarseMat ) {
01353 std::cout<<"Building Full Coarse Mat."<<std::endl;
01354 }
01355 if(buildFullCoarseMat) {
01356 if(!(da->computedLocalToGlobal())) {
01357 da->computeLocalToGlobalMappings();
01358 }
01359 }
01360 bool requirePrivateMats = (da->getNpesActive() != da->getNpesAll());
01361 if(requirePrivateMats) {
01362 Jac1MFreeData* data = new Jac1MFreeData;
01363 data->da = da;
01364 if(damg->nlevels == 1) {
01365 data->isFinestLevel = true;
01366 }else {
01367 data->isFinestLevel = false;
01368 }
01369 if(da->iAmActive()) {
01370 if(buildFullCoarseMat) {
01371 CreateAndComputeFullActiveJacobian1(damg, &(data->Jmat_private));
01372 } else {
01373 iC(MatCreateShell(damg->da->getCommActive(), m ,n,PETSC_DETERMINE,PETSC_DETERMINE,
01374 (void*)(data), &(data->Jmat_private)));
01375
01376 iC(MatShellSetOperation( data->Jmat_private, MATOP_MULT,
01377 (void(*)(void)) Jacobian1MatMult));
01378
01379 iC(MatShellSetOperation( data->Jmat_private, MATOP_GET_DIAGONAL,
01380 (void(*)(void)) Jacobian1MatGetDiagonal));
01381
01382 iC(MatShellSetOperation(data->Jmat_private ,MATOP_DESTROY,
01383 (void(*)(void)) Jacobian1MatDestroy));
01384 }
01385 MatGetVecs(data->Jmat_private, &(data->inTmp), &(data->outTmp));
01386 } else {
01387 data->Jmat_private = NULL;
01388 data->inTmp = NULL;
01389 data->outTmp = NULL;
01390 }
01391 MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE,PETSC_DETERMINE,
01392 (void*)(data), jac);
01393 MatShellSetOperation(*jac ,MATOP_DESTROY, (void(*)(void)) Jacobian1MatDestroy);
01394 MatShellSetOperation(*jac ,MATOP_MULT, (void(*)(void)) Jacobian1ShellMatMult);
01395 } else {
01396 if(buildFullCoarseMat) {
01397 CreateAndComputeFullJacobian1(damg, jac);
01398 } else {
01399 Jac1MFreeData* data = new Jac1MFreeData;
01400 data->da = da;
01401 if(damg->nlevels == 1) {
01402 data->isFinestLevel = true;
01403 }else {
01404 data->isFinestLevel = false;
01405 }
01406 data->Jmat_private = NULL;
01407 data->inTmp = NULL;
01408 data->outTmp = NULL;
01409 MatCreateShell(damg->comm, m ,n,PETSC_DETERMINE,PETSC_DETERMINE,
01410 (void*)(data), jac);
01411
01412 MatShellSetOperation(*jac ,MATOP_MULT,
01413 (void(*)(void)) Jacobian1MatMult);
01414
01415 MatShellSetOperation(*jac ,MATOP_GET_DIAGONAL,
01416 (void(*)(void)) Jacobian1MatGetDiagonal);
01417
01418 MatShellSetOperation(*jac ,MATOP_DESTROY,
01419 (void(*)(void)) Jacobian1MatDestroy);
01420 }
01421 }
01422 if( (!myRank) && buildFullCoarseMat ) {
01423 std::cout<<"Finished Building Full Coarse Mat."<<std::endl;
01424 }
01425 } else {
01426
01427 if(buildFullMatAll) {
01428 if(!(da->computedLocalToGlobal())) {
01429 da->computeLocalToGlobalMappings();
01430 }
01431 if(!myRank) {
01432 std::cout<<"Building Full Mat for level: "<<(damg->nlevels)<<std::endl;
01433 }
01434 CreateAndComputeFullJacobian1(damg,jac);
01435 if(!myRank) {
01436 std::cout<<"Finished Building Full Mat for level: "<<(damg->nlevels)<<std::endl;
01437 }
01438 } else {
01439 Jac1MFreeData* data = new Jac1MFreeData;
01440 data->da = da;
01441 if(damg->nlevels == 1) {
01442 data->isFinestLevel = true;
01443 }else {
01444 data->isFinestLevel = false;
01445 }
01446 data->Jmat_private = NULL;
01447 data->inTmp = NULL;
01448 data->outTmp = NULL;
01449 MatCreateShell(damg->comm, m ,n,PETSC_DETERMINE,PETSC_DETERMINE,
01450 (void*)(data), jac);
01451 MatShellSetOperation(*jac ,MATOP_MULT, (void(*)(void)) Jacobian1MatMult);
01452 MatShellSetOperation(*jac ,MATOP_GET_DIAGONAL, (void(*)(void)) Jacobian1MatGetDiagonal);
01453 MatShellSetOperation(*jac ,MATOP_DESTROY, (void(*)(void)) Jacobian1MatDestroy);
01454 }
01455 }
01456
01457 PetscFunctionReturn(0);
01458 }
01459
01460 PetscErrorCode CreateAndComputeFullJacobian1(ot::DAMG damg,Mat *mat)
01461 {
01462 PetscFunctionBegin;
01463 CreateAndComputeFullJacobian1(damg->da, mat);
01464 PetscFunctionReturn(0);
01465 }
01466
01467 PetscErrorCode CreateAndComputeFullActiveJacobian1(ot::DAMG damg,Mat *mat)
01468 {
01469 PetscFunctionBegin;
01470 CreateAndComputeFullActiveJacobian1(damg->da, mat);
01471 PetscFunctionReturn(0);
01472 }
01473
01474 PetscErrorCode ComputeJacobian1(ot::DAMG damg,Mat J, Mat B) {
01475
01476
01477 PetscFunctionBegin;
01478
01479 PetscFunctionReturn(0);
01480 }
01481
01482 PetscErrorCode CreateJacobian2(ot::DAMG damg, Mat *jac) {
01483 PetscFunctionBegin;
01484 int totalLevels;
01485 PetscTruth flg;
01486 PetscInt buildFullCoarseMat;
01487 PetscInt buildFullMatAll;
01488 PetscOptionsGetInt(PETSC_NULL,"-buildFullMatAll",&buildFullMatAll,&flg);
01489 PetscOptionsGetInt(PETSC_NULL,"-buildFullCoarseMat",&buildFullCoarseMat,&flg);
01490 if(buildFullMatAll) {
01491 buildFullCoarseMat = 1;
01492 }
01493 totalLevels = damg->totalLevels;
01494 ot::DA* da = damg->da;
01495 int myRank;
01496 MPI_Comm_rank(da->getComm(),&myRank);
01497
01498 unsigned int m,n;
01499 m=n=da->getNodeSize();
01500 if(totalLevels == damg->nlevels) {
01501
01502 if( (!myRank) && buildFullCoarseMat ) {
01503 std::cout<<"Building Full Coarse Mat."<<std::endl;
01504 }
01505 char matType[30];
01506 if(buildFullCoarseMat) {
01507 if(!(da->computedLocalToGlobal())) {
01508 da->computeLocalToGlobalMappings();
01509 }
01510 PetscTruth typeFound;
01511 PetscOptionsGetString(PETSC_NULL,"-fullJacMatType",matType,30,&typeFound);
01512 if(!typeFound) {
01513 std::cout<<"I need a MatType for the full Jacobian matrix!"<<std::endl;
01514 assert(false);
01515 }
01516 }
01517 bool requirePrivateMats = (da->getNpesActive() != da->getNpesAll());
01518 if(requirePrivateMats ) {
01519 Jac2MFreeData *data = (static_cast<Jac2MFreeData*>(damg->user));
01520 if(da->iAmActive()) {
01521 if(buildFullCoarseMat) {
01522 da->createActiveMatrix(data->Jmat_private, matType, 1);
01523 } else {
01524 MatCreateShell(da->getCommActive(), m, n, PETSC_DETERMINE,
01525 PETSC_DETERMINE, damg, &(data->Jmat_private));
01526 MatShellSetOperation(data->Jmat_private, MATOP_MULT,
01527 (void (*)(void)) Jacobian2MatMult);
01528 MatShellSetOperation(data->Jmat_private, MATOP_GET_DIAGONAL,
01529 (void (*)(void)) Jacobian2MatGetDiagonal);
01530 MatShellSetOperation(data->Jmat_private, MATOP_DESTROY,
01531 (void (*)(void)) Jacobian2MatDestroy);
01532 }
01533 MatGetVecs(data->Jmat_private, &(data->inTmp), &(data->outTmp));
01534 } else {
01535 data->Jmat_private = NULL;
01536 data->inTmp = NULL;
01537 data->outTmp = NULL;
01538 }
01539 MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE, PETSC_DETERMINE, damg, jac);
01540 MatShellSetOperation(*jac ,MATOP_DESTROY, (void (*)(void)) Jacobian2MatDestroy);
01541 MatShellSetOperation(*jac ,MATOP_MULT, (void(*)(void)) Jacobian2ShellMatMult);
01542 } else {
01543 if(buildFullCoarseMat) {
01544 da->createMatrix(*jac, matType, 1);
01545 } else {
01546 MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE, PETSC_DETERMINE, damg, jac);
01547 MatShellSetOperation(*jac ,MATOP_MULT, (void (*)(void)) Jacobian2MatMult);
01548 MatShellSetOperation(*jac ,MATOP_GET_DIAGONAL, (void (*)(void)) Jacobian2MatGetDiagonal);
01549 MatShellSetOperation(*jac ,MATOP_DESTROY, (void (*)(void)) Jacobian2MatDestroy);
01550 }
01551 }
01552 if((!myRank) && buildFullCoarseMat) {
01553 std::cout<<"Finished Building Full Coarse Mat."<<std::endl;
01554 }
01555 } else {
01556
01557 if(buildFullMatAll) {
01558 if(!myRank) {
01559 std::cout<<"Building Full Mat for level: "<<(damg->nlevels)<<std::endl;
01560 }
01561 if(!(da->computedLocalToGlobal())) {
01562 da->computeLocalToGlobalMappings();
01563 }
01564 char matType[30];
01565 PetscTruth typeFound;
01566 PetscOptionsGetString(PETSC_NULL,"-fullJacMatType",matType,30,&typeFound);
01567 if(!typeFound) {
01568 std::cout<<"I need a MatType for the full Jacobian matrix!"<<std::endl;
01569 assert(false);
01570 }
01571 da->createMatrix(*jac, matType, 1);
01572 if(!myRank) {
01573 std::cout<<"Finished Building Full Mat for level: "<<(damg->nlevels)<<std::endl;
01574 }
01575 } else {
01576 MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE, PETSC_DETERMINE, damg, jac);
01577 MatShellSetOperation(*jac ,MATOP_MULT, (void (*)(void)) Jacobian2MatMult);
01578 MatShellSetOperation(*jac ,MATOP_GET_DIAGONAL, (void (*)(void)) Jacobian2MatGetDiagonal);
01579 MatShellSetOperation(*jac ,MATOP_DESTROY, (void (*)(void)) Jacobian2MatDestroy);
01580 }
01581 }
01582
01583 PetscFunctionReturn(0);
01584 }
01585
01586 PetscErrorCode Jacobian2MatDestroy(Mat J) {
01587 PetscFunctionBegin;
01588
01589
01590
01591 PetscFunctionReturn(0);
01592 }
01593
01594 #define JAC_TYPE2_ELEM_DIAG_BLOCK {\
01595 unsigned int idx = da->curr();\
01596 unsigned int lev = da->getLevel(idx);\
01597 double h = hFac*(1u << (maxD - lev));\
01598 double matP1 = matPropArr[2*idx];\
01599 double matP2 = matPropArr[2*idx+1];\
01600 double fac1 = matP1*h/2.0;\
01601 double fac2 = matP2*h*h*h/8.0;\
01602 unsigned int indices[8];\
01603 da->getNodeIndices(indices);\
01604 unsigned char childNum = da->getChildNumber();\
01605 unsigned char hnMask = da->getHangingNodeIndex(idx);\
01606 unsigned char elemType = 0;\
01607 GET_ETYPE_BLOCK(elemType,hnMask,childNum)\
01608 for(int k = 0; k < 8; k++) {\
01609 diagArr[indices[k]] += ((fac1*(LaplacianType2Stencil[childNum][elemType][k][k])) +\
01610 (fac2*(MassType2Stencil[childNum][elemType][k][k])));\
01611 } \
01612 }
01613
01614 #define JAC_TYPE2_DIAG_BLOCK {\
01615 ot::DA* da = damg->da;\
01616 iC(VecZeroEntries(diag));\
01617 double *matPropArr;\
01618 \
01619 da->vecGetBuffer<double>(*(data->matProp),matPropArr,true,true,true,2);\
01620 PetscScalar *diagArr;\
01621 \
01622 da->vecGetBuffer(diag,diagArr,false,false,false,1);\
01623 unsigned int maxD;\
01624 double hFac;\
01625 if(da->iAmActive()) {\
01626 maxD = (da->getMaxDepth());\
01627 hFac = 1.0/((double)(1u << (maxD-1)));\
01628 \
01629 for(da->init<ot::DA_FLAGS::ALL>();\
01630 da->curr() < da->end<ot::DA_FLAGS::ALL>();\
01631 da->next<ot::DA_FLAGS::ALL>()) {\
01632 JAC_TYPE2_ELEM_DIAG_BLOCK\
01633 } \
01634 } \
01635 da->vecRestoreBuffer<double>(*(data->matProp),matPropArr,true,true,true,2);\
01636 da->vecRestoreBuffer(diag,diagArr,false,false,false,1);\
01637 PetscLogFlops(44*(da->getGhostedElementSize()));\
01638 }
01639
01640 PetscErrorCode Jacobian2MatGetDiagonal(Mat J, Vec diag) {
01641 PetscFunctionBegin;
01642
01643 PetscLogEventBegin(Jac2DiagEvent,diag,0,0,0);
01644
01645 ot::DAMG damg;
01646 iC(MatShellGetContext(J, (void**)(&damg)));
01647
01648 Jac2MFreeData *data = (static_cast<Jac2MFreeData*>(damg->user));
01649
01650 if(data->isFinestLevel) {
01651 PetscLogEventBegin(Jac2FinestDiagEvent,diag,0,0,0);
01652 }
01653
01654 JAC_TYPE2_DIAG_BLOCK
01655
01656 if(data->isFinestLevel) {
01657 PetscLogEventEnd(Jac2FinestDiagEvent,diag,0,0,0);
01658 }
01659
01660 PetscLogEventEnd(Jac2DiagEvent,diag,0,0,0);
01661
01662 PetscFunctionReturn(0);
01663 }
01664
01665 #define JAC_TYPE2_ELEM_MULT_BLOCK {\
01666 unsigned int idx = da->curr();\
01667 unsigned int lev = da->getLevel(idx);\
01668 double h = hFac*(1u << (maxD - lev));\
01669 double matP1 = matPropArr[2*idx];\
01670 double matP2 = matPropArr[2*idx+1];\
01671 double fac1 = matP1*h/2.0;\
01672 double fac2 = matP2*h*h*h/8.0;\
01673 unsigned int indices[8];\
01674 da->getNodeIndices(indices);\
01675 unsigned char childNum = da->getChildNumber();\
01676 unsigned char hnMask = da->getHangingNodeIndex(idx);\
01677 unsigned char elemType = 0;\
01678 GET_ETYPE_BLOCK(elemType,hnMask,childNum)\
01679 for(int k = 0;k < 8;k++) {\
01680 for(int j=0;j<8;j++) {\
01681 outArr[indices[k]] += (((fac1*(LaplacianType2Stencil[childNum][elemType][k][j])) +\
01682 (fac2*(MassType2Stencil[childNum][elemType][k][j])))*inArr[indices[j]]);\
01683 }\
01684 }\
01685 }
01686
01687 #define JAC_TYPE2_MULT_BLOCK {\
01688 ot::DA* da = damg->da;\
01689 iC(VecZeroEntries(out));\
01690 unsigned int maxD;\
01691 double hFac;\
01692 if(da->iAmActive()) {\
01693 maxD = da->getMaxDepth();\
01694 hFac = 1.0/((double)(1u << (maxD-1)));\
01695 }\
01696 double *matPropArr = NULL;\
01697 \
01698 da->vecGetBuffer<double>(*(data->matProp),matPropArr,true,true,true,2);\
01699 PetscScalar *outArr=NULL;\
01700 PetscScalar *inArr=NULL;\
01701 \
01702 da->vecGetBuffer(in,inArr,false,false,true,1);\
01703 if(da->iAmActive()) {\
01704 da->ReadFromGhostsBegin<PetscScalar>(inArr,1);\
01705 }\
01706 \
01707 da->vecGetBuffer(out,outArr,false,false,false,1);\
01708 \
01709 if(da->iAmActive()) {\
01710 for(da->init<ot::DA_FLAGS::INDEPENDENT>();\
01711 da->curr() < da->end<ot::DA_FLAGS::INDEPENDENT>();\
01712 da->next<ot::DA_FLAGS::INDEPENDENT>() ) {\
01713 JAC_TYPE2_ELEM_MULT_BLOCK\
01714 } \
01715 } \
01716 if(da->iAmActive()) {\
01717 da->ReadFromGhostsEnd<PetscScalar>(inArr);\
01718 }\
01719 \
01720 \
01721 \
01722 \
01723 if(da->iAmActive()) {\
01724 for(da->init<ot::DA_FLAGS::DEPENDENT>();\
01725 da->curr() < da->end<ot::DA_FLAGS::DEPENDENT>();\
01726 da->next<ot::DA_FLAGS::DEPENDENT>() ) {\
01727 JAC_TYPE2_ELEM_MULT_BLOCK\
01728 } \
01729 } \
01730 da->vecRestoreBuffer<double>(*(data->matProp),matPropArr,true,true,true,2);\
01731 da->vecRestoreBuffer(in,inArr,false,false,true,1);\
01732 da->vecRestoreBuffer(out,outArr,false,false,false,1);\
01733 PetscLogFlops(332*(da->getGhostedElementSize()));\
01734 }
01735
01736 #define JAC_TYPE2_MULT_DEBUG_BLOCK {\
01737 ot::DA* da = damg->da;\
01738 unsigned int maxD;\
01739 double hFac;\
01740 if(da->iAmActive()) {\
01741 maxD = da->getMaxDepth();\
01742 hFac = 1.0/((double)(1u << (maxD-1)));\
01743 }\
01744 double *matPropArr = NULL;\
01745 \
01746 da->vecGetBuffer<double>(*(data->matProp),matPropArr,true,true,true,2);\
01747 PetscScalar *outArr=NULL;\
01748 PetscScalar *inArr=NULL;\
01749 \
01750 da->vecGetBuffer(in,inArr,false,false,true,1);\
01751 if(da->iAmActive()) {\
01752 da->ReadFromGhostsBegin<PetscScalar>(inArr,1);\
01753 da->ReadFromGhostsEnd<PetscScalar>(inArr);\
01754 }\
01755 \
01756 VecZeroEntries(out);\
01757 da->vecGetBuffer(out,outArr,false,false,false,1);\
01758 if(da->iAmActive()) {\
01759 for(da->init<ot::DA_FLAGS::WRITABLE>();\
01760 da->curr() < da->end<ot::DA_FLAGS::WRITABLE>();\
01761 da->next<ot::DA_FLAGS::WRITABLE>() ) {\
01762 JAC_TYPE2_ELEM_MULT_BLOCK\
01763 } \
01764 } \
01765 if(da->iAmActive()) {\
01766 da->WriteToGhostsBegin<PetscScalar>(outArr,1);\
01767 da->WriteToGhostsEnd<PetscScalar>(outArr,1);\
01768 }\
01769 da->vecRestoreBuffer<double>(*(data->matProp),matPropArr,true,true,true,2);\
01770 da->vecRestoreBuffer(in,inArr,false,false,true,1);\
01771 da->vecRestoreBuffer(out,outArr,false,false,false,1);\
01772 PetscLogFlops(332*(da->getGhostedElementSize()));\
01773 }
01774
01775 PetscErrorCode Jacobian2MatMult(Mat J, Vec in, Vec out)
01776 {
01777 PetscFunctionBegin;
01778
01779 PetscLogEventBegin(Jac2MultEvent,in,out,0,0);
01780
01781 ot::DAMG damg;
01782 iC(MatShellGetContext(J, (void**)(&damg)));
01783
01784 Jac2MFreeData *data = (static_cast<Jac2MFreeData*>(damg->user));
01785
01786 if(data->isFinestLevel) {
01787 PetscLogEventBegin(Jac2FinestMultEvent,in,out,0,0);
01788 }
01789
01790 JAC_TYPE2_MULT_BLOCK
01791
01792 if(data->isFinestLevel) {
01793 PetscLogEventEnd(Jac2FinestMultEvent,in,out,0,0);
01794 }
01795
01796 PetscLogEventEnd(Jac2MultEvent,in,out,0,0);
01797
01798 PetscFunctionReturn(0);
01799 }
01800
01801 #undef JAC_TYPE2_MULT_DEBUG_BLOCK
01802
01803 #define BUILD_FULL_JAC_TYPE2_BLOCK(B) {\
01804 ot::DA* da = damg->da;\
01805 MatZeroEntries(B);\
01806 std::vector<ot::MatRecord> records;\
01807 unsigned int maxD;\
01808 double hFac;\
01809 if(da->iAmActive()) {\
01810 maxD = da->getMaxDepth();\
01811 hFac = 1.0/((double)(1u << (maxD-1)));\
01812 }\
01813 double *matPropArr = NULL;\
01814 \
01815 \
01816 \
01817 \
01818 da->vecGetBuffer<double>(*(data->matProp),matPropArr,true,true,true,2);\
01819 if(da->iAmActive()) {\
01820 for(da->init<ot::DA_FLAGS::WRITABLE>();\
01821 da->curr() < da->end<ot::DA_FLAGS::WRITABLE>();\
01822 da->next<ot::DA_FLAGS::WRITABLE>()) {\
01823 unsigned int idx = da->curr();\
01824 unsigned int lev = da->getLevel(idx);\
01825 double h = hFac*(1u << (maxD - lev));\
01826 double matP1 = matPropArr[2*idx];\
01827 double matP2 = matPropArr[2*idx+1];\
01828 double fac1 = matP1*h/2.0;\
01829 double fac2 = matP2*h*h*h/8.0;\
01830 unsigned int indices[8];\
01831 da->getNodeIndices(indices);\
01832 unsigned char childNum = da->getChildNumber();\
01833 unsigned char hnMask = da->getHangingNodeIndex(idx);\
01834 unsigned char elemType = 0;\
01835 GET_ETYPE_BLOCK(elemType,hnMask,childNum)\
01836 for(int k = 0;k < 8;k++) {\
01837 for(int j=0;j<8;j++) {\
01838 ot::MatRecord currRec;\
01839 currRec.rowIdx = indices[k];\
01840 currRec.colIdx = indices[j];\
01841 currRec.rowDim = 0;\
01842 currRec.colDim = 0;\
01843 currRec.val = ((fac1*(LaplacianType2Stencil[childNum][elemType][k][j])) +\
01844 (fac2*(MassType2Stencil[childNum][elemType][k][j])));\
01845 records.push_back(currRec);\
01846 } \
01847 } \
01848 if(records.size() > 1000) {\
01849 \
01850 da->setValuesInMatrix(B, records, 1, ADD_VALUES);\
01851 }\
01852 } \
01853 } \
01854 da->setValuesInMatrix(B, records, 1, ADD_VALUES);\
01855 MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY);\
01856 da->vecRestoreBuffer<double>(*(data->matProp),matPropArr,true,true,true,2);\
01857 MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY);\
01858 }
01859
01860 PetscErrorCode ComputeJacobian2(ot::DAMG damg, Mat J, Mat B) {
01861
01862 PetscFunctionBegin;
01863
01864 PetscTruth isshell;
01865 PetscTypeCompare((PetscObject)B, MATSHELL, &isshell);
01866
01867 Jac2MFreeData *data = (static_cast<Jac2MFreeData*>(damg->user));
01868
01869 assert(B == J);
01870
01871 if(isshell) {
01872 if( data->Jmat_private == NULL ) {
01873 PetscFunctionReturn(0);
01874 } else {
01875 J = data->Jmat_private;
01876 B = data->Jmat_private;
01877 }
01878 }
01879
01880
01881
01882 PetscTypeCompare((PetscObject)B, MATSHELL, &isshell);
01883 if(isshell) {
01884
01885 PetscFunctionReturn(0);
01886 }
01887
01888 BUILD_FULL_JAC_TYPE2_BLOCK(B)
01889
01890 PetscFunctionReturn(0);
01891 }
01892
01893
01894
01895 PetscErrorCode CreateJacobian3(ot::DAMG damg,Mat *jac) {
01896 PetscFunctionBegin;
01897 int totalLevels;
01898 PetscTruth flg;
01899 PetscInt buildFullMatAll;
01900 PetscInt buildFullCoarseMat;
01901 PetscOptionsGetInt(PETSC_NULL,"-buildFullMatAll",&buildFullMatAll,&flg);
01902 PetscOptionsGetInt(PETSC_NULL,"-buildFullCoarseMat",&buildFullCoarseMat,&flg);
01903 if(buildFullMatAll) {
01904 buildFullCoarseMat = 1;
01905 }
01906 totalLevels = damg->nlevels;
01907 ot::DA* da = damg->da;
01908 int myRank;
01909 MPI_Comm_rank(da->getComm(), &myRank);
01910
01911 unsigned int m,n;
01912 m=n=da->getNodeSize();
01913 if(totalLevels == damg->nlevels) {
01914
01915 if( (!myRank) && buildFullCoarseMat ) {
01916 std::cout<<"Building Full Mat for the coarsest level."<<std::endl;
01917 }
01918 char matType[30];
01919 if(buildFullCoarseMat) {
01920 if(!(da->computedLocalToGlobal())) {
01921 da->computeLocalToGlobalMappings();
01922 }
01923 PetscTruth typeFound;
01924 PetscOptionsGetString(PETSC_NULL,"-fullJacMatType",matType,30,&typeFound);
01925 if(!typeFound) {
01926 std::cout<<"I need a MatType for the full Jacobian matrix!"<<std::endl;
01927 assert(false);
01928 }
01929 }
01930 bool requirePrivateMats = (da->getNpesActive() != da->getNpesAll());
01931 if(requirePrivateMats) {
01932 Jac3MFreeData *data = (static_cast<Jac3MFreeData*>(damg->user));
01933 if(da->iAmActive()) {
01934 if(buildFullCoarseMat) {
01935 da->createActiveMatrix(data->Jmat_private, matType, 1);
01936 } else {
01937 MatCreateShell(damg->da->getCommActive(), m ,n, PETSC_DETERMINE,
01938 PETSC_DETERMINE, damg, &(data->Jmat_private) );
01939
01940 MatShellSetOperation(data->Jmat_private ,MATOP_MULT,
01941 (void (*)(void)) Jacobian3MatMult);
01942
01943 MatShellSetOperation(data->Jmat_private ,MATOP_GET_DIAGONAL,
01944 (void (*)(void)) Jacobian3MatGetDiagonal);
01945
01946 MatShellSetOperation(data->Jmat_private ,MATOP_DESTROY,
01947 (void (*)(void)) Jacobian3MatDestroy);
01948 }
01949 MatGetVecs(data->Jmat_private, &(data->inTmp), &(data->outTmp));
01950 } else {
01951 data->Jmat_private = NULL;
01952 data->inTmp = NULL;
01953 data->outTmp = NULL;
01954 }
01955 MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE, PETSC_DETERMINE, damg, jac);
01956 MatShellSetOperation(*jac ,MATOP_DESTROY, (void (*)(void)) Jacobian3MatDestroy);
01957 MatShellSetOperation(*jac ,MATOP_MULT, (void(*)(void)) Jacobian3ShellMatMult);
01958 } else {
01959 if(buildFullCoarseMat) {
01960 da->createMatrix(*jac, matType, 1);
01961 } else {
01962 MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE, PETSC_DETERMINE, damg, jac);
01963 MatShellSetOperation(*jac ,MATOP_MULT, (void (*)(void)) Jacobian3MatMult);
01964 MatShellSetOperation(*jac ,MATOP_GET_DIAGONAL, (void (*)(void)) Jacobian3MatGetDiagonal);
01965 MatShellSetOperation(*jac ,MATOP_DESTROY, (void (*)(void)) Jacobian3MatDestroy);
01966 }
01967 }
01968 if( (!myRank) && buildFullCoarseMat ) {
01969 std::cout<<"Finished Building Full Mat for the coarsest level."<<std::endl;
01970 }
01971 } else {
01972
01973 if(buildFullMatAll) {
01974 if(!myRank) {
01975 std::cout<<"Building Full Mat for level: "<<(damg->nlevels)<<std::endl;
01976 }
01977 if(!(da->computedLocalToGlobal())) {
01978 da->computeLocalToGlobalMappings();
01979 }
01980 char matType[30];
01981 PetscTruth typeFound;
01982 PetscOptionsGetString(PETSC_NULL,"-fullJacMatType",matType,30,&typeFound);
01983 if(!typeFound) {
01984 std::cout<<"I need a MatType for the full Jacobian matrix!"<<std::endl;
01985 assert(false);
01986 }
01987 da->createMatrix(*jac, matType, 1);
01988 if(!myRank) {
01989 std::cout<<"Finished Building Full Mat for level: "<<(damg->nlevels)<<std::endl;
01990 }
01991 } else {
01992 MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE, PETSC_DETERMINE, damg, jac);
01993 MatShellSetOperation(*jac ,MATOP_MULT, (void (*)(void)) Jacobian3MatMult);
01994 MatShellSetOperation(*jac ,MATOP_GET_DIAGONAL, (void (*)(void)) Jacobian3MatGetDiagonal);
01995 MatShellSetOperation(*jac ,MATOP_DESTROY, (void (*)(void)) Jacobian3MatDestroy);
01996 }
01997 }
01998
01999 PetscFunctionReturn(0);
02000 }
02001
02002 PetscErrorCode Jacobian3MatDestroy(Mat J) {
02003 PetscFunctionBegin;
02004
02005
02006
02007 PetscFunctionReturn(0);
02008 }
02009
02010 #define JAC_TYPE3_DIAG_BLOCK {\
02011 \
02012 \
02013 \
02014 Point Cpt = da->getCurrentOffset();\
02015 while(daf->getCurrentOffset() != Cpt) {\
02016 daf->next<ot::DA_FLAGS::WRITABLE>();\
02017 }\
02018 unsigned int idxC= da->curr();\
02019 unsigned int lev = da->getLevel(idxC);\
02020 double h = hFac*(1u << (maxD - lev));\
02021 unsigned int indices[8];\
02022 da->getNodeIndices(indices);\
02023 unsigned char childNum = da->getChildNumber();\
02024 unsigned char hnMask = da->getHangingNodeIndex(idxC);\
02025 unsigned char elemType = 0;\
02026 GET_ETYPE_BLOCK(elemType,hnMask,childNum)\
02027 if(daf->getLevel(daf->curr()) == lev) {\
02028 \
02029 type2Cnt++;\
02030 unsigned int idxF = daf->curr();\
02031 double matP1 = matPropArr[2*idxF];\
02032 double matP2 = matPropArr[2*idxF+1];\
02033 double fac1 = matP1*h/2.0;\
02034 double fac2 = matP2*h*h*h/8.0;\
02035 for(int k = 0; k < 8; k++) {\
02036 diagArr[indices[k]] += ((fac1*(LaplacianType2Stencil[childNum][elemType][k][k])) +\
02037 (fac2*(MassType2Stencil[childNum][elemType][k][k])));\
02038 } \
02039 daf->next<ot::DA_FLAGS::WRITABLE>();\
02040 }else {\
02041 type1Cnt++;\
02042 for(unsigned int cNumFine = 0; cNumFine < 8; cNumFine++) {\
02043 \
02044 \
02045 \
02046 unsigned int idxF = daf->curr();\
02047 double matP1 = matPropArr[2*idxF];\
02048 double matP2 = matPropArr[2*idxF+1];\
02049 double fac1 = matP1*h/2.0;\
02050 double fac2 = matP2*h*h*h/8.0;\
02051 for(int k = 0; k < 8; k++) {\
02052 diagArr[indices[k]] += \
02053 ((fac1*(LaplacianType1Stencil[childNum][elemType][cNumFine][k][k])) +\
02054 (fac2*(MassType1Stencil[childNum][elemType][cNumFine][k][k])));\
02055 } \
02056 daf->next<ot::DA_FLAGS::WRITABLE>();\
02057 } \
02058 }\
02059 }
02060
02061 PetscErrorCode Jacobian3MatGetDiagonal(Mat J, Vec diag) {
02062
02063 PetscFunctionBegin;
02064
02065 PetscLogEventBegin(Jac3DiagEvent,0,0,0,0);
02066
02067 ot::DAMG damg;
02068 iC(MatShellGetContext(J, (void**)(&damg)));
02069
02070 Jac3MFreeData *data = (static_cast<Jac3MFreeData*>(damg->user));
02071
02072 if(data->isFinestLevel) {
02073 PetscLogEventBegin(Jac3FinestDiagEvent,0,0,0,0);
02074 }
02075
02076 if( (data->isFinestLevel) ||
02077 ( (data->JmatThisLevel != data->BmatThisLevel)
02078 && (J == data->BmatThisLevel) ) ) {
02079 JAC_TYPE2_DIAG_BLOCK
02080 }else {
02081
02082
02083 ot::DA* da = damg->da;
02084 ot::DA* daf = data->daf;
02085 assert(da->iAmActive() == daf->iAmActive());
02086 double *matPropArr = NULL;
02087 if(data->changedPartition) {
02088
02089 daf->vecGetBuffer<double>(*(data->matPropFine),matPropArr,true,false,true,2);
02090 }else {
02091
02092 daf->vecGetBuffer<double>(*(data->matPropFine),matPropArr,true,true,true,2);
02093 }
02094 PetscScalar *diagArr = NULL;
02095 VecZeroEntries(diag);
02096
02097 da->vecGetBuffer(diag,diagArr,false,false,false,1);
02098 unsigned int maxD;
02099 double hFac;
02100 unsigned int type1Cnt = 0;
02101 unsigned int type2Cnt = 0;
02102 if(da->iAmActive()) {
02103 maxD = (da->getMaxDepth());
02104 hFac = 1.0/((double)(1u << (maxD-1)));
02105 for(da->init<ot::DA_FLAGS::W_DEPENDENT>(), daf->init<ot::DA_FLAGS::WRITABLE>();
02106 da->curr() < da->end<ot::DA_FLAGS::W_DEPENDENT>(); da->next<ot::DA_FLAGS::W_DEPENDENT>()) {
02107 JAC_TYPE3_DIAG_BLOCK
02108 }
02109 da->WriteToGhostsBegin<PetscScalar>(diagArr, 1);
02110 for(da->init<ot::DA_FLAGS::INDEPENDENT>(), daf->init<ot::DA_FLAGS::WRITABLE>();
02111 da->curr() < da->end<ot::DA_FLAGS::INDEPENDENT>(); da->next<ot::DA_FLAGS::INDEPENDENT>()) {
02112 JAC_TYPE3_DIAG_BLOCK
02113 }
02114 da->WriteToGhostsEnd<PetscScalar>(diagArr, 1);
02115 }
02116
02117 if(data->changedPartition) {
02118 daf->vecRestoreBuffer<double>(*(data->matPropFine),matPropArr,true,false,true,2);
02119 }else {
02120 daf->vecRestoreBuffer<double>(*(data->matPropFine),matPropArr,true,true,true,2);
02121 }
02122
02123 da->vecRestoreBuffer(diag,diagArr,false,false,false,1);
02124
02125 PetscLogFlops( (type1Cnt*336) + (type2Cnt*44) );
02126 }
02127
02128 if(data->isFinestLevel) {
02129 PetscLogEventEnd(Jac3FinestDiagEvent,0,0,0,0);
02130 }
02131
02132 PetscLogEventEnd(Jac3DiagEvent,0,0,0,0);
02133
02134 PetscFunctionReturn(0);
02135 }
02136
02137 #undef JAC_TYPE3_DIAG_BLOCK
02138
02139 #define JAC_TYPE3_MULT_BLOCK {\
02140 \
02141 \
02142 \
02143 Point Cpt = da->getCurrentOffset();\
02144 while(daf->getCurrentOffset() != Cpt) {\
02145 daf->next<ot::DA_FLAGS::WRITABLE>();\
02146 }\
02147 unsigned int idxC= da->curr();\
02148 unsigned int lev = da->getLevel(idxC);\
02149 double h = hFac*(1u << (maxD - lev));\
02150 unsigned int indices[8];\
02151 da->getNodeIndices(indices);\
02152 unsigned char childNum = da->getChildNumber();\
02153 unsigned char hnMask = da->getHangingNodeIndex(idxC);\
02154 unsigned char elemType = 0;\
02155 GET_ETYPE_BLOCK(elemType,hnMask,childNum)\
02156 if(daf->getLevel(daf->curr()) == lev) {\
02157 \
02158 type2Cnt++;\
02159 unsigned int idxF = daf->curr();\
02160 double matP1 = matPropArr[2*idxF];\
02161 double matP2 = matPropArr[2*idxF+1];\
02162 double fac1 = matP1*h/2.0;\
02163 double fac2 = matP2*h*h*h/8.0;\
02164 for(int k = 0; k < 8; k++) {\
02165 for(int j = 0; j < 8; j++) {\
02166 outArr[indices[k]] += (((fac1*(LaplacianType2Stencil[childNum][elemType][k][j])) +\
02167 (fac2*(MassType2Stencil[childNum][elemType][k][j])))*inArr[indices[j]]);\
02168 } \
02169 } \
02170 daf->next<ot::DA_FLAGS::WRITABLE>();\
02171 }else {\
02172 double matP1[8];\
02173 double matP2[8];\
02174 for(unsigned int cNumFine = 0; cNumFine < 8; cNumFine++) {\
02175 \
02176 \
02177 \
02178 unsigned int idxF = daf->curr();\
02179 matP1[cNumFine] = matPropArr[2*idxF];\
02180 matP2[cNumFine] = matPropArr[2*idxF+1];\
02181 daf->next<ot::DA_FLAGS::WRITABLE>();\
02182 } \
02183 double maxP1 = matP1[0];\
02184 double minP1 = matP1[0];\
02185 double maxP2 = matP2[0];\
02186 double minP2 = matP2[0];\
02187 double totalP1 = 0.0;\
02188 double totalP2 = 0.0;\
02189 for(unsigned int cNumFine = 0; cNumFine < 8; cNumFine++) {\
02190 if(matP1[cNumFine] > maxP1) {\
02191 maxP1 = matP1[cNumFine];\
02192 }\
02193 if(matP2[cNumFine] > maxP2) {\
02194 maxP2 = matP2[cNumFine];\
02195 }\
02196 if(matP1[cNumFine] < minP1) {\
02197 minP1 = matP1[cNumFine];\
02198 }\
02199 if(matP2[cNumFine] < minP2) {\
02200 minP2 = matP2[cNumFine];\
02201 }\
02202 totalP1 += matP1[cNumFine];\
02203 totalP2 += matP2[cNumFine];\
02204 }\
02205 \
02206 \
02207 if( ( (maxP1-minP1) <= (tolToCoarsenMatProp*maxP1) )\
02208 && ( (maxP2-minP2) <= (tolToCoarsenMatProp*maxP2) ) ) {\
02209 type2Cnt++;\
02210 double fac1 = totalP1*h/16.0;\
02211 double fac2 = totalP2*h*h*h/64.0;\
02212 for(int k = 0; k < 8; k++) {\
02213 for(int j = 0; j < 8; j++) {\
02214 outArr[indices[k]] += (((fac1*(LaplacianType2Stencil[childNum][elemType][k][j])) +\
02215 (fac2*(MassType2Stencil[childNum][elemType][k][j])))*inArr[indices[j]]);\
02216 } \
02217 } \
02218 }else {\
02219 type1Cnt++;\
02220 for(unsigned int cNumFine = 0; cNumFine < 8; cNumFine++) {\
02221 double fac1 = (matP1[cNumFine])*h/2.0;\
02222 double fac2 = (matP2[cNumFine])*h*h*h/8.0;\
02223 for(int k = 0; k < 8; k++) {\
02224 for(int j = 0; j < 8; j++) {\
02225 outArr[indices[k]] +=\
02226 (((fac1*(LaplacianType1Stencil[childNum][elemType][cNumFine][k][j])) +\
02227 (fac2*(MassType1Stencil[childNum][elemType][cNumFine][k][j])))*inArr[indices[j]]);\
02228 } \
02229 } \
02230 } \
02231 }\
02232 }\
02233 }
02234
02235 PetscErrorCode Jacobian3MatMult(Mat J, Vec in, Vec out)
02236 {
02237 PetscFunctionBegin;
02238
02239 PetscLogEventBegin(Jac3MultEvent,in,out,0,0);
02240
02241 ot::DAMG damg;
02242 iC(MatShellGetContext(J, (void**)(&damg)));
02243
02244 Jac3MFreeData *data = (static_cast<Jac3MFreeData*>(damg->user));
02245
02246 if(data->isFinestLevel) {
02247 PetscLogEventBegin(Jac3FinestMultEvent,in,out,0,0);
02248 }
02249
02250
02251
02252
02253
02254 if( (data->isFinestLevel) ||
02255 ( (data->BmatThisLevel != data->JmatThisLevel)
02256 && (J == data->BmatThisLevel) ) ) {
02257 JAC_TYPE2_MULT_BLOCK
02258 }else {
02259
02260
02261 PetscReal tolToCoarsenMatProp = 1.0e-12;
02262 PetscTruth optFound;
02263 PetscOptionsGetReal(0,"-tolToCoarsenMatProp",&tolToCoarsenMatProp,&optFound);
02264 assert(tolToCoarsenMatProp >= 0.0);
02265
02266 ot::DA* da = damg->da;
02267 ot::DA* daf = data->daf;
02268 assert(da->iAmActive() == daf->iAmActive());
02269 double *matPropArr = NULL;
02270 if(data->changedPartition) {
02271
02272 daf->vecGetBuffer<double>(*(data->matPropFine),matPropArr,true,false,true,2);
02273 }else {
02274
02275 daf->vecGetBuffer<double>(*(data->matPropFine),matPropArr,true,true,true,2);
02276 }
02277 PetscScalar *inArr = NULL;
02278 PetscScalar *outArr = NULL;
02279
02280 da->vecGetBuffer(in, inArr, false, false, true, 1);
02281 if(da->iAmActive()) {
02282 da->ReadFromGhostsBegin<PetscScalar>(inArr, 1);
02283 }
02284 VecZeroEntries(out);
02285
02286 da->vecGetBuffer(out, outArr, false, false, false, 1);
02287 unsigned int maxD;
02288 double hFac;
02289 unsigned int type1Cnt = 0;
02290 unsigned int type2Cnt = 0;
02291 if(da->iAmActive()) {
02292 maxD = (da->getMaxDepth());
02293 hFac = 1.0/((double)(1u << (maxD-1)));
02294 unsigned int loopCtr = 0;
02295 unsigned int numItersFirstLoop = static_cast<unsigned int>(0.3*static_cast<double>(da->getElementSize()));
02296 for(da->init<ot::DA_FLAGS::INDEPENDENT>(), daf->init<ot::DA_FLAGS::WRITABLE>();
02297 ( (daf->currWithInfo() == daf->currWithInfo()) &&
02298 (da->currWithInfo() < da->end<ot::DA_FLAGS::INDEPENDENT>()) && (loopCtr < numItersFirstLoop) );
02299 da->next<ot::DA_FLAGS::INDEPENDENT>(), loopCtr++) {
02300 JAC_TYPE3_MULT_BLOCK
02301 }
02302 }
02303 if(da->iAmActive()) {
02304 da->ReadFromGhostsEnd<PetscScalar>(inArr);
02305 }
02306 if(da->iAmActive()) {
02307 for(da->init<ot::DA_FLAGS::W_DEPENDENT>(), daf->init<ot::DA_FLAGS::WRITABLE>();
02308 da->curr() < da->end<ot::DA_FLAGS::W_DEPENDENT>(); da->next<ot::DA_FLAGS::W_DEPENDENT>()) {
02309 JAC_TYPE3_MULT_BLOCK
02310 }
02311 da->WriteToGhostsBegin<PetscScalar>(outArr, 1);
02312 for(da->init<ot::DA_FLAGS::FROM_STORED>(), daf->init<ot::DA_FLAGS::FROM_STORED>();
02313 da->curr() < da->end<ot::DA_FLAGS::INDEPENDENT>(); da->next<ot::DA_FLAGS::INDEPENDENT>()) {
02314 JAC_TYPE3_MULT_BLOCK
02315 }
02316 da->WriteToGhostsEnd<PetscScalar>(outArr, 1);
02317 }
02318
02319 if(data->changedPartition) {
02320 daf->vecRestoreBuffer<double>(*(data->matPropFine),matPropArr,true,false,true,2);
02321 }else {
02322 daf->vecRestoreBuffer<double>(*(data->matPropFine),matPropArr,true,true,true,2);
02323 }
02324
02325 da->vecRestoreBuffer(out, outArr, false, false, false, 1);
02326 da->vecRestoreBuffer(in, inArr, false, false, true, 1);
02327
02328 PetscLogFlops( (type1Cnt*2643) + (type2Cnt*333) );
02329 }
02330
02331 if(data->isFinestLevel) {
02332 PetscLogEventEnd(Jac3FinestMultEvent,in,out,0,0);
02333 }
02334 PetscLogEventEnd(Jac3MultEvent,in,out,0,0);
02335
02336 PetscFunctionReturn(0);
02337 }
02338
02339 #undef JAC_TYPE3_MULT_BLOCK
02340
02341 #define BUILD_FULL_JAC_TYPE3_BLOCK(B) {\
02342 ot::DA* da = damg->da;\
02343 ot::DA* daf = data->daf;\
02344 MatZeroEntries(B);\
02345 std::vector<ot::MatRecord> records;\
02346 unsigned int maxD;\
02347 double hFac;\
02348 if(da->iAmActive()) {\
02349 maxD = da->getMaxDepth();\
02350 hFac = 1.0/((double)(1u << (maxD-1)));\
02351 }\
02352 double *matPropArr = NULL;\
02353 if(data->changedPartition) {\
02354 \
02355 daf->vecGetBuffer<double>(*(data->matPropFine),matPropArr,\
02356 true,false,true,2);\
02357 }else {\
02358 \
02359 daf->vecGetBuffer<double>(*(data->matPropFine),matPropArr,\
02360 true,true,true,2);\
02361 }\
02362 if(da->iAmActive()) {\
02363 assert(daf->iAmActive());\
02364 for(da->init<ot::DA_FLAGS::WRITABLE>(),\
02365 daf->init<ot::DA_FLAGS::WRITABLE>();\
02366 da->curr() < da->end<ot::DA_FLAGS::WRITABLE>();\
02367 da->next<ot::DA_FLAGS::WRITABLE>()) {\
02368 Point Cpt = da->getCurrentOffset();\
02369 while(daf->getCurrentOffset() != Cpt) {\
02370 daf->next<ot::DA_FLAGS::WRITABLE>();\
02371 }\
02372 unsigned int idxC = da->curr();\
02373 unsigned int lev = da->getLevel(idxC);\
02374 double h = hFac*(1u << (maxD - lev));\
02375 unsigned int indices[8];\
02376 da->getNodeIndices(indices);\
02377 unsigned char childNum = da->getChildNumber();\
02378 unsigned char hnMask = da->getHangingNodeIndex(idxC);\
02379 unsigned char elemType = 0;\
02380 GET_ETYPE_BLOCK(elemType,hnMask,childNum)\
02381 if(daf->getLevel(daf->curr()) == lev) {\
02382 \
02383 unsigned int idxF = daf->curr();\
02384 double matP1 = matPropArr[2*idxF];\
02385 double matP2 = matPropArr[2*idxF+1];\
02386 double fac1 = matP1*h/2.0;\
02387 double fac2 = matP2*h*h*h/8.0;\
02388 for(int k = 0; k < 8; k++) {\
02389 for(int j = 0; j < 8; j++) {\
02390 ot::MatRecord currRec;\
02391 currRec.rowIdx = indices[k];\
02392 currRec.colIdx = indices[j];\
02393 currRec.rowDim = 0;\
02394 currRec.colDim = 0;\
02395 currRec.val = ((fac1*\
02396 (LaplacianType2Stencil[childNum][elemType][k][j])) +\
02397 (fac2*\
02398 (MassType2Stencil[childNum][elemType][k][j])));\
02399 records.push_back(currRec);\
02400 } \
02401 } \
02402 daf->next<ot::DA_FLAGS::WRITABLE>();\
02403 }else {\
02404 for(unsigned char cNumFine = 0; cNumFine < 8; cNumFine++) {\
02405 \
02406 \
02407 \
02408 unsigned int idxF = daf->curr();\
02409 double matP1 = matPropArr[2*idxF];\
02410 double matP2 = matPropArr[2*idxF+1];\
02411 double fac1 = matP1*h/2.0;\
02412 double fac2 = matP2*h*h*h/8.0;\
02413 for(int k = 0; k < 8; k++) {\
02414 for(int j = 0; j < 8; j++) {\
02415 ot::MatRecord currRec;\
02416 currRec.rowIdx = indices[k];\
02417 currRec.colIdx = indices[j];\
02418 currRec.rowDim = 0;\
02419 currRec.colDim = 0;\
02420 currRec.val = ((fac1*(LaplacianType1Stencil\
02421 [childNum][elemType][cNumFine][k][j]))+\
02422 (fac2*(MassType1Stencil\
02423 [childNum][elemType][cNumFine][k][j])));\
02424 records.push_back(currRec);\
02425 } \
02426 } \
02427 daf->next<ot::DA_FLAGS::WRITABLE>();\
02428 } \
02429 }\
02430 if(records.size() > 1000) {\
02431 \
02432 da->setValuesInMatrix(B, records, 1, ADD_VALUES);\
02433 }\
02434 } \
02435 } else {\
02436 assert(!(daf->iAmActive()));\
02437 } \
02438 da->setValuesInMatrix(B, records, 1, ADD_VALUES);\
02439 MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY);\
02440 if(data->changedPartition) {\
02441 daf->vecRestoreBuffer<double>(*(data->matPropFine),matPropArr,\
02442 true,false,true,2);\
02443 }else {\
02444 daf->vecRestoreBuffer<double>(*(data->matPropFine),matPropArr,\
02445 true,true,true,2);\
02446 }\
02447 MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY);\
02448 }
02449
02450 PetscErrorCode ComputeJacobian3(ot::DAMG damg, Mat J, Mat B) {
02451 PetscFunctionBegin;
02452
02453 Jac3MFreeData *data = (static_cast<Jac3MFreeData*>(damg->user));
02454
02455 PetscTruth isShellB, isShellJ;
02456 PetscTypeCompare((PetscObject)B, MATSHELL, &isShellB);
02457 PetscTypeCompare((PetscObject)J, MATSHELL, &isShellJ);
02458
02459 assert(isShellB == isShellJ);
02460
02461
02462 if(isShellB) {
02463 if( data->Jmat_private == NULL ) {
02464
02465 data->JmatThisLevel = J;
02466 data->BmatThisLevel = B;
02467
02468 PetscFunctionReturn(0);
02469 } else {
02470
02471 J = data->Jmat_private;
02472 B = data->Jmat_private;
02473 }
02474 }
02475
02476
02477 data->JmatThisLevel = J;
02478 data->BmatThisLevel = B;
02479
02480 PetscTypeCompare((PetscObject)B, MATSHELL, &isShellB);
02481 PetscTypeCompare((PetscObject)J, MATSHELL, &isShellJ);
02482
02483 if(J != B) {
02484
02485
02486 if(!isShellJ) {
02487 BUILD_FULL_JAC_TYPE2_BLOCK(J)
02488 }
02489
02490
02491 if(!isShellB) {
02492 BUILD_FULL_JAC_TYPE3_BLOCK(B)
02493 }
02494 } else {
02495
02496 if(!isShellB) {
02497 if(data->isFinestLevel) {
02498
02499 BUILD_FULL_JAC_TYPE2_BLOCK(B)
02500 } else {
02501
02502
02503
02504 BUILD_FULL_JAC_TYPE3_BLOCK(B)
02505 }
02506 }
02507 }
02508
02509 PetscFunctionReturn(0);
02510 }
02511
02512
02513 #undef BUILD_FULL_JAC_TYPE2_BLOCK
02514 #undef BUILD_FULL_JAC_TYPE3_BLOCK
02515 #undef JAC_TYPE2_MULT_BLOCK
02516 #undef JAC_TYPE2_DIAG_BLOCK
02517 #undef JAC_TYPE2_ELEM_DIAG_BLOCK
02518 #undef JAC_TYPE2_ELEM_MULT_BLOCK
02519
02520
02521