lgca.square_ext.IBLGCA_Square

class lgca.square_ext.IBLGCA_Square(nodes=None, dims=None, restchannels=0, density=0.1, bc='periodic', seed=None, propagation=True, **kwargs)

Bases: IBLGCA_base, LGCA_Square

Identity-based LGCA simulator class.

add_family(ancestor_fam)

Create a new family and register it in the family tree.

Parameters:

ancestor_fam (int) – Family that the new one descends from.

Warning

Please do not call this unless you are writing an interaction function that deals with mutations.

It accesses self.maxfamily and self.family_props which do not exist if self.init_families() has not been called in the LGCA initialization.

apply_abc()

Apply absorbing boundary conditions.

Update self.nodes, using the shadow border nodes and respecting the geometry.

apply_inflowbc()

Apply inflow boundary conditions.

Update self.nodes, using the shadow border nodes and respecting the geometry.

Boundary condition for an inflow from x=0, y=:, with reflecting boundary conditions along the y axis and periodic boundaries along the x axis. Nodes at (x=0, y) are set to a homogeneous state with a constant average density given by the attribute 0 <= self.inflow <= 1.

If there is no such attribute, the nodes are filled with the maximum density.

apply_pbc()

Apply periodic boundary conditions.

Update self.nodes, using the shadow border nodes and respecting the geometry.

apply_rbc()

Apply reflecting boundary conditions.

Update self.nodes, using the shadow border nodes and respecting the geometry.

c = array([[ 1.,  0., -1.,  0.],        [ 0.,  1.,  0., -1.]])
calc_family_generations()

Calculate which generation each family belongs to, i.e. how many mutations have occurred. The list is returned and stored in self.family_props['generation'].

Returns:

Family generations indexed by family ID, helper root family = generation 0, families at the beginning of the simulation = generation 1.

calc_family_pop_alive()

Calculate how many cells of each family are alive.

Returns:

Array of family population counts indexed by family ID.

calc_flux(nodes)

Calculate the flux vector for all lattice sites in nodes.

The elements of the flux vectors are computed as the dot product between the LGCA’s neighborhood vectors and the velocity channel configuration in nodes.

Parameters:

nodes (numpy.ndarray) – Lattice configuration to compute the flux for. Must have more than or the same number of dimensions as self.nodes and nodes.shape[-1] >= self.velocitychannels. Is typically self.nodes.

Returns:

Array of flux vectors at each lattice site. Dimensions: nodes.shape[:-1] + (len(self.c),).

calc_generation_pop()

Calculate the current population per family generation.

Returns:

Cell numbers per generation, indexed by generation (helper root family is generation 0, families present at initialization are generation 1).

calc_generation_pop_t(cutoff_abs=None, cutoff_rel=None)

Calculate the population per family generation at each simulation step. Requires a previous self.timeevo() with recordfampop=True.

Parameters:
  • cutoff_abs (int) – Exclude families that never exceeded this population size in absolute numbers. cutoff_rel takes precedence over cutoff_abs.

  • cutoff_rel (float) – Exclude families that never exceeded this population size, expressed as a fraction of the total population. cutoff_rel takes precedence over cutoff_abs.

Returns:

Cell numbers per generation at each timestep (helper root family is generation 0, families present at initialization are generation 1). Dimensions: (timesteps+1, generations+1).

calc_init_families_pop()

Calculate the current population per family that was initialised in the beginning of the simulation (“initial ancestor”) and its descendants.

Returns:

  • init_families_pop (numpy.ndarray) – Population per initial family.

  • init_ancestor_IDs (numpy.ndarray) – Initial family ID corresponding to each position in init_families_pop.

calc_init_families_pop_t(cutoff_abs=None, cutoff_rel=None)

Calculate the current population per family that was initialised in the beginning of the simulation (“initial ancestor”) and its descendants at each simulation step. Requires a previous self.timeevo() with recordfampop=True.

