PageRenderTime 57ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/src/enzo/oxygen_solver.C

https://bitbucket.org/devinsilvia/enzo-dengo-devin
C | 2123 lines | 1231 code | 563 blank | 329 comment | 149 complexity | b918f9adf7d459fef04598a0d7a5b104 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. /* THIS FILE HAS BEEN AUTO-GENERATED. DO NOT EDIT. */
  2. /* This is C++ code to read HDF5 files for
  3. reaction rates, cooling rates, and initial
  4. conditions for the chemical network defined
  5. by the user. In addition, this contains
  6. code for calculating temperature from the
  7. gas energy and computing the RHS and the
  8. Jacobian of the system of equations which
  9. will be fed into the solver.
  10. */
  11. #include <alloca.h>
  12. #include "oxygen_solver.h"
  13. oxygen_data *oxygen_setup_data(void) {
  14. oxygen_data *data = (oxygen_data *) malloc(sizeof(oxygen_data));
  15. data->bounds[0] = 1.0;
  16. data->bounds[1] = 1000000000000.0;
  17. data->nbins = 1024;
  18. data->dbin = (log(data->bounds[1]) - log(data->bounds[0])) / data->nbins;
  19. data->idbin = 1.0L / data->dbin;
  20. oxygen_read_rate_tables(data);
  21. fprintf(stderr, "Successfully read in rate tables.\n");
  22. oxygen_read_cooling_tables(data);
  23. fprintf(stderr, "Successfully read in cooling rate tables.\n");
  24. return data;
  25. }
  26. int oxygen_main(int argc, char** argv)
  27. {
  28. oxygen_data *data = oxygen_setup_data();
  29. /* Initial conditions */
  30. hid_t file_id = H5Fopen("oxygen_initial_conditions.h5", H5F_ACC_RDONLY, H5P_DEFAULT);
  31. if (file_id < 0) {fprintf(stderr, "Failed to open "
  32. "oxygen_initial_conditions.h5 so dying.\n");
  33. return(1);}
  34. /* Allocate the correct number of cells */
  35. hsize_t dims; /* We have flat versus number of species */
  36. /* Check gas energy to get the number of cells */
  37. fprintf(stderr, "Getting dimensionality from ge:\n");
  38. herr_t status = H5LTget_dataset_info(file_id, "/ge", &dims, NULL, NULL);
  39. if(status == -1) {
  40. fprintf(stderr, "Error opening initial conditions file.\n");
  41. return 1;
  42. }
  43. fprintf(stderr, " ncells = % 3i\n", (int) dims);
  44. data->ncells = dims;
  45. int N = 11;
  46. double *atol, *rtol;
  47. atol = (double *) alloca(N * dims * sizeof(double));
  48. rtol = (double *) alloca(N * dims * sizeof(double));
  49. double *tics = (double *) alloca(dims * sizeof(double));
  50. double *ics = (double *) alloca(dims * N * sizeof(double));
  51. double *input = (double *) alloca(dims * N * sizeof(double));
  52. unsigned int i = 0, j;
  53. fprintf(stderr, "Reading I.C. for /ge\n");
  54. H5LTread_dataset_double(file_id, "/ge", tics);
  55. for (j = 0; j < dims; j++) {
  56. ics[j * N + i] = tics[j] / 1.0; /* Convert to number density */
  57. atol[j * N + i] = tics[j] * 1e-06;
  58. rtol[j * N + i] = 1e-06;
  59. if(j==0) {
  60. fprintf(stderr, "ge[0] = %0.3g, atol => % 0.16g\n",
  61. tics[j], atol[j]);
  62. }
  63. }
  64. i++;
  65. fprintf(stderr, "Reading I.C. for /de\n");
  66. H5LTread_dataset_double(file_id, "/de", tics);
  67. for (j = 0; j < dims; j++) {
  68. ics[j * N + i] = tics[j] / 1.0; /* Convert to number density */
  69. atol[j * N + i] = tics[j] * 1e-06;
  70. rtol[j * N + i] = 1e-06;
  71. if(j==0) {
  72. fprintf(stderr, "de[0] = %0.3g, atol => % 0.16g\n",
  73. tics[j], atol[j]);
  74. }
  75. }
  76. i++;
  77. fprintf(stderr, "Reading I.C. for /OI\n");
  78. H5LTread_dataset_double(file_id, "/OI", tics);
  79. for (j = 0; j < dims; j++) {
  80. ics[j * N + i] = tics[j] / 16; /* Convert to number density */
  81. atol[j * N + i] = tics[j] * 1e-06;
  82. rtol[j * N + i] = 1e-06;
  83. if(j==0) {
  84. fprintf(stderr, "OI[0] = %0.3g, atol => % 0.16g\n",
  85. tics[j], atol[j]);
  86. }
  87. }
  88. i++;
  89. fprintf(stderr, "Reading I.C. for /OVII\n");
  90. H5LTread_dataset_double(file_id, "/OVII", tics);
  91. for (j = 0; j < dims; j++) {
  92. ics[j * N + i] = tics[j] / 16; /* Convert to number density */
  93. atol[j * N + i] = tics[j] * 1e-06;
  94. rtol[j * N + i] = 1e-06;
  95. if(j==0) {
  96. fprintf(stderr, "OVII[0] = %0.3g, atol => % 0.16g\n",
  97. tics[j], atol[j]);
  98. }
  99. }
  100. i++;
  101. fprintf(stderr, "Reading I.C. for /OII\n");
  102. H5LTread_dataset_double(file_id, "/OII", tics);
  103. for (j = 0; j < dims; j++) {
  104. ics[j * N + i] = tics[j] / 16; /* Convert to number density */
  105. atol[j * N + i] = tics[j] * 1e-06;
  106. rtol[j * N + i] = 1e-06;
  107. if(j==0) {
  108. fprintf(stderr, "OII[0] = %0.3g, atol => % 0.16g\n",
  109. tics[j], atol[j]);
  110. }
  111. }
  112. i++;
  113. fprintf(stderr, "Reading I.C. for /OVI\n");
  114. H5LTread_dataset_double(file_id, "/OVI", tics);
  115. for (j = 0; j < dims; j++) {
  116. ics[j * N + i] = tics[j] / 16; /* Convert to number density */
  117. atol[j * N + i] = tics[j] * 1e-06;
  118. rtol[j * N + i] = 1e-06;
  119. if(j==0) {
  120. fprintf(stderr, "OVI[0] = %0.3g, atol => % 0.16g\n",
  121. tics[j], atol[j]);
  122. }
  123. }
  124. i++;
  125. fprintf(stderr, "Reading I.C. for /OIII\n");
  126. H5LTread_dataset_double(file_id, "/OIII", tics);
  127. for (j = 0; j < dims; j++) {
  128. ics[j * N + i] = tics[j] / 16; /* Convert to number density */
  129. atol[j * N + i] = tics[j] * 1e-06;
  130. rtol[j * N + i] = 1e-06;
  131. if(j==0) {
  132. fprintf(stderr, "OIII[0] = %0.3g, atol => % 0.16g\n",
  133. tics[j], atol[j]);
  134. }
  135. }
  136. i++;
  137. fprintf(stderr, "Reading I.C. for /OIV\n");
  138. H5LTread_dataset_double(file_id, "/OIV", tics);
  139. for (j = 0; j < dims; j++) {
  140. ics[j * N + i] = tics[j] / 16; /* Convert to number density */
  141. atol[j * N + i] = tics[j] * 1e-06;
  142. rtol[j * N + i] = 1e-06;
  143. if(j==0) {
  144. fprintf(stderr, "OIV[0] = %0.3g, atol => % 0.16g\n",
  145. tics[j], atol[j]);
  146. }
  147. }
  148. i++;
  149. fprintf(stderr, "Reading I.C. for /OV\n");
  150. H5LTread_dataset_double(file_id, "/OV", tics);
  151. for (j = 0; j < dims; j++) {
  152. ics[j * N + i] = tics[j] / 16; /* Convert to number density */
  153. atol[j * N + i] = tics[j] * 1e-06;
  154. rtol[j * N + i] = 1e-06;
  155. if(j==0) {
  156. fprintf(stderr, "OV[0] = %0.3g, atol => % 0.16g\n",
  157. tics[j], atol[j]);
  158. }
  159. }
  160. i++;
  161. fprintf(stderr, "Reading I.C. for /OVIII\n");
  162. H5LTread_dataset_double(file_id, "/OVIII", tics);
  163. for (j = 0; j < dims; j++) {
  164. ics[j * N + i] = tics[j] / 16; /* Convert to number density */
  165. atol[j * N + i] = tics[j] * 1e-06;
  166. rtol[j * N + i] = 1e-06;
  167. if(j==0) {
  168. fprintf(stderr, "OVIII[0] = %0.3g, atol => % 0.16g\n",
  169. tics[j], atol[j]);
  170. }
  171. }
  172. i++;
  173. fprintf(stderr, "Reading I.C. for /OIX\n");
  174. H5LTread_dataset_double(file_id, "/OIX", tics);
  175. for (j = 0; j < dims; j++) {
  176. ics[j * N + i] = tics[j] / 16; /* Convert to number density */
  177. atol[j * N + i] = tics[j] * 1e-06;
  178. rtol[j * N + i] = 1e-06;
  179. if(j==0) {
  180. fprintf(stderr, "OIX[0] = %0.3g, atol => % 0.16g\n",
  181. tics[j], atol[j]);
  182. }
  183. }
  184. i++;
  185. H5Fclose(file_id);
  186. double dtf = 2e17;
  187. double dt = -1.0;
  188. for (i = 0; i < dims * N; i++) input[i] = ics[i];
  189. double ttot;
  190. ttot = dengo_evolve_oxygen(dtf, dt, input, rtol, atol, dims, data);
  191. /* Write results to HDF5 file */
  192. file_id = H5Fcreate("oxygen_solution.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
  193. hsize_t dimsarr[1];
  194. dimsarr[0] = dims;
  195. i = 0;
  196. double ge[dims];
  197. for (j = 0; j < dims; j++) {
  198. ge[j] = input[j * N + i] * 1.0;
  199. }
  200. fprintf(stderr, "Writing solution for /ge\n");
  201. H5LTmake_dataset_double(file_id, "/ge", 1, dimsarr, ge);
  202. i++;
  203. double de[dims];
  204. for (j = 0; j < dims; j++) {
  205. de[j] = input[j * N + i] * 1.0;
  206. }
  207. fprintf(stderr, "Writing solution for /de\n");
  208. H5LTmake_dataset_double(file_id, "/de", 1, dimsarr, de);
  209. i++;
  210. double OI[dims];
  211. for (j = 0; j < dims; j++) {
  212. OI[j] = input[j * N + i] * 16;
  213. }
  214. fprintf(stderr, "Writing solution for /OI\n");
  215. H5LTmake_dataset_double(file_id, "/OI", 1, dimsarr, OI);
  216. i++;
  217. double OVII[dims];
  218. for (j = 0; j < dims; j++) {
  219. OVII[j] = input[j * N + i] * 16;
  220. }
  221. fprintf(stderr, "Writing solution for /OVII\n");
  222. H5LTmake_dataset_double(file_id, "/OVII", 1, dimsarr, OVII);
  223. i++;
  224. double OII[dims];
  225. for (j = 0; j < dims; j++) {
  226. OII[j] = input[j * N + i] * 16;
  227. }
  228. fprintf(stderr, "Writing solution for /OII\n");
  229. H5LTmake_dataset_double(file_id, "/OII", 1, dimsarr, OII);
  230. i++;
  231. double OVI[dims];
  232. for (j = 0; j < dims; j++) {
  233. OVI[j] = input[j * N + i] * 16;
  234. }
  235. fprintf(stderr, "Writing solution for /OVI\n");
  236. H5LTmake_dataset_double(file_id, "/OVI", 1, dimsarr, OVI);
  237. i++;
  238. double OIII[dims];
  239. for (j = 0; j < dims; j++) {
  240. OIII[j] = input[j * N + i] * 16;
  241. }
  242. fprintf(stderr, "Writing solution for /OIII\n");
  243. H5LTmake_dataset_double(file_id, "/OIII", 1, dimsarr, OIII);
  244. i++;
  245. double OIV[dims];
  246. for (j = 0; j < dims; j++) {
  247. OIV[j] = input[j * N + i] * 16;
  248. }
  249. fprintf(stderr, "Writing solution for /OIV\n");
  250. H5LTmake_dataset_double(file_id, "/OIV", 1, dimsarr, OIV);
  251. i++;
  252. double OV[dims];
  253. for (j = 0; j < dims; j++) {
  254. OV[j] = input[j * N + i] * 16;
  255. }
  256. fprintf(stderr, "Writing solution for /OV\n");
  257. H5LTmake_dataset_double(file_id, "/OV", 1, dimsarr, OV);
  258. i++;
  259. double OVIII[dims];
  260. for (j = 0; j < dims; j++) {
  261. OVIII[j] = input[j * N + i] * 16;
  262. }
  263. fprintf(stderr, "Writing solution for /OVIII\n");
  264. H5LTmake_dataset_double(file_id, "/OVIII", 1, dimsarr, OVIII);
  265. i++;
  266. double OIX[dims];
  267. for (j = 0; j < dims; j++) {
  268. OIX[j] = input[j * N + i] * 16;
  269. }
  270. fprintf(stderr, "Writing solution for /OIX\n");
  271. H5LTmake_dataset_double(file_id, "/OIX", 1, dimsarr, OIX);
  272. i++;
  273. double temperature[dims];
  274. for (j = 0; j < dims; j++) {
  275. temperature[j] = data->Ts[j];
  276. }
  277. H5LTmake_dataset_double(file_id, "/T", 1, dimsarr, temperature);
  278. double time[1];
  279. time[0] = ttot;
  280. double timestep[1];
  281. timestep[0] = dt;
  282. H5LTset_attribute_double(file_id, "/", "time", time, 1);
  283. H5LTset_attribute_double(file_id, "/", "timestep", timestep, 1);
  284. H5Fclose(file_id);
  285. return 0;
  286. }
  287. double dengo_evolve_oxygen (double dtf, double &dt, double *input,
  288. double *rtol, double *atol, long long dims, oxygen_data *data) {
  289. int i, j;
  290. hid_t file_id;
  291. /*fprintf(stderr, " ncells = % 3i\n", (int) dims);*/
  292. int N = 11;
  293. rhs_f f = calculate_rhs_oxygen;
  294. jac_f jf = calculate_jacobian_oxygen;
  295. if (dt < 0) dt = dtf / 1000.0;
  296. int niter = 0;
  297. int siter = 0;
  298. double ttot = 0;
  299. double *scale = (double *) alloca(dims * N * sizeof(double));
  300. double *prev = (double *) alloca(dims * N * sizeof(double));
  301. for (i = 0; i < dims * N; i++) scale[i] = 1.0;
  302. for (i = 0; i < dims * N; i++) prev[i] = input[i];
  303. double *u0 = (double *) alloca(N*dims*sizeof(double));
  304. double *s = (double *) alloca(N*sizeof(double));
  305. double *gu = (double *) alloca(N*dims*sizeof(double));
  306. double *Ju = (double *) alloca(N*N*dims*sizeof(double));
  307. double floor_value = 1e-25;
  308. double pssum, issum, sumdiff;
  309. int snum;
  310. int relaxed0 = 0;
  311. int relaxed1 = 0;
  312. int relaxed2 = 0;
  313. int maxspeciesi;
  314. double maxspeciesval;
  315. /*
  316. for (i = 0; i < dims * N; i++) {
  317. fprintf(stderr, "rtol[%d] = %0.5g \n", i, rtol[i]);
  318. }
  319. */
  320. while (ttot < dtf) {
  321. int rv = BE_chem_solve(f, jf, input, dt, rtol, atol, dims, N,
  322. scale, (void *) data, u0, s, gu, Ju);
  323. /*
  324. fprintf(stderr, "Return value [%d]: %i. %0.5g / %0.5g = %0.5g (%0.5g)\n",
  325. niter, rv, ttot, dtf, ttot/dtf, dt);
  326. fprintf(stderr, "Value[80] = %0.5g %0.5g %0.5g\n",
  327. input[80], prev[80]);//, ics[80]);
  328. */
  329. for (i = 0; i < dims * N; i++) {
  330. if (input[i] < 0) {
  331. rv = 1;
  332. //fprintf(stderr, "rv = 1, input[%d] = %0.5g\n", i, input[i]);
  333. break;
  334. }
  335. }
  336. if (rv == 0) {
  337. if (siter == 99999999) {
  338. fprintf(stderr, "Hit maximum number of successful iterations allowed.\n");
  339. break;
  340. }
  341. siter++;
  342. if (siter % 100000 == 0) {
  343. fprintf(stderr, "Successful Iteration[%d]: (%0.4g) %0.6g / %0.6g = %0.6g \n",
  344. siter, dt, ttot, dtf, ttot/dtf);
  345. }
  346. ttot += dt;
  347. dt = DMIN(dt * 1.1, dtf - ttot);
  348. if (dt/dtf > 1e-9 && relaxed2 == 1) {
  349. relaxed2 = 0;
  350. for (i = 0; i < dims * N; i++) rtol[i] *= 0.2;
  351. }
  352. if (dt/dtf > 1e-6 && relaxed1 == 1) {
  353. relaxed1 = 0;
  354. for (i = 0; i < dims * N; i++) rtol[i] *= 0.1;
  355. }
  356. if (dt/dtf > 1e-3 && relaxed0 == 1) {
  357. relaxed0 = 0;
  358. for (i = 0; i < dims * N; i++) rtol[i] *= 0.1;
  359. }
  360. for (i = 0; i < dims * N; i++) prev[i] = input[i];
  361. for (i = 0; i < dims * N; i++) {
  362. if (input[i] < floor_value)
  363. input[i] = floor_value; //Do I need to worry about conservation of species
  364. //here? dealt with below (maybe)
  365. }
  366. pssum = 0.0;
  367. issum = 0.0;
  368. maxspeciesval = 0.0;
  369. maxspeciesi = -1;
  370. for (i = 0; i < dims * N; i++) { //this conservation check method only works
  371. //if solving one cell at a time
  372. snum = i % N;
  373. if (snum == 0) continue;
  374. if (snum == 1) {
  375. input[i] = prev[i]; //we need to make sure electrons aren't floored
  376. //or everything gets weird (I think)
  377. continue;
  378. }
  379. if (prev[i] > maxspeciesval) { //which species is largest?
  380. maxspeciesval = prev[i];
  381. maxspeciesi = i;
  382. }
  383. pssum += prev[i];
  384. issum += input[i];
  385. if (snum == (N - 1)) {
  386. sumdiff = issum - pssum; //how much extra species density did we
  387. //generate by flooring?
  388. if (sumdiff > 0.0) {
  389. //fprintf(stderr, "The amount of extra species generated by flooring values was: %0.5g, max species = %d\n", sumdiff, maxspeciesi);
  390. input[maxspeciesi] -= sumdiff; // to maintain conservation, take it out of
  391. //the most abundant ion (ONLY WORKS IF THERE IS A
  392. //SINGLE ELEMENT)
  393. }
  394. pssum = 0.0; // at end, reset
  395. issum = 0.0; // at end, reset
  396. }
  397. }
  398. } else {
  399. dt /= 2.0;
  400. if (dt/dtf < 1e-6 && relaxed0 == 0) {
  401. relaxed0 = 1;
  402. for (i = 0; i < dims * N; i++) rtol[i] *= 10.0;
  403. }
  404. if (dt/dtf < 1e-9 && relaxed1 == 0) {
  405. relaxed1 = 1;
  406. for (i = 0; i < dims * N; i++) rtol[i] *= 10.0;
  407. }
  408. if (dt/dtf < 1e-12 && relaxed2 == 0) {
  409. relaxed2 = 1;
  410. for (i = 0; i < dims * N; i++) rtol[i] *= 5.0;
  411. }
  412. for (i = 0; i < dims * N; i++) input[i] = prev[i];
  413. if (dt/dtf < 1e-15) {
  414. fprintf(stderr, "Dying! dt/dtf = %0.5g\n", dt/dtf);
  415. break;
  416. }
  417. }
  418. niter++;
  419. }
  420. /*fprintf(stderr, "End: %0.5g / %0.5g (%0.5g)\n",
  421. ttot, dtf, dtf-ttot);*/
  422. return ttot;
  423. }
  424. void oxygen_read_rate_tables(oxygen_data *data)
  425. {
  426. hid_t file_id = H5Fopen("oxygen_tables.h5", H5F_ACC_RDONLY, H5P_DEFAULT);
  427. /* Allocate the correct number of rate tables */
  428. H5LTread_dataset_double(file_id, "/OI_i", data->r_OI_i);
  429. H5LTread_dataset_double(file_id, "/OII_i", data->r_OII_i);
  430. H5LTread_dataset_double(file_id, "/OII_r", data->r_OII_r);
  431. H5LTread_dataset_double(file_id, "/OIII_i", data->r_OIII_i);
  432. H5LTread_dataset_double(file_id, "/OIII_r", data->r_OIII_r);
  433. H5LTread_dataset_double(file_id, "/OIV_i", data->r_OIV_i);
  434. H5LTread_dataset_double(file_id, "/OIV_r", data->r_OIV_r);
  435. H5LTread_dataset_double(file_id, "/OIX_r", data->r_OIX_r);
  436. H5LTread_dataset_double(file_id, "/OV_i", data->r_OV_i);
  437. H5LTread_dataset_double(file_id, "/OV_r", data->r_OV_r);
  438. H5LTread_dataset_double(file_id, "/OVI_i", data->r_OVI_i);
  439. H5LTread_dataset_double(file_id, "/OVI_r", data->r_OVI_r);
  440. H5LTread_dataset_double(file_id, "/OVII_i", data->r_OVII_i);
  441. H5LTread_dataset_double(file_id, "/OVII_r", data->r_OVII_r);
  442. H5LTread_dataset_double(file_id, "/OVIII_i", data->r_OVIII_i);
  443. H5LTread_dataset_double(file_id, "/OVIII_r", data->r_OVIII_r);
  444. H5Fclose(file_id);
  445. }
  446. void oxygen_read_cooling_tables(oxygen_data *data)
  447. {
  448. hid_t file_id = H5Fopen("oxygen_tables.h5", H5F_ACC_RDONLY, H5P_DEFAULT);
  449. /* Allocate the correct number of rate tables */
  450. H5Fclose(file_id);
  451. }
  452. void oxygen_calculate_temperature(oxygen_data *data,
  453. double *input, int nstrip, int nchem)
  454. {
  455. int i, j;
  456. double density;
  457. double kb = 1.3806504e-16; // Boltzmann constant [erg/K]
  458. double mh = 1.67e-24;
  459. double gamma = 5.e0/3.e0;
  460. /* Calculate total density */
  461. double ge;
  462. double de;
  463. double OI;
  464. double OVII;
  465. double OII;
  466. double OVI;
  467. double OIII;
  468. double OIV;
  469. double OV;
  470. double OVIII;
  471. double OIX;
  472. for (i = 0; i<nstrip; i++) {
  473. j = i * nchem;
  474. ge = input[j];
  475. /*fprintf(stderr, "ge[%d] = % 0.16g\n",
  476. i, ge);*/
  477. j++;
  478. de = input[j];
  479. /*fprintf(stderr, "de[%d] = % 0.16g\n",
  480. i, de);*/
  481. j++;
  482. OI = input[j];
  483. /*fprintf(stderr, "OI[%d] = % 0.16g\n",
  484. i, OI);*/
  485. j++;
  486. OVII = input[j];
  487. /*fprintf(stderr, "OVII[%d] = % 0.16g\n",
  488. i, OVII);*/
  489. j++;
  490. OII = input[j];
  491. /*fprintf(stderr, "OII[%d] = % 0.16g\n",
  492. i, OII);*/
  493. j++;
  494. OVI = input[j];
  495. /*fprintf(stderr, "OVI[%d] = % 0.16g\n",
  496. i, OVI);*/
  497. j++;
  498. OIII = input[j];
  499. /*fprintf(stderr, "OIII[%d] = % 0.16g\n",
  500. i, OIII);*/
  501. j++;
  502. OIV = input[j];
  503. /*fprintf(stderr, "OIV[%d] = % 0.16g\n",
  504. i, OIV);*/
  505. j++;
  506. OV = input[j];
  507. /*fprintf(stderr, "OV[%d] = % 0.16g\n",
  508. i, OV);*/
  509. j++;
  510. OVIII = input[j];
  511. /*fprintf(stderr, "OVIII[%d] = % 0.16g\n",
  512. i, OVIII);*/
  513. j++;
  514. OIX = input[j];
  515. /*fprintf(stderr, "OIX[%d] = % 0.16g\n",
  516. i, OIX);*/
  517. j++;
  518. // density = 16*OI + 16*OII + 16*OIII + 16*OIV + 16*OIX + 16*OV + 16*OVI + 16*OVII + 16*OVIII;
  519. /*density = (OI + OII + OIII + OIV + OIX + OV + OVI + OVII + OVIII) * 1e5;
  520. data->Ts[i] = density*ge*mh/(kb*((OI/(gamma - 1.0) + OII/(gamma - 1.0) + OIII/(gamma - 1.0) + OIV/(gamma - 1.0) + OIX/(gamma - 1.0) + OV/(gamma - 1.0) + OVI/(gamma - 1.0) + OVII/(gamma - 1.0) + OVIII/(gamma - 1.0))*1e5));// + de/(gamma - 1.0)))*1e5);
  521. data->Ts[i] *= 0.6;*/
  522. data->Ts[i] = ((gamma - 1.0) * 0.6 * mh * ge) / kb; // THIS IS A HACK, BUT IT WILL WORK FOR NOW
  523. if (data->Ts[i] < data->bounds[0]) {
  524. data->Ts[i] = data->bounds[0];
  525. } else if (data->Ts[i] > data->bounds[1]) {
  526. data->Ts[i] = data->bounds[1];
  527. }
  528. data->logTs[i] = log(data->Ts[i]);
  529. /* data->dTs_ge[i] = density*mh/(kb*((OI/(gamma - 1.0) + OII/(gamma - 1.0) + OIII/(gamma - 1.0) + OIV/(gamma - 1.0) + OIX/(gamma - 1.0) + OV/(gamma - 1.0) + OVI/(gamma - 1.0) + OVII/(gamma - 1.0) + OVIII/(gamma - 1.0))*1e5));// + de/(gamma - 1.0)))*1e5);
  530. data->dTs_ge[i] *= 0.6;*/
  531. data->dTs_ge[i] = ((gamma - 1.0) * 0.6 * mh) / kb; // THIS IS A HACK, BUT IT WILL WORK FOR NOW
  532. /*fprintf(stderr, "T[%d] = % 0.16g, density = % 0.16g, ge = % 0.16g \n",
  533. i, data->Ts[i], density, ge);*/
  534. }
  535. }
  536. /*
  537. This setup may be different than the user may anticipate, as a result
  538. of the lockstep timestep we use for a pencil beam through the grid.
  539. As such, it accepts the number of things to interpolate and makes
  540. assumptions about the sizes of the rates.
  541. */
  542. /* This also requires no templating other than for the solver name...*/
  543. void oxygen_interpolate_rates(oxygen_data *data,
  544. int nstrip)
  545. {
  546. int i, bin_id;
  547. double lb, t1, t2;
  548. lb = log(data->bounds[0]);
  549. /*fprintf(stderr, "lb = % 0.16g, ub = % 0.16g\n", lb, ub);*/
  550. for (i = 0; i < nstrip; i++) {
  551. data->bin_id[i] = bin_id = (int) (data->idbin * (data->logTs[i] - lb));
  552. if (data->bin_id[i] <= 0) {
  553. data->bin_id[i] = 1;
  554. } else if (data->bin_id[i] >= data->nbins) {
  555. data->bin_id[i] = data->nbins - 1;
  556. }
  557. t1 = (lb + (bin_id - 1) * data->dbin);
  558. t2 = (lb + (bin_id ) * data->dbin);
  559. data->Tdef[i] = (data->logTs[i] - t1)/(t2 - t1);
  560. data->dT[i] = (t2 - t1);
  561. /*fprintf(stderr, "INTERP: %d, bin_id = %d, dT = % 0.16g, T = % 0.16g, logT = % 0.16g\n",
  562. i, data->bin_id[i], data->dT[i], data->Ts[i],
  563. data->logTs[i]);*/
  564. }
  565. for (i = 0; i < nstrip; i++) {
  566. bin_id = data->bin_id[i];
  567. data->rs_OI_i[i] = data->r_OI_i[bin_id] +
  568. data->Tdef[i] * (data->r_OI_i[bin_id+1] - data->r_OI_i[bin_id]);
  569. data->drs_OI_i[i] = (data->r_OI_i[bin_id+1] - data->r_OI_i[bin_id]);
  570. data->drs_OI_i[i] /= data->dT[i];
  571. data->drs_OI_i[i] /= data->Ts[i];
  572. }
  573. for (i = 0; i < nstrip; i++) {
  574. bin_id = data->bin_id[i];
  575. data->rs_OII_i[i] = data->r_OII_i[bin_id] +
  576. data->Tdef[i] * (data->r_OII_i[bin_id+1] - data->r_OII_i[bin_id]);
  577. data->drs_OII_i[i] = (data->r_OII_i[bin_id+1] - data->r_OII_i[bin_id]);
  578. data->drs_OII_i[i] /= data->dT[i];
  579. data->drs_OII_i[i] /= data->Ts[i];
  580. }
  581. for (i = 0; i < nstrip; i++) {
  582. bin_id = data->bin_id[i];
  583. data->rs_OII_r[i] = data->r_OII_r[bin_id] +
  584. data->Tdef[i] * (data->r_OII_r[bin_id+1] - data->r_OII_r[bin_id]);
  585. data->drs_OII_r[i] = (data->r_OII_r[bin_id+1] - data->r_OII_r[bin_id]);
  586. data->drs_OII_r[i] /= data->dT[i];
  587. data->drs_OII_r[i] /= data->Ts[i];
  588. }
  589. for (i = 0; i < nstrip; i++) {
  590. bin_id = data->bin_id[i];
  591. data->rs_OIII_i[i] = data->r_OIII_i[bin_id] +
  592. data->Tdef[i] * (data->r_OIII_i[bin_id+1] - data->r_OIII_i[bin_id]);
  593. data->drs_OIII_i[i] = (data->r_OIII_i[bin_id+1] - data->r_OIII_i[bin_id]);
  594. data->drs_OIII_i[i] /= data->dT[i];
  595. data->drs_OIII_i[i] /= data->Ts[i];
  596. }
  597. for (i = 0; i < nstrip; i++) {
  598. bin_id = data->bin_id[i];
  599. data->rs_OIII_r[i] = data->r_OIII_r[bin_id] +
  600. data->Tdef[i] * (data->r_OIII_r[bin_id+1] - data->r_OIII_r[bin_id]);
  601. data->drs_OIII_r[i] = (data->r_OIII_r[bin_id+1] - data->r_OIII_r[bin_id]);
  602. data->drs_OIII_r[i] /= data->dT[i];
  603. data->drs_OIII_r[i] /= data->Ts[i];
  604. }
  605. for (i = 0; i < nstrip; i++) {
  606. bin_id = data->bin_id[i];
  607. data->rs_OIV_i[i] = data->r_OIV_i[bin_id] +
  608. data->Tdef[i] * (data->r_OIV_i[bin_id+1] - data->r_OIV_i[bin_id]);
  609. data->drs_OIV_i[i] = (data->r_OIV_i[bin_id+1] - data->r_OIV_i[bin_id]);
  610. data->drs_OIV_i[i] /= data->dT[i];
  611. data->drs_OIV_i[i] /= data->Ts[i];
  612. }
  613. for (i = 0; i < nstrip; i++) {
  614. bin_id = data->bin_id[i];
  615. data->rs_OIV_r[i] = data->r_OIV_r[bin_id] +
  616. data->Tdef[i] * (data->r_OIV_r[bin_id+1] - data->r_OIV_r[bin_id]);
  617. data->drs_OIV_r[i] = (data->r_OIV_r[bin_id+1] - data->r_OIV_r[bin_id]);
  618. data->drs_OIV_r[i] /= data->dT[i];
  619. data->drs_OIV_r[i] /= data->Ts[i];
  620. }
  621. for (i = 0; i < nstrip; i++) {
  622. bin_id = data->bin_id[i];
  623. data->rs_OIX_r[i] = data->r_OIX_r[bin_id] +
  624. data->Tdef[i] * (data->r_OIX_r[bin_id+1] - data->r_OIX_r[bin_id]);
  625. data->drs_OIX_r[i] = (data->r_OIX_r[bin_id+1] - data->r_OIX_r[bin_id]);
  626. data->drs_OIX_r[i] /= data->dT[i];
  627. data->drs_OIX_r[i] /= data->Ts[i];
  628. }
  629. for (i = 0; i < nstrip; i++) {
  630. bin_id = data->bin_id[i];
  631. data->rs_OV_i[i] = data->r_OV_i[bin_id] +
  632. data->Tdef[i] * (data->r_OV_i[bin_id+1] - data->r_OV_i[bin_id]);
  633. data->drs_OV_i[i] = (data->r_OV_i[bin_id+1] - data->r_OV_i[bin_id]);
  634. data->drs_OV_i[i] /= data->dT[i];
  635. data->drs_OV_i[i] /= data->Ts[i];
  636. }
  637. for (i = 0; i < nstrip; i++) {
  638. bin_id = data->bin_id[i];
  639. data->rs_OV_r[i] = data->r_OV_r[bin_id] +
  640. data->Tdef[i] * (data->r_OV_r[bin_id+1] - data->r_OV_r[bin_id]);
  641. data->drs_OV_r[i] = (data->r_OV_r[bin_id+1] - data->r_OV_r[bin_id]);
  642. data->drs_OV_r[i] /= data->dT[i];
  643. data->drs_OV_r[i] /= data->Ts[i];
  644. }
  645. for (i = 0; i < nstrip; i++) {
  646. bin_id = data->bin_id[i];
  647. data->rs_OVI_i[i] = data->r_OVI_i[bin_id] +
  648. data->Tdef[i] * (data->r_OVI_i[bin_id+1] - data->r_OVI_i[bin_id]);
  649. data->drs_OVI_i[i] = (data->r_OVI_i[bin_id+1] - data->r_OVI_i[bin_id]);
  650. data->drs_OVI_i[i] /= data->dT[i];
  651. data->drs_OVI_i[i] /= data->Ts[i];
  652. }
  653. for (i = 0; i < nstrip; i++) {
  654. bin_id = data->bin_id[i];
  655. data->rs_OVI_r[i] = data->r_OVI_r[bin_id] +
  656. data->Tdef[i] * (data->r_OVI_r[bin_id+1] - data->r_OVI_r[bin_id]);
  657. data->drs_OVI_r[i] = (data->r_OVI_r[bin_id+1] - data->r_OVI_r[bin_id]);
  658. data->drs_OVI_r[i] /= data->dT[i];
  659. data->drs_OVI_r[i] /= data->Ts[i];
  660. }
  661. for (i = 0; i < nstrip; i++) {
  662. bin_id = data->bin_id[i];
  663. data->rs_OVII_i[i] = data->r_OVII_i[bin_id] +
  664. data->Tdef[i] * (data->r_OVII_i[bin_id+1] - data->r_OVII_i[bin_id]);
  665. data->drs_OVII_i[i] = (data->r_OVII_i[bin_id+1] - data->r_OVII_i[bin_id]);
  666. data->drs_OVII_i[i] /= data->dT[i];
  667. data->drs_OVII_i[i] /= data->Ts[i];
  668. }
  669. for (i = 0; i < nstrip; i++) {
  670. bin_id = data->bin_id[i];
  671. data->rs_OVII_r[i] = data->r_OVII_r[bin_id] +
  672. data->Tdef[i] * (data->r_OVII_r[bin_id+1] - data->r_OVII_r[bin_id]);
  673. data->drs_OVII_r[i] = (data->r_OVII_r[bin_id+1] - data->r_OVII_r[bin_id]);
  674. data->drs_OVII_r[i] /= data->dT[i];
  675. data->drs_OVII_r[i] /= data->Ts[i];
  676. }
  677. for (i = 0; i < nstrip; i++) {
  678. bin_id = data->bin_id[i];
  679. data->rs_OVIII_i[i] = data->r_OVIII_i[bin_id] +
  680. data->Tdef[i] * (data->r_OVIII_i[bin_id+1] - data->r_OVIII_i[bin_id]);
  681. data->drs_OVIII_i[i] = (data->r_OVIII_i[bin_id+1] - data->r_OVIII_i[bin_id]);
  682. data->drs_OVIII_i[i] /= data->dT[i];
  683. data->drs_OVIII_i[i] /= data->Ts[i];
  684. }
  685. for (i = 0; i < nstrip; i++) {
  686. bin_id = data->bin_id[i];
  687. data->rs_OVIII_r[i] = data->r_OVIII_r[bin_id] +
  688. data->Tdef[i] * (data->r_OVIII_r[bin_id+1] - data->r_OVIII_r[bin_id]);
  689. data->drs_OVIII_r[i] = (data->r_OVIII_r[bin_id+1] - data->r_OVIII_r[bin_id]);
  690. data->drs_OVIII_r[i] /= data->dT[i];
  691. data->drs_OVIII_r[i] /= data->Ts[i];
  692. }
  693. }
  694. int calculate_rhs_oxygen(double *input, double *rhs, int nstrip,
  695. int nchem, void *sdata)
  696. {
  697. /* We iterate over all of the rates */
  698. /* Calculate temperature first */
  699. oxygen_data *data = (oxygen_data*)sdata;
  700. int i, j;
  701. oxygen_calculate_temperature(data, input, nstrip, nchem);
  702. oxygen_interpolate_rates(data, nstrip);
  703. /* Now we set up some temporaries */
  704. //double *T = data->Ts;
  705. double *OI_i = data->rs_OI_i;
  706. double *OII_i = data->rs_OII_i;
  707. double *OII_r = data->rs_OII_r;
  708. double *OIII_i = data->rs_OIII_i;
  709. double *OIII_r = data->rs_OIII_r;
  710. double *OIV_i = data->rs_OIV_i;
  711. double *OIV_r = data->rs_OIV_r;
  712. double *OIX_r = data->rs_OIX_r;
  713. double *OV_i = data->rs_OV_i;
  714. double *OV_r = data->rs_OV_r;
  715. double *OVI_i = data->rs_OVI_i;
  716. double *OVI_r = data->rs_OVI_r;
  717. double *OVII_i = data->rs_OVII_i;
  718. double *OVII_r = data->rs_OVII_r;
  719. double *OVIII_i = data->rs_OVIII_i;
  720. double *OVIII_r = data->rs_OVIII_r;
  721. double ge;
  722. double de;
  723. double OI;
  724. double OVII;
  725. double OII;
  726. double OVI;
  727. double OIII;
  728. double OIV;
  729. double OV;
  730. double OVIII;
  731. double OIX;
  732. double mh = 1.67e-24;
  733. double total, total_e, total_de, mdensity;
  734. double floor_value = 1e-25; //this should probably be globally stored
  735. int is_floored[nchem];
  736. for (i = 0; i<nstrip; i++) {
  737. //fprintf(stderr, "T = %0.5g\n", T[i]);
  738. for (int s = 0; s < nchem; s++)
  739. is_floored[s] = 0;
  740. j = i * nchem;
  741. total = total_e = total_de = mdensity = 0.0;
  742. ge = input[j];
  743. if (ge < 0.0) {
  744. //fprintf(stderr, "RNegative[%d][ge] = % 0.16g [%d]\n",
  745. // i, ge, j);
  746. return 1;
  747. ge = 1e-20;
  748. }
  749. if (ge <= floor_value) {
  750. is_floored[j % nchem] = 1;
  751. }
  752. j++;
  753. de = input[j];
  754. if (de < 0.0) {
  755. //fprintf(stderr, "RNegative[%d][de] = % 0.16g [%d]\n",
  756. // i, de, j);
  757. return 1;
  758. de = 1e-20;
  759. }
  760. if (de <= floor_value) {
  761. is_floored[j % nchem] = 1;
  762. }
  763. j++;
  764. OI = input[j];
  765. if (OI < 0.0) {
  766. //fprintf(stderr, "RNegative[%d][OI] = % 0.16g [%d]\n",
  767. // i, OI, j);
  768. return 1;
  769. OI = 1e-20;
  770. }
  771. if (OI <= floor_value) {
  772. is_floored[j % nchem] = 1;
  773. }
  774. total+=OI * 16;
  775. j++;
  776. OVII = input[j];
  777. if (OVII < 0.0) {
  778. //fprintf(stderr, "RNegative[%d][OVII] = % 0.16g [%d]\n",
  779. // i, OVII, j);
  780. return 1;
  781. OVII = 1e-20;
  782. }
  783. if (OVII <= floor_value) {
  784. is_floored[j % nchem] = 1;
  785. }
  786. total+=OVII * 16;
  787. j++;
  788. OII = input[j];
  789. if (OII < 0.0) {
  790. //fprintf(stderr, "RNegative[%d][OII] = % 0.16g [%d]\n",
  791. // i, OII, j);
  792. return 1;
  793. OII = 1e-20;
  794. }
  795. if (OII <= floor_value) {
  796. is_floored[j % nchem] = 1;
  797. }
  798. total+=OII * 16;
  799. j++;
  800. OVI = input[j];
  801. if (OVI < 0.0) {
  802. //fprintf(stderr, "RNegative[%d][OVI] = % 0.16g [%d]\n",
  803. // i, OVI, j);
  804. return 1;
  805. OVI = 1e-20;
  806. }
  807. if (OVI <= floor_value) {
  808. is_floored[j % nchem] = 1;
  809. }
  810. total+=OVI * 16;
  811. j++;
  812. OIII = input[j];
  813. if (OIII < 0.0) {
  814. //fprintf(stderr, "RNegative[%d][OIII] = % 0.16g [%d]\n",
  815. // i, OIII, j);
  816. return 1;
  817. OIII = 1e-20;
  818. }
  819. if (OIII <= floor_value) {
  820. is_floored[j % nchem] = 1;
  821. }
  822. total+=OIII * 16;
  823. j++;
  824. OIV = input[j];
  825. if (OIV < 0.0) {
  826. //fprintf(stderr, "RNegative[%d][OIV] = % 0.16g [%d]\n",
  827. // i, OIV, j);
  828. return 1;
  829. OIV = 1e-20;
  830. }
  831. if (OIV <= floor_value) {
  832. is_floored[j % nchem] = 1;
  833. }
  834. total+=OIV * 16;
  835. j++;
  836. OV = input[j];
  837. if (OV < 0.0) {
  838. //fprintf(stderr, "RNegative[%d][OV] = % 0.16g [%d]\n",
  839. // i, OV, j);
  840. return 1;
  841. OV = 1e-20;
  842. }
  843. if (OV <= floor_value) {
  844. is_floored[j % nchem] = 1;
  845. }
  846. total+=OV * 16;
  847. j++;
  848. OVIII = input[j];
  849. if (OVIII < 0.0) {
  850. //fprintf(stderr, "RNegative[%d][OVIII] = % 0.16g [%d]\n",
  851. // i, OVIII, j);
  852. return 1;
  853. OVIII = 1e-20;
  854. }
  855. if (OVIII <= floor_value) {
  856. is_floored[j % nchem] = 1;
  857. }
  858. total+=OVIII * 16;
  859. j++;
  860. OIX = input[j];
  861. if (OIX < 0.0) {
  862. //fprintf(stderr, "RNegative[%d][OIX] = % 0.16g [%d]\n",
  863. // i, OIX, j);
  864. return 1;
  865. OIX = 1e-20;
  866. }
  867. if (OIX <= floor_value) {
  868. is_floored[j % nchem] = 1;
  869. }
  870. total+=OIX * 16;
  871. j++;
  872. mdensity = total * mh;
  873. total = 0.0;
  874. j = i * nchem;
  875. //
  876. // Species: ge
  877. //
  878. rhs[j] = 0.0;
  879. //rhs[j] /= mdensity;
  880. j++;
  881. //
  882. // Species: de
  883. //
  884. rhs[j] = OIII_i[i]*OIII*de - OIII_r[i]*OIII*de + OII_i[i]*OII*de - OII_r[i]*OII*de + OIV_i[i]*OIV*de - OIV_r[i]*OIV*de - OIX_r[i]*OIX*de + OI_i[i]*OI*de + OVIII_i[i]*OVIII*de - OVIII_r[i]*OVIII*de + OVII_i[i]*OVII*de - OVII_r[i]*OVII*de + OVI_i[i]*OVI*de - OVI_r[i]*OVI*de + OV_i[i]*OV*de - OV_r[i]*OV*de;
  885. total_de += -rhs[j];
  886. j++;
  887. //
  888. // Species: OI
  889. //
  890. rhs[j] = OII_r[i]*OII*de - OI_i[i]*OI*de;
  891. /* Already in number density, not mass density */
  892. total += rhs[j] * 16;
  893. total_e += OI * 0;
  894. total_de += rhs[j] * 0;
  895. j++;
  896. //
  897. // Species: OVII
  898. //
  899. rhs[j] = OVIII_r[i]*OVIII*de - OVII_i[i]*OVII*de - OVII_r[i]*OVII*de + OVI_i[i]*OVI*de;
  900. /* Already in number density, not mass density */
  901. total += rhs[j] * 16;
  902. total_e += OVII * 6;
  903. total_de += rhs[j] * 6;
  904. j++;
  905. //
  906. // Species: OII
  907. //
  908. rhs[j] = OIII_r[i]*OIII*de - OII_i[i]*OII*de - OII_r[i]*OII*de + OI_i[i]*OI*de;
  909. /* Already in number density, not mass density */
  910. total += rhs[j] * 16;
  911. total_e += OII * 1;
  912. total_de += rhs[j] * 1;
  913. j++;
  914. //
  915. // Species: OVI
  916. //
  917. rhs[j] = OVII_r[i]*OVII*de - OVI_i[i]*OVI*de - OVI_r[i]*OVI*de + OV_i[i]*OV*de;
  918. /* Already in number density, not mass density */
  919. total += rhs[j] * 16;
  920. total_e += OVI * 5;
  921. total_de += rhs[j] * 5;
  922. j++;
  923. //
  924. // Species: OIII
  925. //
  926. rhs[j] = -OIII_i[i]*OIII*de - OIII_r[i]*OIII*de + OII_i[i]*OII*de + OIV_r[i]*OIV*de;
  927. /* Already in number density, not mass density */
  928. total += rhs[j] * 16;
  929. total_e += OIII * 2;
  930. total_de += rhs[j] * 2;
  931. j++;
  932. //
  933. // Species: OIV
  934. //
  935. rhs[j] = OIII_i[i]*OIII*de - OIV_i[i]*OIV*de - OIV_r[i]*OIV*de + OV_r[i]*OV*de;
  936. /* Already in number density, not mass density */
  937. total += rhs[j] * 16;
  938. total_e += OIV * 3;
  939. total_de += rhs[j] * 3;
  940. j++;
  941. //
  942. // Species: OV
  943. //
  944. rhs[j] = OIV_i[i]*OIV*de + OVI_r[i]*OVI*de - OV_i[i]*OV*de - OV_r[i]*OV*de;
  945. /* Already in number density, not mass density */
  946. total += rhs[j] * 16;
  947. total_e += OV * 4;
  948. total_de += rhs[j] * 4;
  949. j++;
  950. //
  951. // Species: OVIII
  952. //
  953. rhs[j] = OIX_r[i]*OIX*de - OVIII_i[i]*OVIII*de - OVIII_r[i]*OVIII*de + OVII_i[i]*OVII*de;
  954. /* Already in number density, not mass density */
  955. total += rhs[j] * 16;
  956. total_e += OVIII * 7;
  957. total_de += rhs[j] * 7;
  958. j++;
  959. //
  960. // Species: OIX
  961. //
  962. rhs[j] = -OIX_r[i]*OIX*de + OVIII_i[i]*OVIII*de;
  963. /* Already in number density, not mass density */
  964. total += rhs[j] * 16;
  965. total_e += OIX * 8;
  966. total_de += rhs[j] * 8;
  967. j++;
  968. }
  969. return 0;
  970. }
  971. int calculate_jacobian_oxygen(double *input, double *Joutput,
  972. int nstrip, int nchem, void *sdata)
  973. {
  974. /* We iterate over all of the rates */
  975. /* Calculate temperature first */
  976. oxygen_data *data = (oxygen_data*)sdata;
  977. int i, j;
  978. oxygen_calculate_temperature(data, input, nstrip, nchem);
  979. oxygen_interpolate_rates(data, nstrip);
  980. /* Now we set up some temporaries */
  981. double *Tge = data->dTs_ge;
  982. double *OI_i = data->rs_OI_i;
  983. double *rOI_i = data->drs_OI_i;
  984. double *OII_i = data->rs_OII_i;
  985. double *rOII_i = data->drs_OII_i;
  986. double *OII_r = data->rs_OII_r;
  987. double *rOII_r = data->drs_OII_r;
  988. double *OIII_i = data->rs_OIII_i;
  989. double *rOIII_i = data->drs_OIII_i;
  990. double *OIII_r = data->rs_OIII_r;
  991. double *rOIII_r = data->drs_OIII_r;
  992. double *OIV_i = data->rs_OIV_i;
  993. double *rOIV_i = data->drs_OIV_i;
  994. double *OIV_r = data->rs_OIV_r;
  995. double *rOIV_r = data->drs_OIV_r;
  996. double *OIX_r = data->rs_OIX_r;
  997. double *rOIX_r = data->drs_OIX_r;
  998. double *OV_i = data->rs_OV_i;
  999. double *rOV_i = data->drs_OV_i;
  1000. double *OV_r = data->rs_OV_r;
  1001. double *rOV_r = data->drs_OV_r;
  1002. double *OVI_i = data->rs_OVI_i;
  1003. double *rOVI_i = data->drs_OVI_i;
  1004. double *OVI_r = data->rs_OVI_r;
  1005. double *rOVI_r = data->drs_OVI_r;
  1006. double *OVII_i = data->rs_OVII_i;
  1007. double *rOVII_i = data->drs_OVII_i;
  1008. double *OVII_r = data->rs_OVII_r;
  1009. double *rOVII_r = data->drs_OVII_r;
  1010. double *OVIII_i = data->rs_OVIII_i;
  1011. double *rOVIII_i = data->drs_OVIII_i;
  1012. double *OVIII_r = data->rs_OVIII_r;
  1013. double *rOVIII_r = data->drs_OVIII_r;
  1014. double ge;
  1015. double de;
  1016. double OI;
  1017. double OVII;
  1018. double OII;
  1019. double OVI;
  1020. double OIII;
  1021. double OIV;
  1022. double OV;
  1023. double OVIII;
  1024. double OIX;
  1025. double mh = 1.67e-24;
  1026. double total, mdensity;
  1027. for (i = 0; i<nstrip; i++) {
  1028. j = i * nchem;
  1029. total = mdensity = 0.0;
  1030. ge = input[j];
  1031. if (ge < 0.0) {
  1032. fprintf(stderr, "JNegative[%d][ge] = % 0.16g [%d]\n",
  1033. i, ge, j);
  1034. /*ge = 0.0;*/
  1035. ge = 1e-20;
  1036. return 1;
  1037. }
  1038. j++;
  1039. de = input[j];
  1040. if (de < 0.0) {
  1041. fprintf(stderr, "JNegative[%d][de] = % 0.16g [%d]\n",
  1042. i, de, j);
  1043. /*de = 0.0;*/
  1044. de = 1e-20;
  1045. return 1;
  1046. }
  1047. j++;
  1048. OI = input[j];
  1049. if (OI < 0.0) {
  1050. fprintf(stderr, "JNegative[%d][OI] = % 0.16g [%d]\n",
  1051. i, OI, j);
  1052. /*OI = 0.0;*/
  1053. OI = 1e-20;
  1054. return 1;
  1055. }
  1056. total+=OI * 16;
  1057. j++;
  1058. OVII = input[j];
  1059. if (OVII < 0.0) {
  1060. fprintf(stderr, "JNegative[%d][OVII] = % 0.16g [%d]\n",
  1061. i, OVII, j);
  1062. /*OVII = 0.0;*/
  1063. OVII = 1e-20;
  1064. return 1;
  1065. }
  1066. total+=OVII * 16;
  1067. j++;
  1068. OII = input[j];
  1069. if (OII < 0.0) {
  1070. fprintf(stderr, "JNegative[%d][OII] = % 0.16g [%d]\n",
  1071. i, OII, j);
  1072. /*OII = 0.0;*/
  1073. OII = 1e-20;
  1074. return 1;
  1075. }
  1076. total+=OII * 16;
  1077. j++;
  1078. OVI = input[j];
  1079. if (OVI < 0.0) {
  1080. fprintf(stderr, "JNegative[%d][OVI] = % 0.16g [%d]\n",
  1081. i, OVI, j);
  1082. /*OVI = 0.0;*/
  1083. OVI = 1e-20;
  1084. return 1;
  1085. }
  1086. total+=OVI * 16;
  1087. j++;
  1088. OIII = input[j];
  1089. if (OIII < 0.0) {
  1090. fprintf(stderr, "JNegative[%d][OIII] = % 0.16g [%d]\n",
  1091. i, OIII, j);
  1092. /*OIII = 0.0;*/
  1093. OIII = 1e-20;
  1094. return 1;
  1095. }
  1096. total+=OIII * 16;
  1097. j++;
  1098. OIV = input[j];
  1099. if (OIV < 0.0) {
  1100. fprintf(stderr, "JNegative[%d][OIV] = % 0.16g [%d]\n",
  1101. i, OIV, j);
  1102. /*OIV = 0.0;*/
  1103. OIV = 1e-20;
  1104. return 1;
  1105. }
  1106. total+=OIV * 16;
  1107. j++;
  1108. OV = input[j];
  1109. if (OV < 0.0) {
  1110. fprintf(stderr, "JNegative[%d][OV] = % 0.16g [%d]\n",
  1111. i, OV, j);
  1112. /*OV = 0.0;*/
  1113. OV = 1e-20;
  1114. return 1;
  1115. }
  1116. total+=OV * 16;
  1117. j++;
  1118. OVIII = input[j];
  1119. if (OVIII < 0.0) {
  1120. fprintf(stderr, "JNegative[%d][OVIII] = % 0.16g [%d]\n",
  1121. i, OVIII, j);
  1122. /*OVIII = 0.0;*/
  1123. OVIII = 1e-20;
  1124. return 1;
  1125. }
  1126. total+=OVIII * 16;
  1127. j++;
  1128. OIX = input[j];
  1129. if (OIX < 0.0) {
  1130. fprintf(stderr, "JNegative[%d][OIX] = % 0.16g [%d]\n",
  1131. i, OIX, j);
  1132. /*OIX = 0.0;*/
  1133. OIX = 1e-20;
  1134. return 1;
  1135. }
  1136. total+=OIX * 16;
  1137. j++;
  1138. mdensity = total * mh;
  1139. j = i * nchem * nchem;
  1140. //
  1141. // Species: ge
  1142. //
  1143. // ge by ge
  1144. Joutput[j] = 0.0;
  1145. //Joutput[j] /= mdensity;
  1146. Joutput[j] *= Tge[i];
  1147. j++;
  1148. // de by ge
  1149. Joutput[j] = OI*de*rOI_i[i] + OII*de*rOII_i[i] - OII*de*rOII_r[i] + OIII*de*rOIII_i[i] - OIII*de*rOIII_r[i] + OIV*de*rOIV_i[i] - OIV*de*rOIV_r[i] - OIX*de*rOIX_r[i] + OV*de*rOV_i[i] - OV*de*rOV_r[i] + OVI*de*rOVI_i[i] - OVI*de*rOVI_r[i] + OVII*de*rOVII_i[i] - OVII*de*rOVII_r[i] + OVIII*de*rOVIII_i[i] - OVIII*de*rOVIII_r[i];
  1150. Joutput[j] *= Tge[i];
  1151. j++;
  1152. // OI by ge
  1153. Joutput[j] = -OI*de*rOI_i[i] + OII*de*rOII_r[i];
  1154. Joutput[j] *= Tge[i];
  1155. j++;
  1156. // OVII by ge
  1157. Joutput[j] = OVI*de*rOVI_i[i] - OVII*de*rOVII_i[i] - OVII*de*rOVII_r[i] + OVIII*de*rOVIII_r[i];
  1158. Joutput[j] *= Tge[i];
  1159. j++;
  1160. // OII by ge
  1161. Joutput[j] = OI*de*rOI_i[i] - OII*de*rOII_i[i] - OII*de*rOII_r[i] + OIII*de*rOIII_r[i];
  1162. Joutput[j] *= Tge[i];
  1163. j++;
  1164. // OVI by ge
  1165. Joutput[j] = OV*de*rOV_i[i] - OVI*de*rOVI_i[i] - OVI*de*rOVI_r[i] + OVII*de*rOVII_r[i];
  1166. Joutput[j] *= Tge[i];
  1167. j++;
  1168. // OIII by ge
  1169. Joutput[j] = OII*de*rOII_i[i] - OIII*de*rOIII_i[i] - OIII*de*rOIII_r[i] + OIV*de*rOIV_r[i];
  1170. Joutput[j] *= Tge[i];
  1171. j++;
  1172. // OIV by ge
  1173. Joutput[j] = OIII*de*rOIII_i[i] - OIV*de*rOIV_i[i] - OIV*de*rOIV_r[i] + OV*de*rOV_r[i];
  1174. Joutput[j] *= Tge[i];
  1175. j++;
  1176. // OV by ge
  1177. Joutput[j] = OIV*de*rOIV_i[i] - OV*de*rOV_i[i] - OV*de*rOV_r[i] + OVI*de*rOVI_r[i];
  1178. Joutput[j] *= Tge[i];
  1179. j++;
  1180. // OVIII by ge
  1181. Joutput[j] = OIX*de*rOIX_r[i] + OVII*de*rOVII_i[i] - OVIII*de*rOVIII_i[i] - OVIII*de*rOVIII_r[i];
  1182. Joutput[j] *= Tge[i];
  1183. j++;
  1184. // OIX by ge
  1185. Joutput[j] = -OIX*de*rOIX_r[i] + OVIII*de*rOVIII_i[i];
  1186. Joutput[j] *= Tge[i];
  1187. j++;
  1188. //
  1189. // Species: de
  1190. //
  1191. // ge by de
  1192. Joutput[j] = 0.0;
  1193. //Joutput[j] /= mdensity;
  1194. j++;
  1195. // de by de
  1196. Joutput[j] = OIII_i[i]*OIII - OIII_r[i]*OIII + OII_i[i]*OII - OII_r[i]*OII + OIV_i[i]*OIV - OIV_r[i]*OIV - OIX_r[i]*OIX + OI_i[i]*OI + OVIII_i[i]*OVIII - OVIII_r[i]*OVIII + OVII_i[i]*OVII - OVII_r[i]*OVII + OVI_i[i]*OVI - OVI_r[i]*OVI + OV_i[i]*OV - OV_r[i]*OV;
  1197. j++;
  1198. // OI by de
  1199. Joutput[j] = OII_r[i]*OII - OI_i[i]*OI;
  1200. j++;
  1201. // OVII by de
  1202. Joutput[j] = OVIII_r[i]*OVIII - OVII_i[i]*OVII - OVII_r[i]*OVII + OVI_i[i]*OVI;
  1203. j++;
  1204. // OII by de
  1205. Joutput[j] = OIII_r[i]*OIII - OII_i[i]*OII - OII_r[i]*OII + OI_i[i]*OI;
  1206. j++;
  1207. // OVI by de
  1208. Joutput[j] = OVII_r[i]*OVII - OVI_i[i]*OVI - OVI_r[i]*OVI + OV_i[i]*OV;
  1209. j++;
  1210. // OIII by de
  1211. Joutput[j] = -OIII_i[i]*OIII - OIII_r[i]*OIII + OII_i[i]*OII + OIV_r[i]*OIV;
  1212. j++;
  1213. // OIV by de
  1214. Joutput[j] = OIII_i[i]*OIII - OIV_i[i]*OIV - OIV_r[i]*OIV + OV_r[i]*OV;
  1215. j++;
  1216. // OV by de
  1217. Joutput[j] = OIV_i[i]*OIV + OVI_r[i]*OVI - OV_i[i]*OV - OV_r[i]*OV;
  1218. j++;
  1219. // OVIII by de
  1220. Joutput[j] = OIX_r[i]*OIX - OVIII_i[i]*OVIII - OVIII_r[i]*OVIII + OVII_i[i]*OVII;
  1221. j++;
  1222. // OIX by de
  1223. Joutput[j] = -OIX_r[i]*OIX + OVIII_i[i]*OVIII;
  1224. j++;
  1225. //
  1226. // Species: OI
  1227. //
  1228. // ge by OI
  1229. Joutput[j] = 0.0;
  1230. //Joutput[j] /= mdensity;
  1231. j++;
  1232. // de by OI
  1233. Joutput[j] = OI_i[i]*de;
  1234. j++;
  1235. // OI by OI
  1236. Joutput[j] = -OI_i[i]*de;
  1237. j++;
  1238. // OVII by OI
  1239. Joutput[j] = 0.0;
  1240. j++;
  1241. // OII by OI
  1242. Joutput[j] = OI_i[i]*de;
  1243. j++;
  1244. // OVI by OI
  1245. Joutput[j] = 0.0;
  1246. j++;
  1247. // OIII by OI
  1248. Joutput[j] = 0.0;
  1249. j++;
  1250. // OIV by OI
  1251. Joutput[j] = 0.0;
  1252. j++;
  1253. // OV by OI
  1254. Joutput[j] = 0.0;
  1255. j++;
  1256. // OVIII by OI
  1257. Joutput[j] = 0.0;
  1258. j++;
  1259. // OIX by OI
  1260. Joutput[j] = 0.0;
  1261. j++;
  1262. //
  1263. // Species: OVII
  1264. //
  1265. // ge by OVII
  1266. Joutput[j] = 0.0;
  1267. //Joutput[j] /= mdensity;
  1268. j++;
  1269. // de by OVII
  1270. Joutput[j] = OVII_i[i]*de - OVII_r[i]*de;
  1271. j++;
  1272. // OI by OVII
  1273. Joutput[j] = 0.0;
  1274. j++;
  1275. // OVII by OVII
  1276. Joutput[j] = -OVII_i[i]*de - OVII_r[i]*de;
  1277. j++;
  1278. // OII by OVII
  1279. Joutput[j] = 0.0;
  1280. j++;
  1281. // OVI by OVII
  1282. Joutput[j] = OVII_r[i]*de;
  1283. j++;
  1284. // OIII by OVII
  1285. Joutput[j] = 0.0;
  1286. j++;
  1287. // OIV by OVII
  1288. Joutput[j] = 0.0;
  1289. j++;
  1290. // OV by OVII
  1291. Joutput[j] = 0.0;
  1292. j++;
  1293. // OVIII by OVII
  1294. Joutput[j] = OVII_i[i]*de;
  1295. j++;
  1296. // OIX by OVII
  1297. Joutput[j] = 0.0;
  1298. j++;
  1299. //
  1300. // Species: OII
  1301. //
  1302. // ge by OII
  1303. Joutput[j] = 0.0;
  1304. //Joutput[j] /= mdensity;
  1305. j++;
  1306. // de by OII
  1307. Joutput[j] = OII_i[i]*de - OII_r[i]*de;
  1308. j++;
  1309. // OI by OII
  1310. Joutput[j] = OII_r[i]*de;
  1311. j++;
  1312. // OVII by OII
  1313. Joutput[j] = 0.0;
  1314. j++;
  1315. // OII by OII
  1316. Joutput[j] = -OII_i[i]*de - OII_r[i]*de;
  1317. j++;
  1318. // OVI by OII
  1319. Joutput[j] = 0.0;
  1320. j++;
  1321. // OIII by OII
  1322. Joutput[j] = OII_i[i]*de;
  1323. j++;
  1324. // OIV by OII
  1325. Joutput[j] = 0.0;
  1326. j++;
  1327. // OV by OII
  1328. Joutput[j] = 0.0;
  1329. j++;
  1330. // OVIII by OII
  1331. Joutput[j] = 0.0;
  1332. j++;
  1333. // OIX by OII
  1334. Joutput[j] = 0.0;
  1335. j++;
  1336. //
  1337. // Species: OVI
  1338. //
  1339. // ge by OVI
  1340. Joutput[j] = 0.0;
  1341. //Joutput[j] /= mdensity;
  1342. j++;
  1343. // de by OVI
  1344. Joutput[j] = OVI_i[i]*de - OVI_r[i]*de;
  1345. j++;
  1346. // OI by OVI
  1347. Joutput[j] = 0.0;
  1348. j++;
  1349. // OVII by OVI
  1350. Joutput[j] = OVI_i[i]*de;
  1351. j++;
  1352. // OII by OVI
  1353. Joutput[j] = 0.0;
  1354. j++;
  1355. // OVI by OVI
  1356. Joutput[j] = -OVI_i[i]*de - OVI_r[i]*de;
  1357. j++;

Large files files are truncated, but you can click here to view the full file