Sample Oxs_Energy Class
Keywords: progman

Next: Writing a New Oxs_Energy Up: OOMMF eXtensible Solver Previous: OOMMF eXtensible Solver

##
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) files are included below.

    /* 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 2: Example energy class definition. (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
        }
      }
    }

Figure 3: Example energy class code. (Description.)

OOMMF Documentation Team
September 29, 2018