Add files via upload

This commit is contained in:
Nils Berglund 2022-08-20 16:02:07 +02:00 committed by GitHub
parent 731bbc63ea
commit 7cc2823d85
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 3009 additions and 674 deletions

View File

@ -42,7 +42,7 @@
/* Choice of the billiard table, see global_particles.c */
#define B_DOMAIN 15 /* choice of domain shape */
#define B_DOMAIN 1 /* choice of domain shape */
#define CIRCLE_PATTERN 0 /* pattern of circles */
#define POLYLINE_PATTERN 1 /* pattern of polyline */
@ -59,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 */
#define LAMBDA 1.5 /* 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 */
@ -72,13 +72,14 @@
#define DRAW_BILLIARD 1 /* set to 1 to draw billiard */
#define DRAW_CONSTRUCTION_LINES 1 /* set to 1 to draw additional construction lines for billiard */
#define PERIODIC_BC 0 /* set to 1 to enforce periodic boundary conditions when drawing particles */
#define PENROSE_RATIO 2.5 /* parameter controlling the shape of small ellipses in Penrose room */
#define RESAMPLE 0 /* set to 1 if particles should be added when dispersion too large */
#define RESAMPLE 1 /* set to 1 if particles should be added when dispersion too large */
#define NPART 20000 /* number of particles */
#define NPARTMAX 100000 /* maximal number of particles after resampling */
#define NSTEPS 5000 /* number of frames of movie */
#define NSTEPS 5250 /* number of frames of movie */
#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 */
@ -90,25 +91,25 @@
/* simulation parameters */
#define LMAX 0.01 /* minimal segment length triggering resampling */
#define LPERIODIC 0.1 /* lines longer than this are not drawn (useful for Sinai billiard) */
#define LCUT 10000.0 /* controls the max size of segments not considered as being cut */
#define DMIN 0.02 /* minimal distance to boundary for triggering resampling */
#define LMAX 0.1 /* minimal segment length triggering resampling */
#define LPERIODIC 0.5 /* lines longer than this are not drawn (useful for Sinai billiard) */
#define LCUT 10000000.0 /* controls the max size of segments not considered as being cut */
#define DMIN 0.1 /* minimal distance to boundary for triggering resampling */
#define CYCLE 0 /* set to 1 for closed curve (start in all directions) */
#define ORDER_COLORS 1 /* set to 1 if colors should be drawn in order */
#define ORDER_COLORS 0 /* set to 1 if colors should be drawn in order */
/* color and other graphical parameters */
#define COLOR_PALETTE 1 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE 14 /* Color palette, see list in global_pdes.c */
#define NCOLORS 14 /* number of colors */
#define NCOLORS 16 /* number of colors */
#define COLORSHIFT 3 /* hue of initial color */
#define RAINBOW_COLOR 0 /* set to 1 to use different colors for all particles */
#define NSEG 100 /* number of segments of boundary */
#define BILLIARD_WIDTH 4 /* width of billiard */
#define FRONT_WIDTH 4 /* width of wave front */
#define BLACK 0 /* set to 1 for black background */
#define BLACK 1 /* 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) */
@ -119,7 +120,7 @@
#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 END_FRAMES 25 /* number of frames at end of movie */
#define PI 3.141592654
#define DPI 6.283185307
@ -469,11 +470,11 @@ void animation()
for (i=0; i<NPARTMAX; i++)
configs[i] = (double *)malloc(8*sizeof(double));
// init_drop_config(0.1, 0.1, 0.0, DPI, configs);
init_partial_drop_config(0, NPART/4, LAMBDA, 0.0, 0.0, DPI, configs);
init_partial_drop_config(NPART/4, NPART/2, -LAMBDA, 0.0, 0.0, DPI, configs);
init_partial_drop_config(NPART/2, 3*NPART/4, 0.0, LAMBDA, 0.0, DPI, configs);
init_partial_drop_config(3*NPART/4, NPART, 0.0, -LAMBDA, 0.0, DPI, configs);
init_drop_config(0.0, 0.0, 0.0, DPI, configs);
// init_partial_drop_config(0, NPART/4, LAMBDA, 0.0, 0.0, DPI, configs);
// init_partial_drop_config(NPART/4, NPART/2, -LAMBDA, 0.0, 0.0, DPI, configs);
// init_partial_drop_config(NPART/2, 3*NPART/4, 0.0, LAMBDA, 0.0, DPI, configs);
// init_partial_drop_config(3*NPART/4, NPART, 0.0, -LAMBDA, 0.0, DPI, configs);
// init_drop_config(-1.0 + 0.3*sqrt(2.0), -1.0 + 0.5*sqrt(2.0), 0.0, DPI, configs);
// init_drop_config(-0.5, -0.5, 0.0, DPI, configs);
// init_boundary_config(1.5, 1.5, 0.0, PI, configs);

View File

@ -30,6 +30,8 @@
#define POT_COULOMB 2 /* Coulomb (1/r) potential */
#define POT_PERIODIC 3 /* periodic potential */
#define POT_DOUBLE_COULOMB 4 /* sum of Coulomb potentials located at focal points of ellipse */
#define POT_FERMIONS 5 /* two interacting 1D fermions */
#define POT_FERMIONS_PERIODIC 6 /* two interacting 1D fermions on the circle */
/* plot types used by rde */

View File

@ -53,8 +53,13 @@
#define S_CENTRIFUGE_RND 7 /* segments forming centrifuge with more rounded bins */
#define S_CENTRIFUGE_LEAKY 8 /* segments forming centrifuge with rounded bins and holes */
#define S_CIRCLE_EXT 9 /* segments forming a repelling cicle */
#define S_ROCKET_NOZZLE 10 /* segments forming a rocket bell-shpaed nozzle */
#define S_ROCKET_NOZZLE 10 /* segments forming a rocket with bell-shaped nozzle */
#define S_ROCKET_NOZZLE_ROTATED 101 /* rotated version of rocket with bell-shaped nozzle */
#define S_TWO_ROCKETS 102 /* two different rockets, with nozzles specified by NOZZLE_SHAPE and NOZZLE_SHAPE_B */
#define S_TWO_CIRCLES_EXT 11 /* segments forming two repelling cicle */
#define S_DAM 12 /* segments forming a dam that can break */
#define S_DAM_WITH_HOLE 13 /* segments forming a dam in which a hole can open */
#define S_DAM_WITH_HOLE_AND_RAMP 14 /* segments forming a dam in which a hole can open */
/* particle interaction */
@ -83,7 +88,8 @@
#define BC_SCREEN_BINS 12 /* harmonic boundary conditions outside screen area plus "bins" (for Galton board) */
#define BC_BOY 13 /* Boy surface/projective plane (periodic with twisted horizontal and vertical parts) */
#define BC_GENUS_TWO 14 /* surface of genus 2, obtained by identifying opposite sides of an L shape */
#define BC_ABSORBING 20 /* "no-return" boundary conditions outside screen area */
#define BC_ABSORBING 20 /* "no-return" boundary conditions outside BC area */
#define BC_REFLECT_ABS 21 /* reflecting on lower boundary, and "no-return" boundary conditions outside BC area */
/* Regions for partial thermostat couplings */
@ -96,6 +102,15 @@
#define G_INCREASE_RELEASE 1 /* slow increase and instant release */
#define G_INCREASE_DECREASE 2 /* slow increase an decrease */
/* Nozzle shapes */
#define NZ_STRAIGHT 0 /* straight nozzle */
#define NZ_BELL 1 /* bell-shaped nozzle */
#define NZ_GLAS 2 /* glas-shaped nozzle */
#define NZ_CONE 3 /* cone-shaped nozzle */
#define NZ_TRUMPET 4 /* trumpet-shaped nozzle */
#define NZ_NONE 99 /* no nozzle */
/* Plot types */
#define P_KINETIC 0 /* colors represent kinetic energy of particles */
@ -108,6 +123,8 @@
#define P_ANGULAR_SPEED 7 /* colors represent angular speed */
#define P_DIRECT_ENERGY 8 /* hues represent direction, luminosity represents energy */
#define P_DIFF_NEIGHB 9 /* colors represent number of neighbours of different type */
#define P_THERMOSTAT 10 /* colors show which particles are coupled to the thermostat */
#define P_INITIAL_POS 11 /* colors depend on initial position of particle */
/* Color schemes */
@ -163,6 +180,7 @@ typedef struct
double eq_dist; /* equilibrium distance */
double spin_range; /* range of spin-spin interaction */
double spin_freq; /* angular frequency of spin-spin interaction */
double color_hue; /* color hue of particle, for P_INITIAL_POS plot type */
} t_particle;
typedef struct
@ -212,6 +230,7 @@ typedef struct
double nx0, ny0; /* initial normal vector */
double angle01, angle02; /* initial values of angles in which concave corners repel */
double fx, fy; /* x and y-components of force on segment */
short int inactivate; /* set to 1 for segment to become inactive at time SEGMENT_DEACTIVATION_TIME */
} t_segment;
typedef struct

View File

@ -59,6 +59,8 @@
#define D_QRD_ASYM 461 /* asymmetric quadratic resonance diffuser */
#define D_CIRCLE_SEGMENT 47 /* lens-shaped circular segment */
#define D_GROOVE 48 /* groove array supposed to induce polaritons */
#define D_FABRY_PEROT 49 /* Fabry-Perrot cavity (in fact simply a vertical slab) */
#define D_LSHAPE 50 /* L-shaped billiard (surface of genus 2) */
#define NMAXCIRCLES 10000 /* total number of circles/polygons (must be at least NCX*NCY for square grid) */
#define NMAXPOLY 50000 /* maximal number of vertices of polygonal lines (for von Koch et al) */
@ -101,6 +103,7 @@
/* Variable index of refraction */
#define IOR_MANDELBROT 1 /* index of refraction depends on escape time in Mandelbrot set (log) */
#define IOR_MANDELBROT_LIN 100 /* index of refraction depends on escape time in Mandelbrot set (linear) */
#define IOR_EARTH 2 /* index of refraction models speed of seismic waves */
/* Boundary conditions */
@ -109,8 +112,17 @@
#define BC_ABSORBING 2 /* absorbing boundary conditions (beta version) */
#define BC_VPER_HABS 3 /* vertically periodic and horizontally absorbing boundary conditions */
#define BC_ABS_REFLECT 4 /* absorbing boundary conditions, except reflecting at y=0, for comparisons */
#define BC_LSHAPE 10 /* L-shaped boundary conditions (surface of genus 2) */
// #define BC_OSCILL_ABSORB 5 /* oscillating boundary condition on the left, absorbing on other walls */
/* Oscillating boundary conditions */
#define OSC_PERIODIC 0 /* periodic oscillation */
#define OSC_SLOWING 1 /* oscillation of slowing frequency (anti-chirp) */
#define OSC_WAVE_PACKET 2 /* Gaussian wave packet */
#define OSC_CHIRP 3 /* chirp (linearly accelerating frequency) */
/* For debugging purposes only */
// #define FLOOR 0 /* set to 1 to limit wave amplitude to VMAX */
// #define VMAX 10.0 /* max value of wave amplitude */
@ -180,9 +192,13 @@ typedef struct
double posi, posj; /* (i,j) coordinates of vertex */
} t_vertex;
typedef struct
{
int nneighb; /* number of neighbours to compute Laplacian */
double *nghb[4]; /* pointers to neighbours */
} t_laplacian;
// double circlex[NMAXCIRCLES], circley[NMAXCIRCLES], circlerad[NMAXCIRCLES]; /* position and radius of circular scatterers */
// short int circleactive[NMAXCIRCLES]; /* tells which circular scatters are active */
int ncircles = NMAXCIRCLES; /* actual number of circles, can be decreased e.g. for random patterns */
int npolyline = NMAXPOLY; /* actual length of polyline */
@ -190,6 +206,13 @@ t_circle circles[NMAXCIRCLES]; /* circular scatterers */
t_polygon polygons[NMAXCIRCLES]; /* polygonal scatterers */
t_vertex polyline[NMAXPOLY]; /* vertices of polygonal line */
/* the same for comparisons between different domains */
int ncircles_b = NMAXCIRCLES; /* actual number of circles, can be decreased e.g. for random patterns */
int npolyline_b = NMAXPOLY; /* actual length of polyline */
t_circle circles_b[NMAXCIRCLES]; /* circular scatterers */
t_polygon polygons_b[NMAXCIRCLES]; /* polygonal scatterers */
t_vertex polyline_b[NMAXPOLY]; /* vertices of polygonal line */
// double julia_x = -0.5, julia_y = 0.5; /* parameters for Julia sets */
// double julia_x = 0.33267, julia_y = 0.06395; /* parameters for Julia sets */
double julia_x = 0.37468, julia_y = 0.21115; /* parameters for Julia sets */

View File

@ -14,6 +14,7 @@
#define BC_HEX_SITE_DIRICHLET 10 /* hexagonal lattice, site percolation, Dirichlet b.c. */
#define BC_HEX_BOND_DIRICHLET 12 /* hexagonal lattice, bond percolation, Dirichlet b.c. */
#define BC_TRIANGLE_SITE_DIRICHLET 20 /* triangular lattice, site percolation, Dirichlet b.c. */
#define BC_POISSON_DISC 50 /* Poisson disc (blue noise) lattice */
/* Plot types */
@ -22,6 +23,7 @@
#define PLOT_HEX 2 /* plot hexagons */
#define PLOT_TRIANGLE 3 /* plot triangles */
#define PLOT_HEX_BONDS 4 /* plot edges of hexagonal lattice */
#define PLOT_POISSON_DISC 5 /* plot Poisson disc process */
/* Color schemes */
@ -50,17 +52,22 @@
#define COL_TURBO_CYCLIC 101 /* TURBO color palette (by Anton Mikhailov) corrected to be cyclic, beta */
#define NSEG 50 /* number of segments of drawn circles */
#define MAX_NEIGHB 10 /* maximal number of neighbours */
#define NPOISSON_CANDIDATES 30 /* number of candidates in Poisson disc process */
typedef struct
{
double proba; /* probability of being open */
short int nneighb; /* number of neighbours */
int nghb[6]; /* indices of neighbours */
int nghb[MAX_NEIGHB]; /* indices of neighbours */
short int open; /* vertex is open, flooded */
short int flooded; /* vertex is open, flooded */
short int active; /* used in cluster algorithm */
int cluster; /* number of cluster, for search of all clusters */
int previous_cluster; /* number of cluster of previous p, to limit number of color changes */
int tested; /* 1 if the site has been tested for belonging to a cluster */
double x, y; /* coordinates of center, for Poisson disc process */
} t_perco;

11
heat.c
View File

@ -177,6 +177,17 @@
#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 */
/* the following constants are only used by wave_billiard and wave_3d so far */
#define COMPARISON 0 /* set to 1 to compare two different patterns */
#define B_DOMAIN_B 20 /* second domain shape, for comparisons */
#define CIRCLE_PATTERN_B 0 /* second pattern of circles or polygons */
#define OSCILLATION_SCHEDULE 3 /* oscillation schedule, see list in global_pdes.c */
#define ACHIRP 0.2 /* acceleration coefficient in chirp */
#define DAMPING 0.0 /* damping of periodic excitation */
#define OMEGA 0.001 /* frequency of periodic excitation */
#define AMPLITUDE 0.8 /* amplitude of periodic excitation */
/* end of constants only used by wave_billiard and wave_3d */
#include "global_pdes.c"
#include "sub_wave.c"

View File

