Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple Jacobian calls with kinsol and Picard iterations #120

Open
mottelet opened this issue Mar 25, 2022 · 5 comments
Open

Multiple Jacobian calls with kinsol and Picard iterations #120

mottelet opened this issue Mar 25, 2022 · 5 comments
Assignees

Comments

@mottelet
Copy link
Contributor

mottelet commented Mar 25, 2022

Hello,

I noticed that using kinsol Picard iterations triggers a Jacobian evaluation at every iteration, although the Jacobian is supposed to be constant.

What am I doing wrong in the following trivial example (solve x*x-2=0) ? Here is the output of the program, showing that the jacobian function is called at each step though it shouldn't (IMHO):

jac
jac
jac
jac
jac
jac
jac
jac
jac
jac
jac
jac
jac
jac
y=1.414213

Thanks for your help

Stéphane Mottelet

#include <stdio.h>
#include <kinsol/kinsol.h>             /* access to KINSOL func., consts. */
#include <nvector/nvector_serial.h>    /* access to serial N_Vector       */
#include <sunlinsol/sunlinsol_dense.h>  /* access to band SUNLinearSolver  */
#include <sunmatrix/sunmatrix_dense.h>  /* access to dense SUNMatrix        */
#include <sundials/sundials_types.h>   /* defs. of realtype, sunindextype */

int func(N_Vector U, N_Vector F, void *user_data)
{
  double u = NV_Ith_S(U,0);
  NV_Ith_S(F,0) = u*u-2;
  return(0);
}
int jac(N_Vector u, N_Vector f, SUNMatrix J,
               void *user_data, N_Vector tmp1, N_Vector tmp2)
{
  SM_ELEMENT_D(J,0,0) = 2;
  printf("jac\n");
  return(0);
}

int main()
{
  N_Vector y, scale;
  void *kmem;
  SUNMatrix J;
  SUNLinearSolver LS;
  int flag;

  y = N_VNew_Serial(1);
  scale = N_VNew_Serial(1);
  N_VConst(1.0, y);
  N_VConst(1.0,scale);

  kmem = KINCreate();
  flag = KINInit(kmem, func, y);

  J = SUNDenseMatrix(1, 1);
  LS = SUNLinSol_Dense(y, J);
  KINSetLinearSolver(kmem, LS, J);
  KINSetJacFn(kmem, jac);

  flag = KINSol(kmem,y,KIN_PICARD,scale,scale);

  printf("flag=%d,y=%f\n",flag,NV_Ith_S(y,0));
}
@jandrej
Copy link
Member

jandrej commented Mar 25, 2022

If your function is f(x) = x^2-2 then df(x)/dx = 2.0*x. Your Jacobian returns df(x)/dx = 2.0.

@mottelet
Copy link
Contributor Author

mottelet commented Mar 25, 2022

If your function is f(x) = x^2-2 then df(x)/dx = 2.0*x. Your Jacobian returns df(x)/dx = 2.0.

I know how to compute a Jacobian, please see the Kinsol documentation about Picard method were the rhs is spliited in a linear part and a nonlinear part (https://sundials.readthedocs.io/en/latest/kinsol/Mathematics_link.html?highlight=picard#basic-fixed-point-iteration) :

For Picard iteration, as implemented in kinsol, we consider a special form of the nonlinear function F , such that F (u) = Lu − N (u), where L is a constant nonsingular matrix and N is (in general) nonlinear. Then the fixed-point function G is defined as G(u) = u − L−1F (u). The Picard iteration is given by:...,

@gardner48 gardner48 self-assigned this Mar 25, 2022
@gardner48
Copy link
Member

Currently the Picard iteration does not utilize the same linear system reuse controls that are present when using the modified Newton iteration. As such, the Picard iteration evaluates the linear system each iteration. We'll look at incorporating the reuse logic into the Picard iteration as part of a future release.

@mottelet
Copy link
Contributor Author

OK thanks, so let us the issue open ok ?

@gardner48
Copy link
Member

Yes, let's keep this issue open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants