46 typedef void (*
_lsoda_f) (double,
double *,
double *,
void *);
53 #include "../utils/defs.h"
85 if (n <= 1 || incx <= 0)
93 for (i = 1 + incx; i <= n * incx; i = i + incx) {
106 for (i = 2; i <=
n; i++) {
122 dscal(
size_t n,
double da,
double* dx,
size_t incx)
156 for (i = 1; i <= n * incx; i = i + incx)
166 for (i = 1; i <= m; i++)
171 for (i = m + 1; i <=
n; i = i + 5) {
173 dx[i + 1] = da * dx[i + 1];
174 dx[i + 2] = da * dx[i + 2];
175 dx[i + 3] = da * dx[i + 3];
176 dx[i + 4] = da * dx[i + 4];
187 ddot(
size_t n,
double* dx,
size_t incx,
double* dy,
size_t incy)
224 if (incx != incy || incx < 1) {
228 ix = (-n + 1) * incx + 1;
230 iy = (-n + 1) * incy + 1;
231 for (i = 1; i <=
n; i++) {
232 dotprod = dotprod + dx[ix] * dy[iy];
245 for (i = 1; i <= m; i++)
246 dotprod = dotprod + dx[i] * dy[i];
250 for (i = m + 1; i <=
n; i = i + 5)
251 dotprod = dotprod + dx[i] * dy[i] + dx[i + 1] * dy[i + 1] +
252 dx[i + 2] * dy[i + 2] + dx[i + 3] * dy[i + 3] +
253 dx[i + 4] * dy[i + 4];
258 for (i = 1; i <= n * incx; i = i + incx)
259 dotprod = dotprod + dx[i] * dy[i];
277 daxpy(
size_t n,
double da,
double* restr dx,
size_t incx,
double* restr dy,
size_t incy)
310 if (n < 0 || da == 0.)
315 if (incx != incy || incx < 1) {
319 ix = (-n + 1) * incx + 1;
321 iy = (-n + 1) * incy + 1;
322 for (i = 1; i <=
n; i++) {
323 dy[iy] = dy[iy] + da * dx[ix];
336 for (i = 1; i <= m; i++)
337 dy[i] = dy[i] + da * dx[i];
341 for (i = m + 1; i <=
n; i = i + 4) {
342 dy[i] = dy[i] + da * dx[i];
343 dy[i + 1] = dy[i + 1] + da * dx[i + 1];
344 dy[i + 2] = dy[i + 2] + da * dx[i + 2];
345 dy[i + 3] = dy[i + 3] + da * dx[i + 3];
351 for (i = 1; i <= n * incx; i = i + incx)
352 dy[i] = da * dx[i] + dy[i];
362 dgesl(
double *restr * restr a,
int n,
int*
ipvt,
double* restr b,
int job)
413 for (k = 1; k <=
n; k++) {
414 t =
ddot(k - 1, a[k], 1, b, 1);
415 b[k] = (b[k] - t) / a[k][k];
420 for (k = n - 1; k >= 1; k--) {
421 b[k] = b[k] +
ddot(n - k, a[k] + k, 1, b + k, 1);
436 for (k = 1; k <= n - 1; k++) {
443 daxpy(n - k, t, a[k] + k, 1, b + k, 1);
448 for (k = n; k >= 1; k--) {
449 b[k] = b[k] / a[k][k];
451 daxpy(k - 1, t, a[k], 1, b, 1);
509 for (k = 1; k <= n - 1; k++) {
514 j =
idamax(n - k + 1, a[k] + k - 1, 1) + k - 1;
535 dscal(n - k, t, a[k] + k, 1);
539 for (i = k + 1; i <=
n; i++) {
545 daxpy(n - k, t, a[k] + k, 1, a[i] + k, 1);
586 #define max( a , b ) ( (a) > (b) ? (a) : (b) )
587 #define min( a , b ) ( (a) < (b) ? (a) : (b) )
589 #define ETA 2.2204460492503131e-16
591 static void stoda(
int neq,
double *y,
_lsoda_f f,
void *_data);
592 static void correction(
int neq,
double *y,
_lsoda_f f,
int *corflag,
double pnorm,
double *del,
double *delp,
double *told,
593 int *ncf,
double *rh,
int *m,
void *_data);
594 static void prja(
int neq,
double *y,
_lsoda_f f,
void *_data);
597 static void successreturn(
double *y,
double *t,
int itask,
int ihit,
double tcrit,
int *istate);
600 static void ewset(
int itol,
double *rtol,
double *atol,
double *ycur);
602 static void solsy(
double *y);
604 static void orderswitch(
double *rhup,
double dsm,
double *pdh,
double *rh,
int *orderflag);
605 static void intdy(
double t,
int k,
double *dky,
int *iflag);
606 static void corfailure(
double *told,
double *rh,
int *ncf,
int *corflag);
607 static void methodswitch(
double dsm,
double pnorm,
double *pdh,
double *rh);
609 static void scaleh(
double *rh,
double *pdh);
610 static double fnorm(
int n,
double **a,
double *w);
611 static double vmnorm(
int n,
double *v,
double *w);
618 static int mord[3] = {0, 12, 5};
620 static double sm1[13] = {0., 0.5, 0.575, 0.55, 0.45, 0.35, 0.25, 0.2, 0.15, 0.1, 0.075, 0.05, 0.025};
625 static int illin = 0,
init = 0,
mxstep,
mxhnil,
nhnil,
ntrep = 0,
nslast,
nyh,
ierpj,
iersl,
626 jcur,
jstart,
kflag,
l,
meth,
miter,
maxord,
maxcor,
msbp,
mxncf,
n,
nq,
nst,
667 fprintf(stderr,
"[lsoda] repeated occurrence of illegal input. run aborted.. apparent infinite loop\n");
680 for (i = 1; i <=
n; i++)
696 static void successreturn(
double *y,
double *t,
int itask,
int ihit,
double tcrit,
int *istate)
700 for (i = 1; i <=
n; i++)
703 if (itask == 4 || itask == 5)
831 void lsoda(
_lsoda_f f,
int neq,
double *y,
double *t,
double tout,
int itol,
double *rtol,
double *atol,
832 int itask,
int *istate,
int iopt,
int jt,
833 int iwork1,
int iwork2,
int iwork5,
int iwork6,
int iwork7,
int iwork8,
int iwork9,
834 double rwork1,
double rwork5,
double rwork6,
double rwork7,
void *_data)
868 int mxstp0 = 500, mxhnl0 = 10;
870 int i, iflag, lenyh, ihit;
871 double atoli, ayi, big, h0, hmax, hmx, rh, rtoli, tcrit, tdist, tnext, tol,
872 tolsf, tp, size, sum, w0;
885 if (*istate < 1 || *istate > 3) {
886 fprintf(stderr,
"[lsoda] illegal istate = %d\n", *istate);
890 if (itask < 1 || itask > 5) {
891 fprintf(stderr,
"[lsoda] illegal itask = %d\n", itask);
895 if (
init == 0 && (*istate == 2 || *istate == 3)) {
896 fprintf(stderr,
"[lsoda] istate > 1 but lsoda not initialized\n");
904 if (
ntrep < 5)
return;
905 fprintf(stderr,
"[lsoda] repeated calls with istate = 1 and tout = t. run aborted.. apparent infinite loop\n");
919 if (*istate == 1 || *istate == 3) {
922 fprintf(stderr,
"[lsoda] neq = %d is less than 1\n", neq);
926 if (*istate == 3 && neq >
n) {
927 fprintf(stderr,
"[lsoda] istate = 3 and neq increased\n");
932 if (itol < 1 || itol > 4) {
933 fprintf(stderr,
"[lsoda] itol = %d illegal\n", itol);
937 if (iopt < 0 || iopt > 1) {
938 fprintf(stderr,
"[lsoda] iopt = %d illegal\n", iopt);
942 if (jt == 3 || jt < 1 || jt > 5) {
943 fprintf(stderr,
"[lsoda] jt = %d illegal\n", jt);
951 if (ml < 0 || ml >=
n) {
952 fprintf(stderr,
"[lsoda] ml = %d not between 1 and neq\n",
ml);
956 if (mu < 0 || mu >=
n) {
957 fprintf(stderr,
"[lsoda] mu = %d not between 1 and neq\n",
mu);
982 if (ixpr < 0 || ixpr > 1) {
983 fprintf(stderr,
"[lsoda] ixpr = %d is illegal\n",
ixpr);
989 fprintf(stderr,
"[lsoda] mxstep < 0\n");
996 fprintf(stderr,
"[lsoda] mxhnil < 0\n");
1004 fprintf(stderr,
"[lsoda] mxordn = %d is less than 0\n",
mxordn);
1012 fprintf(stderr,
"[lsoda] mxords = %d is less than 0\n",
mxords);
1018 if ((tout - *t) * h0 < 0.) {
1019 fprintf(stderr,
"[lsoda] tout = %g behind t = %g. integration direction is given by %g\n",
1027 fprintf(stderr,
"[lsoda] hmax < 0.\n");
1036 fprintf(stderr,
"[lsoda] hmin < 0.\n");
1057 yh = (
double **) calloc(1 + lenyh,
sizeof(*
yh));
1059 printf(
"lsoda -- insufficient memory for your problem\n");
1063 for (i = 1; i <= lenyh; i++)
1064 yh[i] = (
double *) calloc(1 +
nyh,
sizeof(
double));
1066 wm = (
double **) calloc(1 +
nyh,
sizeof(*
wm));
1069 printf(
"lsoda -- insufficient memory for your problem\n");
1073 for (i = 1; i <=
nyh; i++)
1074 wm[i] = (
double *) calloc(1 +
nyh,
sizeof(
double));
1076 ewt = (
double *) calloc(1 +
nyh,
sizeof(
double));
1080 printf(
"lsoda -- insufficient memory for your problem\n");
1084 savf = (
double *) calloc(1 +
nyh,
sizeof(
double));
1089 printf(
"lsoda -- insufficient memory for your problem\n");
1093 acor = (
double *) calloc(1 +
nyh,
sizeof(
double));
1099 printf(
"lsoda -- insufficient memory for your problem\n");
1103 ipvt = (
int *) calloc(1 +
nyh,
sizeof(
int));
1110 printf(
"lsoda -- insufficient memory for your problem\n");
1118 if (*istate == 1 || *istate == 3) {
1121 for (i = 1; i <=
n; i++) {
1124 if (itol == 2 || itol == 4)
1127 fprintf(stderr,
"[lsoda] rtol = %g is less than 0.\n", rtoli);
1133 fprintf(stderr,
"[lsoda] atol = %g is less than 0.\n", atoli);
1157 if (itask == 4 || itask == 5) {
1159 if ((tcrit - tout) * (tout - *t) < 0.) {
1160 fprintf(stderr,
"[lsoda] itask = 4 or 5 and tcrit behind tout\n");
1165 if (h0 != 0. && (*t + h0 - tcrit) * h0 > 0.)
1184 (*f) (*t, y + 1,
yh[2] + 1, _data);
1190 for (i = 1; i <=
n; i++)
1197 ewset(itol, rtol, atol, y);
1198 for (i = 1; i <=
n; i++) {
1200 fprintf(stderr,
"[lsoda] ewt[%d] = %g <= 0.\n", i,
ewt[i]);
1228 tdist = fabs(tout - *t);
1229 w0 =
max(fabs(*t), fabs(tout));
1230 if (tdist < 2. *
ETA * w0) {
1231 fprintf(stderr,
"[lsoda] tout too close to t to start integration\n ");
1238 for (i = 2; i <=
n; i++)
1239 tol =
max(tol, rtol[i]);
1243 for (i = 1; i <=
n; i++) {
1244 if (itol == 2 || itol == 4)
1248 tol =
max(tol, atoli / ayi);
1251 tol =
max(tol, 100. *
ETA);
1252 tol =
min(tol, 0.001);
1254 sum = 1. / (tol * w0 * w0) + tol * sum * sum;
1255 h0 = 1. / sqrt(sum);
1256 h0 =
min(h0, tdist);
1257 h0 = h0 * ((tout - *t >= 0.) ? 1. : -1.);
1262 rh = fabs(h0) *
hmxi;
1270 for (i = 1; i <=
n; i++)
1278 if (*istate == 2 || *istate == 3) {
1282 if ((
tn - tout) *
h >= 0.) {
1283 intdy(tout, 0, y, &iflag);
1285 fprintf(stderr,
"[lsoda] trouble from intdy, itask = %d, tout = %g\n", itask, tout);
1300 tp =
tn -
hu * (1. + 100. *
ETA);
1301 if ((tp - tout) *
h > 0.) {
1302 fprintf(stderr,
"[lsoda] itask = %d and tout behind tcur - hu\n", itask);
1307 if ((
tn - tout) *
h < 0.)
break;
1312 if ((
tn - tcrit) *
h > 0.) {
1313 fprintf(stderr,
"[lsoda] itask = 4 or 5 and tcrit behind tcur\n");
1318 if ((tcrit - tout) *
h < 0.) {
1319 fprintf(stderr,
"[lsoda] itask = 4 or 5 and tcrit behind tout\n");
1324 if ((
tn - tout) *
h >= 0.) {
1325 intdy(tout, 0, y, &iflag);
1327 fprintf(stderr,
"[lsoda] trouble from intdy, itask = %d, tout = %g\n", itask, tout);
1341 if ((
tn - tcrit) *
h > 0.) {
1342 fprintf(stderr,
"[lsoda] itask = 4 or 5 and tcrit behind tcur\n");
1348 hmx = fabs(
tn) + fabs(
h);
1349 ihit = fabs(
tn - tcrit) <= (100. *
ETA * hmx);
1355 tnext =
tn +
h * (1. + 4. *
ETA);
1356 if ((tnext - tcrit) *
h <= 0.)
1358 h = (tcrit -
tn) * (1. - 4. *
ETA);
1376 if (*istate != 1 ||
nst != 0) {
1378 fprintf(stderr,
"[lsoda] %d steps taken before reaching tout\n",
mxstep);
1383 ewset(itol, rtol, atol,
yh[1]);
1384 for (i = 1; i <=
n; i++) {
1386 fprintf(stderr,
"[lsoda] ewt[%d] = %g <= 0.\n", i,
ewt[i]);
1396 tolsf = tolsf * 200.;
1398 fprintf(stderr,
"lsoda -- at start of problem, too much accuracy\n");
1399 fprintf(stderr,
" requested for precision of machine,\n");
1400 fprintf(stderr,
" suggested scaling factor = %g\n", tolsf);
1405 fprintf(stderr,
"lsoda -- at t = %g, too much accuracy requested\n", *t);
1406 fprintf(stderr,
" for precision of machine, suggested\n");
1407 fprintf(stderr,
" scaling factor = %g\n", tolsf);
1412 if ((
tn +
h) ==
tn) {
1415 fprintf(stderr,
"lsoda -- warning..internal t = %g and h = %g are\n",
tn,
h);
1416 fprintf(stderr,
" such that in the machine, t + h = t on the next step\n");
1417 fprintf(stderr,
" solver will continue anyway.\n");
1419 fprintf(stderr,
"lsoda -- above warning has been issued %d times,\n",
nhnil);
1420 fprintf(stderr,
" it will not be issued again for this problem\n");
1427 stoda(neq, y, f, _data);
1456 fprintf(stderr,
"[lsoda] a switch to the stiff method has occurred ");
1458 fprintf(stderr,
"[lsoda] a switch to the nonstiff method has occurred");
1459 fprintf(stderr,
"at t = %g, tentative step size h = %g, step nst = %d\n",
tn,
h,
nst);
1467 if ((
tn - tout) *
h < 0.)
1469 intdy(tout, 0, y, &iflag);
1488 if ((
tn - tout) *
h >= 0.) {
1499 if ((
tn - tout) *
h >= 0.) {
1500 intdy(tout, 0, y, &iflag);
1507 hmx = fabs(
tn) + fabs(
h);
1508 ihit = fabs(
tn - tcrit) <= (100. *
ETA * hmx);
1513 tnext =
tn +
h * (1. + 4. *
ETA);
1514 if ((tnext - tcrit) *
h <= 0.)
1516 h = (tcrit -
tn) * (1. - 4. *
ETA);
1526 hmx = fabs(
tn) + fabs(
h);
1527 ihit = fabs(
tn - tcrit) <= (100. *
ETA * hmx);
1537 fprintf(stderr,
"lsoda -- at t = %g and step size h = %g, the\n",
tn,
h);
1539 fprintf(stderr,
" error test failed repeatedly or\n");
1540 fprintf(stderr,
" with fabs(h) = hmin\n");
1544 fprintf(stderr,
" corrector convergence failed repeatedly or\n");
1545 fprintf(stderr,
" with fabs(h) = hmin\n");
1550 for (i = 1; i <=
n; i++) {
1551 size = fabs(
acor[i]) *
ewt[i];
1567 int corflag, orderflag;
1568 int i, i1, j, m, ncf;
1569 double del, delp, dsm, dup, exup, r, rh, rhup, told;
1641 for (i = 1; i <= 5; i++)
1644 for (i = 1; i <= 12; i++)
1698 for (j =
nq; j >= 1; j--)
1699 for (i1 = j; i1 <=
nq; i1++) {
1702 for (i = 1; i <=
n; i++)
1707 correction(neq, y, f, &corflag, pnorm, &del, &delp, &told, &ncf, &rh, &m, _data);
1751 for (j = 1; j <=
l; j++) {
1754 for (i = 1; i <=
n; i++)
1776 for (i = 1; i <=
n; i++)
1779 exup = 1. / (double) (
l + 1);
1780 rhup = 1. / (1.4 * pow(dup, exup) + 0.0000014);
1786 if (orderflag == 0) {
1793 if (orderflag == 1) {
1803 if (orderflag == 2) {
1817 for (i = 1; i <=
n; i++)
1833 for (j =
nq; j >= 1; j--)
1834 for (i1 = j; i1 <=
nq; i1++) {
1837 for (i = 1; i <=
n; i++)
1841 if (fabs(
h) <=
hmin * 1.00001) {
1850 if (orderflag == 1 || orderflag == 0) {
1856 if (orderflag == 2) {
1884 for (i = 1; i <=
n; i++)
1886 (*f) (
tn, y + 1,
savf + 1, _data);
1889 for (i = 1; i <=
n; i++)
1890 yp1[i] =
h * savf[i];
1906 static void ewset(
int itol,
double *rtol,
double *atol,
double *ycur)
1912 for (i = 1; i <=
n; i++)
1913 ewt[i] = rtol[1] * fabs(ycur[i]) + atol[1];
1916 for (i = 1; i <=
n; i++)
1917 ewt[i] = rtol[1] * fabs(ycur[i]) + atol[i];
1920 for (i = 1; i <=
n; i++)
1921 ewt[i] = rtol[i] * fabs(ycur[i]) + atol[1];
1924 for (i = 1; i <=
n; i++)
1925 ewt[i] = rtol[i] * fabs(ycur[i]) + atol[i];
1931 static void intdy(
double t,
int k,
double *dky,
int *iflag)
1957 int i, ic, j, jj, jp1;
1961 if (k < 0 || k >
nq) {
1962 fprintf(stderr,
"[intdy] k = %d illegal\n", k);
1967 if ((t - tp) * (t -
tn) > 0.) {
1968 fprintf(stderr,
"intdy -- t = %g illegal. t not in interval tcur - hu to tcur\n", t);
1974 for (jj =
l - k; jj <=
nq; jj++)
1978 for (i = 1; i <=
n; i++)
1979 dky[i] = c *
yp1[i];
1980 for (j = nq - 1; j >= k; j--) {
1983 for (jj = jp1 - k; jj <= j; jj++)
1987 for (i = 1; i <=
n; i++)
1988 dky[i] = c *
yp1[i] + s * dky[i];
1992 r = pow(
h, (
double) (-k));
1993 for (i = 1; i <=
n; i++)
2000 int i,
nq, nqm1, nqp1;
2001 double agamq, fnq, fnqm1, pc[13], pint, ragq, rqfac, rq1fac, tsign, xpin;
2043 for (nq = 2; nq <= 12; nq++) {
2052 rqfac = rqfac / (double) nq;
2054 fnqm1 = (double) nqm1;
2060 for (i = nq; i >= 2; i--)
2061 pc[i] = pc[i - 1] + fnqm1 * pc[i];
2062 pc[1] = fnqm1 * pc[1];
2069 for (i = 2; i <=
nq; i++) {
2071 pint += tsign * pc[i] / (double) i;
2072 xpin += tsign * pc[i] / (double) (i + 1);
2077 elco[
nq][1] = pint * rq1fac;
2079 for (i = 2; i <=
nq; i++)
2080 elco[nq][i + 1] = rq1fac * pc[i] / (
double) i;
2081 agamq = rqfac * xpin;
2085 tesco[nqp1][1] = ragq * rqfac / (double) nqp1;
2086 tesco[nqm1][3] = ragq;
2102 for (nq = 1; nq <= 5; nq++) {
2109 for (i = nq + 1; i >= 2; i--)
2110 pc[i] = pc[i - 1] + fnq * pc[i];
2115 for (i = 1; i <= nqp1; i++)
2116 elco[nq][i] = pc[i] / pc[2];
2138 *rh = *rh /
max(1., fabs(
h) *
hmxi * *rh);
2147 if ((*rh * *pdh * 1.00001) >=
sm1[
nq]) {
2148 *rh =
sm1[
nq] / *pdh;
2153 for (j = 2; j <=
l; j++) {
2156 for (i = 1; i <=
n; i++)
2169 double fac, hl0, r, r0, yj;
2189 fprintf(stderr,
"[prja] miter != 2\n");
2194 r0 = 1000. * fabs(
h) *
ETA * ((double)
n) * fac;
2197 for (j = 1; j <=
n; j++) {
2202 (*f) (
tn, y + 1,
acor + 1, _data);
2203 for (i = 1; i <=
n; i++)
2204 wm[i][j] = (acor[i] -
savf[i]) * fac;
2215 for (i = 1; i <=
n; i++)
2242 for (i = 1; i <=
n; i++)
2243 vm =
max(vm, fabs(v[i]) * w[i]);
2248 static double fnorm(
int n,
double **a,
double *w)
2260 double an, sum, *ap1;
2263 for (i = 1; i <=
n; i++) {
2266 for (j = 1; j <=
n; j++)
2267 sum += fabs(ap1[j]) / w[j];
2268 an =
max(an, sum * w[i]);
2274 static void correction(
int neq,
double *y,
_lsoda_f f,
int *corflag,
double pnorm,
double *del,
double *delp,
double *told,
2275 int *ncf,
double *rh,
int *m,
void *_data)
2284 double rm, rate, dcon;
2298 for (i = 1; i <=
n; i++)
2300 (*f) (
tn, y + 1,
savf + 1, _data);
2310 prja(neq, y, f, _data);
2320 for (i = 1; i <=
n; i++)
2329 for (i = 1; i <=
n; i++) {
2330 savf[i] =
h * savf[i] -
yp1[i];
2331 y[i] = savf[i] -
acor[i];
2335 for (i = 1; i <=
n; i++) {
2336 y[i] =
yp1[i] +
el[1] * savf[i];
2348 for (i = 1; i <=
n; i++)
2349 y[i] =
h * savf[i] - (
yp1[i] +
acor[i]);
2353 for (i = 1; i <=
n; i++) {
2370 if (*del <= 100. * pnorm *
ETA)
2372 if (*m != 0 ||
meth != 1) {
2375 if (*del <= (1024. * *delp))
2377 rate =
max(rate, rm);
2396 if (*m ==
maxcor || (*m >= 2 && *del > 2. * *delp)) {
2409 for (i = 1; i <=
n; i++)
2411 (*f) (
tn, y + 1, savf + 1, _data);
2419 (*f) (
tn, y + 1, savf + 1, _data);
2425 static void corfailure(
double *told,
double *rh,
int *ncf,
int *corflag)
2432 for (j =
nq; j >= 1; j--)
2433 for (i1 = j; i1 <=
nq; i1++) {
2436 for (i = 1; i <=
n; i++)
2439 if (fabs(
h) <=
hmin * 1.00001 || *ncf ==
mxncf) {
2464 printf(
"solsy -- miter != 2\n");
2473 static void methodswitch(
double dsm,
double pnorm,
double *pdh,
double *rh)
2475 int lm1, lm1p1, lm2, lm2p1, nqm1, nqm2;
2476 double rh1, rh2, rh1it, exm2, dm2, exm1, dm1, alpha, exsm;
2499 if (dsm <= (100. * pnorm *
ETA) ||
pdest == 0.) {
2505 exsm = 1. / (double)
l;
2506 rh1 = 1. / (1.2 * pow(dsm, exsm) + 0.0000012);
2509 if ((*pdh * rh1) > 0.00001)
2510 rh1it =
sm1[
nq] / *pdh;
2511 rh1 =
min(rh1, rh1it);
2515 exm2 = 1. / (double) lm2;
2518 rh2 = 1. / (1.2 * pow(dm2, exm2) + 0.0000012);
2521 rh2 = 1. / (1.2 * pow(dm2, exsm) + 0.0000012);
2524 if (rh2 <
ratio * rh1)
2549 exsm = 1. / (double)
l;
2553 exm1 = 1. / (double) lm1;
2556 rh1 = 1. / (1.2 * pow(dm1, exm1) + 0.0000012);
2559 rh1 = 1. / (1.2 * pow(dm1, exsm) + 0.0000012);
2565 if ((*pdh * rh1) > 0.00001)
2566 rh1it =
sm1[nqm1] / *pdh;
2567 rh1 =
min(rh1, rh1it);
2568 rh2 = 1. / (1.2 * pow(dsm, exsm) + 0.0000012);
2569 if ((rh1 *
ratio) < (5. * rh2))
2571 alpha =
max(0.001, rh1);
2572 dm1 *= pow(alpha, exm1);
2573 if (dm1 <= 1000. *
ETA * pnorm)
2599 for (i = 1; i <=
n; i++)
2606 static void orderswitch(
double *rhup,
double dsm,
double *pdh,
double *rh,
int *orderflag)
2624 double exsm, rhdn, rhsm, ddn, exdn, r;
2628 exsm = 1. / (double)
l;
2629 rhsm = 1. / (1.2 * pow(dsm, exsm) + 0.0000012);
2634 exdn = 1. / (double)
nq;
2635 rhdn = 1. / (1.3 * pow(ddn, exdn) + 0.0000013);
2643 *rhup =
min(*rhup,
sm1[
l] / *pdh);
2646 rhdn =
min(rhdn,
sm1[
nq - 1] / *pdh);
2649 if (rhsm >= *rhup) {
2656 if (kflag < 0 && *rh > 1.)
2660 if (*rhup <= rhdn) {
2663 if (kflag < 0 && *rh > 1.)
2668 r =
el[
l] / (double)
l;
2672 for (i = 1; i <=
n; i++)
2686 if ((*rh * *pdh * 1.00001) <
sm1[newq])
2687 if (
kflag == 0 && *rh < 1.1) {
2692 if (
kflag == 0 && *rh < 1.1) {
2698 *rh =
min(*rh, 0.2);
2725 for (i = 1; i <=
l; i++)
2729 conit = 0.5 / (double) (
nq + 2);
2741 if (
wm)
for (i = 1; i <=
g_nyh; ++i) free(
wm[i]);
2742 if (
yh)
for (i = 1; i <=
g_lenyh; ++i) free(
yh[i]);
2753 int n_lsoda(
double y[],
int n,
double *x,
double xout,
double eps,
const double yscal[],
_lsoda_f devis,
void *
data)
2755 int i, istate, itask;
2756 double *_y, *atol, *rtol;
2757 _y = (
double *) calloc(3 * (n + 1),
sizeof(double));
2759 rtol = atol + n + 1;
2760 for (i = 1; i <=
n; ++i) {
2762 atol[i] = eps * yscal[i - 1];
2764 istate =
init? 2 : 1;
2766 lsoda(devis, n, _y, x, xout, 2, rtol, atol, itask, &istate, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0., 0., 0., 0., data);
2767 for (i = 1; i <=
n; ++i) y[i - 1] = _y[i];
2769 return istate < 0 ? istate : 0;
2783 static void fex(
double t,
double *y,
double *ydot,
void *
data)
2785 ydot[0] = 1.0E4 * y[1] * y[2] - .04E0 * y[0];
2786 ydot[2] = 3.0E7 * y[1] * y[1];
2787 ydot[1] = -1.0 * (ydot[0] + ydot[2]);
2792 double rwork1, rwork5, rwork6, rwork7;
2793 double atol[4], rtol[4], t, tout, y[4];
2794 int iwork1, iwork2, iwork5, iwork6, iwork7, iwork8, iwork9;
2796 int itol, itask, istate, iopt, jt, iout;
2798 iwork1 = iwork2 = iwork5 = iwork6 = iwork7 = iwork8 = iwork9 = 0;
2799 rwork1 = rwork5 = rwork6 = rwork7 = 0.0;
2808 rtol[1] = rtol[3] = 1.0E-4;
2818 for (iout = 1; iout <= 12; iout++) {
2819 lsoda(fex, neq, y, &t, tout, itol, rtol, atol, itask, &istate, iopt, jt,
2820 iwork1, iwork2, iwork5, iwork6, iwork7, iwork8, iwork9,
2821 rwork1, rwork5, rwork6, rwork7, 0);
2822 printf(
" at t= %12.4e y= %14.6e %14.6e %14.6e\n", t, y[1], y[2], y[3]);
2824 printf(
"error istate = %d\n", istate);
2827 tout = tout * 10.0E0;