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.
= 0;
count
for (int jj=0; jj<NLS; jj++)
[jj] = xdata[count++];
mEvapi
for (int jj=0; jj<NLS; jj++)
[jj] = xdata[count++];
YLInti
for (int jj=0; jj<NGS; jj++)
[jj] = xdata[count++];
YGInti
#ifdef SOLVE_TEMPERATURE
= xdata[count++];
TInti #endif
Convert mass-to-mole fractions.
{
double inMWG[NGS];
for (int jj=0; jj<NGS; jj++)
[jj] = inMW[jj];
inMWG
double inMWL[NLS];
for (int jj=0; jj<NLS; jj++)
[jj] = inMW[LSI[jj]];
inMWL
(XLInti, YLInti, inMWL, NLS);
mass2molefrac (XGInti, YGInti, inMWG, NGS);
mass2molefrac }
Set to zero gas-only species vaporization mass flow-rates.
for (int jj=0; jj<NLS; jj++)
[LSI[jj]] = mEvapi[jj];
mEvapToti
for (int jj=0; jj<NGOS; jj++)
[GOSI[jj]] = 0.; mEvapToti
Compute diffusive fluxes.
for (int jj=0; jj<NGS; jj++) {
double rho2vh = rho2;
double Dmix2vh = inDmix2[jj];
#ifdef VARPROP
= rho2v[];
rho2vh scalar Dmix2 = Dmix2List[jj];
= Dmix2[];
Dmix2vh //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);
[jj] = -rho2vh*Dmix2vh*gtrgrad;
jG}
for (int jj=0; jj<NLS; jj++) {
double rho1vh = rho1;
double Dmix1vh = inDmix1[jj];
#ifdef VARPROP
= rho1v[];
rho1vh scalar Dmix1 = Dmix1List[jj];
= Dmix1[];
Dmix1vh //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);
[jj] = rho1vh*Dmix1vh*ltrgrad;
jL}
Compute total diffusive fluxes for Fick corrected approach.
double jLtot = 0., jGtot = 0.;
#ifdef FICK_CORRECTED
for (int jj=0; jj<NLS; jj++)
+= jL[jj];
jLtot
for (int jj=0; jj<NGS; jj++)
+= jG[jj];
jGtot #endif
#ifdef SOLVE_TEMPERATURE
= ebmgrad (point, TG, fL, fG, fsL, fsG, true, TInti, &success);
gradTGn = ebmgrad (point, TL, fL, fG, fsL, fsG, false, TInti, &success);
gradTLn #endif
Compute sum of vaporization mass flow-rate.
= 0.;
mEvapSum for (int jj=0; jj<NLS; jj++) {
+= mEvapi[jj];
mEvapSum }
= 0; count
[NEW] Mass balance in gas phase for evaporating species.
for (int jj=0; jj<NLS; jj++) {
[count++] = mEvapi[jj]
fdata- 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++) {
[count++] = mEvapi[jj]
fdata- mEvapSum*YLInti[jj]
- jL[jj]
+ jLtot*YLInti[jj];
;
}
}
else {
[count++] = YLInti[0] - 1.;
fdata}
//
//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++)
[jj] = inKeq[jj];
Keq
#ifdef USE_CLAPEYRON
for (int jj=0; jj<NLS; jj++) {
[jj] = min (clapeyron ( min (TInti, Tboil[jj]-1), Tboil[jj], dhev, inMW[LSI[jj]]), 0.98);
Keq}
#endif
#ifdef USE_ANTOINE
for (int jj=0; jj<NLS; jj++) {
scalar YL = YLList[jj];
[jj] = min (YL.antoine (TInti, Pref), 0.98);
Keq}
#endif
#ifdef USE_ANTOINE_OPENSMOKE
for (int jj=0; jj<NLS; jj++) {
[jj] = min (opensmoke_antoine (TInti, Pref, jj), 0.98);
Keq}
#endif
for (int jj=0; jj<NLS; jj++) {
[count++] = XLInti[jj]*Keq[jj] - XGInti[LSI[jj]];
fdata}
[NEW] Mass balance in gas phase for gas-only species.
for (int jj=0; jj<NGOS; jj++) {
[count++] = mEvapToti[GOSI[jj]]
fdata- 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];
= dhevjj[];
dhevvh #endif
-= dhevvh*mEvapi[jj];
vapheat }
[count++] = vapheat
fdata# 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.
* arrUnk = array_new();
Array
// mInt field
for (int jj=0; jj<NLS; jj++) {
scalar mEvapi = mEvapList[LSI[jj]];
double vali = mEvapi[];
(arrUnk, &vali, sizeof(double));
array_append }
// 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[];
(arrUnk, &vali, sizeof(double));
array_append }
// 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[];
(arrUnk, &vali, sizeof(double));
array_append }
#ifdef SOLVE_TEMPERATURE
// Temperature field
{
double vali = TInt[];
(arrUnk, &vali, sizeof(double));
array_append }
#endif
Gather parameters that must be passed to the non-linear system function.
UserDataNls data;
= {x,y,z};
coord o foreach_dimension()
.c.x = o.x; data
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]];
[] = unk[count++];
mEvapi}
// YLInt field
for (int jj=0; jj<NLS; jj++) {
scalar YLInti = YLIntList[jj];
[] = unk[count++];
YLInti}
// YGInt field
for (int jj=0; jj<NGS; jj++) {
scalar YGInti = YGIntList[jj];
[] = unk[count++];
YGInti}
#ifdef SOLVE_TEMPERATURE
// Temperature field
{
[] = unk[count++];
TInt}
#endif
}
(arrUnk);
array_free }
}
}
#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];
[jj] = YL[];
yl[jj] = inMW[LSI[jj]];
MWl}
(xl, yl, MWl, NLS);
mass2molefrac
for (int jj=0; jj<NGS; jj++) {
scalar YG = YGList[jj];
[jj] = YG[];
yg[jj] = inMW[jj];
MWg}
(xg, yg, MWg, NGS);
mass2molefrac #endif
double vapheat = 0.;
for (int jj=0; jj<NLS; jj++) {
scalar mEvap = mEvapList[LSI[jj]];
#ifdef VARPROP
scalar dhevjj = dhevList[jj];
-= mEvap[]*dhevjj[];
vapheat #else
-= mEvap[]*dhev;
vapheat #endif
}
[0] = vapheat
fdata- 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) {
* arrUnk = array_new();
Array {
double vali = TInt[];
(arrUnk, &vali, sizeof(double));
array_append }
UserDataNls data;
= {x,y,z};
coord o foreach_dimension()
.c.x = o.x;
data
#ifdef USE_GSL
fsolve (EqTemperatureGsl, arrUnk, &data);
#endif
{
double * unk = (double *)arrUnk->p;
[] = unk[0];
TInt//if (unk[0] > 0. && unk[0] < 5000.) // The solution is reasonable
// TInt[] = unk[0];
}
(arrUnk);
array_free }
}
}
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];
+= YL.antoine (Tb, Pref)*xc[jj];
sumKeq #endif
#ifdef USE_ANTOINE_OPENSMOKE
+= opensmoke_antoine (Tb, Pref, jj)*xc[jj];
sumKeq #endif
}
[0] = sumKeq - 1.;
fdata}
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)
{
* arrUnk = array_new();
Array (arrUnk, &Tfg, sizeof(double));
array_append #ifdef USE_GSL
fsolve (EqBoilingTemperatureGsl, arrUnk, xc);
#endif
double * unk = arrUnk->p;
double Tb = unk[0];
(arrUnk);
array_free return Tb;
}
#endif // SOLVE_TEMPERATURE