1 #include <../../nrnconf.h> 7 #include <../nrnoc/section.h> 8 #include <../nrnoc/nrn_ansi.h> 9 #include <../nrnoc/multicore.h> 13 static void ode_solve(
double,
double*,
double*);
130 static inline void*
allocopy(
void* src,
size_t size)
132 void* dst = malloc(size);
133 memcpy(dst, src, size);
191 _curr_scales = (
double*)malloc(
sizeof(
double)*num_currents);
192 memcpy(
_curr_scales, curr_scale,
sizeof(
double)*num_currents);
194 _curr_ptrs = (
double**)malloc(
sizeof(
double*)*num_currents);
195 for(i = 0; i < num_currents; i++)
209 _conc_ptrs = (
double**)malloc(
sizeof(
double*)*conc_count);
210 for(i = 0; i < conc_count; i++)
215 int* grids,
long*
index,
double* scales,
219 int i = 0,
j,
k,
n, grid_id;
237 if(
nrnmpi_use && dynamic_cast<ECS_Grid_node*>(g))
239 if (grid_id == grids[i])
240 n = grid_counts[i++];
245 nrnmpi_int_allgather_inplace(g->proc_num_fluxes, 1);
247 g->proc_flux_offsets[0] = 0;
249 g->proc_flux_offsets[
j] = g->proc_flux_offsets[
j-1] +
250 g->proc_num_fluxes[
j-1];
251 g->node_flux_count = g->proc_flux_offsets[
j-1] + g->proc_num_fluxes[
j-1];
255 g->node_flux_idx = (
long*)malloc(g->node_flux_count*
sizeof(
long));
256 g->node_flux_scale = (
double*)malloc(g->node_flux_count*
sizeof(
double));
257 g->node_flux_src = (PyObject**)
allocopy(&sources[offset], n*
sizeof(PyObject*));
260 for(
j = 0, k = g->proc_flux_offsets[
nrnmpi_myid];
j < n;
j++, k++)
262 g->node_flux_idx[
k] = index[offset +
j];
263 g->node_flux_scale[
k] = scales[offset +
j];
265 nrnmpi_long_allgatherv_inplace(g->node_flux_idx, g->proc_num_fluxes, g->proc_flux_offsets);
266 nrnmpi_dbl_allgatherv_inplace(g->node_flux_scale, g->proc_num_fluxes, g->proc_flux_offsets);
272 if(grid_id == grids[i])
274 g->node_flux_count = grid_counts[
i];
275 if(grid_counts[i] > 0)
277 g->node_flux_idx = (
long*)
allocopy(&index[offset], grid_counts[i]*
sizeof(
long));
278 g->node_flux_scale = (
double*)
allocopy(&scales[offset], grid_counts[i]*
sizeof(
double));
279 g->node_flux_src = (PyObject**)
allocopy(&sources[offset], grid_counts[i]*
sizeof(PyObject*));
281 offset += grid_counts[i++];
285 if(grid_id == grids[i])
287 g->node_flux_count = grid_counts[
i];
288 if(grid_counts[i] > 0)
290 g->node_flux_idx = (
long*)
allocopy(&index[offset], grid_counts[i]*
sizeof(
long));
291 g->node_flux_scale = (
double*)
allocopy(&scales[offset], grid_counts[i]*
sizeof(
double));
292 g->node_flux_src = (PyObject**)
allocopy(&sources[offset], grid_counts[i]*
sizeof(PyObject*));
294 offset += grid_counts[i++];
327 for(i = 0; i <
n; i++)
333 if(PyFloat_Check(source[i]))
335 states[
j] += dt * PyFloat_AsDouble(source[i]) / scale[
i];
337 else if(PyCallable_Check(source[i]))
346 states[
j] += dt * (src->
u.
x_) / scale[i];
350 states[
j] += dt * *(src->
u.
px_) / scale[i];
355 result = PyEval_CallObject(source[i],
NULL);
356 if(PyFloat_Check(result))
358 states[
j] += dt * PyFloat_AsDouble(result) / scale[
i];
360 else if(PyLong_Check(result))
362 states[
j] += dt * (double)PyLong_AsLong(result) / scale[
i];
371 PyErr_SetString(PyExc_Exception,
"node._include_flux callback did not return a number.\n");
377 PyErr_SetString(PyExc_Exception,
"node._include_flux unrecognised source term.\n");
389 long* nonzero_j,
double* nonzero_values,
395 unsigned int* parent_count;
417 _rxd_a = (
double*)calloc(nrow,
sizeof(
double));
418 _rxd_b = (
double*)calloc(nrow,
sizeof(
double));
419 _rxd_c = (
double*)calloc(nrow,
sizeof(
double));
420 _rxd_d = (
double*)calloc(nrow,
sizeof(
double));
421 _rxd_p = (
long*)malloc(nrow*
sizeof(
long));
422 parent_count = (
unsigned int*)calloc(nrow,
sizeof(
unsigned int));
424 for(idx = 0; idx < nrow; idx++)
427 for(idx = 0; idx < nnonzero; idx++)
431 val = nonzero_values[idx];
449 for(idx = 0; idx < nrow; idx++)
472 for(j = 0, k = 0; k < ps; j++)
474 if(_rxd_zero_volume_indices[i] ==
_rxd_p[j])
500 for(side = 0; side < 2; side++)
512 static void mul(
int nnonzero,
long* nonzero_i,
long* nonzero_j,
const double* nonzero_values,
const double*
v,
double*
result) {
516 for (k = 0; k < nnonzero; k++) {
519 result[
i] -= (*nonzero_values++) * v[j];
542 static void nrn_tree_solve(
double* a,
double* b,
double*
c,
double* dbase,
double*
rhs,
long* pindex,
long n,
double dt) {
555 double* d = (
double*)malloc(
sizeof(
double) *
n);
566 for (i = 0; i <
n; i++) {
567 *myd++ = *myc++ + dt * (*mydbase++);
571 for (i = n - 1; i > 0; --
i) {
575 p = dt * a[
i] / d[
i];
576 d[pin] -= dt * p * b[
i];
577 rhs[pin] -= p * rhs[
i];
581 for (i = 0; i <
n; ++
i) {
584 rhs[
i] -= dt * b[
i] * rhs[pin];
599 double* full_b, *full_y;
604 full_b = (
double*)calloc(
sizeof(
double),
num_states);
605 full_y = (
double*)calloc(
sizeof(
double),
num_states);
648 if(species_indices !=
NULL)
651 for(list = species_indices; list->
next !=
NULL; list = list->
next)
653 for(i=0, j=0; i<list->
length; i++)
685 free(_rxd_induced_currents_grid);
691 int* num_species,
int* node_idxs,
double* scales,
694 int i,
j,
k,
id, side, count;
695 int* induced_currents_ecs_idx;
696 int* induced_currents_grid_id;
698 double* current_scales;
720 _memb_cur_ptrs = (
double***)malloc(
sizeof(
double**)*num_currents);
730 for(i = 0, k = 0; i < num_currents; i++)
738 for(j = 0; j < num_species[
i]; j++, k++)
745 for(side = 0; side < 2; side++)
750 for(side = 0; side < 2; side++)
770 if(grid ==
NULL)
continue;
774 if(induced_currents_grid_id[k] ==
id)
776 _rxd_induced_currents_grid[
k] = grid;
782 ecs_indices = (
int*)malloc(count *
sizeof(
int));
786 if(induced_currents_grid_id[k] ==
id)
788 ecs_indices[
i] = induced_currents_ecs_idx[
k];
789 ecs_ptrs[i++] = ptrs[
k];
797 if(induced_currents_grid_id[k] ==
id)
807 free(induced_currents_ecs_idx);
808 free(induced_currents_grid_id);
814 int i,
j,
k, idx, side;
835 for(side = 0; side < 2; side++)
840 grid = _rxd_induced_currents_grid[
k];
922 printf(
"Unknown rxd_nonvint_block call: %d\n", method);
937 extern "C" void register_rate(
int nspecies,
int nparam,
int nregions,
int nseg,
938 int* sidx,
int necs,
int necsparam,
int* ecs_ids,
939 int* ecsidx,
int nmult,
double* mult,
942 int i,
j,
k,idx, ecs_id, ecs_index, ecs_offset;
943 unsigned char counted;
959 react->
vptrs = (
double**)malloc(nseg*
sizeof(
double*));
960 for(i = 0; i < nseg; i++)
967 react->
state_idx = (
int***)malloc(nseg*
sizeof(
double**));
968 for(i = 0, idx = 0; i < nseg; i++)
970 react->
state_idx[
i] = (
int**)malloc((nspecies + nparam)*
sizeof(
int*));
971 for(j = 0; j < nspecies + nparam; j++)
973 react->
state_idx[
i][
j] = (
int*)malloc(nregions*
sizeof(
int));
974 for(k = 0; k < nregions; k++, idx++)
983 if(i==0 && j < nspecies)
991 react->
mc_multiplier = (
double**)malloc(nmult*
sizeof(
double*));
992 for(i = 0; i < nmult; i++)
995 memcpy(react->
mc_multiplier[i], (mult+i*nseg), nseg*
sizeof(
double));
1002 react->
ecs_state = (
double***)malloc(nseg*
sizeof(
double**));
1003 react->
ecs_index = (
int**)malloc(nseg*
sizeof(
int*));
1005 for(i = 0; i < nseg; i++)
1007 react->
ecs_state[
i] = (
double**)malloc((necs+necsparam)*
sizeof(
double*));
1008 react->
ecs_index[
i] = (
int*)malloc((necs+necsparam)*
sizeof(
int));
1011 for(j = 0; j < necs + necsparam; j++)
1018 if (ecs_id == ecs_ids[j])
1028 for(i = 0, counted=
FALSE; i < nseg; i++)
1031 ecs_index = ecsidx[i*(necs + necsparam) + j];
1037 if(j < necs && !counted)
1057 if(_reactions ==
NULL)
1081 for(react = _reactions; react !=
NULL;)
1100 for(i = 0; i < react->
num_mult; i++)
1108 react = react->
next;
1121 if(species_indices !=
NULL)
1123 for(list = species_indices, prev =
NULL;
1142 list->
indices = (
int*)malloc(
sizeof(
int)*len);
1143 memcpy(list->
indices,idx,
sizeof(
int)*len);
1153 for(list = species_indices, prev =
NULL;
1154 list !=
NULL; prev = list, list = list->
next)
1159 species_indices = list->
next;
1162 free(list->indices);
1169 extern "C" void setup_solver(
double* my_states,
int my_num_states,
long* zvi,
int num_zvi) {
1194 Threads = (pthread_t*)malloc(
sizeof(pthread_t)*(n-1));
1195 AllTasks->
task_mutex = (pthread_mutex_t*)malloc(
sizeof(pthread_mutex_t));
1196 AllTasks->
waiting_mutex = (pthread_mutex_t*)malloc(
sizeof(pthread_mutex_t));
1197 AllTasks->
task_cond = (pthread_cond_t*)malloc(
sizeof(pthread_cond_t));
1198 AllTasks->
waiting_cond = (pthread_cond_t*)malloc(
sizeof(pthread_cond_t));
1204 for(i = 0; i < n-1; i++)
1299 for(k=old_num-1; k>=
n; k--)
1313 for (k = old_num-1; k <
n; k++)
1345 rhs = (
double*)calloc(
num_states,
sizeof(
double));
1412 const unsigned char calculate_rhs = p2 ==
NULL ? 0 : 1;
1464 rhs = (
double*)calloc(
num_states,
sizeof(
double));
1474 const double* states3d = orig_states3d;
1475 double* ydot3d = orig_ydot3d;
1483 ydot3d += grid_size;
1484 states3d += grid_size;
1520 double** states_for_reaction = (
double**)malloc(react->
num_species*
sizeof(
double*));
1521 double** params_for_reaction = (
double**)malloc(react->
num_params*
sizeof(
double*));
1522 double** result_array = (
double**)malloc(react->
num_species*
sizeof(
double*));
1523 double* mc_mult =
NULL;
1526 mc_mult = (
double*)malloc(react->
num_mult*
sizeof(
double));
1528 double* ecs_states_for_reaction =
NULL;
1529 double* ecs_params_for_reaction =
NULL;
1530 double* ecs_result =
NULL;
1531 int * ecsindex =
NULL;
1535 ecs_states_for_reaction = (
double*)malloc(react->
num_ecs_species*
sizeof(
double));
1539 ecs_params_for_reaction = (
double*)calloc(react->
num_ecs_params,
sizeof(
double));
1543 flux = (
double**)malloc(react->
icsN*
sizeof(
double*));
1544 for(i = 0; i < react->
icsN; i++)
1545 flux[i] = (
double*)calloc(react->
num_regions,
sizeof(
double));
1550 states_for_reaction[
i] = (
double*)calloc(react->
num_regions,
sizeof(
double));
1551 result_array[
i] = (
double*)malloc(react->
num_regions*
sizeof(
double));
1555 params_for_reaction[i] = (
double*)calloc(react->
num_regions,
sizeof(
double));
1560 for(segment = 0; segment < react->num_segments; segment++)
1568 states_for_reaction[
i][
j] = states[react->
state_idx[segment][
i][
j]];
1572 states_for_reaction[
i][
j] = NAN;
1583 params_for_reaction[
k][
j] = states[react->
state_idx[segment][
i][
j]];
1587 params_for_reaction[
k][
j] = NAN;
1596 ecs_states_for_reaction[
i] = *(react->
ecs_state[segment][
i]);
1600 ecs_states_for_reaction[
i] = NAN;
1608 ecs_params_for_reaction[
k] = *(react->
ecs_state[segment][
i]);
1612 ecs_params_for_reaction[
k] = NAN;
1617 for(i = 0; i < react->
num_mult; i++)
1624 v = *(react->
vptrs[segment]);
1627 react->
reaction(states_for_reaction, params_for_reaction, result_array, mc_mult, ecs_states_for_reaction, ecs_params_for_reaction, ecs_result, flux, v);
1642 rates[idx] += result_array[
i][
j];
1662 for(i = 0; i < react->
icsN; i++)
1668 free(ecs_states_for_reaction);
1673 free(states_for_reaction[i]);
1674 free(result_array[i]);
1676 free(states_for_reaction);
1680 free(params_for_reaction[i]);
1682 free(params_for_reaction);
1685 free(ecs_params_for_reaction);
1694 int i,
j,
k, idx, jac_i, jac_j, jac_idx;
1698 double dx = FLT_EPSILON;
1704 double** states_for_reaction = (
double**)malloc(react->
num_species*
sizeof(
double*));
1705 double** states_for_reaction_dx = (
double**)malloc(react->
num_species*
sizeof(
double*));
1706 double** params_for_reaction = (
double**)malloc(react->
num_params*
sizeof(
double*));
1707 double** result_array = (
double**)malloc(react->
num_species*
sizeof(
double*));
1708 double** result_array_dx = (
double**)malloc(react->
num_species*
sizeof(
double*));
1709 double* mc_mult =
NULL;
1711 mc_mult = (
double*)malloc(react->
num_mult*
sizeof(
double));
1713 double* ecs_states_for_reaction =
NULL;
1714 double* ecs_states_for_reaction_dx =
NULL;
1715 double* ecs_params_for_reaction =
NULL;
1716 double* ecs_result =
NULL;
1717 double* ecs_result_dx =
NULL;
1719 int* ecsindex =
NULL;
1726 ecs_states_for_reaction = (
double*)malloc(react->
num_ecs_species*
sizeof(
double));
1727 ecs_states_for_reaction_dx = (
double*)malloc(react->
num_ecs_species*
sizeof(
double));
1729 ecs_result_dx = (
double*)malloc(react->
num_ecs_species*
sizeof(
double));
1733 ecs_params_for_reaction = (
double*)malloc(react->
num_ecs_params*
sizeof(
double));
1738 states_for_reaction[
i] = (
double*)malloc(react->
num_regions*
sizeof(
double));
1739 states_for_reaction_dx[
i] = (
double*)malloc(react->
num_regions*
sizeof(
double));
1740 result_array[
i] = (
double*)malloc(react->
num_regions*
sizeof(
double));
1741 result_array_dx[
i] = (
double*)malloc(react->
num_regions*
sizeof(
double));
1744 params_for_reaction[i] = (
double*)malloc(react->
num_regions*
sizeof(
double));
1746 for(segment = 0; segment < react->
num_segments; segment++)
1749 v = *(react->
vptrs[segment]);
1757 states_for_reaction[
i][
j] = states[react->
state_idx[segment][
i][
j]];
1758 states_for_reaction_dx[
i][
j] = states_for_reaction[
i][
j];
1763 states_for_reaction_dx[
i][
j] = states_for_reaction[
i][
j];
1776 params_for_reaction[
k][
j] = states[react->
state_idx[segment][
i][
j]];
1791 if(cvode_states !=
NULL)
1793 ecs_states_for_reaction[
i] = cvode_states[react->
ecs_index[segment][
i]];
1797 ecs_states_for_reaction[
i] = *(react->
ecs_state[segment][
i]);
1799 ecs_states_for_reaction_dx[
i] = ecs_states_for_reaction[
i];
1806 ecs_params_for_reaction[
k] = *(react->
ecs_state[segment][
i]);
1816 for(i = 0; i < react->
num_mult; i++)
1821 react->
reaction(states_for_reaction, params_for_reaction, result_array,
1822 mc_mult, ecs_states_for_reaction,
1823 ecs_params_for_reaction, ecs_result,
NULL, v);
1833 v_set_val(b, idx, dt*result_array[i][j]);
1839 states_for_reaction_dx[
i][
j] += dx;
1844 react->
reaction(states_for_reaction_dx, params_for_reaction,
1845 result_array_dx, mc_mult,
1846 ecs_states_for_reaction,
1847 ecs_params_for_reaction, ecs_result_dx,
1850 for (jac_i = 0, jac_idx = 0; jac_i < react->
num_species; jac_i++)
1852 for (jac_j = 0; jac_j < react->
num_regions; jac_j++)
1857 pd = (result_array_dx[jac_i][jac_j] - result_array[jac_i][jac_j])/dx;
1858 m_set_val(jacobian, jac_idx, idx, (idx==jac_idx) - dt*pd);
1861 result_array_dx[jac_i][jac_j] = 0;
1869 pd = (ecs_result_dx[jac_i] - ecs_result[jac_i])/dx;
1870 m_set_val(jacobian, jac_idx, idx, -dt*pd);
1873 ecs_result_dx[jac_i] = 0;
1876 states_for_reaction_dx[
i][
j] -= dx;
1894 ecs_states_for_reaction_dx[
i] += dx;
1899 react->
reaction(states_for_reaction, params_for_reaction, result_array_dx,
1900 mc_mult, ecs_states_for_reaction_dx,
1901 ecs_params_for_reaction, ecs_result_dx,
NULL, v);
1903 for (jac_i = 0, jac_idx = 0; jac_i < react->
num_species; jac_i++)
1905 for (jac_j = 0; jac_j < react->
num_regions; jac_j++)
1910 pd = (result_array_dx[jac_i][jac_j] - result_array[jac_i][jac_j])/dx;
1911 m_set_val(jacobian, jac_idx, idx, - dt*pd);
1921 pd = (ecs_result_dx[jac_i] - ecs_result[jac_i])/dx;
1922 m_set_val(jacobian, jac_idx, idx, (idx==jac_idx) - dt*pd);
1930 ecs_states_for_reaction_dx[
i] -= dx;
1937 LUsolve(jacobian, pivot, b, x);
1941 for(i = 0, jac_idx=0; i < react->
num_species; i++)
1961 for(i = 0, jac_idx=0; i < react->
num_species; i++)
1984 free(states_for_reaction[i]);
1985 free(states_for_reaction_dx[i]);
1986 free(result_array[i]);
1987 free(result_array_dx[i]);
1990 free(params_for_reaction[i]);
1993 free(states_for_reaction_dx);
1994 free(states_for_reaction);
1995 free(params_for_reaction);
1997 free(result_array_dx);
2000 free(ecs_states_for_reaction);
2001 free(ecs_states_for_reaction_dx);
2003 free(ecs_result_dx);
2006 free(ecs_params_for_reaction);
2012 for(react = _reactions; react !=
NULL; react = react->
next)
2024 for(react = _reactions; react !=
NULL; react = react->
next)
static void free_currents()
MAT * LUfactor(MAT *A, PERM *pivot)
int prev_structure_change_cnt
double * _node_flux_scale
void _ecs_ode_reinit(double *)
void solve_reaction(ICSReactions *react, double *states, double *bval, double *cvode_states, double *cvode_b)
double * local_induced_currents
void rxd_set_euler_matrix(int nrow, int nnonzero, long *nonzero_i, long *nonzero_j, double *nonzero_values, double *c_diagonal)
int rxd_nonvint_block(int method, int size, double *p1, double *p2, int)
void _ode_reinit(double *y)
struct ICSReactions * next
ECS_Grid_node ** ecs_grid
static void mul(int nnonzero, long *nonzero_i, long *nonzero_j, const double *nonzero_values, const double *v, double *result)
Represent main neuron object computed by single thread.
long * _rxd_zero_volume_indices
void TaskQueue_sync(TaskQueue *q)
unsigned char _membrane_flux
#define m_set_val(A, i, j, val)
struct SpeciesIndexList * next
static int ode_count(int type)
void set_num_threads(const int n)
void _rhs_variable_step(const double *p1, double *p2)
static void nrn_tree_solve(double *a, double *b, double *c, double *dbase, double *rhs, long *pindex, long n, double dt)
static void * allocopy(void *src, size_t size)
static philox4x32_key_t k
void ecs_atolscale(double *)
void start_threads(const int n)
long * _rxd_euler_nonzero_i
double * set_rxd_currents(int, int *, PyHocObject **)
void rxd_setup_curr_ptrs(int num_currents, int *curr_index, double *curr_scale, PyHocObject **curr_ptrs)
pthread_cond_t * task_cond
unsigned int * _rxd_zvi_child_count
double * all_reaction_states
Grid_node * Parallel_grids[100]
void species_atolscale(int id, double scale, int len, int *idx)
void set_initialize(const fptr initialize_fn)
void do_ics_reactions(double *states, double *b, double *cvode_states, double *cvode_b)
void _rhs_variable_step_ecs(const double *, double *)
void register_rate(int nspecies, int nparam, int nregions, int nseg, int *sidx, int necs, int necsparam, int *ecs_ids, int *ecsidx, int nmult, double *mult, PyHocObject **vptrs, ReactionRate f)
static void _currents(double *rhs)
int const size_t const size_t n
static void free_zvi_child()
VEC * LUsolve(MAT *A, PERM *pivot, VEC *b, VEC *x)
void get_all_reaction_rates(double *states, double *rates, double *ydot)
pthread_mutex_t * task_mutex
double * _rxd_euler_nonzero_values
void rxd_set_no_diffusion()
PyObject ** _node_flux_src
PyTypeObject * hocobject_type
double * _rxd_induced_currents_scale
void remove_species_atolscale(int id)
#define v_set_val(x, i, val)
virtual void variable_step_hybrid_connections(const double *cvode_states_3d, double *const ydot_3d, const double *cvode_states_1d, double *const ydot_1d)=0
static void transfer_to_legacy()
unsigned char initialized
static void add_currents(double *result)
int * _memb_species_count
void apply_node_flux(int n, long *index, double *scale, PyObject **source, double dt, double *states)
static double v_get(void *v)
void get_reaction_rates(ICSReactions *react, double *states, double *rates, double *ydot)
void _fadvance_fixed_step_3D(void)
void rxd_include_node_flux1D(int n, long *index, double *scales, PyObject **sources)
void setup_currents(int num_currents, int num_fluxes, int *num_species, int *node_idxs, double *scales, PyHocObject **ptrs, int *mapped, int *mapped_ecs)
SpeciesIndexList * species_indices
double * _rxd_induced_currents
void rxd_include_node_flux3D(int grid_count, int *grid_counts, int *grids, long *index, double *scales, PyObject **sources)
ICSReactions * _reactions
static void apply_node_flux1D(double dt, double *states)
void rxd_setup_conc_ptrs(int conc_count, int *conc_index, PyHocObject **conc_ptrs)
void set_setup_units(fptr setup_units)
pthread_mutex_t * waiting_mutex
void flux(Item *qREACTION, Item *qdir, Item *qlast)
ECS_Grid_node ** _rxd_induced_currents_grid
void * TaskQueue_exe_tasks(void *dat)
int prev_nrnunit_use_legacy
pthread_cond_t * waiting_cond
int get_num_threads(void)
PyObject ** node_flux_src
double *** _memb_cur_ptrs
void set_num_threads_3D(int n)
void initialize_multicompartment_reaction()
void ics_ode_solve(double, double *, const double *)
void(* ReactionRate)(double **, double **, double **, double *, double *, double *, double *, double **, double)
void set_setup_matrices(fptr setup_matrices)
static void ode_abs_tol(double *p1)
void TaskQueue_add_task(TaskQueue *q, void *(*task)(void *), void *args, void *result)
static double jacobian(void *v)
static void ode_solve(double, double *, double *)
long * _rxd_euler_nonzero_j
void setup_solver(double *my_states, int my_num_states, long *zvi, int num_zvi)
void set_setup(const fptr setup_fn)
int add_multicompartment_reaction(int, int *, int)
int *** _memb_cur_mapped_ecs