00001
00002 template <typename T>
00003 feMatrix<T>::feMatrix() {
00004 m_daType = PETSC;
00005 m_DA = NULL;
00006 m_octDA = NULL;
00007 m_stencil = NULL;
00008 m_uiDof = 1;
00009 m_ucpLut = NULL;
00010
00011
00012 initStencils();
00013 }
00014
00015 template <typename T>
00016 feMatrix<T>::feMatrix(daType da) {
00017 #ifdef __DEBUG__
00018 assert ( ( da == PETSC ) || ( da == OCT ) );
00019 #endif
00020 m_daType = da;
00021 m_DA = NULL;
00022 m_octDA = NULL;
00023 m_stencil = NULL;
00024 m_ucpLut = NULL;
00025
00026
00027 initStencils();
00028 if (da == OCT)
00029 initOctLut();
00030 }
00031
00032 template <typename T>
00033 void feMatrix<T>::initOctLut() {
00034
00035 unsigned char tmp[8][8]={
00036 {0,1,2,3,4,5,6,7},
00037 {1,3,0,2,5,7,4,6},
00038 {2,0,3,1,6,4,7,5},
00039 {3,2,1,0,7,6,5,4},
00040 {4,5,0,1,6,7,2,3},
00041 {5,7,1,3,4,6,0,2},
00042 {6,4,2,0,7,5,3,1},
00043 {7,6,3,2,5,4,1,0}
00044 };
00045
00046
00047 typedef unsigned char* charPtr;
00048 m_ucpLut = new charPtr[8];
00049 for (int i=0;i<8;i++) {
00050 m_ucpLut[i] = new unsigned char[8];
00051 for (int j=0;j<8;j++) {
00052 m_ucpLut[i][j] = tmp[i][j];
00053 }
00054 }
00055 }
00056
00057 template <typename T>
00058 feMatrix<T>::~feMatrix() {
00059 }
00060
00061
00062 #undef __FUNCT__
00063 #define __FUNCT__ "feMatrix_MatGetDiagonal"
00064 template <typename T>
00065 bool feMatrix<T>::MatGetDiagonal(Vec _diag, double scale){
00066 PetscFunctionBegin;
00067 #ifdef __DEBUG__
00068 assert ( ( m_daType == PETSC ) || ( m_daType == OCT ) );
00069 #endif
00070
00071 int ierr;
00072
00073
00074
00075 if (m_daType == PETSC) {
00076
00077 PetscInt x,y,z,m,n,p;
00078 PetscInt mx,my,mz;
00079 int xne,yne,zne;
00080
00081 PetscScalar ***diag;
00082 Vec diagLocal;
00083
00084
00085 if (m_DA == NULL)
00086 std::cerr << "Da is null" << std::endl;
00087 ierr = DAGetCorners(m_DA, &x, &y, &z, &m, &n, &p); CHKERRQ(ierr);
00088
00089 ierr = DAGetInfo(m_DA,0, &mx, &my, &mz, 0,0,0,0,0,0,0); CHKERRQ(ierr);
00090
00091 if (x+m == mx) {
00092 xne=m-1;
00093 } else {
00094 xne=m;
00095 }
00096 if (y+n == my) {
00097 yne=n-1;
00098 } else {
00099 yne=n;
00100 }
00101 if (z+p == mz) {
00102 zne=p-1;
00103 } else {
00104 zne=p;
00105 }
00106
00107 ierr = DAGetLocalVector(m_DA, &diagLocal); CHKERRQ(ierr);
00108 ierr = VecZeroEntries(diagLocal);
00109
00110
00111
00112
00113
00114 ierr = DAVecGetArray(m_DA, diagLocal, &diag);
00115
00116
00117 preMatVec();
00118
00119
00120 for (int k=z; k<z+zne; k++){
00121 for (int j=y; j<y+yne; j++){
00122 for (int i=x; i<x+xne; i++){
00123 ElementalMatGetDiagonal(i, j, k, diag, scale);
00124 }
00125 }
00126 }
00127
00128 postMatVec();
00129
00130 ierr = DAVecRestoreArray(m_DA, diagLocal, &diag); CHKERRQ(ierr);
00131
00132
00133 ierr = DALocalToGlobalBegin(m_DA, diagLocal, _diag); CHKERRQ(ierr);
00134 ierr = DALocalToGlobalEnd(m_DA, diagLocal, _diag); CHKERRQ(ierr);
00135
00136 ierr = DARestoreLocalVector(m_DA, &diagLocal); CHKERRQ(ierr);
00137
00138
00139 } else {
00140
00141 PetscScalar *diag=NULL;
00142
00143
00144
00145 m_octDA->vecGetBuffer(_diag, diag, false, false, false, m_uiDof);
00146
00147 preMatVec();
00148
00149
00150 for ( m_octDA->init<ot::DA_FLAGS::ALL>(); m_octDA->curr() < m_octDA->end<ot::DA_FLAGS::ALL>(); m_octDA->next<ot::DA_FLAGS::ALL>() ) {
00151 ElementalMatGetDiagonal( m_octDA->curr(), diag, scale);
00152 }
00153
00154 postMatVec();
00155
00156
00157 m_octDA->vecRestoreBuffer(_diag, diag, false, false, false, m_uiDof);
00158 }
00159
00160 PetscFunctionReturn(0);
00161 }
00162
00163
00164
00178 #undef __FUNCT__
00179 #define __FUNCT__ "feMatrix_MatVec"
00180 template <typename T>
00181 bool feMatrix<T>::MatVec(Vec _in, Vec _out, double scale){
00182 PetscFunctionBegin;
00183
00184 #ifdef __DEBUG__
00185 assert ( ( m_daType == PETSC ) || ( m_daType == OCT ) );
00186 #endif
00187
00188 int ierr;
00189
00190
00191 if (m_daType == PETSC) {
00192
00193 PetscInt x,y,z,m,n,p;
00194 PetscInt mx,my,mz;
00195 int xne,yne,zne;
00196
00197 PetscScalar ***in, ***out;
00198 Vec inlocal, outlocal;
00199
00200
00201 if (m_DA == NULL)
00202 std::cerr << "Da is null" << std::endl;
00203 ierr = DAGetCorners(m_DA, &x, &y, &z, &m, &n, &p); CHKERRQ(ierr);
00204
00205 ierr = DAGetInfo(m_DA,0, &mx, &my, &mz, 0,0,0,0,0,0,0); CHKERRQ(ierr);
00206
00207 if (x+m == mx) {
00208 xne=m-1;
00209 } else {
00210 xne=m;
00211 }
00212 if (y+n == my) {
00213 yne=n-1;
00214 } else {
00215 yne=n;
00216 }
00217 if (z+p == mz) {
00218 zne=p-1;
00219 } else {
00220 zne=p;
00221 }
00222
00223
00224
00225
00226 ierr = DAGetLocalVector(m_DA, &inlocal); CHKERRQ(ierr);
00227 ierr = DAGetLocalVector(m_DA, &outlocal); CHKERRQ(ierr);
00228
00229
00230 ierr = DAGlobalToLocalBegin(m_DA, _in, INSERT_VALUES, inlocal); CHKERRQ(ierr);
00231 ierr = DAGlobalToLocalEnd(m_DA, _in, INSERT_VALUES, inlocal); CHKERRQ(ierr);
00232
00233
00234
00235 ierr = VecZeroEntries(outlocal);
00236
00237 ierr = DAVecGetArray(m_DA, inlocal, &in);
00238 ierr = DAVecGetArray(m_DA, outlocal, &out);
00239
00240
00241 preMatVec();
00242
00243
00244 for (int k=z; k<z+zne; k++){
00245 for (int j=y; j<y+yne; j++){
00246 for (int i=x; i<x+xne; i++){
00247
00248 ElementalMatVec(i, j, k, in, out, scale);
00249 }
00250 }
00251 }
00252
00253 postMatVec();
00254
00255 ierr = DAVecRestoreArray(m_DA, inlocal, &in); CHKERRQ(ierr);
00256 ierr = DAVecRestoreArray(m_DA, outlocal, &out); CHKERRQ(ierr);
00257
00258 ierr = DALocalToGlobalBegin(m_DA, outlocal, _out); CHKERRQ(ierr);
00259 ierr = DALocalToGlobalEnd(m_DA, outlocal, _out); CHKERRQ(ierr);
00260
00261 ierr = DARestoreLocalVector(m_DA, &inlocal); CHKERRQ(ierr);
00262 ierr = DARestoreLocalVector(m_DA, &outlocal); CHKERRQ(ierr);
00263
00264
00265 } else {
00266
00267
00268
00269 PetscScalar *out=NULL;
00270 PetscScalar *in=NULL;
00271
00272
00273
00274 m_octDA->vecGetBuffer(_in, in, false, false, true, m_uiDof);
00275 m_octDA->vecGetBuffer(_out, out, false, false, false, m_uiDof);
00276
00277
00278
00279
00280 m_octDA->ReadFromGhostsBegin<PetscScalar>(in, m_uiDof);
00281 preMatVec();
00282
00283
00284 for ( m_octDA->init<ot::DA_FLAGS::INDEPENDENT>(), m_octDA->init<ot::DA_FLAGS::WRITABLE>(); m_octDA->curr() < m_octDA->end<ot::DA_FLAGS::INDEPENDENT>(); m_octDA->next<ot::DA_FLAGS::INDEPENDENT>() ) {
00285 ElementalMatVec( m_octDA->curr(), in, out, scale);
00286 }
00287
00288
00289
00290 m_octDA->ReadFromGhostsEnd<PetscScalar>(in);
00291
00292
00293 for ( m_octDA->init<ot::DA_FLAGS::DEPENDENT>(), m_octDA->init<ot::DA_FLAGS::WRITABLE>(); m_octDA->curr() < m_octDA->end<ot::DA_FLAGS::DEPENDENT>(); m_octDA->next<ot::DA_FLAGS::DEPENDENT>() ) {
00294 ElementalMatVec( m_octDA->curr(), in, out, scale);
00295 }
00296
00297 postMatVec();
00298
00299
00300 m_octDA->vecRestoreBuffer(_in, in, false, false, true, m_uiDof);
00301 m_octDA->vecRestoreBuffer(_out, out, false, false, false, m_uiDof);
00302
00303 }
00304
00305 PetscFunctionReturn(0);
00306 }
00307
00308 #undef __FUNCT__
00309 #define __FUNCT__ "alignElementAndVertices"
00310 template <typename T>
00311 PetscErrorCode feMatrix<T>::alignElementAndVertices(ot::DA * da, stdElemType & sType, unsigned int* indices) {
00312 PetscFunctionBegin;
00313
00314 sType = ST_0;
00315 da->getNodeIndices(indices);
00316
00317
00318
00319
00320
00321 if (da->isHanging(da->curr())) {
00322
00323 int childNum = da->getChildNumber();
00324 Point pt = da->getCurrentOffset();
00325
00326 unsigned char hangingMask = da->getHangingNodeIndex(da->curr());
00327
00328
00329 mapVtxAndFlagsToOrientation(childNum, indices, hangingMask);
00330
00331 unsigned char eType = ((126 & hangingMask)>>1);
00332
00333 reOrderIndices(eType, indices);
00334 }
00335 PetscFunctionReturn(0);
00336 }
00337
00338 #undef __FUNCT__
00339 #define __FUNCT__ "mapVtxAndFlagsToOrientation"
00340 template <typename T>
00341 PetscErrorCode feMatrix<T>::mapVtxAndFlagsToOrientation(int childNum,
00342 unsigned int* indices, unsigned char & mask) {
00343 PetscFunctionBegin;
00344 unsigned int tmp[8];
00345 unsigned char tmpFlags = 0;
00346 for (int i = 0; i < 8; i++) {
00347 tmp[i] = indices[m_ucpLut[childNum][i]];
00348 tmpFlags = ( tmpFlags | ( ( (1 << (m_ucpLut[childNum][i])) & mask ) ? (1 << i) : 0 ) );
00349 }
00350 for (int i=0;i<8;i++) {
00351 indices[i] = tmp[i];
00352 }
00353 mask = tmpFlags;
00354 PetscFunctionReturn(0);
00355 }
00356
00357 #undef __FUNCT__
00358 #define __FUNCT__ "reOrderIndices"
00359 template <typename T>
00360 PetscErrorCode feMatrix<T>::reOrderIndices(unsigned char eType, unsigned int* indices) {
00361 #ifdef __DEBUG_1
00362 std::cout << "Entering " << __func__ << std::endl;
00363 #endif
00364 PetscFunctionBegin;
00365 unsigned int tmp;
00366 switch (eType) {
00367 case ET_N:
00368 break;
00369 case ET_Y:
00370 break;
00371 case ET_X:
00372
00373 tmp = indices[1];
00374 indices[1] = indices[2];
00375 indices[2] = tmp;
00376 tmp = indices[5];
00377 indices[5] = indices[6];
00378 indices[6] = tmp;
00379 break;
00380 case ET_XY:
00381 break;
00382 case ET_Z:
00383
00384 tmp = indices[2];
00385 indices[2] = indices[4];
00386 indices[4] = tmp;
00387 tmp = indices[3];
00388 indices[3] = indices[5];
00389 indices[5] = tmp;
00390 break;
00391 case ET_ZY:
00392
00393 tmp = indices[1];
00394 indices[1] = indices[4];
00395 indices[4] = tmp;
00396 tmp = indices[3];
00397 indices[3] = indices[6];
00398 indices[6] = tmp;
00399 break;
00400 case ET_ZX:
00401
00402 tmp = indices[2];
00403 indices[2] = indices[4];
00404 indices[4] = tmp;
00405 tmp = indices[3];
00406 indices[3] = indices[5];
00407 indices[5] = tmp;
00408 break;
00409 case ET_ZXY:
00410 break;
00411 case ET_XY_XY:
00412 break;
00413 case ET_XY_ZXY:
00414 break;
00415 case ET_YZ_ZY:
00416
00417 tmp = indices[1];
00418 indices[1] = indices[4];
00419 indices[4] = tmp;
00420 tmp = indices[3];
00421 indices[3] = indices[6];
00422 indices[6] = tmp;
00423 break;
00424 case ET_YZ_ZXY:
00425
00426 tmp = indices[1];
00427 indices[1] = indices[4];
00428 indices[4] = tmp;
00429 tmp = indices[3];
00430 indices[3] = indices[6];
00431 indices[6] = tmp;
00432 break;
00433 case ET_YZ_XY_ZXY:
00434 break;
00435 case ET_ZX_ZX:
00436
00437 tmp = indices[2];
00438 indices[2] = indices[4];
00439 indices[4] = tmp;
00440 tmp = indices[3];
00441 indices[3] = indices[5];
00442 indices[5] = tmp;
00443 break;
00444 case ET_ZX_ZXY:
00445
00446 tmp = indices[2];
00447 indices[2] = indices[4];
00448 indices[4] = tmp;
00449 tmp = indices[3];
00450 indices[3] = indices[5];
00451 indices[5] = tmp;
00452 break;
00453 case ET_ZX_XY_ZXY:
00454
00455 tmp = indices[1];
00456 indices[1] = indices[2];
00457 indices[2] = tmp;
00458 tmp = indices[5];
00459 indices[5] = indices[6];
00460 indices[6] = tmp;
00461 break;
00462 case ET_ZX_YZ_ZXY:
00463
00464 tmp = indices[2];
00465 indices[2] = indices[4];
00466 indices[4] = tmp;
00467 tmp = indices[3];
00468 indices[3] = indices[5];
00469 indices[5] = tmp;
00470 break;
00471 case ET_ZX_YZ_XY_ZXY:
00472 break;
00473 default:
00474 std::cout<<"in reOrder Etype: "<< (int) eType << std::endl;
00475 assert(false);
00476 }
00477 #ifdef __DEBUG_1
00478 std::cout << "Leaving " << __func__ << std::endl;
00479 #endif
00480 PetscFunctionReturn(0);
00481 }
00482