00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef O2SCL_ODE_IV_SOLVE_H
00024 #define O2SCL_ODE_IV_SOLVE_H
00025
00026 #include <string>
00027 #include <o2scl/collection.h>
00028 #include <o2scl/adapt_step.h>
00029 #include <o2scl/gsl_astep.h>
00030
00031 #ifndef DOXYGENP
00032 namespace o2scl {
00033 #endif
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 template<class param_t, class func_t, class vec_t=ovector_view,
00047 class alloc_vec_t=ovector, class alloc_t=ovector_alloc,
00048 class adapt_step=gsl_astep<param_t,func_t,vec_t,alloc_vec_t,alloc_t> >
00049 class ode_iv_solve
00050
00051 {
00052 public:
00053
00054 ode_iv_solve() {
00055 verbose=0;
00056 }
00057
00058 virtual ~ode_iv_solve() {}
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 template<class mat_t>
00070 int solve_table(double x0, double x1, double h, size_t n,
00071 vec_t &ystart, size_t &nsol, vec_t &xsol,
00072 mat_t &ysol, param_t &pa, func_t &derivs)
00073 {
00074 int ret=0, nmax=nsol, i;
00075 size_t j;
00076
00077 xsol[0]=x0;
00078 for(j=0;j<n;j++) ysol[0][j]=ystart[j];
00079 if (verbose>0) print_iter(xsol[0],n,ystart);
00080
00081 for(i=1;i<nmax && xsol[i-1]<x1 && ret==0;i++) {
00082
00083 xsol[i]=xsol[i-1];
00084 for(j=0;j<n;j++) ysol[i][j]=ysol[i-1][j];
00085
00086 omatrix_row ar(ysol,i);
00087 ret=astepper.astep(xsol[i],h,x1,n,ar,pa,derivs);
00088
00089 if (verbose>0) print_iter(xsol[i],n,ar);
00090 }
00091
00092 nsol=i;
00093
00094 if (ret!=0) return ret;
00095
00096 if (i==nmax && xsol[i-1]<x1) {
00097 set_err("Ran out of space in ode_iv_solve::solve_table().",
00098 gsl_etable);
00099 return gsl_etable;
00100 }
00101 return 0;
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 template<class mat_t>
00115 int solve_grid(double x0, double x1, double h, size_t n,
00116 vec_t &ystart, size_t nsol, vec_t &xsol, mat_t &ysol,
00117 param_t &pa, func_t &derivs)
00118 {
00119 double x=x0, xnext;
00120 int ret=0;
00121 size_t j;
00122
00123 xsol[0]=x0;
00124 for(j=0;j<n;j++) ysol[0][j]=ystart[j];
00125 if (verbose>0) print_iter(xsol[0],n,ystart);
00126
00127 for(size_t i=1;i<nsol && ret==0;i++) {
00128
00129 xsol[i]=xsol[i-1];
00130 for(j=0;j<n;j++) ysol[i][j]=ysol[i-1][j];
00131
00132 xnext=x0+(x1-x0)*((double)i)/((double)(nsol-1));
00133
00134 while(xsol[i]<xnext && ret==0) {
00135 omatrix_row ar(ysol,i);
00136 ret=astepper.astep(xsol[i],h,xnext,n,ar,pa,derivs);
00137 if (verbose>0) print_iter(xsol[i],n,ar);
00138 }
00139
00140 }
00141 if (ret!=0) return ret;
00142 return 0;
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152 int solve_final_value(double x0, double x1, double h, size_t n,
00153 vec_t &ystart, vec_t ¥d,
00154 param_t &pa, func_t &derivs)
00155 {
00156 double x=x0;
00157 int ret=0;
00158 if (verbose>0) print_iter(x0,n,ystart);
00159
00160 for(size_t i=0;i<n;i++) yend[i]=ystart[i];
00161
00162 while(x<x1 && ret==0) {
00163
00164 ret=astepper.astep(x,h,x1,n,yend,pa,derivs);
00165
00166 if (verbose>0) print_iter(x,n,yend);
00167 }
00168
00169 if (ret!=0) return ret;
00170 return 0;
00171 }
00172
00173
00174 int verbose;
00175
00176
00177 adapt_step astepper;
00178
00179 #ifndef DOXYGEN_INTERNAL
00180
00181 protected:
00182
00183
00184 virtual int print_iter(double x, size_t nv, vec_t &y) {
00185 std::cout << x << " ";
00186 for(size_t i=0;i<nv;i++) std::cout << y[i] << " ";
00187 std::cout << std::endl;
00188 if (verbose>1) {
00189 char ch;
00190 std::cin >> ch;
00191 }
00192 return 0;
00193 }
00194
00195 #endif
00196
00197 };
00198
00199 #ifndef DOXYGENP
00200 }
00201 #endif
00202
00203 #endif