Example #1
0
static int trap_aline(uint opcode, uint pc)
{
  uint off = opcode & TRAP_MASK;
  trap_func_t f = traps[off].trap;
  f(opcode, pc);
  
  int flags = traps[off].flags;

  /* a one shot trap is removed after it is triggered */
  if(flags & TRAP_ONE_SHOT) {
    trap_free(off);
  }
  
  if(flags & TRAP_AUTO_RTS) {
    return M68K_ALINE_RTS;
  } else {
    return M68K_ALINE_NONE;
  }
}
Example #2
0
int
main(int argc, char **argv)
{
    /* DEFAULT VALUES */
    par.potentialonly = 0;
    par.dt = 1e-4;
    par.poincare = 1;
    par.nbpmax = 500;
    par.t1 = 1e2;
    par.r0 = 0.0;
    par.L0 = 0.0;
    par.E0 = 0.0;

    par.V_ex = 0.0;		/* excitation */
    par.omega_ex = 0.0;

    par.rmax = 1.0;		/* cutoff */

    /* PARSE */
    {
	int c;
	extern char *optarg;
	extern int optind;
	while((c = getopt(argc, argv, "Pd:n:t:V:W:")) != -1) {
	    switch(c) {
		case 'P':
		    par.potentialonly = 1;
		    break;
		case 'd':
		    par.dt = atof(optarg);
		    break;
		case 'n':
		    par.nbpmax = atoi(optarg);
		    par.poincare = 1;
		    par.t1 = 1e99;
		    break;
		case 't':
		    par.t1 = atof(optarg);
		    par.poincare = 0;
		    break;
		case 'V':
		    par.V_ex = atof(optarg);
		    break;
		case 'W':
		    par.omega_ex = atof(optarg);
		    break;
		case ':':
		case '?':
		    usage(argv);
		default:
		    fprintf(stderr, "Unknown error\n");
	    }
	}
	if (optind + (par.potentialonly?5:8) > argc)
	    usage(argv);

	V1 = atof(argv[optind++]);
	V2 = atof(argv[optind++]);
	V3 = atof(argv[optind++]);
	V4 = atof(argv[optind++]);
	V5 = atof(argv[optind++]);
	if (!par.potentialonly) {
	    par.E0 = atof(argv[optind++]);
	    par.L0 = atof(argv[optind++]);
	    par.r0 = atof(argv[optind++]);
	}
    }

    /* INIT TRAP */
    {
	size_t k;
	for(k=0; k<NPOINTS; k++) {
	    zi[k] += 0.1525;
	}

	trap = trap_alloc(zi, NPOINTS);
	trap->n = 11;
	trap->R = 0.008;
	trap->Rz = 0.013;
	trap_init(trap);

	Vi[0] = 0.0;
	Vi[1] = Vi[2] = V1;
	Vi[3] = Vi[4] = V2;
	Vi[5] = Vi[6] = V3;
	Vi[7] = Vi[8] = V4;
	Vi[9] = Vi[10] = 0.0;
	Vi[11] = Vi[12] = V5;
	Vi[13] = 0.0;
	assert(NPOINTS == 14);
	trap_set_pot(trap, Vi);


	excit = trap_alloc(zi, NPOINTS);
	excit->n = trap->n;
	excit->R = trap->R;
	excit->Rz = trap->Rz;
	trap_init(excit);
	{
	    double Vex[NPOINTS];
	    for(k=0; k<NPOINTS; k++) {
		Vex[k] = 0.0;
	    }
	    Vex[9] = Vex[10] = par.V_ex;
	    trap_set_pot(excit, Vex);
	}
    }

    /* the -P switch */
    if (par.potentialonly) {
	double z;
	printf("# static potential\n");
	for(z=0.0; z<0.2111; z+=1e-4) {
	    printf("%e %e %e %e %e\n", z,
		    trap_get_pot(trap, z),
		    trap_get_pot1(trap, z),
		    trap_get_pot2(trap, z),
		    trap_get_pot3(trap, z)
		  );
	}
	printf("\n");

	printf("# excitation potential\n");
	for(z=0.0; z<0.2111; z+=1e-4) {
	    printf("%e %e %e %e %e\n", z,
		    trap_get_pot(excit, z),
		    trap_get_pot1(excit, z),
		    trap_get_pot2(excit, z),
		    trap_get_pot3(excit, z)
		  );
	}
	exit(0);
    }

    /* rkck is good for energy conservation */
#define GSLODEIVTYPE	gsl_odeiv_step_rkck
#define GSLODEIVEPSREL	1e-8

    gsl_odeiv_step *s = gsl_odeiv_step_alloc(GSLODEIVTYPE, DIM);
    gsl_odeiv_system sys = {&func, NULL, DIM, trap};
    gsl_odeiv_control *c;
    gsl_odeiv_evolve *e;
    double t = 0.0, tprev, dt = par.dt;
    double y[DIM], yprev[DIM];
    int status;
    size_t iter = 0, npp = 0;

    y[0] = par.r0;		// x_i
    y[1] = 0.0;			// y_i
    y[2] = 0.0;			// z_i

    y[3] = 0.0;						// dot x_i
    y[4] = (par.L0 == 0.0) ? 0.0 : par.L0/par.r0;	// dot y_i
    y[5] = sqrt(2*par.E0 - y[3]*y[3] - y[4]*y[4]);	// dot z_i

    printf("\n");
    printf("#V[i]: %g %g %g %g %g\n", V1, V2, V3, V4, V5);
    printf("#excitation: %g %g\n", par.V_ex, par.omega_ex);
    printf("#E0,L0,r0: %g %g %g\n", par.E0, par.L0, par.r0);
    printf("#y0: %e %e %e %e\n", y[0], y[1], y[2], y[3]);
    printf("# 1:t 2:x 3:y 4:z 5:px 6:py 7:pz\n");

    c = gsl_odeiv_control_y_new(GSLODEIVEPSREL, 0.0);
    e = gsl_odeiv_evolve_alloc(DIM);

    while (t < par.t1)
    {
	tprev = t;
	memcpy(yprev, y, sizeof(y));

	/* ONE STEP */
	status = gsl_odeiv_evolve_apply (e, c, s, &sys, &t, par.t1, &dt, y);
	if (status != GSL_SUCCESS) {
	    fprintf(stderr, "GSL failure. Exiting\n");
	    break;
	}
	if (fabs(y[1]) >= 0.013 || fabs(y[2]) >= 0.24 || gsl_isnan(y[2])) {
	    fprintf(stderr, "Trajectory goes out of bound. Exiting.\n");
	    break;
	}
	if (dt > par.dt) dt = par.dt;

	/* OUTPUT */
	if (par.poincare) {
	    if (yprev[2]*y[2] <= 0.0) {
		double h0 = -yprev[2] / (y[2] - yprev[2]);
		printf("%e %e %e %e %e %e %e\n",
			tprev + h0*dt,
			yprev[0] + h0*(y[0]-yprev[0]),
			yprev[1] + h0*(y[1]-yprev[1]),
			yprev[2] + h0*(y[2]-yprev[2]),
			yprev[3] + h0*(y[3]-yprev[3]),
			yprev[4] + h0*(y[4]-yprev[4]),
			yprev[5] + h0*(y[5]-yprev[5])
		      );
		fflush(stdout);
		npp++;
		if (npp % 10 == 0) {
		    fprintf(stderr, "npp:%zu t:%.3e iter:%zuk dt:%.2e\n",
			    npp, t, iter/1000, dt);
		}
		if (npp >= par.nbpmax) {
		    fprintf(stderr, "Enough points on section. Exiting.\n");
		    break;
		}
	    }
	}
	else {
	    printf("%e %e %e %e %e %e %e\n",
		    t, y[0], y[1], y[2], y[3], y[4], y[5]);
	}
	if (iter % 10000 == 0) {
	    if (par.V_ex == 0.0) {
		double dE = (energy(y) - par.E0) / par.E0;
		fprintf(stderr, "t:%e iter:%zuk dt:%.2e dL0:%+.2e dE0:%+.2e\n",
			t, iter/1000, dt, kinmom(y)-par.L0, dE);
		if (fabs(dE) > 1e-3) {
		    fprintf(stderr, "dE is now too high. Exiting.\n");
		    break;
		}
	    }
	    if (isnan(y[0]) || isnan(y[1]) || hypot(y[0],y[1]) > par.rmax) {
		fprintf(stderr, "Diverging (x:%g, y:%g). Exiting.\n", y[0], y[1]);
		break;
	    }
	}
	iter++;
    }
    fprintf(stderr, "END t:%e (%zu iters) r:%e z:%e\n",
	    t, iter, hypot(y[0],y[1]), y[2]);

    /* */
    gsl_odeiv_evolve_free(e);
    gsl_odeiv_control_free(c);
    gsl_odeiv_step_free(s);
    trap_free(trap);
    return 0;
}