In this tutorial, we show how to create a new cell-based simulation modifier
and use this in a cell-based simulation. The simulation modifier class
hierarchy is used to implement setup, update and finalise methods in cell-based
simulations.
As in previous cell-based Chaste tutorials, we begin by including the necessary
header file and archiving headers.
The next header defines a base class for cell-based simulation modifiers.
Our new modifier class will inherit from this abstract class.
The remaining header files define classes that will be used in the cell-based
simulation test. We have encountered each of these header files in previous cell-based
Chaste tutorials.
Defining the cell-based simulation modifier class#
As an example, let us consider a simulation modifier that, at each simulation
time step, calculates each cell’s height (y coordinate) in a two-dimensional
domain and stores it in in the CellData property as “height”. This might be
used, for example in cell-based simulations where cell behaviour is dictated
through some form of positional information along a tissue axis.
Note that usually this code would be separated out into a separate declaration
in a .hpp file and definition in a .cpp file.
Also, while the abstract simulation modifier class is templated over dimensions,
for simplicity we hardcode this concrete modifier class to work in 2D only.
The first public method is a default constructor, which simply calls the base
constructor.
The next public method is a destructor, which calls the base destructor.
Next, we override the UpdateAtEndOfTimeStep() method, which specifies what
to do to the simulation at the end of each time step. In this class, we simply
call the method UpdateCellData() on the cell population; this method is
defined later in the class definition.
The next overridden method, SetupSolve(), specifies what to do to the
simulation before the start of the time loop. In this class, we call
UpdateCellData() on the cell population, just as in
UpdateAtEndOfTimeStep(). This is needed because otherwise
CellData will not have been fully initialised when we enter
the main time loop of the simulation.
Next, we define the UpdateCellData() method itself. This is a helper
method that computes the height (y coordinate) of each cell in the population
and stores this in the CellData property.
We begin by calling Update() on the cell population, which ensures that
it is in a coherent state.
Next, we iterate over the cell population…
…find its height…
…and store this in the CellData item “height”.
Finally, we must override the OutputSimulationModifierParameters() method, which
outputs to file any parameters that are defined in the class. In this class, there are
no such parameters to output, so we simply call the method defined on the direct
parent class (in this case, the abstract class).
This concludes the definition of the CellHeightTrackingModifier class.
As mentioned in previous cell-based Chaste tutorials, we need to include the next block
of code to be able to archive the simulation modifier object in a cell-based simulation,
and to obtain a unique identifier for our new class for when writing results to file.
The identifiers for this class are defined together here, since we can only have each
#include once in this source file. Normally the first include and export would go in
the class’s header file, and the second #include and export would go in in the .cpp file.
We conclude with a brief test demonstrating how CellHeightTrackingModifier can be used
in a cell-based simulation.
In this case, we choose to create a small NodeBasedCellPopulation comprising 25 cells.
We choose a cut-off for mechanical interactions between cells of 1.5 units and add a
simple ReplusionForce to the simulation. We use a UniformCellCycleModel
to implement some random proliferation in the simulation.
Finally, we add a CellHeightTrackingModifier to the simulation.
To run the simulation, we call Solve().
It is most straightforward to visualize the results of this simulation in Paraview.
Load the file /tmp/$USER/testoutput/TestOffLatticeSimulationWithCellHeightTrackingModifier/results_from_time_0/results.pvd,
and add glyphs to represent cells.