void Curve::getstepsize( void ) { minstepsize= 0; if( mapdesc->isConstantSampling() ) { // fixed number of samples per patch in each direction // maxrate is number of s samples per patch setstepsize( mapdesc->maxrate ); } else if( mapdesc->isDomainSampling() ) { // maxrate is number of s samples per unit s length of domain setstepsize( mapdesc->maxrate * range[2] ); } else { // upper bound on path length between sample points assert( order <= MAXORDER ); /* points have been transformed, therefore they are homogeneous */ REAL tmp[MAXORDER][MAXCOORDS]; const int tstride = sizeof(tmp[0]) / sizeof(REAL); int val = mapdesc->project( spts, stride, &tmp[0][0], tstride, order ); if( val == 0 ) { // control points cross infinity, therefore derivatives are undefined setstepsize( mapdesc->maxrate ); } else { REAL t = mapdesc->getProperty( N_PIXEL_TOLERANCE ); if( mapdesc->isParametricDistanceSampling() ) { REAL d = mapdesc->calcPartialVelocity( &tmp[0][0], tstride, order, 2, range[2] ); stepsize = (d > 0.0) ? ::sqrtf( 8.0 * t / d ) : range[2]; minstepsize = ( mapdesc->maxrate > 0.0 ) ? (range[2] / mapdesc->maxrate) : 0.0; } else if( mapdesc->isPathLengthSampling() ) { // t is upper bound on path (arc) length REAL d = mapdesc->calcPartialVelocity( &tmp[0][0], tstride, order, 1, range[2] ); stepsize = ( d > 0.0 ) ? (t / d) : range[2]; minstepsize = ( mapdesc->maxrate > 0.0 ) ? (range[2] / mapdesc->maxrate) : 0.0; } else { // control points cross infinity, therefore partials are undefined setstepsize( mapdesc->maxrate ); } } } }
int Integrator::dointstep(int (*func)(double, const double*, double*, void*), IntParams ¶ms, double data[], double &time, const double endtime) { // Integrates a single step // Sets up the system to integrate, including the function that specifies the derivatives, NULL for the Jacobian, the number of elements // being integrated, and the parameters to pass through to the function gsl_odeiv2_system sys = { func, NULL, numelements, ¶ms }; // Make a copy of the stepsize - the evolution function wants to update this quantity, but a reference to the class' private information // makes things unhappy double stepsizecopy = stepsize; // Actually take the integration step int status = gsl_odeiv2_evolve_apply(evolve, control, step, &sys, &time, endtime, &stepsizecopy, data); // Update the stepsize according to what GSL thinks will work well, but make sure it doesn't get too big. We want some resolution on our functions! setstepsize(stepsizecopy); // Return the status: should be GSL_SUCCESS if everything worked return status; }