Browse Source

first

master
vyaas 4 years ago
commit
48cca4770f
17 changed files with 3119 additions and 0 deletions
  1. +91
    -0
      Makefile
  2. +409
    -0
      UserData.cpp
  3. +170
    -0
      UserData.h
  4. +244
    -0
      gridRoutines.cpp
  5. +82
    -0
      gridRoutines.h
  6. +50
    -0
      input.dat
  7. +63
    -0
      macros.h
  8. +338
    -0
      main.cpp
  9. +20
    -0
      parse.cpp
  10. +31
    -0
      parse.h
  11. +76
    -0
      parse.hpp
  12. +1303
    -0
      residue.cpp
  13. +90
    -0
      residue.h
  14. +90
    -0
      solution.cpp
  15. +15
    -0
      solution.h
  16. +2
    -0
      timing.h
  17. +45
    -0
      timing.hpp

+ 91
- 0
Makefile View File

@@ -0,0 +1,91 @@
#compiler =icpc
#CANTERA_DIR =/opt/scientific/cantera-2.3_intel_mkl
#IDA_DIR =/opt/scientific/sundials-3.1.1_intel_mkl
#EXE =lagrangianCombustion2
#DESTDIR =~/bin

compiler =g++
CANTERA_DIR =/opt/scientific/cantera-2.4_gnu_blas
IDA_DIR =/opt/scientific/sundials-3.1.1_gnu_lapack
EXE =lagrangianCombustion
DESTDIR =~/bin

