Skip to content

Integrators

Runge-Kutta

The generic function RK4 in package Orka.Integrators can be used to perform numerical integration using the Runge-Kutta 4th order method.

It returns the change to a value for a given time step. If the parameter F represent a time-variant system, that is, F depends on a time T, then you must compute the derivative at time T + DT. In this case you must keep track of T yourself and add it to the given DT.

The returned change must be added to the old value to perform the numerical integration.

For example, to numerically compute the position and velocity of an object using the momentum and the inverse of the mass:

type State is record
   Position, Momentum, Velocity : Vectors.Vector4;
   Inverse_Mass                 : Orka.Float_64;
end record;

type Derivative is record
   DX, DP : Vectors.Vector4 := Vectors.Vector4 (Vectors.Zero_Point);
end record;

where DX is the derivative of the position (velocity) and DP is the derivative of the momentum (impulse).

Momentum p = m v where m is the mass and v the velocity

A few functions must then be defined to scale Derivative and add a Derivative to a State or another Derivative:

function "+" (S : State; Motion : Derivative) return State is
   Result : State := S;
begin
   Result.Position := Result.Position + Motion.DX;
   Result.Momentum := Result.Momentum + Motion.DP;

   --  Recompute velocity after updating momentum
   Result.Velocity := Result.Momentum * Result.Inverse_Mass;

   return Result;
end "+";

function "*" (Left : Orka.Float_64; Right : Derivative) return Derivative is
  ((DX => Left * Right.DX, DP => Left * Right.DP));

function "+" (Left, Right : Derivative) return Derivative is
  ((DX => Left.DX + Right.DX, DP => Left.DP + Right.DP));

These functions are then used to instantiate the generic function RK4 and to perform the numerical integration:

function RK4 is new Orka.Integrators.RK4 (State, Derivative, Orka.Float_64);

procedure Integrate
  (S     : in out State;
   Force : not null access function (S : State; Time : Orka.Float_64) return Vectors.Vector4;
   T, DT : Orka.Float_64)
is
   function F (Y : State; DT : Orka.Float_64) return Derivative is
     ((DX => Y.Velocity, DP => Force (Y, T + DT)));
begin
   S := S + RK4 (S, DT, F'Access);
end Integrate;