Add files via upload

This commit is contained in:
Nils Berglund 2023-01-22 16:49:04 +01:00 committed by GitHub
parent 59cc5fbcf3
commit e3a7a58057
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 7632 additions and 620 deletions

View File

@ -29,6 +29,7 @@
#include <tiffio.h> /* Sam Leffler's libtiff library. */
#define MOVIE 0 /* set to 1 to generate movie */
#define SAVE_MEMORY 1 /* set to 1 to save memory when writing tiff images */
#define WINWIDTH 1280 /* window width */
#define WINHEIGHT 720 /* window height */
@ -104,6 +105,8 @@
#define NCOLORS 16 /* number of colors */
#define COLORSHIFT 3 /* hue of initial color */
#define COLOR_HUEMIN 0 /* minimal color hue */
#define COLOR_HUEMAX 360 /* maximal color hue */
#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 */
@ -127,6 +130,8 @@
#define MAZE_MAX_NGBH 4 /* max number of neighbours of maze cell */
#define RAND_SHIFT 58 /* seed of random number generator */
#define MAZE_XSHIFT 0.0 /* horizontal shift of maze */
#define MAZE_RANDOM_FACTOR 0.1 /* randomization factor for S_MAZE_RANDOM */
#define MAZE_CORNER_RADIUS 0.5 /* radius of tounded corners in maze */

View File

@ -13,6 +13,8 @@
#define P_3D_LOG_MEAN_ENERGY 109 /* height/color depends on log on energy averaged over time, luminosity depends on angle */
#define P_3D_PHASE 111 /* phase of wave */
#define P_3D_FLUX_INTENSITY 112 /* energy flux intensity */
#define P_3D_FLUX_DIRECTION 113 /* energy flux direction */
/* Choice of simulated reaction-diffusion equation in rde.c */
@ -23,7 +25,8 @@
#define E_RPS 4 /* rock-paper-scissors equation */
#define E_RPSLZ 41 /* rock-paper-scissors-lizard-Spock equation */
#define E_SCHRODINGER 5 /* Schrodinger equation */
#define E_EULER_INCOMP 6 /* incompressigle Euler equation */
#define E_EULER_INCOMP 6 /* incompressible Euler equation */
#define E_EULER_COMP 7 /* compressible Euler equation */
/* Choice of potential */
@ -40,40 +43,17 @@
#define VPOT_CONSTANT_FIELD 100 /* constant magnetic field */
#define VPOT_AHARONOV_BOHM 101 /* single flux line for Aharonov-Bohm effect */
/* plot types used by rde */
/* Choice of force field in compressible Euler equation */
#define Z_AMPLITUDE 0 /* amplitude of first field */
#define Z_RGB 20 /* RGB plot */
#define Z_POLAR 21 /* polar angle associated with RBG plot */
#define Z_NORM_GRADIENT 22 /* gradient of polar angle */
#define Z_ANGLE_GRADIENT 221 /* direction of polar angle */
#define Z_NORM_GRADIENTX 23 /* norm of gradient of u */
#define Z_ANGLE_GRADIENTX 231 /* direction of gradient of u */
#define Z_NORM_GRADIENT_INTENSITY 24 /* gradient and intensity of polar angle */
#define Z_VORTICITY 25 /* curl of polar angle */
#define Z_VORTICITY_ABS 251 /* absolute value of curl of polar angle */
/* for Schrodinger equation */
#define Z_MODULE 30 /* module squared of first two fields */
#define Z_ARGUMENT 31 /* argument of first two fields, with luminosity depending on module */
#define Z_REALPART 32 /* first field, with luminosity depending on module */
/* for RPSLZ equation */
#define Z_MAXTYPE_RPSLZ 40 /* color of type with maximal density */
#define Z_THETA_RPSLZ 41 /* polar angle */
#define Z_NORM_GRADIENT_RPSLZ 42 /* gradient of polar angle */
/* for Euler equation */
#define Z_EULER_VORTICITY 50 /* vorticity of velocity */
#define Z_EULER_LOG_VORTICITY 51 /* log of vorticity of velocity */
#define Z_EULER_VORTICITY_ASYM 52 /* vorticity of velocity */
#define GF_VERTICAL 0 /* gravity acting vertically */
#define GF_CIRCLE 1 /* repelling circle */
/* macros to avoid unnecessary computations in 3D plots */
#define COMPUTE_THETA ((cplot == Z_POLAR)||(cplot == Z_NORM_GRADIENT)||(cplot == Z_ANGLE_GRADIENT)||(cplot == Z_NORM_GRADIENT_INTENSITY)||(cplot == Z_VORTICITY)||(cplot == Z_VORTICITY_ABS))
#define COMPUTE_THETAZ ((zplot == Z_POLAR)||(zplot == Z_NORM_GRADIENT)||(zplot == Z_ANGLE_GRADIENT)||(zplot == Z_NORM_GRADIENT_INTENSITY)||(zplot == Z_VORTICITY)||(zplot == Z_VORTICITY_ABS))
#define COMPUTE_ENERGY ((zplot == P_3D_ENERGY)||(cplot == P_3D_ENERGY)||(zplot == P_3D_LOG_ENERGY)||(cplot == P_3D_LOG_ENERGY)||(zplot == P_3D_TOTAL_ENERGY)||(cplot == P_3D_TOTAL_ENERGY)||(zplot == P_3D_LOG_TOTAL_ENERGY)||(cplot == P_3D_LOG_TOTAL_ENERGY)||(zplot == P_3D_MEAN_ENERGY)||(cplot == P_3D_MEAN_ENERGY)||(zplot == P_3D_LOG_MEAN_ENERGY)||(cplot == P_3D_LOG_MEAN_ENERGY))
#define COMPUTE_ENERGY ((zplot == P_3D_ENERGY)||(cplot == P_3D_ENERGY)||(zplot == P_3D_LOG_ENERGY)||(cplot == P_3D_LOG_ENERGY)||(zplot == P_3D_TOTAL_ENERGY)||(cplot == P_3D_TOTAL_ENERGY)||(zplot == P_3D_LOG_TOTAL_ENERGY)||(cplot == P_3D_LOG_TOTAL_ENERGY)||(zplot == P_3D_MEAN_ENERGY)||(cplot == P_3D_MEAN_ENERGY)||(zplot == P_3D_LOG_MEAN_ENERGY)||(cplot == P_3D_LOG_MEAN_ENERGY)||(ZPLOT == P_3D_FLUX_INTENSITY)||(CPLOT == P_3D_FLUX_INTENSITY)||(ZPLOT_B == P_3D_FLUX_INTENSITY)||(CPLOT_B == P_3D_FLUX_INTENSITY)||(ZPLOT == P_3D_FLUX_DIRECTION)||(CPLOT == P_3D_FLUX_DIRECTION)||(ZPLOT_B == P_3D_FLUX_DIRECTION)||(CPLOT_B == P_3D_FLUX_DIRECTION))
#define COMPUTE_LOG_TOTAL_ENERGY ((ZPLOT == P_3D_LOG_TOTAL_ENERGY)||(CPLOT == P_3D_LOG_TOTAL_ENERGY)||(ZPLOT_B == P_3D_LOG_TOTAL_ENERGY)||(CPLOT_B == P_3D_LOG_TOTAL_ENERGY))
@ -83,6 +63,8 @@
#define COMPUTE_MEAN_ENERGY ((ZPLOT == P_3D_MEAN_ENERGY)||(CPLOT == P_3D_MEAN_ENERGY)||(ZPLOT_B == P_3D_MEAN_ENERGY)||(CPLOT_B == P_3D_MEAN_ENERGY)||(ZPLOT == P_3D_LOG_MEAN_ENERGY)||(CPLOT == P_3D_LOG_MEAN_ENERGY)||(ZPLOT_B == P_3D_LOG_MEAN_ENERGY)||(CPLOT_B == P_3D_LOG_MEAN_ENERGY))
#define COMPUTE_ENERGY_FLUX ((ZPLOT == P_3D_FLUX_INTENSITY)||(CPLOT == P_3D_FLUX_INTENSITY)||(ZPLOT_B == P_3D_FLUX_INTENSITY)||(CPLOT_B == P_3D_FLUX_INTENSITY)||(ZPLOT == P_3D_FLUX_DIRECTION)||(CPLOT == P_3D_FLUX_DIRECTION)||(ZPLOT_B == P_3D_FLUX_DIRECTION)||(CPLOT_B == P_3D_FLUX_DIRECTION))
#define COMPUTE_TOTAL_ENERGY ((ZPLOT == P_3D_TOTAL_ENERGY)||(CPLOT == P_3D_TOTAL_ENERGY)||(ZPLOT == P_3D_LOG_TOTAL_ENERGY)||(CPLOT == P_3D_LOG_TOTAL_ENERGY)||(ZPLOT == P_3D_MEAN_ENERGY)||(CPLOT == P_3D_MEAN_ENERGY)||(ZPLOT == P_3D_LOG_MEAN_ENERGY)||(CPLOT == P_3D_LOG_MEAN_ENERGY)||(ZPLOT_B == P_3D_TOTAL_ENERGY)||(CPLOT_B == P_3D_TOTAL_ENERGY)||(ZPLOT_B == P_3D_LOG_TOTAL_ENERGY)||(CPLOT_B == P_3D_LOG_TOTAL_ENERGY)||(ZPLOT_B == P_3D_MEAN_ENERGY)||(CPLOT_B == P_3D_MEAN_ENERGY)||(ZPLOT_B == P_3D_LOG_MEAN_ENERGY)||(CPLOT_B == P_3D_LOG_MEAN_ENERGY))
@ -101,9 +83,14 @@ typedef struct
double mean_energy; /* energy averaged since beginning of simulation */
double log_mean_energy; /* log of energy averaged since beginning of simulation */
double cos_angle; /* cos of angle between normal vector and direction of light */
double flux_intensity; /* intensity of energy flux */
double flux_direction; /* direction of energy flux */
double flux_int_table[FLUX_WINDOW]; /* table of energy flux intensities (for averaging) */
short int flux_counter; /* counter for averaging of energy flux */
double rgb[3]; /* RGB color code */
double *p_zfield[2]; /* pointers to z field (second pointer for option DOUBLE_MOVIE) */
double *p_cfield[2]; /* pointers to color field (second pointer for option DOUBLE_MOVIE) */
double *p_cfield[4]; /* pointers to color field (second pointer for option DOUBLE_MOVIE) */
/* third and fourth pointer for color luminosity (for energy flux) */
} t_wave;
@ -117,6 +104,8 @@ typedef struct
double curl; /* curl of field */
double cos_angle; /* cos of angle between normal vector and direction of light */
double log_vorticity; /* logarithm of vorticity (for Euler equation) */
double Lpressure; /* Laplacian of pressure (for Euler equation) */
double dxu, dyu, dxv, dyv; /* gradient of velocity field (for compressible Euler equation) */
double rgb[3]; /* RGB color code */
double *p_zfield[2]; /* pointers to z field (second pointer for option DOUBLE_MOVIE) */
double *p_cfield[2]; /* pointers to color field (second pointer for option DOUBLE_MOVIE) */

View File

@ -42,6 +42,7 @@
#define O_GALTON_BOARD 1 /* Galton board pattern */
#define O_GENUS_TWO 2 /* obstacles in corners of L-shape domeain (for genus 2 b.c.) */
#define O_POOL_TABLE 3 /* obstacles around pockets of pool table */
#define O_HLINE_HOLE_SPOKES 181 /* tips of spokes for S_HLINE_HOLE_SPOKES segment pattern */
/* pattern of additional repelling segments */
#define S_RECTANGLE 0 /* segments forming a rectangle */
@ -65,7 +66,9 @@
#define S_EXT_RECTANGLE 16 /* particles outside a rectangle */
#define S_DAM_BRICKS 17 /* dam made of several bricks */
#define S_HLINE_HOLE 18 /* horizontal line with a hole in the bottom */
#define S_HLINE_HOLE_SPOKES 181 /* horizontal line with a hole in the bottom and extra spokes */
#define S_EXT_CIRCLE_RECT 19 /* particles outside a circle and a rectangle */
#define S_BIN_OPENING 20 /* bin containing particles opening at deactivation time */
/* particle interaction */
@ -124,6 +127,27 @@
#define NZ_BROAD 5 /* broad straight nozzle */
#define NZ_NONE 99 /* no nozzle */
/* Types of chemical reactions */
#define CHEM_RPS 0 /* rock-paper-scissors reaction */
#define CHEM_AAB 1 /* reaction A + A -> B */
#define CHEM_ABC 2 /* reaction A + B -> C */
#define CHEM_A2BC 3 /* reaction 2A + B -> C */
#define CHEM_CATALYSIS 4 /* reaction 2A + C -> B + C */
#define CHEM_BAA 5 /* reaction B -> A + A (dissociation) */
#define CHEM_AABAA 6 /* reaction A + A <-> B (reversible) */
#define CHEM_POLYMER 7 /* reaction A + B -> C, A + C -> D, etc */
#define CHEM_POLYMER_DISS 8 /* polimerisation with dissociation */
/* Initial conditions for chemical reactions */
#define IC_UNIFORM 0 /* all particles have type 1 */
#define IC_UNIFORM2 20 /* all particles have type 2 */
#define IC_RANDOM_UNIF 1 /* particle type chosen uniformly at random */
#define IC_RANDOM_TWO 2 /* particle type chosen randomly between 1 and 2, with TYPE_PROPORTION */
#define IC_CIRCLE 3 /* type 1 in a disc */
#define IC_CATALYSIS 4 /* mix of 1 and 2 in left half, only 1 in right half */
/* Plot types */
#define P_KINETIC 0 /* colors represent kinetic energy of particles */
@ -194,6 +218,7 @@ typedef struct
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 */
int color_rgb[3]; /* RGB colors code of particle, for use in ljones_movie.c */
} t_particle;
typedef struct
@ -271,5 +296,12 @@ typedef struct
} t_group_data;
typedef struct
{
double x, y; /* location of collision */
int time; /* time since collision */
int color; /* color hue in case of different collisions */
} t_collision;
int ncircles, nobstacles, nsegments, ngroups = 1, counter = 0;

View File

@ -4,6 +4,7 @@
// int circlecolor[NMAXCIRCLES]; /* color of circular scatterer */
int ncircles = NMAXCIRCLES; /* actual number of circles, can be decreased e.g. for random patterns */
int nsides = NMAXPOLY; /* actual number of sides of polygonal line */
int narcs = NMAXCIRCLES; /* actual number of arcs */
typedef struct
{
@ -18,8 +19,20 @@ typedef struct
int color;
} t_segment;
typedef struct
{
double xc, yc, radius, angle1, dangle;
int color;
} t_arc;
typedef struct
{
short int left, right;
} t_exit;
t_circle circles[NMAXCIRCLES];
t_segment polyline[NMAXPOLY];
t_arc arcs[NMAXCIRCLES];
double x_shooter = -0.2, y_shooter = -0.6, x_target = 0.4, y_target = 0.7;
/* shooter and target positions for "laser in room of mirrors" simulations, with default values for square domain */
@ -67,7 +80,8 @@ double x_shooter = -0.2, y_shooter = -0.6, x_target = 0.4, y_target = 0.7;
#define C_LASER 11 /* laser fight in a room of mirrors */
#define C_LASER_GENUSN 12 /* laser fight in a translation surface */
#define D_POLYLINE 30 /* general polygon */
#define D_POLYLINE 30 /* polygonal line */
#define D_POLYLINE_ARCS 31 /* polygonal line and circular arcs */
#define P_RECTANGLE 0 /* rectangle (for test purposes) */
#define P_TOKARSKY 1 /* Tokarsky unilluminable room */
@ -80,6 +94,10 @@ double x_shooter = -0.2, y_shooter = -0.6, x_target = 0.4, y_target = 0.7;
#define P_TOKA_NONSELF 8 /* Tokarsky non-self-unilluminable room */
#define P_MAZE 10 /* maze */
#define P_MAZE_DIAG 11 /* maze with 45 degrees angles */
#define P_MAZE_RANDOM 12 /* maze with randomized wall positions */
#define P_MAZE_CIRCULAR 13 /* circular maze */
#define P_MAZE_CIRC_SCATTERER 14 /* circular maze with scatterers */
#define P_MAZE_HEX 15 /* hexagonal maze */
/* Color palettes */

View File

