Solver

Solver

class magnum.Solver(system, _evolver)
solve(stop_condition)
MicroMagneticsSolver.minimize(max_dpns=0.01, samples=10, h_max=1e-05, h_min=1e-16)

Minimizes the energy with a direct minimization strategy.

TODO methods

Evolvers

Currenty, three types of evolvers for the time integration of the LLG equation are available. They are selected using the ‘evolver’ argument at the time of creation of the Solver object:

  • Euler evolver with constant time steps (“euler”)

    # Create solver with Euler evolver
    s = create_solver(evolver="euler", time_step=1e-14)
    

    The time_step parameter is optional, default is 1e-14.

  • Runge-Kutta-Fehlberg evolver (RKF45) with variable time steps (“rkf45”)

    # Create solver with RKF45 evolver
    s = create_solver(evolver="rkf45", eps_abs=1e-3, eps_rel=1e-4)
    

    The eps_abs and eps_rel parameters are optional with the defaults being as shown in the example.

  • CVode implicit evolver with variable timesteps (“cvode”)

    # Create solver with cvode evolver
    s = create_solver(evolver="cvode", eps_abs=1e-3, eps_rel=1e-4,
                      step_size=1e-12, newton_method=False)
    

    The eps_abs, eps_rel, step_size and newton_method parameters are optional with the defaults being as shown in the example.

The RK45 evolver is the default evolver when the ‘evolver’ option is ommited.

Name Evolver id Options (defaults)
Euler euler step_size (\(1\cdot 10^{-14}\))
Runge-Kutta-Fehlberg 45 rkf45 eps_abs (\(1\cdot 10^{-3}\)), eps_rel (\(1\cdot 10^{-4}\))
CVode implicit evolver cvode eps_abs (\(1\cdot 10^{-3}\)), eps_rel (\(1\cdot 10^{-4}\)), step_size (\(1\cdot 10^{-12}\)), newton_method (False)

CVode evolver

CVode uses two iteration methods, fuctional and Newton. The functional method is very fast and more stable than Runge-Kutta. The Newton method is very slow and very stable. Information about the evolver are available on: http://computation.llnl.gov/casc/sundials/documentation/documentation.html The relax condition does not work with CVode, Runge-Kutta should be used.

Conditions

Objects of the Condition class check whether some condition for a magnetic state is true. For example, the Condition.relaxed() condition is true when the time deriviative of the magnetization \(d\mathbf{M}/dt\) of a given simulation state is small enough. This condition are used as abort criterions for simulations. Another application is to specify when step handlers (see StepHandler) are activated during a simulations.

Conditions can be negated, or-combined and and-combined using operators.

magnum.solver.condition

alias of magnum.solver.condition

Step handlers

Step handlers are added to the solver object by calling Solver.addStepHandler().

The base class of all step handlers is the abstract class StepHandler:

class magnum.StepHandler
handle(state)

This method is called by the solver when a new simulation step needs to be processed by the step handler. It must be overridden by a sub-class.

done()

This method is called by the solver when a simulation is complete (before the ‘’solver’’ method returns). Step handlers can use this method to clean up, close log files etc.

Logging step handlers

class magnum.DataTableLog(path, title='(no title)')

This step handler produces a log in the form of a text file in the OOMMF .odt file format. By default, the simulation time, the step size, the averaged magnetizations and the wall time is included in the log.

Example OOMMF data table (.odt) log file that is generated by DataTableLog:

# ODT 1.0
# Table Start
# Title: (no title)
#
## Generated by magnum.DataTableStepHandler.
## Number of columns: 7
#
# Columns:   {time}                    {step size}               {average magn. x}         {average magn. y}         {average magn. z}         {stray-field energy}      {exchange-field energy}
# Units:     {s}                       {s}                       {A/m}                     {A/m}                     {A/m}                     {J}                       {J}
0.0                       1.0000000000000001e-15    773763.05520921084    99865.913350068877    0.51014508223702026    5.425877056278558e-19    8.8083062896386378e-20
7.190533493683745e-12     1.0932486392938052e-12    772611.96576462197    103833.22777842356    -7219.4953021688525   5.4851562239571601e-19    9.0258813551580614e-20
2.3403744897262799e-11    1.5074283534957295e-12    760973.57366955292    139366.78750870723    -22539.08658192489    6.0677999378414166e-19    1.0995487038693322e-19
3.9428649475373533e-11    1.85956428734661e-12      733162.57517834462    204774.35569038574    -35631.238305689978    7.397106785586106e-19    1.4440096479070547e-19
...
...
...
9.6434123993105961e-10    8.9861003891477315e-13    -777442.58149938367    -58344.913010609191   6238.8726882989358    7.5244095099684009e-19    1.2958402944299087e-19
9.7402535807940305e-10    1.2062784047071156e-12    -783542.17931054463    -34240.439240366963   20335.17015782345     8.0952409880500454e-19    1.0968481551637731e-19
9.8338862949946303e-10    9.6173440992413807e-13    -789079.08096694865    8492.6521512550589    30227.519883341236    8.7514283220039697e-19    8.8932130375339342e-20
9.9374164359195942e-10    9.0429246884428303e-13    -789960.99319875205    68987.397611624358    34958.637897265799    9.1911429456896382e-19    7.6963987580309788e-20
# Table End
class magnum.ScreenLog

