Test Tensile Test Tutorial On this page This tutorial is automatically generated from TestTensileTestTutorial at revision 98e266d4 .
Note that the code is given in full at the bottom of the page.
Introduction# In this tutorial we will demonstrate a simulated tensile test on an epithelial sheet. This test
demonstrates:
Working with vertex based off lattice populations Applying boundary conditions Working with forces The Test# import unittest # Python testing framework
import numpy as np # Matrix tools
import chaste # The PyChaste module
import chaste.mesh # Contains meshes
import chaste.cell_based # Contains cell populations
import chaste.visualization # Visualization tools
chaste . init () # Set up MPI
class TestTensileTestTutorial ( chaste . cell_based . AbstractCellBasedTestSuite ):
Test 1 - A 2D test# def test_monolayer ( self ):
# JUPYTER_SETUP
First, we generate a vertex mesh using a HoneycombVertexMeshGenerator.
generator = chaste . mesh . HoneycombVertexMeshGenerator ( 5 , 15 )
mesh = generator . GetMesh ()
Now set up the cells, again we want to avoid proliferation.
differentiated_type = chaste . cell_based . DifferentiatedCellProliferativeType ()
cell_generator = chaste . cell_based . CellsGeneratorUniformG1GenerationalCellCycleModel_2 ()
cells = cell_generator . GenerateBasicRandom ( mesh . GetNumElements (), differentiated_type )
Next, create the cell population
cell_population = chaste . cell_based . VertexBasedCellPopulation2 ( mesh ,
cells )
Pass the cell population into an OffLatticeSimulation
, and set the output directory, output multiple and end time
simulator = chaste . cell_based . OffLatticeSimulation2_2 ( cell_population )
simulator . SetOutputDirectory ( "Python/TestTensileTest" )
simulator . SetEndTime ( 1.0 )
simulator . SetSamplingTimestepMultiple ( 1000 )
Now create a force law
force = chaste . cell_based . NagaiHondaForce2 ()
simulator . AddForce ( force )
A NagaiHondaForce
assumes that each cell has a target area. The target areas of cells are used to determine
pressure forces on each vertex and eventually determine the size of each cell in the simulation.
In order to assign target areas to cells and update them in each time step we add a SimpleTargetAreaModifier
to the simulation, which inherits from AbstractTargetAreaModifier
.
growth_modifier = chaste . cell_based . SimpleTargetAreaModifier2 ()
simulator . AddSimulationModifier ( growth_modifier )
For our tensile test we will fix the bottom of the sheet and subject the top to an applied displacement. We neglect
fixing lateral degress of freedom for simplicity, since we are using an over-damped mechanical model.
my_point = np . array ([ 0.0 , 0.0 ])
normal = np . array ([ 0.0 , - 1.0 ])
bc = chaste . cell_based . AttractingPlaneBoundaryCondition2_2 ( cell_population , my_point , normal )
simulator . AddCellPopulationBoundaryCondition ( bc )
point = np . array ([ 0.0 , 15.5 ])
normal = np . array ([ 0.0 , - 1.0 ])
bc2 = chaste . cell_based . AttractingPlaneBoundaryCondition2_2 ( cell_population , point , normal )
simulator . AddCellPopulationBoundaryCondition ( bc2 )
We want to displace our top boundary over time. We could write a custom boundary condition class to do this.
A more simple alternative is to modify the the position of the point describing our boundary plane in bc2
as the simulation progresses. As per earlier tutorials we make a new SimulationModifier
class to do this.
class BoundaryConditionModifier ( chaste . cell_based . PythonSimulationModifier2 ):
""" Class for time varying boundary conditions
"""
def __init__ ( self , boundary_condition ):
self . boundary_condition = boundary_condition
self . original_location = boundary_condition . rGetPointOnPlane ()
self . velocity = 0.5 # cell lengths per time
super ( BoundaryConditionModifier , self ) . __init__ ()
def UpdateAtEndOfTimeStep ( self , cell_population ):
""" Move the boundary upwards at the specified velocity
"""
total_time = chaste . cell_based . SimulationTime . Instance () . GetTime ()
new_location = [ self . original_location [ 0 ],
self . original_location [ 1 ] + self . velocity * total_time ]
self . boundary_condition . SetPointOnPlane ( np . array ( new_location ))
def SetupSolve ( self , cell_population , output_directory ):
""" Make sure the cell population is in the correct state at the start of the simulation
"""
cell_population . Update ()
bc_modifier = BoundaryConditionModifier ( bc2 )
simulator . AddSimulationModifier ( bc_modifier )
PyChaste can do simple 3D rendering with VTK. We set up a VtkScene
so that we can see the population
evovle in real time.
scene = chaste . visualization . VtkScene2 ()
scene . SetCellPopulation ( cell_population )
# JUPYTER_SHOW_FIRST
scene_modifier = chaste . cell_based . VtkSceneModifier2 ()
scene_modifier . SetVtkScene ( scene )
scene_modifier . SetUpdateFrequency ( 1000 )
simulator . AddSimulationModifier ( scene_modifier )
To run the simulation, we call Solve()
.
scene . Start ()
simulator . Solve ()
# JUPYTER_TEARDOWN
if __name__ == '__main__' :
unittest . main ( verbosity = 2 )
Full code# File name: TestTensileTestTutorial.py
import unittest # Python testing framework
import numpy as np # Matrix tools
import chaste # The PyChaste module
import chaste.mesh # Contains meshes
import chaste.cell_based # Contains cell populations
import chaste.visualization # Visualization tools
chaste . init () # Set up MPI
class TestTensileTestTutorial ( chaste . cell_based . AbstractCellBasedTestSuite ):
def test_monolayer ( self ):
# JUPYTER_SETUP
generator = chaste . mesh . HoneycombVertexMeshGenerator ( 5 , 15 )
mesh = generator . GetMesh ()
differentiated_type = chaste . cell_based . DifferentiatedCellProliferativeType ()
cell_generator = chaste . cell_based . CellsGeneratorUniformG1GenerationalCellCycleModel_2 ()
cells = cell_generator . GenerateBasicRandom ( mesh . GetNumElements (), differentiated_type )
cell_population = chaste . cell_based . VertexBasedCellPopulation2 ( mesh ,
cells )
simulator = chaste . cell_based . OffLatticeSimulation2_2 ( cell_population )
simulator . SetOutputDirectory ( "Python/TestTensileTest" )
simulator . SetEndTime ( 1.0 )
simulator . SetSamplingTimestepMultiple ( 1000 )
force = chaste . cell_based . NagaiHondaForce2 ()
simulator . AddForce ( force )
growth_modifier = chaste . cell_based . SimpleTargetAreaModifier2 ()
simulator . AddSimulationModifier ( growth_modifier )
my_point = np . array ([ 0.0 , 0.0 ])
normal = np . array ([ 0.0 , - 1.0 ])
bc = chaste . cell_based . AttractingPlaneBoundaryCondition2_2 ( cell_population , my_point , normal )
simulator . AddCellPopulationBoundaryCondition ( bc )
point = np . array ([ 0.0 , 15.5 ])
normal = np . array ([ 0.0 , - 1.0 ])
bc2 = chaste . cell_based . AttractingPlaneBoundaryCondition2_2 ( cell_population , point , normal )
simulator . AddCellPopulationBoundaryCondition ( bc2 )
class BoundaryConditionModifier ( chaste . cell_based . PythonSimulationModifier2 ):
""" Class for time varying boundary conditions
"""
def __init__ ( self , boundary_condition ):
self . boundary_condition = boundary_condition
self . original_location = boundary_condition . rGetPointOnPlane ()
self . velocity = 0.5 # cell lengths per time
super ( BoundaryConditionModifier , self ) . __init__ ()
def UpdateAtEndOfTimeStep ( self , cell_population ):
""" Move the boundary upwards at the specified velocity
"""
total_time = chaste . cell_based . SimulationTime . Instance () . GetTime ()
new_location = [ self . original_location [ 0 ],
self . original_location [ 1 ] + self . velocity * total_time ]
self . boundary_condition . SetPointOnPlane ( np . array ( new_location ))
def SetupSolve ( self , cell_population , output_directory ):
""" Make sure the cell population is in the correct state at the start of the simulation
"""
cell_population . Update ()
bc_modifier = BoundaryConditionModifier ( bc2 )
simulator . AddSimulationModifier ( bc_modifier )
scene = chaste . visualization . VtkScene2 ()
scene . SetCellPopulation ( cell_population )
# JUPYTER_SHOW_FIRST
scene_modifier = chaste . cell_based . VtkSceneModifier2 ()
scene_modifier . SetVtkScene ( scene )
scene_modifier . SetUpdateFrequency ( 1000 )
simulator . AddSimulationModifier ( scene_modifier )
scene . Start ()
simulator . Solve ()
# JUPYTER_TEARDOWN
if __name__ == '__main__' :
unittest . main ( verbosity = 2 )