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
}
}
}