1a7e14dcfSSatish Balay #include "adamat.h" /*I "mat.h" I*/ 2a7e14dcfSSatish Balay 3a7e14dcfSSatish Balay #undef __FUNCT__ 4a7e14dcfSSatish Balay #define __FUNCT__ "MatCreateADA" 5a7e14dcfSSatish Balay /*@C 6a7e14dcfSSatish Balay MatCreateADA - Creates a matrix M=A^T D1 A + D2 where D1, D2 are diagonal 7a7e14dcfSSatish Balay 8a7e14dcfSSatish Balay Collective on matrix 9a7e14dcfSSatish Balay 10a7e14dcfSSatish Balay Input Parameters: 11a7e14dcfSSatish Balay + mat - matrix of arbitrary type 12a7e14dcfSSatish Balay . d1 - A vector with diagonal elements of D1 13a7e14dcfSSatish Balay - d2 - A vector 14a7e14dcfSSatish Balay 15a7e14dcfSSatish Balay Output Parameters: 16a7e14dcfSSatish Balay . J - New matrix whose operations are defined in terms of mat, D1, and D2. 17a7e14dcfSSatish Balay 18a7e14dcfSSatish Balay Notes: 19a7e14dcfSSatish Balay The user provides the input data and is responsible for destroying 20a7e14dcfSSatish Balay this data after matrix J has been destroyed. 21a7e14dcfSSatish Balay The operation MatMult(A,D2,D1) must be well defined. 22a7e14dcfSSatish Balay Before calling the operation MatGetDiagonal(), the function 23a7e14dcfSSatish Balay MatADAComputeDiagonal() must be called. The matrices A and D1 must 24a7e14dcfSSatish Balay be the same during calls to MatADAComputeDiagonal() and 25a7e14dcfSSatish Balay MatGetDiagonal(). 26a7e14dcfSSatish Balay 27a7e14dcfSSatish Balay Level: developer 28a7e14dcfSSatish Balay 29a7e14dcfSSatish Balay .seealso: MatCreate() 30a7e14dcfSSatish Balay @*/ 31a7e14dcfSSatish Balay PetscErrorCode MatCreateADA(Mat mat,Vec d1, Vec d2, Mat *J) 32a7e14dcfSSatish Balay { 33a7e14dcfSSatish Balay MPI_Comm comm=((PetscObject)mat)->comm; 34a7e14dcfSSatish Balay TaoMatADACtx ctx; 35a7e14dcfSSatish Balay PetscErrorCode ierr; 36a7e14dcfSSatish Balay PetscInt nloc,n; 37a7e14dcfSSatish Balay 38a7e14dcfSSatish Balay PetscFunctionBegin; 39a7e14dcfSSatish Balay 403c9e27cfSGeoffrey Irving ierr = PetscNew(&ctx);CHKERRQ(ierr); 41a7e14dcfSSatish Balay 42a7e14dcfSSatish Balay ctx->A=mat; 43a7e14dcfSSatish Balay ctx->D1=d1; 44a7e14dcfSSatish Balay ctx->D2=d2; 45a7e14dcfSSatish Balay if (d1){ 46a7e14dcfSSatish Balay ierr = VecDuplicate(d1,&ctx->W);CHKERRQ(ierr); 47a7e14dcfSSatish Balay ierr = PetscObjectReference((PetscObject)d1);CHKERRQ(ierr); 48a7e14dcfSSatish Balay } else { 49a7e14dcfSSatish Balay ctx->W=0; 50a7e14dcfSSatish Balay } 51a7e14dcfSSatish Balay if (d2){ 52a7e14dcfSSatish Balay ierr = VecDuplicate(d2,&ctx->W2);CHKERRQ(ierr); 53a7e14dcfSSatish Balay ierr = VecDuplicate(d2,&ctx->ADADiag);CHKERRQ(ierr); 54a7e14dcfSSatish Balay ierr = PetscObjectReference((PetscObject)d2);CHKERRQ(ierr); 55a7e14dcfSSatish Balay } else { 56a7e14dcfSSatish Balay ctx->W2=0; 57a7e14dcfSSatish Balay ctx->ADADiag=0; 58a7e14dcfSSatish Balay } 59a7e14dcfSSatish Balay 60a7e14dcfSSatish Balay ctx->GotDiag=0; 61a7e14dcfSSatish Balay ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 62a7e14dcfSSatish Balay 63a7e14dcfSSatish Balay ierr=VecGetLocalSize(d2,&nloc);CHKERRQ(ierr); 64a7e14dcfSSatish Balay ierr=VecGetSize(d2,&n);CHKERRQ(ierr); 65a7e14dcfSSatish Balay 66a7e14dcfSSatish Balay ierr = MatCreateShell(comm,nloc,nloc,n,n,ctx,J);CHKERRQ(ierr); 67a7e14dcfSSatish Balay 68a7e14dcfSSatish Balay ierr = MatShellSetOperation(*J,MATOP_MULT,(void(*)(void))MatMult_ADA);CHKERRQ(ierr); 69a7e14dcfSSatish Balay ierr = MatShellSetOperation(*J,MATOP_DESTROY,(void(*)(void))MatDestroy_ADA);CHKERRQ(ierr); 70a7e14dcfSSatish Balay ierr = MatShellSetOperation(*J,MATOP_VIEW,(void(*)(void))MatView_ADA);CHKERRQ(ierr); 71a7e14dcfSSatish Balay ierr = MatShellSetOperation(*J,MATOP_MULT_TRANSPOSE,(void(*)(void))MatMultTranspose_ADA);CHKERRQ(ierr); 72a7e14dcfSSatish Balay ierr = MatShellSetOperation(*J,MATOP_DIAGONAL_SET,(void(*)(void))MatDiagonalSet_ADA);CHKERRQ(ierr); 73a7e14dcfSSatish Balay ierr = MatShellSetOperation(*J,MATOP_SHIFT,(void(*)(void))MatShift_ADA);CHKERRQ(ierr); 74a7e14dcfSSatish Balay ierr = MatShellSetOperation(*J,MATOP_EQUAL,(void(*)(void))MatEqual_ADA);CHKERRQ(ierr); 75a7e14dcfSSatish Balay ierr = MatShellSetOperation(*J,MATOP_SCALE,(void(*)(void))MatScale_ADA);CHKERRQ(ierr); 76a7e14dcfSSatish Balay ierr = MatShellSetOperation(*J,MATOP_TRANSPOSE,(void(*)(void))MatTranspose_ADA);CHKERRQ(ierr); 77a7e14dcfSSatish Balay ierr = MatShellSetOperation(*J,MATOP_GET_DIAGONAL,(void(*)(void))MatGetDiagonal_ADA);CHKERRQ(ierr); 78a7e14dcfSSatish Balay ierr = MatShellSetOperation(*J,MATOP_GET_SUBMATRICES,(void(*)(void))MatGetSubMatrices_ADA);CHKERRQ(ierr); 79a7e14dcfSSatish Balay ierr = MatShellSetOperation(*J,MATOP_NORM,(void(*)(void))MatNorm_ADA);CHKERRQ(ierr); 80a7e14dcfSSatish Balay ierr = MatShellSetOperation(*J,MATOP_DUPLICATE,(void(*)(void))MatDuplicate_ADA);CHKERRQ(ierr); 81a7e14dcfSSatish Balay ierr = MatShellSetOperation(*J,MATOP_GET_SUBMATRIX,(void(*)(void))MatGetSubMatrix_ADA);CHKERRQ(ierr); 82a7e14dcfSSatish Balay 83a7e14dcfSSatish Balay ierr = PetscLogObjectParent((PetscObject)(*J),(PetscObject)ctx->W); CHKERRQ(ierr); 84a7e14dcfSSatish Balay ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)(*J)); CHKERRQ(ierr); 85a7e14dcfSSatish Balay 86a7e14dcfSSatish Balay ierr = MatSetOption(*J,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 87a7e14dcfSSatish Balay PetscFunctionReturn(0); 88a7e14dcfSSatish Balay } 89a7e14dcfSSatish Balay 90a7e14dcfSSatish Balay #undef __FUNCT__ 91a7e14dcfSSatish Balay #define __FUNCT__ "MatMult_ADA" 92a7e14dcfSSatish Balay PetscErrorCode MatMult_ADA(Mat mat,Vec a,Vec y) 93a7e14dcfSSatish Balay { 94a7e14dcfSSatish Balay TaoMatADACtx ctx; 95a7e14dcfSSatish Balay PetscReal one = 1.0; 96a7e14dcfSSatish Balay PetscErrorCode ierr; 97a7e14dcfSSatish Balay 98a7e14dcfSSatish Balay PetscFunctionBegin; 99a7e14dcfSSatish Balay ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 100a7e14dcfSSatish Balay 101a7e14dcfSSatish Balay ierr = MatMult(ctx->A,a,ctx->W);CHKERRQ(ierr); 102a7e14dcfSSatish Balay if (ctx->D1){ 103a7e14dcfSSatish Balay ierr = VecPointwiseMult(ctx->W,ctx->D1,ctx->W);CHKERRQ(ierr); 104a7e14dcfSSatish Balay } 105a7e14dcfSSatish Balay ierr = MatMultTranspose(ctx->A,ctx->W,y);CHKERRQ(ierr); 106a7e14dcfSSatish Balay if (ctx->D2){ 107a7e14dcfSSatish Balay ierr = VecPointwiseMult(ctx->W2, ctx->D2, a);CHKERRQ(ierr); 108a7e14dcfSSatish Balay ierr = VecAXPY(y, one, ctx->W2);CHKERRQ(ierr); 109a7e14dcfSSatish Balay } 110a7e14dcfSSatish Balay PetscFunctionReturn(0); 111a7e14dcfSSatish Balay } 112a7e14dcfSSatish Balay 113a7e14dcfSSatish Balay #undef __FUNCT__ 114a7e14dcfSSatish Balay #define __FUNCT__ "MatMultTranspose_ADA" 115a7e14dcfSSatish Balay PetscErrorCode MatMultTranspose_ADA(Mat mat,Vec a,Vec y) 116a7e14dcfSSatish Balay { 117a7e14dcfSSatish Balay PetscErrorCode ierr; 118a7e14dcfSSatish Balay 119a7e14dcfSSatish Balay PetscFunctionBegin; 120a7e14dcfSSatish Balay ierr = MatMult_ADA(mat,a,y);CHKERRQ(ierr); 121a7e14dcfSSatish Balay PetscFunctionReturn(0); 122a7e14dcfSSatish Balay } 123a7e14dcfSSatish Balay 124a7e14dcfSSatish Balay #undef __FUNCT__ 125a7e14dcfSSatish Balay #define __FUNCT__ "MatDiagonalSet_ADA" 126a7e14dcfSSatish Balay PetscErrorCode MatDiagonalSet_ADA(Vec D, Mat M) 127a7e14dcfSSatish Balay { 128a7e14dcfSSatish Balay TaoMatADACtx ctx; 129a7e14dcfSSatish Balay PetscReal zero=0.0,one = 1.0; 130a7e14dcfSSatish Balay PetscErrorCode ierr; 131a7e14dcfSSatish Balay 132a7e14dcfSSatish Balay PetscFunctionBegin; 133a7e14dcfSSatish Balay ierr = MatShellGetContext(M,(void **)&ctx);CHKERRQ(ierr); 134a7e14dcfSSatish Balay 1356c23d075SBarry Smith if (ctx->D2==NULL){ 136a7e14dcfSSatish Balay ierr = VecDuplicate(D,&ctx->D2);CHKERRQ(ierr); 137a7e14dcfSSatish Balay ierr = VecSet(ctx->D2, zero);CHKERRQ(ierr); 138a7e14dcfSSatish Balay } 139a7e14dcfSSatish Balay ierr = VecAXPY(ctx->D2, one, D);CHKERRQ(ierr); 140a7e14dcfSSatish Balay 141a7e14dcfSSatish Balay PetscFunctionReturn(0); 142a7e14dcfSSatish Balay } 143a7e14dcfSSatish Balay 144a7e14dcfSSatish Balay #undef __FUNCT__ 145a7e14dcfSSatish Balay #define __FUNCT__ "MatDestroy_ADA" 146a7e14dcfSSatish Balay PetscErrorCode MatDestroy_ADA(Mat mat) 147a7e14dcfSSatish Balay { 148a7e14dcfSSatish Balay PetscErrorCode ierr; 149a7e14dcfSSatish Balay TaoMatADACtx ctx; 150a7e14dcfSSatish Balay 151a7e14dcfSSatish Balay PetscFunctionBegin; 152a7e14dcfSSatish Balay ierr=MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 153a7e14dcfSSatish Balay if (ctx->W) { 154a7e14dcfSSatish Balay ierr=VecDestroy(&ctx->W);CHKERRQ(ierr); 155a7e14dcfSSatish Balay } 156a7e14dcfSSatish Balay if (ctx->W2) { 157a7e14dcfSSatish Balay ierr=VecDestroy(&ctx->W2);CHKERRQ(ierr); 158a7e14dcfSSatish Balay } 159a7e14dcfSSatish Balay if (ctx->ADADiag) { 160a7e14dcfSSatish Balay ierr=VecDestroy(&ctx->ADADiag);CHKERRQ(ierr); 161a7e14dcfSSatish Balay } 162a7e14dcfSSatish Balay if (ctx->A) { 163a7e14dcfSSatish Balay ierr=MatDestroy(&ctx->A);CHKERRQ(ierr); 164a7e14dcfSSatish Balay } 165a7e14dcfSSatish Balay if (ctx->D1) { 166a7e14dcfSSatish Balay ierr=VecDestroy(&ctx->D1);CHKERRQ(ierr); 167a7e14dcfSSatish Balay } 168a7e14dcfSSatish Balay if (ctx->D2) { 169a7e14dcfSSatish Balay ierr=VecDestroy(&ctx->D2);CHKERRQ(ierr); 170a7e14dcfSSatish Balay } 171a7e14dcfSSatish Balay ierr = PetscFree(ctx); CHKERRQ(ierr); 172a7e14dcfSSatish Balay PetscFunctionReturn(0); 173a7e14dcfSSatish Balay } 174a7e14dcfSSatish Balay 175a7e14dcfSSatish Balay #undef __FUNCT__ 176a7e14dcfSSatish Balay #define __FUNCT__ "MatView_ADA" 177a7e14dcfSSatish Balay PetscErrorCode MatView_ADA(Mat mat,PetscViewer viewer) 178a7e14dcfSSatish Balay { 179a7e14dcfSSatish Balay 180a7e14dcfSSatish Balay PetscFunctionBegin; 181a7e14dcfSSatish Balay PetscFunctionReturn(0); 182a7e14dcfSSatish Balay } 183a7e14dcfSSatish Balay 184a7e14dcfSSatish Balay #undef __FUNCT__ 185a7e14dcfSSatish Balay #define __FUNCT__ "MatShift_ADA" 186a7e14dcfSSatish Balay PetscErrorCode MatShift_ADA(Mat Y, PetscReal a) 187a7e14dcfSSatish Balay { 188a7e14dcfSSatish Balay PetscErrorCode ierr; 189a7e14dcfSSatish Balay TaoMatADACtx ctx; 190a7e14dcfSSatish Balay 191a7e14dcfSSatish Balay PetscFunctionBegin; 192a7e14dcfSSatish Balay ierr = MatShellGetContext(Y,(void **)&ctx);CHKERRQ(ierr); 193a7e14dcfSSatish Balay ierr = VecShift(ctx->D2,a);CHKERRQ(ierr); 194a7e14dcfSSatish Balay PetscFunctionReturn(0); 195a7e14dcfSSatish Balay } 196a7e14dcfSSatish Balay 197a7e14dcfSSatish Balay #undef __FUNCT__ 198a7e14dcfSSatish Balay #define __FUNCT__ "MatDuplicate_ADA" 199a7e14dcfSSatish Balay PetscErrorCode MatDuplicate_ADA(Mat mat,MatDuplicateOption op,Mat *M) 200a7e14dcfSSatish Balay { 201a7e14dcfSSatish Balay PetscErrorCode ierr; 202a7e14dcfSSatish Balay TaoMatADACtx ctx; 203a7e14dcfSSatish Balay Mat A2; 204a7e14dcfSSatish Balay Vec D1b=NULL,D2b; 205a7e14dcfSSatish Balay 206a7e14dcfSSatish Balay PetscFunctionBegin; 207a7e14dcfSSatish Balay ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 208a7e14dcfSSatish Balay ierr = MatDuplicate(ctx->A,op,&A2);CHKERRQ(ierr); 209a7e14dcfSSatish Balay if (ctx->D1){ 210a7e14dcfSSatish Balay ierr = VecDuplicate(ctx->D1,&D1b);CHKERRQ(ierr); 211a7e14dcfSSatish Balay ierr = VecCopy(ctx->D1,D1b);CHKERRQ(ierr); 212a7e14dcfSSatish Balay } 213a7e14dcfSSatish Balay ierr = VecDuplicate(ctx->D2,&D2b);CHKERRQ(ierr); 214a7e14dcfSSatish Balay ierr = VecCopy(ctx->D2,D2b);CHKERRQ(ierr); 215a7e14dcfSSatish Balay ierr = MatCreateADA(A2,D1b,D2b,M);CHKERRQ(ierr); 216a7e14dcfSSatish Balay if (ctx->D1){ 217a7e14dcfSSatish Balay ierr = PetscObjectDereference((PetscObject)D1b);CHKERRQ(ierr); 218a7e14dcfSSatish Balay } 219a7e14dcfSSatish Balay ierr = PetscObjectDereference((PetscObject)D2b);CHKERRQ(ierr); 220a7e14dcfSSatish Balay ierr = PetscObjectDereference((PetscObject)A2);CHKERRQ(ierr); 221a7e14dcfSSatish Balay 222a7e14dcfSSatish Balay PetscFunctionReturn(0); 223a7e14dcfSSatish Balay } 224a7e14dcfSSatish Balay 225a7e14dcfSSatish Balay #undef __FUNCT__ 226a7e14dcfSSatish Balay #define __FUNCT__ "MatEqual_ADA" 227a7e14dcfSSatish Balay PetscErrorCode MatEqual_ADA(Mat A,Mat B,PetscBool *flg) 228a7e14dcfSSatish Balay { 229a7e14dcfSSatish Balay PetscErrorCode ierr; 230a7e14dcfSSatish Balay TaoMatADACtx ctx1,ctx2; 231a7e14dcfSSatish Balay 232a7e14dcfSSatish Balay PetscFunctionBegin; 233a7e14dcfSSatish Balay ierr = MatShellGetContext(A,(void **)&ctx1);CHKERRQ(ierr); 234a7e14dcfSSatish Balay ierr = MatShellGetContext(B,(void **)&ctx2);CHKERRQ(ierr); 235a7e14dcfSSatish Balay ierr = VecEqual(ctx1->D2,ctx2->D2,flg);CHKERRQ(ierr); 236a7e14dcfSSatish Balay if (*flg==PETSC_TRUE){ 237a7e14dcfSSatish Balay ierr = VecEqual(ctx1->D1,ctx2->D1,flg);CHKERRQ(ierr); 238a7e14dcfSSatish Balay } 239a7e14dcfSSatish Balay if (*flg==PETSC_TRUE){ 240a7e14dcfSSatish Balay ierr = MatEqual(ctx1->A,ctx2->A,flg);CHKERRQ(ierr); 241a7e14dcfSSatish Balay } 242a7e14dcfSSatish Balay PetscFunctionReturn(0); 243a7e14dcfSSatish Balay } 244a7e14dcfSSatish Balay 245a7e14dcfSSatish Balay #undef __FUNCT__ 246a7e14dcfSSatish Balay #define __FUNCT__ "MatScale_ADA" 247a7e14dcfSSatish Balay PetscErrorCode MatScale_ADA(Mat mat, PetscReal a) 248a7e14dcfSSatish Balay { 249a7e14dcfSSatish Balay PetscErrorCode ierr; 250a7e14dcfSSatish Balay TaoMatADACtx ctx; 251a7e14dcfSSatish Balay 252a7e14dcfSSatish Balay PetscFunctionBegin; 253a7e14dcfSSatish Balay ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 254a7e14dcfSSatish Balay ierr = VecScale(ctx->D1,a);CHKERRQ(ierr); 255a7e14dcfSSatish Balay if (ctx->D2){ 256a7e14dcfSSatish Balay ierr = VecScale(ctx->D2,a);CHKERRQ(ierr); 257a7e14dcfSSatish Balay } 258a7e14dcfSSatish Balay PetscFunctionReturn(0); 259a7e14dcfSSatish Balay } 260a7e14dcfSSatish Balay 261a7e14dcfSSatish Balay #undef __FUNCT__ 262a7e14dcfSSatish Balay #define __FUNCT__ "MatTranspose_ADA" 263a7e14dcfSSatish Balay PetscErrorCode MatTranspose_ADA(Mat mat,Mat *B) 264a7e14dcfSSatish Balay { 265a7e14dcfSSatish Balay PetscErrorCode ierr; 266a7e14dcfSSatish Balay TaoMatADACtx ctx; 267a7e14dcfSSatish Balay 268a7e14dcfSSatish Balay PetscFunctionBegin; 269a7e14dcfSSatish Balay if (*B){ 270a7e14dcfSSatish Balay ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 271a7e14dcfSSatish Balay ierr = MatDuplicate(mat,MAT_COPY_VALUES,B);CHKERRQ(ierr); 272a7e14dcfSSatish Balay } 273a7e14dcfSSatish Balay PetscFunctionReturn(0); 274a7e14dcfSSatish Balay } 275a7e14dcfSSatish Balay 276a7e14dcfSSatish Balay #undef __FUNCT__ 277a7e14dcfSSatish Balay #define __FUNCT__ "MatADAComputeDiagonal" 278a7e14dcfSSatish Balay PetscErrorCode MatADAComputeDiagonal(Mat mat) 279a7e14dcfSSatish Balay { 280a7e14dcfSSatish Balay PetscErrorCode ierr; 281a7e14dcfSSatish Balay PetscInt i,m,n,low,high; 282a7e14dcfSSatish Balay PetscReal *dtemp,*dptr; 283a7e14dcfSSatish Balay TaoMatADACtx ctx; 284a7e14dcfSSatish Balay 285a7e14dcfSSatish Balay PetscFunctionBegin; 286a7e14dcfSSatish Balay ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 287a7e14dcfSSatish Balay 288a7e14dcfSSatish Balay ierr = MatGetOwnershipRange(mat, &low, &high);CHKERRQ(ierr); 289a7e14dcfSSatish Balay ierr = MatGetSize(mat,&m,&n);CHKERRQ(ierr); 290a7e14dcfSSatish Balay 291a7e14dcfSSatish Balay ierr = PetscMalloc( n*sizeof(PetscReal),&dtemp ); CHKERRQ(ierr); 292a7e14dcfSSatish Balay 293a7e14dcfSSatish Balay for (i=0; i<n; i++){ 294a7e14dcfSSatish Balay ierr = MatGetColumnVector(ctx->A, ctx->W, i);CHKERRQ(ierr); 295a7e14dcfSSatish Balay ierr = VecPointwiseMult(ctx->W,ctx->W,ctx->W);CHKERRQ(ierr); 296a7e14dcfSSatish Balay ierr = VecDotBegin(ctx->D1, ctx->W,dtemp+i);CHKERRQ(ierr); 297a7e14dcfSSatish Balay } 298a7e14dcfSSatish Balay for (i=0; i<n; i++){ 299a7e14dcfSSatish Balay ierr = VecDotEnd(ctx->D1, ctx->W,dtemp+i);CHKERRQ(ierr); 300a7e14dcfSSatish Balay } 301a7e14dcfSSatish Balay 302a7e14dcfSSatish Balay ierr = VecGetArray(ctx->ADADiag,&dptr);CHKERRQ(ierr); 303a7e14dcfSSatish Balay for (i=low; i<high; i++){ 304a7e14dcfSSatish Balay dptr[i-low]= dtemp[i]; 305a7e14dcfSSatish Balay } 306a7e14dcfSSatish Balay ierr = VecRestoreArray(ctx->ADADiag,&dptr);CHKERRQ(ierr); 307a7e14dcfSSatish Balay if (dtemp) { 308a7e14dcfSSatish Balay ierr = PetscFree(dtemp); CHKERRQ(ierr); 309a7e14dcfSSatish Balay } 310a7e14dcfSSatish Balay PetscFunctionReturn(0); 311a7e14dcfSSatish Balay } 312a7e14dcfSSatish Balay 313a7e14dcfSSatish Balay #undef __FUNCT__ 314a7e14dcfSSatish Balay #define __FUNCT__ "MatGetDiagonal_ADA" 315a7e14dcfSSatish Balay PetscErrorCode MatGetDiagonal_ADA(Mat mat,Vec v) 316a7e14dcfSSatish Balay { 317a7e14dcfSSatish Balay PetscErrorCode ierr; 318a7e14dcfSSatish Balay PetscReal one=1.0; 319a7e14dcfSSatish Balay TaoMatADACtx ctx; 320a7e14dcfSSatish Balay 321a7e14dcfSSatish Balay PetscFunctionBegin; 322a7e14dcfSSatish Balay ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 323a7e14dcfSSatish Balay ierr = MatADAComputeDiagonal(mat); CHKERRQ(ierr); 324a7e14dcfSSatish Balay ierr=VecCopy(ctx->ADADiag,v);CHKERRQ(ierr); 325a7e14dcfSSatish Balay if (ctx->D2){ 326a7e14dcfSSatish Balay ierr=VecAXPY(v, one, ctx->D2);CHKERRQ(ierr); 327a7e14dcfSSatish Balay } 328a7e14dcfSSatish Balay 329a7e14dcfSSatish Balay PetscFunctionReturn(0); 330a7e14dcfSSatish Balay } 331a7e14dcfSSatish Balay 332a7e14dcfSSatish Balay #undef __FUNCT__ 333a7e14dcfSSatish Balay #define __FUNCT__ "MatGetSubMatrices_ADA" 334a7e14dcfSSatish Balay PetscErrorCode MatGetSubMatrices_ADA(Mat A,PetscInt n, IS *irow,IS *icol,MatReuse scall,Mat **B) 335a7e14dcfSSatish Balay { 336a7e14dcfSSatish Balay PetscErrorCode ierr; 337a7e14dcfSSatish Balay PetscInt i; 338a7e14dcfSSatish Balay 339a7e14dcfSSatish Balay PetscFunctionBegin; 340a7e14dcfSSatish Balay if (scall == MAT_INITIAL_MATRIX) { 341a7e14dcfSSatish Balay ierr = PetscMalloc( (n+1)*sizeof(Mat),B );CHKERRQ(ierr); 342a7e14dcfSSatish Balay } 343a7e14dcfSSatish Balay 344a7e14dcfSSatish Balay for ( i=0; i<n; i++ ) { 345a7e14dcfSSatish Balay ierr = MatGetSubMatrix_ADA(A,irow[i],icol[i],scall,&(*B)[i]);CHKERRQ(ierr); 346a7e14dcfSSatish Balay } 347a7e14dcfSSatish Balay PetscFunctionReturn(0); 348a7e14dcfSSatish Balay } 349a7e14dcfSSatish Balay 350a7e14dcfSSatish Balay #undef __FUNCT__ 351a7e14dcfSSatish Balay #define __FUNCT__ "MatGetSubMatrix_ADA" 352a7e14dcfSSatish Balay PetscErrorCode MatGetSubMatrix_ADA(Mat mat,IS isrow,IS iscol,MatReuse cll, 353a7e14dcfSSatish Balay Mat *newmat) 354a7e14dcfSSatish Balay { 355a7e14dcfSSatish Balay PetscErrorCode ierr; 356a7e14dcfSSatish Balay PetscInt low,high; 357a7e14dcfSSatish Balay PetscInt n,nlocal,i; 358a7e14dcfSSatish Balay const PetscInt *iptr; 359a7e14dcfSSatish Balay PetscReal *dptr,*ddptr,zero=0.0; 360a7e14dcfSSatish Balay VecType type_name; 361a7e14dcfSSatish Balay IS ISrow; 362a7e14dcfSSatish Balay Vec D1,D2; 363a7e14dcfSSatish Balay Mat Atemp; 364a7e14dcfSSatish Balay TaoMatADACtx ctx; 365a7e14dcfSSatish Balay 366a7e14dcfSSatish Balay PetscFunctionBegin; 367a7e14dcfSSatish Balay 368a7e14dcfSSatish Balay ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 369a7e14dcfSSatish Balay 370a7e14dcfSSatish Balay ierr = MatGetOwnershipRange(ctx->A,&low,&high);CHKERRQ(ierr); 371a7e14dcfSSatish Balay ierr = ISCreateStride(((PetscObject)mat)->comm,high-low,low,1,&ISrow);CHKERRQ(ierr); 372a7e14dcfSSatish Balay ierr = MatGetSubMatrix(ctx->A,ISrow,iscol,cll,&Atemp);CHKERRQ(ierr); 373a7e14dcfSSatish Balay ierr = ISDestroy(&ISrow);CHKERRQ(ierr); 374a7e14dcfSSatish Balay 375a7e14dcfSSatish Balay if (ctx->D1){ 376a7e14dcfSSatish Balay ierr=VecDuplicate(ctx->D1,&D1);CHKERRQ(ierr); 377a7e14dcfSSatish Balay ierr=VecCopy(ctx->D1,D1);CHKERRQ(ierr); 378a7e14dcfSSatish Balay } else { 3796c23d075SBarry Smith D1=NULL; 380a7e14dcfSSatish Balay } 381a7e14dcfSSatish Balay 382a7e14dcfSSatish Balay if (ctx->D2){ 383a7e14dcfSSatish Balay ierr=ISGetSize(isrow,&n);CHKERRQ(ierr); 384a7e14dcfSSatish Balay ierr=ISGetLocalSize(isrow,&nlocal);CHKERRQ(ierr); 385a7e14dcfSSatish Balay ierr=VecCreate(((PetscObject)(ctx->D2))->comm,&D2);CHKERRQ(ierr); 386a7e14dcfSSatish Balay ierr=VecGetType(ctx->D2,&type_name);CHKERRQ(ierr); 387a7e14dcfSSatish Balay ierr=VecSetSizes(D2,nlocal,n);CHKERRQ(ierr); 388a7e14dcfSSatish Balay ierr=VecSetType(D2,type_name);CHKERRQ(ierr); 389a7e14dcfSSatish Balay ierr=VecSet(D2, zero);CHKERRQ(ierr); 390a7e14dcfSSatish Balay ierr=VecGetArray(ctx->D2, &dptr); CHKERRQ(ierr); 391a7e14dcfSSatish Balay ierr=VecGetArray(D2, &ddptr); CHKERRQ(ierr); 392a7e14dcfSSatish Balay ierr=ISGetIndices(isrow,&iptr); CHKERRQ(ierr); 393a7e14dcfSSatish Balay for (i=0;i<nlocal;i++){ 394a7e14dcfSSatish Balay ddptr[i] = dptr[iptr[i]-low]; 395a7e14dcfSSatish Balay } 396a7e14dcfSSatish Balay ierr=ISRestoreIndices(isrow,&iptr); CHKERRQ(ierr); 397a7e14dcfSSatish Balay ierr=VecRestoreArray(D2, &ddptr); CHKERRQ(ierr); 398a7e14dcfSSatish Balay ierr=VecRestoreArray(ctx->D2, &dptr); CHKERRQ(ierr); 399a7e14dcfSSatish Balay 400a7e14dcfSSatish Balay } else { 4016c23d075SBarry Smith D2=NULL; 402a7e14dcfSSatish Balay } 403a7e14dcfSSatish Balay 404a7e14dcfSSatish Balay ierr = MatCreateADA(Atemp,D1,D2,newmat);CHKERRQ(ierr); 405a7e14dcfSSatish Balay ierr = MatShellGetContext(*newmat,(void **)&ctx);CHKERRQ(ierr); 406a7e14dcfSSatish Balay ierr = PetscObjectDereference((PetscObject)Atemp);CHKERRQ(ierr); 407a7e14dcfSSatish Balay if (ctx->D1){ 408a7e14dcfSSatish Balay ierr = PetscObjectDereference((PetscObject)D1);CHKERRQ(ierr); 409a7e14dcfSSatish Balay } 410a7e14dcfSSatish Balay if (ctx->D2){ 411a7e14dcfSSatish Balay ierr = PetscObjectDereference((PetscObject)D2);CHKERRQ(ierr); 412a7e14dcfSSatish Balay } 413a7e14dcfSSatish Balay PetscFunctionReturn(0); 414a7e14dcfSSatish Balay } 415a7e14dcfSSatish Balay 416a7e14dcfSSatish Balay #undef __FUNCT__ 417a7e14dcfSSatish Balay #define __FUNCT__ "MatGetRowADA" 418a7e14dcfSSatish Balay PetscErrorCode MatGetRowADA(Mat mat,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscReal **vals) 419a7e14dcfSSatish Balay { 420a7e14dcfSSatish Balay PetscErrorCode ierr; 421a7e14dcfSSatish Balay PetscInt m,n; 422a7e14dcfSSatish Balay 423a7e14dcfSSatish Balay PetscFunctionBegin; 424a7e14dcfSSatish Balay ierr = MatGetSize(mat,&m,&n);CHKERRQ(ierr); 425a7e14dcfSSatish Balay 426a7e14dcfSSatish Balay if (*ncols>0){ 427a7e14dcfSSatish Balay ierr = PetscMalloc( (*ncols)*sizeof(PetscInt),cols );CHKERRQ(ierr); 428a7e14dcfSSatish Balay ierr = PetscMalloc( (*ncols)*sizeof(PetscReal),vals );CHKERRQ(ierr); 429a7e14dcfSSatish Balay } else { 4306c23d075SBarry Smith *cols=NULL; 4316c23d075SBarry Smith *vals=NULL; 432a7e14dcfSSatish Balay } 433a7e14dcfSSatish Balay 434a7e14dcfSSatish Balay PetscFunctionReturn(0); 435a7e14dcfSSatish Balay } 436a7e14dcfSSatish Balay 437a7e14dcfSSatish Balay #undef __FUNCT__ 438a7e14dcfSSatish Balay #define __FUNCT__ "MatRestoreRowADA" 439a7e14dcfSSatish Balay PetscErrorCode MatRestoreRowADA(Mat mat,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscReal **vals) 440a7e14dcfSSatish Balay { 441a7e14dcfSSatish Balay PetscErrorCode ierr; 442a7e14dcfSSatish Balay PetscFunctionBegin; 443a7e14dcfSSatish Balay if (*ncols>0){ 444a7e14dcfSSatish Balay ierr = PetscFree(*cols); CHKERRQ(ierr); 445a7e14dcfSSatish Balay ierr = PetscFree(*vals); CHKERRQ(ierr); 446a7e14dcfSSatish Balay } 4476c23d075SBarry Smith *cols=NULL; 4486c23d075SBarry Smith *vals=NULL; 449a7e14dcfSSatish Balay PetscFunctionReturn(0); 450a7e14dcfSSatish Balay } 451a7e14dcfSSatish Balay 452a7e14dcfSSatish Balay #undef __FUNCT__ 453a7e14dcfSSatish Balay #define __FUNCT__ "MatGetColumnVectorADA" 454a7e14dcfSSatish Balay PetscErrorCode MatGetColumnVector_ADA(Mat mat,Vec Y, PetscInt col) 455a7e14dcfSSatish Balay { 456a7e14dcfSSatish Balay PetscErrorCode ierr; 457a7e14dcfSSatish Balay PetscInt low,high; 458a7e14dcfSSatish Balay PetscReal zero=0.0,one=1.0; 459a7e14dcfSSatish Balay 460a7e14dcfSSatish Balay PetscFunctionBegin; 461a7e14dcfSSatish Balay ierr=VecSet(Y, zero);CHKERRQ(ierr); 462a7e14dcfSSatish Balay ierr=VecGetOwnershipRange(Y,&low,&high);CHKERRQ(ierr); 463a7e14dcfSSatish Balay if (col>=low && col<high){ 464a7e14dcfSSatish Balay ierr=VecSetValue(Y,col,one,INSERT_VALUES);CHKERRQ(ierr); 465a7e14dcfSSatish Balay } 466a7e14dcfSSatish Balay ierr=VecAssemblyBegin(Y);CHKERRQ(ierr); 467a7e14dcfSSatish Balay ierr=VecAssemblyEnd(Y);CHKERRQ(ierr); 468a7e14dcfSSatish Balay ierr=MatMult_ADA(mat,Y,Y);CHKERRQ(ierr); 469a7e14dcfSSatish Balay 470a7e14dcfSSatish Balay PetscFunctionReturn(0); 471a7e14dcfSSatish Balay } 472a7e14dcfSSatish Balay 473a7e14dcfSSatish Balay PetscErrorCode MatConvert_ADA(Mat mat,MatType newtype,Mat *NewMat) 474a7e14dcfSSatish Balay { 475a7e14dcfSSatish Balay PetscErrorCode ierr; 476a7e14dcfSSatish Balay PetscMPIInt size; 477a7e14dcfSSatish Balay PetscBool sametype, issame, isdense, isseqdense; 478a7e14dcfSSatish Balay TaoMatADACtx ctx; 479a7e14dcfSSatish Balay 480a7e14dcfSSatish Balay PetscFunctionBegin; 481a7e14dcfSSatish Balay ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 482*87f595a5SBarry Smith ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr); 483a7e14dcfSSatish Balay 484a7e14dcfSSatish Balay ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr); 485a7e14dcfSSatish Balay ierr = PetscObjectTypeCompare((PetscObject)mat,MATSAME,&issame); CHKERRQ(ierr); 486a7e14dcfSSatish Balay ierr = PetscObjectTypeCompare((PetscObject)mat,MATMPIDENSE,&isdense); CHKERRQ(ierr); 487a7e14dcfSSatish Balay ierr = PetscObjectTypeCompare((PetscObject)mat,MATSEQDENSE,&isseqdense); CHKERRQ(ierr); 488a7e14dcfSSatish Balay 489a7e14dcfSSatish Balay if (sametype || issame) { 490a7e14dcfSSatish Balay ierr=MatDuplicate(mat,MAT_COPY_VALUES,NewMat);CHKERRQ(ierr); 491a7e14dcfSSatish Balay } else if (isdense) { 492a7e14dcfSSatish Balay PetscInt i,j,low,high,m,n,M,N; 493a7e14dcfSSatish Balay PetscReal *dptr; 494a7e14dcfSSatish Balay Vec X; 495a7e14dcfSSatish Balay 496a7e14dcfSSatish Balay ierr = VecDuplicate(ctx->D2,&X);CHKERRQ(ierr); 497a7e14dcfSSatish Balay ierr=MatGetSize(mat,&M,&N);CHKERRQ(ierr); 498a7e14dcfSSatish Balay ierr=MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 499*87f595a5SBarry Smith ierr = MatCreateDense(((PetscObject)mat)->comm,m,m,N,N,NULL,NewMat);CHKERRQ(ierr); 500a7e14dcfSSatish Balay ierr = MatGetOwnershipRange(*NewMat,&low,&high);CHKERRQ(ierr); 501a7e14dcfSSatish Balay for (i=0;i<M;i++){ 502a7e14dcfSSatish Balay ierr = MatGetColumnVector_ADA(mat,X,i);CHKERRQ(ierr); 503a7e14dcfSSatish Balay ierr = VecGetArray(X,&dptr);CHKERRQ(ierr); 504a7e14dcfSSatish Balay for (j=0; j<high-low; j++){ 505a7e14dcfSSatish Balay ierr = MatSetValue(*NewMat,low+j,i,dptr[j],INSERT_VALUES);CHKERRQ(ierr); 506a7e14dcfSSatish Balay } 507a7e14dcfSSatish Balay ierr=VecRestoreArray(X,&dptr);CHKERRQ(ierr); 508a7e14dcfSSatish Balay } 509a7e14dcfSSatish Balay ierr=MatAssemblyBegin(*NewMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 510a7e14dcfSSatish Balay ierr=MatAssemblyEnd(*NewMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 511a7e14dcfSSatish Balay ierr = VecDestroy(&X);CHKERRQ(ierr); 512a7e14dcfSSatish Balay } else if (isseqdense && size==1){ 513a7e14dcfSSatish Balay PetscInt i,j,low,high,m,n,M,N; 514a7e14dcfSSatish Balay PetscReal *dptr; 515a7e14dcfSSatish Balay Vec X; 516a7e14dcfSSatish Balay 517a7e14dcfSSatish Balay ierr = VecDuplicate(ctx->D2,&X);CHKERRQ(ierr); 518a7e14dcfSSatish Balay ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 519a7e14dcfSSatish Balay ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); 520*87f595a5SBarry Smith ierr = MatCreateSeqDense(((PetscObject)mat)->comm,N,N,NULL,NewMat); CHKERRQ(ierr); 521a7e14dcfSSatish Balay ierr = MatGetOwnershipRange(*NewMat,&low,&high);CHKERRQ(ierr); 522a7e14dcfSSatish Balay for (i=0;i<M;i++){ 523a7e14dcfSSatish Balay ierr = MatGetColumnVector_ADA(mat,X,i);CHKERRQ(ierr); 524a7e14dcfSSatish Balay ierr = VecGetArray(X,&dptr);CHKERRQ(ierr); 525a7e14dcfSSatish Balay for (j=0; j<high-low; j++){ 526a7e14dcfSSatish Balay ierr = MatSetValue(*NewMat,low+j,i,dptr[j],INSERT_VALUES);CHKERRQ(ierr); 527a7e14dcfSSatish Balay } 528a7e14dcfSSatish Balay ierr=VecRestoreArray(X,&dptr);CHKERRQ(ierr); 529a7e14dcfSSatish Balay } 530a7e14dcfSSatish Balay ierr=MatAssemblyBegin(*NewMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 531a7e14dcfSSatish Balay ierr=MatAssemblyEnd(*NewMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 532a7e14dcfSSatish Balay ierr=VecDestroy(&X);CHKERRQ(ierr); 533*87f595a5SBarry Smith } else SETERRQ(PETSC_COMM_SELF,1,"No support to convert objects to that type"); 534a7e14dcfSSatish Balay PetscFunctionReturn(0); 535a7e14dcfSSatish Balay } 536a7e14dcfSSatish Balay 537a7e14dcfSSatish Balay #undef __FUNCT__ 538a7e14dcfSSatish Balay #define __FUNCT__ "MatNorm_ADA" 539a7e14dcfSSatish Balay PetscErrorCode MatNorm_ADA(Mat mat,NormType type,PetscReal *norm) 540a7e14dcfSSatish Balay { 541a7e14dcfSSatish Balay PetscErrorCode ierr; 542a7e14dcfSSatish Balay TaoMatADACtx ctx; 543a7e14dcfSSatish Balay 544a7e14dcfSSatish Balay PetscFunctionBegin; 545a7e14dcfSSatish Balay ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr); 546a7e14dcfSSatish Balay if (type == NORM_FROBENIUS) { 547a7e14dcfSSatish Balay *norm = 1.0; 548a7e14dcfSSatish Balay } else if (type == NORM_1 || type == NORM_INFINITY) { 549a7e14dcfSSatish Balay *norm = 1.0; 550*87f595a5SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm"); 551a7e14dcfSSatish Balay PetscFunctionReturn(0); 552a7e14dcfSSatish Balay } 553