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
c396e5ce
authored
Nov 30, 2022
by
Jigyasa Watwani
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
works in 1D, 2D -- visualize both analytical and numerical solutions
parent
9ce31f90
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
120 additions
and
67 deletions
growing_domain/diffusion_on_growing_domain_exact_solutions.py → growing_domain/diffusion_growing_domain_an_vs_num.py
growing_domain/diffusion_
on_growing_domain_exact_solutions
.py
→
growing_domain/diffusion_
growing_domain_an_vs_num
.py
View file @
c396e5ce
...
...
@@ -4,7 +4,6 @@ import numpy as np
import
dolfin
as
df
import
h5py
from
matplotlib.widgets
import
Slider
import
os
import
argparse
,
json
from
tempfile
import
TemporaryDirectory
...
...
@@ -22,33 +21,72 @@ DIR = os.path.dirname(args.jsonfile)
offscreen
=
(
not
args
.
onscreen
)
# parameters
Nt
=
int
(
params
[
'maxtime'
]
/
params
[
'timestep'
])
times
=
np
.
linspace
(
0
,
params
[
'maxtime'
],
Nt
+
1
)
tmax
=
params
[
'maxtime'
]
d
=
params
[
'dimension'
]
L
=
params
[
'system_size'
]
alpha
=
params
[
'growth_parameter'
]
dt
=
params
[
'timestep'
]
dts
=
params
[
'savetime'
]
Dc
=
params
[
'Dc'
]
k
=
params
[
'reaction_rate'
]
growth
=
params
[
'growth'
]
timestamp
=
params
[
'timestamp'
]
m
=
2
# mth mode of cosine in the initial condition for d=1
p
=
1
# pth zero of bessel 1 in the initial condition for d=2
# mesh
if
d
==
2
:
mesh
=
df
.
Mesh
(
'disk.xml.gz'
)
else
:
mesh
=
df
.
IntervalMesh
(
params
[
'resolution'
],
0
,
L
)
Nv
=
mesh
.
num_vertices
()
# gives params['resolution'] + 1
# topology array, initialize geometry arrays
topology_array
=
mesh
.
cells
()
geometry_array
=
np
.
zeros
(((
Nt
+
1
,
Nv
,
d
)))
#################### get the numerical solution, the mesh, its geometry and topology ##################################
def
get_data
(
params
,
DIR
=
''
):
savesteps
=
int
(
params
[
'maxtime'
]
/
params
[
'savetime'
])
times
=
np
.
arange
(
savesteps
+
1
)
*
params
[
'savetime'
]
# Read mesh geometry from h5 file
var
=
'concentration'
h5
=
h5py
.
File
(
os
.
path
.
join
(
DIR
,
'
%
s_
%
s.h5'
%
(
timestamp
,
var
)),
"r"
)
# should be in the loop if remeshing
topology
=
np
.
array
(
h5
[
'
%
s/
%
s_0/mesh/topology'
%
(
var
,
var
)])
geometry
=
[]
for
i
in
range
(
len
(
times
)):
geometry
.
append
(
np
.
array
(
h5
[
'
%
s/
%
s_
%
d/mesh/geometry'
%
(
var
,
var
,
i
)]))
h5
.
close
()
geometry
=
np
.
array
(
geometry
)
if
d
==
1
:
geometry
,
zeros
=
np
.
dsplit
(
geometry
,
2
)
# initialize r and sol arrays
r_array
=
np
.
zeros
((
Nt
+
1
,
Nv
))
sol
=
np
.
zeros
((
len
(
times
),
len
(
r_array
[
0
])))
# create a mesh
if
params
[
'dimension'
]
==
1
:
mesh
=
df
.
IntervalMesh
(
params
[
'resolution'
],
0
,
L
)
else
:
mesh
=
df
.
Mesh
()
editor
=
df
.
MeshEditor
()
editor
.
open
(
mesh
,
type
=
'triangle'
if
d
==
2
else
'tetrahedron'
,
tdim
=
d
,
gdim
=
d
)
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
])
# vertex 0 --> (x0, y0, z0), vertex 1 --> (x1, y1, z1), ...
for
i
in
range
(
len
(
topology
)):
editor
.
add_cell
(
i
,
topology
[
i
])
# cell 0 --> vertices(0,1,2), cell 1 --> ()...
editor
.
close
()
# Read concentration data
concentration
=
np
.
zeros
((
len
(
times
),
len
(
geometry
[
0
])))
cFile
=
os
.
path
.
join
(
DIR
,
'
%
s_
%
s.xdmf'
%
(
timestamp
,
var
))
with
df
.
XDMFFile
(
cFile
)
as
cFile
:
for
steps
in
range
(
savesteps
+
1
):
mesh
.
coordinates
()[:]
=
geometry
[
steps
]
VFS
=
df
.
FunctionSpace
(
mesh
,
'P'
,
1
)
c
=
df
.
Function
(
VFS
)
cFile
.
read_checkpoint
(
c
,
var
,
steps
)
concentration
[
steps
]
=
c
.
compute_vertex_values
(
mesh
)
return
(
mesh
,
times
,
geometry
,
topology
,
concentration
)
(
mesh
,
times
,
geometry
,
topology
,
concentration
)
=
get_data
(
params
,
DIR
)
#################################### get the analytical solution #########################################################
radius
=
np
.
zeros
((
len
(
times
),
mesh
.
num_vertices
()))
sol
=
np
.
zeros_like
(
radius
)
# velocity to move the mesh
VFS
=
df
.
VectorFunctionSpace
(
mesh
,
'P'
,
1
)
...
...
@@ -61,7 +99,7 @@ growth_direction = tuple(['x['+str(i)+']' for i in range(0, d)])
growth_direction
=
df
.
Expression
(
growth_direction
,
degree
=
1
)
velocity
=
df
.
project
(
sigma
*
growth_direction
,
VFS
)
# modes en
e
tering the solution
# modes entering the solution
if
d
==
1
:
mode
=
m
*
np
.
pi
else
:
...
...
@@ -69,29 +107,16 @@ else:
# time loop
t
=
0
for
steps
in
range
(
0
,
Nt
+
1
):
for
steps
in
range
(
0
,
len
(
times
)):
# update sigma
sigma
.
t
=
t
# update velocity
velocity
.
assign
(
df
.
project
(
sigma
*
growth_direction
,
VFS
))
# find r, geometry and sol arrays on the mesh
# geometry array
if
d
==
1
:
x
=
np
.
reshape
(
mesh
.
coordinates
()[:],
(
Nv
,
1
))
geometry_array
[
steps
]
=
x
else
:
x
=
np
.
reshape
(
mesh
.
coordinates
()[:,
0
],
(
Nv
,
1
))
y
=
np
.
reshape
(
mesh
.
coordinates
()[:,
1
],
(
Nv
,
1
))
geometry_array
[
steps
]
=
np
.
concatenate
((
x
,
y
),
axis
=
1
)
# r array
r_array
[
steps
]
=
0
for
j
in
range
(
0
,
d
):
r_array
[
steps
]
+=
mesh
.
coordinates
()[:,
j
]
**
2
r_array
[
steps
]
=
np
.
sqrt
(
r_array
[
steps
])
# r_array
radius
[
steps
]
=
np
.
linalg
.
norm
(
geometry
[
steps
],
axis
=
1
)
# sol array
mode_indep_time_part
=
{
'none'
:
np
.
exp
(
k
*
t
),
...
...
@@ -108,32 +133,34 @@ for steps in range(0, Nt+1):
'exponential'
:
L
*
np
.
exp
(
alpha
*
t
),
'linear'
:
L
+
alpha
*
t
}
if
d
==
1
:
sol
[
steps
]
=
(
1
+
mode_dep_time_part
[
growth
]
*
np
.
cos
(
mode
*
r
_array
[
steps
]
/
domain_length
[
growth
]))
*
mode_indep_time_part
[
growth
]
sol
[
steps
]
=
(
1
+
mode_dep_time_part
[
growth
]
*
np
.
cos
(
mode
*
r
adius
[
steps
]
/
domain_length
[
growth
]))
*
mode_indep_time_part
[
growth
]
else
:
sol
[
steps
]
=
(
1
+
mode_dep_time_part
[
growth
]
*
sc
.
special
.
j0
(
mode
*
r
_array
[
steps
]
/
domain_length
[
growth
]))
*
mode_indep_time_part
[
growth
]
sol
[
steps
]
=
(
1
+
mode_dep_time_part
[
growth
]
*
sc
.
special
.
j0
(
mode
*
r
adius
[
steps
]
/
domain_length
[
growth
]))
*
mode_indep_time_part
[
growth
]
# move the mesh
displacement
=
df
.
project
(
velocity
*
dt
,
VFS
)
df
.
ALE
.
move
(
mesh
,
displacement
)
# update time
t
+=
dt
t
+=
dts
#
visualise the solution
#
##################### visualise the analytical solution #######################################################
if
d
==
1
:
fig
,
axc
=
plt
.
subplots
(
1
,
1
,
figsize
=
(
8
,
8
))
axc
.
set_xlabel
(
r'$x$'
)
axc
.
set_xlim
(
np
.
min
(
r
_array
),
np
.
max
(
r_array
))
axc
.
set_ylim
(
np
.
min
(
sol
),
np
.
max
(
sol
))
axc
.
set_xlim
(
np
.
min
(
r
adius
),
np
.
max
(
radius
))
axc
.
set_ylim
(
min
(
np
.
min
(
sol
),
np
.
min
(
concentration
)),
max
(
np
.
max
(
sol
),
np
.
max
(
concentration
)
))
axc
.
set_ylabel
(
r'$c(x,t)$'
)
cplot
,
=
axc
.
plot
(
r_array
[
0
],
sol
[
0
])
c_exactplot
,
=
axc
.
plot
(
radius
[
0
],
sol
[
0
])
cplot
,
=
axc
.
plot
(
radius
[
0
],
concentration
[
0
])
def
update
(
value
):
ti
=
np
.
abs
(
times
-
value
)
.
argmin
()
cplot
.
set_ydata
(
sol
[
ti
])
cplot
.
set_xdata
(
r_array
[
ti
])
c_exactplot
.
set_ydata
(
sol
[
ti
])
c_exactplot
.
set_xdata
(
radius
[
ti
])
cplot
.
set_ydata
(
concentration
[
ti
])
cplot
.
set_xdata
(
radius
[
ti
])
plt
.
draw
()
sax
=
plt
.
axes
([
0.1
,
0.92
,
0.7
,
0.02
])
...
...
@@ -145,17 +172,19 @@ if d==1:
plt
.
show
()
else
:
# for heat map
n_cmap_vals
=
16
scalar_cmap
=
'viridis'
geometry
=
np
.
dstack
((
geometry
_array
,
np
.
zeros
(
geometry_arra
y
.
shape
[
0
:
2
])))
geometry
=
np
.
dstack
((
geometry
,
np
.
zeros
(
geometr
y
.
shape
[
0
:
2
])))
cmin
,
cmax
=
np
.
min
(
sol
),
np
.
max
(
sol
)
plotter
=
vd
.
plotter
.
Plotter
(
axes
=
0
)
poly
=
vd
.
utils
.
buildPolyData
(
geometry
[
0
],
topology
_array
)
poly
=
vd
.
utils
.
buildPolyData
(
geometry
[
0
],
topology
)
scalar_actor
=
vd
.
mesh
.
Mesh
(
poly
)
scalar_actor
.
pointdata
[
'concentration'
]
=
sol
[
0
]
scalar_actor
.
cmap
(
scalar_cmap
,
sol
[
0
],
vmin
=
cmin
,
vmax
=
cmax
,
n
=
n_cmap_vals
)
scalar_actor
.
add_scalarbar
(
title
=
r'$c$'
,
scalar_actor
.
add_scalarbar
(
title
=
r'$c
_{analytical}
$'
,
pos
=
(
0.8
,
0.04
),
nlabels
=
2
,
# titleYOffset=15, titleFontSize=28, size=(100, 600)
)
...
...
@@ -176,24 +205,48 @@ else:
vd
.
show
(
interactive
=
(
not
offscreen
),
zoom
=
0.8
)
# make movie
if
offscreen
:
FPS
=
10
movFile
=
'
%
s.mov'
%
dt
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
()
fig1
,
axc1
=
plt
.
subplots
(
1
,
1
,
figsize
=
(
8
,
8
))
axc1
.
set_xlabel
(
r'$r$'
)
axc1
.
set_xlim
(
np
.
min
(
radius
),
np
.
max
(
radius
))
axc1
.
set_ylim
(
np
.
min
(
sol
),
np
.
max
(
sol
))
axc1
.
set_ylabel
(
r'$c(r,t)$'
)
c_exactplot
,
=
axc1
.
plot
(
radius
[
0
],
sol
[
0
],
'o'
,
ms
=
3
,
label
=
'analytical solution'
)
cplot
,
=
axc1
.
plot
(
radius
[
0
],
concentration
[
0
],
'o'
,
ms
=
3
,
label
=
'numerical solution'
)
def
update
(
value
):
ti
=
np
.
abs
(
times
-
value
)
.
argmin
()
c_exactplot
.
set_ydata
(
sol
[
ti
])
c_exactplot
.
set_xdata
(
radius
[
ti
])
cplot
.
set_ydata
(
concentration
[
ti
])
cplot
.
set_xdata
(
radius
[
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
)
axc1
.
legend
()
plt
.
show
()
# make movie
if
offscreen
:
FPS
=
10
movFile
=
'
%
s_analytical.mov'
%
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
()
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