Add files via upload

This commit is contained in:
nilsberglund-orleans 2022-03-13 15:29:50 +01:00 committed by GitHub
parent ca88b9db5c
commit f570f6885e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 4564 additions and 1593 deletions

View File

@ -2339,3 +2339,210 @@ void hsl_to_rgb_twilight(double h, double s, double l, double rgb[3])
else if (color_hue < 0) color_hue = 0;
for (i=0; i<3; i++) rgb[i] = 2.0*l*(double)twilight_srgb_floats[color_hue][i];
}
void hsl_to_rgb_palette(double h, double s, double l, double rgb[3], int palette)
/* color conversion from HSL to RGB */
{
int color_hue, i;
double r, g, b, ratio = 0.711111111, interpolate; /* ratio equals 256/360 */
switch (palette) {
case (COL_JET):
{
hsl_to_rgb_jet(h, s, l, rgb);
break;
}
case (COL_HSLUV):
{
hsluv2rgb(h, 100.0*s, l, &r, &g, &b);
rgb[0] = 2.0*l*r*100.0;
rgb[1] = 2.0*l*g*100.0;
rgb[2] = 2.0*l*b*100.0;
break;
}
case (COL_GRAY):
{
color_hue = h/360.0;
rgb[0] = color_hue;
rgb[1] = color_hue;
rgb[2] = color_hue;
break;
}
case (COL_TURBO):
{
color_hue = 255 - (int)(ratio*h);
for (i=0; i<3; i++) rgb[i] = 2.0*l*(double)turbo_srgb_floats[color_hue][i];
break;
}
case (COL_VIRIDIS):
{
color_hue = 255 - (int)(ratio*h);
for (i=0; i<3; i++) rgb[i] = 2.0*l*(double)viridis_srgb_floats[color_hue][i];
break;
}
case (COL_MAGMA):
{
color_hue = 255 - (int)(ratio*h);
for (i=0; i<3; i++) rgb[i] = 2.0*l*(double)magma_srgb_floats[color_hue][i];
break;
}
case (COL_INFERNO):
{
color_hue = 255 - (int)(ratio*h);
for (i=0; i<3; i++) rgb[i] = 2.0*l*(double)inferno_srgb_floats[color_hue][i];
break;
}
case (COL_PLASMA):
{
color_hue = 255 - (int)(ratio*h);
for (i=0; i<3; i++) rgb[i] = 2.0*l*(double)plasma_srgb_floats[color_hue][i];
break;
}
case (COL_CIVIDIS):
{
color_hue = 255 - (int)(ratio*h);
for (i=0; i<3; i++) rgb[i] = 2.0*l*(double)cividis_srgb_floats[color_hue][i];
break;
}
case (COL_PARULA):
{
color_hue = 255 - (int)(ratio*h);
for (i=0; i<3; i++) rgb[i] = 2.0*l*(double)parula_srgb_floats[color_hue][i];
break;
}
case (COL_TWILIGHT):
{
color_hue = 510 - (int)(2.0*ratio*h);
if (color_hue > 510) color_hue = 510;
else if (color_hue < 0) color_hue = 0;
for (i=0; i<3; i++) rgb[i] = 2.0*l*(double)twilight_srgb_floats[color_hue][i];
break;
}
case (COL_TWILIGHT_SHIFTED):
{
// color_hue = 255 - (int)(2.0*ratio*h);
color_hue = (int)(2.0*ratio*h) - 255;
if (color_hue > 510) color_hue -= 510;
else if (color_hue < 0) color_hue += 510;
for (i=0; i<3; i++) rgb[i] = 2.0*l*(double)twilight_srgb_floats[color_hue][i];
break;
}
case (COL_TURBO_CYCLIC):
{
if (h < 330.0)
{
color_hue = 255 - (int)(ratio*h*12.0/11.0);
for (i=0; i<3; i++) rgb[i] = 2.0*l*(double)turbo_srgb_floats[color_hue][i];
}
else /* use a convex combination to interpolate between extremal Turbo values */
{
if (h > 360.0) h = 360.0;
interpolate = (h - 330.0)/30.0;
for (i=0; i<3; i++)
rgb[i] = (1.0 - interpolate)*(double)turbo_srgb_floats[255][i] + interpolate*(double)turbo_srgb_floats[0][i];
}
break;
}
}
}
void amp_to_rgb_palette(double h, double rgb[3], int palette) /* color conversion from amplitude in [0,1] to RGB */
{
int color_hue, i;
double r, g, b, interpolate;
color_hue = (int)(256.0*h);
if (color_hue > 255) color_hue = 255;
switch (palette) {
case (COL_JET):
{
hsl_to_rgb_jet(360.0*(1.0 - h), 0.9, 0.5, rgb);
break;
}
case (COL_HSLUV):
{
hsluv2rgb(360.0*(1.0 - h), 90.0, 0.5, &r, &g, &b);
rgb[0] = r*100.0;
rgb[1] = g*100.0;
rgb[2] = b*100.0;
break;
}
case (COL_GRAY):
{
rgb[0] = h;
rgb[1] = h;
rgb[2] = h;
break;
}
case (COL_TURBO):
{
for (i=0; i<3; i++) rgb[i] = (double)turbo_srgb_floats[color_hue][i];
break;
}
case (COL_VIRIDIS):
{
for (i=0; i<3; i++) rgb[i] = (double)viridis_srgb_floats[color_hue][i];
break;
}
case (COL_MAGMA):
{
for (i=0; i<3; i++) rgb[i] = (double)magma_srgb_floats[color_hue][i];
break;
}
case (COL_INFERNO):
{
for (i=0; i<3; i++) rgb[i] = (double)inferno_srgb_floats[color_hue][i];
break;
}
case (COL_PLASMA):
{
for (i=0; i<3; i++) rgb[i] = (double)plasma_srgb_floats[color_hue][i];
break;
}
case (COL_CIVIDIS):
{
for (i=0; i<3; i++) rgb[i] = (double)cividis_srgb_floats[color_hue][i];
break;
}
case (COL_PARULA):
{
for (i=0; i<3; i++) rgb[i] = (double)parula_srgb_floats[color_hue][i];
break;
}
case (COL_TWILIGHT):
{
color_hue = (int)(511.0*h);
if (color_hue > 510) color_hue = 510;
else if (color_hue < 0) color_hue = 0;
for (i=0; i<3; i++) rgb[i] = (double)twilight_srgb_floats[color_hue][i];
break;
}
case (COL_TWILIGHT_SHIFTED):
{
// color_hue = (int)(511.0*h) + 255;
color_hue = 255 - (int)(511.0*h);
if (color_hue > 510) color_hue -= 510;
else if (color_hue < 0) color_hue += 510;
for (i=0; i<3; i++) rgb[i] = (double)twilight_srgb_floats[color_hue][i];
break;
}
case (COL_TURBO_CYCLIC):
{
if (h < 0.9)
{
color_hue = (int)(256.0*h/0.9);
for (i=0; i<3; i++) rgb[i] = (double)turbo_srgb_floats[color_hue][i];
}
else /* use a convex combination to interpolate between extremal Turbo values */
{
if (h > 1.0) h = 1.0;
interpolate = (h - 0.9)/0.1;
for (i=0; i<3; i++)
rgb[i] = (1.0 - interpolate)*(double)turbo_srgb_floats[255][i] + interpolate*(double)turbo_srgb_floats[0][i];
}
break;
}
}
}

View File

@ -141,3 +141,92 @@ void color_scheme_asym(int scheme, double value, double scale, int time, double
}
}
void color_scheme_palette(int scheme, int palette, double value, double scale, int time, double rgb[3]) /* color scheme */
{
double hue, y, r, amplitude;
int intpart;
/* saturation = r, luminosity = y */
switch (scheme) {
case (C_LUM):
{
hue = COLORHUE + (double)time*COLORDRIFT/(double)NSTEPS;
if (hue < 0.0) hue += 360.0;
if (hue >= 360.0) hue -= 360.0;
r = 0.9;
amplitude = color_amplitude(value, scale, time);
y = LUMMEAN + amplitude*LUMAMP;
intpart = (int)y;
y -= (double)intpart;
hsl_to_rgb_palette(hue, r, y, rgb, palette);
break;
}
case (C_HUE):
{
r = 0.9;
amplitude = color_amplitude(value, scale, time);
y = 0.5;
hue = HUEMEAN + amplitude*HUEAMP;
if (hue < 0.0) hue += 360.0;
if (hue >= 360.0) hue -= 360.0;
hsl_to_rgb_palette(hue, r, y, rgb, palette);
break;
}
case (C_ONEDIM):
{
amplitude = color_amplitude(value, scale, time);
amp_to_rgb_palette(0.5*(1.0 + amplitude), rgb, palette);
break;
}
case (C_ONEDIM_LINEAR):
{
amplitude = color_amplitude_linear(value, scale, time);
if (amplitude > 1.0) amplitude -= 1.0;
else if (amplitude < 0.0) amplitude += 1.0;
amp_to_rgb_palette(amplitude, rgb, palette);
break;
}
}
}
void color_scheme_asym_palette(int scheme, int palette, double value, double scale, int time, double rgb[3]) /* color scheme */
{
double hue, y, r, amplitude;
int intpart;
/* saturation = r, luminosity = y */
switch (scheme) {
case (C_LUM):
{
hue = COLORHUE + (double)time*COLORDRIFT/(double)NSTEPS;
if (hue < 0.0) hue += 360.0;
if (hue >= 360.0) hue -= 360.0;
r = 0.9;
amplitude = color_amplitude(value, scale, time);
y = LUMMEAN + amplitude*LUMAMP;
intpart = (int)y;
y -= (double)intpart;
hsl_to_rgb_palette(hue, r, y, rgb, palette);
break;
}
case (C_HUE):
{
r = 0.9;
amplitude = color_amplitude_asym(value, scale, time);
y = 0.5;
hue = HUEMEAN + 0.8*amplitude*HUEAMP;
if (hue < 0.0) hue += 360.0;
if (hue >= 360.0) hue -= 360.0;
hsl_to_rgb_palette(hue, r, y, rgb, palette);
break;
}
case (C_ONEDIM):
{
amplitude = color_amplitude(value, scale, time);
amp_to_rgb_palette(amplitude, rgb, palette);
break;
}
}
}

