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