1*4222ddf1SHong Zhang 2*4222ddf1SHong Zhang /* 3*4222ddf1SHong Zhang Routines for matrix products. Calling procedure: 4*4222ddf1SHong Zhang 5*4222ddf1SHong Zhang MatProductCreate(A,B,C,&D); or MatProductCreateWithMat(A,B,C,D); 6*4222ddf1SHong Zhang MatProductSetType(D, MATPRODUCT_AB/AtB/ABt/PtAP/RARt/ABC); 7*4222ddf1SHong Zhang MatProductSetAlgorithm(D, alg); 8*4222ddf1SHong Zhang MatProductSetFill(D,fill); 9*4222ddf1SHong Zhang MatProductSetFromOptions(D); 10*4222ddf1SHong Zhang -> MatProductSetFromOptions_producttype(D): 11*4222ddf1SHong Zhang # Check matrix global sizes 12*4222ddf1SHong Zhang -> MatProductSetFromOptions_Atype_Btype_Ctype(D); 13*4222ddf1SHong Zhang ->MatProductSetFromOptions_Atype_Btype_Ctype_productype(D): 14*4222ddf1SHong Zhang # Check matrix local sizes for mpi matrices 15*4222ddf1SHong Zhang # Set default algorithm 16*4222ddf1SHong Zhang # Get runtime option 17*4222ddf1SHong Zhang # Set D->ops->productsymbolic = MatProductSymbolic_productype_Atype_Btype_Ctype; 18*4222ddf1SHong Zhang 19*4222ddf1SHong Zhang PetscLogEventBegin() 20*4222ddf1SHong Zhang MatProductSymbolic(D): 21*4222ddf1SHong Zhang # Call MatxxxSymbolic_Atype_Btype_Ctype(); 22*4222ddf1SHong Zhang # Set D->ops->productnumeric = MatProductNumeric_productype_Atype_Btype_Ctype; 23*4222ddf1SHong Zhang PetscLogEventEnd() 24*4222ddf1SHong Zhang 25*4222ddf1SHong Zhang PetscLogEventBegin() 26*4222ddf1SHong Zhang MatProductNumeric(D); 27*4222ddf1SHong Zhang # Call (D->ops->matxxxnumeric)(); 28*4222ddf1SHong Zhang PetscLogEventEnd() 29*4222ddf1SHong Zhang */ 30*4222ddf1SHong Zhang 31*4222ddf1SHong Zhang #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 32*4222ddf1SHong Zhang 33*4222ddf1SHong Zhang static PetscErrorCode MatProductNumeric_PtAP_Basic(Mat C) 34*4222ddf1SHong Zhang { 35*4222ddf1SHong Zhang PetscErrorCode ierr; 36*4222ddf1SHong Zhang Mat_Product *product = C->product; 37*4222ddf1SHong Zhang Mat P = product->B,AP = product->Dwork; 38*4222ddf1SHong Zhang 39*4222ddf1SHong Zhang PetscFunctionBegin; 40*4222ddf1SHong Zhang /* AP = A*P */ 41*4222ddf1SHong Zhang ierr = MatProductNumeric(AP);CHKERRQ(ierr); 42*4222ddf1SHong Zhang /* C = P^T*AP */ 43*4222ddf1SHong Zhang ierr = (C->ops->transposematmultnumeric)(P,AP,C);CHKERRQ(ierr); 44*4222ddf1SHong Zhang PetscFunctionReturn(0); 45*4222ddf1SHong Zhang } 46*4222ddf1SHong Zhang 47*4222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_PtAP_Basic(Mat C) 48*4222ddf1SHong Zhang { 49*4222ddf1SHong Zhang PetscErrorCode ierr; 50*4222ddf1SHong Zhang Mat_Product *product = C->product; 51*4222ddf1SHong Zhang Mat A=product->A,P=product->B,AP; 52*4222ddf1SHong Zhang PetscReal fill=product->fill; 53*4222ddf1SHong Zhang 54*4222ddf1SHong Zhang PetscFunctionBegin; 55*4222ddf1SHong Zhang /* AP = A*P */ 56*4222ddf1SHong Zhang ierr = MatProductCreate(A,P,NULL,&AP);CHKERRQ(ierr); 57*4222ddf1SHong Zhang ierr = MatProductSetType(AP,MATPRODUCT_AB);CHKERRQ(ierr); 58*4222ddf1SHong Zhang ierr = MatProductSetAlgorithm(AP,"default");CHKERRQ(ierr); 59*4222ddf1SHong Zhang ierr = MatProductSetFill(AP,fill);CHKERRQ(ierr); 60*4222ddf1SHong Zhang ierr = MatProductSetFromOptions(AP);CHKERRQ(ierr); 61*4222ddf1SHong Zhang ierr = MatProductSymbolic(AP);CHKERRQ(ierr); 62*4222ddf1SHong Zhang 63*4222ddf1SHong Zhang /* C = P^T*AP */ 64*4222ddf1SHong Zhang ierr = MatProductSetType(C,MATPRODUCT_AtB);CHKERRQ(ierr); 65*4222ddf1SHong Zhang product->alg = "default"; 66*4222ddf1SHong Zhang product->A = P; 67*4222ddf1SHong Zhang product->B = AP; 68*4222ddf1SHong Zhang ierr = MatProductSetFromOptions(C);CHKERRQ(ierr); 69*4222ddf1SHong Zhang ierr = MatProductSymbolic(C);CHKERRQ(ierr); 70*4222ddf1SHong Zhang 71*4222ddf1SHong Zhang /* resume user's original input matrix setting for A and B */ 72*4222ddf1SHong Zhang product->A = A; 73*4222ddf1SHong Zhang product->B = P; 74*4222ddf1SHong Zhang product->Dwork = AP; 75*4222ddf1SHong Zhang 76*4222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_PtAP_Basic; 77*4222ddf1SHong Zhang PetscFunctionReturn(0); 78*4222ddf1SHong Zhang } 79*4222ddf1SHong Zhang 80*4222ddf1SHong Zhang static PetscErrorCode MatProductNumeric_RARt_Basic(Mat C) 81*4222ddf1SHong Zhang { 82*4222ddf1SHong Zhang PetscErrorCode ierr; 83*4222ddf1SHong Zhang Mat_Product *product = C->product; 84*4222ddf1SHong Zhang Mat R=product->B,RA=product->Dwork; 85*4222ddf1SHong Zhang 86*4222ddf1SHong Zhang PetscFunctionBegin; 87*4222ddf1SHong Zhang /* RA = R*A */ 88*4222ddf1SHong Zhang ierr = MatProductNumeric(RA);CHKERRQ(ierr); 89*4222ddf1SHong Zhang /* C = RA*R^T */ 90*4222ddf1SHong Zhang ierr = (C->ops->mattransposemultnumeric)(RA,R,C);CHKERRQ(ierr); 91*4222ddf1SHong Zhang PetscFunctionReturn(0); 92*4222ddf1SHong Zhang } 93*4222ddf1SHong Zhang 94*4222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_RARt_Basic(Mat C) 95*4222ddf1SHong Zhang { 96*4222ddf1SHong Zhang PetscErrorCode ierr; 97*4222ddf1SHong Zhang Mat_Product *product = C->product; 98*4222ddf1SHong Zhang Mat A=product->A,R=product->B,RA; 99*4222ddf1SHong Zhang PetscReal fill=product->fill; 100*4222ddf1SHong Zhang 101*4222ddf1SHong Zhang PetscFunctionBegin; 102*4222ddf1SHong Zhang /* RA = R*A */ 103*4222ddf1SHong Zhang ierr = MatProductCreate(R,A,NULL,&RA);CHKERRQ(ierr); 104*4222ddf1SHong Zhang ierr = MatProductSetType(RA,MATPRODUCT_AB);CHKERRQ(ierr); 105*4222ddf1SHong Zhang ierr = MatProductSetAlgorithm(RA,"default");CHKERRQ(ierr); 106*4222ddf1SHong Zhang ierr = MatProductSetFill(RA,fill);CHKERRQ(ierr); 107*4222ddf1SHong Zhang ierr = MatProductSetFromOptions(RA);CHKERRQ(ierr); 108*4222ddf1SHong Zhang ierr = MatProductSymbolic(RA);CHKERRQ(ierr); 109*4222ddf1SHong Zhang 110*4222ddf1SHong Zhang /* C = RA*R^T */ 111*4222ddf1SHong Zhang ierr = MatProductSetType(C,MATPRODUCT_ABt);CHKERRQ(ierr); 112*4222ddf1SHong Zhang product->alg = "default"; 113*4222ddf1SHong Zhang product->A = RA; 114*4222ddf1SHong Zhang ierr = MatProductSetFromOptions(C);CHKERRQ(ierr); 115*4222ddf1SHong Zhang ierr = MatProductSymbolic(C);CHKERRQ(ierr); 116*4222ddf1SHong Zhang 117*4222ddf1SHong Zhang /* resume user's original input matrix setting for A */ 118*4222ddf1SHong Zhang product->A = A; 119*4222ddf1SHong Zhang product->Dwork = RA; /* save here so it will be destroyed with product C */ 120*4222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_RARt_Basic; 121*4222ddf1SHong Zhang PetscFunctionReturn(0); 122*4222ddf1SHong Zhang } 123*4222ddf1SHong Zhang 124*4222ddf1SHong Zhang static PetscErrorCode MatProductNumeric_ABC_Basic(Mat mat) 125*4222ddf1SHong Zhang { 126*4222ddf1SHong Zhang PetscErrorCode ierr; 127*4222ddf1SHong Zhang Mat_Product *product = mat->product; 128*4222ddf1SHong Zhang Mat A=product->A,BC=product->Dwork; 129*4222ddf1SHong Zhang 130*4222ddf1SHong Zhang PetscFunctionBegin; 131*4222ddf1SHong Zhang /* Numeric BC = B*C */ 132*4222ddf1SHong Zhang ierr = MatProductNumeric(BC);CHKERRQ(ierr); 133*4222ddf1SHong Zhang /* Numeric mat = A*BC */ 134*4222ddf1SHong Zhang ierr = (mat->ops->matmultnumeric)(A,BC,mat);CHKERRQ(ierr); 135*4222ddf1SHong Zhang PetscFunctionReturn(0); 136*4222ddf1SHong Zhang } 137*4222ddf1SHong Zhang 138*4222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_ABC_Basic(Mat mat) 139*4222ddf1SHong Zhang { 140*4222ddf1SHong Zhang PetscErrorCode ierr; 141*4222ddf1SHong Zhang Mat_Product *product = mat->product; 142*4222ddf1SHong Zhang Mat B=product->B,C=product->C,BC; 143*4222ddf1SHong Zhang PetscReal fill=product->fill; 144*4222ddf1SHong Zhang 145*4222ddf1SHong Zhang PetscFunctionBegin; 146*4222ddf1SHong Zhang /* Symbolic BC = B*C */ 147*4222ddf1SHong Zhang ierr = MatProductCreate(B,C,NULL,&BC);CHKERRQ(ierr); 148*4222ddf1SHong Zhang ierr = MatProductSetType(BC,MATPRODUCT_AB);CHKERRQ(ierr); 149*4222ddf1SHong Zhang ierr = MatProductSetAlgorithm(BC,"default");CHKERRQ(ierr); 150*4222ddf1SHong Zhang ierr = MatProductSetFill(BC,fill);CHKERRQ(ierr); 151*4222ddf1SHong Zhang ierr = MatProductSetFromOptions(BC);CHKERRQ(ierr); 152*4222ddf1SHong Zhang ierr = MatProductSymbolic(BC);CHKERRQ(ierr); 153*4222ddf1SHong Zhang 154*4222ddf1SHong Zhang /* Symbolic mat = A*BC */ 155*4222ddf1SHong Zhang ierr = MatProductSetType(mat,MATPRODUCT_AB);CHKERRQ(ierr); 156*4222ddf1SHong Zhang product->alg = "default"; 157*4222ddf1SHong Zhang product->B = BC; 158*4222ddf1SHong Zhang product->Dwork = BC; 159*4222ddf1SHong Zhang ierr = MatProductSetFromOptions(mat);CHKERRQ(ierr); 160*4222ddf1SHong Zhang ierr = MatProductSymbolic(mat);CHKERRQ(ierr); 161*4222ddf1SHong Zhang 162*4222ddf1SHong Zhang /* resume user's original input matrix setting for B */ 163*4222ddf1SHong Zhang product->B = B; 164*4222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_ABC_Basic; 165*4222ddf1SHong Zhang PetscFunctionReturn(0); 166*4222ddf1SHong Zhang } 167*4222ddf1SHong Zhang 168*4222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_Basic(Mat mat) 169*4222ddf1SHong Zhang { 170*4222ddf1SHong Zhang PetscErrorCode ierr; 171*4222ddf1SHong Zhang Mat_Product *product = mat->product; 172*4222ddf1SHong Zhang 173*4222ddf1SHong Zhang PetscFunctionBegin; 174*4222ddf1SHong Zhang switch (product->type) { 175*4222ddf1SHong Zhang case MATPRODUCT_PtAP: 176*4222ddf1SHong Zhang PetscInfo2((PetscObject)mat, "MatProduct_Basic_PtAP() for A %s, P %s is used",((PetscObject)product->A)->type_name,((PetscObject)product->B)->type_name); 177*4222ddf1SHong Zhang ierr = MatProductSymbolic_PtAP_Basic(mat);CHKERRQ(ierr); 178*4222ddf1SHong Zhang break; 179*4222ddf1SHong Zhang case MATPRODUCT_RARt: 180*4222ddf1SHong Zhang PetscInfo2((PetscObject)mat, "MatProduct_Basic_RARt() for A %s, R %s is used",((PetscObject)product->A)->type_name,((PetscObject)product->B)->type_name); 181*4222ddf1SHong Zhang ierr = MatProductSymbolic_RARt_Basic(mat);CHKERRQ(ierr); 182*4222ddf1SHong Zhang break; 183*4222ddf1SHong Zhang case MATPRODUCT_ABC: 184*4222ddf1SHong 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); 185*4222ddf1SHong Zhang ierr = MatProductSymbolic_ABC_Basic(mat);CHKERRQ(ierr); 186*4222ddf1SHong Zhang break; 187*4222ddf1SHong Zhang default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"ProductType is not supported"); 188*4222ddf1SHong Zhang } 189*4222ddf1SHong Zhang PetscFunctionReturn(0); 190*4222ddf1SHong Zhang } 191*4222ddf1SHong Zhang 192*4222ddf1SHong Zhang /* ----------------------------------------------- */ 193*4222ddf1SHong Zhang /*@C 194*4222ddf1SHong Zhang MatProductReplaceMats - Replace input matrices for a matrix product. 195*4222ddf1SHong Zhang 196*4222ddf1SHong Zhang Collective on Mat 197*4222ddf1SHong Zhang 198*4222ddf1SHong Zhang Input Parameters: 199*4222ddf1SHong Zhang + A - the matrix or NULL if not being replaced 200*4222ddf1SHong Zhang . B - the matrix or NULL if not being replaced 201*4222ddf1SHong Zhang . C - the matrix or NULL if not being replaced 202*4222ddf1SHong Zhang - D - the matrix product 203*4222ddf1SHong Zhang 204*4222ddf1SHong Zhang Level: intermediate 205*4222ddf1SHong Zhang 206*4222ddf1SHong Zhang Notes: 207*4222ddf1SHong Zhang Input matrix must have exactly same data structure as replaced one. 208*4222ddf1SHong Zhang 209*4222ddf1SHong Zhang .seealso: MatProductCreate() 210*4222ddf1SHong Zhang @*/ 211*4222ddf1SHong Zhang PetscErrorCode MatProductReplaceMats(Mat A,Mat B,Mat C,Mat D) 212*4222ddf1SHong Zhang { 213*4222ddf1SHong Zhang Mat_Product *product=D->product; 214*4222ddf1SHong Zhang 215*4222ddf1SHong Zhang PetscFunctionBegin; 216*4222ddf1SHong Zhang if (!product) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_ARG_NULL,"Mat D does not have struct 'product'. Call MatProductReplaceProduct(). \n"); 217*4222ddf1SHong Zhang if (A) { 218*4222ddf1SHong Zhang if (!product->Areplaced) { 219*4222ddf1SHong Zhang product->A = A; 220*4222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_SUP,"Matrix A was changed by a PETSc internal routine, cannot be replaced"); 221*4222ddf1SHong Zhang } 222*4222ddf1SHong Zhang if (B) { 223*4222ddf1SHong Zhang if (!product->Breplaced) { 224*4222ddf1SHong Zhang product->B = B; 225*4222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_SUP,"Matrix B was changed by a PETSc internal routine, cannot be replaced"); 226*4222ddf1SHong Zhang } 227*4222ddf1SHong Zhang if (C) product->C = C; 228*4222ddf1SHong Zhang PetscFunctionReturn(0); 229*4222ddf1SHong Zhang } 230*4222ddf1SHong Zhang 231*4222ddf1SHong Zhang /* ----------------------------------------------- */ 232*4222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_AB(Mat mat) 233*4222ddf1SHong Zhang { 234*4222ddf1SHong Zhang PetscErrorCode ierr; 235*4222ddf1SHong Zhang Mat_Product *product = mat->product; 236*4222ddf1SHong Zhang Mat A=product->A,B=product->B; 237*4222ddf1SHong Zhang PetscBool sametype; 238*4222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 239*4222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 240*4222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 241*4222ddf1SHong Zhang PetscBool A_istrans,B_istrans; 242*4222ddf1SHong Zhang 243*4222ddf1SHong Zhang PetscFunctionBegin; 244*4222ddf1SHong Zhang /* Check matrix global sizes */ 245*4222ddf1SHong 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); 246*4222ddf1SHong Zhang 247*4222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 248*4222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 249*4222ddf1SHong Zhang 250*4222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 251*4222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&A_istrans);CHKERRQ(ierr); 252*4222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&B_istrans);CHKERRQ(ierr); 253*4222ddf1SHong Zhang 254*4222ddf1SHong Zhang if (fB == fA && sametype && (!A_istrans || !B_istrans)) { 255*4222ddf1SHong Zhang f = fB; 256*4222ddf1SHong Zhang } else { 257*4222ddf1SHong Zhang char mtypes[256]; 258*4222ddf1SHong Zhang PetscBool At_istrans=PETSC_TRUE,Bt_istrans=PETSC_TRUE; 259*4222ddf1SHong Zhang Mat At = NULL,Bt = NULL; 260*4222ddf1SHong Zhang 261*4222ddf1SHong Zhang if (A_istrans && !B_istrans) { 262*4222ddf1SHong Zhang ierr = MatTransposeGetMat(A,&At);CHKERRQ(ierr); 263*4222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)At,MATTRANSPOSEMAT,&At_istrans);CHKERRQ(ierr); 264*4222ddf1SHong Zhang if (At_istrans) { /* mat = ATT * B */ 265*4222ddf1SHong Zhang Mat Att = NULL; 266*4222ddf1SHong Zhang ierr = MatTransposeGetMat(At,&Att);CHKERRQ(ierr); 267*4222ddf1SHong Zhang A = Att; 268*4222ddf1SHong Zhang product->A = Att; /* use Att for matproduct */ 269*4222ddf1SHong Zhang product->Areplaced = PETSC_TRUE; /* Att = A, but has native matrix type */ 270*4222ddf1SHong Zhang } else { /* !At_istrans: mat = At^T*B */ 271*4222ddf1SHong Zhang A = At; 272*4222ddf1SHong Zhang product->A = At; 273*4222ddf1SHong Zhang product->Areplaced = PETSC_TRUE; 274*4222ddf1SHong Zhang product->type = MATPRODUCT_AtB; 275*4222ddf1SHong Zhang } 276*4222ddf1SHong Zhang } else if (!A_istrans && B_istrans) { 277*4222ddf1SHong Zhang ierr = MatTransposeGetMat(B,&Bt);CHKERRQ(ierr); 278*4222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)Bt,MATTRANSPOSEMAT,&Bt_istrans);CHKERRQ(ierr); 279*4222ddf1SHong Zhang if (Bt_istrans) { /* mat = A * BTT */ 280*4222ddf1SHong Zhang Mat Btt = NULL; 281*4222ddf1SHong Zhang ierr = MatTransposeGetMat(Bt,&Btt);CHKERRQ(ierr); 282*4222ddf1SHong Zhang B = Btt; 283*4222ddf1SHong Zhang product->B = Btt; /* use Btt for matproduct */ 284*4222ddf1SHong Zhang product->Breplaced = PETSC_TRUE; 285*4222ddf1SHong Zhang } else { /* !Bt_istrans */ 286*4222ddf1SHong Zhang /* mat = A*Bt^T */ 287*4222ddf1SHong Zhang B = Bt; 288*4222ddf1SHong Zhang product->B = Bt; 289*4222ddf1SHong Zhang product->Breplaced = PETSC_TRUE; 290*4222ddf1SHong Zhang product->type = MATPRODUCT_ABt; 291*4222ddf1SHong Zhang } 292*4222ddf1SHong Zhang } else if (A_istrans && B_istrans) { /* mat = At^T * Bt^T */ 293*4222ddf1SHong Zhang ierr = MatTransposeGetMat(A,&At);CHKERRQ(ierr); 294*4222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)At,MATTRANSPOSEMAT,&At_istrans);CHKERRQ(ierr); 295*4222ddf1SHong Zhang ierr = MatTransposeGetMat(B,&Bt);CHKERRQ(ierr); 296*4222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)Bt,MATTRANSPOSEMAT,&Bt_istrans);CHKERRQ(ierr); 297*4222ddf1SHong Zhang if (At_istrans && Bt_istrans) { 298*4222ddf1SHong Zhang Mat Att= NULL,Btt = NULL; 299*4222ddf1SHong Zhang ierr = MatTransposeGetMat(At,&Att);CHKERRQ(ierr); 300*4222ddf1SHong Zhang ierr = MatTransposeGetMat(Bt,&Btt);CHKERRQ(ierr); 301*4222ddf1SHong Zhang A = Att; 302*4222ddf1SHong Zhang product->A = Att; product->Areplaced = PETSC_TRUE; 303*4222ddf1SHong Zhang B = Btt; 304*4222ddf1SHong Zhang product->B = Btt; product->Breplaced = PETSC_TRUE; 305*4222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not supported yet"); 306*4222ddf1SHong Zhang } 307*4222ddf1SHong Zhang 308*4222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 309*4222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 310*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 311*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 312*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 313*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 314*4222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 315*4222ddf1SHong Zhang if (!f) { 316*4222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 317*4222ddf1SHong Zhang } 318*4222ddf1SHong Zhang } 319*4222ddf1SHong Zhang 320*4222ddf1SHong 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); 321*4222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 322*4222ddf1SHong Zhang PetscFunctionReturn(0); 323*4222ddf1SHong Zhang } 324*4222ddf1SHong Zhang 325*4222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_AtB(Mat mat) 326*4222ddf1SHong Zhang { 327*4222ddf1SHong Zhang PetscErrorCode ierr; 328*4222ddf1SHong Zhang Mat_Product *product = mat->product; 329*4222ddf1SHong Zhang Mat A=product->A,B=product->B; 330*4222ddf1SHong Zhang PetscBool sametype; 331*4222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 332*4222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 333*4222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 334*4222ddf1SHong Zhang 335*4222ddf1SHong Zhang PetscFunctionBegin; 336*4222ddf1SHong Zhang /* Check matrix global sizes */ 337*4222ddf1SHong 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); 338*4222ddf1SHong Zhang 339*4222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 340*4222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 341*4222ddf1SHong Zhang 342*4222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 343*4222ddf1SHong Zhang 344*4222ddf1SHong Zhang if (fB == fA && sametype) { 345*4222ddf1SHong Zhang f = fB; 346*4222ddf1SHong Zhang } else { 347*4222ddf1SHong Zhang char mtypes[256]; 348*4222ddf1SHong Zhang PetscBool istrans; 349*4222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 350*4222ddf1SHong Zhang if (!istrans) { 351*4222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 352*4222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 353*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 354*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 355*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 356*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 357*4222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 358*4222ddf1SHong Zhang } else { 359*4222ddf1SHong Zhang Mat T = NULL; 360*4222ddf1SHong 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); 361*4222ddf1SHong Zhang 362*4222ddf1SHong Zhang ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 363*4222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 364*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)T)->type_name,sizeof(mtypes));CHKERRQ(ierr); 365*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 366*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 367*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 368*4222ddf1SHong Zhang 369*4222ddf1SHong Zhang product->type = MATPRODUCT_AtB; 370*4222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 371*4222ddf1SHong Zhang } 372*4222ddf1SHong Zhang 373*4222ddf1SHong Zhang if (!f) { 374*4222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 375*4222ddf1SHong Zhang } 376*4222ddf1SHong Zhang } 377*4222ddf1SHong 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); 378*4222ddf1SHong Zhang 379*4222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 380*4222ddf1SHong Zhang PetscFunctionReturn(0); 381*4222ddf1SHong Zhang } 382*4222ddf1SHong Zhang 383*4222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_ABt(Mat mat) 384*4222ddf1SHong Zhang { 385*4222ddf1SHong Zhang PetscErrorCode ierr; 386*4222ddf1SHong Zhang Mat_Product *product = mat->product; 387*4222ddf1SHong Zhang Mat A=product->A,B=product->B; 388*4222ddf1SHong Zhang PetscBool sametype; 389*4222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 390*4222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 391*4222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 392*4222ddf1SHong Zhang 393*4222ddf1SHong Zhang PetscFunctionBegin; 394*4222ddf1SHong Zhang /* Check matrix global sizes */ 395*4222ddf1SHong 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); 396*4222ddf1SHong Zhang 397*4222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 398*4222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 399*4222ddf1SHong Zhang 400*4222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 401*4222ddf1SHong Zhang 402*4222ddf1SHong Zhang if (fB == fA && sametype) { 403*4222ddf1SHong Zhang f = fB; 404*4222ddf1SHong Zhang } else { 405*4222ddf1SHong Zhang char mtypes[256]; 406*4222ddf1SHong Zhang PetscBool istrans; 407*4222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 408*4222ddf1SHong Zhang if (!istrans) { 409*4222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 410*4222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 411*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 412*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 413*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 414*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 415*4222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 416*4222ddf1SHong Zhang } else { 417*4222ddf1SHong Zhang Mat T = NULL; 418*4222ddf1SHong 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); 419*4222ddf1SHong Zhang 420*4222ddf1SHong Zhang ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 421*4222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 422*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)T)->type_name,sizeof(mtypes));CHKERRQ(ierr); 423*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 424*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 425*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 426*4222ddf1SHong Zhang 427*4222ddf1SHong Zhang product->type = MATPRODUCT_ABt; 428*4222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 429*4222ddf1SHong Zhang } 430*4222ddf1SHong Zhang 431*4222ddf1SHong Zhang if (!f) { 432*4222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 433*4222ddf1SHong Zhang } 434*4222ddf1SHong Zhang } 435*4222ddf1SHong Zhang if (!f) { 436*4222ddf1SHong 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); 437*4222ddf1SHong Zhang } 438*4222ddf1SHong Zhang 439*4222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 440*4222ddf1SHong Zhang PetscFunctionReturn(0); 441*4222ddf1SHong Zhang } 442*4222ddf1SHong Zhang 443*4222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_PtAP(Mat mat) 444*4222ddf1SHong Zhang { 445*4222ddf1SHong Zhang PetscErrorCode ierr; 446*4222ddf1SHong Zhang Mat_Product *product = mat->product; 447*4222ddf1SHong Zhang Mat A=product->A,B=product->B; 448*4222ddf1SHong Zhang PetscBool sametype; 449*4222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 450*4222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 451*4222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 452*4222ddf1SHong Zhang 453*4222ddf1SHong Zhang PetscFunctionBegin; 454*4222ddf1SHong Zhang /* Check matrix global sizes */ 455*4222ddf1SHong 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); 456*4222ddf1SHong 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); 457*4222ddf1SHong Zhang 458*4222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 459*4222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 460*4222ddf1SHong Zhang 461*4222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 462*4222ddf1SHong Zhang if (fB == fA && sametype) { 463*4222ddf1SHong Zhang f = fB; 464*4222ddf1SHong Zhang } else { 465*4222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 466*4222ddf1SHong Zhang char mtypes[256]; 467*4222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 468*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 469*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 470*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 471*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 472*4222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 473*4222ddf1SHong Zhang 474*4222ddf1SHong Zhang if (!f) { 475*4222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 476*4222ddf1SHong Zhang } 477*4222ddf1SHong Zhang } 478*4222ddf1SHong Zhang 479*4222ddf1SHong Zhang if (f) { 480*4222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 481*4222ddf1SHong Zhang } else { 482*4222ddf1SHong Zhang mat->ops->productsymbolic = MatProductSymbolic_Basic; 483*4222ddf1SHong Zhang PetscInfo2((PetscObject)mat, "MatProductSetFromOptions_PtAP for A %s, P %s uses MatProduct_Basic() implementation",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 484*4222ddf1SHong Zhang } 485*4222ddf1SHong Zhang PetscFunctionReturn(0); 486*4222ddf1SHong Zhang } 487*4222ddf1SHong Zhang 488*4222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_RARt(Mat mat) 489*4222ddf1SHong Zhang { 490*4222ddf1SHong Zhang PetscErrorCode ierr; 491*4222ddf1SHong Zhang Mat_Product *product = mat->product; 492*4222ddf1SHong Zhang Mat A=product->A,B=product->B; 493*4222ddf1SHong Zhang PetscBool sametype; 494*4222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 495*4222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 496*4222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 497*4222ddf1SHong Zhang 498*4222ddf1SHong Zhang PetscFunctionBegin; 499*4222ddf1SHong Zhang /* Check matrix global sizes */ 500*4222ddf1SHong 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); 501*4222ddf1SHong 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); 502*4222ddf1SHong Zhang 503*4222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 504*4222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 505*4222ddf1SHong Zhang 506*4222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 507*4222ddf1SHong Zhang if (fB == fA && sametype) { 508*4222ddf1SHong Zhang f = fB; 509*4222ddf1SHong Zhang } else { 510*4222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 511*4222ddf1SHong Zhang char mtypes[256]; 512*4222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 513*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 514*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 515*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 516*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 517*4222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 518*4222ddf1SHong Zhang 519*4222ddf1SHong Zhang if (!f) { 520*4222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 521*4222ddf1SHong Zhang } 522*4222ddf1SHong Zhang } 523*4222ddf1SHong Zhang 524*4222ddf1SHong Zhang if (f) { 525*4222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 526*4222ddf1SHong Zhang } else { 527*4222ddf1SHong Zhang mat->ops->productsymbolic = MatProductSymbolic_Basic; 528*4222ddf1SHong Zhang } 529*4222ddf1SHong Zhang PetscFunctionReturn(0); 530*4222ddf1SHong Zhang } 531*4222ddf1SHong Zhang 532*4222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_ABC(Mat mat) 533*4222ddf1SHong Zhang { 534*4222ddf1SHong Zhang PetscErrorCode ierr; 535*4222ddf1SHong Zhang Mat_Product *product = mat->product; 536*4222ddf1SHong Zhang Mat A=product->A,B=product->B,C=product->C; 537*4222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 538*4222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 539*4222ddf1SHong Zhang PetscErrorCode (*fC)(Mat); 540*4222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 541*4222ddf1SHong Zhang 542*4222ddf1SHong Zhang PetscFunctionBegin; 543*4222ddf1SHong Zhang /* Check matrix global sizes */ 544*4222ddf1SHong 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); 545*4222ddf1SHong 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); 546*4222ddf1SHong Zhang 547*4222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 548*4222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 549*4222ddf1SHong Zhang fC = C->ops->productsetfromoptions; 550*4222ddf1SHong Zhang if (fA == fB && fA == fC && fA) { 551*4222ddf1SHong Zhang f = fA; 552*4222ddf1SHong Zhang } else { 553*4222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype_Ctype */ 554*4222ddf1SHong Zhang char mtypes[256]; 555*4222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 556*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 557*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 558*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 559*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 560*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)C)->type_name,sizeof(mtypes));CHKERRQ(ierr); 561*4222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 562*4222ddf1SHong Zhang 563*4222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 564*4222ddf1SHong Zhang if (!f) { 565*4222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 566*4222ddf1SHong Zhang } 567*4222ddf1SHong Zhang if (!f) { 568*4222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)C,mtypes,&f);CHKERRQ(ierr); 569*4222ddf1SHong Zhang } 570*4222ddf1SHong Zhang } 571*4222ddf1SHong Zhang 572*4222ddf1SHong Zhang if (f) { 573*4222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 574*4222ddf1SHong Zhang } else { /* use MatProductSymbolic/Numeric_Basic() */ 575*4222ddf1SHong Zhang mat->ops->productsymbolic = MatProductSymbolic_Basic; 576*4222ddf1SHong Zhang } 577*4222ddf1SHong Zhang PetscFunctionReturn(0); 578*4222ddf1SHong Zhang } 579*4222ddf1SHong Zhang 580*4222ddf1SHong Zhang /*@C 581*4222ddf1SHong Zhang MatProductSetFromOptions - Creates a matrix product where the type, the algorithm etc are determined from the options database. 582*4222ddf1SHong Zhang 583*4222ddf1SHong Zhang Logically Collective on Mat 584*4222ddf1SHong Zhang 585*4222ddf1SHong Zhang Input Parameter: 586*4222ddf1SHong Zhang . mat - the matrix 587*4222ddf1SHong Zhang 588*4222ddf1SHong Zhang Level: beginner 589*4222ddf1SHong Zhang 590*4222ddf1SHong Zhang .seealso: MatSetFromOptions() 591*4222ddf1SHong Zhang @*/ 592*4222ddf1SHong Zhang PetscErrorCode MatProductSetFromOptions(Mat mat) 593*4222ddf1SHong Zhang { 594*4222ddf1SHong Zhang PetscErrorCode ierr; 595*4222ddf1SHong Zhang 596*4222ddf1SHong Zhang PetscFunctionBegin; 597*4222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 598*4222ddf1SHong Zhang 599*4222ddf1SHong Zhang if (mat->ops->productsetfromoptions) { 600*4222ddf1SHong Zhang ierr = (*mat->ops->productsetfromoptions)(mat);CHKERRQ(ierr); 601*4222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_NULL,"Call MatProductSetType() first"); 602*4222ddf1SHong Zhang PetscFunctionReturn(0); 603*4222ddf1SHong Zhang } 604*4222ddf1SHong Zhang 605*4222ddf1SHong Zhang /* ----------------------------------------------- */ 606*4222ddf1SHong Zhang PetscErrorCode MatProductNumeric_AB(Mat mat) 607*4222ddf1SHong Zhang { 608*4222ddf1SHong Zhang PetscErrorCode ierr; 609*4222ddf1SHong Zhang Mat_Product *product = mat->product; 610*4222ddf1SHong Zhang Mat A=product->A,B=product->B; 611*4222ddf1SHong Zhang 612*4222ddf1SHong Zhang PetscFunctionBegin; 613*4222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 614*4222ddf1SHong Zhang ierr = (mat->ops->matmultnumeric)(A,B,mat);CHKERRQ(ierr); 615*4222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 616*4222ddf1SHong Zhang PetscFunctionReturn(0); 617*4222ddf1SHong Zhang } 618*4222ddf1SHong Zhang 619*4222ddf1SHong Zhang PetscErrorCode MatProductNumeric_AtB(Mat mat) 620*4222ddf1SHong Zhang { 621*4222ddf1SHong Zhang PetscErrorCode ierr; 622*4222ddf1SHong Zhang Mat_Product *product = mat->product; 623*4222ddf1SHong Zhang Mat A=product->A,B=product->B; 624*4222ddf1SHong Zhang 625*4222ddf1SHong Zhang PetscFunctionBegin; 626*4222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr); 627*4222ddf1SHong Zhang ierr = (mat->ops->transposematmultnumeric)(A,B,mat);CHKERRQ(ierr); 628*4222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr); 629*4222ddf1SHong Zhang PetscFunctionReturn(0); 630*4222ddf1SHong Zhang } 631*4222ddf1SHong Zhang 632*4222ddf1SHong Zhang PetscErrorCode MatProductNumeric_ABt(Mat mat) 633*4222ddf1SHong Zhang { 634*4222ddf1SHong Zhang PetscErrorCode ierr; 635*4222ddf1SHong Zhang Mat_Product *product = mat->product; 636*4222ddf1SHong Zhang Mat A=product->A,B=product->B; 637*4222ddf1SHong Zhang 638*4222ddf1SHong Zhang PetscFunctionBegin; 639*4222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 640*4222ddf1SHong Zhang ierr = (mat->ops->mattransposemultnumeric)(A,B,mat);CHKERRQ(ierr); 641*4222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 642*4222ddf1SHong Zhang PetscFunctionReturn(0); 643*4222ddf1SHong Zhang } 644*4222ddf1SHong Zhang 645*4222ddf1SHong Zhang PetscErrorCode MatProductNumeric_PtAP(Mat mat) 646*4222ddf1SHong Zhang { 647*4222ddf1SHong Zhang PetscErrorCode ierr; 648*4222ddf1SHong Zhang Mat_Product *product = mat->product; 649*4222ddf1SHong Zhang Mat A=product->A,B=product->B; 650*4222ddf1SHong Zhang 651*4222ddf1SHong Zhang PetscFunctionBegin; 652*4222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_PtAPNumeric,mat,0,0,0);CHKERRQ(ierr); 653*4222ddf1SHong Zhang ierr = (mat->ops->ptapnumeric)(A,B,mat);CHKERRQ(ierr); 654*4222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_PtAPNumeric,mat,0,0,0);CHKERRQ(ierr); 655*4222ddf1SHong Zhang PetscFunctionReturn(0); 656*4222ddf1SHong Zhang } 657*4222ddf1SHong Zhang 658*4222ddf1SHong Zhang PetscErrorCode MatProductNumeric_RARt(Mat mat) 659*4222ddf1SHong Zhang { 660*4222ddf1SHong Zhang PetscErrorCode ierr; 661*4222ddf1SHong Zhang Mat_Product *product = mat->product; 662*4222ddf1SHong Zhang Mat A=product->A,B=product->B; 663*4222ddf1SHong Zhang 664*4222ddf1SHong Zhang PetscFunctionBegin; 665*4222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_RARtNumeric,A,B,0,0);CHKERRQ(ierr); 666*4222ddf1SHong Zhang ierr = (mat->ops->rartnumeric)(A,B,mat);CHKERRQ(ierr); 667*4222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_RARtNumeric,A,B,0,0);CHKERRQ(ierr); 668*4222ddf1SHong Zhang PetscFunctionReturn(0); 669*4222ddf1SHong Zhang } 670*4222ddf1SHong Zhang 671*4222ddf1SHong Zhang PetscErrorCode MatProductNumeric_ABC(Mat mat) 672*4222ddf1SHong Zhang { 673*4222ddf1SHong Zhang PetscErrorCode ierr; 674*4222ddf1SHong Zhang Mat_Product *product = mat->product; 675*4222ddf1SHong Zhang Mat A=product->A,B=product->B,C=product->C; 676*4222ddf1SHong Zhang 677*4222ddf1SHong Zhang PetscFunctionBegin; 678*4222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr); 679*4222ddf1SHong Zhang ierr = (mat->ops->matmatmultnumeric)(A,B,C,mat);CHKERRQ(ierr); 680*4222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr); 681*4222ddf1SHong Zhang PetscFunctionReturn(0); 682*4222ddf1SHong Zhang } 683*4222ddf1SHong Zhang 684*4222ddf1SHong Zhang /*@ 685*4222ddf1SHong Zhang MatProductNumeric - Implement a matrix product with numerical values. 686*4222ddf1SHong Zhang 687*4222ddf1SHong Zhang Collective on Mat 688*4222ddf1SHong Zhang 689*4222ddf1SHong Zhang Input Parameters: 690*4222ddf1SHong Zhang . mat - the matrix to hold a product 691*4222ddf1SHong Zhang 692*4222ddf1SHong Zhang Output Parameters: 693*4222ddf1SHong Zhang . mat - the matrix product 694*4222ddf1SHong Zhang 695*4222ddf1SHong Zhang Level: intermediate 696*4222ddf1SHong Zhang 697*4222ddf1SHong Zhang .seealso: MatProductCreate(), MatSetType() 698*4222ddf1SHong Zhang @*/ 699*4222ddf1SHong Zhang PetscErrorCode MatProductNumeric(Mat mat) 700*4222ddf1SHong Zhang { 701*4222ddf1SHong Zhang PetscErrorCode ierr; 702*4222ddf1SHong Zhang 703*4222ddf1SHong Zhang PetscFunctionBegin; 704*4222ddf1SHong Zhang PetscValidPointer(mat,1); 705*4222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 706*4222ddf1SHong Zhang 707*4222ddf1SHong Zhang if (mat->ops->productnumeric) { 708*4222ddf1SHong Zhang ierr = (*mat->ops->productnumeric)(mat);CHKERRQ(ierr); 709*4222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_USER,"Call MatProductSymbolic() first"); 710*4222ddf1SHong Zhang PetscFunctionReturn(0); 711*4222ddf1SHong Zhang } 712*4222ddf1SHong Zhang 713*4222ddf1SHong Zhang /* ----------------------------------------------- */ 714*4222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_AB(Mat mat) 715*4222ddf1SHong Zhang { 716*4222ddf1SHong Zhang PetscErrorCode ierr; 717*4222ddf1SHong Zhang Mat_Product *product = mat->product; 718*4222ddf1SHong Zhang Mat A=product->A,B=product->B; 719*4222ddf1SHong Zhang 720*4222ddf1SHong Zhang PetscFunctionBegin; 721*4222ddf1SHong Zhang ierr = (mat->ops->matmultsymbolic)(A,B,product->fill,mat);CHKERRQ(ierr); 722*4222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_AB; 723*4222ddf1SHong Zhang PetscFunctionReturn(0); 724*4222ddf1SHong Zhang } 725*4222ddf1SHong Zhang 726*4222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_AtB(Mat mat) 727*4222ddf1SHong Zhang { 728*4222ddf1SHong Zhang PetscErrorCode ierr; 729*4222ddf1SHong Zhang Mat_Product *product = mat->product; 730*4222ddf1SHong Zhang Mat A=product->A,B=product->B; 731*4222ddf1SHong Zhang 732*4222ddf1SHong Zhang PetscFunctionBegin; 733*4222ddf1SHong Zhang ierr = (mat->ops->transposematmultsymbolic)(A,B,product->fill,mat);CHKERRQ(ierr); 734*4222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_AtB; 735*4222ddf1SHong Zhang PetscFunctionReturn(0); 736*4222ddf1SHong Zhang } 737*4222ddf1SHong Zhang 738*4222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_ABt(Mat mat) 739*4222ddf1SHong Zhang { 740*4222ddf1SHong Zhang PetscErrorCode ierr; 741*4222ddf1SHong Zhang Mat_Product *product = mat->product; 742*4222ddf1SHong Zhang Mat A=product->A,B=product->B; 743*4222ddf1SHong Zhang 744*4222ddf1SHong Zhang PetscFunctionBegin; 745*4222ddf1SHong Zhang ierr = (mat->ops->mattransposemultsymbolic)(A,B,product->fill,mat);CHKERRQ(ierr); 746*4222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_ABt; 747*4222ddf1SHong Zhang PetscFunctionReturn(0); 748*4222ddf1SHong Zhang } 749*4222ddf1SHong Zhang 750*4222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_ABC(Mat mat) 751*4222ddf1SHong Zhang { 752*4222ddf1SHong Zhang PetscErrorCode ierr; 753*4222ddf1SHong Zhang Mat_Product *product = mat->product; 754*4222ddf1SHong Zhang Mat A=product->A,B=product->B,C=product->C; 755*4222ddf1SHong Zhang 756*4222ddf1SHong Zhang PetscFunctionBegin; 757*4222ddf1SHong Zhang ierr = (mat->ops->matmatmultsymbolic)(A,B,C,product->fill,mat);CHKERRQ(ierr); 758*4222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_ABC; 759*4222ddf1SHong Zhang PetscFunctionReturn(0); 760*4222ddf1SHong Zhang } 761*4222ddf1SHong Zhang 762*4222ddf1SHong Zhang /*@ 763*4222ddf1SHong Zhang MatProductSymbolic - Perform the symbolic portion of a matrix product, this creates a data structure for use with the numerical produce. 764*4222ddf1SHong Zhang 765*4222ddf1SHong Zhang Collective on Mat 766*4222ddf1SHong Zhang 767*4222ddf1SHong Zhang Input Parameters: 768*4222ddf1SHong Zhang . mat - the matrix to hold a product 769*4222ddf1SHong Zhang 770*4222ddf1SHong Zhang Output Parameters: 771*4222ddf1SHong Zhang . mat - the matrix product data structure 772*4222ddf1SHong Zhang 773*4222ddf1SHong Zhang Level: intermediate 774*4222ddf1SHong Zhang 775*4222ddf1SHong Zhang .seealso: MatProductCreate(), MatSetType(), MatProductNumeric(), MatProductType, MatProductAlgorithm 776*4222ddf1SHong Zhang @*/ 777*4222ddf1SHong Zhang PetscErrorCode MatProductSymbolic(Mat mat) 778*4222ddf1SHong Zhang { 779*4222ddf1SHong Zhang PetscErrorCode ierr; 780*4222ddf1SHong Zhang Mat_Product *product = mat->product; 781*4222ddf1SHong Zhang MatProductType productype = product->type; 782*4222ddf1SHong Zhang PetscLogEvent eventtype=-1; 783*4222ddf1SHong Zhang 784*4222ddf1SHong Zhang PetscFunctionBegin; 785*4222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 786*4222ddf1SHong Zhang 787*4222ddf1SHong Zhang /* log event */ 788*4222ddf1SHong Zhang switch (productype) { 789*4222ddf1SHong Zhang case MATPRODUCT_AB: 790*4222ddf1SHong Zhang eventtype = MAT_MatMultSymbolic; 791*4222ddf1SHong Zhang break; 792*4222ddf1SHong Zhang case MATPRODUCT_AtB: 793*4222ddf1SHong Zhang eventtype = MAT_TransposeMatMultSymbolic; 794*4222ddf1SHong Zhang break; 795*4222ddf1SHong Zhang case MATPRODUCT_ABt: 796*4222ddf1SHong Zhang eventtype = MAT_MatTransposeMultSymbolic; 797*4222ddf1SHong Zhang break; 798*4222ddf1SHong Zhang case MATPRODUCT_PtAP: 799*4222ddf1SHong Zhang eventtype = MAT_PtAPSymbolic; 800*4222ddf1SHong Zhang break; 801*4222ddf1SHong Zhang case MATPRODUCT_RARt: 802*4222ddf1SHong Zhang eventtype = MAT_RARtSymbolic; 803*4222ddf1SHong Zhang break; 804*4222ddf1SHong Zhang case MATPRODUCT_ABC: 805*4222ddf1SHong Zhang eventtype = MAT_MatMatMultSymbolic; 806*4222ddf1SHong Zhang break; 807*4222ddf1SHong Zhang default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MATPRODUCT type is not supported"); 808*4222ddf1SHong Zhang } 809*4222ddf1SHong Zhang 810*4222ddf1SHong Zhang if (mat->ops->productsymbolic) { 811*4222ddf1SHong Zhang ierr = PetscLogEventBegin(eventtype,mat,0,0,0);CHKERRQ(ierr); 812*4222ddf1SHong Zhang ierr = (*mat->ops->productsymbolic)(mat);CHKERRQ(ierr); 813*4222ddf1SHong Zhang ierr = PetscLogEventEnd(eventtype,mat,0,0,0);CHKERRQ(ierr); 814*4222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_USER,"Call MatProductSetFromOptions() first"); 815*4222ddf1SHong Zhang PetscFunctionReturn(0); 816*4222ddf1SHong Zhang } 817*4222ddf1SHong Zhang 818*4222ddf1SHong Zhang /*@ 819*4222ddf1SHong Zhang MatProductSetFill - Set an expected fill of the matrix product. 820*4222ddf1SHong Zhang 821*4222ddf1SHong Zhang Collective on Mat 822*4222ddf1SHong Zhang 823*4222ddf1SHong Zhang Input Parameters: 824*4222ddf1SHong Zhang + mat - the matrix product 825*4222ddf1SHong 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. 826*4222ddf1SHong Zhang 827*4222ddf1SHong Zhang Level: intermediate 828*4222ddf1SHong Zhang 829*4222ddf1SHong Zhang .seealso: MatProductSetType(), MatProductSetAlgorithm(), MatProductCreate() 830*4222ddf1SHong Zhang @*/ 831*4222ddf1SHong Zhang PetscErrorCode MatProductSetFill(Mat mat,PetscReal fill) 832*4222ddf1SHong Zhang { 833*4222ddf1SHong Zhang Mat_Product *product = mat->product; 834*4222ddf1SHong Zhang 835*4222ddf1SHong Zhang PetscFunctionBegin; 836*4222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 837*4222ddf1SHong Zhang 838*4222ddf1SHong Zhang if (!product) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_NULL,"Data struc Mat_Product is not created, call MatProductCreate() first"); 839*4222ddf1SHong Zhang if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) { 840*4222ddf1SHong Zhang product->fill = 2.0; 841*4222ddf1SHong Zhang } else product->fill = fill; 842*4222ddf1SHong Zhang PetscFunctionReturn(0); 843*4222ddf1SHong Zhang } 844*4222ddf1SHong Zhang 845*4222ddf1SHong Zhang /*@ 846*4222ddf1SHong Zhang MatProductSetAlgorithm - Requests a particular algorithm for a matrix product implementation. 847*4222ddf1SHong Zhang 848*4222ddf1SHong Zhang Collective on Mat 849*4222ddf1SHong Zhang 850*4222ddf1SHong Zhang Input Parameters: 851*4222ddf1SHong Zhang + mat - the matrix product 852*4222ddf1SHong Zhang - alg - particular implementation algorithm of the matrix product, e.g., MATPRODUCTALGORITHM_DEFAULT. 853*4222ddf1SHong Zhang 854*4222ddf1SHong Zhang Level: intermediate 855*4222ddf1SHong Zhang 856*4222ddf1SHong Zhang .seealso: MatProductSetType(), MatProductSetFill(), MatProductCreate() 857*4222ddf1SHong Zhang @*/ 858*4222ddf1SHong Zhang PetscErrorCode MatProductSetAlgorithm(Mat mat,MatProductAlgorithm alg) 859*4222ddf1SHong Zhang { 860*4222ddf1SHong Zhang Mat_Product *product = mat->product; 861*4222ddf1SHong Zhang 862*4222ddf1SHong Zhang PetscFunctionBegin; 863*4222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 864*4222ddf1SHong Zhang 865*4222ddf1SHong Zhang if (!product) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_NULL,"Data struc Mat_Product is not created, call MatProductCreate() first"); 866*4222ddf1SHong Zhang product->alg = alg; 867*4222ddf1SHong Zhang PetscFunctionReturn(0); 868*4222ddf1SHong Zhang } 869*4222ddf1SHong Zhang 870*4222ddf1SHong Zhang /*@ 871*4222ddf1SHong Zhang MatProductSetType - Sets a particular matrix product type, for example Mat*Mat. 872*4222ddf1SHong Zhang 873*4222ddf1SHong Zhang Collective on Mat 874*4222ddf1SHong Zhang 875*4222ddf1SHong Zhang Input Parameters: 876*4222ddf1SHong Zhang + mat - the matrix 877*4222ddf1SHong Zhang - productype - matrix product type, e.g., MATPRODUCT_AB,MATPRODUCT_AtB,MATPRODUCT_ABt,MATPRODUCT_PtAP,MATPRODUCT_RARt,MATPRODUCT_ABC. 878*4222ddf1SHong Zhang 879*4222ddf1SHong Zhang Level: intermediate 880*4222ddf1SHong Zhang 881*4222ddf1SHong Zhang .seealso: MatProductCreate(), MatProductType, MatProductAlgorithm 882*4222ddf1SHong Zhang @*/ 883*4222ddf1SHong Zhang PetscErrorCode MatProductSetType(Mat mat,MatProductType productype) 884*4222ddf1SHong Zhang { 885*4222ddf1SHong Zhang PetscErrorCode ierr; 886*4222ddf1SHong Zhang Mat_Product *product = mat->product; 887*4222ddf1SHong Zhang MPI_Comm comm; 888*4222ddf1SHong Zhang 889*4222ddf1SHong Zhang PetscFunctionBegin; 890*4222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 891*4222ddf1SHong Zhang 892*4222ddf1SHong Zhang ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 893*4222ddf1SHong Zhang if (!product) SETERRQ(comm,PETSC_ERR_ARG_NULL,"Data struc Mat_Product is not created, call MatProductCreate() first"); 894*4222ddf1SHong Zhang product->type = productype; 895*4222ddf1SHong Zhang 896*4222ddf1SHong Zhang switch (productype) { 897*4222ddf1SHong Zhang case MATPRODUCT_AB: 898*4222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_AB; 899*4222ddf1SHong Zhang break; 900*4222ddf1SHong Zhang case MATPRODUCT_AtB: 901*4222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_AtB; 902*4222ddf1SHong Zhang break; 903*4222ddf1SHong Zhang case MATPRODUCT_ABt: 904*4222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_ABt; 905*4222ddf1SHong Zhang break; 906*4222ddf1SHong Zhang case MATPRODUCT_PtAP: 907*4222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_PtAP; 908*4222ddf1SHong Zhang break; 909*4222ddf1SHong Zhang case MATPRODUCT_RARt: 910*4222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_RARt; 911*4222ddf1SHong Zhang break; 912*4222ddf1SHong Zhang case MATPRODUCT_ABC: 913*4222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_ABC; 914*4222ddf1SHong Zhang break; 915*4222ddf1SHong Zhang default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"ProductType is not supported\n"); 916*4222ddf1SHong Zhang } 917*4222ddf1SHong Zhang PetscFunctionReturn(0); 918*4222ddf1SHong Zhang } 919*4222ddf1SHong Zhang 920*4222ddf1SHong Zhang /* Create a supporting struct and attach it to the matrix product */ 921*4222ddf1SHong Zhang static PetscErrorCode MatProductCreate_Private(Mat A,Mat B,Mat C,Mat D) 922*4222ddf1SHong Zhang { 923*4222ddf1SHong Zhang PetscErrorCode ierr; 924*4222ddf1SHong Zhang Mat_Product *product=NULL; 925*4222ddf1SHong Zhang 926*4222ddf1SHong Zhang PetscFunctionBegin; 927*4222ddf1SHong Zhang ierr = PetscNewLog(D,&product);CHKERRQ(ierr); 928*4222ddf1SHong Zhang product->A = A; 929*4222ddf1SHong Zhang product->B = B; 930*4222ddf1SHong Zhang product->C = C; 931*4222ddf1SHong Zhang product->Dwork = NULL; 932*4222ddf1SHong Zhang product->alg = MATPRODUCTALGORITHM_DEFAULT; 933*4222ddf1SHong Zhang product->fill = 2.0; /* PETSC_DEFAULT */ 934*4222ddf1SHong Zhang product->Areplaced = PETSC_FALSE; 935*4222ddf1SHong Zhang product->Breplaced = PETSC_FALSE; 936*4222ddf1SHong Zhang product->api_user = PETSC_FALSE; 937*4222ddf1SHong Zhang D->product = product; 938*4222ddf1SHong Zhang PetscFunctionReturn(0); 939*4222ddf1SHong Zhang } 940*4222ddf1SHong Zhang 941*4222ddf1SHong Zhang /*@ 942*4222ddf1SHong Zhang MatProductCreateWithMat - Setup a given matrix as a matrix product. 943*4222ddf1SHong Zhang 944*4222ddf1SHong Zhang Collective on Mat 945*4222ddf1SHong Zhang 946*4222ddf1SHong Zhang Input Parameters: 947*4222ddf1SHong Zhang + A - the first matrix 948*4222ddf1SHong Zhang . B - the second matrix 949*4222ddf1SHong Zhang . C - the third matrix (optional) 950*4222ddf1SHong Zhang - D - the matrix which will be used as a product 951*4222ddf1SHong Zhang 952*4222ddf1SHong Zhang Output Parameters: 953*4222ddf1SHong Zhang . D - the product matrix 954*4222ddf1SHong Zhang 955*4222ddf1SHong Zhang Level: intermediate 956*4222ddf1SHong Zhang 957*4222ddf1SHong Zhang .seealso: MatProductCreate() 958*4222ddf1SHong Zhang @*/ 959*4222ddf1SHong Zhang PetscErrorCode MatProductCreateWithMat(Mat A,Mat B,Mat C,Mat D) 960*4222ddf1SHong Zhang { 961*4222ddf1SHong Zhang PetscErrorCode ierr; 962*4222ddf1SHong Zhang 963*4222ddf1SHong Zhang PetscFunctionBegin; 964*4222ddf1SHong Zhang PetscValidHeaderSpecific(A,MAT_CLASSID,1); 965*4222ddf1SHong Zhang PetscValidType(A,1); 966*4222ddf1SHong Zhang MatCheckPreallocated(A,1); 967*4222ddf1SHong Zhang if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 968*4222ddf1SHong Zhang if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 969*4222ddf1SHong Zhang 970*4222ddf1SHong Zhang PetscValidHeaderSpecific(B,MAT_CLASSID,2); 971*4222ddf1SHong Zhang PetscValidType(B,2); 972*4222ddf1SHong Zhang MatCheckPreallocated(B,2); 973*4222ddf1SHong Zhang if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 974*4222ddf1SHong Zhang if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 975*4222ddf1SHong Zhang 976*4222ddf1SHong Zhang if (C) { 977*4222ddf1SHong Zhang PetscValidHeaderSpecific(C,MAT_CLASSID,3); 978*4222ddf1SHong Zhang PetscValidType(C,3); 979*4222ddf1SHong Zhang MatCheckPreallocated(C,3); 980*4222ddf1SHong Zhang if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 981*4222ddf1SHong Zhang if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 982*4222ddf1SHong Zhang } 983*4222ddf1SHong Zhang 984*4222ddf1SHong Zhang PetscValidHeaderSpecific(D,MAT_CLASSID,4); 985*4222ddf1SHong Zhang PetscValidType(D,4); 986*4222ddf1SHong Zhang MatCheckPreallocated(D,4); 987*4222ddf1SHong Zhang if (!D->assembled) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 988*4222ddf1SHong Zhang if (D->factortype) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 989*4222ddf1SHong Zhang 990*4222ddf1SHong Zhang /* Create a supporting struct and attach it to D */ 991*4222ddf1SHong Zhang ierr = MatProductCreate_Private(A,B,C,D);CHKERRQ(ierr); 992*4222ddf1SHong Zhang PetscFunctionReturn(0); 993*4222ddf1SHong Zhang } 994*4222ddf1SHong Zhang 995*4222ddf1SHong Zhang /*@ 996*4222ddf1SHong Zhang MatProductCreate - create a matrix product object that can be used to compute various matrix times matrix operations. 997*4222ddf1SHong Zhang 998*4222ddf1SHong Zhang Collective on Mat 999*4222ddf1SHong Zhang 1000*4222ddf1SHong Zhang Input Parameters: 1001*4222ddf1SHong Zhang + A - the first matrix 1002*4222ddf1SHong Zhang . B - the second matrix 1003*4222ddf1SHong Zhang - C - the third matrix (optional) 1004*4222ddf1SHong Zhang 1005*4222ddf1SHong Zhang Output Parameters: 1006*4222ddf1SHong Zhang . D - the product matrix 1007*4222ddf1SHong Zhang 1008*4222ddf1SHong Zhang Level: intermediate 1009*4222ddf1SHong Zhang 1010*4222ddf1SHong Zhang .seealso: MatProductCreateWithMat(), MatProductSetType(), MatProductSetAlgorithm() 1011*4222ddf1SHong Zhang @*/ 1012*4222ddf1SHong Zhang PetscErrorCode MatProductCreate(Mat A,Mat B,Mat C,Mat *D) 1013*4222ddf1SHong Zhang { 1014*4222ddf1SHong Zhang PetscErrorCode ierr; 1015*4222ddf1SHong Zhang 1016*4222ddf1SHong Zhang PetscFunctionBegin; 1017*4222ddf1SHong Zhang PetscValidHeaderSpecific(A,MAT_CLASSID,1); 1018*4222ddf1SHong Zhang PetscValidType(A,1); 1019*4222ddf1SHong Zhang MatCheckPreallocated(A,1); 1020*4222ddf1SHong Zhang if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1021*4222ddf1SHong Zhang if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1022*4222ddf1SHong Zhang 1023*4222ddf1SHong Zhang PetscValidHeaderSpecific(B,MAT_CLASSID,2); 1024*4222ddf1SHong Zhang PetscValidType(B,2); 1025*4222ddf1SHong Zhang MatCheckPreallocated(B,2); 1026*4222ddf1SHong Zhang if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1027*4222ddf1SHong Zhang if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1028*4222ddf1SHong Zhang 1029*4222ddf1SHong Zhang if (C) { 1030*4222ddf1SHong Zhang PetscValidHeaderSpecific(C,MAT_CLASSID,3); 1031*4222ddf1SHong Zhang PetscValidType(C,3); 1032*4222ddf1SHong Zhang MatCheckPreallocated(C,3); 1033*4222ddf1SHong Zhang if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1034*4222ddf1SHong Zhang if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1035*4222ddf1SHong Zhang } 1036*4222ddf1SHong Zhang 1037*4222ddf1SHong Zhang PetscValidPointer(D,4); 1038*4222ddf1SHong Zhang 1039*4222ddf1SHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)A),D);CHKERRQ(ierr); 1040*4222ddf1SHong Zhang ierr = MatProductCreate_Private(A,B,C,*D);CHKERRQ(ierr); 1041*4222ddf1SHong Zhang PetscFunctionReturn(0); 1042*4222ddf1SHong Zhang } 1043