CANTERA_INCLUDES=-I$(CANTERA_DIR)/include
GSL_INCLUDES =-I/usr/include/gsl
GSL_LIBS =-L/usr/lib -lgsl -lgslcblas
IDA_INCLUDES =-I$(IDA_DIR)/include
SUN_INCLUDES =-I$(IDA_DIR)/include
IDA_LIBS =-L$(IDA_DIR)/lib -lsundials_nvecopenmp \
-lsundials_ida -lsundials_sunlinsollapackband
CANTERA_LIBS =-L$(CANTERA_DIR)/lib -lcantera_shared
RPATH =-Wl,-rpath=$(IDA_DIR)/lib,-rpath=$(CANTERA_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

OBJS = parse.o UserData.o gridRoutines.o residue.o solution.o main.o

all: $(EXE)

# pull in dependency info for *existing* .o files
-include $(OBJS:.o=.d)

parse.o: parse.cpp parse.h parse.hpp
$(CPP) $(CPPFLAGS) -c parse.cpp -o parse.o
$(CPP) -MM parse.cpp > parse.d

solution.o: solution.cpp solution.h
$(CPP) $(CPPFLAGS) $(CANTERA_INCLUDES) $(IDA_INCLUDES) \
-c solution.cpp -o solution.o
$(CPP) -MM $(CANTERA_INCLUDES) $(IDA_INCLUDES) \
solution.cpp > solution.d

residue.o: residue.cpp residue.h UserData.h gridRoutines.h
$(CPP) $(CPPFLAGS) $(CANTERA_INCLUDES) \
$(IDA_INCLUDES) $(GSL_INCLUDES) -c residue.cpp \
-o residue.o -fopenmp
$(CPP) -MM $(CANTERA_INCLUDES) \
$(IDA_INCLUDES) $(GSL_INCLUDES) \
residue.cpp > residue.d

gridRoutines.o: gridRoutines.cpp gridRoutines.h parse.h
$(CPP) $(CPPFLAGS) -c gridRoutines.cpp -o gridRoutines.o
$(CPP) -MM gridRoutines.cpp > gridRoutines.d

UserData.o: UserData.cpp UserData.h gridRoutines.h parse.h
$(CPP) $(CPPFLAGS) $(CANTERA_INCLUDES) \
-c UserData.cpp -o UserData.o
$(CPP) -MM $(CANTERA_INCLUDES) \
UserData.cpp > UserData.d

main.o: main.cpp UserData.h solution.h residue.h macros.h
$(CPP) $(CPPFLAGS) $(CANTERA_INCLUDES) $(IDA_INCLUDES) \
-c main.cpp -o main.o
$(CPP) -MM $(CANTERA_INCLUDES) $(IDA_INCLUDES) \
main.cpp > main.d

$(EXE): $(OBJS)
$(CPP) $(CPPFLAGS) $(IDA_INCLUDES) \
$(CANTERA_INCLUDES) $(GSL_INCLUDES) $(RPATH) \
$(OBJS) -o $(EXE) -fopenmp $(IDA_LIBS) \
$(CANTERA_LIBS) $(GSL_LIBS)

.PHONY: install
install:
cp $(EXE) $(DESTDIR)/$(EXE)

.PHONY: clean
clean:
rm -f $(EXE) $(OBJS) *.d


+ 409
- 0
UserData.cpp View File

@@ -0,0 +1,409 @@
#include "UserData.h"
#include "parse.h"

void freeUserData(UserData data){
if(data!=NULL){
if(data->trmix!=NULL){
delete data->trmix;
printf("Transport Deleted!\n");

}
if(data->gas!=NULL){
delete data->gas;
printf("Gas Deleted!\n");

}
if(data->adaptiveGrid){
if(data->grid->xOld!=NULL){
delete[] data->grid->xOld;
printf("old grid array Deleted!\n");
}
if(data->grid->x!=NULL){
delete[] data->grid->x;
printf("current grid array Deleted!\n");
}
if(data->grid!=NULL){
free(data->grid);
printf("grid object Freed!\n");
}
}
else{
if(data->uniformGrid!=NULL){
delete[] data->uniformGrid;
printf("uniformGrid deleted!\n");
}
}
if(data->innerMassFractions!=NULL){
delete[] data->innerMassFractions;
printf("innerMassFractions array Deleted!\n");
}
if(data->output!=NULL){
fclose(data->output);
printf("Output File Cleared from Memory!\n");
}
if(data->gridOutput!=NULL){
fclose(data->gridOutput);
printf("Grid Output File Cleared from Memory!\n");
}
//if(data->ratesOutput!=NULL){
// fclose(data->ratesOutput);
// printf("Rates Output File Cleared from Memory!\n");
//}
if(data->globalOutput!=NULL){
fclose(data->globalOutput);
printf("Global Output File Cleared from Memory!\n");
}

}
free(data); /* Free the user data */
printf("\n\n");
}

UserData allocateUserData(FILE *input){

UserData data;
data = (UserData) malloc(sizeof *data);

if(!data){
printf("Allocation Failed!\n");
return(NULL);
}
setSaneDefaults(data);

int ier;

ier=parseNumber<size_t>(input, "basePts" , MAXBUFLEN, &data->npts);
if(ier==-1 || data->npts<=0){
printf("Enter non-zero basePts!\n");
return(NULL);
}

ier=parseNumber<double>(input, "domainLength", MAXBUFLEN, &data->domainLength);
if(ier==-1 || data->domainLength<=0.0e0){
printf("domainLength error!\n");
return(NULL);
}

ier=parseNumber<int>(input, "constantPressure" , MAXBUFLEN, &data->constantPressure);
if(ier==-1 || (data->constantPressure!=0 && data->constantPressure!=1)){
printf("constantPressure error!\n");
return(NULL);
}

ier=parseNumber<int>(input, "problemType" , MAXBUFLEN, &data->problemType);
if(ier==-1 || (data->problemType!=0
&& data->problemType!=1
&& data->problemType!=2
&& data->problemType!=3)){
printf("include valid problemType!\n");
printf("0: premixed combustion with NO equilibrated ignition kernel\n");
printf("1: premixed combustion WITH equilibrated ignition kernel\n");
printf("2: arbitrary initial conditions\n");
printf("3: Restart\n");
return(NULL);
}

ier=parseNumber<double>(input, "dPdt" , MAXBUFLEN, &data->dPdt);

ier=parseNumber<int> (input, "reflectProblem" , MAXBUFLEN, &data->reflectProblem);
if(data->reflectProblem!=0 && data->reflectProblem!=1){
printf("Invalid entry for reflectProblem! Can be only 1 or 0.\n");
return(NULL);
}
ier=parseNumber<double>(input, "mdot" , MAXBUFLEN, &data->mdot);
ier=parseNumber<double>(input, "initialTemperature", MAXBUFLEN,
&data->initialTemperature);
if(ier==-1 || data->initialTemperature<=0.0e0){
printf("Enter positive initialTemperature in K!\n");
return(NULL);
}


ier=parseNumber<double>(input, "initialPressure", MAXBUFLEN,
&data->initialPressure);
if(ier==-1 || data->initialTemperature<=0.0e0){
printf("Enter positive initialPressure in atm!\n");
return(NULL);
}

ier=parseNumber<int> (input, "metric" , MAXBUFLEN, &data->metric);
if(data->metric!=0 && data->metric!=1 && data->metric!=2){
printf("Invalid entry for metric!\n");
printf("0: Cartesian\n");
printf("1: Cylindrical\n");
printf("2: Spherical\n");
return(NULL);
}

ier=parseNumber<double>(input, "QDot", MAXBUFLEN, &data->maxQDot);
if(ier==-1 && data->problemType==0){
printf("Need to specify QDot for problemType 0!\n");
return(NULL);
}

ier=parseNumber<double>(input, "kernelSize", MAXBUFLEN, &data->kernelSize);
if(ier==-1 && data->problemType==0){
printf("Need to specify kernelSize for problemType 0!\n");
return(NULL);
}

ier=parseNumber<double>(input, "ignTime", MAXBUFLEN, &data->ignTime);
if(ier==-1 && data->problemType==0){
printf("Need to specify ignTime for problemType 0!\n");
return(NULL);
}

ier=parseNumber<double>(input, "mixingWidth", MAXBUFLEN,
&data->mixingWidth);
if(ier==-1){
printf("Need to specify mixingWidth!\n");
return(NULL);
}
ier=parseNumber<double>(input, "shift", MAXBUFLEN, &data->shift);

ier=parseNumber<double>(input, "firstRadius", MAXBUFLEN, &data->firstRadius);
ier=parseNumber<double>(input, "wallTemperature", MAXBUFLEN, &data->wallTemperature);

ier=parseNumber<int> (input, "dirichletInner" , MAXBUFLEN,
&data->dirichletInner);
if(data->dirichletInner!=0 && data->dirichletInner!=1){
printf("dirichletInner can either be 0 or 1!\n");
return(NULL);
}

ier=parseNumber<int> (input, "dirichletOuter" , MAXBUFLEN,
&data->dirichletOuter);
if(data->dirichletOuter!=0 && data->dirichletOuter!=1){
printf("dirichletOuter can either be 0 or 1!\n");
return(NULL);
}

ier=parseNumber<int> (input, "adaptiveGrid" , MAXBUFLEN,
&data->adaptiveGrid);
if(ier==-1 || (data->adaptiveGrid!=0 && data->adaptiveGrid!=1)){
printf("specify adaptiveGrid as 0 or 1!\n");
return(NULL);
}

ier=parseNumber<int> (input, "moveGrid" , MAXBUFLEN,
&data->moveGrid);
if(ier==-1 || (data->moveGrid!=0 && data->moveGrid!=1)){
printf("specify moveGrid as 0 or 1!\n");
return(NULL);
}

ier=parseNumber<double> (input, "isotherm" , MAXBUFLEN,
&data->isotherm);
if(ier==-1){
printf("specify temperature of isotherm!\n");
return(NULL);
}

ier=parseNumber<double>(input, "gridOffset", MAXBUFLEN, &data->gridOffset);

ier=parseNumber<int> (input, "nSaves" , MAXBUFLEN, &data->nSaves);
if(data->nSaves<0 ){
printf("nSaves must be greater than 0!\n");
return(NULL);
}
ier=parseNumber<int> (input, "writeRates" , MAXBUFLEN,
&data->writeRates);
if(data->writeRates!=0 && data->writeRates!=1){
printf("writeRates must either be 0 or 1!\n");
return(NULL);
}

ier=parseNumber<int> (input, "writeEveryRegrid", MAXBUFLEN,
&data->writeEveryRegrid);
if(data->writeEveryRegrid!=0 && data->writeEveryRegrid!=1){
printf("writeEveryRegrid must either be 0 or 1!\n");
return(NULL);
}

ier=parseNumber<double> (input, "writeDeltaT", MAXBUFLEN,
&data->writeDeltaT);

ier=parseNumber<int> (input, "setConstraints" , MAXBUFLEN,
&data->setConstraints);
if(data->setConstraints!=0 && data->setConstraints!=1){
printf("setConstraints must either be 0 or 1!\n");
return(NULL);
}

ier=parseNumber<int> (input, "suppressAlg" , MAXBUFLEN,
&data->suppressAlg);
if(data->setConstraints!=0 && data->suppressAlg!=1){
printf("suppressAlg must either be 0 or 1!\n");
return(NULL);
}

ier=parseNumber<int> (input, "dryRun" , MAXBUFLEN,
&data->dryRun);
if(data->dryRun!=0 && data->dryRun!=1){
printf("dryRun must either be 0 or 1!\n");
return(NULL);
}

ier=parseNumber<double> (input, "finalTime" , MAXBUFLEN,
&data->finalTime);

ier=parseNumber<double> (input, "relativeTolerance" , MAXBUFLEN,
&data->relativeTolerance);
ier=parseNumber<double> (input, "radiusTolerance" , MAXBUFLEN,
&data->radiusTolerance);
ier=parseNumber<double> (input, "temperatureTolerance", MAXBUFLEN,
&data->temperatureTolerance);
ier=parseNumber<double> (input, "pressureTolerance", MAXBUFLEN,
&data->pressureTolerance);
ier=parseNumber<double> (input, "massFractionTolerance", MAXBUFLEN,
&data->massFractionTolerance);
ier=parseNumber<double> (input, "bathGasTolerance", MAXBUFLEN,
&data->bathGasTolerance);

char chem[MAXBUFLEN],mix[MAXBUFLEN],tran[MAXBUFLEN];

ier=parseNumber<char>(input, "chemistryFile" , MAXBUFLEN, chem);
if(ier==-1){
printf("Enter chemistryFile!\n");
return(NULL);
}else{
try{
data->gas = new Cantera::IdealGasMix(chem);
data->nsp=data->gas->nSpecies(); //assign no: of species

} catch (Cantera::CanteraError& err) {
printf("Error:\n");
printf("%s\n",err.what());
return(NULL);
}
}

ier=parseNumber<char>(input, "transportModel", MAXBUFLEN, tran);
if(ier==-1){
printf("Enter transportModel!\n");
return(NULL);
}else{
try{
data->trmix = Cantera::newTransportMgr(tran, data->gas);
}catch (Cantera::CanteraError& err) {
printf("Error:\n");
printf("%s\n",err.what());
return(NULL);
}
}

ier=parseNumber<char>(input, "mixtureComposition", MAXBUFLEN, mix);
if(ier==-1){
printf("Enter mixtureComposition!\n");
return(NULL);
}else{
if(data->gas!=NULL){
try{
data->gas->setState_TPX(data->initialTemperature,
data->initialPressure*Cantera::OneAtm,
mix);
}catch (Cantera::CanteraError& err) {
printf("Error:\n");
printf("%s\n",err.what());
return(NULL);
}
}
}

ier=parseNumber<int> (input, "nThreads" , MAXBUFLEN, &data->nThreads);
if(data->nThreads<0 ){
printf("nThreads must be greater than 0!\n");
return(NULL);
}

data->nr=0;
//data->np=data->nr+1;
data->nt=data->nr+1;
data->ny=data->nt+1;
data->np=data->ny+data->nsp;
data->nvar=data->nsp+3; //assign no: of variables (R,T,P,nsp species)

if(!data->adaptiveGrid){
data->uniformGrid = new double [data->npts];
data->neq=data->nvar*data->npts;
}
else{
data->grid=(UserGrid) malloc(sizeof *data->grid);
ier=getGridSettings(input,data->grid);
if(ier==-1)return(NULL);

ier=initializeGrid(data->grid);
if(ier==-1)return(NULL);

ier=reGrid(data->grid, data->grid->position);
if(ier==-1)return(NULL);

data->npts=data->grid->nPts;
data->neq=data->nvar*data->npts;
}

data->output=fopen("output.dat","w");
data->globalOutput=fopen("globalOutput.dat","w");
data->gridOutput=fopen("grid.dat","w");
//data->ratesOutput=fopen("rates.dat","w");
data->innerMassFractions = new double [data->nsp];

return(data);
}

void setSaneDefaults(UserData data){
data->domainLength=1.0e-02;
data->constantPressure=1;
data->problemType=1;
data->dPdt=0.0e0;
data->reflectProblem=0;
data->mdot=0.0;
data->initialTemperature=300.0;
data->initialPressure=1.0;
data->metric=0;
data->ignTime=1e-09;
data->maxQDot=0.0e0;
data->maxTemperature=300.0e0;
data->mixingWidth=1e-04;
data->shift=3.0e-03;
data->firstRadius=1e-04;
data->wallTemperature=298.0e0;
data->dirichletInner=0;
data->dirichletOuter=0;
data->adaptiveGrid=0;
data->moveGrid=0;
data->gridOffset=0.0e0;
data->isotherm=1000.0;
data->nSaves=30;
data->writeRates=0;
data->writeEveryRegrid=0;
data->writeDeltaT=1e-04;
data->relativeTolerance=1e-06;
data->radiusTolerance=1e-08;
data->temperatureTolerance=1e-06;
data->pressureTolerance=1e-06;
data->massFractionTolerance=1e-09;
data->bathGasTolerance=1e-06;
data->finalTime=1e-02;
data->tNow=0.0e0;
data->setConstraints=0;
data->suppressAlg=1;
data->regrid=0;
data->gridDirection=1;
data->dryRun=0;
data->nThreads=1;

data->flamePosition[0]=0.0e0;
data->flamePosition[1]=0.0e0;
data->flameTime[0]=0.0e0;
data->flameTime[1]=0.0e0;
data->nTimeSteps=0;
}


+ 170
- 0
UserData.h View File

@@ -0,0 +1,170 @@
#ifndef CANTERA_DEF
#define CANTERA_DEF
#include <cantera/IdealGasMix.h>
#include <cantera/transport.h>
#endif

#include "gridRoutines.h"

#ifndef USER_DEF
#define USER_DEF
typedef struct UserDataTag{
/*An ideal gas object from Cantera. Contains thermodynamic and kinetic
* info of all species.*/
Cantera::IdealGasMix* gas;
/*A Transport object from Cantera. Contains all transport info of all
* species.*/
Cantera::Transport* trmix;
/*Length of the domain (in meters):*/
double domainLength;
/*Mass of gas in domain (in kg):*/
double mass;
/*Parameter that indicates the symmetry of the problem;*/
/*metric=0:Planar*/
/*metric=1:Cylindrical*/
/*metric=2:Spherical*/
int metric;
/*No: of species:*/
size_t nsp;
/*No: of equations:*/
size_t neq;
/*No: of variables:*/
size_t nvar;
/*Pointer indices (see "macros.h" for aliases that use these):*/
/*Pointer index for temperature:*/
size_t nt;
/*Pointer index for species:*/
size_t ny;
/*Pointer index for spatial coordinate:*/
size_t nr;
/*Pointer index for pressure:*/
size_t np;
/*Species index of bath gas:*/
size_t k_bath;
/*Species index of oxidizer:*/
size_t k_oxidizer;
size_t k_OH;
size_t k_HO2;
/*User-defined mass flux (kg/m^2/s):*/
double mdot;
/*Flag to solve isobaric/isochoric problem;*/
/*constantPressure=1: isobaric*/
/*constantPressure=0: isochoric*/
int constantPressure;
/*User-defined dPdt (Pa/s), activates when problem is "isobaric":*/
double dPdt;
/*Initial temperature of the gas (K):*/
double initialTemperature;
/*Initial Pressure of the gas (atm):*/
double initialPressure;
/*Classification of problem type;*/
/*problemType=0: Mixture is premixed and spatially uniform initially.
* In order for mixture to ignite, an external heat source (finite
* maxQDot) must be used.*/
/*problemType=1: Mixture is premixed but spatially non-uniform
* initially. Equilibrium products are contained within a hot kernel of
* size given by "shift" and a mixing length scale given by
* "mixingWidth".*/
/*problemType=2: User specified initial condition. Use file
* "initialCondition.dat".*/
int problemType;
/*Maximum External heat source (K/s):*/
double maxQDot;
/*Ignition kernel size:*/
double kernelSize;

double maxTemperature;
/*Maximum time for which the external heat source is applied (s):*/
double ignTime;
/*Vector of Mass Fractions used to impose Robin Boundary Condition for
* species at the domain origin:*/
double* innerMassFractions;
/*Value of temperature to be used if Dirichlet Boundary Conditions are
* imposed for temperature:*/
double innerTemperature;
double wallTemperature;
/*Isotherm chosen to find the location of a "burning" front (K):*/
double isotherm;
/*Interval of time integration:*/
double finalTime;
/*Current time:*/
double tNow;
/*Flag to reflect initial conditions across center of the domain:*/
int reflectProblem;
/*Parameters for initial conditions in setting up profiles:
increasing function of x: g=0.5*(erf(x-3*w-shift)/w)+1)
decreasing function of x: f=1-g*/
double mixingWidth;
double shift;
double firstRadius;
/*Flag to run program without time-integration i.e. simply layout the
* initial conditions and quit:*/
int dryRun;
/*Relative Tolerance:*/
double relativeTolerance;
/*Absolute Tolerance for spatial coordinate:*/
double radiusTolerance;
/*Absolute Tolerance for Temperature:*/
double temperatureTolerance;
/*Absolute Tolerance for Pressure:*/
double pressureTolerance;
/*Absolute Tolerance for Mass Fractions:*/
double massFractionTolerance;
/*Absolute Tolerance for bath gas mass fraction:*/
double bathGasTolerance;
/*Flag to set constraints on Mass fractions so they don't acquire
* negative values:*/
int setConstraints;
/*Flag to suppress error checking on algebraic variables:*/
int suppressAlg;
/*Number of time-steps elapsed before saving the solution:*/
int nSaves;
/*Flag to set write for every regrid:*/
int writeEveryRegrid;
double writeDeltaT;
/*Solution output file:*/
FILE* output;
/*Flag to write the rates (ydot) of solution components into the
* "ratesOutput" file:*/
int writeRates;
/*Grid output file:*/
FILE* gridOutput;
///*Rate of change (ydot) output file (see "writeRates"):*/
//FILE* ratesOutput;
/*Global properties (mdot, radius of flame, etc.) output file:*/
FILE* globalOutput;

/*Flag to adapt grid:*/
int adaptiveGrid;
/*Flag to move grid:*/
int moveGrid;
/*Flag to initiate regrid:*/
int regrid;
/*Integer that specifies grid movement direction:
* gridDirection = -1: Move Left
* gridDirection = +1: Move Right*/
int gridDirection;
/*Total number of points for grid:*/
size_t npts;

double gridOffset;

UserGrid grid;
double* uniformGrid;

int dirichletInner,dirichletOuter;

int nThreads;
double clockStart;
/*These arrays are used to compute dr/dt, which in turn is used to
* compute the flame speed S_u:*/
double flamePosition[2];
double flameTime[2];
size_t nTimeSteps;
} *UserData;
UserData allocateUserData(FILE *input);
void setSaneDefaults(UserData data);
void freeUserData(UserData data);
#endif


+ 244
- 0
gridRoutines.cpp View File

@@ -0,0 +1,244 @@
#include "gridRoutines.h"
#include <stdio.h>
inline double l(const double* x,
const double* a,
const double* w,
const double* fac,
const int* refineLeft){
if(*refineLeft==0){
return(tanh(-*a*(*x+*w*100.0e0)));
}else{
return(tanh(-*a*(*x-*w*(*fac))));
}
}

inline double r(const double* x,
const double* a,
const double* w,
const double* fac,
const int* refineRight){
if(*refineRight==0){
return(tanh(*a*(*x-(1.0e0+*w*100.0e0))));
}else{
return(tanh(*a*(*x-(1.0e0-*w*(*fac)))));
}
}

inline double f(const double* x,
const double* a,
const double* c,
const double* w){
return(tanh(-*a*(*x-(*c+*w)))
+tanh(-*a*((*x-1.0e0)-(*c+*w)))
+tanh(-*a*((*x+1.0e0)-(*c+*w))));
}

inline double g(const double* x,
const double* a,
const double* c,
const double* w){
return(tanh(*a*(*x-(*c-*w)))
+tanh(*a*((*x-1.0e0)-(*c-*w)))
+tanh(*a*((*x+1.0e0)-(*c-*w))));
}

inline double rho(const double* x,
const double* a,
const double* c,
const double* w,
const double* mag,
const double* leftFac,
const double* rightFac,
const int* refineLeft,
const int* refineRight){

return(((2.0e0+f(x,a,c,w)
+g(x,a,c,w)
+l(x,a,w,leftFac,refineLeft)
+r(x,a,w,rightFac,refineRight))*0.5e0)
*(*mag-1.0e0)+1.0e0);
}

size_t maxPoints(const size_t basePts,
const double* a,
const double* w,
const double* mag,
const double* leftFac,
const double* rightFac,
const int* refineLeft,
const int* refineRight){
double dx=1.0e0/((double)(basePts)-1.0e0);
double y=0.0e0;
size_t i=0;
double r=0.0e0;
double t=0.5e0;
while(y<=1.0e0){
r=rho(&y,a,&t,w,mag,leftFac,rightFac,refineLeft,refineRight);
y=y+(dx/r);
i++;
}
return(i);
}

void fillGrid(const size_t* basePts,
const size_t* nPts,
const double* a,
const double* c,
const double* w,
const double* mag,
const double* leftFac,
const double* rightFac,
const int* refineLeft,
const int* refineRight,
double x[]){

FILE* out;out=fopen("tmp.dat","w");

double y=0.0e0;
double r=0.0e0;
double dx=1.0e0/((double)(*basePts)-1.0e0);
for(size_t j=0;j<*nPts;j++){
r=rho(&y,a,c,w,mag,leftFac,rightFac,refineLeft,refineRight);
fprintf(out, "%15.15e\n",dx/r);
y=y+(dx/r);
}
fclose(out);
double dxp[*nPts-1];
for (size_t j = 0; j < *nPts; j++) {
dxp[j]=0.0e0;
}

FILE* tmp;tmp=fopen("tmp.dat","r");
char buf[MAXBUFLEN];
size_t i=0;
while (fgets(buf,MAXBUFLEN, tmp)!=NULL){
sscanf(buf, "%lf", &y);
dxp[i]=y;
i++;
}
fclose(tmp);

double sum=0.0e0;
double err=0.0e0;
double fix=0.0e0;
for(size_t j=0;j<*nPts-1;j++){
sum+=dxp[j];
}
err=1.0e0-sum;
printf("sum before correction: %15.6e\n",sum);
printf("err before correction: %15.6e\n",err);
fix=err/((double)(*nPts));
sum=0.0e0;
for(size_t j=0;j<*nPts-1;j++){
dxp[j]+=fix;
sum+=dxp[j];
}
err=1.0e0-sum;
printf("sum after correction:%15.6e\n",sum);
printf("err after correction: %15.6e\n",err);

x[0]=0.0e0;
for(size_t j=0;j<*nPts-1;j++){
x[j+1]=x[j]+dxp[j];
}
x[*nPts-1]=1.0e0;

}

double safePosition(double c, double w){
if(c<w){
return(w);
}
else if(c>1.0e0-w){
return(1.0e0-w);
}
else{
return(c);
}
}

int reGrid(UserGrid grid, double position){

printf("before regrid: %ld\n", grid->nPts);
double xx[grid->nPts];

fillGrid(&grid->basePts,
&grid->nPts,
&grid->a,
&position,
&grid->w,
&grid->mag,
&grid->leftFac,
&grid->rightFac,
&grid->refineLeft,
&grid->refineRight,
xx);

for (size_t i = 0; i < grid->nPts; i++) {
grid->x[i]=xx[i];
}
return(0);
}

void storeGrid(const double* x, double *y, const size_t nPts){
for(size_t i=0;i<nPts;i++){
y[i]=x[i];
}
}

int initializeGrid(UserGrid grid){
grid->nPts=maxPoints(grid->basePts,
&grid->a,
&grid->w,
&grid->mag,
&grid->leftFac,
&grid->rightFac,
&grid->refineLeft,
&grid->refineRight);
printf("nPts: %ld\n",grid->nPts);
grid->leastMove=grid->w;

grid->x = new double [grid->nPts];
grid->xOld = new double [grid->nPts];
for (size_t i = 0; i < grid->nPts; i++) {
grid->x[i]=0.0e0;
grid->xOld[i]=0.0e0;
}
return(0);
}

int getGridSettings(FILE *input, UserGrid grid){

int ier=0;

ier=parseNumber<size_t>(input, "basePts" , MAXBUFLEN, &grid->basePts);
if(ier==-1)return(-1);

ier=parseNumber<double>(input, "gridDensitySlope", MAXBUFLEN, &grid->a);
if(ier==-1)return(-1);

ier=parseNumber<double>(input, "fineGridHalfWidth", MAXBUFLEN, &grid->w);
if(ier==-1)return(-1);

ier=parseNumber<double>(input, "gridRefinement", MAXBUFLEN, &grid->mag);
if(ier==-1)return(-1);

ier=parseNumber<double>(input, "leftRefineFactor", MAXBUFLEN, &grid->leftFac);
if(ier==-1)return(-1);

ier=parseNumber<double>(input, "rightRefineFactor", MAXBUFLEN, &grid->rightFac);
if(ier==-1)return(-1);

ier=parseNumber<int>(input, "refineLeft" , MAXBUFLEN, &grid->refineLeft);
if(ier==-1)return(-1);

ier=parseNumber<int>(input, "refineRight" , MAXBUFLEN, &grid->refineRight);
if(ier==-1)return(-1);

ier=parseNumber<double>(input, "position" , MAXBUFLEN, &grid->position);
if(ier==-1)return(-1);

return(0);
}


+ 82
- 0
gridRoutines.h View File

@@ -0,0 +1,82 @@
#include "parse.h"

#ifndef GSL_DEF
#define GSL_DEF
#include <gsl/gsl_math.h>
#include <gsl/gsl_spline.h>
#endif

#ifndef GRID_DEF
#define GRID_DEF

typedef struct gridTag{

size_t basePts;
size_t nPts;
double position;
double leastMove;
double a;
double w;
double mag;
double leftFac;
double rightFac;
int refineLeft;
int refineRight;
double* x;
double* xOld;

} *UserGrid;

inline double l(const double* x,
const double* a,
const double* w,
const double* fac,
const int* refineLeft);

inline double r(const double* x,
const double* a,
const double* w,
const double* fac,
const int* refineRight);

inline double f(const double* x,
const double* a,
const double* c,
const double* w);

inline double g(const double* x,
const double* a,
const double* c,
const double* w);

inline double rho(const double* x,
const double* a,
const double* c,
const double* w,
const double* mag,
const double* leftFac,
const double* rightFac,
const int* refineLeft,
const int* refineRight);

size_t maxPoints(const size_t basePts,
const double* a,
const double* w,
const double* mag,
const double* leftFac,
const double* rightFac,
const int* refineLeft,
const int* refineRight);


double safePosition(double c, double w);

int reGrid(UserGrid grid, double position);

void storeGrid(const double* x, double *y, const size_t nPts);

int initializeGrid(UserGrid grid);

int getGridSettings(FILE *input, UserGrid grid);

#endif

+ 50
- 0
input.dat View File

@@ -0,0 +1,50 @@
#Problem constants:
domainLength=10.16e-02 #in meters
constantPressure=0 #1=isobaric, 0=isochoric
dPdt=0.0e0 #Units: Pa/s
problemType=1 #0=heatsource to ignite(premix),1=premix, 2=custom initial condition
reflectProblem=0 #If 1, the initial conditions are reflected across the center of the domain. Useful for spherically imploding flames for instance.
mdot=0.0
initialTemperature=300.0 #in Kelvin
initialPressure=1.0 #in atmospheres
chemistryFile=./ch4_1step.xml #File containing thermodynamic, kinetic, and transport info
transportModel=Mix #Transport model
mixtureComposition=CH4:0.45,O2:1.0,N2:3.76 #Mole Fractions!
metric=2 #0=planar,1=cylindrical,2=spherical
ignTime=5e-07 #Time over which energy is supplied in seconds
QDot=1e+14 #Power supplied in units of K/s
kernelSize=0e-03
mixingWidth=2e-03 #mixing layer width in m (for diffusion problem)
shift=4e-03 #shift of mixing layer into domain (for diffusion problem)
dirichletInner=0 #Boundary conditions for scalars (T,Y)
dirichletOuter=1
wallTemperature=300.0
#Grid settings:
adaptiveGrid=1
moveGrid=1
gridOffset=0
basePts=32
gridDensitySlope=70.0e0
fineGridHalfWidth=8e-03
gridRefinement=1000.0e0;
leftRefineFactor=0.01
rightRefineFactor=0.01
refineLeft=1
refineRight=1
position=0.0
isotherm=1000.0
#Solver settings:
nSaves=100 #Save solution every nSaves timesteps
writeEveryRegrid=1
writeRates=0
relativeTolerance=1e-06
radiusTolerance=1e-09 #absolute tolerance for radius
temperatureTolerance=1e-09
pressureTolerance=1e-09
massFractionTolerance=1e-09
bathGasTolerance=1e-09
finalTime=1.0e0 #in seconds
setConstraints=0
suppressAlg=0
nThreads=1
dryRun=0

+ 63
- 0
macros.h View File

@@ -0,0 +1,63 @@
#ifndef MACRO_DEF
#define MACRO_DEF
//#define SUNDIALS_DOUBLE_PRECISION 1
//#define SUNDIALS_SINGLE_PRECISION 1

#define ZERO RCONST(0.0)
#define HALF RCONST(0.5)
#define ONE RCONST(1.0)
#define TWO RCONST(2.0)
#define THREE RCONST(3.0)
#define FOUR RCONST(4.0)
#define TEN RCONST(10.0)

/* In order to keep begin the index numbers from 1 instead of 0, we define
* macros here. Also, we define macros to ease referencing various variables in
* the sundials nvector.
*/
#define psi(i) psidata[i-1]

#define T(i) ydata[((i-1)*data->nvar)+data->nt]
#define Y(i,k) ydata[((i-1)*data->nvar)+data->ny+k-1]
#define R(i) ydata[((i-1)*data->nvar)+data->nr]
#define P(i) ydata[((i-1)*data->nvar)+data->np]

#define Tdot(i) ydotdata[((i-1)*data->nvar)+data->nt]
#define Ydot(i,k) ydotdata[((i-1)*data->nvar)+data->ny+k-1]
#define Rdot(i) ydotdata[((i-1)*data->nvar)+data->nr]
#define Pdot(i) ydotdata[((i-1)*data->nvar)+data->np]

#define Tres(i) resdata[((i-1)*data->nvar)+data->nt]
#define Yres(i,k) resdata[((i-1)*data->nvar)+data->ny+k-1]
#define Rres(i) resdata[((i-1)*data->nvar)+data->nr]
#define Pres(i) resdata[((i-1)*data->nvar)+data->np]

#define Tid(i) iddata[((i-1)*data->nvar)+data->nt]
#define Yid(i,k) iddata[((i-1)*data->nvar)+data->ny+k-1]
#define Rid(i) iddata[((i-1)*data->nvar)+data->nr]
#define Pid(i) iddata[((i-1)*data->nvar)+data->np]

#define Yav(i) Yav[i-1]
#define YAvg(i) YAvg[i-1]
#define YVmhalf(i) YVmhalf[i-1]
#define YVphalf(i) YVphalf[i-1]
#define X(i) X[i-1]
#define Xp(i) Xp[i-1]
#define Xgradhalf(i) Xgradhalf[i-1]
#define XLeft(i) XLeft[i-1]
#define XRight(i) XRight[i-1]
#define gradX(i) gradX[i-1]
#define wdot(i) wdot[i-1]
#define enthalpy(i) enthalpy[i-1]
#define energy(i) energy[i-1]
#define Cp(i) Cp[i-1]

#define atolT(i) atolvdata[((i-1)*data->nvar)+data->nt]
#define atolY(i,k) atolvdata[((i-1)*data->nvar)+data->ny+k-1]
#define atolR(i) atolvdata[((i-1)*data->nvar)+data->nr]
#define atolP(i) atolvdata[((i-1)*data->nvar)+data->np]


#define constraintsY(i,k) constraintsdata[((i-1)*data->nvar)+data->ny+k-1]

#endif

+ 338
- 0
main.cpp View File

@@ -0,0 +1,338 @@
/*
_____ ___ ____ ____
|_ _/ _ \| _ \ / ___|
| || | | | |_) | |
| || |_| | _ <| |___
|_| \___/|_| \_\\____|
*/

#include "UserData.h"
#include "solution.h"
#include "residue.h"
#include "macros.h"
#include "timing.h"

#include <ida/ida.h>
#include <ida/ida_direct.h>
#include <sunmatrix/sunmatrix_band.h>
#include <sunlinsol/sunlinsol_lapackband.h>
//#include <ida/ida_band.h>

static int check_flag(void *flagvalue,
const char *funcname,
int opt);

void freeAtLast(void* mem, N_Vector *y,
N_Vector *ydot,
N_Vector *res,
N_Vector *id,
N_Vector *atolv,
N_Vector *constraints,UserData data);

int main(){

FILE *input;input=fopen("input.dat","r");
UserData data;data=NULL;data=allocateUserData(input);
fclose(input);
data->clockStart=get_wall_time();

if(data==NULL){
printf("check input file!\n");
freeUserData(data);
return(-1);
}
long int ier,mu,ml,count,netf,ncfn,njevals,nrevals;
realtype tNow,*atolvdata,*constraintsdata,finalTime,tolsfac;

N_Vector y,ydot,id,res,atolv,constraints;
y=ydot=id=res=atolv=constraints=NULL;
ier=allocateSolution(data->neq,data->nThreads,&y,&ydot,&id,&res,&atolv,&constraints);
ier=setAlgebraicVariables(&id,data);
ier=setInitialCondition(&y,&ydot,data);
if(ier==-1)return(-1);
tNow=data->tNow;
finalTime=data->finalTime;

double* ydata;
double* ydotdata;
ydata = N_VGetArrayPointer_OpenMP(y);
ydotdata = N_VGetArrayPointer_OpenMP(ydot);

void *mem;mem=NULL;mem = IDACreate();
ier = IDASetUserData(mem, data);
ier = IDASetId(mem, id);
ier = IDAInit(mem, residue, tNow, y, ydot);

// Atol array
atolvdata = N_VGetArrayPointer_OpenMP(atolv);
for (size_t i = 1; i <=data->npts; i++) {
atolT(i) = data->temperatureTolerance;
for (size_t k = 1; k <=data->nsp; k++) {
if(k!=data->k_bath){
atolY(i,k) = data->massFractionTolerance;
}
else{
atolY(i,k) = data->bathGasTolerance;
}

}
atolR(i) = data->radiusTolerance;
atolP(i) = data->pressureTolerance;
}
ier = IDASVtolerances(mem, data->relativeTolerance, atolv);

mu = 2*data->nvar; ml = mu;
SUNMatrix A; A=NULL;
A=SUNBandMatrix(data->neq,mu,ml,mu+ml);
SUNLinearSolver LS; LS=NULL;
//LS=SUNBandLinearSolver(y,A);
LS=SUNLapackBand(y,A);
ier=IDADlsSetLinearSolver(mem,LS,A);
//ier = IDABand(mem, data->neq, mu, ml);

constraintsdata = N_VGetArrayPointer_OpenMP(constraints);
if(data->setConstraints){
for (size_t i = 1; i <=data->npts; i++) {
for (size_t k = 1; k <=data->nsp; k++) {
constraintsY(i,k) = ONE;
}
}
ier=IDASetConstraints(mem, constraints);
}

ier = IDASetSuppressAlg(mem, data->suppressAlg);
if(check_flag(&ier, "IDASetSuppressAlg", 1)) return(1);

//ier= IDASetMaxNumStepsIC(mem, 1);
//ier= IDASetMaxNumJacsIC(mem,8);
//ier= IDASetMaxNumItersIC(mem,100);
//ier= IDASetMaxBacksIC(mem,2000);
//ier = IDASetLineSearchOffIC(mem,SUNTRUE);
if(!data->dryRun){
printf("Calculating Initial Conditions:\n");
printf("Cross your fingers...\n");
ier = IDACalcIC(mem, IDA_YA_YDP_INIT, 1e-05*finalTime);
//If at first IDACalcIC doesn't succeed, try, try, try again:
for (int i = 0; i < 10; i++) {
ier = IDACalcIC(mem, IDA_YA_YDP_INIT, (1e-01+pow(10,i)*finalTime));
if(ier==0){
break;
}
}
//...or else cry again :(
if(check_flag(&ier, "IDACalcIC", 1)){
freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);
return(-1);
}else{
printf("Initial (Consistent) Conditions Calculated!\n");
}
ier = IDASetInitStep(mem,1e-12);
}

printSpaceTimeHeader(data);
printGlobalHeader(data);
printSpaceTimeOutput(tNow, &y, data->output, data);
printSpaceTimeOutput(tNow, &y, data->gridOutput, data);

if(!data->dryRun){
count=0;
double dt=1e-08;
double t1=0.0e0;
double xOld=0.0e0;
double x=0.0e0;
double dx=0.0e0;
double dxMin=1.0e0;
double dxRatio=dx/dxMin;
double writeTime=tNow;
int move=0;
int kcur=0;
if(data->adaptiveGrid){
dxMin=data->grid->leastMove;
//xOld=maxCurvPosition(ydata, data->nt, data->nvar,
// data->grid->x, data->npts);
xOld=isothermPosition(ydata, data->isotherm, data->nt,
data->nvar, data->grid->x, data->npts);
}
while (tNow<=finalTime) {

t1=tNow;
ier = IDASolve(mem, finalTime, &tNow, y, ydot, IDA_ONE_STEP);
if(check_flag(&ier, "IDASolve", 1)){
freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);
return(-1);
}
dt=tNow-t1;

ier = IDAGetCurrentOrder(mem, &kcur);

if(data->adaptiveGrid==1 && data->moveGrid==1){
//x=maxCurvPosition(ydata, data->nt, data->nvar,
// data->grid->x, data->npts);

x=isothermPosition(ydata, data->isotherm, data->nt,
data->nvar, data->grid->x, data->npts);

//x=maxGradPosition(ydata, data->nt, data->nvar,
// data->grid->x, data->npts);
dx=x-xOld;

if(dx*dxMin>0.0e0){
move=1;
}else{
move=-1;
}

//if(fabs(dx)>=dxMin && x+(double)(move)*0.5e0*dxMin<=1.0e0){
dxRatio=fabs(dx/dxMin);
if(dxRatio>=1.0e0 && dxRatio<=2.0e0){
printf("Regridding!\n");

data->regrid=1;
//printSpaceTimeOutput(tNow, &y, data->gridOutput, data);

ier=reGrid(data->grid, x+(double)(move)*0.5e0*dxMin);
if(ier==-1){
freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);
return(-1);
}

updateSolution(ydata, ydotdata, data->nvar,
data->grid->xOld,data->grid->x,data->npts);
storeGrid(data->grid->x,data->grid->xOld,data->npts);
xOld=x;

printf("Regrid Complete! Restarting Problem at %15.6e s\n",tNow);
ier = IDAReInit(mem, tNow, y, ydot);
if(check_flag(&ier, "IDAReInit", 1)){
freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);
return(-1);
}
ier = IDASetInitStep(mem,1e-01*dt);
printf("Reinitialized! Calculating Initial Conditions:\n");
printf("Cross your fingers...\n");
ier = IDACalcIC(mem, IDA_YA_YDP_INIT, tNow+1e-01*dt);
if(check_flag(&ier, "IDACalcIC", 1)){
ier = IDACalcIC(mem, IDA_YA_YDP_INIT, tNow+1e+01*dt);
}
//Every once in a while, for reasons
//that befuddle this mathematically
//lesser author, IDACalcIC fails. Here,
//I desperately try to make it converge
//again by sampling increasingly larger
//time-steps:
for (int i = 0; i < 10; i++) {
ier = IDACalcIC(mem, IDA_YA_YDP_INIT, tNow+(1e-01+pow(10,i)*dt));
if(ier==0){
break;
}
}
//Failure :( Back to the drawing board:
if(check_flag(&ier, "IDACalcIC", 1)){
freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);
return(-1);
}
printf("Initial (Consistent) Conditions Calculated!\n");
printf("------------------------------------------\n\n");
//if(data->writeEveryRegrid){

}
}

