diff options
Diffstat (limited to 'src/petsc_flat_solver.c')
-rw-r--r-- | src/petsc_flat_solver.c | 251 |
1 files changed, 164 insertions, 87 deletions
diff --git a/src/petsc_flat_solver.c b/src/petsc_flat_solver.c index 74e0216..0a8ec9e 100644 --- a/src/petsc_flat_solver.c +++ b/src/petsc_flat_solver.c @@ -15,8 +15,8 @@ #include "cctk_Parameters.h" #include "mpi.h" -#include "sles.h" - +#include "petscsles.h" +#include "ellpetsc.h" #include "CactusPUGH/PUGH/src/include/pugh.h" static const char *rcsid = "$Header$"; @@ -48,7 +48,8 @@ static SLES sles; /* linear solver context */ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, - int *AbsTol, int *RelTol) { + int *AbsTol, int *RelTol) +{ DECLARE_CCTK_PARAMETERS /* CCTK passed parameters */ @@ -105,10 +106,6 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, /* flags to signal if storage is ON or OFF (used/not-used) for M/N*/ int Mstorage=0, Nstorage=0; - - - - octant = CCTK_Equals(domain,"octant"); verbose = CCTK_Equals(petsc_verbose,"yes")|| CCTK_Equals(petsc_verbose,"debug"); @@ -122,14 +119,18 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, /* Get the link to pugh Extension */ pughGH = (pGH*)GH->extensions[CCTK_GHExtensionHandle("PUGH")]; - if (!pughGH) CCTK_WARN(0,"ETERNAL ERROR: Cannot find PUGH Extension Handle\n"); + if (!pughGH) + { + CCTK_WARN(0,"ETERNAL ERROR: Cannot find PUGH Extension Handle"); + } /* Get the extras extension for 3D grid functions */ pEx = pughGH->GFExtras[2]; pCon = pughGH->Connectivity[2]; /* Things to do on first iteration */ - if (trips==0) { + if (trips==0) + { int argc; char **argv; @@ -139,7 +140,7 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, #endif argc = CCTK_CommandLine(&argv); - ierr = PetscSetCommWorld(pughGH->PUGH_COMM_WORLD); CHKERRA(ierr); + ierr = PetscSetCommWorld(pughGH->PUGH_COMM_WORLD); CHKERRQ(ierr); PetscInitialize(&argc,&argv,NULL,NULL); CCTK_INFO("PETSc initialized"); @@ -157,11 +158,13 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, /* if we have a negative index, this GF is not needed, there for don't even look for it. when index positive, set flag Mstorage=1, dito for N */ - if (MIndex>=0) { + if (MIndex>=0) + { Mlin = (CCTK_REAL*) CCTK_VarDataPtrI(GH,0,MIndex); Mstorage = 1; } - if (NIndex>=0) { + if (NIndex>=0) + { Nlin = (CCTK_REAL*) CCTK_VarDataPtrI(GH,0,NIndex); Nstorage = 1; } @@ -171,7 +174,10 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, /* initialize the linear index lookup table with -1; this will indicate a boudary later */ - for (i=0;i<pEx->npoints;i++) wsp[i] = -1.0; + for (i=0;i<pEx->npoints;i++) + { + wsp[i] = -1.0; + } /* Get myproc from the CCTK, get the gridspacing */ myproc = PUGH_MyProc(GH); @@ -199,7 +205,8 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, (we use PUGH's "rn" variables (number of gp on proc[#] in direction [i]) and subtract the ghostzones if nec.) */ - for (i=0;i<myproc;i++) { + for (i=0;i<myproc;i++) + { nxs=pEx->rnsize[i][0]; nxs=((pCon->neighbours[i][XDM]<0) && !(octant) ? nxs-1 : @@ -241,7 +248,10 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, do a sync that means each processor knows the indiced in the ghost zones (eg, on its neighbors) in a FD stencil of 1 */ retcode = PUGH_SyncGroup(GH,"ellpetsc::petscworkspace"); - if (retcode<0) CCTK_WARN(1,"Synchronization failed\n"); + if (retcode<0) + { + CCTK_WARN(1,"Synchronization failed"); + } /* So woohoo. Now for each point in our ijk space, we have information about our row in the matrix (workspace->data[ijk]) @@ -253,7 +263,8 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, nzs = pEx->nsize[2]-2; #ifdef DEBUG - if (debug) { + if (debug) + { printf("nxyzs %d %d %d \n",nxs,nys,nzs); printf("lnxyz: %d %d %d \n",pEx->lnsize[0],pEx->lnsize[1],pEx->lnsize[2]); } @@ -291,23 +302,24 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, 19,PETSC_NULL, /* Diagonal */ 19,PETSC_NULL, /* Off diagonal */ &A[0]); /* The output */ - CHKERRA(ierr); + CHKERRQ(ierr); ierr = VecCreateMPI(pughGH->PUGH_COMM_WORLD,(endpoint-startpoint),rank,&soln); - CHKERRA(ierr); + CHKERRQ(ierr); ierr = VecCreateMPI(pughGH->PUGH_COMM_WORLD,(endpoint-startpoint),rank,&b); - CHKERRA(ierr); + CHKERRQ(ierr); /* Compare the PETSc layout to Cactus, this better be a match */ ierr = VecGetOwnershipRange(soln,&pvstart,&pvend); ierr = MatGetOwnershipRange(A[0],&pstart,&pend); - if (debug) { + if (debug) + { printf("CAC M-Layout: %d %d \n",startpoint, endpoint); printf("PET M-Layout: %d %d \n",pstart, pend); printf("PET V-Layout: %d %d \n",pvstart,pvend); } if (pstart != startpoint && pend != endpoint) - CCTK_WARN(1,"WARNING: PETSC and data layouts differ! (why??)\n"); + CCTK_WARN(1,"WARNING: PETSC and data layouts differ! (why??)"); /* Initialize the stencil array */ @@ -321,11 +333,15 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, a( 0, 0,-1) = 1.0; /* ab */ - for (k=kmin;k<kmax;k++) { - for (j=jmin;j<jmax;j++) { - for (i=imin;i<imax;i++) { + for (k=kmin;k<kmax;k++) + { + for (j=jmin;j<jmax;j++) + { + for (i=imin;i<imax;i++) + { - if (wsp[DATINDEX(pEx,i,j,k)] >= 0) { + if (wsp[DATINDEX(pEx,i,j,k)] >= 0) + { /* Set up indices */ int ijk; /* The lineax index for the array */ @@ -342,16 +358,27 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, I = wsp[ijk]; /* M phi */ - if (Mstorage) a(0,0,0) = a(0,0,0) + Mlin[ijk]; + if (Mstorage) + { + a(0,0,0) = a(0,0,0) + Mlin[ijk]; + } - /* Great now set the values of the matrix. Here we force dirichlet. */ + /* Now set the values of the matrix. Here we force dirichlet. */ VecSetValues(soln,1,&I,&(ell_field[ijk]),INSERT_VALUES); #ifdef DEBUG - if (ijk==1918) { + if (ijk==1918) + { for (l=-1;l<=1;l++) + { for (m=-1;m<=1;m++) - for (n=-1;n<=1;n++) printf(" (%d %d %d): %f \n",l,m,n,a(l,m,n)); + { + for (n=-1;n<=1;n++) + { + printf(" (%d %d %d): %f \n",l,m,n,a(l,m,n)); + } + } + } printf("\n"); } #endif @@ -376,7 +403,8 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, } /* renormalize */ - if (matnormalize) { + if (matnormalize) + { ac = a(0,0,0); for (J=0;J<27;J++) a[J] = a[J] / ac; } @@ -390,27 +418,37 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, 19-way banded matrix. */ for (l=-1;l<=1;l++) + { for (m=-1;m<=1;m++) - for (n=-1;n<=1;n++) { - if (l*m*n == 0) { /* This is the 19 point ... if none are - * zero, then we have no stencil here. - */ - if (wsp[DATINDEX(pEx,i+l,j+m,k+n)] < 0) { + { + for (n=-1;n<=1;n++) + { + if (l*m*n == 0) + { /* This is the 19 point ... if none are + * zero, then we have no stencil here. + */ + if (wsp[DATINDEX(pEx,i+l,j+m,k+n)] < 0) + { /* This is a boundary. */ rhsval += a(l,m,n) * ell_field[DATINDEX(pEx,i+l,j+m,k+n)]; } - else { + else + { J = wsp[DATINDEX(pEx,i+l,j+m,k+n)]; ierr = MatSetValues(A[0],1,&I,1,&J,&(a(l,m,n)),INSERT_VALUES); - CHKERRA(ierr); + CHKERRQ(ierr); } } } - - if (Nstorage) rhsval = -rhsval - Nlin[ijk] / ac; + } + } + if (Nstorage) + { + rhsval = -rhsval - Nlin[ijk] / ac; + } ierr = VecSetValues(b,1,&I,&rhsval,INSERT_VALUES); - CHKERRA(ierr); + CHKERRQ(ierr); /* reset the central value*/ a( 0, 0, 0) = -6.0; @@ -420,20 +458,29 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, } /* for j */ } /* for k */ - if (verbose) CCTK_INFO ("Assembling the vectors"); - ierr = MatAssemblyBegin(A[0],MAT_FINAL_ASSEMBLY); CHKERRA(ierr); - ierr = VecAssemblyBegin(soln); CHKERRA(ierr); - ierr = VecAssemblyBegin(b); CHKERRA(ierr) - ierr = MatAssemblyEnd(A[0],MAT_FINAL_ASSEMBLY); CHKERRA(ierr); - ierr = VecAssemblyEnd(soln); CHKERRA(ierr); - ierr = VecAssemblyEnd(b); CHKERRA(ierr); - ierr = MatSetOption(A[0],MAT_NO_NEW_NONZERO_LOCATIONS); CHKERRA(ierr); + if (verbose) + { + CCTK_INFO ("Assembling the vectors"); + } + ierr = MatAssemblyBegin(A[0],MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); + ierr = VecAssemblyBegin(soln); CHKERRQ(ierr); + ierr = VecAssemblyBegin(b); CHKERRQ(ierr); + ierr = MatAssemblyEnd(A[0],MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); + ierr = VecAssemblyEnd(soln); CHKERRQ(ierr); + ierr = VecAssemblyEnd(b); CHKERRQ(ierr); + ierr = MatSetOption(A[0],MAT_NO_NEW_NONZERO_LOCATIONS); CHKERRQ(ierr); if (trips==0) - OptionsSetValue("-ksp_monitor",""); - - if (verbose) CCTK_INFO("CREATING SLES"); - ierr = SLESCreate(pughGH->PUGH_COMM_WORLD,&sles); CHKERRA(ierr); + { + PetscOptionsSetValue("-ksp_monitor",""); + } + + if (verbose) + { + CCTK_INFO("CREATING SLES"); + } + + ierr = SLESCreate(pughGH->PUGH_COMM_WORLD,&sles); CHKERRQ(ierr); /* @@ -445,16 +492,22 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, using A to precondition itself. Since I don't know what this means, we'll leave it for now. */ - if (verbose) CCTK_INFO("CREATING SLES OPERATOR"); - ierr = SLESSetOperators(sles,A[0],A[0],DIFFERENT_NONZERO_PATTERN); CHKERRA(ierr); + if (verbose) + { + CCTK_INFO("CREATING SLES OPERATOR"); + } + ierr = SLESSetOperators(sles,A[0],A[0],DIFFERENT_NONZERO_PATTERN); CHKERRQ(ierr); /* Set linear solver defaults for this problem. Later this should be replaced/modified with appropriate parsing from the parameter parser. For now it is not. These defaults are reasonable, I hope. */ - if (verbose) CCTK_INFO("SLESGet KSP/PC"); - ierr = SLESGetKSP(sles,&ksp); CHKERRA(ierr); - ierr = SLESGetPC(sles,&pc); CHKERRA(ierr); + if (verbose) + { + CCTK_INFO("SLESGet KSP/PC"); + } + ierr = SLESGetKSP(sles,&ksp); CHKERRQ(ierr); + ierr = SLESGetPC(sles,&pc); CHKERRQ(ierr); /* Get the PC Type */ if (CCTK_Equals(petsc_PC_type,"PCJACOBI")) @@ -471,11 +524,12 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, ierr = PCSetType(pc,PCLU); else if (CCTK_Equals(petsc_PC_type,"PCNONE")) ierr = PCSetType(pc,PCNONE); - else { - CCTK_WARN(1,"Don't understand petsc_PC_type. Using PCNONE\n"); + else + { + CCTK_WARN(1,"Don't understand petsc_PC_type. Using PCNONE"); ierr = PCSetType(pc,PCNONE); } - CHKERRA(ierr); + CHKERRQ(ierr); /* Now the same thing for the KSP Type */ @@ -499,36 +553,47 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, ierr = KSPSetType(ksp,KSPCR); else if (CCTK_Equals(petsc_KSP_type,"KSPLSQR")) ierr = KSPSetType(ksp,KSPLSQR); - else { - CCTK_WARN (1,"I don't understand petsc_KSP_type. Using BiCGSTAB\n"); + else + { + CCTK_WARN (1,"I don't understand petsc_KSP_type. Using BiCGSTAB"); ierr = KSPSetType(ksp,KSPBCGS); } - CHKERRA(ierr); + CHKERRQ(ierr); /* Set up tolerances */ - if (PetscTolStyle == ELLCONV_ABSOLUTE) { + if (PetscTolStyle == ELLCONV_ABSOLUTE) + { rtol = 1.0e-15; atol = tolerance; - } else if (PetscTolStyle == ELLCONV_RELATIVE) { + } + else if (PetscTolStyle == ELLCONV_RELATIVE) + { rtol = tolerance; atol = 1.0e-15; - } else if (PetscTolStyle == ELLCONV_EITHER) { + } + else if (PetscTolStyle == ELLCONV_EITHER) + { rtol = tolerance; atol = tolerance; - } else { + } + else + { printf("PETSC Solver: PetscTolStyle set incorrectly [%d]\n", PetscTolStyle); } ierr = KSPSetTolerances(ksp, rtol, atol, PETSC_DEFAULT, PETSC_DEFAULT); - CHKERRA(ierr); + CHKERRQ(ierr); - if (verbose) CCTK_INFO("KSPSetInitialGuess\n"); + if (verbose) + { + CCTK_INFO("KSPSetInitialGuess"); + } ierr = KSPSetInitialGuessNonzero(ksp); - CHKERRA(ierr); + CHKERRQ(ierr); /* Set runtime options. Since we don't use PETSC runtime options @@ -536,7 +601,7 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, we parse things out. But that may not be such a good idea. So lets put it here. */ - ierr = SLESSetFromOptions(sles); CHKERRA(ierr); + ierr = SLESSetFromOptions(sles); CHKERRQ(ierr); /* OK so finally we are able to ... */ @@ -544,8 +609,12 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the linear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - if (verbose) CCTK_INFO("SLES solve..."); - ierr = SLESSolve(sles,b,soln,&its); CHKERRA(ierr); + if (verbose) + { + CCTK_INFO("SLES solve..."); + } + + ierr = SLESSolve(sles,b,soln,&its); CHKERRQ(ierr); /* Here we can form a "res = Ax - b" and find its norm to get an idea of how well we've converged. Put this in later @@ -559,20 +628,22 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, on (eg, the VecCreateMPI has made the solution local) */ VecGetArray(soln,&values); - for (k=kmin;k<kmax;k++) { - for (j=jmin;j<jmax;j++) { - for (i=imin;i<imax;i++) { + for (k=kmin;k<kmax;k++) + { + for (j=jmin;j<jmax;j++) + { + for (i=imin;i<imax;i++) + { /* Set up indices */ int ijk; /* The data point for the array */ int I; /* The col in the matrix */ /* these guys are easy */ ijk = DATINDEX(pEx,i,j,k); - if (wsp[ijk] >= 0) { - + if (wsp[ijk] >= 0) + { /* Now this one. "Fortran-order" the matrix. But remember - we have stripped off the ghost zones. Hence ig-1 and nxs... - */ + we have stripped off the ghost zones. Hence ig-1 and nxs */ I = wsp[ijk]-startpoint; ell_field[ijk] = values[I]; } @@ -585,19 +656,25 @@ void petsc_flat(cGH *GH, int FieldIndex, int MIndex, int NIndex, PUGH_SyncGroup(GH,"ellpetsc::petscworkspace"); /* And finally free up the matrix memory */ - /*$ierr = MatReleaseValuesMemory(A); CHKERRA(ierr);$*/ + /*$ierr = MatReleaseValuesMemory(A); CHKERRQ(ierr);$*/ /* This code is not used anymore */ - if (verbose) CCTK_INFO("Destroying Matrices"); - ierr = SLESDestroy(sles); CHKERRA(ierr); - ierr = VecDestroy(soln); CHKERRA(ierr); - ierr = VecDestroy(b); CHKERRA(ierr); - ierr = MatDestroy(A[0]); CHKERRA(ierr); + if (verbose) + { + CCTK_INFO("Destroying Matrices"); + } + ierr = SLESDestroy(sles); CHKERRQ(ierr); + ierr = VecDestroy(soln); CHKERRQ(ierr); + ierr = VecDestroy(b); CHKERRQ(ierr); + ierr = MatDestroy(A[0]); CHKERRQ(ierr); free(A); /*$PetscFinalize();$*/ - if (verbose) CCTK_INFO("LEAVING ELLPETSC"); + if (verbose) + { + CCTK_INFO("LEAVING ELLPETSC"); + } } |