Source code for simframe.frame.frame

from datetime import timedelta
import inspect
import numpy as np
from time import monotonic

from simframe.frame.group import Group
from simframe.frame.intvar import IntVar

from simframe.integration.integrator import Integrator
from simframe.io.writer import Writer
from simframe.io.progress import Progressbar
from simframe.utils.color import colorize


[docs] class Frame(Group): """This is the parent object of type ``Group`` that contains all other objects. During integration the ``update()`` function of the ``Frame`` object will be called. You have to sub-delegete the updates of your other ``Group`` and ``Field`` objects within this function. ``Frame`` has additional functionality for writing output files and for integration.""" __name__ = "Frame" def __init__(self, integrator=None, writer=None, updater=None, verbosity=2, progressbar=None, description=""): """ The parent Frame object. Parameters ---------- writer : Writer, optional, default : None Object of type Writer fir writing output files integrator : Integrator, optional, default : None Integrator with integration instructions updater : Heartbeat, Updater, callable, list or None, optional, default : None Updater for updating the frame verbosity : int, optional, default : 2 Level of verbosity progressbar : Progresbar or None, optional, default : None Progressbar. If None, standard is used description : string, optional, default : "" Descriptive string of the frame object""" super().__init__(self, updater=updater, description=description) self.integrator = integrator self.progressbar = progressbar self.verbosity = verbosity self.writer = writer @property def integrator(self): '''``Integrator`` that controls the simulation.''' return self._integrator @integrator.setter def integrator(self, integrator): if integrator is not None and type(integrator) is not Integrator: raise TypeError("integrator has to be of type Integrator or None.") self._integrator = integrator @property def progressbar(self): '''``Progressbar`` for displaying current status.''' return self._progressbar @progressbar.setter def progressbar(self, value): if value is None: self._progressbar = Progressbar() else: if not isinstance(value, Progressbar): raise TypeError("<progressbar> has to be of type Progressbar.") self._progressbar = value @property def verbosity(self): '''Verbosity of the ``Frame`` objects.''' return self._verbosity @verbosity.setter def verbosity(self, value): if not isinstance(value, int): raise TypeError("<verbosity> has to be of type int.") self._verbosity = value @property def writer(self): '''``Writer`` object for writing output files.''' return self._writer @writer.setter def writer(self, value): if inspect.isclass(value): value = value() if value is not None and not isinstance(value, Writer): raise TypeError("writer has to be of type Writer or None.") self._writer = value
[docs] def writeoutput(self, i=0, forceoverwrite=False, filename="", **kwargs): """Writes output to file, if ``Writer`` is specified. Parameters ---------- i : int, optional, default : 0 Number of output forceoverwrite : boolean, optional, default : False If True, this overrules the seetings of the Writer and enforces the file to be overwritten. filename : string, optional, default = "" if given this will write the output to this file. Otherwise, it uses the standard scheme. kwargs : additional keyword arguments Additional options that can be passed to the writer""" if self.writer is not None: self.writer.write(self, i, forceoverwrite, filename, **kwargs)
[docs] def run(self): """This method starts the simulation. An ``Integrator`` has to be set beforehand.""" if not isinstance(self.integrator, Integrator): raise RuntimeError("No integrator set.") # Check if integration variable is set if not isinstance(self.integrator.var, IntVar): raise RuntimeError( "No integration variable assigned to integrator.") # If there are no snapshots set if not len(self.integrator.var.snapshots): raise RuntimeError( "No snapshots set. At least one snapshot has to be given.") # If integration variable passed maximum value of snapshots if self.integrator.var >= self.integrator.var.snapshots[-1]: raise RuntimeError( "Integration variable already passed the largest snapshot.") # Timekeeping tini = monotonic() # Write initial conditions if self.integrator.var < self.integrator.var.snapshots[0]: self.writeoutput(0) # Staring index of snapshots starting_index = np.argmin( self.integrator.var >= self.integrator.var.snapshots) # Starting value of integration variable startingvalue = self.integrator.var.copy() for i in range(starting_index, len(self.integrator.var.snapshots)): # Nextsnapshot cannot be referenced directly, because it dynamically changes. nextsnapshot = self.integrator.var.nextsnapshot prevsnapshot = self.integrator.var.prevsnapshot if self.integrator.var.prevsnapshot is not None else startingvalue while self.integrator.var < nextsnapshot: if self.verbosity > 1: self.progressbar(self.integrator.var, prevsnapshot, nextsnapshot, startingvalue, self.integrator.var.snapshots[-1]) self.integrator.integrate() self.integrator.var += self.integrator.var._prevstepsize self.update() if self.verbosity > 1: self.progressbar._reset() self.writeoutput(i + 1) # Timekeeping tfin = monotonic() t_exec = timedelta(seconds=int(tfin-tini)) if self.verbosity > 0: msg = "Execution time: {}".format(colorize(t_exec, color="blue")) print(msg)