Esempio n. 1
0
/* solve the matrix equation */
void nrn_solve_minimal(NrnThread* _nt) {
    if (use_solve_interleave) {
        solve_interleaved(_nt->id);
    } else {
        triang(_nt);
        bksub(_nt);
    }
}
Esempio n. 2
0
File: lineq.c Progetto: nrnhines/nrn
int matsol(void)
{
	register struct elm *pivot;
	register struct elm *el;
	struct elm *hold;
	int i, j;
	double max;

	/* Upper triangularization */
	for (i=1 ; i <= neqn ; i++)
	{
		if (fabs((pivot = getelm(ELM0, eqord[i], varord[i]))->value) <= SMALL)
		{
			/* use max row element as pivot */
			remelm(pivot);
			max = SMALL;
			pivot = ELM0;
			for (el = rowst[eqord[i]] ; el != ELM0 ;
			   el = el->c_right)
				if (fabs(el->value) > max)
					max = fabs((pivot = el)->value);
			if (pivot == ELM0)
				return(0);
			else
			{
				for (j = i; j<= neqn ; j++)
					if (varord[j] == pivot->col)
						break;
				varord[j] = varord[i];
				varord[i] = pivot->col;
			}
		}
		/* Eliminate all elements in pivot column */
		for (el = colst[pivot->col] ; el != ELM0 ; el = hold)
		{
			hold = el->r_down;	/* el will be freed below */
			if (el != pivot)
			{
				subrow(pivot, el);
				remelm(el);
			}
		}
		/* Remove pivot row from further upper triangle work */
		for (el = rowst[pivot->row] ; el != ELM0 ; el = el->c_right)
		{
			if (el->r_up != ELM0)
				el->r_up->r_down = el->r_down;
			else 
				colst[el->col] = el->r_down;
			if (el->r_down != ELM0)
				el->r_down->r_up = el->r_up;
		}
	}
	bksub();
	return(1);
}
Esempio n. 3
0
int Cvode::solvex_thread(double* b, double* y, NrnThread* nt){
//printf("Cvode::solvex_thread %d t=%g t_=%g\n", nt->id, nt->t, t_);
//printf("Cvode::solvex_thread %d %g\n", nt->id, gam());
//printf("\tenter b\n");
//for (int i=0; i < neq_; ++i) { printf("\t\t%d %g\n", i, b[i]);}
	int i;
	CvodeThreadData& z = CTD(nt->id);
	nt->cj = 1./gam();
	nt->_dt = gam();
	if (z.nvsize_ == 0) { return 0; }
	lhs(nt); // special version for cvode.
	scatter_ydot(b, nt->id);
	nrn_mul_capacity(nt, z.cmlcap_->ml);
	for (i=0; i < z.no_cap_count_; ++i) {
		NODERHS(z.no_cap_node_[i]) = 0.;
	}
	// solve it
#if PARANEURON
	if (nrn_multisplit_solve_) {
		(*nrn_multisplit_solve_)();
	}else
#endif
	{
		triang(nt);
		bksub(nt);
	}
//for (i=0; i < v_node_count; ++i) {
//	printf("%d rhs %d %g t=%g\n", nrnmpi_myid, i, VEC_RHS(i), t);
//}
	if (ncv_->stiff() == 2) {
		solvemem(nt);
	}else{
		// bug here should multiply by gam
	}
	gather_ydot(b, nt->id);
//printf("\texit b\n");
//for (i=0; i < neq_; ++i) { printf("\t\t%d %g\n", i, b[i]);}
	return 0;
}
void solvde(int itmax, float conv,float slowc, float scalv[], int indexv[],
int ne, int nb, int m, float **y, float ***c, float **s)
{
	void bksub(int ne, int nb, int jf, int k1, int k2, float ***c);
	void difeq(int k, int k1, int k2, int jsf, int is1, int isf,
		int indexv[], int ne, float **s, float **y);
	void pinvs(int ie1, int ie2, int je1, int jsf, int jc1, int k,
		float **c, float **s);
	void red(int iz1, int iz2, int jz1, int jz2, int jm1, int jm2, int jmf,
		int ic1, int jc1, int jcf, int kc, float ***c, float **s);
	int ic1,ic2, ic3,ic4,it,j,j1,j2,j3,j4,j5,j6,j7,j8,j9;
	int jc1, jcf, jv, k, k1, k2, km, kp,nvars, *kmax;
	float err, errj, fac, vmax, vz,*ermax;

	kmax=ivector(1,ne);
	ermax=vector(1,ne);
	k1=1;
	k2=m;
	nvars=ne*m;
	j1=1;j2=nb;
	j3=nb+1;
	j4=ne;
	j5=j4+j1;
	j6=j4+j2;
	j7=j4+j3;
	j8=j4+j4;
	j9=j8+j1;
	ic1=1;
	ic2=ne-nb;
	ic3=ic2+1;
	ic4=ne;
	jc1=1;
	jcf=ic3;
	for (it=1;it<=itmax;it++){
		k=k1;
		difeq(k,k1,k2,j9,ic3,ic4,indexv,ne,s,y);
		pinvs(ic3,ic4,j5,j9,jc1,k1,c,s);
		for (k=k1+1;k<=k2;k++){
			kp=k-1;
			difeq(k,k1,k2,j9,ic1,ic4,indexv,ne,s,y);
			red(ic1,ic4,j1,j2,j3,j4,j9,ic3,jc1,jcf,kp,c,s);
			pinvs(ic1,ic4,j3,j9,jc1,k,c,s);
		}
		k=k2+1;
		difeq(k,k1,k2,j9,ic1,ic2,indexv,ne,s,y);
		red(ic1,ic2,j5,j6,j7,j8,j9,ic3,jc1,jcf,k2,c,s);
		pinvs(ic1,ic2,j7,j9,jcf,k2+1,c,s);
		bksub(ne,nb,jcf,k1,k2,c);
		err=0.0;
		for(j=1;j<=ne;j++){
			jv=indexv[j];
			errj=vmax=0.0;
			km=0;
			for (k=k1;k<=k2;k++){
				vz=fabs(c[jv][1][k]);
				if (vz > vmax) {
					vmax=vz;
					km=k;
				}
				errj += vz;
			}
			err += errj/scalv[j];
			ermax[j]=c[jv][1][km]/scalv[j];
			kmax[j]=km;
		}
		err /= nvars;
		fac = (err > slowc ? slowc/err : 1.0);
		for (j=1;j<=ne;j++){
			jv=indexv[j];
			for(k=k1;k<=k2;k++)
				y[j][k] -= fac*c[jv][1][k];
		}
		printf("\n%8s %9s %9s\n","Iter.","Error","FAC");
		printf("%6d %12.6f %11.6f\n",it,err,fac);
		if (err < conv){
			free_vector(ermax,1,ne);
			free_ivector(kmax,1,ne);
			return;
		}
	}
	nrerror("Too many itterations in silvde");
}