diff --git a/func_in_breakpoint/coreneuron/func_in_breakpoint.cpp b/func_in_breakpoint/coreneuron/func_in_breakpoint.cpp new file mode 100644 index 0000000..49876b4 --- /dev/null +++ b/func_in_breakpoint/coreneuron/func_in_breakpoint.cpp @@ -0,0 +1,343 @@ +/********************************************************* +Model Name : func_in_breakpoint +Filename : func_in_breakpoint.mod +NMODL Version : 7.7.0 +Vectorized : true +Threadsafe : true +Created : DATE +Simulator : CoreNEURON +Backend : C++ (api-compatibility) +NMODL Compiler : VERSION +*********************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace coreneuron { + #ifndef NRN_PRCELLSTATE + #define NRN_PRCELLSTATE 0 + #endif + + + /** channel information */ + static const char *mechanism_info[] = { + "7.7.0", + "func_in_breakpoint", + 0, + "il_func_in_breakpoint", + 0, + 0, + 0 + }; + + + /** all global variables */ + struct func_in_breakpoint_Store { + int reset{}; + int mech_type{}; + double c{1}; + }; + static_assert(std::is_trivially_copy_constructible_v); + static_assert(std::is_trivially_move_constructible_v); + static_assert(std::is_trivially_copy_assignable_v); + static_assert(std::is_trivially_move_assignable_v); + static_assert(std::is_trivially_destructible_v); + func_in_breakpoint_Store func_in_breakpoint_global; + + + /** all mechanism instance variables and global variables */ + struct func_in_breakpoint_Instance { + double* il{}; + double* v_unused{}; + double* g_unused{}; + func_in_breakpoint_Store* global{&func_in_breakpoint_global}; + }; + + + /** connect global (scalar) variables to hoc -- */ + static DoubScal hoc_scalar_double[] = { + {"c_func_in_breakpoint", &func_in_breakpoint_global.c}, + {nullptr, nullptr} + }; + + + /** connect global (array) variables to hoc -- */ + static DoubVec hoc_vector_double[] = { + {nullptr, nullptr, 0} + }; + + + static inline int first_pointer_var_index() { + return -1; + } + + + static inline int first_random_var_index() { + return -1; + } + + + static inline int float_variables_size() { + return 3; + } + + + static inline int int_variables_size() { + return 0; + } + + + static inline int get_mech_type() { + return func_in_breakpoint_global.mech_type; + } + + + static inline Memb_list* get_memb_list(NrnThread* nt) { + if (!nt->_ml_list) { + return nullptr; + } + return nt->_ml_list[get_mech_type()]; + } + + + static inline void* mem_alloc(size_t num, size_t size, size_t alignment = 16) { + void* ptr; + posix_memalign(&ptr, alignment, num*size); + memset(ptr, 0, size); + return ptr; + } + + + static inline void mem_free(void* ptr) { + free(ptr); + } + + + static inline void coreneuron_abort() { + abort(); + } + + // Allocate instance structure + static void nrn_private_constructor_func_in_breakpoint(NrnThread* nt, Memb_list* ml, int type) { + assert(!ml->instance); + assert(!ml->global_variables); + assert(ml->global_variables_size == 0); + auto* const inst = new func_in_breakpoint_Instance{}; + assert(inst->global == &func_in_breakpoint_global); + ml->instance = inst; + ml->global_variables = inst->global; + ml->global_variables_size = sizeof(func_in_breakpoint_Store); + } + + // Deallocate the instance structure + static void nrn_private_destructor_func_in_breakpoint(NrnThread* nt, Memb_list* ml, int type) { + auto* const inst = static_cast(ml->instance); + assert(inst); + assert(inst->global); + assert(inst->global == &func_in_breakpoint_global); + assert(inst->global == ml->global_variables); + assert(ml->global_variables_size == sizeof(func_in_breakpoint_Store)); + delete inst; + ml->instance = nullptr; + ml->global_variables = nullptr; + ml->global_variables_size = 0; + } + + /** initialize mechanism instance variables */ + static inline void setup_instance(NrnThread* nt, Memb_list* ml) { + auto* const inst = static_cast(ml->instance); + assert(inst); + assert(inst->global); + assert(inst->global == &func_in_breakpoint_global); + assert(inst->global == ml->global_variables); + assert(ml->global_variables_size == sizeof(func_in_breakpoint_Store)); + int pnodecount = ml->_nodecount_padded; + Datum* indexes = ml->pdata; + inst->il = ml->data+0*pnodecount; + inst->v_unused = ml->data+1*pnodecount; + inst->g_unused = ml->data+2*pnodecount; + } + + + + static void nrn_alloc_func_in_breakpoint(double* data, Datum* indexes, int type) { + // do nothing + } + + + void nrn_constructor_func_in_breakpoint(NrnThread* nt, Memb_list* ml, int type) { + #ifndef CORENEURON_BUILD + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #endif + } + + + void nrn_destructor_func_in_breakpoint(NrnThread* nt, Memb_list* ml, int type) { + #ifndef CORENEURON_BUILD + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #endif + } + + + inline int func_func_in_breakpoint(int id, int pnodecount, func_in_breakpoint_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v); + inline int func_with_v_func_in_breakpoint(int id, int pnodecount, func_in_breakpoint_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v, double arg_v); + inline int func_with_other_func_in_breakpoint(int id, int pnodecount, func_in_breakpoint_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v, double q); + + + inline int func_func_in_breakpoint(int id, int pnodecount, func_in_breakpoint_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v) { + int ret_func = 0; + return ret_func; + } + + + inline int func_with_v_func_in_breakpoint(int id, int pnodecount, func_in_breakpoint_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v, double arg_v) { + int ret_func_with_v = 0; + return ret_func_with_v; + } + + + inline int func_with_other_func_in_breakpoint(int id, int pnodecount, func_in_breakpoint_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v, double q) { + int ret_func_with_other = 0; + return ret_func_with_other; + } + + + /** initialize channel */ + void nrn_init_func_in_breakpoint(NrnThread* nt, Memb_list* ml, int type) { + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + + setup_instance(nt, ml); + auto* const inst = static_cast(ml->instance); + + if (_nrn_skip_initmodel == 0) { + #pragma omp simd + #pragma ivdep + for (int id = 0; id < nodecount; id++) { + int node_id = node_index[id]; + double v = voltage[node_id]; + #if NRN_PRCELLSTATE + inst->v_unused[id] = v; + #endif + } + } + } + + + inline double nrn_current_func_in_breakpoint(int id, int pnodecount, func_in_breakpoint_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v) { + double current = 0.0; + func_func_in_breakpoint(id, pnodecount, inst, data, indexes, thread, nt, v); + func_with_v_func_in_breakpoint(id, pnodecount, inst, data, indexes, thread, nt, v, v); + func_with_other_func_in_breakpoint(id, pnodecount, inst, data, indexes, thread, nt, v, inst->global->c); + current += inst->il[id]; + return current; + } + + + /** update current */ + void nrn_cur_func_in_breakpoint(NrnThread* nt, Memb_list* ml, int type) { + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + double* vec_rhs = nt->_actual_rhs; + double* vec_d = nt->_actual_d; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #pragma omp simd + #pragma ivdep + for (int id = 0; id < nodecount; id++) { + int node_id = node_index[id]; + double v = voltage[node_id]; + #if NRN_PRCELLSTATE + inst->v_unused[id] = v; + #endif + double g = nrn_current_func_in_breakpoint(id, pnodecount, inst, data, indexes, thread, nt, v+0.001); + double rhs = nrn_current_func_in_breakpoint(id, pnodecount, inst, data, indexes, thread, nt, v); + g = (g-rhs)/0.001; + #if NRN_PRCELLSTATE + inst->g_unused[id] = g; + #endif + vec_rhs[node_id] -= rhs; + vec_d[node_id] += g; + } + } + + + /** update state */ + void nrn_state_func_in_breakpoint(NrnThread* nt, Memb_list* ml, int type) { + int nodecount = ml->nodecount; + int pnodecount = ml->_nodecount_padded; + const int* node_index = ml->nodeindices; + double* data = ml->data; + const double* voltage = nt->_actual_v; + Datum* indexes = ml->pdata; + ThreadDatum* thread = ml->_thread; + auto* const inst = static_cast(ml->instance); + + #pragma omp simd + #pragma ivdep + for (int id = 0; id < nodecount; id++) { + int node_id = node_index[id]; + double v = voltage[node_id]; + #if NRN_PRCELLSTATE + inst->v_unused[id] = v; + #endif + } + } + + + /** register channel with the simulator */ + void _func_in_breakpoint_reg() { + + int mech_type = nrn_get_mechtype("func_in_breakpoint"); + func_in_breakpoint_global.mech_type = mech_type; + if (mech_type == -1) { + return; + } + + _nrn_layout_reg(mech_type, 0); + register_mech(mechanism_info, nrn_alloc_func_in_breakpoint, nrn_cur_func_in_breakpoint, nullptr, nrn_state_func_in_breakpoint, nrn_init_func_in_breakpoint, nrn_private_constructor_func_in_breakpoint, nrn_private_destructor_func_in_breakpoint, first_pointer_var_index(), 1); + + hoc_register_prop_size(mech_type, float_variables_size(), int_variables_size()); + hoc_register_var(hoc_scalar_double, hoc_vector_double, NULL); + } +} diff --git a/func_in_breakpoint/neuron/func_in_breakpoint.cpp b/func_in_breakpoint/neuron/func_in_breakpoint.cpp new file mode 100644 index 0000000..b1395cd --- /dev/null +++ b/func_in_breakpoint/neuron/func_in_breakpoint.cpp @@ -0,0 +1,411 @@ +/********************************************************* +Model Name : func_in_breakpoint +Filename : func_in_breakpoint.mod +NMODL Version : 7.7.0 +Vectorized : true +Threadsafe : true +Created : DATE +Simulator : NEURON +Backend : C++ (api-compatibility) +NMODL Compiler : VERSION +*********************************************************/ + +#include +#include +#include + +#include "mech_api.h" +#include "neuron/cache/mechanism_range.hpp" +#include "nrniv_mf.h" +#include "section_fwd.hpp" + +/* NEURON global macro definitions */ +/* VECTORIZED */ +#define NRN_VECTORIZED 1 + +static constexpr auto number_of_datum_variables = 0; +static constexpr auto number_of_floating_point_variables = 3; + +namespace { +template +using _nrn_mechanism_std_vector = std::vector; +using _nrn_model_sorted_token = neuron::model_sorted_token; +using _nrn_mechanism_cache_range = neuron::cache::MechanismRange; +using _nrn_mechanism_cache_instance = neuron::cache::MechanismInstance; +using _nrn_non_owning_id_without_container = neuron::container::non_owning_identifier_without_container; +template +using _nrn_mechanism_field = neuron::mechanism::field; +template +void _nrn_mechanism_register_data_fields(Args&&... args) { + neuron::mechanism::register_data_fields(std::forward(args)...); +} +} // namespace + +Prop* hoc_getdata_range(int type); + + +namespace neuron { + #ifndef NRN_PRCELLSTATE + #define NRN_PRCELLSTATE 0 + #endif + + + /** channel information */ + static const char *mechanism_info[] = { + "7.7.0", + "func_in_breakpoint", + 0, + "il_func_in_breakpoint", + 0, + 0, + 0 + }; + + + /* NEURON global variables */ + static int mech_type; + static Prop* _extcall_prop; + /* _prop_id kind of shadows _extcall_prop to allow validity checking. */ + static _nrn_non_owning_id_without_container _prop_id{}; + static int hoc_nrnpointerindex = -1; + static _nrn_mechanism_std_vector _extcall_thread; + + + /** all global variables */ + struct func_in_breakpoint_Store { + double c{1}; + }; + static_assert(std::is_trivially_copy_constructible_v); + static_assert(std::is_trivially_move_constructible_v); + static_assert(std::is_trivially_copy_assignable_v); + static_assert(std::is_trivially_move_assignable_v); + static_assert(std::is_trivially_destructible_v); + func_in_breakpoint_Store func_in_breakpoint_global; + + + /** all mechanism instance variables and global variables */ + struct func_in_breakpoint_Instance { + double* il{}; + double* v_unused{}; + double* g_unused{}; + func_in_breakpoint_Store* global{&func_in_breakpoint_global}; + }; + + + struct func_in_breakpoint_NodeData { + int const * nodeindices; + double const * node_voltages; + double * node_diagonal; + double * node_rhs; + int nodecount; + }; + + + static func_in_breakpoint_Instance make_instance_func_in_breakpoint(_nrn_mechanism_cache_range& _ml) { + return func_in_breakpoint_Instance { + _ml.template fpfield_ptr<0>(), + _ml.template fpfield_ptr<1>(), + _ml.template fpfield_ptr<2>() + }; + } + + + static func_in_breakpoint_NodeData make_node_data_func_in_breakpoint(NrnThread& _nt, Memb_list& _ml_arg) { + return func_in_breakpoint_NodeData { + _ml_arg.nodeindices, + _nt.node_voltage_storage(), + _nt.node_d_storage(), + _nt.node_rhs_storage(), + _ml_arg.nodecount + }; + } + + + static void nrn_alloc_func_in_breakpoint(Prop* _prop) { + Prop *prop_ion{}; + Datum *_ppvar{}; + _nrn_mechanism_cache_instance _ml_real{_prop}; + auto* const _ml = &_ml_real; + size_t const _iml{}; + assert(_nrn_mechanism_get_num_vars(_prop) == 3); + /*initialize range parameters*/ + } + + + /* Neuron setdata functions */ + extern void _nrn_setdata_reg(int, void(*)(Prop*)); + static void _setdata(Prop* _prop) { + _extcall_prop = _prop; + _prop_id = _nrn_get_prop_id(_prop); + } + static void _hoc_setdata() { + Prop *_prop = hoc_getdata_range(mech_type); + _setdata(_prop); + hoc_retpushx(1.); + } + /* Mechanism procedures and functions */ + inline int func_func_in_breakpoint(_nrn_mechanism_cache_range* _ml, func_in_breakpoint_Instance& inst, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt); + inline int func_with_v_func_in_breakpoint(_nrn_mechanism_cache_range* _ml, func_in_breakpoint_Instance& inst, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt, double v); + inline int func_with_other_func_in_breakpoint(_nrn_mechanism_cache_range* _ml, func_in_breakpoint_Instance& inst, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt, double q); + + + /** connect global (scalar) variables to hoc -- */ + static DoubScal hoc_scalar_double[] = { + {"c_func_in_breakpoint", &func_in_breakpoint_global.c}, + {nullptr, nullptr} + }; + + + /** connect global (array) variables to hoc -- */ + static DoubVec hoc_vector_double[] = { + {nullptr, nullptr, 0} + }; + + + /* declaration of user functions */ + static void _hoc_func(void); + static void _hoc_func_with_v(void); + static void _hoc_func_with_other(void); + static double _npy_func(Prop*); + static double _npy_func_with_v(Prop*); + static double _npy_func_with_other(Prop*); + + + /* connect user functions to hoc names */ + static VoidFunc hoc_intfunc[] = { + {"setdata_func_in_breakpoint", _hoc_setdata}, + {"func_func_in_breakpoint", _hoc_func}, + {"func_with_v_func_in_breakpoint", _hoc_func_with_v}, + {"func_with_other_func_in_breakpoint", _hoc_func_with_other}, + {0, 0} + }; + static NPyDirectMechFunc npy_direct_func_proc[] = { + {"func", _npy_func}, + {"func_with_v", _npy_func_with_v}, + {"func_with_other", _npy_func_with_other}, + }; + static void _hoc_func(void) { + double _r{}; + Datum* _ppvar; + Datum* _thread; + NrnThread* _nt; + Prop* _local_prop = _prop_id ? _extcall_prop : nullptr; + _nrn_mechanism_cache_instance _ml_real{_local_prop}; + auto* const _ml = &_ml_real; + size_t const id{}; + _ppvar = _local_prop ? _nrn_mechanism_access_dparam(_local_prop) : nullptr; + _thread = _extcall_thread.data(); + _nt = nrn_threads; + auto inst = make_instance_func_in_breakpoint(_ml_real); + _r = 1.; + func_func_in_breakpoint(_ml, inst, id, _ppvar, _thread, _nt); + hoc_retpushx(_r); + } + static double _npy_func(Prop* _prop) { + double _r{}; + Datum* _ppvar; + Datum* _thread; + NrnThread* _nt; + _nrn_mechanism_cache_instance _ml_real{_prop}; + auto* const _ml = &_ml_real; + size_t const id{}; + _ppvar = _nrn_mechanism_access_dparam(_prop); + _thread = _extcall_thread.data(); + _nt = nrn_threads; + auto inst = make_instance_func_in_breakpoint(_ml_real); + _r = 1.; + func_func_in_breakpoint(_ml, inst, id, _ppvar, _thread, _nt); + return(_r); + } + static void _hoc_func_with_v(void) { + double _r{}; + Datum* _ppvar; + Datum* _thread; + NrnThread* _nt; + Prop* _local_prop = _prop_id ? _extcall_prop : nullptr; + _nrn_mechanism_cache_instance _ml_real{_local_prop}; + auto* const _ml = &_ml_real; + size_t const id{}; + _ppvar = _local_prop ? _nrn_mechanism_access_dparam(_local_prop) : nullptr; + _thread = _extcall_thread.data(); + _nt = nrn_threads; + auto inst = make_instance_func_in_breakpoint(_ml_real); + _r = 1.; + func_with_v_func_in_breakpoint(_ml, inst, id, _ppvar, _thread, _nt, *getarg(1)); + hoc_retpushx(_r); + } + static double _npy_func_with_v(Prop* _prop) { + double _r{}; + Datum* _ppvar; + Datum* _thread; + NrnThread* _nt; + _nrn_mechanism_cache_instance _ml_real{_prop}; + auto* const _ml = &_ml_real; + size_t const id{}; + _ppvar = _nrn_mechanism_access_dparam(_prop); + _thread = _extcall_thread.data(); + _nt = nrn_threads; + auto inst = make_instance_func_in_breakpoint(_ml_real); + _r = 1.; + func_with_v_func_in_breakpoint(_ml, inst, id, _ppvar, _thread, _nt, *getarg(1)); + return(_r); + } + static void _hoc_func_with_other(void) { + double _r{}; + Datum* _ppvar; + Datum* _thread; + NrnThread* _nt; + Prop* _local_prop = _prop_id ? _extcall_prop : nullptr; + _nrn_mechanism_cache_instance _ml_real{_local_prop}; + auto* const _ml = &_ml_real; + size_t const id{}; + _ppvar = _local_prop ? _nrn_mechanism_access_dparam(_local_prop) : nullptr; + _thread = _extcall_thread.data(); + _nt = nrn_threads; + auto inst = make_instance_func_in_breakpoint(_ml_real); + _r = 1.; + func_with_other_func_in_breakpoint(_ml, inst, id, _ppvar, _thread, _nt, *getarg(1)); + hoc_retpushx(_r); + } + static double _npy_func_with_other(Prop* _prop) { + double _r{}; + Datum* _ppvar; + Datum* _thread; + NrnThread* _nt; + _nrn_mechanism_cache_instance _ml_real{_prop}; + auto* const _ml = &_ml_real; + size_t const id{}; + _ppvar = _nrn_mechanism_access_dparam(_prop); + _thread = _extcall_thread.data(); + _nt = nrn_threads; + auto inst = make_instance_func_in_breakpoint(_ml_real); + _r = 1.; + func_with_other_func_in_breakpoint(_ml, inst, id, _ppvar, _thread, _nt, *getarg(1)); + return(_r); + } + + + inline int func_func_in_breakpoint(_nrn_mechanism_cache_range* _ml, func_in_breakpoint_Instance& inst, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt) { + int ret_func = 0; + auto v = inst.v_unused[id]; + return ret_func; + } + + + inline int func_with_v_func_in_breakpoint(_nrn_mechanism_cache_range* _ml, func_in_breakpoint_Instance& inst, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt, double v) { + int ret_func_with_v = 0; + return ret_func_with_v; + } + + + inline int func_with_other_func_in_breakpoint(_nrn_mechanism_cache_range* _ml, func_in_breakpoint_Instance& inst, size_t id, Datum* _ppvar, Datum* _thread, NrnThread* _nt, double q) { + int ret_func_with_other = 0; + auto v = inst.v_unused[id]; + return ret_func_with_other; + } + + + void nrn_init_func_in_breakpoint(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) { + _nrn_mechanism_cache_range _lmr{_sorted_token, *_nt, *_ml_arg, _type}; + auto inst = make_instance_func_in_breakpoint(_lmr); + auto node_data = make_node_data_func_in_breakpoint(*_nt, *_ml_arg); + auto nodecount = _ml_arg->nodecount; + auto* const _ml = &_lmr; + auto* _thread = _ml_arg->_thread; + for (int id = 0; id < nodecount; id++) { + + int node_id = node_data.nodeindices[id]; + auto* _ppvar = _ml_arg->pdata[id]; + auto v = node_data.node_voltages[node_id]; + inst.v_unused[id] = v; + } + } + + + inline double nrn_current_func_in_breakpoint(_nrn_mechanism_cache_range* _ml, NrnThread* _nt, Datum* _ppvar, Datum* _thread, size_t id, func_in_breakpoint_Instance& inst, func_in_breakpoint_NodeData& node_data, double v) { + double current = 0.0; + func_func_in_breakpoint(_ml, inst, id, _ppvar, _thread, _nt); + func_with_v_func_in_breakpoint(_ml, inst, id, _ppvar, _thread, _nt, v); + func_with_other_func_in_breakpoint(_ml, inst, id, _ppvar, _thread, _nt, inst.global->c); + current += inst.il[id]; + return current; + } + + + /** update current */ + void nrn_cur_func_in_breakpoint(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) { + _nrn_mechanism_cache_range _lmr{_sorted_token, *_nt, *_ml_arg, _type}; + auto inst = make_instance_func_in_breakpoint(_lmr); + auto node_data = make_node_data_func_in_breakpoint(*_nt, *_ml_arg); + auto nodecount = _ml_arg->nodecount; + auto* const _ml = &_lmr; + auto* _thread = _ml_arg->_thread; + for (int id = 0; id < nodecount; id++) { + int node_id = node_data.nodeindices[id]; + double v = node_data.node_voltages[node_id]; + auto* _ppvar = _ml_arg->pdata[id]; + double I1 = nrn_current_func_in_breakpoint(_ml, _nt, _ppvar, _thread, id, inst, node_data, v+0.001); + double I0 = nrn_current_func_in_breakpoint(_ml, _nt, _ppvar, _thread, id, inst, node_data, v); + double rhs = I0; + double g = (I1-I0)/0.001; + node_data.node_rhs[node_id] -= rhs; + // remember the conductances so we can set them later + inst.g_unused[id] = g; + } + } + + + void nrn_state_func_in_breakpoint(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) { + _nrn_mechanism_cache_range _lmr{_sorted_token, *_nt, *_ml_arg, _type}; + auto inst = make_instance_func_in_breakpoint(_lmr); + auto node_data = make_node_data_func_in_breakpoint(*_nt, *_ml_arg); + auto nodecount = _ml_arg->nodecount; + auto* const _ml = &_lmr; + auto* _thread = _ml_arg->_thread; + for (int id = 0; id < nodecount; id++) { + + int node_id = node_data.nodeindices[id]; + auto* _ppvar = _ml_arg->pdata[id]; + auto v = node_data.node_voltages[node_id]; + } + } + + + /** nrn_jacob function */ + static void nrn_jacob_func_in_breakpoint(_nrn_model_sorted_token const& _sorted_token, NrnThread* _nt, Memb_list* _ml_arg, int _type) { + _nrn_mechanism_cache_range _lmr{_sorted_token, *_nt, *_ml_arg, _type}; + auto inst = make_instance_func_in_breakpoint(_lmr); + auto node_data = make_node_data_func_in_breakpoint(*_nt, *_ml_arg); + auto nodecount = _ml_arg->nodecount; + for (int id = 0; id < nodecount; id++) { + // set conductances properly + int node_id = node_data.nodeindices[id]; + node_data.node_diagonal[node_id] += inst.g_unused[id]; + } + } + + + static void _initlists() { + } + + + /** register channel with the simulator */ + extern "C" void _func_in_breakpoint_reg() { + _initlists(); + + + + register_mech(mechanism_info, nrn_alloc_func_in_breakpoint, nrn_cur_func_in_breakpoint, nrn_jacob_func_in_breakpoint, nrn_state_func_in_breakpoint, nrn_init_func_in_breakpoint, hoc_nrnpointerindex, 1); + + mech_type = nrn_get_mechtype(mechanism_info[1]); + _nrn_mechanism_register_data_fields(mech_type, + _nrn_mechanism_field{"il"} /* 0 */, + _nrn_mechanism_field{"v_unused"} /* 1 */, + _nrn_mechanism_field{"g_unused"} /* 2 */ + ); + + hoc_register_prop_size(mech_type, 3, 0); + hoc_register_var(hoc_scalar_double, hoc_vector_double, hoc_intfunc); + hoc_register_npy_direct(mech_type, npy_direct_func_proc); + } +} diff --git a/hodgkin_huxley/neuron/hodhux.cpp b/hodgkin_huxley/neuron/hodhux.cpp index 05b2831..e317f10 100644 --- a/hodgkin_huxley/neuron/hodhux.cpp +++ b/hodgkin_huxley/neuron/hodhux.cpp @@ -447,7 +447,7 @@ namespace neuron { } - inline double nrn_current_hodhux(size_t id, hodhux_Instance& inst, hodhux_NodeData& node_data, double v) { + inline double nrn_current_hodhux(_nrn_mechanism_cache_range* _ml, NrnThread* _nt, Datum* _ppvar, Datum* _thread, size_t id, hodhux_Instance& inst, hodhux_NodeData& node_data, double v) { double current = 0.0; inst.ina[id] = inst.gnabar[id] * inst.m[id] * inst.m[id] * inst.m[id] * inst.h[id] * (v - inst.ena[id]); inst.ik[id] = inst.gkbar[id] * inst.n[id] * inst.n[id] * inst.n[id] * inst.n[id] * (v - inst.ek[id]); @@ -470,12 +470,13 @@ namespace neuron { for (int id = 0; id < nodecount; id++) { int node_id = node_data.nodeindices[id]; double v = node_data.node_voltages[node_id]; + auto* _ppvar = _ml_arg->pdata[id]; inst.ena[id] = (*inst.ion_ena[id]); inst.ek[id] = (*inst.ion_ek[id]); - double I1 = nrn_current_hodhux(id, inst, node_data, v+0.001); + double I1 = nrn_current_hodhux(_ml, _nt, _ppvar, _thread, id, inst, node_data, v+0.001); double dina = inst.ina[id]; double dik = inst.ik[id]; - double I0 = nrn_current_hodhux(id, inst, node_data, v); + double I0 = nrn_current_hodhux(_ml, _nt, _ppvar, _thread, id, inst, node_data, v); double rhs = I0; double g = (I1-I0)/0.001; (*inst.ion_dinadv[id]) += (dina-inst.ina[id])/0.001; diff --git a/net_receive/neuron/snapsyn.cpp b/net_receive/neuron/snapsyn.cpp index f355835..c3a1e6c 100644 --- a/net_receive/neuron/snapsyn.cpp +++ b/net_receive/neuron/snapsyn.cpp @@ -220,7 +220,7 @@ namespace neuron { } - inline double nrn_current_SnapSyn(size_t id, SnapSyn_Instance& inst, SnapSyn_NodeData& node_data, double v) { + inline double nrn_current_SnapSyn(_nrn_mechanism_cache_range* _ml, NrnThread* _nt, Datum* _ppvar, Datum* _thread, size_t id, SnapSyn_Instance& inst, SnapSyn_NodeData& node_data, double v) { double current = 0.0; inst.i[id] = inst.g[id] * (v - inst.e[id]); current += inst.i[id]; @@ -239,8 +239,9 @@ namespace neuron { for (int id = 0; id < nodecount; id++) { int node_id = node_data.nodeindices[id]; double v = node_data.node_voltages[node_id]; - double I1 = nrn_current_SnapSyn(id, inst, node_data, v+0.001); - double I0 = nrn_current_SnapSyn(id, inst, node_data, v); + auto* _ppvar = _ml_arg->pdata[id]; + double I1 = nrn_current_SnapSyn(_ml, _nt, _ppvar, _thread, id, inst, node_data, v+0.001); + double I0 = nrn_current_SnapSyn(_ml, _nt, _ppvar, _thread, id, inst, node_data, v); double rhs = I0; double g = (I1-I0)/0.001; double mfactor = 1.e2/(*inst.node_area[id]); diff --git a/nonspecific_current/neuron/leonhard.cpp b/nonspecific_current/neuron/leonhard.cpp index df3cc28..b4fbbc7 100644 --- a/nonspecific_current/neuron/leonhard.cpp +++ b/nonspecific_current/neuron/leonhard.cpp @@ -190,7 +190,7 @@ namespace neuron { } - inline double nrn_current_leonhard(size_t id, leonhard_Instance& inst, leonhard_NodeData& node_data, double v) { + inline double nrn_current_leonhard(_nrn_mechanism_cache_range* _ml, NrnThread* _nt, Datum* _ppvar, Datum* _thread, size_t id, leonhard_Instance& inst, leonhard_NodeData& node_data, double v) { double current = 0.0; inst.il[id] = inst.c[id] * (v - 1.5); current += inst.il[id]; @@ -209,8 +209,9 @@ namespace neuron { for (int id = 0; id < nodecount; id++) { int node_id = node_data.nodeindices[id]; double v = node_data.node_voltages[node_id]; - double I1 = nrn_current_leonhard(id, inst, node_data, v+0.001); - double I0 = nrn_current_leonhard(id, inst, node_data, v); + auto* _ppvar = _ml_arg->pdata[id]; + double I1 = nrn_current_leonhard(_ml, _nt, _ppvar, _thread, id, inst, node_data, v+0.001); + double I0 = nrn_current_leonhard(_ml, _nt, _ppvar, _thread, id, inst, node_data, v); double rhs = I0; double g = (I1-I0)/0.001; node_data.node_rhs[node_id] -= rhs; diff --git a/spike_travel/neuron/expsyn2.cpp b/spike_travel/neuron/expsyn2.cpp index 74b73c8..8e038ea 100644 --- a/spike_travel/neuron/expsyn2.cpp +++ b/spike_travel/neuron/expsyn2.cpp @@ -229,7 +229,7 @@ namespace neuron { } - inline double nrn_current_ExpSyn2(size_t id, ExpSyn2_Instance& inst, ExpSyn2_NodeData& node_data, double v) { + inline double nrn_current_ExpSyn2(_nrn_mechanism_cache_range* _ml, NrnThread* _nt, Datum* _ppvar, Datum* _thread, size_t id, ExpSyn2_Instance& inst, ExpSyn2_NodeData& node_data, double v) { double current = 0.0; inst.i[id] = inst.g[id] * (v - inst.e[id]); current += inst.i[id]; @@ -248,8 +248,9 @@ namespace neuron { for (int id = 0; id < nodecount; id++) { int node_id = node_data.nodeindices[id]; double v = node_data.node_voltages[node_id]; - double I1 = nrn_current_ExpSyn2(id, inst, node_data, v+0.001); - double I0 = nrn_current_ExpSyn2(id, inst, node_data, v); + auto* _ppvar = _ml_arg->pdata[id]; + double I1 = nrn_current_ExpSyn2(_ml, _nt, _ppvar, _thread, id, inst, node_data, v+0.001); + double I0 = nrn_current_ExpSyn2(_ml, _nt, _ppvar, _thread, id, inst, node_data, v); double rhs = I0; double g = (I1-I0)/0.001; double mfactor = 1.e2/(*inst.node_area[id]); diff --git a/spike_travel/neuron/hodhux.cpp b/spike_travel/neuron/hodhux.cpp index 05b2831..e317f10 100644 --- a/spike_travel/neuron/hodhux.cpp +++ b/spike_travel/neuron/hodhux.cpp @@ -447,7 +447,7 @@ namespace neuron { } - inline double nrn_current_hodhux(size_t id, hodhux_Instance& inst, hodhux_NodeData& node_data, double v) { + inline double nrn_current_hodhux(_nrn_mechanism_cache_range* _ml, NrnThread* _nt, Datum* _ppvar, Datum* _thread, size_t id, hodhux_Instance& inst, hodhux_NodeData& node_data, double v) { double current = 0.0; inst.ina[id] = inst.gnabar[id] * inst.m[id] * inst.m[id] * inst.m[id] * inst.h[id] * (v - inst.ena[id]); inst.ik[id] = inst.gkbar[id] * inst.n[id] * inst.n[id] * inst.n[id] * inst.n[id] * (v - inst.ek[id]); @@ -470,12 +470,13 @@ namespace neuron { for (int id = 0; id < nodecount; id++) { int node_id = node_data.nodeindices[id]; double v = node_data.node_voltages[node_id]; + auto* _ppvar = _ml_arg->pdata[id]; inst.ena[id] = (*inst.ion_ena[id]); inst.ek[id] = (*inst.ion_ek[id]); - double I1 = nrn_current_hodhux(id, inst, node_data, v+0.001); + double I1 = nrn_current_hodhux(_ml, _nt, _ppvar, _thread, id, inst, node_data, v+0.001); double dina = inst.ina[id]; double dik = inst.ik[id]; - double I0 = nrn_current_hodhux(id, inst, node_data, v); + double I0 = nrn_current_hodhux(_ml, _nt, _ppvar, _thread, id, inst, node_data, v); double rhs = I0; double g = (I1-I0)/0.001; (*inst.ion_dinadv[id]) += (dina-inst.ina[id])/0.001;