microbenthos.model package

Submodules

microbenthos.model.equation module

class microbenthos.model.equation.ModelEquation(model, varpath, coeff=1, track_budget=False)[source]

Bases: object

Class that handles the creation of partial differential equations for a transient variable of the model

__init__(model, varpath, coeff=1, track_budget=False)[source]

Initialize the model equation for a given variable

Parameters
  • model (MicroBenthosModel) – model this belongs to

  • varpath (str) – Model path of the equation variable (example: “env.oxygen”)

  • coeff (int, float) – the coefficient for the transient term

model

the model instance this equation belongs to

varpath

the path (str) to the equation variable

var

The equation variable object (Variable)

varname

the name of var

source_formulae

container (dict) of the formulae of the sources (sympy expressions)

source_exprs

container (dict) of the expressions of the sources (fipy variable binOp)

source_terms

container (dict) of the fipy equation terms (explicit & implicit) of the sources

source_coeffs

the coefficients in the equation for the sources

sources_total

The additive sum of the values in source_exprs

diffusion_def

type : (str, float)

The model path to the diffussion coeff and a numeric coefficient to multiply in the equation

obj

the fipy term that is used in the model full_eqn

finalized

flag to indicate if the equation has been finalized

Tracked

namedtuple definition for tracked fields: (‘time_step’, ‘var_expected’, ‘var_actual’, ‘sources_change’, ‘transport_change’)

tracked

a tuple of tracked values according to Tracked

finalize()[source]

Call this to setup the equation. Once this is called, no more terms can be added.

This does:

self.obj = self.term_transient == sum(self.RHS_terms)
Raises

RuntimeError – if no term_transient defined or no RHS terms defined

property term_transient

dv/dt

Type

The transient term of the equation

_get_term_obj(path)[source]

Get the model object at the path and return a usable fipy type

Parameters

path (str) – dotted path in the model store

Returns

Variable | fipy.terms.binaryTerm._BinaryTerm

_add_diffusion_term(coeff)[source]

Add a linear diffusion term to the equation

Parameters

coeff (int, float, term) – Coefficient for diffusion term

add_diffusion_term_from(path, coeff)[source]

Add diffusion term from the object path

Parameters
  • path (str) – Path to model store

  • coeff (int, float) – Multiplier coefficient for object

Returns

Object stored on model store

Raises

ValueError if object not found at path

property term_diffusion

The diffusion term for the equation

Returns

Instance of fipy.DiffusionTerm

add_source_term_from(path, coeff=1)[source]

Add a source term from the model path

Parameters
  • path (str) – Path to model store

  • coeff (int, float) – coeff for source term

Raises

ValueError if path does not point to an object

as_symbolic()[source]

Return a symbolic version (sympy) of the equation

as_latex_string()[source]

Return a latex string of the equation through sympy

as_pretty_string()[source]

Return a pretty (unicode) string of the equation through sympy

property RHS_terms

The right hand side terms of the equation

Returns

A list of terms, with the first one being term_diffusion, followed by the values in source_terms.

snapshot(base=False)[source]

Return a state dictionary of the equation, with the structure

  • “sources”
    • “metadata”: source paths and coefficients

    • “data”: the net rate of the combined sources

  • “diffusion”
  • “transient”
    • “metadata”:
  • “tracked_budget” (if track_budget is True)
    • var_expected: data: integrated density of variable from tracked changes

    • var_actual: data: integrated density of variable

    • time_step: data: the time step duration

    • sources_change: data: integrated rate of combined sources over the time step

    • transport_change: data: change in variable quantity due to mass transport

“metadata”
Returns

dict – A dictionary of the equation state

Raises

RuntimeError – if the equation is not yet finalized

restore_from(state, tidx)[source]

If “tracked_budget” is in the state, then set the values on the instance

sources_rate()[source]

Estimate the rate of change of the variable quantity caused by source terms.

Returns

PhysicalField – The integrated quantity of the sources

