Add files via upload

This commit is contained in:
nilsberglund-orleans 2021-11-12 16:22:24 +01:00 committed by GitHub
parent 7c444b3a0b
commit 1f962fc7c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 4046 additions and 1221 deletions

View File

@ -30,14 +30,11 @@
#define MOVIE 0 /* set to 1 to generate movie */
#define WINWIDTH 720 /* window width */
// #define WINWIDTH 1280 /* window width */
#define WINWIDTH 1280 /* window width */
#define WINHEIGHT 720 /* window height */
// #define XMIN -2.0
// #define XMAX 2.0 /* x interval */
#define XMIN -1.125
#define XMAX 1.125 /* x interval */
#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 */
@ -48,26 +45,29 @@
#define B_DOMAIN 15 /* choice of domain shape */
#define CIRCLE_PATTERN 0 /* pattern of circles */
#define POLYLINE_PATTERN 1 /* pattern of polyline */
#define ABSORBING_CIRCLES 0 /* set to 1 for circular scatterers to be absorbing */
#define NMAXCIRCLES 1000 /* total number of circles (must be at least NCX*NCY for square grid) */
#define NMAXPOLY 1000 /* total number of sides of polygonal line */
// #define NCX 10 /* number of circles in x direction */
// #define NCY 15 /* number of circles in y direction */
#define NCX 15 /* number of circles in x direction */
#define NCY 20 /* number of circles in y direction */
#define NPOISSON 500 /* number of points for Poisson C_RAND_POISSON arrangement */
#define NGOLDENSPIRAL 2000 /* max number of points for C_GOLDEN_SPIRAL arrandement */
#define SDEPTH 1 /* Sierpinski gastket depth */
#define LAMBDA 0.0 /* parameter controlling shape of billiard */
#define LAMBDA 0.3 /* parameter controlling the dimensions of domain */
// #define LAMBDA 1.124950941 /* sin(36°)/sin(31.5°) for 5-star shape with 45° angles */
// #define LAMBDA 1.445124904 /* sin(36°)/sin(24°) for 5-star shape with 60° angles */
// #define LAMBDA 3.75738973 /* sin(36°)/sin(9°) for 5-star shape with 90° angles */
// #define LAMBDA -1.73205080756888 /* -sqrt(3) for Reuleaux triangle */
// #define LAMBDA 1.73205080756888 /* sqrt(3) for triangle tiling plane */
#define MU 1.0 /* second parameter controlling shape of billiard */
#define MU 0.7 /* parameter controlling the dimensions of domain */
#define FOCI 1 /* set to 1 to draw focal points of ellipse */
#define NPOLY 6 /* number of sides of polygon */
#define NPOLY 4 /* number of sides of polygon */
#define APOLY 0.0 /* angle by which to turn polygon, in units of Pi/2 */
#define DRAW_BILLIARD 1 /* set to 1 to draw billiard */
#define DRAW_CONSTRUCTION_LINES 1 /* set to 1 to draw additional construction lines for billiard */
@ -75,7 +75,7 @@
#define RESAMPLE 0 /* set to 1 if particles should be added when dispersion too large */
#define NPART 10000 /* number of particles */
#define NPART 20000 /* number of particles */
#define NPARTMAX 100000 /* maximal number of particles after resampling */
#define NSTEPS 5000 /* number of frames of movie */
@ -92,7 +92,7 @@
#define LMAX 0.01 /* minimal segment length triggering resampling */
#define LPERIODIC 0.1 /* lines longer than this are not drawn (useful for Sinai billiard) */
#define LCUT 2.0 /* controls the max size of segments not considered as being cut */
#define LCUT 10000.0 /* controls the max size of segments not considered as being cut */
#define DMIN 0.02 /* minimal distance to boundary for triggering resampling */
#define CYCLE 0 /* set to 1 for closed curve (start in all directions) */
#define ORDER_COLORS 1 /* set to 1 if colors should be drawn in order */
@ -101,18 +101,18 @@
#define COLOR_PALETTE 1 /* Color palette, see list in global_pdes.c */
#define NCOLORS 6 /* number of colors */
#define NCOLORS 14 /* number of colors */
#define COLORSHIFT 3 /* hue of initial color */
#define RAINBOW_COLOR 0 /* set to 1 to use different colors for all particles */
#define NSEG 100 /* number of segments of boundary */
#define BILLIARD_WIDTH 4 /* width of billiard */
#define FRONT_WIDTH 4 /* width of wave front */
#define BLACK 1 /* set to 1 for black background */
#define BLACK 0 /* set to 1 for black background */
#define COLOR_OUTSIDE 0 /* set to 1 for colored outside */
#define OUTER_COLOR 300.0 /* color outside billiard */
#define PAINT_INT 1 /* set to 1 to paint interior in other color (for polygon) */
#define PAINT_EXT 0 /* set to 1 to paint exterior of billiard */
#define PAINT_INT 0 /* set to 1 to paint interior in other color (for polygon) */
#define PAINT_EXT 1 /* set to 1 to paint exterior of billiard */
#define PAUSE 1000 /* number of frames after which to pause */
@ -125,6 +125,7 @@
#define DPI 6.283185307
#define PID 1.570796327
#include "global_particles.c"
#include "sub_part_billiard.c"
@ -175,6 +176,27 @@ void init_drop_config(double x0, double y0, double angle1, double angle2, double
}
}
void init_partial_drop_config(int i1, int i2, double x0, double y0, double angle1, double angle2, double *configs[NPARTMAX])
/* initialize configuration: drop at (x0,y0) */
{
int i;
double dalpha, alpha, pos[2];
while (angle2 < angle1) angle2 += DPI;
dalpha = (angle2 - angle1)/((double)(i2 - i1));
if (i2 >= NPART) i2 = NPART;
for (i=i1; i<i2; i++)
{
alpha = angle1 + dalpha*((double)i);
pos[0] = x0;
pos[1] = y0;
vbilliard_xy(configs[i], alpha, pos);
}
}
int resample(int color[NPARTMAX], double *configs[NPARTMAX])
/* add particles where the front is stretched too thin */
@ -448,7 +470,10 @@ void animation()
configs[i] = (double *)malloc(8*sizeof(double));
// init_drop_config(0.1, 0.1, 0.0, DPI, configs);
init_drop_config(0.0, 0.0, 0.0, DPI, configs);
init_partial_drop_config(0, NPART/4, LAMBDA, 0.0, 0.0, DPI, configs);
init_partial_drop_config(NPART/4, NPART/2, -LAMBDA, 0.0, 0.0, DPI, configs);
init_partial_drop_config(NPART/2, 3*NPART/4, 0.0, LAMBDA, 0.0, DPI, configs);
init_partial_drop_config(3*NPART/4, NPART, 0.0, -LAMBDA, 0.0, DPI, configs);
// init_drop_config(-1.0 + 0.3*sqrt(2.0), -1.0 + 0.5*sqrt(2.0), 0.0, DPI, configs);
// init_drop_config(-0.5, -0.5, 0.0, DPI, configs);
// init_boundary_config(1.5, 1.5, 0.0, PI, configs);

View File

@ -1,9 +1,25 @@
double circlex[NMAXCIRCLES], circley[NMAXCIRCLES], circlerad[NMAXCIRCLES]; /* position and radius of circular scatters */
short int circleactive[NMAXCIRCLES]; /* tells which circular scatters are active */
short int newcircle[NMAXCIRCLES]; /* takes value 1 when circle has just been hit */
int circlecolor[NMAXCIRCLES]; /* color of circular scatterer */
// double circlex[NMAXCIRCLES], circley[NMAXCIRCLES], circlerad[NMAXCIRCLES]; /* position and radius of circular scatters */
// short int circleactive[NMAXCIRCLES]; /* tells which circular scatters are active */
// short int newcircle[NMAXCIRCLES]; /* takes value 1 when circle has just been hit */
// int circlecolor[NMAXCIRCLES]; /* color of circular scatterer */
int ncircles = NMAXCIRCLES; /* actual number of circles, can be decreased e.g. for random patterns */
int nsides = NMAXPOLY; /* actual number of sides of polygonal line */
typedef struct
{
double xc, yc, radius; /* center and radius of circle */
short int active, new, double_circle; /* circle is active, has just been hit, has a partner (for torus) */
int color, partner; /* circle color, number of partner */
} t_circle;
typedef struct
{
double x1, x2, y1, y2, length, angle;
int color;
} t_segment;
t_circle circles[NMAXCIRCLES];
t_segment polyline[NMAXPOLY];
double x_shooter = -0.2, y_shooter = -0.6, x_target = 0.4, y_target = 0.7;
/* shooter and target positions for "laser in room of mirrors" simulations, with default values for square domain */
@ -48,10 +64,17 @@ double x_shooter = -0.2, y_shooter = -0.6, x_target = 0.4, y_target = 0.7;
#define C_RAND_POISSON 6 /* random Poisson point process */
#define C_POISSON_DISC 7 /* Poisson disc sampling */
#define C_LASER 11 /* laser fight in a room of mirrors */
#define C_LASER_GENUSN 12 /* laser fight in a translation surface */
#define D_POLYLINE 30 /* general polygon */
#define P_RECTANGLE 0 /* rectangle (for test purposes) */
#define P_TOKARSKY 1 /* Tokarsky unilluminable room */
#define P_POLYRING 2 /* polygonal ring */
#define P_SIERPINSKI 3 /* polygonal ring */
#define P_VONKOCH 4 /* von Koch curve */
/* Color palettes */
#define COL_JET 0 /* JET color palette */
@ -62,5 +85,7 @@ double x_shooter = -0.2, y_shooter = -0.6, x_target = 0.4, y_target = 0.7;
#define COL_MAGMA 12 /* Magma color palette */
#define COL_INFERNO 13 /* Inferno color palette */
#define COL_PLASMA 14 /* Plasma color palette */
#define COL_CIVIDIS 15 /* Cividis color palette */
#define COL_PARULA 16 /* Parula color palette */

View File

@ -45,8 +45,14 @@
#define D_TOKARSKY 35 /* Tokarsky unilluminable room */
#define D_ISOSPECTRAL 37 /* isospectral billiards */
#define D_HOMOPHONIC 38 /* homophonic billiards */
#define NMAXCIRCLES 600 /* total number of circles (must be at least NCX*NCY for square grid) */
#define D_POLYGONS 40 /* several polygons */
#define D_VONKOCH 41 /* von Koch snowflake fractal */
#define NMAXCIRCLES 10000 /* total number of circles/polygons (must be at least NCX*NCY for square grid) */
#define NMAXPOLY 10000 /* maximal number of vertices of polygonal lines (for von Koch et al) */
// #define NMAXCIRCLES 10000 /* total number of circles/polygons (must be at least NCX*NCY for square grid) */
#define C_SQUARE 0 /* square grid of circles */
#define C_HEX 1 /* hexagonal/triangular grid of circles */
@ -75,6 +81,7 @@
#define D_MANDELBROT 24 /* Mandelbrot set */
#define D_JULIA 25 /* Julia set */
#define D_MANDELBROT_CIRCLE 26 /* Mandelbrot set with circular conductor */
#define D_VONKOCH_HEATED 27 /* von Koch snowflake in larger circle */
/* Boundary conditions */
@ -121,11 +128,37 @@
#define COL_MAGMA 12 /* Magma color palette */
#define COL_INFERNO 13 /* Inferno color palette */
#define COL_PLASMA 14 /* Plasma color palette */
#define COL_CIVIDIS 15 /* Cividis color palette */
#define COL_PARULA 16 /* Parula color palette */
typedef struct
{
double xc, yc, radius; /* center and radius of circle */
short int active; /* circle is active */
} t_circle;
typedef struct
{
double xc, yc, radius, angle; /* center, radius and angle of polygon */
int nsides; /* number of sides of polygon */
short int active; /* polygon is active */
} t_polygon;
typedef struct
{
double x, y; /* (x,y) coordinates of vertex */
double posi, posj; /* (i,j) coordinates of vertex */
} t_vertex;
double circlex[NMAXCIRCLES], circley[NMAXCIRCLES], circlerad[NMAXCIRCLES]; /* position and radius of circular scatterers */
short int circleactive[NMAXCIRCLES]; /* tells which circular scatters are active */
int ncircles = NMAXCIRCLES; /* actual number of circles, can be decreased e.g. for random patterns */
// double circlex[NMAXCIRCLES], circley[NMAXCIRCLES], circlerad[NMAXCIRCLES]; /* position and radius of circular scatterers */
// short int circleactive[NMAXCIRCLES]; /* tells which circular scatters are active */
int ncircles = NMAXCIRCLES; /* actual number of circles, can be decreased e.g. for random patterns */
int npolyline = NMAXPOLY; /* actual length of polyline */
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.33267, julia_y = 0.06395; /* parameters for Julia sets */

126
heat.c
View File

@ -57,7 +57,7 @@
#define YMIN -1.125
#define YMAX 1.125 /* y interval for 9/16 aspect ratio */
#define JULIA_SCALE 1.0 /* scaling for Julia sets */
#define JULIA_SCALE 0.5 /* scaling for Julia sets */
/* Choice of the billiard table */
@ -67,12 +67,13 @@
#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 0 /* set to 1 to randomize angle of polygons */
#define LAMBDA -1.0 /* parameter controlling the dimensions of domain */
#define MU 0.1 /* parameter controlling the dimensions of domain */
#define NPOLY 6 /* number of sides of polygon */
#define APOLY 1.0 /* angle by which to turn polygon, in units of Pi/2 */
#define MDEPTH 2 /* depth of computation of Menger gasket */
#define MDEPTH 5 /* depth of computation of Menger gasket */
#define MRATIO 5 /* ratio defining Menger gasket */
#define MANDELLEVEL 1000 /* iteration level for Mandelbrot set */
#define MANDELLIMIT 10.0 /* limit value for approximation of Mandelbrot set */
@ -114,11 +115,11 @@
/* Parameters for length and speed of simulation */
#define NSTEPS 4500 /* number of frames of movie */
#define NSTEPS 1000 /* number of frames of movie */
#define NVID 50 /* number of iterations between images displayed on screen */
// #define NVID 100 /* number of iterations between images displayed on screen */
#define NSEG 100 /* number of segments of boundary */
#define BOUNDARY_WIDTH 2 /* width of billiard boundary */
#define BOUNDARY_WIDTH 1 /* width of billiard boundary */
#define PAUSE 100 /* number of frames after which to pause */
#define PSLEEP 1 /* sleep time during pause */
@ -138,12 +139,12 @@
#define DRAW_FIELD_LINES 1 /* set to 1 to draw field lines */
#define FIELD_LINE_WIDTH 1 /* width of field lines */
#define N_FIELD_LINES 50 /* number of field lines */
#define FIELD_LINE_FACTOR 100 /* factor controlling precision when computing origin of field lines */
#define N_FIELD_LINES 120 /* number of field lines */
#define FIELD_LINE_FACTOR 120 /* factor controlling precision when computing origin of field lines */
/* Color schemes, see list in global_pdes.c */
#define COLOR_PALETTE 0 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE 10 /* Color palette, see list in global_pdes.c */
#define BLACK 1 /* black background */
@ -151,18 +152,26 @@
#define SCALE 0 /* set to 1 to adjust color scheme to variance of field */
// #define SLOPE 0.1 /* sensitivity of color on wave amplitude */
#define SLOPE 0.3 /* sensitivity of color on wave amplitude */
#define SLOPE 0.2 /* sensitivity of color on wave amplitude */
#define ATTENUATION 0.0 /* exponential attenuation coefficient of contrast with time */
#define E_SCALE 100.0 /* scaling factor for energy representation */
#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 220.0 /* mean value of hue for color scheme C_HUE */
#define HUEAMP -220.0 /* amplitude of variation of hue for color scheme C_HUE */
// #define HUEMEAN 180.0 /* mean value of hue for color scheme C_HUE */
// #define HUEAMP -180.0 /* amplitude of variation of hue for color scheme C_HUE */
#define HUEMEAN 359.0 /* mean value of hue for color scheme C_HUE */
#define HUEAMP -359.0 /* amplitude of variation of hue for color scheme C_HUE */
// #define HUEMEAN 270.0 /* mean value of hue for color scheme C_HUE */
// #define HUEAMP -130.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 2.0 /* scale of color scheme bar */
#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 */
#include "global_pdes.c"
#include "sub_wave.c"
@ -258,6 +267,7 @@ void draw_field_line(double x, double y, short int *xy_in[NX], double *nablax[NX
int i = 0, ij[2], cont = 1;
glColor3f(1.0, 1.0, 1.0);
// glColor3f(0.0, 0.0, 0.0);
glLineWidth(FIELD_LINE_WIDTH);
x1 = x;
y1 = y;
@ -351,7 +361,8 @@ void draw_wave(double *phi[NX], short int *xy_in[NX], double scale, int time)
x1 = x2;
y1 = y2;
}
distance[N_FIELD_LINES*FIELD_LINE_FACTOR - 1] = module2(x2-LAMBDA,y2-0.5);
distance[N_FIELD_LINES*FIELD_LINE_FACTOR - 1] = module2(x2- 0.99*LAMBDA,y2);
// distance[N_FIELD_LINES*FIELD_LINE_FACTOR - 1] = module2(x2-LAMBDA,y2-0.5);
}
dx = (XMAX-XMIN)/((double)NX);
@ -503,97 +514,7 @@ void evolve_wave(double *phi[NX], double *phi_tmp[NX], short int *xy_in[NX])
}
void old_evolve_wave(double *phi[NX], short int *xy_in[NX])
/* time step of field evolution */
{
int i, j, iplus, iminus, jplus, jminus;
double delta1, delta2, x, y, *newphi[NX];
for (i=0; i<NX; i++) newphi[i] = (double *)malloc(NY*sizeof(double));
#pragma omp parallel for private(i,j,iplus,iminus,jplus,jminus,delta1,delta2,x,y)
for (i=0; i<NX; i++){
for (j=0; j<NY; j++){
if (xy_in[i][j] == 1){
/* discretized Laplacian depending on 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;
}
delta1 = phi[iplus][j] + phi[iminus][j] + phi[i][jplus] + phi[i][jminus] - 4.0*phi[i][j];
x = phi[i][j];
/* evolve phi */
if (B_COND != BC_ABSORBING)
{
newphi[i][j] = x + intstep*(delta1 - SPEED*(phi[iplus][j] - phi[i][j]));
}
else /* case of absorbing b.c. - this is only an approximation of correct way of implementing */
{
/* in the bulk */
if ((i>0)&&(i<NX-1)&&(j>0)&&(j<NY-1))
{
newphi[i][j] = x - intstep*delta2;
}
/* right border */
else if (i==NX-1)
{
newphi[i][j] = x - intstep1*(x - phi[i-1][j]);
}
/* upper border */
else if (j==NY-1)
{
newphi[i][j] = x - intstep1*(x - phi[i][j-1]);
}
/* left border */
else if (i==0)
{
newphi[i][j] = x - intstep1*(x - phi[1][j]);
}
/* lower border */
else if (j==0)
{
newphi[i][j] = x - intstep1*(x - phi[i][1]);
}
}
if (FLOOR)
{
if (newphi[i][j] > VMAX) phi[i][j] = VMAX;
if (newphi[i][j] < -VMAX) phi[i][j] = -VMAX;
}
}
}
}
for (i=0; i<NX; i++){
for (j=0; j<NY; j++){
if (xy_in[i][j] == 1) phi[i][j] = newphi[i][j];
}
}
for (i=0; i<NX; i++)
{
free(newphi[i]);
}
// printf("phi(0,0) = %.3lg, psi(0,0) = %.3lg\n", phi[NX/2][NY/2], psi[NX/2][NY/2]);
}
double compute_variance(double *phi[NX], short int * xy_in[NX])
/* compute the variance (total probability) of the field */
@ -710,6 +631,9 @@ void animation()
xy_in[i] = (short int *)malloc(NY*sizeof(short int));
}
npolyline = init_polyline(MDEPTH, polyline);
for (i=0; i<npolyline; i++) printf("vertex %i: (%.3f, %.3f)\n", i, polyline[i].x, polyline[i].y);
dx = (XMAX-XMIN)/((double)NX);
intstep = DT/(dx*dx*VISCOSITY);
intstep1 = DT/(dx*VISCOSITY);

