Beispiel #1
0
static double use_long_double(void* v) {
	NetCvode* d = (NetCvode*)v;
	hoc_return_type_code = 2; // boolean
	if (ifarg(1)) {
		int i = (int)chkarg(1,0,1);
		d->use_long_double_ = i;
		recalc_diam();
	}
	return (double)d->use_long_double_;
}
Beispiel #2
0
static double use_mxb(void* v) {
	NetCvode* d = (NetCvode*)v;
	hoc_return_type_code = 2; // boolean
	if (ifarg(1)) {
		int i = (int)chkarg(1,0,1);
		if (use_sparse13 != i) {
			use_sparse13 = i;
			recalc_diam();
		}
	}
	return (double) use_sparse13;
}
Beispiel #3
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;
	}
}
Beispiel #4
0
fcurrent()
{
	int i;
	if (tree_changed) {
		setup_topology();
	}
	if (v_structure_change) {
		v_setup_vectors();
	}
	if (diam_changed) {
		recalc_diam();
	}

	dt2thread(-1.);
	nrn_thread_table_check();
	state_discon_allowed_ = 0;
	nrn_multithread_job(setup_tree_matrix);
	state_discon_allowed_ = 1;
	ret(1.);
}
Beispiel #5
0
fadvance()
{
	tstopunset;
#if CVODE
	if (cvode_active_) {
		cvode_fadvance(-1.);
		tstopunset;
		ret(1.);
		return;
	}
#endif
	if (tree_changed) {
		setup_topology();
	}
	if (v_structure_change) {
		v_setup_vectors();
	}
	if (diam_changed) {
		recalc_diam();
	}
	nrn_fixed_step();
	tstopunset;
	ret(1.);
}
Beispiel #6
0
void Cvode::daspk_init_eqn(){
	// DASPK equation order is exactly the same order as the
	// fixed step method for current balance (including
	// extracellular nodes) and linear mechanism. Remaining ode
	// equations are same order as for Cvode. Thus, daspk differs from
	// cvode order primarily in that cap and no-cap nodes are not
	// distinguished.
	// note that only one thread is allowed for sparse right now.
	NrnThread* _nt = nrn_threads;
	CvodeThreadData&z = ctd_[0];
	double vtol;
//printf("Cvode::daspk_init_eqn\n");
	int i, j, in, ie, k, neq_v;

	// how many equations are there?
	Memb_func* mf;
	CvMembList* cml;
	//start with all the equations for the fixed step method.
	if (use_sparse13 == 0 || diam_changed != 0) {
		recalc_diam();
	}
	z.neq_v_ = spGetSize(_nt->_sp13mat, 0);
	z.nvsize_ = z.neq_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) {
			z.nvsize_ += cml->ml->nodecount * (*s)(cml->index);
		}
	}
	neq_ = z.nvsize_;
//printf("Cvode::daspk_init_eqn: neq_v_=%d neq_=%d\n", neq_v_, neq_);
	if (z.pv_) {
		delete [] z.pv_;
		delete [] z.pvdot_;
	}
	z.pv_ = new double*[z.nvsize_];
	z.pvdot_ = new double*[z.nvsize_];
	atolvec_alloc(neq_);
	double* atv = n_vector_data(atolnvec_, 0);
	for (i=0; i < neq_; ++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;
		}
	}
	// deal with voltage and extracellular and linear circuit nodes
	// for daspk the order is the same
	assert(use_sparse13);
	if (use_sparse13) {
		for (in = 0; in < _nt->end; ++in) {
			Node* nd; Extnode* nde;
			nd = _nt->_v_node[in];
			nde = nd->extnode;
			i = nd->eqn_index_ - 1; // the sparse matrix index starts at 1
			z.pv_[i] = &NODEV(nd);
			z.pvdot_[i] = nd->_rhs;
			if (nde) {
				for (ie=0; ie < nlayer; ++ie) {
					k = i + ie + 1;
					z.pv_[k] = nde->v + ie;
					z.pvdot_[k] = nde->_rhs[ie];
				}
			}
		}
		linmod_dkmap(z.pv_, z.pvdot_);
		for (i=0; i < z.neq_v_; ++i) {
			atv[i] *= vtol;
		}
	}

	// map the membrane mechanism ode state and dstate pointers
	int ieq = z.neq_v_;
	for (cml = z.cv_memb_list_; cml; cml = cml->next) {
		int n;
		mf = memb_func + cml->index;
		Pfridot sc = (Pfridot)mf->ode_count;
		if (sc && ( (n = (*sc)(cml->index)) > 0)) {
			Memb_list* ml = cml->ml;
			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;
}
Beispiel #7
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();
}