Skip to content

Commit 11add83

Browse files
author
davidcorteso
committed
Merged from master and modified MonteCarlo with WWs updates
2 parents 37d043a + e1183b5 commit 11add83

File tree

8 files changed

+244
-185
lines changed

8 files changed

+244
-185
lines changed

.travis.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
sudo: required
22

3+
dist: trusty
4+
group: deprecated-2017Q4
5+
36
services:
47
- docker
58

@@ -8,4 +11,4 @@ script:
811

912
notifications:
1013
email:
11-
on_failure: always
14+
on_failure: always

examples/mc/skx.py

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,18 @@
55
import numpy as np
66
from fidimag.atomistic import MonteCarlo
77
from fidimag.common import DataReader, CuboidMesh
8-
9-
10-
def init_m(pos):
11-
x,y,z = pos
12-
13-
return (0,0,1)
8+
import fidimag.common.constant as const
149

1510
def random_m(pos):
1611
return np.random.random(3) - 0.5
1712

18-
1913
def run(mesh):
20-
2114
mc = MonteCarlo(mesh, name='test1')
2215
mc.set_m(random_m)
23-
mc.set_options(H=[0,0,0.0], J=50.0, D=0.27*50, T=5.0, Kc=50*0.1)
24-
mc.run(steps=20000, save_m_steps=None, save_vtk_steps=1000, save_data_steps=10)
16+
J = 50*const.k_B
17+
mc.set_options(H=[0,0,0.0], J=J, D=0.27*J, T=4.0)
18+
mc.run(steps=100000, save_m_steps=None, save_vtk_steps=50000, save_data_steps=50000)
2519

2620
if __name__=='__main__':
27-
28-
#mesh = CuboidMesh(nx=174,ny=150, nz=1, pbc='2d')
29-
mesh = CuboidMesh(nx=100, ny=100, nz=1, periodicity = (True, True, False))
30-
31-
run(mesh)
21+
mesh = CuboidMesh(nx=58, ny=33, nz=1, periodicity = (True, True, False))
22+
run(mesh)

fidimag/atomistic/lib/clib.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,6 @@ void llg_s_rhs(double *dm_dt, double *spin, double *h, double *alpha,
106106
void run_step_mc(mt19937_state *state, double *spin, double *new_spin,
107107
int *ngbs, int *nngbs, int n_ngbs, double J, double J1, double D,
108108
double D1, double *h, double Kc, int n, double T,
109-
int hexagnoal_mesh);
109+
int hexagonal_mesh);
110110

111111
#endif

fidimag/atomistic/lib/mc.c

Lines changed: 157 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,167 +1,188 @@
11
#include "clib.h"
22
#include "fidimag_random.h"
33

4-
inline double dot(double a[3], double b[3]){
5-
return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];
4+
inline double dot(double a[3], double b[3]) {
5+
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
66
}
77

