Skip to content

Commit 2dc1e9f

Browse files
author
Weiwei Wang
committed
2 parents d42ce88 + 17b5c68 commit 2dc1e9f

File tree

9 files changed

+133
-10
lines changed

9 files changed

+133
-10
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
language: python
22
python:
3+
- "3.6"
34
- "3.5"
45
- "3.4"
56
- "2.7"

examples/micromagnetic/baryakhtar/relax_system.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@
1212

1313
def relax_system(mesh):
1414

15-
sim = Sim(mesh, chi=1e-3, name='relax', driver='llbar_full')
15+
sim = Sim(mesh, name='relax', driver='llbar_full')
1616

17+
sim.driver.chi = 1e-3
1718
sim.driver.set_tols(rtol=1e-7, atol=1e-7)
1819
sim.Ms = 8.0e5
1920
sim.driver.alpha = 0.1

fidimag/common/cuboid_mesh.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
2828
"""
2929
from __future__ import print_function
30-
from psutil import virtual_memory
30+
from psutil import virtual_memory
3131
import numpy as np
3232
from textwrap import dedent
3333
from six.moves import range
@@ -53,6 +53,12 @@ def __init__(self, dx=1, dy=1, dz=1, nx=1, ny=1, nz=1, x0=0, y0=0, z0=0,
5353
# of 2 nm in any direction and periodic along the x-axis.
5454
5555
"""
56+
57+
if (np.array([nx, ny, nz]) <= 0).any():
58+
raise ValueError("nx, ny and nz must be integers >= 1")
59+
if (np.array([dx, dy, dz]) <= 0).any():
60+
raise ValueError("dx, dy and dz must be greater than 0")
61+
5662
self.dx = dx
5763
self.dy = dy
5864
self.dz = dz
@@ -279,7 +285,7 @@ def check_size(self, system_memory_fake_for_testing=None):
279285

280286
if 2 * size_coordinates_GiB > mem_GiB:
281287
# print because no logging yet
282-
print("Warning! Size of mesh coordinates i {} GiB.".format(
288+
print("Warning! Size of mesh coordinates is {} GiB.".format(
283289
size_coordinates_GiB))
284290
print(
285291
"You have {} GiB system memory. Possible halt.".format(mem_GiB))

fidimag/common/nebm_cartesian.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from .nebm_tools import spherical2cartesian, cartesian2spherical, compute_norm
99
from .nebm_tools import linear_interpolation_spherical
1010
from .nebm_tools import interpolation_Rodrigues_rotation
11+
from .nebm_tools import m_to_zero_nomaterial
1112

1213
from .nebm_base import NEBMBase
1314

@@ -235,6 +236,10 @@ def generate_initial_band(self, method='linear'):
235236
self.sim._pins
236237
)
237238

239+
interpolation = np.apply_along_axis(lambda m: m_to_zero_nomaterial(m, self.sim),
240+
axis=1,
241+
arr=interpolation)
242+
238243
# We then set the interpolated spins fields at once
239244
self.band[i_initial_images[i] + 1:
240245
i_initial_images[i + 1]] = interpolation

fidimag/common/nebm_geodesic.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from .nebm_tools import spherical2cartesian, cartesian2spherical, compute_norm
1010
from .nebm_tools import linear_interpolation_spherical
1111
from .nebm_tools import interpolation_Rodrigues_rotation
12+
from .nebm_tools import m_to_zero_nomaterial
1213

1314
from .nebm_base import NEBMBase
1415

@@ -247,6 +248,10 @@ def generate_initial_band(self, method='linear'):
247248
self.sim._pins
248249
)
249250

251+
interpolation = np.apply_along_axis(lambda m: m_to_zero_nomaterial(m, self.sim),
252+
axis=1,
253+
arr=interpolation)
254+
250255
# We then set the interpolated spins fields at once
251256
self.band[i_initial_images[i] + 1:
252257
i_initial_images[i + 1]] = interpolation

fidimag/common/nebm_tools.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,19 @@ def interpolation_Rodrigues_rotation(y_initial, y_final, n, pins=None):
213213
y_final.shape = (-1)
214214

215215
return interpolations
216+
217+
def m_to_zero_nomaterial(image_cartesian, sim):
218+
"""
219+
For spins in sites with no material, we set its spin
220+
direction to [0, 0, 0]
221+
222+
Input is an image in Cartesian coordinates:
223+
[mx_0 my_0 mz_0 mx_1 my_1 ... mz_(P-1)]
224+
225+
sim is a fidimag simulation object from which we extract
226+
the Ms or mu_s to filter the spin directions
227+
"""
228+
image_reshape = np.copy(image_cartesian.reshape(-1, 3))
229+
_filter = sim._magnetisation == 0
230+
image_reshape[_filter] = np.array([0., 0., 0.])
231+
return image_reshape.reshape(-1)

fidimag/common/sim_base.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,3 +275,17 @@ def compute_energy(self):
275275
energy += obj.compute_energy()
276276

277277
return energy
278+
279+
def get_field_array(self, interaction):
280+
"""
281+
Returns the field array corresponding to the interaction given:
282+
283+
e.g.
284+
compute_interaction_field('Demag')
285+
returns a numpy array containing the Demag field.
286+
"""
287+
field = self.get_interaction(interaction)
288+
# Copy here to avoid destroying the field accidentally
289+
# e.g. through reshaping
290+
f = field.field.copy()
291+
return f

