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 PetscErrorCode MatMult_Transpose(Mat N,Vec x,Vec y) 985e3dda7SBarry Smith { 1085e3dda7SBarry Smith Mat_Transpose *Na = (Mat_Transpose*)N->data; 1185e3dda7SBarry Smith PetscErrorCode ierr; 1285e3dda7SBarry Smith 1385e3dda7SBarry Smith PetscFunctionBegin; 1485e3dda7SBarry Smith ierr = MatMultTranspose(Na->A,x,y);CHKERRQ(ierr); 1585e3dda7SBarry Smith PetscFunctionReturn(0); 1685e3dda7SBarry Smith } 1785e3dda7SBarry Smith 1885e3dda7SBarry Smith PetscErrorCode MatMultAdd_Transpose(Mat N,Vec v1,Vec v2,Vec v3) 1985e3dda7SBarry Smith { 2085e3dda7SBarry Smith Mat_Transpose *Na = (Mat_Transpose*)N->data; 2185e3dda7SBarry Smith PetscErrorCode ierr; 2285e3dda7SBarry Smith 2385e3dda7SBarry Smith PetscFunctionBegin; 2485e3dda7SBarry Smith ierr = MatMultTransposeAdd(Na->A,v1,v2,v3);CHKERRQ(ierr); 2585e3dda7SBarry Smith PetscFunctionReturn(0); 2685e3dda7SBarry Smith } 2785e3dda7SBarry Smith 2847a9afc9SBarry Smith PetscErrorCode MatMultTranspose_Transpose(Mat N,Vec x,Vec y) 2947a9afc9SBarry Smith { 3047a9afc9SBarry Smith Mat_Transpose *Na = (Mat_Transpose*)N->data; 3147a9afc9SBarry Smith PetscErrorCode ierr; 3247a9afc9SBarry Smith 3347a9afc9SBarry Smith PetscFunctionBegin; 3447a9afc9SBarry Smith ierr = MatMult(Na->A,x,y);CHKERRQ(ierr); 3547a9afc9SBarry Smith PetscFunctionReturn(0); 3647a9afc9SBarry Smith } 3747a9afc9SBarry Smith 3847a9afc9SBarry Smith PetscErrorCode MatMultTransposeAdd_Transpose(Mat N,Vec v1,Vec v2,Vec v3) 3947a9afc9SBarry Smith { 4047a9afc9SBarry Smith Mat_Transpose *Na = (Mat_Transpose*)N->data; 4147a9afc9SBarry Smith PetscErrorCode ierr; 4247a9afc9SBarry Smith 4347a9afc9SBarry Smith PetscFunctionBegin; 4447a9afc9SBarry Smith ierr = MatMultAdd(Na->A,v1,v2,v3);CHKERRQ(ierr); 4547a9afc9SBarry Smith PetscFunctionReturn(0); 4647a9afc9SBarry Smith } 4747a9afc9SBarry Smith 4885e3dda7SBarry Smith PetscErrorCode MatDestroy_Transpose(Mat N) 4985e3dda7SBarry Smith { 5085e3dda7SBarry Smith Mat_Transpose *Na = (Mat_Transpose*)N->data; 5185e3dda7SBarry Smith PetscErrorCode ierr; 5285e3dda7SBarry Smith 5385e3dda7SBarry Smith PetscFunctionBegin; 546bf464f9SBarry Smith ierr = MatDestroy(&Na->A);CHKERRQ(ierr); 558060fb66Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)N,"MatTransposeGetMat_C",NULL);CHKERRQ(ierr); 566718818eSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)N,"MatProductSetFromOptions_anytype_C",NULL);CHKERRQ(ierr); 57bf0cc555SLisandro Dalcin ierr = PetscFree(N->data);CHKERRQ(ierr); 5885e3dda7SBarry Smith PetscFunctionReturn(0); 5985e3dda7SBarry Smith } 6085e3dda7SBarry Smith 61d0de2241SAndrew Spott PetscErrorCode MatDuplicate_Transpose(Mat N, MatDuplicateOption op, Mat* m) 62d0de2241SAndrew Spott { 63d0de2241SAndrew Spott Mat_Transpose *Na = (Mat_Transpose*)N->data; 64d0de2241SAndrew Spott PetscErrorCode ierr; 65d0de2241SAndrew Spott 66d0de2241SAndrew Spott PetscFunctionBegin; 67d0de2241SAndrew Spott if (op == MAT_COPY_VALUES) { 68d0de2241SAndrew Spott ierr = MatTranspose(Na->A,MAT_INITIAL_MATRIX,m);CHKERRQ(ierr); 69d0de2241SAndrew Spott } else if (op == MAT_DO_NOT_COPY_VALUES) { 70d0de2241SAndrew Spott ierr = MatDuplicate(Na->A,MAT_DO_NOT_COPY_VALUES,m);CHKERRQ(ierr); 71c837ededSStefano Zampini ierr = MatTranspose(*m,MAT_INPLACE_MATRIX,m);CHKERRQ(ierr); 72fb41c00aSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)N),PETSC_ERR_SUP,"MAT_SHARE_NONZERO_PATTERN not supported for this matrix type"); 73d0de2241SAndrew Spott PetscFunctionReturn(0); 74d0de2241SAndrew Spott } 75d0de2241SAndrew Spott 76d9b48344SStefano Zampini PetscErrorCode MatCreateVecs_Transpose(Mat A,Vec *r, Vec *l) 77d9b48344SStefano Zampini { 78d9b48344SStefano Zampini Mat_Transpose *Aa = (Mat_Transpose*)A->data; 79d9b48344SStefano Zampini PetscErrorCode ierr; 80d9b48344SStefano Zampini 81d9b48344SStefano Zampini PetscFunctionBegin; 82d9b48344SStefano Zampini ierr = MatCreateVecs(Aa->A,l,r);CHKERRQ(ierr); 83d9b48344SStefano Zampini PetscFunctionReturn(0); 84d9b48344SStefano Zampini } 85d9b48344SStefano Zampini 866171f1c8SPierre Jolivet PetscErrorCode MatAXPY_Transpose(Mat Y,PetscScalar a,Mat X,MatStructure str) 876171f1c8SPierre Jolivet { 886171f1c8SPierre Jolivet Mat_Transpose *Ya = (Mat_Transpose*)Y->data; 896171f1c8SPierre Jolivet Mat_Transpose *Xa = (Mat_Transpose*)X->data; 906171f1c8SPierre Jolivet Mat M = Ya->A; 916171f1c8SPierre Jolivet Mat N = Xa->A; 926171f1c8SPierre Jolivet PetscErrorCode ierr; 936171f1c8SPierre Jolivet 946171f1c8SPierre Jolivet PetscFunctionBegin; 956171f1c8SPierre Jolivet ierr = MatAXPY(M,a,N,str);CHKERRQ(ierr); 966171f1c8SPierre Jolivet PetscFunctionReturn(0); 976171f1c8SPierre Jolivet } 986171f1c8SPierre Jolivet 9952c5f739Sprj- PetscErrorCode MatHasOperation_Transpose(Mat mat,MatOperation op,PetscBool *has) 10052c5f739Sprj- { 10152c5f739Sprj- Mat_Transpose *X = (Mat_Transpose*)mat->data; 10252c5f739Sprj- PetscErrorCode ierr; 10352c5f739Sprj- PetscFunctionBegin; 10452c5f739Sprj- 10552c5f739Sprj- *has = PETSC_FALSE; 1063c6db4c4SPierre Jolivet if (op == MATOP_MULT) { 1073c6db4c4SPierre Jolivet ierr = MatHasOperation(X->A,MATOP_MULT_TRANSPOSE,has);CHKERRQ(ierr); 1083c6db4c4SPierre Jolivet } else if (op == MATOP_MULT_TRANSPOSE) { 1093c6db4c4SPierre Jolivet ierr = MatHasOperation(X->A,MATOP_MULT,has);CHKERRQ(ierr); 1103c6db4c4SPierre Jolivet } else if (op == MATOP_MULT_ADD) { 1113c6db4c4SPierre Jolivet ierr = MatHasOperation(X->A,MATOP_MULT_TRANSPOSE_ADD,has);CHKERRQ(ierr); 1123c6db4c4SPierre Jolivet } else if (op == MATOP_MULT_TRANSPOSE_ADD) { 1133c6db4c4SPierre Jolivet ierr = MatHasOperation(X->A,MATOP_MULT_ADD,has);CHKERRQ(ierr); 1143c6db4c4SPierre Jolivet } else if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 11552c5f739Sprj- PetscFunctionReturn(0); 11652c5f739Sprj- } 11752c5f739Sprj- 1186718818eSStefano Zampini /* used by hermitian transpose */ 1196718818eSStefano Zampini PETSC_INTERN PetscErrorCode MatProductSetFromOptions_Transpose(Mat D) 1206718818eSStefano Zampini { 1216718818eSStefano Zampini Mat A,B,C,Ain,Bin,Cin; 1226718818eSStefano Zampini PetscBool Aistrans,Bistrans,Cistrans; 1236718818eSStefano Zampini PetscInt Atrans,Btrans,Ctrans; 1246718818eSStefano Zampini MatProductType ptype; 1256718818eSStefano Zampini PetscErrorCode ierr; 1266718818eSStefano Zampini 1276718818eSStefano Zampini PetscFunctionBegin; 1286718818eSStefano Zampini MatCheckProduct(D,1); 1296718818eSStefano Zampini A = D->product->A; 1306718818eSStefano Zampini B = D->product->B; 1316718818eSStefano Zampini C = D->product->C; 1326718818eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&Aistrans);CHKERRQ(ierr); 1336718818eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&Bistrans);CHKERRQ(ierr); 1346718818eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)C,MATTRANSPOSEMAT,&Cistrans);CHKERRQ(ierr); 1356718818eSStefano Zampini if (!Aistrans && !Bistrans && !Cistrans) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"This should not happen"); 1366718818eSStefano Zampini Atrans = 0; 1376718818eSStefano Zampini Ain = A; 1386718818eSStefano Zampini while (Aistrans) { 1396718818eSStefano Zampini Atrans++; 1406718818eSStefano Zampini ierr = MatTransposeGetMat(Ain,&Ain);CHKERRQ(ierr); 1416718818eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)Ain,MATTRANSPOSEMAT,&Aistrans);CHKERRQ(ierr); 1426718818eSStefano Zampini } 1436718818eSStefano Zampini Btrans = 0; 1446718818eSStefano Zampini Bin = B; 1456718818eSStefano Zampini while (Bistrans) { 1466718818eSStefano Zampini Btrans++; 1476718818eSStefano Zampini ierr = MatTransposeGetMat(Bin,&Bin);CHKERRQ(ierr); 1486718818eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)Bin,MATTRANSPOSEMAT,&Bistrans);CHKERRQ(ierr); 1496718818eSStefano Zampini } 1506718818eSStefano Zampini Ctrans = 0; 1516718818eSStefano Zampini Cin = C; 1526718818eSStefano Zampini while (Cistrans) { 1536718818eSStefano Zampini Ctrans++; 1546718818eSStefano Zampini ierr = MatTransposeGetMat(Cin,&Cin);CHKERRQ(ierr); 1556718818eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)Cin,MATTRANSPOSEMAT,&Cistrans);CHKERRQ(ierr); 1566718818eSStefano Zampini } 1576718818eSStefano Zampini Atrans = Atrans%2; 1586718818eSStefano Zampini Btrans = Btrans%2; 1596718818eSStefano Zampini Ctrans = Ctrans%2; 1606718818eSStefano Zampini ptype = D->product->type; /* same product type by default */ 1616718818eSStefano Zampini if (Ain->symmetric) Atrans = 0; 1626718818eSStefano Zampini if (Bin->symmetric) Btrans = 0; 1636718818eSStefano Zampini if (Cin && Cin->symmetric) Ctrans = 0; 1646718818eSStefano Zampini 1656718818eSStefano Zampini if (Atrans || Btrans || Ctrans) { 1666718818eSStefano Zampini ptype = MATPRODUCT_UNSPECIFIED; 1676718818eSStefano Zampini switch (D->product->type) { 1686718818eSStefano Zampini case MATPRODUCT_AB: 1696718818eSStefano Zampini if (Atrans && Btrans) { /* At * Bt we do not have support for this */ 1706718818eSStefano Zampini /* TODO custom implementation ? */ 1716718818eSStefano Zampini } else if (Atrans) { /* At * B */ 1726718818eSStefano Zampini ptype = MATPRODUCT_AtB; 1736718818eSStefano Zampini } else { /* A * Bt */ 1746718818eSStefano Zampini ptype = MATPRODUCT_ABt; 1756718818eSStefano Zampini } 1766718818eSStefano Zampini break; 1776718818eSStefano Zampini case MATPRODUCT_AtB: 1786718818eSStefano Zampini if (Atrans && Btrans) { /* A * Bt */ 1796718818eSStefano Zampini ptype = MATPRODUCT_ABt; 1806718818eSStefano Zampini } else if (Atrans) { /* A * B */ 1816718818eSStefano Zampini ptype = MATPRODUCT_AB; 1826718818eSStefano Zampini } else { /* At * Bt we do not have support for this */ 1836718818eSStefano Zampini /* TODO custom implementation ? */ 1846718818eSStefano Zampini } 1856718818eSStefano Zampini break; 1866718818eSStefano Zampini case MATPRODUCT_ABt: 1876718818eSStefano Zampini if (Atrans && Btrans) { /* At * B */ 1886718818eSStefano Zampini ptype = MATPRODUCT_AtB; 1896718818eSStefano Zampini } else if (Atrans) { /* At * Bt we do not have support for this */ 1906718818eSStefano Zampini /* TODO custom implementation ? */ 1916718818eSStefano Zampini } else { /* A * B */ 1926718818eSStefano Zampini ptype = MATPRODUCT_AB; 1936718818eSStefano Zampini } 1946718818eSStefano Zampini break; 1956718818eSStefano Zampini case MATPRODUCT_PtAP: 1966718818eSStefano Zampini if (Atrans) { /* PtAtP */ 1976718818eSStefano Zampini /* TODO custom implementation ? */ 1986718818eSStefano Zampini } else { /* RARt */ 1996718818eSStefano Zampini ptype = MATPRODUCT_RARt; 2006718818eSStefano Zampini } 2016718818eSStefano Zampini break; 2026718818eSStefano Zampini case MATPRODUCT_RARt: 2036718818eSStefano Zampini if (Atrans) { /* RAtRt */ 2046718818eSStefano Zampini /* TODO custom implementation ? */ 2056718818eSStefano Zampini } else { /* PtAP */ 2066718818eSStefano Zampini ptype = MATPRODUCT_PtAP; 2076718818eSStefano Zampini } 2086718818eSStefano Zampini break; 2096718818eSStefano Zampini case MATPRODUCT_ABC: 2106718818eSStefano Zampini /* TODO custom implementation ? */ 2116718818eSStefano Zampini break; 2126718818eSStefano Zampini default: SETERRQ1(PetscObjectComm((PetscObject)D),PETSC_ERR_SUP,"ProductType %s is not supported",MatProductTypes[D->product->type]); 2136718818eSStefano Zampini } 2146718818eSStefano Zampini } 2156718818eSStefano Zampini ierr = MatProductReplaceMats(Ain,Bin,Cin,D);CHKERRQ(ierr); 2166718818eSStefano Zampini ierr = MatProductSetType(D,ptype);CHKERRQ(ierr); 2176718818eSStefano Zampini ierr = MatProductSetFromOptions(D);CHKERRQ(ierr); 2186718818eSStefano Zampini PetscFunctionReturn(0); 2196718818eSStefano Zampini } 2206718818eSStefano Zampini 221a0eea678SPierre Jolivet PetscErrorCode MatGetDiagonal_Transpose(Mat A,Vec v) 222a0eea678SPierre Jolivet { 223a0eea678SPierre Jolivet Mat_Transpose *Aa = (Mat_Transpose*)A->data; 224a0eea678SPierre Jolivet PetscErrorCode ierr; 225a0eea678SPierre Jolivet 226a0eea678SPierre Jolivet PetscFunctionBegin; 227a0eea678SPierre Jolivet ierr = MatGetDiagonal(Aa->A,v);CHKERRQ(ierr); 228a0eea678SPierre Jolivet PetscFunctionReturn(0); 229a0eea678SPierre Jolivet } 230a0eea678SPierre Jolivet 231a0eea678SPierre Jolivet PetscErrorCode MatConvert_Transpose(Mat A,MatType newtype,MatReuse reuse,Mat *newmat) 232a0eea678SPierre Jolivet { 233a0eea678SPierre Jolivet Mat_Transpose *Aa = (Mat_Transpose*)A->data; 234a0eea678SPierre Jolivet Mat B; 235a0eea678SPierre Jolivet PetscErrorCode ierr; 236a0eea678SPierre Jolivet 237a0eea678SPierre Jolivet PetscFunctionBegin; 238a0eea678SPierre Jolivet ierr = MatTranspose(Aa->A,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 239*ff83db7bSPierre Jolivet if (reuse != MAT_INPLACE_MATRIX) { 240a0eea678SPierre Jolivet ierr = MatConvert(B,newtype,reuse,newmat);CHKERRQ(ierr); 241a0eea678SPierre Jolivet ierr = MatDestroy(&B);CHKERRQ(ierr); 242*ff83db7bSPierre Jolivet } else { 243*ff83db7bSPierre Jolivet ierr = MatConvert(B,newtype,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 244*ff83db7bSPierre Jolivet ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 245*ff83db7bSPierre Jolivet } 246a0eea678SPierre Jolivet PetscFunctionReturn(0); 247a0eea678SPierre Jolivet } 248a0eea678SPierre Jolivet 2498060fb66Sstefano_zampini PetscErrorCode MatTransposeGetMat_Transpose(Mat A,Mat *M) 2508060fb66Sstefano_zampini { 2518060fb66Sstefano_zampini Mat_Transpose *Aa = (Mat_Transpose*)A->data; 2528060fb66Sstefano_zampini 2538060fb66Sstefano_zampini PetscFunctionBegin; 2548060fb66Sstefano_zampini *M = Aa->A; 2558060fb66Sstefano_zampini PetscFunctionReturn(0); 2568060fb66Sstefano_zampini } 2578060fb66Sstefano_zampini 2588060fb66Sstefano_zampini /*@ 25906511a5cSPierre Jolivet MatTransposeGetMat - Gets the Mat object stored inside a MATTRANSPOSEMAT 2608060fb66Sstefano_zampini 2618060fb66Sstefano_zampini Logically collective on Mat 2628060fb66Sstefano_zampini 2638060fb66Sstefano_zampini Input Parameter: 2648060fb66Sstefano_zampini . A - the MATTRANSPOSE matrix 2658060fb66Sstefano_zampini 2668060fb66Sstefano_zampini Output Parameter: 2678060fb66Sstefano_zampini . M - the matrix object stored inside A 2688060fb66Sstefano_zampini 2698060fb66Sstefano_zampini Level: intermediate 2708060fb66Sstefano_zampini 2718060fb66Sstefano_zampini .seealso: MatCreateTranspose() 2728060fb66Sstefano_zampini 2738060fb66Sstefano_zampini @*/ 2748060fb66Sstefano_zampini PetscErrorCode MatTransposeGetMat(Mat A,Mat *M) 2758060fb66Sstefano_zampini { 2768060fb66Sstefano_zampini PetscErrorCode ierr; 2778060fb66Sstefano_zampini 2788060fb66Sstefano_zampini PetscFunctionBegin; 2798060fb66Sstefano_zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2808060fb66Sstefano_zampini PetscValidType(A,1); 2818060fb66Sstefano_zampini PetscValidPointer(M,2); 2828060fb66Sstefano_zampini ierr = PetscUseMethod(A,"MatTransposeGetMat_C",(Mat,Mat*),(A,M));CHKERRQ(ierr); 2838060fb66Sstefano_zampini PetscFunctionReturn(0); 2848060fb66Sstefano_zampini } 285d0de2241SAndrew Spott 28685e3dda7SBarry Smith /*@ 28785e3dda7SBarry Smith MatCreateTranspose - Creates a new matrix object that behaves like A' 28885e3dda7SBarry Smith 28985e3dda7SBarry Smith Collective on Mat 29085e3dda7SBarry Smith 29185e3dda7SBarry Smith Input Parameter: 29285e3dda7SBarry Smith . A - the (possibly rectangular) matrix 29385e3dda7SBarry Smith 29485e3dda7SBarry Smith Output Parameter: 29585e3dda7SBarry Smith . N - the matrix that represents A' 29685e3dda7SBarry Smith 29785e3dda7SBarry Smith Level: intermediate 29885e3dda7SBarry Smith 29995452b02SPatrick Sanan Notes: 30095452b02SPatrick Sanan The transpose A' is NOT actually formed! Rather the new matrix 30185e3dda7SBarry Smith object performs the matrix-vector product by using the MatMultTranspose() on 30285e3dda7SBarry Smith the original matrix 30385e3dda7SBarry Smith 30485e3dda7SBarry Smith .seealso: MatCreateNormal(), MatMult(), MatMultTranspose(), MatCreate() 30585e3dda7SBarry Smith 30685e3dda7SBarry Smith @*/ 3077087cfbeSBarry Smith PetscErrorCode MatCreateTranspose(Mat A,Mat *N) 30885e3dda7SBarry Smith { 30985e3dda7SBarry Smith PetscErrorCode ierr; 31085e3dda7SBarry Smith PetscInt m,n; 31185e3dda7SBarry Smith Mat_Transpose *Na; 312487d878eSStefano Zampini VecType vtype; 31385e3dda7SBarry Smith 31485e3dda7SBarry Smith PetscFunctionBegin; 31585e3dda7SBarry Smith ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 316ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),N);CHKERRQ(ierr); 31785e3dda7SBarry Smith ierr = MatSetSizes(*N,n,m,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 318d97d01c0SJed Brown ierr = PetscLayoutSetUp((*N)->rmap);CHKERRQ(ierr); 319d97d01c0SJed Brown ierr = PetscLayoutSetUp((*N)->cmap);CHKERRQ(ierr); 320557cca28SSatish Balay ierr = PetscObjectChangeTypeName((PetscObject)*N,MATTRANSPOSEMAT);CHKERRQ(ierr); 32185e3dda7SBarry Smith 322b00a9115SJed Brown ierr = PetscNewLog(*N,&Na);CHKERRQ(ierr); 32385e3dda7SBarry Smith (*N)->data = (void*) Na; 32485e3dda7SBarry Smith ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 32585e3dda7SBarry Smith Na->A = A; 32685e3dda7SBarry Smith 32785e3dda7SBarry Smith (*N)->ops->destroy = MatDestroy_Transpose; 32885e3dda7SBarry Smith (*N)->ops->mult = MatMult_Transpose; 3296d12b599SJed Brown (*N)->ops->multadd = MatMultAdd_Transpose; 33047a9afc9SBarry Smith (*N)->ops->multtranspose = MatMultTranspose_Transpose; 33147a9afc9SBarry Smith (*N)->ops->multtransposeadd = MatMultTransposeAdd_Transpose; 332d0de2241SAndrew Spott (*N)->ops->duplicate = MatDuplicate_Transpose; 333d9b48344SStefano Zampini (*N)->ops->getvecs = MatCreateVecs_Transpose; 3346171f1c8SPierre Jolivet (*N)->ops->axpy = MatAXPY_Transpose; 33552c5f739Sprj- (*N)->ops->hasoperation = MatHasOperation_Transpose; 3366718818eSStefano Zampini (*N)->ops->productsetfromoptions = MatProductSetFromOptions_Transpose; 337a0eea678SPierre Jolivet (*N)->ops->getdiagonal = MatGetDiagonal_Transpose; 338a0eea678SPierre Jolivet (*N)->ops->convert = MatConvert_Transpose; 33985e3dda7SBarry Smith (*N)->assembled = PETSC_TRUE; 34085e3dda7SBarry Smith 3418060fb66Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)(*N),"MatTransposeGetMat_C",MatTransposeGetMat_Transpose);CHKERRQ(ierr); 3426718818eSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)(*N),"MatProductSetFromOptions_anytype_C",MatProductSetFromOptions_Transpose);CHKERRQ(ierr); 34333d57670SJed Brown ierr = MatSetBlockSizes(*N,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 344487d878eSStefano Zampini ierr = MatGetVecType(A,&vtype);CHKERRQ(ierr); 345487d878eSStefano Zampini ierr = MatSetVecType(*N,vtype);CHKERRQ(ierr); 3462487f3f2SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 3472487f3f2SStefano Zampini ierr = MatBindToCPU(*N,A->boundtocpu);CHKERRQ(ierr); 3482487f3f2SStefano Zampini #endif 349037c98a2SJed Brown ierr = MatSetUp(*N);CHKERRQ(ierr); 35085e3dda7SBarry Smith PetscFunctionReturn(0); 35185e3dda7SBarry Smith } 352