-
Notifications
You must be signed in to change notification settings - Fork 0
/
ex3_diff.py
155 lines (114 loc) · 4.28 KB
/
ex3_diff.py
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Example 3: Unbounded diffusion
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
import steps.interface
from steps.model import *
from steps.geom import *
from steps.sim import *
from steps.saving import *
from steps.rng import *
from matplotlib import pyplot as plt
import numpy as np
########################################################################
# The Abaqus file to import
MESHFILE = 'meshes/sp_10r_3875'
# The number of iterations to run
NITER = 10
# The data collection time increment (s)
DT = 0.001
# The simulation endtime (s)
INT = 0.1
# The number of molecules to be injected into the centre
NINJECT = 10000
# The number of tetrahedral elements to sample data from.
SAMPLE = 2000
# The diffusion constant for our diffusing species (m^2/s)
DCST= 20.0e-12
########################################################################
def gen_model():
mdl = Model()
with mdl:
SA = Species.Create()
vsys = VolumeSystem.Create()
with vsys:
Diffusion(SA, DCST)
return mdl
########################################################################
def gen_geom(meshPath, mdl):
print("Loading mesh...")
mesh = TetMesh.LoadAbaqus(meshPath, 1e-6)
print("Mesh Loaded")
with mesh:
# Create a compartment containing all tetrahedron
cyto = Compartment.Create(mesh.tets, mdl.vsys)
print("Finding tetrahedron samples...")
# List to hold tetrahedrons
tets = TetList()
# Fetch the central tetrahedron
ctet = mesh.tets[0, 0, 0]
tets.append(ctet)
tets += ctet.neighbs
# Find the maximum and minimum coordinates of the mesh
bmin = mesh.bbox.min
bmax = mesh.bbox.max
# Run a loop until we have stored all tet indices we require
while len(tets) < SAMPLE:
# Pick a random position within the bounding box
pos = bmin + (bmax - bmin) * np.random.random(3)
if pos in mesh.tets:
tets.append(mesh.tets[pos])
# Find the radial distance of the tetrahedrons to mesh center:
tetrads = np.array([np.linalg.norm(tet.center - ctet.center)*1e6 for tet in tets])
print("Tetrahedron samples found")
return mesh, tets, tetrads
########################################################################
model = gen_model()
mesh, tets, tetrads = gen_geom(MESHFILE, model)
rng = RNG('mt19937', 512, 2903)
sim = Simulation('Tetexact', model, mesh, rng)
rs = ResultSelector(sim)
AConc = rs.TETS(tets).SA.Conc
sim.toSave(AConc, dt=DT)
for i in range(NITER):
sim.newRun()
print("Running iteration", i)
# Inject all molecules into the central tet:
sim.TET(0, 0, 0).SA.Count = NINJECT
sim.run(INT)
########################################################################
def plotres(tidx, tpnts, res_mean, tetrads):
if tidx >= len(tpnts):
raise ValueError('Time index is out of range.')
t = tpnts[tidx]
plt.scatter(tetrads, res_mean[tidx,:], s=5)
plt.xlabel('Radial distance of tetrahedron ($\mu$m)')
plt.ylabel('Concentration in tetrahedron ($\mu$M)')
plt.title(f'Unbounded diffusion. Time: {t}s')
plotAnalytical(t)
plt.xlim(0.0, max(tetrads))
plt.ylim(0.0)
plt.show()
########################################################################
def plotAnalytical(t):
segs = 100
anlytconc = np.zeros((segs))
radialds = np.zeros((segs))
maxrad = 0.0
for i in tetrads:
if (i > maxrad): maxrad = i
maxrad *= 1e-6
intervals = maxrad/segs
rad = 0.0
for i in range((segs)):
# Find the conc from analytical solution, and convert to mol/L
anlytconc[i]=1.0e3*(1/6.022e23)* \
((NINJECT/((4*np.pi*DCST*t) ** 1.5))* \
(np.exp((-1.0*(rad*rad))/(4*DCST*t))))
radialds[i] = rad*1e6
rad += intervals
plt.plot(radialds, anlytconc, color = 'red')
########################################################################
tpnts = AConc.time[0]
res_mean = np.mean(AConc.data, axis=0)*1e6
plotres(10, tpnts, res_mean, tetrads)
plotres(100, tpnts, res_mean, tetrads)