if(count%data->nSaves==0 && !data->writeEveryRegrid){
printSpaceTimeOutput(tNow, &y, data->output, data);
//if(data->writeRates){
// printSpaceTimeRates(tNow, ydot, data);
//}
}

/*Print global variables only if time-step is of high order!*/
if(data->nTimeSteps==0){
data->flamePosition[0]=0.0e0;
data->flamePosition[1]=0.0e0;
data->flameTime[0]=tNow;
data->flameTime[1]=tNow;
}
if(kcur>=2 ){
printGlobalVariables(tNow,&y,&ydot,data);
}

if(tNow>writeTime){
writeTime+=data->writeDeltaT;
printSpaceTimeOutput(tNow, &y, data->output, data);
FILE* fp;
fp=fopen("restart.bin","w");
writeRestart(tNow, &y, &ydot, fp, data);
fclose(fp);
}

ier = IDAGetNumErrTestFails(mem, &netf);
ier = IDAGetNumNonlinSolvConvFails(mem, &ncfn);
ier = IDADlsGetNumJacEvals(mem, &njevals);
ier = IDADlsGetNumResEvals(mem, &nrevals);
printf("etf = %ld ,"
"nlsf= %ld ,"
"J=%ld ,"
"R=%ld ,"
"o=%d ,",netf, ncfn, njevals, nrevals, kcur);
printf("Time=%15.6e s,",tNow);
printf("frac: %15.6e\n",dxRatio);
count++;
data->nTimeSteps=count;
}
}

