void sled(double k, double q, double p, const QString& fileName) { QFile f(fileName); f.open(QIODevice::WriteOnly); QTextStream stream(&f); auto i = new GslIntegrator(); double y[] = {q, p}; gsl_odeiv2_system sys = {fun_zoga, 0, 2, &k}; gsl_odeiv2_driver* driver = gsl_odeiv2_driver_alloc_y_new(&sys, gsl_odeiv2_step_rk4, 1e-4, 1e-3, 1e-3); double t = 0.0; while (t < 20.0) { int c = fmod(t, 2) > 1 ? 1 : 0; double q = y[0], p = y[1]; omeji(&q, &p); stream << t << " " << q << " " << p << " " << c << endl; int status = gsl_odeiv2_driver_apply_fixed_step(driver, &t, 1e-4, 1, y); if (status != GSL_SUCCESS) { qDebug() << t << gsl_strerror(status); break; } } f.close(); }
void polysolve(double hstep, bool listmodel) { double h, rpmw[4], w1, w2, t; gsl_odeiv2_system sys = { diffrpmw, NULL, 4, NULL }; gsl_odeiv2_driver *drv; int stat; if (npol <= 0.5 || mpol <= -1.0) error("%s: illegal value for n or m\n", getprog()); if (npol >= 3*mpol + 5) error("%s: model would have infinite radius\n", getprog()); Kprime = K * (mpol+1) * pow(PI, -1.5) * pow(2.0, - (mpol+1.5)) * exp(lgamma(mpol+npol+1) - lgamma(mpol+2) - lgamma(npol-0.5)); h = hstep; do { drv = gsl_odeiv2_driver_alloc_y_new(&sys, gsl_odeiv2_step_rk4, h, 1.0, 1.0); rpmw[0] = 0.0; // initialize radius rpmw[1] = PHI0; // initialize potential rpmw[2] = 0.0; // initialize enclosed mass rpmw[3] = 0.0; // initialize binding energy nstep = 0; storestep(rpmw); asmpstep(rpmw, h); // use asymp. approximation storestep(rpmw); while (rpmw[1] < 0.0) { // while potential is neg. stat = gsl_odeiv2_driver_apply_fixed_step(drv, &t, h, 1, rpmw); if (stat) eprintf("[%s.polysolve: stat = %d]\n", getprog(), stat); storestep(rpmw); } fixsurface(); w1 = rpmw[3] - 0.5 * rsqr(mtot) / rad1; w2 = - (2*mpol + 3) / (3*mpol - npol + 5) * rsqr(mtot) / rad1; eprintf("[%s.polysolve: nstep = %3d W = %f error = %f]\n", getprog(), nstep, w2, (w1 - w2)/w2); gsl_odeiv2_driver_free(drv); h = 0.5 * h; // refine step-size by 2 } while (nstep < MAXSTEP/4); polyscale(); pmspline = gsl_spline_alloc(gsl_interp_cspline, nstep); gsl_spline_init(pmspline, rtab, ptab, nstep); if (listmodel) { printf("#%11s %11s %11s\n", "radius", "mass", "potential"); for (int i = 0; i < nstep - 1; i++) printf(" %11.6f %11.6f %11.6f\n", rtab[i], mtab[i], ptab[i]); printf(" %11.6f %11.6f %11.6f\n", rad1, mtot, phi1); } }
void portret(double k, const QString& fileName) { // TODO: Direktro uporabi GSL, da ne porablja toliko RAMa. Interval i = qMakePair(0.0, 10.0); Integrator* integrator = new GslIntegrator; QImage image(QSize(800,800), QImage::Format_Indexed8); for (int j = 0; j < 256; ++j) { image.setColor(j, qRgb(j, j, j)); } image.fill(255); gsl_odeiv2_system sys = {fun_zoga, 0, 2, &k}; gsl_odeiv2_driver* driver = gsl_odeiv2_driver_alloc_y_new(&sys, gsl_odeiv2_step_rk4, 1e-3, 1, 1); double y[2]; double t; for (double q = 0; q < 1; q += 0.02) { qDebug() << "q = " << q; for (double p = -5; p < 5; p += 0.05) { y[0] = q; y[1] = p; t = 0.0; double y[] = {q, p}; while (t < 100.0) { int status = gsl_odeiv2_driver_apply_fixed_step(driver, &t, 1e-3, 1000, y); if (status != GSL_SUCCESS) { qDebug() << t << gsl_strerror(status); break; } double qq = y[0]; double pp = y[1]; omeji(&qq, &pp); uchar& pix = image.scanLine( qBound<int>(0, (5+pp) * 80.0, 799) )[ qBound<int>(0, qq * 800.0, 799) ]; if (pix > 100) { pix -= 100; } } } } image.save(fileName); }
void SQuIDS::Evolve(double dt){ if(AnyNumerics){ int gsl_status = GSL_SUCCESS; // initial time // ODE system error control gsl_odeiv2_driver* d = gsl_odeiv2_driver_alloc_y_new(&sys,step,h,abs_error,rel_error); gsl_odeiv2_driver_set_hmin(d,h_min); gsl_odeiv2_driver_set_hmax(d,h_max); gsl_odeiv2_driver_set_nmax(d,0); double* gsl_sys = system.get(); if(adaptive_step){ gsl_status = gsl_odeiv2_driver_apply(d, &t, t+dt, gsl_sys); }else{ gsl_status = gsl_odeiv2_driver_apply_fixed_step(d, &t, dt/nsteps , nsteps , gsl_sys); } gsl_odeiv2_driver_free(d); if( gsl_status != GSL_SUCCESS ){ throw std::runtime_error("SQUIDS::Evolve: Error in GSL ODE solver (" +std::string(gsl_strerror(gsl_status))+")"); } //after evolving, make estate alias state again for(unsigned int ei = 0; ei < nx; ei++){ for(unsigned int i=0;i<nrhos;i++) estate[ei].rho[i].SetBackingStore(&(system[ei*size_state+i*size_rho])); if(nscalars>0) estate[ei].scalar=&(system[ei*size_state+nrhos*size_rho]); } }else{ t+=dt; PreDerive(t); } }