Droplet Lagrangian Transient One-dimensional Reacting Code Implementation of both liquid and gas phase governing equations.
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

406 lines
11KB

  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;input=fopen("input.dat","r");
  30. UserData data;data=NULL;data=allocateUserData(input);
  31. fclose(input);
  32. data->clockStart=get_wall_time();
  33. if(data==NULL){
  34. printf("check input file!\n");
  35. freeUserData(data);
  36. return(-1);
  37. }
  38. // Allocate solution variables
  39. long int ier,mu,ml,count,netf,ncfn,njevals,nrevals;
  40. realtype tNow,*atolvdata,*constraintsdata,finalTime,dtMax,tolsfac;
  41. N_Vector y,ydot,id,res,atolv,constraints;
  42. y=ydot=id=res=atolv=constraints=NULL;
  43. ier=allocateSolution(data->neq,data->nThreads,&y,&ydot,&id,&res,&atolv,&constraints);
  44. ier=setAlgebraicVariables(&id,data);
  45. ier=setInitialCondition(&y,&ydot,data);
  46. if(ier==-1)return(-1);
  47. tNow=data->tNow;
  48. finalTime=data->finalTime;
  49. //TODO: dtMax should be a user input
  50. dtMax = 1e-4;
  51. double* ydata;
  52. double* ydotdata;
  53. ydata = N_VGetArrayPointer_OpenMP(y);
  54. ydotdata = N_VGetArrayPointer_OpenMP(ydot);
  55. ////////// DEBUG ///////////////////
  56. //double* resdata;
  57. //double* iddata;
  58. //resdata = N_VGetArrayPointer_OpenMP(res);
  59. //iddata = N_VGetArrayPointer_OpenMP(id);
  60. ///////////////////////////////////
  61. void *mem;mem=NULL;mem = IDACreate();
  62. ier = IDASetUserData(mem, data);
  63. ier = IDASetId(mem, id);
  64. ier = IDAInit(mem, residue, tNow, y, ydot);
  65. // Atol array
  66. atolvdata = N_VGetArrayPointer_OpenMP(atolv);
  67. for (size_t i = 1; i <=data->npts; i++) {
  68. atolT(i) = data->temperatureTolerance;
  69. for (size_t k = 1; k <=data->nsp; k++) {
  70. if(k!=data->k_bath){
  71. atolY(i,k) = data->massFractionTolerance;
  72. }
  73. else{
  74. atolY(i,k) = data->bathGasTolerance;
  75. }
  76. }
  77. atolR(i) = data->radiusTolerance;
  78. atolP(i) = data->pressureTolerance;
  79. atolMdot(i) = data->MdotTolerance;
  80. }
  81. ier = IDASVtolerances(mem, data->relativeTolerance, atolv);
  82. mu = 2*data->nvar; ml = mu;
  83. SUNMatrix A; A=NULL;
  84. A=SUNBandMatrix(data->neq,mu,ml,mu+ml);
  85. SUNLinearSolver LS; LS=NULL;
  86. //LS=SUNBandLinearSolver(y,A);
  87. LS=SUNLapackBand(y,A);
  88. ier=IDADlsSetLinearSolver(mem,LS,A);
  89. //ier = IDABand(mem, data->neq, mu, ml);
  90. constraintsdata = N_VGetArrayPointer_OpenMP(constraints);
  91. if(data->setConstraints){
  92. for (size_t i = 1; i <=data->npts; i++) {
  93. for (size_t k = 1; k <=data->nsp; k++) {
  94. constraintsY(i,k) = ONE;
  95. }
  96. }
  97. ier=IDASetConstraints(mem, constraints);
  98. }
  99. if(!data->quasiSteady){
  100. constraintsR(1) = ONE;
  101. ier=IDASetConstraints(mem, constraints);
  102. }
  103. ier = IDASetSuppressAlg(mem, data->suppressAlg);
  104. if(check_flag(&ier, "IDASetSuppressAlg", 1)) return(1);
  105. //ier= IDASetMaxNumStepsIC(mem, 1);
  106. //ier= IDASetMaxNumJacsIC(mem,8);
  107. //ier= IDASetMaxNumItersIC(mem,100);
  108. //ier= IDASetMaxBacksIC(mem,2000);
  109. //ier = IDASetLineSearchOffIC(mem,SUNTRUE);
  110. //////// DEBUG ///////////
  111. //if(data->dryRun){
  112. // ier = residue(tNow,y, ydot, res, data);
  113. // for(size_t k=0; k < data->nvar*data->npts; k++){
  114. // printf("%i: %15.6e\n",k,resdata[k]);
  115. // }
  116. // for(size_t k=0; k < data->nvar*data->npts; k++){
  117. // if(iddata[k] == 1){
  118. // ydotdata[k] = -resdata[k];
  119. // }
  120. // }
  121. // ier = residue(tNow,y, ydot, res, data);
  122. // for(size_t k=0; k < data->nvar*data->npts; k++){
  123. // printf("%i: %15.6e\n",k,resdata[k]);
  124. // }
  125. //}
  126. //for(size_t k=0; k < data->neq; k++){
  127. // if(iddata[k] == 1){
  128. // ydotdata[k] = -resdata[k];
  129. // }
  130. //}
  131. //////////////////////////
  132. if(!data->dryRun){
  133. printf("Calculating Initial Conditions:\n");
  134. printf("Cross your fingers...\n");
  135. ier = IDACalcIC(mem, IDA_YA_YDP_INIT, 1e-05*finalTime);
  136. //If at first IDACalcIC doesn't succeed, try, try, try again:
  137. for (int i = 0; i < 10; i++) {
  138. ier = IDACalcIC(mem, IDA_YA_YDP_INIT, (1e-01+pow(10,i)*finalTime));
  139. if(ier==0){
  140. break;
  141. }
  142. }
  143. //...or else cry again :(
  144. if(check_flag(&ier, "IDACalcIC", 1)){
  145. freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);
  146. return(-1);
  147. }else{
  148. printf("Initial (Consistent) Conditions Calculated!\n");
  149. }
  150. ier = IDASetInitStep(mem,1e-12);
  151. }
  152. printSpaceTimeHeader(data);
  153. printGlobalHeader(data);
  154. printTimescaleHeader(data);
  155. printSpaceTimeOutput(tNow, &y, data->output, data);
  156. printSpaceTimeOutput(tNow, &y, data->gridOutput, data);
  157. getTimescale(data,&y) ;
  158. printTimescaleOutput(tNow, &y, data->timescaleOutput,data);
  159. if(!data->dryRun){
  160. count=0;
  161. double dt=1e-08;
  162. double t1=0.0e0;
  163. double xOld=0.0e0;
  164. double x=0.0e0;
  165. double dx=0.0e0;
  166. double dxMin=1.0e0;
  167. double dxRatio=dx/dxMin;
  168. int move=0;
  169. int kcur=0;
  170. if(data->adaptiveGrid){
  171. dxMin=data->grid->leastMove;
  172. //xOld=maxCurvPosition(ydata, data->nt, data->nvar,
  173. // data->grid->x, data->npts);
  174. xOld=isothermPosition(ydata, data->isotherm, data->nt,
  175. data->nvar, data->grid->x, data->npts);
  176. }
  177. while (tNow<=finalTime && R(1)>100e-9) {
  178. t1=tNow;
  179. /*Floor small value to zero*/
  180. floorSmallValue(data, &y);
  181. if(data->quasiSteady){
  182. ier = IDASolve(mem, finalTime, &tNow, y, ydot, IDA_ONE_STEP);
  183. }else{
  184. /*This prevents the solver from taking a step so large that
  185. *the droplet radius becomes negative.
  186. *TODO:Try adding the constraint that the droplet radius must
  187. * be a positive number*/
  188. ier = IDASolve(mem, tNow+dtMax, &tNow, y, ydot, IDA_ONE_STEP);
  189. //ier = IDASolve(mem, tNow+dtMax, &tNow, y, ydot, IDA_NORMAL);
  190. }
  191. if(check_flag(&ier, "IDASolve", 1)){
  192. freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);
  193. return(-1);
  194. }
  195. dt=tNow-t1;
  196. ier = IDAGetCurrentOrder(mem, &kcur);
  197. if(data->adaptiveGrid==1 && data->moveGrid==1){
  198. x=maxCurvPosition(ydata, data->nt, data->nvar,
  199. data->grid->x, data->npts);
  200. //x=isothermPosition(ydata, data->isotherm, data->nt,
  201. // data->nvar, data->grid->x, data->npts);
  202. //x=maxGradPosition(ydata, data->nt, data->nvar,
  203. // data->grid->x, data->npts);
  204. dx=x-xOld;
  205. if(dx*dxMin>0.0e0){
  206. move=1;
  207. }else{
  208. move=-1;
  209. }
  210. //if(fabs(dx)>=dxMin && x+(double)(move)*0.5e0*dxMin<=1.0e0){
  211. dxRatio=fabs(dx/dxMin);
  212. if(dxRatio>=1.0e0 && dxRatio<=2.0e0){
  213. printf("Regridding!\n");
  214. data->regrid=1;
  215. printSpaceTimeOutput(tNow, &y, data->gridOutput, data);
  216. ier=reGrid(data->grid, x+(double)(move)*0.5e0*dxMin);
  217. if(ier==-1){
  218. freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);
  219. return(-1);
  220. }
  221. updateSolution(ydata, ydotdata, data->nvar,
  222. data->grid->xOld,data->grid->x,data->npts);
  223. storeGrid(data->grid->x,data->grid->xOld,data->npts);
  224. xOld=x;
  225. printf("Regrid Complete! Restarting Problem at %15.6e s\n",tNow);
  226. ier = IDAReInit(mem, tNow, y, ydot);
  227. if(check_flag(&ier, "IDAReInit", 1)){
  228. freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);
  229. return(-1);
  230. }
  231. ier = IDASetInitStep(mem,1e-01*dt);
  232. printf("Reinitialized! Calculating Initial Conditions:\n");
  233. printf("Cross your fingers...\n");
  234. ier = IDACalcIC(mem, IDA_YA_YDP_INIT, tNow+1e-01*dt);
  235. if(check_flag(&ier, "IDACalcIC", 1)){
  236. ier = IDACalcIC(mem, IDA_YA_YDP_INIT, tNow+1e+01*dt);
  237. }
  238. //Every once in a while, for reasons
  239. //that befuddle this mathematically
  240. //lesser author, IDACalcIC fails. Here,
  241. //I desperately try to make it converge
  242. //again by sampling increasingly larger
  243. //time-steps:
  244. for (int i = 0; i < 10; i++) {
  245. ier = IDACalcIC(mem, IDA_YA_YDP_INIT, tNow+(1e-01+pow(10,i)*dt));
  246. if(ier==0){
  247. break;
  248. }
  249. }
  250. //Failure :( Back to the drawing board:
  251. if(check_flag(&ier, "IDACalcIC", 1)){
  252. freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);
  253. return(-1);
  254. }
  255. printf("Initial (Consistent) Conditions Calculated!\n");
  256. printf("------------------------------------------\n\n");
  257. if(data->writeEveryRegrid){
  258. printSpaceTimeOutput(tNow, &y, data->output, data);
  259. FILE* fp;
  260. fp=fopen("restart.bin","w");
  261. writeRestart(tNow, &y, &ydot, fp, data);
  262. fclose(fp);
  263. }
  264. }
  265. }
  266. /*Floor small value to zero*/
  267. floorSmallValue(data, &y);
  268. if(count%data->nSaves==0 && !data->writeEveryRegrid){
  269. printSpaceTimeOutput(tNow, &y, data->output, data);
  270. //if(data->writeRates){
  271. // printSpaceTimeRates(tNow, ydot, data);
  272. //}
  273. }
  274. getTimescale(data,&y);
  275. if(count%data->nSaves==0){
  276. printTimescaleOutput(tNow,&y, data->timescaleOutput,data);
  277. //printSpaceTimeOutput(tNow, &y, data->output, data);
  278. //if(data->writeRates){
  279. // printSpaceTimeRates(tNow, ydot, data);
  280. //}
  281. }
  282. /*Print global variables only if time-step is of high order!*/
  283. if(data->nTimeSteps==0){
  284. data->flamePosition[0]=0.0e0;
  285. data->flamePosition[1]=0.0e0;
  286. data->flameTime[0]=tNow;
  287. data->flameTime[1]=tNow;
  288. }
  289. ier = IDAGetNumErrTestFails(mem, &netf);
  290. ier = IDAGetNumNonlinSolvConvFails(mem, &ncfn);
  291. ier = IDADlsGetNumJacEvals(mem, &njevals);
  292. ier = IDADlsGetNumResEvals(mem, &nrevals);
  293. printf("etf = %ld ,"
  294. "nlsf= %ld ,"
  295. "J=%ld ,"
  296. "R=%ld ,"
  297. "o=%d ,",netf, ncfn, njevals, nrevals, kcur);
  298. printf("Time=%15.6e s,",tNow);
  299. printf("dt=%15.6e s,",dt);
  300. printf("frac: %15.6e\n",dxRatio);
  301. count++;
  302. data->nTimeSteps=count;
  303. }
  304. }
  305. SUNLinSolFree(LS);
  306. SUNMatDestroy(A);
  307. freeAtLast(mem,&y,&ydot,&res,&id,&atolv,&constraints,data);
  308. return(0);
  309. }
  310. void freeAtLast(void* mem,
  311. N_Vector *y,
  312. N_Vector *ydot,
  313. N_Vector *res,
  314. N_Vector *id,
  315. N_Vector *atolv,
  316. N_Vector *constraints,UserData data){
  317. IDAFree(&mem);
  318. freeSolution(y,ydot,res,id,atolv,constraints);
  319. freeUserData(data);
  320. }
  321. static int check_flag(void *flagvalue, const char *funcname, int opt)
  322. {
  323. int *errflag;
  324. /* Check if SUNDIALS function returned NULL pointer - no memory allocated */
  325. if (opt == 0 && flagvalue == NULL) {
  326. fprintf(stderr,
  327. "\nSUNDIALS_ERROR: %s() failed - returned NULL pointer\n\n",
  328. funcname);
  329. return(1);
  330. }
  331. /* Check if flag < 0 */
  332. else if (opt == 1) {
  333. errflag = (int *) flagvalue;
  334. if (*errflag < 0) {
  335. fprintf(stderr,
  336. "\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n",
  337. funcname, *errflag);
  338. return(1);
  339. }
  340. }
  341. /* Check if function returned NULL pointer - no memory allocated */
  342. else if (opt == 2 && flagvalue == NULL) {
  343. fprintf(stderr,
  344. "\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n",
  345. funcname);
  346. return(1);
  347. }
  348. return(0);
  349. }