1d0de2241SAndrew Spott 2af0996ceSBarry Smith #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 3d0de2241SAndrew Spott 4d0de2241SAndrew Spott typedef struct { 5d0de2241SAndrew Spott Mat A; 6fb41c00aSBarry Smith } Mat_HT; 7d0de2241SAndrew Spott 8fb41c00aSBarry Smith PetscErrorCode MatMult_HT(Mat N,Vec x,Vec y) 9d0de2241SAndrew Spott { 10fb41c00aSBarry Smith Mat_HT *Na = (Mat_HT*)N->data; 11d0de2241SAndrew Spott PetscErrorCode ierr; 12d0de2241SAndrew Spott 13d0de2241SAndrew Spott PetscFunctionBegin; 14d0de2241SAndrew Spott ierr = MatMultHermitianTranspose(Na->A,x,y);CHKERRQ(ierr); 15d0de2241SAndrew Spott PetscFunctionReturn(0); 16d0de2241SAndrew Spott } 17d0de2241SAndrew Spott 18fb41c00aSBarry Smith PetscErrorCode MatMultAdd_HT(Mat N,Vec v1,Vec v2,Vec v3) 19d0de2241SAndrew Spott { 20fb41c00aSBarry Smith Mat_HT *Na = (Mat_HT*)N->data; 21d0de2241SAndrew Spott PetscErrorCode ierr; 22d0de2241SAndrew Spott 23d0de2241SAndrew Spott PetscFunctionBegin; 24d0de2241SAndrew Spott ierr = MatMultHermitianTransposeAdd(Na->A,v1,v2,v3);CHKERRQ(ierr); 25d0de2241SAndrew Spott PetscFunctionReturn(0); 26d0de2241SAndrew Spott } 27d0de2241SAndrew Spott 28fb41c00aSBarry Smith PetscErrorCode MatMultHermitianTranspose_HT(Mat N,Vec x,Vec y) 29d0de2241SAndrew Spott { 30fb41c00aSBarry Smith Mat_HT *Na = (Mat_HT*)N->data; 31d0de2241SAndrew Spott PetscErrorCode ierr; 32d0de2241SAndrew Spott 33d0de2241SAndrew Spott PetscFunctionBegin; 34d0de2241SAndrew Spott ierr = MatMult(Na->A,x,y);CHKERRQ(ierr); 35d0de2241SAndrew Spott PetscFunctionReturn(0); 36d0de2241SAndrew Spott } 37d0de2241SAndrew Spott 38fb41c00aSBarry Smith PetscErrorCode MatMultHermitianTransposeAdd_HT(Mat N,Vec v1,Vec v2,Vec v3) 39d0de2241SAndrew Spott { 40fb41c00aSBarry Smith Mat_HT *Na = (Mat_HT*)N->data; 41d0de2241SAndrew Spott PetscErrorCode ierr; 42d0de2241SAndrew Spott 43d0de2241SAndrew Spott PetscFunctionBegin; 44d0de2241SAndrew Spott ierr = MatMultAdd(Na->A,v1,v2,v3);CHKERRQ(ierr); 45d0de2241SAndrew Spott PetscFunctionReturn(0); 46d0de2241SAndrew Spott } 47d0de2241SAndrew Spott 48fb41c00aSBarry Smith PetscErrorCode MatDestroy_HT(Mat N) 49d0de2241SAndrew Spott { 50fb41c00aSBarry Smith Mat_HT *Na = (Mat_HT*)N->data; 51d0de2241SAndrew Spott PetscErrorCode ierr; 52d0de2241SAndrew Spott 53d0de2241SAndrew Spott PetscFunctionBegin; 54d0de2241SAndrew Spott ierr = MatDestroy(&Na->A);CHKERRQ(ierr); 55204606b3SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)N,"MatHermitianTransposeGetMat_C",NULL);CHKERRQ(ierr); 56204606b3SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 57204606b3SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)N,"MatTransposeGetMat_C",NULL);CHKERRQ(ierr); 586718818eSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)N,"MatProductSetFromOptions_anytype_C",NULL);CHKERRQ(ierr); 59204606b3SStefano Zampini #endif 60d0de2241SAndrew Spott ierr = PetscFree(N->data);CHKERRQ(ierr); 61d0de2241SAndrew Spott PetscFunctionReturn(0); 62d0de2241SAndrew Spott } 63d0de2241SAndrew Spott 64fb41c00aSBarry Smith PetscErrorCode MatDuplicate_HT(Mat N, MatDuplicateOption op, Mat* m) 65d0de2241SAndrew Spott { 66fb41c00aSBarry Smith Mat_HT *Na = (Mat_HT*)N->data; 67d0de2241SAndrew Spott PetscErrorCode ierr; 68d0de2241SAndrew Spott 69d0de2241SAndrew Spott PetscFunctionBegin; 70d0de2241SAndrew Spott if (op == MAT_COPY_VALUES) { 71d0de2241SAndrew Spott ierr = MatHermitianTranspose(Na->A,MAT_INITIAL_MATRIX,m);CHKERRQ(ierr); 72d0de2241SAndrew Spott } else if (op == MAT_DO_NOT_COPY_VALUES) { 73d0de2241SAndrew Spott ierr = MatDuplicate(Na->A,MAT_DO_NOT_COPY_VALUES,m);CHKERRQ(ierr); 74f79c2134SBarry Smith ierr = MatHermitianTranspose(*m,MAT_INPLACE_MATRIX,m);CHKERRQ(ierr); 75fb41c00aSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)N),PETSC_ERR_SUP,"MAT_SHARE_NONZERO_PATTERN not supported for this matrix type"); 76d0de2241SAndrew Spott PetscFunctionReturn(0); 77d0de2241SAndrew Spott } 78d0de2241SAndrew Spott 7906511a5cSPierre Jolivet PetscErrorCode MatCreateVecs_HT(Mat N,Vec *r, Vec *l) 8006511a5cSPierre Jolivet { 8106511a5cSPierre Jolivet Mat_HT *Na = (Mat_HT*)N->data; 8206511a5cSPierre Jolivet PetscErrorCode ierr; 8306511a5cSPierre Jolivet 8406511a5cSPierre Jolivet PetscFunctionBegin; 8506511a5cSPierre Jolivet ierr = MatCreateVecs(Na->A,l,r);CHKERRQ(ierr); 8606511a5cSPierre Jolivet PetscFunctionReturn(0); 8706511a5cSPierre Jolivet } 8806511a5cSPierre Jolivet 896171f1c8SPierre Jolivet PetscErrorCode MatAXPY_HT(Mat Y,PetscScalar a,Mat X,MatStructure str) 906171f1c8SPierre Jolivet { 916171f1c8SPierre Jolivet Mat_HT *Ya = (Mat_HT*)Y->data; 926171f1c8SPierre Jolivet Mat_HT *Xa = (Mat_HT*)X->data; 936171f1c8SPierre Jolivet Mat M = Ya->A; 946171f1c8SPierre Jolivet Mat N = Xa->A; 956171f1c8SPierre Jolivet PetscErrorCode ierr; 966171f1c8SPierre Jolivet 976171f1c8SPierre Jolivet PetscFunctionBegin; 986171f1c8SPierre Jolivet ierr = MatAXPY(M,a,N,str);CHKERRQ(ierr); 996171f1c8SPierre Jolivet PetscFunctionReturn(0); 1006171f1c8SPierre Jolivet } 1016171f1c8SPierre Jolivet 10206511a5cSPierre Jolivet PetscErrorCode MatHermitianTransposeGetMat_HT(Mat N,Mat *M) 10306511a5cSPierre Jolivet { 10406511a5cSPierre Jolivet Mat_HT *Na = (Mat_HT*)N->data; 10506511a5cSPierre Jolivet 10606511a5cSPierre Jolivet PetscFunctionBegin; 10706511a5cSPierre Jolivet *M = Na->A; 10806511a5cSPierre Jolivet PetscFunctionReturn(0); 10906511a5cSPierre Jolivet } 11006511a5cSPierre Jolivet 11106511a5cSPierre Jolivet /*@ 11206511a5cSPierre Jolivet MatHermitianTransposeGetMat - Gets the Mat object stored inside a MATTRANSPOSEMAT 11306511a5cSPierre Jolivet 11406511a5cSPierre Jolivet Logically collective on Mat 11506511a5cSPierre Jolivet 11606511a5cSPierre Jolivet Input Parameter: 11706511a5cSPierre Jolivet . A - the MATTRANSPOSE matrix 11806511a5cSPierre Jolivet 11906511a5cSPierre Jolivet Output Parameter: 12006511a5cSPierre Jolivet . M - the matrix object stored inside A 12106511a5cSPierre Jolivet 12206511a5cSPierre Jolivet Level: intermediate 12306511a5cSPierre Jolivet 12406511a5cSPierre Jolivet .seealso: MatCreateHermitianTranspose() 12506511a5cSPierre Jolivet 12606511a5cSPierre Jolivet @*/ 12706511a5cSPierre Jolivet PetscErrorCode MatHermitianTransposeGetMat(Mat A,Mat *M) 12806511a5cSPierre Jolivet { 12906511a5cSPierre Jolivet PetscErrorCode ierr; 13006511a5cSPierre Jolivet 13106511a5cSPierre Jolivet PetscFunctionBegin; 13206511a5cSPierre Jolivet PetscValidHeaderSpecific(A,MAT_CLASSID,1); 13306511a5cSPierre Jolivet PetscValidType(A,1); 13406511a5cSPierre Jolivet PetscValidPointer(M,2); 13506511a5cSPierre Jolivet ierr = PetscUseMethod(A,"MatHermitianTransposeGetMat_C",(Mat,Mat*),(A,M));CHKERRQ(ierr); 13606511a5cSPierre Jolivet PetscFunctionReturn(0); 13706511a5cSPierre Jolivet } 13806511a5cSPierre Jolivet 1396718818eSStefano Zampini PETSC_INTERN PetscErrorCode MatProductSetFromOptions_Transpose(Mat); 1406718818eSStefano Zampini 141a0eea678SPierre Jolivet PetscErrorCode MatGetDiagonal_HT(Mat A,Vec v) 142a0eea678SPierre Jolivet { 143a0eea678SPierre Jolivet Mat_HT *Na = (Mat_HT*)A->data; 144a0eea678SPierre Jolivet PetscErrorCode ierr; 145a0eea678SPierre Jolivet 146a0eea678SPierre Jolivet PetscFunctionBegin; 147a0eea678SPierre Jolivet ierr = MatGetDiagonal(Na->A,v);CHKERRQ(ierr); 148*ff83db7bSPierre Jolivet ierr = VecConjugate(v);CHKERRQ(ierr); 149a0eea678SPierre Jolivet PetscFunctionReturn(0); 150a0eea678SPierre Jolivet } 151a0eea678SPierre Jolivet 152a0eea678SPierre Jolivet PetscErrorCode MatConvert_HT(Mat A,MatType newtype,MatReuse reuse,Mat *newmat) 153a0eea678SPierre Jolivet { 154a0eea678SPierre Jolivet Mat_HT *Na = (Mat_HT*)A->data; 155a0eea678SPierre Jolivet Mat B; 156a0eea678SPierre Jolivet PetscErrorCode ierr; 157a0eea678SPierre Jolivet 158a0eea678SPierre Jolivet PetscFunctionBegin; 159a0eea678SPierre Jolivet ierr = MatHermitianTranspose(Na->A,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 160*ff83db7bSPierre Jolivet if (reuse != MAT_INPLACE_MATRIX) { 161a0eea678SPierre Jolivet ierr = MatConvert(B,newtype,reuse,newmat);CHKERRQ(ierr); 162a0eea678SPierre Jolivet ierr = MatDestroy(&B);CHKERRQ(ierr); 163*ff83db7bSPierre Jolivet } else { 164*ff83db7bSPierre Jolivet ierr = MatConvert(B,newtype,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 165*ff83db7bSPierre Jolivet ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 166*ff83db7bSPierre Jolivet } 167a0eea678SPierre Jolivet PetscFunctionReturn(0); 168a0eea678SPierre Jolivet } 169a0eea678SPierre Jolivet 170d0de2241SAndrew Spott /*@ 171d0de2241SAndrew Spott MatCreateHermitianTranspose - Creates a new matrix object that behaves like A'* 172d0de2241SAndrew Spott 173d0de2241SAndrew Spott Collective on Mat 174d0de2241SAndrew Spott 175d0de2241SAndrew Spott Input Parameter: 176d0de2241SAndrew Spott . A - the (possibly rectangular) matrix 177d0de2241SAndrew Spott 178d0de2241SAndrew Spott Output Parameter: 179d0de2241SAndrew Spott . N - the matrix that represents A'* 180d0de2241SAndrew Spott 181d0de2241SAndrew Spott Level: intermediate 182d0de2241SAndrew Spott 18395452b02SPatrick Sanan Notes: 18495452b02SPatrick Sanan The hermitian transpose A' is NOT actually formed! Rather the new matrix 185d0de2241SAndrew Spott object performs the matrix-vector product by using the MatMultHermitianTranspose() on 186d0de2241SAndrew Spott the original matrix 187d0de2241SAndrew Spott 188d0de2241SAndrew Spott .seealso: MatCreateNormal(), MatMult(), MatMultHermitianTranspose(), MatCreate() 189d0de2241SAndrew Spott 190d0de2241SAndrew Spott @*/ 191d0de2241SAndrew Spott PetscErrorCode MatCreateHermitianTranspose(Mat A,Mat *N) 192d0de2241SAndrew Spott { 193d0de2241SAndrew Spott PetscErrorCode ierr; 194d0de2241SAndrew Spott PetscInt m,n; 195fb41c00aSBarry Smith Mat_HT *Na; 196487d878eSStefano Zampini VecType vtype; 197d0de2241SAndrew Spott 198d0de2241SAndrew Spott PetscFunctionBegin; 199d0de2241SAndrew Spott ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 200d0de2241SAndrew Spott ierr = MatCreate(PetscObjectComm((PetscObject)A),N);CHKERRQ(ierr); 201d0de2241SAndrew Spott ierr = MatSetSizes(*N,n,m,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 202d0de2241SAndrew Spott ierr = PetscLayoutSetUp((*N)->rmap);CHKERRQ(ierr); 203d0de2241SAndrew Spott ierr = PetscLayoutSetUp((*N)->cmap);CHKERRQ(ierr); 204d0de2241SAndrew Spott ierr = PetscObjectChangeTypeName((PetscObject)*N,MATTRANSPOSEMAT);CHKERRQ(ierr); 205d0de2241SAndrew Spott 206d0de2241SAndrew Spott ierr = PetscNewLog(*N,&Na);CHKERRQ(ierr); 207d0de2241SAndrew Spott (*N)->data = (void*) Na; 208d0de2241SAndrew Spott ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 209d0de2241SAndrew Spott Na->A = A; 210d0de2241SAndrew Spott 211fb41c00aSBarry Smith (*N)->ops->destroy = MatDestroy_HT; 212fb41c00aSBarry Smith (*N)->ops->mult = MatMult_HT; 213fb41c00aSBarry Smith (*N)->ops->multadd = MatMultAdd_HT; 214fb41c00aSBarry Smith (*N)->ops->multhermitiantranspose = MatMultHermitianTranspose_HT; 215fb41c00aSBarry Smith (*N)->ops->multhermitiantransposeadd = MatMultHermitianTransposeAdd_HT; 216fb41c00aSBarry Smith (*N)->ops->duplicate = MatDuplicate_HT; 21706511a5cSPierre Jolivet (*N)->ops->getvecs = MatCreateVecs_HT; 2186171f1c8SPierre Jolivet (*N)->ops->axpy = MatAXPY_HT; 2196718818eSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 2206718818eSStefano Zampini (*N)->ops->productsetfromoptions = MatProductSetFromOptions_Transpose; 2216718818eSStefano Zampini #endif 222a0eea678SPierre Jolivet (*N)->ops->getdiagonal = MatGetDiagonal_HT; 223a0eea678SPierre Jolivet (*N)->ops->convert = MatConvert_HT; 224d0de2241SAndrew Spott (*N)->assembled = PETSC_TRUE; 225d0de2241SAndrew Spott 22606511a5cSPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)(*N),"MatHermitianTransposeGetMat_C",MatHermitianTransposeGetMat_HT);CHKERRQ(ierr); 227204606b3SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 228204606b3SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)(*N),"MatTransposeGetMat_C",MatHermitianTransposeGetMat_HT);CHKERRQ(ierr); 2296718818eSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)(*N),"MatProductSetFromOptions_anytype_C",MatProductSetFromOptions_Transpose);CHKERRQ(ierr); 230204606b3SStefano Zampini #endif 231d0de2241SAndrew Spott ierr = MatSetBlockSizes(*N,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 232487d878eSStefano Zampini ierr = MatGetVecType(A,&vtype);CHKERRQ(ierr); 233487d878eSStefano Zampini ierr = MatSetVecType(*N,vtype);CHKERRQ(ierr); 2342487f3f2SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 2352487f3f2SStefano Zampini ierr = MatBindToCPU(*N,A->boundtocpu);CHKERRQ(ierr); 2362487f3f2SStefano Zampini #endif 237d0de2241SAndrew Spott ierr = MatSetUp(*N);CHKERRQ(ierr); 238d0de2241SAndrew Spott PetscFunctionReturn(0); 239d0de2241SAndrew Spott } 240