/**************************************************************************** * electrodynamics.c * David Boozer * 23 June 2008 * 30 July 2008 (modified) ***************************************************************************** * Simulate toy model of electrodynamics. ***************************************************************************** * How to convert sequence of frames into a movie: * * $ makejpgs * $ mencoder \*.jpg -mf on:fps=25 -ovc lavc ****************************************************************************/ #include #include #define R 2000 #define N (2*R + 1) #define NUM_DOF (2*N+2) #define SIGMA 250.0 #define STEP_MAX 0.1 #define TOTAL_CHARGE 1.0 /* charge density profile of particle */ #define F(x) (exp(-(x)*(x)/(2*SIGMA*SIGMA))/(SIGMA*sqrt(2*M_PI))) /* first derivative of charge density profile */ #define F1(x) (-(x)*F(x)/(SIGMA*SIGMA)) /* note: unnamed struct in union may not work in some compilers */ union s_type { struct { double phi[N], pi[N], z, p; } name; double dof[NUM_DOF]; }; #define PHI name.phi #define PI name.pi #define Z name.z #define P name.p double M, omega0; /**************************************************************************** * manipulate states ****************************************************************************/ void evolve_state (void (*f)(union s_type *s_ptr, union s_type *s_dot_ptr), union s_type *s_ptr, double tau) { union s_type s_dot_1, s_dot_2, s_dot_3, s_dot_4; union s_type s_temp; int i, n, num_steps; double step; num_steps = (int) ceil (tau/STEP_MAX); step = tau/num_steps; for (n=0; ndof[i] + 0.5*step*s_dot_1.dof[i]; (*f)(&s_temp, &s_dot_2); for (i=0; idof[i] + 0.5*step*s_dot_2.dof[i]; (*f)(&s_temp, &s_dot_3); for (i=0; idof[i] + step*s_dot_3.dof[i]; (*f)(&s_temp, &s_dot_4); for (i=0; idof[i] += (step/6)*(s_dot_1.dof[i] + 2*s_dot_2.dof[i] + s_dot_4.dof[i] + 2*s_dot_3.dof[i]); } } void reverse_state (union s_type *s_ptr) { int n; for (n=0; nPI[n] = -s_ptr->PI[n]; s_ptr->P = -s_ptr->P; } void initialize_state (union s_type *s_ptr) { double temp; int i, j; s_ptr->Z = 0.0; s_ptr->P = 0.0; for (i=0; iPHI[i] = temp; s_ptr->PI[i] = 0.0; } } /**************************************************************************** * equations of motion ****************************************************************************/ /* equations of motion for a simple harmonic oscillator */ void eqns_sho (union s_type *s_ptr, union s_type *s_dot_ptr) { s_dot_ptr->Z = s_ptr->P; s_dot_ptr->P = -s_ptr->Z - s_ptr->P; } /* equations of motion for a harmonically bound particle */ void eqns_harmonic (union s_type *s_ptr, union s_type *s_dot_ptr) { double *phi = s_ptr->PHI; double *pi = s_ptr->PI; double z = s_ptr->Z; double p = s_ptr->P; double temp; int n; for (n=0; nPI[n] = 2*(phi[1] - phi[0] - pi[0] + TOTAL_CHARGE); else if (n == N-1) s_dot_ptr->PI[n] = 2*(phi[N-2] - phi[N-1] - pi[N-1] + TOTAL_CHARGE); else s_dot_ptr->PI[n] = phi[n+1] - 2*phi[n] + phi[n-1] - 2*F(z-(n-R)); s_dot_ptr->PHI[n] = pi[n]; } s_dot_ptr->Z = p/M; for (n=0, temp=0.0; nP = 2*temp - M*omega0*omega0*z; } /**************************************************************************** * output files ****************************************************************************/ void make_frames (void *f, union s_type *s_ptr, double T) { FILE *file_field, *file_particle; char filename[32]; double *pi = s_ptr->PI; double *phi = s_ptr->PHI; double *p = &s_ptr->P; double *z = &s_ptr->Z; double E, B, Erad, Es[N], temp; double t, delta; int i, n; delta = 4.0; file_particle = fopen ("particle.txt", "w"); for (t=0.0, n=0; t<=T; t+=delta, n++) { /* calculate static electric field */ Es[0] = -TOTAL_CHARGE; for (i=1; i