@ -42,6 +42,7 @@
#define TIME_LAPSE 1 /* set to 1 to add a time-lapse movie at the end */
/* so far incompatible with double movie */
#define TIME_LAPSE_FACTOR 3 /* factor of time-lapse movie */
#define TIME_LAPSE_FIRST 1 /* set to 1 to show time-lapse version first */
/* General geometrical parameters */
@ -53,26 +54,28 @@
#define YMIN -1.125
#define YMAX 1.125 /* y interval for 9/16 aspect ratio */
#define INITXMIN -1.95
#define INITXMAX 1.95 /* x interval for initial condition */
#define INITYMIN -1.05
#define INITYMAX 1.05 /* y interval for initial condition */
#define INITXMIN -2.0
#define INITXMAX -0.04 /* x interval for initial condition */
#define INITYMIN -1.125
#define INITYMAX 0.65 /* y interval for initial condition */
#define BCXMIN -2.0
#define BCXMIN -2.05
#define BCXMAX 2.0 /* x interval for boundary condition */
#define BCYMIN -1.125
#define BCYMAX 1.125 /* y interval for boundary condition */
#define BCYMAX 1.25 /* y interval for boundary condition */
#define OBSXMIN -2.0
#define OBSXMAX 2.0 /* x interval for motion of obstacle */
#define CIRCLE_PATTERN 8 /* pattern of circles, see list in global_ljones.c */
#define CIRCLE_PATTERN 1 /* pattern of circles, see list in global_ljones.c */
#define ADD_FIXED_OBSTACLES 0 /* set to 1 do add fixed circular obstacles */
#define OBSTACLE_PATTERN 3 /* pattern of obstacles, see list in global_ljones.c */
#define ADD_FIXED_SEGMENTS 0 /* set to 1 to add fixed segments as obstacles */
#define SEGMENT_PATTERN 9 /* pattern of repelling segments, see list in global_ljones.c */
#define ADD_FIXED_SEGMENTS 1 /* set to 1 to add fixed segments as obstacles */
#define SEGMENT_PATTERN 14 /* pattern of repelling segments, see list in global_ljones.c */
#define NOZZLE_SHAPE 1 /* shape of nozzle, see list in global_ljones.c */
#define NOZZLE_SHAPE_B 2 /* shape of nozzle for second rocket, see list in global_ljones.c */
#define TWO_TYPES 0 /* set to 1 to have two types of particles */
#define TPYE_PROPORTION 0.7 /* proportion of particles of first type */
@ -88,25 +91,26 @@
#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 4.0 /* minimal distance in Poisson disc process, controls density of particles */
#define PDISC_CANDIDATES 100 /* number of candidates in construction of Poisson disc process */
#define PDISC_DISTANCE 2.5 /* minimal distance in Poisson disc process, controls density of particles */
#define PDISC_CANDIDATES 50 /* number of candidates in construction of Poisson disc process */
#define RANDOM_POLY_ANGLE 0 /* set to 1 to randomize angle of polygons */
#define LAMBDA 0.2 /* parameter controlling the dimensions of domain */
#define MU 0.012 /* parameter controlling radius of particles */
#define LAMBDA 0.8 /* parameter controlling the dimensions of domain */
#define MU 0.0075 /* parameter controlling radius of particles */
#define MU_B 0.018 /* parameter controlling radius of particles of second type */
#define NPOLY 20 /* number of sides of polygon */
#define NPOLY 25 /* number of sides of polygon */
#define APOLY 0.666666666 /* 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 46 /* number of grid point for grid of disks */
#define NGRIDY 24 /* number of grid point for grid of disks */
#define NGRIDX 90 /* number of grid point for grid of disks */
#define NGRIDY 100 /* number of grid point for grid of disks */
#define EHRENFEST_RADIUS 0.9 /* radius of container for Ehrenfest urn configuration */
#define EHRENFEST_WIDTH 0.035 /* width of tube for Ehrenfest urn configuration */
#define TWO_CIRCLES_RADIUS_RATIO 0.8 /* ratio of radii for S_TWO_CIRCLES_EXT segment configuration */
#define DAM_WIDTH 0.05 /* width of dam for S_DAM segment configuration */
#define X_SHOOTER -0.2
#define Y_SHOOTER -0.6
@ -115,11 +119,11 @@
/* Parameters for length and speed of simulation */
#define NSTEPS 3000 /* number of frames of movie */
#define NVID 80 /* number of iterations between images displayed on screen */
#define NSEG 150 /* number of segments of boundary */
#define INITIAL_TIME 100 /* time after which to start saving frames */
#define OBSTACLE_INITIAL_TIME 50 /* time after which to start moving obstacle */
#define NSTEPS 3500 /* number of frames of movie */
#define NVID 60 /* number of iterations between images displayed on screen */
#define NSEG 250 /* number of segments of boundary */
#define INITIAL_TIME 0 /* time after which to start saving frames */
#define OBSTACLE_INITIAL_TIME 10 /* time after which to start moving obstacle */
#define BOUNDARY_WIDTH 1 /* width of particle boundary */
#define LINK_WIDTH 2 /* width of links between particles */
#define CONTAINER_WIDTH 4 /* width of container boundary */
@ -137,12 +141,12 @@
/* Plot type, see list in global_ljones.c */
#define PLOT 0
#define PLOT_B 8 /* plot type for second movie */
#define PLOT 11
#define PLOT_B 0 /* plot type for second movie */
#define DRAW_BONDS 0 /* set to 1 to draw bonds between neighbours */
#define DRAW_BONDS 1 /* set to 1 to draw bonds between neighbours */
#define COLOR_BONDS 1 /* set to 1 to color bonds according to length */
#define FILL_TRIANGLES 0 /* set to 1 to fill triangles between neighbours */
#define FILL_TRIANGLES 1 /* set to 1 to fill triangles between neighbours */
/* Color schemes */
@ -171,17 +175,17 @@
#define PARTICLE_HUE_MAX 0.0 /* color of saturated particle */
#define PARTICLE_EMAX 1.0e3 /* energy of particle with hottest color */
#define HUE_TYPE0 280.0 /* hue of particles of type 0 */
#define HUE_TYPE1 70.0 /* hue of particles of type 1 */
#define HUE_TYPE2 180.0 /* hue of particles of type 2 */
#define HUE_TYPE1 70.0 /* hue of particles of type 1 */
#define HUE_TYPE2 70.0 /* hue of particles of type 2 */
#define HUE_TYPE3 210.0 /* hue of particles of type 3 */
#define RANDOM_RADIUS 0 /* set to 1 for random circle radius */
#define DT_PARTICLE 3.0e-6 /* time step for particle displacement */
#define KREPEL 12.0 /* constant in repelling force between particles */
#define EQUILIBRIUM_DIST 5.0 /* Lennard-Jones equilibrium distance */
#define EQUILIBRIUM_DIST 3.5 /* Lennard-Jones equilibrium distance */
#define EQUILIBRIUM_DIST_B 3.5 /* Lennard-Jones equilibrium distance for second type of particle */
#define REPEL_RADIUS 20.0 /* radius in which repelling force acts (in units of particle radius) */
#define DAMPING 25.0 /* damping coefficient of particles */
#define DAMPING 10.0 /* damping coefficient of particles */
#define PARTICLE_MASS 1.0 /* mass of particle of radius MU */
#define PARTICLE_MASS_B 1.0 /* mass of particle of radius MU */
#define PARTICLE_INERTIA_MOMENT 0.2 /* moment of inertia of particle */
@ -189,18 +193,19 @@
#define V_INITIAL 0.0 /* initial velocity range */
#define OMEGA_INITIAL 10.0 /* initial angular velocity range */
#define THERMOSTAT 1 /* set to 1 to switch on thermostat */
#define THERMOSTAT 0 /* set to 1 to switch on thermostat */
#define VARY_THERMOSTAT 0 /* set to 1 for time-dependent thermostat schedule */
#define SIGMA 5.0 /* noise intensity in thermostat */
#define BETA 0.1 /* initial inverse temperature */
#define BETA 0.02 /* initial inverse temperature */
#define MU_XI 0.01 /* friction constant in thermostat */
#define KSPRING_BOUNDARY 1.0e11 /* confining harmonic potential outside simulation region */
#define KSPRING_OBSTACLE 1.0e11 /* harmonic potential of obstacles */
#define NBH_DIST_FACTOR 6.0 /* radius in which to count neighbours */
#define GRAVITY 1000.0 /* gravity acting on all particles */
#define NBH_DIST_FACTOR 7.0 /* radius in which to count neighbours */
#define GRAVITY 2000.0 /* gravity acting on all particles */
#define GRAVITY_X 0.0 /* gravity acting on all particles */
#define INCREASE_GRAVITY 0 /* set to 1 to increase gravity during the simulation */
#define GRAVITY_SCHEDULE 2 /* type of gravity schedule, see list in global_ljones.c */
#define GRAVITY_FACTOR 50.0 /* factor by which to increase gravity */
#define GRAVITY_FACTOR 100.0 /* factor by which to increase gravity */
#define GRAVITY_INITIAL_TIME 200 /* time at start of simulation with constant gravity */
#define GRAVITY_RESTORE_TIME 700 /* time at end of simulation with gravity restored to initial value */
@ -217,11 +222,13 @@
#define SPIN_RANGE_B 5.0 /* range of spin-spin interaction for second type of particle */
#define QUADRUPOLE_RATIO 0.6 /* anisotropy in quadrupole potential */
#define INCREASE_BETA 1 /* set to 1 to increase BETA during simulation */
#define BETA_FACTOR 0.02 /* factor by which to change BETA during simulation */
#define INCREASE_BETA 0 /* set to 1 to increase BETA during simulation */
#define BETA_FACTOR 0.01 /* factor by which to change BETA during simulation */
#define N_TOSCILLATIONS 1.5 /* number of temperature oscillations in BETA schedule */
#define NO_OSCILLATION 1 /* set to 1 to have exponential BETA change only */
#define FINAL_CONSTANT_PHASE 0 /* final phase in which temperature is constant */
#define MIDDLE_CONSTANT_PHASE 370 /* final phase in which temperature is constant */
#define FINAL_DECREASE_PHASE 350 /* final phase in which temperature decreases */
#define FINAL_CONSTANT_PHASE 1180 /* final phase in which temperature is constant */
#define DECREASE_CONTAINER_SIZE 0 /* set to 1 to decrease size of container */
#define SYMMETRIC_DECREASE 0 /* set tp 1 to decrease container symmetrically */
@ -243,7 +250,7 @@
#define N_T_AVERAGE 50 /* size of temperature averaging window */
#define MAX_PRESSURE 3.0e10 /* pressure shown in "hottest" color */
#define PARTIAL_THERMO_COUPLING 1 /* set to 1 to couple only particles to the right of obstacle to thermostat */
#define PARTIAL_THERMO_REGION 2 /* region for partial thermostat coupling (see list in global_ljones.c) */
#define PARTIAL_THERMO_REGION 1 /* region for partial thermostat coupling (see list in global_ljones.c) */
#define PARTIAL_THERMO_SHIFT 0.2 /* distance from obstacle at the right of which particles are coupled to thermostat */
#define PARTIAL_THERMO_WIDTH 0.5 /* vertical size of partial thermostat coupling */
#define PARTIAL_THERMO_HEIGHT 0.2 /* vertical size of partial thermostat coupling */
@ -279,11 +286,15 @@
#define PRINT_SEGMENTS_SPEEDS 0 /* set to 1 to print velocity of moving segments */
#define MOVE_BOUNDARY 0 /* set to 1 to move repelling segments, due to force from particles */
#define SEGMENTS_MASS 5.0 /* mass of collection of segments */
#define DEACTIVATE_SEGMENT 0 /* set to 1 to deactivate last segment after a certain time */
#define SEGMENT_DEACTIVATION_TIME 1000 /* time at which to deactivate last segment */
#define SEGMENTS_X0 0.0 /* initial position of segments */
#define SEGMENTS_Y0 -0.75 /* initial position of segments */
#define SEGMENTS_MASS 40.0 /* mass of collection of segments */
#define DEACTIVATE_SEGMENT 1 /* set to 1 to deactivate last segment after a certain time */
#define SEGMENT_DEACTIVATION_TIME 500 /* time at which to deactivate last segment */
#define RELEASE_ROCKET_AT_DEACTIVATION 0 /* set to 1 to limit segments velocity before segment release */
#define SEGMENTS_X0 0.0 /* initial position of segments */
#define SEGMENTS_Y0 1.5 /* initial position of segments */
#define SEGMENTS_VX0 0.0 /* initial velocity of segments */
#define SEGMENTS_VY0 -4.0 /* initial velocity of segments */
#define DAMP_SEGS_AT_NEGATIVE_Y 0 /* set to 1 to dampen segments when y coordinate is negative */
#define POSITION_DEPENDENT_TYPE 0 /* set to 1 to make particle type depend on initial position */
#define POSITION_Y_DEPENDENCE 0 /* set to 1 for the separation between particles to be vertical */
@ -311,8 +322,8 @@
#define FLOOR_OMEGA 0 /* set to 1 to limit particle momentum to PMAX */
#define PMAX 1000.0 /* maximal force */
#define HASHX 60 /* size of hashgrid in x direction */
#define HASHY 30 /* size of hashgrid in y direction */
#define HASHX 160 /* size of hashgrid in x direction */
#define HASHY 80 /* 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 */
@ -323,7 +334,7 @@
#define NO_WRAP_BC ((BOUNDARY_COND != BC_PERIODIC)&&(BOUNDARY_COND != BC_PERIODIC_CIRCLE)&&(BOUNDARY_COND != BC_PERIODIC_TRIANGLE)&&(BOUNDARY_COND != BC_KLEIN)&&(BOUNDARY_COND != BC_PERIODIC_FUNNEL)&&(BOUNDARY_COND != BC_BOY)&&(BOUNDARY_COND != BC_GENUS_TWO))
#define PERIODIC_BC ((BOUNDARY_COND == BC_PERIODIC)||(BOUNDARY_COND == BC_PERIODIC_CIRCLE)||(BOUNDARY_COND == BC_PERIODIC_FUNNEL)||(BOUNDARY_COND == BC_PERIODIC_TRIANGLE))
#define TWO_OBSTACLES (SEGMENT_PATTERN == S_TWO_CIRCLES_EXT)
#define TWO_OBSTACLES ((SEGMENT_PATTERN == S_TWO_CIRCLES_EXT)||(SEGMENT_PATTERN == S_TWO_ROCKETS))
double xshift = 0.0; /* x shift of shown window */
double xspeed = 0.0; /* x speed of obstacle */
@ -334,8 +345,8 @@ double vxwall = 0.0; /* x speed of wall (for BC_RECTANGLE_WALL b.c.) */
double angular_speed = 0.0; /* angular speed of rotating segments */
double xsegments[2] = {SEGMENTS_X0, -SEGMENTS_X0}; /* x coordinate of segments (for option MOVE_BOUNDARY) */
double ysegments[2] = {SEGMENTS_Y0, SEGMENTS_Y0}; /* y coordinate of segments (for option MOVE_BOUNDARY) */
double vxsegments[2] = {0.0, 0.0}; /* vx coordinate of segments (for option MOVE_BOUNDARY) */
double vysegments[2] = {0.0, 0.0}; /* vy coordinate of segments (for option MOVE_BOUNDARY) */
double vxsegments[2] = {SEGMENTS_VX0, SEGMENTS_VX0}; /* vx coordinate of segments (for option MOVE_BOUNDARY) */
double vysegments[2] = {SEGMENTS_VY0, SEGMENTS_VY0}; /* vy coordinate of segments (for option MOVE_BOUNDARY) */
int thermostat_on = 1; /* thermostat switch used when VARY_THERMOSTAT is on */
#define THERMOSTAT_ON ((THERMOSTAT)&&((!VARY_THERMOSTAT)||(thermostat_on)))
@ -369,23 +380,32 @@ double repel_schedule(int i)
double temperature_schedule(int i)
{
static double bexponent, omega;
static int first = 1;
static double bexponent, omega, bexp2;
static int first = 1, t1, t2, t3;
double beta;
if (first)
{
bexponent = log(BETA_FACTOR)/(double)(NSTEPS - FINAL_CONSTANT_PHASE);
omega = N_TOSCILLATIONS*DPI/(double)(NSTEPS - FINAL_CONSTANT_PHASE);
t1 = NSTEPS - MIDDLE_CONSTANT_PHASE - FINAL_DECREASE_PHASE - FINAL_CONSTANT_PHASE;
t2 = NSTEPS - FINAL_DECREASE_PHASE - FINAL_CONSTANT_PHASE;
t3 = NSTEPS - FINAL_CONSTANT_PHASE;
bexponent = log(BETA_FACTOR)/(double)(t1);
omega = N_TOSCILLATIONS*DPI/(double)(t1);
bexp2 = -log(BETA_FACTOR)/(double)(FINAL_DECREASE_PHASE);
first = 0;
}
if (i < INITIAL_TIME) beta = BETA;
else if (i > INITIAL_TIME + NSTEPS - FINAL_CONSTANT_PHASE) beta = BETA*BETA_FACTOR;
else
else if (i < INITIAL_TIME + t1)
{
beta = BETA*exp(bexponent*(double)(i - INITIAL_TIME));
if (!NO_OSCILLATION) beta = beta*2.0/(1.0 + cos(omega*(double)(i - INITIAL_TIME)));
}
else if (i < INITIAL_TIME + t2) beta = BETA*BETA_FACTOR;
else if (i < INITIAL_TIME + t3)
{
beta = BETA*exp(bexp2*(double)(i - INITIAL_TIME - t3));
}
else beta = BETA;
printf("beta = %.3lg\n", beta);
return(beta);
}
@ -720,10 +740,12 @@ void evolve_wall(double fboundary)
}
void evolve_segments(t_segment segment[NMAXSEGMENTS])
void evolve_segments(t_segment segment[NMAXSEGMENTS], int time)
{
int i, nactive = 0, group;
double fx[2] = {0.0, 0.0}, fy[2] = {0.0, 0.0}, x, y, padding = 3.0*MU, mass2 = SEGMENTS_MASS*TWO_CIRCLES_RADIUS_RATIO;
double fx[2] = {0.0, 0.0}, fy[2] = {0.0, 0.0}, x, y, padding = 3.0*MU, mass2 = SEGMENTS_MASS;
if (SEGMENT_PATTERN == S_TWO_CIRCLES_EXT) mass2 = SEGMENTS_MASS*TWO_CIRCLES_RADIUS_RATIO;
for (group=0; group<2; group++)
{
@ -745,6 +767,11 @@ void evolve_segments(t_segment segment[NMAXSEGMENTS])
if (y < YMIN + padding) fy[group] += KSPRING_BOUNDARY*(YMIN + padding - y);
else if (y > YMAX - padding) fy[group] -= KSPRING_BOUNDARY*(y - YMAX + padding);
}
else if (BOUNDARY_COND == BC_REFLECT_ABS) /* add force from simulation boundary */
{
y = 0.5*(segment[i].y1 + segment[i].y2);
if (y < YMIN) fy[group] += KSPRING_BOUNDARY*(YMIN - y);
}
if (group == 0) fy[group] -= GRAVITY*SEGMENTS_MASS;
else fy[group] -= GRAVITY*mass2;
}
@ -778,12 +805,31 @@ void evolve_segments(t_segment segment[NMAXSEGMENTS])
xsegments[1] += vxsegments[1]*DT_PARTICLE;
ysegments[1] += vysegments[1]*DT_PARTICLE;
}
/* add some damping if y coordinate is small (for lunar landing) */
if (DAMP_SEGS_AT_NEGATIVE_Y)
for (group=0; group<2; group++)
if (ysegments[group] < 0.1)
{
vysegments[group] *= exp(-DAMPING*DT_PARTICLE);
vxsegments[group] *= exp(-DAMPING*DT_PARTICLE);
}
/* to avoid numerical instabilities */
for (group=0; group<2; group++) if (xsegments[group] + 1.0 > BCXMAX)
for (group=0; group<2; group++)
{
xsegments[group] = BCXMAX - 1.0;
vxsegments[group] = 0.0;
if (xsegments[group] + 1.0 > BCXMAX)
{
xsegments[group] = BCXMAX - 1.0;
vxsegments[group] = 0.0;
}
if ((RELEASE_ROCKET_AT_DEACTIVATION)&&((BOUNDARY_COND == BC_REFLECT_ABS)||(BOUNDARY_COND == BC_ABSORBING)))
{
// ysegments[group] = SEGMENTS_Y0;
if (time < SEGMENT_DEACTIVATION_TIME) vysegments[group] = 0.0;
else if ((ysegments[group] < SEGMENTS_Y0)&&(vysegments[group] < 0.0))
vysegments[group] = -0.5*vysegments[group];
}
}
translate_segments(segment, xsegments, ysegments);
@ -876,8 +922,9 @@ void animation()
thermostat_on = thermostat_schedule(i);
printf("Termostat: %i\n", thermostat_on);
}
if ((ADD_FIXED_SEGMENTS)&&(DEACTIVATE_SEGMENT)&&(i > INITIAL_TIME + SEGMENT_DEACTIVATION_TIME))
segment[nsegments-1].active = 0;
/* deactivate some segments */
if ((ADD_FIXED_SEGMENTS)&&(DEACTIVATE_SEGMENT)&&(i == INITIAL_TIME + SEGMENT_DEACTIVATION_TIME + 1))
for (j=0; j<nsegments; j++) if (segment[j].inactivate) segment[j].active = 0;
blank();
@ -923,9 +970,13 @@ void animation()
fboundary += compute_boundary_force(j, particle, obstacle, segment, xmincontainer, xmaxcontainer, &pleft, &pright, pressure, wall);
/* add gravity */
if (INCREASE_GRAVITY) particle[j].fy -= gravity;
else particle[j].fy -= GRAVITY;
if (INCREASE_GRAVITY) particle[j].fy -= gravity/particle[j].mass_inv;
else
{
particle[j].fy -= GRAVITY/particle[j].mass_inv;
particle[j].fx += GRAVITY_X/particle[j].mass_inv;
}
if (FLOOR_FORCE)
{
if (particle[j].fx > FMAX) particle[j].fx = FMAX;
@ -947,7 +998,7 @@ void animation()
if (i < INITIAL_TIME + WALL_TIME) evolve_wall(fboundary);
else xwall = 0.0;
}
if ((MOVE_BOUNDARY)&&(i > OBSTACLE_INITIAL_TIME)) evolve_segments(segment);
if ((MOVE_BOUNDARY)&&(i > OBSTACLE_INITIAL_TIME)) evolve_segments(segment, i);
} /* end of for (n=0; n<NVID; n++) */
// printf("evolved particles\n");
@ -1051,10 +1102,21 @@ void animation()
{
if (i >= INITIAL_TIME)
{
save_frame_lj();
if ((TIME_LAPSE)&&((i - INITIAL_TIME)%TIME_LAPSE_FACTOR == 0)&&(!DOUBLE_MOVIE))
if (TIME_LAPSE_FIRST)
{
save_frame_lj_counter(NSTEPS + END_FRAMES + (i - INITIAL_TIME)/TIME_LAPSE_FACTOR);
if ((TIME_LAPSE)&&((i - INITIAL_TIME)%TIME_LAPSE_FACTOR == 0)&&(!DOUBLE_MOVIE))
{
save_frame_lj();
}
save_frame_lj_counter(NSTEPS/TIME_LAPSE_FACTOR + MID_FRAMES + i - INITIAL_TIME);
}
else
{
save_frame_lj();
if ((TIME_LAPSE)&&((i - INITIAL_TIME)%TIME_LAPSE_FACTOR == 0)&&(!DOUBLE_MOVIE))
{
save_frame_lj_counter(NSTEPS + END_FRAMES + (i - INITIAL_TIME)/TIME_LAPSE_FACTOR);
}
}
}
else printf("Initial phase time %i of %i\n", i, INITIAL_TIME);
@ -1120,10 +1182,13 @@ void animation()
else if (PRINT_SEGMENTS_SPEEDS) print_segments_speeds(vxsegments, vysegments);
glutSwapBuffers();
}
for (i=0; i<END_FRAMES; i++) save_frame_lj_counter(NSTEPS + MID_FRAMES + 1 + counter + i);
if ((TIME_LAPSE)&&(!DOUBLE_MOVIE))
for (i=0; i<END_FRAMES; i++) save_frame_lj_counter(NSTEPS + END_FRAMES + NSTEPS/TIME_LAPSE_FACTOR + i);
{
for (i=0; i<END_FRAMES; i++)
save_frame_lj_counter(NSTEPS + MID_FRAMES + NSTEPS/TIME_LAPSE_FACTOR + i);
}
else for (i=0; i<END_FRAMES; i++) save_frame_lj_counter(NSTEPS + MID_FRAMES + 1 + counter + i);
s = system("mv lj*.tif tif_ljones/");
}

View File

@ -226,6 +226,15 @@
#define FLOOR 1 /* set to 1 to limit wave amplitude to VMAX */
#define VMAX 10.0 /* max value of wave amplitude */
/* the following constants are only used by wave_billiard and wave_3d so far */
#define COMPARISON 0 /* set to 1 to compare two different patterns */
#define B_DOMAIN_B 20 /* second domain shape, for comparisons */
#define CIRCLE_PATTERN_B 0 /* second pattern of circles or polygons */
#define OSCILLATION_SCHEDULE 3 /* oscillation schedule, see list in global_pdes.c */
#define ACHIRP 0.2 /* acceleration coefficient in chirp */
#define DAMPING 0.0 /* damping of periodic excitation */
/* end of constants only used by wave_billiard and wave_3d */
#include "global_pdes.c"
#include "sub_wave.c"
#include "wave_common.c"
@ -867,8 +876,8 @@ void animation()
hashgrid_mangroves = (int *)malloc(HASHX*HASHY*HASHMAX*sizeof(int)); /* numbers of mangroves in each hash grid cell */
/* initialise positions and radii of circles */
if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN == D_CIRCLES_IN_RECT)) init_circle_config(circles);
else if (B_DOMAIN == D_POLYGONS) init_polygon_config(polygons);
if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN == D_CIRCLES_IN_RECT)) ncircles = init_circle_config(circles);
else if (B_DOMAIN == D_POLYGONS) ncircles = init_polygon_config(polygons);
@ -1294,5 +1303,4 @@ int main(int argc, char** argv)
glutMainLoop();
return 0;
}
}

View File

@ -33,19 +33,28 @@
#define MOVIE 0 /* set to 1 to generate movie */
#define WINWIDTH 720 /* window width */
#define WINWIDTH 1280 /* window width */
#define WINHEIGHT 720 /* window height */
#define XMIN -1.125
#define XMAX 1.125 /* x interval */
#define XMIN -2.0
#define XMAX 2.0 /* x interval */
#define YMIN -1.125
#define YMAX 1.125 /* y interval for 9/16 aspect ratio */
// #define WINWIDTH 1920 /* window width */
// #define WINHEIGHT 1000 /* window height */
//
// #define XMIN -2.0
// #define XMAX 2.0 /* x interval */
// #define YMIN -1.041666667
// #define YMAX 1.041666667 /* y interval for 9/16 aspect ratio */
#define SCALING_FACTOR 1.0 /* scaling factor of drawing, needed for flower billiards, otherwise set to 1.0 */
/* Choice of the billiard table, see global_particles.c */
#define B_DOMAIN 30 /* choice of domain shape */
#define B_DOMAIN 16 /* choice of domain shape */
#define CIRCLE_PATTERN 1 /* pattern of circles */
#define POLYLINE_PATTERN 8 /* pattern of polyline */
@ -54,6 +63,8 @@
#define NMAXCIRCLES 100000 /* total number of circles (must be at least NCX*NCY for square grid) */
#define NMAXPOLY 100000 /* total number of sides of polygonal line */
// #define NCX 10 /* number of circles in x direction */
// #define NCY 10 /* number of circles in y direction */
#define NCX 30 /* number of circles in x direction */
#define NCY 20 /* number of circles in y direction */
#define NPOISSON 500 /* number of points for Poisson C_RAND_POISSON arrangement */
@ -61,10 +72,12 @@
#define SDEPTH 1 /* Sierpinski gastket depth */
#define LAMBDA 1.5 /* parameter controlling shape of domain */
#define MU 0.01 /* second parameter controlling shape of billiard */
#define MU 0.5 /* 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 */
#define PENROSE_RATIO 2.5 /* parameter controlling the shape of small ellipses in Penrose room */
#define DRAW_BILLIARD 1 /* set to 1 to draw billiard */
#define DRAW_CONSTRUCTION_LINES 0 /* set to 1 to draw additional construction lines for billiard */
#define PERIODIC_BC 0 /* set to 1 to enforce periodic boundary conditions when drawing particles */
@ -74,21 +87,23 @@
/* Simulation parameters */
#define NPART 5000 /* number of particles */
#define NPART 16 /* number of particles */
// #define NPART 2000 /* 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 SHOWZOOM 1 /* set to 1 to show zoom on specific area */
#define PRINT_PARTICLE_NUMBER 1 /* set to 1 to print number of particles */
#define SHOWTRAILS 1 /* set to 1 to keep trails of the particles */
#define SHOWZOOM 0 /* 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 0 /* set to 1 to print number of collisions */
#define TEST_ACTIVE 1 /* set to 1 to test whether particle is in billiard */
#define NSTEPS 1000 /* number of frames of movie */
#define TIME 2500 /* time between movie frames, for fluidity of real-time simulation */
#define NSTEPS 5250 /* number of frames of movie */
#define TIME 750 /* time between movie frames, for fluidity of real-time simulation */
#define DPHI 0.00001 /* integration step */
#define NVID 100 /* number of iterations between images displayed on screen */
#define NVID 25 /* number of iterations between images displayed on screen */
// #define NVID 100 /* number of iterations between images displayed on screen */
#define END_FRAMES 25 /* number of still frames at the end of the movie */
/* Decreasing TIME accelerates the animation and the movie */
@ -99,14 +114,15 @@
/* Colors and other graphical parameters */
#define COLOR_PALETTE 17 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE 14 /* Color palette, see list in global_pdes.c */
#define NCOLORS 64 /* number of colors */
#define NCOLORS 16 /* number of colors */
#define COLORSHIFT 0 /* hue of initial color */
#define RAINBOW_COLOR 1 /* set to 1 to use different colors for all particles */
#define 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.03 /* length of velocity vectors */
#define LENGTH 0.005 /* length of velocity vectors */
// #define LENGTH 0.03 /* 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 */

View File

@ -79,6 +79,7 @@
#define DRAW_BILLIARD 1 /* set to 1 to draw billiard */
#define DRAW_CONSTRUCTION_LINES 0 /* set to 1 to draw additional construction lines for billiard */
#define PERIODIC_BC 0 /* set to 1 to enforce periodic boundary conditions when drawing particles */
#define PENROSE_RATIO 2.5 /* parameter controlling the shape of small ellipses in Penrose room */
#define RESAMPLE 0 /* set to 1 if particles should be added when dispersion too large */
#define DEBUG 0 /* draw trajectories, for debugging purposes */

View File