Parameters:
  • cutoff_abs (int) – Exclude families that never exceeded this population size in absolute numbers. cutoff_rel takes precedence over cutoff_abs.

  • cutoff_rel (float) – Exclude families that never exceeded this population size, expressed as a fraction of the total population. cutoff_rel takes precedence over cutoff_abs.

Returns:

  • init_families_pop (numpy.ndarray) – Population per initial family at each timestep, dimensions: (timesteps+1, num_init_families+1).

  • init_ancestor_IDs (numpy.ndarray) – Family ID corresponding to each position on the family dimension in init_families_pop.

calc_permutations()

Initialize lazy computation structures for permutations. Only compute permutations when actually needed.

calc_prop_mean(nodes=None, props=None, propname=None)

Calculate the mean of particle property propname across the lattice configuration nodes.

Parameters:
  • nodes (numpy.ndarray, default=``self.nodes[self.nonborder]``) – Lattice configuration with particle IDs.

  • propname (hashable type, default=first key in props) – Key for the desired property in the props dictionary. If props is the default, propname needs to be a string.

  • props (dict, default=``self.props``) – Property dictionary that maps a property identifier, e.g. a name like 'r_b', to a 1d array or list of values for this property. Indices in the list/array must reflect the ID of the particle that the value is associated with. The value at the 0th element is used for empty lattice sites.

Returns:

Mean value of property propname among particles in each node, dimensions: self.dims.

See also

lgca.lgca_1d.IBLGCA_1D.plot_prop_spatial

Plot mean value of a property in all nodes over time.

lgca.lgca_square.IBLGCA_Square.plot_prop_spatial

Plot mean value of a property in all nodes. Also used for hexagonal IBLGCA.

calc_velocity_correlation(nodes=None)

Calculate the correlation between the node fluxes and the mean node flux in the neighborhood. Used to quantify correlated movement. Parameters ———- nodes : numpy.ndarray

Returns:

Scalar field with the same shape as self.cell_density.

calc_vorticity(nodes=None)

Calculate the vorticity of the flow field corresponding to the lgca state ‘nodes’. The vorticity is used to characterize rotations in a flow field. For more, see https://en.wikipedia.org/wiki/Vorticity Parameters ———- nodes : numpy.ndarray

Returns:

Scalar field with the same shape as self.cell_density.

channel_weight(qty)

Calculate weights for the velocity channels in interactions depending on a field qty.

The weight for the right/upwards/left/downwards velocity channel is given by the value of qty of the right/upwards/left/downwards neighboring node.

Parameters:

qty (numpy.ndarray) – Scalar field with the same shape as self.cell_density.

Returns:

Weights for the velocity channels of shape self.dims + (self.velocitychannels,).

cix = array([ 1.,  0., -1.,  0.])
ciy = array([ 0.,  1.,  0., -1.])
static convert_bool_to_ib(conf)

Convert the booleans in the lattice configuration of a classical LGCA with volume exclusion into unique particle identifiers.

Parameters:

conf (numpy.ndarray) – Lattice configuration for a classical LGCA with volume exclusion.

Returns:

Node configuration of conf converted to an identity-based LGCA. Dimensions: conf.shape.

dy = np.float64(1.0)
filter_family_population_t(fam_pop_t=None, cutoff_abs=None, cutoff_rel=None)

Mask out families from fam_pop_t that never exceeded the given population threshold.

Parameters:
  • cutoff_abs (int) – Exclude families that never exceeded this population size in absolute numbers. cutoff_rel takes precedence over cutoff_abs.

  • cutoff_rel (float) – Exclude families that never exceeded this population size, expressed as a fraction of the total population. cutoff_rel takes precedence over cutoff_abs.

  • fam_pop_t (numpy.ndarray, default=``self.fam_pop_t``) – Each family’s population size over time, dimensions: (timesteps + 1, num_families + 1).

Returns:

fam_pop_t with all population values for too small families set to 0, dimensions: (timesteps + 1, num_families + 1). Original fam_pop_t if both cutoff parameters are None.

get_flux_permutations(n_particles)

Get flux permutations for n_particles.

get_permutations(n_particles)

