sandbox/ecipriano/src/ijc-coupled-gsl.h
#include "intgrad.h"
#include "fsolve-gsl.h"
#include "thermodynamics.h"
extern scalar * mEvapList;
extern scalar * YLList;
extern scalar * YGList;
extern scalar * YLIntList;
extern scalar * YGIntList;
#ifdef VARPROP
extern scalar * Dmix1List;
extern scalar * Dmix2List;
extern scalar * dhevList;
#endif
extern double inDmix1[NLS];
extern double inDmix2[NGS];
extern double inKeq[NLS];
extern double inMW[NGS];
extern double Pref;
extern scalar fL, fG;
extern face vector fsL, fsG;
extern int * LSI;
extern int * GOSI;
extern int inertIndex;
extern int NGOS;
extern double rho1, rho2;
#ifdef SOLVE_TEMPERATURE
extern double lambda1, lambda2, dhev, cp1, cp2, TL0, TG0;
extern scalar TInt, TL, TG, T;
#endif
#ifdef CLAPEYRON
extern double Tsat;
#endif
#ifdef USE_CLAPEYRON
extern double Tboil[NLS];
#endif
typedef struct {
coord c;
} UserDataNls;
void Equations (const double * xdata, double * fdata, void * params) {
UserDataNls * data = (UserDataNls *)params;
double mEvapToti[NGS];
double mEvapi[NLS];
double YLInti[NLS];
double YGInti[NGS];
double XLInti[NLS];
double XGInti[NGS];
double jL[NLS];
double jG[NGS];
double mEvapSum;
bool success;
int count;
#ifdef SOLVE_TEMPERATURE
double TInti;
double gradTGn;
double gradTLn;
#endif
foreach_point (data->c.x, data->c.y, data->c.z, serial) {
Rename unknowns for convenience.
count = 0;
for (int jj=0; jj<NLS; jj++)
mEvapi[jj] = xdata[count++];
for (int jj=0; jj<NLS; jj++)
YLInti[jj] = xdata[count++];
for (int jj=0; jj<NGS; jj++)
YGInti[jj] = xdata[count++];
#ifdef SOLVE_TEMPERATURE
TInti = xdata[count++];
#endif
Convert mass-to-mole fractions.
{
double inMWG[NGS];
for (int jj=0; jj<NGS; jj++)
inMWG[jj] = inMW[jj];
double inMWL[NLS];
for (int jj=0; jj<NLS; jj++)
inMWL[jj] = inMW[LSI[jj]];
mass2molefrac (XLInti, YLInti, inMWL, NLS);
mass2molefrac (XGInti, YGInti, inMWG, NGS);
}
Set to zero gas-only species vaporization mass flow-rates.
for (int jj=0; jj<NLS; jj++)
mEvapToti[LSI[jj]] = mEvapi[jj];
for (int jj=0; jj<NGOS; jj++)
mEvapToti[GOSI[jj]] = 0.;
Compute diffusive fluxes.
for (int jj=0; jj<NGS; jj++) {
double rho2vh = rho2;
double Dmix2vh = inDmix2[jj];
#ifdef VARPROP
rho2vh = rho2v[];
scalar Dmix2 = Dmix2List[jj];
Dmix2vh = Dmix2[];
//rho2vh = tp2.rhov (&ts2);
//Dmix2vh = tp2.diff (&ts2, jj);
#endif
scalar YG = YGList[jj];
double gtrgrad = ebmgrad (point, YG, fL, fG, fsL, fsG, true, YGInti[jj], &success);
jG[jj] = -rho2vh*Dmix2vh*gtrgrad;
}
for (int jj=0; jj<NLS; jj++) {
double rho1vh = rho1;
double Dmix1vh = inDmix1[jj];
#ifdef VARPROP
rho1vh = rho1v[];
scalar Dmix1 = Dmix1List[jj];
Dmix1vh = Dmix1[];
//rho1vh = tp1.rhov (&ts1);
//Dmix1vh = tp1.diff (&ts1, jj);
#endif
scalar YL = YLList[jj];
double ltrgrad = ebmgrad (point, YL, fL, fG, fsL, fsG, false, YLInti[jj], &success);
jL[jj] = rho1vh*Dmix1vh*ltrgrad;
}
Compute total diffusive fluxes for Fick corrected approach.
double jLtot = 0., jGtot = 0.;
#ifdef FICK_CORRECTED
for (int jj=0; jj<NLS; jj++)
jLtot += jL[jj];
for (int jj=0; jj<NGS; jj++)
jGtot += jG[jj];
#endif
#ifdef SOLVE_TEMPERATURE
gradTGn = ebmgrad (point, TG, fL, fG, fsL, fsG, true, TInti, &success);
gradTLn = ebmgrad (point, TL, fL, fG, fsL, fsG, false, TInti, &success);
#endif
Compute sum of vaporization mass flow-rate.
mEvapSum = 0.;
for (int jj=0; jj<NLS; jj++) {
mEvapSum += mEvapi[jj];
}
count = 0;
[NEW] Mass balance in gas phase for evaporating species.
for (int jj=0; jj<NLS; jj++) {
fdata[count++] = mEvapi[jj]
- mEvapSum*YGInti[LSI[jj]]
- jG[jj]
+ jGtot*YGInti[LSI[jj]]
;
}
[NEW] Mass balance in liquid phase for liquid species.
if (NLS > 1) {
for (int jj=0; jj<NLS; jj++) {
fdata[count++] = mEvapi[jj]
- mEvapSum*YLInti[jj]
- jL[jj]
+ jLtot*YLInti[jj];
;
}
}
else {
fdata[count++] = YLInti[0] - 1.;
}
//
//Mass balance for species in liquid phase.
//if (NLS > 1) {
// for (int jj=0; jj<NLS; jj++) {
// fdata[count++] = mEvapi[jj]
// - mEvapSum*YLInti[jj]
// - jL[jj]
// + jLtot*YLInti[jj]
// ;
// }
//}
//else {
// fdata[count++] = YLInti[0] - 1.;
//}
//
//Mass balance for species in gas phase and for gas-only species.
//for (int jj=0; jj<NGS; jj++) {
// fdata[count++] = mEvapToti[jj]
// - mEvapSum*YGInti[jj]
// - jG[jj]
// + jGtot*YGInti[jj]
// ;
//}
Thermodynamic (VLE) equilibrium at the interface.
double Keq[NLS];
for (int jj=0; jj<NLS; jj++)
Keq[jj] = inKeq[jj];
#ifdef USE_CLAPEYRON
for (int jj=0; jj<NLS; jj++) {
Keq[jj] = min (clapeyron ( min (TInti, Tboil[jj]-1), Tboil[jj], dhev, inMW[LSI[jj]]), 0.98);
}
#endif
#ifdef USE_ANTOINE
for (int jj=0; jj<NLS; jj++) {
scalar YL = YLList[jj];
Keq[jj] = min (YL.antoine (TInti, Pref), 0.98);
}
#endif
#ifdef USE_ANTOINE_OPENSMOKE
for (int jj=0; jj<NLS; jj++) {
Keq[jj] = min (opensmoke_antoine (TInti, Pref, jj), 0.98);
}
#endif
for (int jj=0; jj<NLS; jj++) {
fdata[count++] = XLInti[jj]*Keq[jj] - XGInti[LSI[jj]];
}
[NEW] Mass balance in gas phase for gas-only species.
for (int jj=0; jj<NGOS; jj++) {
fdata[count++] = mEvapToti[GOSI[jj]]
- mEvapSum*YGInti[GOSI[jj]]
- jG[GOSI[jj]]
+ jGtot*YGInti[GOSI[jj]]
;
}
#ifdef SOLVE_TEMPERATURE
Interface energy balance.
double vapheat = 0.;
for (int jj=0; jj<NLS; jj++) {
double dhevvh = dhev;
#ifdef VARPROP
scalar dhevjj = dhevList[jj];
dhevvh = dhevjj[];
#endif
vapheat -= dhevvh*mEvapi[jj];
}
fdata[count++] = vapheat
# ifdef VARPROP
+ lambda1v[]*gradTLn
+ lambda2v[]*gradTGn
# else
+ lambda1*gradTLn
+ lambda2*gradTGn
# endif
;
#endif
}
}
int EquationsGsl (const gsl_vector * x, void * params, gsl_vector * f) {
double * xdata = x->data;
double * fdata = f->data;
Equations (xdata, fdata, params);
return GSL_SUCCESS;
}
A partire da YLIntList, YGIntList, mEvapList e delle proprietà fisiche come densità e diffusività , bisogna calcolare la jump condition.
void ijc_CoupledNls ()
{
foreach() {
if (f[] > F_ERR && f[] < 1.-F_ERR) {
Reset variables.
Array * arrUnk = array_new();
// mInt field
for (int jj=0; jj<NLS; jj++) {
scalar mEvapi = mEvapList[LSI[jj]];
double vali = mEvapi[];
array_append (arrUnk, &vali, sizeof(double));
}
// YLInt field
for (int jj=0; jj<NLS; jj++) {
//scalar YLi = YLList[jj];
//double vali = YLi[]/max(f[], I_TOL);
scalar YLInti = YLIntList[jj];
double vali = YLInti[];
array_append (arrUnk, &vali, sizeof(double));
}
// YGInt field
for (int jj=0; jj<NGS; jj++) {
//scalar YGi = YGList[jj];
//double vali = YGi[]/max(1. - f[], I_TOL);
scalar YGInti = YGIntList[jj];
double vali = YGInti[];
array_append (arrUnk, &vali, sizeof(double));
}
#ifdef SOLVE_TEMPERATURE
// Temperature field
{
double vali = TInt[];
array_append (arrUnk, &vali, sizeof(double));
}
#endif
Gather parameters that must be passed to the non-linear system function.
UserDataNls data;
coord o = {x,y,z};
foreach_dimension()
data.c.x = o.x;
Solve the non-linear system of equations.
fsolve (EquationsGsl, arrUnk, &data);
Recover Nls solution.
{
double * unk = (double *)arrUnk->p;
//double * unk = (double *) array_shrink (arrUnk);
int count = 0;
// mInt field
for (int jj=0; jj<NLS; jj++) {
scalar mEvapi = mEvapList[LSI[jj]];
mEvapi[] = unk[count++];
}
// YLInt field
for (int jj=0; jj<NLS; jj++) {
scalar YLInti = YLIntList[jj];
YLInti[] = unk[count++];
}
// YGInt field
for (int jj=0; jj<NGS; jj++) {
scalar YGInti = YGIntList[jj];
YGInti[] = unk[count++];
}
#ifdef SOLVE_TEMPERATURE
// Temperature field
{
TInt[] = unk[count++];
}
#endif
}
array_free (arrUnk);
}
}
}
#ifdef SOLVE_TEMPERATURE
#ifndef RADIATION_INTERFACE
# define RADIATION_INTERFACE 0.
#endif
double divq_rad_int (double TInti, double Tbulk = 300., double alphacorr = 1.) {
//return alphacorr*5.669e-8*(pow(Tbulk, 4.) - pow(TInti, 4.));
return alphacorr*5.670373e-8*(pow(Tbulk, 4.) - pow(TInti, 4.));
}
void EqTemperature (const double * xdata, double * fdata, void * params) {
UserDataNls * data = (UserDataNls *)params;
foreach_point (data->c.x, data->c.y, data->c.z, serial) {
double TInti = xdata[0];
bool success = false;
double gtrgrad = ebmgrad (point, TG, fL, fG, fsL, fsG, true, TInti, &success);
double ltrgrad = ebmgrad (point, TL, fL, fG, fsL, fsG, false, TInti, &success);
#ifdef VARPROP
double yl[NLS], yg[NGS];
double xl[NLS], xg[NGS];
double MWl[NLS], MWg[NGS];
for (int jj=0; jj<NLS; jj++) {
scalar YL = YLList[jj];
yl[jj] = YL[];
MWl[jj] = inMW[LSI[jj]];
}
mass2molefrac (xl, yl, MWl, NLS);
for (int jj=0; jj<NGS; jj++) {
scalar YG = YGList[jj];
yg[jj] = YG[];
MWg[jj] = inMW[jj];
}
mass2molefrac (xg, yg, MWg, NGS);
#endif
double vapheat = 0.;
for (int jj=0; jj<NLS; jj++) {
scalar mEvap = mEvapList[LSI[jj]];
#ifdef VARPROP
scalar dhevjj = dhevList[jj];
vapheat -= mEvap[]*dhevjj[];
#else
vapheat -= mEvap[]*dhev;
#endif
}
fdata[0] = vapheat
- divq_rad_int (TInti, TG0, RADIATION_INTERFACE)
#ifdef VARPROP
+ lambda1v[]*ltrgrad
+ lambda2v[]*gtrgrad
#else
+ lambda1*ltrgrad
+ lambda2*gtrgrad
#endif
;
}
}
int EqTemperatureGsl (const gsl_vector * x, void * params, gsl_vector * f) {
double * xdata = x->data;
double * fdata = f->data;
EqTemperature (xdata, fdata, params);
return GSL_SUCCESS;
}
void ijc_CoupledTemperature ()
{
foreach() {
if (f[] > F_ERR && f[] < 1.-F_ERR) {
Array * arrUnk = array_new();
{
double vali = TInt[];
array_append (arrUnk, &vali, sizeof(double));
}
UserDataNls data;
coord o = {x,y,z};
foreach_dimension()
data.c.x = o.x;
#ifdef USE_GSL
fsolve (EqTemperatureGsl, arrUnk, &data);
#endif
{
double * unk = (double *)arrUnk->p;
TInt[] = unk[0];
//if (unk[0] > 0. && unk[0] < 5000.) // The solution is reasonable
// TInt[] = unk[0];
}
array_free (arrUnk);
}
}
}
void EqBoilingTemperature (const double * xdata, double * fdata, void * params) {
double Tb = xdata[0];
double * xc = (double *)params;
double sumKeq = 0.;
for (int jj=0; jj<NLS; jj++) {
#ifdef USE_ANTOINE
scalar YL = YLList[jj];
sumKeq += YL.antoine (Tb, Pref)*xc[jj];
#endif
#ifdef USE_ANTOINE_OPENSMOKE
sumKeq += opensmoke_antoine (Tb, Pref, jj)*xc[jj];
#endif
}
fdata[0] = sumKeq - 1.;
}
int EqBoilingTemperatureGsl (const gsl_vector * x, void * params, gsl_vector * f) {
double * xdata = x->data;
double * fdata = f->data;
EqBoilingTemperature (xdata, fdata, params);
return GSL_SUCCESS;
}
double boilingtemperature (double Tfg, double * xc)
{
Array * arrUnk = array_new();
array_append (arrUnk, &Tfg, sizeof(double));
#ifdef USE_GSL
fsolve (EqBoilingTemperatureGsl, arrUnk, xc);
#endif
double * unk = arrUnk->p;
double Tb = unk[0];
array_free (arrUnk);
return Tb;
}
#endif // SOLVE_TEMPERATURE