4 OOMMF eXtensible Solver

4.1 Sample Oxs_Energy Class

This sections provides an extended dissection of a simple Oxs_Energy child class. The computational details are kept as simple as possible, so the discussion can focus on the C++ class structural details. Although the calculation details will vary between energy terms, the class structure issues discussed here apply across the board to all energy terms.

The particular example presented here is for simulating uniaxial magneto-crystalline energy, with a single anisotropy constant, K1, and a single axis, axis, which are uniform across the sample. The class definition (.h) and code (.cc) are displayed in Fig. 4.2 and 4.3, respectively.

 

Figure 4.2: Example energy class definition. (description)
/* FILE: exampleanisotropy.h
 *
 * Example anisotropy class definition.
 * This class is derived from the Oxs_Energy class.
 *
 */

#ifndef _OXS_EXAMPLEANISOTROPY
#define _OXS_EXAMPLEANISOTROPY

#include "energy.h"
#include "threevector.h"
#include "meshvalue.h"

/* End includes */

class Oxs_ExampleAnisotropy:public Oxs_Energy {
private:
  double K1;        // Primary anisotropy coeficient
  ThreeVector axis; // Anisotropy direction
public:
  virtual const char* ClassName() const; // ClassName() is
  /// automatically generated by the OXS_EXT_REGISTER macro.
  virtual BOOL Init();
  Oxs_ExampleAnisotropy(const char* name,  // Child instance id
                        Oxs_Director* newdtr, // App director
                        Tcl_Interp* safe_interp, // Safe interpreter
                        const char* argstr);  // MIF input block parameters

  virtual ~Oxs_ExampleAnisotropy() {}

  virtual void GetEnergyAndField(const Oxs_SimState& state,
                                 Oxs_MeshValue<REAL8m>& energy,
                                 Oxs_MeshValue<ThreeVector>& field
                                 ) const;
};


#endif // _OXS_EXAMPLEANISOTROPY

 

 

Figure 4.3: Example energy class code. (description)
/* FILE: exampleanisotropy.cc            -*-Mode: c++-*-
 *
 * Example anisotropy class implementation.
 * This class is derived from the Oxs_Energy class.
 *
 */

#include "exampleanisotropy.h"

// Oxs_Ext registration support
OXS_EXT_REGISTER(Oxs_ExampleAnisotropy);

/* End includes */

#define MU0           12.56637061435917295385e-7   /* 4 PI 10^7 */

// Constructor
Oxs_ExampleAnisotropy::Oxs_ExampleAnisotropy(
  const char* name,     // Child instance id
  Oxs_Director* newdtr, // App director
  Tcl_Interp* safe_interp, // Safe interpreter
  const char* argstr)   // MIF input block parameters
  : Oxs_Energy(name,newdtr,safe_interp,argstr)
{
  // Process arguments
  K1=GetRealInitValue("K1");
  axis=GetThreeVectorInitValue("axis");
  VerifyAllInitArgsUsed();
}

BOOL Oxs_ExampleAnisotropy::Init()
{ return 1; }

void Oxs_ExampleAnisotropy::GetEnergyAndField
(const Oxs_SimState& state,
 Oxs_MeshValue<REAL8m>& energy,
 Oxs_MeshValue<ThreeVector>& field
 ) const
{
  const Oxs_MeshValue<REAL8m>& Ms_inverse = *(state.Ms_inverse);
  const Oxs_MeshValue<ThreeVector>& spin = state.spin;
  UINT4m size = state.mesh->Size();

  for(UINT4m i=0;i<size;++i) {
    REAL8m field_mult = (2.0/MU0)*K1*Ms_inverse[i];
    if(field_mult==0.0) {
      energy[i]=0.0;
      field[i].Set(0.,0.,0.);
      continue;
    }
    REAL8m dot = axis*spin[i];
    field[i] = (field_mult*dot) * axis;
    if(K1>0) {
      energy[i] = -K1*(dot*dot-1.0); // Make easy axis zero energy
    } else {
      energy[i] = -K1*dot*dot; // Easy plane is zero energy
    }
  }
}