Add files via upload

This commit is contained in:
nilsberglund-orleans 2021-12-28 15:42:56 +01:00 committed by GitHub
parent 41a06797c1
commit 416366d8da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 2571 additions and 379 deletions

View File

@ -16,10 +16,10 @@
/* It may be possible to increase parameter PAUSE */
/* */
/* create movie using */
/* ffmpeg -i tif_drop/part.%05d.tif -vcodec libx264 drop.mp4 */
/* ffmpeg -i part.%05d.tif -vcodec libx264 drop.mp4 */
/* */
/*********************************************************************************/
#include <math.h>
#include <string.h>
#include <GL/glut.h>
@ -28,16 +28,10 @@
#include <sys/types.h>
#include <tiffio.h> /* Sam Leffler's libtiff library. */
#define MOVIE 1 /* set to 1 to generate movie */
#define MOVIE 0 /* set to 1 to generate movie */
// #define WINWIDTH 1280 /* window width */
// #define WINHEIGHT 720 /* window height */
#define WINWIDTH 1920 /* window width */
#define WINHEIGHT 1080 /* window height */
// #define WINWIDTH 2560 /* window width */
// #define WINHEIGHT 1440 /* window height */
#define WINWIDTH 1280 /* window width */
#define WINHEIGHT 720 /* window height */
#define XMIN -2.0
#define XMAX 2.0 /* x interval */
@ -65,7 +59,7 @@
#define NGOLDENSPIRAL 2000 /* max number of points for C_GOLDEN_SPIRAL arrandement */
#define SDEPTH 1 /* Sierpinski gastket depth */
#define LAMBDA 0.3 /* parameter controlling the dimensions of domain - with 0.5 @1440p it cut out top-bottom borders. 0.4 is @limit */
#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 */
@ -85,7 +79,7 @@
#define NPARTMAX 100000 /* maximal number of particles after resampling */
#define NSTEPS 5000 /* number of frames of movie */
#define TIME 150 /* time between movie frames, for fluidity of real-time simulation */
#define TIME 150 /* time between movie frames, for fluidity of real-time simulation */
#define DPHI 0.0001 /* integration step */
#define NVID 75 /* number of iterations between images displayed on screen */
@ -107,29 +101,31 @@
#define COLOR_PALETTE 1 /* Color palette, see list in global_pdes.c */
#define NCOLORS 14 /* 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 150 /* number of segments of boundary */
#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 COLOR_OUTSIDE 1 /* set to 1 for colored outside */
#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 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 */
#define PSLEEP 1 /* sleep time during pause */
#define SLEEP1 1 /* initial sleeping time */
#define SLEEP2 100 /* final sleeping time */
#define END_FRAMES 0 /* number of frames at end of movie */
#define PI 3.141592654
#define PI 3.141592654
#define DPI 6.283185307
#define PID 1.570796327
#include "global_particles.c"
#include "sub_part_billiard.c"
@ -200,6 +196,8 @@ void init_partial_drop_config(int i1, int i2, double x0, double y0, double angle
}
}
int resample(int color[NPARTMAX], double *configs[NPARTMAX])
/* add particles where the front is stretched too thin */
{
@ -412,7 +410,7 @@ void graph_movie(int time, int color[NPARTMAX], double *configs[NPARTMAX])
{
// print_config(configs[i]);
if (configs[i][2]<0.0)
if (configs[i][2]<0.0)
{
vbilliard(configs[i]);
if (!RAINBOW_COLOR)

122
global_ljones.c Normal file
View File

@ -0,0 +1,122 @@
/* Global variables and parameters for lennardjones */
/* Basic math */
#define PI 3.141592654
#define DPI 6.283185307
#define PID 1.570796327
/* shape of domain */
#define D_CIRCLES 20 /* several circles */
#define D_CIRCLES_IN_RECT 201 /* several circles in a rectangle */
#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 C_SQUARE 0 /* square grid of circles */
#define C_HEX 1 /* hexagonal/triangular grid of circles */
#define C_RAND_DISPLACED 2 /* randomly displaced square grid */
#define C_RAND_PERCOL 3 /* random percolation arrangement */
#define C_RAND_POISSON 4 /* random Poisson point process */
#define C_CLOAK 5 /* invisibility cloak */
#define C_CLOAK_A 6 /* first optimized invisibility cloak */
#define C_LASER 7 /* laser fight in a room of mirrors */
#define C_POISSON_DISC 8 /* Poisson disc sampling */
#define C_GOLDEN_MEAN 10 /* pattern based on vertical shifts by golden mean */
#define C_GOLDEN_SPIRAL 11 /* spiral pattern based on golden mean */
#define C_SQUARE_HEX 12 /* alternating between square and hexagonal/triangular */
#define C_ONE 97 /* one single circle, as for Sinai */
#define C_TWO 98 /* two concentric circles of different type */
#define C_NOTHING 99 /* no circle at all, for comparisons */
/* particle interaction */
#define I_COULOMB 0 /* Coulomb force */
#define I_LENNARD_JONES 1 /* Lennard-Jones force */
#define I_LJ_DIRECTIONAL 2 /* Lennard-Jones with direction dependence */
#define I_LJ_PENTA 3 /* Lennard-Jones with pentagonal symmetry */
#define I_GOLDENRATIO 4 /* Lennard-Jones type with equilibria related by golden ratio */
/* Boundary conditions */
#define BC_SCREEN 0 /* harmonic boundary conditions outside screen area */
#define BC_RECTANGLE 1 /* harmonic boundary conditions on a resizeable rectangle */
#define BC_CIRCLE 2 /* harmonic boundary conditions outside a moving circle */
/* Plot types */
#define P_KINETIC 0 /* colors represent kinetic energy of particles */
#define P_NEIGHBOURS 1 /* colors represent number of neighbours */
#define P_HEALTH 2 /* colors represent health (for SIR model) */
#define P_BONDS 3 /* draw lattice based on neighbours */
/* Color schemes */
#define C_LUM 0 /* color scheme modifies luminosity (with slow drift of hue) */
#define C_HUE 1 /* color scheme modifies hue */
#define C_PHASE 2 /* color scheme shows phase */
#define C_ONEDIM 3 /* use preset 1d color scheme (for Turbo, Viridis, Magma, Inferno, Plasma) */
/* Color palettes */
#define COL_JET 0 /* JET color palette */
#define COL_HSLUV 1 /* HSLUV color palette (perceptually uniform) */
#define COL_TURBO 10 /* TURBO color palette (by Anton Mikhailov) */
#define COL_VIRIDIS 11 /* Viridis color palette */
#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 */
double energy; /* dissipated energy */
double vx; /* x velocity of particle */
double vy; /* y velocity of particle */
double mass_inv; /* inverse of particle mass */
double fx; /* x component of force on particle */
double fy; /* y component of force on particle */
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 */
} t_particle;
typedef struct
{
int number; /* total number of particles in cell */
int particles[HASHMAX]; /* numbers of particles in cell */
} t_hashgrid;
typedef struct
{
double xc, yc, radius; /* center and radius of circle */
short int active; /* circle is active */
double energy; /* dissipated energy */
double vx; /* x velocity of particle */
double vy; /* y velocity of particle */
double mass_inv; /* inverse of particle mass */
double fx; /* x component of force on particle */
double fy; /* y component of force on particle */
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 */
double infected_time; /* time since infected */
int protected; /* 0 = not protected, 1 = protected */
} t_person;
int ncircles, counter = 0;

View File

@ -72,8 +72,11 @@ double x_shooter = -0.2, y_shooter = -0.6, x_target = 0.4, y_target = 0.7;
#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_SIERPINSKI 3 /* sierpinski carpet */
#define P_VONKOCH 4 /* von Koch curve */
#define P_POLYGON 5 /* regular polygon, alternative for D_POLYGON */
#define P_TOKA_PRIME 6 /* Tokarsky room made of 86 triangles */
#define P_TREE 7 /* pine tree */
/* Color palettes */

View File

@ -43,15 +43,16 @@
#define D_PENROSE 33 /* Penrose unilluminable room */
#define D_HYPERBOLA 34 /* one branch of hyperbola */
#define D_TOKARSKY 35 /* Tokarsky unilluminable room */
#define D_TOKA_PRIME 36 /* Tokarsky room made of 86 triangles */
#define D_ISOSPECTRAL 37 /* isospectral billiards */
#define D_HOMOPHONIC 38 /* homophonic billiards */
#define D_POLYGONS 40 /* several polygons */
#define D_VONKOCH 41 /* von Koch snowflake fractal */
#define D_STAR 42 /* star shape */
#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 NMAXPOLY 50000 /* 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 */
@ -68,6 +69,8 @@
#define C_GOLDEN_SPIRAL 11 /* spiral pattern based on golden mean */
#define C_SQUARE_HEX 12 /* alternating between square and hexagonal/triangular */
#define C_RINGS 20 /* obstacles arranged in concentruc rings */
#define C_ONE 97 /* one single circle, as for Sinai */
#define C_TWO 98 /* two concentric circles of different type */
#define C_NOTHING 99 /* no circle at all, for comparisons */
@ -103,6 +106,8 @@
#define P_ENERGY 1 /* plot energy of wave */
#define P_MIXED 2 /* plot amplitude in upper half, energy in lower half */
#define P_MEAN_ENERGY 3 /* energy averaged over time */
#define P_LOG_ENERGY 4 /* log of energy averaged over time */
#define P_LOG_MEAN_ENERGY 5 /* log of energy averaged over time */
/* For Schrodinger equation */
#define P_MODULE 10 /* plot module of wave function squared */
@ -134,14 +139,14 @@
typedef struct
{
double xc, yc, radius; /* center and radius of circle */
short int active; /* circle is active */
short int active, top; /* circle is active, circle is in top half */
} 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 */
short int active, top; /* polygon is active, polygon is in top half */
} t_polygon;
typedef struct

3
heat.c
View File

@ -154,7 +154,8 @@
// #define SLOPE 0.1 /* 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 E_SCALE 100.0 /* scaling factor for energy representation */
#define LOG_SCALE 1.0 /* scaling factor for energy log 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 */

897
lennardjones.c Normal file
View File

@ -0,0 +1,897 @@
/*********************************************************************************/
/* */
/* Animation of interacting particles in a planar domain */
/* */
/* N. Berglund, november 2021 */
/* */
/* UPDATE 24/04: distinction between damping and "elasticity" parameters */
/* UPDATE 27/04: new billiard shapes, bug in color scheme fixed */
/* UPDATE 28/04: code made more efficient, with help of Marco Mancini */
/* */
/* Feel free to reuse, but if doing so it would be nice to drop a */
/* line to nils.berglund@univ-orleans.fr - Thanks! */
/* */
/* compile with */
/* gcc -o lennardjones lennardjones.c */
/* -L/usr/X11R6/lib -ltiff -lm -lGL -lGLU -lX11 -lXmu -lglut -O3 -fopenmp */
/* */
/* OMP acceleration may be more effective after executing */
/* export OMP_NUM_THREADS=2 in the shell before running the program */
/* */
/* To make a video, set MOVIE to 1 and create subfolder tif_ljones */
/* It may be possible to increase parameter PAUSE */
/* */
/* create movie using */
/* ffmpeg -i lj.%05d.tif -vcodec libx264 lj.mp4 */
/* */
/*********************************************************************************/
#include <math.h>
#include <string.h>
#include <GL/glut.h>
#include <GL/glu.h>
#include <unistd.h>
#include <sys/types.h>
#include <tiffio.h> /* Sam Leffler's libtiff library. */
#include <omp.h>
#define MOVIE 1 /* set to 1 to generate movie */
/* General geometrical parameters */
#define WINWIDTH 1280 /* window width */
#define WINHEIGHT 720 /* window height */
#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 INITXMIN -2.0
#define INITXMAX 2.0 /* x interval for initial condition */
#define INITYMIN -1.125
#define INITYMAX 1.125 /* y interval for initial condition */
#define CIRCLE_PATTERN 8 /* pattern of circles, see list in global_ljones.c */
#define INTERACTION 3 /* particle interaction, see list in global_ljones.c */
#define P_PERCOL 0.25 /* probability of having a circle in C_RAND_PERCOL arrangement */
#define NPOISSON 100 /* number of points for Poisson C_RAND_POISSON arrangement */
#define PDISC_DISTANCE 2.5 /* minimal distance in Poisson disc process, controls density of particles */
#define PDISC_CANDIDATES 100 /* number of candidates in construction of Poisson disc process */
#define RANDOM_POLY_ANGLE 0 /* set to 1 to randomize angle of polygons */
#define LAMBDA 2.0 /* parameter controlling the dimensions of domain */
#define MU 0.02 /* parameter controlling radius of particles */
// #define MU 0.015 /* parameter controlling radius of particles */
#define NPOLY 3 /* 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 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 50 /* number of grid point for grid of disks */
#define NGRIDX 32 /* number of grid point for grid of disks */
#define NGRIDY 26 /* 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 */
/* Boundary conditions, see list in global_ljones.c */
#define B_COND 3
/* Parameters for length and speed of simulation */
#define NSTEPS 3600 /* number of frames of movie */
// #define NSTEPS 1300 /* number of frames of movie */
#define NVID 150 /* 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 */
#define PAUSE 1000 /* 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 END_FRAMES 100 /* number of still frames at end of movie */
/* Parameters of initial condition */
/* Plot type, see list in global_ljones.c */
#define PLOT 3
/* Color schemes */
#define COLOR_PALETTE 10 /* Color palette, see list in global_ljones.c */
#define BLACK 1 /* background */
#define COLOR_SCHEME 1 /* choice of color scheme, see list in global_ljones.c */
#define SCALE 0 /* set to 1 to adjust color scheme to variance of field */
#define SLOPE 0.5 /* sensitivity of color on wave amplitude */
#define ATTENUATION 0.0 /* exponential attenuation coefficient of contrast with time */
#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 -50.0 /* amplitude of variation of hue for color scheme C_HUE */
/* particle properties */
#define PARTICLE_HUE_MIN 330.0 /* color of original particle */
#define PARTICLE_HUE_MAX 30.0 /* color of saturated particle */
#define PARTICLE_EMAX 2.0e1 /* max energy for particle to survive */
#define RANDOM_RADIUS 0 /* set to 1 for random circle radius */
#define MOVE_PARTICLES 1 /* set to 1 for mobile particles */
#define INERTIA 1 /* set to 1 for taking inertia into account */
#define DT_PARTICLE 2.0e-6 /* time step for particle displacement */
#define KREPEL 20.0 /* constant in repelling force between particles */
#define EQUILIBRIUM_DIST 5.0 /* Lennard-Jones equilibrium distance */
// #define EQUILIBRIUM_DIST 15.0 /* Lennard-Jones equilibrium distance */
#define REPEL_RADIUS 20.0 /* radius in which repelling force acts (in units of particle radius) */
#define DAMPING 1.5e5 /* damping coefficient of particles */
// #define DAMPING 1.0e-10 /* damping coefficient of particles */
#define PARTICLE_MASS 1.0 /* mass of particle of radius MU */
// #define V_INITIAL 0.0 /* initial velocity range */
#define V_INITIAL 5.0 /* initial velocity range */
#define SIGMA 5.0 /* noise intensity in thermostat */
#define BETA 5.0e-3 /* initial inverse temperature */
#define MU_XI 0.1 /* friction constant in thermostat */
#define KSPRING_BOUNDARY 1.0e5 /* confining harmonic potential outside simulation region */
#define NBH_DIST_FACTOR 4.5 /* radius in which to count neighbours */
#define INCREASE_BETA 1 /* set to 1 to increase BETA during simulation */
#define BETA_FACTOR 5.0e2 /* factor by which to change BETA during simulation */
#define N_TOSCILLATIONS 2.5 /* number of temperature oscillations in BETA schedule */
// #define BETA_FACTOR 2.0e3 /* factor by which to change BETA during simulation */
#define INCREASE_KREPEL 0 /* set to 1 to increase KREPEL during simulation */
#define KREPEL_FACTOR 1000.0 /* factor by which to change KREPEL during simulation */
#define ADD_PARTICLES 0 /* set to 1 to add particles */
#define ADD_TIME 300 /* time at which to add first particle */
#define ADD_PERIOD 2000 /* time interval between adding further particles */
#define FLOOR_FORCE 0 /* set to 1 to limit force on particle to FMAX */
#define FMAX 2.0e10 /* maximal force */
#define HASHX 32 /* size of hashgrid in x direction */
#define HASHY 18 /* size of hashgrid in y direction */
#define HASHMAX 100 /* maximal number of particles per hashgrid cell */
#define HASHGRID_PADDING 0.1 /* padding of hashgrid outside simulation window */
#define DRAW_COLOR_SCHEME 0 /* set to 1 to plot the color scheme */
#define COLORBAR_RANGE 8.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 1 /* set to 1 to limit wave amplitude to VMAX */
#define VMAX 10.0 /* max value of wave amplitude */
#include "global_ljones.c"
#include "sub_lj.c"
double gaussian()
/* returns standard normal random variable, using Box-Mueller algorithm */
{
static double V1, V2, S;
static int phase = 0;
double X;
if (phase == 0)
{
do
{
double U1 = (double)rand() / RAND_MAX;
double U2 = (double)rand() / RAND_MAX;
V1 = 2 * U1 - 1;
V2 = 2 * U2 - 1;
S = V1 * V1 + V2 * V2;
}
while(S >= 1 || S == 0);
X = V1 * sqrt(-2 * log(S) / S);
}
else X = V2 * sqrt(-2 * log(S) / S);
phase = 1 - phase;
return X;
}
/*********************/
/* animation part */
/*********************/
void hash_xy_to_ij(double x, double y, int ij[2])
{
static int first = 1;
static double lx, ly;
int i, j;
if (first)
{
lx = XMAX - XMIN + 2.0*HASHGRID_PADDING;
ly = YMAX - YMIN + 2.0*HASHGRID_PADDING;
first = 0;
}
i = (int)((double)HASHX*(x - XMIN + HASHGRID_PADDING)/lx);
j = (int)((double)HASHY*(y - YMIN + HASHGRID_PADDING)/ly);
if (i<0) i = 0;
if (i>=HASHX) i = HASHX-1;
if (j<0) j = 0;
if (j>=HASHY) j = HASHY-1;
ij[0] = i;
ij[1] = j;
// printf("Mapped (%.3f,%.3f) to (%i, %i)\n", x, y, ij[0], ij[1]);
}
double lennard_jones_force_aniso(double r, double req)
{
int i;
double rmin = 0.01, rplus, ratio = 1.0;
if (r > REPEL_RADIUS*MU) return(0.0);
else
{
if (r > rmin) rplus = r;
else rplus = rmin;
for (i=0; i<6; i++) ratio *= req*MU/rplus;
return((ratio - 2.0*ratio*ratio)/rplus);
}
}
double lennard_jones_force(double r)
{
int i;
double rmin = 0.01, rplus, ratio = 1.0;
if (r > REPEL_RADIUS*MU) return(0.0);
else
{
if (r > rmin) rplus = r;
else rplus = rmin;
// ratio = pow(EQUILIBRIUM_DIST*MU/rplus, 6.0);
for (i=0; i<6; i++) ratio *= EQUILIBRIUM_DIST*MU/rplus;
return((ratio - 2.0*ratio*ratio)/rplus);
}
}
void aniso_lj_force(double r, double ca, double sa, double force[2])
{
int i;
double rmin = 0.01, rplus, ratio = 1.0, c2, s2, c4, s4, a, aprime, f1, f2;
if (r > REPEL_RADIUS*MU)
{
force[0] = 0.0;
force[1] = 0.0;
}
else
{
if (r > rmin) rplus = r;
else rplus = rmin;
for (i=0; i<6; i++) ratio *= EQUILIBRIUM_DIST*MU/rplus;
/* cos(2phi) and sin(2phi) */
c2 = ca*ca - sa*sa;
s2 = 2.0*ca*sa;
/* cos(4phi) and sin(4phi) */
c4 = c2*c2 - s2*s2;
s4 = 2.0*c2*s2;
a = 0.5*(9.0 - 7.0*c4);
aprime = 14.0*s4;
f1 = ratio*(a - ratio)/rplus;
f2 = ratio*aprime/rplus;
force[0] = f1*ca - f2*sa;
force[1] = f1*sa + f2*ca;
}
}
void penta_lj_force(double r, double ca, double sa, double force[2])
{
int i;
double rmin = 0.01, rplus, ratio = 1.0, c2, s2, c4, s4, c5, s5, a, aprime, f1, f2;
static double a0, b0;
static int first = 1;
if (first)
{
a0 = cos(0.1*PI) + 0.5;
b0 = a0 - 1.0;
first = 0;
}
if (r > REPEL_RADIUS*MU)
{
force[0] = 0.0;
force[1] = 0.0;
}
else
{
if (r > rmin) rplus = r;
else rplus = rmin;
for (i=0; i<6; i++) ratio *= EQUILIBRIUM_DIST*MU/rplus;
/* cos(2phi) and sin(2phi) */
c2 = ca*ca - sa*sa;
s2 = 2.0*ca*sa;
/* cos(4phi) and sin(4phi) */
c4 = c2*c2 - s2*s2;
s4 = 2.0*c2*s2;
/* cos(5phi) and sin(5phi) */
c5 = ca*c4 - sa*s4;
s5 = sa*c4 + ca*s4;
a = a0 - b0*c5;
aprime = 5.0*b0*s5;
f1 = ratio*(a - ratio)/rplus;
f2 = ratio*aprime/rplus;
force[0] = f1*ca - f2*sa;
force[1] = f1*sa + f2*ca;
}
}
int compute_repelling_force(int i, int j, double force[2], t_particle* particle, double krepel)
/* compute repelling force of particle j on particle i */
/* returns 1 if distance between particles is smaller than NBH_DIST_FACTOR*MU */
{
double x1, y1, x2, y2, distance, r, f, angle, ca, sa, aniso, fx, fy, ff[2];
x1 = particle[i].xc;
y1 = particle[i].yc;
x2 = particle[j].xc;
y2 = particle[j].yc;
distance = module2(x2 - x1, y2 - y1);
if (distance == 0.0)
{
force[0] = 0.0;
force[1] = 0.0;
return(1);
}
else
{
ca = (x2 - x1)/distance;
sa = (y2 - y1)/distance;
switch (INTERACTION) {
case (I_COULOMB):
{
f = krepel/(1.0e-8 + distance*distance);
force[0] = f*ca;
force[1] = f*sa;
break;
}
case (I_LENNARD_JONES):
{
f = krepel*lennard_jones_force(distance);
force[0] = f*ca;
force[1] = f*sa;
break;
}
case (I_LJ_DIRECTIONAL):
{
aniso_lj_force(distance, ca, sa, ff);
force[0] = krepel*ff[0];
force[1] = krepel*ff[1];
break;
}
case (I_LJ_PENTA):
{
penta_lj_force(distance, ca, sa, ff);
force[0] = krepel*ff[0];
force[1] = krepel*ff[1];
break;
}
}
}
if ((distance < NBH_DIST_FACTOR*MU)&&(j != i)) return(1);
else return(0);
}
void update_hashgrid(t_particle* particle, int* hashgrid_number, int* hashgrid_particles)
{
int i, j, k, n, m, ij[2], max = 0;
// printf("Updating hashgrid_number\n");
for (i=0; i<HASHX*HASHY; i++) hashgrid_number[i] = 0;
// printf("Updated hashgrid_number\n");
/* place each particle in hash grid */
for (k=1; k<ncircles; k++)
// if (circleactive[k])
{
// printf("placing circle %i\t", k);
hash_xy_to_ij(particle[k].xc, particle[k].yc, ij);
i = ij[0]; j = ij[1];
// printf("ij = (%i, %i)\t", i, j);
n = hashgrid_number[i*HASHY + j];
m = i*HASHY*HASHMAX + j*HASHMAX + n;
// printf("n = %i, m = %i\n", n, m);
if (m < HASHX*HASHY*HASHMAX) hashgrid_particles[m] = k;
else printf("Too many particles in hash cell, try increasing HASHMAX\n");
hashgrid_number[i*HASHY + j]++;
particle[k].hashx = i;
particle[k].hashy = j;
if (n > max) max = n;
// printf("Placed particle %i at (%i,%i) in hashgrid\n", k, ij[0], ij[1]);
// printf("%i particles at (%i,%i)\n", hashgrid_number[ij[0]][ij[1]], ij[0], ij[1]);
}
printf("Maximal number of particles per hash cell: %i\n", max);
}
void add_particle(double x, double y, double vx, double vy, t_particle particle[NMAXCIRCLES])
{
int i = ncircles;
particle[i].xc = x;
particle[i].yc = y;
particle[i].radius = MU;
particle[i].active = 1;
particle[i].neighb = 0;
particle[i].energy = 0.0;
if (RANDOM_RADIUS) particle[i].radius = particle[i].radius*(0.75 + 0.5*((double)rand()/RAND_MAX));
particle[i].mass_inv = 1.0;
particle[i].vx = vx;
particle[i].vy = vy;
particle[i].energy = (particle[i].vx*particle[i].vx + particle[i].vy*particle[i].vy)*particle[i].mass_inv;
ncircles++;
}
double neighbour_color(int nnbg)
{
if (nnbg > 7) nnbg = 7;
switch(nnbg){
case (7): return(350.0);
case (6): return(320.0);
case (5): return(260.0);
case (4): return(200.0);
case (3): return(140.0);
case (2): return(100.0);
case (1): return(70.0);
default: return(30.0);
}
}
void draw_particles(t_particle particle[NMAXCIRCLES])
{
int j, k, m, width, nnbg;
double ej, hue, rgb[3], radius, x1, y1, x2, y2, angle;
for (j=0; j<ncircles; j++) if (particle[j].active)
{
glLineWidth(BOUNDARY_WIDTH);
glColor3f(1.0, 1.0, 1.0);
switch (PLOT) {
case (P_KINETIC):
{
ej = particle[j].energy;
if (ej > 0.0)
{
hue = PARTICLE_HUE_MIN + (PARTICLE_HUE_MAX - PARTICLE_HUE_MIN)*ej/PARTICLE_EMAX;
if (hue > PARTICLE_HUE_MIN) hue = PARTICLE_HUE_MIN;
if (hue < PARTICLE_HUE_MAX) hue = PARTICLE_HUE_MAX;
}
radius = particle[j].radius;
width = BOUNDARY_WIDTH;
break;
}
case (P_NEIGHBOURS):
{
hue = neighbour_color(particle[j].neighb);
radius = particle[j].radius;
width = BOUNDARY_WIDTH;
break;
}
case (P_BONDS):
{
glLineWidth(BOUNDARY_WIDTH);
hue = neighbour_color(particle[j].neighb);
radius = 0.015;
// radius = particle[j].radius;
// radius = 0.8*particle[j].radius;
width = 1;
for (k = 0; k < particle[j].neighb; k++)
{
m = particle[j].neighbours[k];
angle = particle[j].nghangle[k];
x1 = particle[j].xc + radius*cos(angle);
y1 = particle[j].yc + radius*sin(angle);
x2 = particle[m].xc - radius*cos(angle);
y2 = particle[m].yc - radius*sin(angle);
draw_line(x1, y1, x2, y2);
// draw_line(particle[j].xc, particle[j].yc, particle[m].xc, particle[m].yc);
}
break;
}
}
hsl_to_rgb(hue, 0.9, 0.5, rgb);
draw_colored_circle(particle[j].xc, particle[j].yc, radius, NSEG, rgb);
glLineWidth(width);
glColor3f(1.0, 1.0, 1.0);
draw_circle(particle[j].xc, particle[j].yc, radius, NSEG);
}
}
double repel_schedule(int i)
{
static double kexponent;
static int first = 1;
double krepel;
if (first)
{
kexponent = log(KREPEL_FACTOR)/(double)(INITIAL_TIME + NSTEPS);
first = 0;
}
krepel = KREPEL*exp(kexponent*(double)i);
printf("krepel = %.3lg\n", krepel);
return(krepel);
}
double temperature_schedule(int i)
{
static double bexponent, omega;
static int first = 1;
double beta;
if (first)
{
bexponent = log(BETA_FACTOR)/(double)(INITIAL_TIME + NSTEPS);
omega = N_TOSCILLATIONS*DPI/(double)(INITIAL_TIME + NSTEPS);
first = 0;
}
beta = BETA*exp(bexponent*(double)i);
beta = beta*2.0/(1.0 + cos(omega*(double)i));
printf("beta = %.3lg\n", beta);
return(beta);
}
void animation()
{
double time, scale, diss, rgb[3], dissip, gradient[2], x, y, dx, dy, dt, xleft, xright, a, b,
length, fx, fy, force[2], totalenergy = 0.0, krepel = KREPEL, pos[2],
beta = BETA, xi = 0.0;
double *qx, *qy, *px, *py;
int i, j, k, n, m, s, ij[2], i0, iplus, iminus, j0, jplus, jminus, p, q, total_neighbours = 0, min_nb, max_nb, close;
static int imin, imax;
static short int first = 1;
t_particle *particle;
int *hashgrid_number, *hashgrid_particles;
t_hashgrid *hashgrid;
char message[100];
particle = (t_particle *)malloc(NMAXCIRCLES*sizeof(t_particle)); /* particles */
hashgrid = (t_hashgrid *)malloc(HASHX*HASHY*sizeof(t_hashgrid)); /* hashgrid */
hashgrid_number = (int *)malloc(HASHX*HASHY*sizeof(int)); /* total number of particles in each hash grid cell */
hashgrid_particles = (int *)malloc(HASHX*HASHY*HASHMAX*sizeof(int)); /* numbers of particles in each hash grid cell */
qx = (double *)malloc(NMAXCIRCLES*sizeof(double));
qy = (double *)malloc(NMAXCIRCLES*sizeof(double));
px = (double *)malloc(NMAXCIRCLES*sizeof(double));
py = (double *)malloc(NMAXCIRCLES*sizeof(double));
/* initialise positions and radii of circles */
init_particle_config(particle);
/* initialise particles */
for (i=0; i < NMAXCIRCLES; i++)
{
particle[i].neighb = 0;
particle[i].energy = 0.0;
y = particle[i].yc;
if (y >= YMAX) y -= particle[i].radius;
if (y <= YMIN) y += particle[i].radius;
if (RANDOM_RADIUS) particle[i].radius = particle[i].radius*(0.75 + 0.5*((double)rand()/RAND_MAX));
particle[i].mass_inv = 1.0;
particle[i].vx = V_INITIAL*gaussian();
particle[i].vy = V_INITIAL*gaussian();
particle[i].energy = (particle[i].vx*particle[i].vx + particle[i].vy*particle[i].vy)*particle[i].mass_inv;
px[i] = particle[i].vx;
py[i] = particle[i].vy;
}
for (i=ncircles; i < NMAXCIRCLES; i++)
{
particle[i].active = 0;
particle[i].neighb = 0;
particle[i].energy = 0.0;
particle[i].mass_inv = 1.0;
particle[i].vx = 0.0;
particle[i].vy = 0.0;
px[i] = 0.0;
py[i] = 0.0;
}
xi = 0.0;
for (i=0; i<ncircles; i++)
{
printf("Particle %i at (%.3f, %.3f) of energy %.3f\n", i, particle[i].xc, particle[i].yc, particle[i].energy);
}
sleep(1);
b = 0.25*SIGMA*SIGMA*DT_PARTICLE/MU_XI;
update_hashgrid(particle, hashgrid_number, hashgrid_particles);
blank();
// glColor3f(0.0, 0.0, 0.0);
glutSwapBuffers();
sleep(SLEEP1);
for (i=0; i<=INITIAL_TIME + NSTEPS; i++)
{
printf("Computing frame %d\n",i);
if (INCREASE_KREPEL) krepel = repel_schedule(i);
if (INCREASE_BETA) beta = temperature_schedule(i);
blank();
for(n=0; n<NVID; n++)
{
/* compute forces on particles */
for (j=0; j<ncircles; j++)
{
particle[j].neighb = 0;
/* compute repelling force from other particles */
/* determine neighboring grid points */
i0 = particle[j].hashx;
iminus = i0 - 1; if (iminus < 0) iminus = 0;
iplus = i0 + 1; if (iplus >= HASHX) iplus = HASHX-1;
j0 = particle[j].hashy;
jminus = j0 - 1; if (jminus < 0) jminus = 0;
jplus = j0 + 1; if (jplus >= HASHY) jplus = HASHY-1;
fx = 0.0;
fy = 0.0;
for (p=iminus; p<= iplus; p++)
for (q=jminus; q<= jplus; q++)
for (k=0; k<hashgrid_number[p*HASHY+q]; k++)
{
m = p*HASHY*HASHMAX + q*HASHMAX + k;
if ((hashgrid_particles[m]!=j)&&(particle[hashgrid_particles[m]].active))
{
close = compute_repelling_force(j, hashgrid_particles[m], force, particle, krepel);
fx += force[0];
fy += force[1];
if ((close)&&(particle[j].neighb < MAXNEIGH))
{
particle[j].neighbours[particle[j].neighb] = hashgrid_particles[m];
x = particle[hashgrid_particles[m]].xc;
y = particle[hashgrid_particles[m]].yc;
particle[j].nghangle[particle[j].neighb] = argument(x - particle[j].xc, y - particle[j].yc);
}
if (close) particle[j].neighb++;
}
}
/* add harmonic force outside rectangle */
if (particle[j].xc > XMAX) fx -= KSPRING_BOUNDARY*(particle[j].xc - XMAX);
else if (particle[j].xc < XMIN) fx += KSPRING_BOUNDARY*(XMIN - particle[j].xc);
if (particle[j].yc > YMAX) fy -= KSPRING_BOUNDARY*(particle[j].yc - YMAX);
else if (particle[j].yc < YMIN) fy += KSPRING_BOUNDARY*(YMIN - particle[j].yc);
if (FLOOR_FORCE)
{
if (fx > FMAX) fx = FMAX;
if (fx < -FMAX) fx = -FMAX;
if (fy > FMAX) fy = FMAX;
if (fy < -FMAX) fy = -FMAX;
}
particle[j].fx = fx;
particle[j].fy = fy;
}
/* timestep of thermostat algorithm */
for (j=0; j<ncircles; j++)
{
particle[j].vx = px[j] + 0.5*DT_PARTICLE*particle[j].fx;
particle[j].vy = py[j] + 0.5*DT_PARTICLE*particle[j].fy;
px[j] = particle[j].vx + 0.5*DT_PARTICLE*particle[j].fx;
py[j] = particle[j].vy + 0.5*DT_PARTICLE*particle[j].fy;
particle[j].energy = (px[j]*px[j] + py[j]*py[j])*particle[j].mass_inv;
qx[j] = particle[j].xc + 0.5*DT_PARTICLE*px[j];
qy[j] = particle[j].yc + 0.5*DT_PARTICLE*py[j];
px[j] *= exp(- 0.5*DT_PARTICLE*xi);
py[j] *= exp(- 0.5*DT_PARTICLE*xi);
}
/* compute kinetic energy */
totalenergy = 0.0;
for (j=0; j<ncircles; j++) totalenergy += particle[j].energy;
a = DT_PARTICLE*(totalenergy - (double)ncircles/beta)/MU_XI;
a += SIGMA*sqrt(DT_PARTICLE)*gaussian();
xi = (xi + a - b*xi)/(1.0 + b);
for (j=0; j<ncircles; j++)
{
px[j] *= exp(- 0.5*DT_PARTICLE*xi);
py[j] *= exp(- 0.5*DT_PARTICLE*xi);
particle[j].xc = qx[j] + 0.5*DT_PARTICLE*px[j];
particle[j].yc = qy[j] + 0.5*DT_PARTICLE*py[j];
}
}
printf("Mean kinetic energy: %.3f\n", totalenergy/(double)ncircles);
total_neighbours = 0;
min_nb = 100;
max_nb = 0;
for (j=0; j<ncircles; j++) if (particle[j].active)
{
total_neighbours += particle[j].neighb;
if (particle[j].neighb > max_nb) max_nb = particle[j].neighb;
if (particle[j].neighb < min_nb) min_nb = particle[j].neighb;
}
printf("Mean number of neighbours: %.3f\n", (double)total_neighbours/(double)ncircles);
printf("Min number of neighbours: %i\n", min_nb);
printf("Max number of neighbours: %i\n", max_nb);
draw_particles(particle);
/* add a particle */
if ((ADD_PARTICLES)&&((i - ADD_TIME + 1)%ADD_PERIOD == 0))
{
j = 0;
while (module2(particle[j].xc,particle[j].yc) > 0.7) j = rand()%ncircles;
x = particle[j].xc + 2.5*MU;
y = particle[j].yc;
add_particle(x, y, 0.0, 0.0, particle);
}
update_hashgrid(particle, hashgrid_number, hashgrid_particles);
if (INCREASE_BETA) /* print force constant */
{
erase_area_hsl(XMAX - 0.39, YMAX - 0.1 + 0.025, 0.37, 0.05, 0.0, 0.9, 0.0);
glColor3f(1.0, 1.0, 1.0);
sprintf(message, "Temperature %.3f", 1.0/beta);
write_text(XMAX - 0.7, YMAX - 0.1, message);
}
else if (INCREASE_KREPEL) /* print force constant */
{
erase_area_hsl(XMAX - 0.24, YMAX - 0.1 + 0.025, 0.22, 0.05, 0.0, 0.9, 0.0);
glColor3f(1.0, 1.0, 1.0);
sprintf(message, "Force %.0f", krepel);
write_text(XMAX - 0.42, YMAX - 0.1, message);
}
glutSwapBuffers();
if (MOVIE)
{
if (i >= INITIAL_TIME) save_frame_lj();
else printf("Initial phase time %i of %i\n", i, INITIAL_TIME);
/* it seems that saving too many files too fast can cause trouble with the file system */
/* so this is to make a pause from time to time - parameter PAUSE may need adjusting */
if (i % PAUSE == PAUSE - 1)
{
printf("Making a short pause\n");
sleep(PSLEEP);
s = system("mv lj*.tif tif_ljones/");
}
}
}
if (MOVIE)
{
for (i=0; i<END_FRAMES; i++) save_frame_lj();
s = system("mv lj*.tif tif_ljones/");
}
free(particle);
free(hashgrid);
free(hashgrid_number);
free(hashgrid_particles);
free(qx);
free(qy);
free(px);
free(py);
}
void display(void)
{
glPushMatrix();
blank();
glutSwapBuffers();
blank();
glutSwapBuffers();
animation();
sleep(SLEEP2);
glPopMatrix();
glutDestroyWindow(glutGetWindow());
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(WINWIDTH,WINHEIGHT);
glutCreateWindow("Particles with Lennard-Jones interaction in a planar domain");
init();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}

View File

@ -175,6 +175,7 @@
#define SLOPE 1.0 /* sensitivity of color on wave amplitude */
#define ATTENUATION 0.0 /* exponential attenuation coefficient of contrast with time */
#define E_SCALE 2500.0 /* scaling factor for energy representation */
#define LOG_SCALE 1.0 /* scaling factor for energy log representation */
#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 */

View File

@ -32,11 +32,8 @@
#define MOVIE 1 /* set to 1 to generate movie */
// #define WINWIDTH 1280 /* window width */
// #define WINHEIGHT 720 /* window height */
#define WINWIDTH 1920 /* window width */
#define WINHEIGHT 1080 /* window height */
#define WINWIDTH 1280 /* window width */
#define WINHEIGHT 720 /* window height */
#define XMIN -2.0
#define XMAX 2.0 /* x interval */
@ -50,7 +47,7 @@
#define B_DOMAIN 30 /* choice of domain shape */
#define CIRCLE_PATTERN 1 /* pattern of circles */
#define POLYLINE_PATTERN 1 /* pattern of polyline */
#define POLYLINE_PATTERN 6 /* pattern of polyline */
#define ABSORBING_CIRCLES 1 /* set to 1 for circular scatterers to be absorbing */
@ -64,10 +61,8 @@
#define NGOLDENSPIRAL 2000 /* max number of points for C_GOLDEN_SPIRAL arrandement */
#define SDEPTH 1 /* Sierpinski gastket depth */
#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 LAMBDA 0.8 /* parameter controlling shape of domain */
#define MU 0.0025 /* second parameter controlling shape of billiard */
#define FOCI 1 /* set to 1 to draw focal points of ellipse */
#define NPOLY 6 /* number of sides of polygon */
#define APOLY 0.0 /* angle by which to turn polygon, in units of Pi/2 */
@ -80,21 +75,21 @@
/* Simulation parameters */
#define NPART 5000 /* number of particles */
#define NPART 1 /* 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 0 /* set to 1 to keep trails of the particles */
#define SHOWTRAILS 1 /* 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 PRINT_COLLISION_NUMBER 1 /* set to 1 to print number of collisions */
#define TEST_ACTIVE 1 /* set to 1 to test whether particle is in billiard */
#define NSTEPS 5000 /* number of frames of movie */
#define TIME 400 /* time between movie frames, for fluidity of real-time simulation */
// #define DPHI 0.00001 /* integration step */
#define DPHI 0.00005 /* integration step */
#define NVID 150 /* number of iterations between images displayed on screen */
#define NSTEPS 9000 /* 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 NVID 300 /* number of iterations between images displayed on screen */
/* Decreasing TIME accelerates the animation and the movie */
/* For constant speed of movie, TIME*DPHI should be kept constant */
@ -104,23 +99,23 @@
/* Colors and other graphical parameters */
#define COLOR_PALETTE 10 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE 16 /* Color palette, see list in global_pdes.c */
#define NCOLORS 16 /* number of colors */
#define NCOLORS 32 /* 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 RAINBOW_COLOR 0 /* 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.025 /* length of velocity vectors */
#define BILLIARD_WIDTH 3 /* width of billiard */
#define PARTICLE_WIDTH 2 /* width of particles */
#define LENGTH 0.015 /* length of velocity vectors */
#define BILLIARD_WIDTH 2 /* width of billiard */
#define PARTICLE_WIDTH 3 /* width of particles */
#define FRONT_WIDTH 3 /* width of wave front */
#define BLACK 1 /* set to 1 for black background */
#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 0 /* set to 1 to paint exterior */
#define PAINT_EXT 1 /* set to 1 to paint exterior */
#define PAUSE 1000 /* number of frames after which to pause */
#define PSLEEP 1 /* sleep time during pause */
@ -131,6 +126,7 @@
#include "global_particles.c"
#include "sub_part_billiard.c"
int ncollisions = 0;
/*********************/
/* animation part */
@ -253,11 +249,17 @@ 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)
void draw_zoom(int color[NPARTMAX], double *configs[NPARTMAX], int active[NPARTMAX],
double x_target, double y_target, double width, double shiftx, double shifty, double zoomwidth, int shooter)
/* 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;
double x1, y1, x2, y2, xb, yb, cosphi, sinphi, rgb[3], tradius, phi;
// double x1, y1, x2, y2, xb, yb, cosphi, sinphi, rgb[3], shiftx = 0.0, shifty = 0.65, tradius, phi, zoomwidth = 0.4;
// shiftx = 1.65;
// shifty = 0.75;
// zoomwidth = 0.3;
glEnable(GL_LINE_SMOOTH);
glColor3f(1.0, 1.0, 1.0);
@ -308,17 +310,10 @@ void draw_zoom(int color[NPARTMAX], double *configs[NPARTMAX], int active[NPARTM
/* draw target in zoom */
glLineWidth(BILLIARD_WIDTH*2);
glColor3f(0.0, 0.8, 0.2);
glBegin(GL_LINE_LOOP);
if (shooter) glColor3f(1.0, 0.0, 0.0);
else glColor3f(0.0, 0.8, 0.2);
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 ();
draw_circle(shiftx, shifty, tradius, NSEG);
// glLineWidth(PARTICLE_WIDTH*2);
@ -442,7 +437,12 @@ 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);
if (SHOWZOOM)
{
draw_zoom(color, configs, active, x_target, y_target, 0.1, 1.65, 0.75, 0.3, 0);
draw_zoom(color, configs, active, x_shooter, y_shooter, 0.1, -1.65, 0.75, 0.3, 1);
}
// if (SHOWZOOM) draw_zoom(color, configs, active, 0.95, 0.0, 0.1);
}
@ -547,7 +547,12 @@ void draw_config(int color[NPARTMAX], double *configs[NPARTMAX], int active[NPAR
}
if (DRAW_BILLIARD) draw_billiard();
if (SHOWZOOM) draw_zoom(color, configs, active, 0.95, 0.0, 0.1);
if (SHOWZOOM)
{
draw_zoom(color, configs, active, x_target, y_target, 0.1, 1.65, 0.75, 0.3, 0);
draw_zoom(color, configs, active, x_shooter, y_shooter, 0.1, -1.65, 0.75, 0.3, 1);
}
// if (SHOWZOOM) draw_zoom(color, configs, active, 0.95, 0.0, 0.1);
}
@ -564,7 +569,9 @@ 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;
else ncollisions++;
// if (c>=0) color[i]++;
if ((!RAINBOW_COLOR)&&(c>=0)) color[i]++;
if (!RAINBOW_COLOR)
@ -606,13 +613,25 @@ void print_part_number(double *configs[NPARTMAX], int active[NPARTMAX], double x
}
void print_collision_number(int ncollisions, double x, double y)
{
char message[50];
double rgb[3];
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 collisions", ncollisions);
write_text(x, y, message);
}
void animation()
{
double time, dt, alpha, r, rgb[3];
double time, dt, alpha, r, rgb[3], alphamax;
double *configs[NPARTMAX];
int i, j, resamp = 1, s, i1, i2;
int i, j, resamp = 1, s, i1, i2, c, lengthmax;
int *color, *newcolor, *active;
// t_circle *circles; /* experimental */
@ -630,7 +649,15 @@ void animation()
||(B_DOMAIN == D_CIRCLES_IN_TORUS)) init_circles(circles);
else if (B_DOMAIN == D_POLYLINE) init_polyline(polyline, circles);
if (POLYLINE_PATTERN == P_TOKA_PRIME)
{
x_shooter = -polyline[84].x1;
y_shooter = polyline[84].y1;
x_target = polyline[84].x1;
y_target = polyline[84].y1;
}
/* initialize system by putting particles in a given point with a range of velocities */
r = cos(PI/(double)NPOLY)/cos(DPI/(double)NPOLY);
@ -642,8 +669,35 @@ void animation()
// 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.0, 0.0, -PI, PI, configs);
init_drop_config(-0.95, 0.0, PI, 3.0*PI, configs);
// init_drop_config(-0.95, 0.0, -0.103 + DPI/15.0, -0.1 + DPI/15.0, configs);
/* find long trajectory */
// alphamax = 0.0;
// lengthmax = 1;
// for (alpha = 0.0; alpha < DPI; alpha += 0.00001)
// {
// init_drop_config(x_shooter, y_shooter, alpha, alpha + DPI, configs);
// i = 0;
// c = 1;
// while ((c >= 0)&&(i<=1000))
// {
// c = vbilliard(configs[0]);
// i++;
// }
// if (i > 100) printf("Angle %.6lg, length %i\n", alpha, i);
// if (i > lengthmax)
// {
// lengthmax = i;
// alphamax = alpha;
// }
// }
// printf("Angle %.6lg, max length %i\n", alphamax, lengthmax);
alphamax = 2.50949;
init_drop_config(x_shooter, y_shooter, alphamax, alphamax + DPI, configs);
// init_drop_config(-0.95, 0.0, 1.0, 1.0 + DPI, 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(0.5, 0.5, -1.0, 1.0, configs);
@ -663,7 +717,8 @@ void animation()
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);
else if (PRINT_COLLISION_NUMBER) print_collision_number(ncollisions, XMIN + 0.1, YMIN + 0.1);
glutSwapBuffers();
@ -716,6 +771,8 @@ void animation()
// 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);
else if (PRINT_COLLISION_NUMBER) print_collision_number(ncollisions, XMIN + 0.1, YMIN + 0.1);
for (j=0; j<NPARTMAX; j++) color[j] = newcolor[j];
/* draw initial points */

