612 int mxstp0 = 500, mxhnl0 = 10;
614 int iflag = 0, lenyh = 0, ihit = 0;
616 double atoli = 0, ayi = 0, big = 0, h0 = 0, hmax = 0, hmx = 0, rh = 0, rtoli = 0,
617 tcrit = 0, tdist = 0, tnext = 0, tol = 0, tolsf = 0, tp = 0, size = 0, sum = 0,
629 if(*istate < 1 || *istate > 3) {
631 std::cerr <<
"[lsoda] illegal istate = " << *istate << std::endl;
635 if(itask < 1 || itask > 5) {
636 fprintf(stderr,
"[lsoda] illegal itask = %d\n", itask);
640 if(
init == 0 && (*istate == 2 || *istate == 3)) {
641 fprintf(stderr,
"[lsoda] istate > 1 but lsoda not initialized\n");
656 if(*istate == 1 || *istate == 3) {
659 std::cerr <<
"[lsoda] neq = " << neq <<
" is less than 1." << std::endl;
663 if(*istate == 3 && neq >
n) {
664 std::cerr <<
"[lsoda] istate = 3 and neq increased" << std::endl;
669 if(itol_ < 1 || itol_ > 4) {
670 std::cerr <<
"[lsoda] itol = " <<
itol_ <<
" illegal" << std::endl;
674 if(iopt < 0 || iopt > 1) {
675 std::cerr <<
"[lsoda] iopt = " << iopt <<
" illegal" << std::endl;
679 if(jt == 3 || jt < 1 || jt > 5) {
680 std::cerr <<
"[lsoda] jt = " << jt <<
" illegal" << std::endl;
689 std::cerr <<
"[lsoda] ml = " <<
ml <<
" not between 1 and neq" << std::endl;
694 std::cerr <<
"[lsoda] mu = " <<
mu <<
" not between 1 and neq" << std::endl;
720 std::cerr <<
"[lsoda] ixpr = " <<
ixpr <<
" is illegal" << std::endl;
746 if((tout - *t) * h0 < 0.) {
747 std::cerr <<
"[lsoda] tout = " << tout <<
" behind t = " << *t
748 <<
". integration direction is given by " << h0 << std::endl;
755 std::cerr <<
"[lsoda] hmax < 0." << std::endl;
765 std::cerr <<
"[lsoda] hmin < 0." << std::endl;
799 if(*istate == 1 || *istate == 3) {
802 for(
size_t i = 1; i <=
n; i++) {
808 fprintf(stderr,
"[lsoda] rtol = %g is less than 0.\n", rtoli);
813 fprintf(stderr,
"[lsoda] atol = %g is less than 0.\n", atoli);
835 if(itask == 4 || itask == 5) {
837 if((tcrit - tout) * (tout - *t) < 0.) {
838 fprintf(stderr,
"[lsoda] itask = 4 or 5 and tcrit behind tout\n");
842 if(h0 != 0. && (*t + h0 - tcrit) * h0 > 0.)
861 assert((
int)
yh_.size() == lenyh + 1);
862 assert(
yh_[0].size() ==
nyh + 1);
864 derivs(*t, ++y.begin(), ++
yh_[2].begin(), _data);
868 for(
size_t i = 1; i <=
n; i++)
875 for(
size_t i = 1; i <=
n; i++) {
877 std::cerr <<
"[lsoda] ewt[" << i <<
"] = " <<
ewt[i] <<
" <= 0.\n" << std::endl;
905 tdist = fabs(tout - *t);
906 w0 = std::max(fabs(*t), fabs(tout));
907 if(tdist < 2. *
ETA * w0) {
908 fprintf(stderr,
"[lsoda] tout too close to t to start integration\n ");
914 for(
size_t i = 2; i <=
n; i++)
915 tol = std::max(tol,
rtol_[i]);
919 for(
size_t i = 1; i <=
n; i++) {
924 tol = std::max(tol, atoli / ayi);
927 tol = std::max(tol, 100. *
ETA);
928 tol = std::min(tol, 0.001);
930 sum = 1. / (tol * w0 * w0) + tol * sum * sum;
932 h0 = std::min(h0, tdist);
933 h0 = h0 * ((tout - *t >= 0.) ? 1. : -1.);
938 rh = fabs(h0) *
hmxi;
946 for(
size_t i = 1; i <=
n; i++)
954 if(*istate == 2 || *istate == 3) {
958 if((
tn_ - tout) *
h_ >= 0.) {
959 intdy(tout, 0, y, &iflag);
962 "[lsoda] trouble from intdy, itask = %d, tout = %g\n", itask,
977 if((tp - tout) *
h_ > 0.) {
979 stderr,
"[lsoda] itask = %d and tout behind tcur - hu\n", itask);
983 if((
tn_ - tout) *
h_ < 0.)
989 if((
tn_ - tcrit) *
h_ > 0.) {
990 fprintf(stderr,
"[lsoda] itask = 4 or 5 and tcrit behind tcur\n");
994 if((tcrit - tout) *
h_ < 0.) {
995 fprintf(stderr,
"[lsoda] itask = 4 or 5 and tcrit behind tout\n");
999 if((
tn_ - tout) *
h_ >= 0.) {
1000 intdy(tout, 0, y, &iflag);
1003 "[lsoda] trouble from intdy, itask = %d, tout = %g\n", itask,
1011 after_step(*t, ++y.begin());
1018 if((
tn_ - tcrit) *
h_ > 0.) {
1019 fprintf(stderr,
"[lsoda] itask = 4 or 5 and tcrit behind tcur\n");
1024 hmx = fabs(
tn_) + fabs(
h_);
1025 ihit = fabs(
tn_ - tcrit) <= (100. *
ETA * hmx);
1028 successreturn(after_step, y, t, itask, ihit, tcrit, istate);
1031 tnext =
tn_ +
h_ * (1. + 4. *
ETA);
1032 if((tnext - tcrit) *
h_ <= 0.)
1034 h_ = (tcrit -
tn_) * (1. - 4. *
ETA);
1052 if(*istate != 1 ||
nst != 0) {
1054 std::cerr <<
"[lsoda] " <<
mxstep <<
" steps taken before reaching tout" 1062 for(
size_t i = 1; i <=
n; i++) {
1064 std::cerr <<
"[lsoda] ewt[" << i <<
"] = " <<
ewt[i] <<
" <= 0." << std::endl;
1074 tolsf = tolsf * 200.;
1076 fprintf(stderr,
"lsoda -- at start of problem, too much accuracy\n");
1077 fprintf(stderr,
" requested for precision of machine,\n");
1078 fprintf(stderr,
" suggested scaling factor = %g\n", tolsf);
1082 fprintf(stderr,
"lsoda -- at t = %g, too much accuracy requested\n", *t);
1083 fprintf(stderr,
" for precision of machine, suggested\n");
1084 fprintf(stderr,
" scaling factor = %g\n", tolsf);
1093 fprintf(stderr,
"lsoda -- warning..internal t = %g and h_ = %g are\n",
1096 " such that in the machine, t + h_ = t on the next step\n");
1097 fprintf(stderr,
" solver will continue anyway.\n");
1099 std::cerr <<
"lsoda -- above warning has been issued " <<
nhnil 1100 <<
" times, " << std::endl
1101 <<
" it will not be issued again for this problem" << std::endl;
1107 stoda(neq, y, derivs, _data);
1118 if (
tn_ < tout) after_step(
tn_, ++y.begin());
1129 std::cerr <<
"[lsoda] a switch to the stiff method has occurred " 1132 std::cerr <<
"[lsoda] a switch to the nonstiff method has occurred" 1141 if((
tn_ - tout) *
h_ < 0.)
1144 intdy(tout, 0, y, &iflag);
1148 after_step(*t, ++y.begin());
1155 successreturn(after_step, y, t, itask, ihit, tcrit, istate);
1163 if((
tn_ - tout) *
h_ >= 0.) {
1164 successreturn(after_step, y, t, itask, ihit, tcrit, istate);
1174 if((
tn_ - tout) *
h_ >= 0.) {
1175 intdy(tout, 0, y, &iflag);
1179 after_step(*t, ++y.begin());
1183 hmx = fabs(
tn_) + fabs(
h_);
1184 ihit = fabs(
tn_ - tcrit) <= (100. *
ETA * hmx);
1186 successreturn(after_step, y, t, itask, ihit, tcrit, istate);
1189 tnext =
tn_ +
h_ * (1. + 4. *
ETA);
1190 if((tnext - tcrit) *
h_ <= 0.)
1192 h_ = (tcrit -
tn_) * (1. - 4. *
ETA);
1202 hmx = fabs(
tn_) + fabs(
h_);
1203 ihit = fabs(
tn_ - tcrit) <= (100. *
ETA * hmx);
1204 successreturn(after_step, y, t, itask, ihit, tcrit, istate);
1214 fprintf(stderr,
"lsoda -- at t = %g and step size h_ = %g, the\n",
tn_,
h_);
1216 fprintf(stderr,
" error test failed repeatedly or\n");
1217 fprintf(stderr,
" with fabs(h_) = hmin\n");
1221 fprintf(stderr,
" corrector convergence failed repeatedly or\n");
1222 fprintf(stderr,
" with fabs(h_) = hmin\n");
1227 for(
size_t i = 1; i <=
n; i++) {
1228 size = fabs(
acor[i]) *
ewt[i];
void terminate(int *istate)
std::vector< std::vector< double > > yh_
void ewset(const std::vector< double > &ycur)
std::vector< double > ewt
double vmnorm(const size_t n, const std::vector< double > &v, const std::vector< double > &w)
void successreturn(AfterStep &after_step, std::vector< double > &y, double *t, int itask, int ihit, double tcrit, int *istate)
std::array< size_t, 3 > mord
void terminate2(std::vector< double > &y, double *t)
void intdy(double t, int k, std::vector< double > &dky, int *iflag)
std::vector< double > acor
void resize_system(int nyh, int lenyh)
std::vector< double > atol_
void stoda(const size_t neq, std::vector< double > &y, Functor &derivs, void *_data)
std::vector< double > rtol_