Skip to content

Commit

Permalink
Merge pull request #119 from computationalmodelling/refactor_magnetis…
Browse files Browse the repository at this point in the history
…ation

Refactor magnetisation
  • Loading branch information
rpep committed Jul 2, 2018
2 parents 446e98a + 6683963 commit 52a0598
Show file tree
Hide file tree
Showing 31 changed files with 543 additions and 201 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -10,12 +10,14 @@

# ignore automatically generated cython files
fidimag/atomistic/lib/clib.c
fidimag/common/lib/common_clib.c
fidimag/common/dipolar/dipolar.c
fidimag/common/neb/neb_clib.c
fidimag/common/neb_method/*clib.c
fidimag/common/sundials/cvode.c
fidimag/micro/lib/baryakhtar/baryakhtar_clib.c
fidimag/micro/lib/micro_clib.c
fidimag/user/example/example.c

# ignore .cache from pytest
.cache
Expand Down
23 changes: 12 additions & 11 deletions fidimag/atomistic/anisotropy.py
Expand Up @@ -50,8 +50,8 @@ def __init__(self, Ku, axis=(1, 0, 0), name='Anisotropy'):
self.axis = axis
self.jac = True

def setup(self, mesh, spin, mu_s):
super(Anisotropy, self).setup(mesh, spin, mu_s)
def setup(self, mesh, spin, mu_s, mu_s_inv):
super(Anisotropy, self).setup(mesh, spin, mu_s, mu_s_inv)

self._Ku = helper.init_scalar(self.Ku, self.mesh)
self._axis = helper.init_vector(self.axis, self.mesh, True)
Expand All @@ -65,13 +65,14 @@ def compute_field(self, t=0, spin=None):

clib.compute_anisotropy(m,
self.field,
self.mu_s_inv,
self.energy,
self._Ku,
self._axis,
self.n
)

return self.field * self.mu_s_inv
return self.field


class CubicAnisotropy(Energy):
Expand All @@ -84,9 +85,8 @@ def __init__(self, Kc, name='CubicAnisotropy'):
self.name = name
self.jac = True


def setup(self, mesh, spin, mu_s):
super(CubicAnisotropy, self).setup(mesh, spin, mu_s)
def setup(self, mesh, spin, mu_s, mu_s_inv):
super(CubicAnisotropy, self).setup(mesh, spin, mu_s, mu_s_inv)
self._Kc = helper.init_scalar(self.Kc, self.mesh)

def compute_field(self, t=0, spin=None):
Expand All @@ -96,9 +96,10 @@ def compute_field(self, t=0, spin=None):
m = self.spin

clib.compute_anisotropy_cubic(m,
self.field,
self.energy,
self._Kc,
self.n)
self.field,
self.mu_s_inv,
self.energy,
self._Kc,
self.n)

return self.field * self.mu_s_inv
return self.field
4 changes: 4 additions & 0 deletions fidimag/atomistic/atomistic_driver.py
Expand Up @@ -133,7 +133,11 @@ def set_default_options(self, gamma=1, mu_s=1, alpha=0.1):
# When we create the simulation, mu_s is set to the default value. This
# is overriden when calling the set_mu_s method from the Simulation
# class or when setting mu_s directly (property)
# David Tue 19 Jun 2018: Not a very clear thing to do, we must set a
# WARNING
self._mu_s[:] = mu_s
self._mu_s_inv[:] = 1. / mu_s

self.mu_s_const = mu_s
self.gamma = gamma
self.do_precession = True
Expand Down
24 changes: 7 additions & 17 deletions fidimag/atomistic/demag.py
@@ -1,8 +1,9 @@
import fidimag.extensions.dipolar as clib
import numpy as np
from .energy import Energy


class Demag(object):
class Demag(Energy):
"""
Energy class for the demagnetising field (a.k.a. dipolar interactions,
Expand Down Expand Up @@ -37,24 +38,13 @@ def __init__(self, name='Demag'):
self.name = name
self.jac = True

def setup(self, mesh, spin, mu_s):
self.mesh = mesh
self.dx = mesh.dx
self.dy = mesh.dy
self.dz = mesh.dz
self.nx = mesh.nx
self.ny = mesh.ny
self.nz = mesh.nz
self.spin = spin
self.n = mesh.n
self.field = np.zeros(3 * self.n, dtype=np.float)
unit_length = mesh.unit_length
self.mu_s_scale = np.zeros(mesh.n, dtype=np.float)

# note that the 1e-7 comes from \frac{\mu_0}{4\pi}
self.scale = 1e-7 / unit_length**3
def setup(self, mesh, spin, mu_s, mu_s_inv):
super(Demag, self).setup(mesh, spin, mu_s, mu_s_inv)
self.scale = 1e-7 / mesh.unit_length**3

# could be wrong, needs carefully tests!!!
# David Tue 19 Jun 2018: This variable is updated in the SIM class in
# case mu_s changes
self.mu_s_scale = mu_s * self.scale

self.demag = clib.FFTDemag(self.dx, self.dy, self.dz,
Expand Down
4 changes: 2 additions & 2 deletions fidimag/atomistic/demag_full.py
Expand Up @@ -18,8 +18,8 @@ def __init__(self, name='DemagFull'):
self.name = name
self.jac = True

def setup(self, mesh, spin, mu_s):
super(DemagFull, self).setup(mesh, spin, mu_s)
def setup(self, mesh, spin, mu_s, mu_s_inv):
super(DemagFull, self).setup(mesh, spin, mu_s, mu_s_inv)

unit_length = mesh.unit_length
self.mu_s_scale = np.zeros(mesh.n, dtype=np.float)
Expand Down
4 changes: 3 additions & 1 deletion fidimag/atomistic/demag_hexagonal.py
Expand Up @@ -51,7 +51,7 @@ def __init__(self, name='DemagHexagonal'):
self.name = name
self.jac = True

def setup(self, mesh, spin, mu_s):
def setup(self, mesh, spin, mu_s, mu_s_inv):

if mesh.mesh_type != 'hexagonal':
raise Exception('This interaction is only defined'
Expand Down Expand Up @@ -89,6 +89,8 @@ def setup(self, mesh, spin, mu_s):
self.scale = 1e-7 / unit_length ** 3

# could be wrong, needs carefully tests!!!
# David Tue 19 Jun 2018: this variable is upated in the sim class
# in case mu_s changes
self.mu_s_scale = mu_s * self.scale

# This seems not to be necessary
Expand Down
8 changes: 5 additions & 3 deletions fidimag/atomistic/dmi.py
Expand Up @@ -81,8 +81,8 @@ def __init__(self, D, name='DMI', dmi_type='bulk'):

self.jac = True

def setup(self, mesh, spin, mu_s):
super(DMI, self).setup(mesh, spin, mu_s)
def setup(self, mesh, spin, mu_s, mu_s_inv):
super(DMI, self).setup(mesh, spin, mu_s, mu_s_inv)

if self.mesh_type == 'hexagonal':
self.n_ngbs_dmi = 6
Expand Down Expand Up @@ -120,6 +120,7 @@ def compute_field(self, t=0, spin=None):
if self.dmi_type == 'bulk':
clib.compute_dmi_field(m,
self.field,
self.mu_s_inv,
self.energy,
self._D,
self.neighbours,
Expand All @@ -131,6 +132,7 @@ def compute_field(self, t=0, spin=None):

clib.compute_dmi_field_interfacial(m,
self.field,
self.mu_s_inv,
self.energy,
self.D,
self.neighbours,
Expand All @@ -140,7 +142,7 @@ def compute_field(self, t=0, spin=None):
self.DMI_vector
)

return self.field * self.mu_s_inv
return self.field

def compute_energy_direct(self):
"""
Expand Down
12 changes: 2 additions & 10 deletions fidimag/atomistic/energy.py
Expand Up @@ -12,7 +12,7 @@ class Energy(object):
"""

def setup(self, mesh, spin, mu_s):
def setup(self, mesh, spin, mu_s, mu_s_inv):
self.mesh = mesh
self.dx = mesh.dx * mesh.unit_length
self.dy = mesh.dy * mesh.unit_length
Expand All @@ -30,16 +30,8 @@ def setup(self, mesh, spin, mu_s):

self.field = np.zeros(3 * self.n, dtype=np.float)
self.energy = np.zeros(mesh.n, dtype=np.float)
self.mu_s_inv = np.zeros(3 * self.n, dtype=np.float)

self.mu_s_inv.shape = (-1, 3)
for i in range(mesh.n):
if self.mu_s[i] == 0.0:
self.mu_s_inv[i, :] = 0
else:
self.mu_s_inv[i, :] = 1.0 / self.mu_s[i]

self.mu_s_inv.shape = (-1,)
self.mu_s_inv = mu_s_inv

self.xperiodic, self.yperiodic = (mesh.periodicity[0],
mesh.periodicity[1])
Expand Down
17 changes: 11 additions & 6 deletions fidimag/atomistic/exchange.py
Expand Up @@ -86,8 +86,8 @@ def __init__(self, J, name='Exchange'):
self.name = name
self.jac = False

def setup(self, mesh, spin, mu_s):
super(Exchange, self).setup(mesh, spin, mu_s)
def setup(self, mesh, spin, mu_s, mu_s_inv):
super(Exchange, self).setup(mesh, spin, mu_s, mu_s_inv)

# Uniform exchange ----------------------------------------------------
if isinstance(self.J, (int, float)):
Expand Down Expand Up @@ -128,21 +128,23 @@ def compute_field_spatial(self, t=0, spin=None):

clib.compute_exchange_field_spatial(m,
self.field,
self.mu_s_inv,
self.energy,
self._J,
self.neighbours,
self.n,
self.n_ngbs
)

return self.field * self.mu_s_inv
return self.field

def compute_field_uniform(self, t=0, spin=None):

m = spin if spin is not None else self.spin

clib.compute_exchange_field(m,
self.field,
self.mu_s_inv,
self.energy,
self.Jx,
self.Jy,
Expand All @@ -152,13 +154,16 @@ def compute_field_uniform(self, t=0, spin=None):
self.n_ngbs
)

return self.field * self.mu_s_inv
return self.field

def compute_field_full(self, t=0, spin=None):

m = spin if spin is not None else self.spin

clib.compute_full_exchange_field(m, self.field, self.energy,
clib.compute_full_exchange_field(m,
self.field,
self.mu_s_inv,
self.energy,
self._J,
self.neighbours,
self.n, self.mesh.n_ngbs,
Expand All @@ -167,7 +172,7 @@ def compute_field_full(self, t=0, spin=None):
self.mesh._sum_ngbs_shell
)

return self.field * self.mu_s_inv
return self.field


class UniformExchange(Exchange):
Expand Down
41 changes: 29 additions & 12 deletions fidimag/atomistic/lib/anis.c
@@ -1,8 +1,10 @@
#include "clib.h"


void compute_anis(double *restrict spin, double *restrict field, double *restrict energy,
double *restrict Ku, double *restrict axis, int n) {
void compute_anis(double *restrict spin, double *restrict field,
double *restrict mu_s_inv,
double *restrict energy,
double *restrict Ku, double *restrict axis, int n) {

/* Remember that the magnetisation order is
* mx1, my1, mz1, mx2, my2, mz2, mx3,...
Expand All @@ -28,28 +30,43 @@ void compute_anis(double *restrict spin, double *restrict field, double *restric

energy[i] = -Ku[i] * (m_u * m_u);

// Scale field by 1/mu_s
field[3 * i] *= mu_s_inv[i];
field[3 * i + 1] *= mu_s_inv[i];
field[3 * i + 2] *= mu_s_inv[i];

}

}


void compute_anis_cubic(double *restrict spin, double *restrict field, double *restrict energy,
double *restrict Kc, int n) {
void compute_anis_cubic(double *restrict spin, double *restrict field,
double *restrict mu_s_inv,
double *restrict energy,
double *restrict Kc, int n) {

/* Remember that the magnetisation order is
* mx1, my1, mz1, mx2, my2, mz2, mx3,...
* so we get the corresponding components multiplying
* by 3 in every iteration.
*
*/
#pragma omp parallel for
for (int i = 0; i < n; i++) {
int j = 3*i;
field[j] = - 4*Kc[i]*spin[j]*spin[j]*spin[j];
field[j+1] = - 4*Kc[i]*spin[j+1]*spin[j+1]*spin[j+1];
field[j+2] = - 4*Kc[i]*spin[j+2]*spin[j+2]*spin[j+2];

energy[i] = -0.25*(field[j]*spin[j]+field[j+1]*spin[j+1]+field[j+2]*spin[j+2]) ;
#pragma omp parallel for
for (int i = 0; i < n; i++) {
int j = 3 * i;
field[j] = - 4 * Kc[i] * spin[j] * spin[j] * spin[j];
field[j+1] = - 4 * Kc[i] * spin[j+1] * spin[j+1] * spin[j+1];
field[j+2] = - 4 * Kc[i] * spin[j+2] * spin[j+2] * spin[j+2];

energy[i] = -0.25 * (field[j] * spin[j] +
field[j+1] * spin[j+1] +
field[j+2] * spin[j+2]
);

// Scale field by 1/mu_s
field[3 * i] *= mu_s_inv[i];
field[3 * i + 1] *= mu_s_inv[i];
field[3 * i + 2] *= mu_s_inv[i];

}

Expand Down

0 comments on commit 52a0598

Please sign in to comment.