Add files via upload

This commit is contained in:
nilsberglund-orleans 2022-04-12 19:20:18 +02:00 committed by GitHub
parent 6d878e89dd
commit 65aa6866be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 3174 additions and 448 deletions

39
global_3d.c Normal file
View File

@ -0,0 +1,39 @@
/* global variables and definition used by sub_wave_3d.c */
/* plot types used by wave_3d */
#define P_3D_AMPLITUDE 101 /* color depends on amplitude */
#define P_3D_ANGLE 102 /* color depends on angle with fixed direction */
#define P_3D_AMP_ANGLE 103 /* color depends on amplitude, luminosity depends on angle */
#define P_3D_ENERGY 104 /* color depends on energy, luminosity depends on angle */
#define P_3D_LOG_ENERGY 105 /* color depends on logarithm of energy, luminosity depends on angle */
#define P_3D_PHASE 111 /* phase of wave */
/* plot types used by rde */
#define Z_AMPLITUDE 0 /* amplitude of first field */
#define Z_NORM_GRADIENT 22 /* gradient of polar angle */
#define Z_NORM_GRADIENTX 23 /* direction of gradient of u */
#define Z_NORM_GRADIENT_INTENSITY 24 /* gradient and intensity of polar angle */
#define Z_VORTICITY 25 /* curl of polar angle */
#define COMPUTE_THETA ((plot == P_POLAR)||(plot == P_GRADIENT)||(plot == P_GRADIENTX)||(plot == P_GRADIENT_INTENSITY)||(plot == P_VORTICITY))
#define COMPUTE_THETAZ ((zplot == P_POLAR)||(zplot == P_GRADIENT)||(zplot == P_GRADIENTX)||(zplot == P_GRADIENT_INTENSITY)||(zplot == P_VORTICITY))
/* structure used for color and height representations */
/* possible extra fields: zfield, cfield, interpolated coordinates */
typedef struct
{
double energy; /* wave energy */
double phase; /* wave phase */
double log_energy; /* log of wave energy */
double total_energy; /* total energy since beginning of simulation */
double cos_angle; /* cos of angle between normal vector and direction of light */
double rgb[3]; /* RGB color code */
double *p_zfield; /* pointer to z field */
double *p_cfield; /* pointer to color field */
} t_wave;

View File

@ -36,6 +36,7 @@
/* pattern of additional obstacles */
#define O_CORNERS 0 /* obstacles in the corners (for Boy b.c.) */
#define O_GALTON_BOARD 1 /* Galton board pattern */
#define O_GENUS_TWO 2 /* obstacles in corners of L-shape domeain (for genus 2 b.c.) */
/* particle interaction */
@ -59,9 +60,11 @@
#define BC_PERIODIC_FUNNEL 6 /* funnel with periodic boundary conditions */
#define BC_RECTANGLE_LID 7 /* rectangular container with moving lid */
#define BC_PERIODIC_TRIANGLE 8 /* periodic boundary conditions and harmonic b.c. outside moving triangle */
#define BC_RECTANGLE_WALL 9 /* rectangular container with vertical movable wall */
#define BC_KLEIN 11 /* Klein bottle (periodic with twisted vertical parts) */
#define BC_SCREEN_BINS 12 /* harmonic boundary conditions outside screen area plus "bins" (for Galton board) */
#define BC_BOY 13 /* Boy surface/projective plane (periodic with twisted horizontal and vertical parts) */
#define BC_GENUS_TWO 14 /* surface of genus 2, obtained by identifying opposite sides of an L shape */
/* Plot types */

View File

@ -180,6 +180,6 @@ t_circle circles[NMAXCIRCLES]; /* circular scatterers */
t_polygon polygons[NMAXCIRCLES]; /* polygonal scatterers */
t_vertex polyline[NMAXPOLY]; /* vertices of polygonal line */
double julia_x = -0.5, julia_y = 0.5; /* parameters for Julia sets */
// double julia_x = -0.5, julia_y = 0.5; /* parameters for Julia sets */
// double julia_x = 0.33267, julia_y = 0.06395; /* parameters for Julia sets */
// double julia_x = 0.37468, julia_y = 0.21115; /* parameters for Julia sets */
double julia_x = 0.37468, julia_y = 0.21115; /* parameters for Julia sets */

View File

