//-----------------------------------------------------------------------------
//
//  Peter Richter (prichter@princeton.edu)
//  Princeton Plasma Physics Laboratory
//  August 2000
//
//  f77cx.cpp - Implementation of F77 charge exchange reaction routines.
//
//-----------------------------------------------------------------------------
 
#include "preact/f77cx.h"
#include <iostream>
#include "preact/cxreaction.h"

using namespace std ;
 
#define M 100
 
static CXReaction *cx[M];
static int pr_next = 0;
 
//-----------------------------------------------------------------------------
 
integer_function F77NAME(cx_init)(integer& icode, integer& ierrlo,
			      	  integer& ierrhi)
{
  if (pr_next == M) {
    cerr << "Error: Too many (over " << M << ") calls to cx_init.\n";
    F77NAME(bad_exit)();
  }
  switch (icode) {
  case 1:  cx[pr_next] = new CXReaction((char *)"H->H(cx)", ierrlo, ierrhi); break;
  case 2:  cx[pr_next] = new CXReaction((char *)"H+->He0x", ierrlo, ierrhi); break;
  case 3:  cx[pr_next] = new CXReaction((char *)"He++>Hex", ierrlo, ierrhi); break;
  case 4:  cx[pr_next] = new CXReaction((char *)"H+->Li0x", ierrlo, ierrhi); break;
  case 5:  cx[pr_next] = new CXReaction((char *)"He++>Lix", ierrlo, ierrhi); break;
  case 6:  cx[pr_next] = new CXReaction((char *)"Li+++>Lx", ierrlo, ierrhi); break;
  default: cerr << "Error: Invalid icode value passed to cx_init.\n"; F77NAME(bad_exit)();
  }
  return pr_next++;
}
 
//-----------------------------------------------------------------------------
 
real_function F77NAME(cx_sigma)(integer& ihandle, real_8& Erel)
{
  if (ihandle < 0 || ihandle >= pr_next) {
    cerr << "Error: Invalid ihandle value passed to cx_sigma.\n";
    F77NAME(bad_exit)();
  }
  return cx[ihandle]->sigma(Erel);
}
 
//-----------------------------------------------------------------------------
 
real_function F77NAME(cx_vrel)(integer& ihandle, real_8& Erel)
{
  if (ihandle < 0 || ihandle >= pr_next) {
    cerr << "Error: Invalid ihandle value passed to cx_vrel.\n";
    F77NAME(bad_exit)();
  }
  return cx[ihandle]->vrel(Erel);
}
 
//-----------------------------------------------------------------------------
 
subroutine F77NAME(cx_coldtarget_sigmatimesv)(integer& ihandle, real_8 *E,
					      real_8 *f, integer& n)
{
  if (ihandle < 0 || ihandle >= pr_next) {
    cerr << "Error: Invalid ihandle value passed to "
         << "cx_coldtarget_sigmatimesv.\n";
    F77NAME(bad_exit)();
  }
  cx[ihandle]->coldTarget_sigmaTimesV(E, f, n);
}
 
//-----------------------------------------------------------------------------
 
subroutine F77NAME(cx_coldtarget_erange)(integer& ihandle, real_8& Emin,
					 real_8& Emax,
					 integer& min_policy,
					 integer& max_policy)
{
  if (ihandle < 0 || ihandle >= pr_next) {
    cerr << "Error: Invalid ihandle value passed to cx_coldtarget_erange.\n";
    F77NAME(bad_exit)();
  }
  range r = cx[ihandle]->coldTarget_ERange();
  Emin = r.minimum;
  Emax = r.maximum;
  min_policy = r.min_policy;
  max_policy = r.max_policy;
}
 
//-----------------------------------------------------------------------------
subroutine F77NAME(cx_coldtarget_epolicy)(integer& ihandle,
					  integer& min_policy,
					  integer& max_policy)
{
  cx[ihandle]->coldTarget_EPolicy(min_policy,max_policy);
}
 
//-----------------------------------------------------------------------------
 
subroutine F77NAME(cx_warmtarget_sigmatimesv)(integer& ihandle, real_8 *E,
					      real_8 *T, real_8 *f, integer& n)
{
  if (ihandle < 0 || ihandle >= pr_next) {
    cerr << "Error: Invalid ihandle value passed to "
         << "cx_warmtarget_sigmatimesv.\n";
    F77NAME(bad_exit)();
  }
  cx[ihandle]->warmTarget_sigmaTimesV(E, T, f, n);
}
 
//-----------------------------------------------------------------------------
 
subroutine F77NAME(cx_warmtarget_erange)(integer& ihandle, real_8& Emin,
					 real_8& Emax,
					 integer& min_policy,
					 integer& max_policy)
{
  if (ihandle < 0 || ihandle >= pr_next) {
    cerr << "Error: Invalid ihandle value passed to cx_warmtarget_erange.\n";
    F77NAME(bad_exit)();
  }
  range r = cx[ihandle]->warmTarget_ERange();
  Emin = r.minimum;
  Emax = r.maximum;
  min_policy = r.min_policy;
  max_policy = r.max_policy;
}
 
//-----------------------------------------------------------------------------
 
subroutine F77NAME(cx_warmtarget_trange)(integer& ihandle, real_8& Tmin,
					 real_8& Tmax,
					 integer& min_policy,
					 integer& max_policy)
{
  if (ihandle < 0 || ihandle >= pr_next) {
    cerr << "Error: Invalid ihandle value passed to cx_warmtarget_trange.\n";
    F77NAME(bad_exit)();
  }
  range r = cx[ihandle]->warmTarget_TRange();
  Tmin = r.minimum;
  Tmax = r.maximum;
  min_policy = r.min_policy;
  max_policy = r.max_policy;
}
 
