Actual source code: htransm.c
petsc-3.14.6 2021-03-30
2: #include <petsc/private/matimpl.h>
4: typedef struct {
5: Mat A;
6: } Mat_HT;
8: PetscErrorCode MatMult_HT(Mat N,Vec x,Vec y)
9: {
10: Mat_HT *Na = (Mat_HT*)N->data;
14: MatMultHermitianTranspose(Na->A,x,y);
15: return(0);
16: }
18: PetscErrorCode MatMultAdd_HT(Mat N,Vec v1,Vec v2,Vec v3)
19: {
20: Mat_HT *Na = (Mat_HT*)N->data;
24: MatMultHermitianTransposeAdd(Na->A,v1,v2,v3);
25: return(0);
26: }
28: PetscErrorCode MatMultHermitianTranspose_HT(Mat N,Vec x,Vec y)
29: {
30: Mat_HT *Na = (Mat_HT*)N->data;
34: MatMult(Na->A,x,y);
35: return(0);
36: }
38: PetscErrorCode MatMultHermitianTransposeAdd_HT(Mat N,Vec v1,Vec v2,Vec v3)
39: {
40: Mat_HT *Na = (Mat_HT*)N->data;
44: MatMultAdd(Na->A,v1,v2,v3);
45: return(0);
46: }
48: PetscErrorCode MatDestroy_HT(Mat N)
49: {
50: Mat_HT *Na = (Mat_HT*)N->data;
54: MatDestroy(&Na->A);
55: PetscObjectComposeFunction((PetscObject)N,"MatHermitianTransposeGetMat_C",NULL);
56: #if !defined(PETSC_USE_COMPLEX)
57: PetscObjectComposeFunction((PetscObject)N,"MatTransposeGetMat_C",NULL);
58: PetscObjectComposeFunction((PetscObject)N,"MatProductSetFromOptions_anytype_C",NULL);
59: #endif
60: PetscFree(N->data);
61: return(0);
62: }
64: PetscErrorCode MatDuplicate_HT(Mat N, MatDuplicateOption op, Mat* m)
65: {
66: Mat_HT *Na = (Mat_HT*)N->data;
70: if (op == MAT_COPY_VALUES) {
71: MatHermitianTranspose(Na->A,MAT_INITIAL_MATRIX,m);
72: } else if (op == MAT_DO_NOT_COPY_VALUES) {
73: MatDuplicate(Na->A,MAT_DO_NOT_COPY_VALUES,m);
74: MatHermitianTranspose(*m,MAT_INPLACE_MATRIX,m);
75: } else SETERRQ(PetscObjectComm((PetscObject)N),PETSC_ERR_SUP,"MAT_SHARE_NONZERO_PATTERN not supported for this matrix type");
76: return(0);
77: }
79: PetscErrorCode MatCreateVecs_HT(Mat N,Vec *r, Vec *l)
80: {
81: Mat_HT *Na = (Mat_HT*)N->data;
85: MatCreateVecs(Na->A,l,r);
86: return(0);
87: }
89: PetscErrorCode MatAXPY_HT(Mat Y,PetscScalar a,Mat X,MatStructure str)
90: {
91: Mat_HT *Ya = (Mat_HT*)Y->data;
92: Mat_HT *Xa = (Mat_HT*)X->data;
93: Mat M = Ya->A;
94: Mat N = Xa->A;
98: MatAXPY(M,a,N,str);
99: return(0);
100: }
102: PetscErrorCode MatHermitianTransposeGetMat_HT(Mat N,Mat *M)
103: {
104: Mat_HT *Na = (Mat_HT*)N->data;
107: *M = Na->A;
108: return(0);
109: }
111: /*@
112: MatHermitianTransposeGetMat - Gets the Mat object stored inside a MATTRANSPOSEMAT
114: Logically collective on Mat
116: Input Parameter:
117: . A - the MATTRANSPOSE matrix
119: Output Parameter:
120: . M - the matrix object stored inside A
122: Level: intermediate
124: .seealso: MatCreateHermitianTranspose()
126: @*/
127: PetscErrorCode MatHermitianTransposeGetMat(Mat A,Mat *M)
128: {
135: PetscUseMethod(A,"MatHermitianTransposeGetMat_C",(Mat,Mat*),(A,M));
136: return(0);
137: }
139: PETSC_INTERN PetscErrorCode MatProductSetFromOptions_Transpose(Mat);
141: /*@
142: MatCreateHermitianTranspose - Creates a new matrix object that behaves like A'*
144: Collective on Mat
146: Input Parameter:
147: . A - the (possibly rectangular) matrix
149: Output Parameter:
150: . N - the matrix that represents A'*
152: Level: intermediate
154: Notes:
155: The hermitian transpose A' is NOT actually formed! Rather the new matrix
156: object performs the matrix-vector product by using the MatMultHermitianTranspose() on
157: the original matrix
159: .seealso: MatCreateNormal(), MatMult(), MatMultHermitianTranspose(), MatCreate()
161: @*/
162: PetscErrorCode MatCreateHermitianTranspose(Mat A,Mat *N)
163: {
165: PetscInt m,n;
166: Mat_HT *Na;
167: VecType vtype;
170: MatGetLocalSize(A,&m,&n);
171: MatCreate(PetscObjectComm((PetscObject)A),N);
172: MatSetSizes(*N,n,m,PETSC_DECIDE,PETSC_DECIDE);
173: PetscLayoutSetUp((*N)->rmap);
174: PetscLayoutSetUp((*N)->cmap);
175: PetscObjectChangeTypeName((PetscObject)*N,MATTRANSPOSEMAT);
177: PetscNewLog(*N,&Na);
178: (*N)->data = (void*) Na;
179: PetscObjectReference((PetscObject)A);
180: Na->A = A;
182: (*N)->ops->destroy = MatDestroy_HT;
183: (*N)->ops->mult = MatMult_HT;
184: (*N)->ops->multadd = MatMultAdd_HT;
185: (*N)->ops->multhermitiantranspose = MatMultHermitianTranspose_HT;
186: (*N)->ops->multhermitiantransposeadd = MatMultHermitianTransposeAdd_HT;
187: (*N)->ops->duplicate = MatDuplicate_HT;
188: (*N)->ops->getvecs = MatCreateVecs_HT;
189: (*N)->ops->axpy = MatAXPY_HT;
190: #if !defined(PETSC_USE_COMPLEX)
191: (*N)->ops->productsetfromoptions = MatProductSetFromOptions_Transpose;
192: #endif
193: (*N)->assembled = PETSC_TRUE;
195: PetscObjectComposeFunction((PetscObject)(*N),"MatHermitianTransposeGetMat_C",MatHermitianTransposeGetMat_HT);
196: #if !defined(PETSC_USE_COMPLEX)
197: PetscObjectComposeFunction((PetscObject)(*N),"MatTransposeGetMat_C",MatHermitianTransposeGetMat_HT);
198: PetscObjectComposeFunction((PetscObject)(*N),"MatProductSetFromOptions_anytype_C",MatProductSetFromOptions_Transpose);
199: #endif
200: MatSetBlockSizes(*N,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));
201: MatGetVecType(A,&vtype);
202: MatSetVecType(*N,vtype);
203: MatSetUp(*N);
204: return(0);
205: }