1 #include <../../nrnconf.h> 26 "xraxial[N]",
"xg[N]",
"xc[N]",
"e_extracellular", 0,
34 "xraxial", 1
e-9, 1e15,
44 "e_extracellular",
"mV",
46 "i_membrane",
"mA/cm2",
53 static void printnode(
const char*
s);
82 #define xg (pd + (nlayer)) 83 #define xc (pd + 2*(nlayer)) 84 #define e_extracellular pd[3*(nlayer)] 86 #define i_membrane pd[1 + 3*(nlayer)] 87 #define sav_g pd[2 + 3*(nlayer)] 88 #define sav_rhs pd[3 + 3*(nlayer)] 106 cfac = .001 * nt->
cj;
110 for (i=0; i <
cnt; ++
i) {
113 for (il = 0; il <
nlayer; ++il) {
114 nde->
v[il] += *nde->
_rhs[il];
120 for (i=0; i <
cnt; ++
i) {
198 hoc_execerror(
"Extracellular mechanism only works with fixed step methods and daspk", 0);
200 for (i=0; i < ndcount; ++
i) {
255 for (i=0; i < ecell->
s_varn; ++
i) {
257 if (s->
type == RANGEVAR) {
260 if (a && a->
nsub == 1) {
315 nde->
param = (
double *)0;
316 for (p = nd->
prop; p; p = p->
next) {
317 if (p->
type == EXTRACELL) {
334 for (i=0; i <
cnt; ++
i) {
350 for (i = sec->
nnode-1; i>=0; i--) {
373 for (i=0; i <
cnt; ++
i) {
384 for (i=0; i <
cnt; ++
i) {
394 double dv = pnde->
v[
j] - nde->
v[
j];
411 double dv = - nde->
v[0];
420 for (--j; j >= 0; --
j) {
421 double x =
xg[
j]*(nde->
v[
j] - nde->
v[j+1]);
423 *nde->
_rhs[j+1] += x;
428 for (i = 0; i <
cnt; ++
i) {
443 double d, cfac, mfac;
450 cfac = .001 * _nt->
cj;
455 for (i=0; i <
cnt; ++
i) {
460 d = (*nde->
_d[0] +=
NODED(nd));
471 for (i=0; i <
cnt; ++
i) {
480 mfac = (
xg[
j] +
xc[
j]*cfac);
487 *nde->
_x12[
j] -= mfac;
488 *nde->
_x21[
j] -= mfac;
494 *nde->
_d[
j] -= nde->
_b[
j];
495 *pnde->
_d[
j] -= nde->
_a[
j];;
518 if (
sec->pnode[0]->extnode){
520 for (j = 0; j <
sec->nnode-1; j++) {
521 nde =
sec->pnode[
j]->extnode;
528 nde =
sec->pnode[
j]->extnode;
536 if (!
sec->parentsec) {
537 nde =
sec->parentnode->extnode;
556 if(
sec->pnode[0]->extnode){
561 nde =
sec->pnode[0]->extnode;
563 nde->_b[
k] = *nde->_rhs[
k];
565 for (
j = 1;
j <
sec->nnode;
j++) {
566 nde =
sec->pnode[
j]->extnode;
568 nde->_b[
k] = *nde->_rhs[
k] + *(
sec->pnode[
j-1]->extnode->_rhs[
k]);
573 if(
sec->pnode[0]->extnode){
587 nde->_a[
k] = -1.e2*
sec->prop->dparam[4].val/(nde->_b[
k] *
area);
589 for (
j = 1;
j <
sec->nnode;
j++) {
593 nde->_a[
k] = -1.e2/(nde->_b[
k] *
area);
599 if(
sec->pnode[0]->extnode){
600 for (
j=0;
j <
sec->nnode;
j++) {
614 static void printnode(
const char*
s) {
630 printf(
"%s %s nd%d layer%d v=%g rhs=%g:\n", s,
secname(sec), j, k, nde->
v[k], *nde->
_rhs[k]);
637 static int cntndsave;
640 void save2mat(
void) {
641 int i,
j,
k, im, ipm;
645 if (cntndsave < v_node_count) {
649 cntndsave = v_node_count;
652 for (i=0; i < v_node_count; ++
i) {
657 ndesave[
i].
v[
j] = nde->
v[
j];
658 ndesave[
i].rhs[
j] = nde->
_rhs[
j];
659 for (k=0; k < 2*(
nlayer)+1; ++
k) {
660 ndesave[
i].m[
j][
k] = nde->_m[
j][
k];
662 if (!v_parent[i]->
extnode && j > 0) {
663 ndesave[
i].m[
j][0] = 0.;
671 ndesave[
i].
v[0] = nd->v;
674 ndesave[
i].m[0][0] =
NODEB(nd);
686 void check2mat(
void) {
693 for (i=0; i < v_node_count; ++
i) {
707 for (i=0; i < v_node_count; ++
i) {
711 for (k=0; k <= 2*(
nlayer); ++
k) {
712 printf(
" %-8.3g", ndesave[i].m[j][k]);
714 printf(
" %g %g\n", ndesave[i].
v[j], ndesave[i].
rhs[j]);
720 for (i=0; i < v_node_count; ++
i) {
721 DBG(
"work on node %d\n", i);
723 ip = v_parent[
i]->v_node_index;
725 DBG(
" effect of parent %d on node %d\n", ip, i);
727 DBG(
" work on layer %d\n", j);
729 DBG(
" nde[%d].rhs[%d] -= nde[%d].v[%d]*nde[%d].m[%d][%d]\n", i,j,ip,k,i,j,k-j);
730 DBG(
" %g * %g\n",ndesave[ip].
v[k],ndesave[i].m[j][k-j]);
731 ndesave[
i].rhs[
j] -= ndesave[ip].
v[
k]*ndesave[
i].m[
j][k-
j];
735 DBG(
" effect of node %d on parent %d\n", i, ip);
737 DBG(
" work on layer %d\n", j);
738 for (k=0; k <=
j; ++
k) {
739 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);
740 DBG(
" %g * %g\n",ndesave[i].
v[k],ndesave[i].m[j][2*(nlayer)-j+k]);
741 ndesave[ip].rhs[
j] -= ndesave[
i].
v[
k]*ndesave[
i].m[
j][2*(
nlayer)-j+k];
746 DBG(
" effect of node %d on node %d\n", i, i);
748 DBG(
" work on layer %d\n", j);
750 DBG(
" nde[%d].rhs[%d] -= nde[%d].v[%d]*nde[%d].m[%d][%d]\n", i,j,i,k,i,j,(nlayer)+k-j);
751 DBG(
" %g * %g\n",ndesave[i].
v[k],ndesave[i].m[j][(nlayer)+k-j]);
752 ndesave[
i].rhs[
j] -= ndesave[
i].
v[
k]*ndesave[
i].m[
j][(
nlayer)+k-j];
757 for (i=0; i < v_node_count; ++
i) {
759 if (
fabs(ndesave[i].
rhs[j]) > 1
e-5) {
760 printf(
"bad soln of eq %d,%d rhs-M*V=%g\n",
761 i,j, ndesave[i].
rhs[j]);
void * ecalloc(size_t n, size_t size)
void hoc_register_units(int type, HocParmUnits *units)
ForAllSections(sec) if(sec -> pnode[0]->extnode)
void extcell_2d_alloc(Section *sec)
void nrn_delete_prop_pool(int type)
void nlayer_extracellular()
struct Section * parentsec
static HocParmLimits limits[]
#define ITERATE(itm, lst)
Represent main neuron object computed by single thread.
static void update_extracellular_reg(int old_nlayer)
void extcell_node_create(Node *nd)
static philox4x32_key_t k
static HocParmUnits units[]
static void update_existing_extnode(int old_nlayer)
void extnode_free_elements(Extnode *nde)
static void check_if_extracellular_in_use()
int nrn_get_mechtype(const char *mechname)
HocStruct Symbol ** ppsym
Memb_list * _ecell_memb_list
void(* Pvmi)(struct NrnThread *, Memb_list *, int)
const char * secname(Section *sec)
void hoc_execerror(const char *, const char *)
static void extnode_alloc_elements(Extnode *nde)
Symlist * hoc_built_in_symlist
double section_length(Section *sec)
static void extcell_init(NrnThread *nt, Memb_list *ml, int type)
static int _ode_count(int type)
struct Symbol::@52::@53 rng
void hoc_register_cvode(int i, nrn_ode_count_t cnt, nrn_ode_map_t map, Pvmi spec, Pvmi matsol)
void register_mech(const char **, Pvmp, Pvmi, Pvmi, Pvmi, Pvmi, int, int)
void hoc_register_limits(int type, HocParmLimits *limits)
static const char * mechanism[]
double * nrn_prop_data_alloc(int type, int count, Prop *p)
Symbol * hoc_table_lookup(const char *, Symlist *)
void nrn_extcell_update_param(void)
int nrn_nlayer_extracellular
void nrn_update_2d(NrnThread *nt)
static void extcell_alloc(Prop *)
void nrn_setup_ext(NrnThread *_nt)
void nrn_rhs_ext(NrnThread *_nt)
double chkarg(int, double low, double high)
void extracell_reg_(void)