View File

@ -141,6 +141,7 @@
#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 LOG_SCALE 1.0 /* scaling factor for energy log 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 */

666
sub_lj.c Normal file
View File

@ -0,0 +1,666 @@
/*********************/
/* Graphics routines */
/*********************/
#include "colors_waves.c"
int writetiff(char *filename, char *description, int x, int y, int width, int height, int compression)
{
TIFF *file;
GLubyte *image, *p;
int i;
file = TIFFOpen(filename, "w");
if (file == NULL)
{
return 1;
}
image = (GLubyte *) malloc(width * height * sizeof(GLubyte) * 3);
/* OpenGL's default 4 byte pack alignment would leave extra bytes at the
end of each image row so that each full row contained a number of bytes
divisible by 4. Ie, an RGB row with 3 pixels and 8-bit componets would
be laid out like "RGBRGBRGBxxx" where the last three "xxx" bytes exist
just to pad the row out to 12 bytes (12 is divisible by 4). To make sure
the rows are packed as tight as possible (no row padding), set the pack
alignment to 1. */
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, image);
TIFFSetField(file, TIFFTAG_IMAGEWIDTH, (uint32) width);
TIFFSetField(file, TIFFTAG_IMAGELENGTH, (uint32) height);
TIFFSetField(file, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(file, TIFFTAG_COMPRESSION, compression);
TIFFSetField(file, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
TIFFSetField(file, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
TIFFSetField(file, TIFFTAG_SAMPLESPERPIXEL, 3);
TIFFSetField(file, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(file, TIFFTAG_ROWSPERSTRIP, 1);
TIFFSetField(file, TIFFTAG_IMAGEDESCRIPTION, description);
p = image;
for (i = height - 1; i >= 0; i--)
{
// if (TIFFWriteScanline(file, p, height - i - 1, 0) < 0)
if (TIFFWriteScanline(file, p, i, 0) < 0)
{
free(image);
TIFFClose(file);
return 1;
}
p += width * sizeof(GLubyte) * 3;
}
TIFFClose(file);
return 0;
}
void init() /* initialisation of window */
{
glLineWidth(3);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glOrtho(XMIN, XMAX, YMIN, YMAX , -1.0, 1.0);
// glOrtho(0.0, NX, 0.0, NY, -1.0, 1.0);
}
void blank()
{
if (BLACK) glClearColor(0.0, 0.0, 0.0, 1.0);
else glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
}
void save_frame_lj()
{
static int counter = 0;
char *name="lj.", n2[100];
char format[6]=".%05i";
counter++;
// printf (" p2 counter = %d \n",counter);
strcpy(n2, name);
sprintf(strstr(n2,"."), format, counter);
strcat(n2, ".tif");
printf(" saving frame %s \n",n2);
writetiff(n2, "Particles with Lennard-Jones interaction in a planar domain", 0, 0,
WINWIDTH, WINHEIGHT, COMPRESSION_LZW);
}
void save_frame_lj_counter(int counter)
{
char *name="lj.", n2[100];
char format[6]=".%05i";
strcpy(n2, name);
sprintf(strstr(n2,"."), format, counter);
strcat(n2, ".tif");
printf(" saving frame %s \n",n2);
writetiff(n2, "Particles with Lennard-Jones interaction in a planar domain", 0, 0,
WINWIDTH, WINHEIGHT, COMPRESSION_LZW);
}
void write_text_fixedwidth( double x, double y, char *st)
{
int l, i;
l=strlen( st ); // see how many characters are in text string.
glRasterPos2d( x, y); // location to start printing text
for( i=0; i < l; i++) // loop until i is greater then l
{
// glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, st[i]); // Print a character on the screen
// glutBitmapCharacter(GLUT_BITMAP_8_BY_13, st[i]); // Print a character on the screen
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, st[i]); // Print a character on the screen
}
}
void write_text( double x, double y, char *st)
{
int l,i;
l=strlen( st ); // see how many characters are in text string.
glRasterPos2d( x, y); // location to start printing text
for( i=0; i < l; i++) // loop until i is greater then l
{
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, st[i]); // Print a character on the screen
// glutBitmapCharacter(GLUT_BITMAP_8_BY_13, st[i]); // Print a character on the screen
}
}
/*********************/
/* some basic math */
/*********************/
double vabs(double x) /* absolute value */
{
double res;
if (x<0.0) res = -x;
else res = x;
return(res);
}
double module2(double x, double y) /* Euclidean norm */
{
double m;
m = sqrt(x*x + y*y);
return(m);
}
double argument(double x, double y)
{
double alph;
if (x!=0.0)
{
alph = atan(y/x);
if (x<0.0)
alph += PI;
}
else
{
alph = PID;
if (y<0.0)
alph = PI*1.5;
}
return(alph);
}
/*********************/
/* drawing routines */
/*********************/
void erase_area(double x, double y, double dx, double dy)
{
double pos[2], rgb[3];
hsl_to_rgb(220.0, 0.8, 0.7, rgb);
glColor3f(rgb[0], rgb[1], rgb[2]);
glBegin(GL_QUADS);
glVertex2d(x - dx, y - dy);
glVertex2d(x + dx, y - dy);
glVertex2d(x + dx, y + dy);
glVertex2d(x - dx, y + dy);
glEnd();
}
void erase_area_rgb(double x, double y, double dx, double dy, double rgb[3])
{
double pos[2];
glColor3f(rgb[0], rgb[1], rgb[2]);
glBegin(GL_QUADS);
glVertex2d(x - dx, y - dy);
glVertex2d(x + dx, y - dy);
glVertex2d(x + dx, y + dy);
glVertex2d(x - dx, y + dy);
glEnd();
}
void erase_area_hsl(double x, double y, double dx, double dy, double h, double s, double l)
{
double pos[2], rgb[3];
hsl_to_rgb(h, s, l, rgb);
erase_area_rgb(x, y, dx, dy, rgb);
}
void draw_line(double x1, double y1, double x2, double y2)
{
glBegin(GL_LINE_STRIP);
glVertex2d(x1, y1);
glVertex2d(x2, y2);
glEnd();
}
void draw_rectangle(double x1, double y1, double x2, double y2)
{
glBegin(GL_LINE_LOOP);
glVertex2d(x1, y1);
glVertex2d(x2, y1);
glVertex2d(x2, y2);
glVertex2d(x1, y2);
glEnd();
}
void draw_colored_triangle(double x1, double y1, double x2, double y2, double x3, double y3, double rgb[3])
{
glColor3f(rgb[0], rgb[1], rgb[2]);
glBegin(GL_TRIANGLE_FAN);
glVertex2d(x1, y1);
glVertex2d(x2, y2);
glVertex2d(x3, y3);
glEnd();
}
void draw_circle(double x, double y, double r, int nseg)
{
int i;
double pos[2], alpha, dalpha;
dalpha = DPI/(double)nseg;
glBegin(GL_LINE_LOOP);
for (i=0; i<=nseg; i++)
{
alpha = (double)i*dalpha;
glVertex2d(x + r*cos(alpha), y + r*sin(alpha));
}
glEnd();
}
void draw_colored_circle(double x, double y, double r, int nseg, double rgb[3])
{
int i;
double pos[2], alpha, dalpha;
dalpha = DPI/(double)nseg;
glColor3f(rgb[0], rgb[1], rgb[2]);
glBegin(GL_TRIANGLE_FAN);
glVertex2d(x, y);
for (i=0; i<=nseg; i++)
{
alpha = (double)i*dalpha;
glVertex2d(x + r*cos(alpha), y + r*sin(alpha));
}
glEnd();
}
void init_particle_config(t_particle particles[NMAXCIRCLES])
/* initialise particle configuration */
{
int i, j, k, n, ncirc0, n_p_active, ncandidates = PDISC_CANDIDATES, naccepted;
double dx, dy, p, phi, r, r0, ra[5], sa[5], height, x, y = 0.0, gamma, dpoisson = PDISC_DISTANCE*MU, xx[4], yy[4];
short int active_poisson[NMAXCIRCLES], far;
switch (CIRCLE_PATTERN) {
case (C_SQUARE):
{
ncircles = NGRIDX*NGRIDY;
dy = (YMAX - YMIN)/((double)NGRIDY);
for (i = 0; i < NGRIDX; i++)
for (j = 0; j < NGRIDY; j++)
{
n = NGRIDY*i + j;
particles[n].xc = ((double)(i-NGRIDX/2) + 0.5)*dy;
particles[n].yc = YMIN + ((double)j + 0.5)*dy;
particles[n].radius = MU;
particles[n].active = 1;
}
break;
}
case (C_HEX):
{
ncircles = NGRIDX*(NGRIDY+1);
dx = (INITXMAX - INITXMIN)/((double)NGRIDX);
dy = (INITYMAX - INITYMIN)/((double)NGRIDY);
// dx = dy*0.5*sqrt(3.0);
for (i = 0; i < NGRIDX; i++)
for (j = 0; j < NGRIDY+1; j++)
{
n = (NGRIDY+1)*i + j;
particles[n].xc = ((double)(i-NGRIDX/2) + 0.5)*dx; /* is +0.5 needed? */
particles[n].yc = INITYMIN + ((double)j - 0.5)*dy;
if ((i+NGRIDX)%2 == 1) particles[n].yc += 0.5*dy;
particles[n].radius = MU;
/* activate only circles that intersect the domain */
if ((particles[n].yc < INITYMAX + MU)&&(particles[n].yc > INITYMIN - MU)) particles[n].active = 1;
else particles[n].active = 0;
}
break;
}
case (C_RAND_DISPLACED):
{
ncircles = NGRIDX*NGRIDY;
dy = (YMAX - YMIN)/((double)NGRIDY);
for (i = 0; i < NGRIDX; i++)
for (j = 0; j < NGRIDY; j++)
{
n = NGRIDY*i + j;
particles[n].xc = ((double)(i-NGRIDX/2) + 0.5*((double)rand()/RAND_MAX - 0.5))*dy;
particles[n].yc = YMIN + ((double)j + 0.5 + 0.5*((double)rand()/RAND_MAX - 0.5))*dy;
particles[n].radius = MU;
// particles[n].radius = MU*sqrt(1.0 + 0.8*((double)rand()/RAND_MAX - 0.5));
particles[n].active = 1;
}
break;
}
case (C_RAND_PERCOL):
{
ncircles = NGRIDX*NGRIDY;
dy = (YMAX - YMIN)/((double)NGRIDY);
for (i = 0; i < NGRIDX; i++)
for (j = 0; j < NGRIDY; j++)
{
n = NGRIDY*i + j;
particles[n].xc = ((double)(i-NGRIDX/2) + 0.5)*dy;
particles[n].yc = YMIN + ((double)j + 0.5)*dy;
particles[n].radius = MU;
p = (double)rand()/RAND_MAX;
if (p < P_PERCOL) particles[n].active = 1;
else particles[n].active = 0;
}
break;
}
case (C_RAND_POISSON):
{
ncircles = NPOISSON;
for (n = 0; n < NPOISSON; n++)
{
// particles[n].xc = LAMBDA*(2.0*(double)rand()/RAND_MAX - 1.0);
particles[n].xc = (XMAX - XMIN)*(double)rand()/RAND_MAX + XMIN;
particles[n].yc = (YMAX - YMIN)*(double)rand()/RAND_MAX + YMIN;
particles[n].radius = MU;
particles[n].active = 1;
}
break;
}
case (C_CLOAK):
{
ncircles = 200;
for (i = 0; i < 40; i++)
for (j = 0; j < 5; j++)
{
n = 5*i + j;
phi = (double)i*DPI/40.0;
r = LAMBDA*0.5*(1.0 + (double)j/5.0);
particles[n].xc = r*cos(phi);
particles[n].yc = r*sin(phi);
particles[n].radius = MU;
particles[n].active = 1;
}
break;
}
case (C_CLOAK_A): /* optimized model A1 by C. Jo et al */
{
ncircles = 200;
ra[0] = 0.0731; sa[0] = 1.115;
ra[1] = 0.0768; sa[1] = 1.292;
ra[2] = 0.0652; sa[2] = 1.464;
ra[3] = 0.056; sa[3] = 1.633;
ra[4] = 0.0375; sa[4] = 1.794;
for (i = 0; i < 40; i++)
for (j = 0; j < 5; j++)
{
n = 5*i + j;
phi = (double)i*DPI/40.0;
r = LAMBDA*sa[j];
particles[n].xc = r*cos(phi);
particles[n].yc = r*sin(phi);
particles[n].radius = LAMBDA*ra[j];
particles[n].active = 1;
}
break;
}
case (C_LASER):
{
ncircles = 17;
xx[0] = 0.5*(X_SHOOTER + X_TARGET);
xx[1] = LAMBDA - 0.5*(X_TARGET - X_SHOOTER);
xx[2] = -xx[0];
xx[3] = -xx[1];
yy[0] = 0.5*(Y_SHOOTER + Y_TARGET);
yy[1] = 1.0 - 0.5*(Y_TARGET - Y_SHOOTER);
yy[2] = -yy[0];
yy[3] = -yy[1];
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
{
particles[4*i + j].xc = xx[i];
particles[4*i + j].yc = yy[j];
}
particles[ncircles - 1].xc = X_TARGET;
particles[ncircles - 1].yc = Y_TARGET;
for (i=0; i<ncircles - 1; i++)
{
particles[i].radius = MU;
particles[i].active = 1;
}
particles[ncircles - 1].radius = 0.5*MU;
particles[ncircles - 1].active = 2;
break;
}
case (C_POISSON_DISC):
{
printf("Generating Poisson disc sample\n");
/* generate first circle */
// particles[0].xc = LAMBDA*(2.0*(double)rand()/RAND_MAX - 1.0);
particles[0].xc = (INITXMAX - INITXMIN)*(double)rand()/RAND_MAX + INITXMIN;
particles[0].yc = (INITYMAX - INITYMIN)*(double)rand()/RAND_MAX + INITYMIN;
active_poisson[0] = 1;
// particles[0].active = 1;
n_p_active = 1;
ncircles = 1;
while ((n_p_active > 0)&&(ncircles < NMAXCIRCLES))
{
/* randomly select an active circle */
i = rand()%(ncircles);
while (!active_poisson[i]) i = rand()%(ncircles);
// printf("Starting from circle %i at (%.3f,%.3f)\n", i, particles[i].xc, particles[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 = particles[i].xc + r*cos(phi);
y = particles[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))
{
/* new circle is far away from circle k */
far = far*((x - particles[k].xc)*(x - particles[k].xc) + (y - particles[k].yc)*(y - particles[k].yc) >= dpoisson*dpoisson);
/* new circle is in domain */
far = far*(x < INITXMAX)*(x > INITXMIN)*(y < INITYMAX)*(y > INITYMIN);
// far = far*(vabs(x) < LAMBDA)*(y < INITYMAX)*(y > INITYMIN);
}
if (far) /* accept new circle */
{
printf("New circle at (%.3f,%.3f) accepted\n", x, y);
particles[ncircles].xc = x;
particles[ncircles].yc = y;
particles[ncircles].radius = MU;
particles[ncircles].active = 1;
active_poisson[ncircles] = 1;
ncircles++;
n_p_active++;
naccepted++;
}
// else printf("Rejected\n");
}
if (naccepted == 0) /* inactivate circle i */
{
// printf("No candidates work, inactivate circle %i\n", i);
active_poisson[i] = 0;
n_p_active--;
}
printf("%i active circles\n", n_p_active);
}
printf("Generated %i circles\n", ncircles);
break;
}
case (C_GOLDEN_MEAN):
{
ncircles = 300;
gamma = (sqrt(5.0) - 1.0)*0.5; /* golden mean */
height = YMAX - YMIN;
dx = 2.0*LAMBDA/((double)ncircles);
for (n = 0; n < ncircles; n++)
{
particles[n].xc = -LAMBDA + n*dx;
particles[n].yc = y;
y += height*gamma;
if (y > YMAX) y -= height;
particles[n].radius = MU;
particles[n].active = 1;
}
/* test for circles that overlap top or bottom boundary */
ncirc0 = ncircles;
for (n=0; n < ncirc0; n++)
{
if (particles[n].yc + particles[n].radius > YMAX)
{
particles[ncircles].xc = particles[n].xc;
particles[ncircles].yc = particles[n].yc - height;
particles[ncircles].radius = MU;
particles[ncircles].active = 1;
ncircles ++;
}
else if (particles[n].yc - particles[n].radius < YMIN)
{
particles[ncircles].xc = particles[n].xc;
particles[ncircles].yc = particles[n].yc + height;
particles[ncircles].radius = MU;
particles[ncircles].active = 1;
ncircles ++;
}
}
break;
}
case (C_GOLDEN_SPIRAL):
{
ncircles = 1;
particles[0].xc = 0.0;
particles[0].yc = 0.0;
gamma = (sqrt(5.0) - 1.0)*PI; /* golden mean times 2Pi */
phi = 0.0;
r0 = 2.0*MU;
r = r0 + MU;
for (i=0; i<1000; i++)
{
x = r*cos(phi);
y = r*sin(phi);
phi += gamma;
r += MU*r0/r;
if ((vabs(x) < LAMBDA)&&(vabs(y) < YMAX + MU))
{
particles[ncircles].xc = x;
particles[ncircles].yc = y;
ncircles++;
}
}
for (i=0; i<ncircles; i++)
{
particles[i].radius = MU;
/* inactivate circles outside the domain */
if ((particles[i].yc < YMAX + MU)&&(particles[i].yc > YMIN - MU)) particles[i].active = 1;
// printf("i = %i, circlex = %.3lg, circley = %.3lg\n", i, particles[i].xc, particles[i].yc);
}
break;
}
case (C_SQUARE_HEX):
{
ncircles = NGRIDX*(NGRIDY+1);
dy = (YMAX - YMIN)/((double)NGRIDY);
dx = dy*0.5*sqrt(3.0);
for (i = 0; i < NGRIDX; i++)
for (j = 0; j < NGRIDY+1; j++)
{
n = (NGRIDY+1)*i + j;
particles[n].xc = ((double)(i-NGRIDX/2) + 0.5)*dy; /* is +0.5 needed? */
particles[n].yc = YMIN + ((double)j - 0.5)*dy;
if (((i+NGRIDX)%4 == 2)||((i+NGRIDX)%4 == 3)) particles[n].yc += 0.5*dy;
particles[n].radius = MU;
/* activate only circles that intersect the domain */
if ((particles[n].yc < YMAX + MU)&&(particles[n].yc > YMIN - MU)) particles[n].active = 1;
else particles[n].active = 0;
}
break;
}
case (C_ONE):
{
particles[ncircles].xc = 0.0;
particles[ncircles].yc = 0.0;
particles[ncircles].radius = MU;
particles[ncircles].active = 1;
ncircles += 1;
break;
}
case (C_TWO): /* used for comparison with cloak */
{
particles[ncircles].xc = 0.0;
particles[ncircles].yc = 0.0;
particles[ncircles].radius = MU;
particles[ncircles].active = 2;
ncircles += 1;
particles[ncircles].xc = 0.0;
particles[ncircles].yc = 0.0;
particles[ncircles].radius = 2.0*MU;
particles[ncircles].active = 1;
ncircles += 1;
break;
}
case (C_NOTHING):
{
ncircles += 0;
break;
}
default:
{
printf("Function init_circle_config not defined for this pattern \n");
}
}
}
void init_people_config(t_person people[NMAXCIRCLES])
/* initialise particle configuration */
{
t_particle particles[NMAXCIRCLES];
int n;
init_particle_config(particles);
for (n=0; n<ncircles; n++)
{
people[n].xc = particles[n].xc;
people[n].yc = particles[n].yc;
people[n].radius = particles[n].radius;
people[n].active = particles[n].active;
}
}