This step handler produces a log of the simulations on the screen. By default, the simulation time, the step size, and the averaged magnetizations is included in the log.

Example output on the console:

# time: t (s)   step size: h (s)   average magn. x: Mx (A/m)   average magn. y: My (A/m)   average magn. z: Mz (A/m)
t=0.0, h=1.0000000000000001e-15, Mx=720260.46511223307, My=298341.65158440446, Mz=0.0
t=1.3374476956998866e-10, h=1.8554788708302094e-12, Mx=759676.44090676622, My=157975.1496951601, Mz=3802.0657114495889
t=2.9960043454703471e-10, h=1.9145468033064472e-12, Mx=770546.01143940352, My=111393.9534971742, Mz=717.70498717729379
...
# done

Both the classes DataTableLog and ScreenLog have the following member functions:

magnum.addColumn([(id, desc="(no descr.)", unit="unknown", fmt="%r")+, ]func)

Adds one or more columns to the log. Each tuple represents one column. The last argument specifies a function that returns for a state object a tuple of <number of columns> scalar entries. Example:

log = ScreenLog()
log.addColumn(
    # description of one table column
    ("t", "simulation time", "s", "%r"),
    # function that maps a state to its current simulation time
    lambda state: state.t

log.addColumn(
    # description of first table columns
    ("t", "simulation time", "s", "%r"),
    # description of another table column
    ("h", "step size", "s", "%r"),
    # function that maps a state to its current simulation time and step size
    lambda state: (state.t, state.h)
)

The first tuple entry specifies the variable name associated with the column. The second entry is a description of the variable, the third names the unit of the variable. The last entry specifies the format which is used to convert the scalar that is returned by the mapping function to a string. Only the first entry is mandatory. If only the first entry is specified, the tuple may be ommited:

log.addColumn(("t",), lambda state: state.t)   # this line...
log.addColumn("t", lambda state: state.t)      # ...is equal to this line.

# another example:
log.addColumn("t", "h", lambda state: state.t, state.h)
magnum.addTimeColumn()

Adds a simulation time column. As this column is added by default, this function is usually not called by the user.

magnum.addStepSizeColumn()

Adds a step size column. This column is added by default.

magnum.addAverageMagColumn()

Adds three columns to the log with the average magnetization in x, y and z-direction. Added by default.

magnum.addEnergyColumn()

TODO addEnergyColumn

Examples: Log simulation in a text file ‘test.odt’. By default, the simulation time, the time step and <Mx>, <My>, <Mz> is included resulting in five table columns.

solver = create_solver(...)
solver.addStepHandler(DataTableLog("test.odt")
solver.solve(...)

Using the ‘addColumn’ and related functions one can add additional columns to the log file:

log = DataTableLog("test.odt")    # (or: log = ScreenLog() for screen output)
log.addEnergyColumn("exchange")   # adds column with E_exchange scalars
log.addEnergyColumn("stray")      # adds column with E_stray scalars
log.addTimeColumn()               # add (another) column with simulation time

# another way to add a time column
log.addColumn(("t", "time", "%r", "s"), lambda state: state.t)

# Add two columns with vortex core x/y position using the vortex tool box.
# (with (50nm, 50nm) as the origin).
log.addColumn(("Vx", "vortex-core-x", "%r", "m"),
              ("Vy", "vortex-core-y", "%r", "m"),
              lambda state: vortex.findCore(solver, 50e-9, 50e-9))

solver = create_solver(...)
solver.addStepHandler(log)
solver.solve(...)

File storage step handlers

class magnum.VTKStorage(output_dir, field_id_or_ids=[])
class magnum.OOMMFStorage(output_dir, field_id_or_ids, omf_format=0)
magnum.addComment(self, name, fn)