Skip to content

Commit 09b5501

Browse files
committed
add more jacobian tests, not passing yet, so no test in filename
1 parent f89af47 commit 09b5501

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

tests/jacobian_computation.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import numpy as np
2+
from test_domain_wall_cobalt import setup_domain_wall_cobalt
3+
4+
5+
def norm(a):
6+
return np.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2])
7+
8+
9+
def setup_llg_params_near_one(node_count=5, A=3.6 * 4e-7 * np.pi, Ms=6.7e5, K1=4.3, do_precession=True):
10+
sim = setup_domain_wall_cobalt(
11+
node_count=node_count, A=A, Ms=Ms, K1=K1, length=1.3, do_precession=do_precession, unit_length=1)
12+
sim.default_c = 1.23
13+
sim.gamma = 1.56
14+
sim.alpha = 2.35
15+
sim.pins = lambda r: 0
16+
sim.set_m((0, 0, 1))
17+
return sim, sim.spin
18+
19+
20+
def compute_jacobean_fd(sim, m, eps=1):
21+
# use 4th order FD scheme which should produce an exact result without demag
22+
# hence set eps to 1
23+
n = sim.mesh.n
24+
print sim.mesh.coordinates
25+
# compute the jacobean using the finite difference approximation
26+
jac = np.zeros((3 * n, 3 * n))
27+
w = np.array([1. / 12., -2. / 3., 2. / 3., -1. / 12.]) / eps
28+
once = False
29+
for j, v in enumerate(np.eye(3 * n)):
30+
sim.spin[:] = m - 2 * eps * v
31+
f0 = np.zeros(3 * n)
32+
sim.sundials_rhs(0, 0, f0)
33+
sim.spin[:] = m - eps * v
34+
f1 = np.zeros(3 * n)
35+
sim.sundials_rhs(0, 0, f1)
36+
sim.spin[:] = m + eps * v
37+
f2 = np.zeros(3 * n)
38+
sim.sundials_rhs(0, 0, f2)
39+
sim.spin[:] = m + 2 * eps * v
40+
f3 = np.zeros(3 * n)
41+
sim.sundials_rhs(0, 0, f3)
42+
if not once:
43+
print "m", m
44+
print "m - 2 * eps * v", m - 2 * eps * v
45+
print "f0", f0
46+
print "f1", f1
47+
print "f2", f2
48+
print "f3", f3
49+
once = True
50+
jac[:, j] = w[0] * f0 + w[1] * f1 + w[2] * f2 + w[3] * f3
51+
return jac
52+
53+
54+
def compute_jacobean_jtimes(sim, m):
55+
# use the jtimes function to compute the jacobean
56+
n = sim.mesh.n
57+
jac = np.zeros((3 * n, 3 * n))
58+
tmp = np.zeros(m.shape)
59+
fy = np.zeros(m.shape)
60+
jtimes = np.zeros(m.shape)
61+
for j, v in enumerate(np.eye(3 * n)):
62+
# use fy=None since it's not used for the computation
63+
sim.sundials_jtimes(v, jtimes, 0., m, fy)
64+
jac[:, j] = jtimes
65+
return jac
66+
67+
68+
def test_compute_fd():
69+
sim, m = setup_llg_params_near_one()
70+
# Jacobian computation should be exact with eps=1 or eps=2
71+
assert np.max(np.abs(compute_jacobean_fd(sim, m, eps=1) - compute_jacobean_fd(sim, m, eps=2))) < 1e-13
72+
73+
74+
def test_compute_jtimes():
75+
sim, m = setup_llg_params_near_one(node_count=2)
76+
fd = compute_jacobean_fd(sim, m)
77+
jtimes = compute_jacobean_jtimes(sim, m)
78+
print "m"
79+
print m
80+
print "FD"
81+
print fd
82+
print "JTIMES"
83+
print jtimes
84+
assert np.max(np.abs(fd - jtimes)) < 1e-13

0 commit comments

Comments
 (0)