xref: /petsc/src/ksp/pc/impls/tfs/tfs.c (revision b94d7ded0a05f1bbd5e48daa6f92b28259c75b44)
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 
206218e575SSatish Balay   PetscFunctionBegin;
216218e575SSatish Balay   /* free the XXT datastructures */
221baa6e33SBarry Smith   if (tfs->xxt) PetscCall(XXT_free(tfs->xxt));
231baa6e33SBarry Smith   if (tfs->xyt) PetscCall(XYT_free(tfs->xyt));
249566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&tfs->b));
259566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&tfs->xd));
269566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&tfs->xo));
279566063dSJacob Faibussowitsch   PetscCall(PetscFree(pc->data));
286218e575SSatish Balay   PetscFunctionReturn(0);
296218e575SSatish Balay }
306218e575SSatish Balay 
316218e575SSatish Balay static PetscErrorCode PCApply_TFS_XXT(PC pc,Vec x,Vec y)
326218e575SSatish Balay {
336218e575SSatish Balay   PC_TFS            *tfs = (PC_TFS*)pc->data;
343468409bSBarry Smith   PetscScalar       *yy;
353468409bSBarry Smith   const PetscScalar *xx;
366218e575SSatish Balay 
376218e575SSatish Balay   PetscFunctionBegin;
389566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(x,&xx));
399566063dSJacob Faibussowitsch   PetscCall(VecGetArray(y,&yy));
409566063dSJacob Faibussowitsch   PetscCall(XXT_solve(tfs->xxt,yy,(PetscScalar*)xx));
419566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(x,&xx));
429566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(y,&yy));
436218e575SSatish Balay   PetscFunctionReturn(0);
446218e575SSatish Balay }
456218e575SSatish Balay 
466218e575SSatish Balay static PetscErrorCode PCApply_TFS_XYT(PC pc,Vec x,Vec y)
476218e575SSatish Balay {
486218e575SSatish Balay   PC_TFS            *tfs = (PC_TFS*)pc->data;
493468409bSBarry Smith   PetscScalar       *yy;
503468409bSBarry Smith   const PetscScalar *xx;
516218e575SSatish Balay 
526218e575SSatish Balay   PetscFunctionBegin;
539566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(x,&xx));
549566063dSJacob Faibussowitsch   PetscCall(VecGetArray(y,&yy));
559566063dSJacob Faibussowitsch   PetscCall(XYT_solve(tfs->xyt,yy,(PetscScalar*)xx));
569566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(x,&xx));
579566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(y,&yy));
586218e575SSatish Balay   PetscFunctionReturn(0);
596218e575SSatish Balay }
606218e575SSatish Balay 
61fe05c926SBarry Smith static PetscErrorCode PCTFSLocalMult_TFS(PC pc,PetscScalar *xin,PetscScalar *xout)
626218e575SSatish Balay {
636218e575SSatish Balay   PC_TFS         *tfs = (PC_TFS*)pc->data;
646218e575SSatish Balay   Mat            A    = pc->pmat;
656218e575SSatish Balay   Mat_MPIAIJ     *a   = (Mat_MPIAIJ*)A->data;
666218e575SSatish Balay 
676218e575SSatish Balay   PetscFunctionBegin;
689566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(tfs->b,xout));
699566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(tfs->xd,xin));
709566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(tfs->xo,xin+tfs->nd));
719566063dSJacob Faibussowitsch   PetscCall(MatMult(a->A,tfs->xd,tfs->b));
729566063dSJacob Faibussowitsch   PetscCall(MatMultAdd(a->B,tfs->xo,tfs->b,tfs->b));
739566063dSJacob Faibussowitsch   PetscCall(VecResetArray(tfs->b));
749566063dSJacob Faibussowitsch   PetscCall(VecResetArray(tfs->xd));
759566063dSJacob Faibussowitsch   PetscCall(VecResetArray(tfs->xo));
766218e575SSatish Balay   PetscFunctionReturn(0);
776218e575SSatish Balay }
786218e575SSatish Balay 
796218e575SSatish Balay static PetscErrorCode PCSetUp_TFS(PC pc)
806218e575SSatish Balay {
816218e575SSatish Balay   PC_TFS         *tfs = (PC_TFS*)pc->data;
826218e575SSatish Balay   Mat            A    = pc->pmat;
836218e575SSatish Balay   Mat_MPIAIJ     *a   = (Mat_MPIAIJ*)A->data;
846218e575SSatish Balay   PetscInt       *localtoglobal,ncol,i;
85ace3abfcSBarry Smith   PetscBool      ismpiaij;
866218e575SSatish Balay 
876218e575SSatish Balay   /*
88ace3abfcSBarry Smith   PetscBool      issymmetric;
896218e575SSatish Balay   Petsc Real tol = 0.0;
906218e575SSatish Balay   */
916218e575SSatish Balay 
926218e575SSatish Balay   PetscFunctionBegin;
9308401ef6SPierre Jolivet   PetscCheck(A->cmap->N == A->rmap->N,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_SIZ,"matrix must be square");
949566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)pc->pmat,MATMPIAIJ,&ismpiaij));
9528b400f6SJacob Faibussowitsch   PetscCheck(ismpiaij,PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Currently only supports MPIAIJ matrices");
966218e575SSatish Balay 
976218e575SSatish Balay   /* generate the local to global mapping */
98d0f46423SBarry Smith   ncol = a->A->cmap->n + a->B->cmap->n;
999566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ncol,&localtoglobal));
1002fa5cd67SKarl Rupp   for (i=0; i<a->A->cmap->n; i++) localtoglobal[i] = A->cmap->rstart + i + 1;
1012fa5cd67SKarl Rupp   for (i=0; i<a->B->cmap->n; i++) localtoglobal[i+a->A->cmap->n] = a->garray[i] + 1;
1022fa5cd67SKarl Rupp 
1036218e575SSatish Balay   /* generate the vectors needed for the local solves */
1049566063dSJacob Faibussowitsch   PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF,1,a->A->rmap->n,NULL,&tfs->b));
1059566063dSJacob Faibussowitsch   PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF,1,a->A->cmap->n,NULL,&tfs->xd));
1069566063dSJacob Faibussowitsch   PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF,1,a->B->cmap->n,NULL,&tfs->xo));
107d0f46423SBarry Smith   tfs->nd = a->A->cmap->n;
1086218e575SSatish Balay 
1096218e575SSatish Balay   /*  ierr =  MatIsSymmetric(A,tol,&issymmetric); */
1106218e575SSatish Balay   /*  if (issymmetric) { */
1119566063dSJacob Faibussowitsch   PetscCall(PetscBarrier((PetscObject)pc));
112*b94d7dedSBarry Smith   if (A->symmetric == PETSC_BOOL3_TRUE) {
1136218e575SSatish Balay     tfs->xxt       = XXT_new();
1149566063dSJacob Faibussowitsch     PetscCall(XXT_factor(tfs->xxt,localtoglobal,A->rmap->n,ncol,(PetscErrorCode (*)(void*,PetscScalar*,PetscScalar*))PCTFSLocalMult_TFS,pc));
1156218e575SSatish Balay     pc->ops->apply = PCApply_TFS_XXT;
1166218e575SSatish Balay   } else {
1176218e575SSatish Balay     tfs->xyt       = XYT_new();
1189566063dSJacob Faibussowitsch     PetscCall(XYT_factor(tfs->xyt,localtoglobal,A->rmap->n,ncol,(PetscErrorCode (*)(void*,PetscScalar*,PetscScalar*))PCTFSLocalMult_TFS,pc));
1196218e575SSatish Balay     pc->ops->apply = PCApply_TFS_XYT;
1206218e575SSatish Balay   }
1216218e575SSatish Balay 
1229566063dSJacob Faibussowitsch   PetscCall(PetscFree(localtoglobal));
1236218e575SSatish Balay   PetscFunctionReturn(0);
1246218e575SSatish Balay }
1256218e575SSatish Balay 
1264416b707SBarry Smith static PetscErrorCode PCSetFromOptions_TFS(PetscOptionItems *PetscOptionsObject,PC pc)
1276218e575SSatish Balay {
1286218e575SSatish Balay   PetscFunctionBegin;
1296218e575SSatish Balay   PetscFunctionReturn(0);
1306218e575SSatish Balay }
1316218e575SSatish Balay static PetscErrorCode PCView_TFS(PC pc,PetscViewer viewer)
1326218e575SSatish Balay {
1336218e575SSatish Balay   PetscFunctionBegin;
1346218e575SSatish Balay   PetscFunctionReturn(0);
1356218e575SSatish Balay }
1366218e575SSatish Balay 
13794c0dd61SBarry Smith /*MC
13894c0dd61SBarry Smith      PCTFS - A parallel direct solver intended for problems with very few unknowns (like the
139a21bf2d2SBarry Smith          coarse grid in multigrid). Performs a Cholesky or LU factorization of a matrix defined by
140a21bf2d2SBarry Smith          its local matrix vector product.
14194c0dd61SBarry Smith 
142a21bf2d2SBarry Smith    Implemented by  Henry M. Tufo III and Paul Fischer originally for Nek5000 and called XXT or XYT
14394c0dd61SBarry Smith 
14494c0dd61SBarry Smith    Level: beginner
14594c0dd61SBarry Smith 
14695452b02SPatrick Sanan    Notes:
14795452b02SPatrick Sanan     Only implemented for the MPIAIJ matrices
14894c0dd61SBarry Smith 
1497773e740SBarry Smith     Only works on a solver object that lives on all of PETSC_COMM_WORLD!
1507773e740SBarry Smith 
151a21bf2d2SBarry Smith     Only works for real numbers (is not built if PetscScalar is complex)
152a21bf2d2SBarry Smith 
153db781477SPatrick Sanan .seealso: `PCCreate()`, `PCSetType()`, `PCType`, `PC`
15494c0dd61SBarry Smith M*/
1558cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_TFS(PC pc)
1566218e575SSatish Balay {
1576218e575SSatish Balay   PC_TFS         *tfs;
1583cd2be91SBarry Smith   PetscMPIInt    cmp;
1596218e575SSatish Balay 
1606218e575SSatish Balay   PetscFunctionBegin;
1619566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_compare(PETSC_COMM_WORLD,PetscObjectComm((PetscObject)pc),&cmp));
1622472a847SBarry Smith   PetscCheck(cmp == MPI_IDENT || cmp == MPI_CONGRUENT,PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"TFS only works with PETSC_COMM_WORLD objects");
1639566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(pc,&tfs));
1646218e575SSatish Balay 
1650a545947SLisandro Dalcin   tfs->xxt = NULL;
1660a545947SLisandro Dalcin   tfs->xyt = NULL;
1670a545947SLisandro Dalcin   tfs->b   = NULL;
1680a545947SLisandro Dalcin   tfs->xd  = NULL;
1690a545947SLisandro Dalcin   tfs->xo  = NULL;
1706218e575SSatish Balay   tfs->nd  = 0;
1716218e575SSatish Balay 
1720a545947SLisandro Dalcin   pc->ops->apply               = NULL;
1730a545947SLisandro Dalcin   pc->ops->applytranspose      = NULL;
1746218e575SSatish Balay   pc->ops->setup               = PCSetUp_TFS;
1756218e575SSatish Balay   pc->ops->destroy             = PCDestroy_TFS;
1766218e575SSatish Balay   pc->ops->setfromoptions      = PCSetFromOptions_TFS;
1776218e575SSatish Balay   pc->ops->view                = PCView_TFS;
1780a545947SLisandro Dalcin   pc->ops->applyrichardson     = NULL;
1790a545947SLisandro Dalcin   pc->ops->applysymmetricleft  = NULL;
1800a545947SLisandro Dalcin   pc->ops->applysymmetricright = NULL;
1816218e575SSatish Balay   pc->data                     = (void*)tfs;
1826218e575SSatish Balay   PetscFunctionReturn(0);
1836218e575SSatish Balay }
184