-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathnumerical_fem.py
81 lines (71 loc) · 3 KB
/
numerical_fem.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
import os
import numpy as np
from dolfin import *
import parameters as params
def extract_pots(phi, positions):
compt_values = np.zeros(positions.shape[0])
for ii in range(positions.shape[0]):
compt_values[ii] = phi(positions[ii, :])
return compt_values
def main_4shell_fem(mesh, subdomains, boundaries, skull_cond, src_pos, snk_pos):
sigma_B = Constant(params.sigma_brain)
sigma_Sc = Constant(params.sigma_scalp)
sigma_C = Constant(params.sigma_csf)
sigma_Sk = Constant(skull_cond)
sigma_A = Constant(0.)
V = FunctionSpace(mesh, "CG", 2)
v = TestFunction(V)
u = TrialFunction(V)
phi = Function(V)
dx = Measure("dx")[subdomains]
ds = Measure("ds")[boundaries]
a = inner(sigma_B * grad(u), grad(v))*dx(params.whitemattervol) + \
inner(sigma_B * grad(u), grad(v))*dx(params.graymattervol) + \
inner(sigma_Sc * grad(u), grad(v))*dx(params.scalpvol) + \
inner(sigma_C * grad(u), grad(v))*dx(params.csfvol) + \
inner(sigma_Sk * grad(u), grad(v))*dx(params.skullvol)
L = Constant(0)*v*dx
A = assemble(a)
b = assemble(L)
x_pos, y_pos, z_pos = src_pos
point = Point(x_pos, y_pos, z_pos)
delta = PointSource(V, point, 1.)
delta.apply(b)
x_pos, y_pos, z_pos = snk_pos
point1 = Point(x_pos, y_pos, z_pos)
delta1 = PointSource(V, point1, -1.)
delta1.apply(b)
solver = KrylovSolver("cg", "ilu")
solver.parameters["maximum_iterations"] = 1000
solver.parameters["absolute_tolerance"] = 1E-8
solver.parameters["monitor_convergence"] = True
info(solver.parameters, True)
set_log_level(PROGRESS)
solver.solve(A, phi.vector(), b)
ele_pos_list = params.ele_coords
vals = extract_pots(phi, ele_pos_list)
# np.save(os.path.join('results', save_as), vals)
return vals
if __name__ == '__main__':
print 'Loading meshes'
mesh = Mesh(os.path.join("mesh", "sphere_4.xml"))
subdomains = MeshFunction("size_t", mesh, os.path.join("mesh", "sphere_4_physical_region.xml"))
boundaries = MeshFunction("size_t", mesh, os.path.join("mesh", "sphere_4_facet_region.xml"))
for dipole in params.dipole_list:
print 'Now computing FEM for dipole: ', dipole['name']
src_pos = dipole['src_pos']
snk_pos = dipole['snk_pos']
print 'Done loading meshes'
fem_20 = main_4shell_fem(mesh, subdomains, boundaries,
params.sigma_skull20, src_pos, snk_pos)
print 'Done 4Shell-FEM-20'
fem_40 = main_4shell_fem(mesh, subdomains, boundaries,
params.sigma_skull40, src_pos, snk_pos)
print 'Done 4Shell-FEM-40'
fem_80 = main_4shell_fem(mesh, subdomains, boundaries,
params.sigma_skull80, src_pos, snk_pos)
print 'Done 4Shell-FEM-80'
f = open(os.path.join('results',
'Numerical_' + dipole['name'] + '.npz'), 'w')
np.savez(f, fem_20=fem_20, fem_40=fem_40, fem_80=fem_80)
f.close()