예제 #1
0
    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)
예제 #2
0
    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]]
예제 #4
0
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)
예제 #5
0
    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)
예제 #6
0
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
예제 #7
0
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