View File

@ -109,8 +109,7 @@ int writetiff(char *filename, char *description, int x, int y, int width, int he
TIFFSetField(file, TIFFTAG_ROWSPERSTRIP, 1);
TIFFSetField(file, TIFFTAG_IMAGEDESCRIPTION, description);
p = image;
for (i = height - 1; i >= 0; i--)
for (i = height - 1; i >= 0; i--)
{
// if (TIFFWriteScanline(file, p, height - i - 1, 0) < 0)
if (TIFFWriteScanline(file, p, i, 0) < 0)
@ -121,10 +120,10 @@ int writetiff(char *filename, char *description, int x, int y, int width, int he
}
p += width * sizeof(GLubyte) * 3;
}
free(image); /* prenvents RAM consumption*/
TIFFClose(file);
return 0;
}
void init() /* initialisation of window */
{
@ -136,6 +135,8 @@ void init() /* initialisation of window */
glOrtho(XMIN, XMAX, YMIN, YMAX , -1.0, 1.0);
}
void rgb_color_scheme(int i, double rgb[3]) /* color scheme */
{
double hue, y, r;
@ -171,7 +172,7 @@ void blank()
if (COLOR_OUTSIDE)
{
hsl_to_rgb(OUTER_COLOR, 0.9, 0.15, rgb);
hsl_to_rgb(OUTER_COLOR, 0.9, 0.15, rgb);
glClearColor(rgb[0], rgb[1], rgb[2], 1.0);
}
else if (BLACK) glClearColor(0.0, 0.0, 0.0, 1.0);
@ -179,6 +180,7 @@ void blank()
glClear(GL_COLOR_BUFFER_BIT);
}
void save_frame()
{
static int counter = 0;
@ -191,16 +193,12 @@ void save_frame()
sprintf(strstr(n2,"."), format, counter);
strcat(n2, ".tif");
printf(" saving frame %s \n",n2);
// choose one of the following according to the comment beside.
writetiff(n2, "Billiard in an ellipse", 0, 0, WINWIDTH, WINHEIGHT-40, COMPRESSION_LZW); /* to use with 1080p in drop_billiard.c- probably the best because it's
// generating 1080p image, lighter, and then cropping those 40 pixels to
// avoid the strange band*/
// writetiff(n2, "Billiard in an ellipse", 0, 0, WINWIDTH, WINHEIGHT-50, COMPRESSION_LZW); // works for 1080p -> "-50px" band!!!
// writetiff(n2, "Billiard in an ellipse", 0, 0, 1920, 1080-40, COMPRESSION_LZW); //another perfect 1080p from 1440p in setup
// writetiff(n2, "Billiard in an ellipse", -WINWIDTH/8+320, -WINHEIGHT/8+180, WINWIDTH-640, WINHEIGHT-400, COMPRESSION_LZW); // perfect 1040p from 1440p in setup
writetiff(n2, "Billiard in an ellipse", 0, 0,
WINWIDTH, WINHEIGHT, COMPRESSION_LZW);
}
void write_text_fixedwidth( double x, double y, char *st)
{
int l, i;
@ -1173,28 +1171,6 @@ void draw_billiard() /* draws the billiard boundary */
draw_circle(circles[k].xc, circles[k].yc, circles[k].radius, NSEG);
break;
}
// {
// rgb[0] = 0.0; rgb[1] = 0.0; rgb[2] = 0.0;
// for (k=0; k<ncircles; k++) if (circleactive[k])
// {
// printf("k = %i, color = %i\n", k, circlecolor[k]);
// if (circlecolor[k] == 0) draw_colored_circle(circlex[k], circley[k], circlerad[k], NSEG, rgb);
// else
// {
// if (newcircle[k] >= 1)
// {
// rgb_color_scheme_lum(circlecolor[k], 0.85, rgb1);
// newcircle[k]--;
// }
// else rgb_color_scheme(circlecolor[k], rgb1);
// draw_colored_circle(circlex[k], circley[k], circlerad[k], NSEG, rgb1);
// }
// }
// init_billiard_color();
// for (k=0; k<ncircles; k++) if (circleactive[k])
// draw_circle(circlex[k], circley[k], circlerad[k], NSEG);
// break;
// }
case (D_CIRCLES_IN_RECT):
{
rgb[0] = 0.0; rgb[1] = 0.0; rgb[2] = 0.0;
@ -1343,13 +1319,24 @@ void draw_billiard() /* draws the billiard boundary */
glVertex2d(polyline[k].x2, polyline[k].y2);
glEnd();
}
if ((FOCI)&&(POLYLINE_PATTERN == P_TOKARSKY))
if (FOCI)
{
glLineWidth(2);
rgb[0] = 1.0; rgb[1] = 0.0; rgb[2] = 0.0;
draw_colored_circle(-0.95, 0.0, r, NSEG, rgb);
rgb[0] = 0.0; rgb[1] = 0.8; rgb[2] = 0.2;
draw_colored_circle(0.95, 0.0, r, NSEG, rgb);
if (POLYLINE_PATTERN == P_TOKARSKY)
{
glLineWidth(2);
rgb[0] = 1.0; rgb[1] = 0.0; rgb[2] = 0.0;
draw_colored_circle(-0.95, 0.0, r, NSEG, rgb);
rgb[0] = 0.0; rgb[1] = 0.8; rgb[2] = 0.2;
draw_colored_circle(0.95, 0.0, r, NSEG, rgb);
}
else if (POLYLINE_PATTERN == P_TOKA_PRIME)
{
glLineWidth(2);
rgb[0] = 1.0; rgb[1] = 0.0; rgb[2] = 0.0;
draw_colored_circle(-polyline[84].x1, polyline[84].y1, r, NSEG, rgb);
rgb[0] = 0.0; rgb[1] = 0.8; rgb[2] = 0.2;
draw_colored_circle(polyline[84].x1, polyline[84].y1, r, NSEG, rgb);
}
}
if (ABSORBING_CIRCLES)
{
@ -4747,7 +4734,8 @@ void print_colors(int color[NPARTMAX]) /* for debugging purposes */
c = pos_polyline(config, pos, &alpha);
c = vpolyline_xy(config, alpha, pos);
vpolyline_xy(config, alpha, pos);
// c = vpolyline_xy(config, alpha, pos);
return(c);
}
@ -5679,11 +5667,43 @@ int add_rectangle_to_polyline(double xc, double yc, double width, double height,
return(1);
}
int axial_symmetry_tsegment(t_segment z1, t_segment z2, t_segment z, t_segment *zprime)
/* compute reflection of point z wrt axis through z1 and z2 */
{
double r, zdotu;
t_segment u, zparallel, zperp;
/* compute unit vector parallel to z1-z2 */
u.x1 = z2.x1 - z1.x1;
u.y1 = z2.y1 - z1.y1;
r = module2(u.x1, u.y1);
if (r == 0) return(0); /* z1 and z2 are the same */
u.x1 = u.x1/r;
u.y1 = u.y1/r;
/* projection of z1z on z1z2 */
zdotu = (z.x1 - z1.x1)*u.x1 + (z.y1 - z1.y1)*u.y1;
zparallel.x1 = zdotu*u.x1;
zparallel.y1 = zdotu*u.y1;
/* normal vector to z1z2 */
zperp.x1 = z.x1 - z1.x1 - zparallel.x1;
zperp.y1 = z.y1 - z1.y1 - zparallel.y1;
/* reflected point */
zprime->x1 = z.x1 - 2.0*zperp.x1;
zprime->y1 = z.y1 - 2.0*zperp.y1;
return(1);
}
void init_polyline(t_segment polyline[NMAXPOLY], t_circle circles[NMAXCIRCLES])
{
int i, j, k, l, n, z, ii, jj, terni[SDEPTH], ternj[SDEPTH], quater[SDEPTH], cond;
short int vkoch[NMAXCIRCLES], turnright;
double ratio, omega, angle, sw, length, dist, x, y;
double ratio, omega, angle, sw, length, dist, x, y, ta, tb, a, b;
switch (POLYLINE_PATTERN) {
case (P_RECTANGLE):
@ -5931,6 +5951,139 @@ void init_polyline(t_segment polyline[NMAXPOLY], t_circle circles[NMAXCIRCLES])
break;
}
case (P_POLYGON):
{
nsides = NPOLY;
ncircles = 0;
omega = DPI/(double)NPOLY;
sw = sin(omega/2.0);
for (i=0; i<NPOLY; i++)
{
angle = APOLY + (double)i*omega;
polyline[i].x1 = LAMBDA*cos(angle);
polyline[i].y1 = LAMBDA*sin(angle);
polyline[i].angle = angle + PID + 0.5*omega;
polyline[i].length = 2.0*LAMBDA*sw;
}
for (i=0; i<NPOLY; i++)
{
polyline[i].x2 = polyline[(i+1)%NPOLY].x1;
polyline[i].y2 = polyline[(i+1)%NPOLY].y1;
}
for (i=0; i<nsides; i++) polyline[i].color = 0;
break;
}
case (P_TOKA_PRIME):
{
nsides = 84;
ncircles = 84;
polyline[0].x1 = 0.0;
polyline[0].y1 = 1.0;
polyline[42].x1 = 0.0;
polyline[42].y1 = 1.0 - LAMBDA;
ta = tan(0.05*PI);
tb = tan(0.4*PI);
a = LAMBDA*tb/(ta + tb);
b = a*ta;
polyline[41].x1 = b;
polyline[41].y1 = 1.0 - a;
axial_symmetry_tsegment(polyline[0], polyline[41], polyline[42], &polyline[40]);
axial_symmetry_tsegment(polyline[0], polyline[40], polyline[41], &polyline[1]);
axial_symmetry_tsegment(polyline[40], polyline[1], polyline[0], &polyline[84]);
axial_symmetry_tsegment(polyline[1], polyline[84], polyline[40], &polyline[2]);
for (i=2; i<39; i++)
axial_symmetry_tsegment(polyline[i], polyline[84], polyline[i-1], &polyline[i+1]);
for (i=1; i<42; i++)
{
polyline[84-i].x1 = -polyline[i].x1;
polyline[84-i].y1 = polyline[i].y1;
}
printf("xc = %.5f, yc = %.5f\n", polyline[84].x1, polyline[84].y1);
for (i=0; i<nsides; i++)
{
// polyline[i].x1 += -MU;
x = polyline[(i+1)%nsides].x1;
y = polyline[(i+1)%nsides].y1;
polyline[i].x2 = x;
polyline[i].y2 = y;
polyline[i].length = module2(x - polyline[i].x1, y - polyline[i].y1);
polyline[i].angle = argument(x - polyline[i].x1, y - polyline[i].y1);
}
for (i=0; i<ncircles; i++)
{
circles[i].xc = polyline[i].x1;
circles[i].yc = polyline[i].y1;
circles[i].radius = MU;
circles[i].active = 1;
}
break;
}
case (P_TREE):
{
nsides = 11;
ncircles = 11;
polyline[0].x1 = 0.85;
polyline[0].y1 = -1.0;
polyline[1].x1 = 0.4;
polyline[1].y1 = -0.4;
polyline[2].x1 = 0.65;
polyline[2].y1 = -0.4;
polyline[3].x1 = 0.25;
polyline[3].y1 = 0.2;
polyline[4].x1 = 0.5;
polyline[4].y1 = 0.2;
polyline[5].x1 = 0.0;
polyline[5].y1 = 1.0;
for (i=6; i<11; i++)
{
polyline[i].x1 = -polyline[10-i].x1;
polyline[i].y1 = polyline[10-i].y1;
}
for (i=0; i<nsides; i++)
{
x = polyline[(i+1)%nsides].x1;
y = polyline[(i+1)%nsides].y1;
polyline[i].x2 = x;
polyline[i].y2 = y;
polyline[i].length = module2(x - polyline[i].x1, y - polyline[i].y1);
polyline[i].angle = argument(x - polyline[i].x1, y - polyline[i].y1);
}
for (i=0; i<ncircles; i++)
{
circles[i].xc = polyline[i].x1;
circles[i].yc = polyline[i].y1;
circles[i].radius = MU;
circles[i].active = 1;
}
}
}
}

