From 2cd30c0a128c6c9210b852dc0ba0cf25c7550154 Mon Sep 17 00:00:00 2001 From: DSPOM Date: Fri, 1 Jul 2022 10:49:16 +0200 Subject: [PATCH] fix: update diode to latest ngspice version --- test_cases/diode/diode.c | 403 ++++++++++++++++++++------------------- 1 file changed, 206 insertions(+), 197 deletions(-) diff --git a/test_cases/diode/diode.c b/test_cases/diode/diode.c index 85110ef5d..75daef690 100644 --- a/test_cases/diode/diode.c +++ b/test_cases/diode/diode.c @@ -23,6 +23,8 @@ extern uint32_t OSDI_VERSION_MINOR; extern uint32_t OSDI_NUM_DESCRIPTORS; extern OsdiDescriptor OSDI_DESCRIPTORS[1]; +#define IGNORE(x) (void)x + // number of nodes and definitions of node ids for nicer syntax in this file // note: order should be same as "nodes" list defined later #define NUM_NODES 4 @@ -52,8 +54,7 @@ extern OsdiDescriptor OSDI_DESCRIPTORS[1]; #define TNODE_CI 13 // The model structure for the diode -typedef struct DiodeModel -{ +typedef struct DiodeModel { double Rs; bool Rs_given; double Is; @@ -82,16 +83,16 @@ typedef struct DiodeModel } DiodeModel; // The instace structure for the diode -typedef struct DiodeInstace -{ +typedef struct DiodeInstace { double mfactor; // multiplication factor for parallel devices bool mfactor_given; double temperature; - double rhs_resist[NUM_NODES]; - double rhs_react[NUM_NODES]; + double residual_resist[NUM_NODES]; + double residual_react_A; + double residual_react_CI; double jacobian_resist[NUM_MATRIX]; double jacobian_react[NUM_MATRIX]; - bool is_collapsible[NUM_COLLAPSIBLE]; + bool collapsed[NUM_COLLAPSIBLE]; double *jacobian_ptr_resist[NUM_MATRIX]; double *jacobian_ptr_react[NUM_MATRIX]; uint32_t node_off[NUM_NODES]; @@ -99,33 +100,25 @@ typedef struct DiodeInstace #define EXP_LIM 80.0 -double limexp(double x) -{ - if (x < EXP_LIM) - { +static double limexp(double x) { + if (x < EXP_LIM) { return exp(x); - } - else - { + } else { return exp(EXP_LIM) * (x + 1 - EXP_LIM); } } -double dlimexp(double x) -{ - if (x < EXP_LIM) - { +static double dlimexp(double x) { + if (x < EXP_LIM) { return exp(x); - } - else - { + } else { return exp(EXP_LIM); } } // implementation of the access function as defined by the OSDI spec -void *osdi_access(void *inst_, void *model_, uint32_t id, uint32_t flags) -{ +static void *osdi_access(void *inst_, void *model_, uint32_t id, + uint32_t flags) { DiodeModel *model = (DiodeModel *)model_; DiodeInstace *inst = (DiodeInstace *)inst_; @@ -135,13 +128,10 @@ void *osdi_access(void *inst_, void *model_, uint32_t id, uint32_t flags) switch (id) // id of params defined in param_opvar array { case 0: - if (flags & ACCESS_FLAG_INSTANCE) - { + if (flags & ACCESS_FLAG_INSTANCE) { value = (void *)&inst->mfactor; given = &inst->mfactor_given; - } - else - { + } else { value = (void *)&model->mfactor; given = &model->mfactor_given; } @@ -194,8 +184,7 @@ void *osdi_access(void *inst_, void *model_, uint32_t id, uint32_t flags) return NULL; } - if (flags & ACCESS_FLAG_SET) - { + if (flags & ACCESS_FLAG_SET) { *given = true; } @@ -203,102 +192,96 @@ void *osdi_access(void *inst_, void *model_, uint32_t id, uint32_t flags) } // implementation of the setup_model function as defined in the OSDI spec -OsdiInitInfo setup_model(void *_handle, void *model_) -{ +static void setup_model(void *handle, void *model_, OsdiSimParas *sim_params, + OsdiInitInfo *res) { DiodeModel *model = (DiodeModel *)model_; + IGNORE(handle); + IGNORE(sim_params); + // set parameters and check bounds - if (!model->mfactor_given) - { + if (!model->mfactor_given) { model->mfactor = 1.0; } - if (!model->Rs_given) - { + if (!model->Rs_given) { model->Rs = 1e-9; } - if (!model->Is_given) - { + if (!model->Is_given) { model->Is = 1e-14; } - if (!model->zetars_given) - { + if (!model->zetars_given) { model->zetars = 0; } - if (!model->N_given) - { + if (!model->N_given) { model->N = 1; } - if (!model->Cj0_given) - { + if (!model->Cj0_given) { model->Cj0 = 0; } - if (!model->Vj_given) - { + if (!model->Vj_given) { model->Vj = 1.0; } - if (!model->M_given) - { + if (!model->M_given) { model->M = 0.5; } - if (!model->Rth_given) - { + if (!model->Rth_given) { model->Rth = 0; } - if (!model->zetarth_given) - { + if (!model->zetarth_given) { model->zetarth = 0; } - if (!model->zetais_given) - { + if (!model->zetais_given) { model->zetais = 0; } - if (!model->Tnom_given) - { + if (!model->Tnom_given) { model->Tnom = 300; } - return (OsdiInitInfo){.flags = 0, .num_errors = 0, .errors = NULL}; + *res = (OsdiInitInfo){.flags = 0, .num_errors = 0, .errors = NULL}; } // implementation of the setup_instace function as defined in the OSDI spec -OsdiInitInfo setup_instance(void *_handle, void *inst_, void *model_, - double temperature, uint32_t _num_terminals) -{ +static void setup_instance(void *handle, void *inst_, void *model_, + double temperature, uint32_t num_terminals, + OsdiSimParas *sim_params, OsdiInitInfo *res) { + + IGNORE(handle); + IGNORE(num_terminals); + IGNORE(sim_params); + DiodeInstace *inst = (DiodeInstace *)inst_; DiodeModel *model = (DiodeModel *)model_; - // Here the logic for node collapsing ist implemented. The indices in this list must adhere to the "collapsible" List of node pairs. - if (model->Rs<1e-9){ // Rs between Ci C - inst->is_collapsible[0] = true; + // Here the logic for node collapsing ist implemented. The indices in this + // list must adhere to the "collapsible" List of node pairs. + if (model->Rs < 1e-9) { // Rs between Ci C + inst->collapsed[0] = true; } - if (model->Rth<1e-9){ // Rs between Ci C - inst->is_collapsible[1] = true; + if (model->Rth < 1e-9) { // Rs between Ci C + inst->collapsed[1] = true; } - if (!inst->mfactor_given) - { - if (model->mfactor_given) - { + if (!inst->mfactor_given) { + if (model->mfactor_given) { inst->mfactor = model->mfactor; - } - else - { + } else { inst->mfactor = 1; } } inst->temperature = temperature; - return (OsdiInitInfo){.flags = 0, .num_errors = 0, .errors = NULL}; + *res = (OsdiInitInfo){.flags = 0, .num_errors = 0, .errors = NULL}; } // implementation of the eval function as defined in the OSDI spec -uint32_t eval(void *handle, void *inst_, void *model_, uint32_t flags, - double *prev_solve, OsdiSimParas *sim_params) -{ +static uint32_t eval(void *handle, void *inst_, void *model_, + OsdiSimInfo *info) { + IGNORE(handle); DiodeModel *model = (DiodeModel *)model_; DiodeInstace *inst = (DiodeInstace *)inst_; // get voltages + double *prev_solve = info->prev_solve; double va = prev_solve[inst->node_off[A]]; double vc = prev_solve[inst->node_off[C]]; double vci = prev_solve[inst->node_off[CI]]; @@ -308,11 +291,9 @@ uint32_t eval(void *handle, void *inst_, void *model_, uint32_t flags, double vaci = va - vci; double gmin = 1e-12; - for (int i = 0; sim_params->names[i] != NULL; i++) - { - if (strcmp(sim_params->names[i], "gmin") == 0) - { - gmin = sim_params->vals[i]; + for (int i = 0; info->paras.names[i] != NULL; i++) { + if (strcmp(info->paras.names[i], "gmin") == 0) { + gmin = info->paras.vals[i]; } } @@ -325,18 +306,18 @@ uint32_t eval(void *handle, void *inst_, void *model_, uint32_t flags, double pq = 1.602176462e-19; double t_dev = inst->temperature + vdtj; double tdev_tnom = t_dev / model->Tnom; - double rs_t = model->Rs * powf(tdev_tnom, model->zetars); - double rth_t = model->Rth * powf(tdev_tnom, model->zetarth); - double is_t = model->Is * powf(tdev_tnom, model->zetais); + double rs_t = model->Rs * pow(tdev_tnom, model->zetars); + double rth_t = model->Rth * pow(tdev_tnom, model->zetarth); + double is_t = model->Is * pow(tdev_tnom, model->zetais); double vt = t_dev * pk / pq; // derivatives w.r.t. temperature double rs_dt = model->zetars * model->Rs * - powf(tdev_tnom, model->zetars - 1.0) / model->Tnom; + pow(tdev_tnom, model->zetars - 1.0) / model->Tnom; double rth_dt = model->zetarth * model->Rth * - powf(tdev_tnom, model->zetarth - 1.0) / model->Tnom; + pow(tdev_tnom, model->zetarth - 1.0) / model->Tnom; double is_dt = model->zetais * model->Is * - powf(tdev_tnom, model->zetais - 1.0) / model->Tnom; + pow(tdev_tnom, model->zetais - 1.0) / model->Tnom; double vt_tj = pk / pq; // evaluate model equations and calculate all derivatives @@ -351,23 +332,22 @@ uint32_t eval(void *handle, void *inst_, void *model_, uint32_t flags, double irs = 0; double g = 0; double grt = 0; - if (!inst->is_collapsible[0]) { + if (!inst->collapsed[0]) { irs = vcic / rs_t; g = 1.0 / rs_t; grt = -irs / rs_t * rs_dt; } - // thermal resistance double irth = 0; double gt = 0; - if (!inst->is_collapsible[1]) { + if (!inst->collapsed[1]) { irth = vdtj / rth_t; gt = 1.0 / rth_t - irth / rth_t * rth_dt; } // charge - double vf = model->Vj * (1.0 - powf(3.04, -1.0 / model->M)); + double vf = model->Vj * (1.0 - pow(3.04, -1.0 / model->M)); double x = (vf - vaci) / vt; double x_vt = -x / vt; double x_dtj = x_vt * vt_tj; @@ -383,22 +363,22 @@ uint32_t eval(void *handle, void *inst_, void *model_, uint32_t flags, double vd_dtj = vd_x * x_dtj + vd_y * y_dtj + vd_vt * vt_tj; double vd_vaci = vd_x * x_vaci + vd_y * y_vaci; double qd = model->Cj0 * vaci * model->Vj * - (1.0 - powf(1.0 - vd / model->Vj, 1.0 - model->M)) / + (1.0 - pow(1.0 - vd / model->Vj, 1.0 - model->M)) / (1.0 - model->M); double qd_vd = model->Cj0 * model->Vj / (1.0 - model->M) * (1.0 - model->M) * - powf(1.0 - vd / model->Vj, 1.0 - model->M - 1.0) / model->Vj; + pow(1.0 - vd / model->Vj, 1.0 - model->M - 1.0) / model->Vj; double qd_dtj = qd_vd * vd_dtj; double qd_vaci = qd_vd * vd_vaci; // thermal power source = current source - double ith = id * vaci ; - double ith_vtj = gdt * vaci ; + double ith = id * vaci; + double ith_vtj = gdt * vaci; double ith_vcic = 0; double ith_vaci = gd * vaci + id; - if (!inst->is_collapsible[0]) { + if (!inst->collapsed[0]) { ith_vcic = 2.0 * vcic / rs_t; - ith += powf(vcic, 2.0) / rs_t; - ith_vtj -= - powf(vcic, 2.0) / rs_t / rs_t * rs_dt; + ith += pow(vcic, 2.0) / rs_t; + ith_vtj -= -pow(vcic, 2.0) / rs_t / rs_t * rs_dt; } id += gmin * vaci; @@ -410,28 +390,25 @@ uint32_t eval(void *handle, void *inst_, void *model_, uint32_t flags, // write rhs //////////////// - if (flags & CALC_RESIST_RESIDUAL) - { + if (info->flags & CALC_RESIST_RESIDUAL) { // write resist rhs - inst->rhs_resist[A] = id * mfactor; - inst->rhs_resist[CI] = -id * mfactor + irs * mfactor; - inst->rhs_resist[C] = -irs * mfactor; - inst->rhs_resist[TNODE] = -ith * mfactor + irth * mfactor; + inst->residual_resist[A] = id * mfactor; + inst->residual_resist[CI] = -id * mfactor + irs * mfactor; + inst->residual_resist[C] = -irs * mfactor; + inst->residual_resist[TNODE] = -ith * mfactor + irth * mfactor; } - if (flags & CALC_REACT_RESIDUAL) - { + if (info->flags & CALC_REACT_RESIDUAL) { // write react rhs - inst->rhs_react[A] = qd * mfactor; - inst->rhs_react[CI] = -qd * mfactor; + inst->residual_react_A = qd * mfactor; + inst->residual_react_CI = -qd * mfactor; } ////////////////// // write Jacobian ////////////////// - if (flags & CALC_RESIST_JACOBIAN) - { + if (info->flags & CALC_RESIST_JACOBIAN) { // stamp diode (current flowing from Ci into A) inst->jacobian_resist[A_A] = gd * mfactor; inst->jacobian_resist[A_CI] = -gd * mfactor; @@ -460,8 +437,7 @@ uint32_t eval(void *handle, void *inst_, void *model_, uint32_t flags, inst->jacobian_resist[TNODE_A] = ith_vaci * mfactor; } - if (flags & CALC_REACT_JACOBIAN) - { + if (info->flags & CALC_REACT_JACOBIAN) { // write react matrix // stamp Qd between nodes A and Ci depending also on dT inst->jacobian_react[A_A] = qd_vaci * mfactor; @@ -477,43 +453,45 @@ uint32_t eval(void *handle, void *inst_, void *model_, uint32_t flags, } // TODO implementation of the load_noise function as defined in the OSDI spec -void load_noise(void *inst, void *model, double freq, double *noise_dens, - double *ln_noise_dens) -{ +static void load_noise(void *inst, void *model, double freq, double *noise_dens, + double *ln_noise_dens) { + IGNORE(inst); + IGNORE(model); + IGNORE(freq); + IGNORE(noise_dens); + IGNORE(ln_noise_dens); // TODO add noise to example } -#define LOAD_RHS_RESIST(name) \ - dst[inst->node_off[name]] += inst->rhs_resist[name]; +#define LOAD_RESIDUAL_RESIST(name) \ + dst[inst->node_off[name]] += inst->residual_resist[name]; // implementation of the load_rhs_resist function as defined in the OSDI spec -void load_residual_resist(void *inst_, double *dst) -{ +static void load_residual_resist(void *inst_, void *model, double *dst) { DiodeInstace *inst = (DiodeInstace *)inst_; - LOAD_RHS_RESIST(A) - LOAD_RHS_RESIST(CI) - LOAD_RHS_RESIST(C) - LOAD_RHS_RESIST(TNODE) + IGNORE(model); + LOAD_RESIDUAL_RESIST(A) + LOAD_RESIDUAL_RESIST(CI) + LOAD_RESIDUAL_RESIST(C) + LOAD_RESIDUAL_RESIST(TNODE) } -#define LOAD_RHS_REACT(name) dst[inst->node_off[name]] += inst->rhs_react[name]; - // implementation of the load_rhs_react function as defined in the OSDI spec -void load_residual_react(void *inst_, double *dst) -{ +static void load_residual_react(void *inst_, void *model, double *dst) { + IGNORE(model); DiodeInstace *inst = (DiodeInstace *)inst_; - LOAD_RHS_REACT(A) - LOAD_RHS_REACT(CI) + dst[inst->node_off[A]] += inst->residual_react_A; + dst[inst->node_off[CI]] += inst->residual_react_CI; } -#define LOAD_MATRIX_RESIST(name) \ +#define LOAD_MATRIX_RESIST(name) \ *inst->jacobian_ptr_resist[name] += inst->jacobian_resist[name]; // implementation of the load_matrix_resist function as defined in the OSDI spec -void load_jacobian_resist(void *inst_) -{ +static void load_jacobian_resist(void *inst_, void *model) { + IGNORE(model); DiodeInstace *inst = (DiodeInstace *)inst_; LOAD_MATRIX_RESIST(A_A) LOAD_MATRIX_RESIST(A_CI) @@ -534,12 +512,12 @@ void load_jacobian_resist(void *inst_) LOAD_MATRIX_RESIST(TNODE_CI) } -#define LOAD_MATRIX_REACT(name) \ +#define LOAD_MATRIX_REACT(name) \ *inst->jacobian_ptr_react[name] += inst->jacobian_react[name] * alpha; // implementation of the load_matrix_react function as defined in the OSDI spec -void load_jacobian_react(void *inst_, double alpha) -{ +static void load_jacobian_react(void *inst_, void *model, double alpha) { + IGNORE(model); DiodeInstace *inst = (DiodeInstace *)inst_; LOAD_MATRIX_REACT(A_A) LOAD_MATRIX_REACT(A_CI) @@ -550,16 +528,15 @@ void load_jacobian_react(void *inst_, double alpha) LOAD_MATRIX_REACT(CI_TNODE) } -#define LOAD_MATRIX_TRAN(name) \ +#define LOAD_MATRIX_TRAN(name) \ *inst->jacobian_ptr_resist[name] += inst->jacobian_react[name] * alpha; // implementation of the load_matrix_tran function as defined in the OSDI spec -void load_jacobian_tran(void *inst_, double alpha) -{ +static void load_jacobian_tran(void *inst_, void *model, double alpha) { DiodeInstace *inst = (DiodeInstace *)inst_; // set dc stamps - load_jacobian_resist(inst_); + load_jacobian_resist(inst_, model); // add reactive contributions LOAD_MATRIX_TRAN(A_A) @@ -572,41 +549,39 @@ void load_jacobian_tran(void *inst_, double alpha) } // implementation of the load_spice_rhs_dc function as defined in the OSDI spec -void load_spice_rhs_dc(void *inst_, double *dst, double *prev_solve) -{ +static void load_spice_rhs_dc(void *inst_, void *model, double *dst, + double *prev_solve) { + IGNORE(model); DiodeInstace *inst = (DiodeInstace *)inst_; double va = prev_solve[inst->node_off[A]]; double vci = prev_solve[inst->node_off[CI]]; double vc = prev_solve[inst->node_off[C]]; double vdtj = prev_solve[inst->node_off[TNODE]]; - dst[inst->node_off[A]] += inst->jacobian_resist[A_A] * va + - inst->jacobian_resist[A_TNODE] * vdtj + - inst->jacobian_resist[A_CI] * vci - - inst->rhs_resist[A]; + dst[inst->node_off[A]] += + inst->jacobian_resist[A_A] * va + inst->jacobian_resist[A_TNODE] * vdtj + + inst->jacobian_resist[A_CI] * vci - inst->residual_resist[A]; dst[inst->node_off[CI]] += inst->jacobian_resist[CI_A] * va + inst->jacobian_resist[CI_TNODE] * vdtj + inst->jacobian_resist[CI_CI] * vci - - inst->rhs_resist[CI]; + inst->residual_resist[CI]; - dst[inst->node_off[C]] += inst->jacobian_resist[C_C] * vc + - inst->jacobian_resist[C_CI] * vci + - inst->jacobian_resist[C_TNODE] * vdtj - - inst->rhs_resist[C]; + dst[inst->node_off[C]] += + inst->jacobian_resist[C_C] * vc + inst->jacobian_resist[C_CI] * vci + + inst->jacobian_resist[C_TNODE] * vdtj - inst->residual_resist[C]; dst[inst->node_off[TNODE]] += inst->jacobian_resist[TNODE_A] * va + inst->jacobian_resist[TNODE_C] * vc + inst->jacobian_resist[TNODE_CI] * vci + inst->jacobian_resist[TNODE_TNODE] * vdtj - - inst->rhs_resist[TNODE]; + inst->residual_resist[TNODE]; } // implementation of the load_spice_rhs_tran function as defined in the OSDI // spec -void load_spice_rhs_tran(void *inst_, double *dst, double *prev_solve, - double alpha) -{ +static void load_spice_rhs_tran(void *inst_, void *model, double *dst, + double *prev_solve, double alpha) { DiodeInstace *inst = (DiodeInstace *)inst_; double va = prev_solve[inst->node_off[A]]; @@ -614,46 +589,83 @@ void load_spice_rhs_tran(void *inst_, double *dst, double *prev_solve, double vdtj = prev_solve[inst->node_off[TNODE]]; // set DC rhs - load_spice_rhs_dc(inst_, dst, prev_solve); + load_spice_rhs_dc(inst_, model, dst, prev_solve); // add contributions due to reactive elements - dst[inst->node_off[A]] += - alpha * (inst->jacobian_react[A_A] * va + - inst->jacobian_react[A_CI] * vci + - inst->jacobian_react[A_TNODE] * vdtj); + dst[inst->node_off[A]] += alpha * (inst->jacobian_react[A_A] * va + + inst->jacobian_react[A_CI] * vci + + inst->jacobian_react[A_TNODE] * vdtj); dst[inst->node_off[CI]] += alpha * (inst->jacobian_react[CI_CI] * vci + inst->jacobian_react[CI_A] * va + inst->jacobian_react[CI_TNODE] * vdtj); } -// structure that provides information of all nodes of the model -OsdiNode nodes[NUM_NODES] = { - {.name = "A", .units = "V", .is_reactive = true}, - {.name = "C", .units = "V"}, - {.name = "dT", .units = "K"}, - {.name = "CI", .units = "V", .is_reactive = true}, -}; +#define RESIST_RESIDUAL_OFF(NODE) \ + (offsetof(DiodeInstace, residual_resist) + sizeof(uint32_t) * NODE) + +// structure that provides information of all nodes of the model +const OsdiNode nodes[NUM_NODES] = { + { + .name = "A", + .units = "V", + .residual_units = "A", + .resist_residual_off = RESIST_RESIDUAL_OFF(A), + .react_residual_off = offsetof(DiodeInstace, residual_react_A), + }, + { + .name = "C", + .units = "V", + .residual_units = "A", + .resist_residual_off = RESIST_RESIDUAL_OFF(C), + .react_residual_off = UINT32_MAX, // no reactive residual + + }, + { + .name = "dT", + .units = "K", + .residual_units = "W", + .resist_residual_off = RESIST_RESIDUAL_OFF(TNODE), + .react_residual_off = UINT32_MAX, // no reactive residual + }, + { + .name = "CI", + .units = "V", + .residual_units = "A", + .resist_residual_off = RESIST_RESIDUAL_OFF(TNODE), + .react_residual_off = offsetof(DiodeInstace, residual_react_CI), + + }, +}; +#define JACOBI_ENTRY(N1, N2) \ + { \ + .nodes = {N1, N2}, .flags = JACOBIAN_ENTRY_RESIST | JACOBIAN_ENTRY_REACT, \ + .react_ptr_off = \ + offsetof(DiodeInstace, jacobian_ptr_react) + sizeof(double*) * N1##_##N2 \ + } + +#define RESIST_JACOBI_ENTRY(N1, N2) \ + { \ + .nodes = {N1, N2}, .flags = JACOBIAN_ENTRY_RESIST, \ + .react_ptr_off = UINT32_MAX \ + } -// boolean array that tells which Jacobian entries are constant. Nothing is -// constant with selfheating, though. -bool const_jacobian_entries[NUM_MATRIX] = {}; // these node pairs specify which entries in the Jacobian must be accounted for -OsdiNodePair jacobian_entries[NUM_MATRIX] = { - {CI, CI}, - {CI, C}, - {C, CI}, - {C, C}, - {A, A}, - {A, CI}, - {CI, A}, - {A, TNODE}, - {C, TNODE}, - {CI, TNODE}, - {TNODE, TNODE}, - {TNODE, A}, - {TNODE, C}, - {TNODE, CI}, +OsdiJacobianEntry jacobian_entries[NUM_MATRIX] = { + JACOBI_ENTRY(CI, CI), + RESIST_JACOBI_ENTRY(CI, C), + RESIST_JACOBI_ENTRY(C, CI), + RESIST_JACOBI_ENTRY(C, C), + JACOBI_ENTRY(A, A), + JACOBI_ENTRY(A, CI), + JACOBI_ENTRY(CI, A), + JACOBI_ENTRY(A, TNODE), + RESIST_JACOBI_ENTRY(C, TNODE), + JACOBI_ENTRY(CI, TNODE), + RESIST_JACOBI_ENTRY(TNODE, TNODE), + RESIST_JACOBI_ENTRY(TNODE, A), + RESIST_JACOBI_ENTRY(TNODE, C), + RESIST_JACOBI_ENTRY(TNODE, CI), }; OsdiNodePair collapsible[NUM_COLLAPSIBLE] = { {CI, C}, @@ -776,27 +788,17 @@ OsdiDescriptor OSDI_DESCRIPTORS[1] = {{ .num_nodes = NUM_NODES, .num_terminals = 3, .nodes = (OsdiNode *)&nodes, + .node_mapping_offset = offsetof(DiodeInstace, node_off), // matrix entries .num_jacobian_entries = NUM_MATRIX, - .jacobian_entries = (OsdiNodePair *)&jacobian_entries, - .const_jacobian_entries = (bool *)&const_jacobian_entries, - - // memory - .instance_size = sizeof(DiodeInstace), - .model_size = sizeof(DiodeModel), - .residual_resist_offset = offsetof(DiodeInstace, rhs_resist), - .residual_react_offset = offsetof(DiodeInstace, rhs_react), - .node_mapping_offset = offsetof(DiodeInstace, node_off), - .jacobian_resist_offset = offsetof(DiodeInstace, jacobian_resist), - .jacobian_react_offset = offsetof(DiodeInstace, jacobian_react), + .jacobian_entries = (OsdiJacobianEntry *)&jacobian_entries, .jacobian_ptr_resist_offset = offsetof(DiodeInstace, jacobian_ptr_resist), - .jacobian_ptr_react_offset = offsetof(DiodeInstace, jacobian_ptr_react), // node collapsing .num_collapsible = NUM_COLLAPSIBLE, .collapsible = collapsible, - .is_collapsible_offset = offsetof(DiodeInstace, is_collapsible), + .collapsed_offset = offsetof(DiodeInstace, collapsed), // noise .noise_sources = NULL, @@ -808,6 +810,13 @@ OsdiDescriptor OSDI_DESCRIPTORS[1] = {{ .num_opvars = 0, .param_opvar = (OsdiParamOpvar *)¶ms, + // step size bound + .bound_step_offset = UINT32_MAX, + + // memory + .instance_size = sizeof(DiodeInstace), + .model_size = sizeof(DiodeModel), + // setup .access = &osdi_access, .setup_model = &setup_model,