xref: /petsc/src/ksp/pc/impls/tfs/tfs.c (revision c6db04a5321582041def2b1e244c75985478b3ef)
16218e575SSatish Balay /*
26218e575SSatish Balay         Provides an interface to the Tufo-Fischer parallel direct solver
36218e575SSatish Balay */
46218e575SSatish Balay 
5*c6db04a5SJed Brown #include <private/pcimpl.h>   /*I "petscpc.h" I*/
6*c6db04a5SJed Brown #include <../src/mat/impls/aij/mpi/mpiaij.h>
7*c6db04a5SJed 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   }
316218e575SSatish Balay   if (tfs->b) {
326218e575SSatish Balay   ierr = VecDestroy(tfs->b);CHKERRQ(ierr);
336218e575SSatish Balay   }
346218e575SSatish Balay   if (tfs->xd) {
356218e575SSatish Balay   ierr = VecDestroy(tfs->xd);CHKERRQ(ierr);
366218e575SSatish Balay   }
376218e575SSatish Balay   if (tfs->xo) {
386218e575SSatish Balay   ierr = VecDestroy(tfs->xo);CHKERRQ(ierr);
396218e575SSatish Balay   }
40c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
416218e575SSatish Balay   PetscFunctionReturn(0);
426218e575SSatish Balay }
436218e575SSatish Balay 
446218e575SSatish Balay #undef __FUNCT__
456218e575SSatish Balay #define __FUNCT__ "PCApply_TFS_XXT"
466218e575SSatish Balay static PetscErrorCode PCApply_TFS_XXT(PC pc,Vec x,Vec y)
476218e575SSatish Balay {
486218e575SSatish Balay   PC_TFS *tfs = (PC_TFS*)pc->data;
496218e575SSatish Balay   PetscScalar    *xx,*yy;
506218e575SSatish Balay   PetscErrorCode ierr;
516218e575SSatish Balay 
526218e575SSatish Balay   PetscFunctionBegin;
536218e575SSatish Balay   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
546218e575SSatish Balay   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
556218e575SSatish Balay   ierr = XXT_solve(tfs->xxt,yy,xx);CHKERRQ(ierr);
566218e575SSatish Balay   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
576218e575SSatish Balay   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
586218e575SSatish Balay   PetscFunctionReturn(0);
596218e575SSatish Balay }
606218e575SSatish Balay 
616218e575SSatish Balay #undef __FUNCT__
626218e575SSatish Balay #define __FUNCT__ "PCApply_TFS_XYT"
636218e575SSatish Balay static PetscErrorCode PCApply_TFS_XYT(PC pc,Vec x,Vec y)
646218e575SSatish Balay {
656218e575SSatish Balay   PC_TFS *tfs = (PC_TFS*)pc->data;
666218e575SSatish Balay   PetscScalar    *xx,*yy;
676218e575SSatish Balay   PetscErrorCode ierr;
686218e575SSatish Balay 
696218e575SSatish Balay   PetscFunctionBegin;
706218e575SSatish Balay   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
716218e575SSatish Balay   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
726218e575SSatish Balay   ierr = XYT_solve(tfs->xyt,yy,xx);CHKERRQ(ierr);
736218e575SSatish Balay   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
746218e575SSatish Balay   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
756218e575SSatish Balay   PetscFunctionReturn(0);
766218e575SSatish Balay }
776218e575SSatish Balay 
786218e575SSatish Balay #undef __FUNCT__
796218e575SSatish Balay #define __FUNCT__ "LocalMult_TFS"
806218e575SSatish Balay static PetscErrorCode LocalMult_TFS(PC pc,PetscScalar *xin,PetscScalar *xout)
816218e575SSatish Balay {
826218e575SSatish Balay   PC_TFS        *tfs = (PC_TFS*)pc->data;
836218e575SSatish Balay   Mat           A = pc->pmat;
846218e575SSatish Balay   Mat_MPIAIJ    *a = (Mat_MPIAIJ*)A->data;
856218e575SSatish Balay   PetscErrorCode ierr;
866218e575SSatish Balay 
876218e575SSatish Balay   PetscFunctionBegin;
886218e575SSatish Balay   ierr = VecPlaceArray(tfs->b,xout);CHKERRQ(ierr);
896218e575SSatish Balay   ierr = VecPlaceArray(tfs->xd,xin);CHKERRQ(ierr);
906218e575SSatish Balay   ierr = VecPlaceArray(tfs->xo,xin+tfs->nd);CHKERRQ(ierr);
916218e575SSatish Balay   ierr = MatMult(a->A,tfs->xd,tfs->b);CHKERRQ(ierr);
926218e575SSatish Balay   ierr = MatMultAdd(a->B,tfs->xo,tfs->b,tfs->b);CHKERRQ(ierr);
93026a3f60SBarry Smith   ierr = VecResetArray(tfs->b);CHKERRQ(ierr);
94026a3f60SBarry Smith   ierr = VecResetArray(tfs->xd);CHKERRQ(ierr);
95026a3f60SBarry Smith   ierr = VecResetArray(tfs->xo);CHKERRQ(ierr);
966218e575SSatish Balay   PetscFunctionReturn(0);
976218e575SSatish Balay }
986218e575SSatish Balay 
996218e575SSatish Balay #undef __FUNCT__
1006218e575SSatish Balay #define __FUNCT__ "PCSetUp_TFS"
1016218e575SSatish Balay static PetscErrorCode PCSetUp_TFS(PC pc)
1026218e575SSatish Balay {
1036218e575SSatish Balay   PC_TFS        *tfs = (PC_TFS*)pc->data;
1046218e575SSatish Balay   Mat            A = pc->pmat;
1056218e575SSatish Balay   Mat_MPIAIJ     *a = (Mat_MPIAIJ*)A->data;
1066218e575SSatish Balay   PetscErrorCode ierr;
1076218e575SSatish Balay   PetscInt      *localtoglobal,ncol,i;
108ace3abfcSBarry Smith   PetscBool      ismpiaij;
1096218e575SSatish Balay 
1106218e575SSatish Balay   /*
111ace3abfcSBarry Smith   PetscBool      issymmetric;
1126218e575SSatish Balay   Petsc Real tol = 0.0;
1136218e575SSatish Balay   */
1146218e575SSatish Balay 
1156218e575SSatish Balay   PetscFunctionBegin;
116e7e72b3dSBarry Smith   if (A->cmap->N != A->rmap->N) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_SIZ,"matrix must be square");
1176218e575SSatish Balay   ierr = PetscTypeCompare((PetscObject)pc->pmat,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr);
118e7e72b3dSBarry Smith   if (!ismpiaij) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_SUP,"Currently only supports MPIAIJ matrices");
1196218e575SSatish Balay 
1206218e575SSatish Balay   /* generate the local to global mapping */
121d0f46423SBarry Smith   ncol = a->A->cmap->n + a->B->cmap->n;
12252f87cdaSBarry Smith   ierr = PetscMalloc((ncol)*sizeof(PetscInt),&localtoglobal);CHKERRQ(ierr);
123d0f46423SBarry Smith   for (i=0; i<a->A->cmap->n; i++) {
124d0f46423SBarry Smith     localtoglobal[i] = A->cmap->rstart + i + 1;
1256218e575SSatish Balay   }
126d0f46423SBarry Smith   for (i=0; i<a->B->cmap->n; i++) {
127d0f46423SBarry Smith     localtoglobal[i+a->A->cmap->n] = a->garray[i] + 1;
1286218e575SSatish Balay   }
1296218e575SSatish Balay   /* generate the vectors needed for the local solves */
130d0f46423SBarry Smith   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,a->A->rmap->n,PETSC_NULL,&tfs->b);CHKERRQ(ierr);
131d0f46423SBarry Smith   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,a->A->cmap->n,PETSC_NULL,&tfs->xd);CHKERRQ(ierr);
132d0f46423SBarry Smith   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,a->B->cmap->n,PETSC_NULL,&tfs->xo);CHKERRQ(ierr);
133d0f46423SBarry Smith   tfs->nd = a->A->cmap->n;
1346218e575SSatish Balay 
1356218e575SSatish Balay 
1366218e575SSatish Balay   /*  ierr =  MatIsSymmetric(A,tol,&issymmetric); */
1376218e575SSatish Balay   /*  if (issymmetric) { */
138585bbf96SBarry Smith   ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr);
1396218e575SSatish Balay   if (A->symmetric) {
1406218e575SSatish Balay     tfs->xxt       = XXT_new();
141d0f46423SBarry Smith     ierr           = XXT_factor(tfs->xxt,localtoglobal,A->rmap->n,ncol,(void*)LocalMult_TFS,pc);CHKERRQ(ierr);
1426218e575SSatish Balay     pc->ops->apply = PCApply_TFS_XXT;
1436218e575SSatish Balay   } else {
1446218e575SSatish Balay     tfs->xyt       = XYT_new();
145d0f46423SBarry Smith     ierr           = XYT_factor(tfs->xyt,localtoglobal,A->rmap->n,ncol,(void*)LocalMult_TFS,pc);CHKERRQ(ierr);
1466218e575SSatish Balay     pc->ops->apply = PCApply_TFS_XYT;
1476218e575SSatish Balay   }
1486218e575SSatish Balay 
1496218e575SSatish Balay   ierr = PetscFree(localtoglobal);CHKERRQ(ierr);
1506218e575SSatish Balay   PetscFunctionReturn(0);
1516218e575SSatish Balay }
1526218e575SSatish Balay 
1536218e575SSatish Balay #undef __FUNCT__
1546218e575SSatish Balay #define __FUNCT__ "PCSetFromOptions_TFS"
1556218e575SSatish Balay static PetscErrorCode PCSetFromOptions_TFS(PC pc)
1566218e575SSatish Balay {
1576218e575SSatish Balay   PetscFunctionBegin;
1586218e575SSatish Balay   PetscFunctionReturn(0);
1596218e575SSatish Balay }
1606218e575SSatish Balay #undef __FUNCT__
1616218e575SSatish Balay #define __FUNCT__ "PCView_TFS"
1626218e575SSatish Balay static PetscErrorCode PCView_TFS(PC pc,PetscViewer viewer)
1636218e575SSatish Balay {
1646218e575SSatish Balay   PetscFunctionBegin;
1656218e575SSatish Balay   PetscFunctionReturn(0);
1666218e575SSatish Balay }
1676218e575SSatish Balay 
1686218e575SSatish Balay EXTERN_C_BEGIN
1696218e575SSatish Balay #undef __FUNCT__
1706218e575SSatish Balay #define __FUNCT__ "PCCreate_TFS"
17194c0dd61SBarry Smith /*MC
17294c0dd61SBarry Smith      PCTFS - A parallel direct solver intended for problems with very few unknowns (like the
17394c0dd61SBarry Smith          coarse grid in multigrid).
17494c0dd61SBarry Smith 
17594c0dd61SBarry Smith    Implemented by  Henry M. Tufo III and Paul Fischer
17694c0dd61SBarry Smith 
17794c0dd61SBarry Smith    Level: beginner
17894c0dd61SBarry Smith 
17994c0dd61SBarry Smith    Notes: Only implemented for the MPIAIJ matrices
18094c0dd61SBarry Smith 
18194c0dd61SBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC
18294c0dd61SBarry Smith M*/
1837087cfbeSBarry Smith PetscErrorCode  PCCreate_TFS(PC pc)
1846218e575SSatish Balay {
1856218e575SSatish Balay   PetscErrorCode ierr;
1866218e575SSatish Balay   PC_TFS         *tfs;
1876218e575SSatish Balay 
1886218e575SSatish Balay   PetscFunctionBegin;
18938f2d2fdSLisandro Dalcin   ierr = PetscNewLog(pc,PC_TFS,&tfs);CHKERRQ(ierr);
1906218e575SSatish Balay 
1916218e575SSatish Balay   tfs->xxt = 0;
1926218e575SSatish Balay   tfs->xyt = 0;
1936218e575SSatish Balay   tfs->b   = 0;
1946218e575SSatish Balay   tfs->xd  = 0;
1956218e575SSatish Balay   tfs->xo  = 0;
1966218e575SSatish Balay   tfs->nd  = 0;
1976218e575SSatish Balay 
1986218e575SSatish Balay   pc->ops->apply               = 0;
1996218e575SSatish Balay   pc->ops->applytranspose      = 0;
2006218e575SSatish Balay   pc->ops->setup               = PCSetUp_TFS;
2016218e575SSatish Balay   pc->ops->destroy             = PCDestroy_TFS;
2026218e575SSatish Balay   pc->ops->setfromoptions      = PCSetFromOptions_TFS;
2036218e575SSatish Balay   pc->ops->view                = PCView_TFS;
2046218e575SSatish Balay   pc->ops->applyrichardson     = 0;
2056218e575SSatish Balay   pc->ops->applysymmetricleft  = 0;
2066218e575SSatish Balay   pc->ops->applysymmetricright = 0;
2076218e575SSatish Balay   pc->data                     = (void*)tfs;
2086218e575SSatish Balay   PetscFunctionReturn(0);
2096218e575SSatish Balay }
2106218e575SSatish Balay EXTERN_C_END
2116218e575SSatish Balay 
212