from scipy.interpolate import interp1d as interp
"""
Module that contains the implementation of the source term of the pheromone propagation model.
"""
[docs]
class Source:
r"""
Class containing the source term :math:`s(x,y,t)~\forall (x,y)\in\Omega~\forall t\in[0;T]`
that is the quantity of pheromone emitted per second.
Attributes
----------
t : ~numpy.ndarray
The array of times :math:`t` at which the source term maps :math:`s(x,y)` are given. If the source is stationary, set to `None`.
value : ~numpy.ndarray
Quantity of pheromone emitted (source term) map :math:`s(x,y)` at the current time :math:`t`.
time_interpolation : scipy.interpolate.interp1d
Callable function used to compute the source term map :math:`s(x,y)` given a time :math:`t`.
Computation using the linear interpolation of the source term maps provided on the given time array.
"""
[docs]
def __init__(self, msh, value, t=None):
"""
Constructor method.
Parameters
----------
msh : ~pheromone_dispersion.geom.MeshRect2D
The geometry of the domain.
value : ~numpy.ndarray
The source term maps :math:`s(x,y)` at one or multiple times.
t : ~numpy.ndarray, default: None
The array of the times :math:`t` at which the source term maps :math:`s(x,y)` are given. `None` if the source is stationary.
Raises
------
ValueError
if the shape of the provided values of the source term :math:`s(x,y)`
does not fit with the shape of the arrays of the coordinates of the cells' center
and of the provided time array.
"""
self.t = t
if self.t is not None:
if value.ndim != 3:
raise ValueError(
"The number dimension of the source term is incorrect, the source term is unsteady, the number of dimension shoud be 3"
)
if self.t.size != value.shape[0]:
raise ValueError("The shape of the source term does not coincide with the shape of the time vector")
self.value = value[0, :, :]
self.time_interpolation = interp(t, value, axis=0)
else:
if value.ndim != 2:
raise ValueError(
"The number dimension of the source term is incorrect, the source term is steady, the number of dimension shoud be 2"
)
self.value = value
self.t = None
if self.value.shape[0] != msh.y.size or self.value.shape[1] != msh.x.size:
raise ValueError("The shape of the source term at the center of the cells does not match with the shape of the msh.")
[docs]
def at_current_time(self, tc):
r"""
Update the attribute :attr:`value` at a given time using the linear interpolation callable attribute :attr:`time_interpolation`.
Parameters
----------
tc : float or integer
The current time.
Raises
------
ValueError
if the given time is not between the first and last times of the attribute :attr:`t`,
i.e. between the first and last times at which the source term maps are given.
"""
if self.t is not None:
if tc < min(self.t) or tc > max(self.t):
raise ValueError("The given time must be between the lowest and largest times contained in the time vector.")
self.value = self.time_interpolation(tc)