/* FILE: cubicanisotropy8.cc -*-Mode: c++-*- * * Cubic Anisotropy for higher orders, derived from Oxs_Energy class. * implementing interface cubicanisotropy8.h * * This class is a modification of the class * /oommf/app/oxs/ext/cubicanisotropy.cc * It is designed for handling higher orders of the * power series of the cubic anisotropy * * The required values are * -scalar 'K1' (for fourth order power) * -scalar 'K2' (for sixth order power), * -scalar 'K3' (for eigth order power), * -vector 'axis1' indicating first cubic anisotropy direction * -vector 'axis2' indicating second cubic anisotropy direction * (the third axis is assumed to be perpendicular to axis1 and axis2) * * Juergen Zimmermann * Computational Engineering and Design Group * University of Southampton * * file created Wed Mai 11 2005 * * file updated Thu April 19 2007: * renaming issues Ced_CubicAnisotropy to Southampton_CubicAnisotropy8 */ #include "oc.h" #include "nb.h" #include "threevector.h" #include "director.h" #include "simstate.h" #include "ext.h" #include "key.h" #include "mesh.h" #include "meshvalue.h" #include "cubicanisotropy8.h" #include "energy.h" // Needed to make MSVC++ 5 happy // Oxs_Ext registration support OXS_EXT_REGISTER(Southampton_CubicAnisotropy8); /* End includes */ // Constructor Southampton_CubicAnisotropy8::Southampton_CubicAnisotropy8( const char* name, // Child instance id Oxs_Director* newdtr, // App director const char* argstr) // MIF input block parameters : Oxs_Energy(name,newdtr,argstr), mesh_id(0) { // Process arguments OXS_GET_INIT_EXT_OBJECT("K1",Oxs_ScalarField,K1_init); OXS_GET_INIT_EXT_OBJECT("K2",Oxs_ScalarField,K2_init); OXS_GET_INIT_EXT_OBJECT("K3",Oxs_ScalarField,K3_init); OXS_GET_INIT_EXT_OBJECT("axis1",Oxs_VectorField,axis1_init); OXS_GET_INIT_EXT_OBJECT("axis2",Oxs_VectorField,axis2_init); VerifyAllInitArgsUsed(); } void Southampton_CubicAnisotropy8::GetEnergy (const Oxs_SimState& state, Oxs_EnergyData& oed ) const { const Oxs_MeshValue& Ms_inverse = *(state.Ms_inverse); const Oxs_MeshValue& spin = state.spin; // Use supplied buffer space, and reflect that use in oed. oed.energy = oed.energy_buffer; oed.field = oed.field_buffer; Oxs_MeshValue& energy = *oed.energy_buffer; Oxs_MeshValue& field = *oed.field_buffer; UINT4m size = state.mesh->Size(); if(mesh_id != state.mesh->Id()) { // This is either the first pass through, or else mesh // has changed. mesh_id=0; K1_init->FillMeshValue(state.mesh,K1); K2_init->FillMeshValue(state.mesh,K2); K3_init->FillMeshValue(state.mesh,K3); axis1_init->FillMeshValue(state.mesh,axis1); axis2_init->FillMeshValueOrthogonal(state.mesh,axis1,axis2); for(UINT4m i=0;ieps) { string msg="Invalid initialization detected for object " + string(InstanceName()) + ": Anisotropy axis 1 isn't norm 1"; throw Oxs_Ext::Error(msg.c_str()); } if(fabs(axis2[i].MagSq()-1)>eps) { string msg="Invalid initialization detected for object " + string(InstanceName()) + ": Anisotropy axis 2 isn't norm 1"; throw Oxs_Ext::Error(msg.c_str()); } if(fabs(axis1[i]*axis2[i])>eps) { string msg="Invalid initialization detected for object " + string(InstanceName()) + ": Specified anisotropy axes aren't perpendicular"; throw Oxs_Ext::Error(msg.c_str()); } } mesh_id=state.mesh->Id(); } for(UINT4m i=0;i