Skip to content

Moving refactor branch over to develop

To come back to somewhat of a clean git history, the refactor branch will be brought over to the develop again. Changes so far are a lot:

Housekeeping

  • stuff like magnetic_order or geometry_type are now proper enums in common.

Support for new geometries

  • we now support axially symmetric waveguides (waveguide_axial)
  • confined_axial is also possible but so far only without dipole interaction.

new sample object

  • The sample architecture has been entirely changed by getting rid of all inheritances (AbstracSample, FerromagneticMixin, WaveguideAFMSample, ConfinedFMSample, etc.) and instead using composition (Sample has mesh, material, magnetic_order as attributes).

Sample itself

  • has much less responsibilities
  • is now created via the Sample(mesh) and create_sample throws a NotImplementedError
  • needs a mesh upon creation; geometry_type is automatically inferred if templated geometry is used
  • magnetization is automatically initialized to z direction
  • information about the geometry and all differential operators are now gathered in the new SampleMesh class
  • material parameters are now managed by the SampleMaterial class
  • information about both in a notebook can be printed with sample.material or sample.mesh
  • Sample.plot() will be deprecated. It's functionality has been fully integrated in sample.show()which can now take an optional field as the first argument. If no field is provided, the magnetization will be plotted.

SampleMesh

  • container that holds all the mesh information, which takes care of
    • input validation and FEM preprocessing
    • adding the mesh itself or its extrusion to an existing k3d plot
  • quantities like the number of nodes should now be obtained as sample.mesh.nx, but sample.nx is still included but throws a deprecation warning.
  • Template geometries have been refactoed with more meaningful notation, reorganized into packages geometries.confined, geometries.waveguide and so on, for a more overview. Available geometries can be inspected with geometries.available (a list) or geometries.show_available() which also prints the function signatures.

SampleMaterial

  • all material parameters are now managed by a container class SampleMaterial which behaves kind of like a dictionary and takes of a couple of things:
    • the set of materials parameters is chosen upon creation (e.g. when using FM vs AFMs).
    • checking if a parameter exists when getting or setting.
    • notifying the Sample.interactions if their material parameters have changed (which then update via an observer pattern).
  • a specific parameter can be obtained, for example, my ```Sample.material["Msat"]
  • the parameters itself are stored as MaterialParameters which have metadata such as units, etc. They take care of input validation and possible extending of given single numbers to MeshScalars etc. They can have constraints on their values such as is_posive. The numerical values themselves are retrieved with MaterialParameter.value, while their is given by MaterialParameter.average.
  • many material parameters can be set at once with SampleMaterial.set_from_dict() which has an optional fill_missing flag that, if true, sets all parameters that were not given to zero. This is the default when using Sample.material = some_dict on the outside.
  • template materials (which need to be finalized) can be found in materials.

Interactions

  • what as previously a hardcoded list of magnetic tensors is now a dynamic list of SelfInteractions (likely this will be changed to Interaction, which will also include Zeemann etc.
  • they can be dynamically removed or added to the sample or a given experiment.
  • each interaction has methods like unitless_field(vec) or unitless_energy(vec)
  • Dynamic usage may look like this
for interaction in sample.interactions:
    spam.append(interaction.unitless_field(mag)
eggs = sum(spam)
  • by default, each unitless field should return the non-linearized expression. So higher orders can just be included into the function.
  • when doing an eigenmode calculation, the interaction can return an effective spin-wave tensor interaction.linearized_tensor(mag), which gives the linearized magnetic tensor around the specific equilibrium. This behavior is the same for all interactions. Previously, we explicitly handled higher-order interactions like N_cub.make_sparse_mat_with_current_m0() for cubic anisotropy. The new architecture allows to easily expand eigenmode calculations by the linearized versions of higher interaction orders (e.g., for uniaxial anistropy).

Experiments

It has been almost completely refactored. Only the significant behavior changes are described.

eigen

  • lot of cleanup, dynamic_matrix takes care also of km-independent stuff, etc.
  • new parallelization using joblib
  • interactions for the eigensolving can now be dynamically chosen eigenmodes(interactions=...). By default, they are the sample interactions + Zeemann. No more no_dip=True.
  • all configuration is encapsulated in a EigenConfiguration dataclass (this scheme will also be used for other experiments).
  • now supports confined_axial and waveguide_axial geometries by including the azimuthal index m in the wave-vector space
  • now automatically uses conjugate modes as physical ones if the geometry_type allows it.
  • perturbation analysis and absorption are still missing but will be outsourced as post-processing on a possible EigenSpectrum result object.

relax

  • just like for eigen, interactions can now be freely selected.
  • more relaxation parameters are user accessible, method can be freely selected.
  • This means that continue_with_least_squares has been removed. Users can chain different methods as they please.
  • The mistake in the Jabocian has been corrected, which should now lead to more stable equilibration.
Edited by Koerber, Lukas (FWIN-C) - 108045

Merge request reports