MinDriver steps#

In this tutorial, we show how we can save individual steps during minimisation as well as how we can analyse them. We are going to minimise a simple system object. For details on how to define a system object, please have a look at other tutorials.

[1]:
import discretisedfield as df
import micromagneticmodel as mm

import oommfc as mc

region = df.Region(p1=(-50e-9, -50e-9, 0), p2=(50e-9, 50e-9, 10e-9))
mesh = df.Mesh(region=region, cell=(5e-9, 5e-9, 5e-9))

system = mm.System(name="mindriver_steps")

system.energy = mm.Zeeman(H=(0, 0, 1e5))
system.m = df.Field(mesh, nvdim=3, value=(1, 0, 0), norm=1.1e6)

We now have a system object and we can minimise it using MinDriver. By default, MinDriver saves only the data of the last step in the relexation. However, if we want to save all individual steps in between, we have to pass output_step=True to the drive method.

[2]:
md = mc.MinDriver()
md.drive(system, output_step=True)
Running OOMMF (ExeOOMMFRunner)[2023/10/18 12:39]... (0.4 s)

If we have a look at the table, we can see that multiple steps are saved:

[3]:
system.table.data
[3]:
max_mxHxm E delta_E bracket_count line_min_count conjugate_cycle_count cycle_count cycle_sub_count energy_calc_count E_zeeman iteration stage_iteration stage mx my mz
0 1.000000e+05 0.000000e+00 0.000000e+00 0.0 0.0 1.0 1.0 0.0 1.0 0.000000e+00 0.0 0.0 0.0 1.000000e+00 0.0 0.000000
1 9.999996e+04 -1.206285e-20 -1.206285e-20 1.0 0.0 1.0 1.0 0.0 2.0 -1.206285e-20 1.0 1.0 0.0 9.999996e-01 0.0 0.000873
2 9.848078e+04 -2.400340e-18 -2.388277e-18 2.0 0.0 1.0 1.0 0.0 3.0 -2.400340e-18 2.0 2.0 0.0 9.848078e-01 0.0 0.173648
3 9.396926e+04 -4.727747e-18 -2.327407e-18 3.0 0.0 2.0 2.0 0.0 4.0 -4.727747e-18 3.0 3.0 0.0 9.396926e-01 0.0 0.342020
4 8.660254e+04 -6.911504e-18 -2.183757e-18 4.0 0.0 3.0 3.0 0.0 5.0 -6.911504e-18 4.0 4.0 0.0 8.660254e-01 0.0 0.500000
5 7.660444e+04 -8.885258e-18 -1.973754e-18 5.0 0.0 4.0 4.0 0.0 6.0 -8.885258e-18 5.0 5.0 0.0 7.660444e-01 0.0 0.642788
6 6.427876e+04 -1.058904e-17 -1.703780e-18 6.0 0.0 5.0 5.0 0.0 7.0 -1.058904e-17 6.0 6.0 0.0 6.427876e-01 0.0 0.766044
7 5.000000e+04 -1.197108e-17 -1.382038e-18 7.0 0.0 6.0 6.0 0.0 8.0 -1.197108e-17 7.0 7.0 0.0 5.000000e-01 0.0 0.866025
8 3.464669e+04 -1.296684e-17 -9.957653e-19 8.0 0.0 7.0 7.0 0.0 9.0 -1.296684e-17 8.0 8.0 0.0 3.464669e-01 0.0 0.938062
9 3.420201e+04 -1.298938e-17 -2.253721e-20 9.0 0.0 7.0 7.0 0.0 10.0 -1.298938e-17 9.0 9.0 0.0 3.420201e-01 0.0 0.939693
10 1.981052e+04 -1.354905e-17 -5.596679e-19 10.0 0.0 8.0 8.0 0.0 11.0 -1.354905e-17 10.0 10.0 0.0 1.981052e-01 0.0 0.980181
11 1.736482e+04 -1.361301e-17 -6.395896e-20 11.0 0.0 8.0 8.0 0.0 12.0 -1.361301e-17 11.0 11.0 0.0 1.736482e-01 0.0 0.984808
12 6.305027e+03 -1.379550e-17 -1.824996e-19 12.0 0.0 9.0 9.0 0.0 13.0 -1.379550e-17 12.0 12.0 0.0 6.305027e-02 0.0 0.998010
13 3.143399e-11 -1.382301e-17 -2.750291e-20 13.0 0.0 9.0 9.0 0.0 14.0 -1.382301e-17 13.0 13.0 0.0 3.143399e-16 0.0 1.000000

Using all the utility of the Table object, we can analyse the data. For instance, we can plot the energy.

[4]:
system.table.mpl(y=["E"])
../../../_images/documentation_notebooks_oommfc_mindriver-steps_7_0.png

By fecault, iteration is showed on the \(x\)-axis. We can change that by passing x variable. For example:

[5]:
system.table.mpl(x="mx", y=["E"])
../../../_images/documentation_notebooks_oommfc_mindriver-steps_9_0.png

micromagneticdata analysis#

Similar to all other drivers, we can use micromagneticdata package to analyse the data. We start by creationg the data object:

[6]:
import micromagneticdata as md

data = md.Data(name=system.name)

We can have a look at all drives we did so far:

[7]:
data.info
[7]:
drive_number date time driver t n n_threads
0 0 2023-01-16 17:35:54 MinDriver NaN NaN NaN
1 1 2023-01-16 17:35:58 TimeDriver 2.000000e-09 200.0 4.0
2 2 2023-01-16 17:37:00 MinDriver NaN NaN NaN
3 3 2023-01-16 17:37:04 TimeDriver 2.000000e-09 200.0 4.0
4 4 2023-01-16 17:37:28 MinDriver NaN NaN NaN
5 5 2023-01-16 17:38:02 MinDriver NaN NaN NaN
6 6 2023-01-16 17:38:06 TimeDriver 2.000000e-09 200.0 4.0
7 7 2023-10-10 16:55:09 MinDriver NaN NaN NaN
8 8 2023-10-10 16:55:13 TimeDriver 2.000000e-09 200.0 4.0
9 9 2023-10-18 12:37:23 MinDriver NaN NaN NaN
10 10 2023-10-18 12:39:38 MinDriver NaN NaN NaN

There is only one drive and we can get it by passing 0 (ot -1) as an index:

[8]:
drive = data[0]

We can now plot the magnetisation at individual iterations, by indexing it again with the step number and do all usual operations allowed by discretisedfield.Field object.

[9]:
drive[0]
[9]:
Field
  • Mesh
    • Region
      • pmin = [-5e-08, -5e-08, 0.0]
      • pmax = [5e-08, 5e-08, 1e-08]
      • dims = ['x', 'y', 'z']
      • units = ['m', 'm', 'm']
    • n = [20, 20, 2]
  • nvdim = 3
  • vdims:
    • x
    • y
    • z
  • unit = A/m

The number of steps in the drive is:

[10]:
drive.n
[10]:
14

Let us now create an interactive plot. For details on how to create custom interactive plots, please have a look at other tutorials.

[11]:
drive.register_callback(lambda f: f.sel("y")).hv(kdims=["x", "z"]).opts(frame_width=800)
[11]: