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