SUNLinSolFree(LS);
SUNMatDestroy(A);
freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);

return(0);
}

void freeAtLast(void* mem,
N_Vector *y,
N_Vector *ydot,
N_Vector *res,
N_Vector *id,
N_Vector *atolv,
N_Vector *constraints,UserData data){

IDAFree(&mem);
freeSolution(y,ydot,res,id,atolv,constraints);
freeUserData(data);
}

static int check_flag(void *flagvalue, const char *funcname, int opt)
{
int *errflag;

/* Check if SUNDIALS function returned NULL pointer - no memory allocated */
if (opt == 0 && flagvalue == NULL) {
fprintf(stderr,
"\nSUNDIALS_ERROR: %s() failed - returned NULL pointer\n\n",
funcname);
return(1);
}

/* Check if flag < 0 */
else if (opt == 1) {
errflag = (int *) flagvalue;
if (*errflag < 0) {
fprintf(stderr,
"\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n",
funcname, *errflag);
return(1);
}
}

/* Check if function returned NULL pointer - no memory allocated */
else if (opt == 2 && flagvalue == NULL) {
fprintf(stderr,
"\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n",
funcname);
return(1);
}

return(0);
}

+ 20
- 0
parse.cpp View File

@@ -0,0 +1,20 @@
#include "parse.h"
void getFromString (const char* buf, int* n){
*n=atoi(buf);
printf("%d\n",*n);
}

