20 # define MAT(a,I_,J_) ((a)[(I_)*(n)+(J_)])
23 const valarray<double> &a,
24 const valarray<double> &b);
31 realnum *eqerror,
realnum *error,
const long n,
double *rlimit,
double *rmax,
32 valarray<double> &escale,
34 const valarray<double> &b2vec,
35 double *
const ervals,
double *
const amat,
36 const bool lgJac,
bool *lgConserve))
62 for( i=0; i < n; i++ )
69 pred = error0 = error2 = erroreq = grad = f1 = f2 = 0.;
73 const int LOOPMAX = 40;
74 for (loop=0;loop<LOOPMAX;loop++)
77 jacobn(MoleMap, b2vec,
get_ptr(ervals),
get_ptr(amat),loop==0,&lgConserve);
81 for( i=0; i < n; i++ )
83 escale[i] =
MAT(amat,i,i);
98 *rlimit = 1e-19 * (*rmax);
100 else if (*rlimit > *rmax)
105 for( i=0; i < n; i++ )
111 MAT(amat,i,i) -= *rlimit;
119 for( i=0; i < n; i++ )
121 double etmp = ervals[i]/(
SMALLABUND*(*rmax)+fabs(b0vec[i]*escale[i]));
122 erroreq += etmp*etmp;
127 fprintf(
ioQQQ,
"Newton step loop %ld error %15.8g\n",loop,erroreq);
131 for (i=0; i < n; i++)
133 ervals1[i] = ervals[i];
135 ervals1[i] -= (*rlimit)*(b2vec[i]-b0vec[i]);
140 double emax0 = 0.0, emax1 = 0.0;
141 for( i=0; i < n; i++ )
146 double etmp = ervals1[i]/(
SMALLABUND*(*rmax)+fabs(b0vec[i]*escale[i]));
147 double etmp0 = ervals0[i]/(
SMALLABUND*(*rmax)+fabs(b0vec[i]*escale[i]));
150 if (fabs(etmp-etmp0) > fabs(emax1-emax0) )
162 for( i=0; i < n; i++ )
164 ervals0[i] = ervals1[i];
165 b1vec[i] = ervals1[i];
170 *eqerror = *error = 1e30f;
181 if (error1 < (1-2e-4*f1)*error0 || error1 < 1e-20)
189 f1 *= -0.5*f1*grad/(error1-error0-f1*grad);
190 pred = error0+0.5*grad*f1;
196 fprintf(
ioQQQ,
"Newt %ld stp %11.4g err %11.4g erreq %11.4g rlimit %11.4g grd %11.4g fdg %11.4g e0 %11.4g de %11.4g pred %11.4g\n",
197 loop,f1,error1,erroreq,*rlimit,grad,(error1-error0)/f1,error0,error1-error0,pred
200 fprintf(
ioQQQ,
"Maxi %ld %s emax from %11.4g of %11.4g -> %11.4g of %11.4g, diff %11.4g\n",
201 maxi,
groupspecies[maxi]->label.c_str(),emax0,error0, emax1,error1,emax1-emax0);
205 double a = (error1-error0)/(f1*f1) - (error2-error0)/(f2*f2);
206 a += grad * (1./f2 - 1./f1);
208 double b = -f2*(error1-error0)/(f1*f1) + f1*(error2-error0)/(f2*f2);
209 b += grad * (f2/f1 - f1/f2);
218 f1 = 1.-3.*(a/b)*(grad/b)*(ft-f2);
220 f1 = b/(3.*a)*(sqrt(f1)-1.);
229 pred = error0+f1*(grad+f1/(ft-f2)*(b+a*f1));
233 if (f1 > 0.5*f2 || f1 < 0.)
235 else if (f1 < 0.03*f2)
249 for( i=0; i < n; i++ )
251 b2vec[i] = b0vec[i]-b1vec[i]*f1;
258 for( i=0; i < n; i++ )
265 if (0 && LOOPMAX == loop)
267 double rvmax = 0., rval;
269 for( i=0; i < n; ++i )
272 rval = b1vec[i]/b0vec[i];
277 if (fabs(rval) > rvmax)
287 for( j=0; j < n; j++ )
292 jacobn(MoleMap, b1vec,
get_ptr(ervals1),
get_ptr(amat),
false,&lgConserve);
293 for( i=0; i < n; i++ )
295 for( j=0; j < n; j++ )
299 double db = 1e-3*fabs(b0vec[i])+1e-9;
301 db = b1vec[i]-b0vec[i];
302 jacobn(MoleMap, b1vec,
get_ptr(escale),
get_ptr(amat),
false,&lgConserve);
303 for( j=0; j < n; j++ )
305 double e1 =
MAT(amat,i,j);
306 double e2 = (escale[j]-ervals1[j])/db;
307 if (fabs(e1-e2) > 0.01*fabs(e1+e2))
324 const valarray<double> &a,
const valarray<double> &b)
326 fprintf(
ioQQQ,
" CO_solve getrf_wrapper error %ld",(
long int) merror );
327 if( merror > 0 && merror <= n )
330 fprintf(
ioQQQ,
"index \t Row A(i,%li)\t Col A(%li,j) \t B \t Species\n", merror, merror );
331 for(
long index=1; index<=n; index++ )
334 a[(merror-1)*n + index - 1],
335 a[(index -1)*n + merror- 1],
350 valarray<int32> ipiv(n);
354 valarray<double> lufac(n*n),oldb(n),err(n);
356 ASSERT(a.size() == size_t(n*n));
357 ASSERT(b.size() == size_t(n));
372 if (error_print != NULL)
373 error_print(n,merror,a,b);
375 fprintf(
ioQQQ,
" PROBLEM singular matrix in solve_system\n");
383 fprintf(
ioQQQ,
" solve_system: dgetrs finds singular or ill-conditioned matrix\n" );
387 for (k=0;k<nrefine;k++)
397 err[i] -= a[i+j*n]*b[j];
405 double maxb=0., maxe=0.;
410 if (fabs(err[i])>maxe)
415 fprintf(
ioQQQ,
"Max error %g, Condition %g\n",maxe,1e16*maxe/maxb);
void getrs_wrapper(char trans, long N, long nrhs, double *A, long lda, int32 *ipiv, double *B, long ldb, int32 *info)
ConvergenceCounter register_(const string name)
void(* error_print_t)(long, long, const valarray< double > &, const valarray< double > &)
bool newton_step(GroupMap &MoleMap, const valarray< double > &b0vec, valarray< double > &b2vec, realnum *eqerror, realnum *error, const long n, double *rlimit, double *rmax, valarray< double > &escale, void(*jacobn)(GroupMap &MoleMap, const valarray< double > &b2vec, double *const ervals, double *const amat, const bool lgJac, bool *lgConserve))
void getrf_wrapper(long M, long N, double *A, long lda, int32 *ipiv, int32 *info)
int32 solve_system(const valarray< double > &a, valarray< double > &b, long int n, error_print_t error_print)
#define DEBUG_ENTRY(funcname)
int fprintf(const Output &stream, const char *format,...)
vector< molecule * > groupspecies
STATIC void mole_system_error(long n, long merror, const valarray< double > &a, const valarray< double > &b)
void mole_print_species_reactions(molecule *speciesToPrint)