// 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 }
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) }