void getFromString (const char* buf, size_t* n){
*n=(size_t)(atoi(buf));
printf("%lu\n",*n);
}

void getFromString (const char* buf, double* n){
*n=(double)(atof(buf));
printf("%15.6e\n",*n);
}

void getFromString (const char* buf, char* n){
sscanf(buf,"%s",n);
printf("%s\n",n);
}

+ 31
- 0
parse.h View File

@@ -0,0 +1,31 @@
#ifndef PRINT_DEF
#define PRINT_DEF
#include <string.h> //for strings
#include <stdio.h> //for printf,scanf
#include <stdlib.h> //for atoi, atof
#endif

#ifndef PARSE_DEF
#define PARSE_DEF
#define MAXBUFLEN 200

void getFromString (const char* buf, int* n);
void getFromString (const char* buf, size_t* n);
void getFromString (const char* buf, double* n);
void getFromString (const char* buf, char* n);

int parseString(FILE* input, const char* keyword, const size_t bufLen, char* n);

template<typename T>
int parseNumber(FILE* input, const char* keyword, const size_t bufLen, T* n);

template<typename T>
int parseArray(FILE* input, const char* keyword, const size_t bufLen,
const size_t arrLen, T y[]);


#include "parse.hpp"

#endif



+ 76
- 0
parse.hpp View File

