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