#include <stdio.h>
#include <math.h>
#include <mem.h>
#pragma hdrstop

#include "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/
 */

void Subinterval::CalculatePQX(SubintervalParms &parms) {
  parms.P = h / 3;
  parms.Q = 2 * (F - parms.total/h) / h;
}

void Subinterval::CalculatePQ(SubintervalParms& parms, 
			      SubintervalParms &p1, Subinterval& i1) {
  REAL P_h = p1.P + i1.h;		// P+h
  REAL h_h = i1.h + h;			// h+h
  REAL denom = 3*P_h*h_h - 2*SQR(i1.h);
  
  parms.P = (h*P_h*h_h + 2*h*i1.h*p1.P) / denom;
  parms.Q = (-6*P_h*(parms.total/h-p1.total/i1.h) - 2*p1.Q*SQR(i1.h)) / denom;
}

void Subinterval::CalculateAlphaBetaX(SubintervalParms& parms, 
				      SubintervalParms& p0, Subinterval& i0) {
  REAL denom = h * (3*parms.P+h);
  REAL F_T = 6 * (F - parms.total/h);
  
  parms.alpha = (3*h*parms.Q + F_T) / denom;
  parms.beta = (SQR(h)*parms.Q - parms.P*F_T) / denom;
  i0.dXdt = (sK*MW/L/sRho*0.000001)*(2*SQR(i0.h)*p0.alpha+6*
				     (F-p0.total/i0.h))/3/i0.h
    + (lK*MW/L/lRho*0.000001)*(2*SQR(h)*parms.Q+(parms.P+h)*F_T)/denom;
}

void Subinterval::CalculateAlphaBeta(SubintervalParms& parms, 
				     SubintervalParms& p0, Subinterval& i0) {
  REAL h_h = h + i0.h;	// h+h
  REAL diff = p0.total/i0.h - parms.total/h;
  REAL denom = 3*(parms.P+h)*h_h - 2*SQR(h);
  
  parms.alpha = (-2*SQR(i0.h)*p0.alpha + 3*parms.Q*h_h + 6*diff) / denom;
  parms.beta  = (2*SQR(i0.h)*p0.alpha*parms.P + parms.Q*h*(h+3*i0.h) - 
		 6*parms.P*diff) / denom;
}

void Subinterval::InitialAlphaBetaFixed(SubintervalParms& parms, REAL value) {
  REAL denom = h * (3*parms.P+h);
  REAL diff = value - parms.total/h;
  parms.alpha = (3*h*parms.Q + 6*diff) / denom;
  parms.beta  = (SQR(h)*parms.Q - 6*parms.P*diff) / denom;
}

void Subinterval::CalculatePQXS(Subinterval &i1, REAL C, REAL A, REAL B) {
  REAL h3P = i1.h + 3*i1.heat.P;
  REAL g3P = i1.h + 3*i1.salt.P;
  REAL hP  = i1.h + i1.heat.P;
  REAL gP  = i1.h + i1.salt.P;
  
  REAL denom = 3*D*Lp*h*i1.h*gP*h3P - A*C*i1.h*g3P*(sK*i1.h*h3P+3*lK*h*hP);
  /* [denom] = J*m3/sec */
  
  REAL h_3R = i1.h + 3*i1.heat.P;
  REAL h_3P = i1.h + 3*i1.salt.P;
  REAL h_P  = i1.h + i1.salt.P;
  REAL h_R  = i1.h + i1.heat.P;

  heat.P = (-i1.h*A*h*C*h_3P*(h*lK*h_R+i1.h*sK*h_3R)
	    + i1.h*D*SQR(h)*L*lRho*h_3R*h_P/MW*1000000/*ml/m3*/) / denom;
  /* [P] = m */
  
  heat.Q = -(6*lK*i1.h*A*C*h_R*h_3P*(i1.heat.total/i1.h - heat.total/h)
	     +6*D*L*lRho*i1.h*h_3R*h_P*
	     (heat.total/h - B - A*i1.salt.total/i1.h)/MW*1000000/*ml/m3*/
	     -2*lK*i1.h*A*C*SQR(i1.h)*i1.heat.Q*h_3P
	     +2*L*lRho*i1.h*D*SQR(i1.h)*A*i1.salt.Q*h_3R/MW*1000000/*ml/m3*/)
    / denom;
  /* [Q] =  K/m */
}

void Subinterval::CalculateAlphaBetaXS(Subinterval &i0, REAL C, 
				       REAL A, REAL B) {
  REAL h3P = h + 3*heat.P;
  REAL g3P = h + 3*salt.P;
  REAL hP  = h + heat.P;
  REAL gP  = h + salt.P;
  REAL Tm  = i0.heat.total/i0.h;
  REAL Tp  = heat.total/h;
  REAL Tf  = A*salt.total/h + B;

  REAL denom = 3*D*Lp*i0.h*h*gP*h3P - A*C*h*g3P*(sK*h*h3P+3*lK*i0.h*hP);
  /* [denom] = J*m3/sec */

  salt.alpha = (2*C*sK*SQR(i0.h)*h*h3P*i0.heat.alpha
		-3*salt.Q*(A*C*h*(sK*h*h3P+3*lK*i0.h*hP) - D*Lp*i0.h*h*h3P)
               	+6*C*lK*i0.h*SQR(h)*heat.Q
               	+6*C*(sK*h*h3P*(Tf-Tm) + 3*lK*i0.h*hP*(Tf-Tp))) / denom;
  /* [alpha] = mol/ml/m2 */
  
  heat.alpha = (2*A*C*sK*h*SQR(i0.h)*g3P*i0.heat.alpha
		-6*A*D*Lp*SQR(h)*i0.h*salt.Q
                -3*heat.Q*(A*C*h*g3P*(sK*h+lK*i0.h) - 3*D*Lp*i0.h*h*gP)
                +18*D*Lp*i0.h*gP*(Tf-Tp) - 6*A*C*sK*h*g3P*(Tm-Tp)) / denom;
  /* [alpha'] = K/m2 */
  
  i0.dXdt = D*(gP*salt.alpha - salt.Q) / C;
  /* [dXdt] = m/s */
  
  salt.beta  = salt.Q - salt.P*salt.alpha;
  heat.beta  = heat.Q - heat.P*heat.alpha;
  }


