AnisotropicGrowth

Problem

Consider a unit cube tissue, where diffusible growth-inducing morphogen is produced with a rate proportional to the z-axis:

\(\frac{dc}{dt} = D\nabla^2c + e^z - dc\)

where \(c\) is concentration of a morphogen, \(D\) is a diffusion constant and \(d\) is a degradation rate.

Initialise

To implement this problem using morphosolver, we should create a new tissue class (TissueBase) add a new chemical (Chemical) and set it’s diffusion and reaction rates using setDiffusion() and setReaction() methods during the initialisation stage:

class AnisotropicGrowthTissue(TissueBase):
	def init(self):
		self.chemical = Chemical(self, 'morphogen')
		self.chemical.setDiffusion(self.params['D'])
		self.chemical.setReaction( Expression("exp(x[2])", degree = 3) - self.params['d'] * self.chemical.c0 )

We then add an anisotropic growth function(AnisoGrowthFunction) object to the tissue:

		self.growthFunction = AnisoGrowthFunction(self)

Update

Then during the update step, we should update the chemical state using the update() method:

	def update(self, dt):
		self.chemical.update(dt)

apply growth rate proportional to the chemical concentration using projectAGG() method and update the growth tensor \(\mathbf{G}\) of the tissue using the updateG() method of the growth function:

		self.growthFunction.projectAGG(a = Constant(self.params['a']), g = 0.1*self.chemical, gamma = Constant(self.params['g']) )
		self.growthFunction.updateG(dt)

Run

To simulate the problem, we create a new instance of the AnisotropicGrowthTissue:

	tissue = AnisotropicGrowthTissue(params = params)

create and run the simulation:

	simulator = Simulator(tissue)
	simulator.run(params['dt'], params['n'])

Complete listing

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
from morphosolver import *
from dolfin import *

import argparse

class AnisotropicGrowthTissue(TissueBase):
	def init(self):
		self.chemical = Chemical(self, 'morphogen')
		self.chemical.setDiffusion(self.params['D'])
		self.chemical.setReaction( Expression("exp(x[2])", degree = 3) - self.params['d'] * self.chemical.c0 )

		self.growthFunction = AnisoGrowthFunction(self)

	def update(self, dt):
		self.chemical.update(dt)

		self.growthFunction.projectAGG(a = Constant(self.params['a']), g = 0.1*self.chemical, gamma = Constant(self.params['g']) )
		self.growthFunction.updateG(dt)

if __name__ == "__main__":
	
	parser = argparse.ArgumentParser(description=
	'''
	Morphosolver demo: Anisotropic growth\n\
	-------------------------------------\n\n\
	Simulates reaction diffusion of a chemical [c] with reaction term r = e^(z) - 0.1*c on a UnitCubeMesh\
	''', formatter_class = argparse.RawTextHelpFormatter)

	parser.add_argument('-a',		metavar = 'anisotropy',	type = float,	default = 0.8,	help = 'Anisotropy of a tissue [0,1]. Default a = 0.8' )
	parser.add_argument('-g', metavar=('gx', 'gy', 'gz'), nargs=3, default = [0,0,1], help='Vector of anispotropy. Default g = [0.0, 0.0, 1.0]')

	parser.add_argument('-D',		metavar = 'diffusion',	type = float,	default = 0.1,	help = 'Diffusion rate. Default D = 0.1' )
	parser.add_argument('-d',		metavar = 'deg',		type = float,	default = 0.1,	help = 'Degradaion rate. Default d = 0.1' )

	parser.add_argument('-n',		metavar = 'steps',		type = int,		default = 20, 	help = 'Number of timesteps. Default steps = 20')
	parser.add_argument('-dt',								type = float,	default = 0.1, 	help = 'Timestep. Default dt = 0.1')

	params =  vars(parser.parse_args())

	tissue = AnisotropicGrowthTissue(params = params)
	
	simulator = Simulator(tissue)
	simulator.run(params['dt'], params['n'])