Get permutations for n_particles.

Parameters:

n_particles (int) – Number of occupied channels.

Returns:

Array of permutations for n_particles.

get_prop(nodes=None, props=None, propname=None)

Obtain the value of property propname for all particles in the lattice configuration nodes.

The value is drawn from the property dictionary props and placed in the channel that the respective particle resides in.

Parameters:
  • nodes (numpy.ndarray, default=``self.nodes[self.nonborder]``) – Lattice configuration with particle IDs.

  • propname (hashable type, default=first key in props) – Key for the desired property in the props dictionary. If props is the default, propname needs to be a string.

  • props (dict, default=``self.props``) – Property dictionary that maps a property identifier, e.g. a name like 'r_b', to a 1d array or list of values for this property. Indices in the list/array must reflect the ID of the particle that the value is associated with. The value at the 0th element is used for empty lattice sites.

Returns:

Lattice configuration with value for property propname associated to each particle instead of particle ID, dimensions: nodes.shape.

See also

calc_prop_mean

Calculate the mean of a particle property in each node.

plot_prop_timecourse

Plot the timecourse of the mean and standard deviation of a particle property across the lattice.

gradient(qty)

Compute the gradient of qty along all axes.

Parameters:

qty (numpy.ndarray) – Quantity to take the gradient of. Needs to have the same number of dimensions as self.nodes. If qty.shape == self.nodes.shape[:-1] the result can be indexed with the LGCA coordinates (see example).

Returns:

Computed gradient. Dimensions: qty.shape + (len(self.c),). If self and qty are 2D arrays, gradient(qty)[...,0] is the gradient in x direction and gradient(qty)[...,1] the gradient in y direction.

Notes

The gradient is calculated using numpy.gradient() with stepwidth h=0.5 (s.t. no normalization takes place). It is computed as the central finite difference with equidistant support points and supports one-sided differences at the boundaries.

In most cases this yields the simple difference between the two closest array elements in the given direction. For example, the gradient at position 1 of np.array([1, 2, 4]) would be (4 - 1)/(2 * 0.5) = 3.

Examples

If the input quantity has the same x (and y) dimensions as the LGCA’s nodes, the gradient at each node position can be accessed the same way as the node itself.

>>> from lgca import get_lgca
>>> import numpy as np
>>> # define a square LGCA to illustrate dimensions
>>> lgca = get_lgca(geometry='square', dims=(2,3))
>>> lgca.nodes.shape  # (xdim, ydim, number of channels)
(4, 5, 4)
>>> my_qty = np.array([[0,0,0,0,0],
>>>                    [1,1,1,1,1],
>>>                    [2,2,2,3,2],
>>>                    [3,3,3,3,3]])
>>> my_qty.shape  # (xdim, ydim)
(4, 5)
>>> grad = lgca.gradient(my_qty)
>>> grad.shape  # (xdim, ydim, number of dimensions)
(4, 5, 2)
>>> # address like internal LGCA fields: first dimension is x (printed vertically),
>>> # second dimension is y (printed horizontally), this can be a bit confusing
>>> for coord in lgca.coord_pairs:
>>>     if np.any(grad[coord]>2):
>>>         print("Gradient at index", coord, "is ", grad[coord])
>>>         print("Configuration at index ", coord, " is ", lgca.nodes[coord],
>>>               ", with cell density ", lgca.cell_density[coord])
Gradient at index (1, 3) is  [3. 0.]
Configuration at index  (1, 3)  is  [False False False  True] , with cell density  1

The first element of the gradient holds the gradient in x direction, the second element the gradient in y direction. Note that (1, 3) is the index corresponding to a logical non-border coordinate (0, 2) if the interaction radius is 1. This is relevant for defining a custom field qty: Only the field values at non-border indices will be “felt” by the particles in the LGCA if the interaction is defined accordingly, but border nodes can be used to specify the field’s boundary conditions.

The gradient in x direction is 3 = (3 - 0)/1. In y direction it is 0 = (1 - 1)/1.

init_coords()

