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(((PetscObject)pc)->comm,PETSC_ERR_ARG_SIZ,"matrix must be square"); 111 ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 112 if (!ismpiaij) SETERRQ(((PetscObject)pc)->comm,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 = PetscMalloc((ncol)*sizeof(PetscInt),&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,PETSC_NULL,&tfs->b);CHKERRQ(ierr); 122 ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,a->A->cmap->n,PETSC_NULL,&tfs->xd);CHKERRQ(ierr); 123 ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,a->B->cmap->n,PETSC_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(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 EXTERN_C_BEGIN 160 #undef __FUNCT__ 161 #define __FUNCT__ "PCCreate_TFS" 162 /*MC 163 PCTFS - A parallel direct solver intended for problems with very few unknowns (like the 164 coarse grid in multigrid). 165 166 Implemented by Henry M. Tufo III and Paul Fischer 167 168 Level: beginner 169 170 Notes: Only implemented for the MPIAIJ matrices 171 172 Only works on a solver object that lives on all of PETSC_COMM_WORLD! 173 174 .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC 175 M*/ 176 PetscErrorCode PCCreate_TFS(PC pc) 177 { 178 PetscErrorCode ierr; 179 PC_TFS *tfs; 180 PetscMPIInt cmp; 181 182 PetscFunctionBegin; 183 ierr = MPI_Comm_compare(PETSC_COMM_WORLD,((PetscObject)pc)->comm,&cmp);CHKERRQ(ierr); 184 if (cmp != MPI_IDENT && cmp != MPI_CONGRUENT) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_SUP,"TFS only works with PETSC_COMM_WORLD objects"); 185 ierr = PetscNewLog(pc,PC_TFS,&tfs);CHKERRQ(ierr); 186 187 tfs->xxt = 0; 188 tfs->xyt = 0; 189 tfs->b = 0; 190 tfs->xd = 0; 191 tfs->xo = 0; 192 tfs->nd = 0; 193 194 pc->ops->apply = 0; 195 pc->ops->applytranspose = 0; 196 pc->ops->setup = PCSetUp_TFS; 197 pc->ops->destroy = PCDestroy_TFS; 198 pc->ops->setfromoptions = PCSetFromOptions_TFS; 199 pc->ops->view = PCView_TFS; 200 pc->ops->applyrichardson = 0; 201 pc->ops->applysymmetricleft = 0; 202 pc->ops->applysymmetricright = 0; 203 pc->data = (void*)tfs; 204 PetscFunctionReturn(0); 205 } 206 EXTERN_C_END 207 208