/* Author: G. Jungman * RCS: $Id: control.c,v 1.2 1999/08/20 06:24:27 jungman Exp $ */ #include #include #include #include #include "gsl_odeiv.h" static void data_free(void * data) { if(data != 0) free(data); } static int hadjust(void * data, size_t dim, unsigned int ord, const double y[], const double yerr[], const double yp[], double * h) { const double * d = (double *) data; const double eps_abs = d[0]; const double eps_rel = d[1]; const double a_y = d[2]; const double a_dydt = d[3]; const double S = 0.9; const double h_old = fabs(*h); double rmax = DBL_MIN; size_t i; for(i=0; i 1.1) { /* decrease step, no more than factor of 5 */ *h = h_old * S / pow(rmax, 1.0/ord); *h = GSL_MAX_DBL(0.2 * h_old, *h); return GSL_ODEIV_HADJ_DEC; } else if(rmax < 0.9) { /* increase step, no more than factor of 5 */ *h = h_old / S / pow(rmax, 1.0/(ord+1.0)); *h = GSL_MIN_DBL(5.0 * h_old, *h); return GSL_ODEIV_HADJ_INC; } else { /* no change */ return GSL_ODEIV_HADJ_NIL; } } gsl_odeiv_evolve_control * gsl_odeiv_evolve_control_standard_new( double eps_rel, double eps_abs, double a_y, double a_dydt) { gsl_odeiv_evolve_control * c = (gsl_odeiv_evolve_control *) malloc(sizeof(gsl_odeiv_evolve_control)); if(c != 0) { double * d; c->_data_size = 4 * sizeof(double); c->_data = malloc(c->_data_size); if(c->_data == 0) { free(c); return 0; } d = (double *) c->_data; d[0] = eps_abs; d[1] = eps_rel; d[2] = a_y; d[3] = a_dydt; c->_free = data_free; c->_hadjust = hadjust; } return c; } gsl_odeiv_evolve_control * gsl_odeiv_evolve_control_y_new(double eps_rel, double eps_abs) { return gsl_odeiv_evolve_control_standard_new(eps_rel, eps_abs, 1.0, 0.0); } gsl_odeiv_evolve_control * gsl_odeiv_evolve_control_yp_new(double eps_rel, double eps_abs) { return gsl_odeiv_evolve_control_standard_new(eps_rel, eps_abs, 0.0, 1.0); } void gsl_odeiv_evolve_control_free(gsl_odeiv_evolve_control * c) { if(c != 0) { if(c->_free != 0) c->_free(c->_data); free(c); } }