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); 55*204606b3SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)N,"MatHermitianTransposeGetMat_C",NULL);CHKERRQ(ierr); 56*204606b3SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 57*204606b3SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)N,"MatTransposeGetMat_C",NULL);CHKERRQ(ierr); 58*204606b3SStefano Zampini #endif 59d0de2241SAndrew Spott ierr = PetscFree(N->data);CHKERRQ(ierr); 60d0de2241SAndrew Spott PetscFunctionReturn(0); 61d0de2241SAndrew Spott } 62d0de2241SAndrew Spott 63fb41c00aSBarry Smith PetscErrorCode MatDuplicate_HT(Mat N, MatDuplicateOption op, Mat* m) 64d0de2241SAndrew Spott { 65fb41c00aSBarry Smith Mat_HT *Na = (Mat_HT*)N->data; 66d0de2241SAndrew Spott PetscErrorCode ierr; 67d0de2241SAndrew Spott 68d0de2241SAndrew Spott PetscFunctionBegin; 69d0de2241SAndrew Spott if (op == MAT_COPY_VALUES) { 70d0de2241SAndrew Spott ierr = MatHermitianTranspose(Na->A,MAT_INITIAL_MATRIX,m);CHKERRQ(ierr); 71d0de2241SAndrew Spott } else if (op == MAT_DO_NOT_COPY_VALUES) { 72d0de2241SAndrew Spott ierr = MatDuplicate(Na->A,MAT_DO_NOT_COPY_VALUES,m);CHKERRQ(ierr); 73f79c2134SBarry Smith ierr = MatHermitianTranspose(*m,MAT_INPLACE_MATRIX,m);CHKERRQ(ierr); 74fb41c00aSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)N),PETSC_ERR_SUP,"MAT_SHARE_NONZERO_PATTERN not supported for this matrix type"); 75d0de2241SAndrew Spott PetscFunctionReturn(0); 76d0de2241SAndrew Spott } 77d0de2241SAndrew Spott 7806511a5cSPierre Jolivet PetscErrorCode MatCreateVecs_HT(Mat N,Vec *r, Vec *l) 7906511a5cSPierre Jolivet { 8006511a5cSPierre Jolivet Mat_HT *Na = (Mat_HT*)N->data; 8106511a5cSPierre Jolivet PetscErrorCode ierr; 8206511a5cSPierre Jolivet 8306511a5cSPierre Jolivet PetscFunctionBegin; 8406511a5cSPierre Jolivet ierr = MatCreateVecs(Na->A,l,r);CHKERRQ(ierr); 8506511a5cSPierre Jolivet PetscFunctionReturn(0); 8606511a5cSPierre Jolivet } 8706511a5cSPierre Jolivet 886171f1c8SPierre Jolivet PetscErrorCode MatAXPY_HT(Mat Y,PetscScalar a,Mat X,MatStructure str) 896171f1c8SPierre Jolivet { 906171f1c8SPierre Jolivet Mat_HT *Ya = (Mat_HT*)Y->data; 916171f1c8SPierre Jolivet Mat_HT *Xa = (Mat_HT*)X->data; 926171f1c8SPierre Jolivet Mat M = Ya->A; 936171f1c8SPierre Jolivet Mat N = Xa->A; 946171f1c8SPierre Jolivet PetscErrorCode ierr; 956171f1c8SPierre Jolivet 966171f1c8SPierre Jolivet PetscFunctionBegin; 976171f1c8SPierre Jolivet ierr = MatAXPY(M,a,N,str);CHKERRQ(ierr); 986171f1c8SPierre Jolivet PetscFunctionReturn(0); 996171f1c8SPierre Jolivet } 1006171f1c8SPierre Jolivet 10106511a5cSPierre Jolivet PetscErrorCode MatHermitianTransposeGetMat_HT(Mat N,Mat *M) 10206511a5cSPierre Jolivet { 10306511a5cSPierre Jolivet Mat_HT *Na = (Mat_HT*)N->data; 10406511a5cSPierre Jolivet 10506511a5cSPierre Jolivet PetscFunctionBegin; 10606511a5cSPierre Jolivet *M = Na->A; 10706511a5cSPierre Jolivet PetscFunctionReturn(0); 10806511a5cSPierre Jolivet } 10906511a5cSPierre Jolivet 11006511a5cSPierre Jolivet /*@ 11106511a5cSPierre Jolivet MatHermitianTransposeGetMat - Gets the Mat object stored inside a MATTRANSPOSEMAT 11206511a5cSPierre Jolivet 11306511a5cSPierre Jolivet Logically collective on Mat 11406511a5cSPierre Jolivet 11506511a5cSPierre Jolivet Input Parameter: 11606511a5cSPierre Jolivet . A - the MATTRANSPOSE matrix 11706511a5cSPierre Jolivet 11806511a5cSPierre Jolivet Output Parameter: 11906511a5cSPierre Jolivet . M - the matrix object stored inside A 12006511a5cSPierre Jolivet 12106511a5cSPierre Jolivet Level: intermediate 12206511a5cSPierre Jolivet 12306511a5cSPierre Jolivet .seealso: MatCreateHermitianTranspose() 12406511a5cSPierre Jolivet 12506511a5cSPierre Jolivet @*/ 12606511a5cSPierre Jolivet PetscErrorCode MatHermitianTransposeGetMat(Mat A,Mat *M) 12706511a5cSPierre Jolivet { 12806511a5cSPierre Jolivet PetscErrorCode ierr; 12906511a5cSPierre Jolivet 13006511a5cSPierre Jolivet PetscFunctionBegin; 13106511a5cSPierre Jolivet PetscValidHeaderSpecific(A,MAT_CLASSID,1); 13206511a5cSPierre Jolivet PetscValidType(A,1); 13306511a5cSPierre Jolivet PetscValidPointer(M,2); 13406511a5cSPierre Jolivet ierr = PetscUseMethod(A,"MatHermitianTransposeGetMat_C",(Mat,Mat*),(A,M));CHKERRQ(ierr); 13506511a5cSPierre Jolivet PetscFunctionReturn(0); 13606511a5cSPierre Jolivet } 13706511a5cSPierre Jolivet 138d0de2241SAndrew Spott /*@ 139d0de2241SAndrew Spott MatCreateHermitianTranspose - Creates a new matrix object that behaves like A'* 140d0de2241SAndrew Spott 141d0de2241SAndrew Spott Collective on Mat 142d0de2241SAndrew Spott 143d0de2241SAndrew Spott Input Parameter: 144d0de2241SAndrew Spott . A - the (possibly rectangular) matrix 145d0de2241SAndrew Spott 146d0de2241SAndrew Spott Output Parameter: 147d0de2241SAndrew Spott . N - the matrix that represents A'* 148d0de2241SAndrew Spott 149d0de2241SAndrew Spott Level: intermediate 150d0de2241SAndrew Spott 15195452b02SPatrick Sanan Notes: 15295452b02SPatrick Sanan The hermitian transpose A' is NOT actually formed! Rather the new matrix 153d0de2241SAndrew Spott object performs the matrix-vector product by using the MatMultHermitianTranspose() on 154d0de2241SAndrew Spott the original matrix 155d0de2241SAndrew Spott 156d0de2241SAndrew Spott .seealso: MatCreateNormal(), MatMult(), MatMultHermitianTranspose(), MatCreate() 157d0de2241SAndrew Spott 158d0de2241SAndrew Spott @*/ 159d0de2241SAndrew Spott PetscErrorCode MatCreateHermitianTranspose(Mat A,Mat *N) 160d0de2241SAndrew Spott { 161d0de2241SAndrew Spott PetscErrorCode ierr; 162d0de2241SAndrew Spott PetscInt m,n; 163fb41c00aSBarry Smith Mat_HT *Na; 164d0de2241SAndrew Spott 165d0de2241SAndrew Spott PetscFunctionBegin; 166d0de2241SAndrew Spott ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 167d0de2241SAndrew Spott ierr = MatCreate(PetscObjectComm((PetscObject)A),N);CHKERRQ(ierr); 168d0de2241SAndrew Spott ierr = MatSetSizes(*N,n,m,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 169d0de2241SAndrew Spott ierr = PetscLayoutSetUp((*N)->rmap);CHKERRQ(ierr); 170d0de2241SAndrew Spott ierr = PetscLayoutSetUp((*N)->cmap);CHKERRQ(ierr); 171d0de2241SAndrew Spott ierr = PetscObjectChangeTypeName((PetscObject)*N,MATTRANSPOSEMAT);CHKERRQ(ierr); 172d0de2241SAndrew Spott 173d0de2241SAndrew Spott ierr = PetscNewLog(*N,&Na);CHKERRQ(ierr); 174d0de2241SAndrew Spott (*N)->data = (void*) Na; 175d0de2241SAndrew Spott ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 176d0de2241SAndrew Spott Na->A = A; 177d0de2241SAndrew Spott 178fb41c00aSBarry Smith (*N)->ops->destroy = MatDestroy_HT; 179fb41c00aSBarry Smith (*N)->ops->mult = MatMult_HT; 180fb41c00aSBarry Smith (*N)->ops->multadd = MatMultAdd_HT; 181fb41c00aSBarry Smith (*N)->ops->multhermitiantranspose = MatMultHermitianTranspose_HT; 182fb41c00aSBarry Smith (*N)->ops->multhermitiantransposeadd = MatMultHermitianTransposeAdd_HT; 183fb41c00aSBarry Smith (*N)->ops->duplicate = MatDuplicate_HT; 18406511a5cSPierre Jolivet (*N)->ops->getvecs = MatCreateVecs_HT; 1856171f1c8SPierre Jolivet (*N)->ops->axpy = MatAXPY_HT; 186d0de2241SAndrew Spott (*N)->assembled = PETSC_TRUE; 187d0de2241SAndrew Spott 18806511a5cSPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)(*N),"MatHermitianTransposeGetMat_C",MatHermitianTransposeGetMat_HT);CHKERRQ(ierr); 189*204606b3SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 190*204606b3SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)(*N),"MatTransposeGetMat_C",MatHermitianTransposeGetMat_HT);CHKERRQ(ierr); 191*204606b3SStefano Zampini #endif 192d0de2241SAndrew Spott ierr = MatSetBlockSizes(*N,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 193d0de2241SAndrew Spott ierr = MatSetUp(*N);CHKERRQ(ierr); 194d0de2241SAndrew Spott PetscFunctionReturn(0); 195d0de2241SAndrew Spott } 196