View File

@ -13,6 +13,7 @@
#define NMAXCIRCLES 20000 /* total number of circles/polygons (must be at least NCX*NCY for square grid) */
#define MAXNEIGH 20 /* max number of neighbours kept in memory */
#define NMAXOBSTACLES 100 /* max number of obstacles */
#define C_SQUARE 0 /* square grid of circles */
#define C_HEX 1 /* hexagonal/triangular grid of circles */
@ -32,6 +33,10 @@
#define C_TWO 98 /* two concentric circles of different type */
#define C_NOTHING 99 /* no circle at all, for comparisons */
/* pattern of additional obstacles */
#define O_CORNERS 0 /* obstacles in the corners (for Boy b.c.) */
#define O_GALTON_BOARD 1 /* Galton board pattern */
/* particle interaction */
#define I_COULOMB 0 /* Coulomb force */
@ -41,6 +46,7 @@
#define I_GOLDENRATIO 4 /* Lennard-Jones type with equilibria related by golden ratio */
#define I_LJ_DIPOLE 5 /* Lennard-Jones with a dipolar angle dependence */
#define I_LJ_QUADRUPOLE 6 /* Lennard-Jones with a quadropolar angle dependence */
#define I_LJ_WATER 7 /* model for water molecule */
/* Boundary conditions */
@ -50,7 +56,12 @@
#define BC_PERIODIC 3 /* periodic boundary conditions */
#define BC_PERIODIC_CIRCLE 4 /* periodic boundary conditions and harmonic b.c. outside moving circle */
#define BC_EHRENFEST 5 /* Ehrenfest urn-type configuration */
#define BC_PERIODIC_FUNNEL 6 /* funnel with periodic boundary conditions */
#define BC_RECTANGLE_LID 7 /* rectangular container with moving lid */
#define BC_PERIODIC_TRIANGLE 8 /* periodic boundary conditions and harmonic b.c. outside moving triangle */
#define BC_KLEIN 11 /* Klein bottle (periodic with twisted vertical parts) */
#define BC_SCREEN_BINS 12 /* harmonic boundary conditions outside screen area plus "bins" (for Galton board) */
#define BC_BOY 13 /* Boy surface/projective plane (periodic with twisted horizontal and vertical parts) */
/* Plot types */
@ -61,6 +72,7 @@
#define P_ANGLE 4 /* colors represent angle/spin of particle */
#define P_TYPE 5 /* colors represent type of particle */
#define P_DIRECTION 6 /* colors represent direction of velocity */
#define P_ANGULAR_SPEED 7 /* colors represent angular speed */
/* Color schemes */
@ -104,11 +116,12 @@ typedef struct
double fy; /* y component of force on particle */
double torque; /* torque on particle */
short int thermostat; /* whether particle is coupled to thermostat */
int hashx; /* hash grid positions of particles */
int hashy; /* hash grid positions of particles */
int neighb; /* number of neighbours */
int neighbours[MAXNEIGH]; /* coordinates of neighbours */
double nghangle[MAXNEIGH]; /* angles of neighbours */
int hashcell; /* hash cell in which particle is located */
int neighb; /* number of neighbours within given distance */
int hash_nneighb; /* number of neighbours in hashgrid */
int hashneighbour[9*HASHMAX]; /* particle numbers of neighbours in hashgrid */
double deltax[9*HASHMAX]; /* relative position of neighbours */
double deltay[9*HASHMAX]; /* relative position of neighbours */
short int type; /* type of particle, for mixture simulations */
short int interaction; /* type of interaction */
double eq_dist; /* equilibrium distance */
@ -120,6 +133,8 @@ typedef struct
{
int number; /* total number of particles in cell */
int particles[HASHMAX]; /* numbers of particles in cell */
int nneighb; /* number of neighbouring cells */
int neighbour[9]; /* numbers of neighbouring cells */
} t_hashgrid;
typedef struct
@ -135,12 +150,22 @@ typedef struct
int hashx; /* hash grid positions of particles */
int hashy; /* hash grid positions of particles */
int neighb; /* number of neighbours */
int health; /* 0 = sane, 1 = infected, 2 = recovered */
int health; /* 0 = healthy, 1 = infected, 2 = recovered */
double infected_time; /* time since infected */
int protected; /* 0 = not protected, 1 = protected */
} t_person;
typedef struct
{
double xc, yc, radius; /* center and radius of circle */
short int active; /* circle is active */
} t_obstacle;
typedef struct
{
double xc, yc; /* center of circle */
} t_tracer;
int ncircles, counter = 0;
int ncircles, nobstacles, counter = 0;

View File

@ -53,6 +53,8 @@
#define D_FRESNEL 43 /* Fresnel lens */
#define D_NOISEPANEL 44 /* zigzag noise insulating panel */
#define D_DOUBLE_FRESNEL 45 /* two facing Fresnel lenses */
#define D_QRD 46 /* quadratic resonance diffuser */
#define D_CIRCLE_SEGMENT 47 /* lens-shaped circular segment */
#define NMAXCIRCLES 10000 /* total number of circles/polygons (must be at least NCX*NCY for square grid) */
#define NMAXPOLY 50000 /* maximal number of vertices of polygonal lines (for von Koch et al) */

File diff suppressed because it is too large Load Diff

594
sub_hashgrid.c Normal file
View File

