All energy terms in micromagneticmodel
are in micromagneticmodel/hamiltonian
directory. They are all derived from micromagneticmodel.hamiltonian.EnergyTerm
base class.
For instance, let us say we want to implement an energy term with following specifications:
property | value |
---|---|
name | SpecialEnergy |
expression | $U\mathbf{m}\cdot\mathbf{m}$ |
parameter | $U$ |
parameter properties | $U \ge 0$, can be spatially varying |
The energy term class would be:
import micromagneticmodel as mm
class SpecialEnergy(mm.EnergyTerm):
def __init__(self, U, name='specialenergy'):
self.U = U
self.name = name
Now, we can try to instantiate it
try:
se = SpecialEnergy(U=3)
except TypeError:
print('Exception raised.')
Exception raised.
An exception was raised because _repr
and _latex
properties must be implemented. Therefore, an extended implementation of the class is:
class SpecialEnergy(mm.EnergyTerm):
_latex = r'$U\mathbf{m}\cdot\mathbf{m}$'
def __init__(self, U, name='specialenergy'):
self.U = U
self.name = name
@property
def _repr(self):
return f'SpecialEnergy(U={self.U}, name=\'{self.name}\')'
We can try to instantiate the class again:
se = SpecialEnergy(U=3)
se
The energy 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 $U$ values are allowed and that name
attribute accepts only valid Python variable names. This is done by using ubermagutil
. Full documentation can be found here.
import ubermagutil.typesystem as ts
import discretisedfield as df
@ts.typesystem(U=ts.Parameter(descriptor=ts.Scalar(unsigned=True), otherwise=df.Field),
name=ts.Name())
class SpecialEnergy(mm.EnergyTerm):
_latex = r'$U\mathbf{m}\cdot\mathbf{m}$'
def __init__(self, U, name='specialenergy'):
self.U = U
self.name = name
@property
def _repr(self):
return f'SpecialEnergy(U={self.U}, name=\'{self.name}\')'
If we now attempt to pass invalid input arguments, exceptions are raised.
try:
se = SpecialEnergy(U=-3, name='valid_name') # negative U
except ValueError:
print('Exception raised.')
Exception raised.
try:
se = SpecialEnergy(U=3, name='invalid name') # name contains space
except ValueError:
print('Exception raised.')
Exception raised.
Some of the properties and methods of the implemented energy term are:
se = SpecialEnergy(U=5e-5)
se.U
5e-05
se.name
'specialenergy'
se
repr(se)
"SpecialEnergy(U=5e-05, name='specialenergy')"
Finally, the class we have just implemented is going to be inherited by a specific micromagnetic calculator, where _script
method is going to be implemented.
try:
se._script
except NotImplementedError:
print('Exception raised.')
Exception raised.
Full description of all existing descriptors can be found in the API Reference.