示例#1
0
文件: ndatclas.cpp 项目: nrnhines/nrn
NrnProperty::NrnProperty(const char* name) {
	Symbol* sym = hoc_table_lookup(name, hoc_built_in_symlist);
	if (!sym) {
		sym = hoc_table_lookup(name, hoc_top_level_symlist);
	}
	if(sym) {
		if (sym->type == MECHANISM) {
			/*EMPTY*/
		}else if (sym->type == TEMPLATE && sym->u.ctemplate->is_point_){
			sym = hoc_table_lookup(name, sym->u.ctemplate->symtable);

		}else{
			sym = 0;
		}
	}
	if (sym) {
		Prop* p, *p0 = 0, *p1;
//printf("prop_alloc %s %p type=%d\n", sym->name, sym, sym->subtype);
		// need to do this with no args
		hoc_push_frame(sym, 0);
		p = prop_alloc(&p0, sym->subtype, NULL);
		hoc_pop_frame();
		for (; p0 != p; p0 = p1) {
			p1 = p0->next;
			single_prop_free(p0);
		}
		npi_ = new NrnPropertyImpl(p);
		npi_->del_ = true;
	}else{
		npi_ = NULL;
		hoc_execerror(name, "is not a Mechanism or Point Process");
	}
}
示例#2
0
void remake_pmech_types() {
    int i;
    Py_XDECREF(pmech_types);
    Py_XDECREF(rangevars_);
    pmech_types = PyDict_New();
    rangevars_ = PyDict_New();
    rangevars_add(hoc_table_lookup("diam", hoc_built_in_symlist));
    rangevars_add(hoc_table_lookup("cm", hoc_built_in_symlist));
    rangevars_add(hoc_table_lookup("v", hoc_built_in_symlist));
    for (i=4; i < n_memb_func; ++i) { // start at pas
	nrnpy_reg_mech(i);
    }
}
示例#3
0
void nrnpy_reg_mech(int type) {
	int i;
	char* s;
	Memb_func* mf = memb_func + type;
	if (!nrnmodule_) { return; }
	if (mf->is_point) {
		if (nrn_is_artificial_[type] == 0) {
			Symlist* sl = nrn_pnt_template_[type]->symtable;
			Symbol* s = hoc_table_lookup("get_segment", sl);
			if (!s) {
				s = hoc_install("get_segment", OBFUNCTION, 0, &sl);
#if MAC
				s->u.u_proc->defn.pfo = (Object**(*)(...))pp_get_segment;
#else
				s->u.u_proc->defn.pfo = (Object**(*)())pp_get_segment;
#endif
			}
		}
		return;
	}
	s = mf->sym->name;
//printf("nrnpy_reg_mech %s %d\n", s, type); 
	if (PyDict_GetItemString(pmech_types, s)) {
		hoc_execerror(s, "mechanism already exists");
	}
	Py_INCREF(&nrnpy_MechanismType);
	PyModule_AddObject(nrnmodule_, s, (PyObject *)pmech_generic_type);
	PyDict_SetItemString(pmech_types, s, Py_BuildValue("i", type));
	for (i = 0; i < mf->sym->s_varn; ++i) {
		Symbol* sym = mf->sym->u.ppsym[i];
		rangevars_add(sym);
	}
}
示例#4
0
/** Make a hoc equivalent to Java class (jname) calling it hname in hoc.
	Done from NrnJava.load("name")
	after the class is loaded with FindClass.
 */
