16218e575SSatish Balay /* 26218e575SSatish Balay Provides an interface to the Tufo-Fischer parallel direct solver 36218e575SSatish Balay */ 46218e575SSatish Balay 5b45d2f2cSJed Brown #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; 436218e575SSatish Balay PetscScalar *xx,*yy; 446218e575SSatish Balay PetscErrorCode ierr; 456218e575SSatish Balay 466218e575SSatish Balay PetscFunctionBegin; 476218e575SSatish Balay ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 486218e575SSatish Balay ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 496218e575SSatish Balay ierr = XXT_solve(tfs->xxt,yy,xx);CHKERRQ(ierr); 506218e575SSatish Balay ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 516218e575SSatish Balay ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 526218e575SSatish Balay PetscFunctionReturn(0); 536218e575SSatish Balay } 546218e575SSatish Balay 556218e575SSatish Balay #undef __FUNCT__ 566218e575SSatish Balay #define __FUNCT__ "PCApply_TFS_XYT" 576218e575SSatish Balay static PetscErrorCode PCApply_TFS_XYT(PC pc,Vec x,Vec y) 586218e575SSatish Balay { 596218e575SSatish Balay PC_TFS *tfs = (PC_TFS*)pc->data; 606218e575SSatish Balay PetscScalar *xx,*yy; 616218e575SSatish Balay PetscErrorCode ierr; 626218e575SSatish Balay 636218e575SSatish Balay PetscFunctionBegin; 646218e575SSatish Balay ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 656218e575SSatish Balay ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 666218e575SSatish Balay ierr = XYT_solve(tfs->xyt,yy,xx);CHKERRQ(ierr); 676218e575SSatish Balay ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 686218e575SSatish Balay ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 696218e575SSatish Balay PetscFunctionReturn(0); 706218e575SSatish Balay } 716218e575SSatish Balay 726218e575SSatish Balay #undef __FUNCT__ 73fe05c926SBarry Smith #define __FUNCT__ "PCTFSLocalMult_TFS" 74fe05c926SBarry Smith static PetscErrorCode PCTFSLocalMult_TFS(PC pc,PetscScalar *xin,PetscScalar *xout) 756218e575SSatish Balay { 766218e575SSatish Balay PC_TFS *tfs = (PC_TFS*)pc->data; 776218e575SSatish Balay Mat A = pc->pmat; 786218e575SSatish Balay Mat_MPIAIJ *a = (Mat_MPIAIJ*)A->data; 796218e575SSatish Balay PetscErrorCode ierr; 806218e575SSatish Balay 816218e575SSatish Balay PetscFunctionBegin; 826218e575SSatish Balay ierr = VecPlaceArray(tfs->b,xout);CHKERRQ(ierr); 836218e575SSatish Balay ierr = VecPlaceArray(tfs->xd,xin);CHKERRQ(ierr); 846218e575SSatish Balay ierr = VecPlaceArray(tfs->xo,xin+tfs->nd);CHKERRQ(ierr); 856218e575SSatish Balay ierr = MatMult(a->A,tfs->xd,tfs->b);CHKERRQ(ierr); 866218e575SSatish Balay ierr = MatMultAdd(a->B,tfs->xo,tfs->b,tfs->b);CHKERRQ(ierr); 87026a3f60SBarry Smith ierr = VecResetArray(tfs->b);CHKERRQ(ierr); 88026a3f60SBarry Smith ierr = VecResetArray(tfs->xd);CHKERRQ(ierr); 89026a3f60SBarry Smith ierr = VecResetArray(tfs->xo);CHKERRQ(ierr); 906218e575SSatish Balay PetscFunctionReturn(0); 916218e575SSatish Balay } 926218e575SSatish Balay 936218e575SSatish Balay #undef __FUNCT__ 946218e575SSatish Balay #define __FUNCT__ "PCSetUp_TFS" 956218e575SSatish Balay static PetscErrorCode PCSetUp_TFS(PC pc) 966218e575SSatish Balay { 976218e575SSatish Balay PC_TFS *tfs = (PC_TFS*)pc->data; 986218e575SSatish Balay Mat A = pc->pmat; 996218e575SSatish Balay Mat_MPIAIJ *a = (Mat_MPIAIJ*)A->data; 1006218e575SSatish Balay PetscErrorCode ierr; 1016218e575SSatish Balay PetscInt *localtoglobal,ncol,i; 102ace3abfcSBarry Smith PetscBool ismpiaij; 1036218e575SSatish Balay 1046218e575SSatish Balay /* 105ace3abfcSBarry Smith PetscBool issymmetric; 1066218e575SSatish Balay Petsc Real tol = 0.0; 1076218e575SSatish Balay */ 1086218e575SSatish Balay 1096218e575SSatish Balay PetscFunctionBegin; 110ce94432eSBarry Smith if (A->cmap->N != A->rmap->N) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_SIZ,"matrix must be square"); 111251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 112ce94432eSBarry Smith if (!ismpiaij) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Currently only supports MPIAIJ matrices"); 1136218e575SSatish Balay 1146218e575SSatish Balay /* generate the local to global mapping */ 115d0f46423SBarry Smith ncol = a->A->cmap->n + a->B->cmap->n; 11652f87cdaSBarry Smith ierr = PetscMalloc((ncol)*sizeof(PetscInt),&localtoglobal);CHKERRQ(ierr); 1172fa5cd67SKarl Rupp for (i=0; i<a->A->cmap->n; i++) localtoglobal[i] = A->cmap->rstart + i + 1; 1182fa5cd67SKarl Rupp for (i=0; i<a->B->cmap->n; i++) localtoglobal[i+a->A->cmap->n] = a->garray[i] + 1; 1192fa5cd67SKarl Rupp 1206218e575SSatish Balay /* generate the vectors needed for the local solves */ 1210298fd71SBarry Smith ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,a->A->rmap->n,NULL,&tfs->b);CHKERRQ(ierr); 1220298fd71SBarry Smith ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,a->A->cmap->n,NULL,&tfs->xd);CHKERRQ(ierr); 1230298fd71SBarry Smith ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,a->B->cmap->n,NULL,&tfs->xo);CHKERRQ(ierr); 124d0f46423SBarry Smith tfs->nd = a->A->cmap->n; 1256218e575SSatish Balay 1266218e575SSatish Balay 1276218e575SSatish Balay /* ierr = MatIsSymmetric(A,tol,&issymmetric); */ 1286218e575SSatish Balay /* if (issymmetric) { */ 129585bbf96SBarry Smith ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 1306218e575SSatish Balay if (A->symmetric) { 1316218e575SSatish Balay tfs->xxt = XXT_new(); 1325c8f6a95SKarl Rupp ierr = XXT_factor(tfs->xxt,localtoglobal,A->rmap->n,ncol,(PetscErrorCode (*)(void*,PetscScalar*,PetscScalar*))PCTFSLocalMult_TFS,pc);CHKERRQ(ierr); 1336218e575SSatish Balay pc->ops->apply = PCApply_TFS_XXT; 1346218e575SSatish Balay } else { 1356218e575SSatish Balay tfs->xyt = XYT_new(); 1365c8f6a95SKarl Rupp ierr = XYT_factor(tfs->xyt,localtoglobal,A->rmap->n,ncol,(PetscErrorCode (*)(void*,PetscScalar*,PetscScalar*))PCTFSLocalMult_TFS,pc);CHKERRQ(ierr); 1376218e575SSatish Balay pc->ops->apply = PCApply_TFS_XYT; 1386218e575SSatish Balay } 1396218e575SSatish Balay 1406218e575SSatish Balay ierr = PetscFree(localtoglobal);CHKERRQ(ierr); 1416218e575SSatish Balay PetscFunctionReturn(0); 1426218e575SSatish Balay } 1436218e575SSatish Balay 1446218e575SSatish Balay #undef __FUNCT__ 1456218e575SSatish Balay #define __FUNCT__ "PCSetFromOptions_TFS" 1466218e575SSatish Balay static PetscErrorCode PCSetFromOptions_TFS(PC pc) 1476218e575SSatish Balay { 1486218e575SSatish Balay PetscFunctionBegin; 1496218e575SSatish Balay PetscFunctionReturn(0); 1506218e575SSatish Balay } 1516218e575SSatish Balay #undef __FUNCT__ 1526218e575SSatish Balay #define __FUNCT__ "PCView_TFS" 1536218e575SSatish Balay static PetscErrorCode PCView_TFS(PC pc,PetscViewer viewer) 1546218e575SSatish Balay { 1556218e575SSatish Balay PetscFunctionBegin; 1566218e575SSatish Balay PetscFunctionReturn(0); 1576218e575SSatish Balay } 1586218e575SSatish Balay 1596218e575SSatish Balay #undef __FUNCT__ 1606218e575SSatish Balay #define __FUNCT__ "PCCreate_TFS" 16194c0dd61SBarry Smith /*MC 16294c0dd61SBarry Smith PCTFS - A parallel direct solver intended for problems with very few unknowns (like the 16394c0dd61SBarry Smith coarse grid in multigrid). 16494c0dd61SBarry Smith 16594c0dd61SBarry Smith Implemented by Henry M. Tufo III and Paul Fischer 16694c0dd61SBarry Smith 16794c0dd61SBarry Smith Level: beginner 16894c0dd61SBarry Smith 16994c0dd61SBarry Smith Notes: Only implemented for the MPIAIJ matrices 17094c0dd61SBarry Smith 1717773e740SBarry Smith Only works on a solver object that lives on all of PETSC_COMM_WORLD! 1727773e740SBarry Smith 17394c0dd61SBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC 17494c0dd61SBarry Smith M*/ 175*8cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_TFS(PC pc) 1766218e575SSatish Balay { 1776218e575SSatish Balay PetscErrorCode ierr; 1786218e575SSatish Balay PC_TFS *tfs; 1793cd2be91SBarry Smith PetscMPIInt cmp; 1806218e575SSatish Balay 1816218e575SSatish Balay PetscFunctionBegin; 182ce94432eSBarry Smith ierr = MPI_Comm_compare(PETSC_COMM_WORLD,PetscObjectComm((PetscObject)pc),&cmp);CHKERRQ(ierr); 183ce94432eSBarry Smith if (cmp != MPI_IDENT && cmp != MPI_CONGRUENT) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"TFS only works with PETSC_COMM_WORLD objects"); 18438f2d2fdSLisandro Dalcin ierr = PetscNewLog(pc,PC_TFS,&tfs);CHKERRQ(ierr); 1856218e575SSatish Balay 1866218e575SSatish Balay tfs->xxt = 0; 1876218e575SSatish Balay tfs->xyt = 0; 1886218e575SSatish Balay tfs->b = 0; 1896218e575SSatish Balay tfs->xd = 0; 1906218e575SSatish Balay tfs->xo = 0; 1916218e575SSatish Balay tfs->nd = 0; 1926218e575SSatish Balay 1936218e575SSatish Balay pc->ops->apply = 0; 1946218e575SSatish Balay pc->ops->applytranspose = 0; 1956218e575SSatish Balay pc->ops->setup = PCSetUp_TFS; 1966218e575SSatish Balay pc->ops->destroy = PCDestroy_TFS; 1976218e575SSatish Balay pc->ops->setfromoptions = PCSetFromOptions_TFS; 1986218e575SSatish Balay pc->ops->view = PCView_TFS; 1996218e575SSatish Balay pc->ops->applyrichardson = 0; 2006218e575SSatish Balay pc->ops->applysymmetricleft = 0; 2016218e575SSatish Balay pc->ops->applysymmetricright = 0; 2026218e575SSatish Balay pc->data = (void*)tfs; 2036218e575SSatish Balay PetscFunctionReturn(0); 2046218e575SSatish Balay } 2056218e575SSatish Balay 206