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; 102ce94432eSBarry Smith if (A->cmap->N != A->rmap->N) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_SIZ,"matrix must be square"); 103251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 104ce94432eSBarry Smith if (!ismpiaij) SETERRQ(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 1196218e575SSatish Balay /* ierr = MatIsSymmetric(A,tol,&issymmetric); */ 1206218e575SSatish Balay /* if (issymmetric) { */ 121585bbf96SBarry Smith ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 1226218e575SSatish Balay if (A->symmetric) { 1236218e575SSatish Balay tfs->xxt = XXT_new(); 1245c8f6a95SKarl Rupp ierr = XXT_factor(tfs->xxt,localtoglobal,A->rmap->n,ncol,(PetscErrorCode (*)(void*,PetscScalar*,PetscScalar*))PCTFSLocalMult_TFS,pc);CHKERRQ(ierr); 1256218e575SSatish Balay pc->ops->apply = PCApply_TFS_XXT; 1266218e575SSatish Balay } else { 1276218e575SSatish Balay tfs->xyt = XYT_new(); 1285c8f6a95SKarl Rupp ierr = XYT_factor(tfs->xyt,localtoglobal,A->rmap->n,ncol,(PetscErrorCode (*)(void*,PetscScalar*,PetscScalar*))PCTFSLocalMult_TFS,pc);CHKERRQ(ierr); 1296218e575SSatish Balay pc->ops->apply = PCApply_TFS_XYT; 1306218e575SSatish Balay } 1316218e575SSatish Balay 1326218e575SSatish Balay ierr = PetscFree(localtoglobal);CHKERRQ(ierr); 1336218e575SSatish Balay PetscFunctionReturn(0); 1346218e575SSatish Balay } 1356218e575SSatish Balay 1364416b707SBarry Smith static PetscErrorCode PCSetFromOptions_TFS(PetscOptionItems *PetscOptionsObject,PC pc) 1376218e575SSatish Balay { 1386218e575SSatish Balay PetscFunctionBegin; 1396218e575SSatish Balay PetscFunctionReturn(0); 1406218e575SSatish Balay } 1416218e575SSatish Balay static PetscErrorCode PCView_TFS(PC pc,PetscViewer viewer) 1426218e575SSatish Balay { 1436218e575SSatish Balay PetscFunctionBegin; 1446218e575SSatish Balay PetscFunctionReturn(0); 1456218e575SSatish Balay } 1466218e575SSatish Balay 14794c0dd61SBarry Smith /*MC 14894c0dd61SBarry Smith PCTFS - A parallel direct solver intended for problems with very few unknowns (like the 14994c0dd61SBarry Smith coarse grid in multigrid). 15094c0dd61SBarry Smith 15194c0dd61SBarry Smith Implemented by Henry M. Tufo III and Paul Fischer 15294c0dd61SBarry Smith 15394c0dd61SBarry Smith Level: beginner 15494c0dd61SBarry Smith 155*95452b02SPatrick Sanan Notes: 156*95452b02SPatrick 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 16094c0dd61SBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC 16194c0dd61SBarry Smith M*/ 1628cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_TFS(PC pc) 1636218e575SSatish Balay { 1646218e575SSatish Balay PetscErrorCode ierr; 1656218e575SSatish Balay PC_TFS *tfs; 1663cd2be91SBarry Smith PetscMPIInt cmp; 1676218e575SSatish Balay 1686218e575SSatish Balay PetscFunctionBegin; 169ce94432eSBarry Smith ierr = MPI_Comm_compare(PETSC_COMM_WORLD,PetscObjectComm((PetscObject)pc),&cmp);CHKERRQ(ierr); 170ce94432eSBarry Smith if (cmp != MPI_IDENT && cmp != MPI_CONGRUENT) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"TFS only works with PETSC_COMM_WORLD objects"); 171b00a9115SJed Brown ierr = PetscNewLog(pc,&tfs);CHKERRQ(ierr); 1726218e575SSatish Balay 1736218e575SSatish Balay tfs->xxt = 0; 1746218e575SSatish Balay tfs->xyt = 0; 1756218e575SSatish Balay tfs->b = 0; 1766218e575SSatish Balay tfs->xd = 0; 1776218e575SSatish Balay tfs->xo = 0; 1786218e575SSatish Balay tfs->nd = 0; 1796218e575SSatish Balay 1806218e575SSatish Balay pc->ops->apply = 0; 1816218e575SSatish Balay pc->ops->applytranspose = 0; 1826218e575SSatish Balay pc->ops->setup = PCSetUp_TFS; 1836218e575SSatish Balay pc->ops->destroy = PCDestroy_TFS; 1846218e575SSatish Balay pc->ops->setfromoptions = PCSetFromOptions_TFS; 1856218e575SSatish Balay pc->ops->view = PCView_TFS; 1866218e575SSatish Balay pc->ops->applyrichardson = 0; 1876218e575SSatish Balay pc->ops->applysymmetricleft = 0; 1886218e575SSatish Balay pc->ops->applysymmetricright = 0; 1896218e575SSatish Balay pc->data = (void*)tfs; 1906218e575SSatish Balay PetscFunctionReturn(0); 1916218e575SSatish Balay } 1926218e575SSatish Balay 193