Skip to content

Commit b72d423

Browse files
author
davidcorteso
committed
Double checked nebm in spherical coordinates. It appears to work much slower than the Cartesian version. The test using two particles is working now for both coordinate systems giving similar results, thus Spherical coordinates are working. Other tests are too slow to implement for now, like the elongated particle, this may indicate that we need to optimise the nebm code somehow
1 parent 53d0ded commit b72d423

File tree

3 files changed

+57
-29
lines changed

3 files changed

+57
-29
lines changed

fidimag/common/neb_spherical.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -365,12 +365,11 @@ def init_m(pos):
365365
self.coords = np.zeros(2 * self.n * self.total_image_num)
366366
self.last_m = np.zeros(self.coords.shape)
367367

368-
# For the effective field we use the extremes (to fit the energies
369-
# array length). We could save some memory if we don't consider them
370-
# (CHECK this in the future)
371-
self.Heff = np.zeros(self.coords.shape)
368+
# For the effective field we do not consider the extremes
369+
# since they are fixed
370+
self.Heff = np.zeros(2 * self.n * self.image_num)
372371
# self.Heff = np.zeros(2 * self.n * self.total_image_num)
373-
self.Heff.shape = (self.total_image_num, -1)
372+
self.Heff.shape = (self.image_num, -1)
374373

375374
# Tangent components in spherical coordinates
376375
self.tangents = np.zeros(2 * self.n * self.image_num)
@@ -620,7 +619,7 @@ def compute_effective_field(self, y):
620619

621620
# Set the simulation magnetisation to the (i+1)-th image
622621
# spin components
623-
self.sim.spin = spherical2cartesian(y[i + 1])
622+
self.sim.spin[:] = spherical2cartesian(y[i + 1])
624623

625624
# Compute the effective field using Fidimag's methods.
626625
# (we use the time=0 since we are only using the simulation
@@ -632,7 +631,7 @@ def compute_effective_field(self, y):
632631
h = self.sim.field
633632
# Save the field components of the (i + 1)-th image
634633
# to the effective field array which is in spherical coords
635-
self.Heff[i + 1, :] = cartesian2spherical_field(h, y[i + 1])
634+
self.Heff[i, :] = cartesian2spherical_field(h, y[i + 1])
636635
# Compute and save the total energy for this image
637636
self.energy[i + 1] = self.sim.compute_energy()
638637

@@ -688,7 +687,7 @@ def sundials_rhs(self, time, y, ydot):
688687
# D_climb = -nabla E + 2 * [nabla E * t] t
689688
for i in range(self.image_num):
690689
# The eff field has (i + 1) since it considers the extreme images
691-
h = self.Heff[i + 1]
690+
h = self.Heff[i]
692691
# Tangents and springs has length: total images -2 (no extremes)
693692
t = self.tangents[i]
694693
sf = self.springs[i]

fidimag/common/vtk.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def init_VtkData(self, structure, header):
5151
def reset_data(self):
5252
self.vtk_data = pyvtk.VtkData(self.structure, self.header)
5353

54+
@ignore_stderr
5455
def save_scalar(self, s, name="my_field", step=0):
5556
self.vtk_data.cell_data.append(pyvtk.Scalars(s, name))
5657

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
# FIDIMAG:
55
from fidimag.micro import Sim
66
from fidimag.common import CuboidMesh
7-
from fidimag.micro import UniformExchange, UniaxialAnisotropy, Demag
7+
from fidimag.micro import UniformExchange, UniaxialAnisotropy
88
from fidimag.common.neb_cartesian import NEB_Sundials
9+
from fidimag.common.neb_spherical import NEB_Sundials as NEB_Sundials_spherical
910
import numpy as np
1011

1112
# Material Parameters
@@ -25,7 +26,7 @@
2526

2627
def two_part(pos):
2728

28-
x, y = pos[0], pos[1]
29+
x = pos[0]
2930

3031
if x > 6 or x < 3:
3132
return Ms
@@ -34,15 +35,16 @@ def two_part(pos):
3435

