Droplet Lagrangian Transient One-dimensional Reacting Code Implementation of both liquid and gas phase governing equations.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

505 lines
16KB

  1. /*
  2. _____ ___ ____ ____
  3. |_ _/ _ \| _ \ / ___|
  4. | || | | | |_) | |
  5. | || |_| | _ <| |___
  6. |_| \___/|_| \_\\____|
  7. */
  8. #include "UserData.h"
  9. #include "solution.h"
  10. #include "residue.h"
  11. #include "macros.h"
  12. #include "timing.h"
  13. #include <ida/ida.h>
  14. #include <ida/ida_direct.h>
  15. #include <sunmatrix/sunmatrix_band.h>
  16. #include <sunlinsol/sunlinsol_lapackband.h>
  17. //#include <ida/ida_band.h>
  18. static int check_flag(void *flagvalue,
  19. const char *funcname,
  20. int opt);
  21. void freeAtLast(void* mem, N_Vector *y,
  22. N_Vector *ydot,
  23. N_Vector *res,
  24. N_Vector *id,
  25. N_Vector *atolv,
  26. N_Vector *constraints,UserData data);
  27. int main(){
  28. // Read input file specifying the details of the case and store them
  29. FILE *input =fopen("input.dat","r");
  30. UserData data=allocateUserData(input);
  31. fclose(input);
  32. data->clockStart=get_wall_time();
  33. // /**************** TEST THE xOld *******************/
  34. // double* ptr1 = data->grid->xOld ;
  35. // printf("After allocateUserData in main.cpp,Start print the first 5 elements of the xOld array : \n");
  36. // printf("1st:%.6f, 2nd:%.6f, 3rd:%.6f, 4th:%.6f, 5th:%.6f.\n",ptr1[0],ptr1[1],ptr1[2],ptr1[3],ptr1[4]);
  37. if(data==NULL){
  38. printf("check input file!\n");
  39. freeUserData(data);
  40. return(-1);
  41. }
  42. // Allocate solution variables
  43. long int ier,mu,ml,count,netf,ncfn,njevals,nrevals;
  44. realtype tNow,*atolvdata,*constraintsdata,finalTime,dtMax,tolsfac;
  45. N_Vector y,ydot,id,res,atolv,constraints;
  46. y=ydot=id=res=atolv=constraints=NULL;
  47. ier=allocateSolution(data->neq,data->nThreads,&y,&ydot,&id,&res,&atolv,&constraints);
  48. // /**************** TEST THE xOld *******************/
  49. // double* ptr2 = data->grid->xOld ;
  50. // printf("Before setInitialCondition in main.cpp,Start print the first 5 elements of the xOld array : \n");
  51. // printf("1st:%.6f, 2nd:%.6f, 3rd:%.6f, 4th:%.6f, 5th:%.6f.\n",ptr2[0],ptr2[1],ptr2[2],ptr2[3],ptr2[4]);
  52. ier=setInitialCondition(&y,&ydot,data);
  53. if(ier==-1)return(-1);
  54. tNow=data->tNow;
  55. finalTime=data->finalTime;
  56. //TODO: dtMax should be a user input
  57. dtMax = 1e-4;
  58. double* ydata;
  59. double* ydotdata;
  60. ydata = N_VGetArrayPointer_OpenMP(y);
  61. ydotdata = N_VGetArrayPointer_OpenMP(ydot);
  62. ier=setAlgebraicVariables(&id,data,ydata);
  63. ////////// DEBUG ///////////////////
  64. //double* resdata;
  65. //double* iddata;
  66. //resdata = N_VGetArrayPointer_OpenMP(res);
  67. //iddata = N_VGetArrayPointer_OpenMP(id);
  68. ///////////////////////////////////
  69. void *mem;mem=NULL;mem = IDACreate();
  70. ier = IDASetUserData(mem, data);
  71. ier = IDASetId(mem, id);
  72. ier = IDAInit(mem, residue, tNow, y, ydot);
  73. // Atol array
  74. atolvdata = N_VGetArrayPointer_OpenMP(atolv);
  75. for (size_t i = 1; i <=data->npts; i++) {
  76. atolT(i) = data->temperatureTolerance;
  77. for (size_t k = 1; k <=data->nsp; k++) {
  78. if(k!=data->k_bath){
  79. atolY(i,k) = data->massFractionTolerance;
  80. }
  81. else{
  82. atolY(i,k) = data->bathGasTolerance;
  83. }
  84. }
  85. atolR(i) = data->radiusTolerance;
  86. atolP(i) = data->pressureTolerance;
  87. atolMdot(i) = data->MdotTolerance;
  88. }
  89. ier = IDASVtolerances(mem, data->relativeTolerance, atolv);
  90. mu = 2*data->nvar; ml = mu;
  91. SUNMatrix A; A=NULL;
  92. A=SUNBandMatrix(data->neq,mu,ml,mu+ml);
  93. SUNLinearSolver LS; LS=NULL;
  94. //LS=SUNBandLinearSolver(y,A);
  95. LS=SUNLapackBand(y,A);
  96. ier=IDADlsSetLinearSolver(mem,LS,A);
  97. //ier = IDABand(mem, data->neq, mu, ml);
  98. constraintsdata = N_VGetArrayPointer_OpenMP(constraints);
  99. if(data->setConstraints){
  100. for (size_t i = 1; i <=data->npts; i++) {
  101. for (size_t k = 1; k <=data->nsp; k++) {
  102. constraintsY(i,k) = ONE;
  103. }
  104. }
  105. ier=IDASetConstraints(mem, constraints);
  106. }
  107. if(!data->quasiSteady){
  108. constraintsR(1) = ONE;
  109. ier=IDASetConstraints(mem, constraints) ;
  110. }
  111. ier = IDASetSuppressAlg(mem, data->suppressAlg);
  112. if(check_flag(&ier, "IDASetSuppressAlg", 1)) return(1);
  113. //ier= IDASetMaxNumStepsIC(mem, 1);
  114. // ier= IDASetMaxNumStepsIC(mem, 8);
  115. //ier= IDASetMaxNumJacsIC(mem,8);
  116. // ier= IDASetMaxNumItersIC(mem,100);
  117. // ier= IDASetMaxBacksIC(mem,2000);
  118. // ier= IDASetMaxBacksIC(mem,1000);
  119. //ier = IDASetLineSearchOffIC(mem,SUNTRUE);
  120. //////// DEBUG ///////////
  121. //if(data->dryRun){
  122. // ier = residue(tNow,y, ydot, res, data);
  123. // for(size_t k=0; k < data->nvar*data->npts; k++){
  124. // printf("%i: %15.6e\n",k,resdata[k]);
  125. // }
  126. // for(size_t k=0; k < data->nvar*data->npts; k++){
  127. // if(iddata[k] == 1){
  128. // ydotdata[k] = -resdata[k];
  129. // }
  130. // }
  131. // ier = residue(tNow,y, ydot, res, data);
  132. // for(size_t k=0; k < data->nvar*data->npts; k++){
  133. // printf("%i: %15.6e\n",k,resdata[k]);
  134. // }
  135. //}
  136. //for(size_t k=0; k < data->neq; k++){
  137. // if(iddata[k] == 1){
  138. // ydotdata[k] = -resdata[k];
  139. // }
  140. //}
  141. //////////////////////////
  142. if(!data->dryRun){
  143. printf("Calculating Initial Conditions:\n");
  144. printf("Cross your fingers...\n");
  145. // ier = IDACalcIC(mem, IDA_YA_YDP_INIT, 1e-5*finalTime);
  146. ier = IDACalcIC(mem, IDA_YA_YDP_INIT, 1e-7*finalTime);
  147. //If at first IDACalcIC doesn't succeed, try, try, try again:
  148. for (int i = 0; i < 10; i++) {
  149. ier = IDACalcIC(mem, IDA_YA_YDP_INIT, (1e-01+pow(10,i)*finalTime));
  150. /************* Print the #of iterations ************/
  151. //printf("This the %dth try of calculating initial conditions. \n",i);
  152. if(ier==0){
  153. break;
  154. }
  155. }
  156. //...or else cry again :(
  157. if(check_flag(&ier, "IDACalcIC", 1)){
  158. freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);
  159. return(-1);
  160. }else{
  161. printf("Initial (Consistent) Conditions Calculated!\n");
  162. }
  163. ier = IDASetInitStep(mem,1e-12);
  164. }
  165. printSpaceTimeHeader(data);
  166. printGlobalHeader(data);
  167. //printTimescaleHeader(data);
  168. printSpaceTimeOutput(tNow, &y, data->output, data);
  169. printSpaceTimeOutput(tNow, &y, data->gridOutput, data);
  170. // getTimescale(data,&y) ;
  171. // printTimescaleOutput(tNow, &y, data->timescaleOutput,data);
  172. if(!data->dryRun){
  173. count=0;
  174. double dt=1e-08;
  175. double t1=0.0e0;
  176. double xOld=0.0e0;
  177. double x=0.0e0;
  178. double dx=0.0e0;
  179. double dxMin=1.0e0;
  180. double dxRatio=dx/dxMin;
  181. int move=0;
  182. int kcur=0;
  183. int RGCOUNT=0;
  184. int ii=0;
  185. if(data->adaptiveGrid){
  186. dxMin=data->grid->leastMove;
  187. xOld=maxCurvPosition(ydata, data->nt, data->nvar,
  188. data->grid->x, data->npts);
  189. //xOld=isothermPosition(ydata, data->isotherm, data->nt,
  190. // data->nvar, data->grid->x, data->npts);
  191. }
  192. while (tNow<=finalTime && R(data->l_npts)>100e-9) {
  193. t1=tNow;
  194. /*Floor small value to zero*/
  195. // floorSmallValue(data, &y);
  196. if(data->quasiSteady){
  197. ier = IDASolve(mem, finalTime, &tNow, y, ydot, IDA_ONE_STEP);
  198. }else{
  199. /*This prevents the solver from taking a step so large that
  200. *the droplet radius becomes negative.
  201. *TODO:Try adding the constraint that the droplet radius must
  202. * be a positive number*/
  203. ier = IDASolve(mem, tNow+dtMax, &tNow, y, ydot, IDA_ONE_STEP);
  204. //ier = IDASolve(mem, tNow+dtMax, &tNow, y, ydot, IDA_NORMAL);
  205. }
  206. if(check_flag(&ier, "IDASolve", 1)){
  207. freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);
  208. return(-1);
  209. }
  210. dt=tNow-t1;
  211. ier = IDAGetCurrentOrder(mem, &kcur);
  212. /******** Print the max Temperature *********/
  213. // double maxT = 0.00;
  214. // maxT = maxTemperature(ydata,data->nt,data->nvar,data->npts);
  215. // printf("Maximum temperature is : %.3f[K] \n",maxT);
  216. if(data->adaptiveGrid==1 && data->moveGrid==1){
  217. x=maxCurvPosition(ydata, data->nt, data->nvar,
  218. data->grid->x, data->npts);
  219. //x=isothermPosition(ydata, data->isotherm, data->nt,
  220. // data->nvar, data->grid->x, data->npts);
  221. //x=maxGradPosition(ydata, data->nt, data->nvar,
  222. // data->grid->x, data->npts);
  223. dx=x-xOld;
  224. if(dx*dxMin>0.0e0){
  225. move=1;
  226. }else{
  227. move=-1;
  228. }
  229. //if(fabs(dx)>=dxMin && x+(double)(move)*0.5e0*dxMin<=1.0e0){
  230. dxRatio=fabs(dx/dxMin);
  231. /************ Print xOld, x,dx,dxMin,dxRatio ******************/
  232. printf("xOld = %.6f, x = %.6f,",xOld,x);
  233. printf("dx = %.6f, dxMin = %.6f, dxRatio = %.3f\n",dx,dxMin,dxRatio);
  234. if(dxRatio>=1.0e0 && dxRatio<=2.0e0){
  235. printf("Regridding!\n");
  236. data->regrid=1;
  237. printSpaceTimeOutput(tNow, &y, data->gridOutput, data);
  238. ier=reGrid(data->grid, x+(double)(move)*0.5e0*dxMin);
  239. if(ier==-1){
  240. freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);
  241. return(-1);
  242. }
  243. updateSolution(ydata, ydotdata, data->nvar,
  244. data->grid->xOld,data->grid->x,data->npts);
  245. storeGrid(data->grid->x,data->grid->xOld,data->npts);
  246. xOld=x;
  247. printf("Regrid Complete! Restarting Problem at %15.6e s\n",tNow);
  248. ier = IDAReInit(mem, tNow, y, ydot);
  249. if(check_flag(&ier, "IDAReInit", 1)){
  250. freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);
  251. return(-1);
  252. }
  253. ier = IDASetInitStep(mem,1e-01*dt);
  254. printf("Reinitialized! Calculating Initial Conditions:\n");
  255. printf("Cross your fingers...\n");
  256. ier = IDACalcIC(mem, IDA_YA_YDP_INIT, tNow+1e-01*dt);
  257. if(check_flag(&ier, "IDACalcIC", 1)){
  258. ier = IDACalcIC(mem, IDA_YA_YDP_INIT, tNow+1e+01*dt);
  259. }
  260. //Every once in a while, for reasons
  261. //that befuddle this mathematically
  262. //lesser author, IDACalcIC fails. Here,
  263. //I desperately try to make it converge
  264. //again by sampling increasingly larger
  265. //time-steps:
  266. for (int i = 0; i < 10; i++) {
  267. ier = IDACalcIC(mem, IDA_YA_YDP_INIT, tNow+(1e-01+pow(10,i)*dt));
  268. if(ier==0){
  269. break;
  270. }
  271. }
  272. //Failure :( Back to the drawing board:
  273. if(check_flag(&ier, "IDACalcIC", 1)){
  274. freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);
  275. return(-1);
  276. }
  277. printf("Initial (Consistent) Conditions Calculated!\n");
  278. printf("------------------------------------------\n\n");
  279. if(data->writeEveryRegrid){
  280. printSpaceTimeOutput(tNow, &y, data->output, data);
  281. FILE* fp;
  282. fp=fopen("restart.bin","w");
  283. writeRestart(tNow, &y, &ydot, fp, data);
  284. fclose(fp);
  285. }
  286. }
  287. }
  288. /*Print Liquid Thermodynamic data*/
  289. // double rho = getLiquidRho(data->dropMole,T(1),P(1));
  290. // double Cp = getLiquidCp(data->dropMole,T(1),P(1));
  291. // double deltaH = getLiquidHv(data->dropMole,T(1),P(1));
  292. // double boil_T = getLiquidMaxT(data->dropMole,P(1));
  293. // printf("The Mean Density of Liquid Phase:%6.3e [kg/m^3]\n",rho);
  294. // printf("The Mean Specific Heat Capacity of Liquid Phase:%6.3e [J/(kg*K)]\n",Cp);
  295. // printf("The Mean Heat of Evaporation of Liquid Phase:%6.3e [J/kg]\n",deltaH);
  296. // printf("The Boiling Point of More Volitile Component (Propane):%6.3e [K]\n",boil_T);
  297. // printf("Temperature at the liquid/gas phase interface:%6.3e [K]\n\n",T(1));
  298. /*reset the tolerance after ignition*/
  299. //resetTolerance(data,&y,&atolv);
  300. /*regrid and update the solution based on R,re-initialize the problem*/
  301. /*For the time being,we only allow TORC to REGRID once for each run*/
  302. // if(data->JJRG ==1 && (maxT >= data->initialTemperature+data->deltaT)){
  303. // if(RGCOUNT<1){
  304. // RGCOUNT = RGCOUNT +1;
  305. // REGRID(ydata,ydotdata,data);
  306. // initializePsiGrid(ydata,data->uniformGrid,data);
  307. // printf("REGRID Complete!Restarting Problem at %15.6e s\n",tNow);
  308. // ier = IDAReInit(mem,tNow,y,ydot);
  309. //
  310. // if(check_flag(&ier,"IDAReInit",1)){
  311. // freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);
  312. // return(-1);
  313. // }
  314. //
  315. // ier= IDASetInitStep(mem,1e-01*dt);
  316. // //ier= IDASetInitStep(mem,0.0);
  317. // printf("Reinitialized!Calculating Initial Conditions:\n");
  318. // printf("Cross your fingers...\n");
  319. // ier = IDACalcIC(mem, IDA_YA_YDP_INIT, tNow+1e-01*dt);
  320. // if(check_flag(&ier, "IDACalcIC", 1)){
  321. // ier = IDACalcIC(mem, IDA_YA_YDP_INIT, tNow+1e+01*dt);
  322. // }
  323. // //Every once in a while, for reasons
  324. // //that befuddle this mathematically
  325. // //lesser author, IDACalcIC fails. Here,
  326. // //I desperately try to make it converge
  327. // //again by sampling increasingly larger
  328. // //time-steps:
  329. // for (int i = 0; i < 10; i++) {
  330. // ier = IDACalcIC(mem, IDA_YA_YDP_INIT, tNow+(1e-01+pow(10,i)*dt));
  331. // if(ier==0){
  332. // break;
  333. // }
  334. // }
  335. // //Failure :( Back to the drawing board:
  336. // if(check_flag(&ier, "IDACalcIC", 1)){
  337. // freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);
  338. // return(-1);
  339. // }
  340. // printf("Initial (Consistent) Conditions Calculated!\n");
  341. // printf("------------------------------------------\n\n");
  342. //
  343. // }
  344. // }
  345. /*Floor small value to zero*/
  346. //floorSmallValue(data, &y);
  347. if(count%data->nSaves==0 && !data->writeEveryRegrid){
  348. printSpaceTimeOutput(tNow, &y, data->output, data);
  349. //if(data->writeRates){
  350. // printSpaceTimeRates(tNow, ydot, data);
  351. //}
  352. }
  353. /*Get and Print Rxns Rate of Progress and Specie Rate of Production data*/
  354. /*Following code snippet will be executed only once*/
  355. // if(ii==0 && maxT >=(data->initialTemperature+data->deltaT)){
  356. // getReactions(data,&y,data->rxnROPOutput);
  357. // getSpecies(data,&y,data->spROPOutput);
  358. // ii++;
  359. // }
  360. // getTimescale(data,&y);
  361. // if(count%data->nSaves==0){
  362. // printTimescaleOutput(tNow,&y, data->timescaleOutput,data);
  363. // //printSpaceTimeOutput(tNow, &y, data->output, data);
  364. // //if(data->writeRates){
  365. // // printSpaceTimeRates(tNow, ydot, data);
  366. // //}
  367. // }
  368. /*Print global variables only if time-step is of high order!*/
  369. if(data->nTimeSteps==0){
  370. data->flamePosition[0]=0.0e0;
  371. data->flamePosition[1]=0.0e0;
  372. data->flameTime[0]=tNow;
  373. data->flameTime[1]=tNow;
  374. }
  375. ier = IDAGetNumErrTestFails(mem, &netf);
  376. ier = IDAGetNumNonlinSolvConvFails(mem, &ncfn);
  377. ier = IDADlsGetNumJacEvals(mem, &njevals);
  378. ier = IDADlsGetNumResEvals(mem, &nrevals);
  379. printf("etf = %ld ,"
  380. "nlsf= %ld ,"
  381. "J=%ld ,"
  382. "R=%ld ,"
  383. "o=%d ,",netf, ncfn, njevals, nrevals, kcur);
  384. printf("Time=%15.6e s,",tNow);
  385. printf("dt=%15.6e s,",dt);
  386. printf("frac: %15.6e\n",dxRatio);
  387. count++;
  388. data->nTimeSteps=count;
  389. }
  390. }
  391. SUNLinSolFree(LS);
  392. SUNMatDestroy(A);
  393. freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);
  394. return(0);
  395. }
  396. void freeAtLast(void* mem,
  397. N_Vector *y,
  398. N_Vector *ydot,
  399. N_Vector *res,
  400. N_Vector *id,
  401. N_Vector *atolv,
  402. N_Vector *constraints,UserData data){
  403. IDAFree(&mem);
  404. freeSolution(y,ydot,res,id,atolv,constraints);
  405. freeUserData(data);
  406. }
  407. static int check_flag(void *flagvalue, const char *funcname, int opt)
  408. {
  409. int *errflag;
  410. /* Check if SUNDIALS function returned NULL pointer - no memory allocated */
  411. if (opt == 0 && flagvalue == NULL) {
  412. fprintf(stderr,
  413. "\nSUNDIALS_ERROR: %s() failed - returned NULL pointer\n\n",
  414. funcname);
  415. return(1);
  416. }
  417. /* Check if flag < 0 */
  418. else if (opt == 1) {
  419. errflag = (int *) flagvalue;
  420. if (*errflag < 0) {
  421. fprintf(stderr,
  422. "\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n",
  423. funcname, *errflag);
  424. return(1);
  425. }
  426. }
  427. /* Check if function returned NULL pointer - no memory allocated */
  428. else if (opt == 2 && flagvalue == NULL) {
  429. fprintf(stderr,
  430. "\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n",
  431. funcname);
  432. return(1);
  433. }
  434. return(0);
  435. }