int convertJavaClassToHoc( JNIEnv *env, const char* jname, const char* hname, const char* path ) {
	//only if classname not already in use.
	if (!njclassnames) {
		njclassnames = new NJStrList();
	}
	char* hn = nrn_dot2underbar(hname);
//	printf("loading %s --- calling it %s\n", jname, hn);
	Symbol* s = hoc_table_lookup(hn, hoc_top_level_symlist);
	if (s) {
		delete [] hn;
		if (s->type == TEMPLATE && s->u.ctemplate->id < 0) {
			return 2;
		}
		return 0;
	}
	jstring js = env->NewStringUTF( jname );
if (env->ExceptionOccurred()) { env->ExceptionDescribe();}
	jstring hs = env->NewStringUTF( hn );
	jstring jp = env->NewStringUTF(path);

	int i = env->CallStaticIntMethod(neuronCls, makeHocClassID, js, hs, jp);
	if (i == 1) {
		njclassnames->append(new CopyString(jname));
	}
	errno = 0; // have seen this set to 2 by linux
	delete [] hn;
	return i;
}
示例#5
0
JNIEXPORT jlong JNICALL Java_neuron_Neuron_methodID
  (JNIEnv *env, jclass, jlong jc, jstring name){
	const char* s = env->GetStringUTFChars(name, 0);
	Object* ho = (Object*)jc;
	Symbol* sym = hoc_table_lookup(s, ho->ctemplate->symtable);
//printf("methodID %s %s\n", s, sym->name);
	env->ReleaseStringUTFChars(name, s);
	return (jlong)sym;
}
示例#6
0
void OcPointer_reg() {
	class2oc("Pointer", cons, destruct, members, NULL, NULL, s_memb);
	// now make the val variable an actual double
	Symbol* sv = hoc_lookup("Pointer");
	Symbol* sx = hoc_table_lookup("val", sv->u.ctemplate->symtable);
	sx->type = VAR;
	sx->arayinfo = NULL;
	sv->u.ctemplate->steer = steer_val;
}
示例#7
0
JNIEXPORT jstring JNICALL Java_neuron_Neuron_sGet
  (JNIEnv *env, jclass, jstring js){
	const char* s = env->GetStringUTFChars(js, 0);
	Symbol* sym = hoc_table_lookup(s, hoc_top_level_symlist);
	assert(sym && sym->type == STRING);
	char** sval = hoc_top_level_data[sym->u.oboff].ppstr;
	env->ReleaseStringUTFChars(js, s);
	return env->NewStringUTF(*sval);
}
示例#8
0
JNIEXPORT jstring JNICALL Java_neuron_Neuron_hGetStringField
  (JNIEnv *env, jclass, jlong v, jstring js){
	const char* s = env->GetStringUTFChars(js, 0);
	Object* o = (Object*)v;
	Symbol* sym = hoc_table_lookup(s, o->ctemplate->symtable);
	assert(sym && sym->type == STRING);
	char** sval = hoc_top_level_data[sym->u.oboff].ppstr;
	env->ReleaseStringUTFChars(js, s);
	return env->NewStringUTF(*sval);
}
示例#9
0
// note that an sgi CC complained about the alloc token not being interpretable
//as std::alloc so we changed to hm_alloc
static HocMech* common_register(char** m, Symbol* classsym, Symlist* slist,  void (hm_alloc)(Prop*), int& type){
	Pvmi cur, jacob, stat, initialize;	
	cur = nil;
	jacob = nil;
	stat = nil;
	initialize = nil;
	HocMech* hm = new HocMech();
	hm->slist = nil;
	hm->mech = classsym;
	hm->initial = hoc_table_lookup("initial", slist);
	hm->after_step = hoc_table_lookup("after_step", slist);
	if (hm->initial) initialize = (Pvmi)initial;
	if (hm->after_step) stat = (Pvmi)after_step;
	register_mech(m, hm_alloc, cur, jacob, stat, initialize, -1, 0);
	type = nrn_get_mechtype(m[1]);
	hoc_register_cvode(type, nil, nil, nil, nil);
	memb_func[type].hoc_mech = hm;
	return hm;
}
示例#10
0
JNIEXPORT jobject JNICALL Java_neuron_Neuron_oGet
  (JNIEnv *env, jclass, jstring js){
	const char* s = env->GetStringUTFChars(js, 0);
	Symbol* sym = hoc_table_lookup(s, hoc_top_level_symlist);
	assert(sym && sym->type == OBJECTVAR);
	Object** po = hoc_top_level_data[sym->u.oboff].pobj;
	env->ReleaseStringUTFChars(js, s);
	jobject jo = h2jObject(*po);
	hoc_obj_unref(*po);
	return jo;
}
示例#11
0
JNIEXPORT jobject JNICALL Java_neuron_Neuron_hGetObjectField
  (JNIEnv *env, jclass, jlong v, jstring js){
	const char* s = env->GetStringUTFChars(js, 0);
	Object* o = (Object*)v;
	Symbol* sym = hoc_table_lookup(s, o->ctemplate->symtable);
	assert(sym && sym->type == OBJECTVAR);
	Object** po = o->u.dataspace[sym->u.oboff].pobj;
	env->ReleaseStringUTFChars(js, s);
	jobject jo = h2jObject(*po);
	hoc_obj_unref(*po);
	return jo;
}
示例#12
0
JNIEXPORT void JNICALL Java_neuron_Neuron_hSetObjectField__Ljava_lang_String_2Ljava_lang_Object_2I
  (JNIEnv *env, jclass, jstring js, jobject joval, jint type){
	jnisave
	const char* s = env->GetStringUTFChars(js, 0);
	Symbol* sym = hoc_table_lookup(s, hoc_top_level_symlist);
	assert(sym && sym->type == OBJECTVAR);
	Object** po = hoc_top_level_data[sym->u.oboff].pobj;
	Object** poval = nj_j2hObject(joval, type);
	Object* old = *po;
	*po = *poval;
	(*po)->refcount++;
	hoc_obj_unref(old);
	env->ReleaseStringUTFChars(js, s);
	jnirestore
}
示例#13
0
文件: nonlinz.cpp 项目: nrnhines/nrn
NonLinImpRep::NonLinImpRep() {
	int err;
	int i, j, ieq, cnt;
	NrnThread* _nt = nrn_threads;
	maxiter_ = 500;
	m_ = NULL;

	vsymtol_ = NULL;
	Symbol* vsym = hoc_table_lookup("v", hoc_built_in_symlist);
	if (vsym->extra) {
		vsymtol_ = &vsym->extra->tolerance;
	}
	// the equation order is the same order as for the fixed step method
	// for current balance. Remaining ode equation order is
	// defined by the memb_list.

	
	// how many equations
	n_v_ = _nt->end;
	n_ext_ = 0;
	if (_nt->_ecell_memb_list) {
		n_ext_ = _nt->_ecell_memb_list->nodecount*nlayer;
	}
	n_lin_ = nrndae_extra_eqn_count();
	n_ode_ = 0;
	for (NrnThreadMembList* tml = _nt->tml; tml; tml = tml->next) {
		Memb_list* ml = tml->ml;
		i = tml->index;
		Pfridot s = (Pfridot)memb_func[i].ode_count;
		if (s) {
			cnt = (*s)(i);
			n_ode_ += cnt * ml->nodecount;
		}
	}
	neq_v_ = n_v_ + n_ext_ + n_lin_;
	neq_ = neq_v_ + n_ode_;
	if (neq_ == 0) { return; }
	m_ = cmplx_spCreate(neq_, 1, &err);
	assert(err == spOKAY);
	pv_ = new double*[neq_];
	pvdot_ = new double*[neq_];
	v_index_ = new int[n_v_];
	rv_ = new double[neq_+1];
	rv_ += 1;
	jv_ = new double[neq_+1];
	jv_ += 1;
	diag_ = new double*[neq_];
	deltavec_ = new double[neq_];

	for (i=0; i < n_v_; ++i) {
		// utilize nd->eqn_index in case of use_sparse13 later
		Node* nd = _nt->_v_node[i];
		pv_[i] = &NODEV(nd);
		pvdot_[i] = nd->_rhs;
		v_index_[i] = i+1;
	}
	for (i=0; i < n_v_; ++i) {
		diag_[i] = cmplx_spGetElement(m_, v_index_[i], v_index_[i]);
	}
	for (i=neq_v_; i < neq_; ++i) {
		diag_[i] = cmplx_spGetElement(m_, i+1, i+1);
	}
	scnt_ = structure_change_cnt;
}
示例#14
0
static PyObject* segment_getattro(NPySegObj* self, PyObject* name) {
	Symbol* sym;
	Py_INCREF(name);
	char* n = PyString_AsString(name);
//printf("segment_getattr %s\n", n);
	PyObject* result = 0;
	PyObject* otype;
	PyObject* rv;
	if (strcmp(n, "v") == 0) {
		Node* nd = node_exact(self->pysec_->sec_, self->x_);
		result = Py_BuildValue("d", NODEV(nd));
	}else if ((otype = PyDict_GetItemString(pmech_types, n)) != NULL) {
		int type = PyInt_AsLong(otype);
//printf("segment_getattr type=%d\n", type);
		Node* nd = node_exact(self->pysec_->sec_, self->x_);
		Prop* p = nrn_mechanism(type, nd);
		if (!p) {
			rv_noexist(self->pysec_->sec_, n, self->x_, 1);
			Py_DECREF(name);
			return NULL;
		}	
		NPyMechObj* m = PyObject_New(NPyMechObj, pmech_generic_type);
		if (m == NULL) {
			Py_DECREF(name);
			return NULL;
		}
		m->pyseg_ = self;
		m->prop_ = p;
		Py_INCREF(m->pyseg_);
		result = (PyObject*)m;
	}else if ((rv = PyDict_GetItemString(rangevars_, n)) != NULL) {
		sym = ((NPyRangeVar*)rv)->sym_;
		if (ISARRAY(sym)) {
			NPyRangeVar* r = PyObject_New(NPyRangeVar, range_type);
			r->pyseg_ = self;
			Py_INCREF(r->pyseg_);
			r->sym_ = sym;
			r->isptr_ = 0;
			result = (PyObject*)r;
		}else{
			int err;
			double* d = nrnpy_rangepointer(self->pysec_->sec_, sym, self->x_, &err);
			if (!d) {
				rv_noexist(self->pysec_->sec_, n, self->x_, err);
				result = NULL;
			}else{
				result = Py_BuildValue("d", *d);
			}
		}
	}else if (strncmp(n, "_ref_", 5) == 0) {
		if (strcmp(n+5, "v") == 0) {
			Node* nd = node_exact(self->pysec_->sec_, self->x_);
			result = nrn_hocobj_ptr(&(NODEV(nd)));
		}else if ((sym = hoc_table_lookup(n+5, hoc_built_in_symlist)) != 0 && sym->type == RANGEVAR) {
			if (ISARRAY(sym)) {
				NPyRangeVar* r = PyObject_New(NPyRangeVar, range_type);
				r->pyseg_ = self;
				Py_INCREF(r->pyseg_);
				r->sym_ = sym;
				r->isptr_ = 1;
				result = (PyObject*)r;
			}else{
				int err;
				double* d = nrnpy_rangepointer(self->pysec_->sec_, sym, self->x_, &err);
				if (!d) {
					rv_noexist(self->pysec_->sec_, n+5, self->x_, err);
					result = NULL;
				}else{
					result = nrn_hocobj_ptr(d);
				}
			}
		}else{
			rv_noexist(self->pysec_->sec_, n, self->x_, 2);
			result = NULL;
		}
	}else if (strcmp(n, "__dict__") == 0) {
		Node* nd = node_exact(self->pysec_->sec_, self->x_);
		result = PyDict_New();
		assert(PyDict_SetItemString(result, "v", Py_None) == 0);
		assert(PyDict_SetItemString(result, "diam", Py_None) == 0);
		assert(PyDict_SetItemString(result, "cm", Py_None) == 0);
		for (Prop* p = nd->prop; p ; p = p->next) {
			if (p->type > CAP && !memb_func[p->type].is_point){
				char* pn = memb_func[p->type].sym->name;
				assert(PyDict_SetItemString(result, pn, Py_None) == 0);
			}
		}
	}else{
		result = PyObject_GenericGetAttr((PyObject*)self, name);
	}
	Py_DECREF(name);
	return result;
}
示例#15
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;
}
示例#16
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;
}
示例#17
0
static void check_list(const char* s, Symlist* sl) {
	if (hoc_table_lookup(s, sl)) {
		hoc_execerror(s, "already exists");
	}
}
示例#18
0
void make_pointprocess() {
	char buf[256];
	int i, cnt, type, ptype;
	Symbol* sp, *s2;
	char* classname = gargstr(1);
//printf("classname=%s\n", classname);
	char* parnames = nil;
	if (ifarg(2)) {
		parnames = new char[strlen(gargstr(2)) + 1];
		strcpy(parnames, gargstr(2));
	}
//if(parnames) printf("parnames=%s\n", parnames);
	Symbol* classsym = hoc_lookup(classname);
	if (classsym->type != TEMPLATE) {
		hoc_execerror(classname, "not a template");
	}
	cTemplate* tp = classsym->u.ctemplate;
	Symlist* slist = tp->symtable;
	// increase the dataspace by 1 void pointer. The last element
	// is where the Point_process pointer can be found and when
	// the object dataspace is freed, so is the Point_process.
	if (tp->count > 0) {
fprintf(stderr, "%d object(s) of type %s already exist.\n", tp->count, classsym->name);
hoc_execerror("Can't make a template into a PointProcess when instances already exist", 0);
	}
	++tp->dataspace_size;
	char** m = make_m(false, cnt, slist, classsym->name, parnames);
	
	check_list("loc", slist);
	check_list("get_loc", slist);
	check_list("has_loc", slist);
	//so far we need only the name and type
	sp = hoc_install("loc", FUNCTION, 0., &slist); sp->cpublic = 1;
	sp = hoc_install("get_loc", FUNCTION, 0., &slist); sp->cpublic = 1;
	sp = hoc_install("has_loc", FUNCTION, 0., &slist); sp->cpublic = 1;

	Symlist* slsav = hoc_symlist;
	hoc_symlist = nil;
	HocMech* hm = common_register(m, classsym, slist, alloc_pnt, type);
	hm->slist = hoc_symlist;
	hoc_symlist = slsav;
	s2 = hoc_table_lookup(m[1], hm->slist);
	assert(s2->subtype == type);
//	type = s2->subtype;
	ptype = point_reg_helper(s2);
//printf("type=%d pointtype=%d %s %lx\n", type, ptype, s2->name, (long)s2);
	classsym->u.ctemplate->is_point_ = ptype;

	// classsym->name is already in slist as an undef, Remove it and
	// move s2 out of HocMech->slist and into slist.
	// That is the one with the u.ppsym.
	// The only reason it needs to be in slist is to find the
	// mechanims type. And it needs to be LAST in that list.
	// The only reason for the u.ppsym is for ndatclas.c and we
	// need to fill those symbols with oboff.
	sp = hoc_table_lookup(classsym->name, slist);
	hoc_unlink_symbol(sp, slist);
	hoc_unlink_symbol(s2, hm->slist);
	hoc_link_symbol(s2, slist);
	hoc_link_symbol(sp, hm->slist); // just so it isn't counted as leakage
	for (i=0; i < s2->s_varn; ++i) {
		Symbol* sp = hoc_table_lookup(s2->u.ppsym[i]->name, slist);
		s2->u.ppsym[i]->cpublic = 2;
		s2->u.ppsym[1]->u.oboff = sp->u.oboff;
	}
	for (i=0; i < cnt; ++i) {
		if (m[i]) {
			delete [] m[i];
		}
	}
	delete [] m;
	if (parnames) {
		delete [] parnames;
	}
	ret(1.);
}