23 #ifndef O2SCL_ODE_BV_SOLVE_H 24 #define O2SCL_ODE_BV_SOLVE_H 31 #include <o2scl/astep.h> 32 #include <o2scl/astep_gsl.h> 33 #include <o2scl/ode_iv_solve.h> 34 #include <o2scl/mroot_hybrids.h> 36 #ifndef DOXYGEN_NO_O2NS 57 static const int unk=0;
125 vec_t &ystart, vec_t ¥d, vec_int_t &index,
126 vec_t &yerr, vec_t &dydx_end, func_t &derivs) {
129 this->l_index=&index;
130 this->l_ystart=&ystart;
133 this->l_dydx_end=&dydx_end;
137 this->l_derivs=&derivs;
142 int lhs_unks=0, rhs_conts=0;
145 for (
size_t i=0;i<n;i++) {
146 if (index[i]<2) lhs_unks++;
147 if (index[i]%2==1) rhs_conts++;
151 if (lhs_unks!=rhs_conts) {
152 O2SCL_ERR2(
"Incorrect boundary conditions in ",
153 "ode_bv_shoot::solve()",gsl_einval);
157 ubvector tx(lhs_unks);
161 for (
size_t i=0;i<n;i++) {
171 mm_funct_mfptr<ode_bv_shoot<func_t,vec_t,vec_int_t> >
175 int ret=this->mrootp->msolve(lhs_unks,tx,mfm);
177 O2SCL_ERR(
"Solver failed in ode_bv_shoot::solve().",ret);
182 for (
size_t i=0;i<n;i++) {
195 template<
class mat_t,
class mat_row_t>
197 vec_t &ystart, vec_t ¥d,
198 vec_int_t &index,
size_t &n_sol, vec_t &x_sol,
199 mat_t &y_sol, mat_t &yerr_sol, mat_t &dydx_sol,
202 mat_row_t yerr(yerr_sol,0);
203 mat_row_t dydx_end(dydx_sol,0);
206 solve_final_value(x0,x1,h,n,ystart,yend,index,yerr,dydx_end,derivs);
209 for(
size_t i=0;i<n;i++) {
210 y_sol[0][i]=ystart[i];
214 oisp->solve_store<mat_t,mat_row_t>(this->l_x0,this->l_x1,this->l_h,
215 this->l_n,n_sol,x_sol,
216 y_sol,yerr_sol,dydx_sol,derivs);
219 for (
size_t i=0;i<n;i++) {
221 yend[i]=y_sol[n_sol-1][i];
223 ystart[i]=y_sol[0][i];
248 #ifndef DOXYGEN_INTERNAL 290 vec_t sy, sy2, syerr, sdydx;
304 for(
size_t i=0;i<this->l_n;i++) {
305 if ((*this->l_index)[i]<2) {
309 sy[i]=(*this->l_ystart)[i];
317 this->l_n,sy,sy2,*this->l_yerr,
318 *this->l_dydx_end,*this->l_derivs);
321 for(
size_t i=0;i<this->l_n;i++) {
322 if ((*this->l_index)[i]%2==1) {
324 if ((*this->l_yend)[i]==0.0) {
327 ty[j]=(sy2[i]-(*this->l_yend)[i])/(*this->l_yend)[i];
332 (*this->l_yend)[i]=sy2[i];
353 template<
class mat_t=boost::numeric::ublas::matrix<
double>,
354 class mat_row_t=boost::numeric::ublas::matrix_row<
355 boost::numeric::ublas::matrix<
double> >,
356 class func_t=ode_funct<>,
357 class vec_t=boost::numeric::ublas::vector<
double>,
358 class vec_
int_t=boost::numeric::ublas::vector<
int> >
376 vec_t &ystart, vec_t ¥d, vec_int_t &index,
377 size_t nsol, vec_t &xsol, mat_t &ysol,
378 mat_t &err_sol, mat_t &dydx_sol, func_t &derivs) {
382 int lhs_unks=0, rhs_conts=0;
385 for (
size_t i=0;i<n;i++) {
386 if (index[i]<2) lhs_unks++;
387 if (index[i]%2==1) rhs_conts++;
391 if (lhs_unks!=rhs_conts) {
392 O2SCL_ERR2(
"Incorrect boundary conditions in ",
393 "ode_bv_shoot_grid::solve_grid()",gsl_einval);
398 this->l_index=&index;
399 this->l_derivs=&derivs;
400 this->l_ystart=&ystart;
410 ubvector tx(lhs_unks);
414 for (
size_t i=0;i<n;i++) {
426 func_t,vec_t,vec_int_t> >
428 vec_int_t>::solve_grid_fun);
431 int ret=this->mrootp->msolve(lhs_unks,tx,mfm);
433 O2SCL_ERR(
"Solver failed in ode_bv_shoot_grid::solve_grid().",ret);
438 for (
size_t i=0;i<n;i++) {
448 #ifndef DOXYGEN_INTERNAL 475 for(
size_t i=0;i<this->l_n;i++) {
476 if ((*this->l_index)[i]<2) {
477 (*l_ysol)[0][i]=tx[j];
483 this->oisp->template solve_grid<mat_t,mat_row_t>
484 (this->l_h,this->l_n,l_nsol,*l_xsol,*l_ysol,*l_errsol,
485 *l_dydxsol,*this->l_derivs);
488 mat_row_t yend2(*l_ysol,l_nsol-1);
491 for(
size_t i=0;i<this->l_n;i++) {
492 if ((*this->l_index)[i]%2==1) {
494 if ((*this->l_yend)[i]==0.0) {
497 ty[j]=((*this->l_yend)[i]-yend2[i])/(*this->l_yend)[i];
510 #ifndef DOXYGEN_NO_O2NS static const int right
Known on the right boundary.
int set_mroot(mroot< mm_funct<> > &root)
Set the equation solver.
double l_h
Storage for the stepsize.
Solve an initial-value ODE problems given an adaptive ODE stepper.
gsl_mroot_hybrids< mm_funct<> > def_mroot
The default equation solver.
The main O<span style='position: relative; top: 0.3em; font-size: 0.8em'>2</span>scl O$_2$scl names...
size_t mem_size
Size of recent allocation.
int solve_grid_fun(size_t nv, const vec_t &tx, vec_t &ty)
The shooting function to be solved by the multidimensional solver.
int solve_final_value(double x0, double x1, double h, size_t n, vec_t &ystart, vec_t ¥d, vec_int_t &index, vec_t &yerr, vec_t &dydx_end, func_t &derivs)
Solve the boundary-value problem and store the solution.
vec_int_t * l_index
The index defining the boundary conditions.
int verbose
Set output level.
static const int both
Known on both the left and right boundaries.
ode_iv_solve< func_t, vec_t > def_ois
The default initial value solver.
Multidimensional root-finding [abstract base].
Solve boundary-value ODE problems by shooting from one boundary to the other on a grid...
static const int left
Known on the left boundary.
vec_t * l_ystart
Storage for the starting vector.
func_t * l_derivs
The functions to integrate.
void allocate(size_t n)
Allocate internal storage.
Solve boundary-value ODE problems by shooting from one boundary to the other.
One-dimensional solver [abstract base].
vec_t * l_yend
Storage for the ending vector.
mroot< mm_funct<> > * mrootp
The equation solver.
int solve_final_value(double x0, double x1, double h, size_t n, vec_t &ystart, vec_t ¥d, func_t &derivs)
Solve the initial-value problem to get the final value.
#define O2SCL_ERR2(d, d2, n)
Set an error, two-string version.
int solve_grid(double x0, double x1, double h, size_t n, vec_t &ystart, vec_t ¥d, vec_int_t &index, size_t nsol, vec_t &xsol, mat_t &ysol, mat_t &err_sol, mat_t &dydx_sol, func_t &derivs)
Desc.
#define O2SCL_ERR(d, n)
Set an error with message d and code n.
int solve_fun(size_t nv, const vec_t &tx, vec_t &ty)
The shooting function to be solved by the multidimensional solver.
int set_iv(ode_iv_solve< func_t, vec_t > &ois)
Set initial value solver.
size_t l_n
The number of functions.
vec_t * l_yerr
Storage for the starting vector.
static const int unk
Unknown on both the left and right boundaries.
ode_iv_solve< func_t, vec_t > * oisp
The solver for the initial value problem.
double l_x1
Storage for the ending abcissa.
vec_t * l_dydx_end
Storage for the ending vector.
double l_x0
Storage for the starting point.
static const double x1[5]
Base class for boundary-value ODE solvers.
std::function< int(double, size_t, const boost::numeric::ublas::vector< double > &, boost::numeric::ublas::vector< double > &)> ode_funct11
Ordinary differential equation function.
int solve_store(double x0, double x1, double h, size_t n, vec_t &ystart, vec_t ¥d, vec_int_t &index, size_t &n_sol, vec_t &x_sol, mat_t &y_sol, mat_t &yerr_sol, mat_t &dydx_sol, func_t &derivs)
Solve the boundary-value problem and store the solution.