Initialize LGCA coordinates.

These are used to index the lattice nodes logically and programmatically (see below). Initializes self.nonborder, self.xcoords, self.ycoords and self.coord_pairs.

See also

set_dims

Set LGCA dimensions.

init_nodes

Initialize LGCA lattice configuration.

set_r_int

Change the interaction radius.

Notes

self.xcoords and self.ycoords hold the logical coordinates of non-border nodes in x- and y-direction starting with 0. Non-border nodes belong to the lattice in the mathematical definition of the LGCA, while border nodes (=shadow nodes) are only included in order to implement boundary conditions. Note that since the lattice is two-dimensional, so are the coordinates.

>>> lgca = get_lgca(geometry='square', dims=3)
>>> lgca.xcoords
array([[0., 0., 0.],
       [1., 1., 1.],
       [2., 2., 2.]])
>>> lgca.ycoords
array([[0., 1., 2.],
       [0., 1., 2.],
       [0., 1., 2.]])

A column in the printout is a row in the LGCA lattice. self.nonborder holds the programmatical coordinates of non-border nodes, i.e. the indices of the self.nodes array where non-border nodes are stored. This is why it is a tuple: Because it is used to index a numpy array. All non-border lattice nodes can be called as self.nodes[self.nonborder].

>>> lgca = get_lgca(geometry='square', dims=2)  # default: periodic boundary conditions
>>> lgca.r_int
1
>>> lgca.nodes.sum(-1)  # show contents of the lattice
array([[1, 0, 1, 0],
       [0, 0, 0, 0],
       [1, 0, 1, 0],
       [0, 0, 0, 0]])
>>> lgca.nodes[lgca.nonborder].sum(-1)
array([[0, 0],
       [0, 1]])

Summing along the last axis means summing over all channels of a node since we are interested in the geometry. The first and the last row and column in the output of lgca.nodes.sum(-1) are the contents of the border (=shadow) nodes, which reflects the interaction radius of 1. The innermost four elements are the contents of the non-border nodes. Accordingly we find their indices to be:

>>> lgca.nonborder
(array([[1, 1],
        [2, 2]]),
 array([[1, 2],
        [1, 2]]))

The first element of the tuple is the index in x-direction, the second element the index in y-direction. Changing the interaction radius updates the shape of self.nodes by including more border (=shadow) nodes. This also changes the coordinates. With an interaction radius of 2, there is 2 border nodes on each side enveloping the non-border nodes whose contents remain the same. Therefore the first non-border node has the index 2 in each direction.

>>> lgca.set_r_int(2)  # change the interaction radius
>>> lgca.r_int
2
>>> lgca.nodes.sum(-1)  # show contents of the lattice
array([[0, 0, 0, 0, 0, 0],
       [0, 1, 0, 1, 0, 1],
       [0, 0, 0, 0, 0, 0],
       [0, 1, 0, 1, 0, 1],
       [0, 0, 0, 0, 0, 0],
       [0, 1, 0, 1, 0, 1]])
>>> lgca.nonborder
(array([[2, 2],
        [3, 3]]),
 array([[2, 3],
        [2, 3]]))

self.coord_pairs is a list of programmatical (x,y) coordinate tuples for iterating through nodes one by one.

>>> lgca.set_r_int(1)
>>> lgca.coord_pairs
[(1, 1), (1, 2), (2, 1), (2, 2)]
init_families(type='homogeneous', mutation=True)

Initialize structures to track inheritance between cells and/or cell families.

Initializes the 'family' property in self.props and, if needed, the counter self.maxfamily and the dictionary self.family_props. The 'ancestor' and 'descendants' properties in the latter can be used to reconstruct a family tree.

Parameters:
  • mutation (bool, default=True) – If true, mutation can occur so that offspring can have different properties and found its own family. The additional dictionary self.family_props and the counter self.maxfamily keep track of this. If false, the number of families is not supposed to increase during the simulation so that self.family_props and self.maxfamily are not needed.

  • type ({'homogeneous', 'heterogeneous'}, default='homogeneous') – Family composition for the initial population. If homogeneous, all initial cells belong to the same family and have the same properties. If heterogeneous, each initial cell founds its own family and can have individual properties that it passes on to its offspring.

