Streamer fluid modeling - An overview of ARCoS  1.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
reaction.c
Go to the documentation of this file.
1 
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <math.h>
8 
9 #include "cdr.h"
10 #include "grid.h"
11 #include "parameters.h"
12 #include "photo.h"
13 #include "proto.h"
14 #include "react_table.h"
15 #include "species.h"
16 #include "reaction.h"
17 
18 static void fill_react_gaps ();
19 
21 extern double z_cutoff;
22 double species_written[20];
23 
27 int
28 find_species_by_name(const char *spec_name)
29 {
30  int res = -1;
31  int cnt;
32 
33  for (cnt = 0; cnt < no_species; cnt++)
34  {
35  if (strcmp(spec_index[cnt]->name, spec_name) == 0)
36  res = cnt;
37  }
38 
39  if (res == -1) {
40  printf("Species-lookup-failure: %s!\n",spec_name);
41  assert(1 == 0);
42  }
43  return res;
44 }
45 
47 void
49 {
50  react_table *rt;
51 
52  debug (3, "react_add (...)\n");
53 
54  printf("Adding reaction with table: %s\n",react->tablefile);
55 
56  rt = (react_table *) xmalloc (sizeof(react_table));
57 
58  if (react->tablefile != NULL) {
59  react_table_read(react->tablefile, rt);
60  react->rt = rt;
61  }
62 
63  react->next = reactions_list;
64  reactions_list = react;
65 }
66 
68 void
69 react_apply (reaction_t *react, cdr_grid_t *grid, int overwrite)
70 {
71  int i, ir, iz, itheta;
73  *grid_eabs;
74  double *in = NULL, *out = NULL, eabs;
75  double test;
76  double rate;
77  int pos;
78  double e1, e2, val1, val2, log_e, res, r_mod;
79  int cnt, curr_species;
80 
81  debug (3, "react_apply (..., " grid_printf_str ")\n",
82  grid_printf_args (grid));
83 
84  grid_eabs = grid->dens[no_species];
85 
86  for (i = 0; i < react->nin; i++) {
87  grid_in[i] = grid->dens[react->input[i]];
88  grid_out[i] = grid->d_dens[react->input[i]];
89  }
90 
91  for (i = react->nin; i < react->nin + react->nout; i++) {
92  grid_out[i] = grid->d_dens[react->output[i - react->nin]];
93  }
94 
95 #pragma omp parallel private(ir, iz, i, in, out)
96  {
97  /* malloc(0) is legal, but I do not want to play with fire. */
98  if (react->nin > 0) {
99  in = (double *) xmalloc (sizeof(double) * react->nin);
100  }
101 
102  /* Do not know what use nout == 0 may have, (perhaps some debugging?)
103  but we leave it here as theoretically possible. */
104  if (react->nout > 0) {
105  out = (double *) xmalloc (sizeof(double) * (react->nout + react->nin));
106  }
107 
108 
109  #pragma omp for
110  iter_grid_theta(grid, itheta) { //ITER3
111  iter_grid_z(grid, iz) { //ITER2
112  double back_dens;
113  if (sprite_module) {
114  back_dens = spr_density_at (z_at (iz, grid->level));
115  } else {
116  back_dens = 1.0;
117  }
118 
119 
120  iter_grid_r(grid, ir) { //ITER1
121  if ( z_at (iz, grid->level) < z_cutoff ) { //IF1
122  eabs = fabs (RZT(grid_eabs, ir, iz, itheta));
123  for (i = 0; i < react->nin; i++) {
124  in[i] = fabs (RZT(grid_in[i], ir, iz, itheta));
125  }
126 
127  log_e = log10(eabs);
128 
129  /* If the supplied fieldstrength falls outside the boundaries of the table,
130  return predetermined under-/overflow values */
131  if (log_e < react->rt->e_min) {
132  rate = react->rt->underflow;
133  } else if (log_e > react->rt->e_min + react->rt->e_step * react->rt->steps) {
134  rate = react->rt->overflow;
135  } else {
136  pos = floor((log_e - react->rt->e_min) / react->rt->e_step);
137  val1 = react->rt->values[pos];
138  val2 = react->rt->values[pos+1];
139  e1 = pow(10, react->rt->e_min + react->rt->e_step * (double) pos);
140  e2 = e1 * pow(10, react->rt->e_step);
141 
142  rate = val1 + ((val2 - val1) / (e2 - e1)) * (eabs - e1);
143  }
144 
145  for (i = 0; i < react->nin; i++){ rate *= MYMAX(0, in[i]); }
146 
147  for (i = 0; i < react->nin + react->nout; i++) { //FOR1
148  if (i < react->nin) {
149  curr_species = react->input[i]; r_mod = -rate;
150  } else { curr_species = react->output[i - react->nin]; r_mod = rate; }
151 
152  if (spec_index[curr_species]->charge != 0.0) {
153  RZT(grid_out[i], ir, iz, itheta) += r_mod;
154  }
155  } //FOR1
156  } //IF1
157  } //ITER1
158  } //ITER2
159  } //ITER3
160  free (in);
161  free (out);
162  }
163 }
164 
166 void
167 react_apply_r (reaction_t *react, cdr_grid_t *grid, int overwrite)
168 {
169  cdr_grid_t *child;
170 
171  react_apply (react, grid, overwrite);
172 
173  iter_childs (grid, child) {
174  react_apply_r (react, child, overwrite);
175  }
176 }
177 
179 void
181 {
182  int ir, iz, itheta, i;
183 
184  iter_grid_3d (grid, ir, iz, itheta)
185  for (i = 0; i < no_species; i++) {
186  RZT(grid->d_dens[i], ir, iz, itheta) = 0.0;
187  }
188 }
189 
191 void
193 {
194  reaction_t *react;
195  int overwrite;
196  int last = -1;
197  int cnt;
198 
199  zero_fill(grid);
200 
201  overwrite = TRUE;
202 
203  for (react = reactions_list; react; react = react->next) {
204  if (react->is_photo) {
205  photo_calc (photo_terms, grid);
206  } else {
207  react_apply_r (react, grid, overwrite);
208  }
209  overwrite = FALSE;
210  }
211 }
212 
214 static void
216 {
217 }
218 
220 void
222 {
223  /* Note that the reactions are applied in inverse order than listed here. */
224  /* Rest of the kinetic model: */
225  kinetic_init ();
226 
227 }
228 
231 #define EPS_EABS 1e-6