fidimag/micro/baryakhtar.py

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
class LLBarFull(MicroDriver):
99

10-
def __init__(self, mesh, spin, Ms, field, alpha, pins,
10+
def __init__(self, mesh, spin, Ms, field, pins,
1111
interactions,
1212
name,
1313
data_saver,
@@ -18,18 +18,36 @@ def __init__(self, mesh, spin, Ms, field, alpha, pins,
1818

1919
# Inherit from the driver class
2020
super(LLBarFull, self).__init__(mesh, spin, Ms, field,
21-
alpha, pins, interactions, name,
21+
pins, interactions, name,
2222
data_saver,
2323
integrator=integrator,
2424
use_jac=use_jac
2525
)
2626

27-
self.chi = chi
27+
self._chi = 1e-3
28+
add(Relaxation(self.chi, name='chi_relax'),
29+
self.interactions, self.data_saver,
30+
self.mesh, self.spin, self._Ms)
31+
2832
self.lap = Laplace(mesh)
29-
self.add(Relaxation(chi))
33+
# OLD: self.add(Relaxation(chi))
3034

3135
self.beta = 0
3236

37+
def get_chi(self):
38+
"""
39+
"""
40+
return self._chi
41+
42+
def set_chi(self, chi):
43+
"""
44+
"""
45+
for i in self.interactions:
46+
if i.name == 'chi_relax':
47+
i.chi = chi
48+
49+
chi = property(get_chi, set_chi)
50+
3351
def sundials_rhs(self, t, y, ydot):
3452

3553
self.t = t
@@ -58,7 +76,7 @@ def sundials_rhs(self, t, y, ydot):
5876

5977
class LLBar(MicroDriver):
6078

61-
def __init__(self, mesh, spin, Ms, field, alpha, pins,
79+
def __init__(self, mesh, spin, Ms, field, pins,
6280
interactions,
6381
name,
6482
data_saver,
@@ -68,7 +86,7 @@ def __init__(self, mesh, spin, Ms, field, alpha, pins,
6886

6987
# Inherit from the driver class
7088
super(LLBar, self).__init__(mesh, spin, Ms, field,
71-
alpha, pins, interactions, name,
89+
pins, interactions, name,
7290
data_saver,
7391
integrator='sundials',
7492
use_jac=False
@@ -107,3 +125,54 @@ def sundials_rhs(self, t, y, ydot):
107125
#ydot[:] = self.dm_dt[:]
108126

109127
return 0
128+
129+
130+
def add(interaction, interactions_list, data_saver,
131+
mesh, spin, magnetisation, save_field=False):
132+
133+
"""
134+
135+
Add an interaction to the interaction list.
136+
This function is based on the Sim class *add* method
137+
(it is likely that this function will be moved to the common
138+
helpers in the future)
139+
140+
OPTIONAL ARGUMENTS:
141+
142+
save_field :: Set True to save the average values of this
143+
interaction field when relaxing the system
144+
145+
"""
146+
147+
# magnetisation is Ms for the micromagnetic Sim class, and it is
148+
# mu_s for the atomistic Sim class
149+
interaction.setup(mesh, spin, magnetisation)
150+
151+
# TODO: FIX --> ??
152+
# When adding an interaction that was previously added, using
153+
# the same name, append a '_2' to the new interaction name (?)
154+
for i in interactions_list:
155+
if i.name == interaction.name:
156+
interaction.name = i.name + '_2'
157+
158+
interactions_list.append(interaction)
159+
160+
# Specify a name for the energy of the interaction, which will
161+
# appear in a file with saved values
162+
# When saving the energy values, we call the compute_energy() method
163+
# from the (micromagnetic/atomistic) Energy class (overhead?)
164+
energy_name = 'E_{0}'.format(interaction.name)
165+
data_saver.entities[energy_name] = {
166+
'unit': '<J>',
167+
'get': lambda sim: sim.get_interaction(interaction.name).compute_energy(),
168+
'header': energy_name}
169+
170+
# Save the average values of the interaction vector field components
171+
if save_field:
172+
fn = '{0}'.format(interaction.name)
173+
data_saver.entities[fn] = {
174+
'unit': '<>',
175+
'get': lambda sim: sim.get_interaction(interaction.name).average_field(),
176+
'header': ('%s_x' % fn, '%s_y' % fn, '%s_z' % fn)}
177+
178+
data_saver.update_entity_order()

tests/test_mesh.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from fidimag.common import CuboidMesh
2-
2+
import unittest
33

44
def test_mesh1():
55
mesh = CuboidMesh(nx=5, ny=3, nz=2, dx=0.23, dy=0.41)
@@ -9,5 +9,11 @@ def test_mesh1():
99
assert tuple(mesh.coordinates[mesh.index(3, 2, 1)]) == (
1010
(3 + 0.5) * 0.23, (2 + 0.5) * 0.41, 1 + 0.5)
1111

12+
13+
class Mesh_TestCase(unittest.TestCase):
14+
def test_mesh_input_args(self):
15+
self.assertRaises(ValueError, CuboidMesh, 1, 1, 0, 1, 1, 1)
16+
self.assertRaises(ValueError, CuboidMesh, 1, 1, 1, 0, 1, 1)
17+
1218
if __name__ == '__main__':
1319
test_mesh1()

0 commit comments

Comments
 (0)