xref: /petsc/src/ksp/pc/impls/tfs/tfs.c (revision 2c71b3e237ead271e4f3aa1505f92bf476e3413d)
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 PetscErrorCode PCDestroy_TFS(PC pc)
176218e575SSatish Balay {
186218e575SSatish Balay   PC_TFS         *tfs = (PC_TFS*)pc->data;
196218e575SSatish Balay   PetscErrorCode ierr;
206218e575SSatish Balay 
216218e575SSatish Balay   PetscFunctionBegin;
226218e575SSatish Balay   /* free the XXT datastructures */
236218e575SSatish Balay   if (tfs->xxt) {
246218e575SSatish Balay     ierr = XXT_free(tfs->xxt);CHKERRQ(ierr);
256218e575SSatish Balay   }
266218e575SSatish Balay   if (tfs->xyt) {
276218e575SSatish Balay     ierr = XYT_free(tfs->xyt);CHKERRQ(ierr);
286218e575SSatish Balay   }
296bf464f9SBarry Smith   ierr = VecDestroy(&tfs->b);CHKERRQ(ierr);
306bf464f9SBarry Smith   ierr = VecDestroy(&tfs->xd);CHKERRQ(ierr);
316bf464f9SBarry Smith   ierr = VecDestroy(&tfs->xo);CHKERRQ(ierr);
32c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
336218e575SSatish Balay   PetscFunctionReturn(0);
346218e575SSatish Balay }
356218e575SSatish Balay 
366218e575SSatish Balay static PetscErrorCode PCApply_TFS_XXT(PC pc,Vec x,Vec y)
376218e575SSatish Balay {
386218e575SSatish Balay   PC_TFS            *tfs = (PC_TFS*)pc->data;
393468409bSBarry Smith   PetscScalar       *yy;
403468409bSBarry Smith   const PetscScalar *xx;
416218e575SSatish Balay   PetscErrorCode    ierr;
426218e575SSatish Balay 
436218e575SSatish Balay   PetscFunctionBegin;
443468409bSBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
456218e575SSatish Balay   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
463468409bSBarry Smith   ierr = XXT_solve(tfs->xxt,yy,(PetscScalar*)xx);CHKERRQ(ierr);
473468409bSBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
486218e575SSatish Balay   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
496218e575SSatish Balay   PetscFunctionReturn(0);
506218e575SSatish Balay }
516218e575SSatish Balay 
526218e575SSatish Balay static PetscErrorCode PCApply_TFS_XYT(PC pc,Vec x,Vec y)
536218e575SSatish Balay {
546218e575SSatish Balay   PC_TFS            *tfs = (PC_TFS*)pc->data;
553468409bSBarry Smith   PetscScalar       *yy;
563468409bSBarry Smith   const PetscScalar *xx;
576218e575SSatish Balay   PetscErrorCode    ierr;
586218e575SSatish Balay 
596218e575SSatish Balay   PetscFunctionBegin;
603468409bSBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
616218e575SSatish Balay   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
623468409bSBarry Smith   ierr = XYT_solve(tfs->xyt,yy,(PetscScalar*)xx);CHKERRQ(ierr);
633468409bSBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
646218e575SSatish Balay   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
656218e575SSatish Balay   PetscFunctionReturn(0);
666218e575SSatish Balay }
676218e575SSatish Balay 
68fe05c926SBarry Smith static PetscErrorCode PCTFSLocalMult_TFS(PC pc,PetscScalar *xin,PetscScalar *xout)
696218e575SSatish Balay {
706218e575SSatish Balay   PC_TFS         *tfs = (PC_TFS*)pc->data;
716218e575SSatish Balay   Mat            A    = pc->pmat;
726218e575SSatish Balay   Mat_MPIAIJ     *a   = (Mat_MPIAIJ*)A->data;
736218e575SSatish Balay   PetscErrorCode ierr;
746218e575SSatish Balay 
756218e575SSatish Balay   PetscFunctionBegin;
766218e575SSatish Balay   ierr = VecPlaceArray(tfs->b,xout);CHKERRQ(ierr);
776218e575SSatish Balay   ierr = VecPlaceArray(tfs->xd,xin);CHKERRQ(ierr);
786218e575SSatish Balay   ierr = VecPlaceArray(tfs->xo,xin+tfs->nd);CHKERRQ(ierr);
796218e575SSatish Balay   ierr = MatMult(a->A,tfs->xd,tfs->b);CHKERRQ(ierr);
806218e575SSatish Balay   ierr = MatMultAdd(a->B,tfs->xo,tfs->b,tfs->b);CHKERRQ(ierr);
81026a3f60SBarry Smith   ierr = VecResetArray(tfs->b);CHKERRQ(ierr);
82026a3f60SBarry Smith   ierr = VecResetArray(tfs->xd);CHKERRQ(ierr);
83026a3f60SBarry Smith   ierr = VecResetArray(tfs->xo);CHKERRQ(ierr);
846218e575SSatish Balay   PetscFunctionReturn(0);
856218e575SSatish Balay }
866218e575SSatish Balay 
876218e575SSatish Balay static PetscErrorCode PCSetUp_TFS(PC pc)
886218e575SSatish Balay {
896218e575SSatish Balay   PC_TFS         *tfs = (PC_TFS*)pc->data;
906218e575SSatish Balay   Mat            A    = pc->pmat;
916218e575SSatish Balay   Mat_MPIAIJ     *a   = (Mat_MPIAIJ*)A->data;
926218e575SSatish Balay   PetscErrorCode ierr;
936218e575SSatish Balay   PetscInt       *localtoglobal,ncol,i;
94ace3abfcSBarry Smith   PetscBool      ismpiaij;
956218e575SSatish Balay 
966218e575SSatish Balay   /*
97ace3abfcSBarry Smith   PetscBool      issymmetric;
986218e575SSatish Balay   Petsc Real tol = 0.0;
996218e575SSatish Balay   */
1006218e575SSatish Balay 
1016218e575SSatish Balay   PetscFunctionBegin;
102*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(A->cmap->N != A->rmap->N,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_SIZ,"matrix must be square");
103251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr);
104*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!ismpiaij,PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Currently only supports MPIAIJ matrices");
1056218e575SSatish Balay 
1066218e575SSatish Balay   /* generate the local to global mapping */
107d0f46423SBarry Smith   ncol = a->A->cmap->n + a->B->cmap->n;
108854ce69bSBarry Smith   ierr = PetscMalloc1(ncol,&localtoglobal);CHKERRQ(ierr);
1092fa5cd67SKarl Rupp   for (i=0; i<a->A->cmap->n; i++) localtoglobal[i] = A->cmap->rstart + i + 1;
1102fa5cd67SKarl Rupp   for (i=0; i<a->B->cmap->n; i++) localtoglobal[i+a->A->cmap->n] = a->garray[i] + 1;
1112fa5cd67SKarl Rupp 
1126218e575SSatish Balay   /* generate the vectors needed for the local solves */
1130298fd71SBarry Smith   ierr    = VecCreateSeqWithArray(PETSC_COMM_SELF,1,a->A->rmap->n,NULL,&tfs->b);CHKERRQ(ierr);
1140298fd71SBarry Smith   ierr    = VecCreateSeqWithArray(PETSC_COMM_SELF,1,a->A->cmap->n,NULL,&tfs->xd);CHKERRQ(ierr);
1150298fd71SBarry Smith   ierr    = VecCreateSeqWithArray(PETSC_COMM_SELF,1,a->B->cmap->n,NULL,&tfs->xo);CHKERRQ(ierr);
116d0f46423SBarry Smith   tfs->nd = a->A->cmap->n;
1176218e575SSatish Balay 
1186218e575SSatish Balay   /*  ierr =  MatIsSymmetric(A,tol,&issymmetric); */
1196218e575SSatish Balay   /*  if (issymmetric) { */
120585bbf96SBarry Smith   ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr);
1216218e575SSatish Balay   if (A->symmetric) {
1226218e575SSatish Balay     tfs->xxt       = XXT_new();
1235c8f6a95SKarl Rupp     ierr           = XXT_factor(tfs->xxt,localtoglobal,A->rmap->n,ncol,(PetscErrorCode (*)(void*,PetscScalar*,PetscScalar*))PCTFSLocalMult_TFS,pc);CHKERRQ(ierr);
1246218e575SSatish Balay     pc->ops->apply = PCApply_TFS_XXT;
1256218e575SSatish Balay   } else {
1266218e575SSatish Balay     tfs->xyt       = XYT_new();
1275c8f6a95SKarl Rupp     ierr           = XYT_factor(tfs->xyt,localtoglobal,A->rmap->n,ncol,(PetscErrorCode (*)(void*,PetscScalar*,PetscScalar*))PCTFSLocalMult_TFS,pc);CHKERRQ(ierr);
1286218e575SSatish Balay     pc->ops->apply = PCApply_TFS_XYT;
1296218e575SSatish Balay   }
1306218e575SSatish Balay 
1316218e575SSatish Balay   ierr = PetscFree(localtoglobal);CHKERRQ(ierr);
1326218e575SSatish Balay   PetscFunctionReturn(0);
1336218e575SSatish Balay }
1346218e575SSatish Balay 
1354416b707SBarry Smith static PetscErrorCode PCSetFromOptions_TFS(PetscOptionItems *PetscOptionsObject,PC pc)
1366218e575SSatish Balay {
1376218e575SSatish Balay   PetscFunctionBegin;
1386218e575SSatish Balay   PetscFunctionReturn(0);
1396218e575SSatish Balay }
1406218e575SSatish Balay static PetscErrorCode PCView_TFS(PC pc,PetscViewer viewer)
1416218e575SSatish Balay {
1426218e575SSatish Balay   PetscFunctionBegin;
1436218e575SSatish Balay   PetscFunctionReturn(0);
1446218e575SSatish Balay }
1456218e575SSatish Balay 
14694c0dd61SBarry Smith /*MC
14794c0dd61SBarry Smith      PCTFS - A parallel direct solver intended for problems with very few unknowns (like the
148a21bf2d2SBarry Smith          coarse grid in multigrid). Performs a Cholesky or LU factorization of a matrix defined by
149a21bf2d2SBarry Smith          its local matrix vector product.
15094c0dd61SBarry Smith 
151a21bf2d2SBarry Smith    Implemented by  Henry M. Tufo III and Paul Fischer originally for Nek5000 and called XXT or XYT
15294c0dd61SBarry Smith 
15394c0dd61SBarry Smith    Level: beginner
15494c0dd61SBarry Smith 
15595452b02SPatrick Sanan    Notes:
15695452b02SPatrick Sanan     Only implemented for the MPIAIJ matrices
15794c0dd61SBarry Smith 
1587773e740SBarry Smith     Only works on a solver object that lives on all of PETSC_COMM_WORLD!
1597773e740SBarry Smith 
160a21bf2d2SBarry Smith     Only works for real numbers (is not built if PetscScalar is complex)
161a21bf2d2SBarry Smith 
16294c0dd61SBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC
16394c0dd61SBarry Smith M*/
1648cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_TFS(PC pc)
1656218e575SSatish Balay {
1666218e575SSatish Balay   PetscErrorCode ierr;
1676218e575SSatish Balay   PC_TFS         *tfs;
1683cd2be91SBarry Smith   PetscMPIInt    cmp;
1696218e575SSatish Balay 
1706218e575SSatish Balay   PetscFunctionBegin;
171ffc4695bSBarry Smith   ierr = MPI_Comm_compare(PETSC_COMM_WORLD,PetscObjectComm((PetscObject)pc),&cmp);CHKERRMPI(ierr);
172*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(cmp != MPI_IDENT && cmp != MPI_CONGRUENT,PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"TFS only works with PETSC_COMM_WORLD objects");
173b00a9115SJed Brown   ierr = PetscNewLog(pc,&tfs);CHKERRQ(ierr);
1746218e575SSatish Balay 
1750a545947SLisandro Dalcin   tfs->xxt = NULL;
1760a545947SLisandro Dalcin   tfs->xyt = NULL;
1770a545947SLisandro Dalcin   tfs->b   = NULL;
1780a545947SLisandro Dalcin   tfs->xd  = NULL;
1790a545947SLisandro Dalcin   tfs->xo  = NULL;
1806218e575SSatish Balay   tfs->nd  = 0;
1816218e575SSatish Balay 
1820a545947SLisandro Dalcin   pc->ops->apply               = NULL;
1830a545947SLisandro Dalcin   pc->ops->applytranspose      = NULL;
1846218e575SSatish Balay   pc->ops->setup               = PCSetUp_TFS;
1856218e575SSatish Balay   pc->ops->destroy             = PCDestroy_TFS;
1866218e575SSatish Balay   pc->ops->setfromoptions      = PCSetFromOptions_TFS;
1876218e575SSatish Balay   pc->ops->view                = PCView_TFS;
1880a545947SLisandro Dalcin   pc->ops->applyrichardson     = NULL;
1890a545947SLisandro Dalcin   pc->ops->applysymmetricleft  = NULL;
1900a545947SLisandro Dalcin   pc->ops->applysymmetricright = NULL;
1916218e575SSatish Balay   pc->data                     = (void*)tfs;
1926218e575SSatish Balay   PetscFunctionReturn(0);
1936218e575SSatish Balay }
1946218e575SSatish Balay 
195