Skip to content

Commit 4fd0d97

Browse files
author
Weiwei Wang
committed
try to move cython version to python version
1 parent b299186 commit 4fd0d97

File tree

6 files changed

+147
-44
lines changed

6 files changed

+147
-44
lines changed

fidimag/atomistic/lib/clib.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ void compute_guiding_center(double *spin, int nx, int ny, int nz, double *res);
7979
void compute_px_py_c(double *spin, int nx, int ny, int nz,
8080
double *px, double *py);
8181

82+
//======================================================================
83+
84+
void llg_rhs_dw_c(double *m, double *h, double *dm, double *T, double *alpha,
85+
double *mu_s_inv, int *pins, double *eta, int n, double gamma, double dt);
8286

8387
//=========================================================
8488
//=========================================================

fidimag/atomistic/lib/clib.pyx

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ np.import_array()
44

55

66
cdef extern from "clib.h":
7-
8-
void gauss_random_vec_with_init(double *x, int n)
7+
void initial_random(int seed)
8+
void gauss_random_vec(double *x, int n)
99

1010
double skyrmion_number(double *spin, double *charge,
1111
int nx, int ny, int nz, int *ngbs)
@@ -70,6 +70,8 @@ cdef extern from "clib.h":
7070
double *alpha, int *pins, double *a_J, double beta, double gamma, int n)
7171

7272
# used for sllg
73+
void llg_rhs_dw_c(double *m, double *h, double *dm, double *T, double *alpha, double *mu_s_inv, int *pins, double *eta, int n, double gamma, double dt)
74+
7375
ctypedef struct ode_solver:
7476
pass
7577

@@ -88,15 +90,6 @@ cdef extern from "clib.h":
8890
double *h, double *m, double *T,
8991
double *alpha, double *mu_s_inv, int *pins)
9092

91-
def random_number(np.ndarray[double, ndim=1, mode="c"] v):
92-
cdef int n = len(v)
93-
94-
95-
print n
96-
97-
gauss_random_vec_with_init(&v[0], n)
98-
99-
10093

