Actual source code: transm.c

petsc-3.13.6 2020-09-29
Report Typos and Errors

  2:  #include <petsc/private/matimpl.h>

  4: typedef struct {
  5:   Mat A;
  6: } Mat_Transpose;

  8: PetscErrorCode MatMult_Transpose(Mat N,Vec x,Vec y)
  9: {
 10:   Mat_Transpose  *Na = (Mat_Transpose*)N->data;

 14:   MatMultTranspose(Na->A,x,y);
 15:   return(0);
 16: }

 18: PetscErrorCode MatMultAdd_Transpose(Mat N,Vec v1,Vec v2,Vec v3)
 19: {
 20:   Mat_Transpose  *Na = (Mat_Transpose*)N->data;

 24:   MatMultTransposeAdd(Na->A,v1,v2,v3);
 25:   return(0);
 26: }

 28: PetscErrorCode MatMultTranspose_Transpose(Mat N,Vec x,Vec y)
 29: {
 30:   Mat_Transpose  *Na = (Mat_Transpose*)N->data;

 34:   MatMult(Na->A,x,y);
 35:   return(0);
 36: }

 38: PetscErrorCode MatMultTransposeAdd_Transpose(Mat N,Vec v1,Vec v2,Vec v3)
 39: {
 40:   Mat_Transpose  *Na = (Mat_Transpose*)N->data;

 44:   MatMultAdd(Na->A,v1,v2,v3);
 45:   return(0);
 46: }

 48: PetscErrorCode MatDestroy_Transpose(Mat N)
 49: {
 50:   Mat_Transpose  *Na = (Mat_Transpose*)N->data;

 54:   MatDestroy(&Na->A);
 55:   PetscObjectComposeFunction((PetscObject)N,"MatTransposeGetMat_C",NULL);
 56:   PetscFree(N->data);
 57:   return(0);
 58: }

 60: PetscErrorCode MatDuplicate_Transpose(Mat N, MatDuplicateOption op, Mat* m)
 61: {
 62:   Mat_Transpose  *Na = (Mat_Transpose*)N->data;

 66:   if (op == MAT_COPY_VALUES) {
 67:     MatTranspose(Na->A,MAT_INITIAL_MATRIX,m);
 68:   } else if (op == MAT_DO_NOT_COPY_VALUES) {
 69:     MatDuplicate(Na->A,MAT_DO_NOT_COPY_VALUES,m);
 70:     MatTranspose(*m,MAT_INPLACE_MATRIX,m);
 71:   } else SETERRQ(PetscObjectComm((PetscObject)N),PETSC_ERR_SUP,"MAT_SHARE_NONZERO_PATTERN not supported for this matrix type");
 72:   return(0);
 73: }

 75: PetscErrorCode MatCreateVecs_Transpose(Mat A,Vec *r, Vec *l)
 76: {
 77:   Mat_Transpose  *Aa = (Mat_Transpose*)A->data;

 81:   MatCreateVecs(Aa->A,l,r);
 82:   return(0);
 83: }

 85: PetscErrorCode MatAXPY_Transpose(Mat Y,PetscScalar a,Mat X,MatStructure str)
 86: {
 87:   Mat_Transpose  *Ya = (Mat_Transpose*)Y->data;
 88:   Mat_Transpose  *Xa = (Mat_Transpose*)X->data;
 89:   Mat              M = Ya->A;
 90:   Mat              N = Xa->A;

 94:   MatAXPY(M,a,N,str);
 95:   return(0);
 96: }

 98: PetscErrorCode MatHasOperation_Transpose(Mat mat,MatOperation op,PetscBool *has)
 99: {
100:   Mat_Transpose  *X = (Mat_Transpose*)mat->data;

104:   *has = PETSC_FALSE;
105:   if (op == MATOP_MULT) {
106:     MatHasOperation(X->A,MATOP_MULT_TRANSPOSE,has);
107:   } else if (op == MATOP_MULT_TRANSPOSE) {
108:     MatHasOperation(X->A,MATOP_MULT,has);
109:   } else if (op == MATOP_MULT_ADD) {
110:     MatHasOperation(X->A,MATOP_MULT_TRANSPOSE_ADD,has);
111:   } else if (op == MATOP_MULT_TRANSPOSE_ADD) {
112:     MatHasOperation(X->A,MATOP_MULT_ADD,has);
113:   } else if (((void**)mat->ops)[op]) *has = PETSC_TRUE;
114:   return(0);
115: }

