#if !defined(__SUBINT_H)
#define __SUBINT_H

/* CryoSimulation v1.01
 *
 * Written by:  Chris Studholme
 * Last Update: 28-Oct-1996
 * Copyright:   GPL (http://www.fsf.org/copyleft/gpl.html)
 * Web Site:    http://www.bus.ualberta.ca/cstudhol/msc/
 */

#define REAL double

#define SQR(i)	((i)*(i))
#define CUBE(i)	((i)*(i)*(i))
#define ABS(i)	((i)<0?(-(i)):(i))
#define ERROR(i,j)	(ABS((i)-(j))/(ABS(i)+ABS(j)))

#define F	273		/* K 			*/
#define L	6009		/* J/mol 		*/
#define MW	18.015		/* g/mol 		*/
#define lRho	1		/* g/ml 		*/
#define lK	0.574		/* J*m/m2/K/sec */
#define lCp	75.98		/* J/K/mol 		*/
#define sRho	1/*0.92*/	/* g/ml 		*/
#define sK	2.2		/* J*m/m2/K/sec */
#define sCp	37.8		/* J/K/mol 		*/
#define Lp      (L*lRho/MW*1e6)	/*ml/m3*/

#define D	0.5e-7	/* diffusion coeff (m2/sec) for NaMnO4 */

struct SubintervalParms {
  REAL alpha;
  REAL beta;
  //	REAL gamma;
  REAL total;		// total heat(K*m) or substance(mol)

  REAL P,Q;
};

class Subinterval {
 public:
  SubintervalParms heat;
  SubintervalParms salt;
  
  REAL x;		// left boundry (m)
  REAL h;		// width (m)
  
  int IsSolid;
  REAL dXdt;
  REAL estConc;
  
  void CalculatePQ(SubintervalParms& parms, SubintervalParms &p1, 
		   Subinterval& i1);
  void CalculatePQX(SubintervalParms& parms);
  void CalculatePQXS(Subinterval &i1, REAL C, REAL A, REAL B);
  
  void CalculateAlphaBeta(SubintervalParms& parms, SubintervalParms& p0, 
			  Subinterval& i0);
  void CalculateAlphaBetaX(SubintervalParms& parms, SubintervalParms& p0, 
			   Subinterval& i0);
  void CalculateAlphaBetaXS(Subinterval &i0, REAL C, REAL A, REAL B);
  
  inline void AdjustTotal(SubintervalParms& parms, REAL Ddt) {
    parms.total += 2*parms.alpha*Ddt*h; 
  }
  
  inline void InitialPQFlux(SubintervalParms& parms, REAL flux) {
    parms.P = h; parms.Q = flux; 
  }
  
  void InitialAlphaBetaFixed(SubintervalParms& parms, REAL value);
  
};

#endif