3536
# Finite differences mesh
3637
mesh = CuboidMesh(nx=3,
37-
ny=1,
38-
nz=1,
39-
dx=3, dy=3, dz=3,
40-
unit_length=1e-9
41-
)
38+
ny=1,
39+
nz=1,
40+
dx=3, dy=3, dz=3,
41+
unit_length=1e-9
42+
)
4243

4344

4445
# Simulation Function
45-
def relax_neb(k, maxst, simname, init_im, interp, save_every=10000):
46+
def relax_neb(k, maxst, simname, init_im, interp, save_every=10000,
47+
coordinates='Cartesian'):
4648
"""
4749
Execute a simulation with the NEB function of the FIDIMAG code, for an
4850
elongated particle (long cylinder)
@@ -78,28 +80,36 @@ def relax_neb(k, maxst, simname, init_im, interp, save_every=10000):
7880
# equal to 'the number of initial states specified', minus one.
7981
interpolations = interp
8082

81-
neb = NEB_Sundials(sim,
82-
init_images,
83-
interpolations=interpolations,
84-
spring=k,
85-
name=simname)
83+
if coordinates == 'Cartesian':
84+
neb = NEB_Sundials(sim,
85+
init_images,
86+
interpolations=interpolations,
87+
spring=k,
88+
name=simname)
89+
elif coordinates == 'Spherical':
90+
neb = NEB_Sundials_spherical(sim,
91+
init_images,
92+
interpolations=interpolations,
93+
spring=k,
94+
name=simname)
8695

8796
neb.relax(max_steps=maxst,
8897
save_vtk_steps=save_every,
8998
save_npy_steps=save_every,
9099
stopping_dmdt=1e-2)
91100

92101

102+
def mid_m(pos):
103+
if pos[0] > 4:
104+
return (0.5, 0, 0.2)
105+
else:
106+
return (-0.5, 0, 0.2)
107+
108+
93109
# this test runs for over a minute
94110
@pytest.mark.slow
95111
def test_energy_barrier_2particles():
96112
# Initial images: we set here a rotation interpolating
97-
def mid_m(pos):
98-
if pos[0] > 4:
99-
return (0.5, 0, 0.2)
100-
else:
101-
return (-0.5, 0, 0.2)
102-
103113
init_im = [(-1, 0, 0), mid_m, (1, 0, 0)]
104114
interp = [6, 6]
105115

@@ -114,12 +124,27 @@ def mid_m(pos):
114124
interp,
115125
save_every=5000)
116126

127+
# Relax the same system using spherical coordinates
128+
relax_neb(float(k), 2000,
129+
'neb_2particles_k{}_10-10int_spherical'.format(k),
130+
init_im,
131+
interp,
132+
save_every=5000,
133+
coordinates='Spherical'
134+
)
135+
117136
# Get the energies from the last state
118137
data = np.loadtxt('neb_2particles_k1e8_10-10int_energy.ndt')[-1][1:]
138+
data_spherical = np.loadtxt(
139+
'neb_2particles_k1e8_10-10int_spherical_energy.ndt')[-1][1:]
119140

120141
ebarrier = np.abs(np.max(data) - np.min(data)) / (1.602e-19)
121142
print(ebarrier)
122143

144+
ebarrier_spherical = np.abs(np.max(data_spherical) -
145+
np.min(data_spherical)) / (1.602e-19)
146+
print(ebarrier_spherical)
147+
123148
# Analitically, the energy when a single particle rotates is:
124149
# K V cos^2 theta
125150
# where theta is the angle of the direction of one particle with respect
@@ -133,6 +158,9 @@ def mid_m(pos):
133158
assert ebarrier < 0.017
134159
assert ebarrier > 0.005
135160

161+
assert ebarrier_spherical < 0.017
162+
assert ebarrier_spherical > 0.005
163+
136164

137-
if __name__=='__main__':
138-
test_energy_barrier_2particles()
165+
if __name__ == '__main__':
166+
test_energy_barrier_2particles()

0 commit comments

Comments
 (0)