18#define SMALL_NUMBER 1e-90
29 for (
unsigned int i_col = 0; i_col < num_spec; ++i_col) {
33 (
unsigned int *)malloc(
BUFFER_SIZE *
sizeof(
unsigned int));
47 unsigned int **jac_struct) {
48 unsigned int num_elem = 0;
49 for (
unsigned int i_col = 0; i_col < num_spec; ++i_col)
50 for (
unsigned int i_row = 0; i_row < num_spec; ++i_row)
51 if (jac_struct[i_col][i_row] == 1) ++num_elem;
55 jac->
col_ptrs = (
unsigned int *)malloc((num_spec + 1) *
sizeof(
unsigned int));
57 jac->
row_ids = (
unsigned int *)malloc(num_elem *
sizeof(
unsigned int));
63 (
long double *)malloc(num_elem *
sizeof(
long double));
69 jac->
loss_partials = (
long double *)malloc(num_elem *
sizeof(
long double));
77 unsigned int i_elem = 0;
78 unsigned int i_col = 0;
79 for (; i_col < num_spec; ++i_col) {
81 for (
unsigned int i_row = 0; i_row < num_spec; ++i_row) {
82 if (jac_struct[i_row][i_col] == 1) jac->
row_ids[i_elem++] = i_row;
93 unsigned int *temp_ids;
95 temp_ids = (
unsigned int *)malloc(column->
array_size *
sizeof(
unsigned int));
96 if (!temp_ids)
return 0;
98 temp_ids[i_elem] = column->
row_ids[i_elem];
106 unsigned int ind_id) {
109 "\n\nERROR - Trying to register elements in a Jacobian that has "
110 "already been built.\n\n");
115 if (column->
row_ids[i_elem] == dep_id)
return;
126 return (*(
unsigned int *)a - *(
unsigned int *)b);
132 "\n\nERROR - Trying to build a Jacobian that has already been "
137 for (
unsigned int i_col = 0; i_col < jac->
num_spec; ++i_col) {
144 (
unsigned int *)malloc((jac->
num_spec + 1) *
sizeof(
unsigned int));
149 jac->
row_ids = (
unsigned int *)malloc(jac->
num_elem *
sizeof(
unsigned int));
154 unsigned int i_elem = 0;
155 for (
unsigned int i_col = 0; i_col < jac->
num_spec; ++i_col) {
165 printf(
"\n\n ERROR - Internal error building Jacobain matrix %d %d\n\n",
170 (
long double *)malloc(jac->
num_elem *
sizeof(
long double));
176 (
long double *)malloc(jac->
num_elem *
sizeof(
long double));
181 for (
unsigned int i_col = 0; i_col < jac->
num_spec; ++i_col) {
201 unsigned int ind_id) {
202 if (ind_id >= jac.
num_spec || ind_id < 0) {
204 "\nError: Bad Jacobian column id: %u. Expected value between 0 and "
209 for (
unsigned int i_elem = jac.
col_ptrs[ind_id];
210 i_elem < jac.
col_ptrs[ind_id + 1]; ++i_elem) {
211 if (jac.
row_ids[i_elem] == dep_id)
return i_elem;
217 for (
unsigned int i_elem = 0; i_elem < jac.
num_elem; ++i_elem) {
224 for (
unsigned int i_col = 0; i_col < jac.
num_spec; ++i_col) {
225 for (
unsigned int i_elem = jac.
col_ptrs[i_col];
226 i_elem < jac.
col_ptrs[i_col + 1]; ++i_elem) {
229 dest_array[i_elem] = drf_dy - drr_dy;
235 unsigned int prod_or_loss,
236 long double jac_contribution) {
244 printf(
"\n *** Jacobian ***");
245 printf(
"\nnumber of variables: %d", jac.
num_spec);
246 printf(
"\nnumber of non-zero Jacobian elements: %d", jac.
num_elem);
249 printf(
"\nstatus: building Jacobian");
250 for (
unsigned int i_col = 0; i_col < jac.
num_spec; ++i_col) {
251 for (
unsigned int i_elem = 0;
253 printf(
"\n col = %6d row = %6d", i_col,
259 printf(
"\nstatus: Jacobian built");
260 for (
unsigned int i_col = 0; i_col < jac.
num_spec; ++i_col) {
261 for (
unsigned int i_elem = jac.
col_ptrs[i_col];
262 i_elem < jac.
col_ptrs[i_col + 1]; ++i_elem) {
263 printf(
"\n col = %6d row = %6d production = %Le loss = %Le", i_col,
269 printf(
"\nstatus: invalid state");
271 printf(
"\n *** end Jacobian ***");
299 for (
unsigned int i_col = 0; i_col < jac->
num_spec; ++i_col) {
unsigned int jacobian_column_pointer_value(Jacobian jac, unsigned int col_id)
Returns the value of a column pointer.
void jacobian_free(Jacobian *jac)
Free memory associated with a Jacobian.
unsigned int jacobian_build_matrix(Jacobian *jac)
Builds the sparse matrix with the registered elements.
int jacobian_initialize_empty(Jacobian *jac, unsigned int num_spec)
Initialize the Jacobian.
int jacobian_initialize(Jacobian *jac, unsigned int num_spec, unsigned int **jac_struct)
Initialize the Jacobian.
unsigned int jacobian_number_of_elements(Jacobian jac)
Returns the number of elements in the Jacobian.
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.
void jacobian_column_elements_free(JacobianColumnElements *column)
Free memory associated with a JacobianColumnElements.
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.
int compare_ids(const void *a, const void *b)
void jacobian_reset(Jacobian jac)
Reset the Jacobian.
void jacobian_register_element(Jacobian *jac, unsigned int dep_id, unsigned int ind_id)
Adds an element to the sparse matrix.
int jacobian_column_elements_add_space(JacobianColumnElements *column)
void jacobian_print(Jacobian jac)
Prints the Jacobian structure.
void jacobian_output(Jacobian jac, double *dest_array)
Output the Jacobian.
unsigned int jacobian_row_index(Jacobian jac, unsigned int elem_id)
Returns the row for a given Jacobian element.
Header for the Jacobian structure and related functions.
#define JACOBIAN_PRODUCTION
unsigned int number_of_elements
JacobianColumnElements * elements
long double * production_partials
long double * loss_partials
Header for the time derivative structure and related functions.