See also

add_family

Add a family to the family tree after a mutation has occurred.

muller_plot

Draw a Muller plot for a simulation timecourse.

init_nodes(density=0.1, nodes=None, **kwargs)

Initialize LGCA lattice configuration. Create the lattice and then assign particles to channels in the nodes. In the implementation, set self.nodes.

Must match what is done in set_dims() and init_coords(). For arguments and attribute types see lgca.base.LGCA_base.

list_families_alive()

Calculate which families are alive and list their IDs.

Returns:

Array of family IDs in ascending order.

muller_plot(t_start_index=None, t_slice=slice(None, None, None), prop=None, cutoff_abs=None, cutoff_rel=None, **kwargs)

Draw a Muller plot from the LGCA simulation data (runtime, family tree, recorded family populations).

Parameters:
  • cutoff_abs (int) – Exclude families that never exceeded this population size in absolute numbers. cutoff_rel takes precedence over cutoff_abs.

  • cutoff_rel (float) – Exclude families that never exceeded this population size, expressed as a fraction of the total population. cutoff_rel takes precedence over cutoff_abs.

  • prop (hashable type, key of the dictionary self.family_props) – Colour the area for each family according to this family property. If None, colour area according to family identity.

  • t_slice (slice) – Which parts of the simulation time to consider for the plot.

  • t_start_index (int) – First number to appear on the x axis (time).

  • **kwargs – Keyword arguments to further style the plot drawn by lgca.plots.muller_plot().

Returns:

  • fig (matplotlib.figure.Figure) – Matplotlib figure handle.

  • ax (matplotlib.axes.Axes) – Muller plot axis handle.

  • (ret) – Handle of legend, handle of colourbar or None. The separate colourbar axis handle can be retrieved as ret.ax.

nb_sum(qty)

For each node, sum up the contents of qty for the 4 nodes in the von Neumann neughborhood, excluding the center.

qty is assumed to contain the value of a calculated quantity for each node in the lattice. nb_sum calculates the “neighborhood sum” of this quantity for each node, excluding the value for the node’s own position.

Parameters:

qty (numpy.ndarray) – Array holding some quantity of the LGCA, e.g. a flux. Of shape self.dims + x, where x is the shape of the quantity for one node, e.g. (2,) if it is a vector with 2 elements. self.dims ensures that lattice positions can be indexed the same way as in self.nodes.

Returns:

Sum of the content of qty in each node’s neighborhood, shape: qty.shape. Lattice positions can be indexed the same way as in self.nodes.

Examples

>>> lgca = get_lgca(geometry='square', dims=3) # periodic boundary conditions
>>> lgca.cell_density[lgca.nonborder]
array([[0, 1, 0],
       [0, 0, 0],
       [0, 1, 2]])
>>> lgca.nb_sum(lgca.cell_density).astype(int)[lgca.nonborder]
array([[1, 1, 3],
       [0, 2, 2],
       [3, 3, 1]])

lgca.cell_density is used as the argument qty. The value at each position in the resulting array is the sum of the values at the neighboring positions in the source array. Note that the reduction to the non-border nodes can only be done after the sum calculation in order to preserve boundary conditions.

num_families_alive()

Calculate how many families are alive.

Returns:

Number of families alive.

num_families_alive_t(cutoff_abs=None, cutoff_rel=None)

Calculate how many families have been alive at each simulation step. Requires a previous self.timeevo() with recordfampop=True.

Parameters:
  • cutoff_abs (int) – Exclude families that never exceeded this population size in absolute numbers. cutoff_rel takes precedence over cutoff_abs.

  • cutoff_rel (float) – Exclude families that never exceeded this population size, expressed as a fraction of the total population. cutoff_rel takes precedence over cutoff_abs.

Returns:

Number of families at each timestep, dimensions: timesteps+1.