transport_rate()[source]

Estimate the rate of change of the variable quantity caused by transport at the domain boundaries

Returns

PhysicalField – The integrated quantity of the transport rate

var_quantity()[source]

Calculate the integral quantity of the variable in the domain

Returns

PhysicalField – depth integrated amount

update_tracked_budget(dt)[source]

Update the tracked quantities for the variable, sources and transport

Parameters

dt (PhysicalField) – the time step

Note

This is not a very accurate way to measure it, because the boundaries conditions keep the value at the domain boundaries constant, and so is not a true measure of the equation change in the time step. However, it should provide an order of magnitude metric for the accuracy of the numerical approximation in solving the equation.

property track_budget

Flag to indicate if the variable quantity should be tracked.

When this is set, the variable quantity in the domain is tracked through update_tracked_budget().

Returns

bool – Flag state

microbenthos.model.model module

class microbenthos.model.model.MicroBenthosModel(**kwargs)[source]

Bases: microbenthos.utils.create.CreateMixin

The theater where all the actors of microbenthos come together in a concerted play driven by the clock. This is the class that encapsulates the nested structure and function of the various entities, variables, microbial groups and binds them with the domain.

schema_key = 'model'
__init__(**kwargs)[source]

Initialize the model instance.

Parameters

**kwargs – definition dictionary assumed to be validated by MicroBenthosSchemaValidator.

env

container (dict) of the environmental variables and processes

equations

container (dict) of the ModelEquation defined in the model

add_formula(name, vars, expr)[source]

Add a formula to the sympy namespace of Expression

Parameters
  • name (str) – Name of the formula

  • vars (str, list) – Variables in the formula expression

  • expr (str) – The expression to be parsed by sympy

Example

name = "optimum_response"
variables = "x Ks Ki"
expr = "x / (x + Ks) / (1 + x/Ki)"
property domain

The model domain, typically SedimentDBLDomain

create_entity_from(defdict)[source]

Create a model entity from dictionary, and set it up with the model and domain.

See Also: Entity.from_dict()

Returns

The entity created

_create_entity_into(target, name, defdict)[source]

Create an entity from its definition dictionary and store it into the target dictionary

Parameters
  • target (str) – Target dict such as "env", "microbes"

  • name (str) – The key for the dictionary

  • defdict (dict) – Parameter definition of the entity

_setup(**definition)[source]

Set up the model instance from the definition dictionary, which is assumed to be validated by MicroBenthosSchemaValidator.

entities_setup()[source]