//-----------------------------------------------------------------------------
 
//-----------------------------------------------------------------------------
subroutine F77NAME(cx_warmtarget_epolicy)(integer& ihandle,
					  integer& min_policy,
					  integer& max_policy)
{
  cx[ihandle]->warmTarget_EPolicy(min_policy,max_policy);
}
 
//-----------------------------------------------------------------------------
subroutine F77NAME(cx_warmtarget_tpolicy)(integer& ihandle,
					  integer& min_policy,
					  integer& max_policy)
{
  cx[ihandle]->warmTarget_TPolicy(min_policy,max_policy);
}
 
//-----------------------------------------------------------------------------
 
subroutine F77NAME(cx_energyavg_peramu)(integer& ihandle, real_8 *E,
					real_8 *T, real_8 *f, integer& n)
{
  if (ihandle < 0 || ihandle >= pr_next) {
    cerr << "Error: Invalid ihandle value passed to cx_energyavg_peramu.\n";
    F77NAME(bad_exit)();
  }
  cx[ihandle]->energyAvg_perAMU(E, T, f, n);
}
 
//-----------------------------------------------------------------------------
 
subroutine F77NAME(cx_energyavg_peramu_erange)(integer& ihandle, real_8& Emin,
					       real_8& Emax,
					       integer& min_policy,
					       integer& max_policy)
{
  if (ihandle < 0 || ihandle >= pr_next) {
    cerr << "Error: Invalid ihandle value passed to "
         << "cx_energyavg_peramu_erange.\n";
    F77NAME(bad_exit)();
  }
  range r = cx[ihandle]->energyAvg_perAMU_ERange();
  Emin = r.minimum;
  Emax = r.maximum;
  min_policy = r.min_policy;
  max_policy = r.max_policy;
}
 
//-----------------------------------------------------------------------------
 
subroutine F77NAME(cx_energyavg_peramu_trange)(integer& ihandle, real_8& Tmin,
					       real_8& Tmax,
					       integer& min_policy,
					       integer& max_policy)
{
  if (ihandle < 0 || ihandle >= pr_next) {
    cerr << "Error: Invalid ihandle value passed to "
         << "cx_energyavg_peramu_trange.\n";
    F77NAME(bad_exit)();
  }
  range r = cx[ihandle]->energyAvg_perAMU_TRange();
  Tmin = r.minimum;
  Tmax = r.maximum;
  min_policy = r.min_policy;
  max_policy = r.max_policy;
}
 
//-----------------------------------------------------------------------------
subroutine F77NAME(cx_energyavg_peramu_epolicy)(integer& ihandle,
					  integer& min_policy,
					  integer& max_policy)
{
  cx[ihandle]->energyAvg_perAMU_EPolicy(min_policy,max_policy);
}
 
//-----------------------------------------------------------------------------
subroutine F77NAME(cx_energyavg_peramu_tpolicy)(integer& ihandle,
					  integer& min_policy,
					  integer& max_policy)
{
  cx[ihandle]->energyAvg_perAMU_TPolicy(min_policy,max_policy);
}
 
//-----------------------------------------------------------------------------
 
subroutine F77NAME(cx_average_vdotnorm)(integer& ihandle, real_8 *E,
					real_8 *T, real_8 *f, integer& n)
{
  if (ihandle < 0 || ihandle >= pr_next) {
    cerr << "Error: Invalid ihandle value passed to cx_average_vdotnorm.\n";
    F77NAME(bad_exit)();
  }
  cx[ihandle]->average_vDotNorm(E, T, f, n);
}
 
//-----------------------------------------------------------------------------
 
subroutine F77NAME(cx_average_vdotnorm_erange)(integer& ihandle, real_8& Emin,
					       real_8& Emax,
					       integer& min_policy,
					       integer& max_policy)
{
  if (ihandle < 0 || ihandle >= pr_next) {
    cerr << "Error: Invalid ihandle value passed to "
         << "cx_average_vdotnorm_erange.\n";
    F77NAME(bad_exit)();
  }
  range r = cx[ihandle]->average_vDotNorm_ERange();
  Emin = r.minimum;
  Emax = r.maximum;
  min_policy = r.min_policy;
  max_policy = r.max_policy;
}
 
//-----------------------------------------------------------------------------
 
subroutine F77NAME(cx_average_vdotnorm_trange)(integer& ihandle, real_8& Tmin,
					       real_8& Tmax,
					       integer& min_policy,
					       integer& max_policy)
{
  if (ihandle < 0 || ihandle >= pr_next) {
    cerr << "Error: Invalid ihandle value passed to "
         << "cx_average_vdotnorm_trange.\n";
    F77NAME(bad_exit)();
  }
  range r = cx[ihandle]->average_vDotNorm_TRange();
  Tmin = r.minimum;
  Tmax = r.maximum;
  min_policy = r.min_policy;
  max_policy = r.max_policy;
}
 
//-----------------------------------------------------------------------------
subroutine F77NAME(cx_average_vdotnorm_epolicy)(integer& ihandle,
					  integer& min_policy,
					  integer& max_policy)
{
  cx[ihandle]->average_vDotNorm_EPolicy(min_policy,max_policy);
}
 
//-----------------------------------------------------------------------------
subroutine F77NAME(cx_average_vdotnorm_tpolicy)(integer& ihandle,
					  integer& min_policy,
					  integer& max_policy)
{
  cx[ihandle]->average_vDotNorm_TPolicy(min_policy,max_policy);
}
 
//-----------------------------------------------------------------------------