num_families_total()

Calculate how many families there are in total, including extinct ones.

Returns:

Number of families.

num_families_total_t(cutoff_abs=None, cutoff_rel=None)

Calculate how many families there are in total at each timestep, including extinct ones.

Parameters:
  • cutoff_abs (int) – Exclude families that never exceeded this population size in absolute numbers. cutoff_rel takes precedence over cutoff_abs.

  • cutoff_rel (float) – Exclude families that never exceeded this population size, expressed as a fraction of the total population. cutoff_rel takes precedence over cutoff_abs.

Returns:

Number of families at each timestep, dimensions: timesteps+1.

plot_density(density=None, channels=slice(None, None, None), **kwargs)

Plot particle density in the lattice. A color bar on the right side shows the color coding of density values. Empty nodes are white.

Parameters:
  • cbar (bool, default=True) – Whether to draw a colorbar for the plot on an extra axis to the right.

  • cbarlabel (str, default='Particle number $n$') – Label of the colorbar.

  • channels (slice) – Indices of the velocity/resting channels that should be considered for the density calculation if density is None.

  • cmap (str or matplotlib.colors.Colormap, default=’viridis’) – Color map for the density values. Used to construct a discretized version of the colormap.

  • colorbarwidth (float) – Width of the additional axis for the color bar, passed to mpl_toolkits.axes_grid1.axes_divider.AxesDivider.append_axes().

  • density (numpy.ndarray, optional) – Particle density values for a lattice to plot. If set to None and a simulation has been performed before, the result of the simulation is plotted. Dimensions: self.dims.

  • edgecolor ({matplotlib color, ‘None’, ‘auto’}, default ‘None’) – Color of the polygon edges for the lattice nodes.

  • figindex (int or str, optional) – An identifier for the figure (passed to matplotlib.pyplot.figure()). If it is a string, the figure label and the window title is set to this value.

  • figsize (tuple of int or tuple of float with 2 elements, default=(8,8)) – Desired figure size in inches (x, y).

  • tight_layout (bool, default=True) – If matplotlib.figure.Figure.tight_layout() is called for padding between and around subplots.

  • vmax (int, optional) – Maximum density value for the color scaling. The minimum value is zero. All density values higher than vmax are drawn in the color at the end of the color bar. If None, vmax is set to the number of channels self.K.

  • **kwargs – Arguments to be passed on to setup_figure().

Returns:

Density plot over time.

See also

setup_figure

Manage basic layout.

plot_prop_timecourse(nodes_t=None, props=None, propname=None, figindex=None, figsize=None, **kwargs)

Plot the time course of the mean and standard deviation of particle property propname across the lattice.

The mean is plotted as a line with the standard deviation shadowed in both directions.

Parameters:
  • figindex (int or str, optional) – An identifier for the figure (passed to matplotlib.pyplot.figure()). If it is a string, the figure label and the window title is set to this value.

  • figsize (tuple of int or tuple of float with 2 elements, optional) – Desired figure size in inches (x, y).

  • nodes_t (numpy.ndarray, default=``self.nodes_t``) – Lattice configuration with particle IDs over time, first dimension: time.

  • propname (hashable type, default=first key in props) – Key for the desired property in the props dictionary. If props is the default, propname needs to be a string.

  • props (dict, default=``self.props``) – Property dictionary that maps a property identifier, e.g. a name like 'r_b', to a 1d array or list of values for this property. Indices in the list/array must reflect the ID of the particle that the value is associated with. The value at the 0th element is used for empty lattice sites.

  • **kwargs – Keyword arguments for the matplotlib.pyplot.plot() command.

Returns:

  • line (matplotlib.lines.Line2D) – Plot of the mean property over time.

  • errors (matplotlib.collections.PolyCollection) – Polygons representing the standard deviation of the property over time, in both directions.

print_interactions()

Print the list of pre-implemented interactions for this LGCA type.

print_nodes()

Print the full lattice configuration as integers.

propagate_ancestor_to_descendants()

