Fortran Example Problems

The Fortran example problem programs supplied with the KINSOL package are all written using the Fortran 2003 standard, use double precision arithmetic, and 32- or 64-bit integers for indexing. See the Fortran section in the KINSOL User Documentation for details.

A serial example: kinDiagon_kry_f2003

The kinDiagon_kry_f2003 program solves the problem

\[F(u) = 0, \quad \text{where} \quad F_i(u) = u_i^2 - i^2, \quad \text{for} \quad 1 \le i \le N.\]

using the serial vector and the GMRES linear solver with a diagonal preconditioner.

The kinDiagonKry_mod module includes the problem parameters (e.g., neq \(=N\)) used in subroutines and functions contained in the module. The subroutines and function defined in the module are:

  • The subroutine init sets the components of the initial guess vector (sunvec_u) to the values \(u_i = 2 i\), all the components of the scaling vector (sunvec_s) are set to 1.0 (i.e., no scaling is done), and the components of the constraints vector (sunvec_c) are set to 0.0 (i.e., no inequality constraints are imposed on the solution vector).

  • The function func defines the user-supplied nonlinear residual \(F(u)\).

  • The functions kpsetup and kpsolve are the preconditioner setup and solve functions, respectively. kpsetup fills the array p with an approximation to the reciprocals of the Jacobian diagonal elements which are then used in kpsolve to solve the preconditioner linear system \(P x = v\) by simple multiplication.

The main program starts with a number of use lines, which allow access to KINSOL (fkinsol_mod), the serial vector (fnvector_serial_mod), and the GMRES linear solver (fsunlinsol_spgmr_mod). This is followed by a number of problem parameters for configuring the linear and nonlinear solver. In particular, the maximum number of iterations between calls to the preconditioner setup routine (msbpre = 5), the tolerance for stopping based on the function norm (fnormtol = 1.0d-5), and the tolerance for stopping based on the step length (scsteptol = 1.0d-4) are specified. After the problem parameters are declarations for local variables including SUNDIALS vector, matrix, and linear solver objects.

After printing the problem description, the main program creates the simulation context (sunctx) that is passed to all SUNDIALS constructors. The program creates then creates serial solution, scaling, and constraint vectors using FN_VNew_Serial and sets the vector values by calling the init subroutine.

The KINSOL solver is created by calling FKINCreate and initialized with FKINInit which takes as input the c_funloc of the Fortran residual function (func), a vector to use as a template to create internal workspace (sunvec_u), and the SUNDIALS context. Then solver options are specified by calling various FKINSet functions. In particular, the maximum number of iterations between calls to the preconditioner setup routine (FKINSetMaxSetupCalls), the tolerance for stopping based on the function norm (FKINSetFuncNormTol), and the tolerance for stopping based on the step length (FKINSetScaledStepTol).

Next, the GMRES linear solver is created with FSUNLinSol_SPGMR specifying the maximum Krylov subspace dimension (maxl = 10) and right preconditioning (prectype = SUN_PREC_RIGHT). The linear solver is then attached to KINSOL with FKINSetLinearSolver. The input matrix (sunmat_J) is assigned to null for the matrix-free linear solver. The maximum number of restarts allowed for GMRES is then updated to maxlrst = 2 by calling FSUNLinSol_SPGMRSetMaxRestarts. The preconditioner functions are then attached by calling FKINSetPreconditioner and passing the c_funloc of kpsetup and kpsolve.

The solution of the nonlinear system is obtained after a successful return from FKINSol, which is then printed using the PrintOutput subroutine. Solver statistics are then output using the PrintFinalStats function which calls various FKINGet functions. Finally, the memory allocated for the KINSOL, the linear solver, vectors, and context are released by calling FKINFree, FSUNLinSolFree, FN_VDestroy, and FSUNContext_Free, respectively.

The following is sample output from kinDiagon_kry_f2003.

Example program kinDiagon_kry_f2003:

This example demonstrates using the KINSOL Fortran interface to
solve a diagonal algebraic system using a Newton-Krylov method
with a diagonal preconditioner in a serial environment.

