CAMP 1.0.0
Chemistry Across Multiple Phases
rxn_wet_deposition.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 * Wet deposition reaction solver functions
6 *
7 */
8/** \file
9 * \brief Wet deposition reaction solver functions
10 */
11#include <math.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include "../rxns.h"
15
16// TODO Lookup environmental indicies during initialization
17#define TEMPERATURE_K_ env_data[0]
18#define PRESSURE_PA_ env_data[1]
19
20#define RXN_ID_ (int_data[0])
21#define NUM_SPEC_ (int_data[1])
22#define SCALING_ float_data[0]
23#define RATE_CONSTANT_ (rxn_env_data[0])
24#define BASE_RATE_ (rxn_env_data[1])
25#define NUM_INT_PROP_ 2
26#define NUM_FLOAT_PROP_ 1
27#define NUM_ENV_PARAM_ 2
28#define REACT_(s) (int_data[NUM_INT_PROP_ + s] - 1)
29#define DERIV_ID_(s) int_data[NUM_INT_PROP_ + NUM_SPEC_ + s]
30#define JAC_ID_(s) int_data[NUM_INT_PROP_ + 2 * NUM_SPEC_ + s]
31
32/** \brief Flag Jacobian elements used by this reaction
33 *
34 * \param rxn_int_data Pointer to the reaction integer data
35 * \param rxn_float_data Pointer to the reaction floating-point data
36 * \param jac Jacobian
37 */
39 double *rxn_float_data,
40 Jacobian *jac) {
41 int *int_data = rxn_int_data;
42 double *float_data = rxn_float_data;
43
44 for (int i_spec = 0; i_spec < NUM_SPEC_; i_spec++) {
45 jacobian_register_element(jac, REACT_(i_spec), REACT_(i_spec));
46 }
47
48 return;
49}
50
51/** \brief Update the time derivative and Jacbobian array indices
52 *
53 * \param model_data Pointer to the model data
54 * \param deriv_ids Id of each state variable in the derivative array
55 * \param jac Jacobian
56 * \param rxn_int_data Pointer to the reaction integer data
57 * \param rxn_float_data Pointer to the reaction floating-point data
58 */
59void rxn_wet_deposition_update_ids(ModelData *model_data, int *deriv_ids,
60 Jacobian jac, int *rxn_int_data,
61 double *rxn_float_data) {
62 int *int_data = rxn_int_data;
63 double *float_data = rxn_float_data;
64
65 for (int i_spec = 0; i_spec < NUM_SPEC_; i_spec++) {
66 // Update the time derivative id
67 DERIV_ID_(i_spec) = deriv_ids[REACT_(i_spec)];
68
69 // Update the Jacobian id
70 JAC_ID_(i_spec) =
71 jacobian_get_element_id(jac, REACT_(i_spec), REACT_(i_spec));
72 }
73
74 return;
75}
76
77/** \brief Update reaction data
78 *
79 * Wet deposition reactions can have their base (pre-scaling) rate constants
80 * updated from the host model based on the calculations of an external
81 * module. The structure of the update data is:
82 *
83 * - \b int rxn_id (Id of one or more wet deposition reactions set by the
84 * host model using the
85 * \c camp_rxn_wet_deposition::rxn_wet_deposition_t::set_rxn_id
86 * function prior to initializing the solver.)
87 * - \b double rate_const (New pre-scaling rate constant.)
88 *
89 * \param update_data Pointer to the updated reaction data
90 * \param rxn_int_data Pointer to the reaction integer data
91 * \param rxn_float_data Pointer to the reaction floating-point data
92 * \param rxn_env_data Pointer to the environment-dependent data
93 * \return Flag indicating whether this is the reaction to update
94 */
95bool rxn_wet_deposition_update_data(void *update_data, int *rxn_int_data,
96 double *rxn_float_data,
97 double *rxn_env_data) {
98 int *int_data = rxn_int_data;
99 double *float_data = rxn_float_data;
100
101 int *rxn_id = (int *)update_data;
102 double *base_rate = (double *)&(rxn_id[1]);
103
104 // Set the base wet deposition rate constants for matching reactions
105 if (*rxn_id == RXN_ID_ && RXN_ID_ > 0) {
106 BASE_RATE_ = (double)*base_rate;
108 return true;
109 }
110
111 return false;
112}
113
114/** \brief Update reaction data for new environmental conditions
115 *
116 * For wet deposition reactions this only involves recalculating the rate
117 * constant.
118 *
119 * \param model_data Pointer to the model data
120 * \param rxn_int_data Pointer to the reaction integer data
121 * \param rxn_float_data Pointer to the reaction floating-point data
122 * \param rxn_env_data Pointer to the environment-dependent parameters
123 */
125 int *rxn_int_data,
126 double *rxn_float_data,
127 double *rxn_env_data) {
128 int *int_data = rxn_int_data;
129 double *float_data = rxn_float_data;
130 double *env_data = model_data->grid_cell_env;
131
132 // Calculate the rate constant in (1/s)
134
135 return;
136}
137
138/** \brief Calculate contributions to the time derivative \f$f(t,y)\f$ from
139 * this reaction.
140 *
141 * \param model_data Pointer to the model data, including the state array
142 * \param time_deriv TimeDerivative object
143 * \param rxn_int_data Pointer to the reaction integer data
144 * \param rxn_float_data Pointer to the reaction floating-point data
145 * \param rxn_env_data Pointer to the environment-dependent parameters
146 * \param time_step Current time step being computed (s)
147 */
148#ifdef CAMP_USE_SUNDIALS
150 ModelData *model_data, TimeDerivative time_deriv, int *rxn_int_data,
151 double *rxn_float_data, double *rxn_env_data, realtype time_step) {
152 int *int_data = rxn_int_data;
153 double *float_data = rxn_float_data;
154 double *state = model_data->grid_cell_state;
155 double *env_data = model_data->grid_cell_env;
156
157 // Add contributions to the time derivative
158 for (int i_spec = 0; i_spec < NUM_SPEC_; i_spec++) {
159 if (DERIV_ID_(i_spec) >= 0) {
160 long double rate = RATE_CONSTANT_ * state[REACT_(i_spec)];
161 time_derivative_add_value(time_deriv, DERIV_ID_(i_spec), -rate);
162 }
163 }
164
165 return;
166}
167#endif
168
169/** \brief Calculate contributions to the Jacobian from this reaction
170 *
171 * \param model_data Pointer to the model data
172 * \param jac Reaction Jacobian
173 * \param rxn_int_data Pointer to the reaction integer data
174 * \param rxn_float_data Pointer to the reaction floating-point data
175 * \param rxn_env_data Pointer to the environment-dependent parameters
176 * \param time_step Current time step being calculated (s)
177 */
178#ifdef CAMP_USE_SUNDIALS
180 int *rxn_int_data,
181 double *rxn_float_data,
182 double *rxn_env_data,
183 realtype time_step) {
184 int *int_data = rxn_int_data;
185 double *float_data = rxn_float_data;
186 double *state = model_data->grid_cell_state;
187 double *env_data = model_data->grid_cell_env;
188
189 // Add contributions to the Jacobian
190 for (int i_spec = 0; i_spec < NUM_SPEC_; i_spec++) {
191 if (JAC_ID_(i_spec) >= 0)
192 jacobian_add_value(jac, (unsigned int)JAC_ID_(i_spec), JACOBIAN_LOSS,
194 }
195
196 return;
197}
198#endif
199
200/** \brief Print the reaction parameters
201 *
202 * \param rxn_int_data Pointer to the reaction integer data
203 * \param rxn_float_data Pointer to the reaction floating-point data
204 */
205void rxn_wet_deposition_print(int *rxn_int_data, double *rxn_float_data) {
206 int *int_data = rxn_int_data;
207 double *float_data = rxn_float_data;
208
209 printf("\n\nWet deposition reaction\n");
210
211 return;
212}
213
214/** \brief Create update data for new wet deposition rates
215 *
216 * \return Pointer to a new rate update data object
217 */
219 int *update_data = (int *)malloc(sizeof(int) + sizeof(double));
220 if (update_data == NULL) {
221 printf("\n\nERROR allocating space for wet deposition update data\n\n");
222 exit(1);
223 }
224 return (void *)update_data;
225}
226
227/** \brief Set rate update data
228 *
229 * \param update_data Pointer to an allocated rate update data object
230 * \param rxn_id Id of wet deposition reactions to update
231 * \param base_rate New pre-scaling wet deposition rate
232 */
233void rxn_wet_deposition_set_rate_update_data(void *update_data, int rxn_id,
234 double base_rate) {
235 int *new_rxn_id = (int *)update_data;
236 double *new_base_rate = (double *)&(new_rxn_id[1]);
237 *new_rxn_id = rxn_id;
238 *new_base_rate = base_rate;
239}
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
void rxn_wet_deposition_get_used_jac_elem(int *rxn_int_data, double *rxn_float_data, Jacobian *jac)
Flag Jacobian elements used by this reaction.
#define JAC_ID_(s)
#define SCALING_
#define REACT_(s)
void * rxn_wet_deposition_create_rate_update_data()
Create update data for new wet deposition rates.
void rxn_wet_deposition_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 NUM_SPEC_
void rxn_wet_deposition_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_wet_deposition_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 RATE_CONSTANT_
void rxn_wet_deposition_print(int *rxn_int_data, double *rxn_float_data)
Print the reaction parameters.
bool rxn_wet_deposition_update_data(void *update_data, int *rxn_int_data, double *rxn_float_data, double *rxn_env_data)
Update reaction data.
#define BASE_RATE_
#define RXN_ID_
#define DERIV_ID_(s)
void rxn_wet_deposition_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_wet_deposition_set_rate_update_data(void *update_data, int rxn_id, double base_rate)
Set rate update data.
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.