@ -0,0 +1,594 @@
/* routines dealing with hashgrid for lennardjones.c */
/* Note: a possible improvement would be to use pointers instead of integers */
/* when referencing other hashgrid cells or particles */
int bc_grouped(int bc)
/* regroup boundary conditions by type: rectangular = 0, periodic = 1, Klein = 2, Boy = 3, ... */
{
switch (bc) {
case (BC_SCREEN): return(0);
case (BC_RECTANGLE): return(0);
case (BC_CIRCLE): return(0);
case (BC_PERIODIC): return(1);
case (BC_PERIODIC_CIRCLE): return(1);
case (BC_EHRENFEST): return(0);
case (BC_PERIODIC_FUNNEL): return(1);
case (BC_RECTANGLE_LID): return(0);
case (BC_PERIODIC_TRIANGLE): return(1);
case (BC_KLEIN): return(2);
case (BC_SCREEN_BINS): return(0);
case (BC_BOY): return(3);
default: return(-1);
}
}
int mhash(int i, int j)
{
return(i*HASHY + j);
}
int hash_cell(double x, double y)
/* compute hash grid position of particle at (x,y) */
/* returns number of hash cell */
{
static int first = 1;
static double lx, ly, padding;
int i, j;
if (first)
{
if (!NO_WRAP_BC) padding = 0.0;
else padding = HASHGRID_PADDING;
lx = BCXMAX - BCXMIN + 2.0*padding;
ly = BCYMAX - (BCYMIN) + 2.0*padding;
first = 0;
}
if (CENTER_VIEW_ON_OBSTACLE) x -= xshift;
i = (int)((double)HASHX*(x - BCXMIN + padding)/lx);
j = (int)((double)HASHY*(y - BCYMIN + padding)/ly);
if (i<0) i = 0;
else if (i>=HASHX) i = HASHX-1;
if (j<0) j = 0;
else if (j>=HASHY) j = HASHY-1;
return(mhash(i,j));
// printf("Mapped (%.3f,%.3f) to (%i, %i)\n", x, y, ij[0], ij[1]);
}
void init_hashgrid(t_hashgrid hashgrid[HASHX*HASHY])
/* initialise table of neighbouring cells for each hashgrid cell, depending on boundary condition */
{
int i, j, k, p, q, m, i1, j1;
printf("Initializing hash grid\n");
/* bulk of the table */
for (i=0; i<HASHX-1; i++)
for (j=0; j<HASHY-1; j++)
{
m = mhash(i, j);
hashgrid[m].nneighb = 9;
for (p=-1; p<2; p++)
for (q=-1; q<2; q++)
hashgrid[m].neighbour[3*p+q+4] = mhash(i+p, j+q);
}
/* different boundary conditions */
switch (bc_grouped(BOUNDARY_COND)) {
case (0): /* rectangular b.c. */
{
/* left/right boundaries */
for (j=1; j<HASHY-1; j++)
{
for (i=0; i<HASHX; i+=HASHX-1) hashgrid[mhash(i, j)].nneighb = 6;
for (q=-1; q<2; q++)
{
for (p=0; p<2; p++) hashgrid[mhash(0, j)].neighbour[2*(q+1)+p] = mhash(p, j+q);
for (p=-1; p<1; p++) hashgrid[mhash(HASHX-1, j)].neighbour[2*(q+1)+p+1] = mhash(HASHX-1+p, j+q);
}
}
/* top/down boundaries */
for (i=1; i<HASHX-1; i++)
{
for (j=0; j<HASHY; j+=HASHY-1) hashgrid[mhash(i, j)].nneighb = 6;
for (p=-1; p<2; p++)
{
for (q=0; q<2; q++) hashgrid[mhash(i, 0)].neighbour[2*(p+1)+q] = mhash(i+p, q);
for (q=-1; q<1; q++) hashgrid[mhash(i, HASHY-1)].neighbour[2*(p+1)+q+1] = mhash(i+p, HASHY-1+q);
}
}
/* corners */
for (i=0; i<HASHX; i+=HASHX-1) for (j=0; j<HASHY; j+=HASHY-1) hashgrid[mhash(i, j)].nneighb = 4;
for (p=0; p<2; p++) for (q=0; q<2; q++)
{
hashgrid[mhash(0,0)].neighbour[2*p+q] = mhash(p, q);
hashgrid[mhash(HASHX-1,0)].neighbour[2*p+q] = mhash(HASHX-1-p, q);
hashgrid[mhash(0,HASHY-1)].neighbour[2*p+q] = mhash(p, HASHY-1-q);
hashgrid[mhash(HASHX-1,HASHY-1)].neighbour[2*p+q] = mhash(HASHX-1-p, HASHY-1-q);
}
break;
}
case(1): /* periodic b.c. */
{
/* left/right boundaries */
for (j=0; j<HASHY; j++) for (i=0; i<HASHX; i+=HASHX-1)
{
hashgrid[mhash(i, j)].nneighb = 9;
for (p=-1; p<2; p++) for (q=-1; q<2; q++)
{
i1 = (i+p+HASHX)%HASHX;
j1 = (j+q+HASHY)%HASHY;
hashgrid[mhash(i,j)].neighbour[3*(p+1)+q+1] = mhash(i1, j1);
}
}
/* top/bottom boundaries */
for (i=1; i<HASHX-1; i++) for (j=0; j<HASHY; j+=HASHY-1)
{
hashgrid[mhash(i, j)].nneighb = 9;
for (p=-1; p<2; p++) for (q=-1; q<2; q++)
{
i1 = (i+p+HASHX)%HASHX;
j1 = (j+q+HASHY)%HASHY;
hashgrid[mhash(i,j)].neighbour[3*(p+1)+q+1] = mhash(i1, j1);
}
}
break;
}
case(2): /* Klein bottle b.c. */
{
/* left/right boundaries */
for (j=0; j<HASHY; j++) for (i=0; i<HASHX; i+=HASHX-1)
{
hashgrid[mhash(i, j)].nneighb = 9;
for (p=-1; p<2; p++) for (q=-1; q<2; q++)
{
i1 = (i+p+HASHX)%HASHX;
if (((i == 0)&&(p >= 0))||((i == HASHX-1)&&(p <= 0))) j1 = (j+q+HASHY)%HASHY;
else j1 = (2*HASHY-1-j-q)%HASHY;
hashgrid[mhash(i,j)].neighbour[3*(p+1)+q+1] = mhash(i1, j1);
}
}
/* top/bottom boundaries */
for (i=1; i<HASHX-1; i++) for (j=0; j<HASHY; j+=HASHY-1)
{
hashgrid[mhash(i, j)].nneighb = 9;
for (p=-1; p<2; p++) for (q=-1; q<2; q++)
{
i1 = (i+p+HASHX)%HASHX;
j1 = (j+q+HASHY)%HASHY;
hashgrid[mhash(i,j)].neighbour[3*(p+1)+q+1] = mhash(i1, j1);
}
}
break;
}
case(3): /* Boy surface/projective plane b.c. */
{
/* left/right boundaries */
for (j=1; j<HASHY-1; j++) for (i=0; i<HASHX; i+=HASHX-1)
{
hashgrid[mhash(i, j)].nneighb = 9;
for (p=-1; p<2; p++) for (q=-1; q<2; q++)
{
i1 = (i+p+HASHX)%HASHX;
if (((i == 0)&&(p >= 0))||((i == HASHX-1)&&(p <= 0))) j1 = (j+q+HASHY)%HASHY;
else j1 = (2*HASHY-1-j-q)%HASHY;
hashgrid[mhash(i,j)].neighbour[3*(p+1)+q+1] = mhash(i1, j1);
}
}
/* top/bottom boundaries */
for (i=1; i<HASHX-1; i++) for (j=0; j<HASHY; j+=HASHY-1)
{
hashgrid[mhash(i, j)].nneighb = 9;
for (p=-1; p<2; p++) for (q=-1; q<2; q++)
{
if (((j == 0)&&(q >= 0))||((j == HASHY-1)&&(q <= 0))) i1 = (i+p+HASHX)%HASHX;
else i1 = (2*HASHX-1-i-p)%HASHX;
j1 = (j+q+HASHY)%HASHY;
hashgrid[mhash(i,j)].neighbour[3*(p+1)+q+1] = mhash(i1, j1);
}
}
/* corners */
for (i=0; i<HASHX; i+=HASHX-1) for (j=0; j<HASHY; j+=HASHY-1) hashgrid[mhash(i, j)].nneighb = 7;
for (p=0; p<2; p++) for (q=0; q<2; q++) hashgrid[mhash(0,0)].neighbour[2*p+q] = mhash(p,q);
hashgrid[mhash(0,0)].neighbour[4] = mhash(HASHX-1,HASHY-1);
hashgrid[mhash(0,0)].neighbour[5] = mhash(HASHX-2,HASHY-1);
hashgrid[mhash(0,0)].neighbour[6] = mhash(HASHX-1,HASHY-2);
for (p=0; p<2; p++) for (q=0; q<2; q++) hashgrid[mhash(HASHX-1,0)].neighbour[2*p+q] = mhash(HASHX-1-p,q);
hashgrid[mhash(HASHX-1,0)].neighbour[4] = mhash(0,HASHY-1);
hashgrid[mhash(HASHX-1,0)].neighbour[5] = mhash(1,HASHY-1);
hashgrid[mhash(HASHX-1,0)].neighbour[6] = mhash(0,HASHY-2);
for (p=0; p<2; p++) for (q=0; q<2; q++) hashgrid[mhash(0,HASHY-1)].neighbour[2*p+q] = mhash(p,HASHY-1-q);
hashgrid[mhash(0,HASHY-1)].neighbour[4] = mhash(HASHX-1,0);
hashgrid[mhash(0,HASHY-1)].neighbour[5] = mhash(HASHX-2,1);
hashgrid[mhash(0,HASHY-1)].neighbour[6] = mhash(HASHX-1,2);
for (p=0; p<2; p++) for (q=0; q<2; q++) hashgrid[mhash(HASHX-1,HASHY-1)].neighbour[2*p+q] = mhash(HASHX-1-p,HASHY-1-q);
hashgrid[mhash(HASHX-1,HASHY-1)].neighbour[4] = mhash(0,1);
hashgrid[mhash(HASHX-1,HASHY-1)].neighbour[5] = mhash(1,1);
hashgrid[mhash(HASHX-1,HASHY-1)].neighbour[6] = mhash(0,2);
break;
}
default: /* do nothing */;
}
// for (i=0; i<HASHX; i++) for (j=0; j<HASHY; j++)
// {
// for (k=0; k<hashgrid[mhash(i,j)].nneighb; k++)
// {
// m = hashgrid[mhash(i,j)].neighbour[k];
// p = m/HASHY;
// q = m%HASHY;
// printf("Grid cell (%i, %i) - neighbour %i = %i = (%i, %i)\n", i, j, k, m, p, q);
// }
// sleep(1);
// }
}
void update_hashgrid(t_particle* particle, t_hashgrid* hashgrid, int verbose)
{
int i, j, k, n, m, max = 0, hashcell;
// printf("Updating hashgrid_number\n");
for (i=0; i<HASHX*HASHY; i++) hashgrid[i].number = 0;
// printf("Updated hashgrid_number\n");
/* place each particle in hash grid */
for (k=0; k<ncircles; k++)
// if (circleactive[k])
{
// printf("placing circle %i\t", k);
hashcell = hash_cell(particle[k].xc, particle[k].yc);
n = hashgrid[hashcell].number;
if (n < HASHMAX) hashgrid[hashcell].particles[n] = k;
else printf("Too many particles in hash cell (%i, %i), try increasing HASHMAX\n", i, j);
hashgrid[hashcell].number++;
particle[k].hashcell = hashcell;
if (n > max) max = n;
}
if(verbose) printf("Maximal number of particles per hash cell: %i\n", max);
}
int wrap_particle(t_particle* particle, double *px, double *py)
/* relocate particles in case of periodic and similar boundary conditions */
{
double x, y, x1, y1, x2, y2;
int move = 0;
x = particle->xc;
y = particle->yc;
x1 = x;
y1 = y;
switch (bc_grouped(BOUNDARY_COND)) {
case (0): /* rectangular b.c. */
{
/* do nothing */
return(0);
break;
}
case (1): /* periodic b.c. */
{
if (x < BCXMIN)
{
x1 += BCXMAX - BCXMIN;
move++;
}
else if (x > BCXMAX)
{
x1 += BCXMIN - BCXMAX;
move++;
}
if (y > BCYMAX)
{
y1 += BCYMIN - BCYMAX;
move++;
}
else if (y < BCYMIN)
{
y1 += BCYMAX - BCYMIN;
move++;
}
particle->xc = x1;
particle->yc = y1;
return(move);
break;
}
case (2): /* Klein bottle b.c. */
{
if (y > BCYMAX)
{
y1 += BCYMIN - BCYMAX;
move++;
}
else if (y < BCYMIN)
{
y1 += BCYMAX - BCYMIN;
move++;
}
if (x < BCXMIN)
{
x1 += BCXMAX - BCXMIN;
y1 = -y1;
*py *= -1.0;
move++;
}
else if (x > BCXMAX)
{
x1 += BCXMIN - BCXMAX;
y1 = -y1;
*py *= -1.0;
move++;
}
particle->xc = x1;
particle->yc = y1;
return(move);
break;
}
case (3): /* Boy surface b.c. */
{
if ((y < BCYMAX)&&(y > BCYMIN))
{
if (x > BCXMAX)
{
x1 += BCXMIN - BCXMAX;
y1 = -y1;
particle->angle *= -1.0;
particle->vy *= -1.0;
*py *= -1.0;
move++;
}
else if (x < BCXMIN)
{
x1 += BCXMAX - BCXMIN;
y1 = -y1;
particle->angle *= -1.0;
particle->vy *= -1.0;
*py *= -1.0;
move++;
}
}
// x = x1;
// y = y1;
if ((x < BCXMAX)&&(x > BCXMIN))
{
if (y > BCYMAX)
{
y1 += BCYMIN - BCYMAX;
x1 = -x1;
particle->angle = PI - particle->angle;
particle->vx *= -1.0;
*px *= -1.0;
move++;
}
else if (y < BCYMIN)
{
y1 += BCYMAX - BCYMIN;
x1 = -x1;
particle->angle = PI - particle->angle;
particle->vx *= -1.0;
*px *= -1.0;
move++;
}
}
if (((x >= BCXMAX)||(x <= BCXMIN))&&((y >= BCYMAX)||(y <= BCYMIN)))
{
/* This case can lead to numerical instabilities, and can be avoided by putting obstacles in the corners */
printf("Double wrap!\n");
if (x >= BCXMAX) x1 = BCXMAX - BCXMIN - x1;
else x1 = -BCXMAX + BCXMIN - x1;
if (y >= BCXMAX) y1 = BCYMAX - BCYMIN - y1;
else y1 = -BCYMAX + BCYMIN - y1;
particle->vx *= -1.0;
*px *= -1.0;
particle->vy *= -1.0;
*py *= -1.0;
// if (x1 >= BCXMAX) x1 = BCXMAX - 1.0e-5;
// else if (x1 <= BCXMIN) x1 = BCXMIN + 1.0e-5;
// if (y1 >= BCXMAX) y1 = BCYMAX - 1.0e-5;
// else if (y1 <= BCYMIN) y1 = BCYMIN + 1.0e-5;
move++;
}
particle->xc = x1;
particle->yc = y1;
return(move);
break;
}
default:
{
/* do nothing */
break;
}
}
}
void wrap_relative_positions(double x1, double y1, double *x2, double *y2)
/* computes relative positions of particles, taking boundary conditions into account */
{
double dxhalf = 0.5*(BCXMAX - BCXMIN), dyhalf = 0.5*(BCYMAX - BCYMIN);
double dx, dy, x3, y3, x4, y4, dh, dv, wrap_x, wrap_y;
int verbose = 0;
dx = *x2 - x1;
dy = *y2 - y1;
switch (bc_grouped(BOUNDARY_COND)) {
case (0): /* rectangular b.c. */
{
/* do nothing */
break;
}
case (1): /* periodic b.c. */
{
if (dx > dxhalf) *x2 -= BCXMAX - BCXMIN;
else if (-dx > dxhalf) *x2 += BCXMAX - BCXMIN;
if (dy > dyhalf) *y2 -= BCYMAX - BCYMIN;
else if (-dy > dyhalf) *y2 += BCYMAX - BCYMIN;
// printf("(x2,y2) = (%.3lg, %.3lg)\n", *x2, *y2);
break;
}
case (2): /* Klein bottle b.c. */
{
if (dx > dxhalf)
{
*x2 -= BCXMAX - BCXMIN;
*y2 *= -1.0;
}
else if (-dx > dxhalf)
{
*x2 += BCXMAX - BCXMIN;
*y2 *= -1.0;
}
dy = *y2 - y1;
if (dy > dyhalf) *y2 -= BCYMAX - BCYMIN;
else if (-dy > dyhalf) *y2 += BCYMAX - BCYMIN;
break;
}
case (3): /* Boy surface - TO FIX */
{
// wrap_x = 2.0*(BCXMAX - BCXMIN)/(double)HASHX;
// wrap_y = 2.0*(BCYMAX - BCYMIN)/(double)HASHY;
wrap_x = dxhalf;
wrap_y = dyhalf;
/* find which wrapped point is closest to (x1, y1) */
dh = 100.0;
if (dx > wrap_x)
{
x3 = *x2 - BCXMAX + BCXMIN;
y3 = -*y2;
dh = (x3-x1)*(x3-x1) + (y3-y1)*(y3-y1);
}
else if (-dx > wrap_x)
{
x3 = *x2 + BCXMAX - BCXMIN;
y3 = -*y2;
dh = (x3-x1)*(x3-x1) + (y3-y1)*(y3-y1);
}
if ((verbose)&&(dh < 100.0)&&(dh > 0.0))
{
printf("Case 1: (x1,y1) = (%.3lg, %.3lg)\t", x1, y1);
printf("(x2,y2) = (%.3lg, %.3lg) -> (%.3lg, %.3lg)\n", *x2, *y2, x3, y3);
}
dv = 100.0;
if (dy > wrap_y)
{
x4 = -*x2;
y4 = *y2 - BCYMAX + BCYMIN;
dv = (x4-x1)*(x4-x1) + (y4-y1)*(y4-y1);
}
else if (-dy > wrap_y)
{
x4 = -*x2;
y4 = *y2 + BCYMAX - BCYMIN;
dv = (x4-x1)*(x4-x1) + (y4-y1)*(y4-y1);
}
if ((verbose)&&(dv < 100.0)&&(dv > 0.0))
{
printf("Case 2: (x1,y1) = (%.3lg, %.3lg)\t", x1, y1);
printf("(x2,y2) = (%.3lg, %.3lg) -> (%.3lg, %.3lg)\n", *x2, *y2, x4, y4);
}
if (dh < 100.0)
{
*x2 = x3;
*y2 = y3;
}
if (dv < dh)
{
*x2 = x4;
*y2 = y4;
}
break;
}
}
}
void compute_relative_positions(t_particle particle[NMAXCIRCLES], t_hashgrid hashgrid[HASHX*HASHY])
{
int j, i0, j0, m0, k, m, p, q, n = 0;
double x1, x2, y1, y2, xtemp, ytemp;
for (j=0; j < ncircles; j++) if (particle[j].active)
{
// i0 = particle[j].hashx;
// j0 = particle[j].hashy;
// m0 = mhash(i0, j0);
m0 = particle[j].hashcell;
x1 = particle[j].xc;
y1 = particle[j].yc;
n = 0;
for (q=0; q<hashgrid[m0].nneighb; q++)
{
m = hashgrid[m0].neighbour[q];
for (k=0; k<hashgrid[m].number; k++)
if ((hashgrid[m].particles[k]!=j)&&(particle[hashgrid[m].particles[k]].active))
{
if (n < 9*HASHMAX)
{
p = hashgrid[m].particles[k];
x2 = particle[p].xc;
y2 = particle[p].yc;
xtemp = x2;
ytemp = y2;
if (bc_grouped(BOUNDARY_COND) != 0) wrap_relative_positions(x1, y1, &x2, &y2);
particle[j].hashneighbour[n] = p;
particle[j].deltax[n] = x2 - x1;
particle[j].deltay[n] = y2 - y1;
// if ((j%50 == 0)&&((vabs(x2-x1)>1.0)||(vabs(y2-y1)>1.0)))
// if (((vabs(x2-x1)>0.7)||(vabs(y2-y1)>0.7)))
// {
// printf("(x1, y1) = (%.3lg, %.3lg), (x2, y2) = (%.3lg, %.3lg) -> (%.3lg, %.3lg)\n", x1, y1, xtemp, ytemp, x2, y2);
// printf("particle[%i].delta[%i] = (%.4lg, %.4lg)\n", j, n, particle[j].deltax[n], particle[j].deltay[n]);
// }
n++;
}
else printf("Not enough memory in particle.deltax, particle.deltay\n");
}
}
particle[j].hash_nneighb = n;
}
}

