The main DDEABM integration class.
Type | Visibility | Attributes | Name | Initial | |||
---|---|---|---|---|---|---|---|
integer, | private | :: | neq | = | 0 |
the number of (first order) differential equations to be integrated (>=0) |
|
integer, | private | :: | maxnum | = | 500 |
the expense of solving the problem is monitored by counting the
number of steps attempted. when this exceeds |
|
procedure(deriv_func), | private, | pointer | :: | df | => | null() |
to define the system of first order differential equations
which is to be solved. for the given values of |
procedure(report_func), | private, | pointer | :: | report | => | null() |
a function for reporting the integration steps (optional).
this can be associated in ddeabm_initialize or
ddeabm_with_event_initialize, and is enabled
using the |
logical, | private | :: | scalar_tols | = | .true. | ||
real(kind=wp), | private, | allocatable, dimension(:) | :: | rtol |
the user input rel tol |
||
real(kind=wp), | private, | allocatable, dimension(:) | :: | atol |
the user input abs tol |
||
real(kind=wp), | private, | allocatable, dimension(:) | :: | rtol_tmp |
rel tol used internally |
||
real(kind=wp), | private, | allocatable, dimension(:) | :: | atol_tmp |
abs tol used internally |
||
integer, | private, | dimension(4) | :: | info | = | 0 |
info array |
integer, | private | :: | initial_step_mode | = | 1 |
how to choose the initial step
|
|
real(kind=wp), | private | :: | initial_step_size | = | 0.0_wp |
when |
|
integer, | private | :: | icount | = | 0 |
replaced |
|
real(kind=wp), | private | :: | tprev | = | 0.0_wp |
replaced |
|
real(kind=wp), | private, | dimension(:), allocatable | :: | two |
array |
||
real(kind=wp), | private, | dimension(:), allocatable | :: | gstr |
array |
||
real(kind=wp), | private, | allocatable, dimension(:) | :: | ypout |
|
||
real(kind=wp), | private, | allocatable, dimension(:) | :: | yp |
|
||
real(kind=wp), | private, | allocatable, dimension(:) | :: | yy |
|
||
real(kind=wp), | private, | allocatable, dimension(:) | :: | wt |
|
||
real(kind=wp), | private, | allocatable, dimension(:) | :: | p |
|
||
real(kind=wp), | private, | allocatable, dimension(:, :) | :: | phi |
|
||
real(kind=wp), | private, | dimension(12) | :: | alpha | = | 0.0_wp | |
real(kind=wp), | private, | dimension(12) | :: | beta | = | 0.0_wp | |
real(kind=wp), | private, | dimension(12) | :: | psi | = | 0.0_wp | |
real(kind=wp), | private, | dimension(12) | :: | v | = | 0.0_wp | |
real(kind=wp), | private, | dimension(12) | :: | w | = | 0.0_wp | |
real(kind=wp), | private, | dimension(13) | :: | sig | = | 0.0_wp | |
real(kind=wp), | private, | dimension(13) | :: | g | = | 0.0_wp | |
real(kind=wp), | private, | dimension(11) | :: | gi | = | 0.0_wp | |
real(kind=wp), | private | :: | h | = | 0.0_wp |
the step size |
|
real(kind=wp), | private | :: | eps | = | 0.0_wp |
if the tolerances have been increased by the
code ( |
|
real(kind=wp), | private | :: | x | = | 0.0_wp |
contains the current value of the
independent variable, i.e. the farthest point
integration has reached. this will be different
from |
|
real(kind=wp), | private | :: | xold | = | 0.0_wp | ||
real(kind=wp), | private | :: | hold | = | 0.0_wp | ||
real(kind=wp), | private | :: | told | = | 0.0_wp | ||
real(kind=wp), | private | :: | delsgn | = | 0.0_wp | ||
real(kind=wp), | private | :: | tstop | = | 0.0_wp |
(see |
|
real(kind=wp), | private | :: | twou | = | 0.0_wp |
machine dependent parameter |
|
real(kind=wp), | private | :: | fouru | = | 0.0_wp |
machine dependent parameter |
|
logical, | private | :: | start | = | .false. |
indicator for dsteps code |
|
logical, | private | :: | phase1 | = | .false. |
indicator for dsteps code |
|
logical, | private | :: | nornd | = | .false. |
indicator for dsteps code |
|
logical, | private | :: | stiff | = | .false. |
indicator for stiffness detection |
|
logical, | private | :: | intout | = | .false. |
indicator for intermediate-output |
|
integer, | private | :: | ns | = | 0 | ||
integer, | private | :: | kord | = | 0 | ||
integer, | private | :: | kold | = | 0 | ||
integer, | private | :: | init | = | 0 |
initialization indicator |
|
integer, | private | :: | ksteps | = | 0 |
counter for attempted steps |
|
integer, | private | :: | kle4 | = | 0 |
step counter for stiffness detection |
|
integer, | private | :: | iquit | = | 0 |
termination flag |
|
integer, | private | :: | kprev | = | 0 | ||
integer, | private | :: | ivc | = | 0 | ||
integer, | private, | dimension(10) | :: | iv | = | 0 | |
integer, | private | :: | kgi | = | 0 | ||
logical, | private | :: | error | = | .false. |
will be set in |
Initialize the ddeabm_class, and set the variables that cannot be changed during a problem.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(ddeabm_class), | intent(inout) | :: | me | |||
integer, | intent(in) | :: | neq |
number of equations to be integrated |
||
integer, | intent(in) | :: | maxnum |
maximum number of integration steps allowed |
||
procedure(deriv_func) | :: | df |
derivative function dx/dt |
|||
real(kind=wp), | intent(in), | dimension(:) | :: | rtol |
relative tolerance for integration (see ddeabm) |
|
real(kind=wp), | intent(in), | dimension(:) | :: | atol |
absolution tolerance for integration (see ddeabm) |
|
procedure(report_func), | optional | :: | report |
reporting function |
||
integer, | intent(in), | optional | :: | initial_step_mode |
how to choose the initial step |
|
real(kind=wp), | intent(in), | optional | :: | initial_step_size |
for |
Wrapper routine for ddeabm.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(ddeabm_class), | intent(inout) | :: | me | |||
real(kind=wp), | intent(inout) | :: | t | |||
real(kind=wp), | intent(inout), | dimension(me%neq) | :: | y | ||
real(kind=wp), | intent(in) | :: | tout |
time at which a solution is desired. |
||
real(kind=wp), | intent(in), | optional | :: | tstop |
for some problems it may not be permissible to integrate
past a point |
|
integer, | intent(out) | :: | idid |
indicator reporting what the code did. you must monitor this integer variable to decide what action to take next. |
||
integer, | intent(in), | optional | :: | integration_mode |
Step mode:
1 - normal integration from |
|
real(kind=wp), | intent(in), | optional | :: | tstep |
Fixed time step to use for |
Destructor for ddeabm_class.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(ddeabm_class), | intent(out) | :: | me |
Call this to indicate that a new problem is being solved.
It sets info(1) = 0
(see ddeabm documentation).
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(ddeabm_class), | intent(inout) | :: | me |
state interpolation function
Interpolation function. Can be used for dense output after a step. It calls the low-level routine dintp.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(ddeabm_class), | intent(inout) | :: | me | |||
real(kind=wp), | intent(in) | :: | tc |
point at which solution is desired |
||
real(kind=wp), | intent(out), | dimension(me%neq) | :: | yc |
interpolated state at |
user can call this in df
routine to stop the integration
Call this to abort the integration if there is an error.
(Can be called in df
by the user.) The step
will be considered invalid and not returned.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(ddeabm_class), | intent(inout) | :: | me |
solve an initial value problem in ordinary differential equations using an adams-bashforth method.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(ddeabm_class), | intent(inout) | :: | me | |||
integer, | intent(in) | :: | neq |
the number of (first order) differential equations to be integrated. (neq >= 1) |
||
real(kind=wp), | intent(inout) | :: | t |
value of the independent variable. on input, set it to the initial point of the integration. the code changes its value. on output, the solution was successfully advanced to the output value of t. |
||
real(kind=wp), | intent(inout), | dimension(neq) | :: | y | ||
real(kind=wp), | intent(in) | :: | tout | |||
integer, | intent(inout), | dimension(4) | :: | info | ||
real(kind=wp), | intent(inout), | dimension(:) | :: | rtol | ||
real(kind=wp), | intent(inout), | dimension(:) | :: | atol | ||
integer, | intent(out) | :: | idid |
ddeabm merely allocates storage for ddes to relieve the user of the inconvenience of a long call list. consequently ddes is used as described in the comments for ddeabm.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(ddeabm_class), | intent(inout) | :: | me | |||
integer, | intent(in) | :: | neq | |||
real(kind=wp), | intent(inout) | :: | t | |||
real(kind=wp), | intent(inout), | dimension(neq) | :: | y | ||
real(kind=wp), | intent(in) | :: | tout | |||
integer, | intent(inout), | dimension(4) | :: | info | ||
real(kind=wp), | intent(inout), | dimension(:) | :: | rtol | ||
real(kind=wp), | intent(inout), | dimension(:) | :: | atol | ||
integer, | intent(inout) | :: | idid | |||
real(kind=wp), | intent(inout), | dimension(neq) | :: | ypout | ||
real(kind=wp), | intent(inout), | dimension(neq) | :: | yp | ||
real(kind=wp), | intent(inout), | dimension(neq) | :: | yy | ||
real(kind=wp), | intent(inout), | dimension(neq) | :: | wt | ||
real(kind=wp), | intent(inout), | dimension(neq) | :: | p | ||
real(kind=wp), | intent(inout), | dimension(neq, 16) | :: | phi | ||
real(kind=wp), | intent(inout), | dimension(12) | :: | alpha | ||
real(kind=wp), | intent(inout), | dimension(12) | :: | beta | ||
real(kind=wp), | intent(inout), | dimension(12) | :: | psi | ||
real(kind=wp), | intent(inout), | dimension(12) | :: | v | ||
real(kind=wp), | intent(inout), | dimension(12) | :: | w | ||
real(kind=wp), | intent(inout), | dimension(13) | :: | sig | ||
real(kind=wp), | intent(inout), | dimension(13) | :: | g | ||
real(kind=wp), | intent(inout), | dimension(11) | :: | gi | ||
real(kind=wp), | intent(inout) | :: | h | |||
real(kind=wp), | intent(inout) | :: | eps | |||
real(kind=wp), | intent(inout) | :: | x | |||
real(kind=wp), | intent(inout) | :: | xold | |||
real(kind=wp), | intent(inout) | :: | hold | |||
real(kind=wp), | intent(inout) | :: | told | |||
real(kind=wp), | intent(inout) | :: | delsgn | |||
real(kind=wp), | intent(inout) | :: | tstop | |||
real(kind=wp), | intent(inout) | :: | twou | |||
real(kind=wp), | intent(inout) | :: | fouru | |||
logical, | intent(inout) | :: | start | |||
logical, | intent(inout) | :: | phase1 | |||
logical, | intent(inout) | :: | nornd | |||
logical, | intent(inout) | :: | stiff | |||
logical, | intent(inout) | :: | intout | |||
integer, | intent(inout) | :: | ns | |||
integer, | intent(inout) | :: | kord | |||
integer, | intent(inout) | :: | kold | |||
integer, | intent(inout) | :: | init | |||
integer, | intent(inout) | :: | ksteps | |||
integer, | intent(inout) | :: | kle4 | |||
integer, | intent(inout) | :: | iquit | |||
integer, | intent(inout) | :: | kprev | |||
integer, | intent(inout) | :: | ivc | |||
integer, | intent(inout), | dimension(10) | :: | iv | ||
integer, | intent(inout) | :: | kgi |
Computes a starting step size to be used in solving initial value problems in ordinary differential equations.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(ddeabm_class), | intent(inout) | :: | me | |||
integer, | intent(in) | :: | neq |
the number of (first order) differential equations to be integrated. |
||
real(kind=wp), | intent(in) | :: | a |
the initial point of integration. |
||
real(kind=wp), | intent(in) | :: | b |
a value of the independent variable used to define
the direction of integration. a reasonable choice is to
set |
||
real(kind=wp), | intent(in), | dimension(neq) | :: | y |
the vector of initial values of the |
|
real(kind=wp), | intent(in), | dimension(neq) | :: | yprime |
the vector of derivatives of the |
|
real(kind=wp), | intent(in), | dimension(neq) | :: | etol |
the vector of error tolerances corresponding to
the |
|
integer, | intent(in) | :: | morder |
the order of the formula which will be used by the initial value method for taking the first integration step. |
||
real(kind=wp), | intent(in) | :: | small |
a small positive machine dependent constant
which is used for protecting against computations with
numbers which are too small relative to the precision of
floating point arithmetic. |
||
real(kind=wp), | intent(in) | :: | big |
a large positive machine dependent constant which is used for preventing machine overflows. a reasonable choice is to set big to (approximately) the square root of the largest double precision number which can be held in the machine. |
||
real(kind=wp), | intent(inout), | dimension(neq) | :: | spy |
work array of length |
|
real(kind=wp), | intent(inout), | dimension(neq) | :: | pv |
work array of length |
|
real(kind=wp), | intent(inout), | dimension(neq) | :: | yp |
work array of length |
|
real(kind=wp), | intent(inout), | dimension(neq) | :: | sf |
work array of length |
|
real(kind=wp), | intent(out) | :: | h |
appropriate starting step size to be attempted by the differential equation method. |
integrate a system of first order ordinary differential equations one step.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(ddeabm_class), | intent(inout) | :: | me | |||
integer, | intent(in) | :: | neqn |
number of equations to be integrated |
||
real(kind=wp), | intent(inout), | dimension(neqn) | :: | y |
solution vector at x |
|
real(kind=wp), | intent(inout) | :: | x |
independent variable |
||
real(kind=wp), | intent(inout) | :: | h |
appropriate step size for next step. normally determined by code |
||
real(kind=wp), | intent(inout) | :: | eps |
local error tolerance |
||
real(kind=wp), | intent(inout), | dimension(neqn) | :: | wt |
vector of weights for error criterion |
|
logical, | intent(inout) | :: | start |
logical variable set .true. for first step, .false. otherwise |
||
real(kind=wp), | intent(inout) | :: | hold |
step size used for last successful step |
||
integer, | intent(inout) | :: | k |
appropriate order for next step (determined by code) |
||
integer, | intent(inout) | :: | kold |
order used for last successful step |
||
logical, | intent(inout) | :: | crash |
logical variable set .true. when no step can be taken, .false. otherwise. |
||
real(kind=wp), | intent(inout), | dimension(neqn, 16) | :: | phi |
required for the interpolation subroutine dintp |
|
real(kind=wp), | intent(inout), | dimension(neqn) | :: | p |
required for the interpolation subroutine dintp |
|
real(kind=wp), | intent(inout), | dimension(neqn) | :: | yp |
derivative of solution vector at x after successful step |
|
real(kind=wp), | intent(inout), | dimension(12) | :: | psi | ||
real(kind=wp), | intent(inout), | dimension(12) | :: | alpha |
required for the interpolation subroutine dintp |
|
real(kind=wp), | intent(inout), | dimension(12) | :: | beta | ||
real(kind=wp), | intent(inout), | dimension(13) | :: | sig | ||
real(kind=wp), | intent(inout), | dimension(12) | :: | v | ||
real(kind=wp), | intent(inout), | dimension(12) | :: | w |
required for the interpolation subroutine dintp |
|
real(kind=wp), | intent(inout), | dimension(13) | :: | g |
required for the interpolation subroutine dintp |
|
logical, | intent(inout) | :: | phase1 | |||
integer, | intent(inout) | :: | ns |
number of dsteps taken with size h |
||
logical, | intent(inout) | :: | nornd | |||
integer, | intent(inout) | :: | ksteps |
counter on attempted steps |
||
real(kind=wp), | intent(inout) | :: | twou |
2.*u where u is machine unit roundoff quantity |
||
real(kind=wp), | intent(inout) | :: | fouru |
4.*u where u is machine unit roundoff quantity |
||
real(kind=wp), | intent(inout) | :: | xold |
required for the interpolation subroutine dintp |
||
integer, | intent(inout) | :: | kprev | |||
integer, | intent(inout) | :: | ivc |
required for the interpolation subroutine dintp |
||
integer, | intent(inout), | dimension(10) | :: | iv |
required for the interpolation subroutine dintp |
|
integer, | intent(inout) | :: | kgi |
required for the interpolation subroutine dintp |
||
real(kind=wp), | intent(inout), | dimension(11) | :: | gi |
required for the interpolation subroutine dintp |
type, public :: ddeabm_class !! The main DDEABM integration class. private integer :: neq = 0 !! the number of (first order) differential equations to be integrated (>=0) integer :: maxnum = 500 !! the expense of solving the problem is monitored by counting the !! number of steps attempted. when this exceeds `maxnum`, the counter !! is reset to zero and the user is informed about possible excessive !! work. procedure(deriv_func), pointer :: df => null() !! to define the system of first order differential equations !! which is to be solved. for the given values of `x` and the !! vector `u(*)=(u(1),u(2),...,u(neq))`, the subroutine must !! evaluate the `neq` components of the system of differential !! equations `du/dx=df(x,u)` and store the derivatives in the !! array `uprime(*)`, that is, `uprime(i) = du(i)/dx` for !! equations `i=1,...,neq`. procedure(report_func), pointer :: report => null() !! a function for reporting the integration steps (optional). !! this can be associated in [[ddeabm_initialize]] or !! [[ddeabm_with_event_initialize]], and is enabled !! using the `mode` argument in [[ddeabm_wrapper]] !! or [[ddeabm_with_event_wrapper]] !tolerances logical :: scalar_tols = .true. real(wp), allocatable, dimension(:) :: rtol !! the user input rel tol real(wp), allocatable, dimension(:) :: atol !! the user input abs tol real(wp), allocatable, dimension(:) :: rtol_tmp !! rel tol used internally real(wp), allocatable, dimension(:) :: atol_tmp !! abs tol used internally integer, dimension(4) :: info = 0 !! info array ! initial step mode: integer :: initial_step_mode = 1 !! how to choose the initial step `h`: !! !! 1. Use [[dhstrt]]. !! 2. Use the older (quicker) algorithm. !! 3. Use a user-specified value. real(wp) :: initial_step_size = 0.0_wp !! when `initial_step_mode=3`, the `h` value to use. !! (for the other modes, this will also contain the value used) !variables formerly in work arrays: integer :: icount = 0 !! replaced `iwork(liw)` in original code real(wp) :: tprev = 0.0_wp !! replaced `rwork(itstar)` in original code !these were fixed in the original code: real(wp), dimension(:), allocatable :: two !! \( 2^i \) array real(wp), dimension(:), allocatable :: gstr !! \( | \gamma^{*}_i | \) array real(wp), allocatable, dimension(:) :: ypout !! `(neq)` contains the approximate derivative !! of the solution component `y(i)`. in [[ddeabm]], it !! is obtained by calling subroutine `df` to !! evaluate the differential equation using `t` and !! `y(*)` when `idid=1` or `2`, and by interpolation !! when `idid=3`. real(wp), allocatable, dimension(:) :: yp !! `(neq)` real(wp), allocatable, dimension(:) :: yy !! `(neq)` real(wp), allocatable, dimension(:) :: wt !! `(neq)` real(wp), allocatable, dimension(:) :: p !! `(neq)` real(wp), allocatable, dimension(:, :) :: phi !! `(neq,16)` real(wp), dimension(12) :: alpha = 0.0_wp real(wp), dimension(12) :: beta = 0.0_wp real(wp), dimension(12) :: psi = 0.0_wp real(wp), dimension(12) :: v = 0.0_wp real(wp), dimension(12) :: w = 0.0_wp real(wp), dimension(13) :: sig = 0.0_wp real(wp), dimension(13) :: g = 0.0_wp real(wp), dimension(11) :: gi = 0.0_wp real(wp) :: h = 0.0_wp !! the step size `h` to be attempted on the next step. real(wp) :: eps = 0.0_wp !! if the tolerances have been increased by the !! code (`idid=-2`), they were multiplied by `eps`. real(wp) :: x = 0.0_wp !! contains the current value of the !! independent variable, i.e. the farthest point !! integration has reached. this will be different !! from `t` only when interpolation has been !! performed (`idid=3`). real(wp) :: xold = 0.0_wp real(wp) :: hold = 0.0_wp real(wp) :: told = 0.0_wp real(wp) :: delsgn = 0.0_wp real(wp) :: tstop = 0.0_wp !! (see `info(4)`) real(wp) :: twou = 0.0_wp !! machine dependent parameter real(wp) :: fouru = 0.0_wp !! machine dependent parameter logical :: start = .false. !! indicator for [[dsteps]] code logical :: phase1 = .false. !! indicator for [[dsteps]] code logical :: nornd = .false. !! indicator for [[dsteps]] code logical :: stiff = .false. !! indicator for stiffness detection logical :: intout = .false. !! indicator for intermediate-output integer :: ns = 0 integer :: kord = 0 integer :: kold = 0 integer :: init = 0 !! initialization indicator integer :: ksteps = 0 !! counter for attempted steps integer :: kle4 = 0 !! step counter for stiffness detection integer :: iquit = 0 !! termination flag integer :: kprev = 0 integer :: ivc = 0 integer, dimension(10) :: iv = 0 integer :: kgi = 0 logical :: error = .false. !! will be set in `stop_integration`. !! indicates an error and to !! abort the integration contains private procedure, non_overridable, public :: initialize => ddeabm_initialize procedure, non_overridable, public :: integrate => ddeabm_wrapper procedure, non_overridable, public :: destroy => destroy_ddeabm procedure, non_overridable, public :: first_call => ddeabm_new_problem procedure, non_overridable, public :: interpolate => ddeabm_interp !! state interpolation function procedure, non_overridable, public :: stop_integration => ddeabm_stop_integration !! user can call this in `df` routine to stop the integration !support routines: procedure, non_overridable :: ddeabm procedure, non_overridable :: ddes procedure, non_overridable :: dhstrt procedure, non_overridable :: dsteps end type ddeabm_class