xref: /petsc/src/ksp/pc/impls/tfs/tfs.c (revision 94c0dd61fc8a097f05705e916edb6041df80fa81)
1dba47a55SKris Buschelman #define PETSCKSP_DLL
26218e575SSatish Balay /*
36218e575SSatish Balay         Provides an interface to the Tufo-Fischer parallel direct solver
46218e575SSatish Balay */
56218e575SSatish Balay 
66356e834SBarry Smith #include "private/pcimpl.h"   /*I "petscpc.h" I*/
76218e575SSatish Balay #include "src/mat/impls/aij/mpi/mpiaij.h"
87758a8cdSBarry Smith #include "src/ksp/pc/impls/tfs/tfs.h"
96218e575SSatish Balay 
106218e575SSatish Balay typedef struct {
116218e575SSatish Balay   xxt_ADT  xxt;
126218e575SSatish Balay   xyt_ADT  xyt;
136218e575SSatish Balay   Vec      b,xd,xo;
146218e575SSatish Balay   PetscInt nd;
156218e575SSatish Balay } PC_TFS;
166218e575SSatish Balay 
176218e575SSatish Balay #undef __FUNCT__
186218e575SSatish Balay #define __FUNCT__ "PCDestroy_TFS"
196218e575SSatish Balay PetscErrorCode PCDestroy_TFS(PC pc)
206218e575SSatish Balay {
216218e575SSatish Balay   PC_TFS *tfs = (PC_TFS*)pc->data;
226218e575SSatish Balay   PetscErrorCode ierr;
236218e575SSatish Balay 
246218e575SSatish Balay   PetscFunctionBegin;
256218e575SSatish Balay   /* free the XXT datastructures */
266218e575SSatish Balay   if (tfs->xxt) {
276218e575SSatish Balay     ierr = XXT_free(tfs->xxt);CHKERRQ(ierr);
286218e575SSatish Balay   }
296218e575SSatish Balay   if (tfs->xyt) {
306218e575SSatish Balay     ierr = XYT_free(tfs->xyt);CHKERRQ(ierr);
316218e575SSatish Balay   }
326218e575SSatish Balay   if (tfs->b) {
336218e575SSatish Balay   ierr = VecDestroy(tfs->b);CHKERRQ(ierr);
346218e575SSatish Balay   }
356218e575SSatish Balay   if (tfs->xd) {
366218e575SSatish Balay   ierr = VecDestroy(tfs->xd);CHKERRQ(ierr);
376218e575SSatish Balay   }
386218e575SSatish Balay   if (tfs->xo) {
396218e575SSatish Balay   ierr = VecDestroy(tfs->xo);CHKERRQ(ierr);
406218e575SSatish Balay   }
416218e575SSatish Balay   ierr = PetscFree(tfs);CHKERRQ(ierr);
426218e575SSatish Balay   PetscFunctionReturn(0);
436218e575SSatish Balay }
446218e575SSatish Balay 
456218e575SSatish Balay #undef __FUNCT__
466218e575SSatish Balay #define __FUNCT__ "PCApply_TFS_XXT"
476218e575SSatish Balay static PetscErrorCode PCApply_TFS_XXT(PC pc,Vec x,Vec y)
486218e575SSatish Balay {
496218e575SSatish Balay   PC_TFS *tfs = (PC_TFS*)pc->data;
506218e575SSatish Balay   PetscScalar    *xx,*yy;
516218e575SSatish Balay   PetscErrorCode ierr;
526218e575SSatish Balay 
536218e575SSatish Balay   PetscFunctionBegin;
546218e575SSatish Balay   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
556218e575SSatish Balay   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
566218e575SSatish Balay   ierr = XXT_solve(tfs->xxt,yy,xx);CHKERRQ(ierr);
576218e575SSatish Balay   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
586218e575SSatish Balay   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
596218e575SSatish Balay   PetscFunctionReturn(0);
606218e575SSatish Balay }
616218e575SSatish Balay 
626218e575SSatish Balay #undef __FUNCT__
636218e575SSatish Balay #define __FUNCT__ "PCApply_TFS_XYT"
646218e575SSatish Balay static PetscErrorCode PCApply_TFS_XYT(PC pc,Vec x,Vec y)
656218e575SSatish Balay {
666218e575SSatish Balay   PC_TFS *tfs = (PC_TFS*)pc->data;
676218e575SSatish Balay   PetscScalar    *xx,*yy;
686218e575SSatish Balay   PetscErrorCode ierr;
696218e575SSatish Balay 
706218e575SSatish Balay   PetscFunctionBegin;
716218e575SSatish Balay   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
726218e575SSatish Balay   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
736218e575SSatish Balay   ierr = XYT_solve(tfs->xyt,yy,xx);CHKERRQ(ierr);
746218e575SSatish Balay   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
756218e575SSatish Balay   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
766218e575SSatish Balay   PetscFunctionReturn(0);
776218e575SSatish Balay }
786218e575SSatish Balay 
796218e575SSatish Balay #undef __FUNCT__
806218e575SSatish Balay #define __FUNCT__ "LocalMult_TFS"
816218e575SSatish Balay static PetscErrorCode LocalMult_TFS(PC pc,PetscScalar *xin,PetscScalar *xout)
826218e575SSatish Balay {
836218e575SSatish Balay   PC_TFS        *tfs = (PC_TFS*)pc->data;
846218e575SSatish Balay   Mat           A = pc->pmat;
856218e575SSatish Balay   Mat_MPIAIJ    *a = (Mat_MPIAIJ*)A->data;
866218e575SSatish Balay   PetscErrorCode ierr;
876218e575SSatish Balay 
886218e575SSatish Balay   PetscFunctionBegin;
896218e575SSatish Balay   ierr = VecPlaceArray(tfs->b,xout);CHKERRQ(ierr);
906218e575SSatish Balay   ierr = VecPlaceArray(tfs->xd,xin);CHKERRQ(ierr);
916218e575SSatish Balay   ierr = VecPlaceArray(tfs->xo,xin+tfs->nd);CHKERRQ(ierr);
926218e575SSatish Balay   ierr = MatMult(a->A,tfs->xd,tfs->b);CHKERRQ(ierr);
936218e575SSatish Balay   ierr = MatMultAdd(a->B,tfs->xo,tfs->b,tfs->b);CHKERRQ(ierr);
94026a3f60SBarry Smith   ierr = VecResetArray(tfs->b);CHKERRQ(ierr);
95026a3f60SBarry Smith   ierr = VecResetArray(tfs->xd);CHKERRQ(ierr);
96026a3f60SBarry Smith   ierr = VecResetArray(tfs->xo);CHKERRQ(ierr);
976218e575SSatish Balay   PetscFunctionReturn(0);
986218e575SSatish Balay }
996218e575SSatish Balay 
1006218e575SSatish Balay #undef __FUNCT__
1016218e575SSatish Balay #define __FUNCT__ "PCSetUp_TFS"
1026218e575SSatish Balay static PetscErrorCode PCSetUp_TFS(PC pc)
1036218e575SSatish Balay {
1046218e575SSatish Balay   PC_TFS        *tfs = (PC_TFS*)pc->data;
1056218e575SSatish Balay   Mat            A = pc->pmat;
1066218e575SSatish Balay   Mat_MPIAIJ     *a = (Mat_MPIAIJ*)A->data;
1076218e575SSatish Balay   PetscErrorCode ierr;
1086218e575SSatish Balay   PetscInt      *localtoglobal,ncol,i;
1096218e575SSatish Balay   PetscTruth     ismpiaij;
1106218e575SSatish Balay 
1116218e575SSatish Balay   /*
1126218e575SSatish Balay   PetscTruth     issymmetric;
1136218e575SSatish Balay   Petsc Real tol = 0.0;
1146218e575SSatish Balay   */
1156218e575SSatish Balay 
1166218e575SSatish Balay   PetscFunctionBegin;
117899cda47SBarry Smith   if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
1186218e575SSatish Balay   ierr = PetscTypeCompare((PetscObject)pc->pmat,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr);
1196218e575SSatish Balay   if (!ismpiaij) {
1206218e575SSatish Balay     SETERRQ(PETSC_ERR_SUP,"Currently only supports MPIAIJ matrices");
1216218e575SSatish Balay   }
1226218e575SSatish Balay 
1236218e575SSatish Balay   /* generate the local to global mapping */
124899cda47SBarry Smith   ncol = a->A->cmap.n + a->B->cmap.n;
12552f87cdaSBarry Smith   ierr = PetscMalloc((ncol)*sizeof(PetscInt),&localtoglobal);CHKERRQ(ierr);
126899cda47SBarry Smith   for (i=0; i<a->A->cmap.n; i++) {
127899cda47SBarry Smith     localtoglobal[i] = A->cmap.rstart + i + 1;
1286218e575SSatish Balay   }
129899cda47SBarry Smith   for (i=0; i<a->B->cmap.n; i++) {
130899cda47SBarry Smith     localtoglobal[i+a->A->cmap.n] = a->garray[i] + 1;
1316218e575SSatish Balay   }
1326218e575SSatish Balay   /* generate the vectors needed for the local solves */
133899cda47SBarry Smith   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,a->A->rmap.n,PETSC_NULL,&tfs->b);CHKERRQ(ierr);
134899cda47SBarry Smith   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,a->A->cmap.n,PETSC_NULL,&tfs->xd);CHKERRQ(ierr);
135899cda47SBarry Smith   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,a->B->cmap.n,PETSC_NULL,&tfs->xo);CHKERRQ(ierr);
136899cda47SBarry Smith   tfs->nd = a->A->cmap.n;
1376218e575SSatish Balay 
1386218e575SSatish Balay 
1396218e575SSatish Balay   /*  ierr =  MatIsSymmetric(A,tol,&issymmetric); */
1406218e575SSatish Balay   /*  if (issymmetric) { */
141585bbf96SBarry Smith   ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr);
1426218e575SSatish Balay   if (A->symmetric) {
1436218e575SSatish Balay     tfs->xxt       = XXT_new();
144899cda47SBarry Smith     ierr           = XXT_factor(tfs->xxt,localtoglobal,A->rmap.n,ncol,(void*)LocalMult_TFS,pc);CHKERRQ(ierr);
1456218e575SSatish Balay     pc->ops->apply = PCApply_TFS_XXT;
1466218e575SSatish Balay   } else {
1476218e575SSatish Balay     tfs->xyt       = XYT_new();
148899cda47SBarry Smith     ierr           = XYT_factor(tfs->xyt,localtoglobal,A->rmap.n,ncol,(void*)LocalMult_TFS,pc);CHKERRQ(ierr);
1496218e575SSatish Balay     pc->ops->apply = PCApply_TFS_XYT;
1506218e575SSatish Balay   }
1516218e575SSatish Balay 
1526218e575SSatish Balay   ierr = PetscFree(localtoglobal);CHKERRQ(ierr);
1536218e575SSatish Balay   PetscFunctionReturn(0);
1546218e575SSatish Balay }
1556218e575SSatish Balay 
1566218e575SSatish Balay #undef __FUNCT__
1576218e575SSatish Balay #define __FUNCT__ "PCSetFromOptions_TFS"
1586218e575SSatish Balay static PetscErrorCode PCSetFromOptions_TFS(PC pc)
1596218e575SSatish Balay {
1606218e575SSatish Balay   PetscFunctionBegin;
1616218e575SSatish Balay   PetscFunctionReturn(0);
1626218e575SSatish Balay }
1636218e575SSatish Balay #undef __FUNCT__
1646218e575SSatish Balay #define __FUNCT__ "PCView_TFS"
1656218e575SSatish Balay static PetscErrorCode PCView_TFS(PC pc,PetscViewer viewer)
1666218e575SSatish Balay {
1676218e575SSatish Balay   PetscFunctionBegin;
1686218e575SSatish Balay   PetscFunctionReturn(0);
1696218e575SSatish Balay }
1706218e575SSatish Balay 
1716218e575SSatish Balay EXTERN_C_BEGIN
1726218e575SSatish Balay #undef __FUNCT__
1736218e575SSatish Balay #define __FUNCT__ "PCCreate_TFS"
174*94c0dd61SBarry Smith /*MC
175*94c0dd61SBarry Smith      PCTFS - A parallel direct solver intended for problems with very few unknowns (like the
176*94c0dd61SBarry Smith          coarse grid in multigrid).
177*94c0dd61SBarry Smith 
178*94c0dd61SBarry Smith    Implemented by  Henry M. Tufo III and Paul Fischer
179*94c0dd61SBarry Smith 
180*94c0dd61SBarry Smith    Level: beginner
181*94c0dd61SBarry Smith 
182*94c0dd61SBarry Smith    Notes: Only implemented for the MPIAIJ matrices
183*94c0dd61SBarry Smith 
184*94c0dd61SBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC
185*94c0dd61SBarry Smith M*/
186dba47a55SKris Buschelman PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_TFS(PC pc)
1876218e575SSatish Balay {
1886218e575SSatish Balay   PetscErrorCode ierr;
1896218e575SSatish Balay   PC_TFS         *tfs;
1906218e575SSatish Balay 
1916218e575SSatish Balay   PetscFunctionBegin;
19238f2d2fdSLisandro Dalcin   ierr = PetscNewLog(pc,PC_TFS,&tfs);CHKERRQ(ierr);
1936218e575SSatish Balay 
1946218e575SSatish Balay   tfs->xxt = 0;
1956218e575SSatish Balay   tfs->xyt = 0;
1966218e575SSatish Balay   tfs->b   = 0;
1976218e575SSatish Balay   tfs->xd  = 0;
1986218e575SSatish Balay   tfs->xo  = 0;
1996218e575SSatish Balay   tfs->nd  = 0;
2006218e575SSatish Balay 
2016218e575SSatish Balay   pc->ops->apply               = 0;
2026218e575SSatish Balay   pc->ops->applytranspose      = 0;
2036218e575SSatish Balay   pc->ops->setup               = PCSetUp_TFS;
2046218e575SSatish Balay   pc->ops->destroy             = PCDestroy_TFS;
2056218e575SSatish Balay   pc->ops->setfromoptions      = PCSetFromOptions_TFS;
2066218e575SSatish Balay   pc->ops->view                = PCView_TFS;
2076218e575SSatish Balay   pc->ops->applyrichardson     = 0;
2086218e575SSatish Balay   pc->ops->applysymmetricleft  = 0;
2096218e575SSatish Balay   pc->ops->applysymmetricright = 0;
2106218e575SSatish Balay   pc->data                     = (void*)tfs;
2116218e575SSatish Balay   PetscFunctionReturn(0);
2126218e575SSatish Balay }
2136218e575SSatish Balay EXTERN_C_END
2146218e575SSatish Balay 
215