FluidityProject / fluidity

Fluidity
http://fluidity-project.org
Other
365 stars 115 forks source link

Error while compiling Fluidity with PETSc 3.14 #292

Closed Patol75 closed 3 years ago

Patol75 commented 3 years ago

Hi, This is just a heads-up that make fails with the newer versions of PETSc (starting somewhere around 3.13.X I believe) - I paste the errors I am getting below. I, sadly, do not quite understand what these errors mean and how to fix them. If anyone more knowledgeable has some time to investigate, please feel free to open a PR. Thank you for your time.

Solvers.F90:1930:89:

 1930 |         call PCBJACOBIGetSubKSP(pc, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, subksp, ierr)
      |                                                                                         1
Error: There is no specific subroutine for the generic ‘pcbjacobigetsubksp’ at (1)
Solvers.F90:1932:85:

 1932 |         call PCASMGetSubKSP(pc, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, subksp, ierr)
      |                                                                                     1
Error: There is no specific subroutine for the generic ‘pcasmgetsubksp’ at (1)
Solvers.F90:1955:88:

 1955 |        call PCBJACOBIGetSubKSP(pc, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, subksp, ierr)
      |                                                                                        1
Error: There is no specific subroutine for the generic ‘pcbjacobigetsubksp’ at (1)
gnikit commented 3 years ago

I think you have stumbled onto this problem https://github.com/FluidityProject/fluidity/pull/267 from my PR a while back. They changed the interface I think, but you can resolve it if you change PETSC_NULL_INTEGER for a standard PETSc int. FYI Another solution is to use PETSC_DECIDE.

gnikit commented 3 years ago

So I might have been a little too lazy with my previous solution, because I didn't even read the PETSc documentation properly. It turns out that we can't pass NULL output arguments to PETSc, at least for PCBJacobiGetSubKSP(). The solution is equally simple as before. Here is a patch.

diff --git a/femtools/Solvers.F90 b/femtools/Solvers.F90
index 23ee87faf..cd6d43a49 100644
--- a/femtools/Solvers.F90
+++ b/femtools/Solvers.F90
@@ -1865,6 +1865,7 @@ subroutine create_ksp_from_options(ksp, mat, pmat, solver_option_path, parallel,
     PCType:: pctype, hypretype
     MatSolverType:: matsolvertype
     PetscErrorCode:: ierr
+    integer :: n_local, first_local

     call get_option(trim(option_path)//'/name', pctype)

@@ -1927,9 +1928,9 @@ subroutine create_ksp_from_options(ksp, mat, pmat, solver_option_path, parallel,
       call PCSetup(pc, ierr)

       if (pctype==PCBJACOBI) then
-        call PCBJACOBIGetSubKSP(pc, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, subksp, ierr)
+        call PCBJACOBIGetSubKSP(pc, n_local, first_local, subksp, ierr)
       else
-        call PCASMGetSubKSP(pc, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, subksp, ierr)
+        call PCASMGetSubKSP(pc, n_local, first_local, subksp, ierr)
       end if

       call KSPGetPC(subksp, subpc, ierr)
@@ -1952,7 +1953,7 @@ subroutine create_ksp_from_options(ksp, mat, pmat, solver_option_path, parallel,
        call PCSetType(pc, PCBJACOBI, ierr)
        ! need to call this before the subpc can be retrieved:
        call PCSetup(pc, ierr)
-       call PCBJACOBIGetSubKSP(pc, PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, subksp, ierr)
+       call PCBJACOBIGetSubKSP(pc, n_local, first_local, subksp, ierr)
        call KSPGetPC(subksp, subpc, ierr)
        call PCSetType(subpc, pctype, ierr)

Having said that, I think the setup for PCBJacobiGetSubKSP() might not be entirely correct. The documentation states

Fortran Usage: You must pass in a KSP array that is large enough to contain all the local KSPs. You can call PCBJacobiGetSubKSP(pc,nlocal,firstlocal,PETSC_NULL_KSP,ierr) to determine how large the KSP array must be.

which means the setup should potentially have to look like this (taken from https://www.mcs.anl.gov/petsc/petsc-current/src/ksp/ksp/tutorials/ex7f.F90.html):

! Extract the array of KSP contexts for the local blocks
call PCBJacobiGetSubKSP(myPc,nlocal,first,PETSC_NULL_KSP,ierr)
allocate(subksp(nlocal))
call PCBJacobiGetSubKSP(myPc,nlocal,first,subksp,ierr)

Although, I do realise that in Fluidity's implementation subksp is not an array, hence there might not be a need for the above.