#ifndef CXREACTION_H
#define CXREACTION_H

//-----------------------------------------------------------------------------
//
//  Peter Richter (prichter@princeton.edu)
//  Princeton Plasma Physics Laboratory
//  August 2000
//
//  cxreaction.h - Interface for charge exchange reaction class.
//
//-----------------------------------------------------------------------------

#include "preact/grid_1d.h"
#include "preact/grid_2d.h"

class CXReaction {

public:    // constructor, destructor...
           CXReaction(char tag[], int errlo = WARN, int errhi = HALT);
	   ~CXReaction();

	   // sigma, vrel as functions of Erel...
           fp_64 sigma(fp_64 Erel);
	   fp_64 vrel(fp_64 Erel);

	   // sigma*v for beam to cold (T=0) target...
	   void coldTarget_sigmaTimesV(fp_64 E[], fp_64 f[], int n);
	   range coldTarget_ERange() const;
	   void coldTarget_EPolicy(int errlo, int errhi);

	   // <sigma*v> for beam to warm (T>0) target...
	   void warmTarget_sigmaTimesV(fp_64 E[], fp_64 T[], fp_64 f[],
				       int n);
	   range warmTarget_ERange() const;
	   range warmTarget_TRange() const;
	   void warmTarget_EPolicy(int errlo, int errhi);
	   void warmTarget_TPolicy(int errlo, int errhi);

	   // <E/A> of target reagent...
	   void energyAvg_perAMU(fp_64 E[], fp_64 T[], fp_64 f[], int n);
	   range energyAvg_perAMU_ERange() const;
	   range energyAvg_perAMU_TRange() const;
	   void energyAvg_perAMU_EPolicy(int errlo, int errhi);
	   void energyAvg_perAMU_TPolicy(int errlo, int errhi);

	   // <Vb dot Vtarg / |Vb|*|Vth|>...
	   void average_vDotNorm(fp_64 E[], fp_64 T[], fp_64 f[], int n);
	   range average_vDotNorm_ERange() const;
	   range average_vDotNorm_TRange() const;
	   void average_vDotNorm_EPolicy(int errlo, int errhi);
	   void average_vDotNorm_TPolicy(int errlo, int errhi);

protected: // auxiliary functions...
	   void setTableParameters(char dir[]);
           void setKReactVariable();
	   void computeAxis(fp_64 axis[], int npts, range endpts, int spac);
	   void compute1DTable(grid_1D& g, char file[]);
	   void compute2DTable(grid_2D& g, char file[]);
	   void read1DTable(grid_1D& g, char file[]);
	   void read2DTable(grid_2D& g, char file[]);
	   void interp1DTable(char table[], grid_1D& g,
			      fp_64 x[], char xdim[],
			      fp_64 f[], int n);
	   void interp2DTable(char table[], grid_2D& g,
			      fp_64 x[], char xdim[],
			      fp_64 y[], char ydim[], fp_64 f[], int n);
	   void g_tablefile(char table[], char file[]);
	   void range_error_exit(char table[]);
	   void range_error_warn(char table[]);

	   // data members...
	   grid_1D coldTarget_data;
           grid_2D warmTarget_data;
	   grid_2D energyAvg_perAMU_data;
	   grid_2D average_vDotNorm_data;
	   int errlo, errhi;
	   int code;
};

//-----------------------------------------------------------------------------

#endif

