Beispiel #1
0
func main() {
	cuda.Init()

	N0, N1, N2 := 1, 64, 128
	c := 1.
	mesh := data.NewMesh(N0, N1, N2, c/2, c*2, c)

	m := cuda.NewSlice(3, mesh)
	conv := cuda.NewDemag(mesh)
	cuda.Memset(m, 1, 1, 1)

	B := cuda.NewSlice(3, mesh)
	Bsat := 1.
	vol := data.NilSlice(1, mesh)
	conv.Exec(B, m, vol, Bsat)
	out := B.HostCopy()

	bx := out.Vectors()[0][N0/2][N1/2][N2/2]
	by := out.Vectors()[1][N0/2][N1/2][N2/2]
	bz := out.Vectors()[2][N0/2][N1/2][N2/2]
	fmt.Println("demag tensor:", bx, by, bz)
	check(bx, -1)
	check(by, 0)
	check(bz, 0)
	fmt.Println("OK")
}
Beispiel #2
0
func main() {
	cuda.Init()

	N0, N1, N2 := 16, 16, 16
	c := 1.
	mesh := data.NewMesh(N0, N1, N2, c, c, c)

	m := cuda.NewSlice(3, mesh)
	conv := cuda.NewDemag(mesh)

	mhost := m.HostCopy()
	m_ := mhost.Vectors()
	r := float64(N2) / 2
	for i := 0; i < N0; i++ {
		x := c * (float64(i) + 0.5 - float64(N0)/2)
		for j := 0; j < N1; j++ {
			y := c * (float64(j) + 0.5 - float64(N1)/2)
			for k := 0; k < N2; k++ {
				z := c * (float64(k) + 0.5 - float64(N2)/2)
				if x*x+y*y+z*z < r*r {
					m_[0][i][j][k] = 1
					m_[1][i][j][k] = 2
					m_[2][i][j][k] = 3
				}
			}
		}
	}

	data.Copy(m, mhost)

	B := cuda.NewSlice(3, mesh)
	conv.Exec(B, m, data.NilSlice(1, mesh), 1)
	out := B.HostCopy()

	bx := out.Vectors()[0][N0/2][N1/2][N2/2]
	by := out.Vectors()[1][N0/2][N1/2][N2/2]
	bz := out.Vectors()[2][N0/2][N1/2][N2/2]
	fmt.Println("demag tensor:", bx, by/2, bz/3)
	check(bx, -1./3.)
	check(by, -2./3.)
	check(bz, -3./3.)
	fmt.Println("OK")
}
Beispiel #3
0
func initialize() {

	// these 2 GPU arrays are re-used to stored various quantities.
	arr1, arr2 := cuda.NewSynced(3, mesh), cuda.NewSynced(3, mesh)

	// cell volumes currently unused
	vol = data.NilSlice(1, mesh)

	// magnetization
	m = newBuffered(arr1, "m", nil)
	M = m

	// effective field
	b_eff := newBuffered(arr2, "B_eff", nil)
	B_eff = b_eff

	// demag field
	demag_ := cuda.NewDemag(mesh)
	b_demag := newBuffered(arr2, "B_demag", func(b *data.Slice) {
		m_ := m.Read()
		demag_.Exec(b, m_, vol, Mu0*Msat()) //TODO: consistent msat or bsat
		m.ReadDone()
	})
	B_demag = b_demag

	// exchange field
	b_exch := newAdder("B_exch", func(dst *data.Slice) {
		m_ := m.Read()
		cuda.AddExchange(dst, m_, Aex(), Msat())
		m.ReadDone()
	})
	B_exch = b_exch

	// Dzyaloshinskii-Moriya field
	b_dmi := newAdder("B_dmi", func(dst *data.Slice) {
		d := DMI()
		if d != 0 {
			m_ := m.Read()
			cuda.AddDMI(dst, m_, d, Msat())
			m.ReadDone()
		}
	})
	B_dmi = b_dmi

	// uniaxial anisotropy
	b_uni := newAdder("B_uni", func(dst *data.Slice) {
		ku1 := Ku1() // in J/m3
		if ku1 != [3]float64{0, 0, 0} {
			m_ := m.Read()
			cuda.AddUniaxialAnisotropy(dst, m_, ku1[2], ku1[1], ku1[0], Msat())
			m.ReadDone()
		}
	})
	B_uni = b_uni

	// external field
	b_ext := newAdder("B_ext", func(dst *data.Slice) {
		bext := B_ext()
		cuda.AddConst(dst, float32(bext[2]), float32(bext[1]), float32(bext[0]))
	})

	// llg torque
	torque := newBuffered(arr2, "torque", func(b *data.Slice) {
		m_ := m.Read()
		cuda.LLGTorque(b, m_, b, float32(Alpha()))
		m.ReadDone()
	})
	Torque = torque

	// spin-transfer torque
	stt := newAdder("stt", func(dst *data.Slice) {
		j := J()
		if j != [3]float64{0, 0, 0} {
			m_ := m.Read()
			p := SpinPol()
			jx := j[2] * p
			jy := j[1] * p
			jz := j[0] * p
			cuda.AddZhangLiTorque(dst, m_, [3]float64{jx, jy, jz}, Msat(), nil, Alpha(), Xi())
			m.ReadDone()
		}
	})
	STT = stt

	// data table
	table := newTable("datatable")
	Table = table

	// solver
	torqueFn := func(good bool) *data.Synced {
		m.touch(good) // saves if needed
		table.send(m.Synced, good)
		b_demag.update(good)
		b_exch.addTo(b_eff, good)
		b_dmi.addTo(b_eff, good)
		b_uni.addTo(b_eff, good)
		b_ext.addTo(b_eff, good)
		b_eff.touch(good)
		torque.update(good)
		stt.addTo(torque, good)
		return torque.Synced
	}
	Solver = cuda.NewHeun(m.Synced, torqueFn, cuda.Normalize, 1e-15, Gamma0, &Time)
}