2461
sub_lj.c

File diff suppressed because it is too large Load Diff

View File

@ -1349,9 +1349,11 @@ int compute_fresnel_coordinates(t_vertex polyline[NMAXPOLY])
ymax = 0.9*LAMBDA;
dy = 2.0*ymax/(double)NSEG;
polyline[0].x = -MU;
if (LAMBDA > 0.0) x = -MU;
else x = MU;
polyline[0].x = x;
polyline[0].y = -ymax;
xy_to_pos(-MU, -ymax, pos);
xy_to_pos(x, -ymax, pos);
polyline[0].posi = pos[0];
polyline[0].posj = pos[1];
@ -1362,6 +1364,7 @@ int compute_fresnel_coordinates(t_vertex polyline[NMAXPOLY])
// x = sqrt(LAMBDA*LAMBDA - y*y) - LAMBDA*LAMBDA;
while (x <= 0.0) x+= MU;
if (LAMBDA < 0.0) x = -x;
polyline[i].x = x;
polyline[i].y = y;
@ -1371,9 +1374,11 @@ int compute_fresnel_coordinates(t_vertex polyline[NMAXPOLY])
polyline[i].posj = pos[1];
}
polyline[NSEG].x = -MU;
if (LAMBDA > 0.0) x = -MU;
else x = MU;
polyline[NSEG].x = x;
polyline[NSEG].y = ymax;
xy_to_pos(-MU, ymax, pos);
xy_to_pos(x, ymax, pos);
polyline[NSEG].posi = pos[0];
polyline[NSEG].posj = pos[1];
@ -1407,7 +1412,7 @@ int compute_double_fresnel_coordinates(t_vertex polyline[NMAXPOLY], double xshif
int compute_noisepanel_coordinates(t_vertex polyline[NMAXPOLY])
/* compute positions of vertices approximating Fresnel lens */
/* compute positions of vertices of noise panel */
{
int i, n, even;
double ymax, dy, x, y, x1, pos[2];
@ -1452,6 +1457,46 @@ int compute_noisepanel_coordinates(t_vertex polyline[NMAXPOLY])
return(2*n);
}
int compute_qrd_coordinates(t_vertex polyline[NMAXPOLY])
/* compute positions of quadratic noise diffuser */
{
int n = 0, b, k, k1, kmin, kmax;
double x, y, x1, y1 = YMIN, pos[2];
kmin = (int)(XMIN/LAMBDA) - 2;
kmax = (int)(XMAX/LAMBDA) + 2;
for (b = -1; b <= 1; b+= 2)
{
if (b == 1) y1 = YMAX;
for (k = kmin; k < kmax; k++)
{
x = LAMBDA*((double)(k) - 0.5);
k1 = (k*k) % 13;
if (b == -1) y = YMIN + (MU/13.0)*(14.0 - (double)k1);
else y = YMAX - (MU/13.0)*(14.0 - (double)k1);
polyline[n].x = x;
polyline[n].y = y1;
xy_to_pos(x, y1, pos);
polyline[n].posi = pos[0];
polyline[n].posj = pos[1];
n++;
polyline[n].x = x;
polyline[n].y = y;
xy_to_pos(x, y, pos);
polyline[n].posi = pos[0];
polyline[n].posj = pos[1];
n++;
y1 = y;
}
}
return(n);
}
int init_polyline(int depth, t_vertex polyline[NMAXPOLY])
/* initialise variable polyline, for certain polygonal domain shapes */
{
@ -1500,6 +1545,10 @@ int init_polyline(int depth, t_vertex polyline[NMAXPOLY])
{
return(compute_noisepanel_coordinates(polyline));
}
case (D_QRD):
{
return(compute_qrd_coordinates(polyline));
}
default:
{
return(0);
@ -1940,13 +1989,22 @@ int xy_in_billiard(double x, double y)
}
case (D_FRESNEL):
{
if (vabs(y) > 0.9*LAMBDA) return(1);
if (vabs(y) > 0.9*vabs(LAMBDA)) return(1);
if (vabs(x) > MU) return(1);
x1 = sqrt(LAMBDA*LAMBDA - y*y) - LAMBDA;
x1 = sqrt(LAMBDA*LAMBDA - y*y) - vabs(LAMBDA);
while (x1 <= 0.0) x1 += MU;
if (x < x1) return(0);
else return(1);
if (LAMBDA > 0.0)
{
if (x < x1) return(0);
else return(1);
}
else
{
x1 = -x1;
if (x > x1) return(0);
else return(1);
}
}
case (D_DOUBLE_FRESNEL):
{
@ -1979,11 +2037,35 @@ int xy_in_billiard(double x, double y)
if (x1 <= LAMBDA) y1 = 0.1 + MU*x1/LAMBDA;
else y1 = 0.1 + 2.0*MU - MU*x1/LAMBDA;
return((y > YMIN + y1)&&(y < YMAX - y1));
// x1 = vabs(x);
// while (x1 > 2.0*LAMBDA) x1 -= 2.0*LAMBDA;
// if (x1 <= LAMBDA) y1 = MU + x1;
// else y1 = 3.0*MU - x1;
// return((y > YMIN + y1)&&(y < YMAX - y1));
}
case (D_QRD):
{
x1 = vabs(x)/LAMBDA;
k = (int)(x1 + 0.5);
k1 = (k*k) % 13;
y1 = (MU/13.0)*(14.0 - (double)k1);
return ((y > YMIN + y1)&&(y < YMAX - y1));
}
case (D_CIRCLE_SEGMENT):
{
if (vabs(y) > 0.9*vabs(LAMBDA)) return(1);
y1 = 0.9*LAMBDA;
x1 = sqrt(LAMBDA*LAMBDA - y1*y1) - vabs(LAMBDA) + MU;
if ((LAMBDA > 0.0)&&(x < x1)) return(1);
else if ((LAMBDA < 0.0)&&(x > -x1)) return(1);
x1 = sqrt(LAMBDA*LAMBDA - y*y) - vabs(LAMBDA) + MU;
if (LAMBDA > 0.0)
{
if (x < x1) return(0);
else return(1);
}
else
{
if (x > -x1) return(0);
else return(1);
}
}
case (D_MENGER):
{
@ -2950,6 +3032,37 @@ void draw_billiard() /* draws the billiard boundary */
glEnd();
break;
}
case (D_QRD):
{
glLineWidth(BOUNDARY_WIDTH);
glBegin(GL_LINE_STRIP);
for (i=0; i<npolyline/2; i++) tvertex_lineto(polyline[i]);
glEnd();
glBegin(GL_LINE_STRIP);
for (i=npolyline/2; i<npolyline; i++) tvertex_lineto(polyline[i]);
glEnd();
break;
}
case (D_CIRCLE_SEGMENT):
{
glLineWidth(BOUNDARY_WIDTH);
glBegin(GL_LINE_LOOP);
for (i=0; i<NSEG; i++)
{
y = -0.9*LAMBDA + (double)i*1.8*LAMBDA/(double)NSEG;
if (LAMBDA > 0.0) x = sqrt(LAMBDA*LAMBDA - y*y) - LAMBDA + MU;
else x = -sqrt(LAMBDA*LAMBDA - y*y) - LAMBDA - MU;
xy_to_pos(x, y, pos);
glVertex2d(pos[0], pos[1]);
}
y = 0.9*LAMBDA;
if (LAMBDA > 0.0) x = sqrt(LAMBDA*LAMBDA - y*y) - LAMBDA + MU;
else x = -sqrt(LAMBDA*LAMBDA - y*y) - LAMBDA - MU;
xy_to_pos(x, y, pos);
glVertex2d(pos[0], pos[1]);
glEnd();
break;
}
case (D_CIRCLES):
{
glLineWidth(BOUNDARY_WIDTH);
@ -3316,4 +3429,110 @@ void draw_color_scheme(double x1, double y1, double x2, double y2, int plot, dou
draw_rectangle(x1, y1, x2, y2);
}
void draw_color_scheme_palette(double x1, double y1, double x2, double y2, int plot, double min, double max, int palette)
{
int j, k, ij_botleft[2], ij_topright[2], imin, imax, jmin, jmax;
double y, dy, dy_e, rgb[3], value, lum, amp;
xy_to_ij(x1, y1, ij_botleft);
xy_to_ij(x2, y2, ij_topright);
rgb[0] = 0.0; rgb[1] = 0.0; rgb[2] = 0.0;
erase_area_rgb(0.5*(x1 + x2), x2 - x1, 0.5*(y1 + y2), y2 - y1, rgb);
if (ROTATE_COLOR_SCHEME)
{
jmin = ij_botleft[0];
jmax = ij_topright[0];
imin = ij_botleft[1];
imax = ij_topright[1];
}
else
{
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_palette(COLOR_SCHEME, palette, value, 1.0, 1, rgb);
break;
}
case (P_ENERGY):
{
value = dy_e*(double)(j - jmin)*100.0/E_SCALE;
if (COLOR_PALETTE >= COL_TURBO) color_scheme_asym_palette(COLOR_SCHEME, palette, value, 1.0, 1, rgb);
else color_scheme_palette(COLOR_SCHEME, palette, value, 1.0, 1, rgb);
break;
}
case (P_MEAN_ENERGY):
{
value = dy_e*(double)(j - jmin)*100.0/E_SCALE;
if (COLOR_PALETTE >= COL_TURBO) color_scheme_asym_palette(COLOR_SCHEME, palette, value, 1.0, 1, rgb);
else color_scheme_palette(COLOR_SCHEME, palette, value, 1.0, 1, rgb);
break;
}
case (P_LOG_ENERGY):
{
value = LOG_SHIFT + LOG_SCALE*log(dy_e*(double)(j - jmin)*100.0/E_SCALE);
// if (value <= 0.0) value = 0.0;
color_scheme_palette(COLOR_SCHEME, palette, value, 1.0, 1, rgb);
break;
}
case (P_LOG_MEAN_ENERGY):
{
value = LOG_SHIFT + LOG_SCALE*log(dy_e*(double)(j - jmin)*100.0/E_SCALE);
// if (value <= 0.0) value = 0.0;
color_scheme_palette(COLOR_SCHEME, palette, value, 1.0, 1, rgb);
break;
}
case (P_PHASE):
{
value = min + 1.0*dy*(double)(j - jmin);
// lum = (color_amplitude(value, 1.0, 1))*0.5;
// if (lum < 0.0) lum = 0.0;
// hsl_to_rgb(value*360.0, 0.9, 0.5, rgb);
// color_scheme(COLOR_SCHEME, value, 1.0, 1, rgb);
// amp = color_amplitude_linear(value, 1.0, 1);
amp = 0.5*color_amplitude_linear(value, 1.0, 1);
while (amp > 1.0) amp -= 2.0;
while (amp < -1.0) amp += 2.0;
amp_to_rgb(0.5*(1.0 + amp), rgb);
break;
}
}
glColor3f(rgb[0], rgb[1], rgb[2]);
if (ROTATE_COLOR_SCHEME)
{
glVertex2i(j, imin);
glVertex2i(j, imax);
glVertex2i(j+1, imax);
glVertex2i(j+1, imin);
}
else
{
glVertex2i(imin, j);
glVertex2i(imax, j);
glVertex2i(imax, j+1);
glVertex2i(imin, j+1);
}
}
glEnd ();
glColor3f(1.0, 1.0, 1.0);
glLineWidth(BOUNDARY_WIDTH);
draw_rectangle(x1, y1, x2, y2);
}

View File

@ -527,7 +527,46 @@ int xy_in_billiard_half(double x, double y, int domain, int pattern, int top)
}
return(1);
}
cdefault:
case (D_FRESNEL):
{
if (vabs(y) > 0.9*vabs(LAMBDA)) return(1);
if (vabs(x) > MU) return(1);
x1 = sqrt(LAMBDA*LAMBDA - y*y) - vabs(LAMBDA);
while (x1 <= 0.0) x1 += MU;
if (LAMBDA > 0.0)
{
if (x < x1) return(0);
else return(1);
}
else
{
if (x > -x1) return(0);
else return(1);
}
}
case (D_CIRCLE_SEGMENT):
{
if (vabs(y) > 0.9*vabs(LAMBDA)) return(1);
y1 = 0.9*LAMBDA;
x1 = sqrt(LAMBDA*LAMBDA - y1*y1) - vabs(LAMBDA) + MU;
if ((LAMBDA > 0.0)&&(x < x1)) return(1);
else if ((LAMBDA < 0.0)&&(x > -x1)) return(1);
x1 = sqrt(LAMBDA*LAMBDA - y*y) - vabs(LAMBDA) + MU;
if (LAMBDA > 0.0)
{
if (x < x1) return(0);
else return(1);
}
else
{
if (x > -x1) return(0);
else return(1);
}
}
default:
{
printf("Function ij_in_billiard not defined for this billiard \n");
return(0);
@ -563,6 +602,7 @@ void draw_billiard_half(int domain, int pattern, int top) /* draws the bill
glEnable(GL_SCISSOR_TEST);
if (top) glScissor(0.0, YMID, NX, YMID);
// if (top) glScissor(0.0, YMID, NX, YMAX);
else glScissor(0.0, 0.0, NX, YMID);
if (BLACK) glColor3f(1.0, 1.0, 1.0);
@ -661,6 +701,34 @@ void draw_billiard_half(int domain, int pattern, int top) /* draws the bill
}
break;
}
case (D_FRESNEL):
{
glLineWidth(BOUNDARY_WIDTH);
glBegin(GL_LINE_LOOP);
for (i=0; i<npolyline; i++) tvertex_lineto(polyline[i]);
glEnd();
break;
}
case (D_CIRCLE_SEGMENT):
{
glLineWidth(BOUNDARY_WIDTH);
glBegin(GL_LINE_LOOP);
for (i=0; i<NSEG; i++)
{
y = -0.9*LAMBDA + (double)i*1.8*LAMBDA/(double)NSEG;
if (LAMBDA > 0.0) x = sqrt(LAMBDA*LAMBDA - y*y) - LAMBDA + MU;
else x = -sqrt(LAMBDA*LAMBDA - y*y) - LAMBDA - MU;
xy_to_pos(x, y, pos);
glVertex2d(pos[0], pos[1]);
}
y = 0.9*LAMBDA;
if (LAMBDA > 0.0) x = sqrt(LAMBDA*LAMBDA - y*y) - LAMBDA + MU;
else x = -sqrt(LAMBDA*LAMBDA - y*y) - LAMBDA - MU;
xy_to_pos(x, y, pos);
glVertex2d(pos[0], pos[1]);
glEnd();
break;
}
case (D_MANDELBROT):
{
/* Do nothing */
@ -731,7 +799,7 @@ void init_wave_flat_comp( double *phi[NX], double *psi[NX], short int * xy_in[NX
}
void draw_wave_comp(double *phi[NX], double *psi[NX], short int *xy_in[NX], double scale, int time)
void draw_wave_comp(double *phi[NX], double *psi[NX], short int *xy_in[NX], double scale, int time, int plot)
/* draw the field */
{
int i, j, iplus, iminus, jplus, jminus;
@ -747,7 +815,7 @@ void draw_wave_comp(double *phi[NX], double *psi[NX], short int *xy_in[NX], doub
{
if (((TWOSPEEDS)&&(xy_in[i][j] != 2))||(xy_in[i][j] == 1))
{
switch (PLOT) {
switch (plot) {
case (P_AMPLITUDE):
{
color_scheme(COLOR_SCHEME, phi[i][j], scale, time, rgb);

View File

@ -154,14 +154,17 @@ void init_wave_flat( double *phi[NX], double *psi[NX], short int * xy_in[NX])
int i, j;
double xy[2], dist2;
for (i=0; i<NX; i++)
for (i=0; i<NX; i++) {
if (i%100 == 0) printf("Wave and table xy_in - Initialising column %i of %i\n", i, NX);
for (j=0; j<NY; j++)
{
ij_to_xy(i, j, xy);
xy_in[i][j] = xy_in_billiard(xy[0],xy[1]);
// if ((i%10 == 0)&&(j == NY/2)) printf ("xy_in[%i][%i] = %i\n", i, j, xy_in[i][j]);
phi[i][j] = 0.0;
psi[i][j] = 0.0;
}
}
}
@ -351,6 +354,173 @@ void draw_wave_e(double *phi[NX], double *psi[NX], double *total_energy[NX], dou
glBegin(GL_QUADS);
// printf("dtinverse = %.5lg\n", dtinverse);
for (i=0; i<NX; i++)
for (j=0; j<NY; j++)
{
if ((TWOSPEEDS)||(xy_in[i][j]))
{
switch (plot) {
case (P_AMPLITUDE):
{
/* make wave luminosity larger inside obstacles */
field_value = phi[i][j];
if (RESCALE_COLOR_IN_CENTER)
{
field_value *= color_scale[i][j];
}
// if (!(xy_in[i][j])) color_scheme_lum(COLOR_SCHEME, field_value, scale, time, 0.7, rgb);
// else
color_scheme(COLOR_SCHEME, field_value, scale, time, rgb);
break;
}
case (P_ENERGY):
{
energy = compute_energy(phi, psi, xy_in, i, j);
if (RESCALE_COLOR_IN_CENTER)
{
energy *= color_scale[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;
}
case (P_MEAN_ENERGY):
{
energy = compute_energy(phi, psi, xy_in, i, j);
total_energy[i][j] += energy;
if (COLOR_PALETTE >= COL_TURBO)
color_scheme_asym(COLOR_SCHEME, total_energy[i][j]/(double)(time+1), scale, time, rgb);
else color_scheme(COLOR_SCHEME, total_energy[i][j]/(double)(time+1), scale, time, rgb);
break;
}
case (P_LOG_ENERGY):
{
energy = compute_energy(phi, psi, xy_in, i, j);
color_scheme(COLOR_SCHEME, LOG_SHIFT + LOG_SCALE*log(energy), scale, time, rgb);
break;
}
case (P_LOG_MEAN_ENERGY):
{
energy = compute_energy(phi, psi, xy_in, i, j);
if (energy == 0.0) energy = 1.0e-20;
total_energy[i][j] += energy;
energy = LOG_SHIFT + LOG_SCALE*log(total_energy[i][j]/(double)(time+1));
color_scheme(COLOR_SCHEME, energy, scale, time, rgb);
break;
}
}
glColor3f(rgb[0], rgb[1], rgb[2]);
glVertex2i(i, j);
glVertex2i(i+1, j);
glVertex2i(i+1, j+1);
glVertex2i(i, j+1);
}
}
glEnd ();
}
void draw_wave_highres(int size, double *phi[NX], double *psi[NX], double *total_energy[NX], short int *xy_in[NX], double scale, int time, int plot)
/* draw the field, new version with total energy option */
{
int i, j, iplus, iminus, jplus, jminus;
double rgb[3], xy[2], x1, y1, x2, y2, velocity, energy, gradientx2, gradienty2;
static double dtinverse = ((double)NX)/(COURANT*(XMAX-XMIN)), dx = (XMAX-XMIN)/((double)NX);
glBegin(GL_QUADS);
// printf("dtinverse = %.5lg\n", dtinverse);
for (i=0; i<NX; i+=size)
for (j=0; j<NY; j+=size)
{
if ((TWOSPEEDS)||(xy_in[i][j]))
{
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;
}
case (P_MEAN_ENERGY):
{
energy = compute_energy(phi, psi, xy_in, i, j);
total_energy[i][j] += energy;
if (COLOR_PALETTE >= COL_TURBO)
color_scheme_asym(COLOR_SCHEME, total_energy[i][j]/(double)(time+1), scale, time, rgb);
else color_scheme(COLOR_SCHEME, total_energy[i][j]/(double)(time+1), scale, time, rgb);
break;
}
case (P_LOG_ENERGY):
{
energy = compute_energy(phi, psi, xy_in, i, j);
// energy = LOG_SHIFT + LOG_SCALE*log(energy);
// if (energy < 0.0) energy = 0.0;
color_scheme(COLOR_SCHEME, LOG_SHIFT + LOG_SCALE*log(energy), scale, time, rgb);
break;
}
case (P_LOG_MEAN_ENERGY):
{
energy = compute_energy(phi, psi, xy_in, i, j);
if (energy == 0.0) energy = 1.0e-20;
total_energy[i][j] += energy;
color_scheme(COLOR_SCHEME, LOG_SHIFT + LOG_SCALE*log(total_energy[i][j]/(double)(time+1)), scale, time, rgb);
break;
}
}
glColor3f(rgb[0], rgb[1], rgb[2]);
glVertex2i(i, j);
glVertex2i(i+size, j);
glVertex2i(i+size, j+size);
glVertex2i(i, j+size);
}
}
glEnd ();
}
void draw_wave_ediss(double *phi[NX], double *psi[NX], double *total_energy[NX], double *color_scale[NX], short int *xy_in[NX],
double *gamma[NX], double gammamax, double scale, int time, int plot)
/* draw the field with luminosity depending on damping */
{
int i, j, k, iplus, iminus, jplus, jminus;
double rgb[3], xy[2], x1, y1, x2, y2, velocity, field_value, energy, gradientx2, gradienty2, r2;
static double dtinverse = ((double)NX)/(COURANT*(XMAX-XMIN)), dx = (XMAX-XMIN)/((double)NX);
glBegin(GL_QUADS);
// printf("dtinverse = %.5lg\n", dtinverse);
for (i=0; i<NX; i++)
@ -413,6 +583,8 @@ void draw_wave_e(double *phi[NX], double *psi[NX], double *total_energy[NX], dou
break;
}
}
for (k=0; k<3; k++) rgb[k]*= 1.0 - gamma[i][j]/gammamax;
glColor3f(rgb[0], rgb[1], rgb[2]);
glVertex2i(i, j);
@ -426,10 +598,11 @@ void draw_wave_e(double *phi[NX], double *psi[NX], double *total_energy[NX], dou
}
void draw_wave_highres(int size, double *phi[NX], double *psi[NX], double *total_energy[NX], short int *xy_in[NX], double scale, int time, int plot)
void draw_wave_highres_diss(int size, double *phi[NX], double *psi[NX], double *total_energy[NX], short int *xy_in[NX],
double *gamma[NX], double gammamax, double scale, int time, int plot)
/* draw the field, new version with total energy option */
{
int i, j, iplus, iminus, jplus, jminus;
int i, j, k, iplus, iminus, jplus, jminus;
double rgb[3], xy[2], x1, y1, x2, y2, velocity, energy, gradientx2, gradienty2;
static double dtinverse = ((double)NX)/(COURANT*(XMAX-XMIN)), dx = (XMAX-XMIN)/((double)NX);
@ -476,9 +649,187 @@ void draw_wave_highres(int size, double *phi[NX], double *psi[NX], double *total
case (P_LOG_ENERGY):
{
energy = compute_energy(phi, psi, xy_in, i, j);
// energy = LOG_SHIFT + LOG_SCALE*log(energy);
// if (energy < 0.0) energy = 0.0;
color_scheme(COLOR_SCHEME, LOG_SHIFT + LOG_SCALE*log(energy), scale, time, rgb);
break;
}
case (P_LOG_MEAN_ENERGY):
{
energy = compute_energy(phi, psi, xy_in, i, j);
if (energy == 0.0) energy = 1.0e-20;
total_energy[i][j] += energy;
color_scheme(COLOR_SCHEME, LOG_SHIFT + LOG_SCALE*log(total_energy[i][j]/(double)(time+1)), scale, time, rgb);
break;
}
}
for (k=0; k<3; k++) rgb[k]*= 1.0 - gamma[i][j]/gammamax;
glColor3f(rgb[0], rgb[1], rgb[2]);
glVertex2i(i, j);
glVertex2i(i+size, j);
glVertex2i(i+size, j+size);
glVertex2i(i, j+size);
}
}
glEnd ();
}
void draw_wave_epalette(double *phi[NX], double *psi[NX], double *total_energy[NX], double *color_scale[NX], short int *xy_in[NX],
double scale, int time, int plot, int palette)
/* same as draw_wave_e, but with color scheme specification */
{
int i, j, iplus, iminus, jplus, jminus;
double rgb[3], xy[2], x1, y1, x2, y2, velocity, field_value, energy, gradientx2, gradienty2, r2;
static double dtinverse = ((double)NX)/(COURANT*(XMAX-XMIN)), dx = (XMAX-XMIN)/((double)NX);
glBegin(GL_QUADS);
// printf("dtinverse = %.5lg\n", dtinverse);
for (i=0; i<NX; i++)
for (j=0; j<NY; j++)
{
if ((TWOSPEEDS)||(xy_in[i][j]))
{
switch (plot) {
case (P_AMPLITUDE):
{
/* make wave luminosity larger inside obstacles */
field_value = phi[i][j];
if (RESCALE_COLOR_IN_CENTER)
{
field_value *= color_scale[i][j];
}
// if (!(xy_in[i][j])) color_scheme_lum(COLOR_SCHEME, field_value, scale, time, 0.7, rgb);
// else
color_scheme_palette(COLOR_SCHEME, palette, field_value, scale, time, rgb);
break;
}
case (P_ENERGY):
{
energy = compute_energy(phi, psi, xy_in, i, j);
if (RESCALE_COLOR_IN_CENTER)
{
energy *= color_scale[i][j];
}
/* adjust energy to color palette */
if (COLOR_PALETTE >= COL_TURBO) color_scheme_asym_palette(COLOR_SCHEME, palette, energy, scale, time, rgb);
else color_scheme_palette(COLOR_SCHEME, palette, energy, scale, time, rgb);
break;
}
case (P_MIXED):
{
if (j > NY/2) color_scheme_palette(COLOR_SCHEME, palette, phi[i][j], scale, time, rgb);
else color_scheme_palette(COLOR_SCHEME, palette, compute_energy(phi, psi, xy_in, i, j), scale, time, rgb);
break;
}
case (P_MEAN_ENERGY):
{
energy = compute_energy(phi, psi, xy_in, i, j);
total_energy[i][j] += energy;
if (COLOR_PALETTE >= COL_TURBO)
color_scheme_asym_palette(COLOR_SCHEME, palette, total_energy[i][j]/(double)(time+1), scale, time, rgb);
else color_scheme_palette(COLOR_SCHEME, palette, total_energy[i][j]/(double)(time+1), scale, time, rgb);
break;
}
case (P_LOG_ENERGY):
{
energy = compute_energy(phi, psi, xy_in, i, j);
color_scheme_palette(COLOR_SCHEME, palette, LOG_SHIFT + LOG_SCALE*log(energy), scale, time, rgb);
break;
}
case (P_LOG_MEAN_ENERGY):
{
energy = compute_energy(phi, psi, xy_in, i, j);
if (energy == 0.0) energy = 1.0e-20;
total_energy[i][j] += energy;
energy = LOG_SHIFT + LOG_SCALE*log(total_energy[i][j]/(double)(time+1));
color_scheme_palette(COLOR_SCHEME, palette, energy, scale, time, rgb);
break;
}
}
glColor3f(rgb[0], rgb[1], rgb[2]);
glVertex2i(i, j);
glVertex2i(i+1, j);
glVertex2i(i+1, j+1);
glVertex2i(i, j+1);
}
}
glEnd ();
}
void draw_wave_highres_palette(int size, double *phi[NX], double *psi[NX], double *total_energy[NX], short int *xy_in[NX], double scale, int time, int plot, int palette)
/* same as draw_wave_highres, but with color scheme option */
{
int i, j, iplus, iminus, jplus, jminus;
double rgb[3], xy[2], x1, y1, x2, y2, velocity, energy, gradientx2, gradienty2;
static double dtinverse = ((double)NX)/(COURANT*(XMAX-XMIN)), dx = (XMAX-XMIN)/((double)NX);
glBegin(GL_QUADS);
// printf("dtinverse = %.5lg\n", dtinverse);
for (i=0; i<NX; i+=size)
for (j=0; j<NY; j+=size)
{
if ((TWOSPEEDS)||(xy_in[i][j]))
{
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_palette(COLOR_SCHEME, palette, 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_palette(COLOR_SCHEME, palette, energy, scale, time, rgb);
else color_scheme_palette(COLOR_SCHEME, palette, energy, scale, time, rgb);
break;
}
case (P_MIXED):
{
if (j > NY/2) color_scheme_palette(COLOR_SCHEME, palette, phi[i][j], scale, time, rgb);
else color_scheme_palette(COLOR_SCHEME, palette, compute_energy(phi, psi, xy_in, i, j), scale, time, rgb);
break;
}
case (P_MEAN_ENERGY):
{
energy = compute_energy(phi, psi, xy_in, i, j);
total_energy[i][j] += energy;
if (COLOR_PALETTE >= COL_TURBO)
color_scheme_asym_palette(COLOR_SCHEME, palette, total_energy[i][j]/(double)(time+1), scale, time, rgb);
else color_scheme_palette(COLOR_SCHEME, palette, total_energy[i][j]/(double)(time+1), scale, time, rgb);
break;
}
case (P_LOG_ENERGY):
{
energy = compute_energy(phi, psi, xy_in, i, j);
// energy = LOG_SHIFT + LOG_SCALE*log(energy);
// if (energy < 0.0) energy = 0.0;
color_scheme_palette(COLOR_SCHEME, palette, LOG_SHIFT + LOG_SCALE*log(energy), scale, time, rgb);
break;
}
case (P_LOG_MEAN_ENERGY):
{
energy = compute_energy(phi, psi, xy_in, i, j);
if (energy == 0.0) energy = 1.0e-20;
total_energy[i][j] += energy;
color_scheme_palette(COLOR_SCHEME, palette, LOG_SHIFT + LOG_SCALE*log(total_energy[i][j]/(double)(time+1)), scale, time, rgb);
break;
}
}
glColor3f(rgb[0], rgb[1], rgb[2]);
@ -494,8 +845,3 @@ void draw_wave_highres(int size, double *phi[NX], double *psi[NX], double *total
}

View File

@ -43,29 +43,28 @@
#include <omp.h>
#define MOVIE 0 /* set to 1 to generate movie */
#define DOUBLE_MOVIE 0 /* set to 1 to produce movies for wave height and energy simultaneously */
#define TIME_LAPSE 1 /* set to 1 to add a time-lapse movie at the end */
#define TIME_LAPSE 0 /* set to 1 to add a time-lapse movie at the end */
#define TIME_LAPSE_FACTOR 4 /* factor of time-lapse movie */
/* uncomment for higher resolution version */
// #define WINWIDTH 1920 /* window width */
// #define WINHEIGHT 1000 /* window height */
// #define NX 1920 /* number of grid points on x axis */
// #define NY 1000 /* number of grid points on y axis */
// #define YMID 500 /* mid point of display */
// #define XMIN -2.0
// #define XMAX 2.0 /* x interval */
// #define XMIN -0.5
// #define XMAX 3.5 /* x interval */
// #define YMIN -1.041666667
// #define YMAX 1.041666667 /* y interval for 9/16 aspect ratio */
/* comment out for higher resolution version */
#define WINWIDTH 1280 /* window width */
#define WINHEIGHT 720 /* window height */
#define NX 1280 /* number of grid points on x axis */
#define NY 720 /* number of grid points on y axis */
#define YMID 360 /* mid point of display */
#define XMIN -2.0
#define XMAX 2.0 /* x interval */
#define XMIN -0.5
#define XMAX 3.5 /* x interval */
#define YMIN -1.125
#define YMAX 1.125 /* y interval for 9/16 aspect ratio */
@ -73,8 +72,8 @@
/* Choice of the billiard table */
#define B_DOMAIN 40 /* choice of domain shape, see list in global_pdes.c */
#define B_DOMAIN_B 40 /* choice of domain shape, see list in global_pdes.c */
#define B_DOMAIN 43 /* choice of domain shape, see list in global_pdes.c */
#define B_DOMAIN_B 47 /* choice of domain shape, see list in global_pdes.c */
#define CIRCLE_PATTERN 13 /* pattern of circles, see list in global_pdes.c */
#define CIRCLE_PATTERN_B 13 /* pattern of circles, see list in global_pdes.c */
@ -90,9 +89,9 @@
#define HEX_NONUNIF_COMPRESSSION 0.15 /* compression factor for HEX_NONUNIF pattern */
#define HEX_NONUNIF_COMPRESSSION_B -0.15 /* compression factor for HEX_NONUNIF pattern */
#define LAMBDA 0.8 /* parameter controlling the dimensions of domain */
#define MU 0.035 /* parameter controlling the dimensions of domain */
#define MUB 0.035 /* parameter controlling the dimensions of domain */
#define LAMBDA -1.1 /* parameter controlling the dimensions of domain */
#define MU 0.1 /* parameter controlling the dimensions of domain */
#define MUB 0.1 /* parameter controlling the dimensions of domain */
// #define MU 0.04665361 /* parameter controlling the dimensions of domain */
// #define MUB 0.04665361 /* parameter controlling the dimensions of domain */
#define NPOLY 3 /* number of sides of polygon */
@ -122,19 +121,19 @@
/* Physical parameters of wave equation */
#define TWOSPEEDS 0 /* set to 1 to replace hardcore boundary by medium with different speed */
#define OSCILLATE_LEFT 0 /* set to 1 to add oscilating boundary condition on the left */
#define TWOSPEEDS 1 /* set to 1 to replace hardcore boundary by medium with different speed */
#define OSCILLATE_LEFT 1 /* set to 1 to add oscilating boundary condition on the left */
#define OSCILLATE_TOPBOT 0 /* set to 1 to enforce a planar wave on top and bottom boundary */
#define OMEGA 0.0 /* frequency of periodic excitation */
#define AMPLITUDE 0.025 /* amplitude of periodic excitation */
#define OMEGA 0.004 /* frequency of periodic excitation */
#define AMPLITUDE 1.0 /* amplitude of periodic excitation */
#define COURANT 0.02 /* Courant number */
#define COURANTB 0.004 /* Courant number in medium B */
#define COURANTB 0.01154 /* Courant number in medium B */
// #define COURANTB 0.005 /* Courant number in medium B */
// #define COURANTB 0.008 /* Courant number in medium B */
#define GAMMA 0.0 /* damping factor in wave equation */
// #define GAMMA 1.0e-8 /* damping factor in wave equation */
#define GAMMAB 1.0e-8 /* damping factor in wave equation */
#define GAMMAB 0.0 /* damping factor in wave equation */
// #define GAMMAB 1.0e-6 /* damping factor in wave equation */
// #define GAMMAB 2.0e-4 /* damping factor in wave equation */
// #define GAMMAB 2.5e-4 /* damping factor in wave equation */
@ -150,22 +149,23 @@
/* Boundary conditions, see list in global_pdes.c */
#define B_COND 3
#define B_COND 0
/* Parameters for length and speed of simulation */
#define NSTEPS 3700 /* number of frames of movie */
#define NSTEPS 2500 /* number of frames of movie */
// #define NSTEPS 3300 /* number of frames of movie */
#define NVID 25 /* number of iterations between images displayed on screen */
#define NSEG 100 /* number of segments of boundary */
#define INITIAL_TIME 150 /* time after which to start saving frames */
#define COMPUTE_ENERGIES 1 /* set to 1 to compute and print energies */
#define INITIAL_TIME 20 /* time after which to start saving frames */
#define COMPUTE_ENERGIES 0 /* set to 1 to compute and print energies */
#define BOUNDARY_WIDTH 2 /* width of billiard boundary */
#define PAUSE 100 /* number of frames after which to pause */
#define PSLEEP 1 /* sleep time during pause */
#define SLEEP1 1 /* initial sleeping time */
#define SLEEP2 1 /* final sleeping time */
#define MID_FRAMES 20 /* number of still frames between movies */
#define END_FRAMES 100 /* number of still frames at end of movie */
/* Parameters of initial condition */
@ -178,11 +178,13 @@
/* Plot type, see list in global_pdes.c */
#define PLOT 4
#define PLOT 0
#define PLOT_B 1
/* Color schemes */
#define COLOR_PALETTE 12 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE 18 /* Color palette, see list in global_pdes.c */
#define BLACK 1 /* background */
#define BLACK_TEXT 1 /* set to 1 to write text in black instead of white */
@ -193,7 +195,7 @@
#define SLOPE 1.0 /* sensitivity of color on wave amplitude */
// #define SLOPE 0.75 /* sensitivity of color on wave amplitude */
#define ATTENUATION 0.0 /* exponential attenuation coefficient of contrast with time */
#define E_SCALE 2000.0 /* scaling factor for energy representation */
#define E_SCALE 200.0 /* scaling factor for energy representation */
#define LOG_SCALE 1.5 /* scaling factor for energy log representation */
#define LOG_SHIFT 1.0 /* shift of colors on log scale */
#define RESCALE_COLOR_IN_CENTER 0 /* set to 1 to decrease color intentiy in the center (for wave escaping ring) */
@ -206,8 +208,8 @@
#define HUEAMP -220.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 30.0 /* scale of color scheme bar */
#define COLORBAR_RANGE_B 30.0 /* scale of color scheme bar for 2nd part */
#define COLORBAR_RANGE 1.5 /* scale of color scheme bar */
#define COLORBAR_RANGE_B 2.5 /* scale of color scheme bar for 2nd part */
#define ROTATE_COLOR_SCHEME 0 /* set to 1 to draw color scheme horizontally */
@ -329,6 +331,12 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
phi_out[0][j] = x - tc[0][j]*(x - phi_in[1][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
case (BC_ABS_REFLECT):
{
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;
}
@ -365,6 +373,12 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
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_ABS_REFLECT):
{
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;
}
@ -414,6 +428,15 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
else phi_out[i][jmid-1] = -y + 2*x + tcc[i][jmid-1]*delta - KAPPA*x - tgamma[i][jmid-1]*(x-y);
break;
}
case (BC_ABS_REFLECT):
{
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;
}
}
psi_out[i][jmid-1] = x;
}
@ -463,6 +486,15 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
else phi_out[i][0] = -y + 2*x + tcc[i][0]*delta - KAPPA*x - tgamma[i][0]*(x-y);
break;
}
case (BC_ABS_REFLECT):
{
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;
}
}
psi_out[i][0] = x;
}
@ -512,6 +544,15 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
else phi_out[i][NY-1] = -y + 2*x + tcc[i][NY-1]*delta - KAPPA*x - tgamma[i][NY-1]*(x-y);
break;
}
case (BC_ABS_REFLECT):
{
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;
}
}
psi_out[i][NY-1] = x;
}
@ -529,7 +570,7 @@ 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;
delta = phi_in[iplus][jmid] + phi_in[iminus][jmid] + phi_in[i][1] - 3.0*x;
delta = phi_in[iplus][jmid] + phi_in[iminus][jmid] + phi_in[i][jmid+1] - 3.0*x;
phi_out[i][jmid] = -y + 2*x + tcc[i][jmid]*delta - KAPPA*x - tgamma[i][jmid]*(x-y);
break;
}
@ -561,6 +602,15 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
else phi_out[i][jmid] = -y + 2*x + tcc[i][jmid]*delta - KAPPA*x - tgamma[i][jmid]*(x-y);
break;
}
case (BC_ABS_REFLECT):
{
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] = -y + 2*x + tcc[i][jmid]*delta - KAPPA*x - tgamma[i][jmid]*(x-y);
break;
}
}
psi_out[i][jmid] = x;
}
@ -603,7 +653,7 @@ void evolve_wave(double *phi[NX], double *psi[NX], double *phi_tmp[NX], double *
void draw_color_bar(int plot, double range)
{
if (ROTATE_COLOR_SCHEME) draw_color_scheme(-1.0, -0.8, XMAX - 0.1, -1.0, plot, -range, range);
else draw_color_scheme(1.7, YMIN + 0.1, 1.9, YMAX - 0.1, plot, -range, range);
else draw_color_scheme(XMAX - 0.3, YMIN + 0.1, XMAX - 0.1, YMAX - 0.1, plot, -range, range);
}
@ -613,7 +663,7 @@ void animation()
double time, scale, energies[6], top_energy, bottom_energy;
double *phi[NX], *psi[NX], *phi_tmp[NX], *psi_tmp[NX];
short int *xy_in[NX];
int i, j, s;
int i, j, s, counter = 0;
/* Since NX and NY are big, it seemed wiser to use some memory allocation here */
for (i=0; i<NX; i++)
@ -630,13 +680,18 @@ void animation()
if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN_B == D_CIRCLES)) init_circle_config_comp(circles);
if ((B_DOMAIN == D_POLYGONS)|(B_DOMAIN_B == D_POLYGONS)) init_polygon_config_comp(polygons);
// for (i=0; i<ncircles; i++) printf("polygon %i at (%.3f, %.3f) radius %.3f\n", i, polygons[i].xc, polygons[i].yc, polygons[i].radius);
/* initialise polyline for von Koch and similar domains */
npolyline = init_polyline(MDEPTH, polyline);
for (i=0; i<npolyline; i++) printf("vertex %i: (%.3f, %.3f)\n", i, polyline[i].x, polyline[i].y);
courant2 = COURANT*COURANT;
courantb2 = COURANTB*COURANTB;
/* initialize wave with a drop at one point, zero elsewhere */
// init_wave_flat_comp(phi, psi, xy_in);
int_planar_wave_comp(XMIN + 0.015, 0.0, phi, psi, xy_in);
init_wave_flat_comp(phi, psi, xy_in);
// int_planar_wave_comp(XMIN + 0.015, 0.0, phi, psi, xy_in);
// int_planar_wave_comp(XMIN + 0.5, 0.0, phi, psi, xy_in);
printf("initializing wave\n");
// int_planar_wave_comp(XMIN + 0.1, 0.0, phi, psi, xy_in);
@ -649,21 +704,21 @@ void animation()
// add_drop_to_wave(1.0, -0.7, 0.0, phi, psi);
// add_drop_to_wave(1.0, 0.0, -0.7, phi, psi);
printf("computing energies\n");
/* initialize energies */
if (COMPUTE_ENERGIES)
{
printf("computing energies\n");
compute_energy_tblr(phi, psi, xy_in, energies);
top_energy = energies[0] + energies[1] + energies[2];
bottom_energy = energies[3] + energies[4] + energies[5];
printf("computed energies\n");
}
printf("computed energies\n");
blank();
glColor3f(0.0, 0.0, 0.0);
printf("drawing wave\n");
draw_wave_comp(phi, psi, xy_in, 1.0, 0);
draw_wave_comp(phi, psi, xy_in, 1.0, 0, PLOT);
printf("drawing billiard\n");
draw_billiard_comp();
@ -688,7 +743,7 @@ void animation()
}
else scale = 1.0;
draw_wave_comp(phi, psi, xy_in, scale, i);
draw_wave_comp(phi, psi, xy_in, scale, i, PLOT);
draw_billiard_comp();
@ -722,6 +777,16 @@ void animation()
if ((TIME_LAPSE)&&((i - INITIAL_TIME)%TIME_LAPSE_FACTOR == 0))
{
save_frame_counter(NSTEPS + END_FRAMES + (i - INITIAL_TIME)/TIME_LAPSE_FACTOR);
counter++;
}
else if (DOUBLE_MOVIE)
{
draw_wave_comp(phi, psi, xy_in, scale, i, PLOT_B);
draw_billiard_comp();
if (DRAW_COLOR_SCHEME) draw_color_bar(PLOT_B, COLORBAR_RANGE_B);
glutSwapBuffers();
save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter);
counter++;
}
}
else printf("Initial phase time %i of %i\n", i, INITIAL_TIME);
@ -742,7 +807,23 @@ void animation()
if (MOVIE)
{
for (i=0; i<END_FRAMES; i++) save_frame();
if (DOUBLE_MOVIE)
{
draw_wave_comp(phi, psi, xy_in, scale, i, PLOT);
draw_billiard_comp();
if (DRAW_COLOR_SCHEME) draw_color_bar(PLOT, COLORBAR_RANGE);
glutSwapBuffers();
}
for (i=0; i<MID_FRAMES; i++) save_frame();
if (DOUBLE_MOVIE)
{
draw_wave_comp(phi, psi, xy_in, scale, i, PLOT_B);
draw_billiard_comp();
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);
if (TIME_LAPSE) for (i=0; i<END_FRAMES; i++) save_frame_counter(NSTEPS + END_FRAMES + NSTEPS/TIME_LAPSE_FACTOR + i);
s = system("mv wave*.tif tif_wave/");
}