00001
00007 #include "petsc.h"
00008 #include "omg.h"
00009 #include "oda.h"
00010 #include "vecMass.h"
00011 #include "elasticityJac.h"
00012
00013 #ifdef PETSC_USE_LOG
00014 extern int vecMassDiagEvent;
00015 extern int vecMassMultEvent;
00016 extern int vecMassFinestDiagEvent;
00017 extern int vecMassFinestMultEvent;
00018 #endif
00019
00020 extern double**** MassType2Stencil;
00021
00022 PetscErrorCode CreateConstVecMass(ot::DAMG damg, Mat *jac) {
00023 PetscFunctionBegin;
00024 PetscInt buildFullCoarseMat;
00025 int totalLevels;
00026 PetscTruth flg;
00027 PetscOptionsGetInt(PETSC_NULL,"-buildFullCoarseMat",&buildFullCoarseMat,&flg);
00028 totalLevels = damg->nlevels;
00029 ot::DA* da = damg->da;
00030 if((totalLevels == damg->nlevels) && buildFullCoarseMat) {
00031
00032 int myRank;
00033 MPI_Comm_rank(MPI_COMM_WORLD,&myRank);
00034 if(!myRank) {
00035 std::cout<<"Building Full vecMass Mat."<<std::endl;
00036 }
00037 if(!(da->computedLocalToGlobal())) {
00038 da->computeLocalToGlobalMappings();
00039 }
00040 char matType[30];
00041 PetscTruth typeFound;
00042 PetscOptionsGetString(PETSC_NULL,"-fullJacMatType",matType,30,&typeFound);
00043 if(!typeFound) {
00044 std::cout<<"I need a MatType for the full matrix!"<<std::endl;
00045 assert(false);
00046 }
00047 da->createMatrix(*jac, matType, 3);
00048 if(!myRank) {
00049 std::cout<<"Finished Building Full vecMass Mat."<<std::endl;
00050 }
00051 }else {
00052
00053 unsigned int m,n;
00054 m=n=(3*(da->getNodeSize()));
00055 MatCreateShell(damg->comm, m ,n, PETSC_DETERMINE, PETSC_DETERMINE, damg, jac);
00056 MatShellSetOperation(*jac ,MATOP_MULT, (void (*)(void)) ConstVecMassMatMult);
00057 MatShellSetOperation(*jac ,MATOP_GET_DIAGONAL, (void (*)(void)) ConstVecMassMatGetDiagonal);
00058 MatShellSetOperation(*jac ,MATOP_DESTROY, (void (*)(void)) ConstVecMassMatDestroy);
00059 }
00060 PetscFunctionReturn(0);
00061 }
00062
00063 PetscErrorCode ConstVecMassMatDestroy(Mat J) {
00064 PetscFunctionBegin;
00065
00066 PetscFunctionReturn(0);
00067 }
00068
00069 #define VEC_MASS_ELEM_DIAG_BLOCK {\
00070 unsigned int idx = da->curr();\
00071 unsigned int lev = da->getLevel(idx);\
00072 double h = hFac*(1u << (maxD - lev));\
00073 double fac = h*h*h/8.0;\
00074 unsigned int indices[8];\
00075 da->getNodeIndices(indices);\
00076 unsigned char childNum = da->getChildNumber();\
00077 unsigned char hnMask = da->getHangingNodeIndex(idx);\
00078 unsigned char elemType = 0;\
00079 GET_ETYPE_BLOCK(elemType,hnMask,childNum)\
00080 for(int k = 0; k < 8; k++) {\
00081 if(bdyArr[indices[k]]) {\
00082 \
00083 for(int dof = 0; dof < 3; dof++) {\
00084 diagArr[(3*indices[k])+dof] = 1.0;\
00085 } \
00086 } else { \
00087 for(int dof = 0; dof < 3; dof++) {\
00088 diagArr[(3*indices[k])+dof] += (fac*(MassType2Stencil[childNum][elemType][k][k]));\
00089 } \
00090 }\
00091 } \
00092 }
00093
00094 #define VEC_MASS_DIAG_BLOCK {\
00095 ot::DA* da = damg->da;\
00096 iC(VecZeroEntries(diag));\
00097 PetscScalar *diagArr;\
00098 unsigned char* bdyArr = data->bdyArr;\
00099 \
00100 da->vecGetBuffer(diag, diagArr, false, false, false, 3);\
00101 unsigned int maxD;\
00102 double hFac;\
00103 if(da->iAmActive()) {\
00104 maxD = (da->getMaxDepth());\
00105 hFac = 1.0/((double)(1u << (maxD-1)));\
00106 \
00107 for(da->init<ot::DA_FLAGS::ALL>(); da->curr() < da->end<ot::DA_FLAGS::ALL>(); da->next<ot::DA_FLAGS::ALL>()) {\
00108 VEC_MASS_ELEM_DIAG_BLOCK\
00109 } \
00110 } \
00111 da->vecRestoreBuffer(diag, diagArr, false, false, false, 3);\
00112 \
00113 PetscLogFlops(93*(da->getGhostedElementSize()));\
00114 }
00115
00116 PetscErrorCode ConstVecMassMatGetDiagonal(Mat J, Vec diag) {
00117 PetscFunctionBegin;
00118
00119 PetscLogEventBegin(vecMassDiagEvent,diag,0,0,0);
00120
00121 ot::DAMG damg;
00122 iC(MatShellGetContext(J, (void**)(&damg)));
00123
00124 ElasticityData* data = (static_cast<ElasticityData*>(damg->user));
00125
00126 bool isFinestLevel = (damg->nlevels == 1);
00127
00128 if(isFinestLevel) {
00129 PetscLogEventBegin(vecMassFinestDiagEvent,diag,0,0,0);
00130 }
00131
00132 VEC_MASS_DIAG_BLOCK
00133
00134 if(isFinestLevel) {
00135 PetscLogEventEnd(vecMassFinestDiagEvent,diag,0,0,0);
00136 }
00137
00138 PetscLogEventEnd(vecMassDiagEvent,diag,0,0,0);
00139
00140 PetscFunctionReturn(0);
00141 }
00142
00143 #define VEC_MASS_ELEM_MULT_BLOCK {\
00144 unsigned int idx = da->curr();\
00145 unsigned int lev = da->getLevel(idx);\
00146 double h = hFac*(1u << (maxD - lev));\
00147 double fac = h*h*h/8.0;\
00148 unsigned int indices[8];\
00149 da->getNodeIndices(indices);\
00150 unsigned char childNum = da->getChildNumber();\
00151 unsigned char hnMask = da->getHangingNodeIndex(idx);\
00152 unsigned char elemType = 0;\
00153 GET_ETYPE_BLOCK(elemType, hnMask, childNum)\
00154 for(int k = 0;k < 8;k++) {\
00155 if(bdyArr[indices[k]]) {\
00156 \
00157 for(int dof = 0; dof < 3; dof++) {\
00158 outArr[(3*indices[k]) + dof] = inArr[(3*indices[k]) + dof];\
00159 }\
00160 } else {\
00161 for(int j=0;j<8;j++) {\
00162 \
00163 if(!(bdyArr[indices[j]])) {\
00164 for(int dof = 0; dof < 3; dof++) {\
00165 outArr[(3*indices[k]) + dof] += (fac*(MassType2Stencil[childNum][elemType][k][j])\
00166 *inArr[(3*indices[j]) + dof]);\
00167 }\
00168 }\
00169 }\
00170 }\
00171 }\
00172 }
00173
00174 #define VEC_MASS_MULT_BLOCK {\
00175 ot::DA* da = damg->da;\
00176 iC(VecZeroEntries(out));\
00177 unsigned int maxD;\
00178 double hFac;\
00179 if(da->iAmActive()) {\
00180 maxD = da->getMaxDepth();\
00181 hFac = 1.0/((double)(1u << (maxD-1)));\
00182 }\
00183 PetscScalar *outArr=NULL;\
00184 PetscScalar *inArr=NULL;\
00185 unsigned char* bdyArr = data->bdyArr;\
00186 \
00187 da->vecGetBuffer(in, inArr, false, false, true, 3);\
00188 if(da->iAmActive()) {\
00189 da->ReadFromGhostsBegin<PetscScalar>(inArr, 3);\
00190 }\
00191 \
00192 da->vecGetBuffer(out, outArr, false, false, false, 3);\
00193 \
00194 if(da->iAmActive()) {\
00195 for(da->init<ot::DA_FLAGS::INDEPENDENT>();\
00196 da->curr() < da->end<ot::DA_FLAGS::INDEPENDENT>(); da->next<ot::DA_FLAGS::INDEPENDENT>() ) {\
00197 VEC_MASS_ELEM_MULT_BLOCK\
00198 } \
00199 } \
00200 if(da->iAmActive()) {\
00201 da->ReadFromGhostsEnd<PetscScalar>(inArr);\
00202 }\
00203 \
00204 \
00205 \
00206 \
00207 if(da->iAmActive()) {\
00208 for(da->init<ot::DA_FLAGS::DEPENDENT>();\
00209 da->curr() < da->end<ot::DA_FLAGS::DEPENDENT>(); da->next<ot::DA_FLAGS::DEPENDENT>() ) {\
00210 VEC_MASS_ELEM_MULT_BLOCK\
00211 } \
00212 } \
00213 da->vecRestoreBuffer(in, inArr, false, false, true, 3);\
00214 da->vecRestoreBuffer(out, outArr, false, false, false, 3);\
00215 \
00216 PetscLogFlops(1095*(da->getGhostedElementSize()));\
00217 }
00218
00219 PetscErrorCode ConstVecMassMatMult(Mat J, Vec in, Vec out)
00220 {
00221 PetscFunctionBegin;
00222
00223 PetscLogEventBegin(vecMassMultEvent,in,out,0,0);
00224
00225 ot::DAMG damg;
00226 iC(MatShellGetContext(J, (void**)(&damg)));
00227
00228 ElasticityData* data = (static_cast<ElasticityData*>(damg->user));
00229
00230 bool isFinestLevel = (damg->nlevels == 1);
00231
00232 if(isFinestLevel) {
00233 PetscLogEventBegin(vecMassFinestMultEvent,in,out,0,0);
00234 }
00235
00236 VEC_MASS_MULT_BLOCK
00237
00238 if(isFinestLevel) {
00239 PetscLogEventEnd(vecMassFinestMultEvent,in,out,0,0);
00240 }
00241
00242 PetscLogEventEnd(vecMassMultEvent,in,out,0,0);
00243
00244 PetscFunctionReturn(0);
00245 }
00246
00247 #define BUILD_FULL_VEC_MASS_BLOCK {\
00248 ot::DA* da = damg->da;\
00249 MatZeroEntries(B);\
00250 std::vector<ot::MatRecord> records;\
00251 unsigned int maxD;\
00252 double hFac;\
00253 if(da->iAmActive()) {\
00254 maxD = da->getMaxDepth();\
00255 hFac = 1.0/((double)(1u << (maxD-1)));\
00256 }\
00257 unsigned char* bdyArr = data->bdyArr;\
00258 if(da->iAmActive()) {\
00259 for(da->init<ot::DA_FLAGS::WRITABLE>();\
00260 da->curr() < da->end<ot::DA_FLAGS::WRITABLE>(); da->next<ot::DA_FLAGS::WRITABLE>()) {\
00261 unsigned int idx = da->curr();\
00262 unsigned int lev = da->getLevel(idx);\
00263 double h = hFac*(1u << (maxD - lev));\
00264 double fac = h/2.0;\
00265 unsigned int indices[8];\
00266 da->getNodeIndices(indices);\
00267 unsigned char childNum = da->getChildNumber();\
00268 unsigned char hnMask = da->getHangingNodeIndex(idx);\
00269 unsigned char elemType = 0;\
00270 GET_ETYPE_BLOCK(elemType, hnMask, childNum)\
00271 for(int k = 0;k < 8;k++) {\
00272 \
00273 \
00274 if(!(bdyArr[indices[k]])) {\
00275 for(int j=0;j<8;j++) {\
00276 if(!(bdyArr[indices[j]])) {\
00277 for(int dof = 0; dof < 3; dof++) {\
00278 ot::MatRecord currRec;\
00279 currRec.rowIdx = indices[k];\
00280 currRec.colIdx = indices[j];\
00281 currRec.rowDim = dof;\
00282 currRec.colDim = dof;\
00283 currRec.val = (fac*(MassType2Stencil[childNum][elemType][k][j]));\
00284 records.push_back(currRec);\
00285 } \
00286 }\
00287 } \
00288 }\
00289 } \
00290 if(records.size() > 1000) {\
00291 \
00292 da->setValuesInMatrix(B, records, 3, ADD_VALUES);\
00293 }\
00294 } \
00295 } \
00296 da->setValuesInMatrix(B, records, 3, ADD_VALUES);\
00297 MatAssemblyBegin(B, MAT_FLUSH_ASSEMBLY);\
00298 MatAssemblyEnd(B, MAT_FLUSH_ASSEMBLY);\
00299 if(da->iAmActive()) {\
00300 for(da->init<ot::DA_FLAGS::WRITABLE>();\
00301 da->curr() < da->end<ot::DA_FLAGS::WRITABLE>(); da->next<ot::DA_FLAGS::WRITABLE>()) {\
00302 unsigned int idx = da->curr();\
00303 unsigned int lev = da->getLevel(idx);\
00304 double h = hFac*(1u << (maxD - lev));\
00305 double fac = h/2.0;\
00306 unsigned int indices[8];\
00307 da->getNodeIndices(indices);\
00308 unsigned char childNum = da->getChildNumber();\
00309 unsigned char hnMask = da->getHangingNodeIndex(idx);\
00310 unsigned char elemType = 0;\
00311 GET_ETYPE_BLOCK(elemType, hnMask, childNum)\
00312 for(int k = 0; k < 8; k++) {\
00313 \
00314 if(bdyArr[indices[k]]) {\
00315 for(int dof = 0; dof < 3; dof++) {\
00316 ot::MatRecord currRec;\
00317 currRec.rowIdx = indices[k];\
00318 currRec.colIdx = indices[k];\
00319 currRec.rowDim = dof;\
00320 currRec.colDim = dof;\
00321 currRec.val = 1.0;\
00322 records.push_back(currRec);\
00323 } \
00324 }\
00325 } \
00326 if(records.size() > 1000) {\
00327 \
00328 da->setValuesInMatrix(B, records, 3, INSERT_VALUES);\
00329 }\
00330 } \
00331 } \
00332 da->setValuesInMatrix(B, records, 3, INSERT_VALUES);\
00333 MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY);\
00334 MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY);\
00335 }
00336
00337 PetscErrorCode ComputeConstVecMass(ot::DAMG damg, Mat J, Mat B) {
00338
00339 PetscFunctionBegin;
00340
00341 PetscTruth isshell;
00342 PetscTypeCompare((PetscObject)B, MATSHELL, &isshell);
00343 if(isshell) {
00344 PetscFunctionReturn(0);
00345 }
00346
00347 ElasticityData* data = (static_cast<ElasticityData*>(damg->user));
00348
00349
00350
00351 BUILD_FULL_VEC_MASS_BLOCK
00352
00353 PetscFunctionReturn(0);
00354 }
00355
00356 #undef BUILD_FULL_VEC_MASS_BLOCK
00357 #undef VEC_MASS_MULT_BLOCK
00358 #undef VEC_MASS_DIAG_BLOCK
00359 #undef VEC_MASS_ELEM_DIAG_BLOCK
00360 #undef VEC_MASS_ELEM_MULT_BLOCK
00361
00362