xref: /petsc/src/mat/impls/transpose/transm.c (revision ecd1d7b800a8e5d54bd2bb04019759f2bc8b1326)
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