@ -39,7 +39,7 @@
#include <omp.h>
#include <time.h>
#define MOVIE 0 /* set to 1 to generate movie */
#define MOVIE 1 /* set to 1 to generate movie */
/* General geometrical parameters */
@ -68,25 +68,22 @@
/* Boundary conditions, see list in global_pdes.c */
#define LATTICE 10
#define LATTICE 2
#define FLOOD_LEFT_BOUNDARY 1 /* set to 1 to flood cells on left boundary */
#define FIND_ALL_CLUSTERS 0 /* set to 1 to find all open clusters */
#define FLOOD_LEFT_BOUNDARY 0 /* set to 1 to flood cells on left boundary */
#define FIND_ALL_CLUSTERS 1 /* set to 1 to find all open clusters */
#define PLOT_CLUSTER_SIZE 1 /* set to 1 to add a plot for the size of the percolation cluster */
#define PLOT_CLUSTER_SIZE 0 /* set to 1 to add a plot for the size of the percolation cluster */
#define PLOT_CLUSTER_NUMBER 0 /* set to 1 to add a graph of the number of clusters */
#define PLOT_CLUSTER_HISTOGRAM 0 /* set to 1 to add a histogram of the number of clusters */
#define PRINT_LARGEST_CLUSTER_SIZE 0 /* set to 1 to print size of largest cluster */
#define PLOT_CLUSTER_HISTOGRAM 1 /* set to 1 to add a histogram of the number of clusters */
#define PRINT_LARGEST_CLUSTER_SIZE 1 /* set to 1 to print size of largest cluster */
#define MAX_CLUSTER_NUMBER 6 /* vertical scale of the cluster number plot */
#define HISTO_BINS 30 /* number of bins in histrogram */
#define HISTO_BINS 30 /* number of bins in histogram */
#define NSTEPS 1270 /* number of frames of movie */
#define DEBUG 0 /* set to 1 for some debugging features */
#define DEBUG_SLEEP_TIME 1 /* sleep time between frames when debugging */
#define TEST_GRAPH 0 /* set to 1 to test graph connectivity matrix */
#define TEST_START 2210 /* start position of connectivity test */
#define NSTEPS 100 /* number of frames of movie */
// #define NSTEPS 700 /* number of frames of movie */
// #define NSTEPS 830 /* number of frames of movie */
#define PAUSE 200 /* number of frames after which to pause */
#define PSLEEP 2 /* sleep time during pause */
@ -102,19 +99,19 @@
#define BLACK 1 /* background */
#define COLOR_CLUSTERS_BY_SIZE 0 /* set to 1 to link cluster color to their size */
#define COLOR_CLUSTERS_BY_SIZE 1 /* set to 1 to link cluster color to their size */
#define SCALE 0 /* set to 1 to adjust color scheme to variance of field */
#define SLOPE 1.0 /* sensitivity of color on wave amplitude */
#define ATTENUATION 0.0 /* exponential attenuation coefficient of contrast with time */
#define HUE_CLOSED 330.0 /* color hue of closed cells */
#define HUE_CLOSED 350.0 /* color hue of closed cells */
#define HUE_OPEN 200.0 /* color hue of open (dry) cells */
#define HUE_FLOODED 45.0 /* color hue of open flooded cells */
#define HUE_GRAPH 150.0 /* color hue in graph of cluster size */
#define HUE_GRAPH 250.0 /* color hue in graph of cluster size */
#define CLUSTER_HUEMIN 0.0 /* minimal color hue of clusters */
#define CLUSTER_HUEMAX 250.0 /* maximal color hue of clusters */
#define CLUSTER_HUEMIN 60.0 /* minimal color hue of clusters */
#define CLUSTER_HUEMAX 300.0 /* maximal color hue of clusters */
#define N_CLUSTER_COLORS 20 /* number of different colors of clusters */
#define COLORHUE 260 /* initial hue of water color for scheme C_LUM */
@ -124,6 +121,13 @@
#define HUEMEAN 180.0 /* mean value of hue for color scheme C_HUE */
#define HUEAMP -180.0 /* amplitude of variation of hue for color scheme C_HUE */
/* debugging options */
#define VERBOSE 0 /* set to 1 to print more messages in shell */
#define DEBUG 0 /* set to 1 for some debugging features */
#define DEBUG_SLEEP_TIME 1 /* sleep time between frames when debugging */
#define TEST_GRAPH 0 /* set to 1 to test graph connectivity matrix */
#define TEST_START 2210 /* start position of connectivity test */
#define ADD_PLOT ((PLOT_CLUSTER_SIZE)||(PLOT_CLUSTER_NUMBER)||(PLOT_CLUSTER_HISTOGRAM))
#define FIND_CLUSTER_SIZES ((COLOR_CLUSTERS_BY_SIZE)||(PLOT_CLUSTER_HISTOGRAM))
@ -134,8 +138,9 @@
void animation(int size)
{
int i, j, k, s, nx, ny, ncells, nmaxcells, maxsize, nopen, nflooded, nstack, nclusters, maxclustersize = 0, maxclusterlabel;
int i, j, k, s, nx, ny, nmaxcells, maxsize, nopen, nflooded, nstack, nclusters, maxclustersize = 0, maxclusterlabel;
int *plot_cluster_number, *cluster_sizes;
int ncells;
double p, *plot_cluster_size;
t_perco *cell;
t_perco **pstack;
@ -147,10 +152,12 @@ void animation(int size)
cell = (t_perco *)malloc(nmaxcells*sizeof(t_perco));
if (PLOT_CLUSTER_SIZE) plot_cluster_size = (double *)malloc(NSTEPS*sizeof(double));
if (PLOT_CLUSTER_NUMBER) plot_cluster_number = (int *)malloc(NSTEPS*sizeof(double));
if (FIND_CLUSTER_SIZES) cluster_sizes = (int *)malloc(2*nmaxcells*sizeof(int));
// if (FIND_CLUSTER_SIZES)
cluster_sizes = (int *)malloc(2*nmaxcells*sizeof(int));
ncells = init_cell_lattice(cell, nx, ny);
printf("nx = %i, ny = %i, ncells = %i\n", nx, ny, ncells);
printf("nx = %i, ny = %i, ncells = %i, maxcells = %i\n", nx, ny, ncells, nmaxcells);
pstack = (t_perco* *)malloc(ncells*sizeof(struct t_perco *));
if (TEST_GRAPH) test_neighbours(TEST_START, cell, nx, ny, size, ncells);
@ -164,11 +171,17 @@ void animation(int size)
init_cell_state(cell, p, ncells, (i == 0));
if (FLOOD_LEFT_BOUNDARY) nstack = init_flooded_cells(cell, nx, ny, pstack);
if (FLOOD_LEFT_BOUNDARY) nstack = init_flooded_cells(cell, ncells, nx, ny, pstack);
nopen = count_open_cells(cell, ncells);
if (FLOOD_LEFT_BOUNDARY) nflooded = find_percolation_cluster(cell, ncells, pstack, nstack);
printf("Flooded cells, %i open cells, nstack = %i\n", nopen, nstack);
if (FLOOD_LEFT_BOUNDARY)
{
nflooded = find_percolation_cluster(cell, ncells, pstack, nstack);
printf("Found percolation cluster with %i flooded cells\n", nflooded);
}
if (FIND_ALL_CLUSTERS)
{
nclusters = find_all_clusters(cell, ncells, (i == 0), &maxclusterlabel);
@ -183,7 +196,7 @@ void animation(int size)
// print_cluster_sizes(cell, ncells, cluster_sizes);
draw_configuration(cell, cluster_sizes, nx, ny, size, ncells);
draw_configuration(cell, cluster_sizes, ncells, nx, ny, size, ncells);
print_p(p);
if (PRINT_LARGEST_CLUSTER_SIZE) print_largest_cluster_size(maxclustersize);
@ -226,7 +239,8 @@ void animation(int size)
if (PLOT_CLUSTER_SIZE) free(plot_cluster_size);
if (PLOT_CLUSTER_NUMBER) free(plot_cluster_number);
if (FIND_CLUSTER_SIZES) free(cluster_sizes);
// if (FIND_CLUSTER_SIZES)
free(cluster_sizes);
}
@ -249,12 +263,12 @@ void display(void)
// animation(128);
// animation(64);
animation(32);
animation(16);
animation(8);
// animation(32);
// animation(16);
// animation(8);
animation(4);
animation(2);
animation(1);
// animation(2);
// animation(1);
sleep(SLEEP2);

228
rde.c
View File

@ -39,54 +39,66 @@
#include <omp.h>
#include <time.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 1920 /* window width */
#define WINHEIGHT 1000 /* window height */
#define NX 480 /* number of grid points on x axis */
#define NY 240 /* number of grid points on y axis */
#define XMIN -2.0
#define XMAX 2.0 /* x interval */
#define YMIN -1.041666667
#define YMAX 1.041666667 /* y interval for 9/16 aspect ratio */
// #define WINWIDTH 1280 /* window width */
// #define WINHEIGHT 720 /* window height */
//
// // #define NX 160 /* number of grid points on x axis */
// // #define NY 90 /* number of grid points on y axis */
// #define NX 320 /* number of grid points on x axis */
// #define NY 180 /* number of grid points on y axis */
//
// // #define NX 640 /* number of grid points on x axis */
// // #define NY 360 /* number of grid points on y axis */
//
// // #define NX 1280 /* number of grid points on x axis */
// // #define NY 720 /* number of grid points on y axis */
// #define NX 600 /* number of grid points on x axis */
// #define NY 300 /* number of grid points on y axis */
// // #define NX 480 /* number of grid points on x axis */
// // #define NY 240 /* number of grid points on y axis */
// // #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.041666667
// #define YMAX 1.041666667 /* y interval for 9/16 aspect ratio */
// #define WINWIDTH 1280 /* window width */
// #define WINHEIGHT 720 /* window height */
// #define NX 200 /* number of grid points on x axis */
// #define NY 200 /* number of grid points on y axis */
#define NX 500 /* number of grid points on x axis */
#define NY 500 /* number of grid points on y axis */
// #define NX 640 /* number of grid points on x axis */
// #define NY 360 /* number of grid points on y axis */
// #define NX 1280 /* number of grid points on x axis */
// #define NY 720 /* number of grid points on y axis */
#define XMIN -1.8
#define XMAX 1.8 /* x interval */
#define YMIN -1.8
#define YMAX 1.8 /* y interval for 9/16 aspect ratio */
/* Choice of simulated equation */
#define RDE_EQUATION 5 /* choice of reaction term, see list in global_3d.c */
#define NFIELDS 2 /* number of fields in reaction-diffusion equation */
#define NLAPLACIANS 2 /* number of fields for which to compute Laplacian */
// #define RDE_EQUATION 4 /* choice of reaction term, see list in global_3d.c */
// #define NFIELDS 3 /* number of fields in reaction-diffusion equation */
// #define NLAPLACIANS 3 /* number of fields for which to compute Laplacian */
#define ADD_POTENTIAL 1 /* set to 1 to add a potential (for Schrodiner equation) */
#define POTENTIAL 2 /* type of potential, see list in global_3d.c */
#define ADD_POTENTIAL 1 /* set to 1 to add a potential (for Schrodinger equation) */
#define POTENTIAL 1 /* type of potential, see list in global_3d.c */
#define ADD_MAGNETIC_FIELD 1 /* set to 1 to add a magnetic field (for Schrodinger equation) - then set POTENTIAL 1 */
#define ANTISYMMETRIZE_WAVE_FCT 0 /* set tot 1 to make wave function antisymmetric */
#define JULIA_SCALE 0.5 /* scaling for Julia sets */
/* Choice of the billiard table */
#define B_DOMAIN 999 /* choice of domain shape, see list in global_pdes.c */
#define B_DOMAIN 999 /* choice of domain shape, see list in global_pdes.c */
#define CIRCLE_PATTERN 99 /* pattern of circles, see list in global_pdes.c */
@ -96,8 +108,8 @@
#define LAMBDA 1.0 /* parameter controlling the dimensions of domain */
#define MU 1.0 /* parameter controlling the dimensions of domain */
#define NPOLY 6 /* number of sides of polygon */
#define APOLY 0.333333333 /* angle by which to turn polygon, in units of Pi/2 */
#define NPOLY 5 /* number of sides of polygon */
#define APOLY 2.0 /* angle by which to turn polygon, in units of Pi/2 */
#define MDEPTH 7 /* depth of computation of Menger gasket */
#define MRATIO 5 /* ratio defining Menger gasket */
#define MANDELLEVEL 1000 /* iteration level for Mandelbrot set */
@ -111,7 +123,7 @@
#define X_TARGET 0.4
#define Y_TARGET 0.7 /* shooter and target positions in laser fight */
#define ISO_XSHIFT_LEFT -1.65
#define ISO_XSHIFT_LEFT -1.65
#define ISO_XSHIFT_RIGHT 0.4
#define ISO_YSHIFT_LEFT -0.05
#define ISO_YSHIFT_RIGHT -0.05
@ -123,6 +135,9 @@
/* Physical patameters of wave equation */
#define DT 0.00000002
// #define DT 0.00000003
// #define DT 0.000000011
// #define DT 0.00000001
#define VISCOSITY 2.0
@ -133,7 +148,7 @@
#define DELTA 0.1 /* time scale separation */
#define FHNA 1.0 /* parameter in FHN equation */
#define FHNC -0.01 /* parameter in FHN equation */
#define K_HARMONIC 0.2 /* spring constant of harmonic potential */
#define K_HARMONIC 0.5 /* spring constant of harmonic potential */
#define K_COULOMB 0.5 /* constant in Coulomb potential */
#define BZQ 0.0008 /* parameter in BZ equation */
#define BZF 1.2 /* parameter in BZ equation */
@ -167,13 +182,15 @@
/* Parameters for length and speed of simulation */
#define NSTEPS 1150 /* number of frames of movie */
#define NVID 850 /* number of iterations between images displayed on screen */
// #define NSTEPS 500 /* number of frames of movie */
#define NSTEPS 1100 /* number of frames of movie */
#define NVID 500 /* number of iterations between images displayed on screen */
// #define NVID 1100 /* number of iterations between images displayed on screen */
#define ACCELERATION_FACTOR 1.0 /* factor by which to increase NVID in course of simulation */
#define DT_ACCELERATION_FACTOR 1.0 /* factor by which to increase time step in course of simulation */
#define MAX_DT 0.024 /* maximal value of integration step */
#define NSEG 100 /* number of segments of boundary */
#define BOUNDARY_WIDTH 4 /* width of billiard boundary */
#define BOUNDARY_WIDTH 5 /* width of billiard boundary */
#define PAUSE 100 /* number of frames after which to pause */
#define PSLEEP 2 /* sleep time during pause */
@ -188,19 +205,19 @@
#define PLOT_3D 1 /* controls whether plot is 2D or 3D */
#define ROTATE_VIEW 1 /* set to 1 to rotate position of observer */
#define ROTATE_VIEW 0 /* set to 1 to rotate position of observer */
#define ROTATE_ANGLE 360.0 /* total angle of rotation during simulation */
/* Plot type - color scheme */
#define CPLOT 30
#define CPLOT 32
// #define CPLOT 32
#define CPLOT_B 31
/* Plot type - height of 3D plot */
// #define ZPLOT 30 /* z coordinate in 3D plot */
// #define ZPLOT_B 32 /* z coordinate in second 3D plot */
#define ZPLOT 30 /* z coordinate in 3D plot */
#define ZPLOT 32 /* z coordinate in 3D plot */
// #define ZPLOT 32 /* z coordinate in 3D plot */
#define ZPLOT_B 30 /* z coordinate in second 3D plot */
#define AMPLITUDE_HIGH_RES 1 /* set to 1 to increase resolution of P_3D_AMPLITUDE plot */
@ -209,8 +226,8 @@
#define WRAP_ANGLE 1 /* experimental: wrap angle to [0, 2Pi) for interpolation in angle schemes */
#define FADE_IN_OBSTACLE 0 /* set to 1 to fade color inside obstacles */
#define DRAW_OUTSIDE_GRAY 0 /* experimental - draw outside of billiard in gray */
#define ADD_POTENTIAL_TO_Z 1 /* set to 1 to add the external potential to z-coordinate of plot */
#define ADD_POT_CONSTANT 0.5 /* constant in front of added potential */
#define ADD_POTENTIAL_TO_Z 0 /* set to 1 to add the external potential to z-coordinate of plot */
#define ADD_POT_CONSTANT 1.0 /* constant in front of added potential */
#define PLOT_SCALE_ENERGY 0.05 /* vertical scaling in energy plot */
@ -237,8 +254,8 @@
/* Color schemes, see list in global_pdes.c */
#define COLOR_PALETTE 14 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE_B 10 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE 11 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE_B 0 /* Color palette, see list in global_pdes.c */
#define BLACK 1 /* black background */
@ -248,12 +265,12 @@
#define SCALE 0 /* set to 1 to adjust color scheme to variance of field */
#define SLOPE 1.0 /* sensitivity of color on wave amplitude */
#define VSCALE_AMPLITUDE 7.5 /* additional scaling factor for color scheme P_3D_AMPLITUDE */
#define VSCALE_AMPLITUDE 30.0 /* additional scaling factor for color scheme P_3D_AMPLITUDE */
#define ATTENUATION 0.0 /* exponential attenuation coefficient of contrast with time */
#define CURL_SCALE 0.000015 /* scaling factor for curl representation */
#define RESCALE_COLOR_IN_CENTER 0 /* set to 1 to decrease color intentiy in the center (for wave escaping ring) */
#define SLOPE_SCHROD_LUM 15.0 /* sensitivity of luminosity on module, for color scheme Z_ARGUMENT */
#define MIN_SCHROD_LUM 0.075 /* minimal luminosity in color scheme Z_ARGUMENT*/
#define SLOPE_SCHROD_LUM 50.0 /* sensitivity of luminosity on module, for color scheme Z_ARGUMENT */
#define MIN_SCHROD_LUM 0.2 /* minimal luminosity in color scheme Z_ARGUMENT*/
#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 */
@ -263,11 +280,11 @@
#define HUEAMP -359.0 /* amplitude of variation of hue for color scheme C_HUE */
#define E_SCALE 100.0 /* scaling factor for energy representation */
#define LOG_SCALE 1.0 /* scaling factor for energy log representation */
#define LOG_SHIFT 0.0
#define LOG_SHIFT 0.0
#define DRAW_COLOR_SCHEME 1 /* set to 1 to plot the color scheme */
#define COLORBAR_RANGE 3.0 /* scale of color scheme bar */
#define COLORBAR_RANGE_B 3.0 /* scale of color scheme bar for 2nd part */
#define COLORBAR_RANGE 2.5 /* scale of color scheme bar */
#define COLORBAR_RANGE_B 2.5 /* scale of color scheme bar for 2nd part */
#define ROTATE_COLOR_SCHEME 0 /* set to 1 to draw color scheme horizontally */
/* only for compatibility with wave_common.c */
@ -281,6 +298,13 @@
#define VSCALE_ENERGY 200.0 /* additional scaling factor for color scheme P_3D_ENERGY */
#define PHASE_FACTOR 20.0 /* factor in computation of phase in color scheme P_3D_PHASE */
#define PHASE_SHIFT 0.0 /* shift of phase in color scheme P_3D_PHASE */
#define OSCILLATION_SCHEDULE 0 /* oscillation schedule, see list in global_pdes.c */
#define AMPLITUDE 0.8 /* amplitude of periodic excitation */
#define ACHIRP 0.2 /* acceleration coefficient in chirp */
#define DAMPING 0.0 /* damping of periodic excitation */
#define COMPARISON 0 /* set to 1 to compare two different patterns (beta) */
#define B_DOMAIN_B 20 /* second domain shape, for comparisons */
#define CIRCLE_PATTERN_B 0 /* second pattern of circles or polygons */
/* end of constants added only for compatibility with wave_common.c */
@ -288,14 +312,14 @@ double u_3d[2] = {0.75, -0.45}; /* projections of basis vectors for REP_AXO_
double v_3d[2] = {-0.75, -0.45};
double w_3d[2] = {0.0, 0.015};
double light[3] = {0.816496581, -0.40824829, 0.40824829}; /* vector of "light" direction for P_3D_ANGLE color scheme */
double observer[3] = {8.0, 8.0, 6.0}; /* location of observer for REP_PROJ_3D representation */
double observer[3] = {8.0, 8.0, 12.0}; /* location of observer for REP_PROJ_3D representation */
int reset_view = 0; /* switch to reset 3D view parameters (for option ROTATE_VIEW) */
#define Z_SCALING_FACTOR 0.75 /* overall scaling factor of z axis for REP_PROJ_3D representation */
#define XY_SCALING_FACTOR 2.2 /* overall scaling factor for on-screen (x,y) coordinates after projection */
#define Z_SCALING_FACTOR 1.25 /* overall scaling factor of z axis for REP_PROJ_3D representation */
#define XY_SCALING_FACTOR 1.8 /* overall scaling factor for on-screen (x,y) coordinates after projection */
#define ZMAX_FACTOR 1.0 /* max value of z coordinate for REP_PROJ_3D representation */
#define XSHIFT_3D -0.1 /* overall x shift for REP_PROJ_3D representation */
#define YSHIFT_3D 0.2 /* overall y shift for REP_PROJ_3D representation */
#define YSHIFT_3D 0.0 /* overall y shift for REP_PROJ_3D representation */
/* For debugging purposes only */
@ -319,7 +343,7 @@ int reset_view = 0; /* switch to reset 3D view parameters (for option RO
double potential(int i, int j)
/* compute potential (e.g. for Schrödinger equation) */
{
double x, y, xy[2], r, small = 2.0e-1, kx, ky;
double x, y, xy[2], r, small = 2.0e-1, kx, ky, lx = XMAX - XMIN, r1, r2, r3;
ij_to_xy(i, j, xy);
x = xy[0];
@ -343,12 +367,42 @@ double potential(int i, int j)
ky = 2.0*DPI/(YMAX - YMIN);
return(-K_HARMONIC*cos(kx*x)*cos(ky*y));
}
case (POT_FERMIONS):
{
r = sqrt((x-y)*(x-y) + small*small);
return (-K_COULOMB/r);
}
case (POT_FERMIONS_PERIODIC):
{
r1 = sqrt((x-y)*(x-y) + small*small);
r2 = sqrt((x-lx-y)*(x-lx-y) + small*small);
r3 = sqrt((x+lx-y)*(x+lx-y) + small*small);
// r = r/3.0;
return (-0.5*K_COULOMB*(1.0/r1 + 1.0/r2 + 1.0/r3));
}
default:
{
return(0.0);
}
}
}
}
void compute_vector_potential(int i, int j, double *ax, double *ay)
/* initialize the vector potential, for Schrodinger equation in a magnetic field */
{
double x, y, xy[2], b;
ij_to_xy(i, j, xy);
x = xy[0];
y = xy[1];
b = sqrt(K_HARMONIC);
/* magnetic field strength b is chosen such that b^2/4 = K_HARMONIC */
*ax = b*y;
*ay = -b*x;
}
void initialize_potential(double potential_field[NX*NY])
@ -364,18 +418,40 @@ void initialize_potential(double potential_field[NX*NY])
}
}
void evolve_wave_half(double *phi_in[NFIELDS], double *phi_out[NFIELDS], short int xy_in[NX*NY], double potential_field[NX*NY])
void initialize_vector_potential(double vpotential_field[2*NX*NY])
/* initialize the potential field, e.g. for the Schrödinger equation */
{
int i, j;
#pragma omp parallel for private(i,j)
for (i=0; i<NX; i++){
for (j=0; j<NY; j++){
compute_vector_potential(i, j, &vpotential_field[i*NY+j], &vpotential_field[NX*NY+i*NY+j]);
}
}
}
void evolve_wave_half(double *phi_in[NFIELDS], double *phi_out[NFIELDS], short int xy_in[NX*NY], double potential_field[NX*NY], double vector_potential_field[2*NX*NY])
/* time step of field evolution */
{
int i, j, k, iplus, iminus, jplus, jminus;
double x, y, z, deltax, deltay, deltaz, rho, pot;
double *delta_phi[NLAPLACIANS];
double x, y, z, deltax, deltay, deltaz, rho, pot, vx, vy;
double *delta_phi[NLAPLACIANS], *nabla_phi, *nabla_psi;
static double invsqr3 = 0.577350269; /* 1/sqrt(3) */
for (i=0; i<NLAPLACIANS; i++) delta_phi[i] = (double *)malloc(NX*NY*sizeof(double));
/* compute the Laplacian of phi */
for (i=0; i<NLAPLACIANS; i++) compute_laplacian(phi_in[i], delta_phi[i], xy_in);
for (i=0; i<NLAPLACIANS; i++) compute_laplacian_rde(phi_in[i], delta_phi[i], xy_in);
/* compute the gradient of phi if there is a magnetic field */
if (ADD_MAGNETIC_FIELD)
{
nabla_phi = (double *)malloc(2*NX*NY*sizeof(double));
nabla_psi = (double *)malloc(2*NX*NY*sizeof(double));
compute_gradient_xy(phi_in[0], nabla_phi);
compute_gradient_xy(phi_in[1], nabla_psi);
}
#pragma omp parallel for private(i,j,k,x,y,z,deltax,deltay,deltaz,rho)
for (i=0; i<NX; i++){
@ -447,6 +523,13 @@ void evolve_wave_half(double *phi_in[NFIELDS], double *phi_out[NFIELDS], short i
phi_out[0][i*NY+j] += intstep*pot*phi_in[1][i*NY+j];
phi_out[1][i*NY+j] -= intstep*pot*phi_in[0][i*NY+j];
}
if (ADD_MAGNETIC_FIELD)
{
vx = vector_potential_field[i*NY+j];
vy = vector_potential_field[NX*NY+i*NY+j];
phi_out[0][i*NY+j] -= 2.0*intstep*(vx*nabla_phi[i*NY+j] + vy*nabla_phi[NX*NY+i*NY+j]);
phi_out[1][i*NY+j] -= 2.0*intstep*(vx*nabla_psi[i*NY+j] + vy*nabla_psi[NX*NY+i*NY+j]);
}
}
}
}
@ -463,13 +546,19 @@ void evolve_wave_half(double *phi_in[NFIELDS], double *phi_out[NFIELDS], short i
}
for (i=0; i<NLAPLACIANS; i++) free(delta_phi[i]);
if (ADD_MAGNETIC_FIELD)
{
free(nabla_phi);
free(nabla_psi);
}
}
void evolve_wave(double *phi[NFIELDS], double *phi_tmp[NFIELDS], short int xy_in[NX*NY], double potential_field[NX*NY])
void evolve_wave(double *phi[NFIELDS], double *phi_tmp[NFIELDS], short int xy_in[NX*NY], double potential_field[NX*NY], double vector_potential_field[2*NX*NY])
/* time step of field evolution */
{
evolve_wave_half(phi, phi_tmp, xy_in, potential_field);
evolve_wave_half(phi_tmp, phi, xy_in, potential_field);
evolve_wave_half(phi, phi_tmp, xy_in, potential_field, vector_potential_field);
evolve_wave_half(phi_tmp, phi, xy_in, potential_field, vector_potential_field);
}
@ -643,7 +732,7 @@ void animation()
{
double time = 0.0, scale, dx, var, jangle, cosj, sinj, sqrintstep,
intstep0, viscosity_printed, fade_value, noise = NOISE_INTENSITY;
double *phi[NFIELDS], *phi_tmp[NFIELDS], *potential_field;
double *phi[NFIELDS], *phi_tmp[NFIELDS], *potential_field, *vector_potential_field;
short int *xy_in;
int i, j, k, s, nvid, field;
static int counter = 0;
@ -664,6 +753,12 @@ void animation()
potential_field = (double *)malloc(NX*NY*sizeof(double));
initialize_potential(potential_field);
}
if (ADD_MAGNETIC_FIELD)
{
vector_potential_field = (double *)malloc(2*NX*NY*sizeof(double));
initialize_vector_potential(vector_potential_field);
}
npolyline = init_polyline(MDEPTH, polyline);
for (i=0; i<npolyline; i++) printf("vertex %i: (%.3f, %.3f)\n", i, polyline[i].x, polyline[i].y);
@ -684,7 +779,9 @@ void animation()
// init_random(0.5, 0.4, phi, xy_in);
// init_random(0.0, 0.4, phi, xy_in);
// init_gaussian(x, y, mean, amplitude, scalex, phi, xy_in)
init_coherent_state(-0.7, 0.0, 3.5, 0.0, 0.15, phi, xy_in);
init_coherent_state(1.0, 0.0, 0.0, 5.0, 0.1, phi, xy_in);
// init_fermion_state(-0.5, 0.5, 2.0, 0.0, 0.1, phi, xy_in);
// init_boson_state(-0.5, 0.5, 2.0, 0.0, 0.1, phi, xy_in);
init_cfield_rde(phi, xy_in, CPLOT, rde, 0);
if (PLOT_3D) init_zfield_rde(phi, xy_in, ZPLOT, rde, 0);
@ -752,7 +849,9 @@ void animation()
// printf("Integration step %.5lg\n", intstep);
printf("Evolving wave\n");
for (j=0; j<nvid; j++) evolve_wave(phi, phi_tmp, xy_in, potential_field);
for (j=0; j<nvid; j++) evolve_wave(phi, phi_tmp, xy_in, potential_field, vector_potential_field);
if (ANTISYMMETRIZE_WAVE_FCT) antisymmetrize_wave_function(phi, xy_in);
for (j=0; j<NFIELDS; j++) printf("field[%i] = %.3lg\t", j, phi[j][0]);
printf("\n");
@ -886,6 +985,7 @@ void animation()
}
free(xy_in);
if (ADD_POTENTIAL) free(potential_field);
if (ADD_MAGNETIC_FIELD) free(vector_potential_field);
printf("Time %.5lg\n", time);

View File

@ -157,6 +157,17 @@
#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 */
/* the following constants are only used by wave_billiard and wave_3d so far */
#define COMPARISON 0 /* set to 1 to compare two different patterns */
#define B_DOMAIN_B 20 /* second domain shape, for comparisons */
#define CIRCLE_PATTERN_B 0 /* second pattern of circles or polygons */
#define OSCILLATION_SCHEDULE 3 /* oscillation schedule, see list in global_pdes.c */
#define ACHIRP 0.2 /* acceleration coefficient in chirp */
#define DAMPING 0.0 /* damping of periodic excitation */
#define OMEGA 0.001 /* frequency of periodic excitation */
#define AMPLITUDE 0.8 /* amplitude of periodic excitation */
/* end of constants only used by wave_billiard and wave_3d */
#include "global_pdes.c"
#include "sub_wave.c"

View File

