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); 55d0de2241SAndrew Spott ierr = PetscFree(N->data);CHKERRQ(ierr); 56d0de2241SAndrew Spott PetscFunctionReturn(0); 57d0de2241SAndrew Spott } 58d0de2241SAndrew Spott 59fb41c00aSBarry Smith PetscErrorCode MatDuplicate_HT(Mat N, MatDuplicateOption op, Mat* m) 60d0de2241SAndrew Spott { 61fb41c00aSBarry Smith Mat_HT *Na = (Mat_HT*)N->data; 62d0de2241SAndrew Spott PetscErrorCode ierr; 63d0de2241SAndrew Spott 64d0de2241SAndrew Spott PetscFunctionBegin; 65d0de2241SAndrew Spott if (op == MAT_COPY_VALUES) { 66d0de2241SAndrew Spott ierr = MatHermitianTranspose(Na->A,MAT_INITIAL_MATRIX,m);CHKERRQ(ierr); 67d0de2241SAndrew Spott } else if (op == MAT_DO_NOT_COPY_VALUES) { 68d0de2241SAndrew Spott ierr = MatDuplicate(Na->A,MAT_DO_NOT_COPY_VALUES,m);CHKERRQ(ierr); 69f79c2134SBarry Smith ierr = MatHermitianTranspose(*m,MAT_INPLACE_MATRIX,m);CHKERRQ(ierr); 70fb41c00aSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)N),PETSC_ERR_SUP,"MAT_SHARE_NONZERO_PATTERN not supported for this matrix type"); 71d0de2241SAndrew Spott PetscFunctionReturn(0); 72d0de2241SAndrew Spott } 73d0de2241SAndrew Spott 7406511a5cSPierre Jolivet PetscErrorCode MatCreateVecs_HT(Mat N,Vec *r, Vec *l) 7506511a5cSPierre Jolivet { 7606511a5cSPierre Jolivet Mat_HT *Na = (Mat_HT*)N->data; 7706511a5cSPierre Jolivet PetscErrorCode ierr; 7806511a5cSPierre Jolivet 7906511a5cSPierre Jolivet PetscFunctionBegin; 8006511a5cSPierre Jolivet ierr = MatCreateVecs(Na->A,l,r);CHKERRQ(ierr); 8106511a5cSPierre Jolivet PetscFunctionReturn(0); 8206511a5cSPierre Jolivet } 8306511a5cSPierre Jolivet 84*6171f1c8SPierre Jolivet PetscErrorCode MatAXPY_HT(Mat Y,PetscScalar a,Mat X,MatStructure str) 85*6171f1c8SPierre Jolivet { 86*6171f1c8SPierre Jolivet Mat_HT *Ya = (Mat_HT*)Y->data; 87*6171f1c8SPierre Jolivet Mat_HT *Xa = (Mat_HT*)X->data; 88*6171f1c8SPierre Jolivet Mat M = Ya->A; 89*6171f1c8SPierre Jolivet Mat N = Xa->A; 90*6171f1c8SPierre Jolivet PetscErrorCode ierr; 91*6171f1c8SPierre Jolivet 92*6171f1c8SPierre Jolivet PetscFunctionBegin; 93*6171f1c8SPierre Jolivet ierr = MatAXPY(M,a,N,str);CHKERRQ(ierr); 94*6171f1c8SPierre Jolivet PetscFunctionReturn(0); 95*6171f1c8SPierre Jolivet } 96*6171f1c8SPierre Jolivet 9706511a5cSPierre Jolivet PetscErrorCode MatHermitianTransposeGetMat_HT(Mat N,Mat *M) 9806511a5cSPierre Jolivet { 9906511a5cSPierre Jolivet Mat_HT *Na = (Mat_HT*)N->data; 10006511a5cSPierre Jolivet 10106511a5cSPierre Jolivet PetscFunctionBegin; 10206511a5cSPierre Jolivet *M = Na->A; 10306511a5cSPierre Jolivet PetscFunctionReturn(0); 10406511a5cSPierre Jolivet } 10506511a5cSPierre Jolivet 10606511a5cSPierre Jolivet /*@ 10706511a5cSPierre Jolivet MatHermitianTransposeGetMat - Gets the Mat object stored inside a MATTRANSPOSEMAT 10806511a5cSPierre Jolivet 10906511a5cSPierre Jolivet Logically collective on Mat 11006511a5cSPierre Jolivet 11106511a5cSPierre Jolivet Input Parameter: 11206511a5cSPierre Jolivet . A - the MATTRANSPOSE matrix 11306511a5cSPierre Jolivet 11406511a5cSPierre Jolivet Output Parameter: 11506511a5cSPierre Jolivet . M - the matrix object stored inside A 11606511a5cSPierre Jolivet 11706511a5cSPierre Jolivet Level: intermediate 11806511a5cSPierre Jolivet 11906511a5cSPierre Jolivet .seealso: MatCreateHermitianTranspose() 12006511a5cSPierre Jolivet 12106511a5cSPierre Jolivet @*/ 12206511a5cSPierre Jolivet PetscErrorCode MatHermitianTransposeGetMat(Mat A,Mat *M) 12306511a5cSPierre Jolivet { 12406511a5cSPierre Jolivet PetscErrorCode ierr; 12506511a5cSPierre Jolivet 12606511a5cSPierre Jolivet PetscFunctionBegin; 12706511a5cSPierre Jolivet PetscValidHeaderSpecific(A,MAT_CLASSID,1); 12806511a5cSPierre Jolivet PetscValidType(A,1); 12906511a5cSPierre Jolivet PetscValidPointer(M,2); 13006511a5cSPierre Jolivet ierr = PetscUseMethod(A,"MatHermitianTransposeGetMat_C",(Mat,Mat*),(A,M));CHKERRQ(ierr); 13106511a5cSPierre Jolivet PetscFunctionReturn(0); 13206511a5cSPierre Jolivet } 13306511a5cSPierre Jolivet 134d0de2241SAndrew Spott /*@ 135d0de2241SAndrew Spott MatCreateHermitianTranspose - Creates a new matrix object that behaves like A'* 136d0de2241SAndrew Spott 137d0de2241SAndrew Spott Collective on Mat 138d0de2241SAndrew Spott 139d0de2241SAndrew Spott Input Parameter: 140d0de2241SAndrew Spott . A - the (possibly rectangular) matrix 141d0de2241SAndrew Spott 142d0de2241SAndrew Spott Output Parameter: 143d0de2241SAndrew Spott . N - the matrix that represents A'* 144d0de2241SAndrew Spott 145d0de2241SAndrew Spott Level: intermediate 146d0de2241SAndrew Spott 14795452b02SPatrick Sanan Notes: 14895452b02SPatrick Sanan The hermitian transpose A' is NOT actually formed! Rather the new matrix 149d0de2241SAndrew Spott object performs the matrix-vector product by using the MatMultHermitianTranspose() on 150d0de2241SAndrew Spott the original matrix 151d0de2241SAndrew Spott 152d0de2241SAndrew Spott .seealso: MatCreateNormal(), MatMult(), MatMultHermitianTranspose(), MatCreate() 153d0de2241SAndrew Spott 154d0de2241SAndrew Spott @*/ 155d0de2241SAndrew Spott PetscErrorCode MatCreateHermitianTranspose(Mat A,Mat *N) 156d0de2241SAndrew Spott { 157d0de2241SAndrew Spott PetscErrorCode ierr; 158d0de2241SAndrew Spott PetscInt m,n; 159fb41c00aSBarry Smith Mat_HT *Na; 160d0de2241SAndrew Spott 161d0de2241SAndrew Spott PetscFunctionBegin; 162d0de2241SAndrew Spott ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 163d0de2241SAndrew Spott ierr = MatCreate(PetscObjectComm((PetscObject)A),N);CHKERRQ(ierr); 164d0de2241SAndrew Spott ierr = MatSetSizes(*N,n,m,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 165d0de2241SAndrew Spott ierr = PetscLayoutSetUp((*N)->rmap);CHKERRQ(ierr); 166d0de2241SAndrew Spott ierr = PetscLayoutSetUp((*N)->cmap);CHKERRQ(ierr); 167d0de2241SAndrew Spott ierr = PetscObjectChangeTypeName((PetscObject)*N,MATTRANSPOSEMAT);CHKERRQ(ierr); 168d0de2241SAndrew Spott 169d0de2241SAndrew Spott ierr = PetscNewLog(*N,&Na);CHKERRQ(ierr); 170d0de2241SAndrew Spott (*N)->data = (void*) Na; 171d0de2241SAndrew Spott ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 172d0de2241SAndrew Spott Na->A = A; 173d0de2241SAndrew Spott 174fb41c00aSBarry Smith (*N)->ops->destroy = MatDestroy_HT; 175fb41c00aSBarry Smith (*N)->ops->mult = MatMult_HT; 176fb41c00aSBarry Smith (*N)->ops->multadd = MatMultAdd_HT; 177fb41c00aSBarry Smith (*N)->ops->multhermitiantranspose = MatMultHermitianTranspose_HT; 178fb41c00aSBarry Smith (*N)->ops->multhermitiantransposeadd = MatMultHermitianTransposeAdd_HT; 179fb41c00aSBarry Smith (*N)->ops->duplicate = MatDuplicate_HT; 18006511a5cSPierre Jolivet (*N)->ops->getvecs = MatCreateVecs_HT; 181*6171f1c8SPierre Jolivet (*N)->ops->axpy = MatAXPY_HT; 182d0de2241SAndrew Spott (*N)->assembled = PETSC_TRUE; 183d0de2241SAndrew Spott 18406511a5cSPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)(*N),"MatHermitianTransposeGetMat_C",MatHermitianTransposeGetMat_HT);CHKERRQ(ierr); 185d0de2241SAndrew Spott ierr = MatSetBlockSizes(*N,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 186d0de2241SAndrew Spott ierr = MatSetUp(*N);CHKERRQ(ierr); 187d0de2241SAndrew Spott PetscFunctionReturn(0); 188d0de2241SAndrew Spott } 189