@@ -0,0 +1,27 @@ | |||||
This is the public repository for the code sensBVP. Its use is in | |||||
calculating sensitivity coefficients of ignition delay time to rate | |||||
coefficients. In sensBVP, this is carried out by transforming the | |||||
initial value problem to a boundary value problem, reducing the time to | |||||
calculate the sensitivity coefficients by at least an order of | |||||
magnitude. | |||||
In order to install sensBVP, modify the various paths in the Makefile. | |||||
Make sure that SUNDIALS (v3.1.1 or higher), Cantera (2.3 or higher), and | |||||
GSL are installed. Run make all, followed by make install in the source | |||||
directory. | |||||
After installing, the executable sensBVP can be executed as follows: | |||||
sensBVP -a <absolute tolerance> | |||||
-r <relative tolerance> | |||||
-f <BVP residue tolerance> | |||||
-T <initial temperature in K> | |||||
-P <initial pressure in atm> | |||||
-m <mechanism file (cti or xml)> | |||||
-c <mole fraction composition> | |||||
-t <integration time> | |||||
-s <enable sensitivity analysis> | |||||
Execute sensBVP -h for all available options. | |||||
Try the cases in the examples directory. |
@@ -0,0 +1 @@ | |||||
sensBVP -r 1e-06 -a 1e-12 -f 1e-07 -T 900.0 -P 10.0 -m ./mech-FFCM1.cti -c CH4:0.0499002,O2:0.199601,N2:0.750499 -t 1 -s |
@@ -0,0 +1 @@ | |||||
sensBrute -r 1e-06 -a 1e-12 -T 900.0 -P 10.0 -m ./mech-FFCM1.cti -c CH4:0.0499002,O2:0.199601,N2:0.750499 -t 1 -s |
@@ -0,0 +1,64 @@ | |||||
""" | |||||
Constant-pressure, adiabatic kinetics simulation with sensitivity analysis | |||||
""" | |||||
import sys | |||||
import time | |||||
import numpy as np | |||||
start = time.time() | |||||
import cantera as ct | |||||
gas = ct.Solution('./mech-FFCM1.cti') | |||||
temp = 900.0 | |||||
pres = 10.0*ct.one_atm | |||||
gas.TPX = temp, pres, 'CH4:0.0499002,O2:0.199601,N2:0.750499' | |||||
r = ct.IdealGasConstPressureReactor(gas, name='R1') | |||||
sim = ct.ReactorNet([r]) | |||||
# enable sensitivity with respect to all reactions | |||||
for i in range(0,gas.n_reactions): | |||||
r.add_sensitivity_reaction(i) | |||||
# set the tolerances for the solution and for the sensitivity coefficients | |||||
sim.rtol = 1.0e-6 | |||||
sim.atol = 1.0e-12 | |||||
sim.rtol_sensitivity = 1.0e-6 | |||||
sim.atol_sensitivity = 1.0e-12 | |||||
#states = ct.SolutionArray(gas, extra=['t','s2']) | |||||
ignitionStateFound=False | |||||
Told=temp | |||||
TIgn=1.115367e+03 #K | |||||
tEnd=1.0 #s | |||||
tauIgn=0.0 | |||||
nPts=1000 | |||||
dt=tEnd/(float(nPts)-1.0) | |||||
sens=np.zeros(gas.n_reactions) | |||||
out=open("ignitionSensitivities.dat","w") | |||||
for t in np.arange(0, tEnd, dt): | |||||
TOld=r.T | |||||
sim.advance(t) | |||||
TCurrent=r.T | |||||
for i in range(0,gas.n_reactions): | |||||
sens[i] = sim.sensitivity('temperature', i) | |||||
if(ignitionStateFound==False): | |||||
if(r.T>=TIgn): | |||||
print("Ignition state found!\n") | |||||
print("T=%15.6e K\n"%(TCurrent)) | |||||
print("tau=%15.6e s\n"%(t)) | |||||
ignitionStateFound=True | |||||
tauIgn=t | |||||
dTdtau=(TCurrent-TOld)/dt | |||||
for i in range(0,gas.n_reactions): | |||||
sens[i]=sens[i]*(-1.0e0/dTdtau)*(TCurrent/tauIgn) | |||||
out.write("%15d\t%15.6e\n"%(i,sens[i])) | |||||
break | |||||
out.close() | |||||
end = time.time() | |||||
print("Elapsed time: %15.6e s\n"%(end-start)) |
@@ -0,0 +1,61 @@ | |||||
compiler =g++ | |||||
CANTERA_DIR =/opt/scientific/cantera-2.4_gnu_blas | |||||
CVODE_DIR =/opt/scientific/sundials-3.1.1_gnu_blas | |||||
KINSOL_DIR =/opt/scientific/sundials-3.1.1_gnu_blas | |||||
BVPEXE =sensBVP | |||||
BRUTEEXE =sensBrute | |||||
DESTDIR =~/bin | |||||
CANTERA_INCLUDES=-I$(CANTERA_DIR)/include | |||||
CVODE_INCLUDES =-I$(CVODE_DIR)/include | |||||
KINSOL_INCLUDES =-I$(KINSOL_DIR)/include | |||||
CVODE_LIBS =-L$(CVODE_DIR)/lib -lsundials_nvecserial -lsundials_cvode | |||||
KINSOL_LIBS =-L$(KINSOL_DIR)/lib -lsundials_kinsol | |||||
CANTERA_LIBS =-L$(CANTERA_DIR)/lib -lcantera_shared | |||||
GSL_INCLUDES =-I/usr/include/gsl | |||||
GSL_LIBS =-L/usr/lib -lgsl -lgslcblas | |||||
RPATH =-Wl,-rpath=$(CVODE_DIR)/lib,-rpath=$(KINSOL_DIR)/lib | |||||
RM=rm -f | |||||
compiler?=g++ | |||||
ifeq ($(compiler),g++) | |||||
CPPFLAGS= -Wall -O3 | |||||
CPP=g++ | |||||
endif | |||||
ifeq ($(compiler),icpc) | |||||
export GXX_INCLUDE=/usr/lib/gcc/x86_64-pc-linux-gnu/7.4.1/include/c++ | |||||
CPPFLAGS= -Wall -O3 -gxx-name=/usr/bin/g++-7 -std=c++11 | |||||
CPP=icpc | |||||
endif | |||||
all: $(BVPEXE) $(BRUTEEXE) | |||||
sensBVP.o: sensBVP.cpp | |||||
$(CPP) $(CPPFLAGS) $(CANTERA_INCLUDES) $(CVODE_INCLUDES) \ | |||||
$(KINSOL_INCLUDES) $(GSL_INCLUDES) \ | |||||
-c sensBVP.cpp -o sensBVP.o | |||||
sensBrute.o: sensBrute.cpp | |||||
$(CPP) $(CPPFLAGS) $(CANTERA_INCLUDES) $(CVODE_INCLUDES) \ | |||||
$(GSL_INCLUDES) \ | |||||
-c sensBrute.cpp -o sensBrute.o | |||||
$(BVPEXE): sensBVP.o | |||||
$(CPP) $(CPPFLAGS) \ | |||||
sensBVP.o -o $(BVPEXE) $(RPATH) $(CVODE_LIBS) \ | |||||
$(KINSOL_LIBS) $(CANTERA_LIBS) $(GSL_LIBS) | |||||
$(BRUTEEXE): sensBrute.o | |||||
$(CPP) $(CPPFLAGS) \ | |||||
sensBrute.o -o $(BRUTEEXE) $(RPATH) $(CVODE_LIBS) \ | |||||
$(CANTERA_LIBS) $(GSL_LIBS) | |||||
.PHONY: install | |||||
install: | |||||
cp $(BVPEXE) $(BRUTEEXE) $(DESTDIR) | |||||
clean: | |||||
rm -f $(BVPEXE) $(BRUTEEXE) *.o *.d | |||||
@@ -1135,30 +1135,12 @@ static int residueKS(N_Vector yp, N_Vector res, void *user_data) | |||||
static void lookupDpdt(UserData data, realtype t, realtype *P, realtype *dPdt) | static void lookupDpdt(UserData data, realtype t, realtype *P, realtype *dPdt) | ||||
{ | { | ||||
realtype *tData, *PData, *dPdtData; | |||||
tData = N_VGetArrayPointer_Serial(data->tArray); | |||||
PData = N_VGetArrayPointer_Serial(data->PArray); | |||||
realtype *dPdtData; | |||||
dPdtData = N_VGetArrayPointer_Serial(data->dPdtArray); | dPdtData = N_VGetArrayPointer_Serial(data->dPdtArray); | ||||
int jguess=data->jguess; | |||||
int k=0; | |||||
int safel=0; | |||||
int nOrder=4; | |||||
realtype dy; | |||||
int npts=data->tArraySize; | int npts=data->tArraySize; | ||||
if(t<=data->t1){ | if(t<=data->t1){ | ||||
//k=hunt(t, tData, npts, jguess); | |||||
////printf("Desired value at %d: %15.6e\t%15.6e\t%15.6e\n",k,t,P(k),dPdt(k)); | |||||
//safel=IMIN(IMAX(k-(nOrder)/2,0),data->tArraySize+1-nOrder-1); | |||||
//data->jguess=safel; | |||||
////printf("safel %d: \n",safel); | |||||
////printf("safel val %15.6e: \n",*(tData+safel)); | |||||
//polint(tData+safel-1, PData+safel-1, nOrder+1, t, P, &dy); | |||||
////printf("P error %15.6e: \n",dy); | |||||
//polint(tData+safel-1, dPdtData+safel-1, nOrder+1, t, dPdt, &dy); | |||||
////printf("dPdt error %15.6e: \n",dy); | |||||
//// | |||||
*P=gsl_spline_eval(data->spline,t,data->acc); | *P=gsl_spline_eval(data->spline,t,data->acc); | ||||
*dPdt=gsl_spline_eval(data->splinedot,t,data->accdot); | *dPdt=gsl_spline_eval(data->splinedot,t,data->accdot); | ||||