This tutorial is automatically generated from TestImmersedBoundaryTutorial at revision 98e266d4.
Note that the code is given in full at the bottom of the page.
This tutorial is a demonstration of the immersed boundary method, a technique
for simulating fluid-structure interactions. We can use the immersed boundary
method to simulate a cell as a structure with its outer boundary immersed
in a fluid. There is a two-way coupling between the fluid and the structure:
the flow of the fluid exerts a force on the structure, and the structure
influences the flow of the fluid.
In this tutorial, we demonstrate:
Building single-cell immersed boundary capable simulations.
Building multi-cellular immersed boundary simulations.
Adding and manipulating immersed boundary fluid sources.
We begin by exploring simulations containing a single cell. This will
familiarise you with how to generate immersed boundary cells, the steps
involved in setting up an immersed boundary simulation, and the options
available for controlling how the cells are generated and behave.
Immersed boundary simulations operate over a square domain, with x and y
coordinates lying in the range 0 to 1. The domain wraps on both axes -
this means that if a cell moves off the right hand edge of the domain,
the segment will appear on the left hand side. This is not purely visual;
forces are also transmitted across these boundaries.
Tip Make sure all your coordinates are between 0 and 1.
Setup the simulation environment in the notebook
Next, we define the necessary geometry by generating a mesh to
contain a single cell.
The first line of code defines an ImmersedBoundaryPalisadeMeshGenerator
called gen. The 3rd parameter controls the exponent of the superellipse(0.1)
and the 4th parameter controls the aspect ratio of the cell(2.0). You can
experiment with modifying these to change the initial shape of the cell.
The second line of code instructs the mesh generator to generate a mesh.
Checking the type of mesh with type(mesh) will show it as
ImmersedBoundaryMesh2_2. The 2_2 suffix denotes that we are using
a 2-dimensional space, and 2-dimensional elements to define the mesh.
We now set the fluid grid resolution. The following code specifies
that we are using a 64x64 grid to simulate our fluid over.
Next, we generate the cells. We specify a cell type and cell cycle model.
These can be changed to modify the life cycle of the cells. The
cell generator then constructs the necessary information for each
of the elements in the mesh.
Finally, we construct the cell population. We then specify whether the
population has active fluid sources or not. For now, we are not
using any fluid sources, so we set this to False
We can make a quick visualization of the cell population
Next, we create an OffLatticeSimulation simulator to control the
simulation. Although the fluid is simulated on a lattice (grid),
the nodes/cells are not bound to a lattice.
As we have an off-lattice simulation, we need a way to model the
fluid. This is handled by the ImmersedBoundarySimulationModifier.
Modifiers in Chaste are classes that can be attached to simulations
to perform some additional custom functionality each timestep.
In this case, the modifier is responsible for solving the
Navier-Stokes equations and propagating forces between the nodes and
the fluid.
We must also provide the modifier with a force model to govern
interactions between the nodes forming the cell membrane.
Note that these forces only act between nodes in the same cell;
they do not control interactions between cells.
The ImmersedBoundaryLinearMembraneForce models forces between
membrane nodes using linear springs i.e, the force applied is
proportional to the deviation of the distance between nodes
from a rest length. The spring constant(1.0 * 1e7) defines how
stiff the cell boundary is.
Practice Experiment with adjusting the spring constant to
change the force behaviour between nodes of the cell boundary.
Next, we set the simulation properties
We can add a modifier to visualize the cell population while the
simulation is in progress
Finally, to run the simulation we call the Solve() method.
In addition to the cells we have seen so far, we can introduce
laminas to the simulation. Laminas are surfaces with reduced
dimensionality. For 3D elements, a lamina is a 2D surface. For the
2D elements we are currently working with, laminas are lines.
Changing the last parameter of the mesh generator constructor from False
to True will generate a basal lamina spanning the palisade cells.
Laminas can also interact with the fluid field, and can be made
“leaky” to allow some flow across their boundary. This can be used
to model a permeable boundary.
Practice Try changing the 6th constructor parameter to create a lamina.
Apart from using the 3rd and 4th constructor parameters to modify
the cell shapes, we can also introduce variation between cells by
modifying the 5th parameter.
Practice Try adjusting the 3rd and 4th constructor parameters to
introduce cell variations.
Next, we generate the mesh and set the fluid grid resolution
Below, we generate the cells
Then we set up the cell population with no active fluid sources
We can visualize the cell population below
Now we create a simulator to manage the simulation
We add an immersed boundary simulation modifier to the simulator
We then add a force law to the simulation modifier to model the
behaviour of the cell membrane
So far, we have encountered forces that act to maintain the shape
of the cell membrane. We can also introduce an inter-cellular
force law using ImmersedBoundaryLinearInteractionForce.
This has a SetSpringConst method instead of a SetElementSpringConst
method. It also has a SetRestLength method that we can use to
modify the rest length.
Next, we set the simulation properties
Finally, we run the simulation
We can visualize the end state of the cell population
This constructs a FluidSource object in 2 dimensions. The first
parameter supplies the index of the fluid source. Each source we
create must have a unique index. The next two parameters are the
x and y coordinates of the source. Fluid sources in Chaste are
point-like, that is to say they do not have any area/volume.
Having created the fluid source, we set its strength:
Next, we create the mesh
We must associate the source with an element in the simulation
so that the simulation is aware of the source.
We now generate the cells
Then we set up the cell population
Finally, we must tell the cell population that fluid sources are present.
Practice Try modifying the spring constant of the
ImmersedBoundaryLinearMembraneForce to see how this changes the
effect of the fluid source on the cells.
Practice Try adding a second fluid source. You will need to
use a unique index, and attach it to a different element as
each element can only manage a single fluid source.
Next, we set the simulation properties
Finally, we run the simulation
Then we visualize the end state
Reset the simulation environment in the notebook
JUPYTER_TEARDOWN