def test_field_scalar(self): name = 'zhangli_field_scalar' mesh = df.Mesh(region=self.region, cell=self.cell) def u_fun(pos): x, y, z = pos if y <= 0: return 0 else: return 1 H = (0, 0, 1e6) u = df.Field(mesh, dim=1, value=u_fun) beta = 0.5 Ms = 1e6 system = mm.System(name=name) system.energy = mm.Zeeman(H=H) system.dynamics = mm.ZhangLi(u=u, beta=beta) system.m = df.Field(mesh, dim=3, value=(0, 0.1, 1), norm=Ms) td = self.calculator.TimeDriver() td.drive(system, t=0.2e-9, n=50) # u=0 region value = system.m((1e-9, -4e-9, 3e-9)) assert np.linalg.norm(np.cross(value, (0, 0.1 * Ms, Ms))) < 1e-3 # u!=0 region value = system.m((1e-9, 4e-9, 3e-9)) assert np.linalg.norm(np.subtract(value, (0, 0, Ms))) > 1 self.calculator.delete(system)
def test_dict_scalar(self): name = 'zhangli_dict_scalar' H = (0, 0, 1e6) u = {'r1': 0, 'r2': 1} beta = 0.5 Ms = 1e6 mesh = df.Mesh(region=self.region, cell=self.cell, subregions=self.subregions) system = mm.System(name=name) system.energy = mm.Zeeman(H=H) system.dynamics = mm.ZhangLi(u=u, beta=beta) system.m = df.Field(mesh, dim=3, value=(0, 0.1, 1), norm=Ms) td = self.calculator.TimeDriver() td.drive(system, t=0.2e-9, n=50) # u=0 region value = system.m((1e-9, -4e-9, 3e-9)) assert np.linalg.norm(np.cross(value, (0, 0.1 * Ms, Ms))) < 1e-3 # u!=0 region value = system.m((1e-9, 4e-9, 3e-9)) assert np.linalg.norm(np.subtract(value, (0, 0, Ms))) > 1 self.calculator.delete(system)
def setup(self): self.precession = mm.Precession(gamma0=2.21e5) self.damping = mm.Damping(alpha={'r1': 1, 'r2': 0.5}) self.zhangli = mm.ZhangLi(u=500, beta=0.2) self.terms = [self.precession, self.damping, self.zhangli] self.invalid_terms = [1, 2.5, 0, 'abc', [3, 7], [self.precession, 5]]
def test_stdprob5(calculator): name = 'stdprob5' # Geometry lx = 100e-9 # x dimension of the sample(m) ly = 100e-9 # y dimension of the sample (m) lz = 10e-9 # sample thickness (m) # Material (permalloy) parameters Ms = 8e5 # saturation magnetisation (A/m) A = 1.3e-11 # exchange energy constant (J/m) # Dynamics (LLG + ZhangLi equation) parameters gamma0 = 2.211e5 # gyromagnetic ratio (m/As) alpha = 0.1 # Gilbert damping ux = -72.35 # velocity in x direction beta = 0.05 # non-adiabatic STT parameter system = mm.System(name=name) p1 = (0, 0, 0) p2 = (lx, ly, lz) cell = (5e-9, 5e-9, 5e-9) region = df.Region(p1=p1, p2=p2) mesh = df.Mesh(region=region, cell=cell) system.energy = mm.Exchange(A=A) + mm.Demag() def m_vortex(pos): x, y, z = pos[0] / 1e-9 - 50, pos[1] / 1e-9 - 50, pos[2] / 1e-9 return (-y, x, 10) system.m = df.Field(mesh, dim=3, value=m_vortex, norm=Ms) md = calculator.MinDriver() md.drive(system) system.dynamics += (mm.Precession(gamma0=gamma0) + mm.Damping(alpha=alpha) + mm.ZhangLi(u=ux, beta=beta)) td = calculator.TimeDriver() td.drive(system, t=8e-9, n=100) mx = system.table.data['mx'].values assert -0.35 < mx.min() < -0.30 assert -0.03 < mx.max() < 0 calculator.delete(system)
def test_scalar_scalar(self): name = 'zhangli_scalar_scalar' u = 0 beta = 0.5 H = (0, 0, 1e5) Ms = 1e6 mesh = df.Mesh(region=self.region, cell=self.cell) system = mm.System(name=name) system.energy = mm.Zeeman(H=H) system.dynamics = mm.ZhangLi(u=u, beta=beta) system.m = df.Field(mesh, dim=3, value=(0, 0.1, 1), norm=Ms) td = self.calculator.TimeDriver() td.drive(system, t=0.2e-9, n=50) # u is zero, nothing should change. value = system.m(mesh.region.random_point()) assert np.linalg.norm(np.cross(value, (0, 0.1 * Ms, Ms))) < 1e-3 self.calculator.delete(system)
def driver_script(driver, system, compute=None, **kwargs): mif = '' if isinstance(driver, oc.MinDriver): # Check evolver and set default if not passed. if not hasattr(driver, 'evolver'): driver.evolver = oc.CGEvolver() elif not isinstance(driver.evolver, oc.CGEvolver): msg = f'Cannot use {type(driver.evolver)} for evolver.' raise TypeError(msg) # Define default stopping_mxHxm if not passed. OOMMF cannot run without # this value. if not hasattr(driver, 'stopping_mxHxm'): driver.stopping_mxHxm = 0.1 mif += oc.scripts.evolver_script(driver.evolver) # Minimisation driver script. mif += '# MinDriver\n' mif += 'Specify Oxs_MinDriver {\n' mif += ' evolver :evolver\n' mif += ' mesh :mesh\n' mif += ' Ms :m0_norm\n' mif += ' m0 :m0\n' for attr, value in driver: if attr != 'evolver': mif += f' {attr} {value}\n' mif += '}\n\n' # Saving results. mif += 'Destination table mmArchive\n' mif += 'Destination mags mmArchive\n\n' mif += 'Schedule DataTable table Stage 1\n' mif += 'Schedule Oxs_MinDriver::Magnetization mags Stage 1' if isinstance(driver, oc.TimeDriver): # Check evolver and set default if not passed. if not hasattr(driver, 'evolver'): if mm.ZhangLi() in system.dynamics: driver.evolver = oc.SpinTEvolver() elif mm.Slonczewski() in system.dynamics: driver.evolver = oc.SpinXferEvolver() else: driver.evolver = oc.RungeKuttaEvolver() elif not isinstance(driver.evolver, (oc.EulerEvolver, oc.RungeKuttaEvolver, oc.SpinTEvolver, oc.SpinXferEvolver)): msg = f'Cannot use {type(driver.evolver)} for evolver.' raise TypeError(msg) # Extract dynamics equation parameters. if mm.Precession() in system.dynamics: driver.evolver.gamma_G = system.dynamics.precession.gamma0 else: driver.evolver.do_precess = 0 if mm.Damping() in system.dynamics: driver.evolver.alpha = system.dynamics.damping.alpha else: driver.evolver.alpha = 0 if mm.ZhangLi() in system.dynamics: driver.evolver.u = system.dynamics.zhangli.u driver.evolver.beta = system.dynamics.zhangli.beta if mm.Slonczewski() in system.dynamics: driver.evolver.J = system.dynamics.slonczewski.J driver.evolver.mp = system.dynamics.slonczewski.mp driver.evolver.P = system.dynamics.slonczewski.P driver.evolver.Lambda = system.dynamics.slonczewski.Lambda driver.evolver.eps_prime = system.dynamics.slonczewski.eps_prime mif += oc.scripts.evolver_script(driver.evolver) # Extract time and number of steps. t, n = kwargs['t'], kwargs['n'] # TimeDriver mif += '# TimeDriver\n' mif += 'Specify Oxs_TimeDriver {\n' mif += ' evolver :evolver\n' mif += ' mesh :mesh\n' mif += f' Ms :m0_norm\n' mif += f' m0 :m0\n' mif += f' stopping_time {t/n}\n' mif += f' stage_count {n}\n' for attr, value in driver: if attr != 'evolver': mif += f' {attr} {value}\n' mif += '}\n\n' # Saving results mif += 'Destination table mmArchive\n' mif += 'Destination mags mmArchive\n' mif += 'Destination archive mmArchive\n\n' mif += 'Schedule DataTable table Stage 1\n' mif += 'Schedule Oxs_TimeDriver::Magnetization mags Stage 1\n' if compute is not None: mif += compute return mif
def driver_script(driver, system, fixed_subregions=None, compute=None, output_step=False, **kwargs): mif = '' if isinstance(driver, oc.HysteresisDriver): # Check evolver and set default if not passed. if not hasattr(driver, 'evolver'): driver.evolver = oc.CGEvolver() elif not isinstance(driver.evolver, oc.CGEvolver): msg = f'Cannot use {type(driver.evolver)} for evolver.' raise TypeError(msg) # Define default stopping_mxHxm if not passed. OOMMF cannot run without # this value. if not hasattr(driver, 'stopping_mxHxm'): driver.stopping_mxHxm = 0.1 # Fixed spins if fixed_subregions is not None: resstr = f'{{main_atlas {" ".join(fixed_subregions)}}}' driver.evolver.fixed_spins = resstr mif += oc.scripts.evolver_script(driver.evolver) # Oxs_UZeeman Hmin, Hmax, n = kwargs['Hmin'], kwargs['Hmax'], kwargs['n'] mif += '# OxS_UZeeman\n' mif += 'Specify Oxs_UZeeman {\n' mif += ' Hrange {\n' mif += ' {{ {} {} {} {} {} {} {} }}\n'.format(*Hmin, *Hmax, n - 1) mif += ' {{ {} {} {} {} {} {} {} }}\n'.format(*Hmax, *Hmin, n - 1) mif += ' }\n' mif += '}\n\n' # Minimisation driver script. mif += '# MinDriver\n' mif += 'Specify Oxs_MinDriver {\n' mif += ' evolver :evolver\n' mif += ' mesh :mesh\n' mif += ' Ms :m0_norm\n' mif += ' m0 :m0\n' for attr, value in driver: if attr != 'evolver': mif += f' {attr} {value}\n' mif += '}\n\n' # Saving results. mif += 'Destination table mmArchive\n' mif += 'Destination mags mmArchive\n\n' mif += 'Schedule DataTable table Stage 1\n' mif += 'Schedule Oxs_MinDriver::Magnetization mags Stage 1' if isinstance(driver, oc.MinDriver): # Check evolver and set default if not passed. if not hasattr(driver, 'evolver'): driver.evolver = oc.CGEvolver() elif not isinstance(driver.evolver, oc.CGEvolver): msg = f'Cannot use {type(driver.evolver)} for evolver.' raise TypeError(msg) # Define default stopping_mxHxm if not passed. OOMMF cannot run without # this value. if not hasattr(driver, 'stopping_mxHxm'): driver.stopping_mxHxm = 0.1 # Fixed spins if fixed_subregions is not None: resstr = f'{{main_atlas {" ".join(fixed_subregions)}}}' driver.evolver.fixed_spins = resstr # What is saved in output? if output_step: output_str = 'Step' else: output_str = 'Stage' mif += oc.scripts.evolver_script(driver.evolver) # Minimisation driver script. mif += '# MinDriver\n' mif += 'Specify Oxs_MinDriver {\n' mif += ' evolver :evolver\n' mif += ' mesh :mesh\n' mif += ' Ms :m0_norm\n' mif += ' m0 :m0\n' for attr, value in driver: if attr != 'evolver': mif += f' {attr} {value}\n' mif += '}\n\n' # Saving results. mif += 'Destination table mmArchive\n' mif += 'Destination mags mmArchive\n\n' mif += f'Schedule DataTable table {output_str} 1\n' mif += f'Schedule Oxs_MinDriver::Magnetization mags {output_str} 1' if isinstance(driver, oc.TimeDriver): # Check evolver and set default if not passed. if not hasattr(driver, 'evolver'): if mm.ZhangLi() in system.dynamics: driver.evolver = oc.SpinTEvolver() elif mm.Slonczewski() in system.dynamics: driver.evolver = oc.SpinXferEvolver() else: driver.evolver = oc.RungeKuttaEvolver() elif not isinstance(driver.evolver, (oc.EulerEvolver, oc.RungeKuttaEvolver, oc.SpinTEvolver, oc.SpinXferEvolver)): msg = f'Cannot use {type(driver.evolver)} for evolver.' raise TypeError(msg) # Extract dynamics equation parameters. if mm.Precession() in system.dynamics: driver.evolver.gamma_G = system.dynamics.precession.gamma0 else: driver.evolver.do_precess = 0 if mm.Damping() in system.dynamics: driver.evolver.alpha = system.dynamics.damping.alpha else: driver.evolver.alpha = 0 if mm.ZhangLi() in system.dynamics: driver.evolver.u = system.dynamics.zhangli.u driver.evolver.beta = system.dynamics.zhangli.beta if mm.Slonczewski() in system.dynamics: driver.evolver.J = system.dynamics.slonczewski.J driver.evolver.mp = system.dynamics.slonczewski.mp driver.evolver.P = system.dynamics.slonczewski.P driver.evolver.Lambda = system.dynamics.slonczewski.Lambda driver.evolver.eps_prime = system.dynamics.slonczewski.eps_prime # Fixed spins if fixed_subregions is not None: resstr = f'{{main_atlas {" ".join(fixed_subregions)}}}' driver.evolver.fixed_spins = resstr mif += oc.scripts.evolver_script(driver.evolver) # Extract time and number of steps. t, n = kwargs['t'], kwargs['n'] # TimeDriver mif += '# TimeDriver\n' mif += 'Specify Oxs_TimeDriver {\n' mif += ' evolver :evolver\n' mif += ' mesh :mesh\n' mif += f' Ms :m0_norm\n' mif += f' m0 :m0\n' mif += f' stopping_time {t/n}\n' mif += f' stage_count {n}\n' for attr, value in driver: if attr != 'evolver': mif += f' {attr} {value}\n' mif += '}\n\n' # Saving results mif += 'Destination table mmArchive\n' mif += 'Destination mags mmArchive\n' mif += 'Destination archive mmArchive\n\n' mif += 'Schedule DataTable table Stage 1\n' mif += 'Schedule Oxs_TimeDriver::Magnetization mags Stage 1\n' if compute is not None: mif += compute return mif