View File

@ -4,6 +4,59 @@
#include "colors_waves.c"
int writetiff_new(char *filename, char *description, int x, int y, int width, int height, int compression)
{
TIFF *file;
GLubyte *image, *p;
int i;
file = TIFFOpen(filename, "w");
if (file == NULL)
{
return 1;
}
image = (GLubyte *) malloc(width * height * sizeof(GLubyte) * 3);
/* OpenGL's default 4 byte pack alignment would leave extra bytes at the
end of each image row so that each full row contained a number of bytes
divisible by 4. Ie, an RGB row with 3 pixels and 8-bit componets would
be laid out like "RGBRGBRGBxxx" where the last three "xxx" bytes exist
just to pad the row out to 12 bytes (12 is divisible by 4). To make sure
the rows are packed as tight as possible (no row padding), set the pack
alignment to 1. */
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, image);
TIFFSetField(file, TIFFTAG_IMAGEWIDTH, (uint32) width);
TIFFSetField(file, TIFFTAG_IMAGELENGTH, (uint32) height);
TIFFSetField(file, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(file, TIFFTAG_COMPRESSION, compression);
TIFFSetField(file, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
TIFFSetField(file, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
TIFFSetField(file, TIFFTAG_SAMPLESPERPIXEL, 3);
TIFFSetField(file, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(file, TIFFTAG_ROWSPERSTRIP, 1);
TIFFSetField(file, TIFFTAG_IMAGEDESCRIPTION, description);
p = image;
for (i = height - 1; i >= 0; i--)
{
// if (TIFFWriteScanline(file, p, height - i - 1, 0) < 0)
if (TIFFWriteScanline(file, p, i, 0) < 0)
{
free(image);
TIFFClose(file);
return 1;
}
p += width * sizeof(GLubyte) * 3;
}
free(image); /* prenvents RAM consumption*/
TIFFClose(file);
return 0;
}
int writetiff(char *filename, char *description, int x, int y, int width, int height, int compression)
{
@ -68,12 +121,6 @@ void init() /* initialisation of window */
glOrtho(0.0, NX, 0.0, NY, -1.0, 1.0);
}
void blank()
{
if (BLACK) glClearColor(0.0, 0.0, 0.0, 1.0);
@ -82,6 +129,53 @@ void blank()
}
void test_save_frame() /* some tests with various resolutions */
{
static int counter = 0;
char *name="wave.", n2[100];
char format[6]=".%05i";
counter++;
// printf (" p2 counter = %d \n",counter);
strcpy(n2, name);
sprintf(strstr(n2,"."), format, counter);
strcat(n2, ".tif");
printf(" saving frame %s \n",n2);
writetiff(n2, "Wave equation in a planar domain", 0, 0, WINWIDTH, WINHEIGHT, COMPRESSION_LZW); // works for 1080p -> "-50px"
// choose one of the following according to the comment beside.
// writetiff(n2, "Wave equation in a planar domain", 0, 0, WINWIDTH, WINHEIGHT-40, COMPRESSION_LZW);
/* to use with 1080p in drop_billiard.c- probably the best because it's
// generating 1080p image, lighter, and then cropping those 40 pixels to
// avoid the strange band*/
// writetiff(n2, "Wave equation in a planar domain", 0, 0, WINWIDTH, WINHEIGHT-50, COMPRESSION_LZW); // works for 1080p -> "-50px" band!!!
// writetiff(n2, "Wave equation in a planar domain", 0, 0, 1920, 1080-40, COMPRESSION_LZW); //another perfect 1080p from 1440p in setup
// writetiff(n2, "Wave equation in a planar domain", -WINWIDTH/8+320, -WINHEIGHT/8+180, WINWIDTH-640, WINHEIGHT-400, COMPRESSION_LZW); // perfect 1040p from 1440p in setup
}
void test_save_frame_counter(int counter) /* some tests with various resolutions */
/* same as save_frame, but with imposed image number (for option DOUBLE_MOVIE) */
{
char *name="wave.", n2[100];
char format[6]=".%05i";
strcpy(n2, name);
sprintf(strstr(n2,"."), format, counter);
strcat(n2, ".tif");
printf(" saving frame %s \n",n2);
writetiff(n2, "Wave equation in a planar domain", 0, 0, WINWIDTH, WINHEIGHT, COMPRESSION_LZW); // works for 1080p -> "-50px"
// choose one of the following according to the comment beside.
// writetiff(n2, "Wave equation in a planar domain", 0, 0, WINWIDTH, WINHEIGHT-40, COMPRESSION_LZW);
/* to use with 1080p in drop_billiard.c- probably the best because it's
// generating 1080p image, lighter, and then cropping those 40 pixels to
// avoid the strange band*/
// writetiff(n2, "Wave equation in a planar domain", 0, 0, WINWIDTH, WINHEIGHT-50, COMPRESSION_LZW); // works for 1080p -> "-50px" band!!!
// writetiff(n2, "Wave equation in a planar domain", 0, 0, 1920, 1080-40, COMPRESSION_LZW); //another perfect 1080p from 1440p in setup
// writetiff(n2, "BWave equation in a planar domain", -WINWIDTH/8+320, -WINHEIGHT/8+180, WINWIDTH-640, WINHEIGHT-400, COMPRESSION_LZW); // perfect 1040p from 1440p in setup
}
void save_frame()
{
@ -419,7 +513,7 @@ void init_circle_config(t_circle circles[NMAXCIRCLES])
/* for billiard shape D_CIRCLES */
{
int i, j, k, n, ncirc0, n_p_active, ncandidates=5000, naccepted;
double dx, dy, p, phi, r, r0, ra[5], sa[5], height, x, y = 0.0, gamma, dpoisson = 3.25*MU, xx[4], yy[4];
double dx, dy, p, phi, r, r0, ra[5], sa[5], height, x, y = 0.0, gamma, dpoisson = 3.25*MU, xx[4], yy[4], dr, dphi;
short int active_poisson[NMAXCIRCLES], far;
switch (CIRCLE_PATTERN) {
@ -728,6 +822,26 @@ void init_circle_config(t_circle circles[NMAXCIRCLES])
}
break;
}
case (C_RINGS):
{
ncircles = NGRIDX*NGRIDY;
dphi = DPI/((double)NGRIDX);
dr = 0.5*LAMBDA/(double)NGRIDY;
for (i = 0; i < NGRIDX; i++)
for (j = 0; j < NGRIDY; j++)
{
n = NGRIDY*i + j;
phi = (double)i*dphi;
r = 0.5*LAMBDA + (double)j*dr;
circles[n].xc = r*cos(phi);
circles[n].yc = r*sin(phi);
circles[n].radius = MU;
/* activate only circles that intersect the domain */
if ((circles[n].yc < YMAX + MU)&&(circles[n].yc > YMIN - MU)) circles[n].active = 1;
else circles[n].active = 0;
}
break;
}
case (C_ONE):
{
circles[ncircles].xc = 0.0;
@ -785,7 +899,11 @@ void init_polygon_config(t_polygon polygons[NMAXCIRCLES])
/*
if (i < ncircles) printf("(x,y) = (%.2f, %.2f), r = %.2f, angle = %.2f, sides = %i\n", polygons[i].xc, polygons[i].yc, polygons[i].radius, polygons[i].angle, polygons[i].nsides);*/
}
/* adjust angles for C_RINGS configuration */
if (CIRCLE_PATTERN == C_RINGS)
for (i=0; i<ncircles; i++) if (polygons[i].active)
polygons[i].angle += argument(polygons[i].xc, polygons[i].yc)/PID;
}
int axial_symmetry(double z1[2], double z2[2], double z[2], double zprime[2])
@ -943,6 +1061,51 @@ void compute_isospectral_coordinates(int type, int ishift, double xshift, double
}
int compute_tokaprime_coordinates(double xshift, t_vertex polyline[NMAXPOLY])
/* compute positions of vertices of Tokarsky room made of 86 triangles */
{
double ta, tb, a, b, pos[2];
int i;
polyline[0].x = 0.0;
polyline[0].y = 1.0;
polyline[1].x = 0.0;
polyline[1].y = 1.0 - LAMBDA;
ta = tan(0.05*PI);
tb = tan(0.4*PI);
a = LAMBDA*tb/(ta + tb);
b = a*ta;
polyline[2].x = b;
polyline[2].y = 1.0 - a;
axial_symmetry_tvertex(polyline[0], polyline[2], polyline[1], &polyline[3]);
axial_symmetry_tvertex(polyline[0], polyline[3], polyline[2], &polyline[4]);
axial_symmetry_tvertex(polyline[3], polyline[4], polyline[0], &polyline[43]);
for (i=4; i<42; i++)
axial_symmetry_tvertex(polyline[i], polyline[43], polyline[i-1], &polyline[i+1]);
for (i=2; i<44; i++)
{
polyline[i+42].x = -polyline[i].x;
polyline[i+42].y = polyline[i].y;
}
for (i=0; i<86; i++)
{
polyline[i].x += xshift;
xy_to_pos(polyline[i].x, polyline[i].y, pos);
polyline[i].posi = pos[0];
polyline[i].posj = pos[1];
}
return(86);
}
void compute_homophonic_coordinates(int type, int ishift, double xshift, double yshift, double scaling,
t_vertex polyline[NMAXPOLY])
/* compute positions of vertices of homophonic billiards */
@ -1047,10 +1210,10 @@ int compute_vonkoch_coordinates(int depth, t_vertex polyline[NMAXPOLY])
}
/* compute vertices */
angle = 2.0*PI/3.0;
x = cos(PI/6.0);
y = -sin(PI/6.0);
length = 2.0*sin(PI/3.0);
angle = APOLY*PID + 2.0*PI/3.0;
x = LAMBDA*cos(APOLY*PID - PI/6.0);
y = LAMBDA*sin(APOLY*PID - PI/6.0);
length = 2.0*LAMBDA*sin(PI/3.0);
for (k=0; k<depth; k++) length = length/3.0;
printf("Length = %.2f\n", length);
@ -1079,6 +1242,37 @@ int compute_vonkoch_coordinates(int depth, t_vertex polyline[NMAXPOLY])
}
int compute_star_coordinates(t_vertex polyline[NMAXPOLY])
/* compute positions of vertices of star-shaped domain */
{
int i;
double alpha, r, x, y, pos[2];
alpha = DPI/(double)NPOLY;
for (i=0; i<NPOLY; i++)
{
if (i%2 == 0) r = LAMBDA - MU;
else r = LAMBDA;
x = r*cos(APOLY*PID + alpha*(double)i);
y = r*sin(APOLY*PID + alpha*(double)i);
polyline[i].x = x;
polyline[i].y = y;
xy_to_pos(x, y, pos);
polyline[i].posi = pos[0];
polyline[i].posj = pos[1];
}
/* add origin to compute xy_in_billiard */
polyline[NPOLY].x = 0.0;
polyline[NPOLY].y = 0.0;
return(NPOLY);
}
int init_polyline(int depth, t_vertex polyline[NMAXPOLY])
/* initialise variable polyline, for certain polygonal domain shapes */
{
@ -1087,6 +1281,10 @@ int init_polyline(int depth, t_vertex polyline[NMAXPOLY])
{
return(compute_tokarsky_coordinates(-4.0, -2.0, (XMAX - XMIN)/8.4, polyline));
}
case (D_TOKA_PRIME):
{
return(compute_tokaprime_coordinates(-MU, polyline));
}
case (D_ISOSPECTRAL):
{
compute_isospectral_coordinates(0, 0, ISO_XSHIFT_LEFT, ISO_YSHIFT_LEFT, ISO_SCALE, polyline);
@ -1107,6 +1305,10 @@ int init_polyline(int depth, t_vertex polyline[NMAXPOLY])
{
return(compute_vonkoch_coordinates(depth, polyline));
}
case (D_STAR):
{
return(compute_star_coordinates(polyline));
}
default:
{
return(0);
@ -1165,8 +1367,8 @@ int xy_in_billiard(double x, double y)
/* returns 1 if (x,y) represents a point in the billiard */
// double x, y;
{
double l2, r2, r2mu, omega, b, c, angle, z, x1, y1, x2, y2, u, v, u1, v1, dx, dy, width;
int i, j, k, k1, k2, condition, m;
double l2, r2, r2mu, omega, b, c, angle, z, x1, y1, x2, y2, u, v, u1, v1, dx, dy, width, alpha;
int i, j, k, k1, k2, condition = 0, m;
static int first = 1, nsides;
switch (B_DOMAIN) {
@ -1399,6 +1601,22 @@ int xy_in_billiard(double x, double y)
else return(1);
}
}
case (D_TOKA_PRIME):
{
// x1 = vabs(x);
if (x + MU > 0.0) x1 = x;
else x1 = -2.0*MU - x;
condition = xy_in_triangle_tvertex(x1, y, polyline[0], polyline[1], polyline[2]);
condition += xy_in_triangle_tvertex(x1, y, polyline[0], polyline[2], polyline[3]);
condition += xy_in_triangle_tvertex(x1, y, polyline[i], polyline[3], polyline[4]);
for (i=3; i<42; i++)
condition += xy_in_triangle_tvertex(x1, y, polyline[i], polyline[43], polyline[i+1]);
condition += xy_in_triangle_tvertex(x1, y, polyline[42], polyline[43], polyline[3]);
return(condition >= 1);
}
case (D_ISOSPECTRAL):
{
/* 1st triangle */
@ -1522,6 +1740,13 @@ int xy_in_billiard(double x, double y)
}
return(condition >= 1);
}
case (D_STAR):
{
condition = xy_in_triangle_tvertex(x, y, polyline[NPOLY], polyline[NPOLY-1], polyline[0]);
for (i = 0; i < NPOLY-1; i++)
condition += xy_in_triangle_tvertex(x, y, polyline[NPOLY], polyline[i], polyline[i+1]);
return(condition >= 1);
}
case (D_MENGER):
{
x1 = 0.5*(x+1.0);
@ -2247,6 +2472,56 @@ void draw_billiard() /* draws the billiard boundary */
}
break;
}
case (D_TOKA_PRIME):
{
glBegin(GL_LINE_LOOP);
tvertex_lineto(polyline[0]);
for (i=4; i<43; i++) tvertex_lineto(polyline[i]);
tvertex_lineto(polyline[3]);
tvertex_lineto(polyline[2]);
tvertex_lineto(polyline[1]);
tvertex_lineto(polyline[44]);
tvertex_lineto(polyline[45]);
for (i=84; i>45; i--) tvertex_lineto(polyline[i]);
glEnd();
/* inner lines */
// glLineWidth(BOUNDARY_WIDTH/2);
glLineWidth(1);
glColor3f(0.75, 0.75, 0.75);
glBegin(GL_LINE_STRIP);
tvertex_lineto(polyline[0]);
tvertex_lineto(polyline[1]);
tvertex_lineto(polyline[2]);
tvertex_lineto(polyline[0]);
tvertex_lineto(polyline[3]);
tvertex_lineto(polyline[4]);
glEnd();
glBegin(GL_LINE_STRIP);
tvertex_lineto(polyline[0]);
tvertex_lineto(polyline[44]);
tvertex_lineto(polyline[45]);
tvertex_lineto(polyline[0]);
tvertex_lineto(polyline[46]);
tvertex_lineto(polyline[45]);
glEnd();
for (i=3; i<43; i++)
{
glBegin(GL_LINE_STRIP);
tvertex_lineto(polyline[i]);
tvertex_lineto(polyline[43]);
glEnd();
glBegin(GL_LINE_STRIP);
tvertex_lineto(polyline[i+42]);
tvertex_lineto(polyline[85]);
glEnd();
}
break;
}
case (D_ISOSPECTRAL):
{
/* 1st triangle */
@ -2402,6 +2677,14 @@ void draw_billiard() /* draws the billiard boundary */
glEnd();
break;
}
case (D_STAR):
{
glLineWidth(BOUNDARY_WIDTH);
glBegin(GL_LINE_LOOP);
for (i=0; i<npolyline; i++) tvertex_lineto(polyline[i]);
glEnd();
break;
}
case (D_CIRCLES):
{
glLineWidth(BOUNDARY_WIDTH);
@ -2713,6 +2996,18 @@ void draw_color_scheme(double x1, double y1, double x2, double y2, int plot, dou
else color_scheme(COLOR_SCHEME, value, 1.0, 1, rgb);
break;
}
case (P_LOG_ENERGY):
{
value = LOG_SCALE*log(dy_e*(double)(j - jmin)*100.0/E_SCALE);
color_scheme(COLOR_SCHEME, value, 1.0, 1, rgb);
break;
}
case (P_LOG_MEAN_ENERGY):
{
value = LOG_SCALE*log(dy_e*(double)(j - jmin)*100.0/E_SCALE);
color_scheme(COLOR_SCHEME, value, 1.0, 1, rgb);
break;
}
case (P_PHASE):
{
value = min + 1.0*dy*(double)(j - jmin);

View File

@ -38,10 +38,10 @@ void init_circle_config_half(int pattern, int top, t_circle circles[NMAXCIRCLES]
dy = (YMAX - YMIN)/((double)NGRIDY);
dx = dy*0.5*sqrt(3.0);
for (i = 0; i < NGRIDX; i++)
for (j = 0; j < NGRIDY/2+1; j++)
for (j = 0; j < NGRIDY/2+2; j++)
{
n = ncircles + (NGRIDY+1)*i/2 + j;
circles[n].xc = ((double)(i-NGRIDX/2))*dy;
n = ncircles + (NGRIDY+2)*i/2 + j;
circles[n].xc = ((double)(i-NGRIDX/2) + 0.5)*dy;
y = ((double)j - 0.5)*dy;
if ((i+NGRIDX)%2 == 1) y += 0.5*dy;
if (top) circles[n].yc = ymean + 0.5*dy + y;
@ -51,7 +51,7 @@ void init_circle_config_half(int pattern, int top, t_circle circles[NMAXCIRCLES]
circles[n].active = 1;
circletop[n] = top;
}
ncircles += NGRIDX*(NGRIDY+1)/2;
ncircles += NGRIDX*(NGRIDY+2)/2;
break;
}
case (C_RAND_DISPLACED):
@ -408,7 +408,7 @@ void init_circle_config_energy(t_circle circles[NMAXCIRCLES])
}
void init_polygon_config_half(int pattern, int top, t_polygon polygons[NMAXCIRCLES])
void init_polygon_config_half(int pattern, int top, int random_angle, int xdep_angle, t_polygon polygons[NMAXCIRCLES])
/* initialise the polygon configuration, for billiard shape D_CIRCLES */
/* uses init_circle_config, this is where C++ would be more elegant */
{
@ -425,10 +425,20 @@ void init_polygon_config_half(int pattern, int top, t_polygon polygons[NMAXCIRCL
polygons[i].active = circle[i].active;
polygons[i].nsides = NPOLY;
if (RANDOM_POLY_ANGLE) polygons[i].angle = DPI*(double)rand()/RAND_MAX;
else polygons[i].angle = APOLY;
// if (i < ncircles) printf("(x,y) = (%.2f, %.2f), r = %.2f, angle = %.2f, sides = %i\n", polygons[i].xc, polygons[i].yc, polygons[i].radius, polygons[i].angle, polygons[i].nsides);
if ((top)&&(circletop[i]))
{
if (random_angle) polygons[i].angle = DPI*(double)rand()/RAND_MAX;
else if (xdep_angle) polygons[i].angle = APOLY + PID*POLY_ROTATION_ANGLE*polygons[i].xc;
else polygons[i].angle = APOLY;
}
else if ((!top)&&(!circletop[i]))
{
if (random_angle) polygons[i].angle = DPI*(double)rand()/RAND_MAX;
else if (xdep_angle) polygons[i].angle = APOLY_B + PID*POLY_ROTATION_ANGLE*polygons[i].xc;
else polygons[i].angle = APOLY_B;
}
if (i < ncircles) printf("(x,y) = (%.2f, %.2f), r = %.2f, angle = %.2f, sides = %i\n", polygons[i].xc, polygons[i].yc, polygons[i].radius, polygons[i].angle, polygons[i].nsides);
}
}
@ -436,8 +446,8 @@ void init_polygon_config_comp(t_polygon polygons[NMAXCIRCLES])
/* initialise polygon configuration for billiard shape D_POLYGONS */
{
ncircles = 0;
init_polygon_config_half(CIRCLE_PATTERN, 1, polygons);
init_polygon_config_half(CIRCLE_PATTERN_B, 0, polygons);
init_polygon_config_half(CIRCLE_PATTERN, 1, RANDOM_POLY_ANGLE, XDEP_POLY_ANGLE, polygons);
init_polygon_config_half(CIRCLE_PATTERN_B, 0, RANDOM_POLY_ANGLE_B, XDEP_POLY_ANGLE_B, polygons);
}
@ -526,6 +536,10 @@ void draw_billiard_half(int domain, int pattern, int top) /* draws the bill
{
double x0, x, y, x1, y1, dx, dy, phi, r = 0.01, pos[2], pos1[2], alpha, dphi, omega, z, l, signtop;
int i, j, k, k1, k2, mr2;
glEnable(GL_SCISSOR_TEST);
if (top) glScissor(0.0, YMID, NX, YMID);
else glScissor(0.0, 0.0, NX, YMID);
if (BLACK) glColor3f(1.0, 1.0, 1.0);
else glColor3f(0.0, 0.0, 0.0);
@ -643,6 +657,8 @@ void draw_billiard_half(int domain, int pattern, int top) /* draws the bill
printf("Function draw_billiard not defined for this billiard \n");
}
}
glDisable(GL_SCISSOR_TEST);
}
@ -707,19 +723,63 @@ 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))
{
if (PLOT == P_AMPLITUDE)
color_scheme(COLOR_SCHEME, phi[i][j], scale, time, rgb);
else if (PLOT == P_ENERGY)
{
energy = compute_energy(phi, psi, xy_in, i, j);
if (COLOR_PALETTE >= COL_TURBO) color_scheme_asym(COLOR_SCHEME, energy, scale, time, rgb);
else color_scheme(COLOR_SCHEME, energy, 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);
switch (PLOT) {
case (P_AMPLITUDE):
{
color_scheme(COLOR_SCHEME, phi[i][j], scale, time, rgb);
break;
}
case (P_ENERGY):
{
energy = compute_energy(phi, psi, xy_in, i, j);
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;
// color_scheme(COLOR_SCHEME, LOG_SCALE*log(total_energy[i][j]/(double)(time+1)), scale, time, rgb);
// break;
// }
}
// if (PLOT == P_AMPLITUDE)
// color_scheme(COLOR_SCHEME, phi[i][j], scale, time, rgb);
// else if (PLOT == P_ENERGY)
// {
// energy = compute_energy(phi, psi, xy_in, i, j);
// if (COLOR_PALETTE >= COL_TURBO) color_scheme_asym(COLOR_SCHEME, energy, scale, time, rgb);
// else color_scheme(COLOR_SCHEME, energy, 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);
// }
glColor3f(rgb[0], rgb[1], rgb[2]);
glVertex2i(i, j);
@ -745,20 +805,29 @@ void compute_energy_tblr(double *phi[NX], double *psi[NX], short int *xy_in[NX],
/* compute total energy in top/bottom left/right boxes */
{
int i, j, ij[2];
double energy = 0.0, rescale, pos, xleft = XMAX, xright = XMIN, emax = 1.2;
double energy_ij[NX][NY];
double energy = 0.0, rescale, pos, xleft = XMAX, xright = XMIN, emax = 1.2, xc, r;
double *energy_ij[NX];
static short int first = 1;
static int ileft, iright, jmid = NY/2;
static double sqremax;
for (i=0; i<NX; i++) energy_ij[i] = (double *)malloc(NY*sizeof(double));
if (first) /* compute box limits */
{
/* find leftmost and rightmost circle */
for (i=0; i<ncircles; 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 ((circles[i].active)&&(circles[i].xc - circles[i].radius < xleft)) xleft = circles[i].xc - circles[i].radius;
if ((polygons[i].active)&&(polygons[i].xc - polygons[i].radius < xleft)) xleft = polygons[i].xc - polygons[i].radius;
if ((circles[i].active)&&(circles[i].xc + circles[i].radius > xright)) xright = circles[i].xc + circles[i].radius;
if ((polygons[i].active)&&(polygons[i].xc + polygons[i].radius > xright)) xright = polygons[i].xc + polygons[i].radius;
}
// for (i=0; i<ncircles; 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 ((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];
@ -837,15 +906,26 @@ void compute_energy_tblr(double *phi[NX], double *psi[NX], short int *xy_in[NX],
// printf("Energies: %.5lg, %.5lg, %.5lg\n %.5lg, %.5lg, %.5lg\n", energies[0], energies[1], energies[2], energies[3], energies[4], energies[5]);
for (i=0; i<NX; i++) free(energy_ij[i]);
}
void print_energies(double energies[6], double top_energy, double bottom_energy)
{
char message[50];
double ytop, ybot, pos[2], centerx = -0.075, boxxright = XMAX - 0.17, textxright = XMAX - 0.28;
double ytop, ybot, pos[2], centerx = -0.075, boxxright = XMAX - 0.17, textxright = XMAX - 0.28, boxwidth = 0.1,
boxheight = 0.05, leftboxshift = 0.185, centerboxshift = 0.085;
/* adapt sizes of text areas to high resolution */
if (WINWIDTH > 1280)
{
boxheight = 0.035;
// centerx -= 0.2;
boxwidth = 0.08;
leftboxshift = 0.16;
centerboxshift = 0.06;
}
ytop = YMAX - 0.1;
// ybot = -0.1;
ybot = YMIN + 0.05;
if (DRAW_COLOR_SCHEME)
{
@ -853,42 +933,42 @@ void print_energies(double energies[6], double top_energy, double bottom_energy)
textxright -= 0.35;
}
erase_area(XMIN + 0.185, ytop + 0.025, 0.1, 0.05);
erase_area(XMIN + leftboxshift, ytop + 0.025, boxwidth, boxheight);
glColor3f(1.0, 1.0, 1.0);
sprintf(message, "%.3f", energies[0]/top_energy);
xy_to_pos(XMIN + 0.1, ytop, pos);
write_text(pos[0], pos[1], message);
erase_area(centerx + 0.085, ytop + 0.025, 0.1, 0.05);
erase_area(centerx + centerboxshift, ytop + 0.025, boxwidth, boxheight);
glColor3f(1.0, 1.0, 1.0);
sprintf(message, "%.3f", energies[1]/top_energy);
xy_to_pos(centerx, ytop, pos);
write_text(pos[0], pos[1], message);
erase_area(boxxright, ytop + 0.025, 0.15, 0.05);
erase_area(boxxright, ytop + 0.025, boxwidth + 0.05, boxheight);
glColor3f(1.0, 1.0, 1.0);
sprintf(message, "%.5f", energies[2]/top_energy);
xy_to_pos(textxright, ytop, pos);
write_text(pos[0], pos[1], message);
erase_area(XMIN + 0.185, ybot + 0.025, 0.1, 0.05);
erase_area(XMIN + leftboxshift, ybot + 0.025, boxwidth, boxheight);
glColor3f(1.0, 1.0, 1.0);
sprintf(message, "%.3f", energies[3]/bottom_energy);
xy_to_pos(XMIN + 0.1, ybot, pos);
write_text(pos[0], pos[1], message);
erase_area(centerx + 0.085, ybot + 0.025, 0.1, 0.05);
erase_area(centerx + centerboxshift, ybot + 0.025, boxwidth, boxheight);
glColor3f(1.0, 1.0, 1.0);
sprintf(message, "%.3f", energies[4]/bottom_energy);
xy_to_pos(centerx, ybot, pos);
write_text(pos[0], pos[1], message);
erase_area(boxxright, ybot + 0.025, 0.15, 0.05);
erase_area(boxxright, ybot + 0.025, boxwidth + 0.05, boxheight);
glColor3f(1.0, 1.0, 1.0);
sprintf(message, "%.5f", energies[5]/bottom_energy);

View File

@ -42,27 +42,37 @@
#include <tiffio.h> /* Sam Leffler's libtiff library. */
#include <omp.h>
#define MOVIE 0 /* set to 1 to generate movie */
#define DOUBLE_MOVIE 0 /* set to 1 to produce movies for wave height and energy simultaneously */
#define MOVIE 1 /* set to 1 to generate movie */
#define DOUBLE_MOVIE 1 /* set to 1 to produce movies for wave height and energy simultaneously */
/* General geometrical parameters */
#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 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 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 YMIN -1.0329
#define YMAX 1.1129 /* y interval for 9/16 aspect ratio */
// #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 NX 2560 /* number of grid points on x axis */
// #define NY 1440 /* number of grid points on y axis */
// #define YMIN -1.125
// #define YMAX 1.125 /* y interval for 9/16 aspect ratio */
#define JULIA_SCALE 1.0 /* scaling for Julia sets */
/* Choice of the billiard table */
#define B_DOMAIN 38 /* choice of domain shape, see list in global_pdes.c */
#define B_DOMAIN 42 /* choice of domain shape, see list in global_pdes.c */
#define CIRCLE_PATTERN 2 /* pattern of circles or polygons, see list in global_pdes.c */
@ -70,10 +80,10 @@
#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.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 LAMBDA 1.1 /* parameter controlling the dimensions of domain */
#define MU 0.4 /* parameter controlling the dimensions of domain */
#define NPOLY 14 /* number of sides of polygon */
#define APOLY -1.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 */
@ -81,8 +91,6 @@
#define FOCI 1 /* set to 1 to draw focal points of ellipse */
#define NGRIDX 10 /* number of grid point for grid of disks */
#define NGRIDY 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
@ -106,11 +114,9 @@
#define OMEGA 0.002 /* frequency of periodic excitation */
#define AMPLITUDE 1.0 /* amplitude of periodic excitation */
#define COURANT 0.02 /* Courant number */
#define COURANT 0.04 /* Courant number */
#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 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 */
@ -128,12 +134,11 @@
/* Parameters for length and speed of simulation */
// #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 NSTEPS 2100 /* 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 0 /* time after which to start saving frames */
#define BOUNDARY_WIDTH 2 /* width of billiard boundary */
#define BOUNDARY_WIDTH 3 /* width of billiard boundary */
#define PAUSE 1000 /* number of frames after which to pause */
#define PSLEEP 1 /* sleep time during pause */
@ -145,8 +150,6 @@
/* Parameters of initial condition */
#define INITIAL_AMP 0.75 /* amplitude 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 */
@ -158,32 +161,29 @@
/* Color schemes */
#define COLOR_PALETTE 14 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE 12 /* 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.25 /* sensitivity of color on wave amplitude */
#define SLOPE 1.0 /* sensitivity of color on wave amplitude */
#define SLOPE 0.5 /* 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 E_SCALE 150.0 /* scaling factor for energy representation */
#define LOG_SCALE 2.5 /* scaling factor for energy log 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 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 COLORBAR_RANGE 6.0 /* scale of color scheme bar */
#define COLORBAR_RANGE_B 10.0 /* scale of color scheme bar for 2nd part */
#define ROTATE_COLOR_SCHEME 0 /* set to 1 to draw color scheme horizontally */
#define SAVE_TIME_SERIES 0 /* set to 1 to save wave time series at a point */
@ -606,7 +606,7 @@ void draw_color_bar(int plot, double range)
void animation()
{
double time, scale, ratio, startleft[2], startright[2];
double time, scale, ratio, startleft[2], startright[2], sign;
double *phi[NX], *psi[NX], *phi_tmp[NX], *psi_tmp[NX], *total_energy[NX];
short int *xy_in[NX];
int i, j, s, sample_left[2], sample_right[2];
@ -635,7 +635,7 @@ void animation()
else if (B_DOMAIN == D_POLYGONS) init_polygon_config(polygons);
printf("Polygons initialized\n");
/* initialise polyline for von Koch and simular domains */
/* 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);
@ -646,7 +646,7 @@ void animation()
// init_circular_wave(0.0, -LAMBDA, phi, psi, xy_in);
/* initialize total energy table */
if ((PLOT == P_MEAN_ENERGY)||(PLOT_B == P_MEAN_ENERGY))
if ((PLOT == P_MEAN_ENERGY)||(PLOT_B == P_MEAN_ENERGY)||(PLOT == P_LOG_MEAN_ENERGY)||(PLOT_B == P_LOG_MEAN_ENERGY))
for (i=0; i<NX; i++)
for (j=0; j<NY; j++)
total_energy[i][j] = 0.0;
@ -654,12 +654,12 @@ void animation()
ratio = (XMAX - XMIN)/8.4; /* for Tokarsky billiard */
// isospectral_initial_point(0.2, 0.0, startleft, startright); /* for isospectral billiards */
homophonic_initial_point(0.5, -0.25, 1.5, -0.25, startleft, startright);
// homophonic_initial_point(0.5, -0.25, 1.5, -0.25, startleft, startright);
// 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);
// xy_to_ij(startleft[0], startleft[1], sample_left);
// xy_to_ij(startright[0], startright[1], sample_right);
// printf("xleft = (%.3f, %.3f) xright = (%.3f, %.3f)\n", xin_left, yin_left, xin_right, yin_right);
// init_wave_flat(phi, psi, xy_in);
@ -670,12 +670,16 @@ void animation()
// 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);
init_circular_wave(0.0, 0.0, phi, psi, xy_in);
// for (i=0; i<3; i++)
// {
// add_circular_wave(-1.0, 0.6*cos(PID + (double)(i)*DPI/3.0), 0.6*sin(PID + (double)(i)*DPI/3.0), phi, psi, xy_in);
// }
// add_circular_wave(-1.0, 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);

View File

@ -388,6 +388,20 @@ void draw_wave_e(double *phi[NX], double *psi[NX], double *total_energy[NX], sho
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_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_SCALE*log(total_energy[i][j]/(double)(time+1)), scale, time, rgb);
break;
}
}
glColor3f(rgb[0], rgb[1], rgb[2]);

View File

@ -44,36 +44,51 @@
#define MOVIE 0 /* set to 1 to generate movie */
#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 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 YMIN -1.125
#define YMAX 1.125 /* y interval for 9/16 aspect ratio */
#define YMIN -1.041666667
#define YMAX 1.041666667 /* y interval for 9/16 aspect ratio */
// #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 YMIN -1.125
// #define YMAX 1.125 /* y interval for 9/16 aspect ratio */
#define JULIA_SCALE 1.0 /* scaling for Julia sets */
/* Choice of the billiard table */
#define B_DOMAIN 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 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 CIRCLE_PATTERN 11 /* pattern of circles, see list in global_pdes.c */
#define CIRCLE_PATTERN_B 8 /* pattern of circles, see list in global_pdes.c */
#define CIRCLE_PATTERN 1 /* pattern of circles, see list in global_pdes.c */
#define CIRCLE_PATTERN_B 1 /* 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 0 /* set to 1 to randomize angle of polygons */
#define RANDOM_POLY_ANGLE_B 1 /* set to 1 to randomize angle of polygons */
#define XDEP_POLY_ANGLE 0 /* set to 1 to rotate polygons depending on x coordinate */
#define XDEP_POLY_ANGLE_B 1 /* set to 1 to rotate polygons depending on x coordinate */
#define POLY_ROTATION_ANGLE -0.645 /* rotation angle for |x|=1 in units of Pi/2 */
#define LAMBDA 0.8 /* parameter controlling the dimensions of domain */
#define MU 0.03 /* parameter controlling the dimensions of domain */
#define MUB 0.03 /* 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 */
#define APOLY 1.0 /* angle by which to turn polygon, in units of Pi/2 */
#define APOLY 0.0 /* angle by which to turn polygon, in units of Pi/2 */
#define APOLY_B 0.0 /* angle by which to turn polygon, in units of Pi/2 */
#define MDEPTH 4 /* depth of computation of Menger gasket */
#define MRATIO 3 /* ratio defining Menger gasket */
#define MANDELLEVEL 1000 /* iteration level for Mandelbrot set */
@ -98,8 +113,8 @@
/* Physical parameters of wave equation */
#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 TWOSPEEDS 0 /* set to 1 to replace hardcore boundary by medium with different speed */
#define OSCILLATE_LEFT 0 /* set to 1 to add oscilating boundary condition on the left */
#define OSCILLATE_TOPBOT 0 /* set to 1 to enforce a planar wave on top and bottom boundary */
#define OMEGA 0.0 /* frequency of periodic excitation */
@ -130,10 +145,11 @@
/* Parameters for length and speed of simulation */
#define NSTEPS 3200 /* number of frames of movie */
// #define NSTEPS 100 /* number of frames of movie */
#define NSTEPS 3500 /* 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 200 /* time after which to start saving frames */
#define INITIAL_TIME 150 /* time after which to start saving frames */
#define COMPUTE_ENERGIES 1 /* set to 1 to compute and print energies */
#define BOUNDARY_WIDTH 2 /* width of billiard boundary */
@ -153,20 +169,22 @@
/* Plot type, see list in global_pdes.c */
#define PLOT 0
#define PLOT 4
/* Color schemes */
#define COLOR_PALETTE 0 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE 13 /* 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 0.5 /* 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 2000.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 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 */
@ -175,8 +193,8 @@
#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 DRAW_COLOR_SCHEME 1 /* set to 1 to plot the color scheme */
#define COLORBAR_RANGE 100.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 */
@ -198,153 +216,6 @@ double courant2, courantb2; /* Courant parameters squared */
/* animation part */
/*********************/
void evolve_wave_half_old(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX], double *psi_out[NX],
short int *xy_in[NX])
/* time step of field evolution */
/* phi is value of field at time t, psi at time t-1 */
{
int i, j, iplus, iminus, jplus, jminus, jmid = NY/2;
double delta, x, y, c, cc, gamma;
static long time = 0;
time++;
#pragma omp parallel for private(i,j,iplus,iminus,jplus,jminus,delta,x,y,c,cc,gamma)
for (i=0; i<NX; i++){
for (j=0; j<NY; j++){
if (xy_in[i][j])
{
c = COURANT;
cc = courant2;
gamma = GAMMA;
}
else if (TWOSPEEDS)
{
c = COURANTB;
cc = courantb2;
gamma = GAMMAB;
}
if (((TWOSPEEDS)&&(xy_in[i][j] != 2))||(xy_in[i][j] == 1)){
/* discretized Laplacian for various boundary conditions */
if ((B_COND == BC_DIRICHLET)||(B_COND == BC_ABSORBING)||(B_COND == BC_ABS_REFLECT))
{
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;
else if (jplus == jmid) jplus = jmid-1;
jminus = (j-1);
if (jminus == -1) jminus = 0;
else if (jminus == jmid-1) jminus = jmid;
}
else if (B_COND == BC_PERIODIC)
{
iplus = (i+1) % NX;
iminus = (i-1) % NX;
if (iminus < 0) iminus += NX;
if (j < jmid) /* lower half */
{
jplus = (j+1) % jmid;
jminus = (j-1) % jmid;
if (jminus < 0) jminus += jmid;
}
else /* upper half */
{
jplus = j+1;
if (jplus >= NY) jplus -= jmid;
jminus = j-1;
if (jminus < jmid) 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;
if (j < jmid) /* lower half */
{
jplus = (j+1);
if (jplus >= jmid) jplus -= jmid;
jminus = (j-1);
if (jminus < 0) jminus += jmid;
}
else /* upper half */
{
jplus = j+1;
if (jplus >= NY) jplus -= jmid;
jminus = j-1;
if (jminus < jmid) jminus += jmid;
}
}
/* imposing linear wave on top and bottom by making Laplacian 1d */
if (OSCILLATE_TOPBOT)
{
if (j == NY-1) jminus = NY-1;
else if (j == 0) jplus = 0;
}
delta = phi_in[iplus][j] + phi_in[iminus][j] + phi_in[i][jplus] + phi_in[i][jminus] - 4.0*phi_in[i][j];
x = phi_in[i][j];
y = psi_in[i][j];
/* evolve phi */
if ((B_COND == BC_PERIODIC)||(B_COND == BC_DIRICHLET))
phi_out[i][j] = -y + 2*x + cc*delta - KAPPA*x - gamma*(x-y);
else if ((B_COND == BC_ABSORBING)||(B_COND == BC_ABS_REFLECT))
{
if ((i>0)&&(i<NX-1)&&(j>0)&&(j<NY-1))
phi_out[i][j] = -y + 2*x + cc*delta - KAPPA*x - gamma*(x-y);
/* upper border */
else if (j==NY-1)
phi_out[i][j] = x - c*(x - phi_in[i][NY-2]) - KAPPA_TOPBOT*x - GAMMA_TOPBOT*(x-y);
/* lower border */
else if (j==0)
phi_out[i][j] = x - c*(x - phi_in[i][1]) - KAPPA_TOPBOT*x - GAMMA_TOPBOT*(x-y);
/* right border */
if (i==NX-1)
phi_out[i][j] = x - c*(x - phi_in[NX-2][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
/* left border */
else if (i==0)
phi_out[i][j] = x - c*(x - phi_in[1][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
}
else if (B_COND == BC_VPER_HABS)
{
if ((i>0)&&(i<NX-1))
phi_out[i][j] = -y + 2*x + cc*delta - KAPPA*x - gamma*(x-y);
/* right border */
else if (i==NX-1)
phi_out[i][j] = x - c*(x - phi_in[NX-2][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
/* left border */
else if (i==0)
phi_out[i][j] = x - c*(x - phi_in[1][j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
}
/* add oscillating boundary condition on the left */
if ((i == 0)&&(OSCILLATE_LEFT)) phi_out[i][j] = AMPLITUDE*cos((double)time*OMEGA);
psi_out[i][j] = x;
if (FLOOR)
{
if (phi_out[i][j] > VMAX) phi_out[i][j] = VMAX;
if (phi_out[i][j] < -VMAX) phi_out[i][j] = -VMAX;
if (psi_out[i][j] > VMAX) psi_out[i][j] = VMAX;
if (psi_out[i][j] < -VMAX) psi_out[i][j] = -VMAX;
}
}
}
}
// printf("phi(0,0) = %.3lg, psi(0,0) = %.3lg\n", phi[NX/2][NY/2], psi[NX/2][NY/2]);
}
void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX], double *psi_out[NX],
short int *xy_in[NX])
/* time step of field evolution */
@ -717,6 +588,13 @@ 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);
}
void animation()
{
@ -739,13 +617,14 @@ void animation()
printf("initializing circle configuration\n");
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);
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);
@ -758,6 +637,7 @@ 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)
{
@ -765,6 +645,8 @@ void animation()
top_energy = energies[0] + energies[1] + energies[2];
bottom_energy = energies[3] + energies[4] + energies[5];
}
printf("computed energies\n");
blank();
glColor3f(0.0, 0.0, 0.0);
@ -774,6 +656,8 @@ void animation()
printf("drawing billiard\n");
draw_billiard_comp();
if (DRAW_COLOR_SCHEME) draw_color_bar(PLOT, COLORBAR_RANGE);
glutSwapBuffers();
@ -814,6 +698,8 @@ void animation()
// if (i % 10 == 9) oscillate_linear_wave(0.2*scale, 0.15*(double)(i*NVID + j), -1.5, YMIN, -1.5, YMAX, phi, psi);
}
if (DRAW_COLOR_SCHEME) draw_color_bar(PLOT, COLORBAR_RANGE);
glutSwapBuffers();
if (MOVIE)

View File

@ -49,6 +49,7 @@
#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 -1.777777778
// #define XMAX 1.777777778 /* x interval */
@ -72,12 +73,18 @@
#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 RANDOM_POLY_ANGLE_B 0 /* set to 1 to randomize angle of polygons */
#define XDEP_POLY_ANGLE 0 /* set to 1 to rotate polygons depending on x coordinate */
#define XDEP_POLY_ANGLE_B 1 /* set to 1 to rotate polygons depending on x coordinate */
#define POLY_ROTATION_ANGLE -0.645 /* rotation angle for |x|=1 in units of Pi/2 */
#define LAMBDA 0.75 /* parameter controlling the dimensions of domain */
#define MU 0.03 /* parameter controlling the dimensions of domain */
#define MUB 0.03 /* parameter controlling the dimensions of domain */
#define NPOLY 3 /* number of sides of polygon */
#define APOLY 1.0 /* angle by which to turn polygon, in units of Pi/2 */
#define APOLY_B 0.335 /* angle by which to turn polygon, in units of Pi/2 */
#define MDEPTH 4 /* depth of computation of Menger gasket */
#define MRATIO 3 /* ratio defining Menger gasket */
#define MANDELLEVEL 1000 /* iteration level for Mandelbrot set */
@ -164,6 +171,8 @@
#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 */
#define LOG_SCALE 1.5 /* scaling factor for energy log representation */
#define LOG_SHIFT 1.0 /* shift of colors on log scale */
#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 */