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(((PetscObject)pc)->comm,PETSC_ERR_ARG_SIZ,"matrix must be square"); 118 ierr = PetscTypeCompare((PetscObject)pc->pmat,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 119 if (!ismpiaij) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_SUP,"Currently only supports MPIAIJ matrices"); 120 121 /* generate the local to global mapping */ 122 ncol = a->A->cmap->n + a->B->cmap->n; 123 ierr = PetscMalloc((ncol)*sizeof(PetscInt),&localtoglobal);CHKERRQ(ierr); 124 for (i=0; i<a->A->cmap->n; i++) { 125 localtoglobal[i] = A->cmap->rstart + i + 1; 126 } 127 for (i=0; i<a->B->cmap->n; i++) { 128 localtoglobal[i+a->A->cmap->n] = a->garray[i] + 1; 129 } 130 /* generate the vectors needed for the local solves */ 131 ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,a->A->rmap->n,PETSC_NULL,&tfs->b);CHKERRQ(ierr); 132 ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,a->A->cmap->n,PETSC_NULL,&tfs->xd);CHKERRQ(ierr); 133 ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,a->B->cmap->n,PETSC_NULL,&tfs->xo);CHKERRQ(ierr); 134 tfs->nd = a->A->cmap->n; 135 136 137 /* ierr = MatIsSymmetric(A,tol,&issymmetric); */ 138 /* if (issymmetric) { */ 139 ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 140 if (A->symmetric) { 141 tfs->xxt = XXT_new(); 142 ierr = XXT_factor(tfs->xxt,localtoglobal,A->rmap->n,ncol,(void*)LocalMult_TFS,pc);CHKERRQ(ierr); 143 pc->ops->apply = PCApply_TFS_XXT; 144 } else { 145 tfs->xyt = XYT_new(); 146 ierr = XYT_factor(tfs->xyt,localtoglobal,A->rmap->n,ncol,(void*)LocalMult_TFS,pc);CHKERRQ(ierr); 147 pc->ops->apply = PCApply_TFS_XYT; 148 } 149 150 ierr = PetscFree(localtoglobal);CHKERRQ(ierr); 151 PetscFunctionReturn(0); 152 } 153 154 #undef __FUNCT__ 155 #define __FUNCT__ "PCSetFromOptions_TFS" 156 static PetscErrorCode PCSetFromOptions_TFS(PC pc) 157 { 158 PetscFunctionBegin; 159 PetscFunctionReturn(0); 160 } 161 #undef __FUNCT__ 162 #define __FUNCT__ "PCView_TFS" 163 static PetscErrorCode PCView_TFS(PC pc,PetscViewer viewer) 164 { 165 PetscFunctionBegin; 166 PetscFunctionReturn(0); 167 } 168 169 EXTERN_C_BEGIN 170 #undef __FUNCT__ 171 #define __FUNCT__ "PCCreate_TFS" 172 /*MC 173 PCTFS - A parallel direct solver intended for problems with very few unknowns (like the 174 coarse grid in multigrid). 175 176 Implemented by Henry M. Tufo III and Paul Fischer 177 178 Level: beginner 179 180 Notes: Only implemented for the MPIAIJ matrices 181 182 .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC 183 M*/ 184 PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_TFS(PC pc) 185 { 186 PetscErrorCode ierr; 187 PC_TFS *tfs; 188 189 PetscFunctionBegin; 190 ierr = PetscNewLog(pc,PC_TFS,&tfs);CHKERRQ(ierr); 191 192 tfs->xxt = 0; 193 tfs->xyt = 0; 194 tfs->b = 0; 195 tfs->xd = 0; 196 tfs->xo = 0; 197 tfs->nd = 0; 198 199 pc->ops->apply = 0; 200 pc->ops->applytranspose = 0; 201 pc->ops->setup = PCSetUp_TFS; 202 pc->ops->destroy = PCDestroy_TFS; 203 pc->ops->setfromoptions = PCSetFromOptions_TFS; 204 pc->ops->view = PCView_TFS; 205 pc->ops->applyrichardson = 0; 206 pc->ops->applysymmetricleft = 0; 207 pc->ops->applysymmetricright = 0; 208 pc->data = (void*)tfs; 209 PetscFunctionReturn(0); 210 } 211 EXTERN_C_END 212 213