14#include <camp/aero_phase_solver.h>
15#include <camp/aero_reps.h>
16#include <camp/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;
166 double *env_data = model_data->grid_cell_env;
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++) {
202 double *state = (
double *)(model_data->grid_cell_state);
212 double phase_volume = 0.0;
215 &phase_volume, NULL);
216 volume += phase_volume;
223 (M_PI * pow(
GMD_(i_section), 3) *
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++) {
237 double *state = (
double *)(model_data->grid_cell_state);
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);
286 ModelData *model_data,
int aero_phase_idx,
double *layer_radius,
287 double *partial_deriv,
int *aero_rep_int_data,
double *aero_rep_float_data,
288 double *aero_rep_env_data) {
289 int *int_data = aero_rep_int_data;
290 double *float_data = aero_rep_float_data;
337 ModelData *model_data,
int aero_phase_idx,
double *radius,
338 double *partial_deriv,
int *aero_rep_int_data,
double *aero_rep_float_data,
339 double *aero_rep_env_data) {
340 int *int_data = aero_rep_int_data;
341 double *float_data = aero_rep_float_data;
343 for (
int i_section = 0; i_section <
NUM_SECTION_; i_section++) {
344 for (
int i_bin = 0; i_bin <
NUM_BINS_(i_section); i_bin++) {
346 if (aero_phase_idx < 0) {
350 for (
int i_phase = 0; i_phase <
NUM_PHASE_(i_section); ++i_phase) {
354 *(partial_deriv++) = ZERO;
386 ModelData *model_data,
int aero_phase_idx_first,
int aero_phase_idx_second,
387 double *surface_area,
double *partial_deriv,
int *aero_rep_int_data,
388 double *aero_rep_float_data,
double *aero_rep_env_data) {
389 int *int_data = aero_rep_int_data;
390 double *float_data = aero_rep_float_data;
393 printf(
"\n\nERROR There are no adjacent pairs in the modal/binned representation.\n\n");
414 ModelData *model_data,
int aero_phase_idx,
double *layer_thickness,
415 double *partial_deriv,
int *aero_rep_int_data,
double *aero_rep_float_data,
416 double *aero_rep_env_data) {
417 int *int_data = aero_rep_int_data;
418 double *float_data = aero_rep_float_data;
420 for (
int i_section = 0; i_section <
NUM_SECTION_; i_section++) {
421 for (
int i_bin = 0; i_bin <
NUM_BINS_(i_section); i_bin++) {
423 if (aero_phase_idx < 0) {
427 for (
int i_phase = 0; i_phase <
NUM_PHASE_(i_section); ++i_phase) {
431 *(partial_deriv++) = ZERO;
482 ModelData *model_data,
int aero_phase_idx,
double *number_conc,
483 double *partial_deriv,
int *aero_rep_int_data,
double *aero_rep_float_data,
484 double *aero_rep_env_data) {
485 int *int_data = aero_rep_int_data;
486 double *float_data = aero_rep_float_data;
488 for (
int i_section = 0; i_section < NUM_SECTION_ && aero_phase_idx >= 0;
490 for (
int i_bin = 0; i_bin <
NUM_BINS_(i_section) && aero_phase_idx >= 0;
493 if (aero_phase_idx < 0) {
496 for (
int i_phase = 0; i_phase <
NUM_PHASE_(i_section); ++i_phase) {
498 double *state = (
double *)(model_data->grid_cell_state);
502 double phase_volume = 0.0;
505 state, &phase_volume, partial_deriv);
513 *(partial_deriv++) *=
514 6.0 / (M_PI * pow(
GMD_(i_section), 3) *
515 exp(9.0 / 2.0 * pow(log(
GSD_(i_section)), 2)));
518 *(partial_deriv++) *= 3.0 / (4.0 * M_PI) /
519 pow(
BIN_DP_(i_section, i_bin) / 2.0, 3);
549 int *aero_rep_int_data,
550 double *aero_rep_float_data,
551 double *aero_rep_env_data) {
552 int *int_data = aero_rep_int_data;
553 double *float_data = aero_rep_float_data;
576 ModelData *model_data,
int aero_phase_idx,
double *aero_phase_mass,
577 double *partial_deriv,
int *aero_rep_int_data,
double *aero_rep_float_data,
578 double *aero_rep_env_data) {
579 int *int_data = aero_rep_int_data;
580 double *float_data = aero_rep_float_data;
582 for (
int i_section = 0; i_section < NUM_SECTION_ && aero_phase_idx >= 0;
584 for (
int i_bin = 0; i_bin <
NUM_BINS_(i_section) && aero_phase_idx >= 0;
586 if (aero_phase_idx < 0 || aero_phase_idx >=
NUM_PHASE_(i_section)) {
590 for (
int i_phase = 0; i_phase <
NUM_PHASE_(i_section); ++i_phase) {
591 if (aero_phase_idx == 0) {
592 *aero_phase_mass =
PHASE_MASS_(i_section, i_phase, i_bin);
595 double *state = (
double *)(model_data->grid_cell_state);
602 state, &mass, &mw, partial_deriv, NULL);
608 }
else if (partial_deriv) {
612 *(partial_deriv++) = ZERO;
639 ModelData *model_data,
int aero_phase_idx,
double *aero_phase_avg_MW,
640 double *partial_deriv,
int *aero_rep_int_data,
double *aero_rep_float_data,
641 double *aero_rep_env_data) {
642 int *int_data = aero_rep_int_data;
643 double *float_data = aero_rep_float_data;
645 for (
int i_section = 0; i_section < NUM_SECTION_ && aero_phase_idx >= 0;
647 for (
int i_bin = 0; i_bin <
NUM_BINS_(i_section) && aero_phase_idx >= 0;
649 if (aero_phase_idx < 0 || aero_phase_idx >=
NUM_PHASE_(i_section)) {
653 for (
int i_phase = 0; i_phase <
NUM_PHASE_(i_section); ++i_phase) {
654 if (aero_phase_idx == 0) {
655 *aero_phase_avg_MW =
PHASE_AVG_MW_(i_section, i_phase, i_bin);
658 double *state = (
double *)(model_data->grid_cell_state);
665 state, &mass, &mw, NULL, partial_deriv);
671 }
else if (partial_deriv) {
675 *(partial_deriv++) = ZERO;
708 int *aero_rep_int_data,
709 double *aero_rep_float_data,
710 double *aero_rep_env_data) {
711 int *int_data = aero_rep_int_data;
712 double *float_data = aero_rep_float_data;
714 int *aero_rep_id = (
int *)update_data;
715 int *update_type = (
int *)&(aero_rep_id[1]);
716 int *section_id = (
int *)&(update_type[1]);
717 double *new_value = (
double *)&(section_id[1]);
718 bool ret_val =
false;
725 "\n\nERROR Trying to set geometric mean diameter for non-modal"
726 " aerosol section.");
729 GMD_(*section_id) = (double)*new_value;
734 "\n\nERROR Trying to set geometric standard deviation for non-modal"
735 " aerosol section.");
738 GSD_(*section_id) = (double)*new_value;
743 if (ret_val ==
true) {
762 double ln_gsd = log(
GSD_(*section_id));
764 GMD_(*section_id) / 2.0 * exp(5.0 * ln_gsd * ln_gsd / 2.0);
777 double *aero_rep_float_data) {
778 int *int_data = aero_rep_int_data;
779 double *float_data = aero_rep_float_data;
781 printf(
"\n\nModal/binned mass-only aerosol representation\n");
791 int *update_data = (
int *)malloc(3 *
sizeof(
int) +
sizeof(
double));
792 if (update_data == NULL) {
793 printf(
"\n\nERROR allocating space for GMD update data.\n\n");
796 return (
void *)update_data;
810 int *new_aero_rep_id = (
int *)update_data;
811 int *update_type = (
int *)&(new_aero_rep_id[1]);
812 int *new_section_id = (
int *)&(update_type[1]);
813 double *new_GMD = (
double *)&(new_section_id[1]);
814 *new_aero_rep_id = aero_rep_id;
816 *new_section_id = section_id;
825 int *update_data = (
int *)malloc(3 *
sizeof(
int) +
sizeof(
double));
826 if (update_data == NULL) {
827 printf(
"\n\nERROR allocating space for GSD update data.\n\n");
830 return (
void *)update_data;
844 int *new_aero_rep_id = (
int *)update_data;
845 int *update_type = (
int *)&(new_aero_rep_id[1]);
846 int *new_section_id = (
int *)&(update_type[1]);
847 double *new_GSD = (
double *)&(new_section_id[1]);
848 *new_aero_rep_id = aero_rep_id;
850 *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_layer_thickness__m(ModelData *model_data, int aero_phase_idx, double *layer_thickness, double *partial_deriv, int *aero_rep_int_data, double *aero_rep_float_data, double *aero_rep_env_data)
Get the thickness of a particle layer (m)
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.
void aero_rep_modal_binned_mass_get_interface_surface_area__m2(ModelData *model_data, int aero_phase_idx_first, int aero_phase_idx_second, double *surface_area, double *partial_deriv, int *aero_rep_int_data, double *aero_rep_float_data, double *aero_rep_env_data)
Get the effective particle surface area (m)
void aero_rep_modal_binned_mass_get_effective_layer_radius__m(ModelData *model_data, int aero_phase_idx, double *layer_radius, double *partial_deriv, int *aero_rep_int_data, double *aero_rep_float_data, double *aero_rep_env_data)
Get the effective radius of a specified layer (m)
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)