/* FILE: MF_magnetoResistance.cc                 -*-Mode: c++-*-
 * version 1.1.1
 *
 * Class allows calculations of resistance of selected areas of the junction
 *  
 * author: Marek Frankowski
 * contact: mfrankow[at]agh.edu.pl
 * website: layer.uci.agh.edu.pl/M.Frankowski
 *
 * This code is public domain work based on other public domains contributions
 */

#ifndef _MF_MagnetoResistance
#define _MF_MagnetoResistance

#include <string>
#include <vector>

#include "oc.h"
#include "director.h"
#include "energy.h"
#include "meshvalue.h"
#include "simstate.h"
#include "threevector.h"

OC_USE_STD_NAMESPACE;
OC_USE_STRING;

/* End includes */

//////////////////////////////////////////////////////////////////
// Old OOMMF version support
#ifndef OC_HAS_INT8
// Typedefs and defines for OOMMF prior to 16-Jul-2010
typedef REAL8m OC_REAL8m;
typedef UINT4m OC_UINT4m;
typedef BOOL OC_BOOL;
typedef INT4m OC_INT4m;
typedef INT4m OC_INT4m;
typedef UINT4m OC_INDEX;  // Supports pre-OC_INDEX API
#define OC_REAL8_EPSILON REAL8_EPSILON
#endif

#if !defined(OOMMF_API_INDEX) || OOMMF_API_INDEX<20110628
// Old API being used
#include "tclcommand.h"
typedef Oxs_TclCommandLineOption Nb_TclCommandLineOption;
typedef Oxs_TclCommand Nb_TclCommand;
typedef Oxs_SplitList Nb_SplitList;
#define Nb_ParseTclCommandLineRequest(a,b,c) Oxs_ParseTclCommandLineRequest((a),(b),(c))
#endif
//////////////////////////////////////////////////////////////////

// MSC++ 5.0 doesn't like embedded classes used for
// vector template types.  So, we just define this
// outside, with a really long name. <g>
struct MF_MagnetoResistanceLinkParams {
  OC_INDEX index1,index2;  // Offsets into mesh to cells in pair
  OC_REAL8m exch_coef1;  // Let d be the computational cellsize along
  OC_REAL8m exch_coef2; /// the direction between the linked cells.
	OC_REAL8m conductance;
  /// And let sigma be the bilinear surface (interfacial) exchange
  /// energy in J/m^2, and sigma2 be the biquadratic surface
  /// (interfacial) exchange energy, also in J/m^2.  Then
  ///          exch_coef1 = (sigma1 + 2*sigma2)/d
  ///          exch_coef2 = -sigma2/d.
  /// The energy density at cell i due to cell j is computed in
  /// terms of b = 0.5*(m_i - m_j)^2 as
  ///
  ///  E_ij = coef1*b + coef2*b*b =
  ///     (1/d)*[(sigma1+sigma2)-sigma1*m_i.m_j-sigma2*(m_i.m_j)^2]
  ///    -(1/d)*[eps*(sigma1+sigma2*m_i.m_j)+eps^2*sigma2*(1-m_i.m_j)]
  ///
  /// where eps = 1 - 0.5*(m_i^2 + m_j^2) is presumably close to 0.
};

// The next 3 operators are defined so MSVC++ 5.0 will accept
// vector<Oxs_RandomSiteExchangeLinkParams>, but are left undefined
// because there is no meaningful way to define them.
OC_BOOL operator<(const MF_MagnetoResistanceLinkParams&,
	       const MF_MagnetoResistanceLinkParams&);
OC_BOOL operator>(const MF_MagnetoResistanceLinkParams&,
	       const MF_MagnetoResistanceLinkParams&);
OC_BOOL operator==(const MF_MagnetoResistanceLinkParams&,
		const MF_MagnetoResistanceLinkParams&);

class MF_MagnetoResistance:public Oxs_Energy {
private:
  OC_REAL8m RA_p;
  OC_REAL8m RA_ap;
 OC_REAL8m Rs_p;
  OC_REAL8m Rs_ap;
  Oxs_OwnedPointer<Oxs_Atlas> atlas1,atlas2;
  String region1,region2;
  Oxs_OwnedPointer<Oxs_ScalarField> bdry1,bdry2;
  OC_REAL8m bdry1_value,bdry2_value;
  String bdry1_side,bdry2_side;
  
  mutable vector<MF_MagnetoResistanceLinkParams> links;
  void FillLinkList(const Oxs_RectangularMesh* mesh) const;

  mutable OC_UINT4m mesh_id;

  // Supplied outputs, in addition to those provided by Oxs_Energy.

	Oxs_ScalarOutput<MF_MagnetoResistance> MR_output;
Oxs_ScalarOutput<MF_MagnetoResistance> mr_area_output;
Oxs_ScalarOutput<MF_MagnetoResistance> mr_area1_output;
Oxs_ScalarOutput<MF_MagnetoResistance> mr_area2_output;
Oxs_ScalarOutput<MF_MagnetoResistance> mr_area3_output;
OC_REAL8m area_x, area_y, delta_x, delta_y;
OC_REAL8m area_x1, area_y1, delta_x1, delta_y1;
OC_REAL8m area_x2, area_y2, delta_x2, delta_y2;
OC_REAL8m area_x3, area_y3, delta_x3, delta_y3;
Oxs_VectorFieldOutput<MF_MagnetoResistance> conductance_output;
  void UpdateDerivedOutputs(const Oxs_SimState& state);
OC_REAL8m area_conductance;
OC_REAL8m area_conductance1;
OC_REAL8m area_conductance2;
OC_REAL8m area_conductance3;
protected:
  virtual void GetEnergy(const Oxs_SimState& state,
			 Oxs_EnergyData& oed) const;

public:
  virtual const char* ClassName() const; // ClassName() is
  /// automatically generated by the OXS_EXT_REGISTER macro.
  MF_MagnetoResistance(const char* name,     // Child instance id
			 Oxs_Director* newdtr, // App director
			 const char* argstr);  // MIF input block parameters
  virtual ~MF_MagnetoResistance();
  virtual OC_BOOL Init();
};


#endif // _MF_MagnetoResistance