Traverse family tree to find the families that were initialised in the beginning of the simulation (“initial ancestors”) and which families descend from them, including the 2nd, 3rd, … generations.

Returns:

Initial ancestors indexed by family ID. The helper root family and initial ancestors have 0, all others their ancestor’s family ID.

propagate_family_prop_to_cells(prop)

Propagate a family property down to all cells that belong to the family. Uses contents of self.family_props[prop] to create a new cell property self.props[prop]

Parameters:

prop (str) – Key of the family property in self.family_props[prop].

static propagate_pop_to_parents(pop_t, ancestor)

Propagate family population in pop_t to all ancestors recorded in ancestor.

Parameters:
  • pop_t (numpy.ndarray) – Population of each family for all timesteps, dimensions: (timesteps, num_families).

  • ancestor (list) – Record of each family’s parent (initially existing families have 0), length: num_families + 1.

Returns:

Family populations over time summed up to all ancestors recursively, cum_pop_t[:, 0] holds total population over time.

See also

muller_plot

Draw a Muller plot for a simulation timecourse.

propagation()

Perform the transport step of the LGCA: Move particles through the lattice according to their velocity.

Updates self.nodes such that resting particles (the contents of self.nodes[:, 4:]) stay in their position and particles in velocity channels (the contents of self.nodes[:, :4]) are relocated according to the direction of the channel they reside in. Boundary conditions are enforced later by apply_boundaries().

See also

base.LGCA_base.nodes

State of the lattice showing the structure of the lgca.nodes array.

Notes

>>> # set up the node configuration
>>> nodes = np.zeros((3,3,5)).astype(bool)
>>> nodes[1,1,:] = True
>>> lgca = get_lgca(geometry='square', nodes=nodes)
>>> lgca.cell_density[lgca.nonborder]
array([[0, 0, 0],
       [0, 5, 0],
       [0, 0, 0]])
>>> lgca.nodes[lgca.nonborder]
       # left column of the lattice
array([[[False, False, False, False, False],
        [False, False, False, False, False],
        [False, False, False, False, False]],
       # central column
       [[False, False, False, False, False],
        [ True,  True,  True,  True,  True], # node (1,1): all channels are filled
        [False, False, False, False, False]],
       # right column
       [[False, False, False, False, False],
        [False, False, False, False, False],
        [False, False, False, False, False]]])

Before propagation, five particles occupy the central node. One resides in the velocity channel to the right, one in the velocity channel upwards, one in the velocity channel to the left, one in the velocity channel downwards and one in the resting channel.

>>> lgca.propagation()
>>> lgca.update_dynamic_fields()  # to update lgca.cell_density
>>> lgca.cell_density[lgca.nonborder]
array([[0, 1, 0],
       [1, 1, 1],
       [0, 1, 0]])
>>> lgca.nodes[lgca.nonborder]
       # left column of the lattice
array([[[False, False, False, False, False],
        [False, False,  True, False, False], # node (0,1): particle moving to the left
        [False, False, False, False, False]],
       # central column
       [[False, False, False,  True, False], # node (1,0): particle moving downwards
        [False, False, False, False,  True], # node (1,1): resting particle
        [False,  True, False, False, False]], # node (1,2): particle moving upwards
       # right column
       [[False, False, False, False, False],
        [ True, False, False, False, False], # node (2,1): particle moving to the right
        [False, False, False, False, False]]])

The particle with velocity to the right has moved to the right velocity channel in the central node of the right side of the lattice (second to last line of the output). The particles in the other velocity channels have also moved according to their direction (see output annotation). The resting particle stayed in its channel in the very center.

r_poly = np.float64(0.7071067811865475)
random_reset(density)

Randomly fill channels so that each node has on average density particles.

Each channel is independently occupied with probability density / self.K.

Parameters:

density (float) – Desired average number of particles per node. density = total_number_of_particles / number_of_nodes.

set_bc(bc)

Set the boundary conditions.

Selects a method which is called every timestep to enforce boundary conditions. The methods to select from are implemented in the derived classes. The chosen one is assigned to self.apply_boundaries().

