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