Example #1
0
void Cvode::nocap_v_part1(NrnThread* _nt){
	int i;
	CvodeThreadData& z = ctd_[_nt->id];

	for (i = 0; i < z.no_cap_count_; ++i) { // initialize storage
		Node* nd = z.no_cap_node_[i];
		NODED(nd) = 0;
		NODERHS(nd) = 0;
	}
	// compute the i(vmold) and di/dv
	rhs_memb(z.no_cap_memb_, _nt);
	lhs_memb(z.no_cap_memb_, _nt);

	for (i = 0; i < z.no_cap_count_; ++i) {// parent axial current
		Node* nd = z.no_cap_node_[i];
		// following from global v_parent
		NODERHS(nd) += NODED(nd) * NODEV(nd);
		Node* pnd = _nt->_v_parent[nd->v_node_index];
		if (pnd) {
			NODERHS(nd) -= NODEB(nd) * NODEV(pnd);
			NODED(nd) -= NODEB(nd);
		}
	}		

	for (i = 0; i < z.no_cap_child_count_; ++i) {// child axial current
		Node* nd = z.no_cap_child_[i];
		// following from global v_parent
		Node* pnd = _nt->_v_parent[nd->v_node_index];
		NODERHS(pnd) -= NODEA(nd) * NODEV(nd);
		NODED(pnd) -= NODEA(nd);
	}		
	nrn_multisplit_nocap_v_part1(_nt);
}
Example #2
0
method3_axial_current() {
	int i;
#if _CRAY
#pragma _CRI ivdep
#endif
	for (i=rootnodecount; i < v_node_count; ++ i) {
		Node* nd = v_node[i];
		Node* pnd = v_parent[i];
		nd->toparent.current +=
			nd->toparent.djdv0 * nd->v
			+ NODEB(nd) * pnd->v;
			
		nd->fromparent.current +=
			nd->fromparent.djdv0 * pnd->v
			+ NODEA(nd) * nd->v;
		
	}	
#if 0
printf("cur0 %g curleft %g curright %g\n", 
	v_node[rootnodecount]->fromparent.current,
	v_node[rootnodecount]->toparent.current,
	v_node[rootnodecount+1]->fromparent.current
	);
#endif
}
Example #3
0
void Cvode::nocap_v(NrnThread* _nt){
	int i;
	CvodeThreadData& z = CTD(_nt->id);

	for (i = 0; i < z.no_cap_count_; ++i) { // initialize storage
		Node* nd = z.no_cap_node_[i];
		NODED(nd) = 0;
		NODERHS(nd) = 0;
	}
	// compute the i(vmold) and di/dv
	rhs_memb(z.no_cap_memb_, _nt);
	lhs_memb(z.no_cap_memb_, _nt);

	for (i = 0; i < z.no_cap_count_; ++i) {// parent axial current
		Node* nd = z.no_cap_node_[i];
		// following from global v_parent
		NODERHS(nd) += NODED(nd) * NODEV(nd);
		Node* pnd = _nt->_v_parent[nd->v_node_index];
		if (pnd) {
			NODERHS(nd) -= NODEB(nd) * NODEV(pnd);
			NODED(nd) -= NODEB(nd);
		}
	}		

	for (i = 0; i < z.no_cap_child_count_; ++i) {// child axial current
		Node* nd = z.no_cap_child_[i];
		// following from global v_parent
		Node* pnd = _nt->_v_parent[nd->v_node_index];
		NODERHS(pnd) -= NODEA(nd) * NODEV(nd);
		NODED(pnd) -= NODEA(nd);
	}		

#if PARANEURON
	if (nrn_multisplit_solve_) { // add up the multisplit equations
		nrn_multisplit_nocap_v();
	}
#endif

	for (i = 0; i < z.no_cap_count_; ++i) {
		Node* nd = z.no_cap_node_[i];
		NODEV(nd) = NODERHS(nd) / NODED(nd);
//		printf("%d %d %g v=%g\n", nrnmpi_myid, i, _nt->_t, NODEV(nd));
	}		
	// no_cap v's are now consistent with adjacent v's
}
Example #4
0
/* triangularization of the matrix equations */
void Cvode::triang(NrnThread* _nt) {
	register Node *nd, *pnd;
	double p;
	int i;
	CvodeThreadData& z = CTD(_nt->id);

	for (i = z.v_node_count_ - 1; i >= z.rootnodecount_; --i) {
		nd = z.v_node_[i];
		pnd = z.v_parent_[i];
		p = NODEA(nd) / NODED(nd);
		NODED(pnd) -= p * NODEB(nd);
		NODERHS(pnd) -= p * NODERHS(nd);
	}
}
Example #5
0
/* back substitution to finish solving the matrix equations */
void Cvode::bksub(NrnThread* _nt) {
	register Node *nd, *cnd;
	int i;
	CvodeThreadData& z = CTD(_nt->id);

	for (i = 0; i < z.rootnodecount_; ++i) {
		NODERHS(z.v_node_[i]) /= NODED(z.v_node_[i]);
	}
	for (i = z.rootnodecount_; i < z.v_node_count_; ++i) {
		cnd = z.v_node_[i];
		nd = z.v_parent_[i];
		NODERHS(cnd) -= NODEB(cnd) * NODERHS(nd);
		NODERHS(cnd) /= NODED(cnd);
	}	
}
Example #6
0
fmatrix() {
	if (ifarg(1)) {
		extern Node* node_exact(Section*, double);
		double x = chkarg(1, 0., 1.);
		int id = (int)chkarg(2, 1., 4.);
		Node* nd = node_exact(chk_access(), x);
		NrnThread* _nt = nd->_nt;
		switch (id) {
		case 1: ret(NODEA(nd)); break;
		case 2: ret(NODED(nd)); break;
		case 3: ret(NODEB(nd)); break;
		case 4: ret(NODERHS(nd)); break;
		}
		return;
	}
	nrn_print_matrix(nrn_threads);
	ret(1.);
}
Example #7
0
void Cvode::rhs(NrnThread* _nt) {
	int i;

	CvodeThreadData& z = CTD(_nt->id);
	if (diam_changed) {
		recalc_diam();
	}
	if (z.v_node_count_ == 0) { return; }
	for (i = 0; i < z.v_node_count_; ++i) {
		NODERHS(z.v_node_[i]) = 0.;
	}
	if (_nt->_nrn_fast_imem) {
		double* p = _nt->_nrn_fast_imem->_nrn_sav_rhs;
		for (i = 0; i < z.v_node_count_; ++i) {
			Node* nd = z.v_node_[i];
			p[nd->v_node_index] = 0;
		}
	}

	rhs_memb(z.cv_memb_list_, _nt);
	nrn_nonvint_block_current(_nt->end, _nt->_actual_rhs, _nt->id);

	if (_nt->_nrn_fast_imem) {
		double* p = _nt->_nrn_fast_imem->_nrn_sav_rhs;
		for (i = 0; i < z.v_node_count_; ++i) {
			Node* nd = z.v_node_[i];
			p[nd->v_node_index] -= NODERHS(nd);
		}
	}

	/* at this point d contains all the membrane conductances */
	/* now the internal axial currents.
		rhs += ai_j*(vi_j - vi)
	*/
	for (i = z.rootnodecount_; i < z.v_node_count_; ++i) {
		Node* nd = z.v_node_[i];
		Node* pnd = z.v_parent_[i];
		double dv = NODEV(pnd) - NODEV(nd);
		/* our connection coefficients are negative so */
		NODERHS(nd) -= NODEB(nd)*dv;
		NODERHS(pnd) += NODEA(nd)*dv;
	}
}
Example #8
0
void Cvode::lhs(NrnThread* _nt) {
	int i;

	CvodeThreadData& z = CTD(_nt->id);
	if (z.v_node_count_ == 0) { return; }
	for (i = 0; i < z.v_node_count_; ++i) {
		NODED(z.v_node_[i]) = 0.;
	}

	lhs_memb(z.cv_memb_list_, _nt);
	nrn_nonvint_block_conductance(_nt->end, _nt->_actual_rhs, _nt->id);
	nrn_cap_jacob(_nt, z.cmlcap_->ml);

	// _nrn_fast_imem not needed since exact icap added in nrn_div_capacity

	/* now add the axial currents */
	for (i = 0; i < z.v_node_count_; ++i) {
		NODED(z.v_node_[i]) -= NODEB(z.v_node_[i]);
	}
        for (i=z.rootnodecount_; i < z.v_node_count_; ++i) {
                NODED(z.v_parent_[i]) -= NODEA(z.v_node_[i]);
        }
}
Example #9
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 #10
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();
}