1 #include <../../nrnconf.h>
44 {
"e_extracellular",
"mV"},
46 {
"i_membrane",
"mA/cm2"},
52 static void printnode(
const char*
s);
81 , field<double>{
"e_extracellular"}
83 , field<double>{
"i_membrane"}
84 , field<double>{
"sav_g"}
85 , field<double>{
"sav_rhs"}
134 for (
i = 0;
i <
cnt; ++
i) {
137 for (il = 0; il <
nlayer; ++il) {
138 nde->
v[il] += *nde->
_rhs[il];
140 nd->
v() -= *nde->
_rhs[0];
144 for (
i = 0;
i <
cnt; ++
i) {
199 hoc_execerror(
"Extracellular mechanism only works with fixed step methods and daspk", 0);
201 for (
int i = 0;
i < ndcount; ++
i) {
229 if (
sec->pnode[0]->extnode) {
255 if (
s->type == RANGEVAR) {
258 if (a && a->
nsub == 1) {
313 for (
p = nd->
prop;
p;
p =
p->next) {
315 for (
auto i = 0;
i <
p->param_num_vars(); ++
i) {
316 for (
auto array_index = 0; array_index <
p->param_array_dimension(
i);
318 nde->
param.push_back(
p->param_handle(
i, array_index));
330 for (
int i =
sec->nnode - 1;
i >= 0;
i--) {
334 if (!
sec->parentsec &&
sec->parentnode) {
353 for (
i = 0;
i <
cnt; ++
i) {
363 for (
i = 0;
i <
cnt; ++
i) {
372 double dv = pnde->
v[
j] - nde->
v[
j];
389 double dv = -nde->
v[0];
399 for (--
j;
j >= 0; --
j) {
402 *nde->
_rhs[
j + 1] += x;
407 for (
i = 0;
i <
cnt; ++
i) {
420 double d, cfac, mfac;
429 cfac = .001 * _nt->
cj;
434 for (
i = 0;
i <
cnt; ++
i) {
439 d = (*nde->
_d[0] +=
NODED(nd));
449 for (
i = 0;
i <
cnt; ++
i) {
464 *nde->
_x12[
j] -= mfac;
465 *nde->
_x21[
j] -= mfac;
471 *nde->
_d[
j] -= nde->
_b[
j];
472 *pnde->
_d[
j] -= nde->
_a[
j];
492 if (
sec->pnode[0]->extnode) {
494 for (
j = 0;
j <
sec->nnode - 1;
j++) {
495 nde =
sec->pnode[
j]->extnode;
502 nde =
sec->pnode[
j]->extnode;
509 if (!
sec->parentsec) {
510 nde =
sec->parentnode->extnode;
528 if (
sec->pnode[0]->extnode) {
533 nde =
sec->pnode[0]->extnode;
537 for (
j = 1;
j <
sec->nnode;
j++) {
538 nde =
sec->pnode[
j]->extnode;
540 nde->
_b[
k] = *nde->
_rhs[
k] + *(
sec->pnode[
j - 1]->extnode->_rhs[
k]);
546 if (
sec->pnode[0]->extnode) {
560 nde->
_a[
k] = -1.e2 *
sec->prop->dparam[4].get<
double>() / (nde->
_b[
k] *
area);
562 for (
j = 1;
j <
sec->nnode;
j++) {
573 if (
sec->pnode[0]->extnode) {
574 for (
j = 0;
j <
sec->nnode;
j++) {
588 static void printnode(
const char*
s) {
605 printf(
"xraxial=%g xg=%g xc=%g e=%g\n", xraxial[
k], xg[
k], xc[
k], e_extracellular);
611 static int cntndsave;
614 void save2mat(
void) {
615 int i,
j,
k, im, ipm;
619 if (cntndsave < v_node_count) {
623 cntndsave = v_node_count;
626 for (
i=0;
i < v_node_count; ++
i) {
631 ndesave[
i].
v[
j] = nde->
v[
j];
632 ndesave[
i].rhs[
j] = nde->
_rhs[
j];
634 ndesave[
i].m[
j][
k] = nde->_m[
j][
k];
637 ndesave[
i].m[
j][0] = 0.;
645 ndesave[
i].
v[0] = nd->
v;
648 ndesave[
i].m[0][0] =
NODEB(nd);
660 void check2mat(
void) {
667 for (
i=0;
i < v_node_count; ++
i) {
681 for (
i=0;
i < v_node_count; ++
i) {
694 for (
i=0;
i < v_node_count; ++
i) {
695 DBG(
"work on node %d\n",
i);
697 ip = v_parent[
i]->v_node_index;
699 DBG(
" effect of parent %d on node %d\n", ip,
i);
701 DBG(
" work on layer %d\n",
j);
703 DBG(
" nde[%d].rhs[%d] -= nde[%d].v[%d]*nde[%d].m[%d][%d]\n",
i,
j,ip,
k,
i,
j,
k-
j);
704 DBG(
" %g * %g\n",ndesave[ip].
v[
k],ndesave[
i].m[
j][
k-
j]);
705 ndesave[
i].rhs[
j] -= ndesave[ip].
v[
k]*ndesave[
i].m[
j][
k-
j];
709 DBG(
" effect of node %d on parent %d\n",
i, ip);
711 DBG(
" work on layer %d\n",
j);
712 for (
k=0;
k <=
j; ++
k) {
713 DBG(
" nde[%d].rhs[%d] -= nde[%d].v[%d]*nde[%d].m[%d][%d]\n", ip,
j,
i,
k,
i,
j,2*(
nlayer)-
j+
k);
714 DBG(
" %g * %g\n",ndesave[
i].
v[
k],ndesave[
i].m[
j][2*(
nlayer)-
j+
k]);
715 ndesave[ip].rhs[
j] -= ndesave[
i].
v[
k]*ndesave[
i].m[
j][2*(
nlayer)-
j+
k];
720 DBG(
" effect of node %d on node %d\n",
i,
i);
722 DBG(
" work on layer %d\n",
j);
724 DBG(
" nde[%d].rhs[%d] -= nde[%d].v[%d]*nde[%d].m[%d][%d]\n",
i,
j,
i,
k,
i,
j,(
nlayer)+
k-
j);
725 DBG(
" %g * %g\n",ndesave[
i].
v[
k],ndesave[
i].m[
j][(
nlayer)+
k-
j]);
731 for (
i=0;
i < v_node_count; ++
i) {
734 printf(
"bad soln of eq %d,%d rhs-M*V=%g\n",
const char * secname(Section *sec)
name of section (for use in error messages)
double section_length(Section *sec)
Symbol * hoc_table_lookup(const char *, Symlist *)
static int _ode_count(int type)
static HocParmUnits units[]
void nrn_update_2d(NrnThread *nt)
static void extcell_init(neuron::model_sorted_token const &, NrnThread *nt, Memb_list *ml, int type)
static HocParmLimits limits[]
constexpr static auto nparm
int nrn_nlayer_extracellular
void extracell_reg_(void)
void nlayer_extracellular()
static void update_parmsize()
static void extnode_alloc_elements(Extnode *nde)
static std::vector< double > param_default
static void extcell_alloc(Prop *)
static void check_if_extracellular_in_use()
void nrn_rhs_ext(NrnThread *_nt)
void extcell_2d_alloc(Section *sec)
static void update_extracellular_reg(int old_nlayer)
void extcell_node_create(Node *nd)
static const char * mechanism[]
static void update_existing_extnode(int old_nlayer)
void nrn_setup_ext(NrnThread *_nt)
void extnode_free_elements(Extnode *nde)
double chkarg(int, double low, double high)
void hoc_retpushx(double x)
constexpr auto range_sec(hoc_List *iterable)
auto for_threads(NrnThread *threads, int num_threads)
void hoc_execerror(const char *s1, const char *s2)
void * ecalloc(size_t n, size_t size)
int nrn_get_mechtype(const char *name)
Get mechanism type by the mechanism name.
void hoc_register_prop_size(int, int, int)
int register_mech(const char **m, mod_alloc_t alloc, mod_f_t cur, mod_f_t jacob, mod_f_t stat, mod_f_t initialize, mod_f_t private_constructor, mod_f_t private_destructor, int nrnpointerindex, int vectorized)
static void register_data_fields(int mech_type, Fields const &... fields)
Type- and array-aware version of hoc_register_prop_size.
void hoc_register_limits(int mechtype, HocParmLimits *limits)
void hoc_register_cvode(int i, nrn_ode_count_t cnt, nrn_ode_map_t map, nrn_ode_spec_t spec, nrn_ode_matsol_t matsol)
void hoc_register_parm_default(int mechtype, const std::vector< double > *pd)
void hoc_register_units(int mechtype, HocParmUnits *units)
Symlist * hoc_built_in_symlist
std::vector< neuron::container::data_handle< double > > param
A view into a set of mechanism instances.
std::vector< double * > data()
Get a vector of double* representing the model data.
Represent main neuron object computed by single thread.
Memb_list * _ecell_memb_list