Source code for coffee.actions.actions

from builtins import object
from coffee.backend import backend as be
import logging


[docs]class Prototype(object): """The prototype of all actions. This class provides basic functionality that all actions require. To subclass this class: 1) define the method _doit in the subclass 2) call the Prototypes constructor to ensure that frequency, start and stop are properly initialised. """ def __init__( self, frequency=1, start=-float("infinity"), stop=float("infinity"), thits=None, thits_toll=1e-14, ): """The initialiser for the Prototype action class. Parameters ========== frequency : int, Optional The action will only run after the given number of iterations. stop : float, Optional After this time the action will not run. start : float, Optional Before this time the action will not run. thits : list of floats, Optional Times at which the action is guaranteed to run thits_toll : float, Optional The tollerance for comparison against times in thits. """ self.frequency = frequency self.stop = stop self.start = start if thits is not None: self.thits = be.asarray(thits) else: self.thits = None self.thits_toll = thits_toll
[docs] def will_run(self, it, u): """Returns true if the action will run for the given iteration and time slice. Parameters ========== it : int The number of iterations in this simulation. u : tslice.TimeSlice The current timeslice. Returns ======= boolean : True if the action will run. """ test = (it % self.frequency) == 0 and self.start <= u.time <= self.stop if self.thits is not None: test = test and (be.absolute(u.time - self.thits) < self.thits_toll).any() return test
def __call__(self, it, u): """If the action will run, runs the action. Parameters ========== it : int The number of iterations in this simulation. u : tslice.TimeSlice The current timeslice. """ if self.will_run(it, u): self._doit(it, u) def _doit(self, it, u): pass
[docs]class BlowupCutoff(Prototype): """An action that stops the simulation if some component of the computed solution is above the given value. """ def __init__(self, cutoff=10, **kwds): """The initialiser for the BlowupCutoff action. The parameters listed below are only the parameters specific to this action. All parameters as given for the initialiser for the actions. Prototype actions are also valid. Parameters ========== cutoff: float The value that is used to test for ending the simulation. """ super(BlowupCutoff, self).__init__(**kwds) self.cutoff = abs(cutoff)
[docs] def above_cutoff(self, u): """Returns true if the absolute value of any component of the data in the timeslice u is above the absolute value of the given cutoff. Parameters ========== u : tslice.TimeSlice The timeslice to be checked. Returns ======= boolean : True if there is a component greater than the cutoff. """ for component in u.fields: if be.any(be.abs(component) >= self.cutoff): return True return False
def _doit(self, it, u): if self.above_cutoff(u): raise Exception("Function values are above the cutoff")
[docs]class Info(Prototype): """Logs the current iterations and data slice. Included more as an example than anything else. """ def __init__(self, *args, **kwds): """The initialiser for the Info action. All parameters as given for the initialiser for the actions.Prototype action are valid. """ self.log = logging.getLogger("Info") super(Info, self).__init__(*args, **kwds) def _doit(self, it, u): self.log.info("Iteration: %d, Time: %f" % (it, u.time))