Parameters:

bc ({'absorbing', 'reflecting', 'periodic', 'inflow'}) – Boundary conditions. Not all bc are supported in all geometries (yet).

set_dims(dims=None, nodes=None, restchannels=0)

Set LGCA dimensions.

Initializes self.K, self.restchannels, self.dims, self.lx and self.ly.

Parameters:
  • dims (int or tuple, default=(50,50)) – Lattice dimensions. Must match with specified geometry, an integer is interpreted as (dims, dims).

  • nodes (np.ndarray) – Custom initial lattice configuration.

  • restchannels (int, default=0) – Number of resting channels.

set_interaction(**kwargs)

Set the interaction rule and respective needed parameters.

Set self.interaction and possibly add entries in self.interaction_params and self.props. If inheritance is involved, initialize self.family_props and self.maxfamily. Do not use this to specify a custom interaction. In order to do this (as of now), self.interaction and self.interaction_params must be manipulated directly from an external script.

Parameters:
  • kwargs['interaction'] (str, default='random_walk') – Name of the predefined interaction in lgca.interactions.

  • **kwargs – Interaction parameters.

set_r_int(r)

Change the interaction radius. Update shadow border nodes accordingly.

This has effects on self.nodes, the coordinates and the computed fields.

Parameters:

r (int) – New interaction radius.

setup_figure(figindex=None, figsize=(8, 8), tight_layout=True)

Create a matplotlib figure and manage basic layout.

Used by the class’ plotting functions.

Parameters:
  • figindex (int or str, optional) – An identifier for the figure (passed to matplotlib.pyplot.figure()). If it is a string, the figure label and the window title is set to this value.

  • figsize (tuple of int or tuple of float with 2 elements, default=(8,8)) – Desired figure size in inches (x, y).

  • tight_layout (bool, default=True) – If matplotlib.figure.Figure.tight_layout() is called for padding between and around subplots.

Returns:

  • fig (matplotlib.figure.Figure) – New customized figure.

  • ax (matplotlib.axes.Axes) – Drawing axis associated with fig.

See also

plot_density

Plot particle density over time.

plot_flux

Plot flux over time.

timeevo(timesteps=100, record=False, recordN=False, recorddens=True, showprogress=True, recordfampop=False)

Perform a simulation of the LGCA for timesteps timesteps.

Different quantities can be recorded during the simulation, e.g. the total number of particles at each timestep. They are stored in LGCA attributes.

Parameters:
  • timesteps (int, default=100) – How long the simulation should be performed.

  • record (bool, default=False) – Record the full lattice configuration for each timestep in self.nodes_t.

  • recorddens (bool, default=True) – Record the number of particles at each lattice site for each timestep in self.dens_t.

  • recordfampop (bool, default=False) – Record the population of all families for each timestep in self.fam_pop_t.

  • recordN (bool, default=False) – Record the total number of particles in the lattice for each timestep in self.n_t.

  • showprogress (bool, default=True) – Show a simple progress bar with a percentage of performed timesteps in the standard output.

timestep()

Update the state of the LGCA from time k to k+1. Includes the interaction and propagation steps.

total_population()

Calculate the amount of particles in the lattice.

Returns:

Total population size.

total_population_t(cutoff_abs=None, cutoff_rel=None)

Calculate the total population of cells at each simulation step. Requires a previous self.timeevo() with recordfampop=True due to the filtering option.

Parameters:
  • cutoff_abs (int) – Exclude families that never exceeded this population size in absolute numbers. cutoff_rel takes precedence over cutoff_abs.

  • cutoff_rel (float) – Exclude families that never exceeded this population size, expressed as a fraction of the total population. cutoff_rel takes precedence over cutoff_abs.

Returns:

Number of cells at each timestep, dimensions: timesteps+1.

update_dynamic_fields()

Update “fields” from the current LGCA state that store important variables to compute other dynamic steps.

Computes self.cell_density, number of particles at each lattice node, and self.occupied, a boolean array that shows which channels are occupied.