CAMP 1.0.0
Chemistry Across Multiple Phases
rxn_condensed_phase_photolysis.c
Go to the documentation of this file.
1/* Copyright (C) 2021 Barcelona Supercomputing Center and University of
2 * Illinois at Urbana-Champaign
3 * SPDX-License-Identifier: MIT
4 *
5 * Condensed Phase photolysis reaction solver functions
6 *
7 */
8/** \file
9 * \brief Condensed Phase photolysis reaction solver functions
10 */
11#include <math.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include "../rxns.h"
15
16#define NUM_REACT_ int_data[0]
17#define NUM_PROD_ int_data[1]
18#define NUM_AERO_PHASE_ int_data[2]
19#define RXN_ID_ int_data[3]
20#define SCALING_ float_data[0]
21#define RATE_CONSTANT_ rxn_env_data[0]
22#define BASE_RATE_ rxn_env_data[1]
23#define NUM_INT_PROP_ 4
24#define NUM_FLOAT_PROP_ 1
25#define NUM_ENV_PARAM_ 2
26#define REACT_(x) (int_data[NUM_INT_PROP_ + x] - 1)
27#define PROD_(x) \
28 (int_data[NUM_INT_PROP_ + NUM_REACT_ * NUM_AERO_PHASE_ + x] - 1)
29#define WATER_(x) \
30 (int_data[NUM_INT_PROP_ + (NUM_REACT_ + NUM_PROD_) * NUM_AERO_PHASE_ + x] - 1)
31#define DERIV_ID_(x) \
32 (int_data[NUM_INT_PROP_ + (NUM_REACT_ + NUM_PROD_ + 1) * NUM_AERO_PHASE_ + x])
33#define JAC_ID_(x) \
34 (int_data[NUM_INT_PROP_ + \
35 (2 * (NUM_REACT_ + NUM_PROD_) + 1) * NUM_AERO_PHASE_ + x])
36#define YIELD_(x) (float_data[NUM_FLOAT_PROP_ + x])
37#define KGM3_TO_MOLM3_(x) (float_data[NUM_FLOAT_PROP_ + NUM_PROD_ + x])
38
39/** \brief Flag Jacobian elements used by this reaction
40 *
41 * \param rxn_int_data Pointer to the reaction integer data
42 * \param rxn_float_data Pointer to the reaction floating-point data
43 * \param jac Jacobian
44 */
46 double *rxn_float_data,
47 Jacobian *jac) {
48 int *int_data = rxn_int_data;
49 double *float_data = rxn_float_data;
50
51 // Loop over all the instances of the specified phase
52 for (int i_phase = 0; i_phase < NUM_AERO_PHASE_; i_phase++) {
53 // Add dependence on reactants for reactants and products
54 for (int i_react_ind = i_phase * NUM_REACT_;
55 i_react_ind < (i_phase + 1) * NUM_REACT_; i_react_ind++) {
56 for (int i_react_dep = i_phase * NUM_REACT_;
57 i_react_dep < (i_phase + 1) * NUM_REACT_; i_react_dep++)
58 jacobian_register_element(jac, REACT_(i_react_dep),
59 REACT_(i_react_ind));
60 for (int i_prod_dep = i_phase * NUM_PROD_;
61 i_prod_dep < (i_phase + 1) * NUM_PROD_; i_prod_dep++)
62 jacobian_register_element(jac, PROD_(i_prod_dep), REACT_(i_react_ind));
63 }
64
65 // Add dependence on aerosol-phase water for reactants and products in
66 // aqueous reactions
67 if (WATER_(i_phase) >= 0) {
68 for (int i_react_dep = i_phase * NUM_REACT_;
69 i_react_dep < (i_phase + 1) * NUM_REACT_; i_react_dep++)
70 jacobian_register_element(jac, REACT_(i_react_dep), WATER_(i_phase));
71 for (int i_prod_dep = i_phase * NUM_PROD_;
72 i_prod_dep < (i_phase + 1) * NUM_PROD_; i_prod_dep++)
73 jacobian_register_element(jac, PROD_(i_prod_dep), WATER_(i_phase));
74 }
75 }
76
77 return;
78}
79
80/** \brief Update the time derivative and Jacbobian array indices
81 *
82 * \param model_data Pointer to the model data
83 * \param deriv_ids Id of each state variable in the derivative array
84 * \param jac Jacobian
85 * \param rxn_int_data Pointer to the reaction integer data
86 * \param rxn_float_data Pointer to the reaction floating-point data
87 */
89 int *deriv_ids, Jacobian jac,
90 int *rxn_int_data,
91 double *rxn_float_data) {
92 int *int_data = rxn_int_data;
93 double *float_data = rxn_float_data;
94
95 // Update the time derivative ids
96 for (int i_phase = 0, i_deriv = 0; i_phase < NUM_AERO_PHASE_; i_phase++) {
97 for (int i_react = 0; i_react < NUM_REACT_; i_react++)
98 DERIV_ID_(i_deriv++) = deriv_ids[REACT_(i_phase * NUM_REACT_ + i_react)];
99 for (int i_prod = 0; i_prod < NUM_PROD_; i_prod++)
100 DERIV_ID_(i_deriv++) = deriv_ids[PROD_(i_phase * NUM_PROD_ + i_prod)];
101 }
102
103 // Update the Jacobian ids
104 for (int i_phase = 0, i_jac = 0; i_phase < NUM_AERO_PHASE_; i_phase++) {
105 // Add dependence on reactants for reactants and products
106 for (int i_react_ind = i_phase * NUM_REACT_;
107 i_react_ind < (i_phase + 1) * NUM_REACT_; i_react_ind++) {
108 for (int i_react_dep = i_phase * NUM_REACT_;
109 i_react_dep < (i_phase + 1) * NUM_REACT_; i_react_dep++)
110 JAC_ID_(i_jac++) = jacobian_get_element_id(jac, REACT_(i_react_dep),
111 REACT_(i_react_ind));
112 for (int i_prod_dep = i_phase * NUM_PROD_;
113 i_prod_dep < (i_phase + 1) * NUM_PROD_; i_prod_dep++)
114 JAC_ID_(i_jac++) = jacobian_get_element_id(jac, PROD_(i_prod_dep),
115 REACT_(i_react_ind));
116 }
117
118 // Add dependence on aerosol-phase water for reactants and products
119 for (int i_react_dep = i_phase * NUM_REACT_;
120 i_react_dep < (i_phase + 1) * NUM_REACT_; i_react_dep++)
121 if (WATER_(i_phase) >= 0) {
122 JAC_ID_(i_jac++) =
123 jacobian_get_element_id(jac, REACT_(i_react_dep), WATER_(i_phase));
124 } else {
125 JAC_ID_(i_jac++) = -1;
126 }
127 for (int i_prod_dep = i_phase * NUM_PROD_;
128 i_prod_dep < (i_phase + 1) * NUM_PROD_; i_prod_dep++)
129 if (WATER_(i_phase) >= 0) {
130 JAC_ID_(i_jac++) =
131 jacobian_get_element_id(jac, PROD_(i_prod_dep), WATER_(i_phase));
132 } else {
133 JAC_ID_(i_jac++) = -1;
134 }
135 }
136
137 return;
138}
139
140/** \brief Update reaction data
141 *
142 * Photolysis reactions can have their base (pre-scaling) rate constants updated
143 * from the host model based on the calculations of an external photolysis
144 * module. The structure of the update data is:
145 *
146 * - \b int photo_id (Id of one or more photolysis reactions set by the host
147 * model using the camp_rxn_photolysis::rxn_photolysis_t::set_photo_id
148 * function prior to initializing the solver.)
149 * - \b double rate_const (New pre-scaling rate constant.)
150 *
151 * \param update_data Pointer to the updated reaction data
152 * \param rxn_int_data Pointer to the reaction integer data
153 * \param rxn_float_data Pointer to the reaction floating-point data
154 * \param rxn_env_data Pointer to the environment-dependent data
155 * \return Flag indicating whether this is the reaction to update
156 */
157bool rxn_condensed_phase_photolysis_update_data(void *update_data, int *rxn_int_data,
158 double *rxn_float_data, double *rxn_env_data) {
159 int *int_data = rxn_int_data;
160 double *float_data = rxn_float_data;
161
162 int *photo_id = (int *)update_data;
163 double *base_rate = (double *)&(photo_id[1]);
164
165 // Set the base photolysis rate constants for matching reactions
166 if (*photo_id == RXN_ID_ && RXN_ID_ > 0) {
167 BASE_RATE_ = (double)*base_rate;
169 return true;
170 }
171
172 return false;
173}
174
175/** \brief Update reaction data for new environmental conditions
176 *
177 * For Condensed Phase photolysis reaction this only involves recalculating the
178 * forward rate constant.
179 *
180 * \param model_data Pointer to the model data
181 * \param rxn_int_data Pointer to the reaction integer data
182 * \param rxn_float_data Pointer to the reaction floating-point data
183 * \param rxn_env_data Pointer to the environment-dependent parameters
184 */
186 int *rxn_int_data,
187 double *rxn_float_data,
188 double *rxn_env_data) {
189 return;
190}
191
192/** \brief Calculate contributions to the time derivative f(t,y) from this
193 * reaction.
194 *
195 * \param model_data Pointer to the model data, including the state array
196 * \param time_deriv TimeDerivative object
197 * \param rxn_int_data Pointer to the reaction integer data
198 * \param rxn_float_data Pointer to the reaction floating-point data
199 * \param rxn_env_data Pointer to the environment-dependent parameters
200 * \param time_step Current time step of the itegrator (s)
201 */
202#ifdef CAMP_USE_SUNDIALS
204 ModelData *model_data, TimeDerivative time_deriv, int *rxn_int_data,
205 double *rxn_float_data, double *rxn_env_data, double time_step) {
206 int *int_data = rxn_int_data;
207 double *float_data = rxn_float_data;
208 double *state = model_data->grid_cell_state;
209 double *env_data = model_data->grid_cell_env;
210
211 // Calculate derivative contributions for each aerosol phase
212 for (int i_phase = 0, i_deriv = 0; i_phase < NUM_AERO_PHASE_; i_phase++) {
213 // If this is an aqueous reaction, get the unit conversion from mol/m3 -> M
214 long double unit_conv = 1.0;
215 if (WATER_(i_phase) >= 0) {
216 unit_conv = state[WATER_(i_phase)]; // convert from kg/m3->L/m3
217
218 // For aqueous reactions, if no aerosol water is present, no reaction
219 // occurs
220 if (unit_conv <= ZERO) {
221 i_deriv += NUM_REACT_ + NUM_PROD_;
222 continue;
223 }
224 unit_conv = 1.0 / unit_conv;
225 }
226
227 // Calculate the reaction rate rate (M/s or mol/m3/s)
228 long double rate = RATE_CONSTANT_;
229 for (int i_react = 0; i_react < NUM_REACT_; i_react++) {
230 rate *= state[REACT_(i_phase * NUM_REACT_ + i_react)] *
231 KGM3_TO_MOLM3_(i_react) * unit_conv;
232 }
233
234 // Reactant change
235 for (int i_react = 0; i_react < NUM_REACT_; i_react++) {
236 if (DERIV_ID_(i_deriv) < 0) {
237 i_deriv++;
238 continue;
239 }
240 time_derivative_add_value(time_deriv, DERIV_ID_(i_deriv++),
241 -rate / (KGM3_TO_MOLM3_(i_react) * unit_conv));
242 }
243
244 // Products change
245 for (int i_prod = 0; i_prod < NUM_PROD_; i_prod++) {
246 if (DERIV_ID_(i_deriv) < 0) {
247 i_deriv++;
248 continue;
249 }
251 time_deriv, DERIV_ID_(i_deriv++),
252 rate * YIELD_(i_prod) /
253 (KGM3_TO_MOLM3_(NUM_REACT_ + i_prod) * unit_conv));
254 }
255 }
256
257 return;
258}
259#endif
260
261/** \brief Calculate contributions to the Jacobian from this reaction
262 *
263 * \param model_data Pointer to the model data
264 * \param jac Reaction Jacobian
265 * \param rxn_int_data Pointer to the reaction integer data
266 * \param rxn_float_data Pointer to the reaction floating-point data
267 * \param rxn_env_data Pointer to the environment-dependent parameters
268 * \param time_step Current time step of the itegrator (s)
269 */
270#ifdef CAMP_USE_SUNDIALS
272 ModelData *model_data, Jacobian jac, int *rxn_int_data,
273 double *rxn_float_data, double *rxn_env_data, double time_step) {
274 int *int_data = rxn_int_data;
275 double *float_data = rxn_float_data;
276 double *state = model_data->grid_cell_state;
277 double *env_data = model_data->grid_cell_env;
278
279 // Calculate Jacobian contributions for each aerosol phase
280 for (int i_phase = 0, i_jac = 0; i_phase < NUM_AERO_PHASE_; i_phase++) {
281 // If this is an aqueous reaction, get the unit conversion from mol/m3 -> M
282 realtype unit_conv = 1.0;
283 if (WATER_(i_phase) >= 0) {
284 unit_conv = state[WATER_(i_phase)]; // convert from kg/m3->L/m3
285
286 // For aqueous reactions, if no aerosol water is present, no reaction
287 // occurs
288 if (unit_conv <= ZERO) {
289 i_jac += (NUM_REACT_ + NUM_PROD_) * (NUM_REACT_ + 1);
290 continue;
291 }
292 unit_conv = 1.0 / unit_conv;
293 }
294
295 // Add dependence on reactants for reactants and products
296 for (int i_react_ind = 0; i_react_ind < NUM_REACT_; i_react_ind++) {
297 // Calculate d_rate / d_react_i
298 realtype rate = RATE_CONSTANT_;
299 for (int i_react = 0; i_react < NUM_REACT_; i_react++) {
300 if (i_react == i_react_ind) {
301 rate *= KGM3_TO_MOLM3_(i_react) * unit_conv;
302 } else {
303 rate *= state[REACT_(i_phase * NUM_REACT_ + i_react)] *
304 KGM3_TO_MOLM3_(i_react) * unit_conv;
305 }
306 }
307
308 // Add the Jacobian elements
309 //
310 // For reactant dependence on reactants
311 for (int i_react_dep = 0; i_react_dep < NUM_REACT_; i_react_dep++) {
312 if (JAC_ID_(i_jac) < 0) {
313 i_jac++;
314 continue;
315 }
316 jacobian_add_value(jac, (unsigned int)JAC_ID_(i_jac++), JACOBIAN_LOSS,
317 rate / (KGM3_TO_MOLM3_(i_react_dep) * unit_conv));
318 }
319 // For product dependence on reactants
320 for (int i_prod_dep = 0; i_prod_dep < NUM_PROD_; i_prod_dep++) {
321 if (JAC_ID_(i_jac) < 0) {
322 i_jac++;
323 continue;
324 }
326 jac, (unsigned int)JAC_ID_(i_jac++), JACOBIAN_PRODUCTION,
327 rate * YIELD_(i_prod_dep) /
328 (KGM3_TO_MOLM3_(NUM_REACT_ + i_prod_dep) * unit_conv));
329 }
330 }
331
332 // Add dependence on aerosol-phase water for reactants and products in
333 // aqueous reactions
334 if (WATER_(i_phase) < 0) {
335 i_jac += NUM_REACT_ + NUM_PROD_;
336 continue;
337 }
338
339 // Calculate the overall reaction rate (M/s or mol/m3/s)
340 realtype rate = RATE_CONSTANT_;
341 for (int i_react = 0; i_react < NUM_REACT_; i_react++) {
342 rate *= state[REACT_(i_phase * NUM_REACT_ + i_react)] *
343 KGM3_TO_MOLM3_(i_react) * unit_conv;
344 }
345
346 // Dependence of reactants on aerosol-phase water
347 for (int i_react_dep = 0; i_react_dep < NUM_REACT_; i_react_dep++) {
348 if (JAC_ID_(i_jac) < 0) {
349 i_jac++;
350 continue;
351 }
353 jac, (unsigned int)JAC_ID_(i_jac++), JACOBIAN_LOSS,
354 -(NUM_REACT_ - 1) * rate / KGM3_TO_MOLM3_(i_react_dep));
355 }
356 // Dependence of products on aerosol-phase water
357 for (int i_prod_dep = 0; i_prod_dep < NUM_PROD_; i_prod_dep++) {
358 if (JAC_ID_(i_jac) < 0) {
359 i_jac++;
360 continue;
361 }
362 jacobian_add_value(jac, (unsigned int)JAC_ID_(i_jac++),
364 -(NUM_REACT_ - 1) * rate * YIELD_(i_prod_dep) /
365 KGM3_TO_MOLM3_(NUM_REACT_ + i_prod_dep));
366 }
367 }
368
369 return;
370}
371#endif
372
373/** \brief Print the Condensed Phase photolysis reaction parameters
374 *
375 * \param rxn_int_data Pointer to the reaction integer data
376 * \param rxn_float_data Pointer to the reaction floating-point data
377 */
379 double *rxn_float_data) {
380 int *int_data = rxn_int_data;
381 double *float_data = rxn_float_data;
382
383 int phase_jac_size = (NUM_REACT_ + 1) * (NUM_REACT_ + NUM_PROD_);
384
385 printf("\n\nCondensed Phase photolysis reaction\n");
386
387 printf("\n number of reactants: %d", NUM_REACT_);
388 printf("\n number of products: %d", NUM_PROD_);
389 printf("\n number of aerosol phases: %d", NUM_AERO_PHASE_);
390 printf("\n water state ids (by phase):");
391 for (int i_phase = 0; i_phase < NUM_AERO_PHASE_; ++i_phase)
392 printf(" %d", WATER_(i_phase));
393 printf("\n *** Reactants ***");
394 for (int i_react = 0; i_react < NUM_REACT_; ++i_react) {
395 printf("\n reactant %d", i_react);
396 printf("\n kg/m3 -> mol/m3: %le", KGM3_TO_MOLM3_(i_react));
397 printf("\n state id (by phase):");
398 for (int i_phase = 0; i_phase < NUM_AERO_PHASE_; ++i_phase)
399 printf(" %d", REACT_(i_phase * NUM_REACT_ + i_react));
400 printf("\n deriv id (by phase):");
401 for (int i_phase = 0; i_phase < NUM_AERO_PHASE_; ++i_phase)
402 printf(" %d", DERIV_ID_(i_phase * (NUM_REACT_ + NUM_PROD_) + i_react));
403 }
404 printf("\n *** Products ***");
405 for (int i_prod = 0; i_prod < NUM_PROD_; ++i_prod) {
406 printf("\n product %d", i_prod);
407 printf("\n kg/m3 -> mol/m3: %le", KGM3_TO_MOLM3_(NUM_REACT_ + i_prod));
408 printf("\n yield: %le", YIELD_(i_prod));
409 printf("\n state id (by phase):");
410 for (int i_phase = 0; i_phase < NUM_AERO_PHASE_; ++i_phase)
411 printf(" %d", PROD_(i_phase * NUM_PROD_ + i_prod));
412 printf("\n deriv id (by phase):");
413 for (int i_phase = 0; i_phase < NUM_AERO_PHASE_; ++i_phase)
414 printf(" %d", DERIV_ID_(i_phase * (NUM_REACT_ + NUM_PROD_) + NUM_REACT_ +
415 i_prod));
416 }
417 printf("\n *** Jac Ids (by phase) ***");
418 for (int i_ind = 0; i_ind < NUM_REACT_; ++i_ind) {
419 for (int i_react = 0; i_react < NUM_REACT_; ++i_react) {
420 printf("\n R->R");
421 for (int i_phase = 0; i_phase < NUM_AERO_PHASE_; ++i_phase) {
422 printf(" Jac[%d][%d] = %d;", REACT_(i_phase * NUM_REACT_ + i_react),
423 REACT_(i_phase * NUM_REACT_ + i_ind),
424 JAC_ID_(i_phase * phase_jac_size +
425 i_ind * (NUM_REACT_ + NUM_PROD_) + i_react));
426 }
427 }
428 for (int i_prod = 0; i_prod < NUM_PROD_; ++i_prod) {
429 printf("\n P->R");
430 for (int i_phase = 0; i_phase < NUM_AERO_PHASE_; ++i_phase) {
431 printf(" Jac[%d][%d] = %d;", PROD_(i_phase * NUM_PROD_ + i_prod),
432 REACT_(i_phase * NUM_REACT_ + i_ind),
433 JAC_ID_(i_phase * phase_jac_size +
434 i_ind * (NUM_REACT_ + NUM_PROD_) + NUM_REACT_ + i_prod));
435 }
436 }
437 }
438 for (int i_react = 0; i_react < NUM_REACT_; ++i_react) {
439 printf("\n R->W");
440 for (int i_phase = 0; i_phase < NUM_AERO_PHASE_; ++i_phase) {
441 printf(" Jac[%d][%d] = %d;", REACT_(i_phase * NUM_REACT_ + i_react),
442 WATER_(i_phase),
443 JAC_ID_(i_phase * phase_jac_size +
444 NUM_REACT_ * (NUM_REACT_ + NUM_PROD_) + i_react));
445 }
446 }
447 for (int i_prod = 0; i_prod < NUM_PROD_; ++i_prod) {
448 printf("\n P->W");
449 for (int i_phase = 0; i_phase < NUM_AERO_PHASE_; ++i_phase) {
450 printf(
451 " Jac[%d][%d] = %d;", PROD_(i_phase * NUM_PROD_ + i_prod),
452 WATER_(i_phase),
453 JAC_ID_(i_phase * phase_jac_size +
454 NUM_REACT_ * (NUM_REACT_ + NUM_PROD_) + NUM_REACT_ + i_prod));
455 }
456 }
457 return;
458}
459
460/** \brief Create update data for new photolysis rates
461 *
462 * \return Pointer to a new rate update data object
463 */
465 int *update_data = (int *)malloc(sizeof(int) + sizeof(double));
466 if (update_data == NULL) {
467 printf("\n\nERROR allocating space for condensded phase photolysis update data\n\n");
468 exit(1);
469 }
470 return (void *)update_data;
471}
472
473/** \brief Set rate update data
474 *
475 * \param update_data Pointer to an allocated rate update data object
476 * \param photo_id Id of photolysis reactions to update
477 * \param base_rate New pre-scaling photolysis rate
478 */
479void rxn_condensed_phase_photolysis_set_rate_update_data(void *update_data, int photo_id,
480 double base_rate) {
481 int *new_photo_id = (int *)update_data;
482 double *new_base_rate = (double *)&(new_photo_id[1]);
483 *new_photo_id = photo_id;
484 *new_base_rate = base_rate;
485}
unsigned int jacobian_get_element_id(Jacobian jac, unsigned int dep_id, unsigned int ind_id)
Get an element id in the Jacobian data arrays.
Definition Jacobian.c:200
void jacobian_add_value(Jacobian jac, unsigned int elem_id, unsigned int prod_or_loss, long double jac_contribution)
Add a contribution to the Jacobian.
Definition Jacobian.c:234
void jacobian_register_element(Jacobian *jac, unsigned int dep_id, unsigned int ind_id)
Adds an element to the sparse matrix.
Definition Jacobian.c:105
#define JACOBIAN_LOSS
Definition Jacobian.h:19
#define JACOBIAN_PRODUCTION
Definition Jacobian.h:18
#define ZERO
Definition camp_common.h:42
void * rxn_condensed_phase_photolysis_create_rate_update_data()
Create update data for new photolysis rates.
#define WATER_(x)
#define KGM3_TO_MOLM3_(x)
void rxn_condensed_phase_photolysis_print(int *rxn_int_data, double *rxn_float_data)
Print the Condensed Phase photolysis reaction parameters.
void rxn_condensed_phase_photolysis_calc_deriv_contrib(ModelData *model_data, TimeDerivative time_deriv, int *rxn_int_data, double *rxn_float_data, double *rxn_env_data, double time_step)
Calculate contributions to the time derivative f(t,y) from this reaction.
#define RATE_CONSTANT_
void rxn_condensed_phase_photolysis_update_env_state(ModelData *model_data, int *rxn_int_data, double *rxn_float_data, double *rxn_env_data)
Update reaction data for new environmental conditions.
void rxn_condensed_phase_photolysis_set_rate_update_data(void *update_data, int photo_id, double base_rate)
Set rate update data.
void rxn_condensed_phase_photolysis_get_used_jac_elem(int *rxn_int_data, double *rxn_float_data, Jacobian *jac)
Flag Jacobian elements used by this reaction.
#define YIELD_(x)
#define PROD_(x)
void rxn_condensed_phase_photolysis_update_ids(ModelData *model_data, int *deriv_ids, Jacobian jac, int *rxn_int_data, double *rxn_float_data)
Update the time derivative and Jacbobian array indices.
#define JAC_ID_(x)
void rxn_condensed_phase_photolysis_calc_jac_contrib(ModelData *model_data, Jacobian jac, int *rxn_int_data, double *rxn_float_data, double *rxn_env_data, double time_step)
Calculate contributions to the Jacobian from this reaction.
#define NUM_AERO_PHASE_
bool rxn_condensed_phase_photolysis_update_data(void *update_data, int *rxn_int_data, double *rxn_float_data, double *rxn_env_data)
Update reaction data.
#define REACT_(x)
#define DERIV_ID_(x)
double * grid_cell_env
double * grid_cell_state
void time_derivative_add_value(TimeDerivative time_deriv, unsigned int spec_id, long double rate_contribution)
Add a contribution to the time derivative.