Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Jigyasa Watwani
/
growth-pattern-control
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
e38db8a2
authored
May 20, 2024
by
Jigyasa Watwani
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fully working 2D problem with remeshing and extend functionality
parent
82d74da7
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
375 additions
and
572 deletions
growing_domain/full_model/growing_domain.py
growing_domain/full_model/parameters.json
growing_domain/full_model/run_growing_domain.py
growing_domain/full_model/viz_growing_domain.py
growing_domain/full_model/growing_domain.py
View file @
e38db8a2
import
dolfin
as
df
import
numpy
as
np
import
os
import
progressbar
import
meshzoo
import
matplotlib.pyplot
as
plt
df
.
set_log_level
(
df
.
LogLevel
.
ERROR
)
df
.
parameters
[
'form_compiler'
][
'optimize'
]
=
True
class
Growing_Domain
(
object
):
def
__init__
(
self
,
parameters
):
def
__init__
(
self
,
parameters
,
mesh
=
None
):
# read in parameters
for
key
in
parameters
:
setattr
(
self
,
key
,
parameters
[
key
])
# create mesh, mixed element and function space
L
=
self
.
system_size
if
self
.
dimension
==
1
:
self
.
mesh
=
df
.
IntervalMesh
(
self
.
resolution
,
0.0
,
L
)
assert
self
.
bulk_elasticity
==
self
.
shear_elasticity
assert
self
.
bulk_viscosity
==
self
.
shear_viscosity
elif
self
.
dimension
==
2
:
# if no mesh is given as initial condition, create one
if
mesh
is
None
:
points
,
cells
=
meshzoo
.
disk
(
10
,
8
)
self
.
mesh
=
df
.
Mesh
()
e
=
df
.
MeshEditor
()
...
...
@@ -32,27 +26,22 @@ class Growing_Domain(object):
for
i
in
range
(
len
(
cells
)):
e
.
add_cell
(
i
,
cells
[
i
])
e
.
close
()
else
:
self
.
mesh
=
mesh
def
setup
(
self
):
scalar_element
=
df
.
FiniteElement
(
'P'
,
self
.
mesh
.
ufl_cell
(),
1
)
vector_element
=
df
.
VectorElement
(
'P'
,
self
.
mesh
.
ufl_cell
(),
1
)
if
self
.
morphogen
:
# u, v, rho, c
mixed_element
=
df
.
MixedElement
([
vector_element
,
vector_element
,
scalar_element
,
scalar_element
])
else
:
# u, v, rho
mixed_element
=
df
.
MixedElement
([
vector_element
,
vector_element
,
scalar_element
])
# u, v, rho
mixed_element
=
df
.
MixedElement
([
vector_element
,
vector_element
,
scalar_element
])
# define function space with this mixed element
self
.
function_space
=
df
.
FunctionSpace
(
self
.
mesh
,
mixed_element
)
# dirichlet boundaries for rho
if
self
.
dirichlet_boundary_rho
:
if
self
.
zero_rho_boundary
:
self
.
bc
=
df
.
DirichletBC
(
self
.
function_space
.
sub
(
2
),
df
.
Constant
(
0.0
),
'on_boundary'
)
elif
self
.
rho0_boundary
:
self
.
bc
=
df
.
DirichletBC
(
self
.
function_space
.
sub
(
2
),
df
.
Constant
(
self
.
average_rho
),
'on_boundary'
)
self
.
bc
=
df
.
DirichletBC
(
self
.
function_space
.
sub
(
2
),
df
.
Constant
(
0.0
),
'on_boundary'
)
# define the reqd functions on this function space
self
.
f
=
df
.
Function
(
self
.
function_space
)
# f at current time
...
...
@@ -60,23 +49,21 @@ class Growing_Domain(object):
def
advection
(
self
,
conc
,
vel
,
tconc
):
return
df
.
inner
(
df
.
div
(
vel
*
conc
),
tconc
)
def
active_stress
(
self
,
rho
,
c
,
v
):
if
self
.
saturating_density_active_stress
:
return
self
.
lamda
*
rho
/
(
rho
+
self
.
saturation_rho
)
*
df
.
Identity
(
self
.
dimension
)
elif
self
.
difference_in_morphogen_active_stress
:
return
self
.
lamda
*
(
c
-
self
.
average_c
)
*
df
.
Identity
(
self
.
dimension
)
elif
self
.
difference_in_density_active_stress
:
return
self
.
lamda
*
(
c
-
self
.
average_rho
)
*
df
.
Identity
(
self
.
dimension
)
def
qtensor
(
self
):
q
=
df
.
Expression
(((
'q_xx'
,
'q_xy'
),
(
'q_yx'
,
'q_yy'
)),
q_xx
=
self
.
q_xx
,
q_xy
=
self
.
q_xy
,
q_yx
=
self
.
q_xy
,
q_yy
=
-
self
.
q_xx
,
degree
=
1
)
return
q
elif
self
.
saturating_density_and_difference_in_density_active_stress
:
return
self
.
lamda
*
(
rho
*
(
rho
-
self
.
average_rho
))
/
(
rho
+
self
.
saturation_rho
)
*
df
.
Identity
(
self
.
dimension
)
def
active_stress
(
self
,
rho
,
u
,
v
):
return
-
(
self
.
lamda
*
rho
*
(
rho
-
self
.
stress_setpoint_rho
)
/
(
rho
**
2
+
self
.
saturation_rho
**
2
)
# self.qtensor()
*
df
.
Identity
(
self
.
dimension
)
)
elif
self
.
saturating_density_and_difference_in_morphogen_active_stress
:
return
self
.
lamda
*
(
rho
*
(
c
-
self
.
average_c
))
/
(
rho
+
self
.
saturation_rho
)
*
df
.
Identity
(
self
.
dimension
)
def
epsilon
(
self
,
v
):
return
df
.
sym
(
df
.
nabla_grad
(
v
))
...
...
@@ -93,224 +80,153 @@ class Growing_Domain(object):
return
(
elastic_stress
+
viscous_stress
)
def
stress
(
self
,
u
,
v
,
rho
,
c
):
return
(
self
.
passive_stress
(
u
,
v
)
+
self
.
active_stress
(
rho
,
c
,
v
))
def
stress
(
self
,
u
,
v
,
rho
):
return
(
self
.
passive_stress
(
u
,
v
)
+
self
.
active_stress
(
rho
,
u
,
v
))
def
reaction_rho
(
self
,
rho
,
trho
,
c
):
if
self
.
morphogen_mediated_turnover_rho
:
return
self
.
turnover_rho
*
df
.
inner
((
c
-
self
.
average_c
/
2
)
*
(
rho
-
self
.
average_rho
),
trho
)
elif
self
.
morphogen_mediated_average_rho
:
return
self
.
turnover_rho
*
df
.
inner
(
rho
-
self
.
average_c
,
trho
)
elif
self
.
density_dependent_turnover_rho
:
# to model that cells are born or die only where the density is non-zero
# tanh approximation: Theta = 1+ tanh = 1 + rho - rho^3/3! + . . .
return
self
.
turnover_rho
*
df
.
inner
((
1
+
rho
)
*
(
rho
-
self
.
average_rho
),
trho
)
else
:
return
self
.
turnover_rho
*
df
.
inner
(
rho
-
self
.
average_rho
,
trho
)
def
reaction_c
(
self
,
c
,
tc
):
return
self
.
turnover_c
*
df
.
inner
(
c
-
self
.
average_c
,
tc
)
def
reaction_rho
(
self
,
rho
,
trho
):
return
-
self
.
turnover_rho
*
df
.
inner
(
rho
*
(
1
-
rho
/
self
.
average_rho
),
trho
)
def
diffusion_reaction_rho
(
self
,
rho
,
trho
,
c
):
def
diffusion_reaction_rho
(
self
,
rho
,
trho
):
return
(
self
.
diffusion_rho
*
df
.
inner
(
df
.
nabla_grad
(
rho
),
df
.
nabla_grad
(
trho
))
+
self
.
reaction_rho
(
rho
,
trho
,
c
))
+
self
.
reaction_rho
(
rho
,
trho
))
def
refine_mesh
(
self
,
mesh
):
cell_markers
=
df
.
MeshFunction
(
"bool"
,
mesh
,
mesh
.
topology
()
.
dim
())
cell_markers
.
set_all
(
False
)
for
cell
in
df
.
cells
(
mesh
):
if
cell
.
volume
()
>
2
*
0.005
:
cell_markers
[
cell
]
=
True
mesh
=
df
.
refine
(
mesh
,
cell_markers
)
def
diffusion_reaction_c
(
self
,
c
,
tc
):
return
(
self
.
diffusion_c
*
df
.
inner
(
df
.
nabla_grad
(
c
),
df
.
nabla_grad
(
tc
))
+
self
.
reaction_c
(
c
,
tc
))
return
mesh
def
setup_initial_conditions
(
self
):
# ic for u
if
self
.
dimension
==
1
:
self
.
zero_vector
=
df
.
Constant
((
0.0
,))
elif
self
.
dimension
==
2
:
self
.
zero_vector
=
df
.
Constant
((
0.0
,
0.0
))
self
.
zero_vector
=
df
.
Constant
((
0.0
,
0.0
))
u0
=
df
.
interpolate
(
self
.
zero_vector
,
self
.
function_space
.
sub
(
0
)
.
collapse
())
# add noise
noise_u
=
self
.
noise_level
*
(
2
*
np
.
random
.
random
(
u0
.
vector
()
.
size
())
-
1
)
u0
.
vector
()[:]
=
u0
.
vector
()[:]
+
noise_u
# ic for rho
rho0
=
'(a/2)*(1-tanh((sqrt(x[0]*x[0]+x[1]*x[1]) - r0)/w))'
r2
=
"+"
.
join
([
'x['
+
str
(
i
)
+
']*x['
+
str
(
i
)
+
']'
for
i
in
range
(
self
.
dimension
)])
if
self
.
dimension
==
1
:
rho0
=
'1-cos(2*pi*x[0]/R)'
else
:
# for rho=rho_0 boundary condition
# rho0 = "%s" % str(self.average_rho)
# rho0 = '(a/2)*(1 + tanh((sqrt(%s) - r0)/w))' %r2
# grad rho=0 boundary condition
rho0
=
'1 + 0.1 * a * cos(2.0*pi*
%
s/R)'
%
r2
# rho = 0 boundary condition
# circular domain --> circular domain
# rho0 = '(a/2)*(1 - tanh((sqrt(%s) - r0)/w))' %r2
# rho0 = 'a*(1-tanh((sqrt(%s) - r0)/w))' %r2 # grows to a different size
# circular domain --> elliptical domain (w=0.19, lambda = -10, k=1)
# rho0 = 'a*x[0]*x[0]*(1-tanh((sqrt(%s) - r0)/w))' %r2
# circular domain --> dumbbell shaped domain (w = 0.8, k = 0.01, lambda = -80)
# rho0 = '0.25 + a*x[0]*x[1]*(1-tanh((sqrt(%s) - r0)/w))' %r2
# circular --> kidney (w=0.8, r0=0.5, k=0.1, lambda=-30)
# rho0 = 'x[0]*(1-tanh((sqrt(%s) - r0)/w))' %r2
rho0
=
df
.
interpolate
(
df
.
Expression
(
rho0
,
pi
=
np
.
pi
,
R
=
self
.
system_size
,
a
=
self
.
average_rho
,
r0
=
0.5
,
w
=
0.19
,
degree
=
1
),
self
.
function_space
.
sub
(
2
)
.
collapse
())
rho0
=
df
.
interpolate
(
df
.
Expression
(
rho0
,
a
=
self
.
average_rho
,
r0
=
0.5
,
w
=
0.1
,
degree
=
1
),
self
.
function_space
.
sub
(
2
)
.
collapse
())
# add noise
noise_rho
=
self
.
noise_level
*
(
2
*
np
.
random
.
random
(
rho0
.
vector
()
.
size
())
-
1
)
rho0
.
vector
()[:]
=
rho0
.
vector
()[:]
+
noise_rho
# ic for c
if
self
.
morphogen
:
# c0 = "%s" % str(5.0)
# c0 = '1 + 0.1*a*cos(2.0*pi*sqrt(%s)/R)' %r2 # shrinks and stops
c0
=
'1 + 0.1*a*cos(2.0*pi*
%
s/R)'
%
r2
# grows and stops
# c0 = '1 + 0.1*a*cos(2.0*pi*x[0]/R)' # grows very slightly, shrinks even more slightly, changes shape
c0
=
df
.
interpolate
(
df
.
Expression
(
c0
,
a
=
self
.
average_c
,
R
=
self
.
system_size
,
pi
=
np
.
pi
,
degree
=
1
),
self
.
function_space
.
sub
(
3
)
.
collapse
())
# add noise
noise_c
=
self
.
noise_level
*
(
2
*
np
.
random
.
random
(
c0
.
vector
()
.
size
())
-
1
)
c0
.
vector
()[:]
=
c0
.
vector
()[:]
+
noise_c
else
:
c0
=
df
.
Constant
(
1.0
)
VFS
=
self
.
function_space
.
sub
(
1
)
.
collapse
()
v0
=
df
.
Function
(
VFS
)
tv
=
df
.
TestFunction
(
VFS
)
vform
=
(
self
.
friction
*
df
.
inner
(
v0
,
tv
)
+
df
.
inner
(
self
.
stress
(
u0
,
v0
,
rho0
,
c0
),
self
.
epsilon
(
tv
))
+
df
.
inner
(
self
.
stress
(
u0
,
v0
,
rho0
),
self
.
epsilon
(
tv
))
)
*
df
.
dx
df
.
solve
(
vform
==
0
,
v0
)
if
self
.
morphogen
:
df
.
assign
(
self
.
f0
,
[
u0
,
v0
,
rho0
,
c0
])
else
:
df
.
assign
(
self
.
f0
,
[
u0
,
v0
,
rho0
])
df
.
assign
(
self
.
f0
,
[
u0
,
v0
,
rho0
])
def
setup_weak_forms
(
self
):
if
self
.
morphogen
:
u0
,
v0
,
rho0
,
c0
=
df
.
split
(
self
.
f0
)
u
,
v
,
rho
,
c
=
df
.
split
(
self
.
f
)
tu
,
tv
,
trho
,
tc
=
df
.
TestFunctions
(
self
.
function_space
)
else
:
u0
,
v0
,
rho0
=
df
.
split
(
self
.
f0
)
u
,
v
,
rho
=
df
.
split
(
self
.
f
)
tu
,
tv
,
trho
=
df
.
TestFunctions
(
self
.
function_space
)
c
=
df
.
Constant
(
1.0
)
u0
,
v0
,
rho0
=
df
.
split
(
self
.
f0
)
u
,
v
,
rho
=
df
.
split
(
self
.
f
)
tu
,
tv
,
trho
=
df
.
TestFunctions
(
self
.
function_space
)
uform
=
(
df
.
inner
((
u
-
u0
)
/
self
.
timestep
,
tu
)
-
df
.
inner
(
v0
,
tu
)
)
vform
=
(
self
.
friction
*
df
.
inner
(
v
,
tv
)
+
df
.
inner
(
self
.
stress
(
u
,
v
,
rho
,
c
),
self
.
epsilon
(
tv
))
+
df
.
inner
(
self
.
stress
(
u
,
v
,
rho
),
self
.
epsilon
(
tv
))
)
rhoform
=
(
df
.
inner
((
rho
-
rho0
)
/
self
.
timestep
,
trho
)
+
self
.
advection
(
rho0
,
v0
,
trho
)
+
self
.
diffusion_reaction_rho
(
rho
,
trho
,
c
)
+
self
.
diffusion_reaction_rho
(
rho
,
trho
)
)
self
.
form
=
(
uform
+
vform
+
rhoform
)
*
df
.
dx
if
self
.
morphogen
:
cform
=
(
df
.
inner
((
c
-
c0
)
/
self
.
timestep
,
tc
)
+
self
.
advection
(
c0
,
v0
,
tc
)
+
self
.
diffusion_reaction_c
(
c
,
tc
)
)
self
.
form
=
(
uform
+
vform
+
rhoform
+
cform
)
*
df
.
dx
def
solve
(
self
,
initu
=
None
,
initv
=
None
,
initrho
=
None
,
initTime
=
0
,
extend
=
False
):
# create function space, functions, bc
self
.
setup
()
# create files if they don't exist, open them if they exist
self
.
uFile
=
df
.
XDMFFile
(
'
%
s_displacement.xdmf'
%
self
.
timestamp
)
self
.
vFile
=
df
.
XDMFFile
(
'
%
s_velocity.xdmf'
%
self
.
timestamp
)
self
.
rhoFile
=
df
.
XDMFFile
(
'
%
s_density.xdmf'
%
self
.
timestamp
)
# time-variables
self
.
time
=
initTime
savesteps
=
round
(
self
.
savetime
/
self
.
timestep
)
maxsteps
=
round
(
self
.
maxtime
/
self
.
timestep
)
if
not
extend
:
# find the initial velocity
self
.
setup_initial_conditions
()
# save the ic
u0
,
v0
,
rho0
=
self
.
f0
.
split
(
deepcopy
=
True
)
self
.
uFile
.
write_checkpoint
(
u0
,
'displacement'
,
self
.
time
)
self
.
vFile
.
write_checkpoint
(
v0
,
'velocity'
,
self
.
time
)
self
.
rhoFile
.
write_checkpoint
(
rho0
,
'density'
,
self
.
time
)
# move the mesh with this initial velocity
dr0
=
df
.
project
(
v0
*
self
.
timestep
,
self
.
function_space
.
sub
(
0
)
.
collapse
())
df
.
ALE
.
move
(
self
.
mesh
,
dr0
)
else
:
self
.
form
=
(
uform
+
vform
+
rhoform
)
*
df
.
dx
def
solve
(
self
,
DIR
=
''
):
# for saving data
self
.
uFile
=
df
.
XDMFFile
(
os
.
path
.
join
(
DIR
,
'
%
s_displacement.xdmf'
%
self
.
timestamp
)
)
self
.
vFile
=
df
.
XDMFFile
(
os
.
path
.
join
(
DIR
,
'
%
s_velocity.xdmf'
%
self
.
timestamp
))
self
.
rhoFile
=
df
.
XDMFFile
(
os
.
path
.
join
(
DIR
,
'
%
s_density.xdmf'
%
self
.
timestamp
))
if
self
.
morphogen
:
self
.
cFile
=
df
.
XDMFFile
(
os
.
path
.
join
(
DIR
,
'
%
s_concentration.xdmf'
%
self
.
timestamp
)
)
# assign fields to f0
u0
=
df
.
project
(
initu
,
self
.
function_space
.
sub
(
0
)
.
collapse
())
v0
=
df
.
project
(
initv
,
self
.
function_space
.
sub
(
1
)
.
collapse
())
rho0
=
df
.
project
(
initrho
,
self
.
function_space
.
sub
(
2
)
.
collapse
())
df
.
assign
(
self
.
f0
,
[
u0
,
v0
,
rho0
]
)
# move the mesh with this initial velocity
dr0
=
df
.
project
(
v0
*
self
.
timestep
,
self
.
function_space
.
sub
(
0
)
.
collapse
())
df
.
ALE
.
move
(
self
.
mesh
,
dr0
)
self
.
setup_initial_conditions
()
self
.
setup_weak_forms
()
# time-variables
self
.
time
=
0.0
savesteps
=
int
(
self
.
savetime
/
self
.
timestep
)
maxsteps
=
int
(
self
.
maxtime
/
self
.
timestep
)
if
self
.
morphogen
:
u
,
v
,
rho
,
c
=
self
.
f0
.
split
(
deepcopy
=
True
)
self
.
uFile
.
write_checkpoint
(
u
,
'displacement'
,
self
.
time
,
append
=
True
)
self
.
vFile
.
write_checkpoint
(
v
,
'velocity'
,
self
.
time
,
append
=
True
)
self
.
rhoFile
.
write_checkpoint
(
rho
,
'density'
,
self
.
time
,
append
=
True
)
self
.
cFile
.
write_checkpoint
(
c
,
'concentration'
,
self
.
time
,
append
=
True
)
else
:
u
,
v
,
rho
=
self
.
f0
.
split
(
deepcopy
=
True
)
self
.
uFile
.
write_checkpoint
(
u
,
'displacement'
,
self
.
time
,
append
=
True
)
self
.
vFile
.
write_checkpoint
(
v
,
'velocity'
,
self
.
time
,
append
=
True
)
self
.
rhoFile
.
write_checkpoint
(
rho
,
'density'
,
self
.
time
,
append
=
True
)
for
steps
in
progressbar
.
progressbar
(
range
(
1
,
maxsteps
+
1
)):
# solve
if
self
.
dirichlet_boundary_rho
:
df
.
solve
(
self
.
form
==
0
,
self
.
f
,
self
.
bc
)
elif
self
.
neumann_boundary_rho
:
if
self
.
zero_grad_rho_boundary
:
df
.
solve
(
self
.
form
==
0
,
self
.
f
)
# update
self
.
f0
.
assign
(
self
.
f
)
if
self
.
morphogen
:
u
,
v
,
rho
,
c
=
self
.
f0
.
split
(
deepcopy
=
True
)
if
steps
%
savesteps
==
0
:
self
.
uFile
.
write_checkpoint
(
u
,
'displacement'
,
self
.
time
,
append
=
True
)
self
.
vFile
.
write_checkpoint
(
v
,
'velocity'
,
self
.
time
,
append
=
True
)
self
.
rhoFile
.
write_checkpoint
(
rho
,
'density'
,
self
.
time
,
append
=
True
)
self
.
cFile
.
write_checkpoint
(
c
,
'concentration'
,
self
.
time
,
append
=
True
)
else
:
u
,
v
,
rho
=
self
.
f0
.
split
(
deepcopy
=
True
)
if
steps
%
savesteps
==
0
:
self
.
uFile
.
write_checkpoint
(
u
,
'displacement'
,
self
.
time
,
append
=
True
)
self
.
vFile
.
write_checkpoint
(
v
,
'velocity'
,
self
.
time
,
append
=
True
)
self
.
rhoFile
.
write_checkpoint
(
rho
,
'density'
,
self
.
time
,
append
=
True
)
bar
=
progressbar
.
ProgressBar
(
maxval
=
maxsteps
)
for
steps
in
bar
(
range
(
1
,
maxsteps
+
1
)):
self
.
time
+=
self
.
timestep
# solve to get fields at next timestep
df
.
solve
(
self
.
form
==
0
,
self
.
f
,
self
.
bc
)
# save the fields
u
,
v
,
rho
=
self
.
f
.
split
(
deepcopy
=
True
)
if
steps
%
savesteps
==
0
:
self
.
uFile
.
write_checkpoint
(
u
,
'displacement'
,
self
.
time
,
append
=
True
)
self
.
vFile
.
write_checkpoint
(
v
,
'velocity'
,
self
.
time
,
append
=
True
)
self
.
rhoFile
.
write_checkpoint
(
rho
,
'density'
,
self
.
time
,
append
=
True
)
# assign the calculated func to a newly-defined function to be used later
old_function
=
df
.
Function
(
self
.
function_space
)
old_function
.
assign
(
self
.
f
)
# move mesh
dr
=
df
.
project
(
u
,
self
.
function_space
.
sub
(
0
)
.
collapse
())
dr
=
df
.
project
(
v
*
self
.
timestep
,
self
.
function_space
.
sub
(
0
)
.
collapse
())
df
.
ALE
.
move
(
self
.
mesh
,
dr
)
# update time
self
.
time
+=
self
.
timestep
self
.
uFile
.
close
()
self
.
vFile
.
close
()
self
.
rhoFile
.
close
()
# def save_data_uvrho(self):
# refine the mesh
self
.
mesh
=
self
.
refine_mesh
(
self
.
mesh
)
if
self
.
morphogen
:
self
.
cFile
.
close
()
# new function space, bc, functions
self
.
setup
()
if
__name__
==
'__main__'
:
import
json
,
datetime
assert
os
.
path
.
isfile
(
'parameters.json'
),
'parameters.json file not found'
# assert that parameters.json is a valid file, otherwise
# give an error message parameters.json file not found
# load the parameters
with
open
(
'parameters.json'
)
as
jsonFile
:
params
=
json
.
load
(
jsonFile
)
# parse parameters
assert
params
[
'dimension'
]
in
(
1
,
2
)
timestamp
=
datetime
.
datetime
.
now
()
.
strftime
(
"
%
d
%
m
%
y-
%
H
%
M
%
S"
)
params
[
'timestamp'
]
=
timestamp
gd
=
Growing_Domain
(
params
)
gd
.
solve
()
# new function0 should be the old function in the old function space projected on the new function space
old_function
.
set_allow_extrapolation
(
True
)
with
open
(
params
[
'timestamp'
]
+
'_parameters.json'
,
"w"
)
as
fp
:
json
.
dump
(
params
,
fp
,
indent
=
4
)
self
.
f0
=
df
.
project
(
old_function
,
self
.
function_space
)
from
viz_growing_domain
import
visualize
visualize
(
params
,
DIR
=
""
,
offscreen
=
False
)
\ No newline at end of file
# new weak form
self
.
setup_weak_forms
()
self
.
uFile
.
close
()
self
.
vFile
.
close
()
self
.
rhoFile
.
close
()
growing_domain/full_model/parameters.json
View file @
e38db8a2
{
"morphogen"
:
false
,
"dimension"
:
2
,
"resolution"
:
100
,
"system_size"
:
1
,
"meshfile"
:
"disk.xml.gz"
,
"dirichlet_boundary_rho"
:
false
,
"zero_rho_boundary"
:
false
,
"rho0_boundary"
:
false
,
"neumann_boundary_rho"
:
true
,
"zero_grad_rho_boundary"
:
true
,
"difference_in_density_active_stress"
:
false
,
"difference_in_morphogen_active_stress"
:
false
,
"saturating_density_active_stress"
:
true
,
"saturating_density_and_difference_in_morphogen_active_stress"
:
false
,
"saturating_density_and_difference_in_density_active_stress"
:
false
,
"
morphogen_mediated_turnover_rho"
:
false
,
"
density_dependent_turnover_rho"
:
true
,
"
resolution"
:
128
,
"
system_size"
:
1
,
"morphogen_mediated_average_rho"
:
false
,
"bulk_elasticity"
:
1
,
"shear_elasticity"
:
1
,
"bulk_elasticity"
:
1.0
,
"shear_elasticity"
:
1.0
,
"shear_viscosity"
:
1.0
,
"bulk_viscosity"
:
1.0
,
"bulk_viscosity"
:
3.0
,
"friction"
:
1.0
,
"lamda"
:
-1.0
,
"diffusion_rho"
:
1.0
,
"turnover_rho"
:
1.0
,
"lamda"
:
-1
,
"diffusion_rho"
:
0.1
,
"turnover_rho"
:
1
,
"average_rho"
:
1.0
,
"saturation_rho"
:
1.0
,
"diffusion_c"
:
1.0
,
"turnover_c"
:
1.0
,
"average_c"
:
1.0
,
"stress_setpoint_rho"
:
2.0
,
"noise_level"
:
0.0
,
"timestep"
:
0.1
,
"savetime"
:
0.2
,
"maxtime"
:
100.0
"timestep"
:
0.01
,
"savetime"
:
0.1
,
"maxtime"
:
100.0
,
"q_xx"
:
1.0
,
"q_xy"
:
0.0
}
\ No newline at end of file
growing_domain/full_model/run_growing_domain.py
0 → 100644
View file @
e38db8a2
import
json
,
datetime
import
os
from
growing_domain
import
Growing_Domain
from
viz_growing_domain
import
visualize
import
argparse
import
dolfin
as
df
import
h5py
import
numpy
as
np
parser
=
argparse
.
ArgumentParser
()
parser
.
add_argument
(
'-j'
,
'--jsonfile'
,
help
=
'data file'
,
default
=
'parameters.json'
)
parser
.
add_argument
(
'-t'
,
'--time'
,
help
=
'time to run'
,
type
=
float
)
args
=
parser
.
parse_args
()
assert
os
.
path
.
isfile
(
args
.
jsonfile
),
'
%
s file not found'
%
args
.
jsonfile
with
open
(
args
.
jsonfile
)
as
jsonFile
:
parameters
=
json
.
load
(
jsonFile
)
if
args
.
jsonfile
==
'parameters.json'
:
extend
=
False
print
(
'Fresh run...'
)
timestamp
=
datetime
.
datetime
.
now
()
.
strftime
(
"
%
d
%
m
%
y-
%
H
%
M
%
S"
)
parameters
[
'timestamp'
]
=
timestamp
parametersFile
=
timestamp
+
'_parameters.json'
initu
=
None
initv
=
None
initrho
=
None
initTime
=
0.0
mesh
=
None
else
:
extend
=
True
print
(
'Extending run
%
s...'
%
parameters
[
'timestamp'
])
parametersFile
=
args
.
jsonfile
savesteps
=
round
(
parameters
[
'maxtime'
]
/
parameters
[
'savetime'
])
# read geometry and topology at the last timepoint from h5 file
var
=
'density'
h5
=
h5py
.
File
(
'
%
s_
%
s.h5'
%
(
parameters
[
'timestamp'
],
var
,),
'r+'
)
geometry
=
np
.
array
(
h5
[
'
%
s/
%
s_
%
d/mesh/geometry'
%
(
var
,
var
,
savesteps
)])
topology
=
np
.
array
(
h5
[
'
%
s/
%
s_
%
d/mesh/topology'
%
(
var
,
var
,
savesteps
)])
# create mesh with this geometry and topology
mesh
=
df
.
Mesh
()
editor
=
df
.
MeshEditor
()
editor
.
open
(
mesh
,
type
=
'triangle'
if
parameters
[
'dimension'
]
==
2
else
'tetrahedron'
,
tdim
=
parameters
[
'dimension'
],
gdim
=
parameters
[
'dimension'
])
editor
.
init_vertices
(
len
(
geometry
))
editor
.
init_cells
(
len
(
topology
))
for
j
in
range
(
len
(
geometry
)):
editor
.
add_vertex
(
j
,
geometry
[
j
])
for
j
in
range
(
len
(
topology
)):
editor
.
add_cell
(
j
,
topology
[
j
])
editor
.
close
()
# Read field values at the last time point
SFS
=
df
.
FunctionSpace
(
mesh
,
'P'
,
1
)
VFS
=
df
.
VectorFunctionSpace
(
mesh
,
'P'
,
1
)
initu
,
initv
,
initrho
=
df
.
Function
(
VFS
),
df
.
Function
(
VFS
),
df
.
Function
(
SFS
)
uFile
=
df
.
XDMFFile
(
'
%
s_displacement.xdmf'
%
parameters
[
'timestamp'
])
vFile
=
df
.
XDMFFile
(
'
%
s_velocity.xdmf'
%
parameters
[
'timestamp'
])
rhoFile
=
df
.
XDMFFile
(
'
%
s_density.xdmf'
%
parameters
[
'timestamp'
])
uFile
.
read_checkpoint
(
initu
,
'displacement'
,
savesteps
)
vFile
.
read_checkpoint
(
initv
,
'velocity'
,
savesteps
)
rhoFile
.
read_checkpoint
(
initrho
,
'density'
,
savesteps
)
uFile
.
close
()
vFile
.
close
()
rhoFile
.
close
()
initTime
=
parameters
[
'maxtime'
]
parameters
[
'maxtime'
]
=
args
.
time
tissue
=
Growing_Domain
(
parameters
,
mesh
)
tissue
.
solve
(
initu
,
initv
,
initrho
,
initTime
,
extend
)
if
extend
:
parameters
[
'maxtime'
]
=
initTime
+
parameters
[
'maxtime'
]
with
open
(
parametersFile
,
"w"
)
as
jsonFile
:
json
.
dump
(
parameters
,
jsonFile
,
indent
=
4
,
sort_keys
=
True
)
visualize
(
parameters
,
DIR
=
''
)
growing_domain/full_model/viz_growing_domain.py
View file @
e38db8a2
...
...
@@ -3,378 +3,193 @@ import numpy as np
import
vedo
as
vd
import
os
import
h5py
from
matplotlib.widgets
import
Slider
import
progressbar
import
matplotlib.pyplot
as
plt
from
tempfile
import
TemporaryDirectory
def
get_data
(
params
,
DIR
=
''
):
savesteps
=
int
(
params
[
'maxtime'
]
/
params
[
'savetime'
])
times
=
np
.
arange
(
savesteps
+
1
)
*
params
[
'savetime'
]
savesteps
=
round
(
params
[
'maxtime'
]
/
params
[
'savetime'
])
times
=
np
.
arange
(
savesteps
+
1
)
*
params
[
'savetime'
]
# Read mesh geometry from h5 file
var
=
'density'
h5
=
h5py
.
File
(
os
.
path
.
join
(
DIR
,
'
%
s_
%
s.h5'
%
(
params
[
'timestamp'
],
var
)),
"r"
)
# should be in the loop if remeshing
topology
=
np
.
array
(
h5
[
'
%
s/
%
s_0/mesh/topology'
%
(
var
,
var
)])
# NOTE: geometry and topology are lists of length len(times)
# NOTE: geometry[k] is a numpy array of shape (Num of vertices, 2) for timestep k
# NOTE: topology[k] is a numpy array of shape (Num of cells, 3) for timestep k
topology
=
[]
geometry
=
[]
for
i
in
range
(
len
(
times
)):
geometry
.
append
(
np
.
array
(
h5
[
'
%
s/
%
s_
%
d/mesh/geometry'
%
(
var
,
var
,
i
)]))
topology
.
append
(
np
.
array
(
h5
[
'
%
s/
%
s_
%
d/mesh/topology'
%
(
var
,
var
,
i
)]))
h5
.
close
()
geometry
=
np
.
array
(
geometry
)
if
params
[
'dimension'
]
==
1
:
geometry
,
zeros
=
np
.
dsplit
(
geometry
,
2
)
# create a mesh
if
params
[
'dimension'
]
==
1
:
mesh
=
df
.
IntervalMesh
(
params
[
'resolution'
],
0
,
params
[
'system_size'
])
else
:
# create a mesh at every timestep with this geometry and topology
meshes
=
[]
print
(
'Making the mesh..'
)
for
k
in
range
(
len
(
times
)):
mesh
=
df
.
Mesh
()
editor
=
df
.
MeshEditor
()
editor
.
open
(
mesh
,
type
=
'triangle'
if
params
[
'dimension'
]
==
2
else
'tetrahedron'
,
tdim
=
params
[
'dimension'
],
gdim
=
params
[
'dimension'
])
editor
.
init_vertices
(
len
(
geometry
[
0
]))
editor
.
init_cells
(
len
(
topology
))
for
i
in
range
(
len
(
geometry
[
0
])):
editor
.
add_vertex
(
i
,
geometry
[
0
][
i
])
for
i
in
range
(
len
(
topology
)):
editor
.
add_cell
(
i
,
topology
[
i
])
editor
.
init_vertices
(
len
(
geometry
[
k
]))
editor
.
init_cells
(
len
(
topology
[
k
]
))
for
j
in
range
(
len
(
geometry
[
k
])):
editor
.
add_vertex
(
j
,
geometry
[
k
][
j
])
for
j
in
range
(
len
(
topology
[
k
]
)):
editor
.
add_cell
(
j
,
topology
[
k
][
j
])
editor
.
close
()
meshes
.
append
(
mesh
)
# Read concentration data
SFS
=
df
.
FunctionSpace
(
mesh
,
'P'
,
1
)
VFS
=
df
.
VectorFunctionSpace
(
mesh
,
'P'
,
1
)
ui
,
vi
,
rhoi
=
df
.
Function
(
VFS
),
df
.
Function
(
VFS
),
df
.
Function
(
SFS
)
u
=
np
.
zeros
((
len
(
times
),
mesh
.
num_vertices
(),
params
[
'dimension'
]))
v
=
np
.
zeros_like
(
u
)
rho
=
np
.
zeros
((
len
(
times
),
mesh
.
num_vertices
()))
iso_stress
=
np
.
zeros
((
len
(
times
),
mesh
.
num_vertices
()))
print
(
meshes
[
0
]
.
num_vertices
(),
meshes
[
0
]
.
num_cells
())
print
(
meshes
[
-
1
]
.
num_vertices
(),
meshes
[
-
1
]
.
num_cells
())
# df.plot(meshes[0])
# plt.show()
# df.plot(meshes[1])
# plt.show()
# df.plot(meshes[2])
# plt.show()
# df.plot(meshes[3])
# plt.show()
# df.plot(meshes[4])
# plt.show()
# df.plot(meshes[5])
# plt.show()
# df.plot(meshes[6])
# plt.show()
# df.plot(meshes[7])
# plt.show()
# df.plot(meshes[8])
# plt.show()
# Read field values
u
=
[]
v
=
[]
rho
=
[]
uFile
=
df
.
XDMFFile
(
os
.
path
.
join
(
DIR
,
'
%
s_displacement.xdmf'
%
params
[
'timestamp'
]))
vFile
=
df
.
XDMFFile
(
os
.
path
.
join
(
DIR
,
'
%
s_velocity.xdmf'
%
params
[
'timestamp'
]))
rhoFile
=
df
.
XDMFFile
(
os
.
path
.
join
(
DIR
,
'
%
s_density.xdmf'
%
params
[
'timestamp'
]))
if
params
[
'morphogen'
]:
ci
=
df
.
Function
(
SFS
)
c
=
np
.
zeros_like
(
rho
)
cFile
=
df
.
XDMFFile
(
os
.
path
.
join
(
DIR
,
'
%
s_concentration.xdmf'
%
params
[
'timestamp'
]))
bar
=
progressbar
.
ProgressBar
(
maxval
=
savesteps
)
for
steps
in
bar
(
range
(
savesteps
+
1
)):
SFS
=
df
.
FunctionSpace
(
meshes
[
steps
],
'P'
,
1
)
VFS
=
df
.
VectorFunctionSpace
(
meshes
[
steps
],
'P'
,
1
)
ui
,
vi
,
rhoi
=
df
.
Function
(
VFS
),
df
.
Function
(
VFS
),
df
.
Function
(
SFS
)
for
steps
in
progressbar
.
progressbar
(
range
(
savesteps
+
1
)):
uFile
.
read_checkpoint
(
ui
,
'displacement'
,
steps
)
vFile
.
read_checkpoint
(
vi
,
'velocity'
,
steps
)
rhoFile
.
read_checkpoint
(
rhoi
,
'density'
,
steps
)
u_vec
=
ui
.
compute_vertex_values
(
mesh
)
u
[
steps
]
=
u_vec
.
reshape
(
params
[
'dimension'
],
int
(
u_vec
.
shape
[
0
]
/
params
[
'dimension'
]))
.
T
u_vec
=
ui
.
compute_vertex_values
(
mesh
es
[
steps
]
)
u
.
append
(
u_vec
.
reshape
(
params
[
'dimension'
],
int
(
u_vec
.
shape
[
0
]
/
params
[
'dimension'
]))
.
T
)
v_vec
=
vi
.
compute_vertex_values
(
mesh
)
v
[
steps
]
=
v_vec
.
reshape
(
params
[
'dimension'
],
int
(
v_vec
.
shape
[
0
]
/
params
[
'dimension'
]))
.
T
v_vec
=
vi
.
compute_vertex_values
(
mesh
es
[
steps
]
)
v
.
append
(
v_vec
.
reshape
(
params
[
'dimension'
],
int
(
v_vec
.
shape
[
0
]
/
params
[
'dimension'
]))
.
T
)
rho
[
steps
]
=
rhoi
.
compute_vertex_values
(
mesh
)
i_stress
=
(
params
[
'bulk_elasticity'
]
*
df
.
div
(
ui
)
+
params
[
'bulk_viscosity'
]
*
df
.
div
(
vi
)
+
params
[
'lamda'
]
*
rhoi
*
(
rhoi
-
params
[
'average_rho'
])
/
(
rhoi
+
params
[
'saturation_rho'
])
)
i_stress
=
df
.
project
(
i_stress
,
SFS
)
iso_stress
[
steps
]
=
i_stress
.
compute_vertex_values
(
mesh
)
if
params
[
'morphogen'
]:
cFile
.
read_checkpoint
(
ci
,
'concentration'
,
steps
)
c
[
steps
]
=
ci
.
compute_vertex_values
(
mesh
)
rho
.
append
(
rhoi
.
compute_vertex_values
(
meshes
[
steps
]))
uFile
.
close
()
vFile
.
close
()
rhoFile
.
close
()
if
params
[
'morphogen'
]:
cFile
.
close
()
return
(
times
,
topology
,
geometry
,
u
,
v
,
rho
,
c
,
iso_stress
)
else
:
return
(
times
,
topology
,
geometry
,
u
,
v
,
rho
,
iso_stress
)
return
(
times
,
topology
,
geometry
,
u
,
v
,
rho
)
def
visualize
(
params
,
DIR
=
''
,
offscreen
=
False
):
if
params
[
'morphogen'
]:
(
times
,
topology
,
geometry
,
u
,
v
,
rho
,
c
,
iso_stress
)
=
get_data
(
params
,
DIR
)
else
:
(
times
,
topology
,
geometry
,
u
,
v
,
rho
,
iso_stress
)
=
get_data
(
params
,
DIR
)
radial_coordinate
=
np
.
linalg
.
norm
(
geometry
,
axis
=
2
)
# print(geometry[-1,1,:] - geometry[-1,0,:])
# print(geometry[-1,1,:]+ v[-2, 1,:] * params['timestep'])
# print(geometry[-1,0,:]+ v[-2, 0,:] * params['timestep'])
##################################################### 1-D ############################################################################################################
if
params
[
'dimension'
]
==
1
:
# c(x,t) and rho(x,t) vs x and t
if
params
[
'morphogen'
]:
fig
,
(
axrho
,
axc
)
=
plt
.
subplots
(
2
,
1
,
sharex
=
True
,
figsize
=
(
8
,
8
))
axc
.
set_xlabel
(
r'$x$'
)
axc
.
set_ylabel
(
r"$c(x,t)$"
)
axc
.
set_xlim
(
np
.
min
(
radial_coordinate
),
np
.
max
(
radial_coordinate
))
axc
.
set_ylim
(
np
.
min
(
c
),
np
.
max
(
c
))
else
:
fig
,
axrho
=
plt
.
subplots
(
1
,
1
,
sharex
=
True
,
figsize
=
(
8
,
8
))
axrho
.
set_xlabel
(
r'$x$'
)
axrho
.
set_ylabel
(
r"$\rho(x,t)$"
)
axrho
.
set_xlim
(
np
.
min
(
radial_coordinate
),
np
.
max
(
radial_coordinate
))
axrho
.
set_ylim
(
np
.
min
(
rho
),
np
.
max
(
rho
))
rhoplot
,
=
axrho
.
plot
(
radial_coordinate
[
0
],
rho
[
0
],
'o'
,
ms
=
3
)
if
params
[
'morphogen'
]:
cplot
,
=
axc
.
plot
(
radial_coordinate
[
0
],
c
[
0
])
def
update
(
value
):
ti
=
np
.
abs
(
times
-
value
)
.
argmin
()
rhoplot
.
set_ydata
(
rho
[
ti
])
rhoplot
.
set_xdata
(
radial_coordinate
[
ti
])
if
params
[
'morphogen'
]:
cplot
.
set_ydata
(
c
[
ti
])
cplot
.
set_xdata
(
radial_coordinate
[
ti
])
plt
.
draw
()
sax
=
plt
.
axes
([
0.1
,
0.92
,
0.7
,
0.02
])
slider
=
Slider
(
sax
,
r'$t/\tau$'
,
min
(
times
),
max
(
times
),
valinit
=
min
(
times
),
valfmt
=
'
%3.1
f'
,
fc
=
'#999999'
)
slider
.
drawon
=
False
slider
.
on_changed
(
update
)
plt
.
show
()
# heat map
# L(t) vs t
length
=
np
.
array
(
np
.
zeros
(
len
(
times
)))
for
j
in
range
(
len
(
times
)):
length
[
j
]
=
np
.
max
(
radial_coordinate
[
j
])
figlength
,
axlength
=
plt
.
subplots
(
1
,
1
,)
axlength
.
set_xlabel
(
'$t$'
)
axlength
.
set_ylabel
(
'$L(t)$'
)
axlength
.
set_xlim
(
np
.
min
(
times
),
np
.
max
(
times
))
axlength
.
set_ylim
(
np
.
min
(
length
),
np
.
max
(
length
))
axlength
.
plot
(
times
,
length
)
plt
.
show
()
###################################### 2D ##############################################################################################################
else
:
# rho and v
n_cmap_vals
=
16
scalar_cmap
=
'viridis'
vector_color
=
'w'
vector_scale
=
0.1
geometry
=
np
.
dstack
((
geometry
,
np
.
zeros
(
geometry
.
shape
[
0
:
2
])))
v
=
np
.
dstack
((
v
,
np
.
zeros
(
v
.
shape
[
0
:
2
])))
vmag
=
np
.
linalg
.
norm
(
v
,
axis
=
2
)
vmax
=
np
.
max
(
vmag
)
v
=
v
/
vmax
rhomin
,
rhomax
=
np
.
min
(
rho
),
np
.
max
(
rho
)
if
params
[
'morphogen'
]:
cmin
,
cmax
=
np
.
min
(
c
),
np
.
max
(
c
)
plotter
=
vd
.
plotter
.
Plotter
(
axes
=
0
)
poly
=
vd
.
utils
.
buildPolyData
(
geometry
[
0
],
topology
)
scalar_actor
=
vd
.
mesh
.
Mesh
(
poly
)
#scalar_actor.computeNormals(points=True, cells=True)
scalar_actor
.
pointdata
[
'density'
]
=
rho
[
0
]
scalar_actor
.
cmap
(
scalar_cmap
,
rho
[
0
],
vmin
=
rhomin
,
vmax
=
rhomax
,
n
=
n_cmap_vals
)
scalar_actor
.
add_scalarbar
(
title
=
r'$\rho/\rho_0$'
,
pos
=
(
0.8
,
0.04
),
nlabels
=
2
,
# titleYOffset=15, titleFontSize=28, size=(100, 600)
)
plotter
+=
scalar_actor
(
times
,
topology
,
geometry
,
u
,
v
,
rho
)
=
get_data
(
params
,
DIR
)
vector_actor
=
vd
.
shapes
.
Arrows
(
geometry
[
0
],
geometry
[
0
]
+
vector_scale
*
v
[
0
])
vector_actor
.
color
(
vector_color
)
plotter
+=
vector_actor
def
update
(
idx
):
nonlocal
plotter
,
vector_actor
scalar_actor
.
points
(
pts
=
geometry
[
idx
],
transformed
=
False
)
scalar_actor
.
pointdata
[
'density'
]
=
rho
[
idx
]
plotter
.
remove
(
vector_actor
)
vector_actor
=
vd
.
shapes
.
Arrows
(
geometry
[
idx
],
geometry
[
idx
]
+
vector_scale
*
v
[
idx
])
vector_actor
.
color
(
vector_color
)
plotter
+=
vector_actor
def
slider_update
(
widget
,
event
):
value
=
widget
.
GetRepresentation
()
.
GetValue
()
idx
=
(
abs
(
times
-
value
))
.
argmin
()
update
(
idx
)
slider
=
plotter
.
add_slider
(
slider_update
,
pos
=
[(
0.1
,
0.94
),
(
0.5
,
0.94
)],
xmin
=
times
[
0
],
xmax
=
times
.
max
(),
value
=
times
[
0
],
title
=
r"$t/\tau$"
)
n_cmap_vals
=
16
scalar_cmap
=
'viridis'
rhomin
,
rhomax
=
min
(
min
(
sublist
)
for
sublist
in
rho
),
max
(
max
(
sublist
)
for
sublist
in
rho
)
plotter
=
vd
.
plotter
.
Plotter
(
axes
=
0
)
vd
.
show
([
scalar_actor
,
vector_actor
],
interactive
=
(
not
offscreen
),
zoom
=
0.8
)
# isotropic stress
iso_stressmin
,
iso_stressmax
=
np
.
min
(
iso_stress
),
np
.
max
(
iso_stress
)
plotter_i_stress
=
vd
.
plotter
.
Plotter
(
axes
=
0
)
poly_i_stress
=
vd
.
utils
.
buildPolyData
(
geometry
[
0
],
topology
)
scalar_actor_i_stress
=
vd
.
mesh
.
Mesh
(
poly_i_stress
)
#scalar_actor.computeNormals(points=True, cells=True)
scalar_actor_i_stress
.
pointdata
[
'iso_stress'
]
=
iso_stress
[
0
]
scalar_actor_i_stress
.
cmap
(
scalar_cmap
,
iso_stress
[
0
],
vmin
=
iso_stressmin
,
vmax
=
iso_stressmax
,
n
=
n_cmap_vals
)
scalar_actor_i_stress
.
add_scalarbar
(
title
=
r'$\rho/\rho_0$'
,
poly
=
vd
.
utils
.
buildPolyData
(
geometry
[
0
],
topology
[
0
])
scalar_actor
=
vd
.
mesh
.
Mesh
(
poly
)
scalar_actor
.
pointdata
[
'density'
]
=
rho
[
0
]
scalar_actor
.
cmap
(
scalar_cmap
,
rho
[
0
],
vmin
=
rhomin
,
vmax
=
rhomax
)
scalar_actor
.
add_scalarbar
(
title
=
r'$\rho/\rho_0$'
,
pos
=
(
0.8
,
0.04
),
nlabels
=
2
,
# titleYOffset=15, titleFontSize=28, size=(100, 600)
)
plotter
+=
scalar_actor
# Create a wireframe of the scalar_actor and add it to the plotter
wireframe_actor
=
scalar_actor
.
clone
()
.
wireframe
(
True
)
.
lw
(
0.1
)
.
c
(
'black'
)
plotter
+=
wireframe_actor
def
update
(
idx
):
nonlocal
plotter
,
scalar_actor
,
wireframe_actor
poly
=
vd
.
utils
.
buildPolyData
(
geometry
[
idx
],
topology
[
idx
])
new_scalar_actor
=
vd
.
mesh
.
Mesh
(
poly
)
new_scalar_actor
.
pointdata
[
'density'
]
=
rho
[
idx
]
new_scalar_actor
.
cmap
(
scalar_cmap
,
rho
[
idx
],
vmin
=
rhomin
,
vmax
=
rhomax
)
new_scalar_actor
.
add_scalarbar
(
title
=
r'$\rho/\rho_0$'
,
pos
=
(
0.8
,
0.04
),
nlabels
=
2
,
# titleYOffset=15, titleFontSize=28, size=(100, 600)
)
plotter_i_stress
+=
scalar_actor_i_stress
def
update_i_stress
(
idx
):
scalar_actor_i_stress
.
points
(
pts
=
geometry
[
idx
],
transformed
=
False
)
scalar_actor_i_stress
.
pointdata
[
'iso_stress'
]
=
iso_stress
[
idx
]
def
slider_update_i_stress
(
widget
,
event
):
value
=
widget
.
GetRepresentation
()
.
GetValue
()
idx
=
(
abs
(
times
-
value
))
.
argmin
()
update_i_stress
(
idx
)
slider_i_stress
=
plotter_i_stress
.
add_slider
(
slider_update_i_stress
,
pos
=
[(
0.1
,
0.94
),
(
0.5
,
0.94
)],
xmin
=
times
[
0
],
xmax
=
times
.
max
(),
value
=
times
[
0
],
title
=
r"$t/\tau$"
)
plotter
.
remove
(
scalar_actor
)
plotter
.
remove
(
wireframe_actor
)
plotter
+=
new_scalar_actor
new_wireframe_actor
=
new_scalar_actor
.
clone
()
.
wireframe
(
True
)
.
lw
(
0.1
)
.
c
(
'black'
)
plotter
+=
new_wireframe_actor
scalar_actor
=
new_scalar_actor
wireframe_actor
=
new_wireframe_actor
# Update the reference to the wireframe_actor
# plotter.render()
def
slider_update
(
widget
,
event
):
value
=
widget
.
GetRepresentation
()
.
GetValue
()
idx
=
(
abs
(
times
-
value
))
.
argmin
()
update
(
idx
)
slider
=
plotter
.
add_slider
(
slider_update
,
pos
=
[(
0.1
,
0.94
),
(
0.5
,
0.94
)],
xmin
=
times
[
0
],
xmax
=
times
.
max
(),
value
=
times
[
0
],
title
=
r"$t/\tau$"
)
vd
.
show
([
scalar_actor
],
interactive
=
(
not
offscreen
),
zoom
=
0.5
)
if
offscreen
:
FPS
=
5
movFile
=
'
%
s_cell_density.mov'
%
params
[
'timestamp'
]
fps
=
float
(
FPS
)
command
=
"ffmpeg -y -r"
options
=
"-b:v 3600k -qscale:v 4 -vcodec mpeg4"
tmp_dir
=
TemporaryDirectory
()
get_filename
=
lambda
x
:
os
.
path
.
join
(
tmp_dir
.
name
,
x
)
for
tt
in
range
(
len
(
times
)):
idx
=
(
abs
(
times
-
times
[
tt
]))
.
argmin
()
update
(
idx
)
slider
.
GetRepresentation
()
.
SetValue
(
times
[
tt
])
fr
=
get_filename
(
"
%03
d.png"
%
tt
)
vd
.
screenshot
(
fr
)
os
.
system
(
command
+
" "
+
str
(
fps
)
+
" -i "
+
tmp_dir
.
name
+
os
.
sep
+
"
%03
d.png "
+
options
+
" "
+
movFile
)
tmp_dir
.
cleanup
()
# radial coordinate
r
=
np
.
zeros
(
len
(
times
))
for
i
in
range
(
len
(
times
)):
r
[
i
]
=
np
.
max
(
np
.
sqrt
(
np
.
sum
(
np
.
square
(
geometry
[
i
]),
axis
=
1
)))
plt
.
plot
(
times
,
r
)
plt
.
xlabel
(
'time'
)
plt
.
ylabel
(
'radius'
)
plt
.
show
()
drdt
=
np
.
gradient
(
r
,
times
)
print
(
drdt
)
plt
.
plot
(
times
,
drdt
)
plt
.
xlabel
(
'time'
)
plt
.
ylabel
(
'dr/dt'
)
plt
.
show
()
vd
.
show
(
scalar_actor_i_stress
,
interactive
=
(
not
offscreen
),
zoom
=
0.8
)
if
offscreen
:
FPS
=
5
movFile
=
'
%
s_cell_density.mov'
%
params
[
'timestamp'
]
fps
=
float
(
FPS
)
command
=
"ffmpeg -y -r"
options
=
"-b:v 3600k -qscale:v 4 -vcodec mpeg4"
tmp_dir
=
TemporaryDirectory
()
get_filename
=
lambda
x
:
os
.
path
.
join
(
tmp_dir
.
name
,
x
)
for
tt
in
range
(
len
(
times
)):
idx
=
(
abs
(
times
-
times
[
tt
]))
.
argmin
()
update
(
idx
)
slider
.
GetRepresentation
()
.
SetValue
(
times
[
tt
])
fr
=
get_filename
(
"
%03
d.png"
%
tt
)
vd
.
io
.
screenshot
(
fr
)
os
.
system
(
command
+
" "
+
str
(
fps
)
+
" -i "
+
tmp_dir
.
name
+
os
.
sep
+
"
%03
d.png "
+
options
+
" "
+
movFile
)
tmp_dir
.
cleanup
()
if
params
[
'morphogen'
]:
plotter1
=
vd
.
plotter
.
Plotter
(
axes
=
0
)
poly1
=
vd
.
utils
.
buildPolyData
(
geometry
[
0
],
topology
)
scalar_actor1
=
vd
.
mesh
.
Mesh
(
poly1
)
#scalar_actor1.computeNormals(points=True, cells=True)
scalar_actor1
.
pointdata
[
'concentration'
]
=
c
[
0
]
scalar_actor1
.
cmap
(
'plasma'
,
c
[
0
],
vmin
=
cmin
,
vmax
=
cmax
,
n
=
n_cmap_vals
)
scalar_actor1
.
add_scalarbar
(
title
=
r'$c/c_0$'
,
pos
=
(
0.8
,
0.04
),
nlabels
=
2
,
# titleYOffset=15, titleFontSize=28, size=(100, 600)
)
plotter1
+=
scalar_actor1
def
update1
(
idx
):
scalar_actor1
.
points
(
pts
=
geometry
[
idx
],
transformed
=
False
)
scalar_actor1
.
pointdata
[
'concentration'
]
=
c
[
idx
]
def
slider_update1
(
widget
,
event
):
value
=
widget
.
GetRepresentation
()
.
GetValue
()
idx
=
(
abs
(
times
-
value
))
.
argmin
()
update1
(
idx
)
slider1
=
plotter1
.
add_slider
(
slider_update1
,
pos
=
[(
0.1
,
0.94
),
(
0.5
,
0.94
)],
xmin
=
times
[
0
],
xmax
=
times
.
max
(),
value
=
times
[
0
],
title
=
r"$t/\tau$"
)
vd
.
show
(
interactive
=
(
not
offscreen
),
zoom
=
0.8
)
if
offscreen
:
FPS1
=
5
movFile1
=
'
%
s_morphogen.mov'
%
params
[
'timestamp'
]
fps1
=
float
(
FPS1
)
command1
=
"ffmpeg -y -r"
options1
=
"-b:v 3600k -qscale:v 4 -vcodec mpeg4"
tmp_dir1
=
TemporaryDirectory
()
get_filename1
=
lambda
x
:
os
.
path
.
join
(
tmp_dir1
.
name
,
x
)
for
tt
in
range
(
len
(
times
)):
idx1
=
(
abs
(
times
-
times
[
tt
]))
.
argmin
()
update1
(
idx1
)
slider1
.
GetRepresentation
()
.
SetValue
(
times
[
tt
])
fr1
=
get_filename1
(
"
%03
d.png"
%
tt
)
vd
.
io
.
screenshot
(
fr1
)
os
.
system
(
command1
+
" "
+
str
(
fps1
)
+
" -i "
+
tmp_dir1
.
name
+
os
.
sep
+
"
%03
d.png "
+
options1
+
" "
+
movFile1
)
tmp_dir1
.
cleanup
()
# R(t) vs t
plt
.
rcParams
.
update
({
'font.size'
:
22
})
radius
=
np
.
array
(
np
.
zeros
(
len
(
times
)))
for
j
in
range
(
len
(
times
)):
radius
[
j
]
=
np
.
max
(
radial_coordinate
[
j
])
figradius3
,
axradius3
=
plt
.
subplots
(
1
,
1
)
axradius3
.
set_xlabel
(
r'$\log t$'
)
# axradius3.set_xlim(np.min(np.log(times)), np.max(np.log(times)))
# axradius3.set_ylim(np.min(np.log(radius)), np.max(np.log(radius)))
axradius3
.
set_ylabel
(
r'$\log R(t)$'
)
axradius3
.
loglog
(
times
,
radius
)
figradius1
,
axradius1
=
plt
.
subplots
(
1
,
1
)
axradius1
.
set_xlabel
(
r'$t$'
)
# axradius1.set_xlim(np.min(times), np.max(times))
# axradius1.set_ylim(np.min(np.log(radius)), np.max(np.log(radius)))
axradius1
.
set_ylabel
(
r'$\log R(t)$'
)
axradius1
.
semilogy
(
times
,
radius
)
figradius2
,
axradius2
=
plt
.
subplots
(
1
,
1
)
axradius2
.
set_xlabel
(
r'$t$'
)
axradius2
.
set_xlim
(
np
.
min
(
times
),
np
.
max
(
times
))
axradius2
.
set_ylim
(
np
.
min
(
radius
),
np
.
max
(
radius
))
axradius2
.
set_ylabel
(
r'$R(t)$'
)
axradius2
.
plot
(
times
,
radius
)
plt
.
show
()
# c(r,t) vs r
if
params
[
'morphogen'
]:
figradial
,
(
axcradial
,
axrhoradial
)
=
plt
.
subplots
(
2
,
1
,
figsize
=
(
8
,
8
))
axcradial
.
set_xlabel
(
r'$r$'
)
axcradial
.
set_xlim
(
np
.
min
(
radial_coordinate
),
np
.
max
(
radial_coordinate
))
axcradial
.
set_ylim
(
np
.
min
(
c
),
np
.
max
(
c
))
axcradial
.
set_ylabel
(
r'$c(r,t)$'
)
cplot
,
=
axcradial
.
plot
(
radial_coordinate
[
0
],
c
[
0
],
'o'
,
ms
=
3
)
else
:
figradial
,
axrhoradial
=
plt
.
subplots
(
1
,
1
,
figsize
=
(
8
,
8
))
axrhoradial
.
set_xlabel
(
r'$r$'
)
axrhoradial
.
set_xlim
(
np
.
min
(
radial_coordinate
),
np
.
max
(
radial_coordinate
))
axrhoradial
.
set_ylim
(
np
.
min
(
rho
),
np
.
max
(
rho
))
axrhoradial
.
set_ylabel
(
r'$\rho(r,t)$'
)
rhoplot
,
=
axrhoradial
.
plot
(
radial_coordinate
[
0
],
rho
[
0
],
'o'
,
ms
=
3
)
def
update
(
value
):
ti
=
np
.
abs
(
times
-
value
)
.
argmin
()
rhoplot
.
set_ydata
(
rho
[
ti
])
rhoplot
.
set_xdata
(
radial_coordinate
[
ti
])
if
params
[
'morphogen'
]:
cplot
.
set_ydata
(
c
[
ti
])
cplot
.
set_xdata
(
radial_coordinate
[
ti
])
plt
.
draw
()
sax
=
plt
.
axes
([
0.1
,
0.92
,
0.7
,
0.02
])
slider1
=
Slider
(
sax
,
r'$t/\tau$'
,
min
(
times
),
max
(
times
),
valinit
=
min
(
times
),
valfmt
=
'
%3.1
f'
,
fc
=
'#999999'
)
slider1
.
drawon
=
False
slider1
.
on_changed
(
update
)
plt
.
show
()
if
__name__
==
'__main__'
:
import
argparse
,
json
parser
=
argparse
.
ArgumentParser
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment