Deriving a dynamics term#

All dynamics terms in micromagneticmodel are in micromagneticmodel/dynamics directory. They are all derived from micromagneticmodel.dynamics.DynamicsTerm base class.

For instance, let us say we want to implement a dynamics term with following specifications:

property

value

name

SpecialDynamics

expression

\(\xi\mathbf{m}\times\mathbf{v}\)

parameters

\(\xi\), \(\mathbf{v}\)

parameter properties

\(\xi \ge 0\), can be spatially varying

\(\mathbf{v}\) is three-dimensional, can be spatially varying

The dynamics term class would be:

[1]:
import micromagneticmodel as mm


class SpecialDynamics(mm.DynamicsTerm):
    pass

Now, we can try to instantiate it

[2]:
try:
    sd = SpecialDynamics(xi=0.1, v=(0, 0, 1))
except TypeError:
    print("Exception raised.")
Exception raised.

An exception was raised because _reprlatex and _allowed_attributes properties must be implemented. Therefore, an extended implementation of the class is:

[3]:
class SpecialDynamics(mm.DynamicsTerm):
    _reprlatex = r"$\xi\mathbf{m}\times\mathbf{v}$"
    _allowed_attributes = ["xi", "v"]

    def dmdt(self, m):
        raise NotImplementedError

We can try to instantiate the class again:

[4]:
sd = SpecialDynamics(xi=0.1, v=(0, 0, 1))
sd
[4]:
$$\xi\mathbf{m}\times\mathbf{v}$$

The dynamics object is created. The last thing we have to impose on the energy class is the typesystem. More precisely, we have to make sure no negative \(\xi\) values are allowed, \(\mathbf{v}\) is three-dimensional and that name attribute accepts only valid Python variable names. This is done by using ubermagutil. Full documentation can be found here.

[5]:
import discretisedfield as df
import ubermagutil.typesystem as ts


@ts.typesystem(
    xi=ts.Parameter(descriptor=ts.Scalar(unsigned=True), otherwise=df.Field),
    v=ts.Parameter(descriptor=ts.Vector(size=3), otherwise=df.Field),
)
class SpecialDynamics(mm.DynamicsTerm):
    _reprlatex = r"$\xi\mathbf{m}\times\mathbf{v}$"
    _allowed_attributes = ["xi", "v"]

    def dmdt(self, m):
        raise NotImplementedError

If we now attempt to pass invalid input arguments, exceptions are raised.

[6]:
try:
    sd = SpecialDynamics(xi=-0.1, v=(0, 0, 1))  # negative xi
except ValueError:
    print("Exception raised.")
Exception raised.
[7]:
try:
    sd = SpecialDynamics(xi=0.1, v=(0, 1))  # 2D v
except ValueError:
    print("Exception raised.")
Exception raised.

Some of the properties and methods of the implemented energy term are:

[8]:
sd = SpecialDynamics(xi=0.1, v=(0, 1, 1))
[9]:
sd.xi
[9]:
0.1
[10]:
sd.v
[10]:
(0, 1, 1)
[11]:
sd.name
[11]:
'specialdynamics'
[12]:
sd
[12]:
$$\xi\mathbf{m}\times\mathbf{v}$$
[13]:
repr(sd)
[13]:
'SpecialDynamics(xi=0.1, v=(0, 1, 1))'