Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/regionwise gammaLL #315

Open
wants to merge 10 commits into
base: 3.11
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion cuda/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
#define MU0 (4*PI*1e-7) // Permeability of vacuum in Tm/A
#define QE 1.60217646E-19 // Electron charge in C
#define MUB 9.2740091523E-24 // Bohr magneton in J/T
#define GAMMA0 1.7595e11 // Gyromagnetic ratio of electron, in rad/Ts
// GAMMA0 should NOT be used. It is a user definable parameter, not constant!
// Anyway, now we implement the region-wise g. It was only used in zhangli.cu
//#define GAMMA0 1.7595e11 // Gyromagnetic ratio of electron, in rad/Ts
#define HBAR 1.05457173E-34

#endif
10 changes: 10 additions & 0 deletions cuda/lltorque.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ func LLTorque(torque, m, B *data.Slice, alpha MSlice) {
alpha.DevPtr(0), alpha.Mul(0), N, cfg)
}

// Scale up the torques by GFactor (to allow regionwise g)
func ScaleGamma(torque *data.Slice, GFactor MSlice) {
N := torque.Len()
cfg := make1DConf(N)

k_scalegamma_async(torque.DevPtr(X), torque.DevPtr(Y), torque.DevPtr(Z),
GFactor.DevPtr(0), GFactor.Mul(0), N, cfg)

}

