/* solve the matrix equation */ void nrn_solve_minimal(NrnThread* _nt) { if (use_solve_interleave) { solve_interleaved(_nt->id); } else { triang(_nt); bksub(_nt); } }
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); }
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"); }