xref: /petsc/src/ksp/pc/impls/tfs/tfs.c (revision 3468409b88586c950b487b015c1e0450f8cb062b)
16218e575SSatish Balay /*
26218e575SSatish Balay         Provides an interface to the Tufo-Fischer parallel direct solver
36218e575SSatish Balay */
46218e575SSatish Balay 
5af0996ceSBarry Smith #include <petsc/private/pcimpl.h>   /*I "petscpc.h" I*/
6c6db04a5SJed Brown #include <../src/mat/impls/aij/mpi/mpiaij.h>
7c6db04a5SJed Brown #include <../src/ksp/pc/impls/tfs/tfs.h>
86218e575SSatish Balay 
96218e575SSatish Balay typedef struct {
106218e575SSatish Balay   xxt_ADT  xxt;
116218e575SSatish Balay   xyt_ADT  xyt;
126218e575SSatish Balay   Vec      b,xd,xo;
136218e575SSatish Balay   PetscInt nd;
146218e575SSatish Balay } PC_TFS;
156218e575SSatish Balay 
166218e575SSatish Balay #undef __FUNCT__
176218e575SSatish Balay #define __FUNCT__ "PCDestroy_TFS"
186218e575SSatish Balay PetscErrorCode PCDestroy_TFS(PC pc)
196218e575SSatish Balay {
206218e575SSatish Balay   PC_TFS         *tfs = (PC_TFS*)pc->data;
216218e575SSatish Balay   PetscErrorCode ierr;
226218e575SSatish Balay 
236218e575SSatish Balay   PetscFunctionBegin;
246218e575SSatish Balay   /* free the XXT datastructures */
256218e575SSatish Balay   if (tfs->xxt) {
266218e575SSatish Balay     ierr = XXT_free(tfs->xxt);CHKERRQ(ierr);
276218e575SSatish Balay   }
286218e575SSatish Balay   if (tfs->xyt) {
296218e575SSatish Balay     ierr = XYT_free(tfs->xyt);CHKERRQ(ierr);
306218e575SSatish Balay   }
316bf464f9SBarry Smith   ierr = VecDestroy(&tfs->b);CHKERRQ(ierr);
326bf464f9SBarry Smith   ierr = VecDestroy(&tfs->xd);CHKERRQ(ierr);
336bf464f9SBarry Smith   ierr = VecDestroy(&tfs->xo);CHKERRQ(ierr);
34c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
356218e575SSatish Balay   PetscFunctionReturn(0);
366218e575SSatish Balay }
376218e575SSatish Balay 
386218e575SSatish Balay #undef __FUNCT__
396218e575SSatish Balay #define __FUNCT__ "PCApply_TFS_XXT"
406218e575SSatish Balay static PetscErrorCode PCApply_TFS_XXT(PC pc,Vec x,Vec y)
416218e575SSatish Balay {
426218e575SSatish Balay   PC_TFS            *tfs = (PC_TFS*)pc->data;
43*3468409bSBarry Smith   PetscScalar       *yy;
44*3468409bSBarry Smith   const PetscScalar *xx;
456218e575SSatish Balay   PetscErrorCode    ierr;
466218e575SSatish Balay 
476218e575SSatish Balay   PetscFunctionBegin;
48*3468409bSBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
496218e575SSatish Balay   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
50*3468409bSBarry Smith   ierr = XXT_solve(tfs->xxt,yy,(PetscScalar*)xx);CHKERRQ(ierr);
51*3468409bSBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
526218e575SSatish Balay   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
536218e575SSatish Balay   PetscFunctionReturn(0);
546218e575SSatish Balay }
556218e575SSatish Balay 
566218e575SSatish Balay #undef __FUNCT__
576218e575SSatish Balay #define __FUNCT__ "PCApply_TFS_XYT"
586218e575SSatish Balay static PetscErrorCode PCApply_TFS_XYT(PC pc,Vec x,Vec y)
596218e575SSatish Balay {
606218e575SSatish Balay   PC_TFS            *tfs = (PC_TFS*)pc->data;
61*3468409bSBarry Smith   PetscScalar       *yy;
62*3468409bSBarry Smith   const PetscScalar *xx;
636218e575SSatish Balay   PetscErrorCode    ierr;
646218e575SSatish Balay 
656218e575SSatish Balay   PetscFunctionBegin;
66*3468409bSBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
676218e575SSatish Balay   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
68*3468409bSBarry Smith   ierr = XYT_solve(tfs->xyt,yy,(PetscScalar*)xx);CHKERRQ(ierr);
69*3468409bSBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
706218e575SSatish Balay   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
716218e575SSatish Balay   PetscFunctionReturn(0);
726218e575SSatish Balay }
736218e575SSatish Balay 
746218e575SSatish Balay #undef __FUNCT__
75fe05c926SBarry Smith #define __FUNCT__ "PCTFSLocalMult_TFS"
76fe05c926SBarry Smith static PetscErrorCode PCTFSLocalMult_TFS(PC pc,PetscScalar *xin,PetscScalar *xout)
776218e575SSatish Balay {
786218e575SSatish Balay   PC_TFS         *tfs = (PC_TFS*)pc->data;
796218e575SSatish Balay   Mat            A    = pc->pmat;
806218e575SSatish Balay   Mat_MPIAIJ     *a   = (Mat_MPIAIJ*)A->data;
816218e575SSatish Balay   PetscErrorCode ierr;
826218e575SSatish Balay 
836218e575SSatish Balay   PetscFunctionBegin;
846218e575SSatish Balay   ierr = VecPlaceArray(tfs->b,xout);CHKERRQ(ierr);
856218e575SSatish Balay   ierr = VecPlaceArray(tfs->xd,xin);CHKERRQ(ierr);
866218e575SSatish Balay   ierr = VecPlaceArray(tfs->xo,xin+tfs->nd);CHKERRQ(ierr);
876218e575SSatish Balay   ierr = MatMult(a->A,tfs->xd,tfs->b);CHKERRQ(ierr);
886218e575SSatish Balay   ierr = MatMultAdd(a->B,tfs->xo,tfs->b,tfs->b);CHKERRQ(ierr);
89026a3f60SBarry Smith   ierr = VecResetArray(tfs->b);CHKERRQ(ierr);
90026a3f60SBarry Smith   ierr = VecResetArray(tfs->xd);CHKERRQ(ierr);
91026a3f60SBarry Smith   ierr = VecResetArray(tfs->xo);CHKERRQ(ierr);
926218e575SSatish Balay   PetscFunctionReturn(0);
936218e575SSatish Balay }
946218e575SSatish Balay 
956218e575SSatish Balay #undef __FUNCT__
966218e575SSatish Balay #define __FUNCT__ "PCSetUp_TFS"
976218e575SSatish Balay static PetscErrorCode PCSetUp_TFS(PC pc)
986218e575SSatish Balay {
996218e575SSatish Balay   PC_TFS         *tfs = (PC_TFS*)pc->data;
1006218e575SSatish Balay   Mat            A    = pc->pmat;
1016218e575SSatish Balay   Mat_MPIAIJ     *a   = (Mat_MPIAIJ*)A->data;
1026218e575SSatish Balay   PetscErrorCode ierr;
1036218e575SSatish Balay   PetscInt       *localtoglobal,ncol,i;
104ace3abfcSBarry Smith   PetscBool      ismpiaij;
1056218e575SSatish Balay 
1066218e575SSatish Balay   /*
107ace3abfcSBarry Smith   PetscBool      issymmetric;
1086218e575SSatish Balay   Petsc Real tol = 0.0;
1096218e575SSatish Balay   */
1106218e575SSatish Balay 
1116218e575SSatish Balay   PetscFunctionBegin;
112ce94432eSBarry Smith   if (A->cmap->N != A->rmap->N) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_SIZ,"matrix must be square");
113251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr);
114ce94432eSBarry Smith   if (!ismpiaij) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Currently only supports MPIAIJ matrices");
1156218e575SSatish Balay 
1166218e575SSatish Balay   /* generate the local to global mapping */
117d0f46423SBarry Smith   ncol = a->A->cmap->n + a->B->cmap->n;
118854ce69bSBarry Smith   ierr = PetscMalloc1(ncol,&localtoglobal);CHKERRQ(ierr);
1192fa5cd67SKarl Rupp   for (i=0; i<a->A->cmap->n; i++) localtoglobal[i] = A->cmap->rstart + i + 1;
1202fa5cd67SKarl Rupp   for (i=0; i<a->B->cmap->n; i++) localtoglobal[i+a->A->cmap->n] = a->garray[i] + 1;
1212fa5cd67SKarl Rupp 
1226218e575SSatish Balay   /* generate the vectors needed for the local solves */
1230298fd71SBarry Smith   ierr    = VecCreateSeqWithArray(PETSC_COMM_SELF,1,a->A->rmap->n,NULL,&tfs->b);CHKERRQ(ierr);
1240298fd71SBarry Smith   ierr    = VecCreateSeqWithArray(PETSC_COMM_SELF,1,a->A->cmap->n,NULL,&tfs->xd);CHKERRQ(ierr);
1250298fd71SBarry Smith   ierr    = VecCreateSeqWithArray(PETSC_COMM_SELF,1,a->B->cmap->n,NULL,&tfs->xo);CHKERRQ(ierr);
126d0f46423SBarry Smith   tfs->nd = a->A->cmap->n;
1276218e575SSatish Balay 
1286218e575SSatish Balay 
1296218e575SSatish Balay   /*  ierr =  MatIsSymmetric(A,tol,&issymmetric); */
1306218e575SSatish Balay   /*  if (issymmetric) { */
131585bbf96SBarry Smith   ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr);
1326218e575SSatish Balay   if (A->symmetric) {
1336218e575SSatish Balay     tfs->xxt       = XXT_new();
1345c8f6a95SKarl Rupp     ierr           = XXT_factor(tfs->xxt,localtoglobal,A->rmap->n,ncol,(PetscErrorCode (*)(void*,PetscScalar*,PetscScalar*))PCTFSLocalMult_TFS,pc);CHKERRQ(ierr);
1356218e575SSatish Balay     pc->ops->apply = PCApply_TFS_XXT;
1366218e575SSatish Balay   } else {
1376218e575SSatish Balay     tfs->xyt       = XYT_new();
1385c8f6a95SKarl Rupp     ierr           = XYT_factor(tfs->xyt,localtoglobal,A->rmap->n,ncol,(PetscErrorCode (*)(void*,PetscScalar*,PetscScalar*))PCTFSLocalMult_TFS,pc);CHKERRQ(ierr);
1396218e575SSatish Balay     pc->ops->apply = PCApply_TFS_XYT;
1406218e575SSatish Balay   }
1416218e575SSatish Balay 
1426218e575SSatish Balay   ierr = PetscFree(localtoglobal);CHKERRQ(ierr);
1436218e575SSatish Balay   PetscFunctionReturn(0);
1446218e575SSatish Balay }
1456218e575SSatish Balay 
1466218e575SSatish Balay #undef __FUNCT__
1476218e575SSatish Balay #define __FUNCT__ "PCSetFromOptions_TFS"
1484416b707SBarry Smith static PetscErrorCode PCSetFromOptions_TFS(PetscOptionItems *PetscOptionsObject,PC pc)
1496218e575SSatish Balay {
1506218e575SSatish Balay   PetscFunctionBegin;
1516218e575SSatish Balay   PetscFunctionReturn(0);
1526218e575SSatish Balay }
1536218e575SSatish Balay #undef __FUNCT__
1546218e575SSatish Balay #define __FUNCT__ "PCView_TFS"
1556218e575SSatish Balay static PetscErrorCode PCView_TFS(PC pc,PetscViewer viewer)
1566218e575SSatish Balay {
1576218e575SSatish Balay   PetscFunctionBegin;
1586218e575SSatish Balay   PetscFunctionReturn(0);
1596218e575SSatish Balay }
1606218e575SSatish Balay 
1616218e575SSatish Balay #undef __FUNCT__
1626218e575SSatish Balay #define __FUNCT__ "PCCreate_TFS"
16394c0dd61SBarry Smith /*MC
16494c0dd61SBarry Smith      PCTFS - A parallel direct solver intended for problems with very few unknowns (like the
16594c0dd61SBarry Smith          coarse grid in multigrid).
16694c0dd61SBarry Smith 
16794c0dd61SBarry Smith    Implemented by  Henry M. Tufo III and Paul Fischer
16894c0dd61SBarry Smith 
16994c0dd61SBarry Smith    Level: beginner
17094c0dd61SBarry Smith 
17194c0dd61SBarry Smith    Notes: Only implemented for the MPIAIJ matrices
17294c0dd61SBarry Smith 
1737773e740SBarry Smith           Only works on a solver object that lives on all of PETSC_COMM_WORLD!
1747773e740SBarry Smith 
17594c0dd61SBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC
17694c0dd61SBarry Smith M*/
1778cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_TFS(PC pc)
1786218e575SSatish Balay {
1796218e575SSatish Balay   PetscErrorCode ierr;
1806218e575SSatish Balay   PC_TFS         *tfs;
1813cd2be91SBarry Smith   PetscMPIInt    cmp;
1826218e575SSatish Balay 
1836218e575SSatish Balay   PetscFunctionBegin;
184ce94432eSBarry Smith   ierr = MPI_Comm_compare(PETSC_COMM_WORLD,PetscObjectComm((PetscObject)pc),&cmp);CHKERRQ(ierr);
185ce94432eSBarry Smith   if (cmp != MPI_IDENT && cmp != MPI_CONGRUENT) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"TFS only works with PETSC_COMM_WORLD objects");
186b00a9115SJed Brown   ierr = PetscNewLog(pc,&tfs);CHKERRQ(ierr);
1876218e575SSatish Balay 
1886218e575SSatish Balay   tfs->xxt = 0;
1896218e575SSatish Balay   tfs->xyt = 0;
1906218e575SSatish Balay   tfs->b   = 0;
1916218e575SSatish Balay   tfs->xd  = 0;
1926218e575SSatish Balay   tfs->xo  = 0;
1936218e575SSatish Balay   tfs->nd  = 0;
1946218e575SSatish Balay 
1956218e575SSatish Balay   pc->ops->apply               = 0;
1966218e575SSatish Balay   pc->ops->applytranspose      = 0;
1976218e575SSatish Balay   pc->ops->setup               = PCSetUp_TFS;
1986218e575SSatish Balay   pc->ops->destroy             = PCDestroy_TFS;
1996218e575SSatish Balay   pc->ops->setfromoptions      = PCSetFromOptions_TFS;
2006218e575SSatish Balay   pc->ops->view                = PCView_TFS;
2016218e575SSatish Balay   pc->ops->applyrichardson     = 0;
2026218e575SSatish Balay   pc->ops->applysymmetricleft  = 0;
2036218e575SSatish Balay   pc->ops->applysymmetricright = 0;
2046218e575SSatish Balay   pc->data                     = (void*)tfs;
2056218e575SSatish Balay   PetscFunctionReturn(0);
2066218e575SSatish Balay }
2076218e575SSatish Balay 
208