@ -68,13 +68,17 @@
#define D_WAVEGUIDE_W 52 /* W-shaped wave guide */
#define D_MAZE 53 /* maze */
#define D_MAZE_CLOSED 54 /* closed maze */
#define D_MAZE_CHANNELS 541 /* maze with two channels attached */
#define D_CHESSBOARD 55 /* chess board configuration */
#define D_TRIANGLE_TILES 56 /* triangular tiling */
#define D_HEX_TILES 57 /* honeycomb tiling */
#define D_FUNNELS 58 /* two funnels */
#define D_ONE_FUNNEL 581 /* one funnel */
#define D_LENSES_RING 59 /* several lenses forming a ring */
#define D_MAZE_CIRCULAR 60 /* circular maze */
#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) */
// #define NMAXCIRCLES 10000 /* total number of circles/polygons (must be at least NCX*NCY for square grid) */
#define C_SQUARE 0 /* square grid of circles */
#define C_HEX 1 /* hexagonal/triangular grid of circles */
@ -114,6 +118,7 @@
#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 */
#define IOR_EXPLO_LENSING 3 /* explosive lensing */
/* Boundary conditions */
@ -185,6 +190,47 @@
#define NPWIDTH 0.02 /* width of noise panel separation */
/* plot types used by rde */
#define Z_AMPLITUDE 0 /* amplitude of first field */
#define Z_RGB 20 /* RGB plot */
#define Z_POLAR 21 /* polar angle associated with RBG plot */
#define Z_NORM_GRADIENT 22 /* gradient of polar angle */
#define Z_ANGLE_GRADIENT 221 /* direction of polar angle */
#define Z_NORM_GRADIENTX 23 /* norm of gradient of u */
#define Z_ANGLE_GRADIENTX 231 /* direction of gradient of u */
#define Z_NORM_GRADIENT_INTENSITY 24 /* gradient and intensity of polar angle */
#define Z_VORTICITY 25 /* curl of polar angle */
#define Z_VORTICITY_ABS 251 /* absolute value of curl of polar angle */
/* for Schrodinger equation */
#define Z_MODULE 30 /* module squared of first two fields */
#define Z_ARGUMENT 31 /* argument of first two fields, with luminosity depending on module */
#define Z_REALPART 32 /* first field, with luminosity depending on module */
/* for RPSLZ equation */
#define Z_MAXTYPE_RPSLZ 40 /* color of type with maximal density */
#define Z_THETA_RPSLZ 41 /* polar angle */
#define Z_NORM_GRADIENT_RPSLZ 42 /* gradient of polar angle */
/* for Euler incompressible Euler equation */
#define Z_EULER_VORTICITY 50 /* vorticity of velocity */
#define Z_EULER_LOG_VORTICITY 51 /* log of vorticity of velocity */
#define Z_EULER_VORTICITY_ASYM 52 /* vorticity of velocity */
#define Z_EULER_LPRESSURE 53 /* Laplacian of pressure */
#define Z_EULER_PRESSURE 54 /* pressure */
/* for Euler compressible Euler equation */
#define Z_EULER_DENSITY 60 /* density */
#define Z_EULER_SPEED 61 /* norm of velocity */
#define Z_EULERC_VORTICITY 62 /* vorticity of velocity */
/* special boundary conditions for Euler equation */
#define BCE_TOPBOTTOM 1 /* laminar flow at top and bottom */
#define BCE_TOPBOTTOMLEFT 2 /* laminar flow at top, bottom and left side */
#define BCE_CHANNELS 3 /* laminar flow in channels at left and right */
#define BCE_MIDDLE_STRIP 4 /* laminar flow in horizontal strip in the middle */
typedef struct
{
double xc, yc, radius; /* center and radius of circle */
@ -210,6 +256,23 @@ typedef struct
double posi1, posj1, posi2, posj2; /* (i,j) coordinates of vertices */
} t_rectangle;
typedef struct
{
double x1, y1, x2, y2; /* (x,y) coordinates of long symmetry axis */
double width; /* width of rectangle */
double posi1, posj1, posi2, posj2; /* (i,j) coordinates of vertices */
double posi3, posj3, posi4, posj4; /* (i,j) coordinates of vertices */
} t_rect_rotated;
typedef struct
{
double xc, yc; /* (x,y) coordinates of center */
double r, width; /* radius and width of arc */
double angle1, dangle; /* start angle and angular width */
double posi1, posj1; /* (i,j) coordinates of center */
// double posi3, posj3, posi4, posj4; /* (i,j) coordinates of vertices */
} t_arc;
typedef struct
{
int nneighb; /* number of neighbours to compute Laplacian */
@ -220,11 +283,15 @@ typedef struct
int ncircles = NMAXCIRCLES; /* actual number of circles, can be decreased e.g. for random patterns */
int npolyline = NMAXPOLY; /* actual length of polyline */
int npolyrect = NMAXPOLY; /* actual number of polyrect */
int npolyrect_rot = NMAXPOLY; /* actual number of rotated polyrect */
int npolyarc = NMAXPOLY; /* actual number of arcs */
t_circle circles[NMAXCIRCLES]; /* circular scatterers */
t_polygon polygons[NMAXCIRCLES]; /* polygonal scatterers */
t_vertex polyline[NMAXPOLY]; /* vertices of polygonal line */
t_rectangle polyrect[NMAXPOLY]; /* vertices of rectangles */
t_rect_rotated polyrectrot[NMAXPOLY]; /* data of rotated rectangles */
t_arc polyarc[NMAXPOLY]; /* data of arcs */
/* the same for comparisons between different domains */
int ncircles_b = NMAXCIRCLES; /* actual number of circles, can be decreased e.g. for random patterns */

2
heat.c
View File

@ -76,7 +76,7 @@
#define MU 0.8 /* parameter controlling the dimensions of domain */
#define NPOLY 6 /* number of sides of polygon */
#define APOLY 1.0 /* angle by which to turn polygon, in units of Pi/2 */
#define MDEPTH 6 /* depth of computation of Menger gasket */
#define MDEPTH 1 /* depth of computation of Menger gasket */
#define MRATIO 5 /* ratio defining Menger gasket */
#define MANDELLEVEL 1000 /* iteration level for Mandelbrot set */
#define MANDELLIMIT 10.0 /* limit value for approximation of Mandelbrot set */

View File

@ -37,12 +37,16 @@
#include <time.h>
#define MOVIE 0 /* set to 1 to generate movie */
#define DOUBLE_MOVIE 1 /* set to 1 to produce movies for wave height and energy simultaneously */
#define DOUBLE_MOVIE 0 /* set to 1 to produce movies for wave height and energy simultaneously */
#define SAVE_MEMORY 1 /* set to 1 to save memory while saving frames */
#define NO_EXTRA_BUFFER_SWAP 0 /* some OS require one less buffer swap when recording images */
#define TIME_LAPSE 0 /* set to 1 to add a time-lapse movie at the end */
#define TIME_LAPSE 1 /* set to 1 to add a time-lapse movie at the end */
/* so far incompatible with double movie */
#define TIME_LAPSE_FACTOR 3 /* factor of time-lapse movie */
#define TIME_LAPSE_FIRST 0 /* set to 1 to show time-lapse version first */
#define TIME_LAPSE_FIRST 1 /* set to 1 to show time-lapse version first */
#define SAVE_TIME_SERIES 0 /* set to 1 to save time series of particle positions */
/* General geometrical parameters */
@ -54,10 +58,10 @@
#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.1
#define INITYMAX 0.15 /* y interval for initial condition */
#define INITXMIN -1.92
#define INITXMAX 1.92 /* x interval for initial condition */
#define INITYMIN -1.05
#define INITYMAX 1.05 /* y interval for initial condition */
#define BCXMIN -2.0
#define BCXMAX 2.0 /* x interval for boundary condition */
@ -70,17 +74,17 @@
#define CIRCLE_PATTERN 8 /* 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 OBSTACLE_PATTERN 181 /* pattern of obstacles, see list in global_ljones.c */
#define ADD_FIXED_SEGMENTS 1 /* set to 1 to add fixed segments as obstacles */
#define SEGMENT_PATTERN 19 /* pattern of repelling segments, see list in global_ljones.c */
#define ADD_FIXED_SEGMENTS 0 /* set to 1 to add fixed segments as obstacles */
#define SEGMENT_PATTERN 181 /* pattern of repelling segments, see list in global_ljones.c */
#define ROCKET_SHAPE 2 /* shape of rocket combustion chamber, see list in global_ljones.c */
#define ROCKET_SHAPE_B 2 /* shape of second rocket */
#define NOZZLE_SHAPE 1 /* shape of nozzle, see list in global_ljones.c */
#define NOZZLE_SHAPE_B 0 /* shape of nozzle for second rocket, see list in global_ljones.c */
#define NOZZLE_SHAPE 2 /* shape of nozzle, see list in global_ljones.c */
#define NOZZLE_SHAPE_B 4 /* 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.5 /* proportion of particles of first type */
#define TYPE_PROPORTION 0.66 /* proportion of particles of first type */
#define SYMMETRIZE_FORCE 1 /* set to 1 to symmetrize two-particle interaction, only needed if particles are not all the same */
#define CENTER_PX 0 /* set to 1 to center horizontal momentum */
#define CENTER_PY 0 /* set to 1 to center vertical momentum */
@ -93,16 +97,15 @@
#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 3.0 /* minimal distance in Poisson disc process, controls density of particles */
#define PDISC_DISTANCE 4.7 /* minimal distance in Poisson disc process, controls density of particles */
#define PDISC_CANDIDATES 100 /* number of candidates in construction of Poisson disc process */
#define RANDOM_POLY_ANGLE 0 /* set to 1 to randomize angle of polygons */
#define LAMBDA 0.3 /* parameter controlling the dimensions of domain */
#define MU 0.009 /* parameter controlling radius of particles */
#define MU_B 0.018 /* parameter controlling radius of particles of second type */
// #define NPOLY 4 /* number of sides of polygon */
#define NPOLY 3 /* number of sides of polygon */
#define APOLY 1.0 /* angle by which to turn polygon, in units of Pi/2 */
#define LAMBDA 0.8 /* parameter controlling the dimensions of domain */
#define MU 0.008 /* parameter controlling radius of particles */
#define MU_B 0.012 /* parameter controlling radius of particles of second type */
#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 */
@ -122,11 +125,11 @@
/* Parameters for length and speed of simulation */
#define NSTEPS 1500 /* number of frames of movie */
#define NVID 100 /* number of iterations between images displayed on screen */
#define NSTEPS 1000 /* number of frames of movie */
#define NVID 150 /* number of iterations between images displayed on screen */
#define NSEG 250 /* number of segments of boundary */
#define INITIAL_TIME 250 /* time after which to start saving frames */
#define OBSTACLE_INITIAL_TIME 350 /* time after which to start moving obstacle */
#define INITIAL_TIME 25 /* time after which to start saving frames */
#define OBSTACLE_INITIAL_TIME 200 /* 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 */
@ -140,18 +143,18 @@
/* Boundary conditions, see list in global_ljones.c */
#define BOUNDARY_COND 0
#define BOUNDARY_COND 3
/* Plot type, see list in global_ljones.c */
#define PLOT 0
#define PLOT_B 8 /* plot type for second movie */
#define PLOT 5
#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 1 /* set to 1 to fill triangles between neighbours */
#define ALTITUDE_LINES 0 /* set to 1 to add horizontal lines to show altitude */
#define COLOR_SEG_GROUPS 1 /* set to 1 to collor segment groups differently */
#define COLOR_SEG_GROUPS 0 /* set to 1 to collor segment groups differently */
/* Color schemes */
@ -178,36 +181,40 @@
#define ENERGY_HUE_MAX 50.0 /* color of saturated particle */
#define PARTICLE_HUE_MIN 359.0 /* color of original particle */
#define PARTICLE_HUE_MAX 0.0 /* color of saturated particle */
#define PARTICLE_EMAX 3.0e2 /* energy of particle with hottest color */
#define PARTICLE_EMAX 1.2e3 /* energy of particle with hottest color */
#define HUE_TYPE0 70.0 /* hue of particles of type 0 */
#define HUE_TYPE1 280.0 /* hue of particles of type 1 */
#define HUE_TYPE2 .0 /* hue of particles of type 2 */
#define HUE_TYPE3 210.0 /* hue of particles of type 3 */
#define HUE_TYPE1 150.0 /* hue of particles of type 1 */
#define HUE_TYPE2 190.0 /* hue of particles of type 2 */
#define HUE_TYPE3 220.0 /* hue of particles of type 3 */
// #define HUE_TYPE1 310.0 /* hue of particles of type 1 */
// #define HUE_TYPE2 150.0 /* hue of particles of type 2 */
// #define HUE_TYPE3 180.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 4.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 10.0 /* damping coefficient of particles */
#define INITIAL_DAMPING 35.0 /* damping coefficient of particles during initial phase */
#define REPEL_RADIUS 15.0 /* radius in which repelling force acts (in units of particle radius) */
#define DAMPING 0.0 /* damping coefficient of particles */
#define INITIAL_DAMPING 0.0 /* damping coefficient of particles during initial phase */
#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 */
#define PARTICLE_MASS_B 2.0 /* mass of particle of radius MU */
#define PARTICLE_INERTIA_MOMENT 0.02 /* moment of inertia of particle */
#define PARTICLE_INERTIA_MOMENT_B 0.02 /* moment of inertia of second type of particle */
#define V_INITIAL 0.0 /* initial velocity range */
#define OMEGA_INITIAL 10.0 /* initial angular velocity range */
#define THERMOSTAT 0 /* set to 1 to switch on thermostat */
#define THERMOSTAT 1 /* 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.02 /* initial inverse temperature */
#define BETA 0.01 /* initial inverse temperature */
#define MU_XI 0.01 /* friction constant in thermostat */
#define KSPRING_BOUNDARY 1.0e7 /* confining harmonic potential outside simulation region */
#define KSPRING_OBSTACLE 1.0e11 /* harmonic potential of obstacles */
#define NBH_DIST_FACTOR 7.5 /* radius in which to count neighbours */
#define GRAVITY 1500.0 /* gravity acting on all particles */
#define NBH_DIST_FACTOR 10.0 /* radius in which to count neighbours */
// #define NBH_DIST_FACTOR 7.5 /* radius in which to count neighbours */
#define GRAVITY 0.0 /* gravity acting on all particles */
#define GRAVITY_X 0.0 /* horizontal 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 */
@ -215,7 +222,7 @@
#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 */
#define ROTATION 0 /* set to 1 to include rotation of particles */
#define ROTATION 1 /* set to 1 to include rotation of particles */
#define COUPLE_ANGLE_TO_THERMOSTAT 0 /* set to 1 to couple angular degrees of freedom to thermostat */
#define DIMENSION_FACTOR 1.0 /* scaling factor taking into account number of degrees of freedom */
#define KTORQUE 100.0 /* force constant in angular dynamics */
@ -232,8 +239,8 @@
#define BETA_FACTOR 0.025 /* 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 MIDDLE_CONSTANT_PHASE 1600 /* final phase in which temperature is constant */
#define FINAL_DECREASE_PHASE 1500 /* final phase in which temperature decreases */
#define MIDDLE_CONSTANT_PHASE 2000 /* final phase in which temperature is constant */
#define FINAL_DECREASE_PHASE 1300 /* final phase in which temperature decreases */
#define FINAL_CONSTANT_PHASE -1 /* final phase in which temperature is constant */
#define DECREASE_CONTAINER_SIZE 0 /* set to 1 to decrease size of container */
@ -271,6 +278,7 @@
#define ADD_PARTICLES 0 /* set to 1 to add particles */
#define ADD_TIME 0 /* time at which to add first particle */
#define ADD_PERIOD 10000 /* time interval between adding further particles */
#define N_ADD_PARTICLES 20 /* number of particles to add */
#define FINAL_NOADD_PERIOD 200 /* final period where no particles are added */
#define SAFETY_FACTOR 2.0 /* no particles are added at distance less than MU*SAFETY_FACTOR of other particles */
@ -289,40 +297,48 @@
#define OMEGAMAX 100.0 /* maximal rotation speed */
#define PRINT_OMEGA 0 /* set to 1 to print angular speed */
#define PRINT_PARTICLE_SPEEDS 0 /* set to 1 to print average speeds/momenta of particles */
#define PRINT_SEGMENTS_SPEEDS 0 /* set to 1 to print velocity of moving segments */
#define PRINT_SEGMENTS_SPEEDS 1 /* 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 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 200 /* time at which to deactivate last segment */
#define RELEASE_ROCKET_AT_DEACTIVATION 1 /* set to 1 to limit segments velocity before segment release */
#define SEGMENTS_X0 1.0 /* initial position of segments */
#define SEGMENTS_Y0 0.8 /* initial position of segments */
#define SEGMENTS_X0 1.5 /* initial position of segments */
#define SEGMENTS_Y0 0.0 /* initial position of segments */
#define SEGMENTS_VX0 0.0 /* initial velocity of segments */
#define SEGMENTS_VY0 0.0 /* initial velocity of segments */
#define DAMP_SEGS_AT_NEGATIVE_Y 0 /* set to 1 to dampen segments when y coordinate is negative */
#define MOVE_SEGMENT_GROUPS 1 /* set to 1 to group segments into moving units */
#define SEGMENT_GROUP_MASS 750.0 /* mass of segment group */
#define SEGMENT_GROUP_I 500.0 /* moment of inertia of segment group */
#define SEGMENT_GROUP_MASS 1000.0 /* mass of segment group */
#define SEGMENT_GROUP_I 1000.0 /* moment of inertia of segment group */
#define SEGMENT_GROUP_DAMPING 0.0 /* damping of segment groups */
#define GROUP_REPULSION 1 /* set to 1 for groups of segments to repel each other */
#define KSPRING_GROUPS 1.0e11 /* harmonic potential between segment groups */
#define GROUP_WIDTH 0.05 /* interaction width of groups */
#define GROUP_G_REPEL 0 /* set to 1 to add repulsion between centers of mass of groups */
#define GROUP_G_REPEL 1 /* set to 1 to add repulsion between centers of mass of groups */
#define GROUP_G_REPEL_RADIUS 1.2 /* radius within which centers of mass of groups repel each other */
#define TRACK_SEGMENT_GROUPS 0 /* set to 1 for view to track group of segments */
#define TRACK_SEGMENT_GROUPS 1 /* set to 1 for view to track group of segments */
#define TRACK_X_PADDING 2.0 /* distance from x boundary where tracking starts */
#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 horizontal */
#define PRINT_ENTROPY 0 /* set to 1 to compute entropy */
#define REACTION_DIFFUSION 0 /* set to 1 to simulate a chemical reaction (particles may change type) */
#define RD_TYPES 3 /* number of types in reaction-diffusion equation */
#define REACTION_PROB 0.0045 /* probability controlling reaction term */
#define REACTION_DIFFUSION 1 /* set to 1 to simulate a chemical reaction (particles may change type) */
#define RD_REACTION 8 /* type of reaction, see list in global_ljones.c */
#define RD_TYPES 9 /* number of types in reaction-diffusion equation */
#define RD_INITIAL_COND 2 /* initial condition of particles */
#define REACION_DIST 3.5 /* maximal distance for reaction to occur */
#define REACTION_PROB 0.5 /* probability controlling reaction term */
#define DISSOCIATION_PROB 0.005 /* probability controlling dissociation reaction */
#define CENTER_COLLIDED_PARTICLES 0 /* set to 1 to recenter particles upon reaction (may interfere with thermostat) */
#define COLLISION_TIME 25 /* time during which collisions are shown */
#define PRINT_PARTICLE_NUMBER 0 /* set to 1 to print total number of particles */
#define PLOT_PARTICLE_NUMBER 1 /* set to 1 to make of plot of particle number over time */
#define PARTICLE_NB_PLOT_FACTOR 1.0 /* expected final number of particles over initial number */
#define PRINT_LEFT 0 /* set to 1 to print certain parameters at the top left instead of right */
#define PLOT_SPEEDS 0 /* set to 1 to add a plot of obstacle speeds (e.g. for rockets) */
#define PLOT_TRAJECTORIES 0 /* set to 1 to add a plot of obstacle trajectories (e.g. for rockets) */
@ -345,12 +361,12 @@
#define MAZE_XSHIFT 0.0 /* horizontal shift of maze */
#define FLOOR_FORCE 1 /* set to 1 to limit force on particle to FMAX */
#define FMAX 1.0e12 /* maximal force */
#define FMAX 1.0e10 /* maximal force */
#define FLOOR_OMEGA 0 /* set to 1 to limit particle momentum to PMAX */
#define PMAX 1000.0 /* maximal force */
#define HASHX 120 /* size of hashgrid in x direction */
#define HASHY 60 /* size of hashgrid in y direction */
#define HASHX 90 /* size of hashgrid in x direction */
#define HASHY 45 /* 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 */
@ -385,6 +401,7 @@ int thermostat_on = 1; /* thermostat switch used when VARY_THERMOSTAT is on *
#include "sub_lj.c"
#include "sub_hashgrid.c"
FILE *lj_time_series, *lj_final_position;
/*********************/
/* animation part */
@ -1032,12 +1049,14 @@ void animation()
double time, scale, diss, rgb[3], dissip, gradient[2], x, y, dx, dy, dt, xleft, xright, a, b,
length, fx, fy, force[2], totalenergy = 0.0, krepel = KREPEL, pos[2], prop, vx,
beta = BETA, xi = 0.0, xmincontainer = BCXMIN, xmaxcontainer = BCXMAX, torque, torque_ij,
fboundary = 0.0, pleft = 0.0, pright = 0.0, entropy[2], mean_energy, gravity = GRAVITY, speed_ratio;
fboundary = 0.0, pleft = 0.0, pright = 0.0, entropy[2], mean_energy, gravity = GRAVITY, speed_ratio,
ymin, ymax;
double *qx, *qy, *px, *py, *qangle, *pangle, *pressure, *obstacle_speeds;
int i, j, k, n, m, s, ij[2], i0, iplus, iminus, j0, jplus, jminus, p, q, p1, q1, p2, q2, total_neighbours = 0,
min_nb, max_nb, close, wrapx = 0, wrapy = 0, nactive = 0, nadd_particle = 0, nmove = 0, nsuccess = 0,
tracer_n[N_TRACER_PARTICLES], traj_position = 0, traj_length = 0, move = 0, old, m0, floor, nthermo, wall = 0,
group, gshift;
group, gshift, n_total_active = 0, ncollisions = 0;
int *particle_numbers;
static int imin, imax;
static short int first = 1;
t_particle *particle;
@ -1046,6 +1065,7 @@ void animation()
t_group_segments *segment_group;
t_tracer *trajectory;
t_group_data *group_speeds;
t_collision *collisions;
t_hashgrid *hashgrid;
char message[100];
@ -1058,7 +1078,8 @@ void animation()
segment_group = (t_group_segments *)malloc(NMAXGROUPS*sizeof(t_group_segments));
}
if (TRACER_PARTICLE) trajectory = (t_tracer *)malloc(TRAJECTORY_LENGTH*N_TRACER_PARTICLES*sizeof(t_tracer));
if (TRACER_PARTICLE)
trajectory = (t_tracer *)malloc(TRAJECTORY_LENGTH*N_TRACER_PARTICLES*sizeof(t_tracer));
hashgrid = (t_hashgrid *)malloc(HASHX*HASHY*sizeof(t_hashgrid)); /* hashgrid */
@ -1070,6 +1091,17 @@ void animation()
pangle = (double *)malloc(NMAXCIRCLES*sizeof(double));
pressure = (double *)malloc(N_PRESSURES*sizeof(double));
if (REACTION_DIFFUSION)
{
collisions = (t_collision *)malloc(2*NMAXCIRCLES*sizeof(t_collision));
for (i=0; i<2*NMAXCIRCLES; i++) collisions[i].time = 0;
}
if (SAVE_TIME_SERIES)
{
lj_time_series = fopen("lj_time_series.dat", "w");
lj_final_position = fopen("lj_final_position.dat", "w");
}
/* initialise positions and radii of circles */
init_particle_config(particle);
@ -1081,7 +1113,7 @@ void animation()
if (ADD_FIXED_OBSTACLES) init_obstacle_config(obstacle);
if (ADD_FIXED_SEGMENTS) init_segment_config(segment);
if (MOVE_SEGMENT_GROUPS)
if ((MOVE_SEGMENT_GROUPS)&&(ADD_FIXED_SEGMENTS))
{
for (i=0; i<ngroups; i++) init_segment_group(segment, i, segment_group);
group_speeds = (t_group_data *)malloc(ngroups*(INITIAL_TIME + NSTEPS)*sizeof(t_group_data));
@ -1089,6 +1121,9 @@ void animation()
if (RECORD_PRESSURES) for (i=0; i<N_PRESSURES; i++) pressure[i] = 0.0;
if (PLOT_SPEEDS) obstacle_speeds = (double *)malloc(2*ngroups*(INITIAL_TIME + NSTEPS)*sizeof(double));
if (PLOT_PARTICLE_NUMBER)
particle_numbers = (int *)malloc((NSTEPS+1)*(RD_TYPES+1)*sizeof(int));
// printf("1\n");
@ -1133,6 +1168,20 @@ void animation()
/* 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;
/* recolor particles in case if P_INITIAL_POS color code */
if ((i <= INITIAL_TIME-1)&&(i%10 == 0)&&((PLOT == P_INITIAL_POS)||(PLOT_B == P_INITIAL_POS)))
{
printf("Recoloring particles\n");
ymin = particle[0].yc;
ymax = particle[0].yc;
for (j=1; j<ncircles; j++) if (particle[j].active)
{
if (particle[j].yc < ymin) ymin = particle[j].yc;
if (particle[j].yc > ymax) ymax = particle[j].yc;
}
for (j=0; j<ncircles; j++) if (particle[j].active)
particle[j].color_hue = 360.0*(particle[j].yc - ymin)/(ymax - ymin);
}
blank();
@ -1213,6 +1262,18 @@ void animation()
if ((MOVE_SEGMENT_GROUPS)&&(i > OBSTACLE_INITIAL_TIME)) evolve_segment_groups(segment, i, segment_group);
} /* end of for (n=0; n<NVID; n++) */
if ((i>INITIAL_TIME)&&(SAVE_TIME_SERIES))
{
n_total_active = 0;
for (j=0; j<ncircles; j++) if (particle[j].active) n_total_active++;
fprintf(lj_time_series, "%i\n", n_total_active);
for (j=0; j<ncircles; j++) if (particle[j].active)
{
fprintf(lj_time_series, "%.4f\n", particle[j].xc);
fprintf(lj_time_series, "%.4f\n", particle[j].yc);
}
}
// printf("evolved particles\n");
if (PLOT_SPEEDS) /* record speeds of segments */
@ -1299,16 +1360,33 @@ void animation()
// printf("Min number of neighbours: %i\n", min_nb);
// printf("Max number of neighbours: %i\n", max_nb);
blank();
/* case of reaction-diffusion equation */
if ((i > INITIAL_TIME)&&(REACTION_DIFFUSION))
{
ncollisions = update_types(particle, collisions, ncollisions);
nactive = 0;
for (j=0; j<ncircles; j++) if (particle[j].active)
{
nactive++;
qx[j] = particle[j].xc;
qy[j] = particle[j].yc;
px[j] = particle[j].vx;
py[j] = particle[j].vy;
}
// draw_collisions(collisions, ncollisions);
}
if (TRACER_PARTICLE) draw_trajectory(trajectory, traj_position, traj_length);
draw_particles(particle, PLOT, beta);
draw_particles(particle, PLOT, beta, collisions, ncollisions);
draw_container(xmincontainer, xmaxcontainer, obstacle, segment, wall);
/* add a particle */
if ((ADD_PARTICLES)&&(i > ADD_TIME)&&((i - INITIAL_TIME - ADD_TIME)%ADD_PERIOD == 1)&&(i < NSTEPS - FINAL_NOADD_PERIOD))
{
for (k=0; k<N_ADD_PARTICLES; k++)
nadd_particle = add_particles(particle, px, py, nadd_particle);
/* case of reaction-diffusion equation */
if (REACTION_DIFFUSION) update_types(particle);
}
update_hashgrid(particle, hashgrid, 1);
@ -1316,7 +1394,12 @@ void animation()
fboundary/(double)(ncircles*NVID), PRINT_LEFT, pressure, gravity);
if ((BOUNDARY_COND == BC_EHRENFEST)||(BOUNDARY_COND == BC_RECTANGLE_WALL))
print_ehrenfest_parameters(particle, pleft, pright);
else if (PRINT_PARTICLE_NUMBER) print_particle_number(ncircles);
else if (PRINT_PARTICLE_NUMBER)
{
if (REACTION_DIFFUSION)
print_particle_types_number(particle, RD_TYPES);
else print_particle_number(ncircles);
}
if ((i > INITIAL_TIME + WALL_TIME)&&(PRINT_ENTROPY))
{
@ -1335,8 +1418,13 @@ void animation()
if (MOVE_BOUNDARY) print_segments_speeds(vxsegments, vysegments);
else print_segment_group_speeds(segment_group);
}
if ((i > INITIAL_TIME)&&(PLOT_PARTICLE_NUMBER))
{
count_particle_number(particle, particle_numbers, i - INITIAL_TIME);
draw_particle_nb_plot(particle_numbers, i - INITIAL_TIME);
}
glutSwapBuffers();
if (!((NO_EXTRA_BUFFER_SWAP)&&(MOVIE))) glutSwapBuffers();
if (MOVIE)
{
@ -1365,14 +1453,19 @@ void animation()
if ((i >= INITIAL_TIME)&&(DOUBLE_MOVIE))
{
if (TRACER_PARTICLE) draw_trajectory(trajectory, traj_position, traj_length);
draw_particles(particle, PLOT_B, beta);
draw_particles(particle, PLOT_B, beta, collisions, ncollisions);
draw_container(xmincontainer, xmaxcontainer, obstacle, segment, wall);
print_parameters(beta, mean_energy, krepel, xmaxcontainer - xmincontainer,
fboundary/(double)(ncircles*NVID), PRINT_LEFT, pressure, gravity);
if (PLOT_SPEEDS) draw_speed_plot(group_speeds, i);
if (PLOT_TRAJECTORIES) draw_trajectory_plot(group_speeds, i);
if (BOUNDARY_COND == BC_EHRENFEST) print_ehrenfest_parameters(particle, pleft, pright);
else if (PRINT_PARTICLE_NUMBER) print_particle_number(ncircles);
else if (PRINT_PARTICLE_NUMBER)
{
if (REACTION_DIFFUSION)
print_particle_types_number(particle, RD_TYPES);
else print_particle_number(ncircles);
}
if (PRINT_OMEGA) print_omega(angular_speed);
else if (PRINT_PARTICLE_SPEEDS) print_particles_speeds(particle);
else if (PRINT_SEGMENTS_SPEEDS) print_segment_group_speeds(segment_group);
@ -1381,6 +1474,7 @@ void animation()
save_frame_lj_counter(NSTEPS + MID_FRAMES + 1 + counter);
counter++;
}
else if (NO_EXTRA_BUFFER_SWAP) glutSwapBuffers();
/* it seems that saving too many files too fast can cause trouble with the file system */
/* so this is to make a pause from time to time - parameter PAUSE may need adjusting */
@ -1394,19 +1488,37 @@ void animation()
}
if (SAVE_TIME_SERIES)
{
n_total_active = 0;
for (j=0; j<ncircles; j++) if (particle[j].active) n_total_active++;
fprintf(lj_final_position, "%i\n", n_total_active);
for (j=0; j<ncircles; j++) if (particle[j].active)
{
fprintf(lj_final_position, "%i\n", j);
fprintf(lj_final_position, "%.4f\n", particle[j].xc);
fprintf(lj_final_position, "%.4f\n", particle[j].yc);
}
}
if (MOVIE)
{
if (DOUBLE_MOVIE)
{
if (TRACER_PARTICLE) draw_trajectory(trajectory, traj_position, traj_length);
draw_particles(particle, PLOT, beta);
draw_particles(particle, PLOT, beta, collisions, ncollisions);
draw_container(xmincontainer, xmaxcontainer, obstacle, segment, wall);
print_parameters(beta, mean_energy, krepel, xmaxcontainer - xmincontainer,
fboundary/(double)(ncircles*NVID), PRINT_LEFT, pressure, gravity);
if (PLOT_SPEEDS) draw_speed_plot(group_speeds, i);
if (PLOT_TRAJECTORIES) draw_trajectory_plot(group_speeds, i);
if (BOUNDARY_COND == BC_EHRENFEST) print_ehrenfest_parameters(particle, pleft, pright);
else if (PRINT_PARTICLE_NUMBER) print_particle_number(ncircles);
else if (PRINT_PARTICLE_NUMBER)
{
if (REACTION_DIFFUSION)
print_particle_types_number(particle, RD_TYPES);
else print_particle_number(ncircles);
}
if (PRINT_OMEGA) print_omega(angular_speed);
else if (PRINT_PARTICLE_SPEEDS) print_particles_speeds(particle);
else if (PRINT_SEGMENTS_SPEEDS) print_segment_group_speeds(segment_group);
@ -1417,19 +1529,24 @@ void animation()
if (DOUBLE_MOVIE)
{
if (TRACER_PARTICLE) draw_trajectory(trajectory, traj_position, traj_length);
draw_particles(particle, PLOT_B, beta);
draw_particles(particle, PLOT_B, beta, collisions, ncollisions);
draw_container(xmincontainer, xmaxcontainer, obstacle, segment, wall);
print_parameters(beta, mean_energy, krepel, xmaxcontainer - xmincontainer,
fboundary/(double)(ncircles*NVID), PRINT_LEFT, pressure, gravity);
if (PLOT_SPEEDS) draw_speed_plot(group_speeds, i);
if (PLOT_TRAJECTORIES) draw_trajectory_plot(group_speeds, i);
if (BOUNDARY_COND == BC_EHRENFEST) print_ehrenfest_parameters(particle, pleft, pright);
else if (PRINT_PARTICLE_NUMBER) print_particle_number(ncircles);
else if (PRINT_PARTICLE_NUMBER)
{
if (REACTION_DIFFUSION)
print_particle_types_number(particle, RD_TYPES);
else print_particle_number(ncircles);
}
if (PRINT_OMEGA) print_omega(angular_speed);
else if (PRINT_PARTICLE_SPEEDS) print_particles_speeds(particle);
else if (PRINT_SEGMENTS_SPEEDS) print_segment_group_speeds(segment_group);
// print_segments_speeds(vxsegments, vysegments);
glutSwapBuffers();
if (!((NO_EXTRA_BUFFER_SWAP)&&(MOVIE))) glutSwapBuffers();
}
if ((TIME_LAPSE)&&(!DOUBLE_MOVIE))
{
@ -1441,26 +1558,52 @@ void animation()
s = system("mv lj*.tif tif_ljones/");
}
nactive = 0;
for (j=0; j<ncircles; j++) if (particle[j].active) nactive++;
printf("%i active particles\n", nactive);
printf("1\n");
free(particle);
printf("2\n");
if (ADD_FIXED_OBSTACLES) free(obstacle);
printf("3\n");
if (ADD_FIXED_SEGMENTS)
{
free(segment);
free(segment_group);
}
printf("4\n");
if (MOVE_SEGMENT_GROUPS) free(group_speeds);
printf("5\n");
if (TRACER_PARTICLE) free(trajectory);
printf("6\n");
if (PLOT_SPEEDS) free(obstacle_speeds);
printf("7\n");
if (PLOT_PARTICLE_NUMBER) free(particle_numbers);
printf("8\n");
free(hashgrid);
printf("9\n");
free(qx);
printf("10\n");
free(qy);
printf("11\n");
free(px);
printf("12\n");
free(py);
printf("13\n");
free(qangle);
printf("14\n");
free(pangle);
printf("15\n");
free(pressure);
printf("16\n");
if (REACTION_DIFFUSION) free(collisions);
if (SAVE_TIME_SERIES)
{
fclose(lj_time_series);
fclose(lj_final_position);
}
}

2084
ljones_movie.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -29,9 +29,11 @@
#include <unistd.h>
#include <sys/types.h>
#include <tiffio.h> /* Sam Leffler's libtiff library. */
#include <omp.h>
#include <time.h>
#define MOVIE 1 /* set to 1 to generate movie */
#define MOVIE 0 /* set to 1 to generate movie */
#define SAVE_MEMORY 1 /* set to 1 to save memory when writing tiff images */
#define WINWIDTH 1280 /* window width */
#define WINHEIGHT 720 /* window height */
@ -54,10 +56,10 @@
/* Choice of the billiard table, see global_particles.c */
#define B_DOMAIN 30 /* choice of domain shape */
#define B_DOMAIN 31 /* choice of domain shape */
#define CIRCLE_PATTERN 1 /* pattern of circles */
#define POLYLINE_PATTERN 11 /* pattern of polyline */
#define POLYLINE_PATTERN 15 /* pattern of polyline */
#define ABSORBING_CIRCLES 0 /* set to 1 for circular scatterers to be absorbing */
@ -72,7 +74,7 @@
#define SDEPTH 1 /* Sierpinski gastket depth */
#define LAMBDA 1.5 /* parameter controlling shape of domain */
#define MU 0.5 /* second parameter controlling shape of billiard */
#define MU 0.005 /* 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 */
@ -87,27 +89,37 @@
/* Simulation parameters */
#define NPART 10000 /* number of particles */
// #define NPART 2000 /* number of particles */
// #define NPART 1 /* number of particles */
#define NPART 20000 /* number of particles */
// #define NPART 10000 /* number of particles */
#define NPARTMAX 100000 /* maximal number of particles after resampling */
#define LMAX 0.01 /* minimal segment length triggering resampling */
#define DMIN 0.02 /* minimal distance to boundary for triggering resampling */
#define CYCLE 1 /* set to 1 for closed curve (start in all directions) */
#define SHOWTRAILS 1 /* set to 1 to keep trails of the particles */
#define SHOWTRAILS 0 /* set to 1 to keep trails of the particles */
#define HEATMAP 1 /* set to 1 to show heat map of particles */
#define DRAW_HEATMAP_PARTICLES 1 /* set to 1 to draw particles in heat map */
#define HEATMAP_MAX_PART_BY_CELL 0 /* to draw only limited number of particles in cell */
#define PLOT_HEATMAP_AVERAGE 0 /* set to 1 to plot average number of particles in heat map */
#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_LEFT_RIGHT_PARTICLE_NUMBER 1 /* set to 1 to print number of particles on left and right side */
#define PRINT_CIRCLE_PARTICLE_NUMBER 0 /* set to 1 to print number of particles outside circular maze */
#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 TEST_INITIAL_COND 0 /* set to 1 to allow only initial conditions that pass a test */
#define NSTEPS 4500 /* number of frames of movie */
#define NSTEPS 12300 /* number of frames of movie */
// #define NSTEPS 6500 /* number of frames of movie */
#define TIME 1500 /* time between movie frames, for fluidity of real-time simulation */
// #define TIME 750 /* time between movie frames, for fluidity of real-time simulation */
#define DPHI 0.00002 /* integration step */
// #define DPHI 0.00005 /* integration step */
// #define DPHI 0.00001 /* integration step */
#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 */
#define END_FRAMES 100 /* number of still frames at the end of the movie */
/* Decreasing TIME accelerates the animation and the movie */
/* For constant speed of movie, TIME*DPHI should be kept constant */
@ -117,15 +129,17 @@
/* Colors and other graphical parameters */
#define COLOR_PALETTE 10 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE 17 /* Color palette, see list in global_pdes.c */
#define NCOLORS 128 /* number of colors */
#define NCOLORS 1000 /* number of colors */
#define COLORSHIFT 0 /* hue of initial color */
#define COLOR_HUEMIN 0 /* minimal color hue */
#define COLOR_HUEMAX 150 /* maximal color hue */
#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.01 /* length of velocity vectors */
#define LENGTH 0.04 /* length of velocity vectors */
#define LENGTH 0.025 /* length of velocity vectors */
// #define LENGTH 0.04 /* length of velocity vectors */
#define BILLIARD_WIDTH 2 /* width of billiard */
#define PARTICLE_WIDTH 2 /* width of particles */
#define FRONT_WIDTH 3 /* width of wave front */
@ -141,14 +155,14 @@
#define SLEEP1 1 /* initial sleeping time */
#define SLEEP2 1 /* final sleeping time */
#define NXMAZE 16 /* width of maze */
#define NYMAZE 16 /* height of maze */
// #define NXMAZE 10 /* width of maze */
// #define NYMAZE 10 /* height of maze */
#define MAZE_MAX_NGBH 4 /* max number of neighbours of maze cell */
#define RAND_SHIFT 1 /* seed of random number generator */
#define NXMAZE 24 /* width of maze */
#define NYMAZE 20 /* height of maze */
#define MAZE_MAX_NGBH 6 /* max number of neighbours of maze cell */
#define RAND_SHIFT 11 /* seed of random number generator */
// #define RAND_SHIFT 0 /* seed of random number generator */
#define MAZE_XSHIFT 0.0 /* horizontal shift of maze */
#define MAZE_RANDOM_FACTOR 0.1 /* randomization factor for S_MAZE_RANDOM */
#define MAZE_CORNER_RADIUS 0.5 /* radius of tounded corners in maze */
#include "global_particles.c"
#include "sub_maze.c"
@ -389,7 +403,7 @@ void draw_zoom(int color[NPARTMAX], double *configs[NPARTMAX], int active[NPARTM
// if ((active[i])&&(vabs(x1) < 1.0)&&(vabs(y1) < 1.0)&&(vabs(x2) < 1.0)&&(vabs(y2) < 1.0))
if (((active[i])&&(vabs(x1) < 1.0)&&(vabs(y1) < 1.0))||((vabs(x2) < 1.0)&&(vabs(y2) < 1.0)))
{
rgb_color_scheme(color[i], rgb);
rgb_color_scheme_minmax(color[i], rgb);
glColor3f(rgb[0], rgb[1], rgb[2]);
glBegin(GL_LINE_STRIP);
@ -447,7 +461,7 @@ void draw_config_showtrails(int color[NPARTMAX], double *configs[NPARTMAX], int
if (active[i])
{
rgb_color_scheme(color[i], rgb);
rgb_color_scheme_minmax(color[i], rgb);
glColor3f(rgb[0], rgb[1], rgb[2]);
glBegin(GL_LINE_STRIP);
@ -483,6 +497,105 @@ void draw_config_showtrails(int color[NPARTMAX], double *configs[NPARTMAX], int
}
void draw_config_heatmap(double *configs[NPARTMAX], int active[NPARTMAX], int heatmap_number[NXMAZE*NYMAZE+1], int heatmap_total[NXMAZE*NYMAZE+1], short int heatmap_visited[NXMAZE*NYMAZE+1], int draw_particles)
/* draw a heat map of particle distribution (for mazes) */
{
int i, j, n, part_number;
double x, y, cosphi, sinphi, rgb[3], len, padding = 0.02;
double *xtable, *ytable;
short int *drawtable;
static int time, first = 1;
static double minprop;
if (first)
{
time = 0;
first = 0;
minprop = 0.01;
// if (PLOT_HEATMAP_AVERAGE) minprop = 0.005;
// else minprop = 0.01;
}
time++;
drawtable = malloc(sizeof(short int)*(NPARTMAX));
xtable = malloc(sizeof(double)*(NPARTMAX));
ytable = malloc(sizeof(double)*(NPARTMAX));
glutSwapBuffers();
blank();
if (PAINT_INT) paint_billiard_interior();
for (i=0; i<NXMAZE*NYMAZE+1; i++) heatmap_number[i] = 0;
for (i=0; i<nparticles; i++)
// if ((active[i])&&(configs[i][0] < DUMMY_ABSORBING))
{
// configs[i][2] += DPHI;
cosphi = (configs[i][6] - configs[i][4])/configs[i][3];
sinphi = (configs[i][7] - configs[i][5])/configs[i][3];
len = configs[i][2];
if (len > configs[i][3] - padding) len = configs[i][3] - padding;
if (len < 1.0e-10) len = 1.0e-10;
// if (len < 0.0) len = 1.0e-10;
x = configs[i][4] + len*cosphi;
y = configs[i][5] + len*sinphi;
xtable[i] = x;
ytable[i] = y;
/* test whether particle does not escape billiard */
if ((TEST_ACTIVE)&&(active[i])) active[i] = xy_in_billiard(x, y);
if (active[i])
{
n = find_maze_cell(x, y);
if ((n > -1)&&(n < NXMAZE*NYMAZE+1))
{
heatmap_number[n]++;
heatmap_total[n]++;
heatmap_visited[n] = 1;
}
if (HEATMAP_MAX_PART_BY_CELL > 0)
{
drawtable[i] = ((n == -2)||((n >= -1)&&(heatmap_number[n] <= HEATMAP_MAX_PART_BY_CELL)));
}
else drawtable[i] = (n >= -1);
}
// printf("Particle %i is in maze cell %i\n", i, n);
}
for (n=0; n<NXMAZE*NYMAZE+1; n++)
{
if (PLOT_HEATMAP_AVERAGE)
{
if (heatmap_total[n] == 0) part_number = 0;
else part_number = 1 + (int)((double)heatmap_total[n]/(double)time);
}
else part_number = heatmap_number[n];
if ((part_number == 0)&&(heatmap_visited[n])) part_number = -1;
draw_maze_cell(n, part_number, minprop);
// if (part_number != 0) printf("%i particles in maze cell %i\n", part_number, n);
}
glColor3f(1.0, 1.0, 1.0);
if (draw_particles)
for (i=0; i<nparticles; i++)
if ((active[i])&&(drawtable[i]))
draw_circle(SCALING_FACTOR*xtable[i], SCALING_FACTOR*ytable[i], 0.001, 6);
if (DRAW_BILLIARD) draw_billiard();
free(xtable);
free(ytable);
free(drawtable);
}
void draw_config(int color[NPARTMAX], double *configs[NPARTMAX], int active[NPARTMAX])
/* draw the particles */
{
@ -491,26 +604,28 @@ void draw_config(int color[NPARTMAX], double *configs[NPARTMAX], int active[NPAR
glutSwapBuffers();
if (!SHOWTRAILS) blank();
// if (!((SHOWTRAILS)||(HEATMAP))) blank();
if (PAINT_INT) paint_billiard_interior();
glLineWidth(PARTICLE_WIDTH);
glEnable(GL_LINE_SMOOTH);
for (i=0; i<nparticles; i++) if (active[i])
for (i=0; i<nparticles; i++)
// if (active[i])
{
if (configs[i][2]<0.0)
{
c = vbilliard(configs[i]);
if (!RAINBOW_COLOR)
{
color[i]++;
if (color[i] >= NCOLORS) color[i] -= NCOLORS;
}
if ((ABSORBING_CIRCLES)&&(c < 0)) active[i] = 0;
}
// if (configs[i][2]<0.0)
// {
// c = vbilliard(configs[i]);
// if (!RAINBOW_COLOR)
// {
// color[i]++;
// if (color[i] >= NCOLORS) color[i] -= NCOLORS;
// }
// if ((ABSORBING_CIRCLES)&&(c < 0)) active[i] = 0;
// }
configs[i][2] += DPHI;
// configs[i][2] += DPHI;
cosphi = (configs[i][6] - configs[i][4])/configs[i][3];
sinphi = (configs[i][7] - configs[i][5])/configs[i][3];
@ -520,11 +635,11 @@ void draw_config(int color[NPARTMAX], double *configs[NPARTMAX], int active[NPAR
y2 = configs[i][5] + (configs[i][2] + LENGTH)*sinphi;
/* test whether particle does not escape billiard */
if (active[i]) active[i] = xy_in_billiard(x1, y1);
if ((TEST_ACTIVE)&&(active[i])) active[i] = xy_in_billiard(x1, y1);
if (active[i])
{
rgb_color_scheme(color[i], rgb);
rgb_color_scheme_minmax(color[i], rgb);
glColor3f(rgb[0], rgb[1], rgb[2]);
glBegin(GL_LINE_STRIP);
@ -580,7 +695,7 @@ void draw_config(int color[NPARTMAX], double *configs[NPARTMAX], int active[NPAR
glLineWidth(3.0);
}
if (configs[i][2] > configs[i][3] - DPHI) configs[i][2] -= configs[i][3];
// if (configs[i][2] > configs[i][3] - DPHI) configs[i][2] -= configs[i][3];
}
if (DRAW_BILLIARD) draw_billiard();
@ -608,6 +723,7 @@ void graph_movie(int time, int color[NPARTMAX], double *configs[NPARTMAX], int a
for (j=0; j<time; j++)
{
#pragma omp parallel for private(i,c)
for (i=0; i<nparticles; i++) if (active[i])
{
if (configs[i][2]<0.0)
@ -616,6 +732,7 @@ void graph_movie(int time, int color[NPARTMAX], double *configs[NPARTMAX], int a
c = vbilliard(configs[i]);
if ((ABSORBING_CIRCLES)&&(c < 0)) active[i] = 0;
if (c < 0) active[i] = 0;
else ncollisions++;
// if (c>=0) color[i]++;
if ((!RAINBOW_COLOR)&&(c>=0)) color[i]++;
@ -658,41 +775,71 @@ void print_part_number(double *configs[NPARTMAX], int active[NPARTMAX], double x
}
void print_left_right_part_number(double *configs[NPARTMAX], int active[NPARTMAX], double xl, double yl, double xr, double yr, double xmin, double xmax)
void print_left_right_part_number(double *configs[NPARTMAX], int active[NPARTMAX], double xl, double yl, double xr, double yr, t_exit exits[NPARTMAX])
{
char message[50];
int i, nleft = 0, nright = 0;
double rgb[3], x1, y1, cosphi, sinphi;
static int maxnleft = 0, maxnright = 0;
static int first = 1;
static double xmin, xmax;
if (first)
{
compute_maze_boundaries(POLYLINE_PATTERN, &xmin, &xmax);
first = 0;
}
/* count active particles, using the fact that absorbed particles have been given dummy coordinates */
for (i=0; i<nparticles; i++) if (configs[i][0] >= DUMMY_ABSORBING)
for (i=0; i<nparticles; i++) if ((configs[i][0] == DUMMY_ABSORBING))
{
cosphi = (configs[i][6] - configs[i][4])/configs[i][3];
sinphi = (configs[i][7] - configs[i][5])/configs[i][3];
x1 = configs[i][4] + configs[i][2]*cosphi;
y1 = configs[i][5] + configs[i][2]*cosphi;
if (x1 < xmin) nleft++;
else if (x1 > xmax)
if ((x1 < xmin)&&(x1 > XMIN)&&(y1 < YMAX)&&(y1 > YMIN)) exits[i].left = 1;
else if ((x1 > xmax)&&(x1 < XMAX)&&(y1 < YMAX)&&(y1 > YMIN))
{
nright++;
printf("Detected leaving particle %i at (%.2f, %2f)\n", i, x1, y1);
exits[i].right = 1;
printf("Detected leaving particle %i at (%.2f, %2f)\n\n\n", i, x1, y1);
}
}
if (nleft > maxnleft) maxnleft = nleft;
if (nright > maxnright) maxnright = nright;
for (i=0; i<nparticles; i++)
{
if (exits[i].left) nleft++;
if (exits[i].right) nright++;
// printf("particle[%i]: left = %i, right = %i\n", i, exits[i].left, exits[i].right);
}
hsl_to_rgb(0.0, 0.0, 0.0, rgb);
erase_area(xl, yl - 0.03, 0.5, 0.12, rgb);
erase_area(xl, yl - 0.03, 0.45, 0.12, rgb);
erase_area(xr, yr - 0.03, 0.35, 0.12, rgb);
glColor3f(1.0, 1.0, 1.0);
if (nleft > 1) sprintf(message, "%i particles", nleft);
else sprintf(message, "%i particle", nleft);
write_text(xl, yl, message);
if (nright > 1) sprintf(message, "%i particles", nright);
else sprintf(message, "%i particle", nright);
write_text(xr, yr, message);
}
void print_circle_part_number(double *configs[NPARTMAX], int active[NPARTMAX], double xr, double yr)
{
char message[50];
int i, npart = 0;
double rgb[3], x1, y1, cosphi, sinphi;
/* count active particles, using the fact that absorbed particles have been given dummy coordinates */
for (i=0; i<nparticles; i++) if (configs[i][0] >= DUMMY_ABSORBING) npart++;
hsl_to_rgb(0.0, 0.0, 0.0, rgb);
erase_area(xr, yr - 0.03, 0.4, 0.12, rgb);
glColor3f(1.0, 1.0, 1.0);
if (nleft > 1) sprintf(message, "%i particles", maxnleft);
else sprintf(message, "%i particle", maxnleft);
write_text(xl, yl, message);
if (nright > 1) sprintf(message, "%i particles", maxnright);
else sprintf(message, "%i particle", maxnright);
if (npart > 1) sprintf(message, "%i particles", npart);
else sprintf(message, "%i particle", npart);
write_text(xr, yr, message);
}
@ -715,7 +862,9 @@ void animation()
double time, dt, alpha, r, rgb[3], alphamax;
double *configs[NPARTMAX];
int i, j, resamp = 1, s, i1, i2, c, lengthmax;
int *color, *newcolor, *active;
int *color, *newcolor, *active, *heatmap_number, *heatmap_total;
short int *heatmap_visited;
t_exit *exits;
// t_circle *circles; /* experimental */
/* Since NPARTMAX can be big, it seemed wiser to use some memory allocation here */
@ -724,6 +873,26 @@ void animation()
active = malloc(sizeof(int)*(NPARTMAX));
// circles = malloc(sizeof(t_circle)*(NMAXCIRCLES)); /* experimental */
if (HEATMAP)
{
heatmap_number = malloc(sizeof(int)*(NXMAZE*NYMAZE+1));
heatmap_total = malloc(sizeof(int)*(NXMAZE*NYMAZE+1));
heatmap_visited = malloc(sizeof(short int)*(NXMAZE*NYMAZE+1));
for (i=0; i<NXMAZE*NYMAZE+1; i++) heatmap_number[i] = 0;
for (i=0; i<NXMAZE*NYMAZE+1; i++) heatmap_total[i] = 0;
for (i=0; i<NXMAZE*NYMAZE+1; i++) heatmap_visited[i] = 0;
}
if (PRINT_LEFT_RIGHT_PARTICLE_NUMBER)
{
exits = malloc(sizeof(t_exit)*(NPARTMAX));
for (i=0; i<NPARTMAX; i++)
{
exits[i].left = 0;
exits[i].right = 0;
}
}
for (i=0; i<NPARTMAX; i++)
configs[i] = (double *)malloc(8*sizeof(double));
@ -731,7 +900,7 @@ void animation()
if ((B_DOMAIN == D_CIRCLES)||(B_DOMAIN == D_CIRCLES_IN_RECT)||(B_DOMAIN == D_CIRCLES_IN_GENUSN)
||(B_DOMAIN == D_CIRCLES_IN_TORUS)) init_circles(circles);
else if (B_DOMAIN == D_POLYLINE) init_polyline(polyline, circles);
else if ((B_DOMAIN == D_POLYLINE)||(B_DOMAIN == D_POLYLINE_ARCS)) init_polyline(polyline, circles, arcs);
if (POLYLINE_PATTERN == P_TOKA_PRIME)
{
@ -779,9 +948,9 @@ void animation()
// alphamax = 2.50949;
// init_drop_config(x_shooter, y_shooter, alphamax, alphamax + DPI, configs);
init_drop_config(-0.05, 0.05, 0.0, 0.3*PID, configs);
// init_drop_config(-0.5, 0.0, 0.2, 0.4, configs);
init_drop_config(-1.15, 0.01, 0.00*PI, 0.3*PI, configs);
// init_drop_config(0.0, 0.05, 0.0, DPI, configs);
// init_drop_config(-1.3, -0.1, 0.0, DPI, configs);
// init_drop_config(1.4, 0.1, 0.0, DPI, configs);
@ -803,7 +972,8 @@ void animation()
if (DRAW_BILLIARD) draw_billiard();
if (PRINT_PARTICLE_NUMBER) print_part_number(configs, active, XMIN + 0.1, YMIN + 0.1);
else if (PRINT_LEFT_RIGHT_PARTICLE_NUMBER)
print_left_right_part_number(configs, active, XMIN + 0.1, YMIN + 0.05, XMAX - 0.45, YMIN + 0.05, XMIN + MAZE_XSHIFT, XMAX + MAZE_XSHIFT);
print_left_right_part_number(configs, active, XMIN + 0.1, YMIN + 0.05, XMAX - 0.45, YMIN + 0.05, exits);
else if (PRINT_CIRCLE_PARTICLE_NUMBER) print_circle_part_number(configs, active, XMAX - 0.45, YMIN + 0.05);
else if (PRINT_COLLISION_NUMBER) print_collision_number(ncollisions, XMIN + 0.1, YMIN + 0.1);
glutSwapBuffers();
@ -856,12 +1026,18 @@ void animation()
graph_movie(TIME, newcolor, configs, active);
if (SHOWTRAILS) draw_config_showtrails(newcolor, configs, active);
else if (HEATMAP)
{
draw_config_heatmap(configs, active, heatmap_number, heatmap_total, heatmap_visited, DRAW_HEATMAP_PARTICLES);
// draw_config(newcolor, configs, active);
}
else draw_config(newcolor, configs, active);
// draw_config(newcolor, configs, active);
if (DRAW_BILLIARD) draw_billiard();
if (PRINT_PARTICLE_NUMBER) print_part_number(configs, active, XMIN + 0.1, YMIN + 0.1);
else if (PRINT_LEFT_RIGHT_PARTICLE_NUMBER)
print_left_right_part_number(configs, active, XMIN + 0.1, YMIN + 0.05, XMAX - 0.45, YMIN + 0.05, YMIN + MAZE_XSHIFT, YMAX + MAZE_XSHIFT);
print_left_right_part_number(configs, active, XMIN + 0.1, YMIN + 0.05, XMAX - 0.45, YMIN + 0.05, exits);
else if (PRINT_CIRCLE_PARTICLE_NUMBER) print_circle_part_number(configs, active, XMAX - 0.45, YMIN + 0.05);
// print_left_right_part_number(configs, XMIN + 0.1, YMIN + 0.1, XMAX - 0.45, YMIN + 0.1, YMIN + MAZE_XSHIFT, YMAX + MAZE_XSHIFT);
else if (PRINT_COLLISION_NUMBER) print_collision_number(ncollisions, XMIN + 0.1, YMIN + 0.1);
@ -890,12 +1066,21 @@ void animation()
if (MOVIE)
{
if (HEATMAP)
draw_config_heatmap(configs, active, heatmap_number, heatmap_total, heatmap_visited, 0);
for (i=0; i<END_FRAMES; i++) save_frame();
s = system("mv part*.tif tif_part/");
}
free(color);
free(newcolor);
if (HEATMAP)
{
free(heatmap_number);
free(heatmap_total);
free(heatmap_visited);
}
if (PRINT_LEFT_RIGHT_PARTICLE_NUMBER) free(exits);
for (i=0; i<NPARTMAX; i++) free(configs[i]);
}

View File

@ -31,6 +31,7 @@
#include <tiffio.h> /* Sam Leffler's libtiff library. */
#define MOVIE 0 /* set to 1 to generate movie */
#define SAVE_MEMORY 1 /* set to 1 to save memory when writing tiff images */
#define WINWIDTH 1280 /* window width */
#define WINHEIGHT 720 /* window height */
@ -117,6 +118,8 @@
// #define NCOLORS 256 /* number of colors */
#define NCOLORS 48 /* number of colors */
#define COLORSHIFT 2 /* hue of initial color */
#define COLOR_HUEMIN 0 /* minimal color hue */
#define COLOR_HUEMAX 360 /* maximal color hue */
#define RAINBOW_COLOR 1 /* set to 1 to use different colors for all particles */
#define SINGLE_COLOR 1 /* set to 1 to make all particles a single color */
#define FLOWER_COLOR 0 /* set to 1 to adapt initial colors to flower billiard (tracks vs core) */
@ -147,6 +150,8 @@
#define MAZE_MAX_NGBH 4 /* max number of neighbours of maze cell */
#define RAND_SHIFT 58 /* seed of random number generator */
#define MAZE_XSHIFT 0.0 /* horizontal shift of maze */
#define MAZE_RANDOM_FACTOR 0.1 /* randomization factor for S_MAZE_RANDOM */
#define MAZE_CORNER_RADIUS 0.5 /* radius of tounded corners in maze */
#define NPATHBINS 200 /* number of bins for path length histogramm */
#define PATHLMAX 1.8 /* max free path on graph */

484
rde.c
View File

@ -41,57 +41,64 @@
#define MOVIE 0 /* set to 1 to generate movie */
#define DOUBLE_MOVIE 1 /* set to 1 to produce movies for wave height and energy simultaneously */
#define SAVE_MEMORY 0 /* set to 1 to save memory when writing tiff images */
#define SAVE_MEMORY 1 /* set to 1 to save memory when writing tiff images */
#define NO_EXTRA_BUFFER_SWAP 1 /* some OS require one less buffer swap when recording images */
/* General geometrical parameters */
#define WINWIDTH 1920 /* window width */
#define WINHEIGHT 1000 /* window height */
#define NX 960 /* number of grid points on x axis */
#define NY 500 /* number of grid points on y axis */
// #define NX 480 /* number of grid points on x axis */
// #define NY 250 /* number of grid points on y axis */
// #define WINWIDTH 1920 /* window width */
// #define WINHEIGHT 1150 /* window height */
// #define NX 960 /* number of grid points on x axis */
// #define NY 575 /* number of grid points on y axis */
// // #define NX 480 /* number of grid points on x axis */
// // #define NY 250 /* number of grid points on y axis */
//
// #define XMIN -1.0
// #define XMAX 3.0 /* x interval */
// #define YMIN -1.197916667
// #define YMAX 1.197916667 /* y interval for 9/16 aspect ratio */
#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 WINWIDTH 1280 /* window width */
// #define WINHEIGHT 720 /* window height */
//
// // #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 960 /* number of grid points on x axis */
// // #define NY 540 /* 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 -2.0
// #define XMAX 2.0 /* x interval */
// #define YMIN -1.125
// #define YMAX 1.125 /* y interval for 9/16 aspect ratio */
// #define NX 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 960 /* number of grid points on x axis */
// #define NY 540 /* 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.0
#define XMAX 3.0 /* x interval */
#define YMIN -1.125
#define YMAX 1.125 /* y interval for 9/16 aspect ratio */
/* Choice of simulated equation */
#define RDE_EQUATION 6 /* choice of reaction term, see list in global_3d.c */
#define NFIELDS 2 /* number of fields in reaction-diffusion equation */
#define NLAPLACIANS 1 /* number of fields for which to compute Laplacian */
#define RDE_EQUATION 7 /* choice of reaction term, see list in global_3d.c */
#define NFIELDS 3 /* number of fields in reaction-diffusion equation */
#define NLAPLACIANS 0 /* number of fields for which to compute Laplacian */
#define ADD_POTENTIAL 0 /* set to 1 to add a potential (for Schrodinger equation) */
#define ADD_MAGNETIC_FIELD 0 /* set to 1 to add a magnetic field (for Schrodinger equation) - then set POTENTIAL 1 */
#define ADD_FORCE_FIELD 1 /* set to 1 to add a foce field (for compressible Euler equation) */
#define POTENTIAL 7 /* type of potential or vector potential, see list in global_3d.c */
#define FORCE_FIELD 1 /* type of force field, see list in global_3d.c */
#define ANTISYMMETRIZE_WAVE_FCT 0 /* set tot 1 to make wave function antisymmetric */
#define ADAPT_STATE_TO_BC 1 /* set to 1 to smoothly adapt initial state to obstacles */
#define OBSTACLE_GEOMETRY 3 /* geometry of obstacles, as in B_DOMAIN */
#define BC_STIFFNESS 50.0 /* controls region of boundary condition control */
#define JULIA_SCALE 0.5 /* scaling for Julia sets */
/* Choice of the billiard table */
#define B_DOMAIN 197 /* choice of domain shape, see list in global_pdes.c */
// #define B_DOMAIN 3 /* choice of domain shape, see list in global_pdes.c */
#define 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 */
@ -99,8 +106,8 @@
#define NPOISSON 300 /* number of points for Poisson C_RAND_POISSON arrangement */
#define RANDOM_POLY_ANGLE 0 /* set to 1 to randomize angle of polygons */
#define LAMBDA 0.7 /* parameter controlling the dimensions of domain */
#define MU 0.15 /* parameter controlling the dimensions of domain */
#define LAMBDA 0.2 /* parameter controlling the dimensions of domain */
#define MU 0.3 /* parameter controlling the dimensions of domain */
#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 */
@ -127,10 +134,11 @@
/* Physical patameters of wave equation */
#define DT 0.00000025
// #define DT 0.00000002
// #define DT 0.00000003
// #define DT 0.000000011
#define DT 0.0000012
// #define DT 0.0000012
// #define DT 0.000001
#define VISCOSITY 2.0
@ -148,17 +156,21 @@
#define BZQ 0.0008 /* parameter in BZ equation */
#define BZF 1.2 /* parameter in BZ equation */
#define B_FIELD 10.0 /* magnetic field */
#define G_FIELD 0.01 /* gravity */
#define AB_RADIUS 0.2 /* radius of region with magnetic field for Aharonov-Bohm effect */
#define K_EULER 50.0 /* constant in stream function integration of Euler equation */
#define K_EULER_INC 0.5 /* constant in incompressible Euler equation */
#define SMOOTHEN_VORTICITY 1 /* set to 1 to smoothen vorticity field in Euler equation */
#define SMOOTHEN_VORTICITY 0 /* set to 1 to smoothen vorticity field in Euler equation */
#define SMOOTHEN_VELOCITY 1 /* set to 1 to smoothen velocity field in Euler equation */
// #define SMOOTHEN_PERIOD 5 /* period between smoothenings */
#define SMOOTHEN_PERIOD 10 /* period between smoothenings */
// #define SMOOTH_FACTOR 0.05 /* factor by which to smoothen */
#define SMOOTH_FACTOR 0.03 /* factor by which to smoothen */
#define SMOOTH_FACTOR 0.1 /* factor by which to smoothen */
// #define SMOOTH_FACTOR 0.035 /* factor by which to smoothen */
// #define SMOOTH_FACTOR 0.015 /* factor by which to smoothen */
// #define SMOOTH_FACTOR 0.01 /* factor by which to smoothen */
#define ADD_TRACERS 1 /* set to 1 to add tracer particles (for Euler equations) */
#define ADD_TRACERS 0 /* set to 1 to add tracer particles (for Euler equations) */
#define N_TRACERS 1000 /* number of tracer particles */
#define T_OUT 2.0 /* outside temperature */
@ -183,25 +195,33 @@
#define RPSLZB_INITIAL_TIME 0 /* initial time during which rpslzb remains constant */
#define RPSLZB_FINAL_TIME 500 /* final time during which rpslzb remains constant */
#define CHANGE_FLOW_SPEED 0 /* set to 1 to change speed of laminar flow */
#define IN_OUT_FLOW_BC 4 /* type of in-flow/out-flow boundary conditions for Euler equation */
/* see list in global_pdes.c */
#define IN_OUT_FLOW_MIN_AMP 0.05 /* amplitude of in-flow/out-flow boundary conditions (for Euler equation) */
#define IN_OUT_FLOW_AMP 0.3 /* amplitude of in-flow/out-flow boundary conditions (for Euler equation) */
#define LAMINAR_FLOW_MODULATION 0.05 /* asymmetry of laminar flow */
#define LAMINAR_FLOW_YPERIOD 1.0 /* period of laminar flow in y direction */
#define EULER_GRADIENT_YSHIFT 0.0 /* y-shift in computation of gradient in Euler equation */
/* Boundary conditions, see list in global_pdes.c */
#define B_COND 1
#define EULER_GRADIENT_YSHIFT 0.0 /* y-shift in computation of gradient in Euler equation */
/* Parameters for length and speed of simulation */
#define NSTEPS 2250 /* number of frames of movie */
// #define NSTEPS 500 /* number of frames of movie */
// #define NSTEPS 1000 /* number of frames of movie */
#define NSTEPS 2200 /* number of frames of movie */
// #define NVID 90 /* number of iterations between images displayed on screen */
#define NVID 120 /* number of iterations between images displayed on screen */
#define NVID 100 /* number of iterations between images displayed on screen */
// #define NVID 200 /* 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 5 /* width of billiard boundary */
#define BOUNDARY_WIDTH 2 /* width of billiard boundary */
#define PAUSE 100 /* number of frames after which to pause */
#define PSLEEP 2 /* sleep time during pause */
@ -214,23 +234,23 @@
/* Visualisation */
#define PLOT_3D 0 /* controls whether plot is 2D or 3D */
#define PLOT_3D 1 /* controls whether plot is 2D or 3D */
#define ROTATE_VIEW 0 /* set to 1 to rotate position of observer */
#define ROTATE_ANGLE 360.0 /* total angle of rotation during simulation */
#define DRAW_PERIODICISED 1 /* set to 1 to repeat wave periodically in x and y directions */
#define DRAW_PERIODICISED 0 /* set to 1 to repeat wave periodically in x and y directions */
/* Plot type - color scheme */
#define CPLOT 52
#define CPLOT_B 51
#define CPLOT 62
#define CPLOT_B 61
/* Plot type - height of 3D plot */
#define ZPLOT 52 /* z coordinate in 3D plot */
#define ZPLOT 62 /* z coordinate in 3D plot */
// #define ZPLOT 32 /* z coordinate in 3D plot */
#define ZPLOT_B 51 /* z coordinate in second 3D plot */
#define ZPLOT_B 61 /* z coordinate in second 3D plot */
#define AMPLITUDE_HIGH_RES 1 /* set to 1 to increase resolution of P_3D_AMPLITUDE plot */
#define SHADE_3D 1 /* set to 1 to change luminosity according to normal vector */
@ -248,6 +268,7 @@
#define PRINT_RPSLZB 0 /* set to 1 to print rpslzb parameter */
#define PRINT_PROBABILITIES 0 /* set to 1 to print probabilities (for Ehrenfest urn configuration) */
#define PRINT_NOISE 0 /* set to 1 to print noise intensity */
#define PRINT_FLOW_SPEED 0 /* set to 1 to print speed of flow */
#define DRAW_FIELD_LINES 0 /* set to 1 to draw field lines */
#define FIELD_LINE_WIDTH 1 /* width of field lines */
@ -266,8 +287,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 13 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE 10 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE_B 11 /* Color palette, see list in global_pdes.c */
#define BLACK 1 /* black background */
@ -277,12 +298,15 @@
#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 1.5 /* additional scaling factor for color scheme P_3D_AMPLITUDE */
#define VSCALE_AMPLITUDE 15.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 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 VSCALE_PRESSURE 0.5 /* additional scaling factor for color scheme Z_EULER_PRESSURE */
#define PRESSURE_SHIFT 25.0 /* shift for color scheme Z_EULER_PRESSURE */
#define PRESSURE_LOG_SHIFT -2.5 /* shift for color scheme Z_EULER_PRESSURE */
#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 */
@ -295,6 +319,11 @@
#define LOG_SCALE 0.5 /* scaling factor for energy log representation */
#define LOG_SHIFT 1.0
#define LOG_MIN 1.0e-3 /* floor value for log vorticity plot */
#define VSCALE_SPEED 1.5 /* additional scaling factor for color scheme Z_EULER_SPEED */
#define VMEAN_SPEED 0.0 /* mean value around which to scale for color scheme Z_EULER_SPEED */
#define VSCALE_DENSITY 10.0 /* additional scaling factor for color scheme Z_EULER_DENSITY */
#define VSCALE_VORTICITY 50.0 /* additional scaling factor for color scheme Z_EULERC_VORTICITY */
#define VORTICITY_SHIFT 0.3 /* vertical shift of vorticity */
#define NXMAZE 7 /* width of maze */
#define NYMAZE 7 /* height of maze */
@ -303,7 +332,7 @@
#define MAZE_XSHIFT 0.0 /* horizontal shift of maze */
#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 2.0 /* scale of color scheme bar */
#define COLORBAR_RANGE_B 3.0 /* scale of color scheme bar for 2nd part */
#define ROTATE_COLOR_SCHEME 0 /* set to 1 to draw color scheme horizontally */
@ -316,6 +345,8 @@
#define INITIAL_VARIANCE 0.0002 /* variance of initial condition */
#define INITIAL_WAVELENGTH 0.1 /* wavelength of initial condition */
#define VSCALE_ENERGY 200.0 /* additional scaling factor for color scheme P_3D_ENERGY */
// #define VSCALE_SPEED 5.0 /* additional scaling factor for color scheme Z_EULER_SPEED */
// #define VMEAN_SPEED 0.0 /* mean value around which to scale for color scheme Z_EULER_SPEED */
#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 */
@ -325,6 +356,7 @@
#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 */
#define FLUX_WINDOW 20 /* averaging window for energy flux */
/* end of constants added only for compatibility with wave_common.c */
@ -335,21 +367,24 @@ double light[3] = {0.816496581, -0.40824829, 0.40824829}; /* vector of "lig
double observer[3] = {8.0, 8.0, 8.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.08 /* overall scaling factor of z axis for REP_PROJ_3D representation */
#define Z_SCALING_FACTOR 2.4 /* overall scaling factor of z axis for REP_PROJ_3D representation */
#define XY_SCALING_FACTOR 1.7 /* 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.1 /* overall y shift for REP_PROJ_3D representation */
#define XSHIFT_3D 0.0 /* overall x shift for REP_PROJ_3D representation */
#define YSHIFT_3D 0.0 /* overall y shift for REP_PROJ_3D representation */
#define BORDER_PADDING 0 /* distance from boundary at which to plot points, to avoid boundary effects due to gradient */
/* For debugging purposes only */
#define FLOOR 1 /* set to 1 to limit wave amplitude to VMAX */
#define VMAX 10.0 /* max value of wave amplitude */
#define VMAX 1000.0 /* max value of wave amplitude */
#define TEST_GRADIENT 0 /* print norm squared of gradient */
#define REFRESH_B (ZPLOT_B != ZPLOT)||(CPLOT_B != CPLOT) /* to save computing time, to be improved */
#define COMPUTE_WRAP_ANGLE ((WRAP_ANGLE)&&((cplot == Z_ANGLE_GRADIENT)||(cplot == Z_ANGLE_GRADIENTX)||(cplot == Z_ARGUMENT)||(cplot == Z_ANGLE_GRADIENTX)))
#define PRINT_PARAMETERS ((PRINT_TIME)||(PRINT_VISCOSITY)||(PRINT_RPSLZB)||(PRINT_PROBABILITIES)||(PRINT_NOISE))
#define PRINT_PARAMETERS ((PRINT_TIME)||(PRINT_VISCOSITY)||(PRINT_RPSLZB)||(PRINT_PROBABILITIES)||(PRINT_NOISE)||(PRINT_FLOW_SPEED))
#define COMPUTE_PRESSURE ((ZPLOT == Z_EULER_PRESSURE)||(CPLOT == Z_EULER_PRESSURE)||(ZPLOT_B == Z_EULER_PRESSURE)||(CPLOT_B == Z_EULER_PRESSURE))
#define ASYM_SPEED_COLOR (VMEAN_SPEED == 0.0)
#include "global_pdes.c"
#include "global_3d.c" /* constants and global variables */
@ -473,7 +508,37 @@ void compute_vector_potential(int i, int j, double *ax, double *ay)
}
}
void compute_gfield(int i, int j, double *gx, double *gy)
/* initialize the exterior field, for the compressible Euler equation */
{
double x, y, xy[2], r, f;
ij_to_xy(i, j, xy);
x = xy[0];
y = xy[1];
switch (FORCE_FIELD) {
case (GF_VERTICAL):
{
*gx = 0.0;
*gy = -G_FIELD;
break;
}
case (GF_CIRCLE):
{
r = module2(x,y) + 1.0e-2;
f = 0.5*(1.0 - tanh(BC_STIFFNESS*(r - LAMBDA)));
*gx = G_FIELD*f*x/r;
*gy = G_FIELD*f*y/r;
break;
}
default:
{
*gx = 0.0;
*gy = 0.0;
}
}
}
void initialize_potential(double potential_field[NX*NY])
/* initialize the potential field, e.g. for the Schrödinger equation */
{
@ -500,21 +565,69 @@ void initialize_vector_potential(double vpotential_field[2*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], double vector_potential_field[2*NX*NY])
void initialize_gfield(double gfield[2*NX*NY])
/* initialize the exterior field, e.g. for the compressible Euler equation */
{
int i, j;
#pragma omp parallel for private(i,j)
for (i=0; i<NX; i++){
for (j=0; j<NY; j++){
compute_gfield(i, j, &gfield[i*NY+j], &gfield[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],
double gfield[2*NX*NY], t_rde rde[NX*NY])
/* time step of field evolution */
{
int i, j, k, iplus, iminus, jplus, jminus;
double x, y, z, deltax, deltay, deltaz, rho, pot, vx, vy, test = 0.0, dx;
double *delta_phi[NLAPLACIANS], *nabla_phi, *nabla_psi, *nabla_omega, *delta_vorticity;
int i, j, k, iplus, iminus, jplus, jminus, ropening;
double x, y, z, deltax, deltay, deltaz, rho, rhox, rhoy, pot, u, v, ux, uy, vx, vy, test = 0.0, dx, dy, xy[2], padding;
double *delta_phi[NLAPLACIANS], *nabla_phi, *nabla_psi, *nabla_omega, *delta_vorticity, *delta_pressure, *delta_p, *delta_u, *delta_v, *nabla_rho, *nabla_u, *nabla_v;
// double u_bc[NY], v_bc[NY];
static double invsqr3 = 0.577350269; /* 1/sqrt(3) */
static double stiffness = 2.0; /* stiffness of Poisson equation solver */
static int smooth = 0;
static int smooth = 0, y_maze_entry, imin, imax, first = 1;
if (first) /* for D_MAZE_CHANNELS boundary conditions in Euler equation */
{
ropening = (NYMAZE+1)/2;
padding = 0.02;
dy = (YMAX - YMIN - 2.0*padding)/(double)(NYMAZE);
y = YMIN + 0.02 + dy*((double)ropening);
x = YMAX - padding + MAZE_XSHIFT;
xy_to_pos(x, y, xy);
y_maze_entry = xy[1] + 3;
if ((RDE_EQUATION == E_EULER_INCOMP)&&(IN_OUT_FLOW_BC == BCE_CHANNELS)&&(B_DOMAIN == D_MAZE_CHANNELS))
{
imax = xy[0] + 2;
x = YMIN + padding + MAZE_XSHIFT;
xy_to_pos(x, y, xy);
imin = xy[0] - 2;
}
else
{
imin = 0;
imax = NX;
}
first = 0;
}
for (i=0; i<NLAPLACIANS; i++) delta_phi[i] = (double *)malloc(NX*NY*sizeof(double));
if (COMPUTE_PRESSURE)
{
delta_pressure = (double *)malloc(NX*NY*sizeof(double));
delta_p = (double *)malloc(NX*NY*sizeof(double));
}
/* compute the Laplacian of phi */
for (i=0; i<NLAPLACIANS; i++) compute_laplacian_rde(phi_in[i], delta_phi[i], xy_in);
if (COMPUTE_PRESSURE) compute_laplacian_rde(phi_in[2], delta_pressure, xy_in);
/* compute the gradient of phi if there is a magnetic field */
if (ADD_MAGNETIC_FIELD)
{
@ -531,7 +644,11 @@ void evolve_wave_half(double *phi_in[NFIELDS], double *phi_out[NFIELDS], short i
nabla_omega = (double *)malloc(2*NX*NY*sizeof(double));
compute_gradient_euler(phi_in[0], nabla_psi, EULER_GRADIENT_YSHIFT);
compute_gradient_euler(phi_in[1], nabla_omega, 0.0);
if (COMPUTE_PRESSURE) compute_pressure_laplacian(phi_in, delta_p);
dx = (XMAX-XMIN)/((double)NX);
dy = (YMAX-YMIN)/((double)NY);
if (SMOOTHEN_VORTICITY) /* beta: try to reduce formation of ripples */
{
@ -539,6 +656,7 @@ void evolve_wave_half(double *phi_in[NFIELDS], double *phi_out[NFIELDS], short i
{
delta_vorticity = (double *)malloc(NX*NY*sizeof(double));
compute_laplacian_rde(phi_in[1], delta_vorticity, xy_in);
// #pragma omp parallel for private(i,delta_vorticity)
for (i=0; i<NX*NY; i++) phi_in[1][i] += intstep*SMOOTH_FACTOR*delta_vorticity[i];
free(delta_vorticity);
}
@ -547,17 +665,50 @@ void evolve_wave_half(double *phi_in[NFIELDS], double *phi_out[NFIELDS], short i
}
}
/* compute gradients of fields for compressible Euler equation */
else if (RDE_EQUATION == E_EULER_COMP)
{
nabla_rho = (double *)malloc(2*NX*NY*sizeof(double));
// nabla_u = (double *)malloc(2*NX*NY*sizeof(double));
// nabla_v = (double *)malloc(2*NX*NY*sizeof(double));
compute_gradient_euler_test(phi_in[0], nabla_rho, xy_in);
compute_velocity_gradients(phi_in, rde);
// compute_gradient_euler_test(phi_in[1], nabla_u, xy_in);
// compute_gradient_euler_test(phi_in[2], nabla_v, xy_in);
if (SMOOTHEN_VELOCITY) /* beta: try to reduce formation of ripples */
{
if (smooth == 0)
{
delta_u = (double *)malloc(NX*NY*sizeof(double));
delta_v = (double *)malloc(NX*NY*sizeof(double));
compute_laplacian_rde(phi_in[1], delta_u, xy_in);
compute_laplacian_rde(phi_in[2], delta_v, xy_in);
#pragma omp parallel for private(i)
for (i=0; i<NX*NY; i++) phi_in[1][i] += intstep*SMOOTH_FACTOR*delta_u[i];
#pragma omp parallel for private(i)
for (i=0; i<NX*NY; i++) phi_in[2][i] += intstep*SMOOTH_FACTOR*delta_v[i];
free(delta_u);
free(delta_v);
}
smooth++;
if (smooth >= SMOOTHEN_PERIOD) smooth = 0;
}
}
if (TEST_GRADIENT) {
test = 0.0;
for (i=0; i<2*NX*NY; i++){
test += nabla_omega[i]*nabla_omega[i];
test += nabla_psi[i]*nabla_psi[i];
test += nabla_v[i]*nabla_v[i];
// test += nabla_omega[i]*nabla_omega[i];
// test += nabla_psi[i]*nabla_psi[i];
}
printf("nabla square = %.5lg\n", test/((double)NX*NY));
}
#pragma omp parallel for private(i,j,k,x,y,z,deltax,deltay,deltaz,rho)
for (i=0; i<NX; i++){
for (i=imin; i<imax; i++){
for (j=0; j<NY; j++){
if (xy_in[i*NY+j]) switch (RDE_EQUATION){
case (E_HEAT):
@ -637,14 +788,44 @@ void evolve_wave_half(double *phi_in[NFIELDS], double *phi_out[NFIELDS], short i
}
case (E_EULER_INCOMP):
{
// if ((j > 1)&&(j < NY - 1))
{
phi_out[0][i*NY+j] = phi_in[0][i*NY+j] + intstep*stiffness*(delta_phi[0][i*NY+j] + phi_in[1][i*NY+j]*dx*dx);
// phi_out[0][i*NY+j] += intstep*EULER_GRADIENT_YSHIFT;
phi_out[1][i*NY+j] = phi_in[1][i*NY+j] - intstep*K_EULER*(nabla_omega[i*NY+j]*nabla_psi[NX*NY+i*NY+j]);
phi_out[1][i*NY+j] += intstep*K_EULER*(nabla_omega[NX*NY+i*NY+j]*nabla_psi[i*NY+j]);
// if ((i == 0)&&(j%10 == 0)) printf("j = %i, psi = %.5lg\n", j, phi_out[0][i*NY+j]);
if (COMPUTE_PRESSURE)
{
phi_out[2][i*NY+j] = phi_in[2][i*NY+j] + intstep*stiffness*(delta_pressure[i*NY+j] - delta_p[i*NY+j]);
phi_out[2][i*NY+j] *= exp(-2.0e-3);
}
break;
}
case (E_EULER_COMP):
{
rho = phi_in[0][i*NY+j];
if (rho == 0.0) rho = 1.0e-1;
u = phi_in[1][i*NY+j];
v = phi_in[2][i*NY+j];
rhox = nabla_rho[i*NY+j];
rhoy = nabla_rho[NX*NY+i*NY+j];
// ux = nabla_u[i*NY+j];
// uy = nabla_u[NX*NY+i*NY+j];
// vx = nabla_v[i*NY+j];
// vy = nabla_v[NX*NY+i*NY+j];
ux = rde[i*NY+j].dxu;
uy = rde[i*NY+j].dyu;
vx = rde[i*NY+j].dxv;
vy = rde[i*NY+j].dyv;
phi_out[0][i*NY+j] = rho - intstep*(u*rhox + v*rhoy + rho*(ux + vy));
phi_out[1][i*NY+j] = u - intstep*(u*ux + v*uy + K_EULER_INC*rhox/rho);
phi_out[2][i*NY+j] = v - intstep*(u*vx + v*vy + K_EULER_INC*rhoy/rho);
if (ADD_FORCE_FIELD)
{
phi_out[1][i*NY+j] += intstep*gfield[i*NY+j];
phi_out[2][i*NY+j] += intstep*gfield[NX*NY+i*NY+j];
}
break;
}
@ -652,12 +833,45 @@ void evolve_wave_half(double *phi_in[NFIELDS], double *phi_out[NFIELDS], short i
}
}
if (TEST_GRADIENT) {
test = 0.0;
for (i=0; i<NX*NY; i++){
test += delta_phi[0][i] + phi_out[1][i]*dx*dx;
/* in-flow/out-flow b.c. for incompressible Euler equation */
if ((RDE_EQUATION == E_EULER_INCOMP)&&(IN_OUT_FLOW_BC > 0))
{
switch (IN_OUT_FLOW_BC) {
case (BCE_TOPBOTTOM):
{
set_boundary_laminar_flow(flow_speed, LAMINAR_FLOW_MODULATION, LAMINAR_FLOW_YPERIOD, -0.1, phi_out, xy_in, 0, NX, 0, 10);
set_boundary_laminar_flow(flow_speed, LAMINAR_FLOW_MODULATION, LAMINAR_FLOW_YPERIOD, -0.1, phi_out, xy_in, 0, NX, NY-10, NY);
break;
}
printf("Delta psi + omega = %.5lg\n", test/((double)NX*NY));
case (BCE_TOPBOTTOMLEFT):
{
set_boundary_laminar_flow(flow_speed, LAMINAR_FLOW_MODULATION, LAMINAR_FLOW_YPERIOD, -0.1, phi_out, xy_in, 0, NX, 0, 10);
set_boundary_laminar_flow(flow_speed, LAMINAR_FLOW_MODULATION, LAMINAR_FLOW_YPERIOD, -0.1, phi_out, xy_in, 0, NX, NY-10, NY);
set_boundary_laminar_flow(flow_speed, LAMINAR_FLOW_MODULATION, LAMINAR_FLOW_YPERIOD, -0.1, phi_out, xy_in, 0, 2, 0, NY);
break;
}
case (BCE_CHANNELS):
{
set_boundary_laminar_flow(flow_speed, LAMINAR_FLOW_MODULATION, LAMINAR_FLOW_YPERIOD, 0.0, phi_out, xy_in, imin-5, imin+10, NY - y_maze_entry, y_maze_entry);
set_boundary_laminar_flow(flow_speed, LAMINAR_FLOW_MODULATION, LAMINAR_FLOW_YPERIOD, 0.0, phi_out, xy_in, imax-10, imax+5, NY- y_maze_entry, y_maze_entry);
break;
}
case (BCE_MIDDLE_STRIP):
{
set_boundary_laminar_flow(flow_speed, LAMINAR_FLOW_MODULATION, LAMINAR_FLOW_YPERIOD, 0.0, phi_out, xy_in, 0, NX, NY/2 - 10, NY/2 + 10);
set_boundary_laminar_flow(flow_speed, LAMINAR_FLOW_MODULATION, LAMINAR_FLOW_YPERIOD, 0.0, phi_out, xy_in, 0, 2, 0, NY);
set_boundary_laminar_flow(flow_speed, LAMINAR_FLOW_MODULATION, LAMINAR_FLOW_YPERIOD, 0.0, phi_out, xy_in, NX-2, NX, 0, NY);
break;
}
}
}
if (TEST_GRADIENT) {
// test = 0.0;
// for (i=0; i<NX*NY; i++){
// test += delta_phi[0][i] + phi_out[1][i]*dx*dx;
// }
// printf("Delta psi + omega = %.5lg\n", test/((double)NX*NY));
}
if (FLOOR) for (i=0; i<NX; i++){
@ -683,13 +897,27 @@ void evolve_wave_half(double *phi_in[NFIELDS], double *phi_out[NFIELDS], short i
free(nabla_psi);
free(nabla_omega);
}
else if (RDE_EQUATION == E_EULER_COMP)
{
free(nabla_rho);
// free(nabla_u);
// free(nabla_v);
}
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])
if (COMPUTE_PRESSURE)
{
free(delta_pressure);
free(delta_p);
}
}
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],
double gfield[2*NX*NY], t_rde rde[NX*NY])
/* time step of field evolution */
{
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);
evolve_wave_half(phi, phi_tmp, xy_in, potential_field, vector_potential_field, gfield, rde);
evolve_wave_half(phi_tmp, phi, xy_in, potential_field, vector_potential_field, gfield, rde);
}
@ -699,7 +927,7 @@ void evolve_tracers(double *phi[NFIELDS], double tracers[2*N_TRACERS*NSTEPS], in
int tracer, i, j, t, ij[2], iplus, jplus;
double x, y, xy[2], vx, vy;
step = 0.2;
step = 0.01;
for (tracer = 0; tracer < N_TRACERS; tracer++)
{
@ -713,6 +941,10 @@ void evolve_tracers(double *phi[NFIELDS], double tracers[2*N_TRACERS*NSTEPS], in
xy_to_ij_safe(x, y, ij);
i = ij[0];
j = ij[1];
switch (RDE_EQUATION) {
case (E_EULER_INCOMP):
{
iplus = i + 1; if (iplus == NX) iplus = 0;
jplus = j + 1; if (jplus == NY) jplus = 0;
@ -721,6 +953,15 @@ void evolve_tracers(double *phi[NFIELDS], double tracers[2*N_TRACERS*NSTEPS], in
if (j == 0) vx += EULER_GRADIENT_YSHIFT;
else if (j == NY-1) vx -= EULER_GRADIENT_YSHIFT;
break;
}
case (E_EULER_COMP):
{
vx = phi[1][i*NY+j];
vy = phi[2][i*NY+j];
break;
}
}
// v = module2(vx, vy);
// if ((v > 0.0)&&(v < 0.1))
@ -783,8 +1024,10 @@ void print_parameters(t_rde rde[NX*NY], short int xy_in[NX*NY], double time, sho
}
else
{
xbox = XMAX - 0.39;
xtext = XMAX - 0.55;
xbox = XMAX - 0.49;
xtext = XMAX - 0.65;
// xbox = XMAX - 0.39;
// xtext = XMAX - 0.55;
}
}
else
@ -798,8 +1041,10 @@ void print_parameters(t_rde rde[NX*NY], short int xy_in[NX*NY], double time, sho
}
else
{
xbox = XMAX - 0.39;
xtext = XMAX - 0.61;
xbox = XMAX - 0.49;
xtext = XMAX - 0.71;
// xbox = XMAX - 0.39;
// xtext = XMAX - 0.61;
}
}
@ -834,6 +1079,7 @@ void print_parameters(t_rde rde[NX*NY], short int xy_in[NX*NY], double time, sho
else if (PRINT_VISCOSITY) sprintf(message, "Viscosity %.3f", viscosity);
else if (PRINT_RPSLZB) sprintf(message, "b = %.3f", rpslzb);
else if (PRINT_NOISE) sprintf(message, "noise %.3f", noise);
else if (PRINT_FLOW_SPEED) sprintf(message, "Speed %.3f", flow_speed);
if (PLOT_3D) write_text(xtext, y, message);
else
{
@ -851,14 +1097,16 @@ void draw_color_bar_palette(int plot, double range, int palette, int fade, doubl
if (PLOT_3D)
{
if (ROTATE_COLOR_SCHEME)
draw_color_scheme_palette_3d(-1.0, -0.8, XMAX - 0.1, -1.0, plot, -range, range, palette, fade, fade_value);
draw_color_scheme_palette_3d(XMIN + 0.3, YMIN + 0.1, XMAX - 0.3, YMIN + 0.1 + width, plot, -range, range, palette, fade, fade_value);
// draw_color_scheme_palette_3d(-1.0, -0.8, XMAX - 0.1, -1.0, plot, -range, range, palette, fade, fade_value);
else
draw_color_scheme_palette_3d(XMAX - 1.5*width, YMIN + 0.1, XMAX - 0.5*width, YMAX - 0.1, plot, -range, range, palette, fade, fade_value);
}
else
{
if (ROTATE_COLOR_SCHEME)
draw_color_scheme_palette_fade(-1.0, -0.8, XMAX - 0.1, -1.0, plot, -range, range, palette, fade, fade_value);
draw_color_scheme_palette_fade(XMIN + 0.8, YMIN + 0.1, XMAX - 0.8, YMIN + 0.1 + width, plot, -range, range, palette, fade, fade_value);
// draw_color_scheme_palette_fade(-1.0, -0.8, XMAX - 0.1, -1.0, plot, -range, range, palette, fade, fade_value);
else
draw_color_scheme_palette_fade(XMAX - 1.5*width, YMIN + 0.1, XMAX - 0.5*width, YMAX - 0.1, plot, -range, range, palette, fade, fade_value);
}
@ -902,6 +1150,14 @@ double rpslzb_schedule(int i)
}
}
double flow_speed_schedule(int i)
{
double ratio;
ratio = (double)i/(double)NSTEPS;
return (IN_OUT_FLOW_MIN_AMP + (IN_OUT_FLOW_AMP - IN_OUT_FLOW_MIN_AMP)*ratio);
}
void viewpoint_schedule(int i)
/* change position of observer */
@ -930,7 +1186,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, *vector_potential_field, *tracers;
double *phi[NFIELDS], *phi_tmp[NFIELDS], *potential_field, *vector_potential_field, *tracers, *gfield, *bc_field;
short int *xy_in;
int i, j, k, s, nvid, field;
static int counter = 0;
@ -965,7 +1221,20 @@ void animation()
initialize_vector_potential(vector_potential_field);
}
if (ADD_TRACERS) tracers = (double *)malloc(2*NSTEPS*N_TRACERS*sizeof(double));
if (ADD_FORCE_FIELD)
{
gfield = (double *)malloc(2*NX*NY*sizeof(double));
initialize_gfield(gfield);
}
if (ADAPT_STATE_TO_BC)
{
bc_field = (double *)malloc(NX*NY*sizeof(double));
initialize_bcfield(bc_field);
}
// if (ADD_TRACERS) tracers = (double *)malloc(2*NSTEPS*N_TRACERS*sizeof(double));
if (ADD_TRACERS) tracers = (double *)malloc(4*NSTEPS*N_TRACERS*sizeof(double));
dx = (XMAX-XMIN)/((double)NX);
intstep = DT/(dx*dx);
@ -988,10 +1257,17 @@ void animation()
// 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_shear_flow(1.0, 0.02, 0.15, 1, 1, phi, xy_in);
// init_laminar_flow(1.0, 0.1, 0.5, 0.0, phi, xy_in);
// init_vortex_state(0.1, 0.4, 0.0, 0.3, -0.1, phi, xy_in);
// add_vortex_state(0.1, -0.4, 0.0, 0.3, 0.1, phi, xy_in);
init_shear_flow(-1.0, 0.0, 0.1, 1, 1, 0.0, phi, xy_in);
// init_shear_flow(1.0, 0.02, 0.15, 1, 1, phi, xy_in);
// init_laminar_flow(flow_speed_schedule(0), LAMINAR_FLOW_MODULATION, LAMINAR_FLOW_YPERIOD, 0.0, phi, xy_in);
init_laminar_flow(IN_OUT_FLOW_AMP, LAMINAR_FLOW_MODULATION, 0.02, 0.1, 1.0, 0.0, 0.1, phi, xy_in);
// init_shear_flow(-1.0, 0.1, 0.2, 1, 1, 0.2, phi, xy_in);
// init_shear_flow(1.0, 0.02, 0.15, 1, 1, 0.0, phi, xy_in);
if (ADAPT_STATE_TO_BC) adapt_state_to_bc(phi, bc_field, xy_in);
init_cfield_rde(phi, xy_in, CPLOT, rde, 0);
if (PLOT_3D) init_zfield_rde(phi, xy_in, ZPLOT, rde, 0);
@ -1043,6 +1319,8 @@ void animation()
}
}
if (CHANGE_RPSLZB) rpslzb = rpslzb_schedule(i);
if (CHANGE_FLOW_SPEED) flow_speed = flow_speed_schedule(i);
else flow_speed = IN_OUT_FLOW_AMP;
if (ROTATE_VIEW)
{
@ -1065,7 +1343,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, vector_potential_field);
for (j=0; j<nvid; j++) evolve_wave(phi, phi_tmp, xy_in, potential_field, vector_potential_field, gfield, rde);
if (ADAPT_STATE_TO_BC) adapt_state_to_bc(phi, bc_field, xy_in);
if (ADD_TRACERS)
{
@ -1073,6 +1353,7 @@ void animation()
evolve_tracers(phi, tracers, i, 10, 0.1);
// for (j=0; j<N_TRACERS; j++)
// printf("Tracer %i position (%.2f, %.2f)\n", j, tracers[2*N_TRACERS*i + 2*j], tracers[2*N_TRACERS*i + 2*j + 1]);
printf("Drawing tracer particles\n");
draw_tracers(phi, tracers, i, 0, 1.0);
}
@ -1118,14 +1399,19 @@ void animation()
// print_level(MDEPTH);
// print_Julia_parameters(i);
glutSwapBuffers();
if (!((NO_EXTRA_BUFFER_SWAP)&&(MOVIE))) glutSwapBuffers();
// glutSwapBuffers();
// save_frame();
/* modify Julia set */
// set_Julia_parameters(i, phi, xy_in);
if (MOVIE)
// if (0)
{
printf("Saving frame %i\n", i);
// if (NO_EXTRA_BUFFER_SWAP) glutSwapBuffers();
save_frame();
if ((i >= INITIAL_TIME)&&(DOUBLE_MOVIE))
@ -1136,9 +1422,14 @@ void animation()
if (PRINT_PARAMETERS) print_parameters(rde, xy_in, time, 0, viscosity_printed, noise);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT_B, COLORBAR_RANGE_B, COLOR_PALETTE_B, 0, 1.0);
glutSwapBuffers();
// if (NO_EXTRA_BUFFER_SWAP) glutSwapBuffers();
save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter);
counter++;
}
else if (NO_EXTRA_BUFFER_SWAP) glutSwapBuffers();
/* TEST */
// if (ADAPT_STATE_TO_BC) adapt_state_to_bc(phi, bc_field, xy_in);
/* it seems that saving too many files too fast can cause trouble with the file system */
/* so this is to make a pause from time to time - parameter PAUSE may need adjusting */
@ -1162,6 +1453,7 @@ void animation()
// draw_billiard();
if (PRINT_PARAMETERS) print_parameters(rde, xy_in, time, 0, viscosity_printed, noise);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT, COLORBAR_RANGE, COLOR_PALETTE, 0, 1.0);
// if (!NO_EXTRA_BUFFER_SWAP) glutSwapBuffers();
glutSwapBuffers();
if (!FADE) for (i=0; i<MID_FRAMES; i++) save_frame();
@ -1173,11 +1465,12 @@ void animation()
// draw_billiard();
if (PRINT_PARAMETERS) print_parameters(rde, xy_in, time, 0, viscosity_printed, noise);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT, COLORBAR_RANGE, COLOR_PALETTE, 1, fade_value);
glutSwapBuffers();
if (!NO_EXTRA_BUFFER_SWAP) glutSwapBuffers();
save_frame_counter(NSTEPS + i + 1);
}
draw_wave_rde(1, phi, xy_in, rde, potential_field, ZPLOT_B, CPLOT_B, COLOR_PALETTE_B, 0, 1.0, REFRESH_B);
if (ADD_TRACERS) draw_tracers(phi, tracers, NSTEPS, 0, 1.0);
if (PRINT_PARAMETERS) print_parameters(rde, xy_in, time, 0, viscosity_printed, noise);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT_B, COLORBAR_RANGE_B, COLOR_PALETTE_B, 0, 1.0);
glutSwapBuffers();
@ -1187,6 +1480,7 @@ void animation()
fade_value = 1.0 - (double)i/(double)END_FRAMES;
draw_wave_rde(1, phi, xy_in, rde, potential_field, ZPLOT_B, CPLOT_B, COLOR_PALETTE_B, 1, fade_value, 0);
if (ADD_TRACERS) draw_tracers(phi, tracers, NSTEPS, 1, fade_value);
if (PRINT_PARAMETERS) print_parameters(rde, xy_in, time, 0, viscosity_printed, noise);
if (DRAW_COLOR_SCHEME) draw_color_bar_palette(CPLOT_B, COLORBAR_RANGE_B, COLOR_PALETTE_B, 1, fade_value);
glutSwapBuffers();
save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter + i);
@ -1222,6 +1516,8 @@ void animation()
free(vector_potential_field);
}
if (ADD_TRACERS) free(tracers);
if (ADD_FORCE_FIELD) free(gfield);
if (ADAPT_STATE_TO_BC) free(bc_field);
printf("Time %.5lg\n", time);

1000
sub_lj.c

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* Warning: the function init_maze does not always return a maze with a solution */
/* The function init_maze has been improved and should return a maze with a solution */
/* The current algorithm uses a self-avoiding random walk. A better option may be */
/* to give random weights to the dual graph, and finite a maximal spanning tree */
@ -10,6 +10,7 @@ typedef struct
int neighb[MAZE_MAX_NGBH]; /* neighbour cells */
short int directions[MAZE_MAX_NGBH]; /* direction of neighbours */
short int north, east, south, west; /* closed walls */
short int northeast, northwest, southeast, southwest; /* closed walls */
short int active; /* takes value 1 if currently active in RW path */
short int tested; /* takes value 1 if tested */
short int connected; /* takes value 1 if connected to exit */
@ -133,7 +134,361 @@ void init_maze_graph(t_maze maze[NXMAZE*NYMAZE])
}
}
int find_maze_path(t_maze maze[NXMAZE*NYMAZE], int n0, int *path, int *pathlength)
void init_circular_maze_graph(t_maze maze[NXMAZE*NYMAZE])
/* initialise graph of circular maze */
/* NXMAZE should be a power of 2, and NYMAZE a multiple of NXMAZE */
/* row number i represents the radial coordinate, and column number j the angular one */
/* the maze is split into square blocks of size NXMAZE times NXMAZE */
/* in each block, the first column has 1 cell, the second has 2 cells */
/* then there are 2 columns of 4 cells, 4 columns of 8 cells, etc */
{
int i, j, k, n, p, q, block, nblocks, width, nextblock, prevblock;
printf("Initializing maze\n");
if (MAZE_MAX_NGBH < 5)
{
printf("Error: MAZE_MAX_NGBH should be at least 5 for circular maze\n");
exit(0);
}
if (NYMAZE%NXMAZE != 0) printf("Warning: NYMAZE should be a multiple of NXMAZE\n");
/* set dummy variables for potentially unused cells */
for (i=0; i<NXMAZE*NYMAZE; i++) maze[i].nneighb = 0;
nblocks = NYMAZE/NXMAZE;
/* initialize neighbours */
for (block=0; block<nblocks; block++)
{
nextblock = (block+1)%nblocks;
prevblock = block-1; if (prevblock < 0) prevblock = nblocks-1;
/* first column */
j = block*NXMAZE;
n = nmaze(0,j);
maze[n].nneighb = 4;
maze[n].neighb[0] = nmaze(1, j);
maze[n].neighb[1] = nmaze(1, j+1);
maze[n].neighb[2] = nmaze(0, nextblock*NXMAZE);
maze[n].neighb[3] = nmaze(0, prevblock*NXMAZE);
maze[n].directions[0] = 1;
maze[n].directions[1] = 4;
maze[n].directions[2] = 0;
maze[n].directions[3] = 2;
/* second column */
for (q=0; q<2; q++)
{
j = block*NXMAZE + q;
n = nmaze(1,j);
maze[n].nneighb = 5;
maze[n].neighb[0] = nmaze(2, j + q);
maze[n].neighb[1] = nmaze(2, j + q + 1);
if (q == 1) maze[n].neighb[2] = nmaze(1, nextblock*NXMAZE);
else maze[n].neighb[2] = nmaze(1, j+1);
if (q == 0) maze[n].neighb[3] = nmaze(1, prevblock*NXMAZE + 1);
else maze[n].neighb[3] = nmaze(1, j-1);
maze[n].neighb[4] = nmaze(0, block*NXMAZE);
maze[n].directions[0] = 1;
maze[n].directions[1] = 4;
maze[n].directions[2] = 0;
maze[n].directions[3] = 2;
maze[n].directions[4] = 3;
}
/* other columns */
width = 2;
i = 2;
while (width < NXMAZE)
{
/* left column of block */
for (q = 0; q < 2*width; q++)
{
j = block*NXMAZE + q;
n = nmaze(i,j);
maze[n].nneighb = 4;
maze[n].neighb[0] = nmaze(i+1, j);
if (q == 2*width-1) maze[n].neighb[1] = nmaze(i, nextblock*NXMAZE);
else maze[n].neighb[1] = nmaze(i, j+1);
if (q == 0) maze[n].neighb[2] = nmaze(i, prevblock*NXMAZE + 2*width - 1);
else maze[n].neighb[2] = nmaze(i, j-1);
maze[n].neighb[3] = nmaze(i-1, block*NXMAZE + q/2);
maze[n].directions[0] = 1;
maze[n].directions[1] = 0;
maze[n].directions[2] = 2;
maze[n].directions[3] = 3;
}
/* middle columns of block */
for (p = 1; p < width-1; p++)
{
i++;
for (q = 0; q < 2*width; q++)
{
j = block*NXMAZE + q;
n = nmaze(i,j);
maze[n].nneighb = 4;
maze[n].neighb[0] = nmaze(i+1, j);
if (q == 2*width-1) maze[n].neighb[1] = nmaze(i, nextblock*NXMAZE);
else maze[n].neighb[1] = nmaze(i, j+1);
if (q == 0) maze[n].neighb[2] = nmaze(i, prevblock*NXMAZE + 2*width - 1);
else maze[n].neighb[2] = nmaze(i, j-1);
maze[n].neighb[3] = nmaze(i-1, j);
maze[n].directions[0] = 1;
maze[n].directions[1] = 0;
maze[n].directions[2] = 2;
maze[n].directions[3] = 3;
}
}
/* right column of block */
i++;
for (q = 0; q < 2*width; q++)
{
j = block*NXMAZE + q;
n = nmaze(i,j);
if (i<NXMAZE-1) maze[n].nneighb = 5;
else maze[n].nneighb = 3;
maze[n].neighb[0] = nmaze(i-1, j);
if (q == 2*width-1) maze[n].neighb[1] = nmaze(i, nextblock*NXMAZE);
else maze[n].neighb[1] = nmaze(i, j+1);
if (q == 0) maze[n].neighb[2] = nmaze(i, prevblock*NXMAZE + 2*width - 1);
else maze[n].neighb[2] = nmaze(i, j-1);
maze[n].directions[0] = 3;
maze[n].directions[1] = 0;
maze[n].directions[2] = 2;
if (i<NXMAZE-1)
{
printf("i = %i, q = %i, j+ = %i\n", i, q, block*NXMAZE + 2*q);
maze[n].neighb[3] = nmaze(i+1, block*NXMAZE + 2*q);
printf("i = %i, q = %i, j+ = %i\n", i, q, block*NXMAZE + 2*q + 1);
maze[n].neighb[4] = nmaze(i+1, block*NXMAZE + 2*q + 1);
maze[n].directions[3] = 1;
maze[n].directions[4] = 4;
}
}
i++;
width *= 2;
}
}
/* initialize other parameters */
for (i=0; i<NXMAZE; i++)
for (j=0; j<NYMAZE; j++)
{
n = nmaze(i, j);
maze[n].active = 0;
if (maze[n].nneighb == 0) maze[n].tested = 1;
else maze[n].tested = 0;
maze[n].connected = 0;
maze[n].closed = 0;
maze[n].north = 1;
maze[n].east = 1;
maze[n].south = 1;
maze[n].west = 1;
maze[n].northeast = 1;
}
/* for debugging */
// for (i=0; i<NXMAZE; i++)
// for (j=0; j<NYMAZE; j++)
// {
// n = nmaze(i, j);
// q = maze[n].nneighb;
// if (q > 0) printf("Cell (%i, %i)\n", i, j);
// for (k = 0; k <q; k++)
// {
// p = maze[n].neighb[k];
// printf("Neighbour %i at (%i, %i)\t", k, p%NXMAZE, p/NXMAZE);
// printf("Direction %i\n", maze[n].directions[k]);
// }
// }
// sleep(5);
}
void init_hex_maze_graph(t_maze maze[NXMAZE*NYMAZE])
/* initialise graph of maze with honeycomb cells */
/* NXMAZE and NYMAZE are assumed to be even */
/* directions are: 0 - north, 1 - NE, 2 - SE, 3 - south, 4 - SW, 5 - NW */
{
int i, j, k, n;
printf("Initializing maze\n");
if (MAZE_MAX_NGBH < 6)
{
printf("Error: MAZE_MAX_NGBH should be at least 5 for circular maze\n");
exit(0);
}
/* initialize neighbours */
/* in the bulk */
for (i=1; i<NXMAZE-1; i++)
for (j=1; j<NYMAZE-1; j++)
{
n = nmaze(i, j);
maze[n].nneighb = 6;
maze[n].neighb[0] = nmaze(i, j+1);
maze[n].neighb[3] = nmaze(i, j-1);
if (i%2 == 0)
{
maze[n].neighb[1] = nmaze(i+1, j+1);
maze[n].neighb[2] = nmaze(i+1, j);
maze[n].neighb[4] = nmaze(i-1, j);
maze[n].neighb[5] = nmaze(i-1, j+1);
}
else
{
maze[n].neighb[1] = nmaze(i+1, j);
maze[n].neighb[2] = nmaze(i+1, j-1);
maze[n].neighb[4] = nmaze(i-1, j-1);
maze[n].neighb[5] = nmaze(i-1, j);
}
for (k=0; k<6; k++) maze[n].directions[k] = k;
}
/* left side */
for (j=1; j<NYMAZE-1; j++)
{
n = nmaze(0, j);
maze[n].nneighb = 4;
maze[n].neighb[0] = nmaze(0, j+1);
maze[n].neighb[1] = nmaze(1, j+1);
maze[n].neighb[2] = nmaze(1, j);
maze[n].neighb[3] = nmaze(0, j-1);
for (k=0; k<4; k++) maze[n].directions[k] = k;
}
/* right side */
for (j=1; j<NYMAZE-1; j++)
{
n = nmaze(NXMAZE-1, j);
maze[n].nneighb = 4;
maze[n].neighb[0] = nmaze(NXMAZE-1, j+1);
maze[n].neighb[1] = nmaze(NXMAZE-1, j-1);
maze[n].neighb[2] = nmaze(NXMAZE-2, j-1);
maze[n].neighb[3] = nmaze(NXMAZE-2, j);
maze[n].directions[0] = 0;
maze[n].directions[1] = 3;
maze[n].directions[2] = 4;
maze[n].directions[3] = 5;
}
/* bottom side */
for (i=1; i<NXMAZE-1; i++)
{
n = nmaze(i, 0);
if (i%2 == 0)
{
maze[n].nneighb = 5;
maze[n].neighb[0] = nmaze(i, 1);
maze[n].neighb[1] = nmaze(i+1, 1);
maze[n].neighb[2] = nmaze(i+1, 0);
maze[n].neighb[3] = nmaze(i-1, 0);
maze[n].neighb[4] = nmaze(i-1, 1);
maze[n].directions[0] = 0;
maze[n].directions[1] = 1;
maze[n].directions[2] = 2;
maze[n].directions[3] = 4;
maze[n].directions[4] = 5;
}
else
{
maze[n].nneighb = 3;
maze[n].neighb[0] = nmaze(i, 1);
maze[n].neighb[1] = nmaze(i+1, 0);
maze[n].neighb[2] = nmaze(i-1, 0);
maze[n].directions[0] = 0;
maze[n].directions[1] = 1;
maze[n].directions[2] = 5;
}
}
/* top side */
for (i=1; i<NXMAZE-1; i++)
{
n = nmaze(i, NYMAZE-1);
if (i%2 == 0)
{
maze[n].nneighb = 3;
maze[n].neighb[0] = nmaze(i+1, NYMAZE-1);
maze[n].neighb[1] = nmaze(i, NYMAZE-2);
maze[n].neighb[2] = nmaze(i-1, NYMAZE-1);
maze[n].directions[0] = 2;
maze[n].directions[1] = 3;
maze[n].directions[2] = 4;
}
else
{
maze[n].nneighb = 5;
maze[n].neighb[0] = nmaze(i+1, NYMAZE-1);
maze[n].neighb[1] = nmaze(i+1, NYMAZE-2);
maze[n].neighb[2] = nmaze(i, NYMAZE-2);
maze[n].neighb[3] = nmaze(i-1, NYMAZE-2);
maze[n].neighb[4] = nmaze(i-1, NYMAZE-1);
maze[n].directions[0] = 1;
maze[n].directions[1] = 2;
maze[n].directions[2] = 3;
maze[n].directions[3] = 4;
maze[n].directions[4] = 5;
}
}
/* corners */
n = nmaze(0,0);
maze[n].nneighb = 3;
maze[n].neighb[0] = nmaze(0,1);
maze[n].neighb[1] = nmaze(1,1);
maze[n].neighb[2] = nmaze(1,0);
maze[n].directions[0] = 0;
maze[n].directions[1] = 1;
maze[n].directions[2] = 2;
n = nmaze(NXMAZE-1,0);
maze[n].nneighb = 2;
maze[n].neighb[0] = nmaze(NXMAZE-1,1);
maze[n].neighb[1] = nmaze(NXMAZE-2,0);
maze[n].directions[0] = 0;
maze[n].directions[1] = 5;
n = nmaze(0,NYMAZE-1);
maze[n].nneighb = 2;
maze[n].neighb[0] = nmaze(1,NYMAZE-1);
maze[n].neighb[1] = nmaze(0,NYMAZE-2);
maze[n].directions[0] = 2;
maze[n].directions[1] = 3;
n = nmaze(NXMAZE-1,NYMAZE-1);
maze[n].nneighb = 3;
maze[n].neighb[0] = nmaze(NXMAZE-1,NYMAZE-2);
maze[n].neighb[1] = nmaze(NXMAZE-2,NYMAZE-2);
maze[n].neighb[2] = nmaze(NXMAZE-2,NYMAZE-1);
maze[n].directions[0] = 3;
maze[n].directions[1] = 4;
maze[n].directions[2] = 5;
/* initialize other parameters */
for (i=0; i<NXMAZE; i++)
for (j=0; j<NYMAZE; j++)
{
n = nmaze(i, j);
maze[n].active = 0;
maze[n].tested = 0;
maze[n].connected = 0;
maze[n].closed = 0;
maze[n].north = 1;
maze[n].northeast = 1;
maze[n].southeast = 1;
maze[n].south = 1;
maze[n].southwest = 1;
maze[n].northwest = 1;
}
}
int find_maze_path(t_maze maze[NXMAZE*NYMAZE], int n0, int *path, int *pathlength, int mazetype)
/* find a random walk path in the maze */
/* returns 0 or 1 depending on whether path reaches a tested cell or a deadend */
{
@ -175,7 +530,8 @@ int find_maze_path(t_maze maze[NXMAZE*NYMAZE], int n0, int *path, int *pathlengt
deadend = 0;
inext = next_table[rand()%nnext];
nextcell = maze[n].neighb[inext];
switch(maze[n].directions[inext]){
/* square and circular maze */
if (mazetype < 2) switch(maze[n].directions[inext]){
case(0):
{
printf("Moving north\n");
@ -201,7 +557,61 @@ int find_maze_path(t_maze maze[NXMAZE*NYMAZE], int n0, int *path, int *pathlengt
{
printf("Moving west\n");
maze[n].west = 0;
/* TODO find which is which */
maze[nextcell].east = 0;
maze[nextcell].northeast = 0;
break;
}
case(4): /* for circular maze */
{
printf("Moving north-east\n");
maze[n].northeast = 0;
maze[nextcell].west = 0;
break;
}
}
/* case of hexagonal maze */
else switch(maze[n].directions[inext]){
case(0):
{
printf("Moving north\n");
maze[n].north = 0;
maze[nextcell].south = 0;
break;
}
case(1):
{
printf("Moving north-east\n");
maze[n].northeast = 0;
maze[nextcell].southwest = 0;
break;
}
case(2):
{
printf("Moving south-east\n");
maze[n].southeast = 0;
maze[nextcell].northwest = 0;
break;
}
case(3):
{
printf("Moving south\n");
maze[n].south = 0;
maze[nextcell].north = 0;
break;
}
case(4):
{
printf("Moving south-west\n");
maze[n].southwest = 0;
maze[nextcell].northeast = 0;
break;
}
case(5):
{
printf("Moving north-west\n");
maze[n].northwest = 0;
maze[nextcell].southeast = 0;
break;
}
}
@ -248,12 +658,12 @@ void init_maze_old(t_maze maze[NXMAZE*NYMAZE])
for (i=0; i<RAND_SHIFT; i++) rand();
for (i=0; i<NXMAZE*NYMAZE; i++) if (!maze[i].tested) find_maze_path(maze, i, path, &pathlength);
for (i=0; i<NXMAZE*NYMAZE; i++) if (!maze[i].tested) find_maze_path(maze, i, path, &pathlength, 0);
}
void init_maze(t_maze maze[NXMAZE*NYMAZE])
/* init a maze with exit at (nx, ny) */
void init_maze_oftype(t_maze maze[NXMAZE*NYMAZE], int type)
/* init a maze of given type */
{
int i, j, n, deadend, pathlength, newpathlength;
int *path, *newpath;
@ -261,16 +671,32 @@ void init_maze(t_maze maze[NXMAZE*NYMAZE])
path = (int *)malloc(2*NXMAZE*NYMAZE*sizeof(short int));
newpath = (int *)malloc(2*NXMAZE*NYMAZE*sizeof(short int));
switch (type) {
case (0):
{
init_maze_graph(maze);
break;
}
case (1):
{
init_circular_maze_graph(maze);
break;
}
case (2):
{
init_hex_maze_graph(maze);
break;
}
}
for (i=0; i<RAND_SHIFT; i++) rand();
find_maze_path(maze, 0, path, &pathlength);
find_maze_path(maze, 0, path, &pathlength, type);
for (n=0; n<pathlength; n++) maze[path[n]].connected = 1;
for (i=0; i<NXMAZE*NYMAZE; i++) if ((!maze[i].tested)&&(!maze[i].connected))
{
deadend = find_maze_path(maze, i, path, &pathlength);
deadend = find_maze_path(maze, i, path, &pathlength, type);
if (!deadend) for (n=0; n<pathlength; n++) maze[path[n]].connected = 1;
j = 0;
printf("deadend = %i, pathlength = %i\n", deadend, pathlength);
@ -282,7 +708,7 @@ void init_maze(t_maze maze[NXMAZE*NYMAZE])
if (j > pathlength) j = 0;
printf("j = %i\n", j);
// while (deadend)
if (!maze[path[j]].connected) deadend = find_maze_path(maze, path[j], newpath, &newpathlength);
if (!maze[path[j]].connected) deadend = find_maze_path(maze, path[j], newpath, &newpathlength, type);
if (!deadend) for (n=0; n<newpathlength; n++) maze[newpath[n]].connected = 1;
}
@ -294,6 +720,45 @@ void init_maze(t_maze maze[NXMAZE*NYMAZE])
free(newpath);
}
void init_maze(t_maze maze[NXMAZE*NYMAZE])
/* init a maze */
{
init_maze_oftype(maze, 0);
}
void init_circular_maze(t_maze maze[NXMAZE*NYMAZE])
/* init a circular maze */
{
// int i, j, n, q;
init_maze_oftype(maze, 1);
/* for debugging */
// for (i=0; i<NXMAZE; i++)
// for (j=0; j<NYMAZE; j++)
// {
// n = nmaze(i, j);
// q = maze[n].nneighb;
// if (q > 0)
// {
// printf("Cell (%i, %i)\t", i, j);
// if (maze[n].north) printf("North ");
// if (maze[n].northeast) printf("N-E ");
// if (maze[n].east) printf("East ");
// if (maze[n].south) printf("South ");
// if (maze[n].west) printf("West ");
// printf("\n");
// }
// }
// sleep(5);
}
void init_hex_maze(t_maze maze[NXMAZE*NYMAZE])
/* init a maze with hexagonal cells */
{
init_maze_oftype(maze, 2);
}
void init_maze_exit(int nx, int ny, t_maze maze[NXMAZE*NYMAZE])
/* init a maze with exit at (nx, ny) */
{
@ -307,12 +772,12 @@ void init_maze_exit(int nx, int ny, t_maze maze[NXMAZE*NYMAZE])
for (i=0; i<RAND_SHIFT; i++) rand();
find_maze_path(maze, nmaze(nx, ny), path, &pathlength);
find_maze_path(maze, nmaze(nx, ny), path, &pathlength, 0);
for (n=0; n<pathlength; n++) maze[path[n]].connected = 1;
for (i=0; i<NXMAZE*NYMAZE; i++) if ((!maze[i].tested)&&(!maze[i].connected))
{
deadend = find_maze_path(maze, i, path, &pathlength);
deadend = find_maze_path(maze, i, path, &pathlength, 0);
if (!deadend) for (n=0; n<pathlength; n++) maze[path[n]].connected = 1;
j = 0;
printf("deadend = %i, pathlength = %i\n", deadend, pathlength);
@ -324,7 +789,7 @@ void init_maze_exit(int nx, int ny, t_maze maze[NXMAZE*NYMAZE])
if (j > pathlength) j = 0;
printf("j = %i\n", j);
// while (deadend)
if (!maze[path[j]].connected) deadend = find_maze_path(maze, path[j], newpath, &newpathlength);
if (!maze[path[j]].connected) deadend = find_maze_path(maze, path[j], newpath, &newpathlength, 0);
if (!deadend) for (n=0; n<newpathlength; n++) maze[newpath[n]].connected = 1;
}

File diff suppressed because it is too large Load Diff

627
sub_rde.c
View File

@ -4,6 +4,7 @@ double intstep; /* integration step */
double intstep1; /* integration step used in absorbing boundary conditions */
double viscosity; /* viscosity (parameter in front of Laplacian) */
double rpslzb; /* second parameter in Rock-Paper-Scissors-Lizard-Spock equation */
double flow_speed; /* flow speed for laminar boundary conditions in Euler equation */
double gaussian()
/* returns standard normal random variable, using Box-Mueller algorithm */
@ -313,14 +314,18 @@ void antisymmetrize_wave_function(double *phi[NFIELDS], short int xy_in[NX*NY])
}
}
void init_vortex_state(double x, double y, double scale, double *phi[NFIELDS], short int xy_in[NX*NY])
/* initialise field with vortex at position (x,y) with variance scale */
/* phi[0] is stream function, phi[1] is vorticity */
void init_vortex_state(double amp, double x, double y, double scale, double density_mod, double *phi[NFIELDS], short int xy_in[NX*NY])
/* initialise field with vortex at position (x,y) with amplitude and variance scale */
/* for incompressible Euler, phi[0] is stream function, phi[1] is vorticity */
/* for compressible Euler, phi[0] is the density, phi[1] and phi[2] are velocity components */
{
int i, j;
double xy[2], dist2, module, phase, scale2, sign;
// scale2 = scale*scale;
switch (RDE_EQUATION) {
case (E_EULER_INCOMP):
{
for (i=0; i<NX; i++)
for (j=0; j<NY; j++)
{
@ -330,7 +335,7 @@ void init_vortex_state(double x, double y, double scale, double *phi[NFIELDS], s
if (xy_in[i*NY+j])
{
dist2 = (xy[0]-x)*(xy[0]-x) + (xy[1]-y)*(xy[1]-y);
module = exp(-dist2/vabs(scale));
module = amp*exp(-dist2/vabs(scale));
if (scale > 0.0) sign = 1.0;
else sign = -1.0;
@ -344,16 +349,54 @@ void init_vortex_state(double x, double y, double scale, double *phi[NFIELDS], s
phi[1][i*NY+j] = 0.0;
}
}
break;
}
case (E_EULER_COMP):
{
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 = amp*exp(-dist2/vabs(scale));
if (scale > 0.0) sign = 1.0;
else sign = -1.0;
// phi[0][i*NY+j] = 1.0;
/* nonconstant density to make things more interesting */
phi[0][i*NY+j] = 0.5 + density_mod*module/amp;
phi[1][i*NY+j] = -sign*module*(xy[1]-y)/vabs(scale);
phi[2][i*NY+j] = sign*module*(xy[0]-x)/vabs(scale);
}
else
{
phi[0][i*NY+j] = 1.0;
phi[1][i*NY+j] = 0.0;
phi[2][i*NY+j] = 0.0;
}
}
break;
}
}
}
void add_vortex_state(double x, double y, double scale, double *phi[NFIELDS], short int xy_in[NX*NY])
void add_vortex_state(double amp, double x, double y, double scale, double density_mod, double *phi[NFIELDS], short int xy_in[NX*NY])
/* add vortex at position (x,y) with variance scale to field */
/* phi[0] is stream function, phi[1] is vorticity */
/* for incompressible Euler, phi[0] is stream function, phi[1] is vorticity */
/* for compressible Euler, phi[0] is the density, phi[1] and phi[2] are velocity components */
{
int i, j;
double xy[2], dist2, module, phase, scale2, sign;
// scale2 = scale*scale;
switch (RDE_EQUATION) {
case (E_EULER_INCOMP):
{
for (i=0; i<NX; i++)
for (j=0; j<NY; j++)
{
@ -363,13 +406,13 @@ void add_vortex_state(double x, double y, double scale, double *phi[NFIELDS], sh
if (xy_in[i*NY+j])
{
dist2 = (xy[0]-x)*(xy[0]-x) + (xy[1]-y)*(xy[1]-y);
module = exp(-dist2/vabs(scale));
module = amp*exp(-dist2/vabs(scale));
if (scale > 0.0) sign = 1.0;
else sign = -1.0;
phi[1][i*NY+j] += sign*module;
phi[0][i*NY+j] -= sign*module; /* approximate, stream function should solve Poisson equation */
phi[1][i*NY+j] -= sign*module;
phi[0][i*NY+j] = sign*module; /* approximate, stream function should solve Poisson equation */
}
else
{
@ -377,6 +420,40 @@ void add_vortex_state(double x, double y, double scale, double *phi[NFIELDS], sh
phi[1][i*NY+j] = 0.0;
}
}
break;
}
case (E_EULER_COMP):
{
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 = amp*exp(-dist2/vabs(scale));
if (scale > 0.0) sign = 1.0;
else sign = -1.0;
// phi[0][i*NY+j] = 1.0;
/* nonconstant density to make things more interesting */
phi[0][i*NY+j] += 0.5 + density_mod*sign*module/amp;
phi[1][i*NY+j] += sign*module*(xy[1]-y)/vabs(scale);
phi[2][i*NY+j] -= sign*module*(xy[0]-x)/vabs(scale);
}
else
{
phi[0][i*NY+j] = 1.0;
phi[1][i*NY+j] = 0.0;
phi[2][i*NY+j] = 0.0;
}
}
break;
}
}
}
@ -421,17 +498,20 @@ void init_shear_flow(double amp, double delta, double rho, int nx, int ny, doubl
phi[1][i*NY+j] = amp*(f - 1.0/(rho*cplus*cplus));
phi[0][i*NY+j] = amp*(f/(a*a) - rho/(cplus*cplus));
}
phi[2][i*NY+j] = 0.0;
}
else
{
phi[0][i*NY+j] = 0.0;
phi[1][i*NY+j] = 0.0;
phi[2][i*NY+j] = 0.0;
}
}
}
void init_laminar_flow(double amp, double modulation, double period, double yshift, double *phi[NFIELDS], short int xy_in[NX*NY])
/* initialise field with a laminar flow in x direction */
void set_boundary_laminar_flow(double amp, double modulation, double period, double yshift, double *phi[NFIELDS], short int xy_in[NX*NY], int imin, int imax, int jmin, int jmax)
/* enfoce laminar flow in x direction on top and bottom boundaries */
/* phi[0] is stream function, phi[1] is vorticity */
/* amp is global amplitude */
{
@ -439,8 +519,36 @@ void init_laminar_flow(double amp, double modulation, double period, double yshi
double xy[2], y1, a, b, f, cplus, cminus;
a = period*PI/YMAX;
// a = PID/YMAX;
for (i=imin; i<imax; i++)
for (j=jmin; j<jmax; j++)
{
ij_to_xy(i, j, xy);
xy_in[i*NY+j] = xy_in_billiard(xy[0],xy[1]);
y1 = xy[1] + yshift;
if (xy_in[i*NY+j])
{
phi[0][i*NY+j] = amp*(y1 + modulation*sin(a*y1)/a);
phi[1][i*NY+j] = amp*modulation*a*sin(a*y1);
}
}
}
void init_laminar_flow(double amp, double xmodulation, double ymodulation, double xperiod, double yperiod, double yshift, double density_mod, double *phi[NFIELDS], short int xy_in[NX*NY])
/* initialise field with a laminar flow in x direction */
/* phi[0] is stream function, phi[1] is vorticity */
/* amp is global amplitude */
{
int i, j;
double xy[2], y1, a, b, f, cplus, cminus;
a = xperiod*PI/YMAX;
b = yperiod*PI/XMAX;
switch (RDE_EQUATION) {
case (E_EULER_INCOMP):
{
for (i=0; i<NX; i++)
for (j=0; j<NY; j++)
{
@ -450,10 +558,8 @@ void init_laminar_flow(double amp, double modulation, double period, double yshi
if (xy_in[i*NY+j])
{
phi[0][i*NY+j] = amp*(y1 + modulation*sin(a*y1)/a);
phi[1][i*NY+j] = amp*modulation*a*sin(a*y1);
// phi[0][i*NY+j] = amp*sin(a*xy[1]);
// phi[1][i*NY+j] = a*a*amp*sin(a*xy[1]);
phi[0][i*NY+j] = amp*(y1 + xmodulation*sin(a*y1)/a);
phi[1][i*NY+j] = amp*xmodulation*a*sin(a*y1);
}
else
{
@ -461,8 +567,72 @@ void init_laminar_flow(double amp, double modulation, double period, double yshi
phi[1][i*NY+j] = 0.0;
}
}
break;
}
case (E_EULER_COMP):
{
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]);
y1 = xy[1] + yshift;
if (xy_in[i*NY+j])
{
phi[0][i*NY+j] = 1.0 + density_mod*cos(a*y1);
phi[1][i*NY+j] = amp*(1.0 + xmodulation*cos(a*y1));
phi[2][i*NY+j] = ymodulation*sin(b*xy[0]);
}
else
{
phi[0][i*NY+j] = 1.0;
phi[1][i*NY+j] = 0.0;
phi[2][i*NY+j] = 0.0;
}
}
break;
}
}
}
void initialize_bcfield(double bc_field[NX*NY])
/* apply smooth modulation to adapt initial state to obstacles */
{
int i, j;
double xy[2], r, f;
switch (OBSTACLE_GEOMETRY) {
case (D_SINAI):
{
for (i=0; i<NX; i++)
for (j=0; j<NY; j++)
{
ij_to_xy(i, j, xy);
r = module2(xy[0], xy[1]);
f = 0.5*(1.0 + tanh(BC_STIFFNESS*(r - 1.0*LAMBDA)));
bc_field[i*NY+j] = f;
}
break;
}
}
}
void adapt_state_to_bc(double *phi[NFIELDS], double bc_field[NX*NY], short int xy_in[NX*NY])
/* apply smooth modulation to adapt initial state to obstacles */
{
int i, j, field;
double xy[2], r, f;
#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])
{
for (field = 1; field < NFIELDS; field++)
phi[field][i*NY+j] *= bc_field[i*NY+j];
}
}
/*********************/
/* animation part */
@ -736,6 +906,105 @@ void compute_gradient_euler(double phi[NX*NY], double gradient[2*NX*NY], double
gradient[NX*NY+i*NY+j] = 0.5*(phi[i*NY+jplus] - phi[i*NY+jminus] - yshift);
}
void compute_gradient_euler_test(double phi[NX*NY], double gradient[2*NX*NY], short int xy_in[NX*NY])
/* compute the gradient of the field */
{
int i, j, iplus, iminus, jplus, jminus, padding = 0;
double deltaphi, maxgradient = 1.0e10;
double dx = (XMAX-XMIN)/((double)NX);
dx = (XMAX-XMIN)/((double)NX);
#pragma omp parallel for private(i)
for (i=0; i<2*NX*NY; i++) gradient[i] = 0.0;
#pragma omp parallel for private(i,j,iplus,iminus,jplus,jminus)
for (i=1; i<NX-1; i++)
{
for (j=1; j<NY-1; j++)
{
iplus = i+1;
iminus = i-1;
jplus = j+1;
jminus = j-1;
if ((xy_in[iplus*NY+j])&&(xy_in[iminus*NY+j]))
gradient[i*NY+j] = 0.5*(phi[iplus*NY+j] - phi[iminus*NY+j]);
if ((xy_in[i*NY+jplus])&&(xy_in[i*NY+jminus]))
gradient[NX*NY+i*NY+j] = 0.5*(phi[i*NY+jplus] - phi[i*NY+jminus]);
}
}
/* boundaries */
for (i=1; i<NX-1; i++)
{
iplus = i+1;
iminus = i-1;
j = 0;
jplus = 1;
jminus = NY-1;
gradient[i*NY+j] = 0.5*(phi[iplus*NY+j] - phi[iminus*NY+j]);
gradient[NX*NY+i*NY+j] = 0.5*(phi[i*NY+jplus] - phi[i*NY+jminus]);
// if (i == 1) printf("psi+ = %.5lg, psi- = %.5lg, gradient = %.5lg\n", phi[i*NY+jplus], phi[i*NY+jminus], gradient[NX*NY+i*NY+j]);
j = NY-1;
jplus = 0;
jminus = NY-2;
gradient[i*NY+j] = 0.5*(phi[iplus*NY+j] - phi[iminus*NY+j]);
gradient[NX*NY+i*NY+j] = 0.5*(phi[i*NY+jplus] - phi[i*NY+jminus]);
}
for (j=1; j<NY-1; j++)
{
jplus = j+1;
jminus = j-1;
i = 0;
iplus = 1;
iminus = NX-1;
gradient[i*NY+j] = 0.5*(phi[iplus*NY+j] - phi[iminus*NY+j]);
gradient[NX*NY+i*NY+j] = 0.5*(phi[i*NY+jplus] - phi[i*NY+jminus]);
// printf("j = %i, psi+ = %.5lg, psi- = %.5lg, gradient = %.5lg\n", j, phi[i*NY+jplus], phi[i*NY+jminus], gradient[NX*NY+i*NY+j]);
i = NX-1;
iplus = 0;
iminus = NX-2;
gradient[i*NY+j] = 0.5*(phi[iplus*NY+j] - phi[iminus*NY+j]);
gradient[NX*NY+i*NY+j] = 0.5*(phi[i*NY+jplus] - phi[i*NY+jminus]);
}
/* corners */
i = 0; iplus = 1; iminus = NX-1;
j = 0; jplus = 1; jminus = NY-1;
gradient[i*NY+j] = 0.5*(phi[iplus*NY+j] - phi[iminus*NY+j]);
gradient[NX*NY+i*NY+j] = 0.5*(phi[i*NY+jplus] - phi[i*NY+jminus]);
j = NY-1; jplus = 0; jminus = NY-2;
gradient[i*NY+j] = 0.5*(phi[iplus*NY+j] - phi[iminus*NY+j]);
gradient[NX*NY+i*NY+j] = 0.5*(phi[i*NY+jplus] - phi[i*NY+jminus]);
i = NX-1; iplus = 0; iminus = NX-2;
j = 0; jplus = 1; jminus = NY-1;
gradient[i*NY+j] = 0.5*(phi[iplus*NY+j] - phi[iminus*NY+j]);
gradient[NX*NY+i*NY+j] = 0.5*(phi[i*NY+jplus] - phi[i*NY+jminus]);
j = NY-1; jplus = 0; jminus = NY-2;
gradient[i*NY+j] = 0.5*(phi[iplus*NY+j] - phi[iminus*NY+j]);
gradient[NX*NY+i*NY+j] = 0.5*(phi[i*NY+jplus] - phi[i*NY+jminus]);
}
void compute_gradient_rde(double phi[NX*NY], t_rde rde[NX*NY])
/* compute the gradient of the field */
{
@ -751,7 +1020,7 @@ void compute_gradient_rde(double phi[NX*NY], t_rde rde[NX*NY])
{
iplus = i+1; if (iplus == NX) iplus = 0;
iminus = i-1; if (iminus == -1) iminus = NX-1;
jplus = j+1; if (jplus == NX) jplus = 0;
jplus = j+1; if (jplus == NY) jplus = 0;
jminus = j-1; if (jminus == -1) jminus = NY-1;
deltaphi = phi[iplus*NY+j] - phi[iminus*NY+j];
@ -787,7 +1056,7 @@ void compute_gradient_theta(t_rde rde[NX*NY])
{
iplus = i+1; if (iplus == NX) iplus = 0;
iminus = i-1; if (iminus == -1) iminus = NX-1;
jplus = j+1; if (jplus == NX) jplus = 0;
jplus = j+1; if (jplus == NY) jplus = 0;
jminus = j-1; if (jminus == -1) jminus = NY-1;
deltaphi = rde[iplus*NY+j].theta - rde[iminus*NY+j].theta;
@ -819,7 +1088,7 @@ void compute_curl(t_rde rde[NX*NY])
{
iplus = i+1; if (iplus == NX) iplus = 0;
iminus = i-1; if (iminus == -1) iminus = NX-1;
jplus = j+1; if (jplus == NX) jplus = 0;
jplus = j+1; if (jplus == NY) jplus = 0;
jminus = j-1; if (jminus == -1) jminus = NY-1;
delta = (rde[i*NY+jplus].nablay - rde[i*NY+jminus].nablay - (rde[iplus*NY+j].nablax - rde[iminus*NY+j].nablax))/dx;
@ -878,7 +1147,7 @@ void compute_field_argument(double *phi[NFIELDS], t_rde rde[NX*NY])
}
void compute_field_log(double *phi[NFIELDS], t_rde rde[NX*NY])
/* compute the norm squared of first two fields */
/* compute the log of a field */
{
int i, j;
double value;
@ -893,6 +1162,217 @@ void compute_field_log(double *phi[NFIELDS], t_rde rde[NX*NY])
}
}
void compute_pressure(double *phi[NFIELDS], t_rde rde[NX*NY])
/* compute the Laplacian of the pressure */
{
int i, j, iplus, iminus, jplus, jminus;
double value, dx, psixx, psiyy, psixy;
static double dx4;
static int first = 1;
if (first)
{
dx = (XMAX-XMIN)/((double)NX);
dx4 = dx*dx;
dx4 = dx4*dx4;
first = 0;
}
#pragma omp parallel for private(i,j,iplus,iminus,jplus,jminus,psixx,psiyy,psixy)
for (i=0; i<NX; i++)
for (j=0; j<NY; j++)
{
iplus = i+1; if (iplus == NX) iplus = 0;
iminus = i-1; if (iminus == -1) iminus = NX-1;
jplus = j+1; if (jplus == NY) jplus = 0;
jminus = j-1; if (jminus == -1) jminus = NY-1;
psixx = phi[0][iplus*NY+j] - 2.0*phi[0][i*NY+j] + phi[0][iminus*NY+j];
psiyy = phi[0][i*NY+jplus] - 2.0*phi[0][i*NY+j] + phi[0][i*NY+jminus];
psixy = phi[0][iplus*NY+jplus] - phi[0][iplus*NY+jminus] - phi[0][iminus*NY+jplus] + phi[0][iminus*NY+jminus];
rde[i*NY+j].Lpressure = (psixx*psiyy - psixy*psixy)/dx4;
}
}
void compute_pressure_laplacian(double *phi[NFIELDS], double *l_pressure)
/* compute the Laplacian of the pressure */
{
int i, j, iplus, iminus, jplus, jminus;
double value, dx, psixx, psiyy, psixy, dx4;
static double scaling;
static int first = 1;
if (first)
{
dx = (XMAX-XMIN)/((double)NX);
dx4 = dx*dx;
scaling = 1.0/(2.0*dx4*dx4);
first = 0;
}
#pragma omp parallel for private(i,j,iplus,iminus,jplus,jminus,psixx,psiyy,psixy)
for (i=0; i<NX; i++)
for (j=0; j<NY; j++)
{
iplus = i+1; if (iplus == NX) iplus = 0;
iminus = i-1; if (iminus == -1) iminus = NX-1;
jplus = j+1; if (jplus == NY) jplus = 0;
jminus = j-1; if (jminus == -1) jminus = NY-1;
psixx = phi[0][iplus*NY+j] - 2.0*phi[0][i*NY+j] + phi[0][iminus*NY+j];
psiyy = phi[0][i*NY+jplus] - 2.0*phi[0][i*NY+j] + phi[0][i*NY+jminus];
psixy = phi[0][iplus*NY+jplus] - phi[0][iplus*NY+jminus] - phi[0][iminus*NY+jplus] + phi[0][iminus*NY+jminus];
l_pressure[i*NY+j] = (psixx*psiyy - psixy*psixy)*scaling;
}
}
void compute_speed(double *phi[NFIELDS], t_rde rde[NX*NY])
/* compute the log of a field */
{
int i, j;
double value;
#pragma omp parallel for private(i,j,value)
for (i=0; i<NX; i++)
for (j=0; j<NY; j++)
{
value = module2(phi[1][i*NY+j], phi[2][i*NY+j]);
rde[i*NY+j].field_norm = value;
}
}
void compute_vorticity(t_rde rde[NX*NY])
/* compute the log of a field */
{
int i, j;
double value;
#pragma omp parallel for private(i,j,value)
for (i=0; i<NX; i++)
for (j=0; j<NY; j++)
{
rde[i*NY+j].curl = rde[i*NY+j].dxv - rde[i*NY+j].dyu + VORTICITY_SHIFT;
}
}
void compute_velocity_gradients(double *phi[NFIELDS], t_rde rde[NX*NY])
/* compute the gradients of the velocity field (for Euler equation) */
{
int i, j, k, iplus, iminus, jplus, jminus, padding = 0;
double deltaphi, maxgradient = 1.0e10;
// double dx = (XMAX-XMIN)/((double)NX);
// dx = (XMAX-XMIN)/((double)NX);
#pragma omp parallel for private(i,j,iplus,iminus,jplus,jminus)
for (i=1; i<NX-1; i++)
for (j=1; j<NY-1; j++)
{
iplus = i+1;
iminus = i-1;
jplus = j+1;
jminus = j-1;
rde[i*NY+j].dxu = 0.5*(phi[1][iplus*NY+j] - phi[1][iminus*NY+j]);
rde[i*NY+j].dyu = 0.5*(phi[1][i*NY+jplus] - phi[1][i*NY+jminus]);
rde[i*NY+j].dxv = 0.5*(phi[2][iplus*NY+j] - phi[2][iminus*NY+j]);
rde[i*NY+j].dyv = 0.5*(phi[2][i*NY+jplus] - phi[2][i*NY+jminus]);
}
/* boundaries */
for (i=1; i<NX-1; i++)
{
iplus = i+1;
iminus = i-1;
j = 0;
jplus = 1;
jminus = NY-1;
rde[i*NY+j].dxu = 0.5*(phi[1][iplus*NY+j] - phi[1][iminus*NY+j]);
rde[i*NY+j].dyu = 0.5*(phi[1][i*NY+jplus] - phi[1][i*NY+jminus]);
rde[i*NY+j].dxv = 0.5*(phi[2][iplus*NY+j] - phi[2][iminus*NY+j]);
rde[i*NY+j].dyv = 0.5*(phi[2][i*NY+jplus] - phi[2][i*NY+jminus]);
j = NY-1;
jplus = 0;
jminus = NY-2;
rde[i*NY+j].dxu = 0.5*(phi[1][iplus*NY+j] - phi[1][iminus*NY+j]);
rde[i*NY+j].dyu = 0.5*(phi[1][i*NY+jplus] - phi[1][i*NY+jminus]);
rde[i*NY+j].dxv = 0.5*(phi[2][iplus*NY+j] - phi[2][iminus*NY+j]);
rde[i*NY+j].dyv = 0.5*(phi[2][i*NY+jplus] - phi[2][i*NY+jminus]);
}
for (j=1; j<NY-1; j++)
{
jplus = j+1;
jminus = j-1;
i = 0;
iplus = 1;
iminus = NX-1;
rde[i*NY+j].dxu = 0.5*(phi[1][iplus*NY+j] - phi[1][iminus*NY+j]);
rde[i*NY+j].dyu = 0.5*(phi[1][i*NY+jplus] - phi[1][i*NY+jminus]);
rde[i*NY+j].dxv = 0.5*(phi[2][iplus*NY+j] - phi[2][iminus*NY+j]);
rde[i*NY+j].dyv = 0.5*(phi[2][i*NY+jplus] - phi[2][i*NY+jminus]);
i = NX-1;
iplus = 0;
iminus = NX-2;
rde[i*NY+j].dxu = 0.5*(phi[1][iplus*NY+j] - phi[1][iminus*NY+j]);
rde[i*NY+j].dyu = 0.5*(phi[1][i*NY+jplus] - phi[1][i*NY+jminus]);
rde[i*NY+j].dxv = 0.5*(phi[2][iplus*NY+j] - phi[2][iminus*NY+j]);
rde[i*NY+j].dyv = 0.5*(phi[2][i*NY+jplus] - phi[2][i*NY+jminus]);
}
/* corners */
i = 0; iplus = 1; iminus = NX-1;
j = 0; jplus = 1; jminus = NY-1;
rde[i*NY+j].dxu = 0.5*(phi[1][iplus*NY+j] - phi[1][iminus*NY+j]);
rde[i*NY+j].dyu = 0.5*(phi[1][i*NY+jplus] - phi[1][i*NY+jminus]);
rde[i*NY+j].dxv = 0.5*(phi[2][iplus*NY+j] - phi[2][iminus*NY+j]);
rde[i*NY+j].dyv = 0.5*(phi[2][i*NY+jplus] - phi[2][i*NY+jminus]);
j = NY-1; jplus = 0; jminus = NY-2;
rde[i*NY+j].dxu = 0.5*(phi[1][iplus*NY+j] - phi[1][iminus*NY+j]);
rde[i*NY+j].dyu = 0.5*(phi[1][i*NY+jplus] - phi[1][i*NY+jminus]);
rde[i*NY+j].dxv = 0.5*(phi[2][iplus*NY+j] - phi[2][iminus*NY+j]);
rde[i*NY+j].dyv = 0.5*(phi[2][i*NY+jplus] - phi[2][i*NY+jminus]);
i = NX-1; iplus = 0; iminus = NX-2;
j = 0; jplus = 1; jminus = NY-1;
rde[i*NY+j].dxu = 0.5*(phi[1][iplus*NY+j] - phi[1][iminus*NY+j]);
rde[i*NY+j].dyu = 0.5*(phi[1][i*NY+jplus] - phi[1][i*NY+jminus]);
rde[i*NY+j].dxv = 0.5*(phi[2][iplus*NY+j] - phi[2][iminus*NY+j]);
rde[i*NY+j].dyv = 0.5*(phi[2][i*NY+jplus] - phi[2][i*NY+jminus]);
j = NY-1; jplus = 0; jminus = NY-2;
rde[i*NY+j].dxu = 0.5*(phi[1][iplus*NY+j] - phi[1][iminus*NY+j]);
rde[i*NY+j].dyu = 0.5*(phi[1][i*NY+jplus] - phi[1][i*NY+jminus]);
rde[i*NY+j].dxv = 0.5*(phi[2][iplus*NY+j] - phi[2][iminus*NY+j]);
rde[i*NY+j].dyv = 0.5*(phi[2][i*NY+jplus] - phi[2][i*NY+jminus]);
}
void compute_probabilities(t_rde rde[NX*NY], short int xy_in[NX*NY], double probas[2])
/* compute probabilities for Ehrenfest urns */
{
@ -1216,6 +1696,36 @@ void compute_field_color_rde(double value, int cplot, int palette, double rgb[3]
color_scheme_palette(COLOR_SCHEME, palette, VSCALE_AMPLITUDE*value, 1.0, 0, rgb);
break;
}
case (Z_EULER_LPRESSURE):
{
color_scheme_palette(COLOR_SCHEME, palette, VSCALE_AMPLITUDE*value, 1.0, 0, rgb);
break;
}
case (Z_EULER_PRESSURE):
{
if (value + PRESSURE_SHIFT < 1.0e-10) value = 1.0e-10 - PRESSURE_SHIFT;
color_scheme_palette(COLOR_SCHEME, palette, VSCALE_PRESSURE*log(value + PRESSURE_SHIFT) + PRESSURE_LOG_SHIFT, 1.0, 0, rgb);
// color_scheme_palette(COLOR_SCHEME, palette, VSCALE_PRESSURE*(value - AVERAGE_PRESSURE), 1.0, 0, rgb);
break;
}
case (Z_EULER_DENSITY):
{
color_scheme_palette(COLOR_SCHEME, palette, VSCALE_DENSITY*(value-1.0), 1.0, 0, rgb);
break;
}
case (Z_EULER_SPEED):
{
if (ASYM_SPEED_COLOR)
color_scheme_asym_palette(COLOR_SCHEME, palette, VSCALE_SPEED*value, 1.0, 0, rgb);
else
color_scheme_palette(COLOR_SCHEME, palette, VSCALE_SPEED*(value-VMEAN_SPEED), 1.0, 0, rgb);
break;
}
case (Z_EULERC_VORTICITY):
{
color_scheme_palette(COLOR_SCHEME, palette, VSCALE_VORTICITY*(value-VORTICITY_SHIFT), 1.0, 0, rgb);
break;
}
}
}
@ -1374,6 +1884,16 @@ void compute_rde_fields(double *phi[NFIELDS], short int xy_in[NX*NY], int zplot,
{
if ((zplot == Z_EULER_LOG_VORTICITY)||(cplot == Z_EULER_LOG_VORTICITY))
compute_field_log(phi, rde);
if ((zplot == Z_EULER_LPRESSURE)||(cplot == Z_EULER_LPRESSURE))
compute_pressure(phi, rde);
break;
}
case (E_EULER_COMP):
{
if ((zplot == Z_EULER_SPEED)||(cplot == Z_EULER_SPEED))
compute_speed(phi, rde);
if ((zplot == Z_EULERC_VORTICITY)||(cplot == Z_EULERC_VORTICITY))
compute_vorticity(rde);
break;
}
default : break;
@ -1494,6 +2014,36 @@ void init_zfield_rde(double *phi[NFIELDS], short int xy_in[NX*NY], int zplot, t_
for (i=0; i<NX; i++) for (j=0; j<NY; j++) rde[i*NY+j].p_zfield[movie] = &phi[1][i*NY+j];
break;
}
case (Z_EULER_LPRESSURE):
{
#pragma omp parallel for private(i,j)
for (i=0; i<NX; i++) for (j=0; j<NY; j++) rde[i*NY+j].p_zfield[movie] = &rde[i*NY+j].Lpressure;
break;
}
case (Z_EULER_PRESSURE):
{
#pragma omp parallel for private(i,j)
for (i=0; i<NX; i++) for (j=0; j<NY; j++) rde[i*NY+j].p_zfield[movie] = &phi[2][i*NY+j];
break;
}
case (Z_EULER_DENSITY):
{
#pragma omp parallel for private(i,j)
for (i=0; i<NX; i++) for (j=0; j<NY; j++) rde[i*NY+j].p_zfield[movie] = &phi[0][i*NY+j];
break;
}
case (Z_EULER_SPEED):
{
#pragma omp parallel for private(i,j)
for (i=0; i<NX; i++) for (j=0; j<NY; j++) rde[i*NY+j].p_zfield[movie] = &rde[i*NY+j].field_norm;
break;
}
case (Z_EULERC_VORTICITY):
{
#pragma omp parallel for private(i,j)
for (i=0; i<NX; i++) for (j=0; j<NY; j++) rde[i*NY+j].p_zfield[movie] = &rde[i*NY+j].curl;
break;
}
}
}
@ -1611,6 +2161,36 @@ void init_cfield_rde(double *phi[NFIELDS], short int xy_in[NX*NY], int cplot, t_
for (i=0; i<NX; i++) for (j=0; j<NY; j++) rde[i*NY+j].p_cfield[movie] = &phi[1][i*NY+j];
break;
}
case (Z_EULER_LPRESSURE):
{
#pragma omp parallel for private(i,j)
for (i=0; i<NX; i++) for (j=0; j<NY; j++) rde[i*NY+j].p_cfield[movie] = &rde[i*NY+j].Lpressure;
break;
}
case (Z_EULER_PRESSURE):
{
#pragma omp parallel for private(i,j)
for (i=0; i<NX; i++) for (j=0; j<NY; j++) rde[i*NY+j].p_cfield[movie] = &phi[2][i*NY+j];
break;
}
case (Z_EULER_DENSITY):
{
#pragma omp parallel for private(i,j)
for (i=0; i<NX; i++) for (j=0; j<NY; j++) rde[i*NY+j].p_cfield[movie] = &phi[0][i*NY+j];
break;
}
case (Z_EULER_SPEED):
{
#pragma omp parallel for private(i,j)
for (i=0; i<NX; i++) for (j=0; j<NY; j++) rde[i*NY+j].p_cfield[movie] = &rde[i*NY+j].field_norm;
break;
}
case (Z_EULERC_VORTICITY):
{
#pragma omp parallel for private(i,j)
for (i=0; i<NX; i++) for (j=0; j<NY; j++) rde[i*NY+j].p_cfield[movie] = &rde[i*NY+j].curl;
break;
}
}
}
@ -1667,8 +2247,7 @@ void draw_wave_2d_rde(short int xy_in[NX*NY], t_rde rde[NX*NY])
}
void draw_wave_3d_ij_rde(int i, int j, int movie, double *phi[NFIELDS], short int xy_in[NX*NY], t_rde rde[NX*NY],
double potential[NX*NY], int zplot, int cplot, int palette, int fade, double fade_value)
void draw_wave_3d_ij_rde(int i, int j, int movie, double *phi[NFIELDS], short int xy_in[NX*NY], t_rde rde[NX*NY], double potential[NX*NY], int zplot, int cplot, int palette, int fade, double fade_value)
{
int k, l, draw = 1;
double xy[2], xy_screen[2], rgb[3], pos[2], ca, rgb_e[3], rgb_w[3], rgb_n[3], rgb_s[3];
@ -1871,8 +2450,8 @@ void draw_periodicised_wave_3d(int movie, double *phi[NFIELDS], short int xy_in[
}
void draw_wave_rde(int movie, double *phi[NFIELDS], short int xy_in[NX*NY], t_rde rde[NX*NY], double potential[NX*NY],
int zplot, int cplot, int palette, int fade, double fade_value, int refresh)
void draw_wave_rde(int movie, double *phi[NFIELDS], short int xy_in[NX*NY], t_rde rde[NX*NY],
double potential[NX*NY], int zplot, int cplot, int palette, int fade, double fade_value, int refresh)
{
int i, j, k, l, draw = 1;
double xy[2], xy_screen[2], rgb[3], pos[2], ca, rgb_e[3], rgb_w[3], rgb_n[3], rgb_s[3];

View File

@ -3,7 +3,7 @@
/*********************/
#include "colors_waves.c"
#define TIFF_FREE_PERIOD 10
#define TIFF_FREE_PERIOD 1
int writetiff_new(char *filename, char *description, int x, int y, int width, int height, int compression)
{
@ -109,15 +109,15 @@ int writetiff(char *filename, char *description, int x, int y, int width, int he
}
/* added 9/9/22 and removed again, since it produces an unwanted "band" on the right */
/* readded 5/11/22 */
if (SAVE_MEMORY)
{
counter++;
if (counter%TIFF_FREE_PERIOD == 0)
{
free(image); /* prevents RAM consumption*/
counter = 0;
}
}
if (SAVE_MEMORY) free(image); /* prevents RAM consumption*/
// {
// counter++;
// if (counter%TIFF_FREE_PERIOD == 0)
// {
// free(image); /* prevents RAM consumption*/
// counter = 0;
// }
// }
TIFFClose(file);
return 0;
}
@ -1630,8 +1630,8 @@ int compute_qrd_coordinates(t_vertex polyline[NMAXPOLY])
return(n);
}
int compute_maze_coordinates(t_rectangle polyrect[NMAXPOLY], int closed)
/* compute positions of quadratic noise diffuser */
int compute_maze_coordinates(t_rectangle polyrect[NMAXPOLY], int type)
/* compute positions of maze */
{
t_maze* maze;
int i, j, n, nsides = 0, ropening;
@ -1639,15 +1639,24 @@ int compute_maze_coordinates(t_rectangle polyrect[NMAXPOLY], int closed)
maze = (t_maze *)malloc(NXMAZE*NYMAZE*sizeof(t_maze));
ropening = (NYMAZE+1)/2;
init_maze(maze);
/* move the entrance for maze type with two channels */
if (type == 2)
{
n = nmaze(0, ropening-1);
maze[n].west = 0;
n = nmaze(0, ropening);
maze[n].west = 1;
}
/* build walls of maze */
// x0 = LAMBDA - 1.0;
dx = (YMAX - YMIN - 2.0*padding)/(double)(NXMAZE);
dy = (YMAX - YMIN - 2.0*padding)/(double)(NYMAZE);
ropening = (NYMAZE+1)/2;
for (i=0; i<NXMAZE; i++)
for (j=0; j<NYMAZE; j++)
{
@ -1661,8 +1670,8 @@ int compute_maze_coordinates(t_rectangle polyrect[NMAXPOLY], int closed)
polyrect[nsides].y1 = y1 - width;
polyrect[nsides].x2 = x1 + width;
polyrect[nsides].y2 = y1 + width + dy;
}
nsides++;
}
if (maze[n].south)
{
@ -1670,9 +1679,9 @@ int compute_maze_coordinates(t_rectangle polyrect[NMAXPOLY], int closed)
polyrect[nsides].y1 = y1 - width;
polyrect[nsides].x2 = x1 + width + dx;
polyrect[nsides].y2 = y1 + width;
}
nsides++;
}
}
/* top side of maze */
polyrect[nsides].x1 = YMIN + padding + MAZE_XSHIFT;
@ -1710,7 +1719,7 @@ int compute_maze_coordinates(t_rectangle polyrect[NMAXPOLY], int closed)
polyrect[nsides].y2 = YMAX + 1.0;
nsides++;
if (closed)
if (type == 1) /* maze with closed sides */
{
polyrect[nsides].x1 = XMIN - 0.5*width;
polyrect[nsides].y1 = YMIN - 0.5*width;
@ -1731,6 +1740,39 @@ int compute_maze_coordinates(t_rectangle polyrect[NMAXPOLY], int closed)
nsides++;
}
else if (type == 2) /* maze with channels */
{
/* right channel */
y1 = YMIN + padding + dy*((double)ropening);
x1 = YMAX - padding + MAZE_XSHIFT;
polyrect[nsides].x1 = x1 - 0.5*width;
polyrect[nsides].y1 = YMIN - padding;
polyrect[nsides].x2 = XMAX + padding;
polyrect[nsides].y2 = y1 - dy + width;
nsides++;
polyrect[nsides].x1 = x1 - 0.5*width;
polyrect[nsides].y1 = y1 - width;
polyrect[nsides].x2 = XMAX + padding;
polyrect[nsides].y2 = YMAX + padding;
nsides++;
/* left channel */
x1 = YMIN + padding + MAZE_XSHIFT;
polyrect[nsides].x1 = XMIN - padding;
polyrect[nsides].y1 = YMIN - padding;
polyrect[nsides].x2 = x1 + 0.5*width;
polyrect[nsides].y2 = y1 - dy + width;
nsides++;
polyrect[nsides].x1 = XMIN - padding;
polyrect[nsides].y1 = y1 - width;
polyrect[nsides].x2 = x1 + 0.5*width;
polyrect[nsides].y2 = YMAX + padding;
nsides++;
}
for (i=0; i<nsides; i++)
{
xy_to_pos(polyrect[i].x1, polyrect[i].y1, pos);
@ -1745,6 +1787,189 @@ int compute_maze_coordinates(t_rectangle polyrect[NMAXPOLY], int closed)
return(nsides);
}
int compute_circular_maze_coordinates(t_rect_rotated polyrectrot[NMAXPOLY], t_arc polyarc[NMAXPOLY], int *npolyrect_rot, int *npolyarc)
/* compute positions of circular maze */
{
int nblocks, block, i, j, n, p, q, np, na;
double rmin, rmax, angle, r, dr, phi, dphi, ww, width = 0.02;
t_maze* maze;
maze = (t_maze *)malloc(NXMAZE*NYMAZE*sizeof(t_maze));
init_circular_maze(maze);
np = 0;
na = 0;
/* build walls of maze */
nblocks = NYMAZE/NXMAZE;
rmin = 0.15;
rmax = 1.0;
angle = DPI/(double)nblocks;
dr = (rmax - rmin)/(double)(NXMAZE);
/* add straight walls */
for (block = 0; block < nblocks; block++)
{
dphi = angle;
/* first circle */
n = nmaze(0, block*NXMAZE);
r = rmin - 0.5*width;
phi = (double)block*angle;
if (maze[n].south)
{
polyrectrot[np].x1 = r*cos(phi) + MAZE_XSHIFT;
polyrectrot[np].y1 = r*sin(phi);
polyrectrot[np].x2 = (r+dr+width)*cos(phi) + MAZE_XSHIFT;
polyrectrot[np].y2 = (r+dr+width)*sin(phi);
polyrectrot[np].width = width;
np++;
}
/* second circle */
r = rmin + dr - 0.5*width;
dphi *= 0.5;
for (q=0; q<2; q++)
{
n = nmaze(1, block*NXMAZE + q);
phi = (double)(block)*angle + (double)q*dphi;
if (maze[n].south)
{
polyrectrot[np].x1 = r*cos(phi) + MAZE_XSHIFT;
polyrectrot[np].y1 = r*sin(phi);
polyrectrot[np].x2 = (r+dr+width)*cos(phi) + MAZE_XSHIFT;
polyrectrot[np].y2 = (r+dr+width)*sin(phi);
polyrectrot[np].width = width;
np++;
}
}
/* other circles */
ww = 2;
i = 2;
while (ww < NXMAZE)
{
dphi *= 0.5;
for (p = 0; p < ww; p++)
{
r = rmin + (double)i*dr - 0.5*width;
// printf("Segment, i = %i, dphi = %.2lg, r = %.2lg\n", i, dphi, r);
for (q = 0; q < 2*ww; q++)
{
j = block*NXMAZE + q;
n = nmaze(i,j);
phi = (double)(block)*angle + (double)q*dphi;
if (maze[n].south)
{
polyrectrot[np].x1 = r*cos(phi) + MAZE_XSHIFT;
polyrectrot[np].y1 = r*sin(phi);
polyrectrot[np].x2 = (r+dr+width)*cos(phi) + MAZE_XSHIFT;
polyrectrot[np].y2 = (r+dr+width)*sin(phi);
polyrectrot[np].width = width;
np++;
}
}
i++;
}
ww *= 2;
}
}
/* add circular arcs */
for (block = 0; block < nblocks; block++)
{
dphi = angle;
/* first circle */
n = nmaze(0, block*NXMAZE);
r = rmin;
phi = (double)block*angle;
if ((block > 0)&&(maze[n].west))
{
polyarc[na].xc = MAZE_XSHIFT;
polyarc[na].yc = 0.0;
polyarc[na].r = r;
polyarc[na].angle1 = phi;
polyarc[na].dangle = dphi;
polyarc[na].width = width;
na++;
}
/* second circle */
r = rmin + dr;
dphi *= 0.5;
for (q=0; q<2; q++)
{
n = nmaze(1, block*NXMAZE + q);
phi = (double)(block)*angle + (double)q*dphi;
if (maze[n].west)
{
polyarc[na].xc = MAZE_XSHIFT;
polyarc[na].yc = 0.0;
polyarc[na].r = r;
polyarc[na].angle1 = phi;
polyarc[na].dangle = dphi;
polyarc[na].width = width;
na++;
}
}
/* other circles */
ww = 2;
i = 2;
while (ww < NXMAZE)
{
dphi *= 0.5;
for (p = 0; p < ww; p++)
{
r = rmin + (double)i*dr;
printf("Circle, i = %i, dphi = %.2lg, r = %.2lg\n", i, dphi, r);
for (q = 0; q < 2*ww; q++)
{
j = block*NXMAZE + q;
n = nmaze(i,j);
phi = (double)(block)*angle + (double)q*dphi;
if (maze[n].west)
{
polyarc[na].xc = MAZE_XSHIFT;
polyarc[na].yc = 0.0;
polyarc[na].r = r;
polyarc[na].angle1 = phi;
polyarc[na].dangle = dphi;
polyarc[na].width = width;
na++;
}
}
i++;
}
ww *= 2;
}
}
/* outer boundary of maze */
polyarc[na].xc = MAZE_XSHIFT;
polyarc[na].yc = 0.0;
polyarc[na].r = rmax;
polyarc[na].angle1 = dphi;
polyarc[na].dangle = DPI - dphi;
polyarc[na].width = width;
na++;
*npolyrect_rot = np;
*npolyarc = na;
free(maze);
}
int init_polyline(int depth, t_vertex polyline[NMAXPOLY])
/* initialise variable polyline, for certain polygonal domain shapes */
{
@ -1820,6 +2045,10 @@ int init_polyrect(t_rectangle polyrect[NMAXPOLY])
{
return(compute_maze_coordinates(polyrect, 1));
}
case (D_MAZE_CHANNELS):
{
return(compute_maze_coordinates(polyrect, 2));
}
default:
{
if ((ADD_POTENTIAL)&&(POTENTIAL == POT_MAZE)) return(compute_maze_coordinates(polyrect, 1));
@ -1828,6 +2057,17 @@ int init_polyrect(t_rectangle polyrect[NMAXPOLY])
}
}
void init_polyrect_arc(t_rect_rotated polyrectrot[NMAXPOLY], t_arc polyarc[NMAXPOLY], int *npolyrect, int *npolyarc)
/* initialise variables polyrectrot and polyarc, for certain domain shapes */
{
switch (B_DOMAIN) {
case (D_MAZE_CIRCULAR):
{
compute_circular_maze_coordinates(polyrectrot, polyarc, npolyrect, npolyarc);
break;
}
}
}
void isospectral_initial_point(double x, double y, double left[2], double right[2])
/* compute initial coordinates in isospectral billiards */
@ -1941,14 +2181,56 @@ int ij_in_polyrect(double i, double j, t_rectangle rectangle)
return(1);
}
int xy_in_rectrotated(double x, double y, t_rect_rotated rectrot)
/* returns 1 if (x,y) is in rectangle */
{
double l, u1, u2, v1, v2, pscal, h2;
l = module2(rectrot.x2 - rectrot.x1, rectrot.y2 - rectrot.y1);
if (l == 0.0) return(0);
/* unit vector along axis */
u1 = (rectrot.x2 - rectrot.x1)/l;
u2 = (rectrot.y2 - rectrot.y1)/l;
/* vector from one extremity to (x,y) */
v1 = x - rectrot.x1;
v2 = y - rectrot.y1;
/* inner product */
pscal = u1*v1 + u2*v2;
if (pscal < 0.0) return(0);
if (pscal > l) return(0);
h2 = v1*v1 + v2*v2 - pscal*pscal;
return(4.0*h2 <= rectrot.width*rectrot.width);
}
int xy_in_arc(double x, double y, t_arc arc)
/* returns 1 if (x,y) is in arc */
{
double rho, phi, alpha;
rho = module2(x - arc.xc, y - arc.yc);
if (vabs(rho - arc.r) > 0.5*arc.width) return(0);
phi = argument(x - arc.xc, y - arc.yc);
alpha = phi - arc.angle1;
while (alpha < 0.0) alpha += DPI;
while (alpha > DPI) alpha -= DPI;
return(alpha <= arc.dangle);
}
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 l2, r2, r2mu, omega, b, c, angle, z, x1, y1, x2, y2, u, v, u1, v1, dx, dy, width, alpha, s, a, r, height;
double l2, r2, r2mu, omega, b, c, angle, z, x1, y1, x2, y2, u, v, u1, v1, dx, dy, width, alpha, s, a, r, height, ca, sa, l, ht;
int i, j, k, k1, k2, condition = 0, m;
static int first = 1, nsides;
static double h, hh, ra, rb;
static double h, hh, ra, rb, ll, salpha;
switch (b_domain) {
case (D_NOTHING):
@ -2123,7 +2405,7 @@ int xy_in_billiard_single_domain(double x, double y, int b_domain, int ncirc, t_
omega = DPI/((double)NPOLY);
for (k=0; k<NPOLY; k++)
{
angle = APOLY*PID + (k+0.5)*omega;
angle = APOLY*PID + ((double)k+0.5)*omega;
x1 = x*cos(angle) + y*sin(angle);
y1 = -x*sin(angle) + y*cos(angle);
condition = condition*(x1 < LAMBDA + MU - 0.25*y1*y1/MU);
@ -2538,6 +2820,20 @@ int xy_in_billiard_single_domain(double x, double y, int b_domain, int ncirc, t_
if ((x > polyrect[i].x1)&&(x < polyrect[i].x2)&&(y > polyrect[i].y1)&&(y < polyrect[i].y2)) return(0);
return(1);
}
case (D_MAZE_CHANNELS):
{
for (i=0; i<npolyrect; i++)
if ((x > polyrect[i].x1)&&(x < polyrect[i].x2)&&(y > polyrect[i].y1)&&(y < polyrect[i].y2)) return(0);
return(1);
}
case (D_MAZE_CIRCULAR):
{
for (i=0; i<npolyrect_rot; i++)
if (xy_in_rectrotated(x, y, polyrectrot[i])) return(0);
for (i=0; i<npolyarc; i++)
if (xy_in_arc(x, y, polyarc[i])) return(0);
return(1);
}
case (D_CHESSBOARD):
{
i = (int)(vabs(x)/LAMBDA + 0.5);
@ -2581,6 +2877,42 @@ int xy_in_billiard_single_domain(double x, double y, int b_domain, int ncirc, t_
if (x1 + y1 > 5.0) return(1);
return(0);
}
case (D_FUNNELS):
{
y1 = y;
if (y > 0.5*YMAX) y1 -= YMAX;
if (y < -0.5*YMAX) y1 += YMAX;
y1 = vabs(y1 - MU*x);
y1 = vabs(y1 - 0.5*YMAX)*2.0/YMAX;
if (y1 > 0.25*(1.0 + LAMBDA + x*x)) return(0);
return(1);
}
case (D_ONE_FUNNEL):
{
y1 = vabs(y);
if (y1 > MU + LAMBDA*x*x) return(0);
return(1);
}
case (D_LENSES_RING):
{
if (first)
{
salpha = DPI/(double)NPOLY;
h = LAMBDA*tan(PI/(double)NPOLY);
if (h < MU) ll = sqrt(MU*MU - h*h);
else ll = 0.0;
first = 0;
}
for (i=0; i<NPOLY; i++)
{
ca = cos((double)i*salpha + APOLY*PID);
sa = sin((double)i*salpha + APOLY*PID);
x1 = x*ca + y*sa;
y1 = -x*sa + y*ca;
if ((module2(x1 - LAMBDA - ll, y1) < MU)&&(module2(x1 - LAMBDA + ll, y1) < MU)) return(0);
}
return(1);
}
case (D_MENGER):
{
x1 = 0.5*(x+1.0);
@ -2791,10 +3123,10 @@ void hex_transfo(double u, double v, double *x, double *y)
void draw_billiard(int fade, double fade_value) /* draws the billiard boundary */
{
double x0, y0, x, y, x1, y1, x2, y2, dx, dy, phi, r = 0.01, pos[2], pos1[2], alpha, dphi, omega, z, l, width, a, b, c, ymax, height;
double x0, y0, x, y, x1, y1, x2, y2, dx, dy, phi, r = 0.01, pos[2], pos1[2], alpha, dphi, omega, z, l, width, a, b, c, ymax, height, xmax, ca, sa;
int i, j, k, k1, k2, mr2, ntiles;
static int first = 1, nsides;
static double h, hh, sqr3;
static double h, hh, sqr3, ll, salpha, arcangle;
if (fade)
{
@ -3807,6 +4139,23 @@ void draw_billiard(int fade, double fade_value) /* draws the billiard bound
draw_filled_rectangle(polyrect[i].x1, polyrect[i].y1, polyrect[i].x2, polyrect[i].y2);
break;
}
case (D_MAZE_CHANNELS):
{
glLineWidth(BOUNDARY_WIDTH);
if (fade) glColor3f(0.15*fade_value, 0.15*fade_value, 0.15*fade_value);
else glColor3f(0.15, 0.15, 0.15);
for (i=0; i<npolyrect; i++)
draw_filled_rectangle(polyrect[i].x1, polyrect[i].y1, polyrect[i].x2, polyrect[i].y2);
break;
}
case (D_MAZE_CIRCULAR):
{
glLineWidth(BOUNDARY_WIDTH);
if (fade) glColor3f(0.15*fade_value, 0.15*fade_value, 0.15*fade_value);
else glColor3f(0.15, 0.15, 0.15);
/* TODO */
break;
}
case (D_CHESSBOARD):
{
glLineWidth(BOUNDARY_WIDTH);
@ -3910,6 +4259,67 @@ void draw_billiard(int fade, double fade_value) /* draws the billiard bound
break;
}
case (D_FUNNELS):
{
if (LAMBDA < 3.0)
{
xmax = sqrt(3.0 - LAMBDA);
for (j=-2; j<2; j++)
for (k=-1; k<=1; k+=2)
{
for (i=0; i <= NSEG; i++)
{
x = -xmax + (2.0*xmax)*(double)i/(double)NSEG;
y = (double)j*YMAX + MU*x + 0.5*YMAX*(1.0 + 0.25*(double)k*(1.0 + LAMBDA + x*x));
if (i > 0) draw_line(x1, y1, x, y);
x1 = x;
y1 = y;
}
}
}
break;
}
case (D_ONE_FUNNEL):
{
for (k=-1; k<2; k+=2)
{
x1 = XMIN;
y1 = (double)k*(MU + LAMBDA*x1*x1);
for (i=0; i<=NSEG; i++)
{
x = XMIN + (XMAX - XMIN)*(double)i/(double)NSEG;
y = (double)k*(MU + LAMBDA*x*x);
draw_line(x1, y1, x, y);
x1 = x;
y1 = y;
}
}
break;
}
case (D_LENSES_RING):
{
if (first)
{
salpha = DPI/(double)NPOLY;
h = LAMBDA*tan(PI/(double)NPOLY);
if (h < MU) ll = sqrt(MU*MU - h*h);
else ll = 0.0;
arcangle = atan(h/ll);
first = 0;
}
for (i=0; i<NPOLY; i++)
{
ca = cos((double)i*salpha + APOLY*PID);
sa = sin((double)i*salpha + APOLY*PID);
x = ca*(LAMBDA - ll);
y = sa*(LAMBDA - ll);
draw_circle_arc(x, y, MU, -arcangle + APOLY*PID + (double)i*salpha, 2.0*arcangle, NSEG);
x = ca*(LAMBDA + ll);
y = sa*(LAMBDA + ll);
draw_circle_arc(x, y, MU, PI-arcangle + APOLY*PID + (double)i*salpha, 2.0*arcangle, NSEG);
}
break;
}
case (D_MENGER):
{
glLineWidth(3);
@ -4150,7 +4560,7 @@ void draw_billiard(int fade, double fade_value) /* draws the billiard bound
void draw_color_scheme(double x1, double y1, double x2, double y2, int plot, double min, double max)
{
int j, k, ij_botleft[2], ij_topright[2], imin, imax, jmin, jmax;
double y, dy, dy_e, rgb[3], value, lum, amp;
double y, dy, dy_e, rgb[3], value, lum, amp, dy_phase;
xy_to_ij(x1, y1, ij_botleft);
xy_to_ij(x2, y2, ij_topright);
@ -4177,6 +4587,7 @@ void draw_color_scheme(double x1, double y1, double x2, double y2, int plot, dou
glBegin(GL_QUADS);
dy = (max - min)/((double)(jmax - jmin));
dy_e = max/((double)(jmax - jmin));
dy_phase = 1.0/((double)(jmax - jmin));
for (j = jmin; j < jmax; j++)
{
@ -4229,11 +4640,13 @@ void draw_color_scheme(double x1, double y1, double x2, double y2, int plot, dou
}
case (P_TOTAL_ENERGY_FLUX):
{
value = min + 1.0*dy*(double)(j - jmin);
amp = 0.7*color_amplitude_linear(value, 1.0, 1);
while (amp > 1.0) amp -= 2.0;
while (amp < -1.0) amp += 2.0;
amp_to_rgb(0.5*(1.0 + amp), rgb);
// value = min + 1.0*dy*(double)(j - jmin);
// amp = 0.7*color_amplitude_linear(value, 1.0, 1);
// while (amp > 1.0) amp -= 2.0;
// while (amp < -1.0) amp += 2.0;
// amp_to_rgb(0.5*(1.0 + amp), rgb);
value = dy_phase*(double)(j - jmin);
color_scheme_palette(C_ONEDIM_LINEAR, COLOR_PALETTE, value, 1.0, 1, rgb);
break;
}
case (P_PHASE):
@ -4277,7 +4690,7 @@ void draw_color_scheme(double x1, double y1, double x2, double y2, int plot, dou
void draw_color_scheme_palette(double x1, double y1, double x2, double y2, int plot, double min, double max, int palette)
{
int j, k, ij_botleft[2], ij_topright[2], imin, imax, jmin, jmax;
double y, dy, dy_e, rgb[3], value, lum, amp;
double y, dy, dy_e, rgb[3], value, lum, amp, dy_phase;
xy_to_ij(x1, y1, ij_botleft);
xy_to_ij(x2, y2, ij_topright);
@ -4304,6 +4717,7 @@ void draw_color_scheme_palette(double x1, double y1, double x2, double y2, int p
glBegin(GL_QUADS);
dy = (max - min)/((double)(jmax - jmin));
dy_e = max/((double)(jmax - jmin));
dy_phase = 1.0/((double)(jmax - jmin));
for (j = jmin; j < jmax; j++)
{
@ -4356,11 +4770,13 @@ void draw_color_scheme_palette(double x1, double y1, double x2, double y2, int p
}
case (P_TOTAL_ENERGY_FLUX):
{
value = min + 1.0*dy*(double)(j - jmin);
amp = 0.7*color_amplitude_linear(value, 1.0, 1);
while (amp > 1.0) amp -= 2.0;
while (amp < -1.0) amp += 2.0;
amp_to_rgb(0.5*(1.0 + amp), rgb);
// value = min + 1.0*dy*(double)(j - jmin);
// amp = 0.7*color_amplitude_linear(value, 1.0, 1);
// while (amp > 1.0) amp -= 2.0;
// while (amp < -1.0) amp += 2.0;
// amp_to_rgb(0.5*(1.0 + amp), rgb);
value = dy_phase*(double)(j - jmin);
color_scheme_palette(C_ONEDIM_LINEAR, palette, value, 1.0, 1, rgb);
break;
}
case (P_PHASE):
@ -4404,7 +4820,7 @@ void draw_color_scheme_palette(double x1, double y1, double x2, double y2, int p
void draw_color_scheme_palette_fade(double x1, double y1, double x2, double y2, int plot, double min, double max, int palette, int fade, double fade_value)
{
int j, k, ij_botleft[2], ij_topright[2], imin, imax, jmin, jmax;
double y, dy, dy_e, rgb[3], value, lum, amp;
double y, dy, dy_e, rgb[3], value, lum, amp, dy_phase;
xy_to_ij(x1, y1, ij_botleft);
xy_to_ij(x2, y2, ij_topright);
@ -4431,6 +4847,7 @@ void draw_color_scheme_palette_fade(double x1, double y1, double x2, double y2,
glBegin(GL_QUADS);
dy = (max - min)/((double)(jmax - jmin));
dy_e = max/((double)(jmax - jmin));
dy_phase = 1.0/((double)(jmax - jmin));
for (j = jmin; j < jmax; j++)
{
@ -4484,11 +4901,13 @@ void draw_color_scheme_palette_fade(double x1, double y1, double x2, double y2,
}
case (P_TOTAL_ENERGY_FLUX):
{
value = min + 1.0*dy*(double)(j - jmin);
amp = 0.7*color_amplitude_linear(value, 1.0, 1);
while (amp > 1.0) amp -= 2.0;
while (amp < -1.0) amp += 2.0;
amp_to_rgb(0.5*(1.0 + amp), rgb);
// value = min + 1.0*dy*(double)(j - jmin);
// amp = 0.7*color_amplitude_linear(value, 1.0, 1);
// while (amp > 1.0) amp -= 2.0;
// while (amp < -1.0) amp += 2.0;
// amp_to_rgb(0.5*(1.0 + amp), rgb);
value = dy_phase*(double)(j - jmin);
color_scheme_palette(C_ONEDIM_LINEAR, palette, value, 1.0, 1, rgb);
break;
}
case (P_PHASE):
@ -4505,19 +4924,55 @@ void draw_color_scheme_palette_fade(double x1, double y1, double x2, double y2,
amp_to_rgb(0.5*(1.0 + amp), rgb);
break;
}
case (50): /* to fix: put #define in correct file */
case (Z_EULER_VORTICITY):
{
value = min + 1.0*dy*(double)(j - jmin);
color_scheme_palette(COLOR_SCHEME, palette, 0.7*value, 1.0, 0, rgb);
break;
}
case (51):
case (Z_EULER_LOG_VORTICITY):
{
value = min + 1.0*dy*(double)(j - jmin);
color_scheme_palette(COLOR_SCHEME, palette, 0.7*value, 1.0, 0, rgb);
break;
}
case (52): /* to fix: put #define in correct file */
case (Z_EULER_VORTICITY_ASYM):
{
value = min + 1.0*dy*(double)(j - jmin);
color_scheme_palette(COLOR_SCHEME, palette, 0.7*value, 1.0, 0, rgb);
break;
}
case (Z_EULER_LPRESSURE):
{
value = min + 1.0*dy*(double)(j - jmin);
color_scheme_palette(COLOR_SCHEME, palette, 0.7*value, 1.0, 0, rgb);
break;
}
case (Z_EULER_PRESSURE):
{
value = min + 1.0*dy*(double)(j - jmin);
color_scheme_palette(COLOR_SCHEME, palette, 0.7*value, 1.0, 0, rgb);
break;
}
case (Z_EULER_DENSITY):
{
value = min + 1.0*dy*(double)(j - jmin);
color_scheme_palette(COLOR_SCHEME, palette, 0.7*value, 1.0, 0, rgb);
break;
}
case (Z_EULER_SPEED):
{
value = min + 1.0*dy*(double)(j - jmin);
color_scheme_palette(COLOR_SCHEME, palette, 0.7*value, 1.0, 0, rgb);
break;
}
case (Z_EULERC_VORTICITY):
{
value = min + 1.0*dy*(double)(j - jmin);
color_scheme_palette(COLOR_SCHEME, palette, 0.7*value, 1.0, 0, rgb);
break;
}
default:
{
value = min + 1.0*dy*(double)(j - jmin);
color_scheme_palette(COLOR_SCHEME, palette, 0.7*value, 1.0, 0, rgb);

View File

@ -961,9 +961,9 @@ void draw_billiard_3d_front(int fade, double fade_value)
void compute_energy_field(double phi[NX*NY], double psi[NX*NY], short int xy_in[NX*NY], t_wave wave[NX*NY])
/* computes cosine of angle between normal vector and vector light */
{
int i, j;
int i, j, k;
static int first = 1;
double energy, logenergy;
double energy, logenergy, gx, gy, arg, mod, sum;
// printf("computing energy field\n");
// printf("COMPUTE_MEAN_ENERGY = %i\n", COMPUTE_MEAN_ENERGY);
@ -1008,6 +1008,20 @@ void compute_energy_field(double phi[NX*NY], double psi[NX*NY], short int xy_in[
if (logenergy > LOG_ENERGY_FLOOR) wave[i*NY+j].log_mean_energy = LOG_SHIFT + PLOT_SCALE_LOG_ENERGY*logenergy;
else wave[i*NY+j].mean_energy = LOG_SHIFT + PLOT_SCALE_LOG_ENERGY*LOG_ENERGY_FLOOR;
}
if (COMPUTE_ENERGY_FLUX)
{
compute_energy_flux_mod(phi, psi, xy_in, i, j, &gx, &gy, &arg, &mod);
wave[i*NY+j].flux_direction = arg/DPI;
/* compute time-averaged flux intensity */
wave[i*NY+j].flux_int_table[wave[i*NY+j].flux_counter] = mod*FLUX_SCALE;
sum = 0.0;
for (k = 0; k < FLUX_WINDOW; k++) sum += wave[i*NY+j].flux_int_table[k];
wave[i*NY+j].flux_intensity = sum/(double)FLUX_WINDOW;
wave[i*NY+j].flux_counter++;
if (wave[i*NY+j].flux_counter == FLUX_WINDOW) wave[i*NY+j].flux_counter = 0;
}
}
else if (first)
{
@ -1016,6 +1030,8 @@ void compute_energy_field(double phi[NX*NY], double psi[NX*NY], short int xy_in[
wave[i*NY+j].log_total_energy = LOG_ENERGY_FLOOR;
wave[i*NY+j].mean_energy = 0.0;
wave[i*NY+j].log_mean_energy = LOG_ENERGY_FLOOR;
wave[i*NY+j].flux_intensity = 0.0;
wave[i*NY+j].flux_direction = 0.0;
}
}
@ -1099,9 +1115,12 @@ void compute_light_angle(short int xy_in[NX*NY], t_wave wave[NX*NY], int movie)
}
void compute_field_color(double value, int cplot, int palette, double rgb[3])
void compute_field_color(double value, double value2, int cplot, int palette, double rgb[3])
/* compute the color depending on the field value and color palette */
/* value2 is only used for flux representation */
{
int k;
switch (cplot) {
case (P_3D_AMP_ANGLE):
{
@ -1110,7 +1129,7 @@ void compute_field_color(double value, int cplot, int palette, double rgb[3])
}
case (P_3D_ENERGY):
{
if (COLOR_PALETTE >= COL_TURBO) color_scheme_asym_palette(COLOR_SCHEME, palette, value, 1.0, 0, rgb);
if (COLOR_PALETTE >= COL_TURBO) color_scheme_asym_palette(COLOR_SCHEME, palette, VSCALE_ENERGY*value, 1.0, 0, rgb);
else color_scheme_palette(COLOR_SCHEME, palette, value, 1.0, 0, rgb);
break;
}
@ -1121,7 +1140,7 @@ void compute_field_color(double value, int cplot, int palette, double rgb[3])
}
case (P_3D_TOTAL_ENERGY):
{
if (COLOR_PALETTE >= COL_TURBO) color_scheme_asym_palette(COLOR_SCHEME, palette, value, 1.0, 0, rgb);
if (COLOR_PALETTE >= COL_TURBO) color_scheme_asym_palette(COLOR_SCHEME, palette, VSCALE_ENERGY*value, 1.0, 0, rgb);
else color_scheme_palette(COLOR_SCHEME, palette, value, 1.0, 0, rgb);
break;
}
@ -1132,7 +1151,7 @@ void compute_field_color(double value, int cplot, int palette, double rgb[3])
}
case (P_3D_MEAN_ENERGY):
{
if (COLOR_PALETTE >= COL_TURBO) color_scheme_asym_palette(COLOR_SCHEME, palette, value, 1.0, 0, rgb);
if (COLOR_PALETTE >= COL_TURBO) color_scheme_asym_palette(COLOR_SCHEME, palette, VSCALE_ENERGY*value, 1.0, 0, rgb);
else color_scheme_palette(COLOR_SCHEME, palette, value, 1.0, 0, rgb);
break;
}
@ -1146,16 +1165,27 @@ void compute_field_color(double value, int cplot, int palette, double rgb[3])
amp_to_rgb_palette(value, rgb, palette);
break;
}
case (P_3D_FLUX_INTENSITY):
{
color_scheme_asym_palette(COLOR_SCHEME, palette, value*FLUX_SCALE, 1.0, 0, rgb);
break;
}
case (P_3D_FLUX_DIRECTION):
{
amp_to_rgb_palette(value, rgb, palette);
for (k=0; k<3; k++) rgb[k] *= tanh(value2*FLUX_CSCALE);
break;
}
}
}
double compute_interpolated_colors_wave(int i, int j, short int xy_in[NX*NY], t_wave wave[NX*NY], double palette, int cplot,
double rgb_e[3], double rgb_w[3], double rgb_n[3], double rgb_s[3],
int fade, double fade_value, int movie)
double compute_interpolated_colors_wave(int i, int j, short int xy_in[NX*NY], t_wave wave[NX*NY],
double palette, int cplot, double rgb_e[3], double rgb_w[3], double rgb_n[3], double rgb_s[3], int fade, double fade_value, int movie)
{
int k;
double cw, ce, cn, cs, c_sw, c_se, c_nw, c_ne, c_mid, ca, z_mid;
double cw2, ce2, cn2, cs2;
double *z_sw, *z_se, *z_nw, *z_ne;
z_sw = wave[i*NY+j].p_zfield[movie];
@ -1177,10 +1207,26 @@ double compute_interpolated_colors_wave(int i, int j, short int xy_in[NX*NY], t_
cs = (c_sw + c_se + c_mid)/3.0;
cn = (c_nw + c_ne + c_mid)/3.0;
compute_field_color(ce, cplot, palette, rgb_e);
compute_field_color(cw, cplot, palette, rgb_w);
compute_field_color(cn, cplot, palette, rgb_n);
compute_field_color(cs, cplot, palette, rgb_s);
/* data for second color parameter */
if (CHANGE_LUMINOSITY)
{
c_sw = *wave[i*NY+j].p_cfield[movie+2];
c_se = *wave[(i+1)*NY+j].p_cfield[movie+2];
c_nw = *wave[i*NY+j+1].p_cfield[movie+2];
c_ne = *wave[(i+1)*NY+j+1].p_cfield[movie+2];
c_mid = 0.25*(c_sw + c_se + c_nw + c_ne);
cw2 = (c_sw + c_nw + c_mid)/3.0;
ce2 = (c_se + c_ne + c_mid)/3.0;
cs2 = (c_sw + c_se + c_mid)/3.0;
cn2 = (c_nw + c_ne + c_mid)/3.0;
}
compute_field_color(ce, ce2, cplot, palette, rgb_e);
compute_field_color(cw, cw2, cplot, palette, rgb_w);
compute_field_color(cn, cn2, cplot, palette, rgb_n);
compute_field_color(cs, cs2, cplot, palette, rgb_s);
if (SHADE_3D)
{
@ -1229,9 +1275,9 @@ void compute_wave_fields(double phi[NX*NY], double psi[NX*NY], short int xy_in[N
void init_speed_dissipation(short int xy_in[NX*NY], double tc[NX*NY], double tcc[NX*NY], double tgamma[NX*NY])
/* initialise fields for wave speed and dissipation */
{
int i, j, k;
double courant2 = COURANT*COURANT, courantb2 = COURANTB*COURANTB;
double u, v, u1, x, y, xy[2], norm2, speed, r2, c;
int i, j, k, inlens;
double courant2 = COURANT*COURANT, courantb2 = COURANTB*COURANTB, lambda1, mu1;
double u, v, u1, x, y, xy[2], norm2, speed, r2, c, salpha, h, ll, ca, sa, x1, y1;
if (VARIABLE_IOR)
{
@ -1327,6 +1373,47 @@ void init_speed_dissipation(short int xy_in[NX*NY], double tc[NX*NY], double tcc
}
break;
}
case (IOR_EXPLO_LENSING):
{
salpha = DPI/(double)NPOLY;
// lambda1 = LAMBDA;
// mu1 = LAMBDA;
lambda1 = 0.5*LAMBDA;
mu1 = 0.5*LAMBDA;
h = lambda1*tan(PI/(double)NPOLY);
if (h < mu1) ll = sqrt(mu1*mu1 - h*h);
else ll = 0.0;
// #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]) {
ij_to_xy(i, j, xy);
x = xy[0];
y = xy[1];
inlens = 0;
for (k=0; k<NPOLY; k++)
{
ca = cos(((double)k+0.5)*salpha + APOLY*PID);
sa = sin(((double)k+0.5)*salpha + APOLY*PID);
x1 = x*ca + y*sa;
y1 = -x*sa + y*ca;
if ((module2(x1 - lambda1 - ll, y1) < mu1)&&(module2(x1 - lambda1 + ll, y1) < mu1)) inlens = 1;
}
if (inlens) c = COURANTB;
else c = COURANT;
tc[i*NY+j] = c;
tcc[i*NY+j] = c*c;
tgamma[i*NY+j] = GAMMA;
}
else
{
tc[i*NY+j] = 0.0;
tcc[i*NY+j] = 0.0;
tgamma[i*NY+j] = 0.0;
}
}
break;
}
default:
{
for (i=0; i<NX; i++){
@ -1417,6 +1504,18 @@ void init_zfield(double phi[NX*NY], double psi[NX*NY], short int xy_in[NX*NY], i
for (i=0; i<NX; i++) for (j=0; j<NY; j++) wave[i*NY+j].p_zfield[movie] = &wave[i*NY+j].phase;
break;
}
case (P_3D_FLUX_INTENSITY):
{
#pragma omp parallel for private(i,j)
for (i=0; i<NX; i++) for (j=0; j<NY; j++) wave[i*NY+j].p_zfield[movie] = &wave[i*NY+j].flux_intensity;
break;
}
case (P_3D_FLUX_DIRECTION):
{
#pragma omp parallel for private(i,j)
for (i=0; i<NX; i++) for (j=0; j<NY; j++) wave[i*NY+j].p_zfield[movie] = &wave[i*NY+j].flux_direction;
break;
}
}
}
@ -1474,6 +1573,30 @@ void init_cfield(double phi[NX*NY], double psi[NX*NY], short int xy_in[NX*NY], i
for (i=0; i<NX; i++) for (j=0; j<NY; j++) wave[i*NY+j].p_cfield[movie] = &wave[i*NY+j].phase;
break;
}
case (P_3D_FLUX_INTENSITY):
{
#pragma omp parallel for private(i,j)
for (i=0; i<NX; i++) for (j=0; j<NY; j++) wave[i*NY+j].p_cfield[movie] = &wave[i*NY+j].flux_intensity;
break;
}
case (P_3D_FLUX_DIRECTION):
{
#pragma omp parallel for private(i,j)
for (i=0; i<NX; i++) for (j=0; j<NY; j++)
{
wave[i*NY+j].p_cfield[movie] = &wave[i*NY+j].flux_direction;
wave[i*NY+j].p_cfield[movie+2] = &wave[i*NY+j].flux_intensity;
/* information on intensity stored in second pointer to adjust luminosity */
}
break;
}
}
if (cplot != P_3D_FLUX_DIRECTION)
{
#pragma omp parallel for private(i,j)
for (i=0; i<NX; i++) for (j=0; j<NY; j++)
wave[i*NY+j].p_cfield[movie+2] = wave[i*NY+j].p_cfield[movie];
}
}
@ -1487,7 +1610,7 @@ void compute_cfield(short int xy_in[NX*NY], int cplot, int palette, t_wave wave[
#pragma omp parallel for private(i,j,ca)
for (i=0; i<NX; i++) for (j=0; j<NY; j++)
{
compute_field_color(*wave[i*NY+j].p_cfield[movie], cplot, palette, wave[i*NY+j].rgb);
compute_field_color(*wave[i*NY+j].p_cfield[movie], *wave[i*NY+j].p_cfield[movie+2], cplot, palette, wave[i*NY+j].rgb);
if (SHADE_3D)
{
ca = wave[i*NY+j].cos_angle;
@ -1613,8 +1736,7 @@ void draw_wave_3d_ij(int i, int j, int movie, double phi[NX*NY], double psi[NX*N
}
void draw_wave_3d(int movie, double phi[NX*NY], double psi[NX*NY], short int xy_in[NX*NY], t_wave wave[NX*NY],
int zplot, int cplot, int palette, int fade, double fade_value, int refresh)
void draw_wave_3d(int movie, double phi[NX*NY], double psi[NX*NY], short int xy_in[NX*NY], t_wave wave[NX*NY], int zplot, int cplot, int palette, int fade, double fade_value, int refresh)
{
int i, j;
double observer_angle;
@ -1671,12 +1793,14 @@ void draw_wave_3d(int movie, double phi[NX*NY], double psi[NX*NY], short int xy_
if (DRAW_BILLIARD_FRONT) draw_billiard_3d_front(fade, fade_value);
}
void draw_color_scheme_palette_3d(double x1, double y1, double x2, double y2, int plot, double min, double max,
int palette, int fade, double fade_value)
void draw_color_scheme_palette_3d(double x1, double y1, double x2, double y2, int plot,
double min, double max, int palette, int fade, double fade_value)
{
int j, k, ij_botleft[2], ij_topright[2], imin, imax, jmin, jmax;
double y, dy, dy_e, dy_phase, rgb[3], value, lum, amp;
printf("Drawing color bar\n");
xy_to_ij(x1, y1, ij_botleft);
xy_to_ij(x2, y2, ij_topright);
@ -1770,6 +1894,19 @@ void draw_color_scheme_palette_3d(double x1, double y1, double x2, double y2, in
color_scheme_palette(C_ONEDIM_LINEAR, palette, value, 1.0, 1, rgb);
break;
}
case (P_3D_FLUX_INTENSITY):
{
value = dy_e*(double)(j - jmin)*100.0/E_SCALE;
if (COLOR_PALETTE >= COL_TURBO) color_scheme_asym_palette(COLOR_SCHEME, palette, value, 1.0, 1, rgb);
else color_scheme_palette(COLOR_SCHEME, palette, value, 1.0, 1, rgb);
break;
}
case (P_3D_FLUX_DIRECTION):
{
value = 2.0*dy_phase*(double)(j - jmin);
color_scheme_palette(C_ONEDIM_LINEAR, palette, value, 1.0, 1, rgb);
break;
}
case (Z_EULER_VORTICITY):
{
value = min + 1.0*dy*(double)(j - jmin);
@ -1788,6 +1925,20 @@ void draw_color_scheme_palette_3d(double x1, double y1, double x2, double y2, in
color_scheme_palette(COLOR_SCHEME, palette, 0.7*value, 1.0, 0, rgb);
break;
}
case (Z_EULER_LPRESSURE):
{
value = min + 1.0*dy*(double)(j - jmin);
color_scheme_palette(COLOR_SCHEME, palette, 0.7*value, 1.0, 0, rgb);
break;
}
case (Z_EULERC_VORTICITY):
{
value = min + 1.0*dy*(double)(j - jmin);
printf("Palette value %.3lg\n", value);
color_scheme_palette(COLOR_SCHEME, palette, 0.7*value, 1.0, 0, rgb);
break;
}
}
if (fade) for (k=0; k<3; k++) rgb[k] *= fade_value;
glColor3f(rgb[0], rgb[1], rgb[2]);
@ -1837,3 +1988,18 @@ void print_speed_3d(double speed, int fade, double fade_value)
write_text(xlefttext + 0.28, y, message);
}
void init_wave_fields(t_wave wave[NX*NY])
/* initialize some auxiliary fields */
{
int i, k;
#pragma omp parallel for private(i)
for (i=0; i<NX*NY; i++)
{
wave[i].total_energy = 0.0;
wave[i].flux_counter = 0;
for (k=0; k<FLUX_WINDOW; k++)
wave[i].flux_int_table[k] = 0.0;
}
}

View File

@ -1491,6 +1491,18 @@ void draw_color_scheme_palette_3d(double x1, double y1, double x2, double y2, in
color_scheme_palette(COLOR_SCHEME, palette, 0.7*value, 1.0, 0, rgb);
break;
}
case (Z_EULER_LPRESSURE):
{
value = min + 1.0*dy*(double)(j - jmin);
color_scheme_palette(COLOR_SCHEME, palette, 0.7*value, 1.0, 0, rgb);
break;
}
default:
{
value = min + 1.0*dy*(double)(j - jmin);
color_scheme_palette(COLOR_SCHEME, palette, 0.7*value, 1.0, 0, rgb);
break;
}
}
if (fade) for (k=0; k<3; k++) rgb[k] *= fade_value;
glColor3f(rgb[0], rgb[1], rgb[2]);

206
wave_3d.c
View File

@ -43,49 +43,59 @@
#include <omp.h>
#include <time.h>
#define MOVIE 0 /* set to 1 to generate movie */
#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 */
#define SAVE_MEMORY 0 /* set to 1 to save memory when writing tiff images */
#define SAVE_MEMORY 1 /* set to 1 to save memory when writing tiff images */
#define NO_EXTRA_BUFFER_SWAP 1 /* some OS require one less buffer swap when recording images */
/* General geometrical parameters */
#define WINWIDTH 1920 /* window width */
#define WINHEIGHT 1000 /* window height */
#define NX 2500 /* number of grid points on x axis */
#define NY 1250 /* number of grid points on y axis */
// #define NX 2700 /* number of grid points on x axis */
// #define NY 1350 /* number of grid points on y axis */
// #define WINWIDTH 1920 /* window width */
// #define WINHEIGHT 1150 /* window height */
// // // // #define NX 2500 /* number of grid points on x axis */
// // // // #define NY 1250 /* number of grid points on y axis */
// #define NX 1800 /* number of grid points on x axis */
// #define NY 1800 /* number of grid points on y axis */
// // #define NX 2700 /* number of grid points on x axis */
// // #define NY 1350 /* 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.0
// #define XMAX 2.0 /* x interval */
// #define YMIN -1.041666667
// #define YMAX 1.041666667 /* y interval for 9/16 aspect ratio */
#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 */
// #define WINWIDTH 1280 /* window width */
// #define WINHEIGHT 720 /* window height */
//
// // #define NX 1280 /* number of grid points on x axis */
// // #define NY 720 /* number of grid points on y axis */
// #define NX 1280 /* number of grid points on x axis */
#define NX 720 /* number of grid points on x axis */
#define NY 720 /* number of grid points on y axis */
// #define NX 2560 /* number of grid points on x axis */
// #define NX 1440 /* number of grid points on x axis */
// #define NY 1440 /* 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 360 /* 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
// #define YMAX 1.125 /* y interval for 9/16 aspect ratio */
#define XMIN -1.1
#define XMAX 1.1 /* x interval */
#define YMIN -1.1
#define YMAX 1.1 /* y interval */
#define JULIA_SCALE 0.8 /* scaling for Julia sets */
/* Choice of the billiard table */
#define B_DOMAIN 57 /* choice of domain shape, see list in global_pdes.c */
#define B_DOMAIN 32 /* 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 2 /* pattern of circles or polygons, see list in global_pdes.c */
@ -93,18 +103,18 @@
#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 2 /* choice of index of refraction, see list in global_pdes.c */
#define VARIABLE_IOR 1 /* set to 1 for a variable index of refraction */
#define IOR 3 /* 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 1 /* set to 1 to randomize angle of polygons */
#define LAMBDA 0.25 /* parameter controlling the dimensions of domain */
#define MU 0.0 /* 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 LAMBDA 0.75 /* parameter controlling the dimensions of domain */
#define MU 0.25 /* parameter controlling the dimensions of domain */
#define NPOLY 6 /* number of sides of polygon */
#define APOLY 0.0 /* angle by which to turn polygon, in units of Pi/2 */
#define MDEPTH 7 /* depth of computation of Menger gasket */
#define MRATIO 3 /* ratio defining Menger gasket */
#define MANDELLEVEL 1000 /* iteration level for Mandelbrot set */
@ -130,7 +140,7 @@
/* Physical parameters of wave equation */
#define TWOSPEEDS 1 /* set to 1 to replace hardcore boundary by medium with different speed */
#define TWOSPEEDS 0 /* set to 1 to replace hardcore boundary by medium with different speed */
#define OSCILLATE_LEFT 0 /* set to 1 to add oscilating boundary condition on the left */
#define OSCILLATE_TOPBOT 0 /* set to 1 to enforce a planar wave on top and bottom boundary */
#define OSCILLATION_SCHEDULE 3 /* oscillation schedule, see list in global_pdes.c */
@ -140,8 +150,9 @@
#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 COURANT 0.05 /* Courant number */
#define COURANTB 0.1 /* Courant number in medium B */
#define COURANT 0.1 /* Courant number */
// #define COURANTB 0.0 /* Courant number in medium B */
#define COURANTB 0.04658753 /* 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 */
@ -156,7 +167,7 @@
#define ADD_OSCILLATING_SOURCE 1 /* set to 1 to add an oscillating wave source */
#define OSCILLATING_SOURCE_PERIOD 100 /* period of oscillating source */
#define ALTERNATE_OSCILLATING_SOURCE 1 /* set to 1 to alternate sign of oscillating source */
#define ALTERNATE_OSCILLATING_SOURCE 0 /* set to 1 to alternate sign of oscillating source */
/* Boundary conditions, see list in global_pdes.c */
@ -167,16 +178,16 @@
/* Parameters for length and speed of simulation */
#define NSTEPS 1400 /* number of frames of movie */
// #define NSTEPS 250 /* number of frames of movie */
#define NVID 5 /* number of iterations between images displayed on screen */
#define NSTEPS 2800 /* number of frames of movie */
// #define NSTEPS 200 /* number of frames of movie */
#define NVID 6 /* 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 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 */
#define PSLEEP 3 /* sleep time during pause */
#define SLEEP1 1 /* initial sleeping time */
#define SLEEP2 1 /* final sleeping time */
#define MID_FRAMES 100 /* number of still frames between parts of two-part movie */
@ -186,31 +197,41 @@
/* Parameters of initial condition */
#define INITIAL_AMP 0.25 /* amplitude of initial condition */
#define INITIAL_VARIANCE 0.0005 /* variance of initial condition */
// #define INITIAL_AMP 0.25 /* amplitude of initial condition */
// #define INITIAL_VARIANCE 0.001 /* variance of initial condition */
// #define INITIAL_WAVELENGTH 0.1 /* wavelength of initial condition */
#define INITIAL_AMP 0.3 /* amplitude of initial condition */
#define INITIAL_VARIANCE 0.0004 /* variance of initial condition */
#define INITIAL_WAVELENGTH 0.02 /* wavelength of initial condition */
// #define INITIAL_AMP 0.35 /* amplitude of initial condition */
// #define INITIAL_VARIANCE 0.0002 /* variance of initial condition */
// #define INITIAL_WAVELENGTH 0.01 /* wavelength of initial condition */
/* Plot type, see list in global_pdes.c */
#define ZPLOT 103 /* wave height */
#define CPLOT 103 /* color scheme */
// #define ZPLOT 103 /* wave height */
// #define CPLOT 103 /* color scheme */
#define ZPLOT 104 /* wave height */
#define CPLOT 104 /* color scheme */
#define ZPLOT_B 107
#define CPLOT_B 107 /* plot type for second movie */
#define ZPLOT_B 108
#define CPLOT_B 108 /* plot type for second movie */
#define CHANGE_LUMINOSITY 1 /* set to 1 to let luminosity depend on energy flux intensity */
#define FLUX_WINDOW 30 /* size of averaging window of flux intensity */
#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 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 1 /* set to 1 to draw front of boundary after drawing wave */
#define DRAW_BILLIARD 0 /* 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.01 /* vertical scaling in energy plot */
#define PLOT_SCALE_LOG_ENERGY 0.25 /* vertical scaling in log energy plot */
#define PLOT_SCALE_LOG_ENERGY 0.2 /* vertical scaling in log energy plot */
/* 3D representation */
@ -220,21 +241,22 @@
#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 360.0 /* total angle of rotation during simulation */
#define ROTATE_ANGLE 540.0 /* total angle of rotation during simulation */
// #define ROTATE_ANGLE 45.0 /* total angle of rotation during simulation */
/* Color schemes */
#define COLOR_PALETTE 10 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE_B 14 /* Color palette, see list in global_pdes.c */
#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 BLACK 1 /* background */
#define COLOR_SCHEME 3 /* choice of color scheme, see list in global_pdes.c */
#define SCALE 0 /* set to 1 to adjust color scheme to variance of field */
#define SLOPE 1.0 /* sensitivity of color on wave amplitude */
#define 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 100.0 /* additional scaling factor for color scheme P_3D_ENERGY */
#define VSCALE_ENERGY 30.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 */
@ -243,7 +265,8 @@
#define LOG_SHIFT 0.5 /* shift of colors on log scale */
#define LOG_ENERGY_FLOOR -10.0 /* floor value for log of (total) energy */
#define LOG_MEAN_ENERGY_SHIFT 1.0 /* additional shift for log of mean energy */
#define FLUX_SCALE 1.0e4 /* scaling factor for enegy flux represtnation */
#define FLUX_SCALE 20.0 /* scaling factor for energy flux representation */
#define FLUX_CSCALE 500.0 /* scaling factor for color in energy flux representation */
#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 */
@ -253,15 +276,15 @@
#define HUEMEAN 240.0 /* mean value of hue for color scheme C_HUE */
#define HUEAMP -200.0 /* amplitude of variation of hue for color scheme C_HUE */
#define NXMAZE 7 /* width of maze */
#define NYMAZE 7 /* height of maze */
#define MAZE_MAX_NGBH 4 /* max number of neighbours of maze cell */
#define RAND_SHIFT 24 /* seed of random number generator */
#define NXMAZE 8 /* width of maze */
#define NYMAZE 32 /* height of maze */
#define MAZE_MAX_NGBH 5 /* max number of neighbours of maze cell */
#define RAND_SHIFT 5 /* seed of random number generator */
#define MAZE_XSHIFT 0.0 /* horizontal shift of maze */
#define DRAW_COLOR_SCHEME 1 /* set to 1 to plot the color scheme */
#define COLORBAR_RANGE 3.5 /* scale of color scheme bar */
#define COLORBAR_RANGE_B 3.0 /* scale of color scheme bar for 2nd part */
#define COLORBAR_RANGE 6.0 /* scale of color scheme bar */
#define COLORBAR_RANGE_B 6.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 */
@ -283,11 +306,11 @@ 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, 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.3 /* overall scaling factor of z axis for REP_PROJ_3D representation */
#define XY_SCALING_FACTOR 2.4 /* overall scaling factor for on-screen (x,y) coordinates after projection */
#define Z_SCALING_FACTOR 0.25 /* overall scaling factor of z axis for REP_PROJ_3D representation */
#define XY_SCALING_FACTOR 2.0 /* 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.1 /* overall y shift for REP_PROJ_3D representation */
@ -892,9 +915,12 @@ void evolve_wave(double phi[NX*NY], double psi[NX*NY], double tmp[NX*NY], short
void draw_color_bar_palette(int plot, double range, int palette, int fade, double fade_value)
{
double width = 0.14;
double width = 0.1;
// double width = 0.14;
// double width = 0.2;
width *= (double)NX/(double)WINWIDTH;
if (ROTATE_COLOR_SCHEME)
draw_color_scheme_palette_3d(-1.0, -0.8, XMAX - 0.1, -1.0, plot, -range, range, palette, fade, fade_value);
else
@ -926,8 +952,9 @@ void viewpoint_schedule(int i)
void animation()
{
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;
double time, scale, ratio, startleft[2], startright[2], sign = 1.0, r2, xy[2], fade_value, yshift, speed = 0.0, a, b, c, angle, lambda1;
double *phi, *psi, *tmp, *color_scale, *tc, *tcc, *tgamma;
// double *total_energy;
short int *xy_in;
int i, j, s, sample_left[2], sample_right[2], period = 0, fade;
static int counter = 0;
@ -946,7 +973,7 @@ void animation()
phi = (double *)malloc(NX*NY*sizeof(double));
psi = (double *)malloc(NX*NY*sizeof(double));
tmp = (double *)malloc(NX*NY*sizeof(double));
total_energy = (double *)malloc(NX*NY*sizeof(double));
// total_energy = (double *)malloc(NX*NY*sizeof(double));
color_scale = (double *)malloc(NX*NY*sizeof(double));
tc = (double *)malloc(NX*NY*sizeof(double));
tcc = (double *)malloc(NX*NY*sizeof(double));
@ -985,6 +1012,10 @@ void animation()
npolyrect = init_polyrect(polyrect);
for (i=0; i<npolyrect; i++) printf("polyrect vertex %i: (%.3f, %.3f) - (%.3f, %.3f)\n", i, polyrect[i].x1, polyrect[i].y1, polyrect[i].x2, polyrect[i].y2);
init_polyrect_arc(polyrectrot, polyarc, &npolyrect_rot, &npolyarc);
printf("Rotated rectangles and arcs initialized\n");
printf("%i rotated rectangles, %i arcs\n", npolyrect_rot, npolyarc);
courant2 = COURANT*COURANT;
courantb2 = COURANTB*COURANTB;
c = COURANT*(XMAX - XMIN)/(double)NX;
@ -1018,17 +1049,26 @@ void animation()
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))
for (i=0; i<NX; i++)
for (j=0; j<NY; j++)
total_energy[i*NY+j] = 0.0;
init_wave_fields(wave);
/* initialize total energy table - no longer needed */
// if ((ZPLOT == P_MEAN_ENERGY)||(ZPLOT_B == P_MEAN_ENERGY)||(ZPLOT == P_LOG_MEAN_ENERGY)||(ZPLOT_B == P_LOG_MEAN_ENERGY))
// for (i=0; i<NX; i++)
// for (j=0; j<NY; j++)
// total_energy[i*NY+j] = 0.0;
ratio = (XMAX - XMIN)/8.4; /* for Tokarsky billiard */
// init_circular_wave_mod(polyline[85].x, polyline[85].y, phi, psi, xy_in);
init_circular_wave_mod(0.0, 0.0, phi, psi, xy_in);
// init_circular_wave_mod(LAMBDA*cos(APOLY*PID), LAMBDA*sin(APOLY*PID), phi, psi, xy_in);
lambda1 = LAMBDA;
angle = DPI/(double)NPOLY;
init_circular_wave_mod(lambda1*cos(0.5*angle), lambda1*sin(0.5*angle), phi, psi, xy_in);
for (j=1; j<NPOLY; j++)
add_circular_wave_mod(1.0, lambda1*cos(((double)j+0.5)*angle), lambda1*sin(((double)j+0.5)*angle), 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);
@ -1110,7 +1150,8 @@ void animation()
// 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);
// yshift = (double)period*a + (double)(period*period)*b;
if (ALTERNATE_OSCILLATING_SOURCE) sign = -sign;
add_circular_wave_mod(sign, 0.0, 0.0, phi, psi, xy_in);
for (j=0; j<NPOLY; j++)
add_circular_wave_mod(sign, lambda1*cos(((double)j+0.5)*angle), lambda1*sin(((double)j+0.5)*angle), 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));
@ -1121,11 +1162,13 @@ void animation()
}
if (PRINT_SPEED) print_speed_3d(speed, 0, 1.0);
glutSwapBuffers();
if (!((NO_EXTRA_BUFFER_SWAP)&&(MOVIE))) glutSwapBuffers();
if (MOVIE)
{
if (i >= INITIAL_TIME) save_frame();
// if (i >= INITIAL_TIME) save_frame_counter(i);
// if (i >= INITIAL_TIME) save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter);
else printf("Initial phase time %i of %i\n", i, INITIAL_TIME);
if ((i >= INITIAL_TIME)&&(DOUBLE_MOVIE))
@ -1135,8 +1178,10 @@ void animation()
if (PRINT_SPEED) print_speed_3d(speed, 0, 1.0);
glutSwapBuffers();
save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter);
// save_frame_counter(i);
counter++;
}
else if (NO_EXTRA_BUFFER_SWAP) glutSwapBuffers();
/* it seems that saving too many files too fast can cause trouble with the file system */
/* so this is to make a pause from time to time - parameter PAUSE may need adjusting */
@ -1172,9 +1217,15 @@ void animation()
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();
if (!NO_EXTRA_BUFFER_SWAP) glutSwapBuffers();
save_frame_counter(NSTEPS + i + 1);
}
if ((ROTATE_VIEW)&&(ROTATE_VIEW_WHILE_FADE))
{
viewpoint_schedule(NSTEPS - INITIAL_TIME);
reset_view = 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);
@ -1201,6 +1252,11 @@ void animation()
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++)
{
if ((ROTATE_VIEW)&&(ROTATE_VIEW_WHILE_FADE))
{
viewpoint_schedule(NSTEPS - INITIAL_TIME + i);
reset_view = 1;
}
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);
@ -1217,7 +1273,7 @@ void animation()
free(phi);
free(psi);
free(tmp);
free(total_energy);
// free(total_energy);
free(color_scale);
free(tc);
free(tcc);

View File

@ -43,24 +43,27 @@
#include <omp.h>
#include <time.h>
#define MOVIE 0 /* set to 1 to generate movie */
#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 */
#define SAVE_MEMORY 0 /* set to 1 to save memory when writing tiff images */
#define SAVE_MEMORY 1 /* set to 1 to save memory when writing tiff images */
#define NO_EXTRA_BUFFER_SWAP 1 /* some OS require one less buffer swap when recording images */
/* General geometrical parameters */
#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 x axis */
#define WINHEIGHT 1150 /* window height */
// // #define NX 1920 /* number of grid points on x axis */
// // #define NY 1000 /* number of grid points on x axis */
#define NX 3840 /* number of grid points on x axis */
#define NY 2000 /* number of grid points on y axis */
#define NY 2300 /* 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 YMIN -1.197916667
#define YMAX 1.197916667 /* y interval for 9/16 aspect ratio */
// #define YMIN -1.041666667
// #define YMAX 1.041666667 /* y interval for 9/16 aspect ratio */
//
#define HIGHRES 1 /* set to 1 if resolution of grid is double that of displayed image */
// #define WINWIDTH 1280 /* window width */
@ -82,7 +85,7 @@
/* Choice of the billiard table */
#define B_DOMAIN 57 /* 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 1 /* pattern of circles or polygons, see list in global_pdes.c */
@ -94,8 +97,8 @@
#define NPOISSON 300 /* number of points for Poisson C_RAND_POISSON arrangement */
#define RANDOM_POLY_ANGLE 1 /* set to 1 to randomize angle of polygons */
#define LAMBDA 0.25 /* parameter controlling the dimensions of domain */
#define MU 0.0 /* parameter controlling the dimensions of domain */
#define LAMBDA 0.5 /* parameter controlling the dimensions of domain */
#define MU 0.5 /* parameter controlling the dimensions of domain */
#define NPOLY 6 /* number of sides of polygon */
#define APOLY 0.0 /* angle by which to turn polygon, in units of Pi/2 */
#define MDEPTH 6 /* depth of computation of Menger gasket */
@ -122,7 +125,7 @@
/* Physical parameters of wave equation */
#define TWOSPEEDS 1 /* set to 1 to replace hardcore boundary by medium with different speed */
#define TWOSPEEDS 0 /* set to 1 to replace hardcore boundary by medium with different speed */
#define OSCILLATE_LEFT 0 /* set to 1 to add oscilating boundary condition on the left */
#define OSCILLATE_TOPBOT 0 /* set to 1 to enforce a planar wave on top and bottom boundary */
#define OSCILLATION_SCHEDULE 1 /* oscillation schedule, see list in global_pdes.c */
@ -131,8 +134,8 @@
#define AMPLITUDE 0.8 /* amplitude 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.1 /* Courant number in medium B */
#define COURANT 0.08 /* Courant number */
#define COURANTB 0.04658753 /* 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 */
@ -146,8 +149,8 @@
/* For similar wave forms, COURANT^2*GAMMA should be kept constant */
#define ADD_OSCILLATING_SOURCE 1 /* set to 1 to add an oscillating wave source */
#define OSCILLATING_SOURCE_PERIOD 50 /* period of oscillating source */
#define ALTERNATE_OSCILLATING_SOURCE 1 /* set to 1 to alternate sign of oscillating source */
#define OSCILLATING_SOURCE_PERIOD 15 /* period of oscillating source */
#define ALTERNATE_OSCILLATING_SOURCE 0 /* set to 1 to alternate sign of oscillating source */
/* Boundary conditions, see list in global_pdes.c */
@ -155,9 +158,10 @@
/* Parameters for length and speed of simulation */
#define NSTEPS 1700 /* number of frames of movie */
// #define NSTEPS 3500 /* number of frames of movie */
#define NSTEPS 2500 /* number of frames of movie */
// #define NSTEPS 500 /* number of frames of movie */
#define NVID 12 /* number of iterations between images displayed on screen */
// #define NVID 9 /* 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 400 /* time after which to start saving frames */
@ -174,35 +178,38 @@
/* Parameters of initial condition */
#define INITIAL_AMP 0.35 /* amplitude of initial condition */
#define INITIAL_VARIANCE 0.0002 /* variance of initial condition */
#define INITIAL_WAVELENGTH 0.01 /* wavelength of initial condition */
#define INITIAL_AMP 0.1 /* amplitude of initial condition */
#define INITIAL_VARIANCE 0.0003 /* variance of initial condition */
#define INITIAL_WAVELENGTH 0.015 /* wavelength of initial condition */
// #define INITIAL_VARIANCE 0.00015 /* variance of initial condition */
// #define INITIAL_WAVELENGTH 0.0075 /* wavelength of initial condition */
/* Plot type, see list in global_pdes.c */
#define PLOT 0
// #define PLOT 1
#define PLOT 7
// #define PLOT 7
#define PLOT_B 5 /* plot type for second movie */
#define PLOT_B 6 /* plot type for second movie */
/* Color schemes */
#define COLOR_PALETTE 13 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE_B 18 /* Color palette, see list in global_pdes.c */
// #define COLOR_PALETTE 15 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE 17 /* Color palette, see list in global_pdes.c */
#define COLOR_PALETTE_B 11 /* Color palette, see list in global_pdes.c */
#define BLACK 1 /* background */
#define COLOR_SCHEME 3 /* choice of color scheme, see list in global_pdes.c */
#define SCALE 0 /* set to 1 to adjust color scheme to variance of field */
#define SLOPE 1.0 /* sensitivity of color on wave amplitude */
#define SLOPE 0.75 /* sensitivity of color on wave amplitude */
#define PHASE_FACTOR 1.0 /* factor in computation of phase in color scheme P_3D_PHASE */
#define PHASE_SHIFT 0.0 /* shift of phase in color scheme P_3D_PHASE */
#define ATTENUATION 0.0 /* exponential attenuation coefficient of contrast with time */
#define E_SCALE 100.0 /* scaling factor for energy representation */
#define LOG_SCALE 0.25 /* scaling factor for energy log representation */
#define LOG_SHIFT 0.0 /* shift of colors on log scale */
#define FLUX_SCALE 1.0e4 /* scaling factor for enegy flux represtnation */
#define E_SCALE 140.0 /* scaling factor for energy representation */
#define LOG_SCALE 1.0 /* scaling factor for energy log representation */
#define LOG_SHIFT 3.5 /* shift of colors on log scale */
#define FLUX_SCALE 2.0e3 /* scaling factor for enegy flux represtnation */
#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 */
@ -213,16 +220,16 @@
#define HUEAMP -180.0 /* amplitude of variation of hue for color scheme C_HUE */
#define DRAW_COLOR_SCHEME 1 /* set to 1 to plot the color scheme */
#define COLORBAR_RANGE 2.0 /* scale of color scheme bar */
#define COLORBAR_RANGE_B 7.0 /* scale of color scheme bar for 2nd part */
#define COLORBAR_RANGE 1.5 /* scale of color scheme bar */
#define COLORBAR_RANGE_B 2.5 /* scale of color scheme bar for 2nd part */
#define ROTATE_COLOR_SCHEME 0 /* set to 1 to draw color scheme horizontally */
#define SAVE_TIME_SERIES 0 /* set to 1 to save wave time series at a point */
#define NXMAZE 7 /* width of maze */
#define NYMAZE 7 /* height of maze */
#define MAZE_MAX_NGBH 4 /* max number of neighbours of maze cell */
#define RAND_SHIFT 24 /* seed of random number generator */
#define NXMAZE 8 /* width of maze */
#define NYMAZE 32 /* height of maze */
#define MAZE_MAX_NGBH 5 /* max number of neighbours of maze cell */
#define RAND_SHIFT 0 /* seed of random number generator */
#define MAZE_XSHIFT 0.0 /* horizontal shift of maze */
/* for compatibility with sub_wave and sub_maze */
@ -231,7 +238,6 @@
#define POTENTIAL 0
/* end of constants only used by sub_wave and sub_maze */
/* 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 */
@ -571,10 +577,10 @@ 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 = 1.0, r2, xy[2], fade_value, yshift, speed = 0.0, a, b, c;
double time, scale, ratio, startleft[2], startright[2], sign = 1.0, r2, xy[2], fade_value, yshift, speed = 0.0, a, b, c, x, y, angle, x1, sign1;
double *phi[NX], *psi[NX], *tmp[NX], *total_energy[NX], *color_scale[NX], *total_flux;
short int *xy_in[NX];
int i, j, s, sample_left[2], sample_right[2], period = 0, fade;
int i, j, k, s, sample_left[2], sample_right[2], period = 0, fade, source_counter = 0;
static int counter = 0;
long int wave_value;
@ -608,6 +614,11 @@ void animation()
npolyrect = init_polyrect(polyrect);
for (i=0; i<npolyrect; i++) printf("polyrect vertex %i: (%.3f, %.3f) - (%.3f, %.3f)\n", i, polyrect[i].x1, polyrect[i].y1, polyrect[i].x2, polyrect[i].y2);
printf("Rectangles initialized\n");
init_polyrect_arc(polyrectrot, polyarc, &npolyrect_rot, &npolyarc);
printf("Rotated rectangles and arcs initialized\n");
printf("%i rotated rectangles, %i arcs\n", npolyrect_rot, npolyarc);
courant2 = COURANT*COURANT;
courantb2 = COURANTB*COURANTB;
@ -649,10 +660,20 @@ void animation()
// xy_to_ij(startright[0], startright[1], sample_right);
// printf("xleft = (%.3f, %.3f) xright = (%.3f, %.3f)\n", xin_left, yin_left, xin_right, yin_right);
// init_wave_flat(phi, psi, xy_in);
init_wave_flat(phi, psi, xy_in);
// init_circular_wave(sqrt(LAMBDA*LAMBDA - 1.0), 0.0, phi, psi, xy_in);
init_circular_wave(0.0, 0.0, phi, psi, xy_in);
// x = XMIN + (XMAX - XMIN)*rand()/RAND_MAX;
// y = YMIN + (YMAX - YMIN)*rand()/RAND_MAX;
// init_circular_wave(0.0, -0.8, phi, psi, xy_in);
// add_circular_wave(-1.0, -1.5, -0.8, phi, psi, xy_in);
// add_circular_wave(-1.0, 1.5, -0.8, phi, psi, xy_in);
// sign = -sign;
// init_circular_wave(2.0*LAMBDA*cos(APOLY*PID), 2.0*LAMBDA*sin(APOLY*PID), phi, psi, xy_in);
// angle = DPI/(double)NPOLY;
// for (j=1; j<NPOLY; j++)
// add_circular_wave(1.0, 2.0*LAMBDA*cos((double)j*angle + APOLY*PID), 2.0*LAMBDA*sin((double)j*angle + APOLY*PID), phi, psi, xy_in);
// init_wave_plus(LAMBDA - 0.3*MU, 0.5*MU, phi, psi, xy_in);
// init_wave(LAMBDA - 0.3*MU, 0.5*MU, phi, psi, xy_in);
@ -753,7 +774,30 @@ void animation()
if ((ADD_OSCILLATING_SOURCE)&&(i%OSCILLATING_SOURCE_PERIOD == OSCILLATING_SOURCE_PERIOD - 1))
{
if (ALTERNATE_OSCILLATING_SOURCE) sign = -sign;
add_circular_wave(sign, 0.0, 0.0, phi, psi, xy_in);
y = -0.8;
sign1 = sign;
for (k=-4; k<5; k++)
{
x1 = 0.3*(double)source_counter + 1.2*(double)k;
if ((x1 > XMIN)&&(x1 < XMAX))
{
add_circular_wave(sign1, x1, y, phi, psi, xy_in);
printf("Adding wave at (%.2lg, %.2lg)\n", x1, y);
}
sign1 = -sign1;
}
source_counter++;
if (source_counter == 4)
{
source_counter = 0;
sign = -sign;
}
// for (j=0; j<NPOLY; j++)
// add_circular_wave(sign, 2.0*LAMBDA*cos((double)j*angle + APOLY*PID), 2.0*LAMBDA*sin((double)j*angle + APOLY*PID), phi, psi, xy_in);
// x = XMIN + (XMAX - XMIN)*rand()/RAND_MAX;
// y = YMIN + (YMAX - YMIN)*rand()/RAND_MAX;
// add_circular_wave(sign, 0.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);
@ -770,7 +814,7 @@ void animation()
}
if (PRINT_SPEED) print_speed(speed, 0, 1.0);
glutSwapBuffers();
if (!((NO_EXTRA_BUFFER_SWAP)&&(MOVIE))) glutSwapBuffers();
if (MOVIE)
{
@ -788,9 +832,9 @@ void animation()
if (PRINT_SPEED) print_speed(speed, 0, 1.0);
glutSwapBuffers();
save_frame_counter(NSTEPS + MID_FRAMES + 1 + counter);
// save_frame_counter(NSTEPS + 21 + counter);
counter++;
}
else if (NO_EXTRA_BUFFER_SWAP) glutSwapBuffers();
/* it seems that saving too many files too fast can cause trouble with the file system */
/* so this is to make a pause from time to time - parameter PAUSE may need adjusting */
@ -826,7 +870,7 @@ void animation()
draw_billiard(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();
if (!NO_EXTRA_BUFFER_SWAP) glutSwapBuffers();
save_frame_counter(NSTEPS + i + 1);
}
if (DOUBLE_MOVIE)

View File

@ -721,7 +721,8 @@ void draw_wave_highres_diss(int size, double *phi[NX], double *psi[NX], double *
}
void draw_wave_epalette(double *phi[NX], double *psi[NX], double *total_energy[NX], double *total_flux, double *color_scale[NX],
void draw_wave_epalette(double *phi[NX], double *psi[NX], double *total_energy[NX], double *total_flux,
double *color_scale[NX],
short int *xy_in[NX], double scale, int time, int plot, int palette, int fade, double fade_value)
/* same as draw_wave_e, but with color scheme specification */
{
@ -920,9 +921,10 @@ void draw_wave_highres_palette(int size, double *phi[NX], double *psi[NX], doubl
case (P_ENERGY_FLUX):
{
compute_energy_flux(phi, psi, xy_in, i, j, &gx, &gy, &arg, &mod);
color_scheme_palette(C_ONEDIM_LINEAR, palette, arg/DPI, 1.0, 1, rgb);
flux_factor = tanh(mod*E_SCALE);
for (k=0; k<3; k++) rgb[k] *= flux_factor;
// color_scheme_palette(C_ONEDIM_LINEAR, palette, arg/DPI, 1.0, 1, rgb);
// flux_factor = tanh(mod*E_SCALE);
// for (k=0; k<3; k++) rgb[k] *= flux_factor;
color_scheme_asym_palette(COLOR_SCHEME, palette, mod*FLUX_SCALE, scale, time, rgb);
break;
}
case (P_TOTAL_ENERGY_FLUX):
@ -1119,6 +1121,60 @@ double compute_energy_mod(double phi[NX*NY], double psi[NX*NY], short int xy_in[
else return(0.0);
}
void compute_energy_flux_mod(double phi[NX*NY], double psi[NX*NY], short int xy_in[NX*NY], int i, int j, double *gx, double *gy, double *arg, double *module)
/* computes energy flux given by c^2 norm(nabla u) du/dt*/
{
double velocity, energy, gradientx, gradienty, max = 1.0e5, current_mod, current_arg;
int iplus, iminus, jplus, jminus;
if ((i == 0)||(i == NX-1)||(j == 0)||(j == NY-1))
{
current_mod = 0.0;
current_arg = PI;
*gx = 0.0;
*gy = 0.0;
}
else if ((xy_in[i*NY+j])||(TWOSPEEDS))
{
velocity = vabs(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;*/
gradientx = (phi[(i+1)*NY+j] - phi[(i-1)*NY+j]);
gradienty = (phi[i*NY+j+1] - phi[i*NY+j-1]);
if (gradientx > max) gradientx = max;
else if (gradientx < -max) gradientx = -max;
if (gradienty > max) gradienty = max;
else if (gradienty < -max) gradienty = -max;
current_mod = velocity*module2(gradientx, gradienty);
if (current_mod > 1.0e-10)
{
current_arg = argument(gradientx,gradienty);
if (current_arg < 0.0) current_arg += DPI;
if (current_arg >= DPI) current_arg -= DPI;
}
else current_arg = PI;
*gx = velocity*gradientx;
*gy = velocity*gradienty;
}
else
{
current_mod = 0.0;
current_arg = PI;
*gx = 0.0;
*gy = 0.0;
}
*module = current_mod;
*arg = current_arg;
}
double compute_phase(double phi[NX*NY], double psi[NX*NY], short int xy_in[NX*NY], int i, int j)
{
double velocity, angle;