Source code for pheromone_dispersion.reaction_operator

import numpy as np
from scipy.sparse.linalg import LinearOperator as LinOp

"""
Module that contains the implementation of the linear operator of the reaction term of the pheromone propagation model.
"""


[docs] class Reaction(LinOp): r""" Class containing the reaction term linear operator :math:`R:c\mapsto \tau_{loss}c~\forall (x,y)\in\Omega~\forall t\in]0;T]`. The implementation of this linear operator is a subclass of the :py:class:`~scipy.sparse.linalg.LinearOperator` class. Attributes ---------- reaction_coeff : ~numpy.ndarray The loss coefficient :math:`\tau_{loss}(x,y)`. msh : ~pheromone_dispersion.geom.MeshRect2D The geometry of the domain. shape : tuple of int Shape of the matrix of the linear operator. The shape is (:attr:`msh.y.size` * :attr:`msh.x.size`, :attr:`msh.y.size` * :attr:`msh.x.size`) dtype : ~numpy.dtype Data type of the elements of the matrix of the linear operator. The type is `float64` """
[docs] def __init__(self, reaction_coeff, msh): r""" Constructor method Parameters ---------- reaction_coeff : ~numpy.ndarray The loss coefficient :math:`\tau_{loss}(x,y)` at the center of each cells. msh: ~pheromone_dispersion.geom.MeshRect2D The geometry of the domain. Raises ------ ValueError if shape of the array of loss coefficient does not fit with the shape of the arrays of the coordinates of the cells' center. """ if reaction_coeff.shape != (msh.y.size, msh.x.size): raise ValueError("The shape of the deposition coefficient at the center of the cells does not match with the shape of the msh.") self.msh = msh self.reaction_coeff = reaction_coeff self.shape = (self.msh.y.size * self.msh.x.size, self.msh.y.size * self.msh.x.size) self.dtype = np.dtype(float)
[docs] def update_reaction_coeff(self, reaction_coeff): r""" Update the attribute :attr:`reaction_coeff` with the value provided as input. Parameters ---------- reaction_coeff : ~numpy.ndarray The new value of loss coefficient :math:`\tau_{loss}(x,y)`. """ self.reaction_coeff = reaction_coeff
[docs] def _matvec(self, x_out): r""" Compute the image (matrix-vector product) of :math:`R:c\mapsto \tau_{loss}c` for a given concentration map :math:`c` at the current time. Parameters ---------- x_out : ~numpy.ndarray The map of concentration of pheromones :math:`c(x,y)` at a given time :math:`t` raveled into a vector. Returns ------- ~numpy.ndarray Array containing the image :math:`\tau_{loss}c`. Notes ----- The input :math:`c` has to be raveled into a (:attr:`msh.y.size` * :attr:`msh.x.size`,)-shape array to match the format of the :py:class:`~scipy.sparse.linalg.LinearOperator` class. The same way, the ouput can be reshape into a (:attr:`msh.y.size`, :attr:`msh.x.size`)-shape array to get the map :math:`Rc(x,y)` at the current time :math:`t` """ # reshape the vector (of (msh.x.size*msh.y.size, )) containg the concentration into a matrix (of shape (msh.y.size, msh.x.size)) x = x_out.reshape((self.msh.y.size, self.msh.x.size)) reaction = self.reaction_coeff * x return reaction.reshape((self.msh.y.size * self.msh.x.size,))
def _matmat(self, x_out): # Compute the image (matrix-matrix product) # using a naive method based on the _matvec method output = np.zeros((self.shape[0], x_out.shape[1])) for i_col, col in enumerate(x_out.T): output[:, i_col] = self.matvec(col) return output
# return np.hstack([self.matvec(col.reshape(-1, 1)) for col in x_out.T])