@@ -0,0 +1,76 @@
template<typename T>
int parseNumber(FILE* input, const char* keyword, const size_t bufLen, T* n){

char buf[bufLen];
char buf1[bufLen];
char comment[1];
char *ret;

while (fgets(buf,bufLen, input)!=NULL){
comment[0]=buf[0];
if(strncmp(comment,"#",1)==0){
//printf("Comment!:%s\n",buf);
}
else{
ret=strtok(buf,"=");
if(strcmp(ret,keyword)==0){
/*offset buf by keyword size + 1 for the "="*/
strncpy (buf1, buf+strlen(keyword)+1, bufLen);
printf("%30s: ",keyword);
getFromString(buf1,n);
rewind(input);
return(0);
}
}
}
rewind(input);
return(-1);
}

template<typename T>
int parseArray(FILE* input, const char* keyword, const size_t bufLen,
const size_t arrLen, T y[]){

char buf[bufLen];
char buf1[bufLen];
char comment[1];
char *ret;

while (fgets(buf,bufLen, input)!=NULL){
comment[0]=buf[0];
if(strncmp(comment,"#",1)==0){
//printf("Comment!:%s\n",buf);
}
else{
ret=strtok(buf,"=");

if(strcmp(ret,keyword)==0){
/*offset buf by keyword size + 1 for the "="*/
strncpy (buf1, buf+strlen(keyword)+1, bufLen);
printf("%30s:\n",keyword);
ret=strtok(buf1,",");
size_t j=0;
while(ret!=NULL){
if(j<arrLen){
//y[j]=atof(ret);
getFromString(ret,&y[j]);
}
ret=strtok(NULL,",");
j++;
}
rewind(input);
if(j!=arrLen){
printf("Check no: of values entered for %s\n",keyword);
printf("%lu values required!\n",arrLen);
return(-1);
}
else{
return(0);
}
}
}
}
rewind(input);
return(-1);
}


