Help with KSPSetConvergenceTest
Hello guys, Today I am about to write a custom convergence test for KSP doing the following job: - if the number of ksp iterations is less than a given threshold, iterate until that threshold is met - if the number of ksp iterations is bigger than the threshold, use the standard convergence checks. As far as I understood from the examples, this is the function I need to use: KSPSetConvergenceTest <https://petsc.org/main/manualpages/KSP/KSPSetConvergenceTest/>(ksp,MyKSPConverged,0,PETSC_NULL_FUNCTION,ierr) With MyKSPConverge a subroutine (I am in fortran) where my custom checks are implemented. Here is how I have coded MyKSPConverged: * subroutine MyKSPConverged(ksp,n,rnorm,flag,dummy,ierr) KSP ksp PetscErrorCode ierr PetscInt n,dummy KSPConvergedReason flag PetscReal rnorm if (n>1) then call KSPConvergedDefault(ksp, n, rnorm, flag, ierr) else flag = 0 endif ierr = 0 end subroutine MyKSPConverged* However I get this error: [0]PETSC ERROR: KSPSolve has not converged, reason DIVERGED_DTOL which I believe to be triggered by *KSPConvergedDefault. *This is odd, as this simulation converge perfectly if I comment ou my dodgy convergence test. *Do you have any advice for me?* *thank you! *
On Sun, May 7, 2023 at 9:21 AM Edoardo alinovi <[email protected]> wrote:
Hello guys,
Today I am about to write a custom convergence test for KSP doing the following job:
- if the number of ksp iterations is less than a given threshold, iterate until that threshold is met - if the number of ksp iterations is bigger than the threshold, use the standard convergence checks.
As far as I understood from the examples, this is the function I need to use:
KSPSetConvergenceTest <https://petsc.org/main/manualpages/KSP/KSPSetConvergenceTest/>(ksp,MyKSPConverged,0,PETSC_NULL_FUNCTION,ierr)
With MyKSPConverge a subroutine (I am in fortran) where my custom checks are implemented.
Here is how I have coded MyKSPConverged:
* subroutine MyKSPConverged(ksp,n,rnorm,flag,dummy,ierr) KSP ksp PetscErrorCode ierr PetscInt n,dummy KSPConvergedReason flag PetscReal rnorm if (n>1) then call KSPConvergedDefault(ksp, n, rnorm, flag, ierr)*
Isn't this call missing an argument? THanks, Matt
* else flag = 0 endif ierr = 0 end subroutine MyKSPConverged*
However I get this error: [0]PETSC ERROR: KSPSolve has not converged, reason DIVERGED_DTOL which I believe to be triggered by *KSPConvergedDefault. *This is odd, as this simulation converge perfectly if I comment ou my dodgy convergence test.
*Do you have any advice for me?*
*thank you! *
-- What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead. -- Norbert Wiener https://www.cse.buffalo.edu/~knepley/ <http://www.cse.buffalo.edu/~knepley/>
Hi Matt, mmmmh, what if I do: KSPConvergedDefault(ksp, n, rnorm, flag, PETSC_NULL_FUNCTION, ierr) That looks to behave OK, but I am not sure about what I am doing -.- Cheers
On Sun, May 7, 2023 at 9:42 AM Edoardo alinovi <[email protected]> wrote:
Hi Matt,
mmmmh, what if I do:
KSPConvergedDefault(ksp, n, rnorm, flag, PETSC_NULL_FUNCTION, ierr)
That looks to behave OK, but I am not sure about what I am doing -.-
You are saying that no convergence context was passed in THanks Matt
Cheers
-- What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead. -- Norbert Wiener https://www.cse.buffalo.edu/~knepley/ <http://www.cse.buffalo.edu/~knepley/>
Thanks, Is this a reasonable thing to do if I want to replicate what KSP is doing by default?
On Sun, May 7, 2023 at 10:02 AM Edoardo alinovi <[email protected]> wrote:
Thanks,
Is this a reasonable thing to do if I want to replicate what KSP is doing by default?
Yes. The other option is to pass along 'dummy' Thanks, Matt -- What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead. -- Norbert Wiener https://www.cse.buffalo.edu/~knepley/ <http://www.cse.buffalo.edu/~knepley/>
The code will not work as written because KSPConvergedDefault() requires a context created with KSPConvergedDefaultCreate(). Here is a starting point for what you need, in main integer*8 defaultctx extern MyKSPConverged, KSPConvergedDefaultDestroy KSPDefaultConvergedCreate(defaultctx,ierr) KSPSetConvergenceTest <https://petsc.org/main/manualpages/KSP/KSPSetConvergenceTest/>(ksp,MyKSPConverged,defaultctx,KSPConvergedDefaultDestroy, ierr) subroutine MyKSPConverged(ksp,n,rnorm,flag,defaultctx,ierr) KSP ksp PetscErrorCode ierr PetscInt n integer*8 defaultctx KSPConvergedReason flag PetscReal rnorm if (n>1) then call KSPConvergedDefault(ksp, n, rnorm, flag,defaultctx, ierr) else flag = 0 endif ierr = 0 end subroutine MyKSPConverged
On May 7, 2023, at 10:09 AM, Matthew Knepley <[email protected]> wrote:
On Sun, May 7, 2023 at 10:02 AM Edoardo alinovi <[email protected] <mailto:[email protected]>> wrote:
Thanks,
Is this a reasonable thing to do if I want to replicate what KSP is doing by default?
Yes. The other option is to pass along 'dummy'
Thanks,
Matt
-- What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead. -- Norbert Wiener
https://www.cse.buffalo.edu/~knepley/ <http://www.cse.buffalo.edu/~knepley/>
Note, you must call the default test on iteration 0. This is how it determines the initial residual for relative residual tests etc. I recommend not having the if () test at all. Instead, always call the default convergence test first and then change the flag value it provides if needed before doing any custom checking.
On May 7, 2023, at 11:38 AM, Barry Smith <[email protected]> wrote:
The code will not work as written because KSPConvergedDefault() requires a context created with KSPConvergedDefaultCreate().
Here is a starting point for what you need, in main
integer*8 defaultctx extern MyKSPConverged, KSPConvergedDefaultDestroy
KSPDefaultConvergedCreate(defaultctx,ierr) KSPSetConvergenceTest <https://petsc.org/main/manualpages/KSP/KSPSetConvergenceTest/>(ksp,MyKSPConverged,defaultctx,KSPConvergedDefaultDestroy, ierr)
subroutine MyKSPConverged(ksp,n,rnorm,flag,defaultctx,ierr)
KSP ksp PetscErrorCode ierr PetscInt n integer*8 defaultctx KSPConvergedReason flag PetscReal rnorm
if (n>1) then call KSPConvergedDefault(ksp, n, rnorm, flag,defaultctx, ierr) else flag = 0 endif ierr = 0
end subroutine MyKSPConverged
On May 7, 2023, at 10:09 AM, Matthew Knepley <[email protected]> wrote:
On Sun, May 7, 2023 at 10:02 AM Edoardo alinovi <[email protected] <mailto:[email protected]>> wrote:
Thanks,
Is this a reasonable thing to do if I want to replicate what KSP is doing by default?
Yes. The other option is to pass along 'dummy'
Thanks,
Matt
-- What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead. -- Norbert Wiener
https://www.cse.buffalo.edu/~knepley/ <http://www.cse.buffalo.edu/~knepley/>
Working example in https://gitlab.com/petsc/petsc/-/merge_requests/6430
On May 7, 2023, at 11:47 AM, Barry Smith <[email protected]> wrote:
Note, you must call the default test on iteration 0. This is how it determines the initial residual for relative residual tests etc.
I recommend not having the if () test at all. Instead, always call the default convergence test first and then change the flag value it provides if needed before doing any custom checking.
On May 7, 2023, at 11:38 AM, Barry Smith <[email protected]> wrote:
The code will not work as written because KSPConvergedDefault() requires a context created with KSPConvergedDefaultCreate().
Here is a starting point for what you need, in main
integer*8 defaultctx extern MyKSPConverged, KSPConvergedDefaultDestroy
KSPDefaultConvergedCreate(defaultctx,ierr) KSPSetConvergenceTest <https://petsc.org/main/manualpages/KSP/KSPSetConvergenceTest/>(ksp,MyKSPConverged,defaultctx,KSPConvergedDefaultDestroy, ierr)
subroutine MyKSPConverged(ksp,n,rnorm,flag,defaultctx,ierr)
KSP ksp PetscErrorCode ierr PetscInt n integer*8 defaultctx KSPConvergedReason flag PetscReal rnorm
if (n>1) then call KSPConvergedDefault(ksp, n, rnorm, flag,defaultctx, ierr) else flag = 0 endif ierr = 0
end subroutine MyKSPConverged
On May 7, 2023, at 10:09 AM, Matthew Knepley <[email protected]> wrote:
On Sun, May 7, 2023 at 10:02 AM Edoardo alinovi <[email protected] <mailto:[email protected]>> wrote:
Thanks,
Is this a reasonable thing to do if I want to replicate what KSP is doing by default?
Yes. The other option is to pass along 'dummy'
Thanks,
Matt
-- What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead. -- Norbert Wiener
https://www.cse.buffalo.edu/~knepley/ <http://www.cse.buffalo.edu/~knepley/>
Hello Barry, Mega! Thank you Berry much for providing me with a working example! I ended up in writing this: * call KSPConvergedDefault(ksp, n, rnorm, flag, PETSC_NULL_FUNCTION, ierr) if (n<flubioSolvers%itmin) then flag = 0 endif ierr = 0* and it looks working but I'll take advantage of your suggestion ;) Is KSPConvergedDefaultDestroy mandatory? I know it's easy code, but maybe you might have a think to add this control and expose it as the max number of iterations in KSP. I can tell you it is very much used, I found myself many times in need to tell the solver to iterate regardless of the tolerances criteria. It happens for example in the RANS equation, especially omega. Sometimes they tend to stall and you do want to tighten the tolerances for a bunch of iters, or you might not know if they do while iterating! Cheers
On May 7, 2023, at 2:22 PM, Edoardo alinovi <[email protected]> wrote:
Hello Barry,
Mega! Thank you Berry much for providing me with a working example! I ended up in writing this:
call KSPConvergedDefault(ksp, n, rnorm, flag, PETSC_NULL_FUNCTION, ierr)
This should not work. The argument to KSPConvergedDefault is a context, not a function
if (n<flubioSolvers%itmin) then flag = 0 endif ierr = 0
and it looks working but I'll take advantage of your suggestion ;) Is KSPConvergedDefaultDestroy mandatory?
You could pass PETSC_NULL_FUNCTION instead of KSPConvergedDefaultDestroy, but there is no reason to.
I know it's easy code, but maybe you might have a think to add this control and expose it as the max number of iterations in KSP. I can tell you it is very much used, I found myself many times in need to tell the solver to iterate regardless of the tolerances criteria. It happens for example in the RANS equation, especially omega. Sometimes they tend to stall and you do want to tighten the tolerances for a bunch of iters, or you might not know if they do while iterating!
Cheers
Thanks Barry, I have fixed the error. Indeed, It's odd it is working. Compiler magic I guess!
See https://gitlab.com/petsc/petsc/-/merge_requests/6436 with commit barry/2023-05-08/add-ksp-min-its
On May 7, 2023, at 2:22 PM, Edoardo alinovi <[email protected]> wrote:
Hello Barry,
Mega! Thank you Berry much for providing me with a working example! I ended up in writing this:
call KSPConvergedDefault(ksp, n, rnorm, flag, PETSC_NULL_FUNCTION, ierr) if (n<flubioSolvers%itmin) then flag = 0 endif ierr = 0
and it looks working but I'll take advantage of your suggestion ;) Is KSPConvergedDefaultDestroy mandatory?
I know it's easy code, but maybe you might have a think to add this control and expose it as the max number of iterations in KSP. I can tell you it is very much used, I found myself many times in need to tell the solver to iterate regardless of the tolerances criteria. It happens for example in the RANS equation, especially omega. Sometimes they tend to stall and you do want to tighten the tolerances for a bunch of iters, or you might not know if they do while iterating!
Cheers
Mega! This is gonna be useful for many people :) Il Mar 9 Mag 2023, 00:54 Barry Smith <[email protected]> ha scritto:
See https://gitlab.com/petsc/petsc/-/merge_requests/6436 with commit barry/2023-05-08/add-ksp-min-its
On May 7, 2023, at 2:22 PM, Edoardo alinovi <[email protected]> wrote:
Hello Barry,
Mega! Thank you Berry much for providing me with a working example! I ended up in writing this:
* call KSPConvergedDefault(ksp, n, rnorm, flag, PETSC_NULL_FUNCTION, ierr) if (n<flubioSolvers%itmin) then flag = 0 endif ierr = 0*
and it looks working but I'll take advantage of your suggestion ;) Is KSPConvergedDefaultDestroy mandatory?
I know it's easy code, but maybe you might have a think to add this control and expose it as the max number of iterations in KSP. I can tell you it is very much used, I found myself many times in need to tell the solver to iterate regardless of the tolerances criteria. It happens for example in the RANS equation, especially omega. Sometimes they tend to stall and you do want to tighten the tolerances for a bunch of iters, or you might not know if they do while iterating!
Cheers
Hello Barry, I have seen you guys merged in main the minimum tolerance stuff. After compiling that branch, I have tried to call KSPSetMinimumIterations(this%ksp, this%minIter, ierr), but the compiler cannot find the function. I have included this module as standard practice: #include "petsc/finclude/petscksp.h" use petscksp Maybe I am missing something else? Thank you!
Run make allfortranstubs to generate the fortran interfaces, then make On Sat, May 13, 2023, 13:35 Edoardo alinovi <[email protected]> wrote:
Hello Barry,
I have seen you guys merged in main the minimum tolerance stuff.
After compiling that branch, I have tried to call KSPSetMinimumIterations(this%ksp, this%minIter, ierr), but the compiler cannot find the function.
I have included this module as standard practice: #include "petsc/finclude/petscksp.h" use petscksp
Maybe I am missing something else?
Thank you!
participants (4)
-
Barry Smith -
Edoardo alinovi -
Matthew Knepley -
Stefano Zampini