File diff suppressed because it is too large Load Diff

View File

@ -32,43 +32,41 @@
#define MOVIE 0 /* set to 1 to generate movie */
// #define WINWIDTH 1280 /* window width */
#define WINWIDTH 720 /* window width */
#define WINWIDTH 1280 /* window width */
#define WINHEIGHT 720 /* window height */
#define XMIN -1.4
#define XMAX 1.4 /* x interval */
#define YMIN -1.4
#define YMAX 1.4 /* y interval for 9/16 aspect ratio */
// #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 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 SCALING_FACTOR 1.0 /* scaling factor of drawing, needed for flower billiards, otherwise set to 1.0 */
/* Choice of the billiard table, see global_particles.c */
#define B_DOMAIN 16 /* choice of domain shape */
#define B_DOMAIN 30 /* choice of domain shape */
#define CIRCLE_PATTERN 2 /* pattern of circles */
#define CIRCLE_PATTERN 1 /* pattern of circles */
#define POLYLINE_PATTERN 1 /* pattern of polyline */
#define ABSORBING_CIRCLES 0 /* set to 1 for circular scatterers to be absorbing */
#define ABSORBING_CIRCLES 1 /* set to 1 for circular scatterers to be absorbing */
#define NMAXCIRCLES 1000 /* total number of circles (must be at least NCX*NCY for square grid) */
#define NMAXCIRCLES 100000 /* total number of circles (must be at least NCX*NCY for square grid) */
#define NMAXPOLY 100000 /* total number of sides of polygonal line */
// #define NCX 10 /* number of circles in x direction */
// #define NCY 10 /* number of circles in y direction */
#define NCX 30 /* number of circles in x direction */
#define NCY 20 /* number of circles in y direction */
#define NPOISSON 500 /* number of points for Poisson C_RAND_POISSON arrangement */
#define NGOLDENSPIRAL 2000 /* max number of points for C_GOLDEN_SPIRAL arrandement */
#define SDEPTH 1 /* Sierpinski gastket depth */
// #define LAMBDA 1.4 /* parameter controlling shape of domain */
// #define MU 0.2 /* second parameter controlling shape of billiard */
#define LAMBDA 1.3 /* parameter controlling shape of domain */
#define MU 0.3 /* second parameter controlling shape of billiard */
#define LAMBDA 1.8 /* parameter controlling shape of domain */
#define MU 0.01 /* second parameter controlling shape of billiard */
// #define LAMBDA 0.3 /* parameter controlling shape of domain */
// #define MU 0.7 /* second parameter controlling shape of billiard */
#define FOCI 1 /* set to 1 to draw focal points of ellipse */
#define NPOLY 4 /* number of sides of polygon */
#define NPOLY 6 /* number of sides of polygon */
#define APOLY 0.0 /* angle by which to turn polygon, in units of Pi/2 */
#define DRAW_BILLIARD 1 /* set to 1 to draw billiard */
#define DRAW_CONSTRUCTION_LINES 0 /* set to 1 to draw additional construction lines for billiard */
@ -79,17 +77,20 @@
/* Simulation parameters */
#define NPART 100 /* number of particles */
#define NPART 5000 /* number of particles */
#define NPARTMAX 100000 /* maximal number of particles after resampling */
#define LMAX 0.01 /* minimal segment length triggering resampling */
#define DMIN 0.02 /* minimal distance to boundary for triggering resampling */
#define CYCLE 1 /* set to 1 for closed curve (start in all directions) */
#define SHOWTRAILS 1 /* set to 1 to keep trails of the particles */
#define SHOWTRAILS 0 /* set to 1 to keep trails of the particles */
#define SHOWZOOM 1 /* set to 1 to show zoom on specific area */
#define PRINT_PARTICLE_NUMBER 0 /* set to 1 to print number of particles */
#define TEST_ACTIVE 1 /* set to 1 to test whether particle is in billiard */
#define NSTEPS 1300 /* number of frames of movie */
#define TIME 2500 /* time between movie frames, for fluidity of real-time simulation */
#define DPHI 0.00001 /* integration step */
#define NSTEPS 1000 /* number of frames of movie */
#define TIME 1500 /* time between movie frames, for fluidity of real-time simulation */
// #define DPHI 0.00001 /* integration step */
#define DPHI 0.000005 /* integration step */
#define NVID 150 /* number of iterations between images displayed on screen */
/* Decreasing TIME accelerates the animation and the movie */
@ -100,15 +101,15 @@
/* Colors and other graphical parameters */
#define COLOR_PALETTE 0 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE 10 /* Color palette, see list in global_pdes.c */
#define NCOLORS 64 /* number of colors */
#define NCOLORS 16 /* number of colors */
#define COLORSHIFT 0 /* hue of initial color */
#define RAINBOW_COLOR 1 /* set to 1 to use different colors for all particles */
#define FLOWER_COLOR 0 /* set to 1 to adapt initial colors to flower billiard (tracks vs core) */
#define NSEG 100 /* number of segments of boundary */
#define LENGTH 0.03 /* length of velocity vectors */
#define BILLIARD_WIDTH 2 /* width of billiard */
#define LENGTH 0.025 /* length of velocity vectors */
#define BILLIARD_WIDTH 3 /* width of billiard */
#define PARTICLE_WIDTH 2 /* width of particles */
#define FRONT_WIDTH 3 /* width of wave front */
@ -116,7 +117,7 @@
#define COLOR_OUTSIDE 0 /* set to 1 for colored outside */
#define OUTER_COLOR 270.0 /* color outside billiard */
#define PAINT_INT 0 /* set to 1 to paint interior in other color (for polygon/Reuleaux) */
#define PAINT_EXT 1 /* set to 1 to paint exterior */
#define PAINT_EXT 0 /* set to 1 to paint exterior */
#define PAUSE 1000 /* number of frames after which to pause */
#define PSLEEP 1 /* sleep time during pause */
@ -249,6 +250,131 @@ void init_line_config(double x0, double y0, double x1, double y1, double angle,
}
}
void draw_zoom(int color[NPARTMAX], double *configs[NPARTMAX], int active[NPARTMAX], double x_target, double y_target, double width)
/* draw zoom around target (for laser in room of mirrors) */
{
int i;
double x1, y1, x2, y2, xb, yb, cosphi, sinphi, rgb[3], shiftx = 0.0, shifty = 0.65, tradius, phi, zoomwidth = 0.4;
glEnable(GL_LINE_SMOOTH);
glColor3f(1.0, 1.0, 1.0);
/* draw zoomed area */
glLineWidth(BILLIARD_WIDTH/2);
x1 = x_target - width;
y1 = y_target - width;
x2 = x_target + width;
y2 = y_target + width;
glBegin(GL_LINE_LOOP);
glVertex2d(x1, y1);
glVertex2d(x2, y1);
glVertex2d(x2, y2);
glVertex2d(x1, y2);
glEnd();
/* draw zoom boundary */
glLineWidth(BILLIARD_WIDTH*2);
x1 = shiftx - zoomwidth;
y1 = shifty - zoomwidth;
x2 = shiftx + zoomwidth;
y2 = shifty + zoomwidth;
glBegin(GL_LINE_LOOP);
glVertex2d(x1, y1);
glVertex2d(x2, y1);
glVertex2d(x2, y2);
glVertex2d(x1, y2);
glEnd();
/* draw billiard boundaries in zoom */
glLineWidth(BILLIARD_WIDTH*2);
if (y_target + width > 1.0)
{
yb = shifty + 0.5*(1.0 - y_target)/width;
glBegin(GL_LINE_STRIP);
glVertex2d(x1, yb);
glVertex2d(x2, yb);
glVertex2d(x2, yb + 0.02);
glVertex2d(x1, yb + 0.02);
glEnd();
}
/* other boundaries not yet implemented */
/* draw target in zoom */
glLineWidth(BILLIARD_WIDTH*2);
glColor3f(0.0, 0.8, 0.2);
glBegin(GL_LINE_LOOP);
tradius = zoomwidth*MU/width;
for (i=0; i<=NSEG; i++)
{
phi = (double)i*DPI/(double)NSEG;
x1 = shiftx + tradius*cos(phi);
y1 = shifty + tradius*sin(phi);
glVertex2d(x1, y1);
}
glEnd ();
// glLineWidth(PARTICLE_WIDTH*2);
for (i=0; i<nparticles; i++)
{
cosphi = (configs[i][6] - configs[i][4])/configs[i][3];
sinphi = (configs[i][7] - configs[i][5])/configs[i][3];
x1 = (configs[i][4] + configs[i][2]*cosphi - x_target)/width;
y1 = (configs[i][5] + configs[i][2]*sinphi - y_target)/width;
x2 = (configs[i][4] + (configs[i][2] + LENGTH)*cosphi - x_target)/width;
y2 = (configs[i][5] + (configs[i][2] + LENGTH)*sinphi - y_target)/width;
/* adjusting segments that are partly in the domain */
if ((vabs(x1) < 1.0)&&(vabs(x2) > 1.0))
{
if (x1 > 0.0) xb = 1.0;
else xb = -1.0;
y2 = y1 + (xb - x1)*(y2 - y1)/(x2 - x1);
x2 = xb;
}
else
if ((vabs(x1) > 1.0)&&(vabs(x2) < 1.0))
{
if (x2 > 0.0) xb = 1.0;
else xb = -1.0;
y1 = y2 + (xb - x2)*(y1 - y2)/(x1 - x2);
x1 = xb;
}
if ((vabs(y1) < 1.0)&&(vabs(y2) > 1.0))
{
if (y1 > 0.0) yb = 1.0;
else yb = -1.0;
x2 = x1 + (yb - y1)*(x2 - x1)/(y2 - y1);
y2 = yb;
}
else
if ((vabs(y1) > 1.0)&&(vabs(y2) < 1.0))
{
if (y2 > 0.0) yb = 1.0;
else yb = -1.0;
x1 = x2 + (yb - y2)*(x1 - x2)/(y1 - y2);
y1 = yb;
}
// if ((active[i])&&(vabs(x1) < 1.0)&&(vabs(y1) < 1.0)&&(vabs(x2) < 1.0)&&(vabs(y2) < 1.0))
if (((active[i])&&(vabs(x1) < 1.0)&&(vabs(y1) < 1.0))||((vabs(x2) < 1.0)&&(vabs(y2) < 1.0)))
{
rgb_color_scheme(color[i], rgb);
glColor3f(rgb[0], rgb[1], rgb[2]);
glBegin(GL_LINE_STRIP);
glVertex2d(shiftx + zoomwidth*SCALING_FACTOR*x1, shifty + zoomwidth*SCALING_FACTOR*y1);
glVertex2d(shiftx + zoomwidth*SCALING_FACTOR*x2, shifty + zoomwidth*SCALING_FACTOR*y2);
glEnd ();
}
}
}
void draw_config_showtrails(int color[NPARTMAX], double *configs[NPARTMAX], int active[NPARTMAX])
/* draw the particles */
@ -312,13 +438,15 @@ void draw_config_showtrails(int color[NPARTMAX], double *configs[NPARTMAX], int
// }
}
if (DRAW_BILLIARD) draw_billiard();
if (SHOWZOOM) draw_zoom(color, configs, active, 0.95, 0.0, 0.1);
}
void draw_config(int color[NPARTMAX], double *configs[NPARTMAX], int active[NPARTMAX])
/* draw the particles */
{
int i;
int i, c;
double x1, y1, x2, y2, cosphi, sinphi, rgb[3];
glutSwapBuffers();
@ -333,12 +461,13 @@ void draw_config(int color[NPARTMAX], double *configs[NPARTMAX], int active[NPAR
{
if (configs[i][2]<0.0)
{
vbilliard(configs[i]);
c = vbilliard(configs[i]);
if (!RAINBOW_COLOR)
{
color[i]++;
if (color[i] >= NCOLORS) color[i] -= NCOLORS;
}
if ((ABSORBING_CIRCLES)&&(c < 0)) active[i] = 0;
}
configs[i][2] += DPHI;
@ -414,6 +543,8 @@ void draw_config(int color[NPARTMAX], double *configs[NPARTMAX], int active[NPAR
if (configs[i][2] > configs[i][3] - DPHI) configs[i][2] -= configs[i][3];
}
if (DRAW_BILLIARD) draw_billiard();
if (SHOWZOOM) draw_zoom(color, configs, active, 0.95, 0.0, 0.1);
}
@ -430,6 +561,7 @@ void graph_movie(int time, int color[NPARTMAX], double *configs[NPARTMAX], int a
{
// printf("reflecting particle %i\n", i);
c = vbilliard(configs[i]);
if ((ABSORBING_CIRCLES)&&(c < 0)) active[i] = 0;
// if (c>=0) color[i]++;
if ((!RAINBOW_COLOR)&&(c>=0)) color[i]++;
if (!RAINBOW_COLOR)
@ -451,31 +583,66 @@ void graph_movie(int time, int color[NPARTMAX], double *configs[NPARTMAX], int a
// draw_config(color, configs);
}
void print_part_number(double *configs[NPARTMAX], int active[NPARTMAX], double x, double y)
{
char message[50];
int i, n_active_particles = 0;
double rgb[3];
/* count active particles, using the fact that absorbed particles have been given dummy coordinates */
for (i=0; i<nparticles; i++)
if (active[i]) n_active_particles++;
// if (configs[i][0] != -10.0) n_active_particles++;
hsl_to_rgb(0.0, 0.0, 0.0, rgb);
erase_area(x, y, 0.5, 0.1, rgb);
glColor3f(1.0, 1.0, 1.0);
sprintf(message, "%i particles", n_active_particles);
write_text(x, y, message);
}
void animation()
{
double time, dt, alpha, r, rgb[3];
double *configs[NPARTMAX];
int i, j, resamp = 1, s, i1, i2;
int *color, *newcolor, *active;
// t_circle *circles; /* experimental */
/* Since NPARTMAX can be big, it seemed wiser to use some memory allocation here */
color = malloc(sizeof(int)*(NPARTMAX));
newcolor = malloc(sizeof(int)*(NPARTMAX));
active = malloc(sizeof(int)*(NPARTMAX));
// circles = malloc(sizeof(t_circle)*(NMAXCIRCLES)); /* experimental */
for (i=0; i<NPARTMAX; i++)
configs[i] = (double *)malloc(8*sizeof(double));
/* init circle configuration if the domain is D_CIRCLES */
if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN == D_CIRCLES_IN_RECT)||(B_DOMAIN == D_CIRCLES_IN_GENUSN)) init_circle_config();
if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN == D_CIRCLES_IN_RECT)||(B_DOMAIN == D_CIRCLES_IN_GENUSN)
||(B_DOMAIN == D_CIRCLES_IN_TORUS)) init_circles(circles);
else if (B_DOMAIN == D_POLYLINE) init_polyline(polyline, circles);
/* initialize system by putting particles in a given point with a range of velocities */
r = cos(PI/(double)NPOLY)/cos(DPI/(double)NPOLY);
// init_partial_drop_config(LAMBDA, 0.0, 0.0, DPI, 0, NPART/4, 0, configs, color, newcolor);
// init_partial_drop_config(-LAMBDA, 0.0, 0.0, DPI, NPART/4, NPART/2, 0, configs, color, newcolor);
// init_partial_drop_config(0.0, LAMBDA, 0.0, DPI, NPART/2, 3*NPART/4, 0, configs, color, newcolor);
// init_partial_drop_config(0.0, -LAMBDA, 0.0, DPI, 3*NPART/4, NPART, 0, configs, color, newcolor);
// init_drop_config(-1.0 + 0.3*sqrt(2.0), -1.0 + 0.5*sqrt(2.0), 0.0, DPI, configs);
// init_line_config(-1.25, -0.5, -1.25, 0.5, 0.0, configs);
// init_drop_config(0.5, 0.7, 0.0, DPI, configs);
// init_drop_config(0.0, 0.0, -PI, PI, configs);
init_drop_config(-0.95, 0.0, PI, 3.0*PI, configs);
// init_drop_config(-1.3, -0.1, 0.0, DPI, configs);
init_drop_config(1.4, 0.1, 0.0, DPI, configs);
// init_drop_config(1.4, 0.1, 0.0, DPI, configs);
// init_drop_config(0.5, 0.5, -1.0, 1.0, configs);
// init_sym_drop_config(-1.0, 0.5, -PID, PID, configs);
// init_drop_config(-0.999, 0.0, -alpha, alpha, configs);
@ -492,6 +659,7 @@ void animation()
if (!SHOWTRAILS) blank();
glColor3f(0.0, 0.0, 0.0);
if (DRAW_BILLIARD) draw_billiard();
if (PRINT_PARTICLE_NUMBER) print_part_number(configs, active, XMIN + 0.1, YMIN + 0.1);
glutSwapBuffers();
@ -528,13 +696,13 @@ void animation()
newcolor[i] = (i*NCOLORS)/NPART;
}
sleep(SLEEP1);
sleep(SLEEP1);
/* initialize drops in different colors */
init_partial_drop_config(0.0, 0.0, 0.0, DPI, 0, 2*NPART/5, 0, configs, color, newcolor);
init_partial_drop_config(0.0, 0.8, 0.0, DPI, 2*NPART/5, 4*NPART/5, 10, configs, color, newcolor);
init_partial_drop_config(1.2, 0.1, 0.0, DPI, 4*NPART/5, NPART, 36, configs, color, newcolor);
// init_partial_drop_config(0.0, 0.0, 0.0, DPI, 0, 2*NPART/5, 0, configs, color, newcolor);
// init_partial_drop_config(0.0, 0.8, 0.0, DPI, 2*NPART/5, 4*NPART/5, 10, configs, color, newcolor);
// init_partial_drop_config(1.2, 0.1, 0.0, DPI, 4*NPART/5, NPART, 36, configs, color, newcolor);
for (i=0; i<=NSTEPS; i++)
{
@ -544,12 +712,13 @@ void animation()
else draw_config(newcolor, configs, active);
// draw_config(newcolor, configs, active);
if (DRAW_BILLIARD) draw_billiard();
if (PRINT_PARTICLE_NUMBER) print_part_number(configs, active, XMIN + 0.1, YMIN + 0.1);
for (j=0; j<NPARTMAX; j++) color[j] = newcolor[j];
/* draw initial points */
draw_initial_condition_circle(0.0, 0.0, 0.02, 0);
draw_initial_condition_circle(0.0, 0.8, 0.02, 10);
draw_initial_condition_circle(1.2, 0.1, 0.02, 36);
// draw_initial_condition_circle(0.0, 0.0, 0.02, 0);
// draw_initial_condition_circle(0.0, 0.8, 0.02, 10);
// draw_initial_condition_circle(1.2, 0.1, 0.02, 36);
if (MOVIE)
{

View File

@ -38,7 +38,6 @@
#define XMIN -4.0
#define XMAX 4.0 /* x interval */
#define YMIN -1.25
// #define YMID 1.25
#define YMAX 3.25 /* y interval for 9/16 aspect ratio */
// #define XMIN -2.0
// #define XMAX 2.0 /* x interval */
@ -54,27 +53,25 @@
#define B_DOMAIN 23 /* choice of domain shape */
#define CIRCLE_PATTERN 6 /* pattern of circles */
#define CIRCLE_PATTERN 7 /* pattern of circles */
#define POLYLINE_PATTERN 1 /* pattern of polyline */
// #define CIRCLE_PATTERN 21 /* pattern of circles */
#define ABSORBING_CIRCLES 0 /* set to 1 for circular scatterers to be absorbing */
#define NMAXCIRCLES 1000 /* total number of circles (must be at least NCX*NCY for square grid) */
#define NMAXCIRCLES 5000 /* total number of circles (must be at least NCX*NCY for square grid) */
#define NMAXPOLY 1000 /* total number of sides of polygonal line */
#define NCX 44 /* number of circles in x direction */
#define NCY 10 /* number of circles in y direction */
// #define NCX 50 /* number of circles in x direction */
// #define NCY 20 /* number of circles in y direction */
// #define NCX 52 /* number of circles in x direction */
// #define NCY 30 /* number of circles in y direction */
#define NPOISSON 350 /* number of points for Poisson C_RAND_POISSON arrangement */
#define NGOLDENSPIRAL 2000 /* max number of points for C_GOLDEN_SPIRAL arrandement */
#define SDEPTH 1 /* Sierpinski gastket depth */
#define LAMBDA 3.8105 /* parameter controlling shape of domain */
#define LAMBDA 3.8 /* parameter controlling shape of domain */
// #define MU 0.1 /* second parameter controlling shape of billiard */
#define MU 0.07 /* second parameter controlling shape of billiard */
// #define MU 0.085 /* second parameter controlling shape of billiard */
// #define MU 0.09 /* second parameter controlling shape of billiard */
#define MU 0.05 /* second parameter controlling shape of billiard */
// #define MU 0.034 /* second parameter controlling shape of billiard */
#define FOCI 1 /* set to 1 to draw focal points of ellipse */
#define NPOLY 4 /* number of sides of polygon */
@ -96,7 +93,7 @@
#define SHOWTRAILS 0 /* set to 1 to keep trails of the particles */
#define TEST_ACTIVE 0 /* set to 1 to test whether particle is in billiard */
#define NSTEPS 11700 /* number of frames of movie */
#define NSTEPS 10400 /* number of frames of movie */
// #define NSTEPS 1000 /* number of frames of movie */
// #define TIME 1500 /* time between movie frames, for fluidity of real-time simulation */
#define TIME 4000 /* time between movie frames, for fluidity of real-time simulation */
@ -145,7 +142,7 @@
#define END_FRAMES 100 /* number of still frames at end of movie */
#define NPATHBINS 200 /* number of bins for path length histogramm */
#define PATHLMAX 2.5 /* max free path on graph */
#define PATHLMAX 1.8 /* max free path on graph */
#include "global_particles.c"
#include "sub_part_billiard.c"
@ -454,13 +451,13 @@ void graph_movie(int time, int color[NPARTMAX], double *configs[NPARTMAX], int a
if (B_DOMAIN != D_CIRCLES_IN_TORUS) ncol++;
else if (c >= 0) ncol++;
if ((c >= 0)&&(circlecolor[c] == 0)) nobst++;
circlecolor[c]++;
if ((c >= 0)&&(circles[c].color == 0)) nobst++;
circles[c].color++;
/* take care of circles doubled because of periodic boundary conditions */
if ((circleactive[c])&&(B_DOMAIN == D_CIRCLES_IN_TORUS)&&(partner_circle[c] != c)) circlecolor[partner_circle[c]]++;
if ((circles[c].active)&&(B_DOMAIN == D_CIRCLES_IN_TORUS)&&(circles[c].partner != c)) circles[circles[c].partner].color++;
newcircle[c] = 10;
circles[c].new = 10;
/* update free path statistics */
if (ncol > 1) /* disregard very first collision */
@ -519,9 +516,9 @@ void print_particle_numbers(double *configs[NPARTMAX])
{
/* find leftmost and rightmost circle */
for (i=0; i<ncircles; i++)
if ((circleactive[i])&&(circlex[i] - circlerad[i] < xleft)) xleft = circlex[i] - circlerad[i];
if ((circles[i].active)&&(circles[i].xc - circles[i].radius < xleft)) xleft = circles[i].xc - circles[i].radius;
for (i=0; i<ncircles; i++)
if ((circleactive[i])&&(circlex[i] + circlerad[i] > xright)) xright = circlex[i] + circlerad[i];
if ((circles[i].active)&&(circles[i].xc + circles[i].radius > xright)) xright = circles[i].xc + circles[i].radius;
first = 0;
@ -574,9 +571,9 @@ void draw_statistics()
/* histogram of number of collisions per peg */
for (i=0; i<colmax; i++) pegcollisions[i] = 0;
for (i=0; i<ncircles; i++) if ((circleactive[i])&&(!double_circle[i]))
for (i=0; i<ncircles; i++) if ((circles[i].active)&&(!circles[i].double_circle))
{
n = circlecolor[i];
n = circles[i].color;
if (n < colmax) pegcollisions[n]++;
}
for (i=1; i<colmax; i++)
@ -758,23 +755,28 @@ void animation(int circle_config)
configs[i] = (double *)malloc(8*sizeof(double));
/* init circle configuration if the domain is D_CIRCLES */
// if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN == D_CIRCLES_IN_RECT)||(B_DOMAIN == D_CIRCLES_IN_GENUSN)
// ||(B_DOMAIN == D_CIRCLES_IN_TORUS))
// init_circle_config_pinball(circle_config);
/* init circle configuration if the domain is D_CIRCLES */
if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN == D_CIRCLES_IN_RECT)||(B_DOMAIN == D_CIRCLES_IN_GENUSN)
||(B_DOMAIN == D_CIRCLES_IN_TORUS))
init_circle_config_pinball(circle_config);
||(B_DOMAIN == D_CIRCLES_IN_TORUS)) init_circles_pinball(circle_config, circles);
/* remove discs that are not in domain */
if ((B_DOMAIN == D_CIRCLES_IN_RECT)||(B_DOMAIN == D_CIRCLES_IN_GENUSN))
// ||(B_DOMAIN == D_CIRCLES_IN_TORUS))
for (i=0; i<ncircles; i++)
{
if (vabs(circley[i]) + circlerad[i] > 0.99) circleactive[i] = 0;
if (vabs(circlex[i]) + circlerad[i] > 0.99*LAMBDA) circleactive[i] = 0;
if (vabs(circles[i].xc) + circles[i].radius > 0.99) circles[i].active = 0;
if (vabs(circles[i].xc) + circles[i].radius > 0.99*LAMBDA) circles[i].active = 0;
}
else if (B_DOMAIN == D_CIRCLES_IN_TORUS)
for (i=0; i<ncircles; i++)
{
if (vabs(circley[i]) - circlerad[i] > 1.0) circleactive[i] = 0;
if (vabs(circlex[i]) - circlerad[i] > LAMBDA) circleactive[i] = 0;
if (vabs(circles[i].yc) - circles[i].radius > 1.0) circles[i].active = 0;
if (vabs(circles[i].xc) - circles[i].radius > LAMBDA) circles[i].active = 0;
}
// for (i=0; i<ncircles; i++)
@ -884,7 +886,7 @@ void animation(int circle_config)
/* count max number a peg is hit */
nmaxpeg = 0;
for (j=0; j<ncircles; j++)
if (circlecolor[j] > nmaxpeg) nmaxpeg = circlecolor[j];
if (circles[j].color > nmaxpeg) nmaxpeg = circles[j].color;
// sprintf(message, "max hits per peg: %d", nmaxpeg);
// glColor3f(1.0, 1.0, 1.0);

View File

@ -39,42 +39,39 @@
/* General geometrical parameters */
// #define WINWIDTH 1280 /* window width */
#define WINWIDTH 720 /* window width */
#define WINWIDTH 1280 /* window width */
#define WINHEIGHT 720 /* window height */
// #define NX 1280 /* number of grid points on x axis */
#define NX 720 /* number of grid points on x axis */
#define NY 720 /* number of grid points on y axis */
// #define NX 640 /* number of grid points on x axis */
// #define NY 360 /* number of grid points on y axis */
// #define NX 720 /* number of grid points on x axis */
#define NX 640 /* number of grid points on x axis */
#define NY 360 /* number of grid points on y axis */
/* setting NX to WINWIDTH and NY to WINHEIGHT increases resolution */
/* but will multiply run time by 4 */
#define XMIN -2.0
#define XMAX 2.0 /* x interval */
#define YMIN -2.0
#define YMAX 2.0 /* y interval for 9/16 aspect ratio */
// #define YMIN -1.125
// #define YMAX 1.125 /* y interval for 9/16 aspect ratio */
#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, see list in global_pdes.c */
#define B_DOMAIN 19 /* choice of domain shape */
#define B_DOMAIN 10 /* choice of domain shape */
#define CIRCLE_PATTERN 0 /* pattern of circles, 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.0 /* parameter controlling the dimensions of domain */
#define MU 1.75 /* parameter controlling the dimensions of domain */
#define LAMBDA 0.1 /* parameter controlling the dimensions of domain */
#define MU 0.03 /* parameter controlling the dimensions of domain */
#define NPOLY 6 /* number of sides of polygon */
#define APOLY 1.0 /* angle by which to turn polygon, in units of Pi/2 */
#define MDEPTH 3 /* depth of computation of Menger gasket */
#define MDEPTH 5 /* 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 */
@ -98,8 +95,8 @@
/* Physical patameters of wave equation */
// #define DT 0.00000005
#define DT 0.00000001
// #define DT 0.00000001
// #define DT 0.000000005
// #define DT 0.000000005
#define HBAR 1.0
@ -110,9 +107,9 @@
/* Parameters for length and speed of simulation */
#define NSTEPS 1400 /* number of frames of movie */
#define NVID 2000 /* number of iterations between images displayed on screen */
// #define NVID 1200 /* number of iterations between images displayed on screen */
#define NSTEPS 2500 /* number of frames of movie */
// #define NVID 2000 /* number of iterations between images displayed on screen */
#define NVID 1200 /* number of iterations between images displayed on screen */
#define NSEG 100 /* number of segments of boundary */
#define BOUNDARY_WIDTH 2 /* width of billiard boundary */
@ -120,6 +117,7 @@
#define PSLEEP 1 /* sleep time during pause */
#define SLEEP1 1 /* initial sleeping time */
#define SLEEP2 1 /* final sleeping time */
#define END_FRAMES 100 /* still frames at end of movie */
/* For debugging purposes only */
#define FLOOR 0 /* set to 1 to limit wave amplitude to VMAX */
@ -133,22 +131,28 @@
/* Color schemes, see list in global_pdes.c */
#define COLOR_PALETTE 0 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE 10 /* Color palette, see list in global_pdes.c */
#define BLACK 1 /* black background */
#define COLOR_SCHEME 1 /* choice of color scheme */
#define COLOR_SCHEME 3 /* choice of color scheme */
#define SCALE 1 /* set to 1 to adjust color scheme to variance of field */
#define SLOPE 1.0 /* sensitivity of color on wave amplitude */
#define ATTENUATION 0.0 /* exponential attenuation coefficient of contrast with time */
#define E_SCALE 150.0 /* scaling factor for energy representation */
#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 150.0 /* mean value of hue for color scheme C_HUE */
#define HUEAMP -150.0 /* amplitude of variation of hue for color scheme C_HUE */
#define HUEMEAN 180.0 /* mean value of hue for color scheme C_HUE */
#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 2.0 /* scale of color scheme bar */
#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 */
#include "global_pdes.c"
#include "sub_wave.c"
@ -249,7 +253,7 @@ void draw_wave(double *phi[NX], double *psi[NX], short int *xy_in[NX], double sc
glEnd ();
}
void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX], double *psi_out[NX],
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])
// void evolve_wave_half(phi_in, psi_in, phi_out, psi_out, xy_in)
// /* time step of field evolution */
@ -342,6 +346,168 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
// 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],
short int *xy_in[NX])
// void evolve_wave_half(phi_in, psi_in, phi_out, psi_out, xy_in)
// /* time step of field evolution */
// /* phi is real part, psi is imaginary part */
{
int i, j, iplus, iminus, jplus, jminus;
double delta1, delta2, x, y;
#pragma omp parallel for private(i,j,iplus,iminus,jplus,jminus,delta1,delta2,x,y)
for (i=1; i<NX-1; i++){
for (j=1; j<NY-1; j++){
if (xy_in[i][j]){
x = phi_in[i][j];
y = psi_in[i][j];
delta1 = phi_in[i+1][j] + phi_in[i-1][j] + phi_in[i][j+1] + phi_in[i][j-1] - 4.0*x;
delta2 = psi_in[i+1][j] + psi_in[i-1][j] + psi_in[i][j+1] + psi_in[i][j-1] - 4.0*y;
/* evolve phi and psi */
phi_out[i][j] = x - intstep*delta2;
psi_out[i][j] = y + intstep*delta1;
}
}
}
/* left boundary */
for (j=1; j<NY-1; j++){
if (xy_in[0][j]){
x = phi_in[0][j];
y = psi_in[0][j];
switch (B_COND) {
case (BC_DIRICHLET):
{
delta1 = phi_in[1][j] + phi_in[0][j+1] + phi_in[0][j-1] - 3.0*x;
delta2 = psi_in[1][j] + psi_in[0][j+1] + psi_in[0][j-1] - 3.0*y;
phi_out[0][j] = x - intstep*delta2;
psi_out[0][j] = y + intstep*delta1;
break;
}
case (BC_PERIODIC):
{
delta1 = phi_in[1][j] + phi_in[NX-1][j] + phi_in[0][j+1] + phi_in[0][j-1] - 4.0*x;
delta2 = psi_in[1][j] + psi_in[NX-1][j] + psi_in[0][j+1] + psi_in[0][j-1] - 4.0*y;
phi_out[0][j] = x - intstep*delta2;
psi_out[0][j] = y + intstep*delta1;
break;
}
}
}
}
/* right boundary */
for (j=1; j<NY-1; j++){
if (xy_in[0][j]){
x = phi_in[NX-1][j];
y = psi_in[NX-1][j];
switch (B_COND) {
case (BC_DIRICHLET):
{
delta1 = phi_in[NX-2][j] + phi_in[NX-1][j+1] + phi_in[NX-1][j-1] - 3.0*x;
delta2 = psi_in[NX-2][j] + psi_in[NX-1][j+1] + psi_in[NX-1][j-1] - 3.0*y;
phi_out[NX-1][j] = x - intstep*delta2;
psi_out[NX-1][j] = y + intstep*delta1;
break;
}
case (BC_PERIODIC):
{
delta1 = phi_in[NX-2][j] + phi_in[0][j] + phi_in[NX-1][j+1] + phi_in[NX-1][j-1] - 4.0*x;
delta2 = psi_in[NX-2][j] + psi_in[0][j] + psi_in[NX-1][j+1] + psi_in[NX-1][j-1] - 4.0*y;
phi_out[NX-1][j] = x - intstep*delta2;
psi_out[NX-1][j] = y + intstep*delta1;
break;
}
}
}
}
/* top boundary */
for (i=0; i<NX; i++){
if (xy_in[i][NY-1]){
x = phi_in[i][NY-1];
y = psi_in[i][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;
delta1 = phi_in[iplus][NY-1] + phi_in[iminus][NY-1] + phi_in[i][NY-2] - 3.0*x;
delta2 = psi_in[iplus][NY-1] + psi_in[iminus][NY-1] + psi_in[i][NY-2] - 3.0*x;
phi_out[i][NY-1] = x - intstep*delta2;
psi_out[i][NY-1] = y + intstep*delta1;
break;
}
case (BC_PERIODIC):
{
iplus = (i+1) % NX;
iminus = (i-1) % NX;
if (iminus < 0) iminus += NX;
delta1 = phi_in[iplus][NY-1] + phi_in[iminus][NY-1] + phi_in[i][NY-2] + phi_in[i][0] - 4.0*x;
delta2 = psi_in[iplus][NY-1] + psi_in[iminus][NY-1] + psi_in[i][NY-2] + psi_in[i][0] - 4.0*y;
phi_out[i][NY-1] = x - intstep*delta2;
psi_out[i][NY-1] = y + intstep*delta1;
break;
}
}
}
}
/* bottom boundary */
for (i=0; i<NX; i++){
if (xy_in[i][0]){
x = phi_in[i][0];
y = psi_in[i][0];
switch (B_COND) {
case (BC_DIRICHLET):
{
iplus = i+1; if (iplus == NX) iplus = NX-1;
iminus = i-1; if (iminus == -1) iminus = 0;
delta1 = phi_in[iplus][0] + phi_in[iminus][0] + phi_in[i][1] - 3.0*x;
delta2 = psi_in[iplus][0] + psi_in[iminus][0] + psi_in[i][1] - 3.0*x;
phi_out[i][0] = x - intstep*delta2;
psi_out[i][0] = y + intstep*delta1;
break;
}
case (BC_PERIODIC):
{
iplus = (i+1) % NX;
iminus = (i-1) % NX;
if (iminus < 0) iminus += NX;
delta1 = phi_in[iplus][0] + phi_in[iminus][0] + phi_in[i][1] + phi_in[i][NY-1] - 4.0*x;
delta2 = psi_in[iplus][0] + psi_in[iminus][0] + psi_in[i][1] + psi_in[i][NY-1] - 4.0*y;
phi_out[i][0] = x - intstep*delta2;
psi_out[i][0] = y + intstep*delta1;
break;
}
}
}
}
/* 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][j] != 0)
{
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;
}
}
}
}
void evolve_wave(double *phi[NX], double *psi[NX], double *phi_tmp[NX], double *psi_tmp[NX], short int *xy_in[NX])
/* time step of field evolution */
/* phi is real part, psi is imaginary part */
@ -392,6 +558,13 @@ void renormalise_field(double *phi[NX], double *psi[NX], short int *xy_in[NX], d
}
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);
}
void animation()
{
double time, scale, dx, var;
@ -408,6 +581,10 @@ void animation()
psi_tmp[i] = (double *)malloc(NY*sizeof(double));
xy_in[i] = (short int *)malloc(NY*sizeof(short int));
}
/* initialise polyline for von Koch and simular 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);
dx = (XMAX-XMIN)/((double)NX);
intstep = DT/(dx*dx*HBAR);
@ -416,7 +593,7 @@ void animation()
printf("Integration step %.3lg\n", intstep);
/* initialize wave wave function */
init_coherent_state(0.5, 0.0, 40.0, 0.0, 0.25, phi, psi, xy_in);
init_coherent_state(-0.5, 0.0, 15.0, 0.0, 0.15, phi, psi, xy_in);
// init_coherent_state(0.0, 0.0, 0.0, 5.0, 0.03, phi, psi, xy_in);
// init_coherent_state(-0.5, 0.0, 1.0, 1.0, 0.05, phi, psi, xy_in);
@ -429,15 +606,14 @@ void animation()
renormalise_field(phi, psi, xy_in, var);
}
blank();
if (DRAW_COLOR_SCHEME) draw_color_bar(PLOT, COLORBAR_RANGE);
glColor3f(0.0, 0.0, 0.0);
glutSwapBuffers();
sleep(SLEEP1);
for (i=0; i<=NSTEPS; i++)
@ -461,6 +637,8 @@ void animation()
draw_billiard();
if (DRAW_COLOR_SCHEME) draw_color_bar(PLOT, COLORBAR_RANGE);
glutSwapBuffers();
if (MOVIE)
@ -476,14 +654,14 @@ void animation()
s = system("mv wave*.tif tif_schrod/");
}
}
}
// if (MOVIE)
// {
// for (i=0; i<20; i++) save_frame();
// s = system("mv wave*.tif tif_schrod/");
// }
if (MOVIE)
{
for (i=0; i<END_FRAMES; i++) save_frame();
s = system("mv wave*.tif tif_schrod/");
}
for (i=0; i<NX; i++)
{
free(phi[i]);

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,14 @@
/* global variables needed for circle configuration with periodic boundary conditions */
short int double_circle[NMAXCIRCLES]; /* set to 1 if a circle is a translate of another one on the boundary */
int partner_circle[NMAXCIRCLES]; /* number of circle of which current circle is a copy */
// short int double_circle[NMAXCIRCLES]; /* set to 1 if a circle is a translate of another one on the boundary */
// int partner_circle[NMAXCIRCLES]; /* number of circle of which current circle is a copy */
void init_circle_config_pinball(int circle_pattern)
void init_circles_pinball(int circle_pattern, t_circle circles[NMAXCIRCLES])
{
int i, j, k, n, ncirc0, n_p_active, ncandidates=5000, naccepted;
double dx, dy, xx[4], yy[4], x, y, gamma, height, phi, r0, r, dpoisson = 3.25*MU;
double dx, dy, xx[4], yy[4], x, y, xk, yk, hy, gamma, height, phi, r0, r, dpoisson = 3.25*MU;
short int active_poisson[NMAXCIRCLES], far;
switch (circle_pattern) {
@ -14,27 +16,27 @@ void init_circle_config_pinball(int circle_pattern)
{
ncircles = 4;
circlex[0] = 1.0;
circley[0] = 0.0;
circlerad[0] = 0.8;
circles[0].xc = 1.0;
circles[0].yc = 0.0;
circles[0].radius = 0.8;
circles[1].xc = -1.0;
circles[1].yc = 0.0;
circles[1].radius = 0.8;
circlex[1] = -1.0;
circley[1] = 0.0;
circlerad[1] = 0.8;
circlex[2] = 0.0;
circley[2] = 0.8;
circlerad[2] = 0.4;
circlex[3] = 0.0;
circley[3] = -0.8;
circlerad[3] = 0.4;
circles[2].xc = 0.0;
circles[2].yc = 0.8;
circles[2].radius = 0.4;
circles[3].xc = 0.0;
circles[3].yc = -0.8;
circles[3].radius = 0.4;
for (i=0; i<4; i++)
{
circleactive[i] = 1;
circlecolor[i] = 0;
newcircle[i] = 0;
circles[i].active = 1;
circles[i].color = 0;
circles[i].new = 0;
}
break;
@ -48,12 +50,12 @@ void init_circle_config_pinball(int circle_pattern)
for (j = 0; j < NCY; j++)
{
n = NCY*i + j;
circlex[n] = ((double)(i-NCX/2) + 0.5)*dy;
circley[n] = BOXYMIN + ((double)j + 0.5)*dy;
circlerad[n] = MU;
circleactive[n] = 1;
circlecolor[n] = 0;
newcircle[n] = 0;
circles[n].xc = ((double)(i-NCX/2) + 0.5)*dy;
circles[n].yc = BOXYMIN + ((double)j + 0.5)*dy;
circles[n].radius = MU;
circles[n].active = 1;
circles[n].color = 0;
circles[n].new = 0;
}
break;
}
@ -66,15 +68,15 @@ void init_circle_config_pinball(int circle_pattern)
for (j = 0; j < NCY+1; j++)
{
n = (NCY+1)*i + j;
// circlex[n] = ((double)(i-NCX/2) + 0.5)*dy;
circlex[n] = ((double)(i-NCX/2))*dy;
if (NCX % 2 == 0) circlex[n] += 0.5*dy;
circley[n] = YMIN + ((double)j - 0.5)*dy;
if ((i+NCX)%2 == 1) circley[n] += 0.5*dy;
circlerad[n] = MU;
circleactive[n] = 1;
circlecolor[n] = 0;
newcircle[n] = 0;
// circles[n].xc = ((double)(i-NCX/2) + 0.5)*dy;
circles[n].xc = ((double)(i-NCX/2))*dy;
if (NCX % 2 == 0) circles[n].xc += 0.5*dy;
circles[n].yc = YMIN + ((double)j - 0.5)*dy;
if ((i+NCX)%2 == 1) circles[n].yc += 0.5*dy;
circles[n].radius = MU;
circles[n].active = 1;
circles[n].color = 0;
circles[n].new = 0;
}
break;
}
@ -87,30 +89,30 @@ void init_circle_config_pinball(int circle_pattern)
for (j = 0; j < NCY+1; j++)
{
n = (NCY+1)*i + j;
circlex[n] = ((double)(i-NCX/2) + 0.5)*dx;
circley[n] = BOXYMIN + ((double)j)*dy;
if ((i+NCX)%2 == 1) circley[n] += 0.5*dy;
circlerad[n] = MU;
circleactive[n] = 1;
circlecolor[n] = 0;
newcircle[n] = 0;
circles[n].xc = ((double)(i-NCX/2) + 0.5)*dx;
circles[n].yc = BOXYMIN + ((double)j)*dy;
if ((i+NCX)%2 == 1) circles[n].yc += 0.5*dy;
circles[n].radius = MU;
circles[n].active = 1;
circles[n].color = 0;
circles[n].new = 0;
/* take care of periodic boundary conditions */
if (B_DOMAIN == D_CIRCLES_IN_TORUS)
{
if ((j == NCY)&&((i+NCX)%2 == 0))
{
double_circle[n] = 1;
partner_circle[n] = (NCY+1)*i;
circles[n].double_circle = 1;
circles[n].partner = (NCY+1)*i;
}
else
{
double_circle[n] = 0;
if ((j == 0)&&((i+NCX)%2 == 0)) partner_circle[n] = (NCY+1)*i + NCY;
else partner_circle[n] = n;
circles[n].double_circle = 0;
if ((j == 0)&&((i+NCX)%2 == 0)) circles[n].partner = (NCY+1)*i + NCY;
else circles[n].partner = n;
}
}
else double_circle[n] = 0;
else circles[n].double_circle = 0;
}
break;
}
@ -122,22 +124,22 @@ void init_circle_config_pinball(int circle_pattern)
dx = 2.0*LAMBDA/((double)ncircles);
for (n = 0; n < ncircles; n++)
{
circlex[n] = -LAMBDA + n*dx;
circley[n] = y;
circles[n].xc = -LAMBDA + n*dx;
circles[n].yc = y;
y += height*gamma;
if (y > YMAX) y -= height;
circlerad[n] = MU;
circleactive[n] = 1;
circlecolor[n] = 0;
newcircle[n] = 0;
circles[n].radius = MU;
circles[n].active = 1;
circles[n].color = 0;
circles[n].new = 0;
}
break;
}
case (C_GOLDEN_SPIRAL):
{
ncircles = 1;
circlex[0] = 0.0;
circley[0] = 0.0;
circles[0].xc = 0.0;
circles[0].yc = 0.0;
gamma = (sqrt(5.0) - 1.0)*PI; /* golden mean times 2Pi */
phi = 0.0;
@ -154,19 +156,19 @@ void init_circle_config_pinball(int circle_pattern)
if ((vabs(x) < LAMBDA)&&(vabs(y) < YMAX + MU))
{
circlex[ncircles] = x;
circley[ncircles] = y;
circles[ncircles].xc = x;
circles[ncircles].yc = y;
ncircles++;
}
}
for (i=0; i<ncircles; i++)
{
circlerad[i] = MU;
circlecolor[i] = 0;
newcircle[i] = 0;
circles[i].radius = MU;
circles[i].color = 0;
circles[i].new = 0;
/* inactivate circles outside the domain */
if ((circley[i] < YMAX + MU)&&(circley[i] > YMIN - MU)) circleactive[i] = 1;
if ((circles[i].yc < YMAX + MU)&&(circles[i].yc > YMIN - MU)) circles[i].active = 1;
}
break;
}
@ -178,12 +180,12 @@ void init_circle_config_pinball(int circle_pattern)
for (j = 0; j < NCY; j++)
{
n = NCY*i + j;
circlex[n] = ((double)(i-NCX/2) + 0.5*((double)rand()/RAND_MAX - 0.5))*dy;
circley[n] = YMIN + ((double)j + 0.5 + 0.5*((double)rand()/RAND_MAX - 0.5))*dy;
circlerad[n] = MU*sqrt(1.0 + 0.8*((double)rand()/RAND_MAX - 0.5));
circleactive[n] = 1;
circlecolor[n] = 0;
newcircle[n] = 0;
circles[n].xc = ((double)(i-NCX/2) + 0.5*((double)rand()/RAND_MAX - 0.5))*dy;
circles[n].yc = YMIN + ((double)j + 0.5 + 0.5*((double)rand()/RAND_MAX - 0.5))*dy;
circles[n].radius = MU*sqrt(1.0 + 0.8*((double)rand()/RAND_MAX - 0.5));
circles[n].active = 1;
circles[n].color = 0;
circles[n].new = 0;
}
break;
}
@ -192,52 +194,52 @@ void init_circle_config_pinball(int circle_pattern)
ncircles = NPOISSON;
for (n = 0; n < NPOISSON; n++)
{
circlex[n] = LAMBDA*(2.0*(double)rand()/RAND_MAX - 1.0);
circley[n] = (BOXYMAX - BOXYMIN)*(double)rand()/RAND_MAX + BOXYMIN;
circlerad[n] = MU;
circleactive[n] = 1;
circlecolor[n] = 0;
newcircle[n] = 0;
double_circle[n] = 0;
partner_circle[n] = n;
circles[n].xc = LAMBDA*(2.0*(double)rand()/RAND_MAX - 1.0);
circles[n].yc = (BOXYMAX - BOXYMIN)*(double)rand()/RAND_MAX + BOXYMIN;
circles[n].radius = MU;
circles[n].active = 1;
circles[n].color = 0;
circles[n].new = 0;
circles[n].double_circle = 0;
circles[n].partner = n;
/* take care of periodic boundary conditions */
if (B_DOMAIN == D_CIRCLES_IN_TORUS)
{
/* inactivate circles in corners */
if ((vabs(circlex[n]) > LAMBDA - MU)&&((circley[n] < BOXYMIN + MU)||(circley[n] > BOXYMAX - MU)))
circleactive[n] = 0;
if ((vabs(circles[n].xc) > LAMBDA - MU)&&((circles[n].yc < BOXYMIN + MU)||(circles[n].yc > BOXYMAX - MU)))
circles[n].active = 0;
if (circlex[n] < - LAMBDA + MU)
if (circles[n].xc < - LAMBDA + MU)
{
circlex[ncircles] = circlex[n] + 2.0*LAMBDA;
circley[ncircles] = circley[n];
partner_circle[ncircles] = n;
partner_circle[n] = ncircles;
circles[ncircles].xc = circles[n].xc + 2.0*LAMBDA;
circles[ncircles].yc = circles[n].yc;
circles[ncircles].partner = n;
circles[n].partner = ncircles;
ncircles++;
}
else if (circlex[n] > LAMBDA - MU)
else if (circles[n].xc > LAMBDA - MU)
{
circlex[ncircles] = circlex[n] - 2.0*LAMBDA;
circley[ncircles] = circley[n];
partner_circle[ncircles] = n;
partner_circle[n] = ncircles;
circles[ncircles].xc = circles[n].xc - 2.0*LAMBDA;
circles[ncircles].yc = circles[n].yc;
circles[ncircles].partner = n;
circles[n].partner = ncircles;
ncircles++;
}
if (circley[n] < BOXYMIN + MU)
if (circles[n].yc < BOXYMIN + MU)
{
circlex[ncircles] = circlex[n];
circley[ncircles] = circley[n] + BOXYMAX - BOXYMIN;
partner_circle[ncircles] = n;
partner_circle[n] = ncircles;
circles[ncircles].xc = circles[n].xc;
circles[ncircles].yc = circles[n].yc + BOXYMAX - BOXYMIN;
circles[ncircles].partner = n;
circles[n].partner = ncircles;
ncircles++;
}
else if (circley[n] > BOXYMAX - MU)
else if (circles[n].yc > BOXYMAX - MU)
{
circlex[ncircles] = circlex[n];
circley[ncircles] = circley[n] - BOXYMAX + BOXYMIN;
partner_circle[ncircles] = n;
partner_circle[n] = ncircles;
circles[ncircles].xc = circles[n].xc;
circles[ncircles].yc = circles[n].yc - BOXYMAX + BOXYMIN;
circles[ncircles].partner = n;
circles[n].partner = ncircles;
ncircles++;
}
}
@ -245,12 +247,12 @@ void init_circle_config_pinball(int circle_pattern)
printf("%i circles\n", ncircles);
if (B_DOMAIN == D_CIRCLES_IN_TORUS) for (n = NPOISSON; n < ncircles; n++)
{
// printf("circle %i at (%.3f, %.3f)\n", n, circlex[n], circley[n]);
circlerad[n] = MU;
if (circleactive[partner_circle[n]]) circleactive[n] = 1;
circlecolor[n] = 0;
newcircle[n] = 0;
double_circle[n] = 1;
// printf("circle %i at (%.3f, %.3f)\n", n, circles[n].xc, circles[n].yc);
circles[n].radius = MU;
if (circles[circles[n].partner].active) circles[n].active = 1;
circles[n].color = 0;
circles[n].new = 0;
circles[n].double_circle = 1;
}
break;
@ -259,9 +261,11 @@ void init_circle_config_pinball(int circle_pattern)
{
printf("Generating Poisson disc sample\n");
/* generate first circle */
circlex[0] = LAMBDA*(2.0*(double)rand()/RAND_MAX - 1.0);
circley[0] = (YMAX - YMIN)*(double)rand()/RAND_MAX + YMIN;
circles[0].xc = LAMBDA*(2.0*(double)rand()/RAND_MAX - 1.0);
circles[0].yc = (BOXYMAX - BOXYMIN)*(double)rand()/RAND_MAX + BOXYMIN;
active_poisson[0] = 1;
circles[0].double_circle = 0;
circles[0].partner = 0;
n_p_active = 1;
ncircles = 1;
@ -277,30 +281,119 @@ void init_circle_config_pinball(int circle_pattern)
{
r = dpoisson*(2.0*(double)rand()/RAND_MAX + 1.0);
phi = DPI*(double)rand()/RAND_MAX;
x = circlex[i] + r*cos(phi);
y = circley[i] + r*sin(phi);
x = circles[i].xc + r*cos(phi);
y = circles[i].yc + r*sin(phi);
// printf("Testing new circle at (%.3f,%.3f)\t", x, y);
far = 1;
for (k=0; k<ncircles; k++) if ((k!=i))
{
xk = circles[k].xc;
yk = circles[k].yc;
hy = BOXYMAX - BOXYMIN;
/* new circle is far away from circle k */
far = far*((x - circlex[k])*(x - circlex[k]) + (y - circley[k])*(y - circley[k]) >= dpoisson*dpoisson);
/* new circle is in domain */
far = far*(vabs(x) < LAMBDA)*(y < YMAX)*(y > YMIN);
}
far = far*((x - xk)*(x - xk) + (y - yk)*(y - yk) >= dpoisson*dpoisson);
far = far*((x - xk)*(x - xk) + (y - yk + hy)*(y - yk + hy) >= dpoisson*dpoisson);
far = far*((x - xk)*(x - xk) + (y - yk - hy)*(y - yk - hy) >= dpoisson*dpoisson);
far = far*((x - xk + 2.0*LAMBDA)*(x - xk + 2.0*LAMBDA) + (y - yk)*(y - yk) >= dpoisson*dpoisson);
far = far*((x - xk - 2.0*LAMBDA)*(x - xk - 2.0*LAMBDA) + (y - yk)*(y - yk) >= dpoisson*dpoisson);
}
/* new circle is in domain */
far = far*(vabs(x) < LAMBDA + 0.0)*(y < BOXYMAX + 0.0)*(y > BOXYMIN - 0.0);
/* exclude circles in corners */
if ((x > LAMBDA - MU)&&((y < BOXYMIN + MU)||(y > BOXYMAX - MU)))
far = 0;
if (far) /* accept new circle */
{
printf("New circle at (%.3f,%.3f) accepted\n", x, y);
circlex[ncircles] = x;
circley[ncircles] = y;
circlerad[ncircles] = MU;
circleactive[ncircles] = 1;
circlecolor[ncircles] = 0;
newcircle[ncircles] = 0;
circles[ncircles].xc = x;
circles[ncircles].yc = y;
circles[ncircles].radius = MU;
circles[ncircles].active = 1;
circles[ncircles].color = 0;
circles[ncircles].new = 0;
active_poisson[ncircles] = 1;
circles[ncircles].double_circle = 0;
circles[ncircles].partner = ncircles;
ncircles++;
n_p_active++;
naccepted++;
/* take care of periodic boundary conditions */
if (B_DOMAIN == D_CIRCLES_IN_TORUS)
{
n = ncircles - 1;
if (x < - LAMBDA + MU)
{
circles[ncircles].xc = x + 2.0*LAMBDA;
circles[ncircles].yc = y;
circles[ncircles].radius = MU;
circles[ncircles].active = 1;
circles[ncircles].color = 0;
circles[ncircles].new = 0;
active_poisson[ncircles] = 1;
circles[n].double_circle = 1;
circles[ncircles].double_circle = 0;
circles[n].partner = ncircles;
circles[ncircles].partner = n;
ncircles++;
n_p_active++;
naccepted++;
}
else if (x > LAMBDA - MU)
{
circles[ncircles].xc = x - 2.0*LAMBDA;
circles[ncircles].yc = y;
circles[ncircles].radius = MU;
circles[ncircles].active = 1;
circles[ncircles].color = 0;
circles[ncircles].new = 0;
active_poisson[ncircles] = 1;
circles[n].double_circle = 1;
circles[ncircles].double_circle = 0;
circles[n].partner = ncircles;
circles[ncircles].partner = n;
ncircles++;
n_p_active++;
naccepted++;
}
if (y < BOXYMIN + MU)
{
circles[ncircles].xc = x;
circles[ncircles].yc = y + BOXYMAX - BOXYMIN;
circles[ncircles].radius = MU;
circles[ncircles].active = 1;
circles[ncircles].color = 0;
circles[ncircles].new = 0;
active_poisson[ncircles] = 1;
circles[n].double_circle = 1;
circles[ncircles].double_circle = 0;
circles[n].partner = ncircles;
circles[ncircles].partner = n;
ncircles++;
n_p_active++;
naccepted++;
}
else if (y > BOXYMAX - MU)
{
circles[ncircles].xc = x;
circles[ncircles].yc = y - BOXYMAX + BOXYMIN;
circles[ncircles].radius = MU;
circles[ncircles].active = 1;
circles[ncircles].color = 0;
circles[ncircles].new = 0;
active_poisson[ncircles] = 1;
circles[n].double_circle = 1;
circles[ncircles].double_circle = 0;
circles[n].partner = ncircles;
circles[ncircles].partner = n;
ncircles++;
n_p_active++;
naccepted++;
}
}
}
// else printf("Rejected\n");
}
@ -314,6 +407,9 @@ void init_circle_config_pinball(int circle_pattern)
}
printf("Generated %i circles\n", ncircles);
// for (i=0; i<ncircles; i++)
// printf("Circle %i at (%.3f, %.3f), partner %i\n", i, circlex[i], circley[i], partner_circle[i]);
break;
}
// case (C_LASER):

