Example #1
0
static void nrn_cur(_NrnThread* _nt, _Memb_list* _ml, int _type) {
double* _p; Datum* _ppvar; Datum* _thread;
Node *_nd; int* _ni; double _rhs, _v; int _iml, _cntml;
#if CACHEVEC
    _ni = _ml->_nodeindices;
#endif
_cntml = _ml->_nodecount;
_thread = _ml->_thread;
for (_iml = 0; _iml < _cntml; ++_iml) {
 _p = _ml->_data[_iml]; _ppvar = _ml->_pdata[_iml];
#if CACHEVEC
  if (use_cachevec) {
    _v = VEC_V(_ni[_iml]);
  }else
#endif
  {
    _nd = _ml->_nodelist[_iml];
    _v = NODEV(_nd);
  }
  ena = _ion_ena;
 _g = _nrn_current(_p, _ppvar, _thread, _nt, _v + .001);
 	{ double _dina;
  _dina = ina;
 _rhs = _nrn_current(_p, _ppvar, _thread, _nt, _v);
  _ion_dinadv += (_dina - ina)/.001 ;
 	}
 _g = (_g - _rhs)/.001;
  _ion_ina += ina ;
#if CACHEVEC
  if (use_cachevec) {
	VEC_RHS(_ni[_iml]) -= _rhs;
  }else
#endif
  {
	NODERHS(_nd) -= _rhs;
  }
 
}}
Example #2
0
static void nrn_cur(_NrnThread* _nt, _Memb_list* _ml, int _type){
Node *_nd; int* _ni; double _rhs, _v; int _iml, _cntml;
#if CACHEVEC
    _ni = _ml->_nodeindices;
#endif
_cntml = _ml->_nodecount;
for (_iml = 0; _iml < _cntml; ++_iml) {
 _p = _ml->_data[_iml]; _ppvar = _ml->_pdata[_iml];
#if CACHEVEC
  if (use_cachevec) {
    _v = VEC_V(_ni[_iml]);
  }else
#endif
  {
    _nd = _ml->_nodelist[_iml];
    _v = NODEV(_nd);
  }
  ek = _ion_ek;
  cai = _ion_cai;
 _g = _nrn_current(_v + .001);
 	{ double _dik;
  _dik = ik;
 _rhs = _nrn_current(_v);
  _ion_dikdv += (_dik - ik)/.001 ;
 	}
 _g = (_g - _rhs)/.001;
  _ion_ik += ik ;
#if CACHEVEC
  if (use_cachevec) {
	VEC_RHS(_ni[_iml]) -= _rhs;
  }else
#endif
  {
	NODERHS(_nd) -= _rhs;
  }
 
}}
Example #3
0
void NonLinImpRep::didv() {
	int i, j, ip;
	Node* nd;
	NrnThread* _nt = nrn_threads;
	// d2v/dv2 terms
	for (i=_nt->ncell; i < n_v_; ++i) {
		nd = _nt->_v_node[i];
		ip = _nt->_v_parent[i]->v_node_index;
		double* a = cmplx_spGetElement(m_, v_index_[ip], v_index_[i]);
		double* b = cmplx_spGetElement(m_, v_index_[i], v_index_[ip]);
		*a += NODEA(nd);
		*b += NODEB(nd);
		*diag_[i] -= NODEB(nd);
		*diag_[ip] -= NODEA(nd);
	}
	// jwC term
	Memb_list* mlc = _nt->tml->ml;
	int n = mlc->nodecount;
	for (i=0; i < n; ++i) {
		double* cd = mlc->data[i];
		j = mlc->nodelist[i]->v_node_index;
		diag_[v_index_[j]-1][1] += .001 * cd[0] * omega_;
	}
	// di/dv terms
	// because there may be several point processes of the same type
	// at the same location, we have to be careful to neither increment that
	// nd->v multiple times nor count the rhs multiple times.
	// So we can't take advantage of vectorized point processes.
	// To avoid this we do each mechanism item separately.
	// We assume there is no interaction between
	// separate locations. Note that interactions such as gap junctions
	// would not be handled in any case without computing a full jacobian.
	// i.e. calling nrn_rhs varying every state one at a time (that would
	// give the d2v/dv2 terms as well), but the expense is unwarranted.
	for (NrnThreadMembList* tml = _nt->tml; tml; tml = tml->next) {
		i = tml->index;
		if (i == CAP) { continue; }
		if (!memb_func[i].current) { continue; }
		Memb_list* ml = tml->ml;
		double* x1 = rv_; // use as temporary storage
		double* x2 = jv_;
		for (j = 0; j < ml->nodecount; ++j) { Node* nd = ml->nodelist[j];
			// zero rhs
			// save v
			NODERHS(nd) = 0;
			x1[j] = NODEV(nd);
			// v+dv
			NODEV(nd) += delta_;
			current(i, ml, j);
			// save rhs
			// zero rhs
			// restore v
			x2[j] = NODERHS(nd);
			NODERHS(nd) = 0;
			NODEV(nd) = x1[j];
			current(i, ml, j);
			// conductance
			// add to matrix
			*diag_[v_index_[nd->v_node_index]-1] -= (x2[j] - NODERHS(nd))/delta_;
		}
	}
}	
Example #4
0
void Cvode::init_eqn(){
	double vtol;

	NrnThread* _nt;
	CvMembList* cml;
	Memb_list* ml;
	Memb_func* mf;
	int i, j, zneq, zneq_v, zneq_cap_v;
//printf("Cvode::init_eqn\n");
	if (nthsizes_) {
		delete [] nthsizes_;
		nthsizes_ = 0;
	}
	neq_ = 0;
    for (int id = 0; id < nctd_; ++id) {
	CvodeThreadData& z = ctd_[id];
	z.cmlcap_ = nil;
	z.cmlext_ = nil;
	for (cml = z.cv_memb_list_; cml; cml = cml->next) {
		if (cml->index == CAP) {
			z.cmlcap_ = cml;
		}
		if (cml->index == EXTRACELL) {
			z.cmlext_ = cml;
		}
	}
    }
	if (use_daspk_) {
		daspk_init_eqn();
		return;
	}
    FOR_THREADS(_nt) {
	// for lvardt, this body done only once and for ctd_[0]
	CvodeThreadData& z = ctd_[_nt->id];
	// how many ode's are there? First ones are non-zero capacitance
	// nodes with non-zero capacitance
	zneq_cap_v = z.cmlcap_ ? z.cmlcap_->ml->nodecount : 0;
	zneq = zneq_cap_v;
	// now add the membrane mechanism ode's to the count
	for (cml = z.cv_memb_list_; cml; cml = cml->next) {
		Pfridot s = (Pfridot)memb_func[cml->index].ode_count;
		if (s) {
			zneq += cml->ml->nodecount * (*s)(cml->index);
		}
	}
//printf("%d Cvode::init_eqn neq_v=%d zneq_=%d\n", nrnmpi_myid, neq_v, zneq_);
	if (z.pv_) {
		delete [] z.pv_;
		delete [] z.pvdot_;
		z.pv_ = 0;
		z.pvdot_ = 0;
	}
	if (zneq) {
		z.pv_ = new double*[zneq];
		z.pvdot_ = new double*[zneq];
	}
	z.nvoffset_ = neq_;
	z.nvsize_ = zneq;
	neq_ += zneq;
	if (nth_) { break; } //lvardt
    }
#if PARANEURON
	if (use_partrans_) {
		global_neq_ = nrnmpi_int_sum_reduce(neq_, mpicomm_);
//printf("%d global_neq_=%d neq=%d\n", nrnmpi_myid, global_neq_, neq_);
	}
#endif
	atolvec_alloc(neq_);
    for (int id = 0; id < nctd_; ++id) {
	CvodeThreadData& z = ctd_[id];
	double* atv = n_vector_data(atolnvec_, id);
	zneq_cap_v = z.cmlcap_ ? z.cmlcap_->ml->nodecount : 0;
	zneq = z.nvsize_;
	zneq_v = zneq_cap_v;

	for (i=0; i < zneq; ++i) {
		atv[i] = ncv_->atol();
	}
	vtol = 1.;
	if (!vsym) {
		vsym = hoc_table_lookup("v", hoc_built_in_symlist);
	}
	if (vsym->extra) {
		double x;
		x = vsym->extra->tolerance;
		if (x != 0 && x < vtol) {
			vtol = x;
		}
	}
	for (i=0; i < zneq_cap_v; ++i) {
		atv[i] *= vtol;
	}

	// deal with voltage nodes
	// only cap nodes for cvode
	for (i=0; i < z.v_node_count_; ++i) {
		//sentinal values for determining no_cap
		NODERHS(z.v_node_[i]) = 1.;
	}
	for (i=0; i < zneq_cap_v; ++i) {
		ml = z.cmlcap_->ml;
		z.pv_[i] = &NODEV(ml->nodelist[i]);
		z.pvdot_[i] = &(NODERHS(ml->nodelist[i]));
		*z.pvdot_[i] = 0.; // only ones = 1 are no_cap
	}

	// the remainder are no_cap nodes
	if (z.no_cap_node_) {
		delete [] z.no_cap_node_;
		delete [] z.no_cap_child_;
	}
	z.no_cap_node_ = new Node*[z.v_node_count_ - zneq_cap_v];
	z.no_cap_child_ = new Node*[z.v_node_count_ - zneq_cap_v];
	z.no_cap_count_ = 0;
	j = 0;
	for (i=0; i < z.v_node_count_; ++i) {
		if (NODERHS(z.v_node_[i]) > .5) {
			z.no_cap_node_[z.no_cap_count_++] = z.v_node_[i];
		}
		if (z.v_parent_[i] && NODERHS(z.v_parent_[i]) > .5) {
			z.no_cap_child_[j++] = z.v_node_[i];
		}
	}
	z.no_cap_child_count_ = j;

	// use the sentinal values in NODERHS to construct a new no cap membrane list
	new_no_cap_memb(z, _nt);
	
	// map the membrane mechanism ode state and dstate pointers
	int ieq = zneq_v;
	for (cml = z.cv_memb_list_; cml; cml = cml->next) {
		int n;
		ml = cml->ml;
		mf = memb_func + cml->index;
		Pfridot sc = (Pfridot)mf->ode_count;
		if (sc && ( (n = (*sc)(cml->index)) > 0)) {
			Pfridot s = (Pfridot)mf->ode_map;
			if (mf->hoc_mech) {
				for (j=0; j < ml->nodecount; ++j) {
(*s)(ieq, z.pv_ + ieq, z.pvdot_ + ieq, ml->prop[j], atv + ieq);
					ieq += n;
				}
			}else{
				for (j=0; j < ml->nodecount; ++j) {
(*s)(ieq, z.pv_ + ieq, z.pvdot_ + ieq, ml->data[j], ml->pdata[j], atv + ieq, cml->index);
					ieq += n;
				}
			}
		}
	}
    }
	structure_change_ = false;
}
Example #5
0
method3_setup_tree_matrix() /* construct diagonal elements */
{
	int i;
	if (diam_changed) {
		recalc_diam();
	}
#if _CRAY
#pragma _CRI ivdep
#endif
	for (i = 0; i < v_node_count; ++i) {
		Node* nd = v_node[i];
		NODED(nd) = 0.;
		NODERHS(nd) = 0.;
		nd->thisnode.GC = 0.;
		nd->thisnode.EC = 0.;
	}
	for (i=0; i < n_memb_func; ++i) if (memb_func[i].current && memb_list[i].nodecount) {
		if (memb_func[i].vectorized) {
			memb_func[i].current(
			   memb_list[i].nodecount,
			   memb_list[i].nodelist,
			   memb_list[i].data,
			   memb_list[i].pdata
			);
		}else{
			int j, count;
			Pfrd s = memb_func[i].current;
			Memb_list* m = memb_list + i;
			count = m->nodecount;
		   if (memb_func[i].is_point) {
			for (j = 0; j < count; ++j) {
				Node* nd = m->nodelist[j];
				NODERHS(nd) -= (*s)(m->data[j], m->pdata[j],
				  		&NODED(nd),nd->v);
			};
		   }else{
			for (j = 0; j < count; ++j) {
				Node* nd = m->nodelist[j];
				nd->thisnode.EC -= (*s)(m->data[j], m->pdata[j],
				  		&nd->thisnode.GC,nd->v);
			};
		   }
		}
		if (errno) {
			if (nrn_errno_check(i)) {
hoc_warning("errno set during calculation of currents", (char*)0);
			}
		}
	}
#if 0 && _CRAY
#pragma _CRI ivdep
#endif
	for (i=rootnodecount; i < v_node_count; ++i) {
		Node* nd2;
		Node* nd = v_node[i];
		Node* pnd = v_parent[nd->v_node_index];
		double dg, de, dgp, dep, fac;

#if 0
if (i == rootnodecount) {
	printf("v0 %g  vn %g  jstim %g  jleft %g jright %g\n",
	nd->v, pnd->v, nd->fromparent.current, nd->toparent.current,
	nd[1].fromparent.current);
}
#endif

		/* dg and de must be second order when used */
		if ((nd2 = nd->toparent.nd2) != (Node*)0) {
			dgp = -(3*(pnd->thisnode.GC - pnd->thisnode.Cdt)
				- 4*(nd->thisnode.GC - nd->thisnode.Cdt)
				+(nd2->thisnode.GC - nd2->thisnode.Cdt))/2
			;
			dep = -(3*(pnd->thisnode.EC - pnd->thisnode.Cdt * pnd->v)
				- 4*(nd->thisnode.EC - nd->thisnode.Cdt * nd->v)
				+(nd2->thisnode.EC - nd2->thisnode.Cdt * nd2->v))/2
			;
		}else{
			dgp = 0.;
			dep = 0.;
		}

		if ((nd2 = pnd->fromparent.nd2) != (Node*)0) {
			dg = -(3*(nd->thisnode.GC - nd->thisnode.Cdt)
				- 4*(pnd->thisnode.GC - pnd->thisnode.Cdt)
				+(nd2->thisnode.GC - nd2->thisnode.Cdt))/2
			;
			de = -(3*(nd->thisnode.EC - nd->thisnode.Cdt * nd->v)
				- 4*(pnd->thisnode.EC - pnd->thisnode.Cdt * pnd->v)
				+(nd2->thisnode.EC - nd2->thisnode.Cdt * nd2->v))/2
			;
		}else{
			dg = 0.;
			de = 0.;
		}

		fac = 1. + nd->toparent.coefjdot * nd->thisnode.GC;
		nd->toparent.djdv0 = (
			nd->toparent.coefj
			+ nd->toparent.coef0 * nd->thisnode.GC
			+ nd->toparent.coefdg * dg
			)/fac;
		NODED(nd) += nd->toparent.djdv0;
		nd->toparent.current = (
			- nd->toparent.coef0 * nd->thisnode.EC
			- nd->toparent.coefn * pnd->thisnode.EC
			+ nd->toparent.coefjdot * 
				nd->thisnode.Cdt * nd->toparent.current
			- nd->toparent.coefdg * de
			)/fac;
		NODERHS(nd) -= nd->toparent.current;
		NODEB(nd) = (
			- nd->toparent.coefj
			+ nd->toparent.coefn * pnd->thisnode.GC
			)/fac;

		/* this can break cray vectors */
		fac = 1. + nd->fromparent.coefjdot * pnd->thisnode.GC;
		nd->fromparent.djdv0 = (
			nd->fromparent.coefj
			+ nd->fromparent.coef0 * pnd->thisnode.GC
			+ nd->fromparent.coefdg * dgp
			)/fac;
		pNODED(nd) += nd->fromparent.djdv0;
		nd->fromparent.current = (
			- nd->fromparent.coef0 * pnd->thisnode.EC
			- nd->fromparent.coefn * nd->thisnode.EC
			+ nd->fromparent.coefjdot * 
				nd->thisnode.Cdt * nd->fromparent.current
			- nd->fromparent.coefdg * dep
			)/fac;
		pNODERHS(nd) -= nd->fromparent.current;
		NODEA(nd) = (
			- nd->fromparent.coefj
			+ nd->fromparent.coefn * nd->thisnode.GC
			)/fac;
	}
	activstim();
	activsynapse();
#if SEJNOWSKI
	activconnect();
#endif
	activclamp();
}