10194
def compute_skyrmion_number(np.ndarray[double, ndim=1, mode="c"] spin,
10295
np.ndarray[double, ndim=1, mode="c"] charge,
@@ -273,6 +266,26 @@ def normalise_spin(np.ndarray[double, ndim=1, mode="c"] spin, n):
273266
normalise(&spin[0], n)
274267

275268

269+
def init_random(seed):
270+
initial_random(seed);
271+
272+
def random_number_array(np.ndarray[double, ndim=1, mode="c"] v):
273+
274+
cdef int n = len(v)
275+
276+
gauss_random_vec(&v[0], n)
277+
278+
279+
def compute_llg_rhs_dw(np.ndarray[double, ndim=1, mode="c"] dm,
280+
np.ndarray[double, ndim=1, mode="c"] spin,
281+
np.ndarray[double, ndim=1, mode="c"] field,
282+
np.ndarray[double, ndim=1, mode="c"] T,
283+
np.ndarray[double, ndim=1, mode="c"] alpha,
284+
np.ndarray[double, ndim=1, mode="c"] mu_s_inv,
285+
np.ndarray[double, ndim=1, mode="c"] eta,
286+
np.ndarray[int, ndim=1, mode="c"] pin, n, gamma, dt):
287+
llg_rhs_dw_c(&spin[0], &field[0], &dm[0], &T[0], &alpha[0], &mu_s_inv[0], &pin[0], &eta[0], n, gamma, dt)
288+
276289

277290
cdef class RK2S(object):
278291
cdef ode_solver * _c_plan

fidimag/atomistic/lib/llg_random.h

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ static inline unsigned int int_rand(void) {
4343
}
4444

4545
//temporary random generator
46-
void initial_random(void) {
47-
unsigned int seed = (unsigned int) time(NULL);
46+
void initial_random(int seed) {
47+
//unsigned int seed = (unsigned int) time(NULL);
4848

4949
int i;
5050
MT[0] = seed & 0xFFFFFFFFU;
@@ -136,12 +136,4 @@ void gauss_random_vec(double *x, int n) {
136136

137137
}
138138

139-
void gauss_random_vec_with_init(double *x, int n) {
140-
141-
initial_random();
142-
143-
gauss_random_vec(x,n);
144-
145-
}
146-
147139
#endif

fidimag/atomistic/lib/sllg.c

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,48 @@
11
#include "clib.h"
22
#include "llg_random.h"
33

4+
/*
5+
* n is the spin number
6+
* eta is the random number array
7+
*/
8+
void llg_rhs_dw_c(double *m, double *h, double *dm, double *T, double *alpha, double *mu_s_inv, int *pins, double *eta, int n, double gamma, double dt) {
9+
10+
double k_B = 1.3806505e-23;
11+
double Q = 2 * k_B * dt / gamma;
12+
13+
//#pragma omp parallel for
14+
for (int id = 0; id < n; id++) {
15+
int i = 3*id;
16+
int j = i+1;
17+
int k = j+1;
18+
19+
if (pins[id]>0){
20+
dm[i] = 0;
21+
dm[j] = 0;
22+
dm[k] = 0;
23+
continue;
24+
}
25+
26+
27+
double coeff = -gamma/ (1.0 + alpha[id] * alpha[id]);
28+
double q = sqrt(Q * alpha[id] * T[id] * mu_s_inv[id]);
29+
30+
double hi = h[i]*dt + eta[i]*q;
31+
double hj = h[j]*dt + eta[j]*q;
32+
double hk = h[k]*dt + eta[k]*q;
33+
34+
double mth0 = coeff * (m[j] * hk - m[k] * hj);
35+
double mth1 = coeff * (m[k] * hi - m[i] * hk);
36+
double mth2 = coeff * (m[i] * hj - m[j] * hi);
37+
38+
dm[i] = mth0 + alpha[id] * (m[j] * mth2 - m[k] * mth1);
39+
dm[j] = mth1 + alpha[id] * (m[k] * mth0 - m[i] * mth2);
40+
dm[k] = mth2 + alpha[id] * (m[i] * mth1 - m[j] * mth0);
41+
42+
}
43+
}
44+
45+
446

547
ode_solver *create_ode_plan(void) {
648

@@ -33,7 +75,7 @@ void init_solver(ode_solver *s, double k_B, double theta, int n, double dt, doub
3375
s->eta[i] = 0;
3476
}
3577

36-
initial_random();
78+
initial_random(2);
3779
}
3880

3981

@@ -57,7 +99,7 @@ void llg_rhs_dw(ode_solver *s, double *m, double *h, double *dm, double *T, doub
5799
j = i+1;
58100
k = j+1;
59101

60-
if (pins[i]>0){
102+
if (pins[id]>0){
61103
dm[i] = 0;
62104
dm[j] = 0;
63105
dm[k] = 0;
@@ -66,7 +108,7 @@ void llg_rhs_dw(ode_solver *s, double *m, double *h, double *dm, double *T, doub
66108

67109

68110
coeff = -s->gamma/ (1.0 + alpha[id] * alpha[id]) ;
69-
q = sqrt(Q * alpha[i] * T[i] * mu_s_inv[id]);
111+
q = sqrt(Q * alpha[i] * T[id] * mu_s_inv[id]);
70112

71113
hi = h[i]*dt + eta[i]*q;
72114
hj = h[j]*dt + eta[j]*q;

fidimag/atomistic/sllg.py

Lines changed: 71 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ def __init__(self, mesh, name='unnamed'):
1919
super(SLLG, self).__init__(mesh, name=name)
2020

2121
self._T = np.zeros(self.n, dtype=np.float)
22+
self.next_spin = np.zeros(3*self.n, dtype=np.float)
23+
self.eta = np.zeros(3*self.n, dtype=np.float)
24+
self.dm1 = np.zeros(3*self.n, dtype=np.float)
25+
self.dm2 = np.zeros(3*self.n, dtype=np.float)
2226

2327
self.set_options()
2428

@@ -30,30 +34,78 @@ def set_T(self, T0):
3034

3135
T = property(get_T, set_T)
3236

33-
def set_options(self, dt=1e-15, theta=1.0, gamma=const.gamma, k_B=const.k_B):
37+
def set_options(self, dt=1e-15, theta=1.0, gamma=const.gamma, k_B=const.k_B, seed=100):
3438

39+
clib.init_random(seed)
3540
self.gamma = gamma
3641
self.k_B = k_B
37-
print 'self.n=',self.n
38-
39-
self.vode = clib.RK2S(dt,
40-
self.n,
41-
self.gamma,
42-
self.k_B,
43-
theta,
44-
self._mu_s_inv,
45-
self.alpha,
46-
self.spin,
47-
self.field,
48-
self._T,
49-
self._pins,
50-
self.update_effective_field)
42+
self.dt = dt
43+
self.theta = theta
44+
self.theta1 = 1-0.5/theta;
45+
self.theta2 = 0.5/theta;
46+
47+
def run_step(self):
48+
49+
clib.random_number_array(self.eta)
50+
51+
#step1
52+
self.update_effective_field(self.spin, self.t)
53+
clib.compute_llg_rhs_dw(self.dm1,
54+
self.spin,
55+
self.field,
56+
self._T,
57+
self._alpha,
58+
self._mu_s_inv,
59+
self.eta,
60+
self._pins,
61+
self.n,
62+
self.gamma,
63+
self.dt)
64+
self.next_spin = self.spin + self.theta * self.dm1
65+
66+
self.step += 1
67+
self.t = self.dt*self.step
68+
69+
#step2
70+
self.update_effective_field(self.next_spin, self.t)
71+
clib.compute_llg_rhs_dw(self.dm2,
72+
self.next_spin,
73+
self.field,
74+
self._T,
75+
self._alpha,
76+
self._mu_s_inv,
77+
self.eta,
78+
self._pins,
79+
self.n,
80+
self.gamma,
81+
self.dt)
82+
self.spin += (self.theta1*self.dm1+self.theta2*self.dm2)
83+
84+
clib.normalise_spin(self.spin, self.n)
85+
5186

52-
def update_effective_field(self, y, t):
5387

54-
self.spin[:] = y[:]
88+
def update_effective_field(self, y, t):
5589

5690
self.field[:] = 0
57-
return 0
91+
5892
for obj in self.interactions:
59-
self.field += obj.compute_field(t)
93+
self.field += obj.compute_field(t, spin=y)
94+
95+
96+
def run_until(self, t):
97+
98+
if t <= self.t:
99+
if t == self.t and self.t == 0.0:
100+
self.compute_effective_field(t)
101+
self.saver.save()
102+
return
103+
104+
self.spin_last[:] = self.spin[:]
105+
106+
while (self.t<t):
107+
self.run_step()
108+
109+
# update field before saving data
110+
self.compute_effective_field(t)
111+
self.saver.save()

fidimag/atomistic/zeeman.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def setup(self, mesh, spin, mu_s):
3030
self.field = np.zeros(3 * self.n)
3131
self.field[:] = helper.init_vector(self.H0, self.mesh)
3232

33-
def compute_field(self, t=0):
33+
def compute_field(self, t=0, spin=None):
3434
return self.field
3535

3636
def average_field(self):

0 commit comments

Comments
 (0)