Beispiel #1
0
def test_value_set_update():
    """
    Test to check that the value member variable updates when set_value is
    called.
    """
    init_value = [1., 2., 3.]
    second_value = [100., 200., 400.]

    zeeman = Zeeman(init_value)
    mesh = df.RectangleMesh(df.Point(0, 0), df.Point(1, 1), 10, 10)
    sim = finmag.Simulation(mesh, 1e5)
    sim.add(zeeman)
    zeeman.set_value(second_value)

    assert zeeman.value == second_value
def test_relax_two_times():
    """
    Test whether we can call the relax method on Sim two times in a row.

    """
    mesh = df.BoxMesh(df.Point(0, 0, 0), df.Point(10, 10, 10), 2, 2, 2)
    Ms = 0.86e6

    sim = Simulation(mesh, Ms)
    sim.set_m((1, 0, 0))

    external_field = Zeeman((0, Ms, 0))
    sim.add(external_field)
    sim.relax()
    t0 = sim.t  # time needed for first relaxation

    external_field.set_value((0, 0, Ms))
    sim.relax()
    t1 = sim.t - t0  # time needed for second relaxation

    assert sim.t > t0
    assert abs(t1 - t0) < 1e-10
Beispiel #3
0
def hysteresis(sim, H_ext_list, fun=None, **kwargs):
    """
    Set the applied field to the first value in `H_ext_list` (which should
    be a list of external field vectors) and then call the relax() method.
    When convergence is reached, the field is changed to the next one in
    H_ext_list, and so on until all values in H_ext_list are exhausted.

    Note: The fields in H_ext_list are applied *in addition to* any Zeeman
          interactions that are already present in the simulation.
          In particular, if only one external field should be present then
          do not add any Zeeman interactions before calling this method.

    If you would like to perform a certain action (e.g. save a VTK
    snapshot of the magnetisation) at the end of each relaxation stage,
    use the sim.schedule() command with the directive 'at_end=True' as
    in the following example:

        sim.schedule('save_vtk', at_end=True, ...)
        sim.hysteresis(...)


    *Arguments*

        H_ext_list:  list of 3-vectors

            List of external fields, where each field can have any of
            the forms accepted by Zeeman.__init__() (see its docstring
            for more details).

        fun:  callable

            The user can pass a function here (which should accept the
            Simulation object as its only argument); this function is
            called after each relaxation and determines the return
            value (see below). For example, if

               fun = (lambda sim: sim.m_average[0])

            then the return value is a list of values representing the
            average x-component of the magnetisation at the end of
            each relaxation.

    All other keyword arguments are passed on to the relax() method.
    See its documentation for details.


    *Return value*

    If `fun` is not None then the return value is a list containing an
    accumulation of all the return values of `fun` after each stage.
    Otherwise the return value is None.

    """
    if H_ext_list == []:
        return

    # Add a new Zeeman interaction, initialised to zero.
    H = Zeeman((0, 0, 0))
    sim.add(H)

    # We keep track of the current stage of the hysteresis loop.
    cur_stage = 0
    num_stages = len(H_ext_list)

    res = []

    try:
        while True:
            H_cur = H_ext_list[cur_stage]
            log.info(
                "Entering hysteresis stage #{} ({} out of {}). Current field: "
                "{}".format(cur_stage, cur_stage + 1, num_stages, H_cur))
            H.set_value(H_cur)
            sim.relax(**kwargs)
            cur_stage += 1
            if fun is not None:
                retval = fun(sim)
                res.append(retval)
                log.debug("hysteresis callback function '{}' returned "
                          "value: {}".format(fun.__name__, retval))
    except IndexError:
        log.info("Hysteresis is finished.")

    log.info("Removing the applied field used for hysteresis.")
    sim.remove_interaction(H.name)

    return res or None