+ 1303
- 0
residue.cpp
File diff suppressed because it is too large
View File


+ 90
- 0
residue.h View File

@@ -0,0 +1,90 @@
#ifndef SUNDIALS_DEF
#define SUNDIALS_DEF
#include <sundials/sundials_types.h>
#include <nvector/nvector_openmp.h>
#endif

#ifndef PRINT_DEF
#define PRINT_DEF
#include <string.h> //for strings
#include <stdio.h> //for printf,scanf
#include <stdlib.h> //for atoi, atof
#endif

#ifndef CANTERA_DEF
#define CANTERA_DEF
#include <cantera/IdealGasMix.h>
#include <cantera/transport.h>
#endif

#include "UserData.h"


double maxGradPosition(const double* y, const size_t nt,
const size_t nvar, const double* x, size_t nPts);

int maxGradIndex(const double* y, const size_t nt,
const size_t nvar, const double* x, size_t nPts);

double maxCurvPosition(const double* y, const size_t nt,
const size_t nvar, const double* x, size_t nPts);

int maxCurvIndex(const double* y, const size_t nt,
const size_t nvar, const double* x, size_t nPts);

double isothermPosition(const double* y, const double T, const size_t nt,
const size_t nvar, const double* x, const size_t nPts);

int setAlgebraicVariables(N_Vector *id,UserData data);

