14222ddf1SHong Zhang 24222ddf1SHong Zhang /* 34222ddf1SHong Zhang Routines for matrix products. Calling procedure: 44222ddf1SHong Zhang 54222ddf1SHong Zhang MatProductCreate(A,B,C,&D); or MatProductCreateWithMat(A,B,C,D); 64222ddf1SHong Zhang MatProductSetType(D, MATPRODUCT_AB/AtB/ABt/PtAP/RARt/ABC); 74222ddf1SHong Zhang MatProductSetAlgorithm(D, alg); 84222ddf1SHong Zhang MatProductSetFill(D,fill); 94222ddf1SHong Zhang MatProductSetFromOptions(D); 104222ddf1SHong Zhang -> MatProductSetFromOptions_producttype(D): 114222ddf1SHong Zhang # Check matrix global sizes 124222ddf1SHong Zhang -> MatProductSetFromOptions_Atype_Btype_Ctype(D); 134222ddf1SHong Zhang ->MatProductSetFromOptions_Atype_Btype_Ctype_productype(D): 144222ddf1SHong Zhang # Check matrix local sizes for mpi matrices 154222ddf1SHong Zhang # Set default algorithm 164222ddf1SHong Zhang # Get runtime option 174222ddf1SHong Zhang # Set D->ops->productsymbolic = MatProductSymbolic_productype_Atype_Btype_Ctype; 184222ddf1SHong Zhang 194222ddf1SHong Zhang PetscLogEventBegin() 204222ddf1SHong Zhang MatProductSymbolic(D): 214222ddf1SHong Zhang # Call MatxxxSymbolic_Atype_Btype_Ctype(); 224222ddf1SHong Zhang # Set D->ops->productnumeric = MatProductNumeric_productype_Atype_Btype_Ctype; 234222ddf1SHong Zhang PetscLogEventEnd() 244222ddf1SHong Zhang 254222ddf1SHong Zhang PetscLogEventBegin() 264222ddf1SHong Zhang MatProductNumeric(D); 274222ddf1SHong Zhang # Call (D->ops->matxxxnumeric)(); 284222ddf1SHong Zhang PetscLogEventEnd() 294222ddf1SHong Zhang */ 304222ddf1SHong Zhang 314222ddf1SHong Zhang #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 324222ddf1SHong Zhang 33*544a5e07SHong Zhang const char *const MatProductTypes[] = {"AB","AtB","ABt","PtAP","RARt","ABC","MatProductType","MAT_Product_",0}; 34*544a5e07SHong Zhang 354222ddf1SHong Zhang static PetscErrorCode MatProductNumeric_PtAP_Basic(Mat C) 364222ddf1SHong Zhang { 374222ddf1SHong Zhang PetscErrorCode ierr; 384222ddf1SHong Zhang Mat_Product *product = C->product; 394222ddf1SHong Zhang Mat P = product->B,AP = product->Dwork; 404222ddf1SHong Zhang 414222ddf1SHong Zhang PetscFunctionBegin; 424222ddf1SHong Zhang /* AP = A*P */ 434222ddf1SHong Zhang ierr = MatProductNumeric(AP);CHKERRQ(ierr); 444222ddf1SHong Zhang /* C = P^T*AP */ 454222ddf1SHong Zhang ierr = (C->ops->transposematmultnumeric)(P,AP,C);CHKERRQ(ierr); 464222ddf1SHong Zhang PetscFunctionReturn(0); 474222ddf1SHong Zhang } 484222ddf1SHong Zhang 494222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_PtAP_Basic(Mat C) 504222ddf1SHong Zhang { 514222ddf1SHong Zhang PetscErrorCode ierr; 524222ddf1SHong Zhang Mat_Product *product = C->product; 534222ddf1SHong Zhang Mat A=product->A,P=product->B,AP; 544222ddf1SHong Zhang PetscReal fill=product->fill; 554222ddf1SHong Zhang 564222ddf1SHong Zhang PetscFunctionBegin; 574222ddf1SHong Zhang /* AP = A*P */ 584222ddf1SHong Zhang ierr = MatProductCreate(A,P,NULL,&AP);CHKERRQ(ierr); 594222ddf1SHong Zhang ierr = MatProductSetType(AP,MATPRODUCT_AB);CHKERRQ(ierr); 604222ddf1SHong Zhang ierr = MatProductSetAlgorithm(AP,"default");CHKERRQ(ierr); 614222ddf1SHong Zhang ierr = MatProductSetFill(AP,fill);CHKERRQ(ierr); 624222ddf1SHong Zhang ierr = MatProductSetFromOptions(AP);CHKERRQ(ierr); 634222ddf1SHong Zhang ierr = MatProductSymbolic(AP);CHKERRQ(ierr); 644222ddf1SHong Zhang 654222ddf1SHong Zhang /* C = P^T*AP */ 664222ddf1SHong Zhang ierr = MatProductSetType(C,MATPRODUCT_AtB);CHKERRQ(ierr); 674222ddf1SHong Zhang product->alg = "default"; 684222ddf1SHong Zhang product->A = P; 694222ddf1SHong Zhang product->B = AP; 704222ddf1SHong Zhang ierr = MatProductSetFromOptions(C);CHKERRQ(ierr); 714222ddf1SHong Zhang ierr = MatProductSymbolic(C);CHKERRQ(ierr); 724222ddf1SHong Zhang 734222ddf1SHong Zhang /* resume user's original input matrix setting for A and B */ 744222ddf1SHong Zhang product->A = A; 754222ddf1SHong Zhang product->B = P; 764222ddf1SHong Zhang product->Dwork = AP; 774222ddf1SHong Zhang 784222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_PtAP_Basic; 794222ddf1SHong Zhang PetscFunctionReturn(0); 804222ddf1SHong Zhang } 814222ddf1SHong Zhang 824222ddf1SHong Zhang static PetscErrorCode MatProductNumeric_RARt_Basic(Mat C) 834222ddf1SHong Zhang { 844222ddf1SHong Zhang PetscErrorCode ierr; 854222ddf1SHong Zhang Mat_Product *product = C->product; 864222ddf1SHong Zhang Mat R=product->B,RA=product->Dwork; 874222ddf1SHong Zhang 884222ddf1SHong Zhang PetscFunctionBegin; 894222ddf1SHong Zhang /* RA = R*A */ 904222ddf1SHong Zhang ierr = MatProductNumeric(RA);CHKERRQ(ierr); 914222ddf1SHong Zhang /* C = RA*R^T */ 924222ddf1SHong Zhang ierr = (C->ops->mattransposemultnumeric)(RA,R,C);CHKERRQ(ierr); 934222ddf1SHong Zhang PetscFunctionReturn(0); 944222ddf1SHong Zhang } 954222ddf1SHong Zhang 964222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_RARt_Basic(Mat C) 974222ddf1SHong Zhang { 984222ddf1SHong Zhang PetscErrorCode ierr; 994222ddf1SHong Zhang Mat_Product *product = C->product; 1004222ddf1SHong Zhang Mat A=product->A,R=product->B,RA; 1014222ddf1SHong Zhang PetscReal fill=product->fill; 1024222ddf1SHong Zhang 1034222ddf1SHong Zhang PetscFunctionBegin; 1044222ddf1SHong Zhang /* RA = R*A */ 1054222ddf1SHong Zhang ierr = MatProductCreate(R,A,NULL,&RA);CHKERRQ(ierr); 1064222ddf1SHong Zhang ierr = MatProductSetType(RA,MATPRODUCT_AB);CHKERRQ(ierr); 1074222ddf1SHong Zhang ierr = MatProductSetAlgorithm(RA,"default");CHKERRQ(ierr); 1084222ddf1SHong Zhang ierr = MatProductSetFill(RA,fill);CHKERRQ(ierr); 1094222ddf1SHong Zhang ierr = MatProductSetFromOptions(RA);CHKERRQ(ierr); 1104222ddf1SHong Zhang ierr = MatProductSymbolic(RA);CHKERRQ(ierr); 1114222ddf1SHong Zhang 1124222ddf1SHong Zhang /* C = RA*R^T */ 1134222ddf1SHong Zhang ierr = MatProductSetType(C,MATPRODUCT_ABt);CHKERRQ(ierr); 1144222ddf1SHong Zhang product->alg = "default"; 1154222ddf1SHong Zhang product->A = RA; 1164222ddf1SHong Zhang ierr = MatProductSetFromOptions(C);CHKERRQ(ierr); 1174222ddf1SHong Zhang ierr = MatProductSymbolic(C);CHKERRQ(ierr); 1184222ddf1SHong Zhang 1194222ddf1SHong Zhang /* resume user's original input matrix setting for A */ 1204222ddf1SHong Zhang product->A = A; 1214222ddf1SHong Zhang product->Dwork = RA; /* save here so it will be destroyed with product C */ 1224222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_RARt_Basic; 1234222ddf1SHong Zhang PetscFunctionReturn(0); 1244222ddf1SHong Zhang } 1254222ddf1SHong Zhang 1264222ddf1SHong Zhang static PetscErrorCode MatProductNumeric_ABC_Basic(Mat mat) 1274222ddf1SHong Zhang { 1284222ddf1SHong Zhang PetscErrorCode ierr; 1294222ddf1SHong Zhang Mat_Product *product = mat->product; 1304222ddf1SHong Zhang Mat A=product->A,BC=product->Dwork; 1314222ddf1SHong Zhang 1324222ddf1SHong Zhang PetscFunctionBegin; 1334222ddf1SHong Zhang /* Numeric BC = B*C */ 1344222ddf1SHong Zhang ierr = MatProductNumeric(BC);CHKERRQ(ierr); 1354222ddf1SHong Zhang /* Numeric mat = A*BC */ 1364222ddf1SHong Zhang ierr = (mat->ops->matmultnumeric)(A,BC,mat);CHKERRQ(ierr); 1374222ddf1SHong Zhang PetscFunctionReturn(0); 1384222ddf1SHong Zhang } 1394222ddf1SHong Zhang 1404222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_ABC_Basic(Mat mat) 1414222ddf1SHong Zhang { 1424222ddf1SHong Zhang PetscErrorCode ierr; 1434222ddf1SHong Zhang Mat_Product *product = mat->product; 1444222ddf1SHong Zhang Mat B=product->B,C=product->C,BC; 1454222ddf1SHong Zhang PetscReal fill=product->fill; 1464222ddf1SHong Zhang 1474222ddf1SHong Zhang PetscFunctionBegin; 1484222ddf1SHong Zhang /* Symbolic BC = B*C */ 1494222ddf1SHong Zhang ierr = MatProductCreate(B,C,NULL,&BC);CHKERRQ(ierr); 1504222ddf1SHong Zhang ierr = MatProductSetType(BC,MATPRODUCT_AB);CHKERRQ(ierr); 1514222ddf1SHong Zhang ierr = MatProductSetAlgorithm(BC,"default");CHKERRQ(ierr); 1524222ddf1SHong Zhang ierr = MatProductSetFill(BC,fill);CHKERRQ(ierr); 1534222ddf1SHong Zhang ierr = MatProductSetFromOptions(BC);CHKERRQ(ierr); 1544222ddf1SHong Zhang ierr = MatProductSymbolic(BC);CHKERRQ(ierr); 1554222ddf1SHong Zhang 1564222ddf1SHong Zhang /* Symbolic mat = A*BC */ 1574222ddf1SHong Zhang ierr = MatProductSetType(mat,MATPRODUCT_AB);CHKERRQ(ierr); 1584222ddf1SHong Zhang product->alg = "default"; 1594222ddf1SHong Zhang product->B = BC; 1604222ddf1SHong Zhang product->Dwork = BC; 1614222ddf1SHong Zhang ierr = MatProductSetFromOptions(mat);CHKERRQ(ierr); 1624222ddf1SHong Zhang ierr = MatProductSymbolic(mat);CHKERRQ(ierr); 1634222ddf1SHong Zhang 1644222ddf1SHong Zhang /* resume user's original input matrix setting for B */ 1654222ddf1SHong Zhang product->B = B; 1664222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_ABC_Basic; 1674222ddf1SHong Zhang PetscFunctionReturn(0); 1684222ddf1SHong Zhang } 1694222ddf1SHong Zhang 1704222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_Basic(Mat mat) 1714222ddf1SHong Zhang { 1724222ddf1SHong Zhang PetscErrorCode ierr; 1734222ddf1SHong Zhang Mat_Product *product = mat->product; 1744222ddf1SHong Zhang 1754222ddf1SHong Zhang PetscFunctionBegin; 1764222ddf1SHong Zhang switch (product->type) { 1774222ddf1SHong Zhang case MATPRODUCT_PtAP: 1784222ddf1SHong Zhang PetscInfo2((PetscObject)mat, "MatProduct_Basic_PtAP() for A %s, P %s is used",((PetscObject)product->A)->type_name,((PetscObject)product->B)->type_name); 1794222ddf1SHong Zhang ierr = MatProductSymbolic_PtAP_Basic(mat);CHKERRQ(ierr); 1804222ddf1SHong Zhang break; 1814222ddf1SHong Zhang case MATPRODUCT_RARt: 1824222ddf1SHong Zhang PetscInfo2((PetscObject)mat, "MatProduct_Basic_RARt() for A %s, R %s is used",((PetscObject)product->A)->type_name,((PetscObject)product->B)->type_name); 1834222ddf1SHong Zhang ierr = MatProductSymbolic_RARt_Basic(mat);CHKERRQ(ierr); 1844222ddf1SHong Zhang break; 1854222ddf1SHong Zhang case MATPRODUCT_ABC: 1864222ddf1SHong Zhang PetscInfo3((PetscObject)mat, "MatProduct_Basic_ABC() for A %s, B %s, C %s is used",((PetscObject)product->A)->type_name,((PetscObject)product->B)->type_name,((PetscObject)product->C)->type_name); 1874222ddf1SHong Zhang ierr = MatProductSymbolic_ABC_Basic(mat);CHKERRQ(ierr); 1884222ddf1SHong Zhang break; 1894222ddf1SHong Zhang default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"ProductType is not supported"); 1904222ddf1SHong Zhang } 1914222ddf1SHong Zhang PetscFunctionReturn(0); 1924222ddf1SHong Zhang } 1934222ddf1SHong Zhang 1944222ddf1SHong Zhang /* ----------------------------------------------- */ 1954222ddf1SHong Zhang /*@C 1964222ddf1SHong Zhang MatProductReplaceMats - Replace input matrices for a matrix product. 1974222ddf1SHong Zhang 1984222ddf1SHong Zhang Collective on Mat 1994222ddf1SHong Zhang 2004222ddf1SHong Zhang Input Parameters: 2014222ddf1SHong Zhang + A - the matrix or NULL if not being replaced 2024222ddf1SHong Zhang . B - the matrix or NULL if not being replaced 2034222ddf1SHong Zhang . C - the matrix or NULL if not being replaced 2044222ddf1SHong Zhang - D - the matrix product 2054222ddf1SHong Zhang 2064222ddf1SHong Zhang Level: intermediate 2074222ddf1SHong Zhang 2084222ddf1SHong Zhang Notes: 2094222ddf1SHong Zhang Input matrix must have exactly same data structure as replaced one. 2104222ddf1SHong Zhang 2114222ddf1SHong Zhang .seealso: MatProductCreate() 2124222ddf1SHong Zhang @*/ 2134222ddf1SHong Zhang PetscErrorCode MatProductReplaceMats(Mat A,Mat B,Mat C,Mat D) 2144222ddf1SHong Zhang { 2154417c5e8SHong Zhang PetscErrorCode ierr; 2164222ddf1SHong Zhang Mat_Product *product=D->product; 2174222ddf1SHong Zhang 2184222ddf1SHong Zhang PetscFunctionBegin; 2194222ddf1SHong Zhang if (!product) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_ARG_NULL,"Mat D does not have struct 'product'. Call MatProductReplaceProduct(). \n"); 2204222ddf1SHong Zhang if (A) { 2214222ddf1SHong Zhang if (!product->Areplaced) { 2224417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); /* take ownership of input */ 2234417c5e8SHong Zhang ierr = MatDestroy(&product->A);CHKERRQ(ierr); /* release old reference */ 2244222ddf1SHong Zhang product->A = A; 2254222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_SUP,"Matrix A was changed by a PETSc internal routine, cannot be replaced"); 2264222ddf1SHong Zhang } 2274222ddf1SHong Zhang if (B) { 2284222ddf1SHong Zhang if (!product->Breplaced) { 2294417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); /* take ownership of input */ 2304417c5e8SHong Zhang ierr = MatDestroy(&product->B);CHKERRQ(ierr); /* release old reference */ 2314222ddf1SHong Zhang product->B = B; 2324222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_SUP,"Matrix B was changed by a PETSc internal routine, cannot be replaced"); 2334222ddf1SHong Zhang } 2344417c5e8SHong Zhang if (C) { 2354417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr); /* take ownership of input */ 2364417c5e8SHong Zhang ierr = MatDestroy(&product->C);CHKERRQ(ierr); /* release old reference */ 2374417c5e8SHong Zhang product->C = C; 2384417c5e8SHong Zhang } 2394222ddf1SHong Zhang PetscFunctionReturn(0); 2404222ddf1SHong Zhang } 2414222ddf1SHong Zhang 2424222ddf1SHong Zhang /* ----------------------------------------------- */ 2434222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_AB(Mat mat) 2444222ddf1SHong Zhang { 2454222ddf1SHong Zhang PetscErrorCode ierr; 2464222ddf1SHong Zhang Mat_Product *product = mat->product; 2474222ddf1SHong Zhang Mat A=product->A,B=product->B; 2484222ddf1SHong Zhang PetscBool sametype; 2494222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 2504222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 2514222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 2524222ddf1SHong Zhang PetscBool A_istrans,B_istrans; 2534222ddf1SHong Zhang 2544222ddf1SHong Zhang PetscFunctionBegin; 2554222ddf1SHong Zhang /* Check matrix global sizes */ 2564222ddf1SHong Zhang if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N); 2574222ddf1SHong Zhang 2584222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 2594222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 2604222ddf1SHong Zhang 2614222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 2624222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&A_istrans);CHKERRQ(ierr); 2634222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&B_istrans);CHKERRQ(ierr); 2644222ddf1SHong Zhang 2654222ddf1SHong Zhang if (fB == fA && sametype && (!A_istrans || !B_istrans)) { 2664222ddf1SHong Zhang f = fB; 2674222ddf1SHong Zhang } else { 2684222ddf1SHong Zhang char mtypes[256]; 2694222ddf1SHong Zhang PetscBool At_istrans=PETSC_TRUE,Bt_istrans=PETSC_TRUE; 2704222ddf1SHong Zhang Mat At = NULL,Bt = NULL; 2714222ddf1SHong Zhang 2724222ddf1SHong Zhang if (A_istrans && !B_istrans) { 2734222ddf1SHong Zhang ierr = MatTransposeGetMat(A,&At);CHKERRQ(ierr); 2744222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)At,MATTRANSPOSEMAT,&At_istrans);CHKERRQ(ierr); 2754222ddf1SHong Zhang if (At_istrans) { /* mat = ATT * B */ 2764222ddf1SHong Zhang Mat Att = NULL; 2774222ddf1SHong Zhang ierr = MatTransposeGetMat(At,&Att);CHKERRQ(ierr); 2784417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)Att);CHKERRQ(ierr); 2794417c5e8SHong Zhang ierr = MatDestroy(&product->A);CHKERRQ(ierr); 2804222ddf1SHong Zhang A = Att; 2814222ddf1SHong Zhang product->A = Att; /* use Att for matproduct */ 2824222ddf1SHong Zhang product->Areplaced = PETSC_TRUE; /* Att = A, but has native matrix type */ 2834222ddf1SHong Zhang } else { /* !At_istrans: mat = At^T*B */ 2844417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)At);CHKERRQ(ierr); 2854417c5e8SHong Zhang ierr = MatDestroy(&product->A);CHKERRQ(ierr); 2864222ddf1SHong Zhang A = At; 2874222ddf1SHong Zhang product->A = At; 2884222ddf1SHong Zhang product->Areplaced = PETSC_TRUE; 2894222ddf1SHong Zhang product->type = MATPRODUCT_AtB; 2904222ddf1SHong Zhang } 2914222ddf1SHong Zhang } else if (!A_istrans && B_istrans) { 2924222ddf1SHong Zhang ierr = MatTransposeGetMat(B,&Bt);CHKERRQ(ierr); 2934222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)Bt,MATTRANSPOSEMAT,&Bt_istrans);CHKERRQ(ierr); 2944222ddf1SHong Zhang if (Bt_istrans) { /* mat = A * BTT */ 2954222ddf1SHong Zhang Mat Btt = NULL; 2964222ddf1SHong Zhang ierr = MatTransposeGetMat(Bt,&Btt);CHKERRQ(ierr); 2974417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)Btt);CHKERRQ(ierr); 2984417c5e8SHong Zhang ierr = MatDestroy(&product->B);CHKERRQ(ierr); 2994222ddf1SHong Zhang B = Btt; 3004222ddf1SHong Zhang product->B = Btt; /* use Btt for matproduct */ 3014222ddf1SHong Zhang product->Breplaced = PETSC_TRUE; 3024222ddf1SHong Zhang } else { /* !Bt_istrans */ 3034222ddf1SHong Zhang /* mat = A*Bt^T */ 3044417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)Bt);CHKERRQ(ierr); 3054417c5e8SHong Zhang ierr = MatDestroy(&product->B);CHKERRQ(ierr); 3064222ddf1SHong Zhang B = Bt; 3074222ddf1SHong Zhang product->B = Bt; 3084222ddf1SHong Zhang product->Breplaced = PETSC_TRUE; 3094222ddf1SHong Zhang product->type = MATPRODUCT_ABt; 3104222ddf1SHong Zhang } 3114222ddf1SHong Zhang } else if (A_istrans && B_istrans) { /* mat = At^T * Bt^T */ 3124222ddf1SHong Zhang ierr = MatTransposeGetMat(A,&At);CHKERRQ(ierr); 3134222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)At,MATTRANSPOSEMAT,&At_istrans);CHKERRQ(ierr); 3144222ddf1SHong Zhang ierr = MatTransposeGetMat(B,&Bt);CHKERRQ(ierr); 3154222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)Bt,MATTRANSPOSEMAT,&Bt_istrans);CHKERRQ(ierr); 3164222ddf1SHong Zhang if (At_istrans && Bt_istrans) { 3174222ddf1SHong Zhang Mat Att= NULL,Btt = NULL; 3184222ddf1SHong Zhang ierr = MatTransposeGetMat(At,&Att);CHKERRQ(ierr); 3194222ddf1SHong Zhang ierr = MatTransposeGetMat(Bt,&Btt);CHKERRQ(ierr); 3204417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)Att);CHKERRQ(ierr); 3214417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)Btt);CHKERRQ(ierr); 3224417c5e8SHong Zhang ierr = MatDestroy(&product->A);CHKERRQ(ierr); 3234417c5e8SHong Zhang ierr = MatDestroy(&product->B);CHKERRQ(ierr); 3244222ddf1SHong Zhang A = Att; 3254222ddf1SHong Zhang product->A = Att; product->Areplaced = PETSC_TRUE; 3264222ddf1SHong Zhang B = Btt; 3274222ddf1SHong Zhang product->B = Btt; product->Breplaced = PETSC_TRUE; 3284222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not supported yet"); 3294222ddf1SHong Zhang } 3304222ddf1SHong Zhang 3314222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 3324222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 3334222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 3344222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 3354222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 3364222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 3374222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 3384222ddf1SHong Zhang if (!f) { 3394222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 3404222ddf1SHong Zhang } 3414222ddf1SHong Zhang } 3424222ddf1SHong Zhang 3434222ddf1SHong Zhang if (!f) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MatProductSetFromOptions_AB for A %s and B %s is not supported",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 3444222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 3454222ddf1SHong Zhang PetscFunctionReturn(0); 3464222ddf1SHong Zhang } 3474222ddf1SHong Zhang 3484222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_AtB(Mat mat) 3494222ddf1SHong Zhang { 3504222ddf1SHong Zhang PetscErrorCode ierr; 3514222ddf1SHong Zhang Mat_Product *product = mat->product; 3524222ddf1SHong Zhang Mat A=product->A,B=product->B; 3534222ddf1SHong Zhang PetscBool sametype; 3544222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 3554222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 3564222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 3574222ddf1SHong Zhang 3584222ddf1SHong Zhang PetscFunctionBegin; 3594222ddf1SHong Zhang /* Check matrix global sizes */ 3604222ddf1SHong Zhang if (B->rmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N); 3614222ddf1SHong Zhang 3624222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 3634222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 3644222ddf1SHong Zhang 3654222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 3664222ddf1SHong Zhang 3674222ddf1SHong Zhang if (fB == fA && sametype) { 3684222ddf1SHong Zhang f = fB; 3694222ddf1SHong Zhang } else { 3704222ddf1SHong Zhang char mtypes[256]; 3714222ddf1SHong Zhang PetscBool istrans; 3724222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 3734222ddf1SHong Zhang if (!istrans) { 3744222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 3754222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 3764222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 3774222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 3784222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 3794222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 3804222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 3814222ddf1SHong Zhang } else { 3824222ddf1SHong Zhang Mat T = NULL; 3834222ddf1SHong Zhang SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MatProductSetFromOptions_AtB for A %s and B %s is not supported",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 3844222ddf1SHong Zhang 3854222ddf1SHong Zhang ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 3864222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 3874222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)T)->type_name,sizeof(mtypes));CHKERRQ(ierr); 3884222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 3894222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 3904222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 3914222ddf1SHong Zhang 3924222ddf1SHong Zhang product->type = MATPRODUCT_AtB; 3934222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 3944222ddf1SHong Zhang } 3954222ddf1SHong Zhang 3964222ddf1SHong Zhang if (!f) { 3974222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 3984222ddf1SHong Zhang } 3994222ddf1SHong Zhang } 4004222ddf1SHong Zhang if (!f) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MatProductSetFromOptions_AB for A %s and B %s is not supported",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 4014222ddf1SHong Zhang 4024222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 4034222ddf1SHong Zhang PetscFunctionReturn(0); 4044222ddf1SHong Zhang } 4054222ddf1SHong Zhang 4064222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_ABt(Mat mat) 4074222ddf1SHong Zhang { 4084222ddf1SHong Zhang PetscErrorCode ierr; 4094222ddf1SHong Zhang Mat_Product *product = mat->product; 4104222ddf1SHong Zhang Mat A=product->A,B=product->B; 4114222ddf1SHong Zhang PetscBool sametype; 4124222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 4134222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 4144222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 4154222ddf1SHong Zhang 4164222ddf1SHong Zhang PetscFunctionBegin; 4174222ddf1SHong Zhang /* Check matrix global sizes */ 4184222ddf1SHong Zhang if (B->cmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N); 4194222ddf1SHong Zhang 4204222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 4214222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 4224222ddf1SHong Zhang 4234222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 4244222ddf1SHong Zhang 4254222ddf1SHong Zhang if (fB == fA && sametype) { 4264222ddf1SHong Zhang f = fB; 4274222ddf1SHong Zhang } else { 4284222ddf1SHong Zhang char mtypes[256]; 4294222ddf1SHong Zhang PetscBool istrans; 4304222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 4314222ddf1SHong Zhang if (!istrans) { 4324222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 4334222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 4344222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 4354222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 4364222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 4374222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 4384222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 4394222ddf1SHong Zhang } else { 4404222ddf1SHong Zhang Mat T = NULL; 4414222ddf1SHong Zhang SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MatProductSetFromOptions_ABt for A %s and B %s is not supported",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 4424222ddf1SHong Zhang 4434222ddf1SHong Zhang ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 4444222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 4454222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)T)->type_name,sizeof(mtypes));CHKERRQ(ierr); 4464222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 4474222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 4484222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 4494222ddf1SHong Zhang 4504222ddf1SHong Zhang product->type = MATPRODUCT_ABt; 4514222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 4524222ddf1SHong Zhang } 4534222ddf1SHong Zhang 4544222ddf1SHong Zhang if (!f) { 4554222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 4564222ddf1SHong Zhang } 4574222ddf1SHong Zhang } 4584222ddf1SHong Zhang if (!f) { 4594222ddf1SHong Zhang SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MatProductSetFromOptions_AB for A %s and B %s is not supported",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 4604222ddf1SHong Zhang } 4614222ddf1SHong Zhang 4624222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 4634222ddf1SHong Zhang PetscFunctionReturn(0); 4644222ddf1SHong Zhang } 4654222ddf1SHong Zhang 4664222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_PtAP(Mat mat) 4674222ddf1SHong Zhang { 4684222ddf1SHong Zhang PetscErrorCode ierr; 4694222ddf1SHong Zhang Mat_Product *product = mat->product; 4704222ddf1SHong Zhang Mat A=product->A,B=product->B; 4714222ddf1SHong Zhang PetscBool sametype; 4724222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 4734222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 4744222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 4754222ddf1SHong Zhang 4764222ddf1SHong Zhang PetscFunctionBegin; 4774222ddf1SHong Zhang /* Check matrix global sizes */ 4784222ddf1SHong Zhang if (A->rmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix A must be square, %D != %D",A->rmap->N,A->cmap->N); 4794222ddf1SHong Zhang if (B->rmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N); 4804222ddf1SHong Zhang 4814222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 4824222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 4834222ddf1SHong Zhang 4844222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 4854222ddf1SHong Zhang if (fB == fA && sametype) { 4864222ddf1SHong Zhang f = fB; 4874222ddf1SHong Zhang } else { 4884222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 4894222ddf1SHong Zhang char mtypes[256]; 4904222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 4914222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 4924222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 4934222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 4944222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 4954222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 4964222ddf1SHong Zhang 4974222ddf1SHong Zhang if (!f) { 4984222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 4994222ddf1SHong Zhang } 5004222ddf1SHong Zhang } 5014222ddf1SHong Zhang 5024222ddf1SHong Zhang if (f) { 5034222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 5044222ddf1SHong Zhang } else { 5054222ddf1SHong Zhang mat->ops->productsymbolic = MatProductSymbolic_Basic; 5064222ddf1SHong Zhang PetscInfo2((PetscObject)mat, "MatProductSetFromOptions_PtAP for A %s, P %s uses MatProduct_Basic() implementation",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 5074222ddf1SHong Zhang } 5084222ddf1SHong Zhang PetscFunctionReturn(0); 5094222ddf1SHong Zhang } 5104222ddf1SHong Zhang 5114222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_RARt(Mat mat) 5124222ddf1SHong Zhang { 5134222ddf1SHong Zhang PetscErrorCode ierr; 5144222ddf1SHong Zhang Mat_Product *product = mat->product; 5154222ddf1SHong Zhang Mat A=product->A,B=product->B; 5164222ddf1SHong Zhang PetscBool sametype; 5174222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 5184222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 5194222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 5204222ddf1SHong Zhang 5214222ddf1SHong Zhang PetscFunctionBegin; 5224222ddf1SHong Zhang /* Check matrix global sizes */ 5234222ddf1SHong Zhang if (A->rmap->N != B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix A must be square, %D != %D",A->rmap->N,A->cmap->N); 5244222ddf1SHong Zhang if (B->cmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap->N,A->cmap->N); 5254222ddf1SHong Zhang 5264222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 5274222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 5284222ddf1SHong Zhang 5294222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 5304222ddf1SHong Zhang if (fB == fA && sametype) { 5314222ddf1SHong Zhang f = fB; 5324222ddf1SHong Zhang } else { 5334222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 5344222ddf1SHong Zhang char mtypes[256]; 5354222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 5364222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 5374222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 5384222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 5394222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 5404222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 5414222ddf1SHong Zhang 5424222ddf1SHong Zhang if (!f) { 5434222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 5444222ddf1SHong Zhang } 5454222ddf1SHong Zhang } 5464222ddf1SHong Zhang 5474222ddf1SHong Zhang if (f) { 5484222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 5494222ddf1SHong Zhang } else { 5504222ddf1SHong Zhang mat->ops->productsymbolic = MatProductSymbolic_Basic; 5514222ddf1SHong Zhang } 5524222ddf1SHong Zhang PetscFunctionReturn(0); 5534222ddf1SHong Zhang } 5544222ddf1SHong Zhang 5554222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_ABC(Mat mat) 5564222ddf1SHong Zhang { 5574222ddf1SHong Zhang PetscErrorCode ierr; 5584222ddf1SHong Zhang Mat_Product *product = mat->product; 5594222ddf1SHong Zhang Mat A=product->A,B=product->B,C=product->C; 5604222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 5614222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 5624222ddf1SHong Zhang PetscErrorCode (*fC)(Mat); 5634222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 5644222ddf1SHong Zhang 5654222ddf1SHong Zhang PetscFunctionBegin; 5664222ddf1SHong Zhang /* Check matrix global sizes */ 5674222ddf1SHong Zhang if (B->rmap->N!= A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N); 5684222ddf1SHong Zhang if (C->rmap->N!= B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",C->rmap->N,B->cmap->N); 5694222ddf1SHong Zhang 5704222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 5714222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 5724222ddf1SHong Zhang fC = C->ops->productsetfromoptions; 5734222ddf1SHong Zhang if (fA == fB && fA == fC && fA) { 5744222ddf1SHong Zhang f = fA; 5754222ddf1SHong Zhang } else { 5764222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype_Ctype */ 5774222ddf1SHong Zhang char mtypes[256]; 5784222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 5794222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 5804222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 5814222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 5824222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 5834222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)C)->type_name,sizeof(mtypes));CHKERRQ(ierr); 5844222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 5854222ddf1SHong Zhang 5864222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 5874222ddf1SHong Zhang if (!f) { 5884222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 5894222ddf1SHong Zhang } 5904222ddf1SHong Zhang if (!f) { 5914222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)C,mtypes,&f);CHKERRQ(ierr); 5924222ddf1SHong Zhang } 5934222ddf1SHong Zhang } 5944222ddf1SHong Zhang 5954222ddf1SHong Zhang if (f) { 5964222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 5974222ddf1SHong Zhang } else { /* use MatProductSymbolic/Numeric_Basic() */ 5984222ddf1SHong Zhang mat->ops->productsymbolic = MatProductSymbolic_Basic; 5994222ddf1SHong Zhang } 6004222ddf1SHong Zhang PetscFunctionReturn(0); 6014222ddf1SHong Zhang } 6024222ddf1SHong Zhang 6034222ddf1SHong Zhang /*@C 6044222ddf1SHong Zhang MatProductSetFromOptions - Creates a matrix product where the type, the algorithm etc are determined from the options database. 6054222ddf1SHong Zhang 6064222ddf1SHong Zhang Logically Collective on Mat 6074222ddf1SHong Zhang 6084222ddf1SHong Zhang Input Parameter: 6094222ddf1SHong Zhang . mat - the matrix 6104222ddf1SHong Zhang 6114222ddf1SHong Zhang Level: beginner 6124222ddf1SHong Zhang 6134222ddf1SHong Zhang .seealso: MatSetFromOptions() 6144222ddf1SHong Zhang @*/ 6154222ddf1SHong Zhang PetscErrorCode MatProductSetFromOptions(Mat mat) 6164222ddf1SHong Zhang { 6174222ddf1SHong Zhang PetscErrorCode ierr; 6184222ddf1SHong Zhang 6194222ddf1SHong Zhang PetscFunctionBegin; 6204222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6214222ddf1SHong Zhang 6224222ddf1SHong Zhang if (mat->ops->productsetfromoptions) { 6234222ddf1SHong Zhang ierr = (*mat->ops->productsetfromoptions)(mat);CHKERRQ(ierr); 6244222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_NULL,"Call MatProductSetType() first"); 6254222ddf1SHong Zhang PetscFunctionReturn(0); 6264222ddf1SHong Zhang } 6274222ddf1SHong Zhang 6284222ddf1SHong Zhang /* ----------------------------------------------- */ 6294222ddf1SHong Zhang PetscErrorCode MatProductNumeric_AB(Mat mat) 6304222ddf1SHong Zhang { 6314222ddf1SHong Zhang PetscErrorCode ierr; 6324222ddf1SHong Zhang Mat_Product *product = mat->product; 6334222ddf1SHong Zhang Mat A=product->A,B=product->B; 6344222ddf1SHong Zhang 6354222ddf1SHong Zhang PetscFunctionBegin; 6364222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 6374222ddf1SHong Zhang ierr = (mat->ops->matmultnumeric)(A,B,mat);CHKERRQ(ierr); 6384222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 6394222ddf1SHong Zhang PetscFunctionReturn(0); 6404222ddf1SHong Zhang } 6414222ddf1SHong Zhang 6424222ddf1SHong Zhang PetscErrorCode MatProductNumeric_AtB(Mat mat) 6434222ddf1SHong Zhang { 6444222ddf1SHong Zhang PetscErrorCode ierr; 6454222ddf1SHong Zhang Mat_Product *product = mat->product; 6464222ddf1SHong Zhang Mat A=product->A,B=product->B; 6474222ddf1SHong Zhang 6484222ddf1SHong Zhang PetscFunctionBegin; 6494222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr); 6504222ddf1SHong Zhang ierr = (mat->ops->transposematmultnumeric)(A,B,mat);CHKERRQ(ierr); 6514222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr); 6524222ddf1SHong Zhang PetscFunctionReturn(0); 6534222ddf1SHong Zhang } 6544222ddf1SHong Zhang 6554222ddf1SHong Zhang PetscErrorCode MatProductNumeric_ABt(Mat mat) 6564222ddf1SHong Zhang { 6574222ddf1SHong Zhang PetscErrorCode ierr; 6584222ddf1SHong Zhang Mat_Product *product = mat->product; 6594222ddf1SHong Zhang Mat A=product->A,B=product->B; 6604222ddf1SHong Zhang 6614222ddf1SHong Zhang PetscFunctionBegin; 6624222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 6634222ddf1SHong Zhang ierr = (mat->ops->mattransposemultnumeric)(A,B,mat);CHKERRQ(ierr); 6644222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 6654222ddf1SHong Zhang PetscFunctionReturn(0); 6664222ddf1SHong Zhang } 6674222ddf1SHong Zhang 6684222ddf1SHong Zhang PetscErrorCode MatProductNumeric_PtAP(Mat mat) 6694222ddf1SHong Zhang { 6704222ddf1SHong Zhang PetscErrorCode ierr; 6714222ddf1SHong Zhang Mat_Product *product = mat->product; 6724222ddf1SHong Zhang Mat A=product->A,B=product->B; 6734222ddf1SHong Zhang 6744222ddf1SHong Zhang PetscFunctionBegin; 6754222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_PtAPNumeric,mat,0,0,0);CHKERRQ(ierr); 6764222ddf1SHong Zhang ierr = (mat->ops->ptapnumeric)(A,B,mat);CHKERRQ(ierr); 6774222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_PtAPNumeric,mat,0,0,0);CHKERRQ(ierr); 6784222ddf1SHong Zhang PetscFunctionReturn(0); 6794222ddf1SHong Zhang } 6804222ddf1SHong Zhang 6814222ddf1SHong Zhang PetscErrorCode MatProductNumeric_RARt(Mat mat) 6824222ddf1SHong Zhang { 6834222ddf1SHong Zhang PetscErrorCode ierr; 6844222ddf1SHong Zhang Mat_Product *product = mat->product; 6854222ddf1SHong Zhang Mat A=product->A,B=product->B; 6864222ddf1SHong Zhang 6874222ddf1SHong Zhang PetscFunctionBegin; 6884222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_RARtNumeric,A,B,0,0);CHKERRQ(ierr); 6894222ddf1SHong Zhang ierr = (mat->ops->rartnumeric)(A,B,mat);CHKERRQ(ierr); 6904222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_RARtNumeric,A,B,0,0);CHKERRQ(ierr); 6914222ddf1SHong Zhang PetscFunctionReturn(0); 6924222ddf1SHong Zhang } 6934222ddf1SHong Zhang 6944222ddf1SHong Zhang PetscErrorCode MatProductNumeric_ABC(Mat mat) 6954222ddf1SHong Zhang { 6964222ddf1SHong Zhang PetscErrorCode ierr; 6974222ddf1SHong Zhang Mat_Product *product = mat->product; 6984222ddf1SHong Zhang Mat A=product->A,B=product->B,C=product->C; 6994222ddf1SHong Zhang 7004222ddf1SHong Zhang PetscFunctionBegin; 7014222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr); 7024222ddf1SHong Zhang ierr = (mat->ops->matmatmultnumeric)(A,B,C,mat);CHKERRQ(ierr); 7034222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr); 7044222ddf1SHong Zhang PetscFunctionReturn(0); 7054222ddf1SHong Zhang } 7064222ddf1SHong Zhang 7074222ddf1SHong Zhang /*@ 7084222ddf1SHong Zhang MatProductNumeric - Implement a matrix product with numerical values. 7094222ddf1SHong Zhang 7104222ddf1SHong Zhang Collective on Mat 7114222ddf1SHong Zhang 7124222ddf1SHong Zhang Input Parameters: 7134222ddf1SHong Zhang . mat - the matrix to hold a product 7144222ddf1SHong Zhang 7154222ddf1SHong Zhang Output Parameters: 7164222ddf1SHong Zhang . mat - the matrix product 7174222ddf1SHong Zhang 7184222ddf1SHong Zhang Level: intermediate 7194222ddf1SHong Zhang 7204222ddf1SHong Zhang .seealso: MatProductCreate(), MatSetType() 7214222ddf1SHong Zhang @*/ 7224222ddf1SHong Zhang PetscErrorCode MatProductNumeric(Mat mat) 7234222ddf1SHong Zhang { 7244222ddf1SHong Zhang PetscErrorCode ierr; 7254222ddf1SHong Zhang 7264222ddf1SHong Zhang PetscFunctionBegin; 7274222ddf1SHong Zhang PetscValidPointer(mat,1); 7284222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7294222ddf1SHong Zhang 7304222ddf1SHong Zhang if (mat->ops->productnumeric) { 7314222ddf1SHong Zhang ierr = (*mat->ops->productnumeric)(mat);CHKERRQ(ierr); 7324222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_USER,"Call MatProductSymbolic() first"); 7334222ddf1SHong Zhang PetscFunctionReturn(0); 7344222ddf1SHong Zhang } 7354222ddf1SHong Zhang 7364222ddf1SHong Zhang /* ----------------------------------------------- */ 7374222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_AB(Mat mat) 7384222ddf1SHong Zhang { 7394222ddf1SHong Zhang PetscErrorCode ierr; 7404222ddf1SHong Zhang Mat_Product *product = mat->product; 7414222ddf1SHong Zhang Mat A=product->A,B=product->B; 7424222ddf1SHong Zhang 7434222ddf1SHong Zhang PetscFunctionBegin; 7444222ddf1SHong Zhang ierr = (mat->ops->matmultsymbolic)(A,B,product->fill,mat);CHKERRQ(ierr); 7454222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_AB; 7464222ddf1SHong Zhang PetscFunctionReturn(0); 7474222ddf1SHong Zhang } 7484222ddf1SHong Zhang 7494222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_AtB(Mat mat) 7504222ddf1SHong Zhang { 7514222ddf1SHong Zhang PetscErrorCode ierr; 7524222ddf1SHong Zhang Mat_Product *product = mat->product; 7534222ddf1SHong Zhang Mat A=product->A,B=product->B; 7544222ddf1SHong Zhang 7554222ddf1SHong Zhang PetscFunctionBegin; 7564222ddf1SHong Zhang ierr = (mat->ops->transposematmultsymbolic)(A,B,product->fill,mat);CHKERRQ(ierr); 7574222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_AtB; 7584222ddf1SHong Zhang PetscFunctionReturn(0); 7594222ddf1SHong Zhang } 7604222ddf1SHong Zhang 7614222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_ABt(Mat mat) 7624222ddf1SHong Zhang { 7634222ddf1SHong Zhang PetscErrorCode ierr; 7644222ddf1SHong Zhang Mat_Product *product = mat->product; 7654222ddf1SHong Zhang Mat A=product->A,B=product->B; 7664222ddf1SHong Zhang 7674222ddf1SHong Zhang PetscFunctionBegin; 7684222ddf1SHong Zhang ierr = (mat->ops->mattransposemultsymbolic)(A,B,product->fill,mat);CHKERRQ(ierr); 7694222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_ABt; 7704222ddf1SHong Zhang PetscFunctionReturn(0); 7714222ddf1SHong Zhang } 7724222ddf1SHong Zhang 7734222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_ABC(Mat mat) 7744222ddf1SHong Zhang { 7754222ddf1SHong Zhang PetscErrorCode ierr; 7764222ddf1SHong Zhang Mat_Product *product = mat->product; 7774222ddf1SHong Zhang Mat A=product->A,B=product->B,C=product->C; 7784222ddf1SHong Zhang 7794222ddf1SHong Zhang PetscFunctionBegin; 7804222ddf1SHong Zhang ierr = (mat->ops->matmatmultsymbolic)(A,B,C,product->fill,mat);CHKERRQ(ierr); 7814222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_ABC; 7824222ddf1SHong Zhang PetscFunctionReturn(0); 7834222ddf1SHong Zhang } 7844222ddf1SHong Zhang 7854222ddf1SHong Zhang /*@ 7864222ddf1SHong Zhang MatProductSymbolic - Perform the symbolic portion of a matrix product, this creates a data structure for use with the numerical produce. 7874222ddf1SHong Zhang 7884222ddf1SHong Zhang Collective on Mat 7894222ddf1SHong Zhang 7904222ddf1SHong Zhang Input Parameters: 7914222ddf1SHong Zhang . mat - the matrix to hold a product 7924222ddf1SHong Zhang 7934222ddf1SHong Zhang Output Parameters: 7944222ddf1SHong Zhang . mat - the matrix product data structure 7954222ddf1SHong Zhang 7964222ddf1SHong Zhang Level: intermediate 7974222ddf1SHong Zhang 7984222ddf1SHong Zhang .seealso: MatProductCreate(), MatSetType(), MatProductNumeric(), MatProductType, MatProductAlgorithm 7994222ddf1SHong Zhang @*/ 8004222ddf1SHong Zhang PetscErrorCode MatProductSymbolic(Mat mat) 8014222ddf1SHong Zhang { 8024222ddf1SHong Zhang PetscErrorCode ierr; 8034222ddf1SHong Zhang Mat_Product *product = mat->product; 8044222ddf1SHong Zhang MatProductType productype = product->type; 8054222ddf1SHong Zhang PetscLogEvent eventtype=-1; 8064222ddf1SHong Zhang 8074222ddf1SHong Zhang PetscFunctionBegin; 8084222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8094222ddf1SHong Zhang 8104222ddf1SHong Zhang /* log event */ 8114222ddf1SHong Zhang switch (productype) { 8124222ddf1SHong Zhang case MATPRODUCT_AB: 8134222ddf1SHong Zhang eventtype = MAT_MatMultSymbolic; 8144222ddf1SHong Zhang break; 8154222ddf1SHong Zhang case MATPRODUCT_AtB: 8164222ddf1SHong Zhang eventtype = MAT_TransposeMatMultSymbolic; 8174222ddf1SHong Zhang break; 8184222ddf1SHong Zhang case MATPRODUCT_ABt: 8194222ddf1SHong Zhang eventtype = MAT_MatTransposeMultSymbolic; 8204222ddf1SHong Zhang break; 8214222ddf1SHong Zhang case MATPRODUCT_PtAP: 8224222ddf1SHong Zhang eventtype = MAT_PtAPSymbolic; 8234222ddf1SHong Zhang break; 8244222ddf1SHong Zhang case MATPRODUCT_RARt: 8254222ddf1SHong Zhang eventtype = MAT_RARtSymbolic; 8264222ddf1SHong Zhang break; 8274222ddf1SHong Zhang case MATPRODUCT_ABC: 8284222ddf1SHong Zhang eventtype = MAT_MatMatMultSymbolic; 8294222ddf1SHong Zhang break; 8304222ddf1SHong Zhang default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MATPRODUCT type is not supported"); 8314222ddf1SHong Zhang } 8324222ddf1SHong Zhang 8334222ddf1SHong Zhang if (mat->ops->productsymbolic) { 8344222ddf1SHong Zhang ierr = PetscLogEventBegin(eventtype,mat,0,0,0);CHKERRQ(ierr); 8354222ddf1SHong Zhang ierr = (*mat->ops->productsymbolic)(mat);CHKERRQ(ierr); 8364222ddf1SHong Zhang ierr = PetscLogEventEnd(eventtype,mat,0,0,0);CHKERRQ(ierr); 8374222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_USER,"Call MatProductSetFromOptions() first"); 8384222ddf1SHong Zhang PetscFunctionReturn(0); 8394222ddf1SHong Zhang } 8404222ddf1SHong Zhang 8414222ddf1SHong Zhang /*@ 8424222ddf1SHong Zhang MatProductSetFill - Set an expected fill of the matrix product. 8434222ddf1SHong Zhang 8444222ddf1SHong Zhang Collective on Mat 8454222ddf1SHong Zhang 8464222ddf1SHong Zhang Input Parameters: 8474222ddf1SHong Zhang + mat - the matrix product 8484222ddf1SHong Zhang - fill - expected fill as ratio of nnz(mat)/(nnz(A) + nnz(B) + nnz(C)); use PETSC_DEFAULT if you do not have a good estimate. If the product is a dense matrix, this is irrelevent. 8494222ddf1SHong Zhang 8504222ddf1SHong Zhang Level: intermediate 8514222ddf1SHong Zhang 8524222ddf1SHong Zhang .seealso: MatProductSetType(), MatProductSetAlgorithm(), MatProductCreate() 8534222ddf1SHong Zhang @*/ 8544222ddf1SHong Zhang PetscErrorCode MatProductSetFill(Mat mat,PetscReal fill) 8554222ddf1SHong Zhang { 8564222ddf1SHong Zhang Mat_Product *product = mat->product; 8574222ddf1SHong Zhang 8584222ddf1SHong Zhang PetscFunctionBegin; 8594222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8604222ddf1SHong Zhang 8614222ddf1SHong Zhang if (!product) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_NULL,"Data struc Mat_Product is not created, call MatProductCreate() first"); 8624222ddf1SHong Zhang if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) { 8634222ddf1SHong Zhang product->fill = 2.0; 8644222ddf1SHong Zhang } else product->fill = fill; 8654222ddf1SHong Zhang PetscFunctionReturn(0); 8664222ddf1SHong Zhang } 8674222ddf1SHong Zhang 8684222ddf1SHong Zhang /*@ 8694222ddf1SHong Zhang MatProductSetAlgorithm - Requests a particular algorithm for a matrix product implementation. 8704222ddf1SHong Zhang 8714222ddf1SHong Zhang Collective on Mat 8724222ddf1SHong Zhang 8734222ddf1SHong Zhang Input Parameters: 8744222ddf1SHong Zhang + mat - the matrix product 8754222ddf1SHong Zhang - alg - particular implementation algorithm of the matrix product, e.g., MATPRODUCTALGORITHM_DEFAULT. 8764222ddf1SHong Zhang 8774222ddf1SHong Zhang Level: intermediate 8784222ddf1SHong Zhang 8794222ddf1SHong Zhang .seealso: MatProductSetType(), MatProductSetFill(), MatProductCreate() 8804222ddf1SHong Zhang @*/ 8814222ddf1SHong Zhang PetscErrorCode MatProductSetAlgorithm(Mat mat,MatProductAlgorithm alg) 8824222ddf1SHong Zhang { 8834222ddf1SHong Zhang Mat_Product *product = mat->product; 8844222ddf1SHong Zhang 8854222ddf1SHong Zhang PetscFunctionBegin; 8864222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8874222ddf1SHong Zhang 8884222ddf1SHong Zhang if (!product) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_NULL,"Data struc Mat_Product is not created, call MatProductCreate() first"); 8894222ddf1SHong Zhang product->alg = alg; 8904222ddf1SHong Zhang PetscFunctionReturn(0); 8914222ddf1SHong Zhang } 8924222ddf1SHong Zhang 8934222ddf1SHong Zhang /*@ 8944222ddf1SHong Zhang MatProductSetType - Sets a particular matrix product type, for example Mat*Mat. 8954222ddf1SHong Zhang 8964222ddf1SHong Zhang Collective on Mat 8974222ddf1SHong Zhang 8984222ddf1SHong Zhang Input Parameters: 8994222ddf1SHong Zhang + mat - the matrix 9004222ddf1SHong Zhang - productype - matrix product type, e.g., MATPRODUCT_AB,MATPRODUCT_AtB,MATPRODUCT_ABt,MATPRODUCT_PtAP,MATPRODUCT_RARt,MATPRODUCT_ABC. 9014222ddf1SHong Zhang 9024222ddf1SHong Zhang Level: intermediate 9034222ddf1SHong Zhang 9044222ddf1SHong Zhang .seealso: MatProductCreate(), MatProductType, MatProductAlgorithm 9054222ddf1SHong Zhang @*/ 9064222ddf1SHong Zhang PetscErrorCode MatProductSetType(Mat mat,MatProductType productype) 9074222ddf1SHong Zhang { 9084222ddf1SHong Zhang PetscErrorCode ierr; 9094222ddf1SHong Zhang Mat_Product *product = mat->product; 9104222ddf1SHong Zhang MPI_Comm comm; 9114222ddf1SHong Zhang 9124222ddf1SHong Zhang PetscFunctionBegin; 9134222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9144222ddf1SHong Zhang 9154222ddf1SHong Zhang ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 9164222ddf1SHong Zhang if (!product) SETERRQ(comm,PETSC_ERR_ARG_NULL,"Data struc Mat_Product is not created, call MatProductCreate() first"); 9174222ddf1SHong Zhang product->type = productype; 9184222ddf1SHong Zhang 9194222ddf1SHong Zhang switch (productype) { 9204222ddf1SHong Zhang case MATPRODUCT_AB: 9214222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_AB; 9224222ddf1SHong Zhang break; 9234222ddf1SHong Zhang case MATPRODUCT_AtB: 9244222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_AtB; 9254222ddf1SHong Zhang break; 9264222ddf1SHong Zhang case MATPRODUCT_ABt: 9274222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_ABt; 9284222ddf1SHong Zhang break; 9294222ddf1SHong Zhang case MATPRODUCT_PtAP: 9304222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_PtAP; 9314222ddf1SHong Zhang break; 9324222ddf1SHong Zhang case MATPRODUCT_RARt: 9334222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_RARt; 9344222ddf1SHong Zhang break; 9354222ddf1SHong Zhang case MATPRODUCT_ABC: 9364222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_ABC; 9374222ddf1SHong Zhang break; 938*544a5e07SHong Zhang default: SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"ProductType %s is not supported",MatProductTypes[product->type]); 9394222ddf1SHong Zhang } 9404222ddf1SHong Zhang PetscFunctionReturn(0); 9414222ddf1SHong Zhang } 9424222ddf1SHong Zhang 9434417c5e8SHong Zhang /*@ 9444417c5e8SHong Zhang MatProductClear - Clears matrix product internal structure. 9454417c5e8SHong Zhang 9464417c5e8SHong Zhang Collective on Mat 9474417c5e8SHong Zhang 9484417c5e8SHong Zhang Input Parameters: 9494417c5e8SHong Zhang . mat - the product matrix 9504417c5e8SHong Zhang 9514417c5e8SHong Zhang Level: intermediate 9524417c5e8SHong Zhang @*/ 9534417c5e8SHong Zhang PetscErrorCode MatProductClear(Mat mat) 9544417c5e8SHong Zhang { 9554417c5e8SHong Zhang PetscErrorCode ierr; 9564417c5e8SHong Zhang Mat_Product *product = mat->product; 9574417c5e8SHong Zhang 9584417c5e8SHong Zhang PetscFunctionBegin; 9594417c5e8SHong Zhang if (product) { 9604417c5e8SHong Zhang /* release reference */ 9614417c5e8SHong Zhang ierr = MatDestroy(&product->A);CHKERRQ(ierr); 9624417c5e8SHong Zhang ierr = MatDestroy(&product->B);CHKERRQ(ierr); 9634417c5e8SHong Zhang ierr = MatDestroy(&product->C);CHKERRQ(ierr); 9644417c5e8SHong Zhang ierr = MatDestroy(&product->Dwork);CHKERRQ(ierr); 9654417c5e8SHong Zhang ierr = PetscFree(mat->product);CHKERRQ(ierr); 9664417c5e8SHong Zhang } 9674417c5e8SHong Zhang PetscFunctionReturn(0); 9684417c5e8SHong Zhang } 9694417c5e8SHong Zhang 9704222ddf1SHong Zhang /* Create a supporting struct and attach it to the matrix product */ 9714417c5e8SHong Zhang PetscErrorCode MatProductCreate_Private(Mat A,Mat B,Mat C,Mat D) 9724222ddf1SHong Zhang { 9734222ddf1SHong Zhang PetscErrorCode ierr; 9744222ddf1SHong Zhang Mat_Product *product=NULL; 9754222ddf1SHong Zhang 9764222ddf1SHong Zhang PetscFunctionBegin; 9774222ddf1SHong Zhang ierr = PetscNewLog(D,&product);CHKERRQ(ierr); 9784222ddf1SHong Zhang product->A = A; 9794222ddf1SHong Zhang product->B = B; 9804222ddf1SHong Zhang product->C = C; 9814222ddf1SHong Zhang product->Dwork = NULL; 9824222ddf1SHong Zhang product->alg = MATPRODUCTALGORITHM_DEFAULT; 9834222ddf1SHong Zhang product->fill = 2.0; /* PETSC_DEFAULT */ 9844222ddf1SHong Zhang product->Areplaced = PETSC_FALSE; 9854222ddf1SHong Zhang product->Breplaced = PETSC_FALSE; 9864222ddf1SHong Zhang product->api_user = PETSC_FALSE; 9874222ddf1SHong Zhang D->product = product; 9884417c5e8SHong Zhang 9894417c5e8SHong Zhang /* take ownership */ 9904417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 9914417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 9924417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr); 9934222ddf1SHong Zhang PetscFunctionReturn(0); 9944222ddf1SHong Zhang } 9954222ddf1SHong Zhang 9964222ddf1SHong Zhang /*@ 9974222ddf1SHong Zhang MatProductCreateWithMat - Setup a given matrix as a matrix product. 9984222ddf1SHong Zhang 9994222ddf1SHong Zhang Collective on Mat 10004222ddf1SHong Zhang 10014222ddf1SHong Zhang Input Parameters: 10024222ddf1SHong Zhang + A - the first matrix 10034222ddf1SHong Zhang . B - the second matrix 10044222ddf1SHong Zhang . C - the third matrix (optional) 10054222ddf1SHong Zhang - D - the matrix which will be used as a product 10064222ddf1SHong Zhang 10074222ddf1SHong Zhang Output Parameters: 10084222ddf1SHong Zhang . D - the product matrix 10094222ddf1SHong Zhang 10104222ddf1SHong Zhang Level: intermediate 10114222ddf1SHong Zhang 10124222ddf1SHong Zhang .seealso: MatProductCreate() 10134222ddf1SHong Zhang @*/ 10144222ddf1SHong Zhang PetscErrorCode MatProductCreateWithMat(Mat A,Mat B,Mat C,Mat D) 10154222ddf1SHong Zhang { 10164222ddf1SHong Zhang PetscErrorCode ierr; 10174222ddf1SHong Zhang 10184222ddf1SHong Zhang PetscFunctionBegin; 10194222ddf1SHong Zhang PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10204222ddf1SHong Zhang PetscValidType(A,1); 10214222ddf1SHong Zhang MatCheckPreallocated(A,1); 10224222ddf1SHong Zhang if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10234222ddf1SHong Zhang if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10244222ddf1SHong Zhang 10254222ddf1SHong Zhang PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10264222ddf1SHong Zhang PetscValidType(B,2); 10274222ddf1SHong Zhang MatCheckPreallocated(B,2); 10284222ddf1SHong Zhang if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10294222ddf1SHong Zhang if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10304222ddf1SHong Zhang 10314222ddf1SHong Zhang if (C) { 10324222ddf1SHong Zhang PetscValidHeaderSpecific(C,MAT_CLASSID,3); 10334222ddf1SHong Zhang PetscValidType(C,3); 10344222ddf1SHong Zhang MatCheckPreallocated(C,3); 10354222ddf1SHong Zhang if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10364222ddf1SHong Zhang if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10374222ddf1SHong Zhang } 10384222ddf1SHong Zhang 10394222ddf1SHong Zhang PetscValidHeaderSpecific(D,MAT_CLASSID,4); 10404222ddf1SHong Zhang PetscValidType(D,4); 10414222ddf1SHong Zhang MatCheckPreallocated(D,4); 10424222ddf1SHong Zhang if (!D->assembled) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10434222ddf1SHong Zhang if (D->factortype) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10444222ddf1SHong Zhang 10454222ddf1SHong Zhang /* Create a supporting struct and attach it to D */ 10464222ddf1SHong Zhang ierr = MatProductCreate_Private(A,B,C,D);CHKERRQ(ierr); 10474222ddf1SHong Zhang PetscFunctionReturn(0); 10484222ddf1SHong Zhang } 10494222ddf1SHong Zhang 10504222ddf1SHong Zhang /*@ 10514222ddf1SHong Zhang MatProductCreate - create a matrix product object that can be used to compute various matrix times matrix operations. 10524222ddf1SHong Zhang 10534222ddf1SHong Zhang Collective on Mat 10544222ddf1SHong Zhang 10554222ddf1SHong Zhang Input Parameters: 10564222ddf1SHong Zhang + A - the first matrix 10574222ddf1SHong Zhang . B - the second matrix 10584222ddf1SHong Zhang - C - the third matrix (optional) 10594222ddf1SHong Zhang 10604222ddf1SHong Zhang Output Parameters: 10614222ddf1SHong Zhang . D - the product matrix 10624222ddf1SHong Zhang 10634222ddf1SHong Zhang Level: intermediate 10644222ddf1SHong Zhang 10654222ddf1SHong Zhang .seealso: MatProductCreateWithMat(), MatProductSetType(), MatProductSetAlgorithm() 10664222ddf1SHong Zhang @*/ 10674222ddf1SHong Zhang PetscErrorCode MatProductCreate(Mat A,Mat B,Mat C,Mat *D) 10684222ddf1SHong Zhang { 10694222ddf1SHong Zhang PetscErrorCode ierr; 10704222ddf1SHong Zhang 10714222ddf1SHong Zhang PetscFunctionBegin; 10724222ddf1SHong Zhang PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10734222ddf1SHong Zhang PetscValidType(A,1); 10744222ddf1SHong Zhang MatCheckPreallocated(A,1); 10754222ddf1SHong Zhang if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10764222ddf1SHong Zhang if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10774222ddf1SHong Zhang 10784222ddf1SHong Zhang PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10794222ddf1SHong Zhang PetscValidType(B,2); 10804222ddf1SHong Zhang MatCheckPreallocated(B,2); 10814222ddf1SHong Zhang if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10824222ddf1SHong Zhang if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10834222ddf1SHong Zhang 10844222ddf1SHong Zhang if (C) { 10854222ddf1SHong Zhang PetscValidHeaderSpecific(C,MAT_CLASSID,3); 10864222ddf1SHong Zhang PetscValidType(C,3); 10874222ddf1SHong Zhang MatCheckPreallocated(C,3); 10884222ddf1SHong Zhang if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10894222ddf1SHong Zhang if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10904222ddf1SHong Zhang } 10914222ddf1SHong Zhang 10924222ddf1SHong Zhang PetscValidPointer(D,4); 10934222ddf1SHong Zhang 10944222ddf1SHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)A),D);CHKERRQ(ierr); 10954222ddf1SHong Zhang ierr = MatProductCreate_Private(A,B,C,*D);CHKERRQ(ierr); 10964222ddf1SHong Zhang PetscFunctionReturn(0); 10974222ddf1SHong Zhang } 1098