8-
//the bulk DMI for a cuboid mesh
9-
inline double dmi_energy_site(double a[3], double b[3], int i){
10-
double res=0;
11-
switch (i) {
12-
case 0:
13-
res=-(a[1] * b[2] - a[2] * b[1]);break;//-x
14-
case 1:
15-
res= (a[1] * b[2] - a[2] * b[1]); break;//+x
16-
case 2:
17-
res = -(a[2] * b[0] - a[0] * b[2]); break;//-y
18-
case 3:
19-
res = (a[2] * b[0] - a[0] * b[2]); break;//+y
20-
case 4:
21-
res = -(a[0] * b[1] - a[1] * b[0]); break;//-z
22-
case 5:
23-
res = (a[0] * b[1] - a[1] * b[0]); break;//+z
24-
default:
25-
break;
26-
}
27-
return res;
8+
// helper function to compute the bulk DMI for a cuboid mesh with neighbour i
9+
inline double dmi_energy_site(double a[3], double b[3], int i) {
10+
double res = 0;
11+
switch (i) {
12+
case 0:
13+
res = -(a[1] * b[2] - a[2] * b[1]);
14+
break; //-x
15+
case 1:
16+
res = (a[1] * b[2] - a[2] * b[1]);
17+
break; //+x
18+
case 2:
19+
res = -(a[2] * b[0] - a[0] * b[2]);
20+
break; //-y
21+
case 3:
22+
res = (a[2] * b[0] - a[0] * b[2]);
23+
break; //+y
24+
case 4:
25+
res = -(a[0] * b[1] - a[1] * b[0]);
26+
break; //-z
27+
case 5:
28+
res = (a[0] * b[1] - a[1] * b[0]);
29+
break; //+z
30+
default:
31+
break;
32+
}
33+
return res;
2834
}
2935

30-
//note that this DMI only works for a 2d hexagnoal mesh.
31-
inline double dmi_energy_hexagnoal_site(double a[3], double b[3], int i){
32-
double res=0;
33-
switch (i) {
34-
case 0:
35-
res=(a[1] * b[2] - a[2] * b[1]);break;//+x
36-
case 1:
37-
res=-(a[1] * b[2] - a[2] * b[1]); break;//-x
38-
case 2:
39-
res=0.5*(a[1] * b[2] - a[2] * b[1])+0.86602540378443864676*(a[2] * b[0] - a[0] * b[2]); break;//top right, r={1/2, sqrt(3)/2, 0}
40-
case 3:
41-
res=-0.5*(a[1] * b[2] - a[2] * b[1])-0.86602540378443864676*(a[2] * b[0] - a[0] * b[2]); break;//bottom left, r={-1/2, -sqrt(3)/2, 0}
42-
case 4:
43-
res=-0.5*(a[1] * b[2] - a[2] * b[1])+0.86602540378443864676*(a[2] * b[0] - a[0] * b[2]); break;//top left, r={-1/2, sqrt(3)/2, 0}
44-
case 5:
45-
res=0.5*(a[1] * b[2] - a[2] * b[1])-0.86602540378443864676*(a[2] * b[0] - a[0] * b[2]); break;//bottom right, r={1/2, -sqrt(3)/2, 0}
46-
default:
47-
break;
48-
}
49-
return res;
36+
// note that this DMI only works for a 2d hexagonal mesh.
37+
inline double dmi_energy_hexagonal_site(double a[3], double b[3], int i) {
38+
double res = 0;
39+
switch (i) {
40+
case 0:
41+
res = (a[1] * b[2] - a[2] * b[1]);
42+
break; //+x
43+
case 1:
44+
res = -(a[1] * b[2] - a[2] * b[1]);
45+
break; //-x
46+
case 2:
47+
res = 0.5 * (a[1] * b[2] - a[2] * b[1]) +
48+
0.86602540378443864676 * (a[2] * b[0] - a[0] * b[2]);
49+
break; // top right, r={1/2, sqrt(3)/2, 0}
50+
case 3:
51+
res = -0.5 * (a[1] * b[2] - a[2] * b[1]) -
52+
0.86602540378443864676 * (a[2] * b[0] - a[0] * b[2]);
53+
break; // bottom left, r={-1/2, -sqrt(3)/2, 0}
54+
case 4:
55+
res = -0.5 * (a[1] * b[2] - a[2] * b[1]) +
56+
0.86602540378443864676 * (a[2] * b[0] - a[0] * b[2]);
57+
break; // top left, r={-1/2, sqrt(3)/2, 0}
58+
case 5:
59+
res = 0.5 * (a[1] * b[2] - a[2] * b[1]) -
60+
0.86602540378443864676 * (a[2] * b[0] - a[0] * b[2]);
61+
break; // bottom right, r={1/2, -sqrt(3)/2, 0}
62+
default:
63+
break;
64+
}
65+
return res;
5066
}
5167

68+
// helper function to compute the cubic energy
69+
inline double cubic_energy_site(double *m, double Kc) {
5270

53-
//helper function to compute the cubic energy
54-
inline double cubic_energy_site(double *m, double Kc){
71+
double mx2 = m[0] * m[0];
72+
double my2 = m[1] * m[1];
73+
double mz2 = m[2] * m[2];
5574

56-
double mx2 = m[0]*m[0];
57-
double my2 = m[1]*m[1];
58-
double mz2 = m[2]*m[2];
59-
60-
return -Kc*(mx2*mx2+my2*my2+mz2*mz2);
61-
75+
return -Kc * (mx2 * mx2 + my2 * my2 + mz2 * mz2);
6276
}
6377

64-
double compute_deltaE_anisotropy(double *spin, double *new_spin, double *h, double Kc, int i){
78+
double compute_deltaE_anisotropy(double *spin, double *new_spin, double *h,
79+
double Kc, int i, int new_i) {
80+
81+
double energy1 = -dot(&spin[3 * i], &h[3 * i]); // zeeman energy
82+
double energy2 = -dot(&new_spin[3 * new_i], &h[3 * i]);
6583

66-
double energy1 = -dot(&spin[3*i], &h[3*i]); //zeeman energy
67-
double energy2 = -dot(&new_spin[3*i], &h[3*i]);
68-
69-
energy1 += cubic_energy_site(&spin[3*i], Kc); //cubic anisotropy energy
70-
energy2 += cubic_energy_site(&new_spin[3*i], Kc);
71-
72-
return energy2-energy1;
84+
energy1 += cubic_energy_site(&spin[3 * i], Kc); // cubic anisotropy energy
85+
energy2 += cubic_energy_site(&new_spin[3 * new_i], Kc);
7386

87+
return energy2 - energy1;
7488
}
7589

7690
/*
7791
* n is the total spin number
7892
*/
79-
double compute_deltaE_exchange_DMI_hexagnoal(double *spin, double *new_spin, int *ngbs, int n_ngbs, double J, double D, int i){
80-
81-
int id_nn = n_ngbs * i;
82-
double energy1=0, energy2=0;
83-
84-
for (int j = 0; j < 6; j++) {
85-
int k = ngbs[id_nn + j];
86-
if (k >= 0) {
87-
energy1 -= J*dot(&spin[3*i], &spin[3*k]);//exchange energy
88-
energy1 += D*dmi_energy_hexagnoal_site(&spin[3*i], &spin[3*k], j); //DMI energy
89-
90-
energy2 -= J*dot(&new_spin[3*i], &spin[3*k]);
91-
energy2 += D*dmi_energy_hexagnoal_site(&new_spin[3*i], &spin[3*k], j);
92-
93-
}
93+
double compute_deltaE_exchange_DMI_hexagonal(double *spin, double *new_spin,
94+
int *ngbs, int n_ngbs, double J, double D,
95+
int i, int new_i) {
96+
97+
int id_nn = n_ngbs * i;
98+
double energy1 = 0, energy2 = 0;
99+
100+
for (int j = 0; j < 6; j++) {
101+
int k = ngbs[id_nn + j];
102+
if (k >= 0) {
103+
energy1 -= J * dot(&spin[3 * i], &spin[3 * k]); // exchange energy
104+
energy1 += D * dmi_energy_hexagonal_site(&spin[3 * i], &spin[3 * k],
105+
j); // DMI energy
106+
107+
energy2 -= J * dot(&new_spin[3 * new_i], &spin[3 * k]);
108+
energy2 += D * dmi_energy_hexagonal_site(&new_spin[3 * new_i],
109+
&spin[3 * k], j); // DMI energy
94110
}
111+
}
95112

96-
return energy2-energy1;
97-
113+
return energy2 - energy1;
98114
}
99115

100-
double compute_deltaE_exchange_DMI(double *spin, double *new_spin, int *ngbs, int *nngbs, int n_ngbs, double J, double J1, double D, double D1, int i){
101-
102-
int id_nn = n_ngbs * i;
103-
double energy1=0, energy2=0;
104-
105-
for (int j = 0; j < 6; j++) {
106-
int k = ngbs[id_nn + j];
107-
if (k >= 0) {
108-
energy1 -= J*dot(&spin[3*i], &spin[3*k]) ;//exchange energy
109-
energy1 += D*dmi_energy_site(&spin[3*i], &spin[3*k], j); //DMI energy
110-
111-
energy2 -= J*dot(&new_spin[3*i], &spin[3*k]);
112-
energy2 += D*dmi_energy_site(&new_spin[3*i], &spin[3*k], j);
113-
}
114-
k = nngbs[id_nn + j];
115-
if (k >= 0) {
116-
energy1 -= J1*dot(&spin[3*i], &spin[3*k]) ;//exchange energy
117-
energy1 += D1*dmi_energy_site(&spin[3*i], &spin[3*k], j); //DMI energy
118-
119-
energy2 -= J1*dot(&new_spin[3*i], &spin[3*k]);
120-
energy2 += D1*dmi_energy_site(&new_spin[3*i], &spin[3*k], j);
121-
}
122-
116+
double compute_deltaE_exchange_DMI(double *spin, double *new_spin, int *ngbs,
117+
int *nngbs, int n_ngbs, double J, double J1, double D,
118+
double D1, int i, int new_i) {
119+
120+
int id_nn = n_ngbs * i;
121+
double energy1 = 0, energy2 = 0;
122+
123+
for (int j = 0; j < 6; j++) {
124+
int k = ngbs[id_nn + j];
125+
if (k >= 0) {
126+
energy1 -= J * dot(&spin[3 * i], &spin[3 * k]); // exchange energy
127+
energy1 += D * dmi_energy_site(&spin[3 * i], &spin[3 * k], j); // DMI
128+
129+
energy2 -= J * dot(&new_spin[3 * new_i], &spin[3 * k]);
130+
energy2 += D * dmi_energy_site(&new_spin[3 * new_i], &spin[3 * k], j);
123131
}
124-
125-
return energy2-energy1;
126-
132+
k = nngbs[id_nn + j];
133+
if (k >= 0) {
134+
energy1 -= J1 * dot(&spin[3 * i], &spin[3 * k]); // exchange energy
135+
energy1 += D1 * dmi_energy_site(&spin[3 * i], &spin[3 * k], j); // DMI
136+
137+
energy2 -= J1 * dot(&new_spin[3 * new_i], &spin[3 * k]);
138+
energy2 += D1 * dmi_energy_site(&new_spin[3 * new_i], &spin[3 * k], j);
139+
}
140+
}
141+
142+
return energy2 - energy1;
127143
}
128144

145+
void run_step_mc(mt19937_state *state, double *spin, double *new_spin,
146+
int *ngbs, int *nngbs, int n_ngbs, double J, double J1, double D,
147+
double D1, double *h, double Kc, int n, double T,
148+
int hexagonal_mesh) {
129149

130-
void run_step_mc(mt19937_state *state, double *spin, double *new_spin, int *ngbs, int *nngbs, int n_ngbs, double J, double J1, double D, double D1, double *h, double Kc, int n, double T, int hexagnoal_mesh){
131-
132-
double delta_E, r;
133-
int update=0;
134-
135-
uniform_random_sphere(state, new_spin, n);
136-
137-
for(int i=0;i<n;i++){
138-
139-
int index = rand_int_n(state, n);
140-
int j=3*index;
141-
142-
delta_E = compute_deltaE_anisotropy(&spin[0], &new_spin[0], &h[0], Kc, index);
143-
144-
if(hexagnoal_mesh){
145-
delta_E += compute_deltaE_exchange_DMI_hexagnoal(&spin[0], &new_spin[0], &ngbs[0], n_ngbs, J, D, index);
146-
}else{
147-
delta_E += compute_deltaE_exchange_DMI(&spin[0], &new_spin[0], &ngbs[0], &nngbs[0], n_ngbs, J, J1, D, D1, index);
148-
}
149-
150-
151-
if (delta_E<0) {update=1;}
152-
else{
153-
r = random_double_half_open(state);
154-
if (r<exp(-delta_E/T)) update=1;
155-
}
156-
157-
if(update){
158-
spin[j]=new_spin[j];
159-
spin[j+1]=new_spin[j+1];
160-
spin[j+2]=new_spin[j+2];
161-
}
162-
163-
update = 0;
164-
150+
double delta_E, r;
151+
int update = 0;
152+
153+
uniform_random_sphere(state, new_spin, n);
154+
155+
for (int new_i = 0; new_i < n; new_i++) {
156+
157+
int i = rand_int_n(state, n);
158+
int j = 3 * i;
159+
int new_j = 3 * new_i;
160+
161+
delta_E =
162+
compute_deltaE_anisotropy(&spin[0], &new_spin[0], &h[0], Kc, i, new_i);
163+
164+
if (hexagonal_mesh) {
165+
delta_E += compute_deltaE_exchange_DMI_hexagonal(
166+
&spin[0], &new_spin[0], &ngbs[0], n_ngbs, J, D, i, new_i);
167+
} else {
168+
delta_E += compute_deltaE_exchange_DMI(&spin[0], &new_spin[0], &ngbs[0], n_ngbs,
169+
&nngbs[0], J, J1, D, D1, i, new_i);
165170
}
166171

172+
update = 0;
173+
174+
if (delta_E < 0) {
175+
update = 1;
176+
} else {
177+
r = random_double_half_open(state);
178+
if (r < exp(-delta_E / T))
179+
update = 1;
180+
}
181+
182+
if (update) {
183+
spin[j] = new_spin[new_j];
184+
spin[j + 1] = new_spin[new_j + 1];
185+
spin[j + 2] = new_spin[new_j + 2];
186+
}
187+
}
167188
}

0 commit comments

Comments
 (0)