inline double calc_area(double x,int* i);

void updateSolution(double* y, double* ydot, const size_t nvar,
const double xOld[],const double xNew[],const size_t npts);

void readInitialCondition(FILE* input, double* ydata, const size_t nvar, const size_t nr, const size_t nPts);

double systemMass(double* ydata, UserData data);

int initializePsiGrid(double* ydata, double* psidata, UserData data);

int setInitialCondition(N_Vector* y,
N_Vector* ydot,
UserData data);


inline void setGas(UserData data, double *ydata, size_t gridPoint);

void getTransport(UserData data,
double *ydata,
size_t gridPoint,
double *rho,
double *lambda,
double *YV);

int residue(double t,
N_Vector y,
N_Vector ydot,
N_Vector res,
void *user_data);

void trackFlameOH(N_Vector y,UserData data);
void trackFlame(N_Vector y,UserData data);
size_t BathGasIndex(UserData data);
size_t oxidizerIndex(UserData data);

inline double Qdot(double* t,
double* x,
double* ignTime,
double* kernelSize,
double* maxQdot);

void printSpaceTimeHeader(UserData data);
void printSpaceTimeOutput(double t, N_Vector* y, FILE* output, UserData data);
void printSpaceTimeRates(double t, N_Vector ydot, UserData data);
void printGlobalHeader(UserData data);
void printGlobalVariables(double t, N_Vector* y, N_Vector* ydot, UserData data);
void printSpaceTimeOutputInterpolated(double t, N_Vector y, UserData data);

void writeRestart(double t, N_Vector* y, N_Vector* ydot, FILE* output, UserData data);
void readRestart(N_Vector* y, N_Vector* ydot, FILE* input, UserData data);

+ 90
- 0
solution.cpp View File

@@ -0,0 +1,90 @@
#include "solution.h"
int allocateSolution(size_t neq,
int nThreads,
N_Vector *y,
N_Vector *ydot,
N_Vector *res,
N_Vector *id,
N_Vector *atolv,
N_Vector *constraints){


*y = N_VNew_OpenMP(neq,nThreads);
if(*y==NULL){
printf("Allocation Failed!\n");
return(1);
}
N_VConst((realtype)(0.0e0), *y);

*ydot = N_VNew_OpenMP(neq,nThreads);
if(*ydot==NULL){
printf("Allocation Failed!\n");
return(1);
}
N_VConst((realtype)(0.0e0), *ydot);

*res = N_VNew_OpenMP(neq,nThreads);
if(*res==NULL){
printf("Allocation Failed!\n");
return(1);
}
N_VConst((realtype)(0.0e0), *res);

*id = N_VNew_OpenMP(neq,nThreads);
if(*id==NULL){
printf("Allocation Failed!\n");
return(1);
}
N_VConst((realtype)(1.0e0), *id);

*atolv = N_VNew_OpenMP(neq,nThreads);
if(*atolv==NULL){
printf("Allocation Failed!\n");
return(1);
}
N_VConst((realtype)(0.0e0), *atolv);

*constraints = N_VNew_OpenMP(neq,nThreads);
if(*constraints==NULL){
printf("Allocation Failed!\n");
return(1);
}
N_VConst((realtype)(0.0e0), *constraints);

return(0);
}

void freeSolution(N_Vector *y,
N_Vector *ydot,
N_Vector *res,
N_Vector *id,
N_Vector *atolv,
N_Vector *constraints){

if(*y!=NULL){
N_VDestroy_OpenMP(*y);
printf("y Destroyed!\n");
}
if(*ydot!=NULL){
N_VDestroy_OpenMP(*ydot);
printf("ydot Destroyed!\n");
}
if(*res!=NULL){
N_VDestroy_OpenMP(*res);
printf("res Destroyed!\n");
}
if(*id!=NULL){
N_VDestroy_OpenMP(*id);
printf("id Destroyed!\n");
}
if(*atolv!=NULL){
N_VDestroy_OpenMP(*atolv);
printf("atolv Destroyed!\n");
}

if(*constraints!=NULL){
N_VDestroy_OpenMP(*constraints);
printf("constraints Destroyed!\n");
}
printf("\n\n");
}

+ 15
- 0
solution.h View File

@@ -0,0 +1,15 @@
#ifndef PRINT_DEF
#define PRINT_DEF
#include <string.h> //for strings
#include <stdio.h> //for printf,scanf
#include <stdlib.h> //for atoi, atof
#endif

#ifndef SUNDIALS_DEF
#define SUNDIALS_DEF
#include <sundials/sundials_types.h>
#include <nvector/nvector_openmp.h>
#endif

int allocateSolution(size_t neq, int nThreads, N_Vector *y, N_Vector *ydot, N_Vector *res, N_Vector *id, N_Vector *atolv, N_Vector *constraints);
void freeSolution(N_Vector *y, N_Vector *ydot, N_Vector *res, N_Vector *id, N_Vector *atolv, N_Vector *constraints);

+ 2
- 0
timing.h View File

@@ -0,0 +1,2 @@
double get_wall_time();
double get_cpu_time();

+ 45
- 0
timing.hpp View File

@@ -0,0 +1,45 @@
// Windows
#ifdef _WIN32
#include <Windows.h>
double get_wall_time(){
LARGE_INTEGER time,freq;
if (!QueryPerformanceFrequency(&freq)){
// Handle error
return 0;
}
if (!QueryPerformanceCounter(&time)){
// Handle error
return 0;
}
return (double)time.QuadPart / freq.QuadPart;
}
double get_cpu_time(){
FILETIME a,b,c,d;
if (GetProcessTimes(GetCurrentProcess(),&a,&b,&c,&d) != 0){
// Returns total user time.
// Can be tweaked to include kernel times as well.
return
(double)(d.dwLowDateTime |
((unsigned long long)d.dwHighDateTime << 32)) * 0.0000001;
}else{
// Handle error
return 0;
}
}

// Posix/Linux
#else
#include <time.h>
#include <sys/time.h>
double get_wall_time(){
struct timeval time;
if (gettimeofday(&time,NULL)){
// Handle error
return 0;
}
return (double)time.tv_sec + (double)time.tv_usec * .000001;
}
double get_cpu_time(){
return (double)clock() / CLOCKS_PER_SEC;
}
#endif

Loading…
Cancel
Save