1 2 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 3 4 typedef struct { 5 Mat A; 6 } Mat_Transpose; 7 8 #undef __FUNCT__ 9 #define __FUNCT__ "MatMult_Transpose" 10 PetscErrorCode MatMult_Transpose(Mat N,Vec x,Vec y) 11 { 12 Mat_Transpose *Na = (Mat_Transpose*)N->data; 13 PetscErrorCode ierr; 14 15 PetscFunctionBegin; 16 ierr = MatMultTranspose(Na->A,x,y);CHKERRQ(ierr); 17 PetscFunctionReturn(0); 18 } 19 20 #undef __FUNCT__ 21 #define __FUNCT__ "MatMultAdd_Transpose" 22 PetscErrorCode MatMultAdd_Transpose(Mat N,Vec v1,Vec v2,Vec v3) 23 { 24 Mat_Transpose *Na = (Mat_Transpose*)N->data; 25 PetscErrorCode ierr; 26 27 PetscFunctionBegin; 28 ierr = MatMultTransposeAdd(Na->A,v1,v2,v3);CHKERRQ(ierr); 29 PetscFunctionReturn(0); 30 } 31 32 #undef __FUNCT__ 33 #define __FUNCT__ "MatMultTranspose_Transpose" 34 PetscErrorCode MatMultTranspose_Transpose(Mat N,Vec x,Vec y) 35 { 36 Mat_Transpose *Na = (Mat_Transpose*)N->data; 37 PetscErrorCode ierr; 38 39 PetscFunctionBegin; 40 ierr = MatMult(Na->A,x,y);CHKERRQ(ierr); 41 PetscFunctionReturn(0); 42 } 43 44 #undef __FUNCT__ 45 #define __FUNCT__ "MatMultTransposeAdd_Transpose" 46 PetscErrorCode MatMultTransposeAdd_Transpose(Mat N,Vec v1,Vec v2,Vec v3) 47 { 48 Mat_Transpose *Na = (Mat_Transpose*)N->data; 49 PetscErrorCode ierr; 50 51 PetscFunctionBegin; 52 ierr = MatMultAdd(Na->A,v1,v2,v3);CHKERRQ(ierr); 53 PetscFunctionReturn(0); 54 } 55 56 #undef __FUNCT__ 57 #define __FUNCT__ "MatDestroy_Transpose" 58 PetscErrorCode MatDestroy_Transpose(Mat N) 59 { 60 Mat_Transpose *Na = (Mat_Transpose*)N->data; 61 PetscErrorCode ierr; 62 63 PetscFunctionBegin; 64 ierr = MatDestroy(&Na->A);CHKERRQ(ierr); 65 ierr = PetscObjectComposeFunction((PetscObject)N,"MatTransposeGetMat_C",NULL);CHKERRQ(ierr); 66 ierr = PetscFree(N->data);CHKERRQ(ierr); 67 PetscFunctionReturn(0); 68 } 69 70 #undef __FUNCT__ 71 #define __FUNCT__ "MatDuplicate_Transpose" 72 PetscErrorCode MatDuplicate_Transpose(Mat N, MatDuplicateOption op, Mat* m) 73 { 74 Mat_Transpose *Na = (Mat_Transpose*)N->data; 75 PetscErrorCode ierr; 76 77 PetscFunctionBegin; 78 if (op == MAT_COPY_VALUES) { 79 ierr = MatTranspose(Na->A,MAT_INITIAL_MATRIX,m);CHKERRQ(ierr); 80 } else if (op == MAT_DO_NOT_COPY_VALUES) { 81 ierr = MatDuplicate(Na->A,MAT_DO_NOT_COPY_VALUES,m);CHKERRQ(ierr); 82 ierr = MatTranspose(*m,MAT_REUSE_MATRIX,m);CHKERRQ(ierr); 83 } else SETERRQ(PetscObjectComm((PetscObject)N),PETSC_ERR_SUP,"MAT_SHARE_NONZERO_PATTERN not supported for this matrix type"); 84 PetscFunctionReturn(0); 85 } 86 87 #undef __FUNCT__ 88 #define __FUNCT__ "MatTransposeGetMat_Transpose" 89 PetscErrorCode MatTransposeGetMat_Transpose(Mat A,Mat *M) 90 { 91 Mat_Transpose *Aa = (Mat_Transpose*)A->data; 92 93 PetscFunctionBegin; 94 *M = Aa->A; 95 PetscFunctionReturn(0); 96 } 97 98 #undef __FUNCT__ 99 #define __FUNCT__ "MatTransposeGetMat" 100 /*@ 101 MatTransposeGetMat - Gets the Mat object stored inside a MATTRANSPOSEMAT' 102 103 Logically collective on Mat 104 105 Input Parameter: 106 . A - the MATTRANSPOSE matrix 107 108 Output Parameter: 109 . M - the matrix object stored inside A 110 111 Level: intermediate 112 113 .seealso: MatCreateTranspose() 114 115 @*/ 116 PetscErrorCode MatTransposeGetMat(Mat A,Mat *M) 117 { 118 PetscErrorCode ierr; 119 120 PetscFunctionBegin; 121 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 122 PetscValidType(A,1); 123 PetscValidPointer(M,2); 124 ierr = PetscUseMethod(A,"MatTransposeGetMat_C",(Mat,Mat*),(A,M));CHKERRQ(ierr); 125 PetscFunctionReturn(0); 126 } 127 128 #undef __FUNCT__ 129 #define __FUNCT__ "MatCreateTranspose" 130 /*@ 131 MatCreateTranspose - Creates a new matrix object that behaves like A' 132 133 Collective on Mat 134 135 Input Parameter: 136 . A - the (possibly rectangular) matrix 137 138 Output Parameter: 139 . N - the matrix that represents A' 140 141 Level: intermediate 142 143 Notes: The transpose A' is NOT actually formed! Rather the new matrix 144 object performs the matrix-vector product by using the MatMultTranspose() on 145 the original matrix 146 147 .seealso: MatCreateNormal(), MatMult(), MatMultTranspose(), MatCreate() 148 149 @*/ 150 PetscErrorCode MatCreateTranspose(Mat A,Mat *N) 151 { 152 PetscErrorCode ierr; 153 PetscInt m,n; 154 Mat_Transpose *Na; 155 156 PetscFunctionBegin; 157 ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 158 ierr = MatCreate(PetscObjectComm((PetscObject)A),N);CHKERRQ(ierr); 159 ierr = MatSetSizes(*N,n,m,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 160 ierr = PetscLayoutSetUp((*N)->rmap);CHKERRQ(ierr); 161 ierr = PetscLayoutSetUp((*N)->cmap);CHKERRQ(ierr); 162 ierr = PetscObjectChangeTypeName((PetscObject)*N,MATTRANSPOSEMAT);CHKERRQ(ierr); 163 164 ierr = PetscNewLog(*N,&Na);CHKERRQ(ierr); 165 (*N)->data = (void*) Na; 166 ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 167 Na->A = A; 168 169 (*N)->ops->destroy = MatDestroy_Transpose; 170 (*N)->ops->mult = MatMult_Transpose; 171 (*N)->ops->multadd = MatMultAdd_Transpose; 172 (*N)->ops->multtranspose = MatMultTranspose_Transpose; 173 (*N)->ops->multtransposeadd = MatMultTransposeAdd_Transpose; 174 (*N)->ops->duplicate = MatDuplicate_Transpose; 175 (*N)->assembled = PETSC_TRUE; 176 177 ierr = PetscObjectComposeFunction((PetscObject)(*N),"MatTransposeGetMat_C",MatTransposeGetMat_Transpose);CHKERRQ(ierr); 178 ierr = MatSetBlockSizes(*N,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 179 ierr = MatSetUp(*N);CHKERRQ(ierr); 180 PetscFunctionReturn(0); 181 } 182 183