1*6218e575SSatish Balay /* 2*6218e575SSatish Balay Provides an interface to the Tufo-Fischer parallel direct solver 3*6218e575SSatish Balay */ 4*6218e575SSatish Balay 5*6218e575SSatish Balay #include "src/ksp/pc/pcimpl.h" /*I "petscpc.h" I*/ 6*6218e575SSatish Balay #include "src/mat/impls/aij/mpi/mpiaij.h" 7*6218e575SSatish Balay 8*6218e575SSatish Balay #include "src/ksp/pc/impls/tfs/xxt.h" 9*6218e575SSatish Balay #include "src/ksp/pc/impls/tfs/xyt.h" 10*6218e575SSatish Balay 11*6218e575SSatish Balay typedef struct { 12*6218e575SSatish Balay xxt_ADT xxt; 13*6218e575SSatish Balay xyt_ADT xyt; 14*6218e575SSatish Balay Vec b,xd,xo; 15*6218e575SSatish Balay PetscInt nd; 16*6218e575SSatish Balay } PC_TFS; 17*6218e575SSatish Balay 18*6218e575SSatish Balay #undef __FUNCT__ 19*6218e575SSatish Balay #define __FUNCT__ "PCDestroy_TFS" 20*6218e575SSatish Balay PetscErrorCode PCDestroy_TFS(PC pc) 21*6218e575SSatish Balay { 22*6218e575SSatish Balay PC_TFS *tfs = (PC_TFS*)pc->data; 23*6218e575SSatish Balay PetscErrorCode ierr; 24*6218e575SSatish Balay 25*6218e575SSatish Balay PetscFunctionBegin; 26*6218e575SSatish Balay /* free the XXT datastructures */ 27*6218e575SSatish Balay if (tfs->xxt) { 28*6218e575SSatish Balay ierr = XXT_free(tfs->xxt);CHKERRQ(ierr); 29*6218e575SSatish Balay } 30*6218e575SSatish Balay if (tfs->xyt) { 31*6218e575SSatish Balay ierr = XYT_free(tfs->xyt);CHKERRQ(ierr); 32*6218e575SSatish Balay } 33*6218e575SSatish Balay if (tfs->b) { 34*6218e575SSatish Balay ierr = VecDestroy(tfs->b);CHKERRQ(ierr); 35*6218e575SSatish Balay } 36*6218e575SSatish Balay if (tfs->xd) { 37*6218e575SSatish Balay ierr = VecDestroy(tfs->xd);CHKERRQ(ierr); 38*6218e575SSatish Balay } 39*6218e575SSatish Balay if (tfs->xo) { 40*6218e575SSatish Balay ierr = VecDestroy(tfs->xo);CHKERRQ(ierr); 41*6218e575SSatish Balay } 42*6218e575SSatish Balay ierr = PetscFree(tfs);CHKERRQ(ierr); 43*6218e575SSatish Balay PetscFunctionReturn(0); 44*6218e575SSatish Balay } 45*6218e575SSatish Balay 46*6218e575SSatish Balay #undef __FUNCT__ 47*6218e575SSatish Balay #define __FUNCT__ "PCApply_TFS_XXT" 48*6218e575SSatish Balay static PetscErrorCode PCApply_TFS_XXT(PC pc,Vec x,Vec y) 49*6218e575SSatish Balay { 50*6218e575SSatish Balay PC_TFS *tfs = (PC_TFS*)pc->data; 51*6218e575SSatish Balay PetscScalar *xx,*yy; 52*6218e575SSatish Balay PetscErrorCode ierr; 53*6218e575SSatish Balay 54*6218e575SSatish Balay PetscFunctionBegin; 55*6218e575SSatish Balay ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 56*6218e575SSatish Balay ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 57*6218e575SSatish Balay ierr = XXT_solve(tfs->xxt,yy,xx);CHKERRQ(ierr); 58*6218e575SSatish Balay ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 59*6218e575SSatish Balay ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 60*6218e575SSatish Balay PetscFunctionReturn(0); 61*6218e575SSatish Balay } 62*6218e575SSatish Balay 63*6218e575SSatish Balay #undef __FUNCT__ 64*6218e575SSatish Balay #define __FUNCT__ "PCApply_TFS_XYT" 65*6218e575SSatish Balay static PetscErrorCode PCApply_TFS_XYT(PC pc,Vec x,Vec y) 66*6218e575SSatish Balay { 67*6218e575SSatish Balay PC_TFS *tfs = (PC_TFS*)pc->data; 68*6218e575SSatish Balay PetscScalar *xx,*yy; 69*6218e575SSatish Balay PetscErrorCode ierr; 70*6218e575SSatish Balay 71*6218e575SSatish Balay PetscFunctionBegin; 72*6218e575SSatish Balay ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 73*6218e575SSatish Balay ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 74*6218e575SSatish Balay ierr = XYT_solve(tfs->xyt,yy,xx);CHKERRQ(ierr); 75*6218e575SSatish Balay ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 76*6218e575SSatish Balay ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 77*6218e575SSatish Balay PetscFunctionReturn(0); 78*6218e575SSatish Balay } 79*6218e575SSatish Balay 80*6218e575SSatish Balay #undef __FUNCT__ 81*6218e575SSatish Balay #define __FUNCT__ "LocalMult_TFS" 82*6218e575SSatish Balay static PetscErrorCode LocalMult_TFS(PC pc,PetscScalar *xin,PetscScalar *xout) 83*6218e575SSatish Balay { 84*6218e575SSatish Balay PC_TFS *tfs = (PC_TFS*)pc->data; 85*6218e575SSatish Balay Mat A = pc->pmat; 86*6218e575SSatish Balay Mat_MPIAIJ *a = (Mat_MPIAIJ*)A->data; 87*6218e575SSatish Balay PetscErrorCode ierr; 88*6218e575SSatish Balay 89*6218e575SSatish Balay PetscFunctionBegin; 90*6218e575SSatish Balay ierr = VecPlaceArray(tfs->b,xout);CHKERRQ(ierr); 91*6218e575SSatish Balay ierr = VecPlaceArray(tfs->xd,xin);CHKERRQ(ierr); 92*6218e575SSatish Balay ierr = VecPlaceArray(tfs->xo,xin+tfs->nd);CHKERRQ(ierr); 93*6218e575SSatish Balay ierr = MatMult(a->A,tfs->xd,tfs->b);CHKERRQ(ierr); 94*6218e575SSatish Balay ierr = MatMultAdd(a->B,tfs->xo,tfs->b,tfs->b);CHKERRQ(ierr); 95*6218e575SSatish Balay PetscFunctionReturn(0); 96*6218e575SSatish Balay } 97*6218e575SSatish Balay 98*6218e575SSatish Balay #undef __FUNCT__ 99*6218e575SSatish Balay #define __FUNCT__ "PCSetUp_TFS" 100*6218e575SSatish Balay static PetscErrorCode PCSetUp_TFS(PC pc) 101*6218e575SSatish Balay { 102*6218e575SSatish Balay PC_TFS *tfs = (PC_TFS*)pc->data; 103*6218e575SSatish Balay Mat A = pc->pmat; 104*6218e575SSatish Balay Mat_MPIAIJ *a = (Mat_MPIAIJ*)A->data; 105*6218e575SSatish Balay PetscErrorCode ierr; 106*6218e575SSatish Balay PetscInt *localtoglobal,ncol,i; 107*6218e575SSatish Balay PetscTruth ismpiaij; 108*6218e575SSatish Balay 109*6218e575SSatish Balay /* 110*6218e575SSatish Balay PetscTruth issymmetric; 111*6218e575SSatish Balay PetscReal tol = 0.0; 112*6218e575SSatish Balay */ 113*6218e575SSatish Balay 114*6218e575SSatish Balay PetscFunctionBegin; 115*6218e575SSatish Balay if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square"); 116*6218e575SSatish Balay ierr = PetscTypeCompare((PetscObject)pc->pmat,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 117*6218e575SSatish Balay if (!ismpiaij) { 118*6218e575SSatish Balay SETERRQ(PETSC_ERR_SUP,"Currently only supports MPIAIJ matrices"); 119*6218e575SSatish Balay } 120*6218e575SSatish Balay 121*6218e575SSatish Balay /* generate the local to global mapping */ 122*6218e575SSatish Balay ncol = a->A->n + a->B->n; 123*6218e575SSatish Balay ierr = PetscMalloc((ncol)*sizeof(int),&localtoglobal);CHKERRQ(ierr); 124*6218e575SSatish Balay for (i=0; i<a->A->n; i++) { 125*6218e575SSatish Balay localtoglobal[i] = a->cstart + i + 1; 126*6218e575SSatish Balay } 127*6218e575SSatish Balay for (i=0; i<a->B->n; i++) { 128*6218e575SSatish Balay localtoglobal[i+a->A->n] = a->garray[i] + 1; 129*6218e575SSatish Balay } 130*6218e575SSatish Balay /* generate the vectors needed for the local solves */ 131*6218e575SSatish Balay ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,a->A->m,PETSC_NULL,&tfs->b);CHKERRQ(ierr); 132*6218e575SSatish Balay ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,a->A->n,PETSC_NULL,&tfs->xd);CHKERRQ(ierr); 133*6218e575SSatish Balay ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,a->B->n,PETSC_NULL,&tfs->xo);CHKERRQ(ierr); 134*6218e575SSatish Balay tfs->nd = a->A->n; 135*6218e575SSatish Balay 136*6218e575SSatish Balay 137*6218e575SSatish Balay /* ierr = MatIsSymmetric(A,tol,&issymmetric); */ 138*6218e575SSatish Balay /* if (issymmetric) { */ 139*6218e575SSatish Balay PetscBarrier(pc); 140*6218e575SSatish Balay if (A->symmetric) { 141*6218e575SSatish Balay tfs->xxt = XXT_new(); 142*6218e575SSatish Balay ierr = XXT_factor(tfs->xxt,localtoglobal,A->m,ncol,(void*)LocalMult_TFS,pc);CHKERRQ(ierr); 143*6218e575SSatish Balay pc->ops->apply = PCApply_TFS_XXT; 144*6218e575SSatish Balay } else { 145*6218e575SSatish Balay tfs->xyt = XYT_new(); 146*6218e575SSatish Balay ierr = XYT_factor(tfs->xyt,localtoglobal,A->m,ncol,(void*)LocalMult_TFS,pc);CHKERRQ(ierr); 147*6218e575SSatish Balay pc->ops->apply = PCApply_TFS_XYT; 148*6218e575SSatish Balay } 149*6218e575SSatish Balay 150*6218e575SSatish Balay ierr = PetscFree(localtoglobal);CHKERRQ(ierr); 151*6218e575SSatish Balay PetscFunctionReturn(0); 152*6218e575SSatish Balay } 153*6218e575SSatish Balay 154*6218e575SSatish Balay #undef __FUNCT__ 155*6218e575SSatish Balay #define __FUNCT__ "PCSetFromOptions_TFS" 156*6218e575SSatish Balay static PetscErrorCode PCSetFromOptions_TFS(PC pc) 157*6218e575SSatish Balay { 158*6218e575SSatish Balay PetscFunctionBegin; 159*6218e575SSatish Balay PetscFunctionReturn(0); 160*6218e575SSatish Balay } 161*6218e575SSatish Balay #undef __FUNCT__ 162*6218e575SSatish Balay #define __FUNCT__ "PCView_TFS" 163*6218e575SSatish Balay static PetscErrorCode PCView_TFS(PC pc,PetscViewer viewer) 164*6218e575SSatish Balay { 165*6218e575SSatish Balay PetscFunctionBegin; 166*6218e575SSatish Balay PetscFunctionReturn(0); 167*6218e575SSatish Balay } 168*6218e575SSatish Balay 169*6218e575SSatish Balay EXTERN_C_BEGIN 170*6218e575SSatish Balay #undef __FUNCT__ 171*6218e575SSatish Balay #define __FUNCT__ "PCCreate_TFS" 172*6218e575SSatish Balay PetscErrorCode PCCreate_TFS(PC pc) 173*6218e575SSatish Balay { 174*6218e575SSatish Balay PetscErrorCode ierr; 175*6218e575SSatish Balay PC_TFS *tfs; 176*6218e575SSatish Balay 177*6218e575SSatish Balay PetscFunctionBegin; 178*6218e575SSatish Balay ierr = PetscNew(PC_TFS,&tfs);CHKERRQ(ierr); 179*6218e575SSatish Balay PetscLogObjectMemory(pc,sizeof(PC_TFS)); 180*6218e575SSatish Balay 181*6218e575SSatish Balay tfs->xxt = 0; 182*6218e575SSatish Balay tfs->xyt = 0; 183*6218e575SSatish Balay tfs->b = 0; 184*6218e575SSatish Balay tfs->xd = 0; 185*6218e575SSatish Balay tfs->xo = 0; 186*6218e575SSatish Balay tfs->nd = 0; 187*6218e575SSatish Balay 188*6218e575SSatish Balay pc->ops->apply = 0; 189*6218e575SSatish Balay pc->ops->applytranspose = 0; 190*6218e575SSatish Balay pc->ops->setup = PCSetUp_TFS; 191*6218e575SSatish Balay pc->ops->destroy = PCDestroy_TFS; 192*6218e575SSatish Balay pc->ops->setfromoptions = PCSetFromOptions_TFS; 193*6218e575SSatish Balay pc->ops->view = PCView_TFS; 194*6218e575SSatish Balay pc->ops->applyrichardson = 0; 195*6218e575SSatish Balay pc->ops->applysymmetricleft = 0; 196*6218e575SSatish Balay pc->ops->applysymmetricright = 0; 197*6218e575SSatish Balay pc->data = (void*)tfs; 198*6218e575SSatish Balay PetscFunctionReturn(0); 199*6218e575SSatish Balay } 200*6218e575SSatish Balay EXTERN_C_END 201*6218e575SSatish Balay 202