@ -21,6 +21,7 @@ int bc_grouped(int bc)
case (BC_BOY): return(3);
case (BC_GENUS_TWO): return(4);
case (BC_ABSORBING): return(0);
case (BC_REFLECT_ABS): return(0);
default:
{
printf("Warning: Hashgrid will not be properly initialised, update bc_grouped()\n\n");

811
sub_lj.c

File diff suppressed because it is too large Load Diff

View File

@ -4,8 +4,6 @@
#define BOUNDARY_SHIFT 100000.0 /* shift of boundary parametrisation for circles in domain */
#define DUMMY_SIDE_ABS -10000 /* dummy value of returned side for absorbing circles */
#define PENROSE_RATIO 0.2 /* parameter controlling the shape of small ellipses in Penrose room */
long int global_time = 0; /* counter to keep track of global time of simulation */
int nparticles=NPART;
@ -6154,3 +6152,100 @@ void init_polyline(t_segment polyline[NMAXPOLY], t_circle circles[NMAXCIRCLES])
}
void init_polyline_depth(t_segment polyline[NMAXPOLY], t_circle circles[NMAXCIRCLES], int sdepth, double mu)
/* initialise polyline with variable depth parameter (for von Koch snowflake) */
{
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, ta, tb, a, b;
switch (POLYLINE_PATTERN) {
case (P_VONKOCH):
{
nsides = 3;
for (k=0; k<sdepth; k++) nsides *= 4;
printf("nsides = %i\n", nsides);
ncircles = nsides;
if (nsides > NMAXPOLY)
{
printf("NMAXPOLY has to be increased to at least %i\n", nsides);
nsides = NMAXPOLY;
}
for (i=0; i<nsides/3; i++)
{
/* compute quaternary expansion of i */
ii = i;
for (l=0; l<sdepth; l++)
{
quater[l] = ii%4;
ii = ii - (ii%4);
ii = ii/4;
}
/* find first nonzero digit */
z = 0;
while ((quater[z] == 0)&&(z<sdepth)) z++;
/* compute left/right turns */
if (i==0) vkoch[0] = 0;
else if (z != sdepth)
{
if (quater[z] == 2) vkoch[i] = 0;
else vkoch[i] = 1;
}
// printf("%i", vkoch[i]);
}
printf("\n");
/* 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);
for (k=0; k<sdepth; k++) length = length/3.0;
printf("Length = %.2f\n", length);
for (i=0; i<nsides; i++)
{
polyline[i].x1 = x;
polyline[i].y1 = y;
polyline[i].angle = angle;
x += length*cos(angle);
y += length*sin(angle);
polyline[i].length = length;
turnright = vkoch[i%(nsides/3)+1];
if (turnright) angle -= PI/3.0;
else angle += 2.0*PI/3.0;
while (angle > DPI) angle -= DPI;
while (angle < 0.0) angle += DPI;
}
for (i=0; i<nsides; i++)
{
polyline[i].color = 0;
if (i < nsides-1) polyline[i].x2 = polyline[i+1].x1;
else polyline[i].x2 = polyline[0].x1;
if (i < nsides-1) polyline[i].y2 = polyline[i+1].y1;
else polyline[i].y2 = polyline[0].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;
}
}
}

View File

@ -151,6 +151,14 @@ int ipowi(int base, int n)
}
}
double module2(double x, double y) /* Euclidean norm */
{
double m;
m = sqrt(x*x + y*y);
return(m);
}
@ -267,6 +275,46 @@ void draw_colored_rectangle(double x1, double y1, double x2, double y2, double h
}
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;
xy_to_pos(x + r*cos(alpha), y + r*sin(alpha), pos);
glVertex2d(pos[0], pos[1]);
}
glEnd();
}
void draw_colored_circle(double x, double y, double r, int nseg)
{
int i;
double pos[2], alpha, dalpha;
dalpha = DPI/(double)nseg;
glBegin(GL_TRIANGLE_FAN);
xy_to_pos(x, y, pos);
glVertex2d(pos[0], pos[1]);
for (i=0; i<=nseg; i++)
{
alpha = (double)i*dalpha;
xy_to_pos(x + r*cos(alpha), y + r*sin(alpha), pos);
glVertex2d(pos[0], pos[1]);
}
glEnd();
}
int graphical_rep(int bcondition)
/* return type of drawing, depending on lattice/boundary conditions */
{
@ -277,15 +325,16 @@ int graphical_rep(int bcondition)
case (BC_HEX_SITE_DIRICHLET): return(PLOT_HEX);
case (BC_HEX_BOND_DIRICHLET): return(PLOT_HEX_BONDS);
case (BC_TRIANGLE_SITE_DIRICHLET): return(PLOT_TRIANGLE);
case (BC_POISSON_DISC): return(PLOT_POISSON_DISC);
default: return(0);
}
}
double pcritical(int bcondition)
double pcritical(int lattice)
/* critical probability in terms of lattice and boundary condition */
{
switch (LATTICE) {
switch (lattice) {
case (BC_SQUARE_DIRICHLET): return(0.59274);
case (BC_SQUARE_PERIODIC): return(0.59274);
case (BC_SQUARE_BOND_DIRICHLET): return(0.5);
@ -304,33 +353,37 @@ int cellnb(int i, int j, int group, int nx, int ny)
case (BC_SQUARE_DIRICHLET):
{
return(i*ny+j);
break;
// break;
}
case (BC_SQUARE_PERIODIC):
{
return(i*ny+j);
break;
// break;
}
case (BC_SQUARE_BOND_DIRICHLET):
{
if (group == 0) return(i+nx*j);
else return (nx*(ny+1) + i*ny+j);
break;
// break;
}
case (BC_HEX_SITE_DIRICHLET):
{
return(i+nx*j);
break;
// break;
}
case (BC_HEX_BOND_DIRICHLET):
{
return (group*nx*(ny+1) + i+nx*j);
break;
// break;
}
case (BC_TRIANGLE_SITE_DIRICHLET):
{
return(i+2*nx*j);
break;
// break;
}
case (BC_POISSON_DISC):
{
return(i);
}
}
}
@ -411,7 +464,7 @@ double p_schedule(int i)
int in_plot_box(double x, double y)
{
int pos[2];
static double xmin, xmax, ymin, ymax;
static double xmin, ymin;
static int first = 1;
if (first)
@ -423,7 +476,21 @@ int in_plot_box(double x, double y)
}
return((x > xmin)&&(y > ymin));
// return((x + 0.5*(double)size > xmin)&&(y + 0.5*(double)size > ymin));
}
int in_plot_box_screencoord(double x, double y)
{
static double xmin, ymin;
static int first = 1;
if (first)
{
xmin = XMAX - 1.0;
ymin = YMAX - 1.0;
first = 0;
}
return((x > xmin)&&(y > ymin));
}
double size_ratio_color(int clustersize, int ncells)
@ -916,6 +983,11 @@ void draw_cell(int c, int nx, int ny, int size)
glEnd();
break;
}
case (PLOT_POISSON_DISC):
{
/* beta version, TO DO */
// draw_circle();
}
}
}
@ -939,11 +1011,11 @@ void test_neighbours(int start, t_perco *cell, int nx, int ny, int size, int nce
void draw_configuration(t_perco *cell, int *cluster_sizes, int nx, int ny, int size, int max_cluster_size)
void draw_configuration(t_perco *cell, int *cluster_sizes, int ncells, int nx, int ny, int size, int max_cluster_size)
/* draw the configuration */
{
int i, j, ishift, k;
double rgb[3], x, y, alpha, r, fade = 0, dsize;
int i, j, ishift, k, n;
double rgb[3], x, y, alpha, r, fade = 0, dsize, radius, x2, y2;
static double h, h1;
static int first = 1;
@ -1142,7 +1214,7 @@ void draw_configuration(t_perco *cell, int *cluster_sizes, int nx, int ny, int s
x = 0.5*((double)i + 1.25)*dsize;
y = h*dsize*((double)j);
if ((ADD_PLOT)&&(in_plot_box(x, y))) fade = 1;
if ((ADD_PLOT)&&(in_plot_box(x, y+0.5*h*dsize))) fade = 1;
else fade = 0;
set_cell_color(cell[2*j*nx+i], cluster_sizes, fade, max_cluster_size);
@ -1164,6 +1236,41 @@ void draw_configuration(t_perco *cell, int *cluster_sizes, int nx, int ny, int s
}
break;
}
case (PLOT_POISSON_DISC):
{
radius = sqrt((XMAX - XMIN)*(YMAX - YMIN)/(PI*(double)nx));;
blank();
if (ADD_PLOT)
{
rgb[0] = 1.0; rgb[1] = 1.0; rgb[2] = 1.0;
erase_area_rgb(XMAX - 0.5, YMAX - 0.5, 0.5, 0.5, rgb);
}
for (i=0; i<ncells; i++)
{
x = cell[i].x;
y = cell[i].y;
if ((ADD_PLOT)&&(in_plot_box_screencoord(x, y))) fade = 1;
else fade = 0;
set_cell_color(cell[i], cluster_sizes, fade, max_cluster_size);
for (k=0; k<cell[i].nneighb; k++)
{
n = cell[i].nghb[k];
// printf("Cell %i, %ith neighbour cell %i\n", i, k, n);
x2 = cell[n].x;
y2 = cell[n].y;
draw_line(x, y, 0.5*(x + x2), 0.5*(y + y2));
}
draw_colored_circle(x, y, radius, NSEG);
}
break;
}
}
}
@ -1259,6 +1366,74 @@ void print_largest_cluster_size(int max_cluster_size)
/* animation part */
/*********************/
int generate_poisson_discs(t_perco *cell, double dpoisson, int nmaxcells)
/* generate Poisson disc configuration */
{
double x, y, r, phi;
int i, j, k, n_p_active, ncircles, ncandidates=NPOISSON_CANDIDATES, naccepted;
short int *active_poisson, far;
active_poisson = (short int *)malloc(2*(nmaxcells)*sizeof(short int));
printf("Generating Poisson disc sample\n");
/* generate first circle */
cell[0].x = (XMAX - XMIN)*(double)rand()/RAND_MAX + XMIN;
cell[0].y = (YMAX - YMIN)*(double)rand()/RAND_MAX + YMIN;
active_poisson[0] = 1;
n_p_active = 1;
ncircles = 1;
while ((n_p_active > 0)&&(ncircles < nmaxcells))
{
/* randomly select an active circle */
i = rand()%(ncircles);
while (!active_poisson[i]) i = rand()%(ncircles);
/* 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 = cell[i].x + r*cos(phi);
y = cell[i].y + 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 - cell[k].x)*(x - cell[k].x) + (y - cell[k].y)*(y - cell[k].y) >= dpoisson*dpoisson);
/* new circle is in domain */
far = far*(x < XMAX)*(x > XMIN)*(y < YMAX)*(y > YMIN);
}
if (far) /* accept new circle */
{
printf("New circle at (%.3f,%.3f) accepted\n", x, y);
cell[ncircles].x = x;
cell[ncircles].y = y;
cell[ncircles].active = 1;
active_poisson[ncircles] = 1;
ncircles++;
n_p_active++;
naccepted++;
}
// else printf("Rejected\n");
}
if (naccepted == 0) /* inactivate circle i */
{
active_poisson[i] = 0;
n_p_active--;
}
printf("%i active circles\n", n_p_active);
}
printf("Generated %i circles\n", ncircles);
free(active_poisson);
return(ncircles);
}
int cell_number(int nx, int ny)
/* total number of cells in graph */
{
@ -1270,6 +1445,7 @@ int cell_number(int nx, int ny)
case (BC_HEX_BOND_DIRICHLET): return(3*(int)((double)((nx+2)*(ny+2))*2.0/sqrt(3.0)));
/* hex lattice requires more vertical space! */
case (BC_TRIANGLE_SITE_DIRICHLET): return((int)((double)(2*nx*ny)*2.0/sqrt(3.0))); /* triangle lattice requires more vertical space! */
case (BC_POISSON_DISC): return(nx*ny); /* TO IMPROVE */
}
}
@ -1296,6 +1472,13 @@ void compute_nxny(int size, int *nx, int *ny)
*ny = (int)((double)NY*2.0/((double)size*sqrt(3.0))) + 1;
break;
}
case (BC_POISSON_DISC):
{
/* for Poisson disc configuration, use a 1d labelling */
*nx = NX*NY/(size*size);
*ny = 1;
break;
}
default:
{
*nx = NX/size;
@ -1308,7 +1491,9 @@ void compute_nxny(int size, int *nx, int *ny)
int init_cell_lattice(t_perco *cell, int nx, int ny)
/* initialize the graph of connected cells - returns the number of cells */
{
int i, j, iplus, iminus, ishift, n;
int i, j, k, iplus, iminus, ishift, n;
int ncells;
double dpoisson, radius;
printf("Initializing cell lattice ...");
@ -2073,6 +2258,33 @@ int init_cell_lattice(t_perco *cell, int nx, int ny)
return(2*nx*ny);
break;
}
case (BC_POISSON_DISC):
{
dpoisson = 3.0*sqrt((XMAX - XMIN)*(YMAX - YMIN)/(PI*(double)nx));
// printf("nx = %i, dpoisson = %.5lg\n", nx, dpoisson);
ncells = generate_poisson_discs(cell, dpoisson, nx);
radius = 1.8*dpoisson;
for (i=0; i<ncells; i++)
{
k = 0;
for (j=0; j<ncells; j++) if ((j != i)&&(k < MAX_NEIGHB))
{
if (module2(cell[j].x - cell[i].x, cell[j].y - cell[i].y) < radius)
{
cell[i].nghb[k] = j;
// printf("%i ", j);
k++;
}
}
cell[i].nneighb = k;
}
return(ncells);
break;
}
}
printf("Done\n");
}
@ -2095,12 +2307,15 @@ void init_cell_probabilities(t_perco *cell, int ncells)
void init_cell_state(t_perco *cell, double p, int ncells, int first)
/* initialize the probabilities of cells being open */
{
int i;
int i, delta_i;
delta_i = ncells/100;
printf("Initializing cell state ...");
#pragma omp parallel for private(i)
for (i=0; i<ncells; i++)
{
if ((VERBOSE)&&(i%delta_i == 0)) printf("%i ", i/delta_i);
if (cell[i].proba < p)
{
cell[i].open = 1;
@ -2120,10 +2335,11 @@ void init_cell_state(t_perco *cell, double p, int ncells, int first)
printf("Done\n");
}
int init_flooded_cells(t_perco *cell, int nx, int ny, t_perco* *pstack)
int init_flooded_cells(t_perco *cell, int ncells, int nx, int ny, t_perco* *pstack)
/* make the left row of cells flooded, returns number of flooded cells */
{
int j, ishift;
int j, n, ishift;
double pdisc_prop;
// printf("Initializing flooded cells ...");
switch (graphical_rep(LATTICE)) {
@ -2199,6 +2415,25 @@ int init_flooded_cells(t_perco *cell, int nx, int ny, t_perco* *pstack)
}
return(ny);
}
case (PLOT_POISSON_DISC):
{
n = 0;
pdisc_prop = 0.5/sqrt((double)ncells);
#pragma omp parallel for private(j)
for (j=0; j<ncells; j++) if (cell[j].x - XMIN < (XMAX - XMIN)*pdisc_prop)
{
// printf("Flooding cell %i\n", j);
cell[j].open = 1;
cell[j].flooded = 1;
cell[j].cluster = 1;
cell[j].previous_cluster = 1;
cell[j].active = 1;
pstack[n] = &cell[j];
n++;
}
printf("Flooded %i cells\n", n);
return(n);
}
}
// printf("Done\n");
}
@ -2207,9 +2442,14 @@ int init_flooded_cells(t_perco *cell, int nx, int ny, t_perco* *pstack)
int count_open_cells(t_perco *cell, int ncells)
/* count the number of active cells */
{
int n = 0, i;
int n = 0, i, delta_i;
for (i=0; i<ncells; i++) if (cell[i].open) n++;
delta_i = ncells/100;
for (i=0; i<ncells; i++)
{
if (cell[i].open) n++;
if ((VERBOSE)&&(i%delta_i == 0)) printf("%i ", i/delta_i);
}
return(n);
}
@ -2235,7 +2475,7 @@ int count_active_cells(t_perco *cell, int ncells)
int find_open_cells(t_perco *cell, int ncells, int position, t_perco* *pstack, int *stacksize, int cluster)
/* look for open neighbours of start_cell, returns difference in open cells */
/* look for open neighbours of cell[position], returns difference in open cells */
{
int k, nopen = 0, n;
@ -2286,6 +2526,7 @@ int find_percolation_cluster(t_perco *cell, int ncells, t_perco* *pstack, int ns
nactive += find_open_cells(cell, ncells, position, pstack, &stacksize, 1);
}
printf("Stack size %i\n", stacksize);
return(stacksize);
}
@ -2293,7 +2534,7 @@ int find_percolation_cluster(t_perco *cell, int ncells, t_perco* *pstack, int ns
int find_all_clusters(t_perco *cell, int ncells, int reset, int *max_cluster_label)
/* find all clusters of open cells; returns number of clusters */
{
int nclusters = 0, i, j, nactive, stacksize, position, newcluster = 1, maxlabel = 0;
int nclusters = 0, i, j, nactive, stacksize, position, newcluster = 1, maxlabel = 0, delta_i;
t_perco **cstack;
static int cluster;
@ -2302,6 +2543,8 @@ int find_all_clusters(t_perco *cell, int ncells, int reset, int *max_cluster_lab
if (reset) cluster = CLUSTER_SHIFT;
else cluster = (*max_cluster_label) + CLUSTER_SHIFT; /* give higher labels than before to new clusters */
delta_i = ncells/1000;
for (i=0; i<ncells; i++) if ((cell[i].open)&&(cell[i].cluster != 1)&&(!cell[i].tested))
{
position = 0;
@ -2327,8 +2570,11 @@ int find_all_clusters(t_perco *cell, int ncells, int reset, int *max_cluster_lab
if (position == stacksize) position = 0;
nactive += find_open_cells(cell, ncells, position, cstack, &stacksize, newcluster);
// if ((VERBOSE)&&(nactive%100 == 99)) printf ("%i active cells\n", nactive + 1);
}
// printf("Found cluster %i with %i active cells\n", cluster, stacksize);
if ((VERBOSE)&&(i%delta_i == 0)) printf("Found cluster %i with %i active cells\n", cluster, stacksize);
nclusters++;
}

194
sub_rde.c
View File

@ -129,7 +129,157 @@ void init_coherent_state(double x, double y, double px, double py, double scalex
}
}
void init_fermion_state(double x, double y, double px, double py, double scalex, double *phi[NFIELDS], short int xy_in[NX*NY])
/* initialise field with antisymmetric coherent state of position (x,y) and momentum (px, py) */
/* phi[0] is real part, phi[1] is imaginary part */
{
int i, j;
double xy[2], dist2, module, phase, scale2;
scale2 = scalex*scalex;
for (i=0; i<NX; i++)
for (j=0; j<NY; j++)
{
ij_to_xy(i, j, xy);
xy_in[i*NY+j] = xy_in_billiard(xy[0],xy[1]);
if (xy_in[i*NY+j])
{
dist2 = (xy[0]-x)*(xy[0]-x) + (xy[1]-y)*(xy[1]-y);
module = exp(-dist2/scale2);
if (module < 1.0e-15) module = 1.0e-15;
phase = (px*(xy[0]-x) + py*(xy[1]-y))/scalex;
phi[0][i*NY+j] = module*cos(phase);
phi[1][i*NY+j] = module*sin(phase);
/* antisymmetrize wave function */
dist2 = (xy[1]-x)*(xy[1]-x) + (xy[0]-y)*(xy[0]-y);
module = exp(-dist2/scale2);
if (module < 1.0e-15) module = 1.0e-15;
phase = (px*(xy[1]-x) + py*(xy[0]-y))/scalex;
phi[0][i*NY+j] -= module*cos(phase);
phi[1][i*NY+j] -= module*sin(phase);
}
else
{
phi[0][i*NY+j] = 0.0;
phi[1][i*NY+j] = 0.0;
}
}
}
void init_boson_state(double x, double y, double px, double py, double scalex, double *phi[NFIELDS], short int xy_in[NX*NY])
/* initialise field with symmetric coherent state of position (x,y) and momentum (px, py) */
/* phi[0] is real part, phi[1] is imaginary part */
{
int i, j;
double xy[2], dist2, module, phase, scale2;
scale2 = scalex*scalex;
for (i=0; i<NX; i++)
for (j=0; j<NY; j++)
{
ij_to_xy(i, j, xy);
xy_in[i*NY+j] = xy_in_billiard(xy[0],xy[1]);
if (xy_in[i*NY+j])
{
dist2 = (xy[0]-x)*(xy[0]-x) + (xy[1]-y)*(xy[1]-y);
module = exp(-dist2/scale2);
if (module < 1.0e-15) module = 1.0e-15;
phase = (px*(xy[0]-x) + py*(xy[1]-y))/scalex;
phi[0][i*NY+j] = module*cos(phase);
phi[1][i*NY+j] = module*sin(phase);
/* symmetrize wave function */
dist2 = (xy[1]-x)*(xy[1]-x) + (xy[0]-y)*(xy[0]-y);
module = exp(-dist2/scale2);
if (module < 1.0e-15) module = 1.0e-15;
phase = (px*(xy[1]-x) + py*(xy[0]-y))/scalex;
phi[0][i*NY+j] += module*cos(phase);
phi[1][i*NY+j] += module*sin(phase);
}
else
{
phi[0][i*NY+j] = 0.0;
phi[1][i*NY+j] = 0.0;
}
}
}
void init_fermion_state2(double x, double y, double px, double py, double scalex, double *phi[NFIELDS], short int xy_in[NX*NY])
/* initialise field with antisymmetric coherent state of position (x,y) and momentum (px, py) */
/* phi[0] is real part, phi[1] is imaginary part */
{
int i, j;
double xy[2], dist2, module, phase, scale2, fx[2], fy[2], gx[2], gy[2];
scale2 = scalex*scalex;
for (i=0; i<NX; i++)
for (j=0; j<NY; j++)
{
ij_to_xy(i, j, xy);
xy_in[i*NY+j] = xy_in_billiard(xy[0],xy[1]);
if (xy_in[i*NY+j])
{
dist2 = (xy[0]-x)*(xy[0]-x);
module = exp(-dist2/scale2);
if (module < 1.0e-15) module = 1.0e-15;
phase = px*(xy[0]-x)/scalex;
fx[0] = module*cos(phase);
fx[1] = module*sin(phase);
dist2 = (xy[0]-y)*(xy[0]-y);
module = exp(-dist2/scale2);
if (module < 1.0e-15) module = 1.0e-15;
phase = px*(xy[0]-y)/scalex;
fy[0] = module*cos(phase);
fy[1] = module*sin(phase);
dist2 = (xy[1]-x)*(xy[1]-x);
module = exp(-dist2/scale2);
if (module < 1.0e-15) module = 1.0e-15;
phase = py*(xy[1]-x)/scalex;
gx[0] = module*cos(phase);
gx[1] = module*sin(phase);
dist2 = (xy[1]-y)*(xy[1]-y);
module = exp(-dist2/scale2);
if (module < 1.0e-15) module = 1.0e-15;
phase = py*(xy[1]-y)/scalex;
gy[0] = module*cos(phase);
gy[1] = module*sin(phase);
phi[0][i*NY+j] = 0.5*(fx[0]*gy[0] - gx[0]*fy[0]);
phi[1][i*NY+j] = 0.5*(fx[1]*gy[1] - gx[1]*fy[1]);
}
else
{
phi[0][i*NY+j] = 0.0;
phi[1][i*NY+j] = 0.0;
}
}
}
void antisymmetrize_wave_function(double *phi[NFIELDS], short int xy_in[NX*NY])
/* force the wave function to be antisymmetric, for simulations of fermions */
{
int i, j, k;
#pragma omp parallel for private(i,j,k)
for (i=0; i<NX; i++)
for (j=0; j<=i; j++) if ((j<NY)&&(xy_in[i*NY+j]))
for (k=0; k<2; k++)
{
phi[k][i*NY+j] = 0.5*(phi[k][i*NY+j] - phi[k][j*NY+i]);
phi[k][j*NY+i] = -phi[k][i*NY+j];
}
}
/*********************/
/* animation part */
@ -263,6 +413,48 @@ void compute_theta_rpslz(double *phi[NFIELDS], short int xy_in[NX*NY], t_rde rde
}
}
void compute_gradient_xy(double phi[NX*NY], double gradient[2*NX*NY])
/* compute the gradient of the field */
{
int i, j, iplus, iminus, jplus, jminus, padding = 0;
double deltaphi;
double dx = (XMAX-XMIN)/((double)NX);
dx = (XMAX-XMIN)/((double)NX);
#pragma omp parallel for private(i,j,iplus,iminus,jplus,jminus,deltaphi)
for (i=1; i<NX-1; i++)
for (j=1; j<NY-1; j++)
{
deltaphi = phi[iplus*NY+j] - phi[iminus*NY+j];
if (vabs(deltaphi) < 1.0e9) gradient[i*NY+j] = (deltaphi)/dx;
else gradient[i*NY+j] = 0.0;
deltaphi = phi[i*NY+jplus] - phi[i*NY+jminus];
if (vabs(deltaphi) < 1.0e9) gradient[NX*NY+i*NY+j] = (deltaphi)/dx;
else gradient[NX*NY+i*NY+j] = 0.0;
}
/* boundaries */
for (i=0; i<NX; i++)
{
gradient[i*NY] = 0.0;
gradient[NX*NY+i*NY] = 0.0;
gradient[i*NY+NY-1] = 0.0;
gradient[NX*NY+i*NY+NY-1] = 0.0;
}
for (j=1; j<NY-1; j++)
{
gradient[j] = 0.0;
gradient[(NX-1)*NY+j] = 0.0;
gradient[NX*NY+j] = 0.0;
gradient[NX*NY+(NX-1)*NY+j] = 0.0;
}
}
void compute_gradient_rde(double phi[NX*NY], t_rde rde[NX*NY])
/* compute the gradient of the field */
@ -457,7 +649,7 @@ void compute_probabilities(t_rde rde[NX*NY], short int xy_in[NX*NY], double prob
void compute_laplacian(double phi_in[NX*NY], double phi_out[NX*NY], short int xy_in[NX*NY])
void compute_laplacian_rde(double phi_in[NX*NY], double phi_out[NX*NY], short int xy_in[NX*NY])
/* computes the Laplacian of phi_in and stores it in phi_out */
{
int i, j, iplus, iminus, jplus, jminus;

View File

@ -520,7 +520,7 @@ void draw_tpolygon(t_polygon polygon)
}
void init_circle_config(t_circle circles[NMAXCIRCLES])
int init_circle_config_pattern(t_circle circles[NMAXCIRCLES], int circle_pattern)
/* initialise the arrays circlex, circley, circlerad and circleactive */
/* for billiard shape D_CIRCLES */
{
@ -528,7 +528,7 @@ void init_circle_config(t_circle circles[NMAXCIRCLES])
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) {
switch (circle_pattern) {
case (C_SQUARE):
{
ncircles = NGRIDX*NGRIDY;
@ -571,8 +571,8 @@ void init_circle_config(t_circle circles[NMAXCIRCLES])
for (j = 0; j < NGRIDY; j++)
{
n = NGRIDY*i + j;
circles[n].xc = ((double)(i-NGRIDX/2) + 0.5*((double)rand()/RAND_MAX - 0.5))*dy;
circles[n].yc = YMIN + ((double)j + 0.5 + 0.5*((double)rand()/RAND_MAX - 0.5))*dy;
circles[n].xc = ((double)(i-NGRIDX/2) + 0.5 + 0.5*((double)rand()/RAND_MAX - 0.5))*dy;
circles[n].yc = YMIN + 0.5 + ((double)j + 0.5 + 0.5*((double)rand()/RAND_MAX - 0.5))*dy;
circles[n].radius = MU*sqrt(1.0 + 0.8*((double)rand()/RAND_MAX - 0.5));
circles[n].active = 1;
}
@ -944,16 +944,23 @@ void init_circle_config(t_circle circles[NMAXCIRCLES])
printf("Function init_circle_config not defined for this pattern \n");
}
}
return(ncircles);
}
void init_polygon_config(t_polygon polygons[NMAXCIRCLES])
int init_circle_config(t_circle circles[NMAXCIRCLES])
/* for backward compatibility */
{
return (init_circle_config_pattern(circles, CIRCLE_PATTERN));
}
int init_polygon_config_pattern(t_polygon polygons[NMAXCIRCLES], int circle_pattern)
/* initialise the polygon configuration, for billiard shape D_CIRCLES */
/* uses init_circle_config, this is where C++ would be more elegant */
{
int i;
int i, ncircles;
t_circle circle[NMAXCIRCLES];
init_circle_config(circle);
ncircles = init_circle_config_pattern(circle, circle_pattern);
for (i=0; i<NMAXCIRCLES; i++)
{
polygons[i].xc = circle[i].xc;
@ -969,11 +976,19 @@ void init_polygon_config(t_polygon polygons[NMAXCIRCLES])
}
/* adjust angles for C_RINGS configuration */
if ((CIRCLE_PATTERN == C_RINGS)||(CIRCLE_PATTERN == C_RINGS_T)||(CIRCLE_PATTERN == C_RINGS_SPIRAL))
if ((circle_pattern == C_RINGS)||(circle_pattern == C_RINGS_T)||(circle_pattern == C_RINGS_SPIRAL))
for (i=0; i<ncircles; i++) if (polygons[i].active)
polygons[i].angle += argument(polygons[i].xc, polygons[i].yc)/PID;
return(ncircles);
}
int init_polygon_config(t_polygon polygons[NMAXCIRCLES])
/* for backward compatibility */
{
return (init_polygon_config_pattern(polygons, CIRCLE_PATTERN));
}
int axial_symmetry(double z1[2], double z2[2], double z[2], double zprime[2])
/* compute reflection of point z wrt axis through z1 and z2 */
{
@ -1661,15 +1676,14 @@ int xy_in_triangle_tvertex(double x, double y, t_vertex z1, t_vertex z2, t_verte
}
int xy_in_billiard(double x, double y)
int xy_in_billiard_single_domain(double x, double y, int b_domain, int ncirc, t_circle *circles)
/* 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, alpha, s, a;
int i, j, k, k1, k2, condition = 0, m;
static int first = 1, nsides;
switch (B_DOMAIN) {
switch (b_domain) {
case (D_NOTHING):
{
return(1);
@ -2000,7 +2014,7 @@ int xy_in_billiard(double x, double y)
}
case (D_CIRCLES):
{
for (i = 0; i < ncircles; i++)
for (i = 0; i < ncirc; i++)
if (circles[i].active)
{
x1 = circles[i].xc;
@ -2012,7 +2026,7 @@ int xy_in_billiard(double x, double y)
}
case (D_CIRCLES_IN_RECT): /* returns 2 inside circles, 0 outside rectangle */
{
for (i = 0; i < ncircles; i++)
for (i = 0; i < ncirc; i++)
if (circles[i].active)
{
x1 = circles[i].xc;
@ -2025,7 +2039,7 @@ int xy_in_billiard(double x, double y)
}
case (D_POLYGONS):
{
for (i = 0; i < ncircles; i++)
for (i = 0; i < ncirc; i++)
if ((polygons[i].active)&&(in_tpolygon(x, y, polygons[i]))) return(0);
return(1);
}
@ -2173,6 +2187,17 @@ int xy_in_billiard(double x, double y)
if (x1 < a) return (y > YMIN + LAMBDA);
else return (y > YMIN + LAMBDA + s);
}
case (D_FABRY_PEROT):
{
return(vabs(x - y*LAMBDA/YMAX) > 0.5*MU);
}
case (D_LSHAPE):
{
if (vabs(x) > LAMBDA) return(0);
else if (vabs(y) > 1.0) return(0);
else if ((x > 0.0)&&(y > 0.0)) return(0);
else return(1);
}
case (D_MENGER):
{
x1 = 0.5*(x+1.0);
@ -2335,6 +2360,17 @@ int xy_in_billiard(double x, double y)
}
}
int xy_in_billiard(double x, double y)
/* returns 1 if (x,y) represents a point in the billiard */
{
if (COMPARISON)
{
if (y > 0.0) return (xy_in_billiard_single_domain(x, y, B_DOMAIN, ncircles, circles));
else return (xy_in_billiard_single_domain(x, y, B_DOMAIN_B, ncircles_b, circles_b));
}
else return (xy_in_billiard_single_domain(x, y, B_DOMAIN, ncircles, circles));
}
int ij_in_billiard(int i, int j)
/* returns 1 if (i,j) represents a point in the billiard */
{
@ -3166,6 +3202,13 @@ void draw_billiard(int fade, double fade_value) /* draws the billiard bound
glEnd();
break;
}
case (D_FABRY_PEROT):
{
glLineWidth(BOUNDARY_WIDTH);
draw_line(-LAMBDA - 0.5*MU, YMIN, LAMBDA - 0.5*MU, YMAX);
draw_line(-LAMBDA + 0.5*MU, YMIN, LAMBDA + 0.5*MU, YMAX);
break;
}
case (D_CIRCLE_SEGMENT):
{
glLineWidth(BOUNDARY_WIDTH);
@ -3565,7 +3608,7 @@ void draw_color_scheme_palette(double x1, double y1, double x2, double y2, int p
xy_to_ij(x2, y2, ij_topright);
rgb[0] = 0.0; rgb[1] = 0.0; rgb[2] = 0.0;
erase_area_rgb(0.5*(x1 + x2), x2 - x1, 0.5*(y1 + y2), y2 - y1, rgb);
// erase_area_rgb(0.5*(x1 + x2), x2 - x1, 0.5*(y1 + y2), y2 - y1, rgb);
if (ROTATE_COLOR_SCHEME)
{
@ -3671,7 +3714,7 @@ void draw_color_scheme_palette_fade(double x1, double y1, double x2, double y2,
xy_to_ij(x2, y2, ij_topright);
rgb[0] = 0.0; rgb[1] = 0.0; rgb[2] = 0.0;
erase_area_rgb(0.5*(x1 + x2), x2 - x1, 0.5*(y1 + y2), y2 - y1, rgb);
// erase_area_rgb(0.5*(x1 + x2), x2 - x1, 0.5*(y1 + y2), y2 - y1, rgb);
if (ROTATE_COLOR_SCHEME)
{
@ -3770,3 +3813,474 @@ void draw_color_scheme_palette_fade(double x1, double y1, double x2, double y2,
draw_rectangle(x1, y1, x2, y2);
}
void print_speed(double speed, int fade, double fade_value)
{
char message[100];
double y = YMAX - 0.1, pos[2];
static double xleftbox, xlefttext;
static int first = 1;
if (first)
{
xleftbox = XMIN + 0.3;
xlefttext = xleftbox - 0.45;
first = 0;
}
erase_area_hsl(xleftbox, y + 0.025, 0.22, 0.05, 0.0, 0.9, 0.0);
if (fade) glColor3f(fade_value, fade_value, fade_value);
else glColor3f(1.0, 1.0, 1.0);
xy_to_pos(xlefttext + 0.28, y, pos);
sprintf(message, "Mach %.3lg", speed);
write_text(pos[0], pos[1], message);
}
void init_laplacian_coords(t_laplacian laplace[NX*NY], double phi[NX*NY])
/* compute coordinates of neighbours to compute Laplacian */
{
int i, j, iplus, iminus, i1, i2, i3, j1, j2, j3, ij[2];;
printf("Initialising Laplacian table\n");
/* Laplacian in the bulk */
#pragma omp parallel for private(i,j)
for (i=1; i<NX-1; i++){
for (j=1; j<NY-1; j++){
laplace[i*NY+j].nneighb = 4;
laplace[i*NY+j].nghb[0] = &phi[(i+1)*NY+j];
laplace[i*NY+j].nghb[1] = &phi[(i-1)*NY+j];
laplace[i*NY+j].nghb[2] = &phi[i*NY+j+1];
laplace[i*NY+j].nghb[3] = &phi[i*NY+j-1];
}
}
switch (B_COND) {
case (BC_DIRICHLET):
{
/* left boundary */
#pragma omp parallel for private(j)
for (j=1; j<NY-1; j++)
{
laplace[j].nneighb = 3;
laplace[j].nghb[0] = &phi[NY+j];
laplace[j].nghb[1] = &phi[j+1];
laplace[j].nghb[2] = &phi[j-1];
}
/* right boundary */
#pragma omp parallel for private(j)
for (j=1; j<NY-1; j++)
{
laplace[(NX-1)*NY+j].nneighb = 3;
laplace[(NX-1)*NY+j].nghb[0] = &phi[(NX-2)*NY+j];
laplace[(NX-1)*NY+j].nghb[1] = &phi[(NX-1)*NY+j+1];
laplace[(NX-1)*NY+j].nghb[2] = &phi[(NX-1)*NY+j-1];
}
/* top boundary */
#pragma omp parallel for private(i,iplus,iminus)
for (i=0; i<NX; i++)
{
iplus = i+1; if (iplus == NX) iplus = NX-1;
iminus = i-1; if (iminus == -1) iminus = 0;
laplace[i*NY+NY-1].nneighb = 3;
laplace[i*NY+NY-1].nghb[0] = &phi[iplus*NY+NY-1];
laplace[i*NY+NY-1].nghb[1] = &phi[iminus*NY+NY-1];
laplace[i*NY+NY-1].nghb[2] = &phi[i*NY+NY-2];
}
/* bottom boundary */
#pragma omp parallel for private(i,iplus,iminus)
for (i=0; i<NX; i++)
{
iplus = i+1; if (iplus == NX) iplus = NX-1;
iminus = i-1; if (iminus == -1) iminus = 0;
laplace[i*NY].nneighb = 3;
laplace[i*NY].nghb[0] = &phi[iplus*NY];
laplace[i*NY].nghb[1] = &phi[iminus*NY];
laplace[i*NY].nghb[2] = &phi[i*NY+1];
}
break;
}
case (BC_PERIODIC):
{
/* left boundary */
#pragma omp parallel for private(j)
for (j=1; j<NY-1; j++)
{
laplace[j].nneighb = 4;
laplace[j].nghb[0] = &phi[NY+j];
laplace[j].nghb[1] = &phi[(NX-1)*NY+j];
laplace[j].nghb[2] = &phi[j+1];
laplace[j].nghb[3] = &phi[j-1];
}
/* right boundary */
#pragma omp parallel for private(j)
for (j=1; j<NY-1; j++)
{
laplace[(NX-1)*NY+j].nneighb = 4;
laplace[(NX-1)*NY+j].nghb[0] = &phi[(NX-2)*NY+j];
laplace[(NX-1)*NY+j].nghb[1] = &phi[j];
laplace[(NX-1)*NY+j].nghb[2] = &phi[(NX-1)*NY+j+1];
laplace[(NX-1)*NY+j].nghb[3] = &phi[(NX-1)*NY+j-1];
}
/* top boundary */
#pragma omp parallel for private(i,iplus,iminus)
for (i=0; i<NX; i++)
{
iplus = (i+1) % NX;
iminus = (i-1) % NX;
if (iminus < 0) iminus += NX;
laplace[i*NY+NY-1].nneighb = 4;
laplace[i*NY+NY-1].nghb[0] = &phi[iplus*NY+NY-1];
laplace[i*NY+NY-1].nghb[1] = &phi[iminus*NY+NY-1];
laplace[i*NY+NY-1].nghb[2] = &phi[i*NY+NY-2];
laplace[i*NY+NY-1].nghb[3] = &phi[i*NY];
}
/* bottom boundary */
#pragma omp parallel for private(i,iplus,iminus)
for (i=0; i<NX; i++)
{
iplus = (i+1) % NX;
iminus = (i-1) % NX;
if (iminus < 0) iminus += NX;
laplace[i*NY].nneighb = 4;
laplace[i*NY].nghb[0] = &phi[iplus*NY];
laplace[i*NY].nghb[1] = &phi[iminus*NY];
laplace[i*NY].nghb[2] = &phi[i*NY+1];
laplace[i*NY].nghb[3] = &phi[i*NY+NY-1];
}
break;
}
case (BC_ABSORBING):
{
/* left boundary */
#pragma omp parallel for private(j)
for (j=1; j<NY-1; j++)
{
laplace[j].nneighb = 3;
laplace[j].nghb[0] = &phi[NY+j];
laplace[j].nghb[1] = &phi[j+1];
laplace[j].nghb[2] = &phi[j-1];
}
/* right boundary */
#pragma omp parallel for private(j)
for (j=1; j<NY-1; j++)
{
laplace[(NX-1)*NY+j].nneighb = 3;
laplace[(NX-1)*NY+j].nghb[0] = &phi[(NX-2)*NY+j];
laplace[(NX-1)*NY+j].nghb[1] = &phi[(NX-1)*NY+j+1];
laplace[(NX-1)*NY+j].nghb[2] = &phi[(NX-1)*NY+j-1];
}
/* top boundary */
#pragma omp parallel for private(i,iplus,iminus)
for (i=0; i<NX; i++)
{
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
laplace[i*NY+NY-1].nneighb = 3;
laplace[i*NY+NY-1].nghb[0] = &phi[iplus*NY+NY-1];
laplace[i*NY+NY-1].nghb[1] = &phi[iminus*NY+NY-1];
laplace[i*NY+NY-1].nghb[2] = &phi[i*NY+NY-2];
}
/* bottom boundary */
#pragma omp parallel for private(i,iplus,iminus)
for (i=0; i<NX; i++)
{
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
laplace[i*NY].nneighb = 3;
laplace[i*NY].nghb[0] = &phi[iplus*NY];
laplace[i*NY].nghb[1] = &phi[iminus*NY];
laplace[i*NY].nghb[2] = &phi[i*NY+1];
}
break;
}
case (BC_VPER_HABS):
{
/* left boundary */
#pragma omp parallel for private(j)
for (j=1; j<NY-1; j++)
{
laplace[j].nneighb = 3;
laplace[j].nghb[0] = &phi[NY+j];
laplace[j].nghb[1] = &phi[j+1];
laplace[j].nghb[2] = &phi[j-1];
}
/* right boundary */
#pragma omp parallel for private(j)
for (j=1; j<NY-1; j++)
{
laplace[(NX-1)*NY+j].nneighb = 3;
laplace[(NX-1)*NY+j].nghb[0] = &phi[(NX-2)*NY+j];
laplace[(NX-1)*NY+j].nghb[1] = &phi[(NX-1)*NY+j+1];
laplace[(NX-1)*NY+j].nghb[2] = &phi[(NX-1)*NY+j-1];
}
/* top boundary */
#pragma omp parallel for private(i,iplus,iminus)
for (i=0; i<NX; i++)
{
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
laplace[i*NY+NY-1].nneighb = 4;
laplace[i*NY+NY-1].nghb[0] = &phi[iplus*NY+NY-1];
laplace[i*NY+NY-1].nghb[1] = &phi[iminus*NY+NY-1];
laplace[i*NY+NY-1].nghb[2] = &phi[i*NY+NY-2];
laplace[i*NY+NY-1].nghb[3] = &phi[i*NY];
}
/* bottom boundary */
#pragma omp parallel for private(i,iplus,iminus)
for (i=0; i<NX; i++)
{
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
laplace[i*NY].nneighb = 4;
laplace[i*NY].nghb[0] = &phi[iplus*NY];
laplace[i*NY].nghb[1] = &phi[iminus*NY];
laplace[i*NY].nghb[2] = &phi[i*NY+1];
laplace[i*NY].nghb[3] = &phi[i*NY+NY-1];
}
break;
}
case (BC_LSHAPE):
{
/* boundaries */
xy_to_ij(-LAMBDA, -1.0, ij);
i1 = ij[0] + 1; j1 = ij[1] + 1;
xy_to_ij(0.0, 0.0, ij);
i2 = ij[0] - 1; j2 = ij[1] - 1;
xy_to_ij(LAMBDA, 1.0, ij);
i3 = ij[0] - 1; j3 = ij[1] - 1;
printf("L shape corners (%i,%i), (%i,%i), (%i,%i)\n", i1, j1, i2, j2, i3, j3);
/* left boundary */
#pragma omp parallel for private(j)
for (j=j1+1; j<j2; j++)
{
laplace[i1*NY+j].nneighb = 4;
laplace[i1*NY+j].nghb[0] = &phi[(i1+1)*NY+j];
laplace[i1*NY+j].nghb[1] = &phi[(i3)*NY+j];
laplace[i1*NY+j].nghb[2] = &phi[i1*NY+j+1];
laplace[i1*NY+j].nghb[3] = &phi[i1*NY+j-1];
}
#pragma omp parallel for private(j)
for (j=j2; j<j3-1; j++)
{
laplace[i1*NY+j].nneighb = 4;
laplace[i1*NY+j].nghb[0] = &phi[(i1+1)*NY+j];
laplace[i1*NY+j].nghb[1] = &phi[(i2-1)*NY+j];
laplace[i1*NY+j].nghb[2] = &phi[i1*NY+j+1];
laplace[i1*NY+j].nghb[3] = &phi[i1*NY+j-1];
}
/* right boundary */
#pragma omp parallel for private(j)
for (j=j1+1; j<j2; j++)
{
laplace[(i3)*NY+j].nneighb = 4;
laplace[(i3)*NY+j].nghb[0] = &phi[i1*NY+j];
laplace[(i3)*NY+j].nghb[1] = &phi[(i3-1)*NY+j];
laplace[(i3)*NY+j].nghb[2] = &phi[(i3)*NY+j+1];
laplace[(i3)*NY+j].nghb[3] = &phi[(i3)*NY+j-1];
}
#pragma omp parallel for private(j)
for (j=j2; j<j3-1; j++)
{
laplace[(i2)*NY+j].nneighb = 4;
laplace[(i2)*NY+j].nghb[0] = &phi[i1*NY+j];
laplace[(i2)*NY+j].nghb[1] = &phi[(i2-1)*NY+j];
laplace[(i2)*NY+j].nghb[2] = &phi[(i2)*NY+j+1];
laplace[(i2)*NY+j].nghb[3] = &phi[(i2)*NY+j-1];
}
/* top boundary */
#pragma omp parallel for private(i)
for (i=i1; i<i2; i++)
{
laplace[i*NY+j3].nneighb = 4;
laplace[i*NY+j3].nghb[0] = &phi[(i+1)*NY+j3];
laplace[i*NY+j3].nghb[1] = &phi[(i-1)*NY+j3];
laplace[i*NY+j3].nghb[2] = &phi[i*NY+j1];
laplace[i*NY+j3].nghb[3] = &phi[i*NY+j3-1];
}
#pragma omp parallel for private(i)
for (i=i2; i<i3; i++)
{
laplace[i*NY+j2].nneighb = 4;
laplace[i*NY+j2].nghb[0] = &phi[(i+1)*NY+j2];
laplace[i*NY+j2].nghb[1] = &phi[(i-1)*NY+j2];
laplace[i*NY+j2].nghb[2] = &phi[i*NY+j1];
laplace[i*NY+j2].nghb[3] = &phi[i*NY+j2-1];
}
/* bottom boundary */
#pragma omp parallel for private(i)
for (i=i1; i<i2; i++)
{
laplace[i*NY+j1].nneighb = 4;
laplace[i*NY+j1].nghb[0] = &phi[(i+1)*NY+j1];
laplace[i*NY+j1].nghb[1] = &phi[(i-1)*NY+j1];
laplace[i*NY+j1].nghb[2] = &phi[i*NY+j1+1];
laplace[i*NY+j1].nghb[3] = &phi[i*NY+j3];
}
#pragma omp parallel for private(i)
for (i=i2; i<i3; i++)
{
laplace[i*NY+j1].nneighb = 4;
laplace[i*NY+j1].nghb[0] = &phi[(i+1)*NY+j1];
laplace[i*NY+j1].nghb[1] = &phi[(i-1)*NY+j1];
laplace[i*NY+j1].nghb[2] = &phi[i*NY+j1+1];
laplace[i*NY+j1].nghb[3] = &phi[i*NY+j2];
}
/* corners */
laplace[i1*NY+j1].nneighb = 4;
laplace[i1*NY+j1].nghb[0] = &phi[(i1+1)*NY+j1];
laplace[i1*NY+j1].nghb[1] = &phi[(i3-1)*NY+j1];
laplace[i1*NY+j1].nghb[2] = &phi[i1*NY+j1+1];
laplace[i1*NY+j1].nghb[3] = &phi[i1*NY+j3-1];
laplace[(i3)*NY+j1].nneighb = 4;
laplace[(i3)*NY+j1].nghb[0] = &phi[i1*NY+j1];
laplace[(i3)*NY+j1].nghb[1] = &phi[(i3-1)*NY+j1];
laplace[(i3)*NY+j1].nghb[2] = &phi[(i3)*NY+j1+1];
laplace[(i3)*NY+j1].nghb[3] = &phi[(i3)*NY+j3];
laplace[i1*NY+j3].nneighb = 4;
laplace[i1*NY+j3].nghb[0] = &phi[(i1+1)*NY+j3];
laplace[i1*NY+j3].nghb[1] = &phi[(i3)*NY+j3];
laplace[i1*NY+j3].nghb[2] = &phi[i1*NY+j1];
laplace[i1*NY+j3].nghb[3] = &phi[i1*NY+j3-1];
break;
}
}
}
void compute_laplacian(double phi[NX*NY], t_laplacian laplace[NX*NY], double delta[NX*NY], short int xy_in[NX*NY])
/* compute the discretized Laplacian of phi */
{
int i, j, k, n;
/* in the bulk */
if (B_COND == BC_LSHAPE)
{
#pragma omp parallel for private(i,j,k)
for (i=1; i<NX-1; i++)
for (j=1; j<NY-1; j++)
if (xy_in[i*NY+j])
{
delta[i*NY+j] = -4.0*phi[i*NY+j];
for (k=0; k<4; k++)
delta[i*NY+j] += *(laplace[i*NY+j].nghb[k]);
}
}
else
{
#pragma omp parallel for private(i,j,k)
for (i=1; i<NX-1; i++)
for (j=1; j<NY-1; j++)
if (xy_in[i*NY+j])
{
delta[i*NY+j] = phi[(i+1)*NY+j] + phi[(i-1)*NY+j] + phi[i*NY+j+1] + phi[i*NY+j-1] - 4.0*phi[i*NY+j];
}
}
/* top and bottom boundaries */
#pragma omp parallel for private(i,k,n)
for (i=0; i<NX; i++)
{
if (xy_in[i*NY])
{
n = laplace[i*NY].nneighb;
delta[i*NY] = -(double)n*phi[i*NY];
for (k=0; k<n; k++)
delta[i*NY] += *(laplace[i*NY].nghb[k]);
}
if (xy_in[i*NY+NY-1])
{
n = laplace[i*NY+NY-1].nneighb;
delta[i*NY+NY-1] = -(double)n*phi[i*NY+NY-1];
for (k=0; k<n; k++)
delta[i*NY+NY-1] += *(laplace[i*NY+NY-1].nghb[k]);
}
}
/* left and right boundaries */
#pragma omp parallel for private(j,k,n)
for (j=1; j<NY-1; j++)
{
if (xy_in[j])
{
n = laplace[j].nneighb;
delta[j] = -(double)n*phi[j];
for (k=0; k<n; k++)
delta[j] += *(laplace[j].nghb[k]);
}
if (xy_in[(NX-1)*NY+j])
{
n = laplace[(NX-1)*NY+j].nneighb;
delta[(NX-1)*NY+j] = -(double)n*phi[(NX-1)*NY+j];
for (k=0; k<n; k++)
delta[(NX-1)*NY+j] += *(laplace[(NX-1)*NY+j].nghb[k]);
}
}
}
double oscillating_bc(int time)
{
double t, phase, a, envelope, omega;
switch (OSCILLATION_SCHEDULE)
{
case (OSC_PERIODIC):
{
return(AMPLITUDE*cos((double)time*OMEGA)*exp(-(double)time*DAMPING));
}
case (OSC_SLOWING):
{
a = 0.0025;
t = (double)time*OMEGA;
phase = t - a*t*t;
// if (time%1000 == 0) printf("time = %i, phase = %.4lg\n", time, phase);
return(AMPLITUDE*cos(phase)*exp(-phase*DAMPING));
}
case (OSC_WAVE_PACKET):
{
t = (double)time*OMEGA;
// a = 10.0;
a = 0.02/OMEGA;
phase = AMPLITUDE*cos(t);
envelope = exp(-(t-0.2)*(t-0.2)/(a*a))*sqrt(DPI/a);
return(phase*envelope);
}
case (OSC_CHIRP):
{
// a = 0.25;
t = (double)time*OMEGA;
phase = t + ACHIRP*t*t;
return(AMPLITUDE*sin(phase)*exp(-phase*DAMPING));
}
}
}

View File

@ -90,6 +90,33 @@ void draw_vertex_x_y_z(double x, double y, double z)
glVertex2d(xy_screen[0], xy_screen[1]);
}
void draw_segment_hsl(double x1, double y1, double x2, double y2, double h, double s, double l)
/* draw line segment (x1,y1)-(x2,y2) in color (h,s,l) */
{
double rgb[3], pos[2];
glBegin(GL_LINE_STRIP);
hsl_to_rgb_palette(h, s, l, rgb, COL_JET);
glColor3f(rgb[0], rgb[1], rgb[2]);
draw_vertex_x_y_z(x1, y1, 0.0);
draw_vertex_x_y_z(x2, y2, 0.0);
glEnd();
}
void draw_segment_rgb(double x1, double y1, double x2, double y2, double r, double g, double b)
/* draw line segment (x1,y1)-(x2,y2) in color (h,s,l) */
{
double rgb[3], pos[2];
glBegin(GL_LINE_STRIP);
glColor3f(r, g, b);
draw_vertex_x_y_z(x1, y1, 0.0);
draw_vertex_x_y_z(x2, y2, 0.0);
glEnd();
}
void draw_rectangle_3d(double x1, double y1, double x2, double y2)
{
glBegin(GL_LINE_LOOP);
@ -152,7 +179,7 @@ void draw_tpolygon_3d(t_polygon polygon)
void draw_billiard_3d(int fade, double fade_value) /* draws the billiard boundary */
{
double x0, x, y, x1, y1, dx, dy, phi, r = 0.01, pos[2], pos1[2], alpha, dphi, omega, z, l, width, a, b, c, ymax;
double x0, x, y, x1, y1, dx, dy, phi, r = 0.01, pos[2], pos1[2], alpha, dphi, omega, z, l, width, a, b, c, ymax, padd;
int i, j, k, k1, k2, mr2;
static int first = 1, nsides;
@ -725,6 +752,20 @@ void draw_billiard_3d(int fade, double fade_value) /* draws the billiard bo
if (polygons[i].active) draw_tpolygon_3d(polygons[i]);
break;
}
case (D_LSHAPE):
{
padd = 0.005;
glLineWidth(BOUNDARY_WIDTH);
draw_segment_hsl(-LAMBDA - padd, -1.0 - padd, 0.0, -1.0 - padd, 0.0, 1.0, 0.5*fade_value);
draw_segment_hsl(-LAMBDA - padd, 1.0 + padd, 0.0, 1.0 + padd, 0.0, 1.0, 0.5*fade_value);
draw_segment_hsl(0.0, -1.0 - padd, LAMBDA + padd, -1.0 - padd, 220.0, 1.0, 0.5*fade_value);
draw_segment_hsl(0.0, padd, LAMBDA + padd, padd, 220.0, 1.0, 0.5*fade_value);
draw_segment_hsl(-LAMBDA - padd, -1.0 - padd, -LAMBDA - padd, 0.0, 60.0, 1.0, 0.5*fade_value);
draw_segment_hsl( LAMBDA + padd, -1.0 - padd, LAMBDA + padd, 0.0, 60.0, 1.0, 0.5*fade_value);
draw_segment_hsl(-LAMBDA - padd, 0.0, -LAMBDA - padd, 1.0 + padd, 180.0, 1.0, 0.5*fade_value);
draw_segment_hsl( padd, padd, padd, LAMBDA + padd, 180.0, 1.0, 0.5*fade_value);
break;
}
case (D_NOTHING):
{
break;
@ -764,13 +805,42 @@ void draw_polyline_visible(int j, int k, double margin)
glEnd();
}
}
void draw_segment_hsl_visible(double x1, double y1, double x2, double y2, double h, double s, double l, double margin)
/* hack to draw the billiard boundary in front of the wave */
/* only parts of the boundary having a small enough angle with the observer vector are drawn */
{
double length, length1, olength;
olength = module2(observer[0], observer[1]);
length = module2(x1,y1);
length1 = module2(x2,y2);
if ((x1*observer[0] + y1*observer[1] > margin*length*olength)&&(x2*observer[0] + y2*observer[1] > margin*length1*olength))
draw_segment_hsl(x1, y1, x2, y2, h, s, l);
}
void draw_segment_rgb_visible(double x1, double y1, double x2, double y2, double r, double g, double b, double margin)
/* hack to draw the billiard boundary in front of the wave */
/* only parts of the boundary having a small enough angle with the observer vector are drawn */
{
double length, length1, olength;
olength = module2(observer[0], observer[1]);
length = module2(x1,y1);
length1 = module2(x2,y2);
if ((x1*observer[0] + y1*observer[1] > margin*length*olength)&&(x2*observer[0] + y2*observer[1] > margin*length1*olength))
draw_segment_rgb(x1, y1, x2, y2, r, g, b);
}
void draw_billiard_3d_front(int fade, double fade_value)
/* hack to draw the billiard boundary in front of the wave */
/* only parts of the boundary having a small enough angle with the observer vector are drawn */
{
double x0, x, y, x1, y1, dx, dy, phi, r = 0.01, pos[2], pos1[2], alpha, dphi, omega, z, l, width, a, b, c, ymax, length, length1;
double x0, x, y, x1, y1, dx, dy, phi, r = 0.01, pos[2], pos1[2], alpha, dphi, omega, z, l, width, a, b, c, ymax, length, length1, padd, margin;
int i, j, k, k1, k2, mr2;
static int first = 1, nsides;
static double olength;
@ -805,6 +875,20 @@ void draw_billiard_3d_front(int fade, double fade_value)
glEnd();
break;
}
case (D_ELLIPSE):
{
glBegin(GL_LINE_LOOP);
dphi = DPI/(double)NSEG;
margin = 0.0;
for (i=0; i<=NSEG; i++)
{
phi = (double)i*dphi;
draw_segment_rgb_visible(LAMBDA*cos(phi), sin(phi), LAMBDA*cos(phi+dphi), sin(phi+dphi), fade_value, fade_value, fade_value, margin);
draw_vertex_x_y_z(LAMBDA*cos(phi), sin(phi), 0.0);
}
glEnd ();
break;
}
case (D_YOUNG):
{
glBegin(GL_LINE_STRIP);
@ -852,6 +936,21 @@ void draw_billiard_3d_front(int fade, double fade_value)
draw_polyline_visible(i%npolyline, (i+1)%npolyline, -0.5);
break;
}
case (D_LSHAPE):
{
padd = 0.005;
margin = 0.0;
glLineWidth(BOUNDARY_WIDTH);
draw_segment_hsl_visible(-LAMBDA - padd, -1.0 - padd, 0.0, -1.0 - padd, 0.0, 1.0, 0.5*fade_value, margin);
draw_segment_hsl_visible(-LAMBDA - padd, 1.0 + padd, 0.0, 1.0 + padd, 0.0, 1.0, 0.5*fade_value, margin);
draw_segment_hsl_visible(0.0, -1.0 - padd, LAMBDA + padd, -1.0 - padd, 220.0, 1.0, 0.5*fade_value, margin);
draw_segment_hsl_visible(0.0, padd, LAMBDA + padd, padd, 220.0, 1.0, 0.5*fade_value, 0.2);
draw_segment_hsl_visible(-LAMBDA - padd, -1.0 - padd, -LAMBDA - padd, 0.0, 60.0, 1.0, 0.5*fade_value, margin);
draw_segment_hsl_visible( LAMBDA + padd, -1.0 - padd, LAMBDA + padd, 0.0, 60.0, 1.0, 0.5*fade_value, margin);
draw_segment_hsl_visible(-LAMBDA - padd, 0.0, -LAMBDA - padd, 1.0 + padd, 180.0, 1.0, 0.5*fade_value, margin);
draw_segment_hsl_visible( padd, padd, padd, LAMBDA + padd, 180.0, 1.0, 0.5*fade_value, 0.6);
break;
}
default:
{
break;
@ -1118,8 +1217,8 @@ void compute_wave_fields(double phi[NX*NY], double psi[NX*NY], short int xy_in[N
if (COMPUTE_ENERGY)
compute_energy_field(phi, psi, xy_in, wave);
// if ((zplot == P_3D_LOG_ENERGY)||(cplot == P_3D_LOG_ENERGY))
// compute_log_energy_field(phi, psi, xy_in, wave);
if ((zplot == P_3D_LOG_ENERGY)||(cplot == P_3D_LOG_ENERGY))
compute_log_energy_field(phi, psi, xy_in, wave);
if ((zplot == P_3D_PHASE)||(cplot == P_3D_PHASE))
compute_phase_field(phi, psi, xy_in, wave);
@ -1132,7 +1231,7 @@ void init_speed_dissipation(short int xy_in[NX*NY], double tc[NX*NY], double tcc
{
int i, j, k;
double courant2 = COURANT*COURANT, courantb2 = COURANTB*COURANTB;
double u, v, u1, x, y, xy[2], norm2, speed;
double u, v, u1, x, y, xy[2], norm2, speed, r2, c;
if (VARIABLE_IOR)
{
@ -1211,6 +1310,23 @@ void init_speed_dissipation(short int xy_in[NX*NY], double tc[NX*NY], double tcc
}
break;
}
case (IOR_EARTH):
{
for (i=0; i<NX; i++){
for (j=0; j<NY; j++){
ij_to_xy(i, j, xy);
r2 = xy[0]*xy[0] + xy[1]*xy[1];
if (r2 > 1.0) c = 0.0;
else if (r2 < 0.25*0.25) c = 0.8*COURANT;
else if (r2 < 0.58*0.58) c = COURANT*(0.68 - 0.55*r2);
else c = COURANT*(1.3 - 0.9*r2);
tc[i*NY+j] = c;
tcc[i*NY+j] = c;
tgamma[i*NY+j] = GAMMA;
}
}
break;
}
default:
{
for (i=0; i<NX; i++){
@ -1515,8 +1631,8 @@ void draw_wave_3d(int movie, double phi[NX*NY], double psi[NX*NY], short int xy_
if (!ROTATE_VIEW)
{
for (i=0; i<NX-2; i++)
for (j=0; j<NY-2; j++)
for (i=1; i<NX-2; i++)
for (j=1; j<NY-2; j++)
draw_wave_3d_ij(i, j, movie, phi, psi, xy_in, wave, zplot, cplot, palette, fade, fade_value);
}
else /* draw facets in an order depending on the position of the observer */
@ -1528,26 +1644,26 @@ void draw_wave_3d(int movie, double phi[NX*NY], double psi[NX*NY], short int xy_
if ((observer_angle > 0.0)&&(observer_angle < PID))
{
for (j=0; j<NY-2; j++)
for (i=0; i<NX-2; i++)
for (j=1; j<NY-2; j++)
for (i=1; i<NX-2; i++)
draw_wave_3d_ij(i, j, movie, phi, psi, xy_in, wave, zplot, cplot, palette, fade, fade_value);
}
else if (observer_angle < PI)
{
for (i=NX-3; i>0; i--)
for (j=0; j<NY-2; j++)
for (j=1; j<NY-2; j++)
draw_wave_3d_ij(i, j, movie, phi, psi, xy_in, wave, zplot, cplot, palette, fade, fade_value);
}
else if (observer_angle < 1.5*PI)
{
for (j=NY-3; j>0; j--)
for (i=0; i<NX-2; i++)
for (i=1; i<NX-2; i++)
draw_wave_3d_ij(i, j, movie, phi, psi, xy_in, wave, zplot, cplot, palette, fade, fade_value);
}
else
{
for (i=0; i<NX-2; i++)
for (j=0; j<NY-2; j++)
for (i=1; i<NX-2; i++)
for (j=1; j<NY-2; j++)
draw_wave_3d_ij(i, j, movie, phi, psi, xy_in, wave, zplot, cplot, palette, fade, fade_value);
}
}
@ -1680,3 +1796,26 @@ void draw_color_scheme_palette_3d(double x1, double y1, double x2, double y2, in
draw_rectangle_noscale(x1, y1, x2, y2);
}
void print_speed_3d(double speed, int fade, double fade_value)
{
char message[100];
double y = YMAX - 0.1, pos[2];
static double xleftbox, xlefttext;
static int first = 1;
if (first)
{
xleftbox = XMIN + 0.3;
xlefttext = xleftbox - 0.45;
first = 0;
}
erase_area_hsl(xleftbox, y + 0.025, 0.22, 0.05, 0.0, 0.9, 0.0);
if (fade) glColor3f(fade_value, fade_value, fade_value);
else glColor3f(1.0, 1.0, 1.0);
// xy_to_pos(xlefttext + 0.28, y, pos);
sprintf(message, "Mach %.3lg", speed);
write_text(xlefttext + 0.28, y, message);
}

587
wave_3d.c
View File

@ -50,11 +50,15 @@
// #define WINWIDTH 1920 /* window width */
// #define WINHEIGHT 1000 /* window height */
// #define NX 1800 /* number of grid points on x axis */
// #define NY 900 /* number of grid points on y axis */
// #define NX 2000 /* number of grid points on x axis */
// #define NY 2000 /* number of grid points on y axis */
// // #define NX 1920 /* number of grid points on x axis */
// // #define NY 1000 /* number of grid points on y axis */
// // // #define YMIN -1.041666667
// // // #define YMAX 1.041666667 /* y interval for 9/16 aspect ratio */
//
// #define XMIN -2.2
// #define XMAX 1.8 /* x interval */
// #define XMIN -2.0
// #define XMAX 2.0 /* x interval */
// #define YMIN -1.041666667
// #define YMAX 1.041666667 /* y interval for 9/16 aspect ratio */
@ -62,10 +66,16 @@
#define WINWIDTH 1280 /* window width */
#define WINHEIGHT 720 /* window height */
// //
// #define NX 1500 /* number of grid points on x axis */
// #define NY 1500 /* number of grid points on y axis */
// //
#define NX 1280 /* number of grid points on x axis */
#define NY 720 /* number of grid points on y axis */
// #define NX 640 /* number of grid points on x axis */
// #define NY 360 /* number of grid points on y axis */
#define XMIN -2.0
#define XMAX 2.0 /* x interval */
#define YMIN -1.125
@ -75,23 +85,27 @@
/* Choice of the billiard table */
#define B_DOMAIN 24 /* choice of domain shape, see list in global_pdes.c */
#define B_DOMAIN 49 /* choice of domain shape, see list in global_pdes.c */
#define CIRCLE_PATTERN 202 /* pattern of circles or polygons, see list in global_pdes.c */
#define CIRCLE_PATTERN 201 /* pattern of circles or polygons, see list in global_pdes.c */
#define VARIABLE_IOR 1 /* set to 1 for a variable index of refraction */
#define COMPARISON 0 /* set to 1 to compare two different patterns */
#define B_DOMAIN_B 20 /* second domain shape, for comparisons */
#define CIRCLE_PATTERN_B 0 /* second pattern of circles or polygons */
#define VARIABLE_IOR 0 /* set to 1 for a variable index of refraction */
#define IOR 1 /* choice of index of refraction, see list in global_pdes.c */
#define MANDEL_IOR_SCALE -0.05 /* parameter controlling dependence of IoR on Mandelbrot escape speed */
#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 1 /* set to 1 to randomize angle of polygons */
#define LAMBDA 2.0 /* parameter controlling the dimensions of domain */
#define MU 0.5 /* parameter controlling the dimensions of domain */
#define LAMBDA -0.5 /* parameter controlling the dimensions of domain */
#define MU 0.25 /* parameter controlling the dimensions of domain */
#define NPOLY 3 /* number of sides of polygon */
#define APOLY 2.0 /* angle by which to turn polygon, in units of Pi/2 */
#define MDEPTH 3 /* depth of computation of Menger gasket */
#define MDEPTH 7 /* 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 */
@ -117,15 +131,18 @@
/* Physical parameters of wave equation */
#define TWOSPEEDS 1 /* 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 OSCILLATE_LEFT 1 /* set to 1 to add oscilating boundary condition on the left */
#define OSCILLATE_TOPBOT 1 /* set to 1 to enforce a planar wave on top and bottom boundary */
#define OSCILLATION_SCHEDULE 3 /* oscillation schedule, see list in global_pdes.c */
#define OMEGA 0.017 /* frequency of periodic excitation */
#define AMPLITUDE 0.9 /* amplitude of periodic excitation */
#define COURANT 0.08 /* Courant number */
#define COURANTB 0.025 /* Courant number in medium B */
#define OMEGA 0.001 /* frequency of periodic excitation */
#define AMPLITUDE 0.8 /* amplitude of periodic excitation */
#define ACHIRP 0.2 /* acceleration coefficient in chirp */
#define COURANT 0.1 /* Courant number */
#define COURANTB 0.025 /* Courant number in medium B */
#define DAMPING 0.0 /* damping of periodic excitation */
#define GAMMA 0.0 /* damping factor in wave equation */
#define GAMMAB 1.0e-6 /* damping factor in wave equation */
#define GAMMAB 0.0 /* damping factor in wave equation */
#define GAMMA_SIDES 1.0e-4 /* damping factor on boundary */
#define GAMMA_TOPBOT 1.0e-7 /* damping factor on boundary */
#define KAPPA 0.0 /* "elasticity" term enforcing oscillations */
@ -137,19 +154,22 @@
/* For similar wave forms, COURANT^2*GAMMA should be kept constant */
#define ADD_OSCILLATING_SOURCE 0 /* set to 1 to add an oscillating wave source */
#define OSCILLATING_SOURCE_PERIOD 30 /* period of oscillating source */
#define OSCILLATING_SOURCE_PERIOD 30 /* period of oscillating source */
/* Boundary conditions, see list in global_pdes.c */
#define B_COND 2
#define B_COND 3
#define PRECOMPUTE_BC 0 /* set to 1 to compute neighbours for Laplacian in advance */
/* Parameters for length and speed of simulation */
#define NSTEPS 2100 /* number of frames of movie */
#define NVID 6 /* number of iterations between images displayed on screen */
#define NSTEPS 3000 /* number of frames of movie */
#define NVID 8 /* number of iterations between images displayed on screen */
#define NSEG 1000 /* number of segments of boundary */
#define INITIAL_TIME 0 /* time after which to start saving frames */
#define BOUNDARY_WIDTH 1 /* width of billiard boundary */
#define BOUNDARY_WIDTH 2 /* width of billiard boundary */
#define PRINT_SPEED 0 /* set to 1 to print speed of moving source */
#define PAUSE 100 /* number of frames after which to pause */
#define PSLEEP 2 /* sleep time during pause */
@ -158,33 +178,33 @@
#define MID_FRAMES 100 /* number of still frames between parts of two-part movie */
#define END_FRAMES 100 /* number of still frames at end of movie */
#define FADE 1 /* set to 1 to fade at end of movie */
#define ROTATE_VIEW_WHILE_FADE 0 /* set to 1 to keep rotating viewpoint during fade */
#define ROTATE_VIEW_WHILE_FADE 1 /* set to 1 to keep rotating viewpoint during fade */
/* 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.02 /* wavelength of initial condition */
#define INITIAL_VARIANCE 0.0005 /* variance of initial condition */
#define INITIAL_WAVELENGTH 0.1 /* wavelength of initial condition */
/* Plot type, see list in global_pdes.c */
#define ZPLOT 103 /* wave height */
#define CPLOT 103 /* color scheme */
#define ZPLOT_B 109
#define CPLOT_B 109 /* plot type for second movie */
#define ZPLOT_B 105
#define CPLOT_B 105 /* plot type for second movie */
#define AMPLITUDE_HIGH_RES 1 /* set to 1 to increase resolution of plot */
#define SHADE_3D 1 /* set to 1 to change luminosity according to normal vector */
#define NON_DIRICHLET_BC 0 /* set to 1 to draw only facets in domain, if field is not zero on boundary */
#define FLOOR_ZCOORD 0 /* set to 1 to draw only facets with z not too negative */
#define DRAW_BILLIARD 0 /* set to 1 to draw boundary */
#define FLOOR_ZCOORD 1 /* set to 1 to draw only facets with z not too negative */
#define DRAW_BILLIARD 1 /* set to 1 to draw boundary */
#define DRAW_BILLIARD_FRONT 0 /* set to 1 to draw front of boundary after drawing wave */
#define DRAW_CONSTRUCTION_LINES 0 /* set to 1 to draw construction lines of certain domains */
#define FADE_IN_OBSTACLE 1 /* set to 1 to fade color inside obstacles */
#define DRAW_OUTSIDE_GRAY 0 /* experimental, draw outside of billiard in gray */
#define PLOT_SCALE_ENERGY 0.02 /* vertical scaling in energy plot */
#define PLOT_SCALE_ENERGY 0.5 /* vertical scaling in energy plot */
#define PLOT_SCALE_LOG_ENERGY 1.0 /* vertical scaling in log energy plot */
/* 3D representation */
@ -194,30 +214,30 @@
#define REP_AXO_3D 0 /* linear projection (axonometry) */
#define REP_PROJ_3D 1 /* projection on plane orthogonal to observer line of sight */
#define ROTATE_VIEW 1 /* set to 1 to rotate position of observer */
#define ROTATE_ANGLE 540.0 /* total angle of rotation during simulation */
#define ROTATE_VIEW 0 /* set to 1 to rotate position of observer */
#define ROTATE_ANGLE 360.0 /* total angle of rotation during simulation */
/* Color schemes */
#define COLOR_PALETTE 11 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE_B 13 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE 17 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE_B 14 /* Color palette, see list in global_pdes.c */
#define BLACK 1 /* background */
#define COLOR_SCHEME 3 /* choice of color scheme, see list in global_pdes.c */
#define SCALE 0 /* set to 1 to adjust color scheme to variance of field */
#define SLOPE 2.0 /* sensitivity of color on wave amplitude */
#define VSCALE_AMPLITUDE 0.2 /* additional scaling factor for color scheme P_3D_AMPLITUDE */
#define VSCALE_ENERGY 7.0 /* additional scaling factor for color scheme P_3D_ENERGY */
#define SLOPE 0.5 /* sensitivity of color on wave amplitude */
#define VSCALE_AMPLITUDE 1.0 /* additional scaling factor for color scheme P_3D_AMPLITUDE */
#define VSCALE_ENERGY 60.0 /* additional scaling factor for color scheme P_3D_ENERGY */
#define PHASE_FACTOR 20.0 /* factor in computation of phase in color scheme P_3D_PHASE */
#define PHASE_SHIFT 0.0 /* shift of phase in color scheme P_3D_PHASE */
#define ATTENUATION 0.0 /* exponential attenuation coefficient of contrast with time */
#define E_SCALE 1000.0 /* scaling factor for energy representation */
#define LOG_SCALE 0.2 /* scaling factor for energy log representation */
#define LOG_SHIFT -0.5 /* shift of colors on log scale */
#define LOG_ENERGY_FLOOR -1000.0 /* floor value for log of (total) energy */
#define LOG_MEAN_ENERGY_SHIFT 5.0 /* additional shift for log of mean energy */
#define E_SCALE 250.0 /* scaling factor for energy representation */
#define LOG_SCALE 0.5 /* scaling factor for energy log representation */
#define LOG_SHIFT 0.0 /* shift of colors on log scale */
#define LOG_ENERGY_FLOOR -100.0 /* floor value for log of (total) energy */
#define LOG_MEAN_ENERGY_SHIFT 1.0 /* additional shift for log of mean energy */
#define RESCALE_COLOR_IN_CENTER 0 /* set to 1 to decrease color intentiy in the center (for wave escaping ring) */
#define COLORHUE 260 /* initial hue of water color for scheme C_LUM */
@ -228,14 +248,14 @@
#define HUEAMP -200.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.5 /* scale of color scheme bar */
#define COLORBAR_RANGE_B 50.0 /* scale of color scheme bar for 2nd part */
#define COLORBAR_RANGE 3.0 /* scale of color scheme bar */
#define COLORBAR_RANGE_B 15.0 /* scale of color scheme bar for 2nd part */
#define ROTATE_COLOR_SCHEME 0 /* set to 1 to draw color scheme horizontally */
#define SAVE_TIME_SERIES 0 /* set to 1 to save wave time series at a point */
/* For debugging purposes only */
#define FLOOR 0 /* set to 1 to limit wave amplitude to VMAX */
#define FLOOR 1 /* set to 1 to limit wave amplitude to VMAX */
#define VMAX 10.0 /* max value of wave amplitude */
/* Parameters controlling 3D projection */
@ -244,14 +264,14 @@ double u_3d[2] = {0.75, -0.45}; /* projections of basis vectors for REP_AXO_
double v_3d[2] = {-0.75, -0.45};
double w_3d[2] = {0.0, 0.015};
double light[3] = {0.816496581, -0.40824829, 0.40824829}; /* vector of "light" direction for P_3D_ANGLE color scheme */
double observer[3] = {8.0, 8.0, 8.0}; /* location of observer for REP_PROJ_3D representation */
double observer[3] = {8.0, 8.0, 6.0}; /* location of observer for REP_PROJ_3D representation */
int reset_view = 0; /* switch to reset 3D view parameters (for option ROTATE_VIEW) */
#define Z_SCALING_FACTOR 0.05 /* overall scaling factor of z axis for REP_PROJ_3D representation */
#define XY_SCALING_FACTOR 2.2 /* overall scaling factor for on-screen (x,y) coordinates after projection */
#define Z_SCALING_FACTOR 0.2 /* overall scaling factor of z axis for REP_PROJ_3D representation */
#define XY_SCALING_FACTOR 2.1 /* overall scaling factor for on-screen (x,y) coordinates after projection */
#define ZMAX_FACTOR 1.0 /* max value of z coordinate for REP_PROJ_3D representation */
#define XSHIFT_3D -0.1 /* overall x shift for REP_PROJ_3D representation */
#define YSHIFT_3D 0.0 /* overall y shift for REP_PROJ_3D representation */
#define YSHIFT_3D 0.1 /* overall y shift for REP_PROJ_3D representation */
#include "global_pdes.c" /* constants and global variables */
@ -266,22 +286,234 @@ FILE *time_series_left, *time_series_right;
double courant2, courantb2; /* Courant parameters squared */
void evolve_wave_half(double phi_in[NX*NY], double psi_in[NX*NY], double phi_out[NX*NY],
short int xy_in[NX*NY], double tc[NX*NY], double tcc[NX*NY], double tgamma[NX*NY])
// void evolve_wave_half(double *phi_in, double *psi_in, double *phi_out, double *psi_out,
// short int *xy_in[NX])
void evolve_wave_half_new(double phi_in[NX*NY], double psi_in[NX*NY], double phi_out[NX*NY],
short int xy_in[NX*NY], double tc[NX*NY], double tcc[NX*NY], double tgamma[NX*NY],
t_laplacian laplace[NX*NY])
/* time step of field evolution */
/* phi is value of field at time t, psi at time t-1 */
/* this version of the function has been rewritten in order to minimize the number of if-branches */
{
int i, j, iplus, iminus, jplus, jminus;
double delta, x, y, c, cc, gamma;
double x, y, c, cc, gamma, tb_shift;
static long time = 0;
// static double tc[NX*NY], tcc[NX*NY], tgamma[NX*NY];
// static short int first = 1;
double *delta;
delta = (double *)malloc(NX*NY*sizeof(double));
/* compute the Laplacian */
compute_laplacian(phi_in, laplace, delta, xy_in);
time++;
if (OSCILLATE_TOPBOT) tb_shift = (int)((XMAX - XMIN)*(double)NX/(XMAX - XMIN));
/* evolution in the bulk */
#pragma omp parallel for private(i,j,iplus,iminus,jplus,jminus,x,y)
for (i=1; i<NX-1; i++){
for (j=1; j<NY-1; j++){
if ((TWOSPEEDS)||(xy_in[i*NY+j] != 0)){
x = phi_in[i*NY+j];
y = psi_in[i*NY+j];
/* evolve phi */
phi_out[i*NY+j] = -y + 2*x + tcc[i*NY+j]*delta[i*NY+j] - KAPPA*x - tgamma[i*NY+j]*(x-y);
}
}
}
/* left boundary */
// if (OSCILLATE_LEFT) for (j=1; j<NY-1; j++) phi_out[j] = AMPLITUDE*cos((double)time*OMEGA);
if (OSCILLATE_LEFT)
{
for (j=1; j<NY-1; j++) phi_out[j] = oscillating_bc(time);
printf("Boundary condition %.3lg\n", oscillating_bc(time));
}
else for (j=1; j<NY-1; j++){
if ((TWOSPEEDS)||(xy_in[j] != 0)){
x = phi_in[j];
y = psi_in[j];
switch (B_COND) {
case (BC_DIRICHLET):
{
phi_out[j] = -y + 2*x + tcc[j]*delta[j] - KAPPA*x - tgamma[j]*(x-y);
break;
}
case (BC_PERIODIC):
{
phi_out[j] = -y + 2*x + tcc[j]*delta[j] - KAPPA*x - tgamma[j]*(x-y);
break;
}
case (BC_ABSORBING):
{
phi_out[j] = x - tc[j]*(x - phi_in[NY+j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
case (BC_VPER_HABS):
{
phi_out[j] = x - tc[j]*(x - phi_in[NY+j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
}
}
}
/* right boundary */
for (j=1; j<NY-1; j++){
if ((TWOSPEEDS)||(xy_in[(NX-1)*NY+j] != 0)){
x = phi_in[(NX-1)*NY+j];
y = psi_in[(NX-1)*NY+j];
switch (B_COND) {
case (BC_DIRICHLET):
{
phi_out[(NX-1)*NY+j] = -y + 2*x + tcc[(NX-1)*NY+j]*delta[(NX-1)*NY+j] - KAPPA*x - tgamma[(NX-1)*NY+j]*(x-y);
break;
}
case (BC_PERIODIC):
{
phi_out[(NX-1)*NY+j] = -y + 2*x + tcc[(NX-1)*NY+j]*delta[(NX-1)*NY+j] - KAPPA*x - tgamma[(NX-1)*NY+j]*(x-y);
break;
}
case (BC_ABSORBING):
{
phi_out[(NX-1)*NY+j] = x - tc[(NX-1)*NY+j]*(x - phi_in[(NX-2)*NY+j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
case (BC_VPER_HABS):
{
phi_out[(NX-1)*NY+j] = x - tc[(NX-1)*NY+j]*(x - phi_in[(NX-2)*NY+j]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
break;
}
}
}
}
/* top boundary */
for (i=0; i<NX; i++){
if ((TWOSPEEDS)||(xy_in[i*NY+NY-1] != 0)){
x = phi_in[i*NY+NY-1];
y = psi_in[i*NY+NY-1];
if ((OSCILLATE_TOPBOT)&&(i < tb_shift)&&(i<NX-1)&&(i>0))
{
iplus = i+1;
iminus = i-1; if (iminus < 0) iminus = 0;
/* TO ADAPT */
phi_out[i*NY+NY-1] = -y + 2*x + tcc[i*NY+NY-1]*delta[i*NY+NY-1] - KAPPA*x - tgamma[i*NY+NY-1]*(x-y);
}
else switch (B_COND) {
case (BC_DIRICHLET):
{
phi_out[i*NY+NY-1] = -y + 2*x + tcc[i*NY+NY-1]*delta[i*NY+NY-1] - KAPPA*x - tgamma[i*NY+NY-1]*(x-y);
break;
}
case (BC_PERIODIC):
{
phi_out[i*NY+NY-1] = -y + 2*x + tcc[i*NY+NY-1]*delta[i*NY+NY-1] - KAPPA*x - tgamma[i*NY+NY-1]*(x-y);
break;
}
case (BC_ABSORBING):
{
phi_out[i*NY+NY-1] = x - tc[i*NY+NY-1]*(x - phi_in[i*NY+NY-2]) - KAPPA_TOPBOT*x - GAMMA_TOPBOT*(x-y);
break;
}
case (BC_VPER_HABS):
{
if (i==0) phi_out[NY-1] = x - tc[NY-1]*(x - phi_in[1*NY+NY-1]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
else phi_out[i*NY+NY-1] = -y + 2*x + tcc[i*NY+NY-1]*delta[i*NY+NY-1] - KAPPA*x - tgamma[i*NY+NY-1]*(x-y);
break;
}
}
}
}
/* bottom boundary */
for (i=0; i<NX; i++){
if ((TWOSPEEDS)||(xy_in[i*NY] != 0)){
x = phi_in[i*NY];
y = psi_in[i*NY];
if ((OSCILLATE_TOPBOT)&&(i < tb_shift)&&(i<NX-1)&&(i>0))
{
/* TO ADAPT */
phi_out[i*NY] = -y + 2*x + tcc[i*NY]*delta[i*NY] - KAPPA*x - tgamma[i*NY]*(x-y);
}
else switch (B_COND) {
case (BC_DIRICHLET):
{
phi_out[i*NY] = -y + 2*x + tcc[i*NY]*delta[i*NY] - KAPPA*x - tgamma[i*NY]*(x-y);
break;
}
case (BC_PERIODIC):
{
phi_out[i*NY] = -y + 2*x + tcc[i*NY]*delta[i*NY] - KAPPA*x - tgamma[i*NY]*(x-y);
break;
}
case (BC_ABSORBING):
{
phi_out[i*NY] = x - tc[i*NY]*(x - phi_in[i*NY+1]) - KAPPA_TOPBOT*x - GAMMA_TOPBOT*(x-y);
break;
}
case (BC_VPER_HABS):
{
if (i==0) phi_out[0] = x - tc[0]*(x - phi_in[NY]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
else phi_out[i*NY] = -y + 2*x + tcc[i*NY]*delta[i*NY] - KAPPA*x - tgamma[i*NY]*(x-y);
break;
}
}
}
}
/* add oscillating boundary condition on the left corners */
if (OSCILLATE_LEFT)
{
phi_out[0] = AMPLITUDE*cos((double)time*OMEGA);
phi_out[NY-1] = AMPLITUDE*cos((double)time*OMEGA);
}
/* for debugging purposes/if there is a risk of blow-up */
if (FLOOR)
{
#pragma omp parallel for private(i,j)
for (i=0; i<NX; i++){
for (j=0; j<NY; j++){
if (xy_in[i*NY+j] != 0)
{
if (phi_out[i*NY+j] > VMAX) phi_out[i*NY+j] = VMAX;
if (phi_out[i*NY+j] < -VMAX) phi_out[i*NY+j] = -VMAX;
}
}
}
}
free(delta);
}
void evolve_wave_half(double phi_in[NX*NY], double psi_in[NX*NY], double phi_out[NX*NY],
short int xy_in[NX*NY], double tc[NX*NY], double tcc[NX*NY], double tgamma[NX*NY])
/* time step of field evolution */
/* phi is value of field at time t, psi at time t-1 */
/* this version of the function has been rewritten in order to minimize the number of if-branches */
{
int i, j, iplus, iminus, jplus, jminus, jtop, jbot;
double delta, x, y, c, cc, gamma;
static long time = 0;
static short int first = 1;
static double tb_shift;
time++;
if ((OSCILLATE_TOPBOT)&&(first))
{
tb_shift = (int)((XMAX - XMIN)*(double)NX/(XMAX - XMIN));
if (tb_shift >= NX-1) tb_shift = NY - 2;
first = 0;
}
#pragma omp parallel for private(i,j,iplus,iminus,jplus,jminus,delta,x,y)
/* evolution in the bulk */
for (i=1; i<NX-1; i++){
@ -300,7 +532,12 @@ void evolve_wave_half(double phi_in[NX*NY], double psi_in[NX*NY], double phi_out
}
/* left boundary */
if (OSCILLATE_LEFT) for (j=1; j<NY-1; j++) phi_out[j] = AMPLITUDE*cos((double)time*OMEGA);
// if (OSCILLATE_LEFT) for (j=1; j<NY-1; j++) phi_out[j] = AMPLITUDE*cos((double)time*OMEGA);
if (OSCILLATE_LEFT)
{
for (j=1; j<NY-1; j++) phi_out[j] = oscillating_bc(time);
// printf("Boundary condition %.3lg\n", oscillating_bc(time));
}
else for (j=1; j<NY-1; j++){
if ((TWOSPEEDS)||(xy_in[j] != 0)){
x = phi_in[j];
@ -371,12 +608,22 @@ void evolve_wave_half(double phi_in[NX*NY], double psi_in[NX*NY], double phi_out
}
/* top boundary */
if (COMPARISON) jbot = NY/2;
else jbot = 0;
for (i=0; i<NX; i++){
if ((TWOSPEEDS)||(xy_in[i*NY+NY-1] != 0)){
x = phi_in[i*NY+NY-1];
y = psi_in[i*NY+NY-1];
switch (B_COND) {
if ((OSCILLATE_TOPBOT)&&(i < tb_shift)&&(i<NX-1)&&(i>0))
{
iplus = i+1;
iminus = i-1; if (iminus < 0) iminus = 0;
delta = phi_in[iplus*NY+NY-1] + phi_in[iminus*NY+NY-1] + - 2.0*x;
phi_out[i*NY+NY-1] = -y + 2*x + tcc[i*NY+NY-1]*delta - KAPPA*x - tgamma[i*NY+NY-1]*(x-y);
}
else switch (B_COND) {
case (BC_DIRICHLET):
{
iplus = i+1; if (iplus == NX) iplus = NX-1;
@ -392,7 +639,7 @@ void evolve_wave_half(double phi_in[NX*NY], double psi_in[NX*NY], double phi_out
iminus = (i-1) % NX;
if (iminus < 0) iminus += NX;
delta = phi_in[iplus*NY+NY-1] + phi_in[iminus*NY+NY-1] + phi_in[i*NY+NY-2] + phi_in[i*NY] - 4.0*x;
delta = phi_in[iplus*NY+NY-1] + phi_in[iminus*NY+NY-1] + phi_in[i*NY+NY-2] + phi_in[i*NY+jbot] - 4.0*x;
phi_out[i*NY+NY-1] = -y + 2*x + tcc[i*NY+NY-1]*delta - KAPPA*x - tgamma[i*NY+NY-1]*(x-y);
break;
}
@ -410,7 +657,7 @@ void evolve_wave_half(double phi_in[NX*NY], double psi_in[NX*NY], double phi_out
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
delta = phi_in[iplus*NY+NY-1] + phi_in[iminus*NY+NY-1] + phi_in[i*NY+NY-2] + phi_in[i*NY] - 4.0*x;
delta = phi_in[iplus*NY+NY-1] + phi_in[iminus*NY+NY-1] + phi_in[i*NY+NY-2] + phi_in[i*NY+jbot] - 4.0*x;
if (i==0) phi_out[NY-1] = x - tc[NY-1]*(x - phi_in[1*NY+NY-1]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
else phi_out[i*NY+NY-1] = -y + 2*x + tcc[i*NY+NY-1]*delta - KAPPA*x - tgamma[i*NY+NY-1]*(x-y);
break;
@ -420,12 +667,22 @@ void evolve_wave_half(double phi_in[NX*NY], double psi_in[NX*NY], double phi_out
}
/* bottom boundary */
if (COMPARISON) jtop = NY/2-1;
else jtop = NY-1;
for (i=0; i<NX; i++){
if ((TWOSPEEDS)||(xy_in[i*NY] != 0)){
x = phi_in[i*NY];
y = psi_in[i*NY];
switch (B_COND) {
if ((OSCILLATE_TOPBOT)&&(i < tb_shift)&&(i<NX-1)&&(i>0))
{
iplus = i+1;
iminus = i-1; if (iminus < 0) iminus = 0;
delta = phi_in[iplus*NY] + phi_in[iminus*NY] + - 2.0*x;
phi_out[i*NY] = -y + 2*x + tcc[i*NY]*delta - KAPPA*x - tgamma[i*NY]*(x-y);
}
else switch (B_COND) {
case (BC_DIRICHLET):
{
iplus = i+1; if (iplus == NX) iplus = NX-1;
@ -441,7 +698,7 @@ void evolve_wave_half(double phi_in[NX*NY], double psi_in[NX*NY], double phi_out
iminus = (i-1) % NX;
if (iminus < 0) iminus += NX;
delta = phi_in[iplus*NY] + phi_in[iminus*NY] + phi_in[i*NY+1] + phi_in[i*NY+NY-1] - 4.0*x;
delta = phi_in[iplus*NY] + phi_in[iminus*NY] + phi_in[i*NY+1] + phi_in[i*NY+jtop] - 4.0*x;
phi_out[i*NY] = -y + 2*x + tcc[i*NY]*delta - KAPPA*x - tgamma[i*NY]*(x-y);
break;
}
@ -459,7 +716,7 @@ void evolve_wave_half(double phi_in[NX*NY], double psi_in[NX*NY], double phi_out
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
delta = phi_in[iplus*NY] + phi_in[iminus*NY] + phi_in[i*NY+1] + phi_in[i*NY+NY-1] - 4.0*x;
delta = phi_in[iplus*NY] + phi_in[iminus*NY] + phi_in[i*NY+1] + phi_in[i*NY+jtop] - 4.0*x;
if (i==0) phi_out[0] = x - tc[0]*(x - phi_in[NY]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
else phi_out[i*NY] = -y + 2*x + tcc[i*NY]*delta - KAPPA*x - tgamma[i*NY]*(x-y);
break;
@ -468,13 +725,113 @@ void evolve_wave_half(double phi_in[NX*NY], double psi_in[NX*NY], double phi_out
}
}
/* case of comparisons - top of bottom half */
if (COMPARISON) for (i=0; i<NX; i++){
if ((TWOSPEEDS)||(xy_in[i*NY+jtop] != 0)){
x = phi_in[i*NY+jtop];
y = psi_in[i*NY+jtop];
switch (B_COND) {
case (BC_DIRICHLET):
{
iplus = i+1; if (iplus == NX) iplus = NX-1;
iminus = i-1; if (iminus == -1) iminus = 0;
delta = phi_in[iplus*NY+jtop] + phi_in[iminus*NY+jtop] + phi_in[i*NY+jtop-1] - 3.0*x;
phi_out[i*NY+jtop] = -y + 2*x + tcc[i*NY+jtop]*delta - KAPPA*x - tgamma[i*NY+jtop]*(x-y);
break;
}
case (BC_PERIODIC):
{
iplus = (i+1) % NX;
iminus = (i-1) % NX;
if (iminus < 0) iminus += NX;
delta = phi_in[iplus*NY+jtop] + phi_in[iminus*NY+jtop] + phi_in[i*NY+jtop-1] + phi_in[i*NY] - 4.0*x;
phi_out[i*NY+jtop] = -y + 2*x + tcc[i*NY+jtop]*delta - KAPPA*x - tgamma[i*NY+jtop]*(x-y);
break;
}
case (BC_ABSORBING):
{
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
delta = phi_in[iplus*NY+jtop] + phi_in[iminus*NY+jtop] + phi_in[i*NY+jtop-1] - 3.0*x;
phi_out[i*NY+jtop] = x - tc[i*NY+jtop]*(x - phi_in[i*NY+jtop-1]) - KAPPA_TOPBOT*x - GAMMA_TOPBOT*(x-y);
break;
}
case (BC_VPER_HABS):
{
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
delta = phi_in[iplus*NY+jtop] + phi_in[iminus*NY+jtop] + phi_in[i*NY+jtop-1] + phi_in[i*NY] - 4.0*x;
if (i==0) phi_out[jtop] = x - tc[jtop]*(x - phi_in[1*NY+jtop]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
else phi_out[i*NY+jtop] = -y + 2*x + tcc[i*NY+jtop]*delta - KAPPA*x - tgamma[i*NY+jtop]*(x-y);
break;
}
}
}
}
/* case of comparisons - bottom of top half */
if (COMPARISON) for (i=0; i<NX; i++){
if ((TWOSPEEDS)||(xy_in[i*NY+jbot] != 0)){
x = phi_in[i*NY+jbot];
y = psi_in[i*NY+jbot];
switch (B_COND) {
case (BC_DIRICHLET):
{
iplus = i+1; if (iplus == NX) iplus = NX-1;
iminus = i-1; if (iminus == -1) iminus = 0;
delta = phi_in[iplus*NY+jbot] + phi_in[iminus*NY+jbot] + phi_in[i*NY+jbot+1] - 3.0*x;
phi_out[i*NY+jbot] = -y + 2*x + tcc[i*NY+jbot]*delta - KAPPA*x - tgamma[i*NY+jbot]*(x-y);
break;
}
case (BC_PERIODIC):
{
iplus = (i+1) % NX;
iminus = (i-1) % NX;
if (iminus < 0) iminus += NX;
delta = phi_in[iplus*NY+jbot] + phi_in[iminus*NY+jbot] + phi_in[i*NY+jbot+1] + phi_in[i*NY+jbot] - 4.0*x;
phi_out[i*NY+jbot] = -y + 2*x + tcc[i*NY+jbot]*delta - KAPPA*x - tgamma[i*NY+jbot]*(x-y);
break;
}
case (BC_ABSORBING):
{
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
delta = phi_in[iplus*NY+jbot] + phi_in[iminus*NY+jbot] + phi_in[i*NY+jbot+1] - 3.0*x;
phi_out[i*NY+jbot] = x - tc[i*NY+jbot]*(x - phi_in[i*NY+jbot+1]) - KAPPA_TOPBOT*x - GAMMA_TOPBOT*(x-y);
break;
}
case (BC_VPER_HABS):
{
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
delta = phi_in[iplus*NY+jbot] + phi_in[iminus*NY+jbot] + phi_in[i*NY+jbot+1] + phi_in[i*NY+NY-1] - 4.0*x;
if (i==0) phi_out[jbot] = x - tc[jbot]*(x - phi_in[NY]) - KAPPA_SIDES*x - GAMMA_SIDES*(x-y);
else phi_out[i*NY+jbot] = -y + 2*x + tcc[i*NY+jbot]*delta - KAPPA*x - tgamma[i*NY+jbot]*(x-y);
break;
}
}
}
}
/* add oscillating boundary condition on the left corners */
if (OSCILLATE_LEFT)
{
phi_out[0] = AMPLITUDE*cos((double)time*OMEGA);
phi_out[NY-1] = AMPLITUDE*cos((double)time*OMEGA);
phi_out[0] = oscillating_bc(time);
phi_out[NY-1] = oscillating_bc(time);
}
/* for debugging purposes/if there is a risk of blow-up */
if (FLOOR) for (i=0; i<NX; i++){
for (j=0; j<NY; j++){
@ -489,13 +846,27 @@ void evolve_wave_half(double phi_in[NX*NY], double psi_in[NX*NY], double phi_out
void evolve_wave(double phi[NX*NY], double psi[NX*NY], double tmp[NX*NY], short int xy_in[NX*NY],
double tc[NX*NY], double tcc[NX*NY], double tgamma[NX*NY])
double tc[NX*NY], double tcc[NX*NY], double tgamma[NX*NY], t_laplacian laplace[NX*NY], t_laplacian laplace1[NX*NY],
t_laplacian laplace2[NX*NY])
/* time step of field evolution */
/* phi is value of field at time t, psi at time t-1 */
{
evolve_wave_half(phi, psi, tmp, xy_in, tc, tcc, tgamma);
evolve_wave_half(tmp, phi, psi, xy_in, tc, tcc, tgamma);
evolve_wave_half(psi, tmp, phi, xy_in, tc, tcc, tgamma);
if (PRECOMPUTE_BC)
{
// evolve_wave_half_new(phi, psi, phi_tmp, psi_tmp, xy_in, tc, tcc, tgamma, laplace);
// evolve_wave_half_new(phi_tmp, psi_tmp, phi, psi, xy_in, tc, tcc, tgamma, laplace_tmp);
evolve_wave_half_new(phi, psi, tmp, xy_in, tc, tcc, tgamma, laplace);
evolve_wave_half_new(tmp, phi, psi, xy_in, tc, tcc, tgamma, laplace1);
evolve_wave_half_new(psi, tmp, phi, xy_in, tc, tcc, tgamma, laplace2);
}
else
{
// evolve_wave_half(phi, psi, phi_tmp, psi_tmp, xy_in, tc, tcc, tgamma);
// evolve_wave_half(phi_tmp, psi_tmp, phi, psi, xy_in, tc, tcc, tgamma);
evolve_wave_half(phi, psi, tmp, xy_in, tc, tcc, tgamma);
evolve_wave_half(tmp, phi, psi, xy_in, tc, tcc, tgamma);
evolve_wave_half(psi, tmp, phi, xy_in, tc, tcc, tgamma);
}
}
@ -535,13 +906,14 @@ void viewpoint_schedule(int i)
void animation()
{
double time, scale, ratio, startleft[2], startright[2], sign, r2, xy[2], fade_value;
double *phi, *psi, *phi_tmp, *tmp, *total_energy, *color_scale, *tc, *tcc, *tgamma;
double time, scale, ratio, startleft[2], startright[2], sign = 1.0, r2, xy[2], fade_value, yshift, speed = 0.0, a, b, c;
double *phi, *psi, *tmp, *total_energy, *color_scale, *tc, *tcc, *tgamma;
short int *xy_in;
int i, j, s, sample_left[2], sample_right[2], period = 0, fade;
static int counter = 0;
long int wave_value;
t_wave *wave;
t_laplacian *laplace, *laplace1, *laplace2;
if (SAVE_TIME_SERIES)
{
@ -562,18 +934,43 @@ void animation()
wave = (t_wave *)malloc(NX*NY*sizeof(t_wave));
laplace = (t_laplacian *)malloc(NX*NY*sizeof(t_laplacian));
laplace1 = (t_laplacian *)malloc(NX*NY*sizeof(t_laplacian));
laplace2 = (t_laplacian *)malloc(NX*NY*sizeof(t_laplacian));
/* initialise positions and radii of circles */
if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN == D_CIRCLES_IN_RECT)) init_circle_config(circles);
else if (B_DOMAIN == D_POLYGONS) init_polygon_config(polygons);
if (COMPARISON)
{
if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN == D_CIRCLES_IN_RECT))
ncircles = init_circle_config_pattern(circles, CIRCLE_PATTERN);
else if (B_DOMAIN == D_POLYGONS) ncircles = init_polygon_config_pattern(polygons, CIRCLE_PATTERN);
if ((B_DOMAIN_B == D_CIRCLES)||(B_DOMAIN_B == D_CIRCLES_IN_RECT))
ncircles_b = init_circle_config_pattern(circles_b, CIRCLE_PATTERN_B);
else if (B_DOMAIN_B == D_POLYGONS) ncircles_b = init_polygon_config_pattern(polygons_b, CIRCLE_PATTERN_B);
/* TO DO: adapt to different polygon patterns */
}
else
{
if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN == D_CIRCLES_IN_RECT)) ncircles = init_circle_config(circles);
else if (B_DOMAIN == D_POLYGONS) ncircles = init_polygon_config(polygons);
}
printf("Polygons initialized\n");
/* initialise polyline for von Koch and similar domains */
npolyline = init_polyline(MDEPTH, polyline);
for (i=0; i<npolyline; i++) printf("vertex %i: (%.3f, %.3f)\n", i, polyline[i].x, polyline[i].y);
if (COMPARISON) npolyline_b = init_polyline(MDEPTH, polyline);
courant2 = COURANT*COURANT;
courantb2 = COURANTB*COURANTB;
c = COURANT*(XMAX - XMIN)/(double)NX;
// a = 0.015;
// b = 0.0003;
// a = 0.04;
// b = 0.0018;
a = 0.05;
b = 0.0016;
/* initialize color scale, for option RESCALE_COLOR_IN_CENTER */
if (RESCALE_COLOR_IN_CENTER)
@ -589,6 +986,14 @@ void animation()
/* initialize wave with a drop at one point, zero elsewhere */
// init_circular_wave(0.0, -LAMBDA, phi, psi, xy_in);
/* initialize coordinates of neighbours for discrete Laplacian */
if (PRECOMPUTE_BC)
{
init_laplacian_coords(laplace, phi);
init_laplacian_coords(laplace1, tmp);
init_laplacian_coords(laplace2, psi);
}
/* initialize total energy table */
if ((ZPLOT == P_MEAN_ENERGY)||(ZPLOT_B == P_MEAN_ENERGY)||(ZPLOT == P_LOG_MEAN_ENERGY)||(ZPLOT_B == P_LOG_MEAN_ENERGY))
@ -600,8 +1005,8 @@ void animation()
// init_circular_wave_mod(polyline[85].x, polyline[85].y, phi, psi, xy_in);
init_circular_wave_mod(0.0, 0.0, phi, psi, xy_in);
// init_wave_flat_mod(phi, psi, xy_in);
// init_circular_wave_mod(0.95, 0.0, phi, psi, xy_in);
init_wave_flat_mod(phi, psi, xy_in);
// add_circular_wave_mod(1.0, 1.0, 0.0, phi, psi, xy_in);
// printf("Wave initialized\n");
@ -656,7 +1061,7 @@ void animation()
draw_wave_3d(0, phi, psi, xy_in, wave, ZPLOT, CPLOT, COLOR_PALETTE, 0, 1.0, 1);
for (j=0; j<NVID; j++)
{
evolve_wave(phi, psi, tmp, xy_in, tc, tcc, tgamma);
evolve_wave(phi, psi, tmp, xy_in, tc, tcc, tgamma, laplace, laplace1, laplace2);
if (SAVE_TIME_SERIES)
{
wave_value = (long int)(phi[sample_left[0]*NY+sample_left[1]]*1.0e16);
@ -674,13 +1079,23 @@ void animation()
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT, COLORBAR_RANGE, COLOR_PALETTE, fade, fade_value);
/* add oscillating waves */
if ((ADD_OSCILLATING_SOURCE)&&(i%OSCILLATING_SOURCE_PERIOD == OSCILLATING_SOURCE_PERIOD - 1))
// if ((ADD_OSCILLATING_SOURCE)&&(i%OSCILLATING_SOURCE_PERIOD == OSCILLATING_SOURCE_PERIOD - 1))
if ((ADD_OSCILLATING_SOURCE)&&(i%OSCILLATING_SOURCE_PERIOD == 1))
{
add_circular_wave_mod(1.0, -1.0, 0.0, phi, psi, xy_in);
// add_circular_wave_mod(1.0, -1.0, 0.0, phi, psi, xy_in);
// add_circular_wave(1.0, -1.5*LAMBDA, 0.0, phi, psi, xy_in);
// add_circular_wave(-1.0, 0.6*cos((double)(period)*DPI/3.0), 0.6*sin((double)(period)*DPI/3.0), phi, psi, xy_in);
period++;
yshift = (double)period*a + (double)(period*period)*b;
add_circular_wave_mod(sign, -1.5 + yshift, 0.0, phi, psi, xy_in);
// speed = (a + 2.0*(double)(period)*b)/((double)(NVID));
// speed = 0.55*(a + 2.0*(double)(period)*b)/((double)(NVID*OSCILLATING_SOURCE_PERIOD));
speed = (a + 2.0*(double)(period)*b)/((double)(3*NVID*OSCILLATING_SOURCE_PERIOD));
printf("v = %.3lg, c = %.3lg\n", speed, c);
speed = speed/c;
sign = -sign;
period++;
}
if (PRINT_SPEED) print_speed_3d(speed, 0, 1.0);
glutSwapBuffers();
@ -693,6 +1108,7 @@ void animation()
{
draw_wave_3d(1, phi, psi, xy_in, wave, ZPLOT_B, CPLOT_B, COLOR_PALETTE_B, 0, 1.0, 1);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT_B, COLORBAR_RANGE_B, COLOR_PALETTE_B, 0, 1.0);
if (PRINT_SPEED) print_speed_3d(speed, 0, 1.0);
glutSwapBuffers();
save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter);
counter++;
@ -707,6 +1123,7 @@ void animation()
s = system("mv wave*.tif tif_wave/");
}
}
else printf("Computing frame %i\n", i);
}
@ -716,6 +1133,7 @@ void animation()
{
draw_wave_3d(0, phi, psi, xy_in, wave, ZPLOT, CPLOT, COLOR_PALETTE, 0, 1.0, 1);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT, COLORBAR_RANGE, COLOR_PALETTE, 0, 1.0);
if (PRINT_SPEED) print_speed_3d(speed, 0, 1.0);
glutSwapBuffers();
if (!FADE) for (i=0; i<MID_FRAMES; i++) save_frame();
@ -729,11 +1147,13 @@ void animation()
fade_value = 1.0 - (double)i/(double)MID_FRAMES;
draw_wave_3d(0, phi, psi, xy_in, wave, ZPLOT, CPLOT, COLOR_PALETTE, 1, fade_value, 0);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT, COLORBAR_RANGE, COLOR_PALETTE, 1, fade_value);
if (PRINT_SPEED) print_speed_3d(speed, 1, fade_value);
glutSwapBuffers();
save_frame_counter(NSTEPS + i + 1);
}
draw_wave_3d(1, phi, psi, xy_in, wave, ZPLOT_B, CPLOT_B, COLOR_PALETTE_B, 0, 1.0, 1);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT_B, COLORBAR_RANGE_B, COLOR_PALETTE_B, 0, 1.0);
if (PRINT_SPEED) print_speed_3d(speed, 0, 1.0);
glutSwapBuffers();
if (!FADE) for (i=0; i<END_FRAMES; i++) save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter + i);
@ -747,6 +1167,7 @@ void animation()
fade_value = 1.0 - (double)i/(double)END_FRAMES;
draw_wave_3d(1, phi, psi, xy_in, wave, ZPLOT_B, CPLOT_B, COLOR_PALETTE_B, 1, fade_value, 0);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT_B, COLORBAR_RANGE_B, COLOR_PALETTE_B, 1, fade_value);
if (PRINT_SPEED) print_speed_3d(speed, 1, fade_value);
glutSwapBuffers();
save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter + i);
}
@ -759,6 +1180,7 @@ void animation()
fade_value = 1.0 - (double)i/(double)END_FRAMES;
draw_wave_3d(0, phi, psi, xy_in, wave, ZPLOT, CPLOT, COLOR_PALETTE, 1, fade_value, 0);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT, COLORBAR_RANGE, COLOR_PALETTE, 1, fade_value);
if (PRINT_SPEED) print_speed_3d(speed, 1, fade_value);
glutSwapBuffers();
save_frame_counter(NSTEPS + 1 + counter + i);
}
@ -778,6 +1200,9 @@ void animation()
free(tgamma);
free(wave);
free(laplace);
free(laplace1);
free(laplace2);
if (SAVE_TIME_SERIES)

View File

@ -24,7 +24,7 @@
/* create movie using */
/* ffmpeg -i wave.%05d.tif -vcodec libx264 wave.mp4 */
/* */
/*********************************************************************************/
/******************************F***************************************************/
/*********************************************************************************/
/* */
@ -50,17 +50,17 @@
#define WINWIDTH 1920 /* window width */
#define WINHEIGHT 1000 /* window height */
#define NX 1920 /* number of grid points on x axis */
#define NY 1000 /* number of grid points on y axis */
// #define NX 3840 /* number of grid points on x axis */
// #define NY 2000 /* number of grid points on y axis */
// #define NX 1920 /* number of grid points on x axis */
// #define NY 1000 /* number of grid points on y axis */
#define NX 3840 /* number of grid points on x axis */
#define NY 2000 /* number of grid points on y axis */
#define XMIN -2.0
#define XMAX 2.0 /* x interval */
#define YMIN -1.041666667
#define YMAX 1.041666667 /* y interval for 9/16 aspect ratio */
#define HIGHRES 0 /* set to 1 if resolution of grid is double that of displayed image */
#define HIGHRES 1 /* set to 1 if resolution of grid is double that of displayed image */
// #define WINWIDTH 1280 /* window width */
// #define WINHEIGHT 720 /* window height */
@ -79,16 +79,20 @@
/* Choice of the billiard table */
#define B_DOMAIN 3 /* choice of domain shape, see list in global_pdes.c */
#define B_DOMAIN 20 /* choice of domain shape, see list in global_pdes.c */
#define CIRCLE_PATTERN 201 /* pattern of circles or polygons, see list in global_pdes.c */
#define CIRCLE_PATTERN 1 /* pattern of circles or polygons, see list in global_pdes.c */
#define COMPARISON 0 /* set to 1 to compare two different patterns */
#define B_DOMAIN_B 20 /* second domain shape, for comparisons */
#define CIRCLE_PATTERN_B 0 /* second pattern of circles or polygons */
#define P_PERCOL 0.25 /* probability of having a circle in C_RAND_PERCOL arrangement */
#define NPOISSON 300 /* number of points for Poisson C_RAND_POISSON arrangement */
#define RANDOM_POLY_ANGLE 1 /* set to 1 to randomize angle of polygons */
#define LAMBDA 0.75 /* parameter controlling the dimensions of domain */
#define MU 0.2 /* parameter controlling the dimensions of domain */
#define LAMBDA 0.7 /* parameter controlling the dimensions of domain */
#define MU 0.028 /* parameter controlling the dimensions of domain */
#define NPOLY 3 /* number of sides of polygon */
#define APOLY 0.3333333333333333 /* angle by which to turn polygon, in units of Pi/2 */
#define MDEPTH 6 /* depth of computation of Menger gasket */
@ -96,8 +100,8 @@
#define MANDELLEVEL 1000 /* iteration level for Mandelbrot set */
#define MANDELLIMIT 10.0 /* limit value for approximation of Mandelbrot set */
#define FOCI 1 /* set to 1 to draw focal points of ellipse */
#define NGRIDX 36 /* number of grid point for grid of disks */
#define NGRIDY 6 /* number of grid point for grid of disks */
#define NGRIDX 12 /* number of grid point for grid of disks */
#define NGRIDY 15 /* number of grid point for grid of disks */
#define X_SHOOTER -0.2
#define Y_SHOOTER -0.6
@ -118,13 +122,14 @@
#define TWOSPEEDS 1 /* set to 1 to replace hardcore boundary by medium with different speed */
#define OSCILLATE_LEFT 1 /* set to 1 to add oscilating boundary condition on the left */
#define OSCILLATE_TOPBOT 0 /* set to 1 to enforce a planar wave on top and bottom boundary */
#define OSCILLATION_SCHEDULE 3 /* oscillation schedule, see list in global_pdes.c */
#define OMEGA 0.005 /* frequency of periodic excitation */
#define OMEGA 0.0005 /* frequency of periodic excitation */
#define AMPLITUDE 0.8 /* amplitude of periodic excitation */
#define DAMPING 2.5e-5 /* damping of periodic excitation */
#define ACHIRP 0.25 /* acceleration coefficient in chirp */
#define DAMPING 0.0 /* damping of periodic excitation */
#define COURANT 0.05 /* Courant number */
#define COURANTB 0.0375 /* Courant number in medium B */
// #define COURANTB 0.016363636 /* Courant number in medium B */
#define COURANTB 0.0125 /* Courant number in medium B */
#define GAMMA 0.0 /* damping factor in wave equation */
#define GAMMAB 0.0 /* damping factor in wave equation */
#define GAMMA_SIDES 1.0e-4 /* damping factor on boundary */
@ -138,21 +143,20 @@
/* For similar wave forms, COURANT^2*GAMMA should be kept constant */
#define ADD_OSCILLATING_SOURCE 0 /* set to 1 to add an oscillating wave source */
#define OSCILLATING_SOURCE_PERIOD 100 /* period of oscillating source */
#define OSCILLATING_SOURCE_PERIOD 6 /* period of oscillating source */
/* Boundary conditions, see list in global_pdes.c */
#define B_COND 3
// #define B_COND 2
/* Parameters for length and speed of simulation */
#define NSTEPS 2700 /* number of frames of movie */
// #define NSTEPS 100 /* number of frames of movie */
#define NVID 30 /* number of iterations between images displayed on screen */
#define NVID 15 /* number of iterations between images displayed on screen */
#define NSEG 1000 /* number of segments of boundary */
#define INITIAL_TIME 0 /* time after which to start saving frames */
#define INITIAL_TIME 50 /* time after which to start saving frames */
#define BOUNDARY_WIDTH 1 /* width of billiard boundary */
#define PRINT_SPEED 0 /* print speed of moving source */
#define PAUSE 200 /* number of frames after which to pause */
#define PSLEEP 2 /* sleep time during pause */
@ -165,21 +169,19 @@
/* Parameters of initial condition */
#define INITIAL_AMP 0.75 /* amplitude of initial condition */
#define INITIAL_VARIANCE 0.00025 /* variance of initial condition */
#define INITIAL_WAVELENGTH 0.015 /* wavelength of initial condition */
#define INITIAL_VARIANCE 0.00005 /* variance of initial condition */
#define INITIAL_WAVELENGTH 0.004 /* wavelength of initial condition */
/* Plot type, see list in global_pdes.c */
#define PLOT 0
// #define PLOT 0
// #define PLOT 1
#define PLOT 1
#define PLOT_B 3 /* plot type for second movie */
#define PLOT_B 0 /* plot type for second movie */
/* Color schemes */
#define COLOR_PALETTE 18 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE_B 13 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE 13 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE_B 11 /* Color palette, see list in global_pdes.c */
#define BLACK 1 /* background */
@ -190,7 +192,7 @@
#define PHASE_FACTOR 1.0 /* factor in computation of phase in color scheme P_3D_PHASE */
#define PHASE_SHIFT 0.0 /* shift of phase in color scheme P_3D_PHASE */
#define ATTENUATION 0.0 /* exponential attenuation coefficient of contrast with time */
#define E_SCALE 300.0 /* scaling factor for energy representation */
#define E_SCALE 250.0 /* scaling factor for energy representation */
#define LOG_SCALE 1.0 /* scaling factor for energy log representation */
#define LOG_SHIFT 1.0 /* shift of colors on log scale */
#define RESCALE_COLOR_IN_CENTER 0 /* set to 1 to decrease color intentiy in the center (for wave escaping ring) */
@ -202,9 +204,9 @@
#define HUEMEAN 180.0 /* mean value of hue for color scheme C_HUE */
#define HUEAMP -180.0 /* amplitude of variation of hue for color scheme C_HUE */
#define DRAW_COLOR_SCHEME 1 /* set to 1 to plot the color scheme */
#define COLORBAR_RANGE 1.0 /* scale of color scheme bar */
#define COLORBAR_RANGE_B 5.0 /* scale of color scheme bar for 2nd part */
#define DRAW_COLOR_SCHEME 1 /* set to 1 to plot the color scheme */
#define COLORBAR_RANGE 5.0 /* scale of color scheme bar */
#define COLORBAR_RANGE_B 2.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 */
@ -226,21 +228,25 @@ double courant2, courantb2; /* Courant parameters squared */
/*********************/
void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX],
// void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX], double *psi_out[NX],
// short int *xy_in[NX])
void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX],
short int *xy_in[NX])
/* time step of field evolution */
/* phi is value of field at time t, psi at time t-1 */
/* this version of the function has been rewritten in order to minimize the number of if-branches */
{
int i, j, iplus, iminus, jplus, jminus;
double delta, x, y, c, cc, gamma;
double delta, x, y, c, cc, gamma, tb_shift;
static long time = 0;
static double tc[NX][NY], tcc[NX][NY], tgamma[NX][NY];
static short int first = 1;
time++;
// if (OSCILLATE_TOPBOT) tb_shift = (int)((X_SHIFT - XMIN)*(double)NX/(XMAX - XMIN));
if (OSCILLATE_TOPBOT) tb_shift = (int)((XMAX - XMIN)*(double)NX/(XMAX - XMIN));
/* initialize tables with wave speeds and dissipation */
if (first)
{
@ -277,12 +283,13 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
/* evolve phi */
phi_out[i][j] = -y + 2*x + tcc[i][j]*delta - KAPPA*x - tgamma[i][j]*(x-y);
// psi_out[i][j] = x;
}
}
}
/* left boundary */
if (OSCILLATE_LEFT) for (j=1; j<NY-1; j++) phi_out[0][j] = AMPLITUDE*cos((double)time*OMEGA)*exp(-(double)time*DAMPING);
if (OSCILLATE_LEFT) for (j=1; j<NY-1; j++) phi_out[0][j] = oscillating_bc(time);
else for (j=1; j<NY-1; j++){
if ((TWOSPEEDS)||(xy_in[0][j] != 0)){
x = phi_in[0][j];
@ -314,6 +321,7 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
break;
}
}
// psi_out[0][j] = x;
}
}
@ -349,6 +357,7 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
break;
}
}
// psi_out[NX-1][j] = x;
}
}
@ -358,7 +367,15 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
x = phi_in[i][NY-1];
y = psi_in[i][NY-1];
switch (B_COND) {
if ((OSCILLATE_TOPBOT)&&(i < tb_shift)&&(i<NX-1)&&(i>0))
{
iplus = i+1;
iminus = i-1; if (iminus < 0) iminus = 0;
delta = phi_in[iplus][NY-1] + phi_in[iminus][NY-1] + - 2.0*x;
phi_out[i][NY-1] = -y + 2*x + tcc[i][NY-1]*delta - KAPPA*x - tgamma[i][NY-1]*(x-y);
}
else switch (B_COND) {
case (BC_DIRICHLET):
{
iplus = i+1; if (iplus == NX) iplus = NX-1;
@ -398,6 +415,7 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
break;
}
}
// psi_out[i][NY-1] = x;
}
}
@ -407,7 +425,15 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
x = phi_in[i][0];
y = psi_in[i][0];
switch (B_COND) {
if ((OSCILLATE_TOPBOT)&&(i < tb_shift)&&(i<NX-1)&&(i>0))
{
iplus = i+1;
iminus = i-1; if (iminus < 0) iminus = 0;
delta = phi_in[iplus][0] + phi_in[iminus][0] + - 2.0*x;
phi_out[i][0] = -y + 2*x + tcc[i][0]*delta - KAPPA*x - tgamma[i][0]*(x-y);
}
else switch (B_COND) {
case (BC_DIRICHLET):
{
iplus = i+1; if (iplus == NX) iplus = NX-1;
@ -447,14 +473,15 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
break;
}
}
// psi_out[i][0] = x;
}
}
/* add oscillating boundary condition on the left corners */
if (OSCILLATE_LEFT)
{
phi_out[0][0] = AMPLITUDE*cos((double)time*OMEGA)*exp(-(double)time*DAMPING);
phi_out[0][NY-1] = AMPLITUDE*cos((double)time*OMEGA)*exp(-(double)time*DAMPING);
phi_out[0][0] = oscillating_bc(time);
phi_out[0][NY-1] = oscillating_bc(time);
}
/* for debugging purposes/if there is a risk of blow-up */
@ -464,6 +491,8 @@ void evolve_wave_half(double *phi_in[NX], double *psi_in[NX], double *phi_out[NX
{
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;
}
}
}
@ -474,7 +503,7 @@ void evolve_wave(double *phi[NX], double *psi[NX], double *tmp[NX], short int *x
/* time step of field evolution */
/* phi is value of field at time t, psi at time t-1 */
{
// For the purpose of these comments w[t], w[t-1], w[t+1] are used to refer
// For the purpose of these comments w[t], w[t-1], w[t+1] are used to refer
// to phi, psi and the result respectively to avoid confusion with the
// passed parameter names.
// At the beginning w[t] is saved in phi, w[t-1] in psi and tmp is space
@ -518,7 +547,8 @@ void draw_color_bar_palette(int plot, double range, int palette, int fade, doubl
void animation()
{
double time, scale, ratio, startleft[2], startright[2], sign, r2, xy[2], fade_value;
double time, scale, ratio, startleft[2], startright[2], sign = 1.0, r2, xy[2], fade_value, yshift, speed = 0.0, a, b, c;
// double *phi[NX], *psi[NX], *phi_tmp[NX], *psi_tmp[NX], *total_energy[NX], *color_scale[NX];
double *phi[NX], *psi[NX], *tmp[NX], *total_energy[NX], *color_scale[NX];
short int *xy_in[NX];
int i, j, s, sample_left[2], sample_right[2], period = 0, fade;
@ -536,6 +566,8 @@ void animation()
{
phi[i] = (double *)malloc(NY*sizeof(double));
psi[i] = (double *)malloc(NY*sizeof(double));
// phi_tmp[i] = (double *)malloc(NY*sizeof(double));
// psi_tmp[i] = (double *)malloc(NY*sizeof(double));
tmp[i] = (double *)malloc(NY*sizeof(double));
total_energy[i] = (double *)malloc(NY*sizeof(double));
xy_in[i] = (short int *)malloc(NY*sizeof(short int));
@ -543,8 +575,8 @@ void animation()
}
/* initialise positions and radii of circles */
if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN == D_CIRCLES_IN_RECT)) init_circle_config(circles);
else if (B_DOMAIN == D_POLYGONS) init_polygon_config(polygons);
if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN == D_CIRCLES_IN_RECT)) ncircles = init_circle_config(circles);
else if (B_DOMAIN == D_POLYGONS) ncircles = init_polygon_config(polygons);
printf("Polygons initialized\n");
/* initialise polyline for von Koch and similar domains */
@ -553,6 +585,7 @@ void animation()
courant2 = COURANT*COURANT;
courantb2 = COURANTB*COURANTB;
c = COURANT*(XMAX - XMIN)/(double)NX;
/* initialize color scale, for option RESCALE_COLOR_IN_CENTER */
if (RESCALE_COLOR_IN_CENTER)
@ -627,13 +660,23 @@ void animation()
blank();
glColor3f(0.0, 0.0, 0.0);
// draw_wave(phi, psi, xy_in, 1.0, 0, PLOT);
if (HIGHRES) draw_wave_highres_palette(2, phi, psi, total_energy, xy_in, 1.0, 0, PLOT, COLOR_PALETTE);
if (HIGHRES) draw_wave_highres_palette(2, phi, psi, total_energy, xy_in, 1.0, 0, PLOT, COLOR_PALETTE, 0, 1.0);
else draw_wave_epalette(phi, psi, total_energy, color_scale, xy_in, 1.0, 0, PLOT, COLOR_PALETTE, 0, 1.0);
draw_billiard(0, 1.0);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(PLOT, COLORBAR_RANGE, COLOR_PALETTE, fade, fade_value);
if (PRINT_SPEED)
{
a = 0.0075;
b = 0.00015;
// speed = a/((double)(NVID)*c);
// speed = 0.55*a/((double)(NVID*OSCILLATING_SOURCE_PERIOD)*c);
speed = a/((double)(3*NVID*OSCILLATING_SOURCE_PERIOD)*c);
/* the factor 3 is due to evolve_wave calling evolve_wave_half 3 times */
print_speed(speed, 0, 1.0);
}
glutSwapBuffers();
@ -654,10 +697,11 @@ void animation()
else scale = 1.0;
// draw_wave(phi, psi, xy_in, scale, i, PLOT);
if (HIGHRES) draw_wave_highres_palette(2, phi, psi, total_energy, xy_in, scale, i, PLOT, COLOR_PALETTE);
if (HIGHRES) draw_wave_highres_palette(2, phi, psi, total_energy, xy_in, scale, i, PLOT, COLOR_PALETTE, 0, 1.0);
else draw_wave_epalette(phi, psi, total_energy, color_scale, xy_in, scale, i, PLOT, COLOR_PALETTE, 0, 1.0);
for (j=0; j<NVID; j++)
{
// evolve_wave(phi, psi, phi_tmp, psi_tmp, xy_in);
evolve_wave(phi, psi, tmp, xy_in);
if (SAVE_TIME_SERIES)
{
@ -673,15 +717,26 @@ void animation()
draw_billiard(0, 1.0);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(PLOT, COLORBAR_RANGE, COLOR_PALETTE, fade, fade_value);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(PLOT, COLORBAR_RANGE, COLOR_PALETTE, fade, fade_value);
/* add oscillating waves */
if ((ADD_OSCILLATING_SOURCE)&&(i%OSCILLATING_SOURCE_PERIOD == OSCILLATING_SOURCE_PERIOD - 1))
{
// add_circular_wave(1.0, -1.5*LAMBDA, 0.0, phi, psi, xy_in);
add_circular_wave(-1.0, 0.6*cos((double)(period)*DPI/3.0), 0.6*sin((double)(period)*DPI/3.0), phi, psi, xy_in);
period++;
// add_circular_wave(-1.0, 0.6*cos((double)(period)*DPI/3.0), 0.6*sin((double)(period)*DPI/3.0), phi, psi, xy_in);
sign = -sign;
period++;
yshift = (double)period*a + (double)(period*period)*b;
add_circular_wave(sign, -1.5 + yshift, 0.0, phi, psi, xy_in);
// speed = (a + 2.0*(double)(period)*b)/((double)(NVID));
// speed = 0.55*(a + 2.0*(double)(period)*b)/((double)(NVID*OSCILLATING_SOURCE_PERIOD));
speed = (a + 2.0*(double)(period)*b)/((double)(3*NVID*OSCILLATING_SOURCE_PERIOD));
printf("v = %.3lg, c = %.3lg\n", speed, c);
speed = speed/c;
// speed = 120.0*speed/((double)NVID*COURANT);
}
if (PRINT_SPEED) print_speed(speed, 0, 1.0);
glutSwapBuffers();
@ -693,10 +748,12 @@ void animation()
if ((i >= INITIAL_TIME)&&(DOUBLE_MOVIE))
{
// draw_wave(phi, psi, xy_in, scale, i, PLOT_B);
if (HIGHRES) draw_wave_highres_palette(2, phi, psi, total_energy, xy_in, scale, i, PLOT_B, COLOR_PALETTE_B);
if (HIGHRES)
draw_wave_highres_palette(2, phi, psi, total_energy, xy_in, scale, i, PLOT_B, COLOR_PALETTE_B, 0, 1.0);
else draw_wave_epalette(phi, psi, total_energy, color_scale, xy_in, scale, i, PLOT_B, COLOR_PALETTE_B, 0, 1.0);
draw_billiard(0, 1.0);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(PLOT_B, COLORBAR_RANGE_B, COLOR_PALETTE_B, 0, 1.0);
if (PRINT_SPEED) print_speed(speed, 0, 1.0);
glutSwapBuffers();
save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter);
// save_frame_counter(NSTEPS + 21 + counter);
@ -720,42 +777,50 @@ void animation()
if (DOUBLE_MOVIE)
{
// draw_wave(phi, psi, xy_in, scale, i, PLOT);
if (HIGHRES) draw_wave_highres_palette(2, phi, psi, total_energy, xy_in, scale, NSTEPS, PLOT, COLOR_PALETTE);
if (HIGHRES) draw_wave_highres_palette(2, phi, psi, total_energy, xy_in, scale, NSTEPS, PLOT, COLOR_PALETTE, 0, 1.0);
else draw_wave_epalette(phi, psi, total_energy, color_scale, xy_in, scale, NSTEPS, PLOT, COLOR_PALETTE, 0, 1.0);
draw_billiard(0, 1.0);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(PLOT, COLORBAR_RANGE, COLOR_PALETTE, 0, 1.0);
if (PRINT_SPEED) print_speed(speed, 0, 1.0);
glutSwapBuffers();
}
if (!FADE) for (i=0; i<MID_FRAMES; i++) save_frame();
else for (i=0; i<MID_FRAMES; i++)
{
fade_value = 1.0 - (double)i/(double)MID_FRAMES;
if (HIGHRES) draw_wave_highres_palette(2, phi, psi, total_energy, xy_in, scale, NSTEPS, PLOT, COLOR_PALETTE);
if (HIGHRES)
draw_wave_highres_palette(2, phi, psi, total_energy, xy_in, scale, NSTEPS, PLOT, COLOR_PALETTE, 1, fade_value);
else draw_wave_epalette(phi, psi, total_energy, color_scale, xy_in, scale, NSTEPS, PLOT, COLOR_PALETTE, 1, fade_value);
draw_billiard(1, fade_value);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(PLOT, COLORBAR_RANGE, COLOR_PALETTE, 1, fade_value);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(PLOT, COLORBAR_RANGE, COLOR_PALETTE, 1, fade_value);
if (PRINT_SPEED) print_speed(speed, 1, fade_value);
glutSwapBuffers();
save_frame_counter(NSTEPS + i + 1);
}
if (DOUBLE_MOVIE)
{
// draw_wave(phi, psi, xy_in, scale, i, PLOT_B);
if (HIGHRES) draw_wave_highres_palette(2, phi, psi, total_energy, xy_in, scale, NSTEPS, PLOT_B, COLOR_PALETTE_B);
if (HIGHRES)
draw_wave_highres_palette(2, phi, psi, total_energy, xy_in, scale, NSTEPS, PLOT_B, COLOR_PALETTE_B, 0, 1.0);
else draw_wave_epalette(phi, psi, total_energy, color_scale, xy_in, scale, NSTEPS, PLOT_B, COLOR_PALETTE_B, 0, 1.0);
draw_billiard(0, 1.0);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(PLOT_B, COLORBAR_RANGE_B, COLOR_PALETTE_B, 0, 1.0);
if (PRINT_SPEED) print_speed(speed, 0, 1.0);
glutSwapBuffers();
}
if (!FADE) for (i=0; i<END_FRAMES; i++) save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter + i);
else for (i=0; i<END_FRAMES; i++)
{
fade_value = 1.0 - (double)i/(double)END_FRAMES;
if (HIGHRES) draw_wave_highres_palette(2, phi, psi, total_energy, xy_in, scale, NSTEPS, PLOT_B, COLOR_PALETTE_B);
else draw_wave_epalette(phi, psi, total_energy, color_scale, xy_in, scale, NSTEPS, PLOT_B, COLOR_PALETTE_B, 1, fade_value);
draw_billiard(1, fade_value);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(PLOT_B, COLORBAR_RANGE_B, COLOR_PALETTE_B, 1, fade_value);
glutSwapBuffers();
save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter + i);
if (!FADE) for (i=0; i<END_FRAMES; i++) save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter + i);
else for (i=0; i<END_FRAMES; i++)
{
fade_value = 1.0 - (double)i/(double)END_FRAMES;
if (HIGHRES)
draw_wave_highres_palette(2, phi, psi, total_energy, xy_in, scale, NSTEPS, PLOT_B, COLOR_PALETTE_B, 1, fade_value);
else draw_wave_epalette(phi, psi, total_energy, color_scale, xy_in, scale, NSTEPS, PLOT_B, COLOR_PALETTE_B, 1, fade_value);
draw_billiard(1, fade_value);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(PLOT_B, COLORBAR_RANGE_B, COLOR_PALETTE_B, 1, fade_value);
if (PRINT_SPEED) print_speed(speed, 1, fade_value);
glutSwapBuffers();
save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter + i);
}
}
s = system("mv wave*.tif tif_wave/");
@ -764,6 +829,8 @@ void animation()
{
free(phi[i]);
free(psi[i]);
// free(phi_tmp[i]);
// free(psi_tmp[i]);
free(tmp[i]);
free(total_energy[i]);
free(xy_in[i]);

View File

@ -770,10 +770,10 @@ void draw_wave_epalette(double *phi[NX], double *psi[NX], double *total_energy[N
}
void draw_wave_highres_palette(int size, double *phi[NX], double *psi[NX], double *total_energy[NX], short int *xy_in[NX], double scale, int time, int plot, int palette)
void draw_wave_highres_palette(int size, double *phi[NX], double *psi[NX], double *total_energy[NX], short int *xy_in[NX], double scale, int time, int plot, int palette, int fade, double fade_value)
/* same as draw_wave_highres, but with color scheme option */
{
int i, j, iplus, iminus, jplus, jminus;
int i, j, k, iplus, iminus, jplus, jminus;
double rgb[3], xy[2], x1, y1, x2, y2, velocity, energy, gradientx2, gradienty2;
static double dtinverse = ((double)NX)/(COURANT*(XMAX-XMIN)), dx = (XMAX-XMIN)/((double)NX);
@ -836,8 +836,9 @@ void draw_wave_highres_palette(int size, double *phi[NX], double *psi[NX], doubl
}
}
if (fade) for (k=0; k<3; k++) rgb[k] *= fade_value;
glColor3f(rgb[0], rgb[1], rgb[2]);
glVertex2i(i, j);
glVertex2i(i+size, j);
glVertex2i(i+size, j+size);
@ -937,14 +938,66 @@ double compute_energy_mod(double phi[NX*NY], double psi[NX*NY], short int xy_in[
{
double velocity, energy, gradientx2, gradienty2;
int iplus, iminus, jplus, jminus;
static int i1, j1, i2, j2, i3, j3, ij[2];
static int first = 1;
if (first)
{
xy_to_ij(-LAMBDA, -1.0, ij);
i1 = ij[0] + 1; j1 = ij[1] + 1;
xy_to_ij(0.0, 0.0, ij);
i2 = ij[0] - 1; j2 = ij[1] - 1;
xy_to_ij(LAMBDA, 1.0, ij);
i3 = ij[0] - 1; j3 = ij[1] - 1;
first = 0;
}
velocity = (phi[i*NY+j] - psi[i*NY+j]);
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
jplus = (j+1); if (jplus == NY) jplus = NY-1;
jminus = (j-1); if (jminus == -1) jminus = 0;
/* avoid computing gradient across boundary of compared regions */
if (COMPARISON)
{
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 == NY/2) jplus = NY/2-1;
jminus = (j-1); if (jminus == -1) jminus = 0; else if (jminus == NY/2-1) jminus = NY/2;
}
else
{
iplus = (i+1); if (iplus == NX) iplus = NX-1;
iminus = (i-1); if (iminus == -1) iminus = 0;
jplus = (j+1); if (jplus == NY) jplus = NY-1;
jminus = (j-1); if (jminus == -1) jminus = 0;
}
// else
// {
// iplus = i+1;
// if ((j<j2)&&(iplus>i3-1)) iplus = i1;
// else if ((j>=j2)&&(iplus>i2-1)) iplus = i1;
//
// iminus = i-1;
// if ((j<j2)&&(iminus<i1)) iminus = i3-1;
// else if ((j>=j2)&&(iminus<i1)) iminus = i2-1;
//
// jplus = j+1;
// if ((i<i2)&&(jplus>j3-1)) jplus = j1;
// else if ((i>=i2)&&(jplus>j2-1)) jplus = j1;
//
// jminus = j-1;
// if ((i<i2)&&(jminus<j1)) jminus = j3-1;
// else if ((i>=i2)&&(jminus<j1)) jminus = j2-1;
//
// jminus = j-1;
// }
if (B_COND == BC_LSHAPE)
{
if ((i<=i1)||(j<=j1)) return(0.0);
if ((i>=i2-1)&&(j>=j2-1)) return(0.0);
if ((i>=i3-1)||(j>=j3-1)) return(0.0);
}
gradientx2 = (phi[iplus*NY+j]-phi[i*NY+j])*(phi[iplus*NY+j]-phi[i*NY+j])
+ (phi[i*NY+j] - phi[iminus*NY+j])*(phi[i*NY+j] - phi[iminus*NY+j]);
gradienty2 = (phi[i*NY+jplus]-phi[i*NY+j])*(phi[i*NY+jplus]-phi[i*NY+j])

View File

@ -219,6 +219,12 @@
#define FLOOR 0 /* set to 1 to limit wave amplitude to VMAX */
#define VMAX 5.0 /* max value of wave amplitude */
/* the following constants are only used by wave_billiard and wave_3d so far */
#define COMPARISON 0 /* set to 1 to compare two different patterns */
#define OSCILLATION_SCHEDULE 3 /* oscillation schedule, see list in global_pdes.c */
#define ACHIRP 0.2 /* acceleration coefficient in chirp */
#define DAMPING 0.0 /* damping of periodic excitation */
/* end of constants only used by wave_billiard and wave_3d */
#include "global_pdes.c" /* constants and global variables */
#include "sub_wave.c" /* common functions for wave_billiard, heat and schrodinger */
@ -863,5 +869,4 @@ int main(int argc, char** argv)
glutMainLoop();
return 0;
}
}

View File

@ -196,6 +196,12 @@
#define FLOOR 0 /* set to 1 to limit wave amplitude to VMAX */
#define VMAX 5.0 /* max value of wave amplitude */
/* the following constants are only used by wave_billiard and wave_3d so far */
#define COMPARISON 0 /* set to 1 to compare two different patterns */
#define OSCILLATION_SCHEDULE 3 /* oscillation schedule, see list in global_pdes.c */
#define ACHIRP 0.2 /* acceleration coefficient in chirp */
#define DAMPING 0.0 /* damping of periodic excitation */
/* end of constants only used by wave_billiard and wave_3d */
#include "global_pdes.c" /* constants and global variables */
#include "sub_wave.c" /* common functions for wave_billiard, heat and schrodinger */
@ -917,5 +923,4 @@ int main(int argc, char** argv)
glutMainLoop();
return 0;
}
}