1056
sub_wave.c

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
short int circletop[NMAXCIRCLES]; /* set to 1 if circle is in top half */
void init_circle_config_half(int pattern, int top)
void init_circle_config_half(int pattern, int top, t_circle circles[NMAXCIRCLES])
/* initialise the arrays circlex, circley, circlerad and circleactive */
/* for billiard shape D_CIRCLES */
{
@ -21,12 +21,12 @@ void init_circle_config_half(int pattern, int top)
{
printf("i = %i, j = %i, n = %i\n", i, j, n);
n = ncircles + NGRIDY*i/2 + j;
circlex[n] = ((double)(i-NGRIDX/2) + 0.5)*dy;
circles[n].xc = ((double)(i-NGRIDX/2) + 0.5)*dy;
y = ((double)j + 0.5)*dy;
if (top) circley[n] = ymean + y;
else circley[n] = ymean - y;
circlerad[n] = MU;
circleactive[n] = 1;
if (top) circles[n].yc = ymean + y;
else circles[n].yc = ymean - y;
circles[n].radius = MU;
circles[n].active = 1;
circletop[n] = top;
}
ncircles += NGRIDX*NGRIDY/2;
@ -40,13 +40,13 @@ void init_circle_config_half(int pattern, int top)
for (j = 0; j < NGRIDY/2+1; j++)
{
n = ncircles + (NGRIDY+1)*i/2 + j;
circlex[n] = ((double)(i-NGRIDX/2))*dy;
circles[n].xc = ((double)(i-NGRIDX/2))*dy;
y = ((double)j - 0.5)*dy;
if ((i+NGRIDX)%2 == 1) y += 0.5*dy;
if (top) circley[n] = ymean + 0.5*dy + y;
else circley[n] = ymean - 0.5*dy - y;
circlerad[n] = MU;
circleactive[n] = 1;
if (top) circles[n].yc = ymean + 0.5*dy + y;
else circles[n].yc = ymean - 0.5*dy - y;
circles[n].radius = MU;
circles[n].active = 1;
circletop[n] = top;
}
ncircles += NGRIDX*(NGRIDY+1)/2;
@ -59,15 +59,15 @@ void init_circle_config_half(int pattern, int top)
for (j = 0; j < NGRIDY/2; j++)
{
n = ncircles + NGRIDY*i/2 + j;
circlex[n] = ((double)(i-NGRIDX/2) + 0.5*((double)rand()/RAND_MAX - 0.5))*dy;
if (NGRIDX%2 == 0) circlex[n] += 0.5*dy;
circles[n].xc = ((double)(i-NGRIDX/2) + 0.5*((double)rand()/RAND_MAX - 0.5))*dy;
if (NGRIDX%2 == 0) circles[n].xc += 0.5*dy;
y = ((double)j + 0.5 + 0.5*((double)rand()/RAND_MAX - 0.5))*dy;
if (top) circley[n] = ymean + y;
else circley[n] = ymean - y;
circlerad[n] = MU*sqrt(1.0 + 0.8*((double)rand()/RAND_MAX - 0.5));
circleactive[n] = 1;
if (top) circles[n].yc = ymean + y;
else circles[n].yc = ymean - y;
circles[n].radius = MU*sqrt(1.0 + 0.8*((double)rand()/RAND_MAX - 0.5));
circles[n].active = 1;
circletop[n] = top;
printf("n = %i, x = %.3lg\n", n, circlex[n]);
printf("n = %i, x = %.3lg\n", n, circles[n].xc);
}
ncircles += NGRIDX*NGRIDY/2;
break;
@ -79,14 +79,14 @@ void init_circle_config_half(int pattern, int top)
for (j = 0; j < NGRIDY/2; j++)
{
n = ncircles + NGRIDY*i/2 + j;
circlex[n] = ((double)(i-NGRIDX/2) + 0.5)*dy;
circles[n].xc = ((double)(i-NGRIDX/2) + 0.5)*dy;
y = YMIN + ((double)j + 0.5)*dy;
if ( ((top)&&(y > 0.0))||((!top)&&(y <= 0.0)) )
circley[n] = y;
circlerad[n] = MU;
circles[n].yc = y;
circles[n].radius = MU;
p = (double)rand()/RAND_MAX;
if (p < P_PERCOL) circleactive[n] = 1;
else circleactive[n] = 0;
if (p < P_PERCOL) circles[n].active = 1;
else circles[n].active = 0;
circletop[n] = top;
}
ncircles += NGRIDX*NGRIDY/2;
@ -97,15 +97,15 @@ void init_circle_config_half(int pattern, int top)
for (i = 0; i < NPOISSON/2; i++)
{
n = ncircles + i;
circlex[n] = LAMBDA*(2.0*(double)rand()/RAND_MAX - 1.0);
circles[n].xc = LAMBDA*(2.0*(double)rand()/RAND_MAX - 1.0);
if (top) y = ymean + (YMAX-ymean)*(double)rand()/RAND_MAX;
else y = ymean + (YMIN-ymean)*(double)rand()/RAND_MAX;
if ( ((top)&&(y > 0.0))||((!top)&&(y <= 0.0)) )
circley[n] = y;
circlerad[n] = MU;
circleactive[n] = 1;
circles[n].yc = y;
circles[n].radius = MU;
circles[n].active = 1;
circletop[n] = top;
printf("n = %i, x = %.3lg\n", n, circlex[n]);
printf("n = %i, x = %.3lg\n", n, circles[n].xc);
}
ncircles += NPOISSON/2;
break;
@ -118,12 +118,12 @@ void init_circle_config_half(int pattern, int top)
n = ncircles + 5*i + j;
phi = (double)i*DPI/40.0;
r = LAMBDA*0.5*(1.0 + (double)j/5.0);
circlex[n] = r*cos(phi);
circles[n].xc = r*cos(phi);
y = r*sin(phi);
if ( ((top)&&(y > 0.0))||((!top)&&(y <= 0.0)) )
circley[n] = y;
circlerad[n] = MU;
circleactive[n] = 1;
circles[n].yc = y;
circles[n].radius = MU;
circles[n].active = 1;
circletop[n] = top;
}
ncircles += 200;
@ -142,25 +142,25 @@ void init_circle_config_half(int pattern, int top)
n = ncircles + 5*i + j;
phi = (double)i*DPI/40.0;
r = LAMBDA*sa[j];
circlex[n] = r*cos(phi);
circley[n] = r*sin(phi);
circles[n].xc = r*cos(phi);
circles[n].yc = r*sin(phi);
if (top) y = r*sin(phi);
else y = -r*sin(phi);
circley[n] = y;
circles[n].yc = y;
circlerad[n] = LAMBDA*ra[j];
circleactive[n] = 1;
circles[n].radius = LAMBDA*ra[j];
circles[n].active = 1;
circletop[n] = top;
}
ncircles += 105;
/* add circle in the center */
circlex[ncircles] = 0.0;
circley[ncircles] = 0.0;
circlerad[ncircles] = MU;
circleactive[ncircles] = 2;
circles[ncircles].xc = 0.0;
circles[ncircles].yc = 0.0;
circles[ncircles].radius = MU;
circles[ncircles].active = 2;
circletop[ncircles] = top;
ncircles += 1;
break;
@ -170,12 +170,12 @@ void init_circle_config_half(int pattern, int top)
printf("Generating Poisson disc sample\n");
/* generate first circle */
n = ncircles;
circlex[n] = LAMBDA*(2.0*(double)rand()/RAND_MAX - 1.0);
circles[n].xc = LAMBDA*(2.0*(double)rand()/RAND_MAX - 1.0);
if (top) y = ymean + (YMAX-ymean)*(double)rand()/RAND_MAX;
else y = ymean + (YMIN-ymean)*(double)rand()/RAND_MAX;
circley[n] = y;
circlerad[n] = MU;
circleactive[n] = 1;
circles[n].yc = y;
circles[n].radius = MU;
circles[n].active = 1;
circletop[n] = top;
active_poisson[n] = 1;
n_p_active = 1;
@ -187,21 +187,21 @@ void init_circle_config_half(int pattern, int top)
i = rand()%(ncirc0);
n = ncircles + i;
while (!active_poisson[ncircles + i]) i = rand()%(ncirc0);
// printf("Starting from circle %i at (%.3f,%.3f)\n", i, circlex[i], circley[i]);
// printf("Starting from circle %i at (%.3f,%.3f)\n", i, circles[i].xc, circles[i].yc);
/* generate new candidates */
naccepted = 0;
for (j=0; j<ncandidates; j++)
{
r = dpoisson*(2.0*(double)rand()/RAND_MAX + 1.0);
phi = DPI*(double)rand()/RAND_MAX;
x = circlex[n] + r*cos(phi);
y = circley[n] + r*sin(phi);
x = circles[n].xc + r*cos(phi);
y = circles[n].yc + r*sin(phi);
// printf("Testing new circle at (%.3f,%.3f)\t", x, y);
far = 1;
for (k=ncircles; k<ncircles + ncirc0; k++) if ((k!=n))
{
/* new circle is far away from circle k */
far = far*((x - circlex[k])*(x - circlex[k]) + (y - circley[k])*(y - circley[k]) >= dpoisson*dpoisson);
far = far*((x - circles[k].xc)*(x - circles[k].xc) + (y - circles[k].yc)*(y - circles[k].yc) >= dpoisson*dpoisson);
/* new circle is in domain */
if (top) far = far*(vabs(x) < LAMBDA)*(y < YMAX)*(y > 0.0);
else far = far*(vabs(x) < LAMBDA)*(y > YMIN)*(y < 0.0);
@ -210,12 +210,12 @@ void init_circle_config_half(int pattern, int top)
{
printf("New circle at (%.3f,%.3f) accepted\n", x, y);
nnew = ncircles + ncirc0;
circlex[nnew] = x;
circley[nnew] = y;
circlerad[nnew] = MU;
circleactive[nnew] = 1;
circles[nnew].xc = x;
circles[nnew].yc = y;
circles[nnew].radius = MU;
circles[nnew].active = 1;
active_poisson[nnew] = 1;
circleactive[nnew] = 1;
// circleactive[nnew] = 1;
circletop[nnew] = top;
ncirc0++;
n_p_active++;
@ -248,8 +248,8 @@ void init_circle_config_half(int pattern, int top)
else y = ymean - 0.5*height;
for (n = 0; n < 150; n++)
{
circlex[ncircles + n] = -LAMBDA + n*dx;
circley[ncircles + n] = y;
circles[ncircles + n].xc = -LAMBDA + n*dx;
circles[ncircles + n].yc = y;
if (top)
{
@ -263,8 +263,8 @@ void init_circle_config_half(int pattern, int top)
}
circlerad[ncircles + n] = MU;
circleactive[ncircles + n] = 1;
circles[ncircles + n].radius = MU;
circles[ncircles + n].active = 1;
circletop[ncircles] = top;
}
@ -279,20 +279,20 @@ void init_circle_config_half(int pattern, int top)
for (n=0; n < 150; n++)
{
if (circley[ncirc0 + n] + circlerad[ncirc0 + n] > ytop)
if (circles[ncirc0+n].yc + circles[ncirc0 + n].radius > ytop)
{
circlex[ncircles] = circlex[ncirc0 + n];
circley[ncircles] = circley[ncirc0 + n] - height;
circlerad[ncircles] = MU;
circleactive[ncircles] = 1;
circles[ncircles].xc = circles[ncirc0 + n].xc;
circles[ncircles].yc = circles[ncirc0+n].yc - height;
circles[ncircles].radius = MU;
circles[ncircles].active = 1;
ncircles ++;
}
else if (circley[ncirc0 + n] - circlerad[ncirc0 + n] < ybottom)
else if (circles[ncirc0+n].yc - circles[ncirc0 + n].radius < ybottom)
{
circlex[ncircles] = circlex[ncirc0 + n];
circley[ncircles] = circley[ncirc0 + n] + height;
circlerad[ncircles] = MU;
circleactive[ncircles] = 1;
circles[ncircles].xc = circles[ncirc0 + n].xc;
circles[ncircles].yc = circles[ncirc0+n].yc + height;
circles[ncircles].radius = MU;
circles[ncircles].active = 1;
ncircles ++;
}
}
@ -301,10 +301,10 @@ void init_circle_config_half(int pattern, int top)
}
case (C_GOLDEN_SPIRAL):
{
circlex[ncircles] = 0.0;
circley[ncircles] = 0.0;
circlerad[ncircles] = MU;
circleactive[ncircles] = 1;
circles[ncircles].xc = 0.0;
circles[ncircles].yc = 0.0;
circles[ncircles].radius = MU;
circles[ncircles].active = 1;
circletop[ncircles] = top;
gamma = (sqrt(5.0) - 1.0)*PI; /* golden mean times 2Pi */
@ -322,13 +322,13 @@ void init_circle_config_half(int pattern, int top)
if ((vabs(x) < LAMBDA)&&(vabs(y) < YMAX + MU))
{
circlex[ncircles] = x;
circley[ncircles] = y;
circlerad[ncircles] = MU;
if (((top)&&(circley[ncircles] < YMAX + MU)&&(circley[ncircles] > ymean - MU))
||((!top)&&(circley[ncircles] < ymean + MU)&&(circley[ncircles] > YMIN - MU)))
circles[ncircles].xc = x;
circles[ncircles].yc = y;
circles[ncircles].radius = MU;
if (((top)&&(circles[ncircles].yc < YMAX + MU)&&(circles[ncircles].yc > ymean - MU))
||((!top)&&(circles[ncircles].yc < ymean + MU)&&(circles[ncircles].yc > YMIN - MU)))
{
circleactive[ncircles] = 1;
circles[ncircles].active = 1;
circletop[ncircles] = top;
ncircles++;
}
@ -338,30 +338,30 @@ void init_circle_config_half(int pattern, int top)
}
case (C_ONE):
{
circlex[ncircles] = 0.0;
circley[ncircles] = 0.0;
if (top) circlerad[ncircles] = MU;
else circlerad[ncircles] = MUB;
circleactive[ncircles] = 1;
circles[ncircles].xc = 0.0;
circles[ncircles].yc = 0.0;
if (top) circles[ncircles].radius = MU;
else circles[ncircles].radius = MUB;
circles[ncircles].active = 1;
circletop[ncircles] = top;
ncircles += 1;
break;
}
case (C_TWO):
{
circlex[ncircles] = 0.0;
circley[ncircles] = 0.0;
if (top) circlerad[ncircles] = MU;
else circlerad[ncircles] = MUB;
circleactive[ncircles] = 2;
circles[ncircles].xc = 0.0;
circles[ncircles].yc = 0.0;
if (top) circles[ncircles].radius = MU;
else circles[ncircles].radius = MUB;
circles[ncircles].active = 2;
circletop[ncircles] = top;
ncircles += 1;
circlex[ncircles] = 0.0;
circley[ncircles] = 0.0;
if (top) circlerad[ncircles] = 2.0*MU;
else circlerad[ncircles] = 2.0*MUB;
circleactive[ncircles] = 1;
circles[ncircles].xc = 0.0;
circles[ncircles].yc = 0.0;
if (top) circles[ncircles].radius = 2.0*MU;
else circles[ncircles].radius = 2.0*MUB;
circles[ncircles].active = 1;
circletop[ncircles] = top;
ncircles += 1;
break;
@ -379,21 +379,21 @@ void init_circle_config_half(int pattern, int top)
}
void init_circle_config_comp()
void init_circle_config_comp(t_circle circles[NMAXCIRCLES])
/* initialise the arrays circlex, circley, circlerad and circleactive */
/* for billiard shape D_CIRCLES */
{
ncircles = 0;
init_circle_config_half(CIRCLE_PATTERN, 1);
init_circle_config_half(CIRCLE_PATTERN_B, 0);
init_circle_config_half(CIRCLE_PATTERN, 1, circles);
init_circle_config_half(CIRCLE_PATTERN_B, 0, circles);
}
void init_circle_config_energy()
void init_circle_config_energy(t_circle circles[NMAXCIRCLES])
/* initialise the arrays circlex, circley, circlerad and circleactive */
/* for billiard shape D_CIRCLES */
{
ncircles = 0;
init_circle_config_half(CIRCLE_PATTERN, 0);
init_circle_config_half(CIRCLE_PATTERN, 0, circles);
}
int xy_in_billiard_half(double x, double y, int domain, int pattern, int top)
@ -419,15 +419,15 @@ int xy_in_billiard_half(double x, double y, int domain, int pattern, int top)
case D_CIRCLES:
{
for (i = 0; i < ncircles; i++)
if (circleactive[i] != 0)
if (circles[i].active != 0)
{
/* choose specific type according to value of circleactive[i] */
if (circleactive[i] == 1) type = 0;
else type = circleactive[i];
/* choose specific type according to value of circles[i].active */
if (circles[i].active == 1) type = 0;
else type = circles[i].active;
x1 = circlex[i];
y1 = circley[i];
r2 = circlerad[i]*circlerad[i];
x1 = circles[i].xc;
y1 = circles[i].yc;
r2 = circles[i].radius*circles[i].radius;
if ((top)&&(circletop[i])&&(y > 0.0)&&((x-x1)*(x-x1) + (y-y1)*(y-y1) < r2)) return(type);
else if ((!top)&&(!circletop[i])&&(y < 0.0)&&((x-x1)*(x-x1) + (y-y1)*(y-y1) < r2)) return(type);
}
@ -535,14 +535,14 @@ void draw_billiard_half(int domain, int pattern, int top) /* draws the bill
{
glLineWidth(2);
for (i = 0; i < ncircles; i++)
if ((circleactive[i])&&(circletop[i] == top))
if ((circles[i].active)&&(circletop[i] == top))
{
glBegin(GL_LINE_STRIP);
for (k=0; k<=NSEG; k++)
{
phi = (double)k*DPI/(double)NSEG;
x = circlex[i] + circlerad[i]*cos(phi);
y = circley[i] + circlerad[i]*sin(phi);
x = circles[i].xc + circles[i].radius*cos(phi);
y = circles[i].yc + circles[i].radius*sin(phi);
if ((top)&&(circletop[i])&&(y < 0.0)) y = 0.0;
if ((!top)&&(!circletop[i])&&(y > 0.0)) y = 0.0;
xy_to_pos(x, y, pos);
@ -681,9 +681,9 @@ void compute_energy_tblr(double *phi[NX], double *psi[NX], short int *xy_in[NX],
{
/* find leftmost and rightmost circle */
for (i=0; i<ncircles; i++)
if ((circleactive[i])&&(circlex[i] - circlerad[i] < xleft)) xleft = circlex[i] - circlerad[i];
if ((circles[i].active)&&(circles[i].xc - circles[i].radius < xleft)) xleft = circles[i].xc - circles[i].radius;
for (i=0; i<ncircles; i++)
if ((circleactive[i])&&(circlex[i] + circlerad[i] > xright)) xright = circlex[i] + circlerad[i];
if ((circles[i].active)&&(circles[i].xc + circles[i].radius > xright)) xright = circles[i].xc + circles[i].radius;
xy_to_ij(xleft, 0.0, ij);
ileft = ij[0];

View File

@ -62,35 +62,38 @@
/* Choice of the billiard table */
#define B_DOMAIN 32 /* choice of domain shape, see list in global_pdes.c */
#define B_DOMAIN 38 /* choice of domain shape, see list in global_pdes.c */
#define CIRCLE_PATTERN 7 /* pattern of circles, see list in global_pdes.c */
#define CIRCLE_PATTERN 2 /* 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.0 /* parameter controlling the dimensions of domain */
#define MU 1.0 /* parameter controlling the dimensions of domain */
#define NPOLY 7 /* number of sides of polygon */
#define APOLY 1.0 /* angle by which to turn polygon, in units of Pi/2 */
#define MDEPTH 4 /* depth of computation of Menger gasket */
#define LAMBDA 0.9 /* parameter controlling the dimensions of domain */
#define MU 0.03 /* parameter controlling the dimensions of domain */
#define NPOLY 6 /* number of sides of polygon */
#define APOLY 2.0 /* angle by which to turn polygon, in units of Pi/2 */
#define MDEPTH 5 /* 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 16 /* number of grid point for grid of disks */
#define NGRIDY 20 /* number of grid point for grid of disks */
#define NGRIDX 10 /* number of grid point for grid of disks */
#define NGRIDY 12 /* number of grid point for grid of disks */
// #define NGRIDX 16 /* number of grid point for grid of disks */
// #define NGRIDY 20 /* 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 -1.65
#define ISO_XSHIFT_RIGHT 0.4
#define ISO_YSHIFT_LEFT -0.05
#define ISO_YSHIFT_RIGHT -0.05
#define ISO_SCALE 0.85 /* coordinates for isospectral billiards */
#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 */
@ -104,9 +107,11 @@
#define OMEGA 0.002 /* frequency of periodic excitation */
#define AMPLITUDE 1.0 /* amplitude of periodic excitation */
#define COURANT 0.02 /* Courant number */
#define COURANTB 0.02 /* Courant number in medium B */
#define COURANTB 0.01 /* Courant number in medium B */
#define GAMMA 0.0 /* damping factor in wave equation */
#define GAMMAB 5.0e-3 /* damping factor in wave equation */
// #define GAMMAB 5.0e-3 /* damping factor in wave equation */
// #define GAMMAB 1.0e-2 /* damping factor in wave equation */
#define GAMMAB 1.0e-6 /* 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 */
@ -119,12 +124,13 @@
/* Boundary conditions, see list in global_pdes.c */
#define B_COND 2
#define B_COND 3
/* Parameters for length and speed of simulation */
#define NSTEPS 5000 /* number of frames of movie */
#define NVID 50 /* number of iterations between images displayed on screen */
// #define NSTEPS 500 /* number of frames of movie */
#define NSTEPS 1500 /* number of frames of movie */
#define NVID 40 /* number of iterations between images displayed on screen */
#define NSEG 100 /* number of segments of boundary */
#define INITIAL_TIME 0 /* time after which to start saving frames */
#define BOUNDARY_WIDTH 2 /* width of billiard boundary */
@ -134,31 +140,35 @@
#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 100 /* number of still frames at end of movie */
#define END_FRAMES 50 /* number of still frames at end of movie */
/* Parameters of initial condition */
#define INITIAL_AMP 0.75 /* amplitude of initial condition */
#define INITIAL_VARIANCE 0.0005 /* variance of initial condition */
#define INITIAL_WAVELENGTH 0.02 /* wavelength of initial condition */
// #define INITIAL_VARIANCE 0.0003 /* variance of initial condition */
// #define INITIAL_WAVELENGTH 0.015 /* wavelength of initial condition */
#define INITIAL_VARIANCE 0.0003 /* variance of initial condition */
#define INITIAL_WAVELENGTH 0.015 /* wavelength of initial condition */
/* Plot type, see list in global_pdes.c */
#define PLOT 1
#define PLOT_B 3 /* plot type for second movie */
#define PLOT_B 0 /* plot type for second movie */
/* Color schemes */
#define COLOR_PALETTE 13 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE 14 /* 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.15 /* sensitivity of color on wave amplitude */
// #define SLOPE 0.25 /* sensitivity of color on wave amplitude */
#define SLOPE 1.0 /* sensitivity of color on wave amplitude */
#define ATTENUATION 0.0 /* exponential attenuation coefficient of contrast with time */
// #define E_SCALE 150.0 /* scaling factor for energy representation */
#define E_SCALE 100.0 /* scaling factor for energy representation */
#define COLORHUE 260 /* initial hue of water color for scheme C_LUM */
@ -166,9 +176,14 @@
#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 180.0 /* mean value of hue for color scheme C_HUE */
// #define HUEMEAN 210.0 /* mean value of hue for color scheme C_HUE */
#define HUEAMP -180.0 /* amplitude of variation of hue for color scheme C_HUE */
// #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 2.0 /* scale of color scheme bar */
#define COLORBAR_RANGE_B 12.0 /* scale of color scheme bar for 2nd part */
#define ROTATE_COLOR_SCHEME 1 /* set to 1 to draw color scheme horizontally */
#define SAVE_TIME_SERIES 0 /* set to 1 to save wave time series at a point */
@ -188,8 +203,7 @@ double courant2, courantb2; /* Courant parameters squared */
/* animation part */
/*********************/
void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX], double *psi_out[NX],
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 */
@ -306,7 +320,7 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
/* 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;
// psi_out[i][j] = x;
if (FLOOR)
{
@ -322,12 +336,271 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
}
void evolve_wave_half(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 */
/* 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++;
/* initialize tables with wave speeds and dissipation */
if (first)
{
for (i=0; i<NX; i++){
for (j=0; j<NY; j++){
if (xy_in[i][j] != 0)
{
tc[i][j] = COURANT;
tcc[i][j] = courant2;
if (xy_in[i][j] == 1) tgamma[i][j] = GAMMA;
else tgamma[i][j] = GAMMAB;
}
else if (TWOSPEEDS)
{
tc[i][j] = COURANTB;
tcc[i][j] = courantb2;
tgamma[i][j] = GAMMAB;
}
}
}
first = 0;
}
#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][j] != 0)){
x = phi_in[i][j];
y = psi_in[i][j];
/* discretized Laplacian */
delta = phi_in[i+1][j] + phi_in[i-1][j] + phi_in[i][j+1] + phi_in[i][j-1] - 4.0*x;
/* evolve phi */
phi_out[i][j] = -y + 2*x + tcc[i][j]*delta - KAPPA*x - tgamma[i][j]*(x-y);
psi_out[i][j] = x;
}
}
}
/* left boundary */
if (OSCILLATE_LEFT) for (j=1; j<NY-1; j++) phi_out[0][j] = AMPLITUDE*cos((double)time*OMEGA);
else for (j=1; j<NY-1; j++){
if ((TWOSPEEDS)||(xy_in[0][j] != 0)){
x = phi_in[0][j];
y = psi_in[0][j];
switch (B_COND) {
case (BC_DIRICHLET):
{
delta = phi_in[1][j] + phi_in[0][j+1] + phi_in[0][j-1] - 3.0*x;
phi_out[0][j] = -y + 2*x + tcc[0][j]*delta - KAPPA*x - tgamma[0][j]*(x-y);
break;
}
case (BC_PERIODIC):
{
delta = phi_in[1][j] + phi_in[NX-1][j] + phi_in[0][j+1] + phi_in[0][j-1] - 4.0*x;
phi_out[0][j] = -y + 2*x + tcc[0][j]*delta - KAPPA*x - tgamma[0][j]*(x-y);
break;
}
case (BC_ABSORBING):
{
delta = phi_in[1][j] + phi_in[0][j+1] + phi_in[0][j-1] - 3.0*x;
phi_out[0][j] = x - tc[0][j]*(x - phi_in[1][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
case (BC_VPER_HABS):
{
delta = phi_in[1][j] + phi_in[0][j+1] + phi_in[0][j-1] - 3.0*x;
phi_out[0][j] = x - tc[0][j]*(x - phi_in[1][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
}
psi_out[0][j] = x;
}
}
/* right boundary */
for (j=1; j<NY-1; j++){
if ((TWOSPEEDS)||(xy_in[NX-1][j] != 0)){
x = phi_in[NX-1][j];
y = psi_in[NX-1][j];
switch (B_COND) {
case (BC_DIRICHLET):
{
delta = phi_in[NX-2][j] + phi_in[NX-1][j+1] + phi_in[NX-1][j-1] - 3.0*x;
phi_out[NX-1][j] = -y + 2*x + tcc[NX-1][j]*delta - KAPPA*x - tgamma[NX-1][j]*(x-y);
break;
}
case (BC_PERIODIC):
{
delta = phi_in[NX-2][j] + phi_in[0][j] + phi_in[NX-1][j+1] + phi_in[NX-1][j-1] - 4.0*x;
phi_out[NX-1][j] = -y + 2*x + tcc[NX-1][j]*delta - KAPPA*x - tgamma[NX-1][j]*(x-y);
break;
}
case (BC_ABSORBING):
{
delta = phi_in[NX-2][j] + phi_in[NX-1][j+1] + phi_in[NX-1][j-1] - 3.0*x;
phi_out[NX-1][j] = x - tc[NX-1][j]*(x - phi_in[NX-2][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
case (BC_VPER_HABS):
{
delta = phi_in[NX-2][j] + phi_in[NX-1][j+1] + phi_in[NX-1][j-1] - 3.0*x;
phi_out[NX-1][j] = x - tc[NX-1][j]*(x - phi_in[NX-2][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
}
psi_out[NX-1][j] = x;
}
}
/* top boundary */
for (i=0; i<NX; i++){
if ((TWOSPEEDS)||(xy_in[i][NY-1] != 0)){
x = phi_in[i][NY-1];
y = psi_in[i][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-1] + phi_in[iminus][NY-1] + phi_in[i][NY-2] - 3.0*x;
phi_out[i][NY-1] = -y + 2*x + tcc[i][NY-1]*delta - KAPPA*x - tgamma[i][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-1] + phi_in[iminus][NY-1] + phi_in[i][NY-2] + phi_in[i][0] - 4.0*x;
phi_out[i][NY-1] = -y + 2*x + tcc[i][NY-1]*delta - KAPPA*x - tgamma[i][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-1] + phi_in[iminus][NY-1] + phi_in[i][NY-2] - 3.0*x;
phi_out[i][NY-1] = x - tc[i][NY-1]*(x - phi_in[i][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-1] + phi_in[iminus][NY-1] + phi_in[i][NY-2] + phi_in[i][0] - 4.0*x;
if (i==0) phi_out[0][NY-1] = x - tc[0][NY-1]*(x - phi_in[1][NY-1]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
else phi_out[i][NY-1] = -y + 2*x + tcc[i][NY-1]*delta - KAPPA*x - tgamma[i][NY-1]*(x-y);
break;
}
}
psi_out[i][NY-1] = x;
}
}
/* bottom boundary */
for (i=0; i<NX; i++){
if ((TWOSPEEDS)||(xy_in[i][0] != 0)){
x = phi_in[i][0];
y = psi_in[i][0];
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][0] + phi_in[iminus][0] + phi_in[i][1] - 3.0*x;
phi_out[i][0] = -y + 2*x + tcc[i][0]*delta - KAPPA*x - tgamma[i][0]*(x-y);
break;
}
case (BC_PERIODIC):
{
iplus = (i+1) % NX;
iminus = (i-1) % NX;
if (iminus < 0) iminus += NX;
delta = phi_in[iplus][0] + phi_in[iminus][0] + phi_in[i][1] + phi_in[i][NY-1] - 4.0*x;
phi_out[i][0] = -y + 2*x + tcc[i][0]*delta - KAPPA*x - tgamma[i][0]*(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][0] + phi_in[iminus][0] + phi_in[i][1] - 3.0*x;
phi_out[i][0] = x - tc[i][0]*(x - phi_in[i][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][0] + phi_in[iminus][0] + phi_in[i][1] + phi_in[i][NY-1] - 4.0*x;
if (i==0) phi_out[0][0] = x - tc[0][0]*(x - phi_in[1][0]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
else phi_out[i][0] = -y + 2*x + tcc[i][0]*delta - KAPPA*x - tgamma[i][0]*(x-y);
break;
}
}
psi_out[i][0] = x;
}
}
/* 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);
}
/* 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][j] != 0)
{
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;
}
}
}
}
void evolve_wave(double *phi[NX], double *psi[NX], double *phi_tmp[NX], double *psi_tmp[NX], short int *xy_in[NX])
/* 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);
evolve_wave_half(phi_tmp, psi_tmp, phi, psi, xy_in);
// evolve_wave_half_old(phi, psi, phi_tmp, psi_tmp, xy_in);
// evolve_wave_half_old(phi_tmp, psi_tmp, phi, psi, xy_in);
}
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);
}
@ -358,7 +631,13 @@ void animation()
}
/* initialise positions and radii of circles */
if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN == D_CIRCLES_IN_RECT)) init_circle_config();
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 simular 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;
@ -374,7 +653,11 @@ void animation()
ratio = (XMAX - XMIN)/8.4; /* for Tokarsky billiard */
isospectral_initial_point(0.25, 0.0, startleft, startright); /* for isospectral billiards */
// 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);
@ -384,18 +667,21 @@ void animation()
// 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);
init_circular_wave(-LAMBDA, 0.0, phi, psi, xy_in);
// init_circular_wave(0.5, 0.5, phi, psi, xy_in);
// printf("Initializing wave\n");
// init_circular_wave(-1.0, 0.0, phi, psi, xy_in);
// printf("Wave initialized\n");
// init_circular_wave(0.0, 0.0, phi, psi, xy_in);
// add_circular_wave(-1.0, 0.0, LAMBDA, 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(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.8, 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);
@ -410,7 +696,8 @@ void animation()
draw_wave_e(phi, psi, total_energy, xy_in, 1.0, 0, PLOT);
draw_billiard();
if (DRAW_COLOR_SCHEME) draw_color_scheme(1.7, YMIN + 0.1, 1.9, YMAX - 0.1, PLOT, -12.0, 12.0);
if (DRAW_COLOR_SCHEME) draw_color_bar(PLOT, COLORBAR_RANGE);
glutSwapBuffers();
@ -449,13 +736,13 @@ void animation()
draw_billiard();
if (DRAW_COLOR_SCHEME) draw_color_scheme(1.7, YMIN + 0.1, 1.9, YMAX - 0.1, PLOT, -12.0, 12.0);
if (DRAW_COLOR_SCHEME) draw_color_bar(PLOT, COLORBAR_RANGE);
/* add oscillating waves */
if (i%345 == 344)
{
add_circular_wave(1.0, -LAMBDA, 0.0, phi, psi, xy_in);
}
// if (i%345 == 344)
// {
// add_circular_wave(1.0, -LAMBDA, 0.0, phi, psi, xy_in);
// }
glutSwapBuffers();
@ -468,7 +755,7 @@ void animation()
{
// draw_wave(phi, psi, xy_in, scale, i, PLOT_B);
draw_wave_e(phi, psi, total_energy, xy_in, scale, i, PLOT_B);
if (DRAW_COLOR_SCHEME) draw_color_scheme(1.7, YMIN + 0.1, 1.9, YMAX - 0.1, PLOT_B, -12.0, 12.0);
if (DRAW_COLOR_SCHEME) draw_color_bar(PLOT_B, COLORBAR_RANGE_B);
draw_billiard();
glutSwapBuffers();
save_frame_counter(NSTEPS + 21 + counter);
@ -494,6 +781,7 @@ void animation()
// draw_wave(phi, psi, xy_in, scale, i, PLOT);
draw_wave_e(phi, psi, total_energy, xy_in, scale, NSTEPS, PLOT);
draw_billiard();
if (DRAW_COLOR_SCHEME) draw_color_bar(PLOT, COLORBAR_RANGE);
glutSwapBuffers();
}
for (i=0; i<MID_FRAMES; i++) save_frame();
@ -502,8 +790,8 @@ void animation()
// draw_wave(phi, psi, xy_in, scale, i, PLOT_B);
draw_wave_e(phi, psi, total_energy, xy_in, scale, NSTEPS, PLOT_B);
draw_billiard();
if (DRAW_COLOR_SCHEME) draw_color_bar(PLOT_B, COLORBAR_RANGE_B);
glutSwapBuffers();
// for (i=0; i<END_FRAMES; i++) save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter + i);
}
for (i=0; i<END_FRAMES; i++) save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter + i);

View File

@ -60,6 +60,7 @@ void init_circular_wave(double x, double y, double *phi[NX], double *psi[NX], sh
int i, j;
double xy[2], dist2;
printf("Initializing wave\n");
for (i=0; i<NX; i++)
for (j=0; j<NY; j++)
{
@ -124,21 +125,26 @@ void init_planar_wave(double x, double y, double *phi[NX], double *psi[NX], shor
double xy[2], dist2;
for (i=0; i<NX; i++)
{
// if (i%100 == 0) printf("Initializing column %i\n", i);
for (j=0; j<NY; j++)
{
ij_to_xy(i, j, xy);
dist2 = (xy[0]-x)*(xy[0]-x);
xy_in[i][j] = xy_in_billiard(xy[0],xy[1]);
if ((xy_in[i][j])||(TWOSPEEDS))
phi[i][j] = INITIAL_AMP*exp(-dist2/INITIAL_VARIANCE)*cos(-sqrt(dist2)/INITIAL_WAVELENGTH);
// if ((xy_in[i][j])||(TWOSPEEDS)) phi[i][j] = 0.01*exp(-dist2/0.0005)*cos(-sqrt(dist2)/0.01);
// if ((xy_in[i][j])||(TWOSPEEDS)) phi[i][j] = 0.01*exp(-dist2/0.0005)*cos(-sqrt(dist2)/0.02);
// if ((xy_in[i][j])||(TWOSPEEDS)) phi[i][j] = 0.01*exp(-dist2/0.005)*cos(-sqrt(dist2)/0.02);
// if ((xy_in[i][j])||(TWOSPEEDS)) phi[i][j] = 0.01*exp(-dist2/0.01)*cos(-sqrt(dist2)/0.02);
if ((xy_in[i][j])||(TWOSPEEDS)) phi[i][j] = 0.01*exp(-dist2/0.0005)*cos(-sqrt(dist2)/0.01);
// if ((xy_in[i][j])||(TWOSPEEDS)) phi[i][j] = 0.01*exp(-dist2/0.0005)*cos(-sqrt(dist2)/0.01);
// if ((xy_in[i][j])||(TWOSPEEDS)) phi[i][j] = 0.01*exp(-dist2/0.05)*cos(-sqrt(dist2)/0.025);
else phi[i][j] = 0.0;
psi[i][j] = 0.0;
}
}
}
@ -396,59 +402,6 @@ void draw_wave_e(double *phi[NX], double *psi[NX], double *total_energy[NX], sho
}
void draw_color_scheme(double x1, double y1, double x2, double y2, int plot, double min, double max)
{
int j, ij_botleft[2], ij_topright[2], imin, imax, jmin, jmax;
double y, dy, dy_e, rgb[3], value;
xy_to_ij(x1, y1, ij_botleft);
xy_to_ij(x2, y2, ij_topright);
imin = ij_botleft[0];
imax = ij_topright[0];
jmin = ij_botleft[1];
jmax = ij_topright[1];
glBegin(GL_QUADS);
dy = (max - min)/((double)(jmax - jmin));
dy_e = max/((double)(jmax - jmin));
for (j = jmin; j < jmax; j++)
{
switch (plot) {
case (P_AMPLITUDE):
{
value = min + 1.0*dy*(double)(j - jmin);
color_scheme(COLOR_SCHEME, value, 1.0, 1, rgb);
break;
}
case (P_ENERGY):
{
value = dy_e*(double)(j - jmin);
if (COLOR_PALETTE >= COL_TURBO) color_scheme_asym(COLOR_SCHEME, value, 1.0, 1, rgb);
else color_scheme(COLOR_SCHEME, value, 1.0, 1, rgb);
break;
}
case (P_MEAN_ENERGY):
{
value = dy_e*(double)(j - jmin);
if (COLOR_PALETTE >= COL_TURBO) color_scheme_asym(COLOR_SCHEME, value, 1.0, 1, rgb);
else color_scheme(COLOR_SCHEME, value, 1.0, 1, rgb);
break;
}
}
glColor3f(rgb[0], rgb[1], rgb[2]);
glVertex2i(imin, j);
glVertex2i(imax, j);
glVertex2i(imax, j+1);
glVertex2i(imin, j+1);
}
glEnd ();
glColor3f(1.0, 1.0, 1.0);
draw_rectangle(x1, y1, x2, y2);
}

View File

@ -67,6 +67,7 @@
#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 0 /* set to 1 to randomize angle of polygons */
#define LAMBDA 0.8 /* parameter controlling the dimensions of domain */
#define MU 0.03 /* parameter controlling the dimensions of domain */
@ -174,6 +175,12 @@
#define HUEMEAN 220.0 /* mean value of hue for color scheme C_HUE */
#define HUEAMP -220.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 4.0 /* scale of color scheme bar */
#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 */
/* For debugging purposes only */
#define FLOOR 0 /* set to 1 to limit wave amplitude to VMAX */
#define VMAX 5.0 /* max value of wave amplitude */
@ -191,7 +198,7 @@ double courant2, courantb2; /* Courant parameters squared */
/* animation part */
/*********************/
void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX], double *psi_out[NX],
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 */
@ -338,6 +345,368 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
// 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],
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, jmid = NY/2;
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++;
/* initialize tables with wave speeds and dissipation */
if (first)
{
for (i=0; i<NX; i++){
for (j=0; j<NY; j++){
if (xy_in[i][j])
{
tc[i][j] = COURANT;
tcc[i][j] = courant2;
tgamma[i][j] = GAMMA;
}
else if (TWOSPEEDS)
{
tc[i][j] = COURANTB;
tcc[i][j] = courantb2;
tgamma[i][j] = GAMMAB;
}
}
}
first = 0;
}
#pragma omp parallel for private(i,j,iplus,iminus,jplus,jminus,delta,x,y,c,cc,gamma)
/* evolution in the bulk */
for (i=1; i<NX-1; i++){
for (j=1; j<jmid-1; j++){
if ((TWOSPEEDS)||(xy_in[i][j] != 0)){
x = phi_in[i][j];
y = psi_in[i][j];
/* discretized Laplacian */
delta = phi_in[i+1][j] + phi_in[i-1][j] + phi_in[i][j+1] + phi_in[i][j-1] - 4.0*x;
/* evolve phi */
phi_out[i][j] = -y + 2*x + tcc[i][j]*delta - KAPPA*x - tgamma[i][j]*(x-y);
psi_out[i][j] = x;
}
}
for (j=jmid+1; j<NY-1; j++){
if ((TWOSPEEDS)||(xy_in[i][j] != 0)){
x = phi_in[i][j];
y = psi_in[i][j];
/* discretized Laplacian */
delta = phi_in[i+1][j] + phi_in[i-1][j] + phi_in[i][j+1] + phi_in[i][j-1] - 4.0*x;
/* evolve phi */
phi_out[i][j] = -y + 2*x + tcc[i][j]*delta - KAPPA*x - tgamma[i][j]*(x-y);
psi_out[i][j] = x;
}
}
}
/* left boundary */
if (OSCILLATE_LEFT) {
for (j=1; j<jmid-1; j++) phi_out[0][j] = AMPLITUDE*cos((double)time*OMEGA);
for (j=jmid+1; j<NY-1; j++) phi_out[0][j] = AMPLITUDE*cos((double)time*OMEGA);
}
else for (j=1; j<NY-1; j++) if ((j!=jmid-1)&&(j!=jmid)) {
if ((TWOSPEEDS)||(xy_in[0][j] != 0)){
x = phi_in[0][j];
y = psi_in[0][j];
switch (B_COND) {
case (BC_DIRICHLET):
{
delta = phi_in[1][j] + phi_in[0][j+1] + phi_in[0][j-1] - 3.0*x;
phi_out[0][j] = -y + 2*x + tcc[0][j]*delta - KAPPA*x - tgamma[0][j]*(x-y);
break;
}
case (BC_PERIODIC):
{
delta = phi_in[1][j] + phi_in[NX-1][j] + phi_in[0][j+1] + phi_in[0][j-1] - 4.0*x;
phi_out[0][j] = -y + 2*x + tcc[0][j]*delta - KAPPA*x - tgamma[0][j]*(x-y);
break;
}
case (BC_ABSORBING):
{
delta = phi_in[1][j] + phi_in[0][j+1] + phi_in[0][j-1] - 3.0*x;
phi_out[0][j] = x - tc[0][j]*(x - phi_in[1][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
case (BC_VPER_HABS):
{
delta = phi_in[1][j] + phi_in[0][j+1] + phi_in[0][j-1] - 3.0*x;
phi_out[0][j] = x - tc[0][j]*(x - phi_in[1][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
}
psi_out[0][j] = x;
}
}
/* right boundary */
for (j=1; j<NY-1; j++) if ((j!=jmid-1)&&(j!=jmid)) {
if ((TWOSPEEDS)||(xy_in[NX-1][j] != 0)){
x = phi_in[NX-1][j];
y = psi_in[NX-1][j];
switch (B_COND) {
case (BC_DIRICHLET):
{
delta = phi_in[NX-2][j] + phi_in[NX-1][j+1] + phi_in[NX-1][j-1] - 3.0*x;
phi_out[NX-1][j] = -y + 2*x + tcc[NX-1][j]*delta - KAPPA*x - tgamma[NX-1][j]*(x-y);
break;
}
case (BC_PERIODIC):
{
delta = phi_in[NX-2][j] + phi_in[0][j] + phi_in[NX-1][j+1] + phi_in[NX-1][j-1] - 4.0*x;
phi_out[NX-1][j] = -y + 2*x + tcc[NX-1][j]*delta - KAPPA*x - tgamma[NX-1][j]*(x-y);
break;
}
case (BC_ABSORBING):
{
delta = phi_in[NX-2][j] + phi_in[NX-1][j+1] + phi_in[NX-1][j-1] - 3.0*x;
phi_out[NX-1][j] = x - tc[NX-1][j]*(x - phi_in[NX-2][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
case (BC_VPER_HABS):
{
delta = phi_in[NX-2][j] + phi_in[NX-1][j+1] + phi_in[NX-1][j-1] - 3.0*x;
phi_out[NX-1][j] = x - tc[NX-1][j]*(x - phi_in[NX-2][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
}
psi_out[NX-1][j] = x;
}
}
/* top mid boundary */
for (i=0; i<NX; i++){
if ((TWOSPEEDS)||(xy_in[i][jmid-1] != 0)){
x = phi_in[i][jmid-1];
y = psi_in[i][jmid-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][jmid-1] + phi_in[iminus][jmid-1] + phi_in[i][jmid-2] - 3.0*x;
phi_out[i][jmid-1] = -y + 2*x + tcc[i][jmid-1]*delta - KAPPA*x - tgamma[i][jmid-1]*(x-y);
break;
}
case (BC_PERIODIC):
{
iplus = (i+1) % NX;
iminus = (i-1) % NX; if (iminus < 0) iminus += NX;
delta = phi_in[iplus][jmid-1] + phi_in[iminus][jmid-1] + phi_in[i][jmid-2] + phi_in[i][0] - 4.0*x;
phi_out[i][jmid-1] = -y + 2*x + tcc[i][jmid-1]*delta - KAPPA*x - tgamma[i][jmid-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][jmid-1] + phi_in[iminus][jmid-1] + phi_in[i][jmid-2] - 3.0*x;
phi_out[i][jmid-1] = x - tc[i][jmid-1]*(x - phi_in[i][jmid-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][jmid-1] + phi_in[iminus][jmid-1] + phi_in[i][jmid-2] + phi_in[i][0] - 4.0*x;
if (i==0) phi_out[0][jmid-1] = x - tc[0][jmid-1]*(x - phi_in[1][jmid-1]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
else phi_out[i][jmid-1] = -y + 2*x + tcc[i][jmid-1]*delta - KAPPA*x - tgamma[i][jmid-1]*(x-y);
break;
}
}
psi_out[i][jmid-1] = x;
}
}
/* bottom boundary */
for (i=0; i<NX; i++){
if ((TWOSPEEDS)||(xy_in[i][0] != 0)){
x = phi_in[i][0];
y = psi_in[i][0];
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][0] + phi_in[iminus][0] + phi_in[i][1] - 3.0*x;
phi_out[i][0] = -y + 2*x + tcc[i][0]*delta - KAPPA*x - tgamma[i][0]*(x-y);
break;
}
case (BC_PERIODIC):
{
iplus = (i+1) % NX;
iminus = (i-1) % NX; if (iminus < 0) iminus += NX;
delta = phi_in[iplus][0] + phi_in[iminus][0] + phi_in[i][1] + phi_in[i][jmid-1] - 4.0*x;
phi_out[i][0] = -y + 2*x + tcc[i][0]*delta - KAPPA*x - tgamma[i][0]*(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][0] + phi_in[iminus][0] + phi_in[i][1] - 3.0*x;
phi_out[i][0] = x - tc[i][0]*(x - phi_in[i][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][0] + phi_in[iminus][0] + phi_in[i][1] + phi_in[i][jmid-1] - 4.0*x;
if (i==0) phi_out[0][0] = x - tc[0][0]*(x - phi_in[1][0]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
else phi_out[i][0] = -y + 2*x + tcc[i][0]*delta - KAPPA*x - tgamma[i][0]*(x-y);
break;
}
}
psi_out[i][0] = x;
}
}
/* top boundary */
for (i=0; i<NX; i++){
if ((TWOSPEEDS)||(xy_in[i][NY-1] != 0)){
x = phi_in[i][NY-1];
y = psi_in[i][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-1] + phi_in[iminus][NY-1] + phi_in[i][NY-2] - 3.0*x;
phi_out[i][NY-1] = -y + 2*x + tcc[i][NY-1]*delta - KAPPA*x - tgamma[i][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-1] + phi_in[iminus][NY-1] + phi_in[i][NY-2] + phi_in[i][jmid] - 4.0*x;
phi_out[i][NY-1] = -y + 2*x + tcc[i][NY-1]*delta - KAPPA*x - tgamma[i][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-1] + phi_in[iminus][NY-1] + phi_in[i][NY-2] - 3.0*x;
phi_out[i][NY-1] = x - tc[i][NY-1]*(x - phi_in[i][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-1] + phi_in[iminus][NY-1] + phi_in[i][NY-2] + phi_in[i][jmid] - 4.0*x;
if (i==0) phi_out[0][NY-1] = x - tc[0][NY-1]*(x - phi_in[1][NY-1]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
else phi_out[i][NY-1] = -y + 2*x + tcc[i][NY-1]*delta - KAPPA*x - tgamma[i][NY-1]*(x-y);
break;
}
}
psi_out[i][NY-1] = x;
}
}
/* bottom mid boundary */
for (i=0; i<NX; i++){
if ((TWOSPEEDS)||(xy_in[i][jmid] != 0)){
x = phi_in[i][jmid];
y = psi_in[i][jmid];
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][jmid] + phi_in[iminus][jmid] + phi_in[i][1] - 3.0*x;
phi_out[i][jmid] = -y + 2*x + tcc[i][jmid]*delta - KAPPA*x - tgamma[i][jmid]*(x-y);
break;
}
case (BC_PERIODIC):
{
iplus = (i+1) % NX;
iminus = (i-1) % NX; if (iminus < 0) iminus += NX;
delta = phi_in[iplus][jmid] + phi_in[iminus][jmid] + phi_in[i][jmid+1] + phi_in[i][NY-1] - 4.0*x;
phi_out[i][jmid] = -y + 2*x + tcc[i][jmid]*delta - KAPPA*x - tgamma[i][jmid]*(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][jmid] + phi_in[iminus][jmid] + phi_in[i][jmid+1] - 3.0*x;
phi_out[i][jmid] = x - tc[i][jmid]*(x - phi_in[i][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][jmid] + phi_in[iminus][jmid] + phi_in[i][jmid+1] + phi_in[i][NY-1] - 4.0*x;
if (i==0) phi_out[0][jmid] = x - tc[0][jmid]*(x - phi_in[1][jmid]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
else phi_out[i][jmid] = -y + 2*x + tcc[i][jmid]*delta - KAPPA*x - tgamma[i][jmid]*(x-y);
break;
}
}
psi_out[i][jmid] = x;
}
}
/* add oscillating boundary condition on the left corners */
if ((i == 0)&&(OSCILLATE_LEFT))
{
phi_out[i][0] = AMPLITUDE*cos((double)time*OMEGA);
phi_out[i][jmid-1] = AMPLITUDE*cos((double)time*OMEGA);
phi_out[i][jmid] = AMPLITUDE*cos((double)time*OMEGA);
phi_out[i][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][j] != 0)
{
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(double *phi[NX], double *psi[NX], double *phi_tmp[NX], double *psi_tmp[NX], short int *xy_in[NX])
/* time step of field evolution */
@ -368,7 +737,7 @@ void animation()
/* initialise positions and radii of circles */
printf("initializing circle configuration\n");
if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN_B == D_CIRCLES)) init_circle_config_comp();
if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN_B == D_CIRCLES)) init_circle_config_comp(circles);
courant2 = COURANT*COURANT;
courantb2 = COURANTB*COURANTB;

View File

@ -66,11 +66,12 @@
#define B_DOMAIN 20 /* choice of domain shape, see list in global_pdes.c */
#define B_DOMAIN_B 20 /* choice of domain shape, see list in global_pdes.c */
#define CIRCLE_PATTERN 1 /* pattern of circles, see list in global_pdes.c */
#define CIRCLE_PATTERN 2 /* pattern of circles, see list in global_pdes.c */
#define CIRCLE_PATTERN_B 11 /* pattern of circles, 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.75 /* parameter controlling the dimensions of domain */
#define MU 0.03 /* parameter controlling the dimensions of domain */
@ -123,6 +124,7 @@
/* Boundary conditions, see list in global_pdes.c */
// #define B_COND 2
#define B_COND 3
/* Parameters for length and speed of simulation */
@ -152,14 +154,14 @@
/* Color schemes */
#define COLOR_PALETTE 0 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE 14 /* Color palette, see list in global_pdes.c */
#define BLACK 1 /* background */
#define COLOR_SCHEME 1 /* choice of color scheme, see list in global_pdes.c */
#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 50.0 /* sensitivity of color on wave amplitude */
#define SLOPE 10.0 /* sensitivity of color on wave amplitude */
#define ATTENUATION 0.0 /* exponential attenuation coefficient of contrast with time */
#define E_SCALE 500.0 /* scaling factor for energy representation */
@ -170,6 +172,11 @@
#define HUEMEAN 220.0 /* mean value of hue for color scheme C_HUE */
#define HUEAMP -220.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 4.0 /* scale of color scheme bar */
#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 */
/* For debugging purposes only */
#define FLOOR 0 /* set to 1 to limit wave amplitude to VMAX */
#define VMAX 5.0 /* max value of wave amplitude */
@ -227,16 +234,29 @@ void draw_wave_energy(double *phi[NX], double *psi[NX], short int *xy_in[NX], do
for (i=0; i<NX; i++)
for (j=0; j<NY/2; j++)
{
if (((TWOSPEEDS)&&(xy_in[i][j] != 2))||(xy_in[i][j] == 1))
{
if (PLOT == P_AMPLITUDE)
color_scheme(COLOR_SCHEME, phi[i][j], scale, time, rgb);
else if (PLOT == P_ENERGY)
color_scheme(COLOR_SCHEME, compute_energy(phi, psi, xy_in, i, j), scale, time, rgb);
else if (PLOT == P_MIXED)
{
if (j > NY/2) color_scheme(COLOR_SCHEME, phi[i][j], scale, time, rgb);
else color_scheme(COLOR_SCHEME, compute_energy(phi, psi, xy_in, i, j), scale, time, rgb);
if (((TWOSPEEDS)&&(xy_in[i][j] != 2))||(xy_in[i][j] == 1)) {
switch (PLOT) {
case (P_AMPLITUDE):
{
/* make wave luminosity larger inside obstacles */
if (!(xy_in[i][j])) color_scheme_lum(COLOR_SCHEME, phi[i][j], scale, time, 0.7, rgb);
else color_scheme(COLOR_SCHEME, phi[i][j], scale, time, rgb);
break;
}
case (P_ENERGY):
{
energy = compute_energy(phi, psi, xy_in, i, j);
/* adjust energy to color palette */
if (COLOR_PALETTE >= COL_TURBO) color_scheme_asym(COLOR_SCHEME, energy, scale, time, rgb);
else color_scheme(COLOR_SCHEME, energy, scale, time, rgb);
break;
}
case (P_MIXED):
{
if (j > NY/2) color_scheme(COLOR_SCHEME, phi[i][j], scale, time, rgb);
else color_scheme(COLOR_SCHEME, compute_energy(phi, psi, xy_in, i, j), scale, time, rgb);
break;
}
}
glColor3f(rgb[0], rgb[1], rgb[2]);
@ -360,7 +380,7 @@ void draw_wave_energy(double *phi[NX], double *psi[NX], short int *xy_in[NX], do
/* animation part */
/*********************/
void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX], double *psi_out[NX],
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 */
@ -393,28 +413,22 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
{
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
jplus = (j+1);
if (jplus == jmid) jplus = jmid-1;
jminus = (j-1);
if (jminus == -1) jminus = 0;
jplus = (j+1); if (jplus == jmid) jplus = jmid-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;
iminus = (i-1) % NX; if (iminus < 0) iminus += NX;
jplus = (j+1) % jmid;
jminus = (j-1) % jmid;
if (jminus < 0) jminus += jmid;
jminus = (j-1) % jmid; if (jminus < 0) jminus += jmid;
}
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);
if (jplus >= jmid) jplus -= jmid;
jminus = (j-1);
if (jminus < 0) jminus += jmid;
jplus = (j+1); if (jplus >= jmid) jplus -= jmid;
jminus = (j-1); if (jminus < 0) jminus += jmid;
}
/* imposing linear wave on top and bottom by making Laplacian 1d */
@ -486,10 +500,261 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
}
void evolve_wave_half(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, jmid = NY/2;
double delta, x, y, c, cc, gamma;
static long time = 0;
static double tc[NX][NY/2], tcc[NX][NY/2], tgamma[NX][NY/2];
static short int first = 1;
time++;
/* initialize tables with wave speeds and dissipation */
if (first)
{
for (i=0; i<NX; i++){
for (j=0; j<jmid; j++){
if (xy_in[i][j])
{
tc[i][j] = COURANT;
tcc[i][j] = courant2;
tgamma[i][j] = GAMMA;
}
else if (TWOSPEEDS)
{
tc[i][j] = COURANTB;
tcc[i][j] = courantb2;
tgamma[i][j] = GAMMAB;
}
}
}
first = 0;
}
#pragma omp parallel for private(i,j,iplus,iminus,jplus,jminus,delta,x,y,c,cc,gamma)
/* evolution in the bulk */
for (i=1; i<NX-1; i++){
for (j=1; j<jmid-1; j++){
if ((TWOSPEEDS)||(xy_in[i][j] != 0)){
x = phi_in[i][j];
y = psi_in[i][j];
/* discretized Laplacian */
delta = phi_in[i+1][j] + phi_in[i-1][j] + phi_in[i][j+1] + phi_in[i][j-1] - 4.0*x;
/* evolve phi */
phi_out[i][j] = -y + 2*x + tcc[i][j]*delta - KAPPA*x - tgamma[i][j]*(x-y);
psi_out[i][j] = x;
}
}
}
/* left boundary */
if (OSCILLATE_LEFT) for (j=1; j<jmid; j++) phi_out[0][j] = AMPLITUDE*cos((double)time*OMEGA);
else for (j=1; j<jmid-1; j++){
if ((TWOSPEEDS)||(xy_in[0][j] != 0)){
x = phi_in[0][j];
y = psi_in[0][j];
switch (B_COND) {
case (BC_DIRICHLET):
{
delta = phi_in[1][j] + phi_in[0][j+1] + phi_in[0][j-1] - 3.0*x;
phi_out[0][j] = -y + 2*x + tcc[0][j]*delta - KAPPA*x - tgamma[0][j]*(x-y);
break;
}
case (BC_PERIODIC):
{
delta = phi_in[1][j] + phi_in[NX-1][j] + phi_in[0][j+1] + phi_in[0][j-1] - 4.0*x;
phi_out[0][j] = -y + 2*x + tcc[0][j]*delta - KAPPA*x - tgamma[0][j]*(x-y);
break;
}
case (BC_ABSORBING):
{
delta = phi_in[1][j] + phi_in[0][j+1] + phi_in[0][j-1] - 3.0*x;
phi_out[0][j] = x - tc[0][j]*(x - phi_in[1][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
case (BC_VPER_HABS):
{
delta = phi_in[1][j] + phi_in[0][j+1] + phi_in[0][j-1] - 3.0*x;
phi_out[0][j] = x - tc[0][j]*(x - phi_in[1][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
}
psi_out[0][j] = x;
}
}
/* right boundary */
for (j=1; j<jmid-1; j++){
if ((TWOSPEEDS)||(xy_in[NX-1][j] != 0)){
x = phi_in[NX-1][j];
y = psi_in[NX-1][j];
switch (B_COND) {
case (BC_DIRICHLET):
{
delta = phi_in[NX-2][j] + phi_in[NX-1][j+1] + phi_in[NX-1][j-1] - 3.0*x;
phi_out[NX-1][j] = -y + 2*x + tcc[NX-1][j]*delta - KAPPA*x - tgamma[NX-1][j]*(x-y);
break;
}
case (BC_PERIODIC):
{
delta = phi_in[NX-2][j] + phi_in[0][j] + phi_in[NX-1][j+1] + phi_in[NX-1][j-1] - 4.0*x;
phi_out[NX-1][j] = -y + 2*x + tcc[NX-1][j]*delta - KAPPA*x - tgamma[NX-1][j]*(x-y);
break;
}
case (BC_ABSORBING):
{
delta = phi_in[NX-2][j] + phi_in[NX-1][j+1] + phi_in[NX-1][j-1] - 3.0*x;
phi_out[NX-1][j] = x - tc[NX-1][j]*(x - phi_in[NX-2][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
case (BC_VPER_HABS):
{
delta = phi_in[NX-2][j] + phi_in[NX-1][j+1] + phi_in[NX-1][j-1] - 3.0*x;
phi_out[NX-1][j] = x - tc[NX-1][j]*(x - phi_in[NX-2][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
}
psi_out[NX-1][j] = x;
}
}
/* top boundary */
for (i=0; i<NX; i++){
if ((TWOSPEEDS)||(xy_in[i][jmid-1] != 0)){
x = phi_in[i][jmid-1];
y = psi_in[i][jmid-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][jmid-1] + phi_in[iminus][jmid-1] + phi_in[i][jmid-2] - 3.0*x;
phi_out[i][jmid-1] = -y + 2*x + tcc[i][jmid-1]*delta - KAPPA*x - tgamma[i][jmid-1]*(x-y);
break;
}
case (BC_PERIODIC):
{
iplus = (i+1) % NX;
iminus = (i-1) % NX; if (iminus < 0) iminus += NX;
delta = phi_in[iplus][jmid-1] + phi_in[iminus][jmid-1] + phi_in[i][jmid-2] + phi_in[i][0] - 4.0*x;
phi_out[i][jmid-1] = -y + 2*x + tcc[i][jmid-1]*delta - KAPPA*x - tgamma[i][jmid-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][jmid-1] + phi_in[iminus][jmid-1] + phi_in[i][jmid-2] - 3.0*x;
phi_out[i][jmid-1] = x - tc[i][jmid-1]*(x - phi_in[i][jmid-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][jmid-1] + phi_in[iminus][jmid-1] + phi_in[i][jmid-2] + phi_in[i][0] - 4.0*x;
if (i==0) phi_out[0][jmid-1] = x - tc[0][jmid-1]*(x - phi_in[1][jmid-1]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
else phi_out[i][jmid-1] = -y + 2*x + tcc[i][jmid-1]*delta - KAPPA*x - tgamma[i][jmid-1]*(x-y);
// delta = phi_in[1][j] + phi_in[0][j+1] + phi_in[0][j-1] - 3.0*x;
// phi_out[0][j] = x - tc[0][j]*(x - phi_in[1][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
}
psi_out[i][jmid-1] = x;
}
}
/* bottom boundary */
for (i=0; i<NX; i++){
if ((TWOSPEEDS)||(xy_in[i][0] != 0)){
x = phi_in[i][0];
y = psi_in[i][0];
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][0] + phi_in[iminus][0] + phi_in[i][1] - 3.0*x;
phi_out[i][0] = -y + 2*x + tcc[i][0]*delta - KAPPA*x - tgamma[i][0]*(x-y);
break;
}
case (BC_PERIODIC):
{
iplus = (i+1) % NX;
iminus = (i-1) % NX; if (iminus < 0) iminus += NX;
delta = phi_in[iplus][0] + phi_in[iminus][0] + phi_in[i][1] + phi_in[i][jmid-1] - 4.0*x;
phi_out[i][0] = -y + 2*x + tcc[i][0]*delta - KAPPA*x - tgamma[i][0]*(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][0] + phi_in[iminus][0] + phi_in[i][1] - 3.0*x;
phi_out[i][0] = x - tc[i][0]*(x - phi_in[i][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][0] + phi_in[iminus][0] + phi_in[i][1] + phi_in[i][jmid-1] - 4.0*x;
if (i==0) phi_out[0][0] = x - tc[0][0]*(x - phi_in[1][0]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
else phi_out[i][0] = -y + 2*x + tcc[i][0]*delta - KAPPA*x - tgamma[i][0]*(x-y);
break;
}
}
psi_out[i][0] = x;
}
}
/* add oscillating boundary condition on the left corners */
if ((i == 0)&&(OSCILLATE_LEFT))
{
phi_out[i][0] = AMPLITUDE*cos((double)time*OMEGA);
phi_out[i][jmid-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<jmid; j++){
if (xy_in[i][j] != 0)
{
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(double *phi[NX], double *psi[NX], double *phi_tmp[NX], double *psi_tmp[NX], short int *xy_in[NX])
/* time step of field evolution */
/* phi is value of field at time t, psi at time t-1 */
{
// evolve_wave_half_old(phi, psi, phi_tmp, psi_tmp, xy_in);
// evolve_wave_half_old(phi_tmp, psi_tmp, phi, psi, xy_in);
evolve_wave_half(phi, psi, phi_tmp, psi_tmp, xy_in);
evolve_wave_half(phi_tmp, psi_tmp, phi, psi, xy_in);
}
@ -515,8 +780,9 @@ void animation()
/* initialise positions and radii of circles */
printf("initializing circle configuration\n");
if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN_B == D_CIRCLES)) init_circle_config_energy();
// if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN_B == D_CIRCLES)) init_circle_config_comp();
if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN_B == D_CIRCLES)) init_circle_config_energy(circles);
else if (B_DOMAIN == D_POLYGONS) init_polygon_config(polygons);
courant2 = COURANT*COURANT;
courantb2 = COURANTB*COURANTB;