@ -38,7 +38,7 @@
#define MOVIE 0 /* set to 1 to generate movie */
#define DOUBLE_MOVIE 0 /* set to 1 to produce movies for wave height and energy simultaneously */
#define TIME_LAPSE 0 /* set to 1 to add a time-lapse movie at the end */
#define TIME_LAPSE 1 /* set to 1 to add a time-lapse movie at the end */
/* so far incompatible with double movie */
#define TIME_LAPSE_FACTOR 3 /* factor of time-lapse movie */
@ -53,10 +53,10 @@
#define YMIN -1.125
#define YMAX 1.125 /* y interval for 9/16 aspect ratio */
#define INITXMIN -1.85
#define INITXMAX 1.85 /* x interval for initial condition */
#define INITYMIN -0.9
#define INITYMAX 0.9 /* y interval for initial condition */
#define INITXMIN -1.9
#define INITXMAX 1.9 /* x interval for initial condition */
#define INITYMIN -1.0
#define INITYMAX 1.0 /* y interval for initial condition */
#define BCXMIN -2.0
#define BCXMAX 2.0 /* x interval for boundary condition */
@ -69,38 +69,39 @@
#define CIRCLE_PATTERN 8 /* pattern of circles, see list in global_ljones.c */
#define ADD_FIXED_OBSTACLES 1 /* set to 1 do add fixed circular obstacles */
#define OBSTACLE_PATTERN 0 /* pattern of obstacles, see list in global_ljones.c */
#define OBSTACLE_PATTERN 2 /* pattern of obstacles, see list in global_ljones.c */
#define TWO_TYPES 0 /* set to 1 to have two types of particles */
#define TPYE_PROPORTION 0.8 /* proportion of particles of first type */
#define SYMMETRIZE_FORCE 0 /* set to 1 to symmetrize two-particle interaction, only needed if particles are not all the same */
#define SYMMETRIZE_FORCE 1 /* set to 1 to symmetrize two-particle interaction, only needed if particles are not all the same */
#define CENTER_PX 0 /* set to 1 to center horizontal momentum */
#define CENTER_PY 0 /* set to 1 to center vertical momentum */
#define CENTER_PANGLE 0 /* set to 1 to center angular momentum */
#define INTERACTION 3 /* particle interaction, see list in global_ljones.c */
#define INTERACTION 1 /* particle interaction, see list in global_ljones.c */
#define INTERACTION_B 1 /* particle interaction for second type of particle, see list in global_ljones.c */
#define SPIN_INTER_FREQUENCY 5.0 /* angular frequency of spin-spin interaction */
#define SPIN_INTER_FREQUENCY_B 2.0 /* angular frequency of spin-spin interaction for second particle type */
#define P_PERCOL 0.25 /* probability of having a circle in C_RAND_PERCOL arrangement */
#define NPOISSON 100 /* number of points for Poisson C_RAND_POISSON arrangement */
#define PDISC_DISTANCE 1.8 /* minimal distance in Poisson disc process, controls density of particles */
#define PDISC_DISTANCE 5.75 /* minimal distance in Poisson disc process, controls density of particles */
// #define PDISC_DISTANCE 2.25 /* minimal distance in Poisson disc process, controls density of particles */
#define PDISC_CANDIDATES 100 /* number of candidates in construction of Poisson disc process */
#define RANDOM_POLY_ANGLE 0 /* set to 1 to randomize angle of polygons */
#define LAMBDA 2.0 /* parameter controlling the dimensions of domain */
#define MU 0.045 /* parameter controlling radius of particles */
#define MU_B 0.02427051 /* parameter controlling radius of particles of second type */
#define MU 0.015 /* parameter controlling radius of particles */
#define MU_B 0.0254 /* parameter controlling radius of particles of second type */
#define NPOLY 3 /* number of sides of polygon */
#define APOLY 0.0 /* angle by which to turn polygon, in units of Pi/2 */
#define APOLY 0.125 /* angle by which to turn polygon, in units of Pi/2 */
#define MDEPTH 4 /* depth of computation of Menger gasket */
#define MRATIO 3 /* ratio defining Menger gasket */
#define MANDELLEVEL 1000 /* iteration level for Mandelbrot set */
#define MANDELLIMIT 10.0 /* limit value for approximation of Mandelbrot set */
#define FOCI 1 /* set to 1 to draw focal points of ellipse */
#define NGRIDX 10 /* number of grid point for grid of disks */
#define NGRIDY 3 /* number of grid point for grid of disks */
#define NGRIDX 30 /* number of grid point for grid of disks */
#define NGRIDY 20 /* number of grid point for grid of disks */
#define EHRENFEST_RADIUS 0.9 /* radius of container for Ehrenfest urn configuration */
#define EHRENFEST_WIDTH 0.035 /* width of tube for Ehrenfest urn configuration */
@ -111,10 +112,11 @@
/* Parameters for length and speed of simulation */
#define NSTEPS 3750 /* number of frames of movie */
#define NVID 100 /* number of iterations between images displayed on screen */
#define NSEG 150 /* number of segments of boundary */
#define INITIAL_TIME 0 /* time after which to start saving frames */
#define NSTEPS 5100 /* number of frames of movie */
// #define NSTEPS 2750 /* number of frames of movie */
#define NVID 200 /* number of iterations between images displayed on screen */
#define NSEG 250 /* number of segments of boundary */
#define INITIAL_TIME 20 /* time after which to start saving frames */
#define BOUNDARY_WIDTH 1 /* width of particle boundary */
#define LINK_WIDTH 2 /* width of links between particles */
#define CONTAINER_WIDTH 4 /* width of container boundary */
@ -128,18 +130,18 @@
/* Boundary conditions, see list in global_ljones.c */
#define BOUNDARY_COND 13
#define BOUNDARY_COND 14
/* Plot type, see list in global_ljones.c */
#define PLOT 4
#define PLOT_B 3 /* plot type for second movie */
#define PLOT 5
#define PLOT_B 4 /* plot type for second movie */
#define COLOR_BONDS 1 /* set to 1 to color bonds according to length */
/* Color schemes */
#define COLOR_PALETTE 0 /* Color palette, see list in global_ljones.c */
#define COLOR_PALETTE 10 /* Color palette, see list in global_ljones.c */
#define BLACK 1 /* background */
@ -162,35 +164,42 @@
#define ENERGY_HUE_MAX 50.0 /* color of saturated particle */
#define PARTICLE_HUE_MIN 359.0 /* color of original particle */
#define PARTICLE_HUE_MAX 0.0 /* color of saturated particle */
#define PARTICLE_EMAX 5.0e2 /* energy of particle with hottest color */
#define PARTICLE_EMAX 1.0e3 /* energy of particle with hottest color */
#define HUE_TYPE0 280.0 /* hue of particles of type 0 */
#define HUE_TYPE1 135.0 /* hue of particles of type 1 */
#define HUE_TYPE2 70.0 /* hue of particles of type 1 */
#define HUE_TYPE3 210.0 /* hue of particles of type 1 */
#define RANDOM_RADIUS 0 /* set to 1 for random circle radius */
#define DT_PARTICLE 1.0e-6 /* time step for particle displacement */
#define KREPEL 10.0 /* constant in repelling force between particles */
#define EQUILIBRIUM_DIST 6.0 /* Lennard-Jones equilibrium distance for second type of particle */
#define DT_PARTICLE 5.0e-7 /* time step for particle displacement */
#define KREPEL 12.0 /* constant in repelling force between particles */
#define EQUILIBRIUM_DIST 5.0 /* Lennard-Jones equilibrium distance */
#define EQUILIBRIUM_DIST_B 5.0 /* Lennard-Jones equilibrium distance for second type of particle */
#define REPEL_RADIUS 20.0 /* radius in which repelling force acts (in units of particle radius) */
#define DAMPING 0.0 /* damping coefficient of particles */
#define PARTICLE_MASS 1.0 /* mass of particle of radius MU */
#define PARTICLE_MASS_B 0.1 /* mass of particle of radius MU */
#define PARTICLE_INERTIA_MOMENT 0.02 /* moment of inertia of particle */
#define PARTICLE_MASS_B 1.0 /* mass of particle of radius MU */
#define PARTICLE_INERTIA_MOMENT 0.2 /* moment of inertia of particle */
#define PARTICLE_INERTIA_MOMENT_B 0.02 /* moment of inertia of second type of particle */
#define V_INITIAL 10.0 /* initial velocity range */
#define OMEGA_INITIAL 10.0 /* initial angular velocity range */
#define THERMOSTAT 1 /* set to 1 to switch on thermostat */
#define SIGMA 5.0 /* noise intensity in thermostat */
#define BETA 0.002 /* initial inverse temperature */
#define MU_XI 0.05 /* friction constant in thermostat */
#define KSPRING_BOUNDARY 5.0e8 /* confining harmonic potential outside simulation region */
#define BETA 0.0001 /* initial inverse temperature */
#define MU_XI 0.01 /* friction constant in thermostat */
#define KSPRING_BOUNDARY 5.0e9 /* confining harmonic potential outside simulation region */
#define KSPRING_OBSTACLE 5.0e8 /* harmonic potential of obstacles */
#define NBH_DIST_FACTOR 3.5 /* radius in which to count neighbours */
#define GRAVITY 0.0 /* gravity acting on all particles */
#define NBH_DIST_FACTOR 4.0 /* radius in which to count neighbours */
#define GRAVITY 0.0 /* gravity acting on all particles */
#define INCREASE_GRAVITY 0 /* set to 1 to increase gravity during the simulation */
#define GRAVITY_FACTOR 100.0 /* factor by which to increase gravity */
#define GRAVITY_RESTORE_TIME 750 /* time at end of simulation with gravity restored to initial value */
#define ROTATION 1 /* set to 1 to include rotation of particles */
#define COUPLE_ANGLE_TO_THERMOSTAT 1 /* set to 1 to couple angular degrees of freedom to thermostat */
#define ROTATION 0 /* set to 1 to include rotation of particles */
#define COUPLE_ANGLE_TO_THERMOSTAT 0 /* set to 1 to couple angular degrees of freedom to thermostat */
#define DIMENSION_FACTOR 1.0 /* scaling factor taking into account number of degrees of freedom */
#define KTORQUE 600.0 /* force constant in angular dynamics */
#define KTORQUE 50.0 /* force constant in angular dynamics */
#define KTORQUE_B 10.0 /* force constant in angular dynamics */
#define KTORQUE_DIFF 150.0 /* force constant in angular dynamics for different particles */
#define DRAW_SPIN 0 /* set to 1 to draw spin vectors of particles */
@ -200,8 +209,8 @@
#define SPIN_RANGE_B 5.0 /* range of spin-spin interaction for second type of particle */
#define QUADRUPOLE_RATIO 0.6 /* anisotropy in quadrupole potential */
#define INCREASE_BETA 1 /* set to 1 to increase BETA during simulation */
#define BETA_FACTOR 500.0 /* factor by which to change BETA during simulation */
#define INCREASE_BETA 0 /* set to 1 to increase BETA during simulation */
#define BETA_FACTOR 20.0 /* factor by which to change BETA during simulation */
#define N_TOSCILLATIONS 1.5 /* number of temperature oscillations in BETA schedule */
#define NO_OSCILLATION 0 /* set to 1 to have exponential BETA change only */
#define FINAL_CONSTANT_PHASE 0 /* final phase in which temperature is constant */
@ -216,16 +225,17 @@
#define CENTER_VIEW_ON_OBSTACLE 0 /* set to 1 to center display on moving obstacle */
#define RESAMPLE_Y 0 /* set to 1 to resample y coordinate of moved particles (for shock waves) */
#define NTRIALS 2000 /* number of trials when resampling */
#define OBSTACLE_RADIUS 0.15 /* radius of obstacle for circle boundary conditions */
#define OBSTACLE_RADIUS 0.12 /* radius of obstacle for circle boundary conditions */
#define FUNNEL_WIDTH 0.25 /* funnel width for funnel boundary conditions */
#define OBSTACLE_XMIN 0.0 /* initial position of obstacle */
#define OBSTACLE_XMAX 3.0 /* final position of obstacle */
#define RECORD_PRESSURES 0 /* set to 1 to record pressures on obstacle */
#define N_PRESSURES 100 /* number of intervals to record pressure */
#define N_P_AVERAGE 100 /* size of pressure averaging window */
#define MAX_PRESSURE 3.0e10 /* pressure shown in "hottest" color */
#define N_T_AVERAGE 50 /* size of temperature averaging window */
#define PARTIAL_THERMO_COUPLING 1 /* set to 1 to couple only particles to the right of obstacle to thermostat */
#define MAX_PRESSURE 3.0e10 /* pressure shown in "hottest" color */
#define PARTIAL_THERMO_COUPLING 0 /* set to 1 to couple only particles to the right of obstacle to thermostat */
#define PARTIAL_THERMO_SHIFT 0.5 /* distance from obstacle at the right of which particles are coupled to thermostat */
#define INCREASE_KREPEL 0 /* set to 1 to increase KREPEL during simulation */
#define KREPEL_FACTOR 1000.0 /* factor by which to change KREPEL during simulation */
@ -240,12 +250,14 @@
#define FINAL_NOADD_PERIOD 250 /* final period where no particles are added */
#define SAFETY_FACTOR 2.0 /* no particles are added at distance less than MU*SAFETY_FACTOR of other particles */
#define TRACER_PARTICLE 0 /* set to 1 to have a tracer particle */
#define TRAJECTORY_LENGTH 6000 /* length of recorded trajectory */
#define TRACER_PARTICLE_MASS 0.1 /* relative mass of tracer particle */
#define TRACER_PARTICLE 1 /* set to 1 to have a tracer particle */
#define N_TRACER_PARTICLES 3 /* number of tracer particles */
#define TRAJECTORY_LENGTH 8000 /* length of recorded trajectory */
#define TRACER_PARTICLE_MASS 4.0 /* relative mass of tracer particle */
#define TRAJECTORY_WIDTH 3 /* width of tracer particle trajectory */
#define POSITION_DEPENDENT_TYPE 0 /* set to 1 to make particle type depend on initial position */
#define POSITION_Y_DEPENDENCE 0 /* set to 1 for the separation between particles to be vertical */
#define PRINT_ENTROPY 0 /* set to 1 to compute entropy */
#define PRINT_PARTICLE_NUMBER 0 /* set to 1 to print total number of particles */
@ -254,14 +266,19 @@
#define LID_MASS 1000.0 /* mass of lid for BC_RECTANGLE_LID b.c. */
#define LID_WIDTH 0.1 /* width of lid for BC_RECTANGLE_LID b.c. */
#define WALL_MASS 2000.0 /* mass of wall for BC_RECTANGLE_WALL b.c. */
#define WALL_FRICTION 0.0 /* friction on wall for BC_RECTANGLE_WALL b.c. */
#define WALL_WIDTH 0.1 /* width of wall for BC_RECTANGLE_WALL b.c. */
#define WALL_VMAX 100.0 /* max speed of wall */
#define WALL_TIME 500 /* time during which to keep wall */
#define FLOOR_FORCE 0 /* set to 1 to limit force on particle to FMAX */
#define FLOOR_FORCE 1 /* set to 1 to limit force on particle to FMAX */
#define FMAX 1.0e9 /* maximal force */
#define FLOOR_OMEGA 0 /* set to 1 to limit particle momentum to PMAX */
#define PMAX 10.0 /* maximal force */
#define FLOOR_OMEGA 1 /* set to 1 to limit particle momentum to PMAX */
#define PMAX 1000.0 /* maximal force */
#define HASHX 30 /* size of hashgrid in x direction */
#define HASHY 20 /* size of hashgrid in y direction */
#define HASHX 34 /* size of hashgrid in x direction */
#define HASHY 18 /* size of hashgrid in y direction */
#define HASHMAX 100 /* maximal number of particles per hashgrid cell */
#define HASHGRID_PADDING 0.1 /* padding of hashgrid outside simulation window */
@ -270,13 +287,15 @@
#define COLORBAR_RANGE_B 12.0 /* scale of color scheme bar for 2nd part */
#define ROTATE_COLOR_SCHEME 0 /* set to 1 to draw color scheme horizontally */
#define NO_WRAP_BC ((BOUNDARY_COND != BC_PERIODIC)&&(BOUNDARY_COND != BC_PERIODIC_CIRCLE)&&(BOUNDARY_COND != BC_PERIODIC_TRIANGLE)&&(BOUNDARY_COND != BC_KLEIN)&&(BOUNDARY_COND != BC_PERIODIC_FUNNEL)&&(BOUNDARY_COND != BC_BOY))
#define NO_WRAP_BC ((BOUNDARY_COND != BC_PERIODIC)&&(BOUNDARY_COND != BC_PERIODIC_CIRCLE)&&(BOUNDARY_COND != BC_PERIODIC_TRIANGLE)&&(BOUNDARY_COND != BC_KLEIN)&&(BOUNDARY_COND != BC_PERIODIC_FUNNEL)&&(BOUNDARY_COND != BC_BOY)&&(BOUNDARY_COND != BC_GENUS_TWO))
#define PERIODIC_BC ((BOUNDARY_COND == BC_PERIODIC)||(BOUNDARY_COND == BC_PERIODIC_CIRCLE)||(BOUNDARY_COND == BC_PERIODIC_FUNNEL)||(BOUNDARY_COND == BC_PERIODIC_TRIANGLE))
double xshift = 0.0; /* x shift of shown window */
double xspeed = 0.0; /* x speed of obstacle */
double ylid = 0.9; /* y coordinate of lid (for BC_RECTANGLE_LID b.c.) */
double vylid = 0.0; /* y speed coordinate of lid (for BC_RECTANGLE_LID b.c.) */
double ylid = 0.9; /* y coordinate of lid (for BC_RECTANGLE_LID b.c.) */
double vylid = 0.0; /* y speed coordinate of lid (for BC_RECTANGLE_LID b.c.) */
double xwall = 0.0; /* x coordinate of wall (for BC_RECTANGLE_WALL b.c.) */
double vxwall = 0.0; /* x speed of wall (for BC_RECTANGLE_WALL b.c.) */
#include "global_ljones.c"
#include "sub_lj.c"
@ -388,6 +407,20 @@ double obstacle_schedule_smooth(int i, int j)
}
}
double gravity_schedule(int i, int j)
{
double time, gravity;
if ((i < INITIAL_TIME)||(i > NSTEPS + INITIAL_TIME - GRAVITY_RESTORE_TIME)) return(GRAVITY);
else
{
time = ((double)(i - INITIAL_TIME) + (double)j/(double)NVID)/(double)(NSTEPS - GRAVITY_RESTORE_TIME);
gravity = GRAVITY*(1.0 + time*(GRAVITY_FACTOR - 1.0));
// printf("i = %i, time = %.3lg, Gravity = %.3lg\n", i, time, gravity);
return(gravity);
}
}
double evolve_particles(t_particle particle[NMAXCIRCLES], t_hashgrid hashgrid[HASHX*HASHY],
double qx[NMAXCIRCLES], double qy[NMAXCIRCLES], double qangle[NMAXCIRCLES],
double px[NMAXCIRCLES], double py[NMAXCIRCLES], double pangle[NMAXCIRCLES],
@ -513,22 +546,40 @@ void evolve_lid(double fboundary)
force = fboundary - GRAVITY*LID_MASS;
if (ylid > BCYMAX + LID_WIDTH) force -= KSPRING_BOUNDARY*(ylid - BCYMAX - LID_WIDTH);
// printf("Force on lid = %.3lg\n", force);
vylid += force*DT_PARTICLE/LID_MASS;
ylid += vylid*DT_PARTICLE;
// if (ylid > BCYMAX + LID_WIDTH) ylid = BCYMAX;
}
void evolve_wall(double fboundary)
{
double force;
force = fboundary;
if (xwall > BCYMAX - WALL_WIDTH) force -= KSPRING_BOUNDARY*(xwall - BCYMAX + WALL_WIDTH);
else if (xwall < BCYMIN + WALL_WIDTH) force += KSPRING_BOUNDARY*(BCYMIN + WALL_WIDTH - xwall);
force -= vxwall*WALL_FRICTION;
vxwall += fboundary*DT_PARTICLE/WALL_MASS;
if (vxwall > WALL_VMAX) vxwall = WALL_VMAX;
else if (vxwall < -WALL_VMAX) vxwall = -WALL_VMAX;
xwall += vxwall*DT_PARTICLE;
// printf("fboundary = %.3lg, xwall = %.3lg, vxwall = %.3lg\n", fboundary, xwall, vxwall);
}
void animation()
{
double time, scale, diss, rgb[3], dissip, gradient[2], x, y, dx, dy, dt, xleft, xright, a, b,
length, fx, fy, force[2], totalenergy = 0.0, krepel = KREPEL, pos[2], prop, vx,
beta = BETA, xi = 0.0, xmincontainer = INITXMIN, xmaxcontainer = INITXMAX, torque, torque_ij,
fboundary = 0.0, pleft = 0.0, pright = 0.0, entropy[2], mean_energy;
beta = BETA, xi = 0.0, xmincontainer = BCXMIN, xmaxcontainer = BCXMAX, torque, torque_ij,
fboundary = 0.0, pleft = 0.0, pright = 0.0, entropy[2], mean_energy, gravity = GRAVITY;
double *qx, *qy, *px, *py, *qangle, *pangle, *pressure;
int i, j, k, n, m, s, ij[2], i0, iplus, iminus, j0, jplus, jminus, p, q, p1, q1, p2, q2, total_neighbours = 0,
min_nb, max_nb, close, wrapx = 0, wrapy = 0, nactive = 0, nadd_particle = 0, nmove = 0, nsuccess = 0,
tracer_n, traj_position = 0, traj_length = 0, move = 0, old, m0, floor, nthermo;
tracer_n[N_TRACER_PARTICLES], traj_position = 0, traj_length = 0, move = 0, old, m0, floor, nthermo, wall = 0;
static int imin, imax;
static short int first = 1;
t_particle *particle;
@ -541,7 +592,7 @@ void animation()
particle = (t_particle *)malloc(NMAXCIRCLES*sizeof(t_particle)); /* particles */
if (ADD_FIXED_OBSTACLES) obstacle = (t_obstacle *)malloc(NMAXOBSTACLES*sizeof(t_obstacle)); /* obstacles */
if (TRACER_PARTICLE) trajectory = (t_tracer *)malloc(TRAJECTORY_LENGTH*sizeof(t_tracer));
if (TRACER_PARTICLE) trajectory = (t_tracer *)malloc(TRAJECTORY_LENGTH*N_TRACER_PARTICLES*sizeof(t_tracer));
hashgrid = (t_hashgrid *)malloc(HASHX*HASHY*sizeof(t_hashgrid)); /* hashgrid */
@ -558,12 +609,14 @@ void animation()
init_hashgrid(hashgrid);
xshift = OBSTACLE_XMIN;
if (ADD_FIXED_OBSTACLES) init_obstacle_config(obstacle);
if (RECORD_PRESSURES) for (i=0; i<N_PRESSURES; i++) pressure[i] = 0.0;
nactive = initialize_configuration(particle, hashgrid, obstacle, px, py, pangle);
printf("1\n");
nactive = initialize_configuration(particle, hashgrid, obstacle, px, py, pangle, tracer_n);
// xi = 0.0;
@ -609,6 +662,9 @@ void animation()
xmincontainer = obstacle_schedule_smooth(i, n);
xshift = xmincontainer;
}
if (INCREASE_GRAVITY) gravity = gravity_schedule(i,n);
if ((BOUNDARY_COND == BC_RECTANGLE_WALL)&&(i < INITIAL_TIME + WALL_TIME)) wall = 1;
else wall = 0;
compute_relative_positions(particle, hashgrid);
update_hashgrid(particle, hashgrid, 0);
@ -624,10 +680,11 @@ void animation()
compute_particle_force(j, krepel, particle, hashgrid);
/* take care of boundary conditions */
fboundary += compute_boundary_force(j, particle, obstacle, xmincontainer, xmaxcontainer, &pleft, &pright, pressure);
fboundary += compute_boundary_force(j, particle, obstacle, xmincontainer, xmaxcontainer, &pleft, &pright, pressure, wall);
/* add gravity */
particle[j].fy -= GRAVITY;
if (INCREASE_GRAVITY) particle[j].fy -= gravity;
else particle[j].fy -= GRAVITY;
if (FLOOR_FORCE)
{
@ -645,12 +702,17 @@ void animation()
/* evolution of lid coordinate */
if (BOUNDARY_COND == BC_RECTANGLE_LID) evolve_lid(fboundary);
if (BOUNDARY_COND == BC_RECTANGLE_WALL)
{
if (i < INITIAL_TIME + WALL_TIME) evolve_wall(fboundary);
else xwall = 0.0;
}
} /* end of for (n=0; n<NVID; n++) */
// if ((PARTIAL_THERMO_COUPLING))
if ((PARTIAL_THERMO_COUPLING)&&(i>N_T_AVERAGE))
{
nthermo = partial_thermostat_coupling(particle, xshift + OBSTACLE_RADIUS);
nthermo = partial_thermostat_coupling(particle, xshift + PARTIAL_THERMO_SHIFT);
printf("%i particles coupled to thermostat out of %i active\n", nthermo, nactive);
mean_energy = compute_mean_energy(particle);
}
@ -673,10 +735,13 @@ void animation()
/* update tracer particle trajectory */
if ((TRACER_PARTICLE)&&(i > INITIAL_TIME))
if ((TRACER_PARTICLE)&&(i > INITIAL_TIME))
{
trajectory[traj_position].xc = particle[tracer_n].xc;
trajectory[traj_position].yc = particle[tracer_n].yc;
for (j=0; j<N_TRACER_PARTICLES; j++)
{
trajectory[j*TRAJECTORY_LENGTH + traj_position].xc = particle[tracer_n[j]].xc;
trajectory[j*TRAJECTORY_LENGTH + traj_position].yc = particle[tracer_n[j]].yc;
}
traj_position++;
if (traj_position >= TRAJECTORY_LENGTH) traj_position = 0;
traj_length++;
@ -688,6 +753,7 @@ void animation()
printf("Mean kinetic energy: %.3f\n", totalenergy/(double)ncircles);
printf("Boundary force: %.3f\n", fboundary/(double)(ncircles*NVID));
if (RESAMPLE_Y) printf("%i succesful moves out of %i trials\n", nsuccess, nmove);
if (INCREASE_GRAVITY) printf("Gravity: %.3f\n", gravity);
total_neighbours = 0;
min_nb = 100;
@ -704,7 +770,7 @@ void animation()
if (TRACER_PARTICLE) draw_trajectory(trajectory, traj_position, traj_length);
draw_particles(particle, PLOT);
draw_container(xmincontainer, xmaxcontainer, obstacle);
draw_container(xmincontainer, xmaxcontainer, obstacle, wall);
/* add a particle */
if ((ADD_PARTICLES)&&((i - INITIAL_TIME - ADD_TIME + 1)%ADD_PERIOD == 0)&&(i < NSTEPS - FINAL_NOADD_PERIOD))
@ -713,11 +779,12 @@ void animation()
update_hashgrid(particle, hashgrid, 1);
print_parameters(beta, mean_energy, krepel, xmaxcontainer - xmincontainer,
fboundary/(double)(ncircles*NVID), 1, pressure);
if (BOUNDARY_COND == BC_EHRENFEST) print_ehrenfest_parameters(particle, pleft, pright);
fboundary/(double)(ncircles*NVID), 0, pressure, gravity);
if ((BOUNDARY_COND == BC_EHRENFEST)||(BOUNDARY_COND == BC_RECTANGLE_WALL))
print_ehrenfest_parameters(particle, pleft, pright);
else if (PRINT_PARTICLE_NUMBER) print_particle_number(ncircles);
if (PRINT_ENTROPY)
if ((i > INITIAL_TIME + WALL_TIME)&&(PRINT_ENTROPY))
{
compute_entropy(particle, entropy);
printf("Entropy 1 = %.5lg, Entropy 2 = %.5lg\n", entropy[0], entropy[1]);
@ -744,9 +811,9 @@ void animation()
{
if (TRACER_PARTICLE) draw_trajectory(trajectory, traj_position, traj_length);
draw_particles(particle, PLOT_B);
draw_container(xmincontainer, xmaxcontainer, obstacle);
draw_container(xmincontainer, xmaxcontainer, obstacle, wall);
print_parameters(beta, mean_energy, krepel, xmaxcontainer - xmincontainer,
fboundary/(double)(ncircles*NVID), 0, pressure);
fboundary/(double)(ncircles*NVID), 0, pressure, gravity);
if (BOUNDARY_COND == BC_EHRENFEST) print_ehrenfest_parameters(particle, pleft, pright);
else if (PRINT_PARTICLE_NUMBER) print_particle_number(ncircles);
glutSwapBuffers();
@ -772,9 +839,9 @@ void animation()
{
if (TRACER_PARTICLE) draw_trajectory(trajectory, traj_position, traj_length);
draw_particles(particle, PLOT);
draw_container(xmincontainer, xmaxcontainer, obstacle);
draw_container(xmincontainer, xmaxcontainer, obstacle, wall);
print_parameters(beta, mean_energy, krepel, xmaxcontainer - xmincontainer,
fboundary/(double)(ncircles*NVID), 0, pressure);
fboundary/(double)(ncircles*NVID), 0, pressure, gravity);
if (BOUNDARY_COND == BC_EHRENFEST) print_ehrenfest_parameters(particle, pleft, pright);
else if (PRINT_PARTICLE_NUMBER) print_particle_number(ncircles);
glutSwapBuffers();
@ -784,9 +851,9 @@ void animation()
{
if (TRACER_PARTICLE) draw_trajectory(trajectory, traj_position, traj_length);
draw_particles(particle, PLOT_B);
draw_container(xmincontainer, xmaxcontainer, obstacle);
draw_container(xmincontainer, xmaxcontainer, obstacle, wall);
print_parameters(beta, mean_energy, krepel, xmaxcontainer - xmincontainer,
fboundary/(double)(ncircles*NVID), 0, pressure);
fboundary/(double)(ncircles*NVID), 0, pressure, gravity);
if (BOUNDARY_COND == BC_EHRENFEST) print_ehrenfest_parameters(particle, pleft, pright);
else if (PRINT_PARTICLE_NUMBER) print_particle_number(ncircles);
glutSwapBuffers();

View File

@ -173,6 +173,8 @@
#define SCALE 0 /* set to 1 to adjust color scheme to variance of field */
#define SLOPE 1.0 /* sensitivity of color on wave amplitude */
#define PHASE_FACTOR 1.0 /* factor in computation of phase in color scheme P_3D_PHASE */
#define PHASE_SHIFT 0.0 /* shift of phase in color scheme P_3D_PHASE */
#define ATTENUATION 0.0 /* exponential attenuation coefficient of contrast with time */
#define E_SCALE 2500.0 /* scaling factor for energy representation */
#define LOG_SCALE 1.0 /* scaling factor for energy log representation */

View File

@ -3,7 +3,7 @@
/* when referencing other hashgrid cells or particles */
int bc_grouped(int bc)
/* regroup boundary conditions by type: rectangular = 0, periodic = 1, Klein = 2, Boy = 3, ... */
/* regroup boundary conditions by type: rectangular = 0, periodic = 1, Klein = 2, Boy = 3, L shape = 4, ... */
{
switch (bc) {
case (BC_SCREEN): return(0);
@ -14,11 +14,17 @@ int bc_grouped(int bc)
case (BC_EHRENFEST): return(0);
case (BC_PERIODIC_FUNNEL): return(1);
case (BC_RECTANGLE_LID): return(0);
case (BC_RECTANGLE_WALL): return(0);
case (BC_PERIODIC_TRIANGLE): return(1);
case (BC_KLEIN): return(2);
case (BC_SCREEN_BINS): return(0);
case (BC_BOY): return(3);
default: return(-1);
case (BC_GENUS_TWO): return(4);
default:
{
printf("Warning: Hashgrid will not be properly initialised, update bc_grouped()\n\n");
return(-1);
}
}
}
@ -236,20 +242,130 @@ void init_hashgrid(t_hashgrid hashgrid[HASHX*HASHY])
break;
}
case(4): /* genus 2 (L-shape) b.c. */
{
if ((HASHX%2 == 1)||(HASHY%2 == 1))
{
printf("Error: HASHX and HASHY must be even for this boundary condition\n");
exit(0);
}
/* dummy value for unused cells */
for (i=HASHX/2; i<HASHX; i++) for (j=HASHY/2; j<HASHY; j++) hashgrid[mhash(i, j)].nneighb = 0;
/* left boundary */
for (j=0; j<HASHY; j++)
{
hashgrid[mhash(0, j)].nneighb = 9;
for (p=-1; p<2; p++) for (q=-1; q<2; q++)
{
j1 = (j+q+HASHY)%HASHY;
if (j1 < HASHY/2) i1 = (p+HASHX)%HASHX;
else i1 = (p+HASHX/2)%(HASHX/2);
hashgrid[mhash(0, j)].neighbour[3*(p+1)+q+1] = mhash(i1, j1);
}
}
/* right boundary */
for (j=0; j<HASHY; j++)
{
if (j < HASHY/2)
{
hashgrid[mhash(HASHX-1, j)].nneighb = 9;
for (p=-1; p<2; p++) for (q=-1; q<2; q++)
{
j1 = (j+q+HASHY)%HASHY;
if (j1 < HASHY/2) i1 = (HASHX-1+p)%HASHX;
else i1 = (HASHX/2-1+p)%(HASHX/2);
hashgrid[mhash(HASHX-1,j)].neighbour[3*(p+1)+q+1] = mhash(i1, j1);
}
}
else
{
hashgrid[mhash(HASHX/2-1, j)].nneighb = 9;
// hashgrid[mhash(HASHX-1, j)].nneighb = 0; /* dummy value for unused boundary */
for (p=-1; p<2; p++) for (q=-1; q<2; q++)
{
j1 = (j+q+HASHY)%HASHY;
if (j1 < HASHY/2) i1 = (HASHX-1+p)%HASHX;
else i1 = (HASHX/2-1+p)%(HASHX/2);
hashgrid[mhash(HASHX/2-1, j)].neighbour[3*(p+1)+q+1] = mhash(i1, j1);
}
}
}
/* bottom boundary */
for (i=1; i<HASHX-1; i++)
{
hashgrid[mhash(i, 0)].nneighb = 9;
for (p=-1; p<2; p++) for (q=-1; q<2; q++)
{
i1 = (i+p+HASHX)%HASHX;
if (i1 < HASHX/2) j1 = (q+HASHY)%HASHY;
else j1 = (q+HASHY/2)%(HASHY/2);
hashgrid[mhash(i,0)].neighbour[3*(p+1)+q+1] = mhash(i1, j1);
}
}
/* top boundary */
for (i=1; i<HASHX-1; i++)
{
if (i < HASHX/2)
{
hashgrid[mhash(i, HASHY-1)].nneighb = 9;
for (p=-1; p<2; p++) for (q=-1; q<2; q++)
{
i1 = (i+p+HASHX/2)%(HASHX/2);
if (i1 < HASHX/2) j1 = (HASHY-1+q)%HASHY;
else j1 = (HASHY/2-1+q)%(HASHY/2);
hashgrid[mhash(i, HASHY-1)].neighbour[3*(p+1)+q+1] = mhash(i1, j1);
}
}
else
{
hashgrid[mhash(i, HASHY/2-1)].nneighb = 9;
// hashgrid[mhash(i, HASHY-1)].nneighb = 0; /* dummy value for unused boundary */
for (p=-1; p<2; p++) for (q=-1; q<2; q++)
{
i1 = (i+p+HASHX)%HASHX;
if (i1 < HASHX/2) j1 = (HASHY-1+q)%HASHY;
else j1 = (HASHY/2-1+q)%(HASHY/2);
hashgrid[mhash(i, HASHY/2-1)].neighbour[3*(p+1)+q+1] = mhash(i1, j1);
}
}
}
/* TO DO : add more cells for "corners" ? */
break;
}
default: /* do nothing */;
}
// for (i=0; i<HASHX; i++) for (j=0; j<HASHY; j++)
// {
// for (k=0; k<hashgrid[mhash(i,j)].nneighb; k++)
// {
// m = hashgrid[mhash(i,j)].neighbour[k];
// p = m/HASHY;
// q = m%HASHY;
// printf("Grid cell (%i, %i) - neighbour %i = %i = (%i, %i)\n", i, j, k, m, p, q);
// }
for (i=0; i<HASHX; i++)
{
for (j=0; j<HASHY; j++)
{
for (k=0; k<hashgrid[mhash(i,j)].nneighb; k++)
{
m = hashgrid[mhash(i,j)].neighbour[k];
p = m/HASHY;
q = m%HASHY;
if (vabs((double)(p-i)) + vabs((double)(q-j)) > 2.0)
printf("Grid cell (%i, %i) - neighbour %i = %i = (%i, %i)\n", i, j, k, m, p, q);
}
// sleep(1);
// }
}
// sleep(1);
}
sleep(1);
}
void update_hashgrid(t_particle* particle, t_hashgrid* hashgrid, int verbose)
@ -428,6 +544,66 @@ int wrap_particle(t_particle* particle, double *px, double *py)
return(move);
break;
}
case (4): /* genus two (L-shaped domain) b.c. */
{
if ((x > 0.0)&&(y > 0.0))
{
if (x > y) y1 -= 0.5*(BCYMAX - BCYMIN);
else x1 -= 0.5*(BCXMAX - BCXMIN);
move++;
}
else
{
if (x < BCXMIN)
{
if (y < 0.0) x1 += BCXMAX - BCXMIN;
else x1 += 0.5*(BCXMAX - BCXMIN);
move++;
}
else
{
if ((y < 0.0)&&(x > BCXMAX))
{
x1 += BCXMIN - BCXMAX;
move++;
}
else if ((y >= 0.0)&&(x > 0.0)&&(x < OBSTACLE_RADIUS))
{
x1 += 0.5*(BCXMIN - BCXMAX);
move++;
}
}
if (y < BCYMIN)
{
if (x1 < 0.0) y1 += BCYMAX - BCYMIN;
else y1 += 0.5*(BCYMAX - BCYMIN);
move++;
}
else
{
if ((x1 < 0.0)&&(y > BCYMAX))
{
y1 += BCYMIN - BCYMAX;
move++;
}
else if ((x1 >= 0.0)&&(y > 0.0)&&(y < OBSTACLE_RADIUS))
{
y1 += 0.5*(BCYMIN - BCYMAX);
move++;
}
}
}
// if (move > 0) printf("Moved particle from (%.3lg, %.3lg) to (%.3lg, %.3lg)\n", x, y, x1, y1);
particle->xc = x1;
particle->yc = y1;
return(move);
break;
}
default:
{
/* do nothing */
@ -538,6 +714,36 @@ int verbose = 0;
}
break;
}
case (4): /* genus 2 (L-shaped) b.c. */
{
x3 = *x2;
y3 = *y2;
if ((x1 < 0.0)&&(y1 < 0.0))
{
if (dx > dxhalf) *x2 -= (BCXMAX - BCXMIN);
if (dy > dyhalf) *y2 -= (BCYMAX - BCYMIN);
}
else if ((x1 >= 0.0)&&(y1 < 0.0))
{
if (dx < -dxhalf) *x2 += (BCXMAX - BCXMIN);
if (dy > 0.5*dyhalf) *y2 -= 0.5*(BCYMAX - BCYMIN);
else if (dy < -0.5*dyhalf) *y2 += 0.5*(BCYMAX - BCYMIN);
}
else if ((x1 < 0.0)&&(y1 >= 0.0))
{
if (dy < -dyhalf) *y2 += BCYMAX - BCYMIN;
if (dx > 0.5*dxhalf) *x2 -= 0.5*(BCXMAX - BCXMIN);
else if (dx < -0.5*dxhalf) *x2 += 0.5*(BCXMAX - BCXMIN);
}
if ((verbose)&&(module2(*x2 - x1, *y2 - y1) > dyhalf))
{
printf("(x1,y1) = (%.3lg, %.3lg)\n", x1, y1);
printf("(x2,y2) = (%.3lg, %.3lg) ", x3, y3);
printf("-> (%.3lg, %.3lg)\n", *x2, *y2);
}
// printf("(x2,y2) = (%.3lg, %.3lg)\n", *x2, *y2);
break;
}
}
}

