Droplet Lagrangian Transient One-dimensional Reacting Code Implementation of both liquid and gas phase governing equations.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

505 Zeilen
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. }