Problem size: 128

   1   1.000000   2.000000   3.000000   4.000000
   5   5.000000   6.000000   7.000000   8.000000
   9   9.000000  10.000000  11.000000  12.000000
  13  13.000000  14.000000  15.000000  16.000000
  17  17.000000  18.000000  19.000000  20.000000
  21  21.000000  22.000000  23.000000  24.000000
  25  25.000000  26.000000  27.000000  28.000000
  29  29.000000  30.000000  31.000000  32.000000
  33  33.000000  34.000000  35.000000  36.000000
  37  37.000000  38.000000  39.000000  40.000000
  41  41.000000  42.000000  43.000000  44.000000
  45  45.000000  46.000000  47.000000  48.000000
  49  49.000000  50.000000  51.000000  52.000000
  53  53.000000  54.000000  55.000000  56.000000
  57  57.000000  58.000000  59.000000  60.000000
  61  61.000000  62.000000  63.000000  64.000000
  65  65.000000  66.000000  67.000000  68.000000
  69  69.000000  70.000000  71.000000  72.000000
  73  73.000000  74.000000  75.000000  76.000000
  77  77.000000  78.000000  79.000000  80.000000
  81  81.000000  82.000000  83.000000  84.000000
  85  85.000000  86.000000  87.000000  88.000000
  89  89.000000  90.000000  91.000000  92.000000
  93  93.000000  94.000000  95.000000  96.000000
  97  97.000000  98.000000  99.000000 100.000000
 101 101.000000 102.000000 103.000000 104.000000
 105 105.000000 106.000000 107.000000 108.000000
 109 109.000000 110.000000 111.000000 112.000000
 113 113.000000 114.000000 115.000000 116.000000
 117 117.000000 118.000000 119.000000 120.000000
 121 121.000000 122.000000 123.000000 124.000000
 125 125.000000 126.000000 127.000000 128.000000

Final Statistics..

nni      =     7    nli     =    21
nfe      =     8    npe     =     2
nps      =    28    nlcf    =     0

A parallel example: kin_diagon_kry_f2003

The program kin_diagon_kry_f2003 is a straightforward modification of kinDiagon_kry_f2003 to use the MPI vector.

After initialing MPI, the MPI parallel vectors are created using FN_VNew_Parallel with the default MPI communicator and the local and global vector sizes as its first three arguments. The rank of the local process, myid, is used in both the initial guess and the system function, inasmuch as the global and local indices to the vector u are related by iglobal = ilocal + mype*nlocal. In other respects, the problem setup (KINSOL initialization, linear solver creation and specification, etc.) and solution steps are the same as in kinDiagon_kry_f2003. Upon successful return from FKINSol, the solution on all ranks is printed and statistics are output from the root processes. Finally, the allocated memory is released and the MPI environment is finalized.

For this simple example, no inter-process communication is required to evaluate the nonlinear system function or the preconditioner. As a consequence, the user-supplied routines func, kpsetup, and kpsolve are basically identical to those in kinDiagon_kry_f2003.

The following is sample output from kin_diagon_kry_2003 using 4 MPI ranks.

Example program kinDiagon_kry_f2003:

This example demonstrates using the KINSOL Fortran interface to
solve a diagonal algebraic system using a Newton-Krylov method
with a diagonal preconditioner in a MPI parallel environment.

Problem size: 128
Number of procs:   4

   1   1.000000   2.000000   3.000000   4.000000
   5   5.000000   6.000000   7.000000   8.000000
   9   9.000000  10.000000  11.000000  12.000000
  13  13.000000  14.000000  15.000000  16.000000
  17  17.000000  18.000000  19.000000  20.000000
  21  21.000000  22.000000  23.000000  24.000000
  25  25.000000  26.000000  27.000000  28.000000
  29  29.000000  30.000000  31.000000  32.000000
  33  33.000000  34.000000  35.000000  36.000000
  37  37.000000  38.000000  39.000000  40.000000
  41  41.000000  42.000000  43.000000  44.000000
  45  45.000000  46.000000  47.000000  48.000000
  49  49.000000  50.000000  51.000000  52.000000
  53  53.000000  54.000000  55.000000  56.000000
  57  57.000000  58.000000  59.000000  60.000000
  61  61.000000  62.000000  63.000000  64.000000
  65  65.000000  66.000000  67.000000  68.000000
  69  69.000000  70.000000  71.000000  72.000000
  73  73.000000  74.000000  75.000000  76.000000
  77  77.000000  78.000000  79.000000  80.000000
  81  81.000000  82.000000  83.000000  84.000000
  85  85.000000  86.000000  87.000000  88.000000
  89  89.000000  90.000000  91.000000  92.000000
  93  93.000000  94.000000  95.000000  96.000000
  97  97.000000  98.000000  99.000000 100.000000
 101 101.000000 102.000000 103.000000 104.000000
 105 105.000000 106.000000 107.000000 108.000000
 109 109.000000 110.000000 111.000000 112.000000
 113 113.000000 114.000000 115.000000 116.000000
 117 117.000000 118.000000 119.000000 120.000000
 121 121.000000 122.000000 123.000000 124.000000
 125 125.000000 126.000000 127.000000 128.000000

Final Statistics..

nni      =     7    nli     =    21
nfe      =     8    npe     =     2
nps      =    28    nlcf    =     0