Ejemplo n.º 1
0
// returns a GPU buffer for temporarily adding a quantity to and saving it
func addBuf() *buffered {
	if _addBuf == nil {
		util.DashExit()
		log.Println("allocating GPU buffer for output")
		_addBuf = newBuffered(cuda.NewSynced(3, mesh), "buffer", nil)
	}
	return _addBuf
}
Ejemplo n.º 2
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)
}