1367daffbSBarry Smith #include <petscmat.h> /*I "mat.h" I*/ 2e0877f53SBarry Smith 30ebee16dSLisandro Dalcin PETSC_INTERN PetscErrorCode MatCreateADA(Mat,Vec, Vec, Mat*); 40ebee16dSLisandro Dalcin 5e0877f53SBarry Smith typedef struct { 6e0877f53SBarry Smith Mat A; 7e0877f53SBarry Smith Vec D1; 8e0877f53SBarry Smith Vec D2; 9e0877f53SBarry Smith Vec W; 10e0877f53SBarry Smith Vec W2; 11e0877f53SBarry Smith Vec ADADiag; 12e0877f53SBarry Smith PetscInt GotDiag; 13e0877f53SBarry Smith } _p_TaoMatADACtx; 14e0877f53SBarry Smith typedef _p_TaoMatADACtx* TaoMatADACtx; 15e0877f53SBarry Smith 16e0877f53SBarry Smith static PetscErrorCode MatMult_ADA(Mat mat,Vec a,Vec y) 17e0877f53SBarry Smith { 18e0877f53SBarry Smith TaoMatADACtx ctx; 19e0877f53SBarry Smith PetscReal one = 1.0; 20e0877f53SBarry Smith 21e0877f53SBarry Smith PetscFunctionBegin; 229566063dSJacob Faibussowitsch PetscCall(MatShellGetContext(mat,&ctx)); 239566063dSJacob Faibussowitsch PetscCall(MatMult(ctx->A,a,ctx->W)); 24e0877f53SBarry Smith if (ctx->D1) { 259566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(ctx->W,ctx->D1,ctx->W)); 26e0877f53SBarry Smith } 279566063dSJacob Faibussowitsch PetscCall(MatMultTranspose(ctx->A,ctx->W,y)); 28e0877f53SBarry Smith if (ctx->D2) { 299566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(ctx->W2, ctx->D2, a)); 309566063dSJacob Faibussowitsch PetscCall(VecAXPY(y, one, ctx->W2)); 31e0877f53SBarry Smith } 32e0877f53SBarry Smith PetscFunctionReturn(0); 33e0877f53SBarry Smith } 34e0877f53SBarry Smith 35e0877f53SBarry Smith static PetscErrorCode MatMultTranspose_ADA(Mat mat,Vec a,Vec y) 36e0877f53SBarry Smith { 37e0877f53SBarry Smith PetscFunctionBegin; 389566063dSJacob Faibussowitsch PetscCall(MatMult_ADA(mat,a,y)); 39e0877f53SBarry Smith PetscFunctionReturn(0); 40e0877f53SBarry Smith } 41e0877f53SBarry Smith 420c0fd78eSBarry Smith static PetscErrorCode MatDiagonalSet_ADA(Mat M,Vec D, InsertMode mode) 43e0877f53SBarry Smith { 44e0877f53SBarry Smith TaoMatADACtx ctx; 45e0877f53SBarry Smith PetscReal zero=0.0,one = 1.0; 46e0877f53SBarry Smith 47e0877f53SBarry Smith PetscFunctionBegin; 483c859ba3SBarry Smith PetscCheck(mode != INSERT_VALUES,PetscObjectComm((PetscObject)M),PETSC_ERR_SUP,"Cannot insert diagonal entries of this matrix type, can only add"); 499566063dSJacob Faibussowitsch PetscCall(MatShellGetContext(M,&ctx)); 50e0877f53SBarry Smith if (!ctx->D2) { 519566063dSJacob Faibussowitsch PetscCall(VecDuplicate(D,&ctx->D2)); 529566063dSJacob Faibussowitsch PetscCall(VecSet(ctx->D2, zero)); 53e0877f53SBarry Smith } 549566063dSJacob Faibussowitsch PetscCall(VecAXPY(ctx->D2, one, D)); 55e0877f53SBarry Smith PetscFunctionReturn(0); 56e0877f53SBarry Smith } 57e0877f53SBarry Smith 58e0877f53SBarry Smith static PetscErrorCode MatDestroy_ADA(Mat mat) 59e0877f53SBarry Smith { 60e0877f53SBarry Smith TaoMatADACtx ctx; 61e0877f53SBarry Smith 62e0877f53SBarry Smith PetscFunctionBegin; 639566063dSJacob Faibussowitsch PetscCall(MatShellGetContext(mat,&ctx)); 649566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ctx->W)); 659566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ctx->W2)); 669566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ctx->ADADiag)); 679566063dSJacob Faibussowitsch PetscCall(MatDestroy(&ctx->A)); 689566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ctx->D1)); 699566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ctx->D2)); 709566063dSJacob Faibussowitsch PetscCall(PetscFree(ctx)); 71e0877f53SBarry Smith PetscFunctionReturn(0); 72e0877f53SBarry Smith } 73e0877f53SBarry Smith 74e0877f53SBarry Smith static PetscErrorCode MatView_ADA(Mat mat,PetscViewer viewer) 75e0877f53SBarry Smith { 76e0877f53SBarry Smith PetscFunctionBegin; 77e0877f53SBarry Smith PetscFunctionReturn(0); 78e0877f53SBarry Smith } 79e0877f53SBarry Smith 80e0877f53SBarry Smith static PetscErrorCode MatShift_ADA(Mat Y, PetscReal a) 81e0877f53SBarry Smith { 82e0877f53SBarry Smith TaoMatADACtx ctx; 83e0877f53SBarry Smith 84e0877f53SBarry Smith PetscFunctionBegin; 859566063dSJacob Faibussowitsch PetscCall(MatShellGetContext(Y,&ctx)); 869566063dSJacob Faibussowitsch PetscCall(VecShift(ctx->D2,a)); 87e0877f53SBarry Smith PetscFunctionReturn(0); 88e0877f53SBarry Smith } 89e0877f53SBarry Smith 90e0877f53SBarry Smith static PetscErrorCode MatDuplicate_ADA(Mat mat,MatDuplicateOption op,Mat *M) 91e0877f53SBarry Smith { 92e0877f53SBarry Smith TaoMatADACtx ctx; 93e0877f53SBarry Smith Mat A2; 94e0877f53SBarry Smith Vec D1b=NULL,D2b; 95e0877f53SBarry Smith 96e0877f53SBarry Smith PetscFunctionBegin; 979566063dSJacob Faibussowitsch PetscCall(MatShellGetContext(mat,&ctx)); 989566063dSJacob Faibussowitsch PetscCall(MatDuplicate(ctx->A,op,&A2)); 99e0877f53SBarry Smith if (ctx->D1) { 1009566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ctx->D1,&D1b)); 1019566063dSJacob Faibussowitsch PetscCall(VecCopy(ctx->D1,D1b)); 102e0877f53SBarry Smith } 1039566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ctx->D2,&D2b)); 1049566063dSJacob Faibussowitsch PetscCall(VecCopy(ctx->D2,D2b)); 1059566063dSJacob Faibussowitsch PetscCall(MatCreateADA(A2,D1b,D2b,M)); 106e0877f53SBarry Smith if (ctx->D1) { 1079566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)D1b)); 108e0877f53SBarry Smith } 1099566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)D2b)); 1109566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)A2)); 111e0877f53SBarry Smith PetscFunctionReturn(0); 112e0877f53SBarry Smith } 113e0877f53SBarry Smith 114e0877f53SBarry Smith static PetscErrorCode MatEqual_ADA(Mat A,Mat B,PetscBool *flg) 115e0877f53SBarry Smith { 116e0877f53SBarry Smith TaoMatADACtx ctx1,ctx2; 117e0877f53SBarry Smith 118e0877f53SBarry Smith PetscFunctionBegin; 1199566063dSJacob Faibussowitsch PetscCall(MatShellGetContext(A,&ctx1)); 1209566063dSJacob Faibussowitsch PetscCall(MatShellGetContext(B,&ctx2)); 1219566063dSJacob Faibussowitsch PetscCall(VecEqual(ctx1->D2,ctx2->D2,flg)); 122e0877f53SBarry Smith if (*flg==PETSC_TRUE) { 1239566063dSJacob Faibussowitsch PetscCall(VecEqual(ctx1->D1,ctx2->D1,flg)); 124e0877f53SBarry Smith } 125e0877f53SBarry Smith if (*flg==PETSC_TRUE) { 1269566063dSJacob Faibussowitsch PetscCall(MatEqual(ctx1->A,ctx2->A,flg)); 127e0877f53SBarry Smith } 128e0877f53SBarry Smith PetscFunctionReturn(0); 129e0877f53SBarry Smith } 130e0877f53SBarry Smith 131e0877f53SBarry Smith static PetscErrorCode MatScale_ADA(Mat mat, PetscReal a) 132e0877f53SBarry Smith { 133e0877f53SBarry Smith TaoMatADACtx ctx; 134e0877f53SBarry Smith 135e0877f53SBarry Smith PetscFunctionBegin; 1369566063dSJacob Faibussowitsch PetscCall(MatShellGetContext(mat,&ctx)); 1379566063dSJacob Faibussowitsch PetscCall(VecScale(ctx->D1,a)); 138e0877f53SBarry Smith if (ctx->D2) { 1399566063dSJacob Faibussowitsch PetscCall(VecScale(ctx->D2,a)); 140e0877f53SBarry Smith } 141e0877f53SBarry Smith PetscFunctionReturn(0); 142e0877f53SBarry Smith } 143e0877f53SBarry Smith 144cf37664fSBarry Smith static PetscErrorCode MatTranspose_ADA(Mat mat,MatReuse reuse,Mat *B) 145e0877f53SBarry Smith { 146e0877f53SBarry Smith TaoMatADACtx ctx; 147e0877f53SBarry Smith 148e0877f53SBarry Smith PetscFunctionBegin; 1499566063dSJacob Faibussowitsch PetscCall(MatShellGetContext(mat,&ctx)); 150cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX) { 1519566063dSJacob Faibussowitsch PetscCall(MatDuplicate(mat,MAT_COPY_VALUES,B)); 152cf37664fSBarry Smith } else if (reuse == MAT_REUSE_MATRIX) { 1539566063dSJacob Faibussowitsch PetscCall(MatCopy(mat,*B,SAME_NONZERO_PATTERN)); 154cf37664fSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Does not support inplace transpose"); 155e0877f53SBarry Smith PetscFunctionReturn(0); 156e0877f53SBarry Smith } 157e0877f53SBarry Smith 1580c0fd78eSBarry Smith static PetscErrorCode MatADAComputeDiagonal(Mat mat) 159e0877f53SBarry Smith { 160e0877f53SBarry Smith PetscInt i,m,n,low,high; 161e0877f53SBarry Smith PetscScalar *dtemp,*dptr; 162e0877f53SBarry Smith TaoMatADACtx ctx; 163e0877f53SBarry Smith 164e0877f53SBarry Smith PetscFunctionBegin; 1659566063dSJacob Faibussowitsch PetscCall(MatShellGetContext(mat,&ctx)); 1669566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(mat, &low, &high)); 1679566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat,&m,&n)); 168e0877f53SBarry Smith 1699566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n,&dtemp)); 170e0877f53SBarry Smith for (i=0; i<n; i++) { 1719566063dSJacob Faibussowitsch PetscCall(MatGetColumnVector(ctx->A, ctx->W, i)); 1729566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(ctx->W,ctx->W,ctx->W)); 1739566063dSJacob Faibussowitsch PetscCall(VecDotBegin(ctx->D1, ctx->W,dtemp+i)); 174e0877f53SBarry Smith } 175e0877f53SBarry Smith for (i=0; i<n; i++) { 1769566063dSJacob Faibussowitsch PetscCall(VecDotEnd(ctx->D1, ctx->W,dtemp+i)); 177e0877f53SBarry Smith } 178e0877f53SBarry Smith 1799566063dSJacob Faibussowitsch PetscCall(VecGetArray(ctx->ADADiag,&dptr)); 180e0877f53SBarry Smith for (i=low; i<high; i++) { 181e0877f53SBarry Smith dptr[i-low]= dtemp[i]; 182e0877f53SBarry Smith } 1839566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(ctx->ADADiag,&dptr)); 1849566063dSJacob Faibussowitsch PetscCall(PetscFree(dtemp)); 185e0877f53SBarry Smith PetscFunctionReturn(0); 186e0877f53SBarry Smith } 187e0877f53SBarry Smith 188e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_ADA(Mat mat,Vec v) 189e0877f53SBarry Smith { 190e0877f53SBarry Smith PetscReal one=1.0; 191e0877f53SBarry Smith TaoMatADACtx ctx; 192e0877f53SBarry Smith 193e0877f53SBarry Smith PetscFunctionBegin; 1949566063dSJacob Faibussowitsch PetscCall(MatShellGetContext(mat,&ctx)); 1959566063dSJacob Faibussowitsch PetscCall(MatADAComputeDiagonal(mat)); 1969566063dSJacob Faibussowitsch PetscCall(VecCopy(ctx->ADADiag,v)); 197e0877f53SBarry Smith if (ctx->D2) { 1989566063dSJacob Faibussowitsch PetscCall(VecAXPY(v, one, ctx->D2)); 199e0877f53SBarry Smith } 200e0877f53SBarry Smith PetscFunctionReturn(0); 201e0877f53SBarry Smith } 202e0877f53SBarry Smith 2037dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_ADA(Mat mat,IS isrow,IS iscol,MatReuse cll, Mat *newmat) 204e0877f53SBarry Smith { 205e0877f53SBarry Smith PetscInt low,high; 206e0877f53SBarry Smith IS ISrow; 207e0877f53SBarry Smith Vec D1,D2; 208e0877f53SBarry Smith Mat Atemp; 209e0877f53SBarry Smith TaoMatADACtx ctx; 210e0877f53SBarry Smith PetscBool isequal; 211e0877f53SBarry Smith 212e0877f53SBarry Smith PetscFunctionBegin; 2139566063dSJacob Faibussowitsch PetscCall(ISEqual(isrow,iscol,&isequal)); 2143c859ba3SBarry Smith PetscCheck(isequal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Only for identical column and row indices"); 2159566063dSJacob Faibussowitsch PetscCall(MatShellGetContext(mat,&ctx)); 216e0877f53SBarry Smith 2179566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(ctx->A,&low,&high)); 2189566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PetscObjectComm((PetscObject)mat),high-low,low,1,&ISrow)); 2199566063dSJacob Faibussowitsch PetscCall(MatCreateSubMatrix(ctx->A,ISrow,iscol,cll,&Atemp)); 2209566063dSJacob Faibussowitsch PetscCall(ISDestroy(&ISrow)); 221e0877f53SBarry Smith 222e0877f53SBarry Smith if (ctx->D1) { 2239566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ctx->D1,&D1)); 2249566063dSJacob Faibussowitsch PetscCall(VecCopy(ctx->D1,D1)); 225e0877f53SBarry Smith } else { 226e0877f53SBarry Smith D1 = NULL; 227e0877f53SBarry Smith } 228e0877f53SBarry Smith 229e0877f53SBarry Smith if (ctx->D2) { 230e0877f53SBarry Smith Vec D2sub; 231e0877f53SBarry Smith 2329566063dSJacob Faibussowitsch PetscCall(VecGetSubVector(ctx->D2,isrow,&D2sub)); 2339566063dSJacob Faibussowitsch PetscCall(VecDuplicate(D2sub,&D2)); 2349566063dSJacob Faibussowitsch PetscCall(VecCopy(D2sub,D2)); 2359566063dSJacob Faibussowitsch PetscCall(VecRestoreSubVector(ctx->D2,isrow,&D2sub)); 236e0877f53SBarry Smith } else { 237e0877f53SBarry Smith D2 = NULL; 238e0877f53SBarry Smith } 239e0877f53SBarry Smith 2409566063dSJacob Faibussowitsch PetscCall(MatCreateADA(Atemp,D1,D2,newmat)); 2419566063dSJacob Faibussowitsch PetscCall(MatShellGetContext(*newmat,&ctx)); 2429566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)Atemp)); 243e0877f53SBarry Smith if (ctx->D1) { 2449566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)D1)); 245e0877f53SBarry Smith } 246e0877f53SBarry Smith if (ctx->D2) { 2479566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)D2)); 248e0877f53SBarry Smith } 249e0877f53SBarry Smith PetscFunctionReturn(0); 250e0877f53SBarry Smith } 251e0877f53SBarry Smith 2527dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_ADA(Mat A,PetscInt n, IS *irow,IS *icol,MatReuse scall,Mat **B) 253e0877f53SBarry Smith { 254e0877f53SBarry Smith PetscInt i; 255e0877f53SBarry Smith 256e0877f53SBarry Smith PetscFunctionBegin; 257e0877f53SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2589566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(n+1,B)); 259e0877f53SBarry Smith } 260e0877f53SBarry Smith for (i=0; i<n; i++) { 2619566063dSJacob Faibussowitsch PetscCall(MatCreateSubMatrix_ADA(A,irow[i],icol[i],scall,&(*B)[i])); 262e0877f53SBarry Smith } 263e0877f53SBarry Smith PetscFunctionReturn(0); 264e0877f53SBarry Smith } 265e0877f53SBarry Smith 266e0877f53SBarry Smith static PetscErrorCode MatGetColumnVector_ADA(Mat mat,Vec Y, PetscInt col) 267e0877f53SBarry Smith { 268e0877f53SBarry Smith PetscInt low,high; 269e0877f53SBarry Smith PetscScalar zero=0.0,one=1.0; 270e0877f53SBarry Smith 271e0877f53SBarry Smith PetscFunctionBegin; 2729566063dSJacob Faibussowitsch PetscCall(VecSet(Y, zero)); 2739566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(Y,&low,&high)); 274e0877f53SBarry Smith if (col>=low && col<high) { 2759566063dSJacob Faibussowitsch PetscCall(VecSetValue(Y,col,one,INSERT_VALUES)); 276e0877f53SBarry Smith } 2779566063dSJacob Faibussowitsch PetscCall(VecAssemblyBegin(Y)); 2789566063dSJacob Faibussowitsch PetscCall(VecAssemblyEnd(Y)); 2799566063dSJacob Faibussowitsch PetscCall(MatMult_ADA(mat,Y,Y)); 280e0877f53SBarry Smith PetscFunctionReturn(0); 281e0877f53SBarry Smith } 282e0877f53SBarry Smith 283cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_ADA(Mat mat,MatType newtype,Mat *NewMat) 284e0877f53SBarry Smith { 285e0877f53SBarry Smith PetscMPIInt size; 286e0877f53SBarry Smith PetscBool sametype, issame, isdense, isseqdense; 287e0877f53SBarry Smith TaoMatADACtx ctx; 288e0877f53SBarry Smith 289e0877f53SBarry Smith PetscFunctionBegin; 2909566063dSJacob Faibussowitsch PetscCall(MatShellGetContext(mat,&ctx)); 2919566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 292e0877f53SBarry Smith 2939566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype)); 2949566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)mat,MATSAME,&issame)); 2959566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)mat,MATMPIDENSE,&isdense)); 2969566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)mat,MATSEQDENSE,&isseqdense)); 297e0877f53SBarry Smith 298e0877f53SBarry Smith if (sametype || issame) { 2999566063dSJacob Faibussowitsch PetscCall(MatDuplicate(mat,MAT_COPY_VALUES,NewMat)); 300e0877f53SBarry Smith } else if (isdense) { 301e0877f53SBarry Smith PetscInt i,j,low,high,m,n,M,N; 302e0877f53SBarry Smith const PetscScalar *dptr; 303e0877f53SBarry Smith Vec X; 304e0877f53SBarry Smith 3059566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ctx->D2,&X)); 3069566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat,&M,&N)); 3079566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat,&m,&n)); 3089566063dSJacob Faibussowitsch PetscCall(MatCreateDense(PetscObjectComm((PetscObject)mat),m,m,N,N,NULL,NewMat)); 3099566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(*NewMat,&low,&high)); 310e0877f53SBarry Smith for (i=0;i<M;i++) { 3119566063dSJacob Faibussowitsch PetscCall(MatGetColumnVector_ADA(mat,X,i)); 3129566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X,&dptr)); 313e0877f53SBarry Smith for (j=0; j<high-low; j++) { 3149566063dSJacob Faibussowitsch PetscCall(MatSetValue(*NewMat,low+j,i,dptr[j],INSERT_VALUES)); 315e0877f53SBarry Smith } 3169566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X,&dptr)); 317e0877f53SBarry Smith } 3189566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(*NewMat,MAT_FINAL_ASSEMBLY)); 3199566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(*NewMat,MAT_FINAL_ASSEMBLY)); 3209566063dSJacob Faibussowitsch PetscCall(VecDestroy(&X)); 321e0877f53SBarry Smith } else if (isseqdense && size==1) { 322e0877f53SBarry Smith PetscInt i,j,low,high,m,n,M,N; 323e0877f53SBarry Smith const PetscScalar *dptr; 324e0877f53SBarry Smith Vec X; 325e0877f53SBarry Smith 3269566063dSJacob Faibussowitsch PetscCall(VecDuplicate(ctx->D2,&X)); 3279566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat,&M,&N)); 3289566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat,&m,&n)); 3299566063dSJacob Faibussowitsch PetscCall(MatCreateSeqDense(PetscObjectComm((PetscObject)mat),N,N,NULL,NewMat)); 3309566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(*NewMat,&low,&high)); 331e0877f53SBarry Smith for (i=0;i<M;i++) { 3329566063dSJacob Faibussowitsch PetscCall(MatGetColumnVector_ADA(mat,X,i)); 3339566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X,&dptr)); 334e0877f53SBarry Smith for (j=0; j<high-low; j++) { 3359566063dSJacob Faibussowitsch PetscCall(MatSetValue(*NewMat,low+j,i,dptr[j],INSERT_VALUES)); 336e0877f53SBarry Smith } 3379566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X,&dptr)); 338e0877f53SBarry Smith } 3399566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(*NewMat,MAT_FINAL_ASSEMBLY)); 3409566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(*NewMat,MAT_FINAL_ASSEMBLY)); 3419566063dSJacob Faibussowitsch PetscCall(VecDestroy(&X)); 342691b26d3SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"No support to convert objects to that type"); 343e0877f53SBarry Smith PetscFunctionReturn(0); 344e0877f53SBarry Smith } 345e0877f53SBarry Smith 346e0877f53SBarry Smith static PetscErrorCode MatNorm_ADA(Mat mat,NormType type,PetscReal *norm) 347e0877f53SBarry Smith { 348e0877f53SBarry Smith TaoMatADACtx ctx; 349e0877f53SBarry Smith 350e0877f53SBarry Smith PetscFunctionBegin; 3519566063dSJacob Faibussowitsch PetscCall(MatShellGetContext(mat,&ctx)); 352e0877f53SBarry Smith if (type == NORM_FROBENIUS) { 353e0877f53SBarry Smith *norm = 1.0; 354e0877f53SBarry Smith } else if (type == NORM_1 || type == NORM_INFINITY) { 355e0877f53SBarry Smith *norm = 1.0; 356e0877f53SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm"); 357e0877f53SBarry Smith PetscFunctionReturn(0); 358e0877f53SBarry Smith } 359a7e14dcfSSatish Balay 360a7e14dcfSSatish Balay /*@C 361a7e14dcfSSatish Balay MatCreateADA - Creates a matrix M=A^T D1 A + D2 where D1, D2 are diagonal 362a7e14dcfSSatish Balay 363a7e14dcfSSatish Balay Collective on matrix 364a7e14dcfSSatish Balay 365a7e14dcfSSatish Balay Input Parameters: 366a7e14dcfSSatish Balay + mat - matrix of arbitrary type 3670c0fd78eSBarry Smith . d1 - A vector defining a diagonal matrix 3680c0fd78eSBarry Smith - d2 - A vector defining a diagonal matrix 369a7e14dcfSSatish Balay 370a7e14dcfSSatish Balay Output Parameters: 371a7e14dcfSSatish Balay . J - New matrix whose operations are defined in terms of mat, D1, and D2. 372a7e14dcfSSatish Balay 373a7e14dcfSSatish Balay Notes: 374a7e14dcfSSatish Balay The user provides the input data and is responsible for destroying 375a7e14dcfSSatish Balay this data after matrix J has been destroyed. 376a7e14dcfSSatish Balay 377a7e14dcfSSatish Balay Level: developer 378a7e14dcfSSatish Balay 379*db781477SPatrick Sanan .seealso: `MatCreate()` 380a7e14dcfSSatish Balay @*/ 381a7e14dcfSSatish Balay PetscErrorCode MatCreateADA(Mat mat,Vec d1, Vec d2, Mat *J) 382a7e14dcfSSatish Balay { 383367daffbSBarry Smith MPI_Comm comm = PetscObjectComm((PetscObject)mat); 384a7e14dcfSSatish Balay TaoMatADACtx ctx; 385a7e14dcfSSatish Balay PetscInt nloc,n; 386a7e14dcfSSatish Balay 387a7e14dcfSSatish Balay PetscFunctionBegin; 3889566063dSJacob Faibussowitsch PetscCall(PetscNew(&ctx)); 389a7e14dcfSSatish Balay ctx->A=mat; 390a7e14dcfSSatish Balay ctx->D1=d1; 391a7e14dcfSSatish Balay ctx->D2=d2; 392a7e14dcfSSatish Balay if (d1) { 3939566063dSJacob Faibussowitsch PetscCall(VecDuplicate(d1,&ctx->W)); 3949566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)d1)); 395a7e14dcfSSatish Balay } else { 3960e660641SBarry Smith ctx->W = NULL; 397a7e14dcfSSatish Balay } 398a7e14dcfSSatish Balay if (d2) { 3999566063dSJacob Faibussowitsch PetscCall(VecDuplicate(d2,&ctx->W2)); 4009566063dSJacob Faibussowitsch PetscCall(VecDuplicate(d2,&ctx->ADADiag)); 4019566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)d2)); 402a7e14dcfSSatish Balay } else { 4030e660641SBarry Smith ctx->W2 = NULL; 4040e660641SBarry Smith ctx->ADADiag = NULL; 405a7e14dcfSSatish Balay } 406a7e14dcfSSatish Balay 407a7e14dcfSSatish Balay ctx->GotDiag = 0; 4089566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)mat)); 409a7e14dcfSSatish Balay 4109566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(d2,&nloc)); 4119566063dSJacob Faibussowitsch PetscCall(VecGetSize(d2,&n)); 412a7e14dcfSSatish Balay 4139566063dSJacob Faibussowitsch PetscCall(MatCreateShell(comm,nloc,nloc,n,n,ctx,J)); 4149566063dSJacob Faibussowitsch PetscCall(MatShellSetManageScalingShifts(*J)); 4159566063dSJacob Faibussowitsch PetscCall(MatShellSetOperation(*J,MATOP_MULT,(void(*)(void))MatMult_ADA)); 4169566063dSJacob Faibussowitsch PetscCall(MatShellSetOperation(*J,MATOP_DESTROY,(void(*)(void))MatDestroy_ADA)); 4179566063dSJacob Faibussowitsch PetscCall(MatShellSetOperation(*J,MATOP_VIEW,(void(*)(void))MatView_ADA)); 4189566063dSJacob Faibussowitsch PetscCall(MatShellSetOperation(*J,MATOP_MULT_TRANSPOSE,(void(*)(void))MatMultTranspose_ADA)); 4199566063dSJacob Faibussowitsch PetscCall(MatShellSetOperation(*J,MATOP_DIAGONAL_SET,(void(*)(void))MatDiagonalSet_ADA)); 4209566063dSJacob Faibussowitsch PetscCall(MatShellSetOperation(*J,MATOP_SHIFT,(void(*)(void))MatShift_ADA)); 4219566063dSJacob Faibussowitsch PetscCall(MatShellSetOperation(*J,MATOP_EQUAL,(void(*)(void))MatEqual_ADA)); 4229566063dSJacob Faibussowitsch PetscCall(MatShellSetOperation(*J,MATOP_SCALE,(void(*)(void))MatScale_ADA)); 4239566063dSJacob Faibussowitsch PetscCall(MatShellSetOperation(*J,MATOP_TRANSPOSE,(void(*)(void))MatTranspose_ADA)); 4249566063dSJacob Faibussowitsch PetscCall(MatShellSetOperation(*J,MATOP_GET_DIAGONAL,(void(*)(void))MatGetDiagonal_ADA)); 4259566063dSJacob Faibussowitsch PetscCall(MatShellSetOperation(*J,MATOP_CREATE_SUBMATRICES,(void(*)(void))MatCreateSubMatrices_ADA)); 4269566063dSJacob Faibussowitsch PetscCall(MatShellSetOperation(*J,MATOP_NORM,(void(*)(void))MatNorm_ADA)); 4279566063dSJacob Faibussowitsch PetscCall(MatShellSetOperation(*J,MATOP_DUPLICATE,(void(*)(void))MatDuplicate_ADA)); 4289566063dSJacob Faibussowitsch PetscCall(MatShellSetOperation(*J,MATOP_CREATE_SUBMATRIX,(void(*)(void))MatCreateSubMatrix_ADA)); 429a7e14dcfSSatish Balay 4309566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)(*J),(PetscObject)ctx->W)); 4319566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)mat,(PetscObject)(*J))); 432a7e14dcfSSatish Balay 4339566063dSJacob Faibussowitsch PetscCall(MatSetOption(*J,MAT_SYMMETRIC,PETSC_TRUE)); 434a7e14dcfSSatish Balay PetscFunctionReturn(0); 435a7e14dcfSSatish Balay } 436