Source code for pararealml.initial_value_problem

from __future__ import annotations

from typing import Callable, Optional, Tuple

import numpy as np

from pararealml.constrained_problem import ConstrainedProblem
from pararealml.initial_condition import InitialCondition

TemporalDomainInterval = Tuple[float, float]


[docs]class InitialValueProblem: """ A representation of an initial value problem around a boundary value problem. """ def __init__( self, cp: ConstrainedProblem, t_interval: TemporalDomainInterval, initial_condition: InitialCondition, exact_y: Optional[ Callable[ [InitialValueProblem, float, Optional[np.ndarray]], np.ndarray ] ] = None): """ :param cp: the constrained problem to base the initial value problem on :param t_interval: the bounds of the time domain of the initial value problem :param initial_condition: the initial condition of the problem :param exact_y: the function returning the exact solution to the initial value problem at time step t and points x. If it is None, the problem is assumed to have no analytical solution. """ if t_interval[0] > t_interval[1]: raise ValueError( f'lower bound of time interval ({t_interval[0]}) cannot be ' f'greater than its upper bound ({t_interval[1]})') self._cp = cp self._t_interval = t_interval self._initial_condition = initial_condition self._exact_y = exact_y @property def constrained_problem(self) -> ConstrainedProblem: """ The constrained problem the IVP is based on. """ return self._cp @property def t_interval(self) -> TemporalDomainInterval: """ The bounds of the temporal domain of the differential equation. """ return self._t_interval @property def initial_condition(self) -> InitialCondition: """ The initial condition of the IVP. """ return self._initial_condition @property def has_exact_solution(self) -> bool: """ Whether the differential equation has an analytic solution """ return self._exact_y is not None
[docs] def exact_y( self, t: float, x: Optional[np.ndarray] = None) -> np.ndarray: """ Returns the exact value of y(t, x). :param t: the point in the temporal domain :param x: the points in the non-temporal domain. If the differential equation is an ODE, it is None. :return: the value of y(t, x) or y(t) if it is an ODE. """ if not self.has_exact_solution: raise RuntimeError( 'exact solution of initial value problem undefined') return self._exact_y(self, t, x)