1*d8588912SDave May #define PETSCMAT_DLL 2*d8588912SDave May 3*d8588912SDave May #include "matnestimpl.h" 4*d8588912SDave May 5*d8588912SDave May /* private functions */ 6*d8588912SDave May #undef __FUNCT__ 7*d8588912SDave May #define __FUNCT__ "MatNestGetSize_Recursive" 8*d8588912SDave May static PetscErrorCode MatNestGetSize_Recursive(Mat A,PetscBool globalsize,PetscInt *M,PetscInt *N) 9*d8588912SDave May { 10*d8588912SDave May Mat_Nest *bA = (Mat_Nest*)A->data; 11*d8588912SDave May PetscInt sizeM,sizeN,i,j,index; 12*d8588912SDave May PetscErrorCode ierr; 13*d8588912SDave May 14*d8588912SDave May PetscFunctionBegin; 15*d8588912SDave May /* rows */ 16*d8588912SDave May /* now descend recursively */ 17*d8588912SDave May for (i=0; i<bA->nr; i++) { 18*d8588912SDave May for (j=0; j<bA->nc; j++) { 19*d8588912SDave May if (bA->m[i][j]) { index = j; break; } 20*d8588912SDave May } 21*d8588912SDave May if (bA->m[i][index]) { 22*d8588912SDave May if (globalsize) { ierr = MatGetSize(bA->m[i][index],&sizeM,&sizeN);CHKERRQ(ierr); } 23*d8588912SDave May else { ierr = MatGetLocalSize(bA->m[i][index],&sizeM,&sizeN);CHKERRQ(ierr); } 24*d8588912SDave May *M = *M + sizeM; 25*d8588912SDave May } 26*d8588912SDave May } 27*d8588912SDave May 28*d8588912SDave May /* cols */ 29*d8588912SDave May /* now descend recursively */ 30*d8588912SDave May for (j=0; j<bA->nc; j++) { 31*d8588912SDave May for (i=0; i<bA->nr; i++) { 32*d8588912SDave May if (bA->m[i][j]) { index = i; break; } 33*d8588912SDave May } 34*d8588912SDave May if (bA->m[index][j]) { 35*d8588912SDave May if (globalsize) { ierr = MatGetSize(bA->m[index][j],&sizeM,&sizeN);CHKERRQ(ierr); } 36*d8588912SDave May else { ierr = MatGetLocalSize(bA->m[index][j],&sizeM,&sizeN);CHKERRQ(ierr); } 37*d8588912SDave May *N = *N + sizeN; 38*d8588912SDave May } 39*d8588912SDave May } 40*d8588912SDave May PetscFunctionReturn(0); 41*d8588912SDave May } 42*d8588912SDave May 43*d8588912SDave May #undef __FUNCT__ 44*d8588912SDave May #define __FUNCT__ "PETSc_MatNest_CheckMatVecCompatibility2" 45*d8588912SDave May static PetscErrorCode PETSc_MatNest_CheckMatVecCompatibility2(Mat A,Vec x,Vec y) 46*d8588912SDave May { 47*d8588912SDave May PetscBool isANest, isxNest, isyNest; 48*d8588912SDave May PetscErrorCode ierr; 49*d8588912SDave May 50*d8588912SDave May PetscFunctionBegin; 51*d8588912SDave May isANest = isxNest = isyNest = PETSC_FALSE; 52*d8588912SDave May ierr = PetscTypeCompare( (PetscObject)A, MATNEST, &isANest );CHKERRQ(ierr); 53*d8588912SDave May ierr = PetscTypeCompare( (PetscObject)x, VECNEST, &isxNest );CHKERRQ(ierr); 54*d8588912SDave May ierr = PetscTypeCompare( (PetscObject)y, VECNEST, &isyNest );CHKERRQ(ierr); 55*d8588912SDave May 56*d8588912SDave May if (isANest && isxNest && isyNest) { 57*d8588912SDave May PetscFunctionReturn(0); 58*d8588912SDave May } else { 59*d8588912SDave May SETERRQ( ((PetscObject)A)->comm, PETSC_ERR_SUP, "Operation only valid for Mat(Nest)-Vec(Nest) combinations"); 60*d8588912SDave May PetscFunctionReturn(0); 61*d8588912SDave May } 62*d8588912SDave May PetscFunctionReturn(0); 63*d8588912SDave May } 64*d8588912SDave May 65*d8588912SDave May /* 66*d8588912SDave May This function is called every time we insert a sub matrix the Nest. 67*d8588912SDave May It ensures that every Nest along row r, and col c has the same dimensions 68*d8588912SDave May as the submat being inserted. 69*d8588912SDave May */ 70*d8588912SDave May #undef __FUNCT__ 71*d8588912SDave May #define __FUNCT__ "PETSc_MatNest_CheckConsistency" 72*d8588912SDave May static PetscErrorCode PETSc_MatNest_CheckConsistency(Mat A,Mat submat,PetscInt r,PetscInt c) 73*d8588912SDave May { 74*d8588912SDave May Mat_Nest *b = (Mat_Nest*)A->data; 75*d8588912SDave May PetscInt i,j; 76*d8588912SDave May PetscInt nr,nc; 77*d8588912SDave May PetscInt sM,sN,M,N; 78*d8588912SDave May Mat mat; 79*d8588912SDave May PetscErrorCode ierr; 80*d8588912SDave May 81*d8588912SDave May PetscFunctionBegin; 82*d8588912SDave May nr = b->nr; 83*d8588912SDave May nc = b->nc; 84*d8588912SDave May ierr = MatGetSize(submat,&sM,&sN);CHKERRQ(ierr); 85*d8588912SDave May for (i=0; i<nr; i++) { 86*d8588912SDave May mat = b->m[i][c]; 87*d8588912SDave May if (mat) { 88*d8588912SDave May ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 89*d8588912SDave May /* Check columns match */ 90*d8588912SDave May if (sN != N) { 91*d8588912SDave May SETERRQ3(((PetscObject)A)->comm,PETSC_ERR_SUP,"Inserted incompatible submatrix into Nest at (%D,%D). Submatrix must have %D rows",r,c,N ); 92*d8588912SDave May } 93*d8588912SDave May } 94*d8588912SDave May } 95*d8588912SDave May 96*d8588912SDave May for (j=0; j<nc; j++) { 97*d8588912SDave May mat = b->m[r][j]; 98*d8588912SDave May if (mat) { 99*d8588912SDave May ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 100*d8588912SDave May /* Check rows match */ 101*d8588912SDave May if (sM != M) { 102*d8588912SDave May SETERRQ3(((PetscObject)A)->comm,PETSC_ERR_SUP,"Inserted incompatible submatrix into Nest at (%D,%D). Submatrix must have %D cols",r,c,M ); 103*d8588912SDave May } 104*d8588912SDave May } 105*d8588912SDave May } 106*d8588912SDave May PetscFunctionReturn(0); 107*d8588912SDave May } 108*d8588912SDave May 109*d8588912SDave May /* 110*d8588912SDave May Checks if the row/col's contain a complete set of IS's. 111*d8588912SDave May Once they are filled, the offsets are computed. This saves having to update 112*d8588912SDave May the index set entries each time we insert something new. 113*d8588912SDave May */ 114*d8588912SDave May #undef __FUNCT__ 115*d8588912SDave May #define __FUNCT__ "PETSc_MatNest_UpdateStructure" 116*d8588912SDave May static PetscErrorCode PETSc_MatNest_UpdateStructure(Mat A,PetscInt ridx,PetscInt cidx) 117*d8588912SDave May { 118*d8588912SDave May Mat_Nest *b = (Mat_Nest*)A->data; 119*d8588912SDave May PetscInt m,n,i,j; 120*d8588912SDave May PetscBool fullrow,fullcol; 121*d8588912SDave May PetscErrorCode ierr; 122*d8588912SDave May 123*d8588912SDave May PetscFunctionBegin; 124*d8588912SDave May ierr = MatGetLocalSize(b->m[ridx][cidx],&m,&n);CHKERRQ(ierr); 125*d8588912SDave May b->row_len[ridx] = m; 126*d8588912SDave May b->col_len[cidx] = n; 127*d8588912SDave May 128*d8588912SDave May fullrow = PETSC_TRUE; 129*d8588912SDave May for (i=0; i<b->nr; i++) { 130*d8588912SDave May if (b->row_len[i]==-1) { fullrow = PETSC_FALSE; break; } 131*d8588912SDave May } 132*d8588912SDave May if ( (fullrow) && (!b->is_row[0]) ){ 133*d8588912SDave May PetscInt cnt = 0; 134*d8588912SDave May for (i=0; i<b->nr; i++) { 135*d8588912SDave May ierr = ISCreateStride(PETSC_COMM_SELF,b->row_len[i],cnt,1,&b->is_row[i]);CHKERRQ(ierr); 136*d8588912SDave May cnt = cnt + b->row_len[i]; 137*d8588912SDave May } 138*d8588912SDave May } 139*d8588912SDave May 140*d8588912SDave May fullcol = PETSC_TRUE; 141*d8588912SDave May for (j=0; j<b->nc; j++) { 142*d8588912SDave May if (b->col_len[j]==-1) { fullcol = PETSC_FALSE; break; } 143*d8588912SDave May } 144*d8588912SDave May if( (fullcol) && (!b->is_col[0]) ){ 145*d8588912SDave May PetscInt cnt = 0; 146*d8588912SDave May for (j=0; j<b->nc; j++) { 147*d8588912SDave May ierr = ISCreateStride(PETSC_COMM_SELF,b->col_len[j],cnt,1,&b->is_col[j]);CHKERRQ(ierr); 148*d8588912SDave May cnt = cnt + b->col_len[j]; 149*d8588912SDave May } 150*d8588912SDave May } 151*d8588912SDave May PetscFunctionReturn(0); 152*d8588912SDave May } 153*d8588912SDave May 154*d8588912SDave May /* operations */ 155*d8588912SDave May #undef __FUNCT__ 156*d8588912SDave May #define __FUNCT__ "MatMult_Nest" 157*d8588912SDave May PetscErrorCode MatMult_Nest(Mat A,Vec x,Vec y) 158*d8588912SDave May { 159*d8588912SDave May Mat_Nest *bA = (Mat_Nest*)A->data; 160*d8588912SDave May Vec *bx; 161*d8588912SDave May Vec *by; 162*d8588912SDave May PetscInt i,j; 163*d8588912SDave May PetscErrorCode ierr; 164*d8588912SDave May 165*d8588912SDave May PetscFunctionBegin; 166*d8588912SDave May ierr = PETSc_MatNest_CheckMatVecCompatibility2(A,x,y);CHKERRQ(ierr); 167*d8588912SDave May ierr = VecNestGetSubVecs(x,PETSC_NULL,&bx);CHKERRQ(ierr); 168*d8588912SDave May ierr = VecNestGetSubVecs(y,PETSC_NULL,&by);CHKERRQ(ierr); 169*d8588912SDave May 170*d8588912SDave May for (i=0; i<bA->nr; i++) { 171*d8588912SDave May ierr = VecZeroEntries(by[i]);CHKERRQ(ierr); 172*d8588912SDave May for (j=0; j<bA->nc; j++) { 173*d8588912SDave May if (!bA->m[i][j]) { 174*d8588912SDave May continue; 175*d8588912SDave May } 176*d8588912SDave May /* y[i] <- y[i] + A[i][j] * x[j] */ 177*d8588912SDave May ierr = MatMultAdd(bA->m[i][j],bx[j],by[i],by[i]);CHKERRQ(ierr); 178*d8588912SDave May } 179*d8588912SDave May } 180*d8588912SDave May PetscFunctionReturn(0); 181*d8588912SDave May } 182*d8588912SDave May 183*d8588912SDave May #undef __FUNCT__ 184*d8588912SDave May #define __FUNCT__ "MatMultTranspose_Nest" 185*d8588912SDave May PetscErrorCode MatMultTranspose_Nest(Mat A,Vec x,Vec y) 186*d8588912SDave May { 187*d8588912SDave May Mat_Nest *bA = (Mat_Nest*)A->data; 188*d8588912SDave May Vec *bx; 189*d8588912SDave May Vec *by; 190*d8588912SDave May PetscInt i,j; 191*d8588912SDave May PetscErrorCode ierr; 192*d8588912SDave May 193*d8588912SDave May PetscFunctionBegin; 194*d8588912SDave May ierr = PETSc_MatNest_CheckMatVecCompatibility2(A,x,y);CHKERRQ(ierr); 195*d8588912SDave May ierr = VecNestGetSubVecs(x,PETSC_NULL,&bx);CHKERRQ(ierr); 196*d8588912SDave May ierr = VecNestGetSubVecs(y,PETSC_NULL,&by);CHKERRQ(ierr); 197*d8588912SDave May if (A->symmetric) { 198*d8588912SDave May ierr = MatMult_Nest(A,x,y);CHKERRQ(ierr); 199*d8588912SDave May PetscFunctionReturn(0); 200*d8588912SDave May } 201*d8588912SDave May for (i=0; i<bA->nr; i++) { 202*d8588912SDave May ierr = VecZeroEntries(by[i]);CHKERRQ(ierr); 203*d8588912SDave May for (j=0; j<bA->nc; j++) { 204*d8588912SDave May if (!bA->m[j][i]) { 205*d8588912SDave May continue; 206*d8588912SDave May } 207*d8588912SDave May /* y[i] <- y[i] + A^T[i][j] * x[j], so we swap i,j in mat[][] */ 208*d8588912SDave May ierr = MatMultTransposeAdd(bA->m[j][i],bx[j],by[i],by[i]);CHKERRQ(ierr); 209*d8588912SDave May } 210*d8588912SDave May } 211*d8588912SDave May PetscFunctionReturn(0); 212*d8588912SDave May } 213*d8588912SDave May 214*d8588912SDave May /* Returns the sum of the global size of all the consituent vectors in the nest */ 215*d8588912SDave May #undef __FUNCT__ 216*d8588912SDave May #define __FUNCT__ "MatGetSize_Nest" 217*d8588912SDave May PetscErrorCode MatGetSize_Nest(Mat A,PetscInt *M,PetscInt *N) 218*d8588912SDave May { 219*d8588912SDave May PetscFunctionBegin; 220*d8588912SDave May if (M) { *M = A->rmap->N; } 221*d8588912SDave May if (N) { *N = A->cmap->N; } 222*d8588912SDave May PetscFunctionReturn(0); 223*d8588912SDave May } 224*d8588912SDave May 225*d8588912SDave May /* Returns the sum of the local size of all the consituent vectors in the nest */ 226*d8588912SDave May #undef __FUNCT__ 227*d8588912SDave May #define __FUNCT__ "MatGetLocalSize_Nest" 228*d8588912SDave May PetscErrorCode MatGetLocalSize_Nest(Mat A,PetscInt *m,PetscInt *n) 229*d8588912SDave May { 230*d8588912SDave May PetscFunctionBegin; 231*d8588912SDave May if (m) { *m = A->rmap->n; } 232*d8588912SDave May if (n) { *n = A->cmap->n; } 233*d8588912SDave May PetscFunctionReturn(0); 234*d8588912SDave May } 235*d8588912SDave May 236*d8588912SDave May #undef __FUNCT__ 237*d8588912SDave May #define __FUNCT__ "MatDestroy_Nest" 238*d8588912SDave May PetscErrorCode MatDestroy_Nest(Mat A) 239*d8588912SDave May { 240*d8588912SDave May Mat_Nest *vs = (Mat_Nest*)A->data; 241*d8588912SDave May PetscInt i,j; 242*d8588912SDave May PetscErrorCode ierr; 243*d8588912SDave May 244*d8588912SDave May PetscFunctionBegin; 245*d8588912SDave May /* release the matrices and the place holders */ 246*d8588912SDave May if (vs->is_row) { 247*d8588912SDave May for (i=0; i<vs->nr; i++) { 248*d8588912SDave May if(vs->is_row[i]) ierr = ISDestroy(vs->is_row[i]);CHKERRQ(ierr); 249*d8588912SDave May } 250*d8588912SDave May ierr = PetscFree(vs->is_row);CHKERRQ(ierr); 251*d8588912SDave May } 252*d8588912SDave May if (vs->is_col) { 253*d8588912SDave May for (j=0; j<vs->nc; j++) { 254*d8588912SDave May if(vs->is_col[j]) ierr = ISDestroy(vs->is_col[j]);CHKERRQ(ierr); 255*d8588912SDave May } 256*d8588912SDave May ierr = PetscFree(vs->is_col);CHKERRQ(ierr); 257*d8588912SDave May } 258*d8588912SDave May 259*d8588912SDave May ierr = PetscFree(vs->row_len);CHKERRQ(ierr); 260*d8588912SDave May ierr = PetscFree(vs->col_len);CHKERRQ(ierr); 261*d8588912SDave May 262*d8588912SDave May /* release the matrices and the place holders */ 263*d8588912SDave May if (vs->m) { 264*d8588912SDave May for (i=0; i<vs->nr; i++) { 265*d8588912SDave May for (j=0; j<vs->nc; j++) { 266*d8588912SDave May 267*d8588912SDave May if (vs->m[i][j]) { 268*d8588912SDave May ierr = MatDestroy(vs->m[i][j]);CHKERRQ(ierr); 269*d8588912SDave May vs->m[i][j] = PETSC_NULL; 270*d8588912SDave May } 271*d8588912SDave May } 272*d8588912SDave May ierr = PetscFree( vs->m[i] );CHKERRQ(ierr); 273*d8588912SDave May vs->m[i] = PETSC_NULL; 274*d8588912SDave May } 275*d8588912SDave May ierr = PetscFree(vs->m);CHKERRQ(ierr); 276*d8588912SDave May vs->m = PETSC_NULL; 277*d8588912SDave May } 278*d8588912SDave May ierr = PetscFree(vs);CHKERRQ(ierr); 279*d8588912SDave May 280*d8588912SDave May PetscFunctionReturn(0); 281*d8588912SDave May } 282*d8588912SDave May 283*d8588912SDave May #undef __FUNCT__ 284*d8588912SDave May #define __FUNCT__ "MatAssemblyBegin_Nest" 285*d8588912SDave May PetscErrorCode MatAssemblyBegin_Nest(Mat A,MatAssemblyType type) 286*d8588912SDave May { 287*d8588912SDave May Mat_Nest *vs = (Mat_Nest*)A->data; 288*d8588912SDave May PetscInt i,j; 289*d8588912SDave May PetscErrorCode ierr; 290*d8588912SDave May 291*d8588912SDave May PetscFunctionBegin; 292*d8588912SDave May for (i=0; i<vs->nr; i++) { 293*d8588912SDave May for (j=0; j<vs->nc; j++) { 294*d8588912SDave May if (vs->m[i][j]) { ierr = MatAssemblyBegin(vs->m[i][j],type);CHKERRQ(ierr); } 295*d8588912SDave May } 296*d8588912SDave May } 297*d8588912SDave May PetscFunctionReturn(0); 298*d8588912SDave May } 299*d8588912SDave May 300*d8588912SDave May #undef __FUNCT__ 301*d8588912SDave May #define __FUNCT__ "MatAssemblyEnd_Nest" 302*d8588912SDave May PetscErrorCode MatAssemblyEnd_Nest(Mat A, MatAssemblyType type) 303*d8588912SDave May { 304*d8588912SDave May Mat_Nest *vs = (Mat_Nest*)A->data; 305*d8588912SDave May PetscInt i,j; 306*d8588912SDave May PetscErrorCode ierr; 307*d8588912SDave May 308*d8588912SDave May PetscFunctionBegin; 309*d8588912SDave May for (i=0; i<vs->nr; i++) { 310*d8588912SDave May for (j=0; j<vs->nc; j++) { 311*d8588912SDave May if (vs->m[i][j]) { ierr = MatAssemblyEnd(vs->m[i][j],type);CHKERRQ(ierr); } 312*d8588912SDave May } 313*d8588912SDave May } 314*d8588912SDave May PetscFunctionReturn(0); 315*d8588912SDave May } 316*d8588912SDave May 317*d8588912SDave May #undef __FUNCT__ 318*d8588912SDave May #define __FUNCT__ "MatGetLocalSubMatrix_Nest" 319*d8588912SDave May PetscErrorCode MatGetLocalSubMatrix_Nest(Mat A,IS irow,IS icol,Mat *sub) 320*d8588912SDave May { 321*d8588912SDave May Mat_Nest *bA = (Mat_Nest*)A->data; 322*d8588912SDave May PetscInt i,j; 323*d8588912SDave May PetscBool found_row,found_col; 324*d8588912SDave May PetscInt row=-1,col=-1; 325*d8588912SDave May PetscErrorCode ierr; 326*d8588912SDave May 327*d8588912SDave May PetscFunctionBegin; 328*d8588912SDave May found_row = PETSC_FALSE; 329*d8588912SDave May for (i=0; i<bA->nr; i++) { 330*d8588912SDave May ierr = ISEqual(irow,bA->is_row[i],&found_row);CHKERRQ(ierr); 331*d8588912SDave May if(found_row){ row = i; break; } 332*d8588912SDave May } 333*d8588912SDave May found_col = PETSC_FALSE; 334*d8588912SDave May for (j=0; j<bA->nc; j++) { 335*d8588912SDave May ierr = ISEqual(icol,bA->is_col[j],&found_col);CHKERRQ(ierr); 336*d8588912SDave May if(found_col){ col = j; break; } 337*d8588912SDave May } 338*d8588912SDave May /* check valid i,j */ 339*d8588912SDave May if ((row<0)||(col<0)) { 340*d8588912SDave May SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat(Nest) must contain at least one matrix within each row and column"); 341*d8588912SDave May } 342*d8588912SDave May if ((row>=bA->nr)||(col>=bA->nc)) { 343*d8588912SDave May SETERRQ(((PetscObject)A)->comm,PETSC_ERR_USER,"Mat(Nest) row and column is too large"); 344*d8588912SDave May } 345*d8588912SDave May 346*d8588912SDave May *sub = bA->m[row][col]; 347*d8588912SDave May if (bA->m[row][col]) { 348*d8588912SDave May ierr = PetscObjectReference( (PetscObject)bA->m[row][col] );CHKERRQ(ierr); 349*d8588912SDave May } 350*d8588912SDave May 351*d8588912SDave May PetscFunctionReturn(0); 352*d8588912SDave May } 353*d8588912SDave May 354*d8588912SDave May #undef __FUNCT__ 355*d8588912SDave May #define __FUNCT__ "MatRestoreLocalSubMatrix_Nest" 356*d8588912SDave May PetscErrorCode MatRestoreLocalSubMatrix_Nest(Mat A,IS irow,IS icol,Mat *sub) 357*d8588912SDave May { 358*d8588912SDave May Mat_Nest *bA = (Mat_Nest*)A->data; 359*d8588912SDave May PetscInt i,j; 360*d8588912SDave May PetscBool found_row,found_col; 361*d8588912SDave May PetscInt row=-1,col=-1; 362*d8588912SDave May PetscErrorCode ierr; 363*d8588912SDave May 364*d8588912SDave May PetscFunctionBegin; 365*d8588912SDave May found_row = PETSC_FALSE; 366*d8588912SDave May for (i=0; i<bA->nr; i++) { 367*d8588912SDave May ierr = ISEqual(irow,bA->is_row[i],&found_row);CHKERRQ(ierr); 368*d8588912SDave May if (found_row){ row = i; break; } 369*d8588912SDave May } 370*d8588912SDave May found_col = PETSC_FALSE; 371*d8588912SDave May for (j=0; j<bA->nc; j++) { 372*d8588912SDave May ierr = ISEqual(icol,bA->is_col[j],&found_col);CHKERRQ(ierr); 373*d8588912SDave May if (found_col){ col = j; break; } 374*d8588912SDave May } 375*d8588912SDave May /* check valid i,j */ 376*d8588912SDave May if ((row<0)||(col<0)) { 377*d8588912SDave May SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat(Nest) must contain at least one matrix within each row and column"); 378*d8588912SDave May } 379*d8588912SDave May if ((row>=bA->nr)||(col>=bA->nc)) { 380*d8588912SDave May SETERRQ(((PetscObject)A)->comm,PETSC_ERR_USER,"Mat(Nest) row and column is too large"); 381*d8588912SDave May } 382*d8588912SDave May 383*d8588912SDave May if (*sub) { 384*d8588912SDave May ierr = MatDestroy(*sub);CHKERRQ(ierr); 385*d8588912SDave May } 386*d8588912SDave May 387*d8588912SDave May PetscFunctionReturn(0); 388*d8588912SDave May } 389*d8588912SDave May 390*d8588912SDave May #undef __FUNCT__ 391*d8588912SDave May #define __FUNCT__ "MatGetVecs_Nest" 392*d8588912SDave May PetscErrorCode MatGetVecs_Nest(Mat A,Vec *right,Vec *left) 393*d8588912SDave May { 394*d8588912SDave May Mat_Nest *bA = (Mat_Nest*)A->data; 395*d8588912SDave May Vec *L,*R; 396*d8588912SDave May MPI_Comm comm; 397*d8588912SDave May PetscInt i,j; 398*d8588912SDave May PetscErrorCode ierr; 399*d8588912SDave May 400*d8588912SDave May PetscFunctionBegin; 401*d8588912SDave May comm = ((PetscObject)A)->comm; 402*d8588912SDave May if (right) { 403*d8588912SDave May /* allocate R */ 404*d8588912SDave May ierr = PetscMalloc( sizeof(Vec) * bA->nc, &R );CHKERRQ(ierr); 405*d8588912SDave May /* Create the right vectors */ 406*d8588912SDave May for (j=0; j<bA->nc; j++) { 407*d8588912SDave May for (i=0; i<bA->nr; i++) { 408*d8588912SDave May if (bA->m[i][j]) { 409*d8588912SDave May ierr = MatGetVecs(bA->m[i][j],&R[j],PETSC_NULL);CHKERRQ(ierr); 410*d8588912SDave May break; 411*d8588912SDave May } 412*d8588912SDave May } 413*d8588912SDave May if (i==bA->nr) { 414*d8588912SDave May /* have an empty column */ 415*d8588912SDave May SETERRQ( ((PetscObject)A)->comm, PETSC_ERR_ARG_WRONG, "Mat(Nest) contains a null column."); 416*d8588912SDave May } 417*d8588912SDave May } 418*d8588912SDave May ierr = VecCreateNest(comm,bA->nc,bA->is_col,R,right);CHKERRQ(ierr); 419*d8588912SDave May /* hand back control to the nest vector */ 420*d8588912SDave May for (j=0; j<bA->nc; j++) { 421*d8588912SDave May ierr = VecDestroy(R[j]);CHKERRQ(ierr); 422*d8588912SDave May } 423*d8588912SDave May ierr = PetscFree(R);CHKERRQ(ierr); 424*d8588912SDave May } 425*d8588912SDave May 426*d8588912SDave May if (left) { 427*d8588912SDave May /* allocate L */ 428*d8588912SDave May ierr = PetscMalloc( sizeof(Vec) * bA->nr, &L );CHKERRQ(ierr); 429*d8588912SDave May /* Create the left vectors */ 430*d8588912SDave May for (i=0; i<bA->nr; i++) { 431*d8588912SDave May for (j=0; j<bA->nc; j++) { 432*d8588912SDave May if (bA->m[i][j]) { 433*d8588912SDave May ierr = MatGetVecs(bA->m[i][j],PETSC_NULL,&L[i]);CHKERRQ(ierr); 434*d8588912SDave May break; 435*d8588912SDave May } 436*d8588912SDave May } 437*d8588912SDave May if (j==bA->nc) { 438*d8588912SDave May /* have an empty row */ 439*d8588912SDave May SETERRQ( ((PetscObject)A)->comm, PETSC_ERR_ARG_WRONG, "Mat(Nest) contains a null row."); 440*d8588912SDave May } 441*d8588912SDave May } 442*d8588912SDave May 443*d8588912SDave May ierr = VecCreateNest(comm,bA->nr,bA->is_row,L,left);CHKERRQ(ierr); 444*d8588912SDave May for (i=0; i<bA->nr; i++) { 445*d8588912SDave May ierr = VecDestroy(L[i]);CHKERRQ(ierr); 446*d8588912SDave May } 447*d8588912SDave May 448*d8588912SDave May ierr = PetscFree(L);CHKERRQ(ierr); 449*d8588912SDave May } 450*d8588912SDave May PetscFunctionReturn(0); 451*d8588912SDave May } 452*d8588912SDave May 453*d8588912SDave May #undef __FUNCT__ 454*d8588912SDave May #define __FUNCT__ "MatView_Nest" 455*d8588912SDave May PetscErrorCode MatView_Nest(Mat A,PetscViewer viewer) 456*d8588912SDave May { 457*d8588912SDave May Mat_Nest *bA = (Mat_Nest*)A->data; 458*d8588912SDave May PetscBool isascii; 459*d8588912SDave May PetscInt i,j; 460*d8588912SDave May PetscErrorCode ierr; 461*d8588912SDave May 462*d8588912SDave May PetscFunctionBegin; 463*d8588912SDave May ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 464*d8588912SDave May if (isascii) { 465*d8588912SDave May 466*d8588912SDave May PetscViewerASCIIPrintf(viewer,"Matrix object: \n" ); 467*d8588912SDave May PetscViewerASCIIPushTab( viewer ); /* push0 */ 468*d8588912SDave May PetscViewerASCIIPrintf( viewer, "type=nest, rows=%d, cols=%d \n",bA->nr,bA->nc); 469*d8588912SDave May 470*d8588912SDave May PetscViewerASCIIPrintf(viewer,"MatNest structure: \n" ); 471*d8588912SDave May for (i=0; i<bA->nr; i++) { 472*d8588912SDave May for (j=0; j<bA->nc; j++) { 473*d8588912SDave May const MatType type; 474*d8588912SDave May const char *name; 475*d8588912SDave May PetscInt NR,NC; 476*d8588912SDave May PetscBool isNest = PETSC_FALSE; 477*d8588912SDave May 478*d8588912SDave May if (!bA->m[i][j]) { 479*d8588912SDave May PetscViewerASCIIPrintf( viewer, "(%D,%D) : PETSC_NULL \n",i,j); 480*d8588912SDave May continue; 481*d8588912SDave May } 482*d8588912SDave May ierr = MatGetSize(bA->m[i][j],&NR,&NC);CHKERRQ(ierr); 483*d8588912SDave May ierr = MatGetType( bA->m[i][j], &type );CHKERRQ(ierr); 484*d8588912SDave May name = ((PetscObject)bA->m[i][j])->prefix; 485*d8588912SDave May ierr = PetscTypeCompare((PetscObject)bA->m[i][j],MATNEST,&isNest);CHKERRQ(ierr); 486*d8588912SDave May 487*d8588912SDave May PetscViewerASCIIPrintf( viewer, "(%D,%D) : name=\"%s\", type=%s, rows=%D, cols=%D \n",i,j,name,type,NR,NC); 488*d8588912SDave May 489*d8588912SDave May if (isNest) { 490*d8588912SDave May PetscViewerASCIIPushTab( viewer ); /* push1 */ 491*d8588912SDave May ierr = MatView( bA->m[i][j], viewer );CHKERRQ(ierr); 492*d8588912SDave May PetscViewerASCIIPopTab(viewer); /* pop1 */ 493*d8588912SDave May } 494*d8588912SDave May } 495*d8588912SDave May } 496*d8588912SDave May PetscViewerASCIIPopTab(viewer); /* pop0 */ 497*d8588912SDave May } 498*d8588912SDave May PetscFunctionReturn(0); 499*d8588912SDave May } 500*d8588912SDave May 501*d8588912SDave May #undef __FUNCT__ 502*d8588912SDave May #define __FUNCT__ "MatZeroEntries_Nest" 503*d8588912SDave May PetscErrorCode MatZeroEntries_Nest(Mat A) 504*d8588912SDave May { 505*d8588912SDave May Mat_Nest *bA = (Mat_Nest*)A->data; 506*d8588912SDave May PetscInt i,j; 507*d8588912SDave May PetscErrorCode ierr; 508*d8588912SDave May 509*d8588912SDave May PetscFunctionBegin; 510*d8588912SDave May for (i=0; i<bA->nr; i++) { 511*d8588912SDave May for (j=0; j<bA->nc; j++) { 512*d8588912SDave May if (!bA->m[i][j]) continue; 513*d8588912SDave May ierr = MatZeroEntries(bA->m[i][j]);CHKERRQ(ierr); 514*d8588912SDave May } 515*d8588912SDave May } 516*d8588912SDave May PetscFunctionReturn(0); 517*d8588912SDave May } 518*d8588912SDave May 519*d8588912SDave May #undef __FUNCT__ 520*d8588912SDave May #define __FUNCT__ "MatDuplicate_Nest" 521*d8588912SDave May PetscErrorCode MatDuplicate_Nest(Mat A,MatDuplicateOption op,Mat *B) 522*d8588912SDave May { 523*d8588912SDave May Mat_Nest *bA = (Mat_Nest*)A->data; 524*d8588912SDave May Mat **b; 525*d8588912SDave May PetscInt i,j; 526*d8588912SDave May PetscErrorCode ierr; 527*d8588912SDave May 528*d8588912SDave May // TODO 529*d8588912SDave May PetscFunctionBegin; 530*d8588912SDave May 531*d8588912SDave May ierr = PetscMalloc(sizeof(Mat*)*bA->nr,&b);CHKERRQ(ierr); 532*d8588912SDave May for (i=0; i<bA->nr; i++) { 533*d8588912SDave May ierr = PetscMalloc(sizeof(Mat)*bA->nc,&b[i]);CHKERRQ(ierr); 534*d8588912SDave May } 535*d8588912SDave May for (i=0; i<bA->nr; i++) { 536*d8588912SDave May for (j=0; j<bA->nc; j++) { 537*d8588912SDave May if (!bA->m[i][j]) continue; 538*d8588912SDave May ierr = MatDuplicate(bA->m[i][j],op,&b[i][j]);CHKERRQ(ierr); 539*d8588912SDave May } 540*d8588912SDave May } 541*d8588912SDave May ierr = MatCreateNest(((PetscObject)A)->comm,bA->nr,bA->nc,bA->is_row,bA->is_col,bA->m,B);CHKERRQ(ierr); 542*d8588912SDave May /* hand back control to the nest */ 543*d8588912SDave May for (i=0; i<bA->nr; i++) { 544*d8588912SDave May for (j=0; j<bA->nc; j++) { 545*d8588912SDave May if (!bA->m[i][j]) continue; 546*d8588912SDave May ierr = MatDestroy(b[i][j]);CHKERRQ(ierr); 547*d8588912SDave May } 548*d8588912SDave May } 549*d8588912SDave May ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 550*d8588912SDave May ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 551*d8588912SDave May 552*d8588912SDave May for (i=0; i<bA->nr; i++) { 553*d8588912SDave May ierr = PetscFree(b[i]);CHKERRQ(ierr); 554*d8588912SDave May } 555*d8588912SDave May ierr = PetscFree(b);CHKERRQ(ierr); 556*d8588912SDave May 557*d8588912SDave May PetscFunctionReturn(0); 558*d8588912SDave May } 559*d8588912SDave May 560*d8588912SDave May /* nest api */ 561*d8588912SDave May EXTERN_C_BEGIN 562*d8588912SDave May #undef __FUNCT__ 563*d8588912SDave May #define __FUNCT__ "MatNestGetSubMat_Nest" 564*d8588912SDave May PetscErrorCode MatNestGetSubMat_Nest(Mat A,PetscInt idxm,PetscInt jdxm,Mat *mat) 565*d8588912SDave May { 566*d8588912SDave May Mat_Nest *bA = (Mat_Nest*)A->data; 567*d8588912SDave May PetscFunctionBegin; 568*d8588912SDave May if (idxm >= bA->nr) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",idxm,bA->nr-1); 569*d8588912SDave May if (jdxm >= bA->nc) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Col too large: row %D max %D",jdxm,bA->nc-1); 570*d8588912SDave May *mat = bA->m[idxm][jdxm]; 571*d8588912SDave May PetscFunctionReturn(0); 572*d8588912SDave May } 573*d8588912SDave May EXTERN_C_END 574*d8588912SDave May 575*d8588912SDave May #undef __FUNCT__ 576*d8588912SDave May #define __FUNCT__ "MatNestGetSubMat" 577*d8588912SDave May /*@C 578*d8588912SDave May MatNestGetSubMat - Returns a single, sub-matrix from a nest matrix. 579*d8588912SDave May 580*d8588912SDave May Not collective 581*d8588912SDave May 582*d8588912SDave May Input Parameters: 583*d8588912SDave May . A - nest matrix 584*d8588912SDave May . idxm - index of the matrix within the nest matrix 585*d8588912SDave May . jdxm - index of the matrix within the nest matrix 586*d8588912SDave May 587*d8588912SDave May Output Parameter: 588*d8588912SDave May . sub - matrix at index idxm,jdxm within the nest matrix 589*d8588912SDave May 590*d8588912SDave May Notes: 591*d8588912SDave May 592*d8588912SDave May Level: developer 593*d8588912SDave May 594*d8588912SDave May .seealso: MatNestGetSize(), MatNestGetSubMats() 595*d8588912SDave May @*/ 596*d8588912SDave May PetscErrorCode PETSCMAT_DLLEXPORT MatNestGetSubMat(Mat A,PetscInt idxm,PetscInt jdxm,Mat *sub) 597*d8588912SDave May { 598*d8588912SDave May PetscErrorCode ierr,(*f)(Mat,PetscInt,PetscInt,Mat*); 599*d8588912SDave May 600*d8588912SDave May PetscFunctionBegin; 601*d8588912SDave May ierr = PetscObjectQueryFunction((PetscObject)A,"MatNestGetSubMat_C",(void (**)(void))&f);CHKERRQ(ierr); 602*d8588912SDave May if (f) { 603*d8588912SDave May ierr = (*f)(A,idxm,jdxm,sub);CHKERRQ(ierr); 604*d8588912SDave May } 605*d8588912SDave May PetscFunctionReturn(0); 606*d8588912SDave May } 607*d8588912SDave May 608*d8588912SDave May EXTERN_C_BEGIN 609*d8588912SDave May #undef __FUNCT__ 610*d8588912SDave May #define __FUNCT__ "MatNestGetSubMats_Nest" 611*d8588912SDave May PetscErrorCode MatNestGetSubMats_Nest(Mat A,PetscInt *M,PetscInt *N,Mat ***mat) 612*d8588912SDave May { 613*d8588912SDave May Mat_Nest *bA = (Mat_Nest*)A->data; 614*d8588912SDave May PetscFunctionBegin; 615*d8588912SDave May if (M) { *M = bA->nr; } 616*d8588912SDave May if (N) { *N = bA->nc; } 617*d8588912SDave May if (mat) { *mat = bA->m; } 618*d8588912SDave May PetscFunctionReturn(0); 619*d8588912SDave May } 620*d8588912SDave May EXTERN_C_END 621*d8588912SDave May 622*d8588912SDave May #undef __FUNCT__ 623*d8588912SDave May #define __FUNCT__ "MatNestGetSubMats" 624*d8588912SDave May /*@C 625*d8588912SDave May MatNestGetSubMats - Returns the entire two dimensional array of matrices defining a nest matrix. 626*d8588912SDave May 627*d8588912SDave May Not collective 628*d8588912SDave May 629*d8588912SDave May Input Parameters: 630*d8588912SDave May . A - nest matri 631*d8588912SDave May 632*d8588912SDave May Output Parameter: 633*d8588912SDave May . M - number of rows in the nest matrix 634*d8588912SDave May . N - number of cols in the nest matrix 635*d8588912SDave May . mat - 2d array of matrices 636*d8588912SDave May 637*d8588912SDave May Notes: 638*d8588912SDave May 639*d8588912SDave May The user should not free the array mat. 640*d8588912SDave May 641*d8588912SDave May Level: developer 642*d8588912SDave May 643*d8588912SDave May .seealso: MatNestGetSize(), MatNestGetSubMat() 644*d8588912SDave May @*/ 645*d8588912SDave May PetscErrorCode PETSCMAT_DLLEXPORT MatNestGetSubMats(Mat A,PetscInt *M,PetscInt *N,Mat ***mat) 646*d8588912SDave May { 647*d8588912SDave May PetscErrorCode ierr,(*f)(Mat,PetscInt*,PetscInt*,Mat***); 648*d8588912SDave May 649*d8588912SDave May PetscFunctionBegin; 650*d8588912SDave May ierr = PetscObjectQueryFunction((PetscObject)A,"MatNestGetSubMats_C",(void (**)(void))&f);CHKERRQ(ierr); 651*d8588912SDave May if (f) { 652*d8588912SDave May ierr = (*f)(A,M,N,mat);CHKERRQ(ierr); 653*d8588912SDave May } 654*d8588912SDave May PetscFunctionReturn(0); 655*d8588912SDave May } 656*d8588912SDave May 657*d8588912SDave May EXTERN_C_BEGIN 658*d8588912SDave May #undef __FUNCT__ 659*d8588912SDave May #define __FUNCT__ "MatNestGetSize_Nest" 660*d8588912SDave May PetscErrorCode PETSCMAT_DLLEXPORT MatNestGetSize_Nest(Mat A,PetscInt *M,PetscInt *N) 661*d8588912SDave May { 662*d8588912SDave May Mat_Nest *bA = (Mat_Nest*)A->data; 663*d8588912SDave May 664*d8588912SDave May PetscFunctionBegin; 665*d8588912SDave May if (M) { *M = bA->nr; } 666*d8588912SDave May if (N) { *N = bA->nc; } 667*d8588912SDave May PetscFunctionReturn(0); 668*d8588912SDave May } 669*d8588912SDave May EXTERN_C_END 670*d8588912SDave May 671*d8588912SDave May #undef __FUNCT__ 672*d8588912SDave May #define __FUNCT__ "MatNestGetSize" 673*d8588912SDave May /*@C 674*d8588912SDave May MatNestGetSize - Returns the size of the nest matrix. 675*d8588912SDave May 676*d8588912SDave May Not collective 677*d8588912SDave May 678*d8588912SDave May Input Parameters: 679*d8588912SDave May . A - nest matrix 680*d8588912SDave May 681*d8588912SDave May Output Parameter: 682*d8588912SDave May . M - number of rows in the nested mat 683*d8588912SDave May . N - number of cols in the nested mat 684*d8588912SDave May 685*d8588912SDave May Notes: 686*d8588912SDave May 687*d8588912SDave May Level: developer 688*d8588912SDave May 689*d8588912SDave May .seealso: MatNestGetSubMat(), MatNestGetSubMats() 690*d8588912SDave May @*/ 691*d8588912SDave May PetscErrorCode PETSCMAT_DLLEXPORT MatNestGetSize(Mat A,PetscInt *M,PetscInt *N) 692*d8588912SDave May { 693*d8588912SDave May PetscErrorCode ierr,(*f)(Mat,PetscInt*,PetscInt*); 694*d8588912SDave May 695*d8588912SDave May PetscFunctionBegin; 696*d8588912SDave May ierr = PetscObjectQueryFunction((PetscObject)A,"MatNestGetSize_C",(void (**)(void))&f);CHKERRQ(ierr); 697*d8588912SDave May if (f) { 698*d8588912SDave May ierr = (*f)(A,M,N);CHKERRQ(ierr); 699*d8588912SDave May } 700*d8588912SDave May PetscFunctionReturn(0); 701*d8588912SDave May } 702*d8588912SDave May 703*d8588912SDave May /* constructor */ 704*d8588912SDave May #undef __FUNCT__ 705*d8588912SDave May #define __FUNCT__ "MatNestSetOps_Private" 706*d8588912SDave May static PetscErrorCode MatNestSetOps_Private(struct _MatOps* ops) 707*d8588912SDave May { 708*d8588912SDave May PetscFunctionBegin; 709*d8588912SDave May /* 0*/ 710*d8588912SDave May ops->setvalues = 0; 711*d8588912SDave May ops->getrow = 0; 712*d8588912SDave May ops->restorerow = 0; 713*d8588912SDave May ops->mult = MatMult_Nest; 714*d8588912SDave May ops->multadd = 0; 715*d8588912SDave May /* 5*/ 716*d8588912SDave May ops->multtranspose = MatMultTranspose_Nest; 717*d8588912SDave May ops->multtransposeadd = 0; 718*d8588912SDave May ops->solve = 0; 719*d8588912SDave May ops->solveadd = 0; 720*d8588912SDave May ops->solvetranspose = 0; 721*d8588912SDave May /*10*/ 722*d8588912SDave May ops->solvetransposeadd = 0; 723*d8588912SDave May ops->lufactor = 0; 724*d8588912SDave May ops->choleskyfactor = 0; 725*d8588912SDave May ops->sor = 0; 726*d8588912SDave May ops->transpose = 0; 727*d8588912SDave May /*15*/ 728*d8588912SDave May ops->getinfo = 0; 729*d8588912SDave May ops->equal = 0; 730*d8588912SDave May ops->getdiagonal = 0; 731*d8588912SDave May ops->diagonalscale = 0; 732*d8588912SDave May ops->norm = 0; 733*d8588912SDave May /*20*/ 734*d8588912SDave May ops->assemblybegin = MatAssemblyBegin_Nest; 735*d8588912SDave May ops->assemblyend = MatAssemblyEnd_Nest; 736*d8588912SDave May ops->setoption = 0; 737*d8588912SDave May ops->zeroentries = MatZeroEntries_Nest; 738*d8588912SDave May /*24*/ 739*d8588912SDave May ops->zerorows = 0; 740*d8588912SDave May ops->lufactorsymbolic = 0; 741*d8588912SDave May ops->lufactornumeric = 0; 742*d8588912SDave May ops->choleskyfactorsymbolic = 0; 743*d8588912SDave May ops->choleskyfactornumeric = 0; 744*d8588912SDave May /*29*/ 745*d8588912SDave May ops->setuppreallocation = 0; 746*d8588912SDave May ops->ilufactorsymbolic = 0; 747*d8588912SDave May ops->iccfactorsymbolic = 0; 748*d8588912SDave May ops->getarray = 0; 749*d8588912SDave May ops->restorearray = 0; 750*d8588912SDave May /*34*/ 751*d8588912SDave May ops->duplicate = MatDuplicate_Nest; 752*d8588912SDave May ops->forwardsolve = 0; 753*d8588912SDave May ops->backwardsolve = 0; 754*d8588912SDave May ops->ilufactor = 0; 755*d8588912SDave May ops->iccfactor = 0; 756*d8588912SDave May /*39*/ 757*d8588912SDave May ops->axpy = 0; 758*d8588912SDave May ops->getsubmatrices = 0; 759*d8588912SDave May ops->increaseoverlap = 0; 760*d8588912SDave May ops->getvalues = 0; 761*d8588912SDave May ops->copy = 0; 762*d8588912SDave May /*44*/ 763*d8588912SDave May ops->getrowmax = 0; 764*d8588912SDave May ops->scale = 0; 765*d8588912SDave May ops->shift = 0; 766*d8588912SDave May ops->diagonalset = 0; 767*d8588912SDave May ops->zerorowscolumns = 0; 768*d8588912SDave May /*49*/ 769*d8588912SDave May ops->setblocksize = 0; 770*d8588912SDave May ops->getrowij = 0; 771*d8588912SDave May ops->restorerowij = 0; 772*d8588912SDave May ops->getcolumnij = 0; 773*d8588912SDave May ops->restorecolumnij = 0; 774*d8588912SDave May /*54*/ 775*d8588912SDave May ops->fdcoloringcreate = 0; 776*d8588912SDave May ops->coloringpatch = 0; 777*d8588912SDave May ops->setunfactored = 0; 778*d8588912SDave May ops->permute = 0; 779*d8588912SDave May ops->setvaluesblocked = 0; 780*d8588912SDave May /*59*/ 781*d8588912SDave May ops->getsubmatrix = 0; 782*d8588912SDave May ops->destroy = MatDestroy_Nest; 783*d8588912SDave May ops->view = MatView_Nest; 784*d8588912SDave May ops->convertfrom = 0; 785*d8588912SDave May ops->usescaledform = 0; 786*d8588912SDave May /*64*/ 787*d8588912SDave May ops->scalesystem = 0; 788*d8588912SDave May ops->unscalesystem = 0; 789*d8588912SDave May ops->setlocaltoglobalmapping = 0; 790*d8588912SDave May ops->setvalueslocal = 0; 791*d8588912SDave May ops->zerorowslocal = 0; 792*d8588912SDave May /*69*/ 793*d8588912SDave May ops->getrowmaxabs = 0; 794*d8588912SDave May ops->getrowminabs = 0; 795*d8588912SDave May ops->convert = 0;/*MatConvert_Nest;*/ 796*d8588912SDave May ops->setcoloring = 0; 797*d8588912SDave May ops->setvaluesadic = 0; 798*d8588912SDave May /* 74 */ 799*d8588912SDave May ops->setvaluesadifor = 0; 800*d8588912SDave May ops->fdcoloringapply = 0; 801*d8588912SDave May ops->setfromoptions = 0; 802*d8588912SDave May ops->multconstrained = 0; 803*d8588912SDave May ops->multtransposeconstrained = 0; 804*d8588912SDave May /*79*/ 805*d8588912SDave May ops->permutesparsify = 0; 806*d8588912SDave May ops->mults = 0; 807*d8588912SDave May ops->solves = 0; 808*d8588912SDave May ops->getinertia = 0; 809*d8588912SDave May ops->load = 0; 810*d8588912SDave May /*84*/ 811*d8588912SDave May ops->issymmetric = 0; 812*d8588912SDave May ops->ishermitian = 0; 813*d8588912SDave May ops->isstructurallysymmetric = 0; 814*d8588912SDave May ops->dummy4 = 0; 815*d8588912SDave May ops->getvecs = MatGetVecs_Nest; 816*d8588912SDave May /*89*/ 817*d8588912SDave May ops->matmult = 0;/*MatMatMult_Nest;*/ 818*d8588912SDave May ops->matmultsymbolic = 0; 819*d8588912SDave May ops->matmultnumeric = 0; 820*d8588912SDave May ops->ptap = 0; 821*d8588912SDave May ops->ptapsymbolic = 0; 822*d8588912SDave May /*94*/ 823*d8588912SDave May ops->ptapnumeric = 0; 824*d8588912SDave May ops->matmulttranspose = 0; 825*d8588912SDave May ops->matmulttransposesymbolic = 0; 826*d8588912SDave May ops->matmulttransposenumeric = 0; 827*d8588912SDave May ops->ptapsymbolic_seqaij = 0; 828*d8588912SDave May /*99*/ 829*d8588912SDave May ops->ptapnumeric_seqaij = 0; 830*d8588912SDave May ops->ptapsymbolic_mpiaij = 0; 831*d8588912SDave May ops->ptapnumeric_mpiaij = 0; 832*d8588912SDave May ops->conjugate = 0; 833*d8588912SDave May ops->setsizes = 0; 834*d8588912SDave May /*104*/ 835*d8588912SDave May ops->setvaluesrow = 0; 836*d8588912SDave May ops->realpart = 0; 837*d8588912SDave May ops->imaginarypart = 0; 838*d8588912SDave May ops->getrowuppertriangular = 0; 839*d8588912SDave May ops->restorerowuppertriangular = 0; 840*d8588912SDave May /*109*/ 841*d8588912SDave May ops->matsolve = 0; 842*d8588912SDave May ops->getredundantmatrix = 0; 843*d8588912SDave May ops->getrowmin = 0; 844*d8588912SDave May ops->getcolumnvector = 0; 845*d8588912SDave May ops->missingdiagonal = 0; 846*d8588912SDave May /* 114 */ 847*d8588912SDave May ops->getseqnonzerostructure = 0; 848*d8588912SDave May ops->create = 0; 849*d8588912SDave May ops->getghosts = 0; 850*d8588912SDave May ops->getlocalsubmatrix = MatGetLocalSubMatrix_Nest; 851*d8588912SDave May ops->restorelocalsubmatrix = MatRestoreLocalSubMatrix_Nest; 852*d8588912SDave May /* 119 */ 853*d8588912SDave May ops->multdiagonalblock = 0; 854*d8588912SDave May ops->hermitiantranspose = 0; 855*d8588912SDave May ops->multhermitiantranspose = 0; 856*d8588912SDave May ops->multhermitiantransposeadd = 0; 857*d8588912SDave May ops->getmultiprocblock = 0; 858*d8588912SDave May /* 124 */ 859*d8588912SDave May ops->dummy1 = 0; 860*d8588912SDave May ops->dummy2 = 0; 861*d8588912SDave May ops->dummy3 = 0; 862*d8588912SDave May ops->dummy4 = 0; 863*d8588912SDave May ops->getsubmatricesparallel = 0; 864*d8588912SDave May 865*d8588912SDave May PetscFunctionReturn(0); 866*d8588912SDave May } 867*d8588912SDave May 868*d8588912SDave May #undef __FUNCT__ 869*d8588912SDave May #define __FUNCT__ "MatSetUp_Nest_Private" 870*d8588912SDave May static PetscErrorCode MatSetUp_Nest_Private(Mat A,PetscInt nr,PetscInt nc,Mat **sub) 871*d8588912SDave May { 872*d8588912SDave May Mat_Nest *ctx = (Mat_Nest*)A->data; 873*d8588912SDave May PetscInt i,j; 874*d8588912SDave May PetscErrorCode ierr; 875*d8588912SDave May 876*d8588912SDave May PetscFunctionBegin; 877*d8588912SDave May if(ctx->setup_called) PetscFunctionReturn(0); 878*d8588912SDave May 879*d8588912SDave May ctx->nr = nr; 880*d8588912SDave May ctx->nc = nc; 881*d8588912SDave May if (ctx->nr < 0) { 882*d8588912SDave May SETERRQ( ((PetscObject)A)->comm, PETSC_ERR_ARG_WRONG, "Cannot create MAT_NEST with < 0 row Nests." ); 883*d8588912SDave May } 884*d8588912SDave May if (ctx->nc < 0) { 885*d8588912SDave May SETERRQ( ((PetscObject)A)->comm, PETSC_ERR_ARG_WRONG, "Cannot create MAT_NEST with < 0 col Nests." ); 886*d8588912SDave May } 887*d8588912SDave May 888*d8588912SDave May /* Create space */ 889*d8588912SDave May ierr = PetscMalloc(sizeof(Mat*)*ctx->nr,&ctx->m);CHKERRQ(ierr); 890*d8588912SDave May for (i=0; i<ctx->nr; i++) { 891*d8588912SDave May ierr = PetscMalloc(sizeof(Mat)*ctx->nc,&ctx->m[i]);CHKERRQ(ierr); 892*d8588912SDave May } 893*d8588912SDave May for (i=0; i<ctx->nr; i++) { 894*d8588912SDave May for (j=0; j<ctx->nc; j++) { 895*d8588912SDave May ctx->m[i][j] = sub[i][j]; 896*d8588912SDave May if (sub[i][j]) { 897*d8588912SDave May ierr = PetscObjectReference((PetscObject)sub[i][j]);CHKERRQ(ierr); 898*d8588912SDave May } 899*d8588912SDave May } 900*d8588912SDave May } 901*d8588912SDave May 902*d8588912SDave May ierr = PetscMalloc(sizeof(IS)*ctx->nr,&ctx->is_row);CHKERRQ(ierr); 903*d8588912SDave May ierr = PetscMalloc(sizeof(IS)*ctx->nc,&ctx->is_col);CHKERRQ(ierr); 904*d8588912SDave May 905*d8588912SDave May ierr = PetscMalloc(sizeof(PetscInt)*ctx->nr,&ctx->row_len);CHKERRQ(ierr); 906*d8588912SDave May ierr = PetscMalloc(sizeof(PetscInt)*ctx->nc,&ctx->col_len);CHKERRQ(ierr); 907*d8588912SDave May for (i=0;i<ctx->nr;i++) ctx->row_len[i]=-1; 908*d8588912SDave May for (j=0;j<ctx->nc;j++) ctx->col_len[j]=-1; 909*d8588912SDave May 910*d8588912SDave May ctx->setup_called = PETSC_TRUE; 911*d8588912SDave May 912*d8588912SDave May PetscFunctionReturn(0); 913*d8588912SDave May } 914*d8588912SDave May 915*d8588912SDave May 916*d8588912SDave May /* If an IS was provided, there is nothing Nest needs to do, otherwise Nest will build a strided IS */ 917*d8588912SDave May /* 918*d8588912SDave May nprocessors = NP 919*d8588912SDave May Nest x^T = ( (g_0,g_1,...g_nprocs-1), (h_0,h_1,...h_NP-1) ) 920*d8588912SDave May proc 0: => (g_0,h_0,) 921*d8588912SDave May proc 1: => (g_1,h_1,) 922*d8588912SDave May ... 923*d8588912SDave May proc nprocs-1: => (g_NP-1,h_NP-1,) 924*d8588912SDave May 925*d8588912SDave May proc 0: proc 1: proc nprocs-1: 926*d8588912SDave May is[0] = ( 0,1,2,...,nlocal(g_0)-1 ) ( 0,1,...,nlocal(g_1)-1 ) ( 0,1,...,nlocal(g_NP-1) ) 927*d8588912SDave May 928*d8588912SDave May proc 0: 929*d8588912SDave May is[1] = ( nlocal(g_0),nlocal(g_0)+1,...,nlocal(g_0)+nlocal(h_0)-1 ) 930*d8588912SDave May proc 1: 931*d8588912SDave May is[1] = ( nlocal(g_1),nlocal(g_1)+1,...,nlocal(g_1)+nlocal(h_1)-1 ) 932*d8588912SDave May 933*d8588912SDave May proc NP-1: 934*d8588912SDave May is[1] = ( nlocal(g_NP-1),nlocal(g_NP-1)+1,...,nlocal(g_NP-1)+nlocal(h_NP-1)-1 ) 935*d8588912SDave May */ 936*d8588912SDave May #undef __FUNCT__ 937*d8588912SDave May #define __FUNCT__ "MatSetUp_NestIS_Private" 938*d8588912SDave May static PetscErrorCode MatSetUp_NestIS_Private(Mat A,PetscInt nr,PetscInt nc,IS is_row[],IS is_col[]) 939*d8588912SDave May { 940*d8588912SDave May Mat_Nest *ctx = (Mat_Nest*)A->data; 941*d8588912SDave May PetscInt i,j,offset,n,start,index; 942*d8588912SDave May PetscErrorCode ierr; 943*d8588912SDave May 944*d8588912SDave May PetscFunctionBegin; 945*d8588912SDave May if (is_row) { /* valid IS is passed in */ 946*d8588912SDave May /* refs on is[] are incremeneted */ 947*d8588912SDave May for (i=0; i<ctx->nr; i++) { 948*d8588912SDave May ierr = PetscObjectReference((PetscObject)is_row[i]);CHKERRQ(ierr); 949*d8588912SDave May ctx->is_row[i] = is_row[i]; 950*d8588912SDave May } 951*d8588912SDave May } else { 952*d8588912SDave May for (j=0; j<ctx->nc; j++) { 953*d8588912SDave May if (ctx->m[0][j]) { index = j; break; } 954*d8588912SDave May } 955*d8588912SDave May ierr = MatGetOwnershipRange(ctx->m[0][index],&start,PETSC_NULL);CHKERRQ(ierr); 956*d8588912SDave May offset = start; 957*d8588912SDave May for (i=0; i<ctx->nr; i++) { 958*d8588912SDave May 959*d8588912SDave May ierr = MatGetLocalSize(ctx->m[i][index],&n,PETSC_NULL);CHKERRQ(ierr); 960*d8588912SDave May ierr = ISCreateStride(((PetscObject)ctx->m[i][index])->comm,n,offset,1,&ctx->is_row[i]);CHKERRQ(ierr); 961*d8588912SDave May offset = offset + n; 962*d8588912SDave May } 963*d8588912SDave May } 964*d8588912SDave May 965*d8588912SDave May if (is_col) { /* valid IS is passed in */ 966*d8588912SDave May /* refs on is[] are incremeneted */ 967*d8588912SDave May for (j=0; j<ctx->nc; j++) { 968*d8588912SDave May ierr = PetscObjectReference((PetscObject)is_col[j]);CHKERRQ(ierr); 969*d8588912SDave May ctx->is_col[j] = is_col[j]; 970*d8588912SDave May } 971*d8588912SDave May } else { 972*d8588912SDave May for (i=0; i<ctx->nr; i++) { 973*d8588912SDave May if (ctx->m[i][0]) { index = i; break; } 974*d8588912SDave May } 975*d8588912SDave May ierr = MatGetOwnershipRange(ctx->m[index][0],&start,PETSC_NULL);CHKERRQ(ierr); 976*d8588912SDave May offset = start; 977*d8588912SDave May for (j=0; j<ctx->nc; j++) { 978*d8588912SDave May for (i=0; i<ctx->nr; i++) { 979*d8588912SDave May if (ctx->m[i][j]) { index = i; break; } 980*d8588912SDave May } 981*d8588912SDave May ierr = MatGetLocalSize(ctx->m[index][j],PETSC_NULL,&n);CHKERRQ(ierr); 982*d8588912SDave May ierr = ISCreateStride(((PetscObject)ctx->m[index][j])->comm,n,offset,1,&ctx->is_col[j]);CHKERRQ(ierr); 983*d8588912SDave May offset = offset + n; 984*d8588912SDave May } 985*d8588912SDave May } 986*d8588912SDave May PetscFunctionReturn(0); 987*d8588912SDave May } 988*d8588912SDave May 989*d8588912SDave May #undef __FUNCT__ 990*d8588912SDave May #define __FUNCT__ "MatCreateNest" 991*d8588912SDave May PetscErrorCode PETSCMAT_DLLEXPORT MatCreateNest(MPI_Comm comm,PetscInt nr,PetscInt nc,IS is_row[],IS is_col[],Mat **a,Mat *B) 992*d8588912SDave May { 993*d8588912SDave May Mat A; 994*d8588912SDave May Mat_Nest *s; 995*d8588912SDave May PetscInt m,n,M,N; 996*d8588912SDave May PetscErrorCode ierr; 997*d8588912SDave May 998*d8588912SDave May PetscFunctionBegin; 999*d8588912SDave May ierr = MatCreate(comm,&A);CHKERRQ(ierr); 1000*d8588912SDave May 1001*d8588912SDave May ierr = PetscMalloc( sizeof(Mat_Nest), &s );CHKERRQ(ierr); 1002*d8588912SDave May ierr = PetscMemzero( s, sizeof(Mat_Nest) );CHKERRQ(ierr); 1003*d8588912SDave May A->data = (void*)s; 1004*d8588912SDave May s->setup_called = PETSC_FALSE; 1005*d8588912SDave May s->nr = s->nc = -1; 1006*d8588912SDave May s->m = PETSC_NULL; 1007*d8588912SDave May 1008*d8588912SDave May /* define the operations */ 1009*d8588912SDave May ierr = MatNestSetOps_Private(A->ops);CHKERRQ(ierr); 1010*d8588912SDave May A->spptr = 0; 1011*d8588912SDave May A->same_nonzero = PETSC_FALSE; 1012*d8588912SDave May A->assembled = PETSC_FALSE; 1013*d8588912SDave May 1014*d8588912SDave May ierr = PetscObjectChangeTypeName((PetscObject) A, MATNEST );CHKERRQ(ierr); 1015*d8588912SDave May ierr = MatSetUp_Nest_Private(A,nr,nc,a);CHKERRQ(ierr); 1016*d8588912SDave May 1017*d8588912SDave May m = n = 0; 1018*d8588912SDave May M = N = 0; 1019*d8588912SDave May ierr = MatNestGetSize_Recursive(A,PETSC_TRUE,&M,&N);CHKERRQ(ierr); 1020*d8588912SDave May ierr = MatNestGetSize_Recursive(A,PETSC_FALSE,&m,&n);CHKERRQ(ierr); 1021*d8588912SDave May 1022*d8588912SDave May ierr = PetscLayoutSetSize(A->rmap,M);CHKERRQ(ierr); 1023*d8588912SDave May ierr = PetscLayoutSetLocalSize(A->rmap,m);CHKERRQ(ierr); 1024*d8588912SDave May ierr = PetscLayoutSetBlockSize(A->rmap,1);CHKERRQ(ierr); 1025*d8588912SDave May ierr = PetscLayoutSetSize(A->cmap,N);CHKERRQ(ierr); 1026*d8588912SDave May ierr = PetscLayoutSetLocalSize(A->cmap,n);CHKERRQ(ierr); 1027*d8588912SDave May ierr = PetscLayoutSetBlockSize(A->cmap,1);CHKERRQ(ierr); 1028*d8588912SDave May 1029*d8588912SDave May ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 1030*d8588912SDave May ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 1031*d8588912SDave May 1032*d8588912SDave May ierr = MatSetUp_NestIS_Private(A,nr,nc,is_row,is_col);CHKERRQ(ierr); 1033*d8588912SDave May 1034*d8588912SDave May /* expose Nest api's */ 1035*d8588912SDave May ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatNestGetSubMat_C","MatNestGetSubMat_Nest",MatNestGetSubMat_Nest);CHKERRQ(ierr); 1036*d8588912SDave May ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatNestGetSubMats_C","MatNestGetSubMats_Nest",MatNestGetSubMats_Nest);CHKERRQ(ierr); 1037*d8588912SDave May ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatNestGetSize_C","MatNestGetSize_Nest",MatNestGetSize_Nest);CHKERRQ(ierr); 1038*d8588912SDave May 1039*d8588912SDave May *B = A; 1040*d8588912SDave May PetscFunctionReturn(0); 1041*d8588912SDave May } 1042*d8588912SDave May 1043