/* FILE: uzeeman.h            -*-Mode: c++-*-
 *
 * Uniform Zeeman (applied field) energy, derived from Oxs_Energy class.
 *
 */

#ifndef _OXS_UZEEMAN
#define _OXS_UZEEMAN

#include <vector>
#include "chunkenergy.h"
#include "energy.h"
#include "output.h"
#include "simstate.h"
#include "threevector.h"

OC_USE_STD_NAMESPACE;

/* End includes */

class Oxs_UZeeman
  : public Oxs_ChunkEnergy, public Oxs_EnergyPreconditionerSupport {
private:
  vector<ThreeVector> Happ;  // Indexed off of state stage_number

  ThreeVector GetAppliedField(OC_UINT4m stage_number) const;
  /// Utility function. Indexes Happ off of stage_number with
  /// proper range behavior.

  ThreeVector GetAppliedField(const Oxs_SimState& state) const;

  OC_UINT4m FieldCount() const {
    return static_cast<OC_UINT4m>(Happ.size());
  }

  // Supplied outputs, in addition to those provided by Oxs_Energy.
  Oxs_ScalarOutput<Oxs_UZeeman> Bapp_output;
  Oxs_ScalarOutput<Oxs_UZeeman> Bappx_output;
  Oxs_ScalarOutput<Oxs_UZeeman> Bappy_output;
  Oxs_ScalarOutput<Oxs_UZeeman> Bappz_output;
  void Fill__Bapp_output(const Oxs_SimState& state);

protected:
  virtual void GetEnergy(const Oxs_SimState& state,
			 Oxs_EnergyData& oed) const {
    GetEnergyAlt(state,oed);
  }

  virtual void ComputeEnergy(const Oxs_SimState& state,
                             Oxs_ComputeEnergyData& oced) const {
    ComputeEnergyAlt(state,oced);
  }

  virtual void ComputeEnergyChunkInitialize
  (const Oxs_SimState& state,
   Oxs_ComputeEnergyDataThreaded& ocedt,
   Oc_AlignedVector<Oxs_ComputeEnergyDataThreadedAux>& thread_ocedtaux,
   int number_of_threads) const;

  virtual void ComputeEnergyChunk(const Oxs_SimState& state,
                                  Oxs_ComputeEnergyDataThreaded& ocedt,
                                  Oxs_ComputeEnergyDataThreadedAux& ocedtaux,
                                  OC_INDEX node_start,OC_INDEX node_stop,
                                  int threadnumber) const;

public:
  virtual const char* ClassName() const; // ClassName() is
  /// automatically generated by the OXS_EXT_REGISTER macro.
  Oxs_UZeeman(const char* name,     // Child instance id
	      Oxs_Director* newdtr, // App director
	      const char* argstr);  // MIF input block parameters
  virtual ~Oxs_UZeeman();
  virtual OC_BOOL Init();
  virtual void StageRequestCount(unsigned int& min,
				 unsigned int& max) const;
  // min is set to the size of Happ, i.e., the number of applied
  // field values.  If this value larger than 1, then max is set
  // to the same value, for tight stage range checking.
  // Otherwise, max is set to UINT_MAX, i.e., infinity.

  // Optional interface for conjugate-gradient evolver.
  virtual OC_INT4m IncrementPreconditioner(PreconditionerData& pcd);
};


#endif // _OXS_UZEEMAN
