CAMP 1.0.0
Chemistry Across Multiple Phases
rxn_HL_phase_transfer.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 * Phase Transfer reaction solver functions
6 *
7 */
8/** \file
9 * \brief Phase Transfer reaction solver functions
10 */
11#include <math.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include "../aero_rep_solver.h"
15#include "../rxns.h"
16#include "../util.h"
17
18// TODO Lookup environmental indices during initialization
19#define TEMPERATURE_K_ env_data[0]
20#define PRESSURE_PA_ env_data[1]
21
22// Factor used to calculate minimum aerosol water concentrations for
23// HL phase transfer
24#define MIN_WATER_ 1.0e-4
25
26// Jacobian set indices
27#define JAC_GAS 0
28#define JAC_AERO 1
29
30#define DELTA_H_ float_data[0]
31#define DELTA_S_ float_data[1]
32#define DIFF_COEFF_ float_data[2]
33#define PRE_C_AVG_ float_data[3]
34#define A_ float_data[4]
35#define C_ float_data[5]
36#define CONV_ float_data[6]
37#define MW_ float_data[7]
38#define NUM_AERO_PHASE_ int_data[0]
39#define GAS_SPEC_ (int_data[1] - 1)
40#define MFP_M_ rxn_env_data[0]
41#define ALPHA_ rxn_env_data[1]
42#define EQUIL_CONST_ rxn_env_data[2]
43#define KGM3_TO_PPM_ rxn_env_data[3]
44#define NUM_INT_PROP_ 2
45#define NUM_FLOAT_PROP_ 8
46#define NUM_ENV_PARAM_ 4
47#define DERIV_ID_(x) int_data[NUM_INT_PROP_ + x]
48#define JAC_ID_(x) int_data[NUM_INT_PROP_ + 1 + NUM_AERO_PHASE_ + x]
49#define PHASE_INT_LOC_(x) \
50 (int_data[NUM_INT_PROP_ + 2 + 6 * NUM_AERO_PHASE_ + x] - 1)
51#define PHASE_REAL_LOC_(x) \
52 (int_data[NUM_INT_PROP_ + 2 + 7 * NUM_AERO_PHASE_ + x] - 1)
53#define AERO_SPEC_(x) (int_data[PHASE_INT_LOC_(x)] - 1)
54#define AERO_WATER_(x) (int_data[PHASE_INT_LOC_(x) + 1] - 1)
55#define AERO_PHASE_ID_(x) (int_data[PHASE_INT_LOC_(x) + 2] - 1)
56#define AERO_REP_ID_(x) (int_data[PHASE_INT_LOC_(x) + 3] - 1)
57#define NUM_AERO_PHASE_JAC_ELEM_(x) (int_data[PHASE_INT_LOC_(x) + 4])
58#define PHASE_JAC_ID_(x, s, e) \
59 int_data[PHASE_INT_LOC_(x) + 5 + (s) * NUM_AERO_PHASE_JAC_ELEM_(x) + e]
60#define SMALL_WATER_CONC_(x) (float_data[PHASE_REAL_LOC_(x)])
61#define EFF_RAD_JAC_ELEM_(x, e) float_data[PHASE_REAL_LOC_(x) + 1 + e]
62#define NUM_CONC_JAC_ELEM_(x, e) \
63 float_data[PHASE_REAL_LOC_(x) + 1 + NUM_AERO_PHASE_JAC_ELEM_(x) + e]
64
65/** \brief Flag Jacobian elements used by this reaction
66 *
67 * \param model_data Pointer to the model data
68 * \param rxn_int_data Pointer to the reaction integer data
69 * \param rxn_float_data Pointer to the reaction floating-point data
70 * \param jac Jacobian
71 */
73 int *rxn_int_data,
74 double *rxn_float_data,
75 Jacobian *jac) {
76 int *int_data = rxn_int_data;
77 double *float_data = rxn_float_data;
78
79 bool *aero_jac_elem =
80 (bool *)malloc(sizeof(bool) * model_data->n_per_cell_state_var);
81 if (aero_jac_elem == NULL) {
82 printf(
83 "\n\nERROR allocating space for 1D jacobian structure array for HL "
84 "partitioning reaction\n\n");
85 exit(1);
86 }
87
89 for (int i_aero_phase = 0; i_aero_phase < NUM_AERO_PHASE_; i_aero_phase++) {
92 jacobian_register_element(jac, AERO_SPEC_(i_aero_phase),
93 AERO_SPEC_(i_aero_phase));
95 jacobian_register_element(jac, AERO_SPEC_(i_aero_phase),
96 AERO_WATER_(i_aero_phase));
97
98 for (int i_elem = 0; i_elem < model_data->n_per_cell_state_var; i_elem++)
99 aero_jac_elem[i_elem] = false;
100
101 int n_jac_elem =
102 aero_rep_get_used_jac_elem(model_data, AERO_REP_ID_(i_aero_phase),
103 AERO_PHASE_ID_(i_aero_phase), aero_jac_elem);
104 if (n_jac_elem > NUM_AERO_PHASE_JAC_ELEM_(i_aero_phase)) {
105 printf(
106 "\n\nERROR Received more Jacobian elements than expected for HL "
107 "partitioning reaction. Got %d, expected <= %d",
108 n_jac_elem, NUM_AERO_PHASE_JAC_ELEM_(i_aero_phase));
109 exit(1);
110 }
111 int i_used_elem = 0;
112 for (int i_elem = 0; i_elem < model_data->n_per_cell_state_var; i_elem++) {
113 if (aero_jac_elem[i_elem] == true) {
115 jacobian_register_element(jac, AERO_SPEC_(i_aero_phase), i_elem);
116 PHASE_JAC_ID_(i_aero_phase, JAC_GAS, i_used_elem) = i_elem;
117 PHASE_JAC_ID_(i_aero_phase, JAC_AERO, i_used_elem) = i_elem;
118 i_used_elem++;
119 }
120 }
121 for (; i_used_elem < NUM_AERO_PHASE_JAC_ELEM_(i_aero_phase);
122 ++i_used_elem) {
123 PHASE_JAC_ID_(i_aero_phase, JAC_GAS, i_used_elem) = -1;
124 PHASE_JAC_ID_(i_aero_phase, JAC_AERO, i_used_elem) = -1;
125 }
126 if (i_used_elem != n_jac_elem) {
127 printf(
128 "\n\nERROR Error setting used Jacobian elements in HL "
129 "partitioning reaction %d %d\n\n",
130 i_used_elem, n_jac_elem);
131 rxn_HL_phase_transfer_print(rxn_int_data, rxn_float_data);
132 exit(1);
133 }
134 }
135
136 free(aero_jac_elem);
137
138 return;
139}
140
141/** \brief Update the time derivative and Jacbobian array indices
142 *
143 * \param model_data Pointer to the model data
144 * \param deriv_ids Id of each state variable in the derivative array
145 * \param jac Jacobian
146 * \param rxn_int_data Pointer to the reaction integer data
147 * \param rxn_float_data Pointer to the reaction floating-point data
148 */
149void rxn_HL_phase_transfer_update_ids(ModelData *model_data, int *deriv_ids,
150 Jacobian jac, int *rxn_int_data,
151 double *rxn_float_data) {
152 int *int_data = rxn_int_data;
153 double *float_data = rxn_float_data;
154
155 // Update the time derivative ids
156 DERIV_ID_(0) = deriv_ids[GAS_SPEC_];
157 for (int i = 0; i < NUM_AERO_PHASE_; i++)
158 DERIV_ID_(i + 1) = deriv_ids[AERO_SPEC_(i)];
159
160 // Update the Jacobian ids
161 int i_jac = 0;
163 for (int i_aero_phase = 0; i_aero_phase < NUM_AERO_PHASE_; i_aero_phase++) {
164 JAC_ID_(i_jac++) =
165 jacobian_get_element_id(jac, AERO_SPEC_(i_aero_phase), GAS_SPEC_);
166 JAC_ID_(i_jac++) =
167 jacobian_get_element_id(jac, GAS_SPEC_, AERO_SPEC_(i_aero_phase));
168 JAC_ID_(i_jac++) = jacobian_get_element_id(jac, AERO_SPEC_(i_aero_phase),
169 AERO_SPEC_(i_aero_phase));
170 JAC_ID_(i_jac++) =
171 jacobian_get_element_id(jac, GAS_SPEC_, AERO_WATER_(i_aero_phase));
172 JAC_ID_(i_jac++) = jacobian_get_element_id(jac, AERO_SPEC_(i_aero_phase),
173 AERO_WATER_(i_aero_phase));
174 for (int i_elem = 0; i_elem < NUM_AERO_PHASE_JAC_ELEM_(i_aero_phase);
175 i_elem++) {
176 if (PHASE_JAC_ID_(i_aero_phase, JAC_GAS, i_elem) > 0) {
177 PHASE_JAC_ID_(i_aero_phase, JAC_GAS, i_elem) = jacobian_get_element_id(
178 jac, GAS_SPEC_, PHASE_JAC_ID_(i_aero_phase, JAC_GAS, i_elem));
179 }
180 if (PHASE_JAC_ID_(i_aero_phase, JAC_AERO, i_elem) > 0) {
181 PHASE_JAC_ID_(i_aero_phase, JAC_AERO, i_elem) = jacobian_get_element_id(
182 jac, AERO_SPEC_(i_aero_phase),
183 PHASE_JAC_ID_(i_aero_phase, JAC_AERO, i_elem));
184 }
185 }
186 }
187
188 // Calculate a small concentration for aerosol-phase water based on the
189 // integration tolerances to use during solving. TODO find a better place
190 // to do this
191 double *abs_tol = (double *)model_data->abs_tol;
192 for (int i_aero_phase = 0; i_aero_phase < NUM_AERO_PHASE_; i_aero_phase++) {
193 SMALL_WATER_CONC_(i_aero_phase) = abs_tol[AERO_WATER_(i_aero_phase)] / 10.0;
194 }
195
196 return;
197}
198
199/** \brief Update reaction data for new environmental conditions
200 *
201 * For Phase Transfer reaction this only involves recalculating the rate
202 * constant.
203 *
204 * \param model_data Pointer to the model data
205 * \param rxn_int_data Pointer to the reaction integer data
206 * \param rxn_float_data Pointer to the reaction floating-point data
207 * \param rxn_env_data Pointer to the environment-dependent parameters
208 */
210 int *rxn_int_data,
211 double *rxn_float_data,
212 double *rxn_env_data) {
213 int *int_data = rxn_int_data;
214 double *float_data = rxn_float_data;
215 double *env_data = model_data->grid_cell_env;
216
217 // Calculate the mass accomodation coefficient if the N* parameter
218 // was provided, otherwise set it to 0.1 (per Zaveri 2008)
219 ALPHA_ = 0.1;
220 if (DELTA_H_ != 0.0 || DELTA_S_ != 0.0) {
221 double del_G = DELTA_H_ - TEMPERATURE_K_ * DELTA_S_;
222 ALPHA_ = exp(-del_G / (UNIV_GAS_CONST_ * TEMPERATURE_K_));
223 ALPHA_ = ALPHA_ / (1.0 + ALPHA_);
224 }
225
226 // replaced by transition-regime rate equation
227#if 0
228 // Save c_rms * mass_acc for use in mass transfer rate calc
229 MFP_M_ = PRE_C_AVG_ * sqrt(TEMPERATURE_K_) * mass_acc;
230#endif
231
232 // save the mean free path [m] for calculating condensation rates
234
235 // Calculate the Henry's Law equilibrium rate constant in units of
236 // (kg_x/kg_H2O/ppm) where x is the aerosol-phase species. (A is in
237 // units of M/Pa.)
238 if (C_ == 0.0) {
239 EQUIL_CONST_ = A_ * PRESSURE_PA_ * 1.0e-6 * MW_;
240 } else {
241 EQUIL_CONST_ = A_ * PRESSURE_PA_ * 1.0e-6 *
242 exp(C_ * (1.0 / TEMPERATURE_K_ - 1.0 / 298.0)) * MW_;
243 }
244
245 // Calculate the conversion from kg/m^3 -> ppm
247
248 return;
249}
250
251/** \brief Calculate contributions to the time derivative \f$f(t,y)\f$ from
252 * this reaction.
253 *
254 * \bug this does not work for modal/binned aero reps. Needs update following
255 * the logic in the SIMPOL partitioning reaction
256 *
257 * \param model_data Pointer to the model data, including the state array
258 * \param time_deriv TimeDerivative object
259 * \param rxn_int_data Pointer to the reaction integer data
260 * \param rxn_float_data Pointer to the reaction floating-point data
261 * \param rxn_env_data Pointer to the environment-dependent parameters
262 * \param time_step Current time step being computed (s)
263 */
264#ifdef CAMP_USE_SUNDIALS
266 ModelData *model_data, TimeDerivative time_deriv, int *rxn_int_data,
267 double *rxn_float_data, double *rxn_env_data, realtype time_step) {
268 int *int_data = rxn_int_data;
269 double *float_data = rxn_float_data;
270 double *state = model_data->grid_cell_state;
271 double *env_data = model_data->grid_cell_env;
272
273 // Calculate derivative contributions for each aerosol phase
274 for (int i_phase = 0; i_phase < NUM_AERO_PHASE_; i_phase++) {
275 // Get the particle effective radius (m)
276 realtype radius;
278 model_data, // model data
279 AERO_REP_ID_(i_phase), // aerosol representation index
280 AERO_PHASE_ID_(i_phase), // aerosol phase index
281 &radius, // particle effective radius (m)
282 NULL); // partial derivative
283
284 // Check the aerosol concentration type (per-particle or total per-phase
285 // mass)
286 int aero_conc_type = aero_rep_get_aero_conc_type(
287 model_data, // model data
288 AERO_REP_ID_(i_phase), // aerosol representation index
289 AERO_PHASE_ID_(i_phase)); // aerosol phase index
290
291 // Get the particle number concentration (#/m3) for per-particle mass
292 // concentrations; otherwise set to 1
293 realtype number_conc = ONE;
294 if (aero_conc_type == 0) {
296 model_data, // model data
297 AERO_REP_ID_(i_phase), // aerosol representation index
298 AERO_PHASE_ID_(i_phase), // aerosol phase index
299 &number_conc, // particle number concentration
300 // (#/m3)
301 NULL); // partial derivative
302 }
303
304 // this was replaced with transition-regime rate equation
305#if 0
306 long double cond_rate =
307 ((long double)1.0) / (radius * radius / (3.0 * DIFF_COEFF_) +
308 4.0 * radius / (3.0 * MFP_M_));
309#endif
310
311 // Calculate the rate constant for diffusion limited mass transfer to the
312 // aerosol phase (1/s)
313 long double cond_rate =
315
316 // Calculate the evaporation rate constant (1/s)
317 long double evap_rate = cond_rate / (EQUIL_CONST_);
318
319 // Calculate the evaporation and condensation rates (ppm/s)
320 cond_rate *= state[GAS_SPEC_];
321 evap_rate *= state[AERO_SPEC_(i_phase)] / state[AERO_WATER_(i_phase)];
322
323 // Change in the gas-phase is evaporation - condensation (ppm/s)
324 if (DERIV_ID_(0) >= 0) {
326 number_conc * evap_rate);
328 -number_conc * cond_rate);
329 }
330
331 // Change in the aerosol-phase species is condensation - evaporation
332 // (kg/m^3/s)
333 if (DERIV_ID_(1 + i_phase) >= 0) {
334 time_derivative_add_value(time_deriv, DERIV_ID_(1 + i_phase),
335 -evap_rate / KGM3_TO_PPM_);
336 time_derivative_add_value(time_deriv, DERIV_ID_(1 + i_phase),
337 cond_rate / KGM3_TO_PPM_);
338 }
339 }
340 return;
341}
342#endif
343
344/** \brief Calculate contributions to the Jacobian from this reaction
345 *
346 * \param model_data Pointer to the model data
347 * \param jac Reaction Jacobian
348 * \param rxn_int_data Pointer to the reaction integer data
349 * \param rxn_float_data Pointer to the reaction floating-point data
350 * \param rxn_env_data Pointer to the environment-dependent parameters
351 * \param time_step Current time step being calculated (s)
352 */
353#ifdef CAMP_USE_SUNDIALS
355 int *rxn_int_data,
356 double *rxn_float_data,
357 double *rxn_env_data,
358 realtype time_step) {
359 int *int_data = rxn_int_data;
360 double *float_data = rxn_float_data;
361 double *state = model_data->grid_cell_state;
362 double *env_data = model_data->grid_cell_env;
363
364 // Calculate derivative contributions for each aerosol phase
365 for (int i_phase = 0; i_phase < NUM_AERO_PHASE_; i_phase++) {
366 // Get the particle effective radius (m)
367 realtype radius;
369 model_data, // model data
370 AERO_REP_ID_(i_phase), // aerosol representation index
371 AERO_PHASE_ID_(i_phase), // aerosol phase index
372 &radius, // particle effective radius (m)
373 &(EFF_RAD_JAC_ELEM_(i_phase, 0))); // partial derivative
374
375 // Check the aerosol concentration type (per-particle or total per-phase
376 // mass)
377 int aero_conc_type = aero_rep_get_aero_conc_type(
378 model_data, // model data
379 AERO_REP_ID_(i_phase), // aerosol representation index
380 AERO_PHASE_ID_(i_phase)); // aerosol phase index
381
382 // Get the particle number concentration (#/m3) for per-particle
383 // concentrations
384 realtype number_conc = ONE;
385 if (aero_conc_type == 0) {
387 model_data, // model data
388 AERO_REP_ID_(i_phase), // aerosol representation index
389 AERO_PHASE_ID_(i_phase), // aerosol phase index
390 &number_conc, // particle number concentration
391 // (#/m3)
392 &(NUM_CONC_JAC_ELEM_(i_phase, 0))); // partial derivative
393 } else {
394 for (int i_elem = 0; i_elem < NUM_AERO_PHASE_JAC_ELEM_(i_phase); ++i_elem)
395 NUM_CONC_JAC_ELEM_(i_phase, i_elem) = ZERO;
396 }
397
398 // this was replaced with transition-regime rate equation
399#if 0
400 long double cond_rate = 1.0 / (radius * radius / (3.0 * DIFF_COEFF_) +
401 4.0 * radius / (3.0 * MFP_M_));
402#endif
403
404 // Calculate the rate constant for diffusion limited mass transfer to the
405 // aerosol phase (1/s)
406 long double cond_rate =
408
409 // Calculate the evaporation rate constant (1/s)
410 long double evap_rate = cond_rate / (EQUIL_CONST_);
411
412 // Change in the gas-phase is evaporation - condensation (ppm/s)
413 if (JAC_ID_(0) >= 0)
414 jacobian_add_value(jac, (unsigned int)JAC_ID_(0), JACOBIAN_LOSS,
415 number_conc * cond_rate);
416 if (JAC_ID_(1 + i_phase * 5 + 1) >= 0)
417 jacobian_add_value(jac, (unsigned int)JAC_ID_(1 + i_phase * 5 + 1),
419 number_conc * evap_rate / state[AERO_WATER_(i_phase)]);
420 if (JAC_ID_(1 + i_phase * 5 + 3) >= 0)
422 jac, (unsigned int)JAC_ID_(1 + i_phase * 5 + 3), JACOBIAN_PRODUCTION,
423 -number_conc * evap_rate * state[AERO_SPEC_(i_phase)] /
424 state[AERO_WATER_(i_phase)] / state[AERO_WATER_(i_phase)]);
425
426 // Change in the aerosol-phase species is condensation - evaporation
427 // (kg/m^3/s)
428 if (JAC_ID_(1 + i_phase * 5) >= 0)
429 jacobian_add_value(jac, (unsigned int)JAC_ID_(1 + i_phase * 5),
430 JACOBIAN_PRODUCTION, cond_rate / KGM3_TO_PPM_);
431 if (JAC_ID_(1 + i_phase * 5 + 2) >= 0)
433 jac, (unsigned int)JAC_ID_(1 + i_phase * 5 + 2), JACOBIAN_LOSS,
434 evap_rate / state[AERO_WATER_(i_phase)] / KGM3_TO_PPM_);
435 if (JAC_ID_(1 + i_phase * 5 + 4) >= 0)
437 jac, (unsigned int)JAC_ID_(1 + i_phase * 5 + 4), JACOBIAN_LOSS,
438 -evap_rate * state[AERO_SPEC_(i_phase)] / KGM3_TO_PPM_ /
439 state[AERO_WATER_(i_phase)] / state[AERO_WATER_(i_phase)]);
440
441 // Calculate the condensation and evaporation rates (ppm/s)
442 cond_rate *= state[GAS_SPEC_];
443 evap_rate *= state[AERO_SPEC_(i_phase)] / state[AERO_WATER_(i_phase)];
444
445 // Add contributions from species used in aerosol property calculations
446
447 // Calculate d_rate/d_effecive_radius and d_rate/d_number_concentration
448 // ( This was replaced with transition-regime rate equation. )
449#if 0
450 long double d_rate_d_radius =
451 -rate * cond_rate *
452 (2.0 * radius / (3.0 * DIFF_COEFF_) + 4.0 / (3.0 * MFP_M_));
453#endif
454 long double d_cond_d_radius =
456 DIFF_COEFF_, MFP_M_, radius, ALPHA_) * state[GAS_SPEC_];
457 long double d_evap_d_radius = d_cond_d_radius / state[GAS_SPEC_] /
458 (EQUIL_CONST_)*state[AERO_SPEC_(i_phase)] /
459 state[AERO_WATER_(i_phase)];
460
461 // Loop through Jac elements and update
462 for (int i_elem = 0; i_elem < NUM_AERO_PHASE_JAC_ELEM_(i_phase); ++i_elem) {
463 // Gas-phase species dependencies
464 if (PHASE_JAC_ID_(i_phase, JAC_GAS, i_elem) > 0) {
465 // species involved in effective radius calculation
467 jac, (unsigned int)PHASE_JAC_ID_(i_phase, JAC_GAS, i_elem),
469 number_conc * d_evap_d_radius * EFF_RAD_JAC_ELEM_(i_phase, i_elem));
471 jac, (unsigned int)PHASE_JAC_ID_(i_phase, JAC_GAS, i_elem),
473 number_conc * d_cond_d_radius * EFF_RAD_JAC_ELEM_(i_phase, i_elem));
474
475 // species involved in number concentration
477 jac, (unsigned int)PHASE_JAC_ID_(i_phase, JAC_GAS, i_elem),
479 evap_rate * NUM_CONC_JAC_ELEM_(i_phase, i_elem));
481 jac, (unsigned int)PHASE_JAC_ID_(i_phase, JAC_GAS, i_elem),
482 JACOBIAN_LOSS, cond_rate * NUM_CONC_JAC_ELEM_(i_phase, i_elem));
483 }
484
485 // Aerosol-phase species dependencies
486 if (PHASE_JAC_ID_(i_phase, JAC_AERO, i_elem) > 0) {
487 // species involved in effective radius calculation
489 jac, (unsigned int)PHASE_JAC_ID_(i_phase, JAC_AERO, i_elem),
491 d_evap_d_radius / KGM3_TO_PPM_ *
492 EFF_RAD_JAC_ELEM_(i_phase, i_elem));
494 jac, (unsigned int)PHASE_JAC_ID_(i_phase, JAC_AERO, i_elem),
496 d_cond_d_radius / KGM3_TO_PPM_ *
497 EFF_RAD_JAC_ELEM_(i_phase, i_elem));
498 }
499 }
500 }
501 return;
502}
503#endif
504
505/** \brief Print the Phase Transfer reaction parameters
506 *
507 * \param rxn_int_data Pointer to the reaction integer data
508 * \param rxn_float_data Pointer to the reaction floating-point data
509 */
510void rxn_HL_phase_transfer_print(int *rxn_int_data, double *rxn_float_data) {
511 int *int_data = rxn_int_data;
512 double *float_data = rxn_float_data;
513
514 printf("\n\nPhase Transfer reaction\n");
515
516 return;
517}
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
int aero_rep_get_aero_conc_type(ModelData *model_data, int aero_rep_idx, int aero_phase_idx)
Check whether aerosol concentrations are per-particle or total for each phase.
int aero_rep_get_used_jac_elem(ModelData *model_data, int aero_rep_idx, int aero_phase_idx, bool *jac_struct)
Flag Jacobian elements used to calculated mass, volume, etc.
void aero_rep_get_number_conc__n_m3(ModelData *model_data, int aero_rep_idx, int aero_phase_idx, double *number_conc, double *partial_deriv)
Get the particle number concentration ( )
void aero_rep_get_effective_radius__m(ModelData *model_data, int aero_rep_idx, int aero_phase_idx, double *radius, double *partial_deriv)
Get the effective particle radius, (m)
#define ONE
Definition camp_common.h:43
#define ZERO
Definition camp_common.h:42
#define JAC_AERO
#define DELTA_H_
#define MW_
#define JAC_GAS
#define SMALL_WATER_CONC_(x)
void rxn_HL_phase_transfer_print(int *rxn_int_data, double *rxn_float_data)
Print the Phase Transfer reaction parameters.
#define PRESSURE_PA_
#define AERO_PHASE_ID_(x)
void rxn_HL_phase_transfer_calc_jac_contrib(ModelData *model_data, Jacobian jac, int *rxn_int_data, double *rxn_float_data, double *rxn_env_data, realtype time_step)
Calculate contributions to the Jacobian from this reaction.
void rxn_HL_phase_transfer_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.
#define EQUIL_CONST_
void rxn_HL_phase_transfer_get_used_jac_elem(ModelData *model_data, int *rxn_int_data, double *rxn_float_data, Jacobian *jac)
Flag Jacobian elements used by this reaction.
#define A_
#define PRE_C_AVG_
#define MFP_M_
void rxn_HL_phase_transfer_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 KGM3_TO_PPM_
#define CONV_
#define ALPHA_
#define GAS_SPEC_
void rxn_HL_phase_transfer_calc_deriv_contrib(ModelData *model_data, TimeDerivative time_deriv, int *rxn_int_data, double *rxn_float_data, double *rxn_env_data, realtype time_step)
Calculate contributions to the time derivative from this reaction.
#define TEMPERATURE_K_
#define JAC_ID_(x)
#define PHASE_JAC_ID_(x, s, e)
#define NUM_AERO_PHASE_JAC_ELEM_(x)
#define C_
#define DIFF_COEFF_
#define NUM_AERO_PHASE_
#define AERO_REP_ID_(x)
#define EFF_RAD_JAC_ELEM_(x, e)
#define AERO_SPEC_(x)
#define DELTA_S_
#define NUM_CONC_JAC_ELEM_(x, e)
#define AERO_WATER_(x)
#define DERIV_ID_(x)
int n_per_cell_state_var
Definition camp_common.h:63
double * grid_cell_env
double * grid_cell_state
double * abs_tol
Definition camp_common.h:72
void time_derivative_add_value(TimeDerivative time_deriv, unsigned int spec_id, long double rate_contribution)
Add a contribution to the time derivative.
static double d_gas_aerosol_transition_rxn_rate_constant_d_radius(double diffusion_coeff__m2_s, double mean_free_path__m, double radius__m, double alpha)
Definition util.h:154
static double gas_aerosol_transition_rxn_rate_constant(double diffusion_coeff__m2_s, double mean_free_path__m, double radius__m, double alpha)
Definition util.h:129
static double mean_free_path__m(double diffusion_coeff__m2_s, double temperature__K, double mw__kg_mol)
Definition util.h:50
#define UNIV_GAS_CONST_
Definition util.h:15