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
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
initsets 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 to1.0(i.e., no scaling is done), and the components of the constraints vector (sunvec_c) are set to0.0(i.e., no inequality constraints are imposed on the solution vector).The function
funcdefines the user-supplied nonlinear residual \(F(u)\).The functions
kpsetupandkpsolveare the preconditioner setup and solve functions, respectively.kpsetupfills the arraypwith an approximation to the reciprocals of the Jacobian diagonal elements which are then used inkpsolveto 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