637
sub_lj.c
View File

@ -4,8 +4,9 @@
#include "colors_waves.c"
#define HUE_TYPE0 300.0 /* hue of particles of type 0 */
#define HUE_TYPE1 90.0 /* hue of particles of type 1 */
// #define HUE_TYPE0 260.0 /* hue of particles of type 0 */
// #define HUE_TYPE0 300.0 /* hue of particles of type 0 */
// #define HUE_TYPE1 90.0 /* hue of particles of type 1 */
int writetiff(char *filename, char *description, int x, int y, int width, int height, int compression)
{
@ -874,6 +875,21 @@ void init_obstacle_config(t_obstacle obstacle[NMAXOBSTACLES])
nobstacles = n;
break;
}
case (O_GENUS_TWO):
{
n = 0;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
{
obstacle[n].xc = BCXMIN + 0.5*((double)i)*(BCXMAX - BCXMIN);
obstacle[n].yc = BCYMIN + 0.5*((double)j)*(BCYMAX - BCYMIN);
obstacle[n].radius = OBSTACLE_RADIUS;
obstacle[n].active = 1;
n++;
}
nobstacles = n;
break;
}
default:
{
printf("Function init_obstacle_config not defined for this pattern \n");
@ -1341,13 +1357,19 @@ int compute_particle_interaction(int i, int k, double force[2], double *torque,
static double dxhalf = 0.5*(BCXMAX - BCXMIN), dyhalf = 0.5*(BCYMAX - BCYMIN);
int wwrapx, wwrapy;
if (BOUNDARY_COND == BC_GENUS_TWO)
{
dxhalf *= 0.75;
dyhalf *= 0.75;
}
x1 = particle[i].xc;
y1 = particle[i].yc;
x2 = particle[k].xc;
y2 = particle[k].yc;
wwrapx = ((BOUNDARY_COND == BC_KLEIN)||(BOUNDARY_COND == BC_BOY))&&(vabs(x2 - x1) > dxhalf);
wwrapy = (BOUNDARY_COND == BC_BOY)&&(vabs(y2 - y1) > dyhalf);
wwrapx = ((BOUNDARY_COND == BC_KLEIN)||(BOUNDARY_COND == BC_BOY)||(BOUNDARY_COND == BC_GENUS_TWO))&&(vabs(x2 - x1) > dxhalf);
wwrapy = ((BOUNDARY_COND == BC_BOY)||(BOUNDARY_COND == BC_GENUS_TWO))&&(vabs(y2 - y1) > dyhalf);
switch (particle[k].interaction) {
case (I_COULOMB):
@ -1460,6 +1482,8 @@ int compute_repelling_force(int i, int j, double force[2], double *torque, t_par
static double distmin = 10.0*((XMAX - XMIN)/HASHX + (YMAX - YMIN)/HASHY);
int interact, k;
if (BOUNDARY_COND == BC_GENUS_TWO) distmin *= 2.0;
k = particle[i].hashneighbour[j];
distance = module2(particle[i].deltax[j], particle[i].deltay[j]);
@ -1546,7 +1570,7 @@ int resample_particle(int n, int maxtrials, t_particle particle[NMAXCIRCLES])
{
success = 1;
x = particle[n].xc - MU*(double)rand()/RAND_MAX;
y = 0.9*(BCYMIN + (BCYMAX - BCYMIN)*(double)rand()/RAND_MAX);
y = 0.95*(BCYMIN + (BCYMAX - BCYMIN)*(double)rand()/RAND_MAX);
i = 0;
while ((success)&&(i<ncircles))
{
@ -1666,7 +1690,7 @@ double neighbour_color(int nnbg)
void compute_entropy(t_particle particle[NMAXCIRCLES], double entropy[2])
{
int i, nleft1 = 0, nleft2 = 0;
double p1, p2;
double p1, p2, x;
static int first = 1, ntot1 = 0, ntot2 = 0;
static double log2;
@ -1680,13 +1704,15 @@ void compute_entropy(t_particle particle[NMAXCIRCLES], double entropy[2])
for (i=0; i<ncircles; i++)
{
if (POSITION_Y_DEPENDENCE) x = particle[i].yc;
else x = particle[i].xc;
if (particle[i].type == 0)
{
if (particle[i].xc < 0.0) nleft1++;
if (x < 0.0) nleft1++;
}
else
{
if (particle[i].xc < 0.0) nleft2++;
if (x < 0.0) nleft2++;
}
}
p1 = (double)nleft1/(double)ntot1;
@ -1699,6 +1725,127 @@ void compute_entropy(t_particle particle[NMAXCIRCLES], double entropy[2])
else entropy[1] = -(p2*log(p2) + (1.0-p2)*log(1.0-p2)/log2);
}
void draw_one_particle_links(t_particle particle)
/* draw links of one particle */
{
int i, j, k;
double x1, x2, y1, y2, length, linkcolor,periodx, periody, xt1, yt1, xt2, yt2;
glLineWidth(LINK_WIDTH);
// if (particle.active)
// {
// radius = particle[j].radius;
for (k = 0; k < particle.hash_nneighb; k++)
{
x1 = particle.xc;
if (CENTER_VIEW_ON_OBSTACLE) x1 -= xshift;
y1 = particle.yc;
x2 = x1 + particle.deltax[k];
y2 = y1 + particle.deltay[k];
length = module2(particle.deltax[k], particle.deltay[k])/particle.radius;
if (COLOR_BONDS)
{
if (length < 1.5) linkcolor = 1.0;
else linkcolor = 1.0 - 0.75*(length - 1.5)/(NBH_DIST_FACTOR - 1.5);
glColor3f(linkcolor, linkcolor, linkcolor);
}
if (length < 1.0*NBH_DIST_FACTOR) draw_line(x1, y1, x2, y2);
}
// {
// draw_line(x1, y1, x2, y2);
/* in case of periodic b.c., draw translates of particles */
// if (PERIODIC_BC)
// {
// for (i=-1; i<2; i++)
// for (j=-1; j<2; j++)
// draw_line(x1 + (double)i*(BCXMAX - BCXMIN), y1 + (double)j*(BCYMAX - BCYMIN), x2 + (double)i*(BCXMAX - BCXMIN), y2 + (double)j*(BCYMAX - BCYMIN));
// }
// else if (BOUNDARY_COND == BC_KLEIN)
// {
// x1 = particle[j].xc;
// y1 = particle[j].yc;
//
// for (i=-2; i<3; i++)
// {
// if (vabs(i) == 1) sign = -1.0;
// else sign = 1.0;
// angle1 = angle*sign;
// for (k=-1; k<2; k++)
// draw_one_particle(particle[j], x1 + (double)i*(BCXMAX - BCXMIN), sign*(y1 + (double)k*(BCYMAX - BCYMIN)),
// radius, angle1, nsides, width, rgb);
// }
// }
// else if (BOUNDARY_COND == BC_BOY)
// {
// x1 = particle[j].xc;
// y1 = particle[j].yc;
//
// for (i=-1; i<2; i++) for (k=-1; k<2; k++)
// {
// if (vabs(i) == 1) sign = -1.0;
// else sign = 1.0;
// if (vabs(k) == 1) signy = -1.0;
// else signy = 1.0;
// if (signy == 1.0) angle1 = angle*sign;
// else angle1 = PI - angle;
// if (sign == -1.0) draw_one_particle(particle[j], signy*(x1 + (double)i*(BCXMAX - BCXMIN)),
// sign*(y1 + (double)k*(BCYMAX - BCYMIN)), radius, angle1, nsides, width, rgbx);
// else if (signy == -1.0) draw_one_particle(particle[j], signy*(x1 + (double)i*(BCXMAX - BCXMIN)),
// sign*(y1 + (double)k*(BCYMAX - BCYMIN)), radius, angle1, nsides, width, rgby);
// else draw_one_particle(particle[j], signy*(x1 + (double)i*(BCXMAX - BCXMIN)),
// sign*(y1 + (double)k*(BCYMAX - BCYMIN)), radius, angle1, nsides, width, rgb);
// }
// }
// else if (BOUNDARY_COND == BC_GENUS_TWO)
// {
// if (x1 < 0.0) periody = BCYMAX - BCYMIN;
// else periody = 0.5*(BCYMAX - BCYMIN);
//
// if (y1 < 0.0) periodx = BCXMAX - BCXMIN;
// else periodx = 0.5*(BCXMAX - BCXMIN);
// if ((x1 < 0.0)&&(y1 < 0.0))
// for (i=-1; i<2; i++)
// for (j=-1; j<2; j++)
// {
// xt1 = x1 + (double)i*periodx;
// yt1 = y1 + (double)j*periody;
// xt2 = x2 + (double)i*periodx;
// yt2 = y2 + (double)j*periody;
// draw_line(xt1, yt1, xt2, yt2);
// }
// else if ((x1 < 0.0)&&(y1 >= 0.0))
// for (i=-1; i<2; i++)
// for (j=-1; j<2; j++)
// {
// xt1 = x1 + (double)i*periodx;
// yt1 = y1 + (double)j*periody;
// xt2 = x2 + (double)i*periodx;
// yt2 = y2 + (double)j*periody;
// draw_line(xt1, yt1, xt2, yt2);
// }
// else if ((x1 >= 0.0)&&(y1 < 0.0))
// for (i=-1; i<2; i++)
// for (j=-1; j<2; j++)
// {
// xt1 = x1 + (double)i*periodx;
// yt1 = y1 + (double)j*periody;
// xt2 = x2 + (double)i*periodx;
// yt2 = y2 + (double)j*periody;
// draw_line(xt1, yt1, xt2, yt2);
// }
// }
// }
// }
// sprintf(message, "%i - %i", particle[j].hash_nneighb, particle[j].hashcell);
// write_text(particle[j].xc, particle[j].yc, message);
// }
}
void draw_one_particle(t_particle particle, double xc, double yc, double radius, double angle, int nsides, double width, double rgb[3])
/* draw one of the particles */
@ -1753,58 +1900,67 @@ void draw_one_particle(t_particle particle, double xc, double yc, double radius,
}
void draw_trajectory(t_tracer trajectory[TRAJECTORY_LENGTH], int traj_position, int traj_length)
void draw_trajectory(t_tracer trajectory[TRAJECTORY_LENGTH*N_TRACER_PARTICLES], int traj_position, int traj_length)
/* draw tracer particle trajectory */
{
int i, time;
int i, j, time;
double x1, x2, y1, y2, rgb[3], lum;
blank();
glLineWidth(TRAJECTORY_WIDTH);
hsl_to_rgb(70.0, 0.9, 0.5, rgb);
glColor3f(rgb[0], rgb[1], rgb[2]);
printf("drawing trajectory\n");
if (traj_length < TRAJECTORY_LENGTH)
for (i=0; i < traj_length-1; i++)
{
x1 = trajectory[i].xc;
x2 = trajectory[i+1].xc;
y1 = trajectory[i].yc;
y2 = trajectory[i+1].yc;
time = traj_length - i;
lum = 1.0 - (double)time/(double)TRAJECTORY_LENGTH;
glColor3f(lum*rgb[0], lum*rgb[1], lum*rgb[2]);
if (module2(x2 - x1, y2 - y1) < 0.25*(YMAX - YMIN)) draw_line(x1, y1, x2, y2);
}
else
for (j=0; j<N_TRACER_PARTICLES; j++)
{
for (i = traj_position + 1; i < traj_length-1; i++)
if (j == 0) hsl_to_rgb(HUE_TYPE1, 0.9, 0.5, rgb);
else if (j == 1) hsl_to_rgb(HUE_TYPE2, 0.9, 0.5, rgb);
else hsl_to_rgb(HUE_TYPE3, 0.9, 0.5, rgb);
glColor3f(rgb[0], rgb[1], rgb[2]);
if (traj_length < TRAJECTORY_LENGTH)
for (i=0; i < traj_length-1; i++)
{
x1 = trajectory[j*TRAJECTORY_LENGTH + i].xc;
x2 = trajectory[j*TRAJECTORY_LENGTH + i+1].xc;
y1 = trajectory[j*TRAJECTORY_LENGTH + i].yc;
y2 = trajectory[j*TRAJECTORY_LENGTH + i+1].yc;
time = traj_length - i;
lum = 1.0 - (double)time/(double)TRAJECTORY_LENGTH;
glColor3f(lum*rgb[0], lum*rgb[1], lum*rgb[2]);
if (module2(x2 - x1, y2 - y1) < 0.25*(YMAX - YMIN)) draw_line(x1, y1, x2, y2);
// printf("(x1, y1) = (%.3lg, %.3lg), (x2, y2) = (%.3lg, %.3lg)\n", x1, y1, x2, y2);
}
else
{
x1 = trajectory[i].xc;
x2 = trajectory[i+1].xc;
y1 = trajectory[i].yc;
y2 = trajectory[i+1].yc;
for (i = traj_position + 1; i < traj_length-1; i++)
{
x1 = trajectory[j*TRAJECTORY_LENGTH + i].xc;
x2 = trajectory[j*TRAJECTORY_LENGTH + i+1].xc;
y1 = trajectory[j*TRAJECTORY_LENGTH + i].yc;
y2 = trajectory[j*TRAJECTORY_LENGTH + i+1].yc;
time = traj_position + traj_length - i;
lum = 1.0 - (double)time/(double)TRAJECTORY_LENGTH;
glColor3f(lum*rgb[0], lum*rgb[1], lum*rgb[2]);
time = traj_position + traj_length - i;
lum = 1.0 - (double)time/(double)TRAJECTORY_LENGTH;
glColor3f(lum*rgb[0], lum*rgb[1], lum*rgb[2]);
if (module2(x2 - x1, y2 - y1) < 0.1*(YMAX - YMIN)) draw_line(x1, y1, x2, y2);
}
for (i=0; i < traj_position-1; i++)
{
x1 = trajectory[i].xc;
x2 = trajectory[i+1].xc;
y1 = trajectory[i].yc;
y2 = trajectory[i+1].yc;
if (module2(x2 - x1, y2 - y1) < 0.1*(YMAX - YMIN)) draw_line(x1, y1, x2, y2);
}
for (i=0; i < traj_position-1; i++)
{
x1 = trajectory[j*TRAJECTORY_LENGTH + i].xc;
x2 = trajectory[j*TRAJECTORY_LENGTH + i+1].xc;
y1 = trajectory[j*TRAJECTORY_LENGTH + i].yc;
y2 = trajectory[j*TRAJECTORY_LENGTH + i+1].yc;
time = traj_position - i;
lum = 1.0 - (double)time/(double)TRAJECTORY_LENGTH;
glColor3f(lum*rgb[0], lum*rgb[1], lum*rgb[2]);
time = traj_position - i;
lum = 1.0 - (double)time/(double)TRAJECTORY_LENGTH;
glColor3f(lum*rgb[0], lum*rgb[1], lum*rgb[2]);
if (module2(x2 - x1, y2 - y1) < 0.1*(YMAX - YMIN)) draw_line(x1, y1, x2, y2);
if (module2(x2 - x1, y2 - y1) < 0.1*(YMAX - YMIN)) draw_line(x1, y1, x2, y2);
}
}
}
}
@ -1813,7 +1969,7 @@ void draw_trajectory(t_tracer trajectory[TRAJECTORY_LENGTH], int traj_position,
void draw_particles(t_particle particle[NMAXCIRCLES], int plot)
{
int i, j, k, m, width, nnbg, nsides;
double ej, hue, huex, huey, rgb[3], rgbx[3], rgby[3], radius, x1, y1, x2, y2, angle, ca, sa, length, linkcolor, sign = 1.0, angle1, signy = 1.0;
double ej, hue, huex, huey, rgb[3], rgbx[3], rgby[3], radius, x1, y1, x2, y2, angle, ca, sa, length, linkcolor, sign = 1.0, angle1, signy = 1.0, periodx, periody, x, y;
char message[100];
if (!TRACER_PARTICLE) blank();
@ -1823,32 +1979,33 @@ void draw_particles(t_particle particle[NMAXCIRCLES], int plot)
if (plot == P_BONDS)
{
glLineWidth(LINK_WIDTH);
for (j=0; j<ncircles; j++) if (particle[j].active)
{
// radius = particle[j].radius;
for (k = 0; k < particle[j].hash_nneighb; k++)
{
x1 = particle[j].xc;
y1 = particle[j].yc;
x2 = x1 + particle[j].deltax[k];
y2 = y1 + particle[j].deltay[k];
length = module2(particle[j].deltax[k], particle[j].deltay[k])/particle[j].radius;
if (COLOR_BONDS)
{
if (length < 1.5) linkcolor = 1.0;
else linkcolor = 1.0 - 0.75*(length - 1.5)/(NBH_DIST_FACTOR - 1.5);
glColor3f(linkcolor, linkcolor, linkcolor);
}
if (length < 1.0*NBH_DIST_FACTOR)
draw_line(x1, y1, x2, y2);
}
// sprintf(message, "%i - %i", particle[j].hash_nneighb, particle[j].hashcell);
// write_text(particle[j].xc, particle[j].yc, message);
}
for (j=0; j<ncircles; j++) if (particle[j].active) draw_one_particle_links(particle[j]);
// if (0) {
// // radius = particle[j].radius;
// for (k = 0; k < particle[j].hash_nneighb; k++)
// {
// x1 = particle[j].xc;
// if (CENTER_VIEW_ON_OBSTACLE) x1 -= xshift;
// y1 = particle[j].yc;
// x2 = x1 + particle[j].deltax[k];
// y2 = y1 + particle[j].deltay[k];
//
// length = module2(particle[j].deltax[k], particle[j].deltay[k])/particle[j].radius;
//
// // if (COLOR_BONDS)
// // {
// // if (length < 1.5) linkcolor = 1.0;
// // else linkcolor = 1.0 - 0.75*(length - 1.5)/(NBH_DIST_FACTOR - 1.5);
// // glColor3f(linkcolor, linkcolor, linkcolor);
// // }
//
// if (length < 2.0*NBH_DIST_FACTOR)
// draw_line(x1, y1, x2, y2);
// }
//
// // sprintf(message, "%i - %i", particle[j].hash_nneighb, particle[j].hashcell);
// // write_text(particle[j].xc, particle[j].yc, message);
// }
}
/* determine particle color and size */
@ -1907,8 +2064,10 @@ void draw_particles(t_particle particle[NMAXCIRCLES], int plot)
{
// if (particle[j].type == 0) hue = 310.0;
// else hue = 70.0;
if (particle[j].type == 0) hue = HUE_TYPE0;
else hue = HUE_TYPE1;
if (particle[j].type <= 1) hue = HUE_TYPE0;
else if (particle[j].type == 2) hue = HUE_TYPE1;
else if (particle[j].type == 3) hue = HUE_TYPE2;
else hue = HUE_TYPE3;
radius = particle[j].radius;
width = BOUNDARY_WIDTH;
break;
@ -2037,6 +2196,44 @@ void draw_particles(t_particle particle[NMAXCIRCLES], int plot)
sign*(y1 + (double)k*(BCYMAX - BCYMIN)), radius, angle1, nsides, width, rgb);
}
}
else if (BOUNDARY_COND == BC_GENUS_TWO)
{
x1 = particle[j].xc;
y1 = particle[j].yc;
if (x1 < 0.0) periody = BCYMAX - BCYMIN;
else periody = 0.5*(BCYMAX - BCYMIN);
if (y1 < 0.0) periodx = BCXMAX - BCXMIN;
else periodx = 0.5*(BCXMAX - BCXMIN);
if ((x1 < 0.0)&&(y1 < 0.0))
for (i=-1; i<2; i++)
for (k=-1; k<2; k++)
{
x = x1 + (double)i*periodx;
y = y1 + (double)k*periody;
draw_one_particle(particle[j], x, y, radius, angle, nsides, width, rgb);
}
else if ((x1 < 0.0)&&(y1 >= 0.0))
for (i=-1; i<2; i++)
for (k=-1; k<2; k++)
{
x = x1 + (double)i*periodx;
y = y1 + (double)k*periody;
if (x < 1.2*particle[j].radius)
draw_one_particle(particle[j], x, y, radius, angle, nsides, width, rgb);
}
else if ((x1 >= 0.0)&&(y1 < 0.0))
for (i=-1; i<2; i++)
for (k=-1; k<2; k++)
{
x = x1 + (double)i*periodx;
y = y1 + (double)k*periody;
if (y < 1.2*particle[j].radius)
draw_one_particle(particle[j], x, y, radius, angle, nsides, width, rgb);
}
}
}
// /* draw spin vectors */
@ -2060,13 +2257,25 @@ void draw_particles(t_particle particle[NMAXCIRCLES], int plot)
}
void draw_container(double xmin, double xmax, t_obstacle obstacle[NMAXOBSTACLES])
void draw_container(double xmin, double xmax, t_obstacle obstacle[NMAXOBSTACLES], int wall)
/* draw the container, for certain boundary conditions */
{
int i, j;
double rgb[3], x, phi, angle, dx, dy, ybin, x1, x2, h;
char message[100];
/* draw fixed obstacles */
if (ADD_FIXED_OBSTACLES)
{
glLineWidth(CONTAINER_WIDTH);
hsl_to_rgb(300.0, 0.1, 0.5, rgb);
for (i = 0; i < nobstacles; i++)
draw_colored_circle(obstacle[i].xc, obstacle[i].yc, obstacle[i].radius, NSEG, rgb);
glColor3f(1.0, 1.0, 1.0);
for (i = 0; i < nobstacles; i++)
draw_circle(obstacle[i].xc, obstacle[i].yc, obstacle[i].radius, NSEG);
}
switch (BOUNDARY_COND) {
case (BC_SCREEN):
{
@ -2078,18 +2287,18 @@ void draw_container(double xmin, double xmax, t_obstacle obstacle[NMAXOBSTACLES]
glColor3f(1.0, 1.0, 1.0);
glLineWidth(CONTAINER_WIDTH);
draw_line(INITXMIN, INITYMIN, INITXMAX, INITYMIN);
draw_line(INITXMIN, INITYMAX, INITXMAX, INITYMAX);
draw_line(BCXMIN, BCYMIN, BCXMAX, BCYMIN);
draw_line(BCXMIN, BCYMAX, BCXMAX, BCYMAX);
if (!SYMMETRIC_DECREASE) draw_line(INITXMAX, INITYMIN, INITXMAX, INITYMAX);
if (!SYMMETRIC_DECREASE) draw_line(BCXMAX, BCYMIN, BCXMAX, BCYMAX);
draw_line(xmin, INITYMIN, xmin, INITYMAX);
draw_line(XMIN, 0.5*(INITYMIN + INITYMAX), xmin, 0.5*(INITYMIN + INITYMAX));
draw_line(xmin, BCYMIN, xmin, BCYMAX);
// draw_line(XMIN, 0.5*(BCYMIN + BCYMAX), xmin, 0.5*(BCYMIN + BCYMAX));
if (SYMMETRIC_DECREASE)
{
draw_line(xmax, INITYMIN, xmax, INITYMAX);
draw_line(XMAX, 0.5*(INITYMIN + INITYMAX), xmax, 0.5*(INITYMIN + INITYMAX));
draw_line(xmax, BCYMIN, xmax, BCYMAX);
draw_line(XMAX, 0.5*(BCYMIN + BCYMAX), xmax, 0.5*(BCYMIN + BCYMAX));
}
break;
@ -2151,8 +2360,8 @@ void draw_container(double xmin, double xmax, t_obstacle obstacle[NMAXOBSTACLES]
draw_triangle(x1, 0.0, x2, h, x2, -h);
glColor3f(0.0, 0.0, 0.0);
sprintf(message, "Mach %.2f", xspeed/20.0);
write_text(x-0.18, -0.025, message);
sprintf(message, "Mach %.2f", xspeed*3.0/40.0);
write_text(x-0.25, -0.025, message);
}
break;
}
@ -2194,6 +2403,26 @@ void draw_container(double xmin, double xmax, t_obstacle obstacle[NMAXOBSTACLES]
break;
}
case (BC_RECTANGLE_WALL):
{
glColor3f(1.0, 1.0, 1.0);
glLineWidth(CONTAINER_WIDTH);
draw_rectangle(BCXMIN, BCYMIN, BCXMAX, BCYMAX);
draw_line(0.5*(BCXMIN+BCXMAX), BCYMAX, 0.5*(BCXMIN+BCXMAX), BCYMAX + 0.5*WALL_WIDTH);
draw_line(0.5*(BCXMIN+BCXMAX), BCYMIN, 0.5*(BCXMIN+BCXMAX), BCYMIN - 0.5*WALL_WIDTH);
if (wall)
{
hsl_to_rgb(300.0, 0.1, 0.5, rgb);
draw_colored_rectangle(xwall - 0.5*WALL_WIDTH, BCYMIN + 0.025, xwall + 0.5*WALL_WIDTH, BCYMAX - 0.025, rgb);
glColor3f(1.0, 1.0, 1.0);
draw_rectangle(xwall - 0.5*WALL_WIDTH, BCYMIN + 0.025, xwall + 0.5*WALL_WIDTH, BCYMAX - 0.025);
}
break;
}
case (BC_EHRENFEST):
{
glLineWidth(CONTAINER_WIDTH);
@ -2228,21 +2457,29 @@ void draw_container(double xmin, double xmax, t_obstacle obstacle[NMAXOBSTACLES]
}
break;
}
case (BC_GENUS_TWO):
{
hsl_to_rgb(300.0, 0.1, 0.5, rgb);
draw_colored_rectangle(0.0, 0.0, BCXMAX, BCYMAX, rgb);
}
}
/* draw fixed obstacles */
if (ADD_FIXED_OBSTACLES)
{
glLineWidth(CONTAINER_WIDTH);
glColor3f(1.0, 1.0, 1.0);
for (i = 0; i < nobstacles; i++)
draw_circle(obstacle[i].xc, obstacle[i].yc, obstacle[i].radius, NSEG);
}
// /* draw fixed obstacles */
// if (ADD_FIXED_OBSTACLES)
// {
// glLineWidth(CONTAINER_WIDTH);
// hsl_to_rgb(300.0, 0.1, 0.5, rgb);
// for (i = 0; i < nobstacles; i++)
// draw_colored_circle(obstacle[i].xc, obstacle[i].yc, obstacle[i].radius, NSEG, rgb);
// glColor3f(1.0, 1.0, 1.0);
// for (i = 0; i < nobstacles; i++)
// draw_circle(obstacle[i].xc, obstacle[i].yc, obstacle[i].radius, NSEG);
// }
}
void print_parameters(double beta, double temperature, double krepel, double lengthcontainer, double boundary_force,
short int left, double pressure[N_PRESSURES])
short int left, double pressure[N_PRESSURES], double gravity)
{
char message[100];
int i, j, k;
@ -2409,8 +2646,15 @@ void print_parameters(double beta, double temperature, double krepel, double len
else glColor3f(0.0, 0.0, 0.0);
sprintf(message, "Temperature %.2f", mean_temp);
write_text(xtext, y, message);
}
if (INCREASE_GRAVITY)
{
erase_area_hsl(xmid, y + 0.025, 0.22, 0.05, 0.0, 0.9, 0.0);
glColor3f(1.0, 1.0, 1.0);
sprintf(message, "Gravity %.2f", gravity/GRAVITY);
write_text(xmidtext + 0.1, y, message);
}
}
@ -2418,13 +2662,13 @@ void print_ehrenfest_parameters(t_particle particle[NMAXCIRCLES], double pleft,
{
char message[100];
int i, j, nleft1 = 0, nleft2 = 0, nright1 = 0, nright2 = 0;
double density, hue, rgb[3], logratio, y, shiftx = 0.3;
double density, hue, rgb[3], logratio, y, shiftx = 0.3, xmidplus, xmidminus;
static double xleftbox, xlefttext, xmidbox, xmidtext, xrightbox, xrighttext, pressures[500][2], meanpressure[2];
static int first = 1, i_pressure, naverage = 500;
static int first = 1, i_pressure, naverage = 500, n_pressure;
if (first)
{
xleftbox = -1.0;
xleftbox = -0.85;
xlefttext = xleftbox - 0.5;
xrightbox = 1.0;
xrighttext = xrightbox - 0.45;
@ -2439,68 +2683,84 @@ void print_ehrenfest_parameters(t_particle particle[NMAXCIRCLES], double pleft,
pressures[i][1] = 0.0;
}
i_pressure = 0;
n_pressure = 0;
first = 0;
}
if (BOUNDARY_COND == BC_EHRENFEST)
{
xmidplus = 1.0 - EHRENFEST_RADIUS;
xmidminus = -1.0 + EHRENFEST_RADIUS;
}
else
{
xmidplus = xwall;
xmidminus = xwall;
}
/* table of pressures */
pressures[i_pressure][0] = pleft;
pressures[i_pressure][1] = pright;
i_pressure++;
if (i_pressure == naverage) i_pressure = 0;
if (n_pressure < naverage - 1) n_pressure++;
for (i=0; i<naverage; i++)
for (i=0; i<n_pressure; i++)
for (j=0; j<2; j++)
meanpressure[j] += pressures[i][j];
for (j=0; j<2; j++) meanpressure[j] = meanpressure[j]/(double)naverage;
for (j=0; j<2; j++) meanpressure[j] = meanpressure[j]/(double)n_pressure;
for (i = 0; i < ncircles; i++) if (particle[i].active)
{
if (particle[i].xc < -1.0 + EHRENFEST_RADIUS)
if (particle[i].xc < xmidminus)
{
if (particle[i].type == 0) nleft1++;
else nleft2++;
}
else if (particle[i].xc > 1.0 - EHRENFEST_RADIUS)
else if (particle[i].xc > xmidplus)
{
if (particle[i].type == 0) nright1++;
else nright2++;
}
}
y = YMIN + 0.1;
y = YMIN + 0.05;
erase_area_hsl(xleftbox - shiftx, y + 0.025, 0.22, 0.05, 0.0, 0.9, 0.0);
hsl_to_rgb(310.0, 0.9, 0.5, rgb);
hsl_to_rgb(HUE_TYPE0, 0.9, 0.5, rgb);
glColor3f(rgb[0], rgb[1], rgb[2]);
sprintf(message, "%i particles", nleft1);
write_text(xlefttext + 0.28 - shiftx, y, message);
erase_area_hsl(xleftbox + shiftx, y + 0.025, 0.22, 0.05, 0.0, 0.9, 0.0);
hsl_to_rgb(70.0, 0.9, 0.5, rgb);
hsl_to_rgb(HUE_TYPE1, 0.9, 0.5, rgb);
glColor3f(rgb[0], rgb[1], rgb[2]);
sprintf(message, "%i particles", nleft2);
write_text(xlefttext + 0.28 + shiftx, y, message);
erase_area_hsl(xrightbox - shiftx, y + 0.025, 0.22, 0.05, 0.0, 0.9, 0.0);
hsl_to_rgb(310.0, 0.9, 0.5, rgb);
hsl_to_rgb(HUE_TYPE0, 0.9, 0.5, rgb);
glColor3f(rgb[0], rgb[1], rgb[2]);
sprintf(message, "%i particles", nright1);
write_text(xrighttext + 0.28 - shiftx, y, message);
erase_area_hsl(xrightbox + shiftx, y + 0.025, 0.22, 0.05, 0.0, 0.9, 0.0);
hsl_to_rgb(70.0, 0.9, 0.5, rgb);
hsl_to_rgb(HUE_TYPE1, 0.9, 0.5, rgb);
glColor3f(rgb[0], rgb[1], rgb[2]);
sprintf(message, "%i particles", nright2);
write_text(xrighttext + 0.28 + shiftx, y, message);
y = YMAX - 0.1;
erase_area_hsl(xleftbox - 0.1, y + 0.025, 0.22, 0.05, 0.0, 0.9, 0.0);
glColor3f(1.0, 1.0, 1.0);
hsl_to_rgb_turbo(HUE_TYPE1, 0.9, 0.5, rgb);
glColor3f(rgb[0], rgb[1], rgb[2]);
sprintf(message, "Pressure %.2f", 0.001*meanpressure[0]/(double)ncircles);
write_text(xlefttext + 0.25, y, message);
erase_area_hsl(xrightbox - 0.1, y + 0.025, 0.22, 0.05, 0.0, 0.9, 0.0);
glColor3f(1.0, 1.0, 1.0);
hsl_to_rgb_turbo(HUE_TYPE0, 0.9, 0.5, rgb);
glColor3f(rgb[0], rgb[1], rgb[2]);
sprintf(message, "Pressure %.2f", 0.001*meanpressure[1]/(double)ncircles);
write_text(xrighttext + 0.2, y, message);
@ -2530,24 +2790,35 @@ void print_particle_number(int npart)
void print_entropy(double entropy[2])
{
char message[100];
double y = YMAX - 0.1, rgb[3];
static double xleftbox, xlefttext, xrightbox, xrighttext;
double rgb[3];
static double xleftbox, xlefttext, xrightbox, xrighttext, y = YMAX - 0.1, ymin = YMIN + 0.05;
static int first = 1;
if (first)
{
xleftbox = XMIN + 0.5;
xleftbox = XMIN + 0.4;
xlefttext = xleftbox - 0.55;
xrightbox = XMAX - 0.39;
xrighttext = xrightbox - 0.55;
first = 0;
}
erase_area_hsl(xleftbox, y + 0.025, 0.35, 0.05, 0.0, 0.9, 0.0);
hsl_to_rgb_turbo(HUE_TYPE1, 0.9, 0.5, rgb);
glColor3f(rgb[0], rgb[1], rgb[2]);
sprintf(message, "Entropy = %.4f", entropy[1]);
write_text(xlefttext + 0.28, y, message);
if (POSITION_Y_DEPENDENCE)
{
erase_area_hsl(xrightbox, ymin + 0.025, 0.35, 0.05, 0.0, 0.9, 0.0);
hsl_to_rgb_turbo(HUE_TYPE1, 0.9, 0.5, rgb);
glColor3f(rgb[0], rgb[1], rgb[2]);
sprintf(message, "Entropy = %.4f", entropy[1]);
write_text(xrighttext + 0.28, ymin, message);
}
else
{
erase_area_hsl(xleftbox, y + 0.025, 0.35, 0.05, 0.0, 0.9, 0.0);
hsl_to_rgb_turbo(HUE_TYPE1, 0.9, 0.5, rgb);
glColor3f(rgb[0], rgb[1], rgb[2]);
sprintf(message, "Entropy = %.4f", entropy[1]);
write_text(xlefttext + 0.28, y, message);
}
erase_area_hsl(xrightbox, y + 0.025, 0.35, 0.05, 0.0, 0.9, 0.0);
hsl_to_rgb_turbo(HUE_TYPE0, 0.9, 0.5, rgb);
@ -2559,11 +2830,11 @@ void print_entropy(double entropy[2])
double compute_boundary_force(int j, t_particle particle[NMAXCIRCLES], t_obstacle obstacle[NMAXOBSTACLES],
double xleft, double xright, double *pleft, double *pright, double pressure[N_PRESSURES])
double xleft, double xright, double *pleft, double *pright, double pressure[N_PRESSURES], int wall)
{
int i, k;
double xmin, xmax, ymin, ymax, padding, r, rp, r2, cphi, sphi,
f, fperp = 0.0, x, y, xtube, distance, dx, dy, width, ybin, angle, x1, x2, h, ytop, norm, dleft, dplus, dminus;
double xmin, xmax, ymin, ymax, padding, r, rp, r2, cphi, sphi, f, fperp = 0.0, x, y, xtube, distance, dx, dy,
width, ybin, angle, x1, x2, h, ytop, norm, dleft, dplus, dminus, tmp_pleft = 0.0, tmp_pright = 0.0;
/* compute force from fixed obstacles */
if (ADD_FIXED_OBSTACLES) for (i=0; i<nobstacles; i++)
@ -2724,12 +2995,12 @@ double compute_boundary_force(int j, t_particle particle[NMAXCIRCLES], t_obstacl
}
/* force from tip of triangle */
r = module2(particle[j].xc - x1, particle[j].yc);
if (r < padding)
if (r < 0.5*padding)
{
if (r < 1.0e-5) r = 1.0e-05;
cphi = (particle[j].xc - x1)/r;
sphi = particle[j].yc/r;
f = KSPRING_OBSTACLE*(padding - r);
f = KSPRING_OBSTACLE*(0.5*padding - r);
particle[j].fx += f*cphi;
particle[j].fy += f*sphi;
}
@ -2780,6 +3051,71 @@ double compute_boundary_force(int j, t_particle particle[NMAXCIRCLES], t_obstacl
}
return(fperp);
}
case (BC_RECTANGLE_WALL):
{
padding = particle[j].radius + 0.01;
xmin = BCXMIN + padding;
xmax = BCXMAX - padding;
ymin = BCYMIN + padding;
ymax = BCYMAX - padding;
if (particle[j].xc > xmax)
{
fperp = KSPRING_BOUNDARY*(particle[j].xc - xmax);
particle[j].fx -= fperp;
tmp_pright += fperp;
}
else if (particle[j].xc < xmin)
{
fperp = KSPRING_BOUNDARY*(xmin - particle[j].xc);
particle[j].fx += fperp;
tmp_pleft += fperp;
}
if (particle[j].yc > ymax)
{
fperp = KSPRING_BOUNDARY*(particle[j].yc - ymax);
particle[j].fy -= fperp;
if (particle[j].xc > xwall) tmp_pright += fperp;
else tmp_pleft += fperp;
}
else if (particle[j].yc < ymin)
{
fperp = KSPRING_BOUNDARY*(ymin - particle[j].yc);
particle[j].fy += fperp;
if (particle[j].xc > xwall) tmp_pright += fperp;
else tmp_pleft += fperp;
}
if (wall)
{
*pleft += tmp_pleft/(2.0*(BCYMAX - BCYMIN) + 2.0*(xwall - BCXMIN));
*pright += tmp_pright/(2.0*(BCYMAX - BCYMIN) + 2.0*(BCXMAX - xwall));
}
else
{
*pleft += tmp_pleft/(2.0*(BCYMAX - BCYMIN + BCXMAX - BCXMIN));
*pright += tmp_pright/(2.0*(BCYMAX - BCYMIN + BCXMAX - BCXMIN));
}
if ((wall)&&(vabs(particle[j].xc - xwall) < 0.5*WALL_WIDTH + padding))
{
if (particle[j].xc > xwall)
{
fperp = -KSPRING_BOUNDARY*(xwall + 0.5*WALL_WIDTH + padding - particle[j].xc);
particle[j].fx -= fperp;
*pright -= fperp/(BCYMAX - BCYMIN);
}
else
{
fperp = KSPRING_BOUNDARY*(particle[j].xc - xwall + 0.5*WALL_WIDTH + padding);
particle[j].fx -= fperp;
*pleft += fperp/(BCYMAX - BCYMIN);
}
return(fperp);
}
return(0.0);
}
case (BC_EHRENFEST):
{
rp = particle[j].radius;
@ -2916,11 +3252,11 @@ void compute_particle_force(int j, double krepel, t_particle particle[NMAXCIRCLE
int initialize_configuration(t_particle particle[NMAXCIRCLES], t_hashgrid hashgrid[HASHX*HASHY],
t_obstacle obstacle[NMAXOBSTACLES], double px[NMAXCIRCLES], double py[NMAXCIRCLES], double pangle[NMAXCIRCLES])
t_obstacle obstacle[NMAXOBSTACLES], double px[NMAXCIRCLES], double py[NMAXCIRCLES], double pangle[NMAXCIRCLES], int tracer_n[N_TRACER_PARTICLES])
/* initialize all particles, obstacles, and the hashgrid */
{
int i, j, k, n, tracer_n, nactive = 0;
double x, y, h;
int i, j, k, n, nactive = 0;
double x, y, h, xx, yy;
for (i=0; i < ncircles; i++)
{
@ -3045,24 +3381,32 @@ int initialize_configuration(t_particle particle[NMAXCIRCLES], t_hashgrid hashgr
}
/* change type of tracer particle */
if (TRACER_PARTICLE)
if (TRACER_PARTICLE) for (j=0; j<N_TRACER_PARTICLES; j++)
{
i = 0;
while ((!particle[i].active)||(module2(particle[i].xc, particle[i].yc) > 0.5)) i++;
tracer_n = i;
particle[tracer_n].type = 2;
particle[tracer_n].radius *= 1.5;
particle[tracer_n].mass_inv *= 1.0/TRACER_PARTICLE_MASS;
particle[tracer_n].vx *= 0.1;
particle[tracer_n].vy *= 0.1;
particle[tracer_n].thermostat = 0;
px[tracer_n] *= 0.1;
py[tracer_n] *= 0.1;
if (j%2==0) xx = 1.0;
else xx = -1.0;
if (j/2 == 0) yy = -0.5;
else yy = 0.5;
// if (j%2 == 1) yy = -yy;
// while ((!particle[i].active)||(module2(particle[i].xc, particle[i].yc) > 0.5)) i++;
while ((!particle[i].active)||(module2(particle[i].xc + xx, particle[i].yc - yy) > 0.4)) i++;
tracer_n[j] = i;
particle[i].type = 2 + j;
particle[i].radius *= 1.5;
particle[i].mass_inv *= 1.0/TRACER_PARTICLE_MASS;
particle[i].vx *= 0.1;
particle[i].vy *= 0.1;
particle[i].thermostat = 0;
px[i] *= 0.1;
py[i] *= 0.1;
}
/* position-dependent particle type */
if (POSITION_DEPENDENT_TYPE) for (i=0; i<ncircles; i++)
if (particle[i].xc < 0)
if (((!POSITION_Y_DEPENDENCE)&&(particle[i].xc < 0))||((POSITION_Y_DEPENDENCE)&&(particle[i].yc < 0)))
{
particle[i].type = 2;
particle[i].mass_inv = 1.0/PARTICLE_MASS_B;
@ -3091,7 +3435,7 @@ int initialize_configuration(t_particle particle[NMAXCIRCLES], t_hashgrid hashgr
{
h = 2.0*OBSTACLE_RADIUS*tan(APOLY*PID);
for (i=0; i< ncircles; i++)
if ((vabs(particle[i].xc) < OBSTACLE_RADIUS + 2.0*MU)
if ((vabs(particle[i].xc) < 1.1*OBSTACLE_RADIUS + 2.0*MU)
&&(2.0*OBSTACLE_RADIUS*vabs(particle[i].yc) < h*(OBSTACLE_RADIUS + 2.0*MU - particle[i].xc)))
{
printf("Inactivating particle at (%.3lg, %.3lg)\n", particle[i].xc, particle[i].yc);
@ -3104,6 +3448,21 @@ int initialize_configuration(t_particle particle[NMAXCIRCLES], t_hashgrid hashgr
if (module2(vabs(particle[i].xc) -1.0, particle[i].yc) > EHRENFEST_RADIUS)
particle[i].active = 0;
}
else if (BOUNDARY_COND == BC_RECTANGLE_WALL)
{
for (i=0; i< ncircles; i++)
if (vabs(particle[i].xc - xwall) < WALL_WIDTH)
particle[i].active = 0;
}
else if (BOUNDARY_COND == BC_GENUS_TWO)
{
for (i=0; i< ncircles; i++)
if ((particle[i].xc > 0.0)&&(particle[i].yc > 0.0))
particle[i].active = 0;
}
if (ADD_FIXED_OBSTACLES)
{
for (i=0; i< ncircles; i++) for (j=0; j < nobstacles; j++)

View File

@ -4,6 +4,8 @@
#define BOUNDARY_SHIFT 100000.0 /* shift of boundary parametrisation for circles in domain */
#define DUMMY_SIDE_ABS -10000 /* dummy value of returned side for absorbing circles */
#define PENROSE_RATIO 0.2 /* parameter controlling the shape of small ellipses in Penrose room */
long int global_time = 0; /* counter to keep track of global time of simulation */
int nparticles=NPART;
@ -1024,7 +1026,7 @@ void draw_billiard() /* draws the billiard boundary */
for (i=0; i<=NSEG; i++)
{
phi = (double)i*dphi;
x = cc - 0.5*MU*sin(phi);
x = cc - 0.5*PENROSE_RATIO*MU*sin(phi);
y = MU*cos(phi);
glVertex2d(x, y);
}
@ -1035,7 +1037,7 @@ void draw_billiard() /* draws the billiard boundary */
for (i=0; i<=NSEG; i++)
{
phi = (double)i*dphi;
x = -cc + 0.5*MU*sin(phi);
x = -cc + 0.5*PENROSE_RATIO*MU*sin(phi);
y = MU*cos(phi);
glVertex2d(x, y);
}
@ -1107,7 +1109,7 @@ void draw_billiard() /* draws the billiard boundary */
for (i=0; i<=NSEG; i++)
{
phi = (double)i*dphi;
x = -cc + 0.5*MU*sin(phi);
x = -cc + 0.5*MU*PENROSE_RATIO*sin(phi);
y = MU*cos(phi);
glVertex2d(x, y);
}
@ -1135,7 +1137,7 @@ void draw_billiard() /* draws the billiard boundary */
for (i=0; i<=NSEG; i++)
{
phi = (double)i*dphi;
x = cc - 0.5*MU*sin(phi);
x = cc - 0.5*MU*PENROSE_RATIO*sin(phi);
y = -MU*cos(phi);
glVertex2d(x, y);
}
@ -3532,9 +3534,9 @@ void print_colors(int color[NPARTMAX]) /* for debugging purposes */
else if (s < sval[5]) /* left ellipse/mushroom head */
{
s1 = s - sval[4];
pos[0] = -cc + 0.5*MU*sin(s1);
pos[0] = -cc + 0.5*PENROSE_RATIO*MU*sin(s1);
pos[1] = MU*cos(s1);
phi = argument(0.5*MU*cos(s1), -MU*sin(s1));
phi = argument(0.5*PENROSE_RATIO*MU*cos(s1), -MU*sin(s1));
*alpha = phi + theta;
return(4);
}
@ -3599,9 +3601,9 @@ void print_colors(int color[NPARTMAX]) /* for debugging purposes */
else if (s < sval[13]) /* right ellipse/mushroom head */
{
s1 = s - sval[12];
pos[0] = cc - 0.5*MU*sin(s1);
pos[0] = cc - 0.5*PENROSE_RATIO*MU*sin(s1);
pos[1] = -MU*cos(s1);
phi = argument(-0.5*MU*cos(s1), MU*sin(s1));
phi = argument(-0.5*PENROSE_RATIO*MU*cos(s1), MU*sin(s1));
*alpha = phi + theta;
return(12);
}
@ -3713,9 +3715,9 @@ void print_colors(int color[NPARTMAX]) /* for debugging purposes */
}
/* intersection with right ellipse */
a = 4.0*ca*ca + sa*sa;
b = 4.0*(pos[0] - cc)*ca + pos[1]*sa;
d = 4.0*(pos[0] - cc)*(pos[0] - cc) + pos[1]*pos[1] - MU*MU;
a = 4.0*ca*ca + sa*sa*PENROSE_RATIO*PENROSE_RATIO;
b = 4.0*(pos[0] - cc)*ca + pos[1]*sa*PENROSE_RATIO*PENROSE_RATIO;
d = 4.0*(pos[0] - cc)*(pos[0] - cc) + (pos[1]*pos[1] - MU*MU)*PENROSE_RATIO*PENROSE_RATIO;
if (b*b > a*d)
{
@ -3729,8 +3731,8 @@ void print_colors(int color[NPARTMAX]) /* for debugging purposes */
tval[nt] = t;
x1[nt] = x;
y1[nt] = y;
tempconf[nt][0] = sval[12] + argument(-y/MU, 2.0*(cc-x)/MU);
tempconf[nt][1] = argument(0.5*y, 2.0*(cc-x)) - alpha;
tempconf[nt][0] = sval[12] + argument(-y/MU, 2.0*(cc-x)/(MU*PENROSE_RATIO));
tempconf[nt][1] = argument(0.5*PENROSE_RATIO*y, 2.0*(cc-x)/PENROSE_RATIO) - alpha;
nt++;
}
@ -3744,16 +3746,16 @@ void print_colors(int color[NPARTMAX]) /* for debugging purposes */
tval[nt] = t;
x1[nt] = x;
y1[nt] = y;
tempconf[nt][0] = sval[12] + argument(-y/MU, 2.0*(cc-x)/MU);
tempconf[nt][1] = argument(0.5*y, 2.0*(cc-x)) - alpha;
tempconf[nt][0] = sval[12] + argument(-y/MU, 2.0*(cc-x)/(MU*PENROSE_RATIO));
tempconf[nt][1] = argument(0.5*PENROSE_RATIO*y, 2.0*(cc-x)/PENROSE_RATIO) - alpha;
nt++;
}
}
/* intersection with left ellipse */
b = 4.0*(pos[0] + cc)*ca + pos[1]*sa;
d = 4.0*(pos[0] + cc)*(pos[0] + cc) + pos[1]*pos[1] - MU*MU;
b = 4.0*(pos[0] + cc)*ca + pos[1]*sa*PENROSE_RATIO*PENROSE_RATIO;
d = 4.0*(pos[0] + cc)*(pos[0] + cc) + (pos[1]*pos[1] - MU*MU)*PENROSE_RATIO*PENROSE_RATIO;
if (b*b > a*d)
{
@ -3767,8 +3769,8 @@ void print_colors(int color[NPARTMAX]) /* for debugging purposes */
tval[nt] = t;
x1[nt] = x;
y1[nt] = y;
tempconf[nt][0] = sval[4] + argument(y/MU, 2.0*(cc+x)/MU);
tempconf[nt][1] = argument(0.5*y, -2.0*(cc+x)) - alpha;
tempconf[nt][0] = sval[4] + argument(y/MU, 2.0*(cc+x)/(MU*PENROSE_RATIO));
tempconf[nt][1] = argument(0.5*PENROSE_RATIO*y, -2.0*(cc+x)/PENROSE_RATIO) - alpha;
nt++;
}
@ -3782,8 +3784,8 @@ void print_colors(int color[NPARTMAX]) /* for debugging purposes */
tval[nt] = t;
x1[nt] = x;
y1[nt] = y;
tempconf[nt][0] = sval[4] + argument(y/MU, 2.0*(cc+x)/MU);
tempconf[nt][1] = argument(0.5*y, -2.0*(cc+x)) - alpha;
tempconf[nt][0] = sval[4] + argument(y/MU, 2.0*(cc+x)/(MU*PENROSE_RATIO));
tempconf[nt][1] = argument(0.5*PENROSE_RATIO*y, -2.0*(cc+x)/PENROSE_RATIO) - alpha;
nt++;
}
@ -5280,7 +5282,7 @@ void print_colors(int color[NPARTMAX]) /* for debugging purposes */
/* upper and lower ellipse */
else if ((vabs(y) >= MU)&&(x*x/(LAMBDA*LAMBDA) + (y1-MU)*(y1-MU)/((1.0-MU)*(1.0-MU)) >= 1.0)) return(0);
/* small ellipses */
else if ((vabs(x) <= c)&&(4.0*(x1-c)*(x1-c)/(MU*MU) + y*y/(MU*MU) <= 1.0)) return(0);
else if ((vabs(x) <= c)&&(4.0*(x1-c)*(x1-c)/(MU*MU*PENROSE_RATIO*PENROSE_RATIO) + y*y/(MU*MU) <= 1.0)) return(0);
/* straight parts */
else if ((vabs(x) >= c)&&(vabs(y) <= width)) return(0);
else return(1);

1206
sub_wave_3d.c Normal file

File diff suppressed because it is too large Load Diff

836
wave_3d.c Normal file
View File

@ -0,0 +1,836 @@
/*********************************************************************************/
/* */
/* Animation of wave equation in a planar domain */
/* */
/* N. Berglund, december 2012, may 2021 */
/* */
/* UPDATE 24/04: distinction between damping and "elasticity" parameters */
/* UPDATE 27/04: new billiard shapes, bug in color scheme fixed */
/* UPDATE 28/04: code made more efficient, with help of Marco Mancini */
/* */
/* Feel free to reuse, but if doing so it would be nice to drop a */
/* line to nils.berglund@univ-orleans.fr - Thanks! */
/* */
/* compile with */
/* gcc -o wave_billiard wave_billiard.c */
/* -L/usr/X11R6/lib -ltiff -lm -lGL -lGLU -lX11 -lXmu -lglut -O3 -fopenmp */
/* */
/* OMP acceleration may be more effective after executing */
/* export OMP_NUM_THREADS=2 in the shell before running the program */
/* */
/* To make a video, set MOVIE to 1 and create subfolder tif_wave */
/* It may be possible to increase parameter PAUSE */
/* */
/* create movie using */
/* ffmpeg -i wave.%05d.tif -vcodec libx264 wave.mp4 */
/* */
/*********************************************************************************/
/*********************************************************************************/
/* */
/* NB: The algorithm used to simulate the wave equation is highly paralellizable */
/* One could make it much faster by using a GPU */
/* */
/*********************************************************************************/
#include <math.h>
#include <string.h>
#include <GL/glut.h>
#include <GL/glu.h>
#include <unistd.h>
#include <sys/types.h>
#include <tiffio.h> /* Sam Leffler's libtiff library. */
#include <omp.h>
#define MOVIE 0 /* set to 1 to generate movie */
#define DOUBLE_MOVIE 0 /* set to 1 to produce movies for wave height and energy simultaneously */
/* General geometrical parameters */
/* uncomment for higher resolution */
// #define WINWIDTH 1920 /* window width */
// #define WINHEIGHT 1000 /* window height */
// #define NX 1920 /* number of grid points on x axis */
// #define NY 1000 /* number of grid points on y axis */
// // #define NX 3840 /* number of grid points on x axis */
// // #define NY 2000 /* number of grid points on y axis */
//
// #define XMIN -2.0
// #define XMAX 2.0 /* x interval */
// #define YMIN -1.041666667
// #define YMAX 1.041666667 /* y interval for 9/16 aspect ratio */
#define HIGHRES 0 /* set to 1 if resolution of grid is double that of displayed image */
/* comment out for higher resolution */
#define WINWIDTH 1280 /* window width */
#define WINHEIGHT 720 /* window height */
#define NX 1280 /* number of grid points on x axis */
#define NY 720 /* number of grid points on y axis */
#define XMIN -2.0
#define XMAX 2.0 /* x interval */
#define YMIN -1.125
#define YMAX 1.125 /* y interval for 9/16 aspect ratio */
#define JULIA_SCALE 0.8 /* scaling for Julia sets */
/* Choice of the billiard table */
#define B_DOMAIN 16 /* choice of domain shape, see list in global_pdes.c */
#define CIRCLE_PATTERN 201 /* pattern of circles or polygons, see list in global_pdes.c */
#define P_PERCOL 0.25 /* probability of having a circle in C_RAND_PERCOL arrangement */
#define NPOISSON 300 /* number of points for Poisson C_RAND_POISSON arrangement */
#define RANDOM_POLY_ANGLE 1 /* set to 1 to randomize angle of polygons */
#define LAMBDA 0.6 /* parameter controlling the dimensions of domain */
#define MU 0.6 /* parameter controlling the dimensions of domain */
#define NPOLY 6 /* number of sides of polygon */
#define APOLY 0.0 /* angle by which to turn polygon, in units of Pi/2 */
#define MDEPTH 3 /* depth of computation of Menger gasket */
#define MRATIO 3 /* ratio defining Menger gasket */
#define MANDELLEVEL 1000 /* iteration level for Mandelbrot set */
#define MANDELLIMIT 10.0 /* limit value for approximation of Mandelbrot set */
#define FOCI 1 /* set to 1 to draw focal points of ellipse */
#define NGRIDX 36 /* number of grid point for grid of disks */
#define NGRIDY 6 /* number of grid point for grid of disks */
#define X_SHOOTER -0.2
#define Y_SHOOTER -0.6
#define X_TARGET 0.4
#define Y_TARGET 0.7 /* shooter and target positions in laser fight */
#define ISO_XSHIFT_LEFT -2.9
#define ISO_XSHIFT_RIGHT 1.4
#define ISO_YSHIFT_LEFT -0.15
#define ISO_YSHIFT_RIGHT -0.15
#define ISO_SCALE 0.5 /* coordinates for isospectral billiards */
/* You can add more billiard tables by adapting the functions */
/* xy_in_billiard and draw_billiard below */
/* Physical parameters of wave equation */
// #define TWOSPEEDS 0 /* set to 1 to replace hardcore boundary by medium with different speed */
#define TWOSPEEDS 0 /* set to 1 to replace hardcore boundary by medium with different speed */
#define OSCILLATE_LEFT 0 /* set to 1 to add oscilating boundary condition on the left */
#define OSCILLATE_TOPBOT 0 /* set to 1 to enforce a planar wave on top and bottom boundary */
#define OMEGA 0.005 /* frequency of periodic excitation */
#define AMPLITUDE 0.8 /* amplitude of periodic excitation */
#define COURANT 0.06 /* Courant number */
#define COURANTB 0.03 /* Courant number in medium B */
// #define COURANTB 0.016363636 /* Courant number in medium B */
#define GAMMA 0.0 /* damping factor in wave equation */
#define GAMMAB 1.0e-7 /* damping factor in wave equation */
#define GAMMA_SIDES 1.0e-4 /* damping factor on boundary */
#define GAMMA_TOPBOT 1.0e-7 /* damping factor on boundary */
#define KAPPA 0.0 /* "elasticity" term enforcing oscillations */
#define KAPPA_SIDES 5.0e-4 /* "elasticity" term on absorbing boundary */
#define KAPPA_TOPBOT 0.0 /* "elasticity" term on absorbing boundary */
/* The Courant number is given by c*DT/DX, where DT is the time step and DX the lattice spacing */
/* The physical damping coefficient is given by GAMMA/(DT)^2 */
/* Increasing COURANT speeds up the simulation, but decreases accuracy */
/* For similar wave forms, COURANT^2*GAMMA should be kept constant */
#define ADD_OSCILLATING_SOURCE 0 /* set to 1 to add an oscillating wave source */
#define OSCILLATING_SOURCE_PERIOD 30 /* period of oscillating source */
// #define OSCILLATING_SOURCE_PERIOD 14 /* period of oscillating source */
/* Boundary conditions, see list in global_pdes.c */
#define B_COND 2
// #define B_COND 2
/* Parameters for length and speed of simulation */
#define NSTEPS 2500 /* number of frames of movie */
#define NVID 10 /* number of iterations between images displayed on screen */
#define NSEG 1000 /* number of segments of boundary */
#define INITIAL_TIME 0 /* time after which to start saving frames */
#define BOUNDARY_WIDTH 3 /* width of billiard boundary */
#define PAUSE 200 /* number of frames after which to pause */
#define PSLEEP 2 /* sleep time during pause */
#define SLEEP1 1 /* initial sleeping time */
#define SLEEP2 1 /* final sleeping time */
#define MID_FRAMES 200 /* number of still frames between parts of two-part movie */
#define END_FRAMES 100 /* number of still frames at end of movie */
#define FADE 1 /* set to 1 to fade at end of movie */
/* Parameters of initial condition */
#define INITIAL_AMP 0.5 /* amplitude of initial condition */
#define INITIAL_VARIANCE 0.0005 /* variance of initial condition */
#define INITIAL_WAVELENGTH 0.1 /* wavelength of initial condition */
/* Plot type, see list in global_pdes.c */
#define ZPLOT 103 /* wave height */
#define CPLOT 103 /* color scheme */
#define ZPLOT_B 104
#define CPLOT_B 104 /* plot type for second movie */
#define AMPLITUDE_HIGH_RES 1 /* set to 1 to increase resolution of plot */
#define SHADE_3D 1 /* set to 1 to change luminosity according to normal vector */
#define NON_DIRICHLET_BC 0 /* set to 1 to draw only facets in domain, if field is not zero on boundary */
#define DRAW_BILLIARD 1 /* set to 1 to draw boundary */
#define DRAW_BILLIARD_FRONT 1 /* set to 1 to draw front of boundary after drawing wave */
#define FADE_IN_OBSTACLE 1 /* set to 1 to fade color inside obstacles */
#define PLOT_SCALE_ENERGY 0.05 /* vertical scaling in energy plot */
#define PLOT_SCALE_LOG_ENERGY 0.6 /* vertical scaling in log energy plot */
/* 3D representation */
#define REPRESENTATION_3D 1 /* choice of 3D representation */
#define REP_AXO_3D 0 /* linear projection (axonometry) */
#define REP_PROJ_3D 1 /* projection on plane orthogonal to observer line of sight */
/* Color schemes */
#define COLOR_PALETTE 14 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE_B 11 /* Color palette, see list in global_pdes.c */
#define BLACK 1 /* background */
#define COLOR_SCHEME 3 /* choice of color scheme, see list in global_pdes.c */
#define SCALE 0 /* set to 1 to adjust color scheme to variance of field */
#define SLOPE 1.0 /* sensitivity of color on wave amplitude */
#define VSCALE_AMPLITUDE 0.2 /* additional scaling factor for color scheme P_3D_AMPLITUDE */
#define VSCALE_ENERGY 0.35 /* additional scaling factor for color scheme P_3D_ENERGY */
#define PHASE_FACTOR 20.0 /* factor in computation of phase in color scheme P_3D_PHASE */
#define PHASE_SHIFT 0.0 /* shift of phase in color scheme P_3D_PHASE */
#define ATTENUATION 0.0 /* exponential attenuation coefficient of contrast with time */
#define E_SCALE 200.0 /* scaling factor for energy representation */
#define LOG_SCALE 1.0 /* scaling factor for energy log representation */
#define LOG_SHIFT 1.0 /* shift of colors on log scale */
#define RESCALE_COLOR_IN_CENTER 0 /* set to 1 to decrease color intentiy in the center (for wave escaping ring) */
#define COLORHUE 260 /* initial hue of water color for scheme C_LUM */
#define COLORDRIFT 0.0 /* how much the color hue drifts during the whole simulation */
#define LUMMEAN 0.5 /* amplitude of luminosity variation for scheme C_LUM */
#define LUMAMP 0.3 /* amplitude of luminosity variation for scheme C_LUM */
#define HUEMEAN 240.0 /* mean value of hue for color scheme C_HUE */
#define HUEAMP -200.0 /* amplitude of variation of hue for color scheme C_HUE */
#define DRAW_COLOR_SCHEME 0 /* set to 1 to plot the color scheme */
#define COLORBAR_RANGE 3.0 /* scale of color scheme bar */
#define COLORBAR_RANGE_B 5.0 /* scale of color scheme bar for 2nd part */
#define ROTATE_COLOR_SCHEME 0 /* set to 1 to draw color scheme horizontally */
#define SAVE_TIME_SERIES 0 /* set to 1 to save wave time series at a point */
/* For debugging purposes only */
#define FLOOR 0 /* set to 1 to limit wave amplitude to VMAX */
#define VMAX 10.0 /* max value of wave amplitude */
/* Parameters controlling 3D projection */
double u_3d[2] = {0.75, -0.45}; /* projections of basis vectors for REP_AXO_3D representation */
double v_3d[2] = {-0.75, -0.45};
double w_3d[2] = {0.0, 0.015};
double light[3] = {0.816496581, -0.40824829, 0.40824829}; /* vector of "light" direction for P_3D_ANGLE color scheme */
double observer[3] = {10.0, 6.0, 8.5}; /* location of observer for REP_PROJ_3D representation */
#define Z_SCALING_FACTOR 0.018 /* overall scaling factor of z axis for REP_PROJ_3D representation */
#define XY_SCALING_FACTOR 3.75 /* overall scaling factor for on-screen (x,y) coordinates after projection */
#define ZMAX_FACTOR 1.0 /* max value of z coordinate for REP_PROJ_3D representation */
#define XSHIFT_3D 0.0 /* overall x shift for REP_PROJ_3D representation */
#define YSHIFT_3D 0.0 /* overall y shift for REP_PROJ_3D representation */
#include "global_pdes.c" /* constants and global variables */
#include "sub_wave.c" /* common functions for wave_billiard, heat and schrodinger */
#include "wave_common.c" /* common functions for wave_billiard, wave_comparison, etc */
#include "global_3d.c" /* constants and global variables */
#include "sub_wave_3d.c" /* graphical functions specific to wave_3d */
FILE *time_series_left, *time_series_right;
double courant2, courantb2; /* Courant parameters squared */
void evolve_wave_half(double phi_in[NX*NY], double psi_in[NX*NY], double phi_out[NX*NY], double psi_out[NX*NY],
short int xy_in[NX*NY], double tc[NX*NY], double tcc[NX*NY], double tgamma[NX*NY])
// void evolve_wave_half(double *phi_in, double *psi_in, double *phi_out, double *psi_out,
// short int *xy_in[NX])
/* time step of field evolution */
/* phi is value of field at time t, psi at time t-1 */
/* this version of the function has been rewritten in order to minimize the number of if-branches */
{
int i, j, iplus, iminus, jplus, jminus;
double delta, x, y, c, cc, gamma;
static long time = 0;
// static double tc[NX*NY], tcc[NX*NY], tgamma[NX*NY];
// static short int first = 1;
time++;
#pragma omp parallel for private(i,j,iplus,iminus,jplus,jminus,delta,x,y)
/* evolution in the bulk */
for (i=1; i<NX-1; i++){
for (j=1; j<NY-1; j++){
if ((TWOSPEEDS)||(xy_in[i*NY+j] != 0)){
x = phi_in[i*NY+j];
y = psi_in[i*NY+j];
/* discretized Laplacian */
delta = phi_in[(i+1)*NY+j] + phi_in[(i-1)*NY+j] + phi_in[i*NY+j+1] + phi_in[i*NY+j-1] - 4.0*x;
/* evolve phi */
phi_out[i*NY+j] = -y + 2*x + tcc[i*NY+j]*delta - KAPPA*x - tgamma[i*NY+j]*(x-y);
psi_out[i*NY+j] = x;
}
}
}
/* left boundary */
if (OSCILLATE_LEFT) for (j=1; j<NY-1; j++) phi_out[j] = AMPLITUDE*cos((double)time*OMEGA);
else for (j=1; j<NY-1; j++){
if ((TWOSPEEDS)||(xy_in[j] != 0)){
x = phi_in[j];
y = psi_in[j];
switch (B_COND) {
case (BC_DIRICHLET):
{
delta = phi_in[NY+j] + phi_in[j+1] + phi_in[j-1] - 3.0*x;
phi_out[j] = -y + 2*x + tcc[j]*delta - KAPPA*x - tgamma[j]*(x-y);
break;
}
case (BC_PERIODIC):
{
delta = phi_in[NY+j] + phi_in[(NX-1)*NY+j] + phi_in[j+1] + phi_in[j-1] - 4.0*x;
phi_out[j] = -y + 2*x + tcc[j]*delta - KAPPA*x - tgamma[j]*(x-y);
break;
}
case (BC_ABSORBING):
{
delta = phi_in[NY+j] + phi_in[j+1] + phi_in[j-1] - 3.0*x;
phi_out[j] = x - tc[j]*(x - phi_in[NY+j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
case (BC_VPER_HABS):
{
delta = phi_in[NY+j] + phi_in[j+1] + phi_in[j-1] - 3.0*x;
phi_out[j] = x - tc[j]*(x - phi_in[NY+j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
}
psi_out[j] = x;
}
}
/* right boundary */
for (j=1; j<NY-1; j++){
if ((TWOSPEEDS)||(xy_in[(NX-1)*NY+j] != 0)){
x = phi_in[(NX-1)*NY+j];
y = psi_in[(NX-1)*NY+j];
switch (B_COND) {
case (BC_DIRICHLET):
{
delta = phi_in[(NX-2)*NY+j] + phi_in[(NX-1)*NY+j+1] + phi_in[(NX-1)*NY+j-1] - 3.0*x;
phi_out[(NX-1)*NY+j] = -y + 2*x + tcc[(NX-1)*NY+j]*delta - KAPPA*x - tgamma[(NX-1)*NY+j]*(x-y);
break;
}
case (BC_PERIODIC):
{
delta = phi_in[(NX-2)*NY+j] + phi_in[j] + phi_in[(NX-1)*NY+j+1] + phi_in[(NX-1)*NY+j-1] - 4.0*x;
phi_out[(NX-1)*NY+j] = -y + 2*x + tcc[(NX-1)*NY+j]*delta - KAPPA*x - tgamma[(NX-1)*NY+j]*(x-y);
break;
}
case (BC_ABSORBING):
{
delta = phi_in[(NX-2)*NY+j] + phi_in[(NX-1)*NY+j+1] + phi_in[(NX-1)*NY+j-1] - 3.0*x;
phi_out[(NX-1)*NY+j] = x - tc[(NX-1)*NY+j]*(x - phi_in[(NX-2)*NY+j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
case (BC_VPER_HABS):
{
delta = phi_in[(NX-2)*NY+j] + phi_in[(NX-1)*NY+j+1] + phi_in[(NX-1)*NY+j-1] - 3.0*x;
phi_out[(NX-1)*NY+j] = x - tc[(NX-1)*NY+j]*(x - phi_in[(NX-2)*NY+j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
}
psi_out[(NX-1)*NY+j] = x;
}
}
/* top boundary */
for (i=0; i<NX; i++){
if ((TWOSPEEDS)||(xy_in[i*NY+NY-1] != 0)){
x = phi_in[i*NY+NY-1];
y = psi_in[i*NY+NY-1];
switch (B_COND) {
case (BC_DIRICHLET):
{
iplus = i+1; if (iplus == NX) iplus = NX-1;
iminus = i-1; if (iminus == -1) iminus = 0;
delta = phi_in[iplus*NY+NY-1] + phi_in[iminus*NY+NY-1] + phi_in[i*NY+NY-2] - 3.0*x;
phi_out[i*NY+NY-1] = -y + 2*x + tcc[i*NY+NY-1]*delta - KAPPA*x - tgamma[i*NY+NY-1]*(x-y);
break;
}
case (BC_PERIODIC):
{
iplus = (i+1) % NX;
iminus = (i-1) % NX;
if (iminus < 0) iminus += NX;
delta = phi_in[iplus*NY+NY-1] + phi_in[iminus*NY+NY-1] + phi_in[i*NY+NY-2] + phi_in[i*NY] - 4.0*x;
phi_out[i*NY+NY-1] = -y + 2*x + tcc[i*NY+NY-1]*delta - KAPPA*x - tgamma[i*NY+NY-1]*(x-y);
break;
}
case (BC_ABSORBING):
{
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
delta = phi_in[iplus*NY+NY-1] + phi_in[iminus*NY+NY-1] + phi_in[i*NY+NY-2] - 3.0*x;
phi_out[i*NY+NY-1] = x - tc[i*NY+NY-1]*(x - phi_in[i*NY+NY-2]) - KAPPA_TOPBOT*x - GAMMA_TOPBOT*(x-y);
break;
}
case (BC_VPER_HABS):
{
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
delta = phi_in[iplus*NY+NY-1] + phi_in[iminus*NY+NY-1] + phi_in[i*NY+NY-2] + phi_in[i*NY] - 4.0*x;
if (i==0) phi_out[NY-1] = x - tc[NY-1]*(x - phi_in[1*NY+NY-1]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
else phi_out[i*NY+NY-1] = -y + 2*x + tcc[i*NY+NY-1]*delta - KAPPA*x - tgamma[i*NY+NY-1]*(x-y);
break;
}
}
psi_out[i*NY+NY-1] = x;
}
}
/* bottom boundary */
for (i=0; i<NX; i++){
if ((TWOSPEEDS)||(xy_in[i*NY] != 0)){
x = phi_in[i*NY];
y = psi_in[i*NY];
switch (B_COND) {
case (BC_DIRICHLET):
{
iplus = i+1; if (iplus == NX) iplus = NX-1;
iminus = i-1; if (iminus == -1) iminus = 0;
delta = phi_in[iplus*NY] + phi_in[iminus*NY] + phi_in[i*NY+1] - 3.0*x;
phi_out[i*NY] = -y + 2*x + tcc[i*NY]*delta - KAPPA*x - tgamma[i*NY]*(x-y);
break;
}
case (BC_PERIODIC):
{
iplus = (i+1) % NX;
iminus = (i-1) % NX;
if (iminus < 0) iminus += NX;
delta = phi_in[iplus*NY] + phi_in[iminus*NY] + phi_in[i*NY+1] + phi_in[i*NY+NY-1] - 4.0*x;
phi_out[i*NY] = -y + 2*x + tcc[i*NY]*delta - KAPPA*x - tgamma[i*NY]*(x-y);
break;
}
case (BC_ABSORBING):
{
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
delta = phi_in[iplus*NY] + phi_in[iminus*NY] + phi_in[i*NY+1] - 3.0*x;
phi_out[i*NY] = x - tc[i*NY]*(x - phi_in[i*NY+1]) - KAPPA_TOPBOT*x - GAMMA_TOPBOT*(x-y);
break;
}
case (BC_VPER_HABS):
{
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
delta = phi_in[iplus*NY] + phi_in[iminus*NY] + phi_in[i*NY+1] + phi_in[i*NY+NY-1] - 4.0*x;
if (i==0) phi_out[0] = x - tc[0]*(x - phi_in[NY]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
else phi_out[i*NY] = -y + 2*x + tcc[i*NY]*delta - KAPPA*x - tgamma[i*NY]*(x-y);
break;
}
}
psi_out[i*NY] = x;
}
}
/* add oscillating boundary condition on the left corners */
if (OSCILLATE_LEFT)
{
phi_out[0] = AMPLITUDE*cos((double)time*OMEGA);
phi_out[NY-1] = AMPLITUDE*cos((double)time*OMEGA);
}
/* for debugging purposes/if there is a risk of blow-up */
if (FLOOR) for (i=0; i<NX; i++){
for (j=0; j<NY; j++){
if (xy_in[i*NY+j] != 0)
{
if (phi_out[i*NY+j] > VMAX) phi_out[i*NY+j] = VMAX;
if (phi_out[i*NY+j] < -VMAX) phi_out[i*NY+j] = -VMAX;
if (psi_out[i*NY+j] > VMAX) psi_out[i*NY+j] = VMAX;
if (psi_out[i*NY+j] < -VMAX) psi_out[i*NY+j] = -VMAX;
}
}
}
}
void evolve_wave(double phi[NX*NY], double psi[NX*NY], double phi_tmp[NX*NY], double psi_tmp[NX*NY], short int xy_in[NX*NY],
double tc[NX*NY], double tcc[NX*NY], double tgamma[NX*NY])
/* time step of field evolution */
/* phi is value of field at time t, psi at time t-1 */
{
evolve_wave_half(phi, psi, phi_tmp, psi_tmp, xy_in, tc, tcc, tgamma);
evolve_wave_half(phi_tmp, psi_tmp, phi, psi, xy_in, tc, tcc, tgamma);
}
void draw_color_bar_palette(int plot, double range, int palette)
{
if (ROTATE_COLOR_SCHEME) draw_color_scheme_palette_3d(-1.0, -0.8, XMAX - 0.1, -1.0, plot, -range, range, palette);
else draw_color_scheme_palette_3d(XMAX - 0.3, YMIN + 0.1, XMAX - 0.1, YMAX - 0.1, plot, -range, range, palette);
}
void animation()
{
double time, scale, ratio, startleft[2], startright[2], sign, r2, xy[2], fade_value;
double *phi, *psi, *phi_tmp, *psi_tmp, *total_energy, *color_scale, *tc, *tcc, *tgamma;
short int *xy_in;
int i, j, s, sample_left[2], sample_right[2], period = 0, fade;
static int counter = 0;
long int wave_value;
t_wave *wave;
if (SAVE_TIME_SERIES)
{
time_series_left = fopen("wave_left.dat", "w");
time_series_right = fopen("wave_right.dat", "w");
}
/* Since NX and NY are big, it seemed wiser to use some memory allocation here */
xy_in = (short int *)malloc(NX*NY*sizeof(short int));
phi = (double *)malloc(NX*NY*sizeof(double));
psi = (double *)malloc(NX*NY*sizeof(double));
phi_tmp = (double *)malloc(NX*NY*sizeof(double));
psi_tmp = (double *)malloc(NX*NY*sizeof(double));
total_energy = (double *)malloc(NX*NY*sizeof(double));
color_scale = (double *)malloc(NX*NY*sizeof(double));
tc = (double *)malloc(NX*NY*sizeof(double));
tcc = (double *)malloc(NX*NY*sizeof(double));
tgamma = (double *)malloc(NX*NY*sizeof(double));
wave = (t_wave *)malloc(NX*NY*sizeof(t_wave));
/* initialise positions and radii of circles */
if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN == D_CIRCLES_IN_RECT)) init_circle_config(circles);
else if (B_DOMAIN == D_POLYGONS) init_polygon_config(polygons);
printf("Polygons initialized\n");
/* initialise polyline for von Koch and similar domains */
npolyline = init_polyline(MDEPTH, polyline);
for (i=0; i<npolyline; i++) printf("vertex %i: (%.3f, %.3f)\n", i, polyline[i].x, polyline[i].y);
courant2 = COURANT*COURANT;
courantb2 = COURANTB*COURANTB;
/* initialize color scale, for option RESCALE_COLOR_IN_CENTER */
if (RESCALE_COLOR_IN_CENTER)
{
for (i=0; i<NX; i++)
for (j=0; j<NY; j++)
{
ij_to_xy(i, j, xy);
r2 = xy[0]*xy[0] + xy[1]*xy[1];
color_scale[i*NY+j] = 1.0 - exp(-4.0*r2/LAMBDA*LAMBDA);
}
}
/* initialize wave with a drop at one point, zero elsewhere */
// init_circular_wave(0.0, -LAMBDA, phi, psi, xy_in);
/* initialize total energy table */
if ((ZPLOT == P_MEAN_ENERGY)||(ZPLOT_B == P_MEAN_ENERGY)||(ZPLOT == P_LOG_MEAN_ENERGY)||(ZPLOT_B == P_LOG_MEAN_ENERGY))
for (i=0; i<NX; i++)
for (j=0; j<NY; j++)
total_energy[i*NY+j] = 0.0;
ratio = (XMAX - XMIN)/8.4; /* for Tokarsky billiard */
// isospectral_initial_point(0.2, 0.0, startleft, startright); /* for isospectral billiards */
// homophonic_initial_point(0.5, -0.25, 1.5, -0.25, startleft, startright);
// homophonic_initial_point(0.5, -0.25, 1.5, -0.25, startleft, startright);
// printf("xleft = (%.3f, %.3f) xright = (%.3f, %.3f)\n", startleft[0], startleft[1], startright[0], startright[1]);
// xy_to_ij(startleft[0], startleft[1], sample_left);
// xy_to_ij(startright[0], startright[1], sample_right);
// printf("xleft = (%.3f, %.3f) xright = (%.3f, %.3f)\n", xin_left, yin_left, xin_right, yin_right);
// init_wave_flat(phi, psi, xy_in);
// init_wave_plus(LAMBDA - 0.3*MU, 0.5*MU, phi, psi, xy_in);
// init_wave(LAMBDA - 0.3*MU, 0.5*MU, phi, psi, xy_in);
// init_circular_wave(X_SHOOTER, Y_SHOOTER, phi, psi, xy_in);
// printf("Initializing wave\n");
// init_circular_wave_mod(polyline[85].x, polyline[85].y, phi, psi, xy_in);
// init_circular_wave_mod(0.0, 0.0, phi, psi, xy_in);
init_circular_wave_mod(0.2, 0.4, phi, psi, xy_in);
add_circular_wave_mod(-1.0, -0.2, -0.4, phi, psi, xy_in);
// add_circular_wave(-1.0, -0.2, -0.4, phi, psi, xy_in);
// printf("Wave initialized\n");
// init_circular_wave(0.6*cos((double)(period)*DPI/3.0), 0.6*sin((double)(period)*DPI/3.0), phi, psi, xy_in);
// period++;
// for (i=0; i<3; i++)
// {
// add_circular_wave(-1.0, 0.6*cos(PID + (double)(i)*DPI/3.0), 0.6*sin(PID + (double)(i)*DPI/3.0), phi, psi, xy_in);
// }
// add_circular_wave(1.0, -LAMBDA, 0.0, phi, psi, xy_in);
// add_circular_wave(-1.0, 0.0, -LAMBDA, phi, psi, xy_in);
// init_circular_wave_xplusminus(startleft[0], startleft[1], startright[0], startright[1], phi, psi, xy_in);
// init_circular_wave_xplusminus(-0.9, 0.0, 0.81, 0.0, phi, psi, xy_in);
// init_circular_wave(-2.0*ratio, 0.0, phi, psi, xy_in);
// init_planar_wave(XMIN + 0.015, 0.0, phi, psi, xy_in);
// init_planar_wave(XMIN + 0.02, 0.0, phi, psi, xy_in);
// init_planar_wave(XMIN + 0.5, 0.0, phi, psi, xy_in);
// init_wave(-1.5, 0.0, phi, psi, xy_in);
// init_wave(0.0, 0.0, phi, psi, xy_in);
/* add a drop at another point */
// add_drop_to_wave(1.0, 0.7, 0.0, phi, psi);
// add_drop_to_wave(1.0, -0.7, 0.0, phi, psi);
// add_drop_to_wave(1.0, 0.0, -0.7, phi, psi);
/* initialize table of wave speeds/dissipation */
for (i=0; i<NX; i++){
for (j=0; j<NY; j++){
if (xy_in[i*NY+j] != 0)
{
tc[i*NY+j] = COURANT;
tcc[i*NY+j] = courant2;
if (xy_in[i*NY+j] == 1) tgamma[i*NY+j] = GAMMA;
else tgamma[i*NY+j] = GAMMAB;
}
else if (TWOSPEEDS)
{
tc[i*NY+j] = COURANTB;
tcc[i*NY+j] = courantb2;
tgamma[i*NY+j] = GAMMAB;
}
}
}
blank();
glColor3f(0.0, 0.0, 0.0);
draw_wave_3d(phi, psi, xy_in, wave, ZPLOT, CPLOT, COLOR_PALETTE, 0, 1.0);
// draw_billiard();
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT, COLORBAR_RANGE, COLOR_PALETTE);
glutSwapBuffers();
sleep(SLEEP1);
for (i=0; i<=INITIAL_TIME + NSTEPS; i++)
{
//printf("%d\n",i);
/* compute the variance of the field to adjust color scheme */
/* the color depends on the field divided by sqrt(1 + variance) */
if (SCALE)
{
scale = sqrt(1.0 + compute_variance_mod(phi,psi, xy_in));
// printf("Scaling factor: %5lg\n", scale);
}
else scale = 1.0;
draw_wave_3d(phi, psi, xy_in, wave, ZPLOT, CPLOT, COLOR_PALETTE, 0, 1.0);
for (j=0; j<NVID; j++)
{
evolve_wave(phi, psi, phi_tmp, psi_tmp, xy_in, tc, tcc, tgamma);
if (SAVE_TIME_SERIES)
{
wave_value = (long int)(phi[sample_left[0]*NY+sample_left[1]]*1.0e16);
fprintf(time_series_left, "%019ld\n", wave_value);
wave_value = (long int)(phi[sample_right[0]*NY+sample_right[1]]*1.0e16);
fprintf(time_series_right, "%019ld\n", wave_value);
if ((j == 0)&&(i%10 == 0)) printf("Frame %i of %i\n", i, NSTEPS);
// fprintf(time_series_right, "%.15f\n", phi[sample_right[0]][sample_right[1]]);
}
// if (i % 10 == 9) oscillate_linear_wave(0.2*scale, 0.15*(double)(i*NVID + j), -1.5, YMIN, -1.5, YMAX, phi, psi);
}
// draw_billiard();
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT, COLORBAR_RANGE, COLOR_PALETTE);
/* add oscillating waves */
if ((ADD_OSCILLATING_SOURCE)&&(i%OSCILLATING_SOURCE_PERIOD == OSCILLATING_SOURCE_PERIOD - 1))
{
add_circular_wave_mod(1.0, -1.0, 0.0, phi, psi, xy_in);
// add_circular_wave(1.0, -1.5*LAMBDA, 0.0, phi, psi, xy_in);
// add_circular_wave(-1.0, 0.6*cos((double)(period)*DPI/3.0), 0.6*sin((double)(period)*DPI/3.0), phi, psi, xy_in);
period++;
}
glutSwapBuffers();
if (MOVIE)
{
if (i >= INITIAL_TIME) save_frame();
else printf("Initial phase time %i of %i\n", i, INITIAL_TIME);
if ((i >= INITIAL_TIME)&&(DOUBLE_MOVIE))
{
draw_wave_3d(phi, psi, xy_in, wave, ZPLOT_B, CPLOT_B, COLOR_PALETTE_B, 0, 1.0);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT_B, COLORBAR_RANGE_B, COLOR_PALETTE_B);
glutSwapBuffers();
save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter);
// save_frame_counter(NSTEPS + 21 + counter);
counter++;
}
/* it seems that saving too many files too fast can cause trouble with the file system */
/* so this is to make a pause from time to time - parameter PAUSE may need adjusting */
if (i % PAUSE == PAUSE - 1)
{
printf("Making a short pause\n");
sleep(PSLEEP);
s = system("mv wave*.tif tif_wave/");
}
}
}
if (MOVIE)
{
if (DOUBLE_MOVIE)
{
draw_wave_3d(phi, psi, xy_in, wave, ZPLOT, CPLOT, COLOR_PALETTE, 0, 1.0);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT, COLORBAR_RANGE, COLOR_PALETTE);
glutSwapBuffers();
if (!FADE) for (i=0; i<MID_FRAMES; i++) save_frame();
else for (i=0; i<MID_FRAMES; i++)
{
draw_wave_3d(phi, psi, xy_in, wave, ZPLOT, CPLOT, COLOR_PALETTE, 1, 1.0 - (double)i/(double)MID_FRAMES);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT, COLORBAR_RANGE, COLOR_PALETTE);
glutSwapBuffers();
save_frame_counter(NSTEPS + i + 1);
}
draw_wave_3d(phi, psi, xy_in, wave, ZPLOT_B, CPLOT_B, COLOR_PALETTE_B, 0, 1.0);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT_B, COLORBAR_RANGE_B, COLOR_PALETTE_B);
glutSwapBuffers();
if (!FADE) for (i=0; i<END_FRAMES; i++) save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter + i);
else for (i=0; i<END_FRAMES; i++)
{
draw_wave_3d(phi, psi, xy_in, wave, ZPLOT_B, CPLOT_B, COLOR_PALETTE_B, 1, 1.0 - (double)i/(double)END_FRAMES);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT_B, COLORBAR_RANGE_B, COLOR_PALETTE_B);
glutSwapBuffers();
save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter + i);
}
}
else
{
if (!FADE) for (i=0; i<END_FRAMES; i++) save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter + i);
else for (i=0; i<END_FRAMES; i++)
{
draw_wave_3d(phi, psi, xy_in, wave, ZPLOT, CPLOT, COLOR_PALETTE, 1, 1.0 - (double)i/(double)END_FRAMES);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT, COLORBAR_RANGE, COLOR_PALETTE);
glutSwapBuffers();
save_frame_counter(NSTEPS + 1 + counter + i);
}
}
s = system("mv wave*.tif tif_wave/");
}
free(xy_in);
free(phi);
free(psi);
free(phi_tmp);
free(psi_tmp);
free(total_energy);
free(color_scale);
free(tc);
free(tcc);
free(tgamma);
free(wave);
if (SAVE_TIME_SERIES)
{
fclose(time_series_left);
fclose(time_series_right);
}
}
void display(void)
{
glPushMatrix();
blank();
glutSwapBuffers();
blank();
glutSwapBuffers();
animation();
sleep(SLEEP2);
glPopMatrix();
glutDestroyWindow(glutGetWindow());
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(WINWIDTH,WINHEIGHT);
glutCreateWindow("Wave equation in a planar domain");
init_3d();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}

View File

@ -47,34 +47,38 @@
/* General geometrical parameters */
/* uncomment for higher resolution version */
// #define WINWIDTH 1920 /* window width */
// #define WINHEIGHT 1000 /* window height */
#define WINWIDTH 1920 /* window width */
#define WINHEIGHT 1000 /* window height */
// #define NX 1920 /* number of grid points on x axis */
// #define NY 1000 /* number of grid points on y axis */
#define NX 3840 /* number of grid points on x axis */
#define NY 2000 /* number of grid points on y axis */
#define XMIN -1.25
#define XMAX 2.75 /* x interval */
#define YMIN -1.041666667
#define YMAX 1.041666667 /* y interval for 9/16 aspect ratio */
#define HIGHRES 1 /* set to 1 if resolution of grid is double that of displayed image */
// #define WINWIDTH 1280 /* window width */
// #define WINHEIGHT 720 /* window height */
//
// #define XMIN -2.0
// #define XMAX 2.0 /* x interval */
// #define YMIN -1.041666667
// #define YMAX 1.041666667 /* y interval for 9/16 aspect ratio */
/* comment out for higher resolution version */
#define WINWIDTH 1280 /* window width */
#define WINHEIGHT 720 /* window height */
#define NX 1280 /* number of grid points on x axis */
#define NY 720 /* number of grid points on y axis */
#define XMIN -2.0
#define XMAX 2.0 /* x interval */
#define YMIN -1.125
#define YMAX 1.125 /* y interval for 9/16 aspect ratio */
// // #define NX 1280 /* number of grid points on x axis */
// // #define NY 720 /* number of grid points on y axis */
// #define NX 2560 /* number of grid points on x axis */
// #define NY 1440 /* number of grid points on y axis */
//
// #define XMIN -1.25
// #define XMAX 2.75 /* x interval */
// #define YMIN -1.125
// #define YMAX 1.125 /* y interval for 9/16 aspect ratio */
#define JULIA_SCALE 1.0 /* scaling for Julia sets */
/* Choice of the billiard table */
#define B_DOMAIN 41 /* choice of domain shape, see list in global_pdes.c */
#define B_DOMAIN 3 /* choice of domain shape, see list in global_pdes.c */
#define CIRCLE_PATTERN 201 /* pattern of circles or polygons, see list in global_pdes.c */
@ -82,8 +86,8 @@
#define NPOISSON 300 /* number of points for Poisson C_RAND_POISSON arrangement */
#define RANDOM_POLY_ANGLE 1 /* set to 1 to randomize angle of polygons */
#define LAMBDA 1.1 /* parameter controlling the dimensions of domain */
#define MU 1.0 /* parameter controlling the dimensions of domain */
#define LAMBDA 0.75 /* parameter controlling the dimensions of domain */
#define MU 0.2 /* parameter controlling the dimensions of domain */
#define NPOLY 3 /* number of sides of polygon */
#define APOLY 0.3333333333333333 /* angle by which to turn polygon, in units of Pi/2 */
#define MDEPTH 6 /* depth of computation of Menger gasket */
@ -110,16 +114,18 @@
/* Physical parameters of wave equation */
#define TWOSPEEDS 0 /* set to 1 to replace hardcore boundary by medium with different speed */
#define OSCILLATE_LEFT 0 /* set to 1 to add oscilating boundary condition on the left */
#define TWOSPEEDS 1 /* set to 1 to replace hardcore boundary by medium with different speed */
#define OSCILLATE_LEFT 1 /* set to 1 to add oscilating boundary condition on the left */
#define OSCILLATE_TOPBOT 0 /* set to 1 to enforce a planar wave on top and bottom boundary */
#define OMEGA 0.002 /* frequency of periodic excitation */
#define AMPLITUDE 1.0 /* amplitude of periodic excitation */
#define COURANT 0.03 /* Courant number */
#define COURANTB 0.01 /* Courant number in medium B */
#define OMEGA 0.005 /* frequency of periodic excitation */
#define AMPLITUDE 0.8 /* amplitude of periodic excitation */
#define DAMPING 2.5e-5 /* damping of periodic excitation */
#define COURANT 0.05 /* Courant number */
#define COURANTB 0.0375 /* Courant number in medium B */
// #define COURANTB 0.016363636 /* Courant number in medium B */
#define GAMMA 0.0 /* damping factor in wave equation */
#define GAMMAB 5.0e-4 /* damping factor in wave equation */
#define GAMMAB 0.0 /* damping factor in wave equation */
#define GAMMA_SIDES 1.0e-4 /* damping factor on boundary */
#define GAMMA_TOPBOT 1.0e-7 /* damping factor on boundary */
#define KAPPA 0.0 /* "elasticity" term enforcing oscillations */
@ -130,18 +136,19 @@
/* Increasing COURANT speeds up the simulation, but decreases accuracy */
/* For similar wave forms, COURANT^2*GAMMA should be kept constant */
#define ADD_OSCILLATING_SOURCE 1 /* set to 1 to add an oscillating wave source */
#define ADD_OSCILLATING_SOURCE 0 /* set to 1 to add an oscillating wave source */
#define OSCILLATING_SOURCE_PERIOD 100 /* period of oscillating source */
/* Boundary conditions, see list in global_pdes.c */
#define B_COND 2
#define B_COND 3
// #define B_COND 2
/* Parameters for length and speed of simulation */
#define NSTEPS 2200 /* number of frames of movie */
#define NSTEPS 2700 /* number of frames of movie */
// #define NSTEPS 100 /* number of frames of movie */
#define NVID 25 /* number of iterations between images displayed on screen */
#define NVID 30 /* number of iterations between images displayed on screen */
#define NSEG 1000 /* number of segments of boundary */
#define INITIAL_TIME 0 /* time after which to start saving frames */
#define BOUNDARY_WIDTH 1 /* width of billiard boundary */
@ -151,7 +158,7 @@
#define SLEEP1 1 /* initial sleeping time */
#define SLEEP2 1 /* final sleeping time */
#define MID_FRAMES 20 /* number of still frames between parts of two-part movie */
#define END_FRAMES 50 /* number of still frames at end of movie */
#define END_FRAMES 100 /* number of still frames at end of movie */
/* Parameters of initial condition */
@ -162,23 +169,28 @@
/* Plot type, see list in global_pdes.c */
#define PLOT 0
// #define PLOT 3
// #define PLOT 1
#define PLOT_B 5 /* plot type for second movie */
#define PLOT_B 3 /* plot type for second movie */
/* Color schemes */
#define COLOR_PALETTE 18 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE_B 13 /* Color palette, see list in global_pdes.c */
#define BLACK 1 /* background */
#define COLOR_SCHEME 3 /* choice of color scheme, see list in global_pdes.c */
#define SCALE 0 /* set to 1 to adjust color scheme to variance of field */
#define SLOPE 0.2 /* sensitivity of color on wave amplitude */
#define SLOPE 1.0 /* sensitivity of color on wave amplitude */
#define PHASE_FACTOR 1.0 /* factor in computation of phase in color scheme P_3D_PHASE */
#define PHASE_SHIFT 0.0 /* shift of phase in color scheme P_3D_PHASE */
#define ATTENUATION 0.0 /* exponential attenuation coefficient of contrast with time */
#define E_SCALE 150.0 /* scaling factor for energy representation */
#define LOG_SCALE 1.5 /* scaling factor for energy log representation */
#define LOG_SHIFT 0.0 /* shift of colors on log scale */
#define E_SCALE 300.0 /* scaling factor for energy representation */
#define LOG_SCALE 1.0 /* scaling factor for energy log representation */
#define LOG_SHIFT 1.0 /* shift of colors on log scale */
#define RESCALE_COLOR_IN_CENTER 0 /* set to 1 to decrease color intentiy in the center (for wave escaping ring) */
#define COLORHUE 260 /* initial hue of water color for scheme C_LUM */
@ -189,8 +201,8 @@
#define HUEAMP -180.0 /* amplitude of variation of hue for color scheme C_HUE */
#define DRAW_COLOR_SCHEME 1 /* set to 1 to plot the color scheme */
#define COLORBAR_RANGE 6.0 /* scale of color scheme bar */
#define COLORBAR_RANGE_B 12.0 /* scale of color scheme bar for 2nd part */
#define COLORBAR_RANGE 1.0 /* scale of color scheme bar */
#define COLORBAR_RANGE_B 5.0 /* scale of color scheme bar for 2nd part */
#define ROTATE_COLOR_SCHEME 0 /* set to 1 to draw color scheme horizontally */
#define SAVE_TIME_SERIES 0 /* set to 1 to save wave time series at a point */
@ -211,137 +223,6 @@ double courant2, courantb2; /* Courant parameters squared */
/* animation part */
/*********************/
void evolve_wave_half_old(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX], double *psi_out[NX],
short int *xy_in[NX])
/* time step of field evolution */
/* phi is value of field at time t, psi at time t-1 */
{
int i, j, iplus, iminus, jplus, jminus;
double delta, x, y, c, cc, gamma;
static long time = 0;
time++;
// c = COURANT;
// cc = courant2;
#pragma omp parallel for private(i,j,iplus,iminus,jplus,jminus,delta,x,y,c,cc,gamma)
for (i=0; i<NX; i++){
for (j=0; j<NY; j++){
// if (xy_in[i][j])
// {
// c = COURANT;
// cc = courant2;
// gamma = GAMMA;
// }
if (xy_in[i][j] != 0)
{
c = COURANT;
cc = courant2;
if (xy_in[i][j] == 1) gamma = GAMMA;
else gamma = GAMMAB;
}
else if (TWOSPEEDS)
{
c = COURANTB;
cc = courantb2;
gamma = GAMMAB;
}
if ((TWOSPEEDS)||(xy_in[i][j] != 0)){
/* discretized Laplacian for various boundary conditions */
if ((B_COND == BC_DIRICHLET)||(B_COND == BC_ABSORBING))
{
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
jplus = (j+1); if (jplus == NY) jplus = NY-1;
jminus = (j-1); if (jminus == -1) jminus = 0;
}
else if (B_COND == BC_PERIODIC)
{
iplus = (i+1) % NX;
iminus = (i-1) % NX;
if (iminus < 0) iminus += NX;
jplus = (j+1) % NY;
jminus = (j-1) % NY;
if (jminus < 0) jminus += NY;
}
else if (B_COND == BC_VPER_HABS)
{
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
jplus = (j+1) % NY;
jminus = (j-1) % NY;
if (jminus < 0) jminus += NY;
}
/* imposing linear wave on top and bottom by making Laplacian 1d */
if (OSCILLATE_TOPBOT)
{
if (j == NY-1) jminus = NY-1;
else if (j == 0) jplus = 0;
}
delta = phi_in[iplus][j] + phi_in[iminus][j] + phi_in[i][jplus] + phi_in[i][jminus] - 4.0*phi_in[i][j];
x = phi_in[i][j];
y = psi_in[i][j];
/* evolve phi */
if ((B_COND == BC_PERIODIC)||(B_COND == BC_DIRICHLET))
phi_out[i][j] = -y + 2*x + cc*delta - KAPPA*x - gamma*(x-y);
else if (B_COND == BC_ABSORBING)
{
if ((i>0)&&(i<NX-1)&&(j>0)&&(j<NY-1))
phi_out[i][j] = -y + 2*x + cc*delta - KAPPA*x - gamma*(x-y);
/* upper border */
else if (j==NY-1)
phi_out[i][j] = x - c*(x - phi_in[i][NY-2]) - KAPPA_TOPBOT*x - GAMMA_TOPBOT*(x-y);
/* lower border */
else if (j==0)
phi_out[i][j] = x - c*(x - phi_in[i][1]) - KAPPA_TOPBOT*x - GAMMA_TOPBOT*(x-y);
/* right border */
if (i==NX-1)
phi_out[i][j] = x - c*(x - phi_in[NX-2][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
/* left border */
else if (i==0)
phi_out[i][j] = x - c*(x - phi_in[1][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
}
else if (B_COND == BC_VPER_HABS)
{
if ((i>0)&&(i<NX-1))
phi_out[i][j] = -y + 2*x + cc*delta - KAPPA*x - gamma*(x-y);
/* right border */
else if (i==NX-1)
phi_out[i][j] = x - c*(x - phi_in[NX-2][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
/* left border */
else if (i==0)
phi_out[i][j] = x - c*(x - phi_in[1][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
}
psi_out[i][j] = x;
/* add oscillating boundary condition on the left */
if ((i == 0)&&(OSCILLATE_LEFT)) phi_out[i][j] = AMPLITUDE*cos((double)time*OMEGA);
// psi_out[i][j] = x;
if (FLOOR)
{
if (phi_out[i][j] > VMAX) phi_out[i][j] = VMAX;
if (phi_out[i][j] < -VMAX) phi_out[i][j] = -VMAX;
if (psi_out[i][j] > VMAX) psi_out[i][j] = VMAX;
if (psi_out[i][j] < -VMAX) psi_out[i][j] = -VMAX;
}
}
}
}
// printf("phi(0,0) = %.3lg, psi(0,0) = %.3lg\n", phi[NX/2][NY/2], psi[NX/2][NY/2]);
}
void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX], double *psi_out[NX],
@ -400,7 +281,7 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
}
/* left boundary */
if (OSCILLATE_LEFT) for (j=1; j<NY-1; j++) phi_out[0][j] = AMPLITUDE*cos((double)time*OMEGA);
if (OSCILLATE_LEFT) for (j=1; j<NY-1; j++) phi_out[0][j] = AMPLITUDE*cos((double)time*OMEGA)*exp(-(double)time*DAMPING);
else for (j=1; j<NY-1; j++){
if ((TWOSPEEDS)||(xy_in[0][j] != 0)){
x = phi_in[0][j];
@ -575,8 +456,8 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
/* add oscillating boundary condition on the left corners */
if (OSCILLATE_LEFT)
{
phi_out[0][0] = AMPLITUDE*cos((double)time*OMEGA);
phi_out[0][NY-1] = AMPLITUDE*cos((double)time*OMEGA);
phi_out[0][0] = AMPLITUDE*cos((double)time*OMEGA)*exp(-(double)time*DAMPING);
phi_out[0][NY-1] = AMPLITUDE*cos((double)time*OMEGA)*exp(-(double)time*DAMPING);
}
/* for debugging purposes/if there is a risk of blow-up */
@ -606,10 +487,15 @@ void evolve_wave(double *phi[NX], double *psi[NX], double *phi_tmp[NX], double *
void draw_color_bar(int plot, double range)
{
if (ROTATE_COLOR_SCHEME) draw_color_scheme(-1.0, -0.8, XMAX - 0.1, -1.0, plot, -range, range);
else draw_color_scheme(1.7, YMIN + 0.1, 1.9, YMAX - 0.1, plot, -range, range);
else draw_color_scheme(XMAX - 0.3, YMIN + 0.1, XMAX - 0.1, YMAX - 0.1, plot, -range, range);
// else draw_color_scheme(1.7, YMIN + 0.25, 1.9, YMAX - 0.25, plot, -range, range);
}
void draw_color_bar_palette(int plot, double range, int palette)
{
if (ROTATE_COLOR_SCHEME) draw_color_scheme_palette(-1.0, -0.8, XMAX - 0.1, -1.0, plot, -range, range, palette);
else draw_color_scheme_palette(XMAX - 0.3, YMIN + 0.1, XMAX - 0.1, YMAX - 0.1, plot, -range, range, palette);
}
void animation()
{
@ -682,16 +568,18 @@ void animation()
// xy_to_ij(startright[0], startright[1], sample_right);
// printf("xleft = (%.3f, %.3f) xright = (%.3f, %.3f)\n", xin_left, yin_left, xin_right, yin_right);
// init_wave_flat(phi, psi, xy_in);
init_wave_flat(phi, psi, xy_in);
// init_wave_plus(LAMBDA - 0.3*MU, 0.5*MU, phi, psi, xy_in);
// init_wave(LAMBDA - 0.3*MU, 0.5*MU, phi, psi, xy_in);
// init_circular_wave(X_SHOOTER, Y_SHOOTER, phi, psi, xy_in);
// printf("Initializing wave\n");
// init_circular_wave(-1.0, 0.0, phi, psi, xy_in);
// init_circular_wave(-0.5, 0.0, phi, psi, xy_in);
// printf("Wave initialized\n");
init_circular_wave(0.6*cos((double)(period)*DPI/3.0), 0.6*sin((double)(period)*DPI/3.0), phi, psi, xy_in);
period++;
// init_circular_wave(0.6*cos((double)(period)*DPI/3.0), 0.6*sin((double)(period)*DPI/3.0), phi, psi, xy_in);
// period++;
// for (i=0; i<3; i++)
// {
// add_circular_wave(-1.0, 0.6*cos(PID + (double)(i)*DPI/3.0), 0.6*sin(PID + (double)(i)*DPI/3.0), phi, psi, xy_in);
@ -718,12 +606,13 @@ void animation()
blank();
glColor3f(0.0, 0.0, 0.0);
// draw_wave(phi, psi, xy_in, 1.0, 0, PLOT);
draw_wave_e(phi, psi, total_energy, color_scale, xy_in, 1.0, 0, PLOT);
// draw_wave_highres(2, phi, psi, total_energy, xy_in, 1.0, 0, PLOT);
if (HIGHRES) draw_wave_highres_palette(2, phi, psi, total_energy, xy_in, 1.0, 0, PLOT, COLOR_PALETTE);
else draw_wave_epalette(phi, psi, total_energy, color_scale, xy_in, 1.0, 0, PLOT, COLOR_PALETTE);
draw_billiard();
if (DRAW_COLOR_SCHEME) draw_color_bar(PLOT, COLORBAR_RANGE);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(PLOT, COLORBAR_RANGE, COLOR_PALETTE);
glutSwapBuffers();
@ -744,8 +633,8 @@ void animation()
else scale = 1.0;
// draw_wave(phi, psi, xy_in, scale, i, PLOT);
draw_wave_e(phi, psi, total_energy, color_scale, xy_in, scale, i, PLOT);
// draw_wave_highres(2, phi, psi, total_energy, xy_in, scale, i, PLOT);
if (HIGHRES) draw_wave_highres_palette(2, phi, psi, total_energy, xy_in, scale, i, PLOT, COLOR_PALETTE);
else draw_wave_epalette(phi, psi, total_energy, color_scale, xy_in, scale, i, PLOT, COLOR_PALETTE);
for (j=0; j<NVID; j++)
{
evolve_wave(phi, psi, phi_tmp, psi_tmp, xy_in);
@ -763,7 +652,7 @@ void animation()
draw_billiard();
if (DRAW_COLOR_SCHEME) draw_color_bar(PLOT, COLORBAR_RANGE);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(PLOT, COLORBAR_RANGE, COLOR_PALETTE);
/* add oscillating waves */
if ((ADD_OSCILLATING_SOURCE)&&(i%OSCILLATING_SOURCE_PERIOD == OSCILLATING_SOURCE_PERIOD - 1))
@ -783,12 +672,13 @@ void animation()
if ((i >= INITIAL_TIME)&&(DOUBLE_MOVIE))
{
// draw_wave(phi, psi, xy_in, scale, i, PLOT_B);
draw_wave_e(phi, psi, total_energy, color_scale, xy_in, scale, i, PLOT_B);
// draw_wave_highres(2, phi, psi, total_energy, xy_in, scale, i, PLOT_B);
if (HIGHRES) draw_wave_highres_palette(2, phi, psi, total_energy, xy_in, scale, i, PLOT_B, COLOR_PALETTE_B);
else draw_wave_epalette(phi, psi, total_energy, color_scale, xy_in, scale, i, PLOT_B, COLOR_PALETTE_B);
draw_billiard();
if (DRAW_COLOR_SCHEME) draw_color_bar(PLOT_B, COLORBAR_RANGE_B);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(PLOT_B, COLORBAR_RANGE_B, COLOR_PALETTE_B);
glutSwapBuffers();
save_frame_counter(NSTEPS + 21 + counter);
save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter);
// save_frame_counter(NSTEPS + 21 + counter);
counter++;
}
@ -809,20 +699,20 @@ void animation()
if (DOUBLE_MOVIE)
{
// draw_wave(phi, psi, xy_in, scale, i, PLOT);
draw_wave_e(phi, psi, total_energy, color_scale, xy_in, scale, NSTEPS, PLOT);
// draw_wave_highres(2, phi, psi, total_energy, xy_in, scale, NSTEPS, PLOT);
if (HIGHRES) draw_wave_highres_palette(2, phi, psi, total_energy, xy_in, scale, NSTEPS, PLOT, COLOR_PALETTE);
else draw_wave_epalette(phi, psi, total_energy, color_scale, xy_in, scale, NSTEPS, PLOT, COLOR_PALETTE);
draw_billiard();
if (DRAW_COLOR_SCHEME) draw_color_bar(PLOT, COLORBAR_RANGE);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(PLOT, COLORBAR_RANGE, COLOR_PALETTE);
glutSwapBuffers();
}
for (i=0; i<MID_FRAMES; i++) save_frame();
if (DOUBLE_MOVIE)
{
// draw_wave(phi, psi, xy_in, scale, i, PLOT_B);
draw_wave_e(phi, psi, total_energy, color_scale, xy_in, scale, NSTEPS, PLOT_B);
// draw_wave_highres(2, phi, psi, total_energy, xy_in, scale, NSTEPS, PLOT_B);
if (HIGHRES) draw_wave_highres_palette(2, phi, psi, total_energy, xy_in, scale, NSTEPS, PLOT_B, COLOR_PALETTE_B);
else draw_wave_epalette(phi, psi, total_energy, color_scale, xy_in, scale, NSTEPS, PLOT_B, COLOR_PALETTE_B);
draw_billiard();
if (DRAW_COLOR_SCHEME) draw_color_bar(PLOT_B, COLORBAR_RANGE_B);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(PLOT_B, COLORBAR_RANGE_B, COLOR_PALETTE_B);
glutSwapBuffers();
}
for (i=0; i<END_FRAMES; i++) save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter + i);

View File

@ -62,6 +62,8 @@ void init_circular_wave(double x, double y, double *phi[NX], double *psi[NX], sh
printf("Initializing wave\n");
for (i=0; i<NX; i++)
{
if (i%100 == 0) printf("Initializing column %i of %i\n", i, NX);
for (j=0; j<NY; j++)
{
ij_to_xy(i, j, xy);
@ -73,6 +75,7 @@ void init_circular_wave(double x, double y, double *phi[NX], double *psi[NX], sh
else phi[i][j] = 0.0;
psi[i][j] = 0.0;
}
}
}
void init_wave_plus(double x, double y, double *phi[NX], double *psi[NX], short int * xy_in[NX])
@ -266,7 +269,7 @@ double compute_energy(double *phi[NX], double *psi[NX], short int *xy_in[NX], in
+ (phi[i][j] - phi[i][jminus])*(phi[i][j] - phi[i][jminus]);
if (xy_in[i][j]) return(E_SCALE*E_SCALE*(velocity*velocity + 0.5*COURANT*COURANT*(gradientx2+gradienty2)));
else if (TWOSPEEDS) return(E_SCALE*E_SCALE*(velocity*velocity + 0.5*COURANTB*COURANTB*(gradientx2+gradienty2)));
else return(0);
else return(0.0);
}
@ -844,4 +847,113 @@ void draw_wave_highres_palette(int size, double *phi[NX], double *psi[NX], doubl
glEnd ();
}
/* modified function for "flattened" wave tables */
void init_circular_wave_mod(double x, double y, double phi[NX*NY], double psi[NX*NY], short int xy_in[NX*NY])
/* initialise field with drop at (x,y) - phi is wave height, psi is phi at time t-1 */
{
int i, j;
double xy[2], dist2;
printf("Initializing wave\n");
#pragma omp parallel for private(i,j,xy,dist2)
for (i=0; i<NX; i++)
{
if (i%100 == 0) printf("Initializing column %i of %i\n", i, NX);
for (j=0; j<NY; j++)
{
// printf("i*NY+j = %i\n", i*NY+j);
ij_to_xy(i, j, xy);
dist2 = (xy[0]-x)*(xy[0]-x) + (xy[1]-y)*(xy[1]-y);
xy_in[i*NY+j] = xy_in_billiard(xy[0],xy[1]);
if ((xy_in[i*NY+j])||(TWOSPEEDS))
phi[i*NY+j] = INITIAL_AMP*exp(-dist2/INITIAL_VARIANCE)*cos(-sqrt(dist2)/INITIAL_WAVELENGTH);
else phi[i*NY+j] = 0.0;
psi[i*NY+j] = 0.0;
}
}
}
void add_circular_wave_mod(double factor, double x, double y, double phi[NX*NY], double psi[NX*NY], short int xy_in[NX*NY])
/* add drop at (x,y) to the field with given prefactor */
{
int i, j;
double xy[2], dist2;
#pragma omp parallel for private(i,j,xy,dist2)
for (i=0; i<NX; i++)
for (j=0; j<NY; j++)
{
ij_to_xy(i, j, xy);
dist2 = (xy[0]-x)*(xy[0]-x) + (xy[1]-y)*(xy[1]-y);
if ((xy_in[i*NY+j])||(TWOSPEEDS))
phi[i*NY+j] += INITIAL_AMP*factor*exp(-dist2/INITIAL_VARIANCE)*cos(-sqrt(dist2)/INITIAL_WAVELENGTH);
}
}
double compute_variance_mod(double phi[NX*NY], double psi[NX*NY], short int xy_in[NX*NY])
/* compute the variance of the field, to adjust color scheme */
{
int i, j, n = 0;
double variance = 0.0;
#pragma omp parallel for private(i,j,variance)
for (i=1; i<NX; i++)
for (j=1; j<NY; j++)
{
if (xy_in[i*NY+j])
{
n++;
variance += phi[i*NY+j]*phi[i*NY+j];
}
}
if (n==0) n=1;
return(variance/(double)n);
}
double compute_energy_mod(double phi[NX*NY], double psi[NX*NY], short int xy_in[NX*NY], int i, int j)
{
double velocity, energy, gradientx2, gradienty2;
int iplus, iminus, jplus, jminus;
velocity = (phi[i*NY+j] - psi[i*NY+j]);
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
jplus = (j+1); if (jplus == NY) jplus = NY-1;
jminus = (j-1); if (jminus == -1) jminus = 0;
gradientx2 = (phi[iplus*NY+j]-phi[i*NY+j])*(phi[iplus*NY+j]-phi[i*NY+j])
+ (phi[i*NY+j] - phi[iminus*NY+j])*(phi[i*NY+j] - phi[iminus*NY+j]);
gradienty2 = (phi[i*NY+jplus]-phi[i*NY+j])*(phi[i*NY+jplus]-phi[i*NY+j])
+ (phi[i*NY+j] - phi[i*NY+jminus])*(phi[i*NY+j] - phi[i*NY+jminus]);
if (xy_in[i*NY+j]) return(E_SCALE*E_SCALE*(velocity*velocity + 0.5*COURANT*COURANT*(gradientx2+gradienty2)));
else if (TWOSPEEDS) return(E_SCALE*E_SCALE*(velocity*velocity + 0.5*COURANTB*COURANTB*(gradientx2+gradienty2)));
else return(0.0);
}
double compute_phase(double phi[NX*NY], double psi[NX*NY], short int xy_in[NX*NY], int i, int j)
{
double velocity, angle;
velocity = (phi[i*NY+j] - psi[i*NY+j]);
if (module2(phi[i*NY+j], velocity) < 1.0e-10) return(0.0);
else if (xy_in[i*NY+j])
{
angle = argument(phi[i*NY+j], PHASE_FACTOR*velocity/COURANT);
if (angle < 0.0) angle += DPI;
if ((i==NY/2)&&(j==NY/2)) printf("Phase = %.3lg Pi\n", angle/PI);
return(angle);
}
else if (TWOSPEEDS)
{
angle = argument(phi[i*NY+j], PHASE_FACTOR*velocity/COURANTB);
if (angle < 0.0) angle += DPI;
return(angle);
}
else return(0.0);
}

View File

@ -194,6 +194,8 @@
#define SCALE 0 /* set to 1 to adjust color scheme to variance of field */
#define SLOPE 1.0 /* sensitivity of color on wave amplitude */
// #define SLOPE 0.75 /* sensitivity of color on wave amplitude */
#define PHASE_FACTOR 1.0 /* factor in computation of phase in color scheme P_3D_PHASE */
#define PHASE_SHIFT 0.0 /* shift of phase in color scheme P_3D_PHASE */
#define ATTENUATION 0.0 /* exponential attenuation coefficient of contrast with time */
#define E_SCALE 200.0 /* scaling factor for energy representation */
#define LOG_SCALE 1.5 /* scaling factor for energy log representation */

View File

@ -172,6 +172,8 @@
#define SCALE 0 /* set to 1 to adjust color scheme to variance of field */
#define SLOPE 10.0 /* sensitivity of color on wave amplitude */
#define PHASE_FACTOR 1.0 /* factor in computation of phase in color scheme P_3D_PHASE */
#define PHASE_SHIFT 0.0 /* shift of phase in color scheme P_3D_PHASE */
#define ATTENUATION 0.0 /* exponential attenuation coefficient of contrast with time */
#define E_SCALE 500.0 /* scaling factor for energy representation */
#define LOG_SCALE 1.5 /* scaling factor for energy log representation */