14#include "../aero_phase_solver.h"
15#include "../aero_reps.h"
16#include "../camp_solver.h"
19#define TEMPERATURE_K_ env_data[0]
20#define PRESSURE_PA_ env_data[1]
28#define NUM_SECTION_ (int_data[0])
29#define INT_DATA_SIZE_ (int_data[1])
30#define FLOAT_DATA_SIZE_ (int_data[2])
31#define AERO_REP_ID_ (int_data[3])
32#define NUM_INT_PROP_ 4
33#define NUM_FLOAT_PROP_ 0
34#define NUM_ENV_PARAM_ 0
35#define MODE_INT_PROP_LOC_(x) (int_data[NUM_INT_PROP_ + x] - 1)
36#define MODE_FLOAT_PROP_LOC_(x) (int_data[NUM_INT_PROP_ + NUM_SECTION_ + x] - 1)
37#define SECTION_TYPE_(x) (int_data[MODE_INT_PROP_LOC_(x)])
40#define NUM_BINS_(x) (int_data[MODE_INT_PROP_LOC_(x) + 1])
43#define NUM_PHASE_(x) (int_data[MODE_INT_PROP_LOC_(x) + 2])
46#define PHASE_STATE_ID_(x, y, b) \
47 (int_data[MODE_INT_PROP_LOC_(x) + 3 + b * NUM_PHASE_(x) + y] - 1)
48#define PHASE_MODEL_DATA_ID_(x, y, b) \
49 (int_data[MODE_INT_PROP_LOC_(x) + 3 + NUM_BINS_(x) * NUM_PHASE_(x) + \
50 b * NUM_PHASE_(x) + y] - \
54#define PHASE_NUM_JAC_ELEM_(x, y, b) \
55 int_data[MODE_INT_PROP_LOC_(x) + 3 + 2 * NUM_BINS_(x) * NUM_PHASE_(x) + \
56 b * NUM_PHASE_(x) + y]
59#define BIN_DP_(x, b) (float_data[MODE_FLOAT_PROP_LOC_(x) + b * 3])
62#define GMD_(x) (aero_rep_env_data[x])
63#define GSD_(x) (aero_rep_env_data[NUM_SECTION_ + x])
66#define NUMBER_CONC_(x, b) (float_data[MODE_FLOAT_PROP_LOC_(x) + b * 3 + 1])
69#define EFFECTIVE_RADIUS_(x, b) \
70 (float_data[MODE_FLOAT_PROP_LOC_(x) + b * 3 + 2])
73#define PHASE_MASS_(x, y, b) \
74 (float_data[MODE_FLOAT_PROP_LOC_(x) + 3 * NUM_BINS_(x) + b * NUM_PHASE_(x) + \
79#define PHASE_AVG_MW_(x, y, b) \
80 (float_data[MODE_FLOAT_PROP_LOC_(x) + (3 + NUM_PHASE_(x)) * NUM_BINS_(x) + \
81 b * NUM_PHASE_(x) + y])
97 int *aero_rep_int_data,
98 double *aero_rep_float_data,
100 int *int_data = aero_rep_int_data;
101 double *float_data = aero_rep_float_data;
103 int num_flagged_elem = 0;
107 for (
int i_section = 0; i_section < NUM_SECTION_ && aero_phase_idx >= 0;
109 for (
int i_bin = 0; i_bin <
NUM_BINS_(i_section) && aero_phase_idx >= 0;
111 for (
int i_phase = 0;
112 i_phase <
NUM_PHASE_(i_section) && aero_phase_idx >= 0; i_phase++) {
113 if (aero_phase_idx == 0) {
114 for (
int j_phase = 0; j_phase <
NUM_PHASE_(i_section); j_phase++) {
127 return num_flagged_elem;
140 double *aero_rep_float_data,
142 int *int_data = aero_rep_int_data;
143 double *float_data = aero_rep_float_data;
161 int *aero_rep_int_data,
162 double *aero_rep_float_data,
163 double *aero_rep_env_data) {
164 int *int_data = aero_rep_int_data;
165 double *float_data = aero_rep_float_data;
184 int *aero_rep_int_data,
185 double *aero_rep_float_data,
186 double *aero_rep_env_data) {
187 int *int_data = aero_rep_int_data;
188 double *float_data = aero_rep_float_data;
192 for (
int i_section = 0; i_section <
NUM_SECTION_; i_section++) {
200 for (
int i_phase = 0; i_phase <
NUM_PHASE_(i_section); i_phase++) {
212 double phase_volume = 0.0;
215 &phase_volume, NULL);
216 volume += phase_volume;
224 exp(9.0 / 2.0 * pow(log(
GSD_(i_section)), 2)));
232 for (
int i_bin = 0; i_bin <
NUM_BINS_(i_section); i_bin++) {
235 for (
int i_phase = 0; i_phase <
NUM_PHASE_(i_section); i_phase++) {
247 double phase_volume = 0.0;
250 state, &phase_volume, NULL);
251 volume += phase_volume;
257 volume * 3.0 / (4.0 *
M_PI) /
258 pow(
BIN_DP_(i_section, i_bin) / 2.0, 3);
301 ModelData *model_data,
int aero_phase_idx,
double *radius,
302 double *partial_deriv,
int *aero_rep_int_data,
double *aero_rep_float_data,
303 double *aero_rep_env_data) {
304 int *int_data = aero_rep_int_data;
305 double *float_data = aero_rep_float_data;
307 for (
int i_section = 0; i_section <
NUM_SECTION_; i_section++) {
308 for (
int i_bin = 0; i_bin <
NUM_BINS_(i_section); i_bin++) {
310 if (aero_phase_idx < 0) {
314 for (
int i_phase = 0; i_phase <
NUM_PHASE_(i_section); ++i_phase) {
318 *(partial_deriv++) =
ZERO;
369 ModelData *model_data,
int aero_phase_idx,
double *number_conc,
370 double *partial_deriv,
int *aero_rep_int_data,
double *aero_rep_float_data,
371 double *aero_rep_env_data) {
372 int *int_data = aero_rep_int_data;
373 double *float_data = aero_rep_float_data;
375 for (
int i_section = 0; i_section < NUM_SECTION_ && aero_phase_idx >= 0;
377 for (
int i_bin = 0; i_bin <
NUM_BINS_(i_section) && aero_phase_idx >= 0;
380 if (aero_phase_idx < 0) {
383 for (
int i_phase = 0; i_phase <
NUM_PHASE_(i_section); ++i_phase) {
389 double phase_volume = 0.0;
392 state, &phase_volume, partial_deriv);
400 *(partial_deriv++) *=
401 6.0 / (
M_PI * pow(
GMD_(i_section), 3) *
402 exp(9.0 / 2.0 * pow(log(
GSD_(i_section)), 2)));
405 *(partial_deriv++) *= 3.0 / (4.0 *
M_PI) /
406 pow(
BIN_DP_(i_section, i_bin) / 2.0, 3);
436 int *aero_rep_int_data,
437 double *aero_rep_float_data,
438 double *aero_rep_env_data) {
439 int *int_data = aero_rep_int_data;
440 double *float_data = aero_rep_float_data;
463 ModelData *model_data,
int aero_phase_idx,
double *aero_phase_mass,
464 double *partial_deriv,
int *aero_rep_int_data,
double *aero_rep_float_data,
465 double *aero_rep_env_data) {
466 int *int_data = aero_rep_int_data;
467 double *float_data = aero_rep_float_data;
469 for (
int i_section = 0; i_section < NUM_SECTION_ && aero_phase_idx >= 0;
471 for (
int i_bin = 0; i_bin <
NUM_BINS_(i_section) && aero_phase_idx >= 0;
473 if (aero_phase_idx < 0 || aero_phase_idx >=
NUM_PHASE_(i_section)) {
477 for (
int i_phase = 0; i_phase <
NUM_PHASE_(i_section); ++i_phase) {
478 if (aero_phase_idx == 0) {
479 *aero_phase_mass =
PHASE_MASS_(i_section, i_phase, i_bin);
489 state, &mass, &mw, partial_deriv, NULL);
495 }
else if (partial_deriv) {
499 *(partial_deriv++) =
ZERO;
526 ModelData *model_data,
int aero_phase_idx,
double *aero_phase_avg_MW,
527 double *partial_deriv,
int *aero_rep_int_data,
double *aero_rep_float_data,
528 double *aero_rep_env_data) {
529 int *int_data = aero_rep_int_data;
530 double *float_data = aero_rep_float_data;
532 for (
int i_section = 0; i_section < NUM_SECTION_ && aero_phase_idx >= 0;
534 for (
int i_bin = 0; i_bin <
NUM_BINS_(i_section) && aero_phase_idx >= 0;
536 if (aero_phase_idx < 0 || aero_phase_idx >=
NUM_PHASE_(i_section)) {
540 for (
int i_phase = 0; i_phase <
NUM_PHASE_(i_section); ++i_phase) {
541 if (aero_phase_idx == 0) {
542 *aero_phase_avg_MW =
PHASE_AVG_MW_(i_section, i_phase, i_bin);
552 state, &mass, &mw, NULL, partial_deriv);
558 }
else if (partial_deriv) {
562 *(partial_deriv++) =
ZERO;
595 int *aero_rep_int_data,
596 double *aero_rep_float_data,
597 double *aero_rep_env_data) {
598 int *int_data = aero_rep_int_data;
599 double *float_data = aero_rep_float_data;
601 int *aero_rep_id = (
int *)update_data;
602 int *update_type = (
int *)&(aero_rep_id[1]);
603 int *section_id = (
int *)&(update_type[1]);
604 double *new_value = (
double *)&(section_id[1]);
605 bool ret_val =
false;
612 "\n\nERROR Trying to set geometric mean diameter for non-modal"
613 " aerosol section.");
616 GMD_(*section_id) = (double)*new_value;
621 "\n\nERROR Trying to set geometric standard deviation for non-modal"
622 " aerosol section.");
625 GSD_(*section_id) = (double)*new_value;
630 if (ret_val ==
true) {
649 double ln_gsd = log(
GSD_(*section_id));
651 GMD_(*section_id) / 2.0 * exp(5.0 * ln_gsd * ln_gsd / 2.0);
664 double *aero_rep_float_data) {
665 int *int_data = aero_rep_int_data;
666 double *float_data = aero_rep_float_data;
668 printf(
"\n\nModal/binned mass-only aerosol representation\n");
678 int *update_data = (
int *)malloc(3 *
sizeof(
int) +
sizeof(double));
679 if (update_data == NULL) {
680 printf(
"\n\nERROR allocating space for GMD update data.\n\n");
683 return (
void *)update_data;
697 int *new_aero_rep_id = (
int *)update_data;
698 int *update_type = (
int *)&(new_aero_rep_id[1]);
699 int *new_section_id = (
int *)&(update_type[1]);
700 double *new_GMD = (
double *)&(new_section_id[1]);
701 *new_aero_rep_id = aero_rep_id;
703 *new_section_id = section_id;
712 int *update_data = (
int *)malloc(3 *
sizeof(
int) +
sizeof(double));
713 if (update_data == NULL) {
714 printf(
"\n\nERROR allocating space for GSD update data.\n\n");
717 return (
void *)update_data;
731 int *new_aero_rep_id = (
int *)update_data;
732 int *update_type = (
int *)&(new_aero_rep_id[1]);
733 int *new_section_id = (
int *)&(update_type[1]);
734 double *new_GSD = (
double *)&(new_section_id[1]);
735 *new_aero_rep_id = aero_rep_id;
737 *new_section_id = section_id;
void aero_phase_get_volume__m3_m3(ModelData *model_data, int aero_phase_idx, double *state_var, double *volume, double *jac_elem)
Get the volume of an aerosol phase.
int aero_phase_get_used_jac_elem(ModelData *model_data, int aero_phase_idx, int state_var_id, bool *jac_struct)
Flag Jacobian elements used in calculations of mass and volume.
void aero_phase_get_mass__kg_m3(ModelData *model_data, int aero_phase_idx, double *state_var, double *mass, double *MW, double *jac_elem_mass, double *jac_elem_MW)
Get the mass and average MW in an aerosol phase.
void aero_rep_modal_binned_mass_set_gsd_update_data(void *update_data, int aero_rep_id, int section_id, double gsd)
Set GSD update data.
bool aero_rep_modal_binned_mass_update_data(void *update_data, int *aero_rep_int_data, double *aero_rep_float_data, double *aero_rep_env_data)
Update the aerosol representation data.
#define PHASE_STATE_ID_(x, y, b)
void aero_rep_modal_binned_mass_get_aero_phase_avg_MW__kg_mol(ModelData *model_data, int aero_phase_idx, double *aero_phase_avg_MW, double *partial_deriv, int *aero_rep_int_data, double *aero_rep_float_data, double *aero_rep_env_data)
Get the average molecular weight in an aerosol phase ( )
void aero_rep_modal_binned_mass_get_number_conc__n_m3(ModelData *model_data, int aero_phase_idx, double *number_conc, double *partial_deriv, int *aero_rep_int_data, double *aero_rep_float_data, double *aero_rep_env_data)
Get the particle number concentration ( )
void aero_rep_modal_binned_mass_set_gmd_update_data(void *update_data, int aero_rep_id, int section_id, double gmd)
Set GMD update data.
#define PHASE_MODEL_DATA_ID_(x, y, b)
void aero_rep_modal_binned_mass_update_state(ModelData *model_data, int *aero_rep_int_data, double *aero_rep_float_data, double *aero_rep_env_data)
Update aerosol representation data for a new state.
void aero_rep_modal_binned_mass_get_aero_conc_type(int aero_phase_idx, int *aero_conc_type, int *aero_rep_int_data, double *aero_rep_float_data, double *aero_rep_env_data)
Get the type of aerosol concentration used.
void aero_rep_modal_binned_mass_update_env_state(ModelData *model_data, int *aero_rep_int_data, double *aero_rep_float_data, double *aero_rep_env_data)
Update aerosol representation data for new environmental conditions.
void aero_rep_modal_binned_mass_print(int *aero_rep_int_data, double *aero_rep_float_data)
Print the mass-only modal/binned reaction parameters.
void aero_rep_modal_binned_mass_get_effective_radius__m(ModelData *model_data, int aero_phase_idx, double *radius, double *partial_deriv, int *aero_rep_int_data, double *aero_rep_float_data, double *aero_rep_env_data)
Get the effective particle radius (m)
void aero_rep_modal_binned_mass_get_dependencies(int *aero_rep_int_data, double *aero_rep_float_data, bool *state_flags)
Flag elements on the state array used by this aerosol representation.
#define NUMBER_CONC_(x, b)
void aero_rep_modal_binned_mass_get_aero_phase_mass__kg_m3(ModelData *model_data, int aero_phase_idx, double *aero_phase_mass, double *partial_deriv, int *aero_rep_int_data, double *aero_rep_float_data, double *aero_rep_env_data)
Get the total mass in an aerosol phase ( )
void * aero_rep_modal_binned_mass_create_gmd_update_data()
Create update data for new GMD.
int aero_rep_modal_binned_mass_get_used_jac_elem(ModelData *model_data, int aero_phase_idx, int *aero_rep_int_data, double *aero_rep_float_data, bool *jac_struct)
Flag Jacobian elements used in calcualtions of mass and volume.
#define PHASE_AVG_MW_(x, y, b)
#define PHASE_NUM_JAC_ELEM_(x, y, b)
#define PHASE_MASS_(x, y, b)
void * aero_rep_modal_binned_mass_create_gsd_update_data()
Create update data for new GSD.
#define EFFECTIVE_RADIUS_(x, b)