// Landau-Lifshitz torque with precession disabled.
// Used by engine.Relax().
func LLNoPrecess(torque, m, B *data.Slice) {
Expand Down
17 changes: 17 additions & 0 deletions cuda/scalegamma.cu
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "amul.h"
#include "float3.h"
#include <stdint.h>

// scale torque by scalar parameter GammaFactor
extern "C" __global__ void
scalegamma(float* __restrict__ tx, float* __restrict__ ty, float* __restrict__ tz,
float* __restrict__ scalegamma_, float scalegamma_mul, int N) {

int i = ( blockIdx.y*gridDim.x + blockIdx.x ) * blockDim.x + threadIdx.x;
if (i < N) {
float gammaf = amul(scalegamma_, scalegamma_mul,i);
tx[i] = tx[i]*gammaf;
ty[i] = ty[i]*gammaf;
tz[i] = tz[i]*gammaf;
}
}
3 changes: 2 additions & 1 deletion cuda/temperature.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

// Set Bth to thermal noise (Brown).
// see temperature.cu
func SetTemperature(Bth, noise *data.Slice, k2mu0_Mu0VgammaDt float64, Msat, Temp, Alpha MSlice) {
func SetTemperature(Bth, noise *data.Slice, k2mu0_Mu0VgammaDt float64, Msat, Temp, Alpha, g MSlice) {
util.Argument(Bth.NComp() == 1 && noise.NComp() == 1)

N := Bth.Len()
Expand All @@ -17,5 +17,6 @@ func SetTemperature(Bth, noise *data.Slice, k2mu0_Mu0VgammaDt float64, Msat, Tem
Msat.DevPtr(0), Msat.Mul(0),
Temp.DevPtr(0), Temp.Mul(0),
Alpha.DevPtr(0), Alpha.Mul(0),
g.DevPtr(0), g.Mul(0),
N, cfg)
}
5 changes: 3 additions & 2 deletions cuda/temperature2.cu
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ settemperature2(float* __restrict__ B, float* __restrict__ noise, float kB
float* __restrict__ Ms_, float Ms_mul,
float* __restrict__ temp_, float temp_mul,
float* __restrict__ alpha_, float alpha_mul,
float* __restrict__ g_, float g_mul,
int N) {

int i = ( blockIdx.y*gridDim.x + blockIdx.x ) * blockDim.x + threadIdx.x;
if (i < N) {
float invMs = inv_Msat(Ms_, Ms_mul, i);
float temp = amul(temp_, temp_mul, i);
float alpha = amul(alpha_, alpha_mul, i);
B[i] = noise[i] * sqrtf((kB2_VgammaDt * alpha * temp * invMs ));
float g = amul(g_, g_mul, i);
B[i] = noise[i] * sqrtf((kB2_VgammaDt * alpha * temp * invMs / g));
}
}

3 changes: 2 additions & 1 deletion cuda/zhangli.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

// Add Zhang-Li ST torque (Tesla) to torque.
// see zhangli.cu
func AddZhangLiTorque(torque, m *data.Slice, Msat, J, alpha, xi, pol MSlice, mesh *data.Mesh) {
func AddZhangLiTorque(torque, m *data.Slice, Msat, J, alpha, xi, pol, g MSlice, gammaLL float32, mesh *data.Mesh) {
c := mesh.CellSize()
N := mesh.Size()
cfg := make3DConf(N)
Expand All @@ -21,6 +21,7 @@ func AddZhangLiTorque(torque, m *data.Slice, Msat, J, alpha, xi, pol MSlice, mes
alpha.DevPtr(0), alpha.Mul(0),
xi.DevPtr(0), xi.Mul(0),
pol.DevPtr(0), pol.Mul(0),
g.DevPtr(0), g.Mul(0)*gammaLL,
float32(c[X]), float32(c[Y]), float32(c[Z]),
N[X], N[Y], N[Z], mesh.PBC_code(), cfg)
}
8 changes: 5 additions & 3 deletions cuda/zhangli2.cu
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
#include "stencil.h"
#include <stdint.h>

#define PREFACTOR ((MUB) / (2 * QE * GAMMA0))
// #define PREFACTOR ((MUB) / (2 * QE * GAMMA0))
#define PREFACTOR ((HBAR) / (2 * QE))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this new calculation of PREFACTOR correct?

The only place where PREFACTOR is used is a bit further in this file, where it is now divided by g. As far as I understand it, g should be 1 by default, so should PREFACTOR then not stay the same?
The previous factor MUB/GAMMA0 == 5.27082077425405e-35 but the new factor HBAR == 1.05457173e-34.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Jonathan,

I think you're right... The only place where this PREFACTOR is used is on line ~41, which is changed
(-) float b = invMs * PREFACTOR / (1.0f + xi*xi);
(+) float b = invMs * PREFACTOR / (g*(1.0f + xi*xi));

So, the new value of PREFACTOR should be the old one times the default value of g (which is 1.), and not twice its value.

I think the problem came about because initially (and in the code I use) I defined g as the physical Landé g-factor (=2.00 by default) and removed the parameter GammaLL. In this case, the new PREFACTOR should indeed be twice the old value. This definition makes much more sense, as g would be the physical well-known g-factor, but breaks the backwards compatibility in scripts that use the parameter GammaLL. I think I might have mixed the files when uploading this change, and I'm surprised it wasn't caught in the validation tests...

~~ João


// spatial derivatives without dividing by cell size
#define deltax(in) (in[idx(hclampx(ix+1), iy, iz)] - in[idx(lclampx(ix-1), iy, iz)])
Expand All @@ -21,6 +22,7 @@ addzhanglitorque2(float* __restrict__ tx, float* __restrict__ ty, float* __restr
float* __restrict__ alpha_, float alpha_mul,
float* __restrict__ xi_, float xi_mul,
float* __restrict__ pol_, float pol_mul,
float* __restrict__ g_, float g_mul,
float cx, float cy, float cz,
int Nx, int Ny, int Nz, uint8_t PBC) {

Expand All @@ -37,8 +39,9 @@ addzhanglitorque2(float* __restrict__ tx, float* __restrict__ ty, float* __restr
float alpha = amul(alpha_, alpha_mul, i);
float xi = amul(xi_, xi_mul, i);
float pol = amul(pol_, pol_mul, i);
float g = amul(g_, g_mul, i);
float invMs = inv_Msat(Ms_, Ms_mul, i);
float b = invMs * PREFACTOR / (1.0f + xi*xi);
float b = invMs * PREFACTOR / (g*(1.0f + xi*xi));
float3 J = pol*vmul(jx_, jy_, jz_, jx_mul, jy_mul, jz_mul, i);

float3 hspin = make_float3(0.0f, 0.0f, 0.0f); // (u·∇)m
Expand All @@ -62,4 +65,3 @@ addzhanglitorque2(float* __restrict__ tx, float* __restrict__ ty, float* __restr
ty[i] += torque.y;
tz[i] += torque.z;
}

4 changes: 3 additions & 1 deletion engine/temperature.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,11 @@ func (b *thermField) update() {
defer temp.Recycle()
alpha := Alpha.MSlice()
defer alpha.Recycle()
g := GFactor.MSlice()
defer g.Recycle()
for i := 0; i < 3; i++ {
b.generator.GenerateNormal(uintptr(noise.DevPtr(0)), int64(N), mean, stddev)
cuda.SetTemperature(dst.Comp(i), noise, k2_VgammaDt, ms, temp, alpha)
cuda.SetTemperature(dst.Comp(i), noise, k2_VgammaDt, ms, temp, alpha, g)
}

b.step = NSteps
Expand Down
27 changes: 24 additions & 3 deletions engine/torque.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (

var (
Alpha = NewScalarParam("alpha", "", "Landau-Lifshitz damping constant")
GFactor = NewScalarParam("GFactor","","Region-wise scaling factor for GammaLL (default: 1.00). If GammaLL is set to µB/hbar (8.7941e10), GFactor is the material's g-factor.")
GammaLL float64 = 1.7595e11 // Gyromagnetic ratio of spins, in rad/Ts
Xi = NewScalarParam("xi", "", "Non-adiabaticity of spin-transfer-torque")
Pol = NewScalarParam("Pol", "", "Electrical current polarization")
Lambda = NewScalarParam("Lambda", "", "Slonczewski Λ parameter")
Expand All @@ -22,17 +24,26 @@ var (
STTorque = NewVectorField("STTorque", "T", "Spin-transfer torque/γ0", AddSTTorque)
J = NewExcitation("J", "A/m2", "Electrical current density")
MaxTorque = NewScalarValue("maxTorque", "T", "Maximum torque/γ0, over all cells", GetMaxTorque)
GammaLL float64 = 1.7595e11 // Gyromagnetic ratio of spins, in rad/Ts
Precess = true
DisableZhangLiTorque = false
DisableSlonczewskiTorque = false
fixedLayerPosition = FIXEDLAYER_TOP // instructs mumax3 how free and fixed layers are stacked along +z direction
)

// Before, GammaLL was a user-settable parameter that was global (the same in all regions).
// Now, we divide it in two:
// GammaLL is a user-settable global constant,
// GFactor is a regionwise parameter.
// The torques will be calculated throughout mumax using GammaLL. Then, the torques will be multiplied regionwise by GFactor.
// For the sake of backward compatibility, gammaLL=1.7595e11 and GFactor=1.0. However, the user may want to set GammaLL=mu_B/hbar=0.879e11.
// In this case, GFactor will be the material's g-factor (i.e., ~~2.0 for most transition metal ferromagnets).
//Beware, gammaLL is defined in two places (!): here and in cuda/constants.h. Before, only this version was changed (leading to false results??)
//GammaLL is also used to scale the timestep in the integration algorithms.
func init() {
Pol.setUniform([]float64{1}) // default spin polarization
Lambda.Set(1) // sensible default value (?).
DeclVar("GammaLL", &GammaLL, "Gyromagnetic ratio in rad/Ts")
DeclVar("GammaLL", &GammaLL, "Gyromagnetic ratio [rad/Ts], that will be multiplied by GFactor (Default 1.7595e11)")
GFactor.Set(1.00)
DeclVar("DisableZhangLiTorque", &DisableZhangLiTorque, "Disables Zhang-Li torque (default=false)")
DeclVar("DisableSlonczewskiTorque", &DisableSlonczewskiTorque, "Disables Slonczewski torque (default=false)")
DeclVar("DoPrecess", &Precess, "Enables LL precession (default=true)")
Expand All @@ -45,6 +56,7 @@ func init() {
func SetTorque(dst *data.Slice) {
SetLLTorque(dst)
AddSTTorque(dst)
ScaleGamma(dst)
FreezeSpins(dst)
}

Expand All @@ -60,6 +72,13 @@ func SetLLTorque(dst *data.Slice) {
}
}

//scales the torque/g by 'GFactor' : a region-wise scalar parameter.
func ScaleGamma(dst *data.Slice) {
gfact := GFactor.MSlice()
defer gfact.Recycle()
cuda.ScaleGamma(dst,gfact)
}

// Adds the current spin transfer torque to dst
func AddSTTorque(dst *data.Slice) {
if J.isZero() {
Expand All @@ -85,7 +104,9 @@ func AddSTTorque(dst *data.Slice) {
defer xi.Recycle()
pol := Pol.MSlice()
defer pol.Recycle()
cuda.AddZhangLiTorque(dst, M.Buffer(), msat, j, alpha, xi, pol, Mesh())
g := GFactor.MSlice()
defer g.Recycle()
cuda.AddZhangLiTorque(dst, M.Buffer(), msat, j, alpha, xi, pol, g, float32(GammaLL), Mesh())
}
if !DisableSlonczewskiTorque && !FixedLayer.isZero() {
msat := Msat.MSlice()
Expand Down