185e3dda7SBarry Smith 2af0996ceSBarry Smith #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 385e3dda7SBarry Smith 485e3dda7SBarry Smith typedef struct { 585e3dda7SBarry Smith Mat A; 685e3dda7SBarry Smith } Mat_Transpose; 785e3dda7SBarry Smith 885e3dda7SBarry Smith #undef __FUNCT__ 985e3dda7SBarry Smith #define __FUNCT__ "MatMult_Transpose" 1085e3dda7SBarry Smith PetscErrorCode MatMult_Transpose(Mat N,Vec x,Vec y) 1185e3dda7SBarry Smith { 1285e3dda7SBarry Smith Mat_Transpose *Na = (Mat_Transpose*)N->data; 1385e3dda7SBarry Smith PetscErrorCode ierr; 1485e3dda7SBarry Smith 1585e3dda7SBarry Smith PetscFunctionBegin; 1685e3dda7SBarry Smith ierr = MatMultTranspose(Na->A,x,y);CHKERRQ(ierr); 1785e3dda7SBarry Smith PetscFunctionReturn(0); 1885e3dda7SBarry Smith } 1985e3dda7SBarry Smith 2085e3dda7SBarry Smith #undef __FUNCT__ 2185e3dda7SBarry Smith #define __FUNCT__ "MatMultAdd_Transpose" 2285e3dda7SBarry Smith PetscErrorCode MatMultAdd_Transpose(Mat N,Vec v1,Vec v2,Vec v3) 2385e3dda7SBarry Smith { 2485e3dda7SBarry Smith Mat_Transpose *Na = (Mat_Transpose*)N->data; 2585e3dda7SBarry Smith PetscErrorCode ierr; 2685e3dda7SBarry Smith 2785e3dda7SBarry Smith PetscFunctionBegin; 2885e3dda7SBarry Smith ierr = MatMultTransposeAdd(Na->A,v1,v2,v3);CHKERRQ(ierr); 2985e3dda7SBarry Smith PetscFunctionReturn(0); 3085e3dda7SBarry Smith } 3185e3dda7SBarry Smith 3285e3dda7SBarry Smith #undef __FUNCT__ 3347a9afc9SBarry Smith #define __FUNCT__ "MatMultTranspose_Transpose" 3447a9afc9SBarry Smith PetscErrorCode MatMultTranspose_Transpose(Mat N,Vec x,Vec y) 3547a9afc9SBarry Smith { 3647a9afc9SBarry Smith Mat_Transpose *Na = (Mat_Transpose*)N->data; 3747a9afc9SBarry Smith PetscErrorCode ierr; 3847a9afc9SBarry Smith 3947a9afc9SBarry Smith PetscFunctionBegin; 4047a9afc9SBarry Smith ierr = MatMult(Na->A,x,y);CHKERRQ(ierr); 4147a9afc9SBarry Smith PetscFunctionReturn(0); 4247a9afc9SBarry Smith } 4347a9afc9SBarry Smith 4447a9afc9SBarry Smith #undef __FUNCT__ 4547a9afc9SBarry Smith #define __FUNCT__ "MatMultTransposeAdd_Transpose" 4647a9afc9SBarry Smith PetscErrorCode MatMultTransposeAdd_Transpose(Mat N,Vec v1,Vec v2,Vec v3) 4747a9afc9SBarry Smith { 4847a9afc9SBarry Smith Mat_Transpose *Na = (Mat_Transpose*)N->data; 4947a9afc9SBarry Smith PetscErrorCode ierr; 5047a9afc9SBarry Smith 5147a9afc9SBarry Smith PetscFunctionBegin; 5247a9afc9SBarry Smith ierr = MatMultAdd(Na->A,v1,v2,v3);CHKERRQ(ierr); 5347a9afc9SBarry Smith PetscFunctionReturn(0); 5447a9afc9SBarry Smith } 5547a9afc9SBarry Smith 5647a9afc9SBarry Smith #undef __FUNCT__ 5785e3dda7SBarry Smith #define __FUNCT__ "MatDestroy_Transpose" 5885e3dda7SBarry Smith PetscErrorCode MatDestroy_Transpose(Mat N) 5985e3dda7SBarry Smith { 6085e3dda7SBarry Smith Mat_Transpose *Na = (Mat_Transpose*)N->data; 6185e3dda7SBarry Smith PetscErrorCode ierr; 6285e3dda7SBarry Smith 6385e3dda7SBarry Smith PetscFunctionBegin; 646bf464f9SBarry Smith ierr = MatDestroy(&Na->A);CHKERRQ(ierr); 65*8060fb66Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)N,"MatTransposeGetMat_C",NULL);CHKERRQ(ierr); 66bf0cc555SLisandro Dalcin ierr = PetscFree(N->data);CHKERRQ(ierr); 6785e3dda7SBarry Smith PetscFunctionReturn(0); 6885e3dda7SBarry Smith } 6985e3dda7SBarry Smith 7085e3dda7SBarry Smith #undef __FUNCT__ 71d0de2241SAndrew Spott #define __FUNCT__ "MatDuplicate_Transpose" 72d0de2241SAndrew Spott PetscErrorCode MatDuplicate_Transpose(Mat N, MatDuplicateOption op, Mat* m) 73d0de2241SAndrew Spott { 74d0de2241SAndrew Spott Mat_Transpose *Na = (Mat_Transpose*)N->data; 75d0de2241SAndrew Spott PetscErrorCode ierr; 76d0de2241SAndrew Spott 77d0de2241SAndrew Spott PetscFunctionBegin; 78d0de2241SAndrew Spott if (op == MAT_COPY_VALUES) { 79d0de2241SAndrew Spott ierr = MatTranspose(Na->A,MAT_INITIAL_MATRIX,m);CHKERRQ(ierr); 80d0de2241SAndrew Spott } else if (op == MAT_DO_NOT_COPY_VALUES) { 81d0de2241SAndrew Spott ierr = MatDuplicate(Na->A,MAT_DO_NOT_COPY_VALUES,m);CHKERRQ(ierr); 82d0de2241SAndrew Spott ierr = MatTranspose(*m,MAT_REUSE_MATRIX,m);CHKERRQ(ierr); 83fb41c00aSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)N),PETSC_ERR_SUP,"MAT_SHARE_NONZERO_PATTERN not supported for this matrix type"); 84d0de2241SAndrew Spott PetscFunctionReturn(0); 85d0de2241SAndrew Spott } 86d0de2241SAndrew Spott 87*8060fb66Sstefano_zampini #undef __FUNCT__ 88*8060fb66Sstefano_zampini #define __FUNCT__ "MatTransposeGetMat_Transpose" 89*8060fb66Sstefano_zampini PetscErrorCode MatTransposeGetMat_Transpose(Mat A,Mat *M) 90*8060fb66Sstefano_zampini { 91*8060fb66Sstefano_zampini Mat_Transpose *Aa = (Mat_Transpose*)A->data; 92*8060fb66Sstefano_zampini 93*8060fb66Sstefano_zampini PetscFunctionBegin; 94*8060fb66Sstefano_zampini *M = Aa->A; 95*8060fb66Sstefano_zampini PetscFunctionReturn(0); 96*8060fb66Sstefano_zampini } 97*8060fb66Sstefano_zampini 98*8060fb66Sstefano_zampini #undef __FUNCT__ 99*8060fb66Sstefano_zampini #define __FUNCT__ "MatTransposeGetMat" 100*8060fb66Sstefano_zampini /*@ 101*8060fb66Sstefano_zampini MatTransposeGetMat - Gets the Mat object stored inside a MATTRANSPOSEMAT' 102*8060fb66Sstefano_zampini 103*8060fb66Sstefano_zampini Logically collective on Mat 104*8060fb66Sstefano_zampini 105*8060fb66Sstefano_zampini Input Parameter: 106*8060fb66Sstefano_zampini . A - the MATTRANSPOSE matrix 107*8060fb66Sstefano_zampini 108*8060fb66Sstefano_zampini Output Parameter: 109*8060fb66Sstefano_zampini . M - the matrix object stored inside A 110*8060fb66Sstefano_zampini 111*8060fb66Sstefano_zampini Level: intermediate 112*8060fb66Sstefano_zampini 113*8060fb66Sstefano_zampini .seealso: MatCreateTranspose() 114*8060fb66Sstefano_zampini 115*8060fb66Sstefano_zampini @*/ 116*8060fb66Sstefano_zampini PetscErrorCode MatTransposeGetMat(Mat A,Mat *M) 117*8060fb66Sstefano_zampini { 118*8060fb66Sstefano_zampini PetscErrorCode ierr; 119*8060fb66Sstefano_zampini 120*8060fb66Sstefano_zampini PetscFunctionBegin; 121*8060fb66Sstefano_zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 122*8060fb66Sstefano_zampini PetscValidType(A,1); 123*8060fb66Sstefano_zampini PetscValidPointer(M,2); 124*8060fb66Sstefano_zampini ierr = PetscUseMethod(A,"MatTransposeGetMat_C",(Mat,Mat*),(A,M));CHKERRQ(ierr); 125*8060fb66Sstefano_zampini PetscFunctionReturn(0); 126*8060fb66Sstefano_zampini } 127d0de2241SAndrew Spott 128d0de2241SAndrew Spott #undef __FUNCT__ 12985e3dda7SBarry Smith #define __FUNCT__ "MatCreateTranspose" 13085e3dda7SBarry Smith /*@ 13185e3dda7SBarry Smith MatCreateTranspose - Creates a new matrix object that behaves like A' 13285e3dda7SBarry Smith 13385e3dda7SBarry Smith Collective on Mat 13485e3dda7SBarry Smith 13585e3dda7SBarry Smith Input Parameter: 13685e3dda7SBarry Smith . A - the (possibly rectangular) matrix 13785e3dda7SBarry Smith 13885e3dda7SBarry Smith Output Parameter: 13985e3dda7SBarry Smith . N - the matrix that represents A' 14085e3dda7SBarry Smith 14185e3dda7SBarry Smith Level: intermediate 14285e3dda7SBarry Smith 14385e3dda7SBarry Smith Notes: The transpose A' is NOT actually formed! Rather the new matrix 14485e3dda7SBarry Smith object performs the matrix-vector product by using the MatMultTranspose() on 14585e3dda7SBarry Smith the original matrix 14685e3dda7SBarry Smith 14785e3dda7SBarry Smith .seealso: MatCreateNormal(), MatMult(), MatMultTranspose(), MatCreate() 14885e3dda7SBarry Smith 14985e3dda7SBarry Smith @*/ 1507087cfbeSBarry Smith PetscErrorCode MatCreateTranspose(Mat A,Mat *N) 15185e3dda7SBarry Smith { 15285e3dda7SBarry Smith PetscErrorCode ierr; 15385e3dda7SBarry Smith PetscInt m,n; 15485e3dda7SBarry Smith Mat_Transpose *Na; 15585e3dda7SBarry Smith 15685e3dda7SBarry Smith PetscFunctionBegin; 15785e3dda7SBarry Smith ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 158ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),N);CHKERRQ(ierr); 15985e3dda7SBarry Smith ierr = MatSetSizes(*N,n,m,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 160d97d01c0SJed Brown ierr = PetscLayoutSetUp((*N)->rmap);CHKERRQ(ierr); 161d97d01c0SJed Brown ierr = PetscLayoutSetUp((*N)->cmap);CHKERRQ(ierr); 162557cca28SSatish Balay ierr = PetscObjectChangeTypeName((PetscObject)*N,MATTRANSPOSEMAT);CHKERRQ(ierr); 16385e3dda7SBarry Smith 164b00a9115SJed Brown ierr = PetscNewLog(*N,&Na);CHKERRQ(ierr); 16585e3dda7SBarry Smith (*N)->data = (void*) Na; 16685e3dda7SBarry Smith ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 16785e3dda7SBarry Smith Na->A = A; 16885e3dda7SBarry Smith 16985e3dda7SBarry Smith (*N)->ops->destroy = MatDestroy_Transpose; 17085e3dda7SBarry Smith (*N)->ops->mult = MatMult_Transpose; 1716d12b599SJed Brown (*N)->ops->multadd = MatMultAdd_Transpose; 17247a9afc9SBarry Smith (*N)->ops->multtranspose = MatMultTranspose_Transpose; 17347a9afc9SBarry Smith (*N)->ops->multtransposeadd = MatMultTransposeAdd_Transpose; 174d0de2241SAndrew Spott (*N)->ops->duplicate = MatDuplicate_Transpose; 17585e3dda7SBarry Smith (*N)->assembled = PETSC_TRUE; 17685e3dda7SBarry Smith 177*8060fb66Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)(*N),"MatTransposeGetMat_C",MatTransposeGetMat_Transpose);CHKERRQ(ierr); 17833d57670SJed Brown ierr = MatSetBlockSizes(*N,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 179037c98a2SJed Brown ierr = MatSetUp(*N);CHKERRQ(ierr); 18085e3dda7SBarry Smith PetscFunctionReturn(0); 18185e3dda7SBarry Smith } 18285e3dda7SBarry Smith 183