cantera/Cantera/cxx/demos/flamespeed/flamespeed.cpp
2012-01-23 03:35:46 +00:00

251 lines
7.6 KiB
C++

#include <cantera/Cantera.h>
#include <cantera/onedim.h>
#include <cantera/IdealGasMix.h>
#include <cantera/equilibrium.h>
#include <cantera/transport.h>
using namespace Cantera;
int flamespeed(int np, void* p) {
try {
int i;
IdealGasMix gas("gri30.cti","gri30_mix");
doublereal temp = 300.0; // K
doublereal pressure = 1.0*OneAtm; //atm
doublereal uin=0.3; //m/sec
gas.setState_TPX(temp, pressure, "CH4:1.0, O2:2.0, N2:7.52");
int nsp = gas.nSpecies();
vector_fp x;
x.resize(nsp);
double phi = 0.0;
if (np > 0) phi = *(double*)(p);
if (phi == 0.0) {
cout << "Enter phi: ";
cin >> phi;
}
doublereal C_atoms=1.0;
doublereal H_atoms=4.0;
doublereal ax=C_atoms+H_atoms/4.0;
doublereal fa_stoic=1.0/(4.76*ax);
for(int k=0;k<nsp;k++){
if(k==gas.speciesIndex("CH4")){ x[k]=1.0; }
else if(k==gas.speciesIndex("O2")){ x[k]=0.21/phi/fa_stoic; }
else if(k==gas.speciesIndex("N2")){ x[k]=0.79/phi/fa_stoic; }
else{ x[k]=0.0; }
}
gas.setState_TPX(temp,pressure,DATA_PTR(x));
doublereal rho_in=gas.density();
double *yin=new double[nsp];
gas.getMassFractions(yin);
try {
equilibrate(gas,"HP");
}
catch (CanteraError) {
showErrors(cout);
}
double *yout=new double[nsp];
gas.getMassFractions(yout);
doublereal rho_out = gas.density();
doublereal Tad=gas.temperature();
cout << phi<<' '<<Tad<<endl;
//double Tin=temp;
//double Tout=Tad;
//double breakpt=0.2;
//============= build each domain ========================
//-------- step 1: create the flow -------------
//AxiStagnFlow flow(&gas);
FreeFlame flow(&gas);
// create an initial grid
int nz=5;
doublereal lz=0.02;
doublereal *z=new double[nz+1];
doublereal dz=lz/((doublereal)(nz-1));
for(int iz=0;iz<nz;iz++){
z[iz]=((doublereal)iz)*dz;
}
//add one node onto end of domain to help with zero gradient at outlet
z[nz]=lz*1.05;
nz++;
flow.setupGrid(nz, z);
// specify the objects to use to compute kinetic rates and
// transport properties
Transport* trmix = newTransportMgr("Mix", &gas);
Transport* trmulti = newTransportMgr("Multi", &gas);
flow.setTransport(*trmix);
flow.setKinetics(gas);
flow.setPressure(pressure);
//------- step 2: create the inlet -----------------------
Inlet1D inlet;
inlet.setMoleFractions(DATA_PTR(x));
doublereal mdot=uin*rho_in;
inlet.setMdot(mdot);
inlet.setTemperature(temp);
//------- step 3: create the outlet ---------------------
Outlet1D outlet;
//=================== create the container and insert the domains =====
vector<Domain1D*> domains;
domains.push_back(&inlet);
domains.push_back(&flow);
domains.push_back(&outlet);
// OneDim flamesim(domains);
Sim1D flame(domains);
//----------- Supply initial guess----------------------
vector_fp locs;
vector_fp value;
locs.resize(3);
value.resize(3);
//ramp values from inlet to adiabatic flame conditions
// over 70% of domain and then level off at equilibrium
double z1=0.7;
double uout;
uout=inlet.mdot()/rho_out;
uin=inlet.mdot()/rho_in;
locs[0]=0.0; locs[1]=z1; locs[2]=1.0;
value[0]=uin; value[1]=uout; value[2]=uout;
flame.setInitialGuess("u",locs,value);
value[0]=temp; value[1]=Tad; value[2]=Tad;
flame.setInitialGuess("T",locs,value);
for(i=0;i<nsp;i++){
value[0]=yin[i]; value[1]=yout[i]; value[2]=yout[i];
flame.setInitialGuess(gas.speciesName(i),locs,value);
}
inlet.setMoleFractions(DATA_PTR(x));
inlet.setMdot(mdot);
inlet.setTemperature(temp);
flame.showSolution();
int flowdomain=1;
double ratio=10.0;
double slope=0.2;
double curve=0.02;
double prune=-0.00005;
flame.setRefineCriteria(flowdomain,ratio,slope,curve,prune);
int loglevel=1;
bool refine_grid = true;
/* Solve species*/
//flow.fixTemperature();
//refine_grid=false;
//flame.solve(loglevel,refine_grid);
/* Solve freely propagating flame*/
/* Linearally interpolate to find location where this
temperature would exist. The temperature at this
location will then be fixed for remainder of
calculation.*/
flow.fixTemperature();
refine_grid=false;
flame.setFixedTemperature(900.0);
// flame.setAdiabaticFlame();
flame.solve(loglevel,refine_grid);
refine_grid = true;
flow.solveEnergyEqn();
flame.solve(loglevel,refine_grid);
double flameSpeed_mix = flame.value(flowdomain,flow.componentIndex("u"),0);
cout << "Flame speed with mixture-averaged transport: " <<
flame.value(flowdomain,flow.componentIndex("u"),0) << " m/s" << endl;
// now switch to multicomponent transport
flow.setTransport(*trmulti);
flame.solve(loglevel, refine_grid);
double flameSpeed_multi = flame.value(flowdomain,flow.componentIndex("u"),0);
cout << "Flame speed with multicomponent transport: " <<
flame.value(flowdomain,flow.componentIndex("u"),0) << " m/s" << endl;
// now enable Soret diffusion
flow.enableSoret(true);
flame.solve(loglevel, refine_grid);
double flameSpeed_full = flame.value(flowdomain,flow.componentIndex("u"),0);
cout << "Flame speed with multicomponent transport + Soret: " <<
flame.value(flowdomain,flow.componentIndex("u"),0) << " m/s" << endl;
int np=flow.nPoints();
vector<doublereal> zvec,Tvec,COvec,CO2vec,Uvec;
printf("\n%9s\t%8s\t%5s\t%7s\n","z (m)", "T (K)", "U (m/s)", "Y(CO)");
for(int n=0;n<np;n++){
Tvec.push_back(flame.value(flowdomain,flow.componentIndex("T"),n));
COvec.push_back(flame.value(flowdomain,flow.componentIndex("CO"),n));
CO2vec.push_back(flame.value(flowdomain,flow.componentIndex("CO2"),n));
Uvec.push_back(flame.value(flowdomain,flow.componentIndex("u"),n));
zvec.push_back(flow.grid(n));
printf("%9.6f\t%8.3f\t%5.3f\t%7.5f\n",flow.grid(n),Tvec[n],Uvec[n],COvec[n]);
}
cout << endl<<"Adiabatic flame temperature from equilibrium is: "<<Tad<<endl;
cout << "Flame speed for phi="<<phi<<" is "<<Uvec[0]<<" m/s."<<endl;
string reportFile = "flamespeed.csv";
FILE * FP = fopen(reportFile.c_str(), "w");
if (!FP) {
printf("Failure to open file\n");
exit(-1);
}
fprintf(FP," Flame speed (mixture-averaged ) = %11.3e m/s\n", flameSpeed_mix);
fprintf(FP," Flame speed (multicomponent ) = %11.3e m/s\n", flameSpeed_multi);
fprintf(FP," Flame speed (multicomponent + Soret) = %11.3e m/s\n", flameSpeed_full);
fprintf(FP," Grid, Temperature, Uvec, CO, CO2\n");
for (int n = 0; n < np; n++) {
fprintf(FP," %11.3e, %11.3e, %11.3e, %11.3e, %11.3e\n",
flow.grid(n), Tvec[n], Uvec[n], COvec[n], CO2vec[n]);
}
fclose(FP);
return 0;
}
catch (CanteraError) {
showErrors(cerr);
cerr << "program terminating." << endl;
return -1;
}
}
#ifndef CXX_DEMO
int main() {
return flamespeed(0, 0);
}
#endif