Check that the model entities are setup fully, if not attempt it for each entity in env and :attr:.microbes`

property all_entities_setup

Flag that indicates if all entities have been setup

snapshot(base=False)[source]

Create a snapshot of the model state.

This method recursively calls the snapshot() method of all contained entities, and compiles them into a nested dictionary. The dictionary has the structure of the model, as well as nodes with the numeric data and metadata. The state of the model can then be serialized, for example through save_snapshot(), or processed through various exporters (in exporters).

Parameters

base (bool) – Whether the entities should be converted to base units?

Returns

dict – model state snapshot

See also

save_snapshot() for details about the nested structure of the state and how it is processed.

restore_from(store, time_idx)[source]

Restore the model entities from the given store

Parameters
  • store (Group) – The root of the model data store

  • time_idx (int) – the index along the time series to restore. Uses

  • syntax (python) –

:param : :param i.e first element is 0: :param second is 1: :param last element is -1: :param etc.:

Warning

This is a potentially destructive operation! After checking that we can_restore_from() the given store, truncate_model_data() is called. This method modifies the data structure in the supplied store by truncating the datasets to the length of the time series as determined from time_idx. Only in the case of time_idx=-1 it may not modify the data.

Raises
  • TypeError – if the store data is not compatible with model

  • Exception – as raised by truncate_model_data().

See also

check_compatibility() to see how the store is assessed to be compatible with the instantiated model.

truncate_model_data() for details on how the store is truncated.

can_restore_from(store)[source]

Check if the model can be resumed from the given store

Parameters

store (hdf.Group) – The root of the model data store

Returns

True if it is compatible

add_equation(name, transient, sources=None, diffusion=None, track_budget=False)[source]

Create a transient reaction-diffusion equation for the model.

The term definitions are provided as (model_path, coeff) pairs to be created for the transient term, diffusion term and source terms.

If all inputs are correct, it creates and finalizes a ModelEquation instance, stored in equations.

Parameters
  • name (str) – Identifier for the equation

  • transient (tuple) – Single definition for transient term

  • sources (list) – A list of definitions for source terms

  • diffusion (tuple) – Single definition for diffusion term

  • track_budget (bool) – flag whether the variable budget should be

  • over time (tracked) –

create_full_equation()[source]

Create the full equation (full_eqn) of the model by coupling the individual equations.

get_object(path)[source]

Get an object stored in the model

Parameters

path (str) – The stored path for the object in the model

Returns

The stored object if found

Raises

ValueError if no object found at given path

on_time_updated()[source]

Callback function to update the time on all the stored entities

revert_vars()[source]

Revert vars to the old settings. This is used when sweeping equations has to be rolled back

update_vars()[source]

Update all stored variables which have an hasOld setting. This is used while sweeping for solutions.

update_equations(dt)[source]

Update the equations for the time increment.

Parameters

dt (PhysicalField) – the time step duration

class microbenthos.model.model.ModelClock(*args, **kwds)[source]

Bases: fipy.variables.variable.Variable

Subclass of fipy.Variable to implement hooks and serve as clock of the model.

property value

“Evaluate” the Variable and return its value (longhand)

>>> a = Variable(value=3)
>>> print(a.value)
3
>>> b = a + 4
>>> b
(Variable(value=array(3)) + 4)
>>> b.value
7
increment_time(dt)[source]

Increment the clock

Parameters

dt (float, PhysicalField) – Time step in seconds

set_time(t)[source]

Set the clock time in hours :param t: Time in hours :type t: float, PhysicalField

property as_hms

Return a tuple of (hour, minute, second)

property as_hms_string

Return a string of hour, min, sec

microbenthos.model.resume module

Module to implement the resumption of a simulation run.

The assumption is that a model object is created, and a HDF data store is available.

microbenthos.model.resume.check_compatibility(state, store)[source]

Check that the given model snapshot is compatible with the structure of the store. This checks that every path in the snapshot exists in the HDF store.

Parameters
  • state (dict) – a model snapshot dictionary

  • store (Group) – the root node of the stored model data

Returns

True if the structures are compatible

Raises
  • ValueError – if an incompatible data is returned

  • NotImplementedError – for state arrays of dim > 1

microbenthos.model.resume.truncate_model_data(store, time_idx)[source]

Truncates the model data in store till the time_idx along the time axis.

Warning

This is a destructive operation on the provided store, if it is write-enabled. Use with caution, because it will resize the datasets in the store to the extent determined by time_idx and all the data beyond that will be lost. Only in the case of time_idx = -1, may there be no data loss as the resize will occur to the same size as the time vector.

Parameters
  • store (hdf.Group) – root store of the model data (should be writable)

  • time_idx (int) – An integer indicating that index of the time point to truncate

Returns

size (int) – the size of the time dimension after truncation

microbenthos.model.saver module

Implements a data saver for model snapshots

microbenthos.model.saver.save_snapshot(fpath, snapshot, compression=6, shuffle=True)[source]

Save a snapshot dictionary of the model to a HDF file

This method preserves the nested structure of the model snapshot. If the specified file path already exists, then the snapshot data is recursively appended to the nested data structure within.

The nested data structure has three keys with special meaning:

  • "metadata"

    The dictionary under this key will be saved as HDF attributes of the group it is in.

  • "data"

    The value here is expected to be a tuple (data_array, meta_dict), and is saved as a HDF dataset with the attributes set from the meta_dict. This dataset will be appended to if future snapshots are appended to the file.

  • "data_static"

    This is similar to the data case, except it is for data that does not change during model evolution. So a fixed-size dataset called “data” is created here.

Note

Due to the recursive traversal of the snapshot, no guarantees are made that the data saving is done atomically for the dictionary. As far as possible, the file access is brief and done under a closing context of File.

Also, nested snapshot dictionaries with infinite self references in nodes will be problematic.

Parameters
  • fpath (str) – Path to the target HDF File

  • snapshot (dict) – Nested snapshot dictionary

  • compression (int) – The compression level 0-9 for the created Dataset (default: 6)

  • shuffle (bool) – Whether to use the shuffle filter

Raises
  • TypeError – if snapshot is not a suitable mapping type

  • ValueError – if saving fails due to incompatible data types

microbenthos.model.saver._save_nested_dict(D, root, **kwargs)[source]

Recursively traverse the nested dictionary and save data and metadata into a mirrored hierarchy

Parameters
  • D (dict) – A possibly nested dictionary with special keys

  • root (Group) – Reference to a node within the state hierarchy

microbenthos.model.saver._save_data(root, data, meta, name='data', **kwargs)[source]

Commit the data to the root node under the given name, and resize the target Dataset accordingly. The dataset is created, if it doesn’t exist.

microbenthos.model.simulation module

Module to handle the simulation of microbenthos models

class microbenthos.model.simulation.Simulation(simtime_total=6, simtime_days=None, simtime_lims=(0.1, 120), snapshot_interval=60, fipy_solver='scipy', max_sweeps=100, max_residual=1e-12)[source]

Bases: microbenthos.utils.create.CreateMixin

This class enables the process of repeatedly solving the model’s equations for a (small) time step to a certain numerical accuracy, and then incrementing the model clock. During the evolution of the simulation, the state of the model as well as the simulation is yielded repeatedly.

Numerically approximating the solution to a set of partial differential equations requires that the solver system has a reasonable target accuracy (“residual”) and enough attempts (“sweeps”) to reach both a stable and accurate approximation for a time step. This class attempts to abstract out these optimizations for the user, by performing adaptive time-stepping. The user needs to specify a worst-case residual ( max_residual), maximum number of sweeps per time-step ( max_sweeps) and the range of time-step values to explore during evolution (simtime_lims). During the evolution of the simulation, the time-step is penalized if the max residual is overshot or max sweeps reached. If not, the reward is a bump up in the time-step duration, allowing for faster evolution of the simulation.

See also

The scheme of simulation evolution().

The adaptive scheme to update_time_step().

schema_key = 'simulation'
FIPY_SOLVERS = ('scipy', 'pyAMG', 'trilinos', 'pysparse')
__init__(simtime_total=6, simtime_days=None, simtime_lims=(0.1, 120), snapshot_interval=60, fipy_solver='scipy', max_sweeps=100, max_residual=1e-12)[source]
Parameters
  • simtime_total (float, PhysicalField) – The number of hours for the

  • to run (simulation) –

  • simtime_days (float) – The number of days (in terms of the model’s irradiance cycle) the simulation should run for. Note that specifying this will override the given simtime_total when the model is supplied.

  • simtime_lims (float, PhysicalField) – The minimum and maximum

  • for the (limits) – simtime_step for adaptive time-stepping. This should be supplied as a pair of values, which are assumed to be in seconds and cast into PhysicalField internally. (default: 0.01, 240)

  • max_sweeps (int) – Maximum number of sweeps to attempt per

  • (default (timestep) –

  • max_residual (float) – Maximum residual value for the solver at a

  • (default – 1e-14)

  • snapshot_interval (int, float, PhysicalField) – the

  • in seconds (duration) – of the model clock between yielding snapshots of the model state for exporters (default: 60)

  • fipy_solver (str) – Name of the fipy solver to use. One of ('scipy', 'pyAMG', 'trilinos','pysparse') (default: “scipy”)

simtime_days

Numer of days to simulate in terms of the model’s irradiance source

property started

Returns: bool: Flag for if the sim evolution has started

property fipy_solver
property simtime_total

The number of hours of the model clock the simulation should be evolved for.

The supplied value must be larger than the time-steps allowed. Also, it may be over-ridden by supplying simtime_days.

Returns

PhysicalField – duration in hours

property simtime_step

The current time-step duration. While setting, the supplied value will be clipped to within simtime_lims.

Returns

PhysicalField – in seconds

property simtime_lims

The limits for the time-step duration allowed during evolution.

This parameter determines the degree to which the simulation evolution can be speeded up. In phases of the model evolution where the numerical solution is reached within a few sweeps, the clock would run at the max limit, whereas when a large number of sweeps are required, it would be penalized towards the min limit.

A high max value enables faster evolution, but can also lead to numerical inaccuracy ( higher residual) or solution breakdown (numerical error) during run_timestep(). A small enough min value allows recovery, but turning back the clock to the previous time step and restarting with the min timestep and allowing subsequent relaxation.

Parameters

vals (float, PhysicalField) – the (min, max) durations in seconds

Returns

lims (tuple) – The (min, max) limits of simtime_step each as a PhysicalField

property max_sweeps

The maximum number of sweeps allowed for a timestep

Parameters

val (int) – should be > 0

Returns

int

property model

The model to run the simulation on. This is typically an instance of MicroBenthosModel or its subclasses. The interface it must provide is:

  • a method create_full_equation()

  • an attribute full_eqn created by above method, which is a _BinaryTerm that has a sweep() method.

  • method model.update_vars() which is called before each

timestep

  • method model.clock.increment_time(dt)() which is called

after each timestep

Additionally, if simtime_days is set, then setting the model will try to find the "env.irradiance: object and use its hours_total attribute to set the simtime_total.

Parameters

model (MicroBenthosModel) – model instance

Returns

MicroBenthosModel

Raises
  • RuntimeError – if model has already been set

  • ValueError – if modes interface does not match

  • ValueError – if model model.full_eqn does not get created even after model.create_full_equation() is called.

_create_solver()[source]

Create the fipy solver to be used

run_timestep()[source]

Evolve the model through a single timestep

evolution()[source]

Evolves the model clock through the time steps for the simulation, i.e. by calling run_timestep() and model.clock.increment_time() repeatedly while model.clock() <= self.simtime_total.

This is a generator that yields the step number, and the state of the evolution after each time step. If snapshot_due() is true, then also the model snapshot is included in the state.

Yields

(step, state) tuple of step number and simulation state

Raises

RuntimeError – if started is already True

get_state(state=None, metrics=None, **kwargs)[source]

Get the state of the simulation evolution

Parameters
  • state (None, dict) – If state is given (from model.snapshot()), then that is used. If None, then just the time info is created by using model.clock.

  • metrics (None, dict) – a dict to get the simulation metrics from, else from kwargs

  • **kwargs – parameters to build metrics dict. Currently the keys “calc_time”, “residual” and “num_sweeps” are used, if available.

Returns

dict – the simulation state

snapshot_due()[source]
Returns

bool – If the current model clock time has exceeded snapshot_interval since the last snapshot time

update_simtime_step(residual, num_sweeps)[source]

Update the simtime_step to be adaptive to the current residual and sweeps.

A multiplicative factor for the time-step is determined based on the number of sweeps and residual. If the residual is more than max_residual, then the time-step is quartered. If not, it is boosted by up to double, depending on the num_sweeps and max_sweeps. Once a new timestep is determined, it is limited to the time left in the model simulation.

Parameters
  • residual (float) – the residual from the last equation step

  • num_sweeps (int) – the number of sweeps from the last equation step

Module contents