forked from mumax/3
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexchange.cu
88 lines (73 loc) · 2.66 KB
/
exchange.cu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <stdint.h>
#include "exchange.h"
#include "float3.h"
#include "stencil.h"
#include "amul.h"
// See exchange.go for more details.
extern "C" __global__ void
addexchange(float* __restrict__ Bx, float* __restrict__ By, float* __restrict__ Bz,
float* __restrict__ mx, float* __restrict__ my, float* __restrict__ mz,
float* __restrict__ Ms_, float Ms_mul,
float* __restrict__ aLUT2d, uint8_t* __restrict__ regions,
float wx, float wy, float wz, int Nx, int Ny, int Nz, uint8_t PBC) {
int ix = blockIdx.x * blockDim.x + threadIdx.x;
int iy = blockIdx.y * blockDim.y + threadIdx.y;
int iz = blockIdx.z * blockDim.z + threadIdx.z;
if (ix >= Nx || iy >= Ny || iz >= Nz) {
return;
}
// central cell
int I = idx(ix, iy, iz);
float3 m0 = make_float3(mx[I], my[I], mz[I]);
if (is0(m0)) {
return;
}
uint8_t r0 = regions[I];
float3 B = make_float3(0.0,0.0,0.0);
int i_; // neighbor index
float3 m_; // neighbor mag
float a__; // inter-cell exchange stiffness
// left neighbor
i_ = idx(lclampx(ix-1), iy, iz); // clamps or wraps index according to PBC
m_ = make_float3(mx[i_], my[i_], mz[i_]); // load m
m_ = ( is0(m_)? m0: m_ ); // replace missing non-boundary neighbor
a__ = aLUT2d[symidx(r0, regions[i_])];
B += wx * a__ *(m_ - m0);
// right neighbor
i_ = idx(hclampx(ix+1), iy, iz);
m_ = make_float3(mx[i_], my[i_], mz[i_]);
m_ = ( is0(m_)? m0: m_ );
a__ = aLUT2d[symidx(r0, regions[i_])];
B += wx * a__ *(m_ - m0);
// back neighbor
i_ = idx(ix, lclampy(iy-1), iz);
m_ = make_float3(mx[i_], my[i_], mz[i_]);
m_ = ( is0(m_)? m0: m_ );
a__ = aLUT2d[symidx(r0, regions[i_])];
B += wy * a__ *(m_ - m0);
// front neighbor
i_ = idx(ix, hclampy(iy+1), iz);
m_ = make_float3(mx[i_], my[i_], mz[i_]);
m_ = ( is0(m_)? m0: m_ );
a__ = aLUT2d[symidx(r0, regions[i_])];
B += wy * a__ *(m_ - m0);
// only take vertical derivative for 3D sim
if (Nz != 1) {
// bottom neighbor
i_ = idx(ix, iy, lclampz(iz-1));
m_ = make_float3(mx[i_], my[i_], mz[i_]);
m_ = ( is0(m_)? m0: m_ );
a__ = aLUT2d[symidx(r0, regions[i_])];
B += wz * a__ *(m_ - m0);
// top neighbor
i_ = idx(ix, iy, hclampz(iz+1));
m_ = make_float3(mx[i_], my[i_], mz[i_]);
m_ = ( is0(m_)? m0: m_ );
a__ = aLUT2d[symidx(r0, regions[i_])];
B += wz * a__ *(m_ - m0);
}
float invMs = inv_Msat(Ms_, Ms_mul, I);
Bx[I] += B.x*invMs;
By[I] += B.y*invMs;
Bz[I] += B.z*invMs;
}