|
| 1 | +import matplotlib as mpl |
| 2 | +mpl.use("Agg") |
| 3 | +import matplotlib.pyplot as plt |
| 4 | +import matplotlib.gridspec as gridspec |
| 5 | + |
| 6 | +import numpy as np |
| 7 | +from fidimag.micro import Sim, UniformExchange, UniaxialAnisotropy |
| 8 | +from fidimag.common import CuboidMesh |
| 9 | +import fidimag.common.constant as const |
| 10 | + |
| 11 | +from scipy.optimize import curve_fit |
| 12 | + |
| 13 | + |
| 14 | +mu0 = 4 * np.pi * 1e-7 |
| 15 | +global_Ms = 8.6e5 |
| 16 | +global_A = 1.3e-11 |
| 17 | +global_K = 0.25*mu0*global_Ms**2 |
| 18 | + |
| 19 | +global_P = 0.5 |
| 20 | +global_d = 2e-9 #2nm |
| 21 | +global_const = const.h_bar*const.gamma*global_P/(2*const.c_e*global_d*global_Ms) |
| 22 | + |
| 23 | +def init_m(pos): |
| 24 | + |
| 25 | + x = pos[0] |
| 26 | + |
| 27 | + if x < 300: |
| 28 | + return (1, 0, 0) |
| 29 | + elif 300 <= x < 400: |
| 30 | + return (0, 1, 1) |
| 31 | + else: |
| 32 | + return (-1, 0, 0) |
| 33 | + |
| 34 | + |
| 35 | +def relax_system(mesh): |
| 36 | + |
| 37 | + # Only relaxation |
| 38 | + sim = Sim(mesh, name='relax') |
| 39 | + |
| 40 | + # Simulation parameters |
| 41 | + sim.set_tols(rtol=1e-8, atol=1e-10) |
| 42 | + sim.alpha = 0.5 |
| 43 | + sim.gamma = 2.211e5 |
| 44 | + sim.Ms = 8.6e5 |
| 45 | + sim.do_precession = False |
| 46 | + |
| 47 | + # The initial state passed as a function |
| 48 | + sim.set_m(init_m) |
| 49 | + # sim.set_m(np.load('m0.npy')) |
| 50 | + |
| 51 | + # Energies |
| 52 | + A = 1.3e-11 |
| 53 | + exch = UniformExchange(A=A) |
| 54 | + sim.add(exch) |
| 55 | + |
| 56 | + anis = UniaxialAnisotropy(5e4) |
| 57 | + sim.add(anis) |
| 58 | + |
| 59 | + # Start relaxation and save the state in m0.npy |
| 60 | + sim.relax(dt=1e-14, stopping_dmdt=0.00001, max_steps=5000, |
| 61 | + save_m_steps=None, save_vtk_steps=None) |
| 62 | + |
| 63 | + np.save('m0.npy', sim.spin) |
| 64 | + |
| 65 | + |
| 66 | + |
| 67 | +def model(xs, x0): |
| 68 | + delta = 16.1245154966 |
| 69 | + return -np.tanh((xs-x0)/delta) |
| 70 | + |
| 71 | +def extract_dw(m): |
| 72 | + |
| 73 | + m.shape=(-1,3) |
| 74 | + mx = m[:,0] |
| 75 | + my = m[:,1] |
| 76 | + mz = m[:,2] |
| 77 | + |
| 78 | + xs = np.linspace(0.5, 999.5, 1000) |
| 79 | + |
| 80 | + id = np.argmin(abs(mx)) |
| 81 | + |
| 82 | + popt, pcov = curve_fit(model, xs, mx, p0=[id*1.0]) |
| 83 | + print(popt[0], id) |
| 84 | + |
| 85 | + theta = np.arctan2(mz[id], my[id]) |
| 86 | + return popt[0], theta |
| 87 | + |
| 88 | +def sinc_fun(t): |
| 89 | + return np.sinc(1e9*t) # sinc(x) = sin(\pi x)/(\pi x) |
| 90 | + |
| 91 | +# This function excites the system with a |
| 92 | +# current in the x-direction using Spin Transfer Torque |
| 93 | +# formalism |
| 94 | +def excite_system(mesh, beta=0.0): |
| 95 | + |
| 96 | + # Specify the stt dynamics in the simulation |
| 97 | + sim = Sim(mesh, name='dyn_%g'%beta, driver='llg_stt_cpp') |
| 98 | + |
| 99 | + sim.set_tols(rtol=1e-12, atol=1e-12) |
| 100 | + sim.alpha = 0.1 |
| 101 | + sim.gamma = 2.211e5 |
| 102 | + sim.Ms = 8.6e5 |
| 103 | + |
| 104 | + # sim.set_m(init_m) |
| 105 | + sim.set_m(np.load('m0.npy')) |
| 106 | + |
| 107 | + # Energies |
| 108 | + A = 1.3e-11 |
| 109 | + exch = UniformExchange(A=A) |
| 110 | + sim.add(exch) |
| 111 | + |
| 112 | + anis = UniaxialAnisotropy(5e4) |
| 113 | + sim.add(anis) |
| 114 | + |
| 115 | + # beta is the parameter in the STT torque |
| 116 | + sim.a_J = global_const*1e11 |
| 117 | + sim.p = (1,0,0) |
| 118 | + sim.beta = beta |
| 119 | + |
| 120 | + # The simulation will run for 5 ns and save |
| 121 | + # 500 snapshots of the system in the process |
| 122 | + ts = np.linspace(0, 0.5e-9, 21) |
| 123 | + |
| 124 | + xs=[] |
| 125 | + thetas=[] |
| 126 | + |
| 127 | + for t in ts: |
| 128 | + print('time', t) |
| 129 | + sim.run_until(t) |
| 130 | + spin = sim.spin.copy() |
| 131 | + x, theta = extract_dw(spin) |
| 132 | + xs.append(x) |
| 133 | + thetas.append(theta) |
| 134 | + sim.save_vtk() |
| 135 | + |
| 136 | + np.savetxt('dw_%g.txt'%beta,np.transpose(np.array([ts, xs,thetas]))) |
| 137 | + |
| 138 | +def analytical(ts): |
| 139 | + delta = 16.1245154966 |
| 140 | + alpha = 0.1 |
| 141 | + beta = 0.16 |
| 142 | + aj = global_const*1e11 |
| 143 | + theta = (beta-alpha)/(1+alpha**2)*ts*aj |
| 144 | + z = (1+alpha*beta)/(1+alpha**2)*delta*aj*ts |
| 145 | + return z, theta |
| 146 | + |
| 147 | + |
| 148 | +def plot(): |
| 149 | + data=np.loadtxt('dw_0.16.txt') |
| 150 | + ts = data[:,0] |
| 151 | + xs = data[:,1]-data[0,1] |
| 152 | + theta = data[:,2]-data[0,2] |
| 153 | + |
| 154 | + z_an, theta_an = analytical(ts) |
| 155 | + |
| 156 | + fig = plt.figure(figsize=(5, 2.6)) |
| 157 | + |
| 158 | + gs = gridspec.GridSpec(1, 2, width_ratios=[4, 4]) |
| 159 | + ax0 = plt.subplot(gs[0]) |
| 160 | + ax0.plot(ts*1e9,xs,'.') |
| 161 | + ax0.plot(ts*1e9, z_an, '-') |
| 162 | + plt.ylabel(r'DW shift') |
| 163 | + plt.xlabel(r'Time (ns)') |
| 164 | + |
| 165 | + |
| 166 | + ax1 = plt.subplot(gs[1]) |
| 167 | + ax1.plot(ts*1e9,theta,'.') |
| 168 | + ax1.plot(ts*1e9, theta_an, '-') |
| 169 | + plt.ylabel(r'$\phi$') |
| 170 | + plt.xlabel(r'Time (ns)') |
| 171 | + |
| 172 | + plt.tight_layout() |
| 173 | + analytical(ts) |
| 174 | + |
| 175 | + plt.savefig('xs_theta.pdf') |
| 176 | + |
| 177 | + |
| 178 | +if __name__ == '__main__': |
| 179 | + |
| 180 | + # We will crate a mesh with 1000 elements of elements |
| 181 | + # in the x direction, and 1 along y and z |
| 182 | + # (so we have a 1D system) |
| 183 | + mesh = CuboidMesh(nx=1000, ny=1, nz=1, |
| 184 | + dx=1.0, dy=2, dz=2.0, |
| 185 | + unit_length=1e-9) |
| 186 | + |
| 187 | + # Relax the initial state |
| 188 | + relax_system(mesh) |
| 189 | + |
| 190 | + excite_system(mesh, beta=0.16) |
| 191 | + plot() |
| 192 | + |
0 commit comments