117: PetscErrorCode MatTransposeGetMat_Transpose(Mat A,Mat *M)
118: {
119:   Mat_Transpose  *Aa = (Mat_Transpose*)A->data;

122:   *M = Aa->A;
123:   return(0);
124: }

126: /*@
127:       MatTransposeGetMat - Gets the Mat object stored inside a MATTRANSPOSEMAT

129:    Logically collective on Mat

131:    Input Parameter:
132: .   A  - the MATTRANSPOSE matrix

134:    Output Parameter:
135: .   M - the matrix object stored inside A

137:    Level: intermediate

139: .seealso: MatCreateTranspose()

141: @*/
142: PetscErrorCode MatTransposeGetMat(Mat A,Mat *M)
143: {

150:   PetscUseMethod(A,"MatTransposeGetMat_C",(Mat,Mat*),(A,M));
151:   return(0);
152: }

154: /*@
155:       MatCreateTranspose - Creates a new matrix object that behaves like A'

157:    Collective on Mat

159:    Input Parameter:
160: .   A  - the (possibly rectangular) matrix

162:    Output Parameter:
163: .   N - the matrix that represents A'

165:    Level: intermediate

167:    Notes:
168:     The transpose A' is NOT actually formed! Rather the new matrix
169:           object performs the matrix-vector product by using the MatMultTranspose() on
170:           the original matrix

172: .seealso: MatCreateNormal(), MatMult(), MatMultTranspose(), MatCreate()

174: @*/
175: PetscErrorCode  MatCreateTranspose(Mat A,Mat *N)
176: {
178:   PetscInt       m,n;
179:   Mat_Transpose  *Na;

182:   MatGetLocalSize(A,&m,&n);
183:   MatCreate(PetscObjectComm((PetscObject)A),N);
184:   MatSetSizes(*N,n,m,PETSC_DECIDE,PETSC_DECIDE);
185:   PetscLayoutSetUp((*N)->rmap);
186:   PetscLayoutSetUp((*N)->cmap);
187:   PetscObjectChangeTypeName((PetscObject)*N,MATTRANSPOSEMAT);

189:   PetscNewLog(*N,&Na);
190:   (*N)->data = (void*) Na;
191:   PetscObjectReference((PetscObject)A);
192:   Na->A      = A;

194:   (*N)->ops->destroy          = MatDestroy_Transpose;
195:   (*N)->ops->mult             = MatMult_Transpose;
196:   (*N)->ops->multadd          = MatMultAdd_Transpose;
197:   (*N)->ops->multtranspose    = MatMultTranspose_Transpose;
198:   (*N)->ops->multtransposeadd = MatMultTransposeAdd_Transpose;
199:   (*N)->ops->duplicate        = MatDuplicate_Transpose;
200:   (*N)->ops->getvecs          = MatCreateVecs_Transpose;
201:   (*N)->ops->axpy             = MatAXPY_Transpose;
202:   (*N)->ops->hasoperation     = MatHasOperation_Transpose;
203:   (*N)->assembled             = PETSC_TRUE;

205:   PetscObjectComposeFunction((PetscObject)(*N),"MatTransposeGetMat_C",MatTransposeGetMat_Transpose);
206:   MatSetBlockSizes(*N,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));
207:   MatSetUp(*N);
208:   return(0);
209: }