2389 lines
77 KiB
C
2389 lines
77 KiB
C
|
/*********************/
|
||
|
/* Graphics routines */
|
||
|
/*********************/
|
||
|
|
||
|
#include "colors_waves.c"
|
||
|
|
||
|
#define CLUSTER_SHIFT 10 /* shift in numbering of open clusters */
|
||
|
|
||
|
int writetiff(char *filename, char *description, int x, int y, int width, int height, int compression)
|
||
|
{
|
||
|
TIFF *file;
|
||
|
GLubyte *image, *p;
|
||
|
int i;
|
||
|
|
||
|
file = TIFFOpen(filename, "w");
|
||
|
if (file == NULL)
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
image = (GLubyte *) malloc(width * height * sizeof(GLubyte) * 3);
|
||
|
|
||
|
/* OpenGL's default 4 byte pack alignment would leave extra bytes at the
|
||
|
end of each image row so that each full row contained a number of bytes
|
||
|
divisible by 4. Ie, an RGB row with 3 pixels and 8-bit componets would
|
||
|
be laid out like "RGBRGBRGBxxx" where the last three "xxx" bytes exist
|
||
|
just to pad the row out to 12 bytes (12 is divisible by 4). To make sure
|
||
|
the rows are packed as tight as possible (no row padding), set the pack
|
||
|
alignment to 1. */
|
||
|
|
||
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||
|
|
||
|
glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, image);
|
||
|
TIFFSetField(file, TIFFTAG_IMAGEWIDTH, (uint32) width);
|
||
|
TIFFSetField(file, TIFFTAG_IMAGELENGTH, (uint32) height);
|
||
|
TIFFSetField(file, TIFFTAG_BITSPERSAMPLE, 8);
|
||
|
TIFFSetField(file, TIFFTAG_COMPRESSION, compression);
|
||
|
TIFFSetField(file, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
|
||
|
TIFFSetField(file, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
|
||
|
TIFFSetField(file, TIFFTAG_SAMPLESPERPIXEL, 3);
|
||
|
TIFFSetField(file, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
|
||
|
TIFFSetField(file, TIFFTAG_ROWSPERSTRIP, 1);
|
||
|
TIFFSetField(file, TIFFTAG_IMAGEDESCRIPTION, description);
|
||
|
p = image;
|
||
|
for (i = height - 1; i >= 0; i--)
|
||
|
{
|
||
|
// if (TIFFWriteScanline(file, p, height - i - 1, 0) < 0)
|
||
|
if (TIFFWriteScanline(file, p, i, 0) < 0)
|
||
|
{
|
||
|
free(image);
|
||
|
TIFFClose(file);
|
||
|
return 1;
|
||
|
}
|
||
|
p += width * sizeof(GLubyte) * 3;
|
||
|
}
|
||
|
TIFFClose(file);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void init() /* initialisation of window */
|
||
|
{
|
||
|
glLineWidth(3);
|
||
|
|
||
|
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||
|
|
||
|
// glOrtho(XMIN, XMAX, YMIN, YMAX , -1.0, 1.0);
|
||
|
glOrtho(0.0, NX, 0.0, NY, -1.0, 1.0);
|
||
|
}
|
||
|
|
||
|
void blank()
|
||
|
{
|
||
|
if (BLACK) glClearColor(0.0, 0.0, 0.0, 1.0);
|
||
|
else glClearColor(1.0, 1.0, 1.0, 1.0);
|
||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||
|
}
|
||
|
|
||
|
|
||
|
void write_text_fixedwidth( double x, double y, char *st)
|
||
|
{
|
||
|
int l, i;
|
||
|
|
||
|
l=strlen( st ); // see how many characters are in text string.
|
||
|
glRasterPos2d( x, y); // location to start printing text
|
||
|
for( i=0; i < l; i++) // loop until i is greater then l
|
||
|
{
|
||
|
// glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, st[i]); // Print a character on the screen
|
||
|
// glutBitmapCharacter(GLUT_BITMAP_8_BY_13, st[i]); // Print a character on the screen
|
||
|
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, st[i]); // Print a character on the screen
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void write_text( double x, double y, char *st)
|
||
|
{
|
||
|
int l,i;
|
||
|
|
||
|
l=strlen( st ); // see how many characters are in text string.
|
||
|
glRasterPos2d( x, y); // location to start printing text
|
||
|
for( i=0; i < l; i++) // loop until i is greater then l
|
||
|
{
|
||
|
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, st[i]); // Print a character on the screen
|
||
|
// glutBitmapCharacter(GLUT_BITMAP_8_BY_13, st[i]); // Print a character on the screen
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void save_frame_perc()
|
||
|
{
|
||
|
static int counter = 0;
|
||
|
char *name="perc.", n2[100];
|
||
|
char format[6]=".%05i";
|
||
|
|
||
|
counter++;
|
||
|
strcpy(n2, name);
|
||
|
sprintf(strstr(n2,"."), format, counter);
|
||
|
strcat(n2, ".tif");
|
||
|
printf(" saving frame %s \n",n2);
|
||
|
writetiff(n2, "Wave equation in a planar domain", 0, 0,
|
||
|
WINWIDTH, WINHEIGHT, COMPRESSION_LZW);
|
||
|
|
||
|
}
|
||
|
|
||
|
/*********************/
|
||
|
/* some basic math */
|
||
|
/*********************/
|
||
|
|
||
|
|
||
|
double ipow(double x, int n)
|
||
|
{
|
||
|
double y;
|
||
|
int i;
|
||
|
|
||
|
y = x;
|
||
|
for (i=1; i<n; i++) y *= x;
|
||
|
|
||
|
return(y);
|
||
|
}
|
||
|
|
||
|
|
||
|
int ipowi(int base, int n)
|
||
|
{
|
||
|
int p, i;
|
||
|
|
||
|
if (n == 0) return(1);
|
||
|
else
|
||
|
{
|
||
|
p = base;
|
||
|
for (i=1; i<n; i++) p *= base;
|
||
|
|
||
|
return(p);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*********************/
|
||
|
/* drawing routines */
|
||
|
/*********************/
|
||
|
|
||
|
/* The billiard boundary is drawn in (x,y) coordinates */
|
||
|
/* However for the grid points, we use integer coordinates (i,j) */
|
||
|
/* GL would allow to always work in (x,y) coordinates but using both */
|
||
|
/* sets of coordinates decreases number of double computations when */
|
||
|
/* drawing the field */
|
||
|
|
||
|
void xy_to_ij(double x, double y, int ij[2])
|
||
|
/* convert (x,y) position to (i,j) in table representing wave */
|
||
|
{
|
||
|
double x1, y1;
|
||
|
|
||
|
x1 = (x - XMIN)/(XMAX - XMIN);
|
||
|
y1 = (y - YMIN)/(YMAX - YMIN);
|
||
|
|
||
|
ij[0] = (int)(x1 * (double)NX);
|
||
|
ij[1] = (int)(y1 * (double)NY);
|
||
|
}
|
||
|
|
||
|
|
||
|
void xy_to_pos(double x, double y, double pos[2])
|
||
|
/* convert (x,y) position to double-valued position in table representing wave */
|
||
|
{
|
||
|
double x1, y1;
|
||
|
|
||
|
x1 = (x - XMIN)/(XMAX - XMIN);
|
||
|
y1 = (y - YMIN)/(YMAX - YMIN);
|
||
|
|
||
|
pos[0] = x1 * (double)NX;
|
||
|
pos[1] = y1 * (double)NY;
|
||
|
}
|
||
|
|
||
|
void erase_area_rgb(double x, double y, double dx, double dy, double rgb[3])
|
||
|
{
|
||
|
double pos[2];
|
||
|
|
||
|
glColor3f(rgb[0], rgb[1], rgb[2]);
|
||
|
glBegin(GL_QUADS);
|
||
|
xy_to_pos(x - dx, y - dy, pos);
|
||
|
glVertex2d(pos[0], pos[1]);
|
||
|
xy_to_pos(x + dx, y - dy, pos);
|
||
|
glVertex2d(pos[0], pos[1]);
|
||
|
xy_to_pos(x + dx, y + dy, pos);
|
||
|
glVertex2d(pos[0], pos[1]);
|
||
|
xy_to_pos(x - dx, y + dy, pos);
|
||
|
glVertex2d(pos[0], pos[1]);
|
||
|
glEnd();
|
||
|
}
|
||
|
|
||
|
|
||
|
void draw_line(double x1, double y1, double x2, double y2)
|
||
|
{
|
||
|
double pos[2];
|
||
|
|
||
|
glBegin(GL_LINE_STRIP);
|
||
|
xy_to_pos(x1, y1, pos);
|
||
|
glVertex2d(pos[0], pos[1]);
|
||
|
xy_to_pos(x2, y2, pos);
|
||
|
glVertex2d(pos[0], pos[1]);
|
||
|
glEnd();
|
||
|
}
|
||
|
|
||
|
void draw_rectangle(double x1, double y1, double x2, double y2)
|
||
|
{
|
||
|
double pos[2];
|
||
|
|
||
|
glBegin(GL_LINE_LOOP);
|
||
|
xy_to_pos(x1, y1, pos);
|
||
|
glVertex2d(pos[0], pos[1]);
|
||
|
xy_to_pos(x2, y1, pos);
|
||
|
glVertex2d(pos[0], pos[1]);
|
||
|
xy_to_pos(x2, y2, pos);
|
||
|
glVertex2d(pos[0], pos[1]);
|
||
|
xy_to_pos(x1, y2, pos);
|
||
|
glVertex2d(pos[0], pos[1]);
|
||
|
glEnd();
|
||
|
}
|
||
|
|
||
|
void draw_colored_rectangle(double x1, double y1, double x2, double y2, double hue)
|
||
|
{
|
||
|
double pos[2], rgb[3];
|
||
|
|
||
|
hsl_to_rgb_palette(hue, 0.9, 0.5, rgb, COLOR_PALETTE);
|
||
|
glColor3f(rgb[0], rgb[1], rgb[2]);
|
||
|
|
||
|
glBegin(GL_QUADS);
|
||
|
xy_to_pos(x1, y1, pos);
|
||
|
glVertex2d(pos[0], pos[1]);
|
||
|
xy_to_pos(x2, y1, pos);
|
||
|
glVertex2d(pos[0], pos[1]);
|
||
|
xy_to_pos(x2, y2, pos);
|
||
|
glVertex2d(pos[0], pos[1]);
|
||
|
xy_to_pos(x1, y2, pos);
|
||
|
glVertex2d(pos[0], pos[1]);
|
||
|
glEnd();
|
||
|
|
||
|
glColor3f(0.0, 0.0, 0.0);
|
||
|
glBegin(GL_LINE_LOOP);
|
||
|
xy_to_pos(x1, y1, pos);
|
||
|
glVertex2d(pos[0], pos[1]);
|
||
|
xy_to_pos(x2, y1, pos);
|
||
|
glVertex2d(pos[0], pos[1]);
|
||
|
xy_to_pos(x2, y2, pos);
|
||
|
glVertex2d(pos[0], pos[1]);
|
||
|
xy_to_pos(x1, y2, pos);
|
||
|
glVertex2d(pos[0], pos[1]);
|
||
|
glEnd();
|
||
|
|
||
|
}
|
||
|
|
||
|
int graphical_rep(int bcondition)
|
||
|
/* return type of drawing, depending on lattice/boundary conditions */
|
||
|
{
|
||
|
switch (bcondition) {
|
||
|
case (BC_SQUARE_DIRICHLET): return(PLOT_SQUARES);
|
||
|
case (BC_SQUARE_PERIODIC): return(PLOT_SQUARES);
|
||
|
case (BC_SQUARE_BOND_DIRICHLET): return(PLOT_SQUARE_BONDS);
|
||
|
case (BC_HEX_SITE_DIRICHLET): return(PLOT_HEX);
|
||
|
case (BC_HEX_BOND_DIRICHLET): return(PLOT_HEX_BONDS);
|
||
|
case (BC_TRIANGLE_SITE_DIRICHLET): return(PLOT_TRIANGLE);
|
||
|
default: return(0);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
double pcritical(int bcondition)
|
||
|
/* critical probability in terms of lattice and boundary condition */
|
||
|
{
|
||
|
switch (LATTICE) {
|
||
|
case (BC_SQUARE_DIRICHLET): return(0.59274);
|
||
|
case (BC_SQUARE_PERIODIC): return(0.59274);
|
||
|
case (BC_SQUARE_BOND_DIRICHLET): return(0.5);
|
||
|
case (BC_HEX_BOND_DIRICHLET): return(1.0 - 2.0*sin(PI/18.0));
|
||
|
case (BC_TRIANGLE_SITE_DIRICHLET): return(0.6970402);
|
||
|
default: return(0.5);
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
int cellnb(int i, int j, int group, int nx, int ny)
|
||
|
/* convert 2d coordinates to 1d */
|
||
|
{
|
||
|
switch (LATTICE) {
|
||
|
case (BC_SQUARE_DIRICHLET):
|
||
|
{
|
||
|
return(i*ny+j);
|
||
|
break;
|
||
|
}
|
||
|
case (BC_SQUARE_PERIODIC):
|
||
|
{
|
||
|
return(i*ny+j);
|
||
|
break;
|
||
|
}
|
||
|
case (BC_SQUARE_BOND_DIRICHLET):
|
||
|
{
|
||
|
if (group == 0) return(i+nx*j);
|
||
|
else return (nx*(ny+1) + i*ny+j);
|
||
|
break;
|
||
|
}
|
||
|
case (BC_HEX_SITE_DIRICHLET):
|
||
|
{
|
||
|
return(i+nx*j);
|
||
|
break;
|
||
|
}
|
||
|
case (BC_HEX_BOND_DIRICHLET):
|
||
|
{
|
||
|
return (group*nx*(ny+1) + i+nx*j);
|
||
|
break;
|
||
|
}
|
||
|
case (BC_TRIANGLE_SITE_DIRICHLET):
|
||
|
{
|
||
|
return(i+2*nx*j);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int cell_to_ij(int c, int *i, int *j, int nx, int ny)
|
||
|
/* convert 1d coordinates to 2d, returns group */
|
||
|
{
|
||
|
int group;
|
||
|
|
||
|
switch (LATTICE) {
|
||
|
case (BC_SQUARE_DIRICHLET):
|
||
|
{
|
||
|
*i = c/ny;
|
||
|
*j = c - *i*ny;
|
||
|
return(0);
|
||
|
}
|
||
|
case (BC_SQUARE_PERIODIC):
|
||
|
{
|
||
|
*i = c/ny;
|
||
|
*j = c - *i*ny;
|
||
|
return(0);
|
||
|
}
|
||
|
case (BC_SQUARE_BOND_DIRICHLET):
|
||
|
{
|
||
|
if (c < nx*(ny+1))
|
||
|
{
|
||
|
*j = c/nx;
|
||
|
*i = c - *j*nx;
|
||
|
return(0);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
c -= nx*(ny+1);
|
||
|
*i = c/ny;
|
||
|
*j = c - *i*ny;
|
||
|
return(1);
|
||
|
}
|
||
|
}
|
||
|
case (BC_HEX_SITE_DIRICHLET):
|
||
|
{
|
||
|
*j = c/nx;
|
||
|
*i = c - *j*nx;
|
||
|
return(0);
|
||
|
}
|
||
|
case (BC_HEX_BOND_DIRICHLET):
|
||
|
{
|
||
|
group = c/(nx*(ny+1));
|
||
|
c -= group*(nx*(ny+1));
|
||
|
*j = c/nx;
|
||
|
*i = c - *j*nx;
|
||
|
return(group);
|
||
|
}
|
||
|
case (BC_TRIANGLE_SITE_DIRICHLET):
|
||
|
{
|
||
|
*j= c/(2*nx);
|
||
|
*i = c - 2*(*j)*nx;
|
||
|
return(0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
double p_schedule(int i)
|
||
|
/* percolation probability p as a function of time */
|
||
|
{
|
||
|
double time, pstar;
|
||
|
int power = 2, factor;
|
||
|
|
||
|
pstar = pcritical(LATTICE);
|
||
|
|
||
|
factor = ipow(2, power);
|
||
|
|
||
|
time = (double)i/(double)(NSTEPS-1);
|
||
|
|
||
|
if (time > 0.5) return(pstar + factor*(1.0 - pstar)*ipow(time - 0.5, power));
|
||
|
else return(pstar - factor*pstar*ipow(0.5 - time, power));
|
||
|
}
|
||
|
|
||
|
int in_plot_box(double x, double y)
|
||
|
{
|
||
|
int pos[2];
|
||
|
static double xmin, xmax, ymin, ymax;
|
||
|
static int first = 1;
|
||
|
|
||
|
if (first)
|
||
|
{
|
||
|
xy_to_ij(XMAX - 1.0, YMAX - 1.0, pos);
|
||
|
xmin = (double)pos[0];
|
||
|
ymin = (double)pos[1];
|
||
|
first = 0;
|
||
|
}
|
||
|
|
||
|
return((x > xmin)&&(y > ymin));
|
||
|
// return((x + 0.5*(double)size > xmin)&&(y + 0.5*(double)size > ymin));
|
||
|
}
|
||
|
|
||
|
double size_ratio_color(int clustersize, int ncells)
|
||
|
/* color of cell as function of the size of its cluster */
|
||
|
{
|
||
|
double ratio, minratio = 1.0e-2, x;
|
||
|
|
||
|
ratio = (double)clustersize/(double)ncells;
|
||
|
if (ratio > 1.0) ratio = 1.0;
|
||
|
else if (ratio < minratio) ratio = minratio;
|
||
|
x = log(ratio/minratio)/log(1.0/minratio);
|
||
|
return(CLUSTER_HUEMIN*x + CLUSTER_HUEMAX*(1.0 -x));
|
||
|
|
||
|
/* other attempts that seem to bug */
|
||
|
// ratio = log((double)(clustersize+1))/log((double)(ncells+1));
|
||
|
// // ratio = ((double)clustersize)/((double)ncells);
|
||
|
// // ratio = sqrt((double)clustersize)/sqrt((double)ncells);
|
||
|
// if (ratio > 1.0) ratio = 1.0;
|
||
|
// else if (ratio < 0.0) ratio = 0.0;
|
||
|
// return(CLUSTER_HUEMAX*ratio + CLUSTER_HUEMIN*(1.0 -ratio));
|
||
|
}
|
||
|
|
||
|
void set_cell_color(t_perco cell, int *cluster_sizes, int fade, int max_cluster_size)
|
||
|
/* compute color of cell */
|
||
|
{
|
||
|
int k, color, csize;
|
||
|
double rgb[3], fade_factor = 0.15, hue;
|
||
|
|
||
|
if (!cell.open) hsl_to_rgb_palette(HUE_CLOSED, 0.9, 0.5, rgb, COLOR_PALETTE);
|
||
|
else
|
||
|
{
|
||
|
if (!cell.flooded) hsl_to_rgb_palette(HUE_OPEN, 0.9, 0.5, rgb, COLOR_PALETTE);
|
||
|
else hsl_to_rgb_palette(HUE_FLOODED, 0.9, 0.5, rgb, COLOR_PALETTE);
|
||
|
|
||
|
if ((FIND_ALL_CLUSTERS)&&(COLOR_CLUSTERS_BY_SIZE))
|
||
|
{
|
||
|
csize = cluster_sizes[cell.cluster];
|
||
|
hue = size_ratio_color(csize, max_cluster_size);
|
||
|
hsl_to_rgb_palette(hue, 0.9, 0.5, rgb, COLOR_PALETTE);
|
||
|
}
|
||
|
else if ((FIND_ALL_CLUSTERS)&&(cell.cluster > 1))
|
||
|
{
|
||
|
color = cell.cluster%N_CLUSTER_COLORS;
|
||
|
hue = CLUSTER_HUEMIN + (CLUSTER_HUEMAX - CLUSTER_HUEMIN)*(double)color/(double)N_CLUSTER_COLORS;
|
||
|
hsl_to_rgb_palette(hue, 0.9, 0.5, rgb, COLOR_PALETTE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (fade) for (k=0; k<3; k++) rgb[k] = 1.0 - fade_factor + fade_factor*rgb[k];
|
||
|
|
||
|
glColor3f(rgb[0], rgb[1], rgb[2]);
|
||
|
}
|
||
|
|
||
|
|
||
|
double plot_coord(double x, double xmin, double xmax)
|
||
|
{
|
||
|
return(xmin + x*(xmax - xmin));
|
||
|
}
|
||
|
|
||
|
void draw_size_plot(double plot_cluster_size[NSTEPS], int i, double pcrit)
|
||
|
/* draw plot of cluster sizes in terms of p */
|
||
|
{
|
||
|
int j;
|
||
|
char message[100];
|
||
|
static double xmin, xmax, ymin, ymax, xmid, ymid, dx, dy, plotxmin, plotxmax, plotymin, plotymax;
|
||
|
double pos[2], x1, y1, x2, y2, rgb[3], x;
|
||
|
static int first = 1;
|
||
|
|
||
|
if (first)
|
||
|
{
|
||
|
xmin = XMAX - 0.95;
|
||
|
xmax = XMAX - 0.05;
|
||
|
ymin = YMAX - 0.95;
|
||
|
ymax = YMAX - 0.05;
|
||
|
|
||
|
xmid = 0.5*(xmin + xmax);
|
||
|
ymid = 0.5*(ymin + ymax);
|
||
|
|
||
|
dx = 0.5*(xmax - xmin);
|
||
|
dy = 0.5*(ymax - ymin);
|
||
|
|
||
|
plotxmin = xmin + 0.05;
|
||
|
plotxmax = xmax - 0.1;
|
||
|
plotymin = ymin + 0.07;
|
||
|
plotymax = ymax - 0.15;
|
||
|
|
||
|
first = 0;
|
||
|
}
|
||
|
|
||
|
rgb[0] = 1.0; rgb[1] = 1.0; rgb[2] = 1.0;
|
||
|
// erase_area_rgb(xmid, ymid, dx, dy, rgb);
|
||
|
|
||
|
glColor3f(0.0, 0.0, 0.0);
|
||
|
glLineWidth(2);
|
||
|
|
||
|
/* axes and labels */
|
||
|
draw_line(plotxmin, plotymin, plotxmax + 0.05, plotymin);
|
||
|
draw_line(plotxmin, plotymin, plotxmin, plotymax + 0.1);
|
||
|
draw_line(plotxmin - 0.02, plotymax, plotxmin + 0.02, plotymax);
|
||
|
x = plot_coord(pcrit, plotxmin, plotxmax);
|
||
|
draw_line(x, plotymin, x, plotymax);
|
||
|
draw_line(plotxmax, plotymin - 0.02, plotxmax, plotymin + 0.02);
|
||
|
|
||
|
xy_to_pos(plotxmax + 0.06, plotymin - 0.03, pos);
|
||
|
sprintf(message, "p");
|
||
|
write_text_fixedwidth(pos[0], pos[1], message);
|
||
|
|
||
|
xy_to_pos(plotxmax - 0.015, plotymin - 0.06, pos);
|
||
|
sprintf(message, "1");
|
||
|
write_text_fixedwidth(pos[0], pos[1], message);
|
||
|
|
||
|
xy_to_pos(x - 0.02, plotymin - 0.04, pos);
|
||
|
sprintf(message, "pc");
|
||
|
write_text_fixedwidth(pos[0], pos[1], message);
|
||
|
|
||
|
xy_to_pos(plotxmin + 0.02, plotymax + 0.05, pos);
|
||
|
sprintf(message, "nflooded/nopen");
|
||
|
write_text_fixedwidth(pos[0], pos[1], message);
|
||
|
|
||
|
xy_to_pos(plotxmin - 0.05, plotymax - 0.01, pos);
|
||
|
sprintf(message, "1");
|
||
|
write_text_fixedwidth(pos[0], pos[1], message);
|
||
|
|
||
|
/* plot */
|
||
|
hsl_to_rgb_palette(HUE_GRAPH, 0.9, 0.5, rgb, COLOR_PALETTE);
|
||
|
glColor3f(rgb[0], rgb[1], rgb[2]);
|
||
|
x1 = plotxmin;
|
||
|
y1 = plotymin;
|
||
|
for (j=0; j<i; j++)
|
||
|
{
|
||
|
// x2 = plot_coord((double)j/(double)NSTEPS, plotxmin, plotxmax);
|
||
|
x2 = plot_coord(p_schedule(j), plotxmin, plotxmax);
|
||
|
y2 = plot_coord(plot_cluster_size[j], plotymin, plotymax);
|
||
|
|
||
|
draw_line(x1, y1, x2, y2);
|
||
|
x1 = x2;
|
||
|
y1 = y2;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void draw_cluster_number_plot(int plot_cluster_number[NSTEPS], int max_number, int i, double pcrit)
|
||
|
/* draw plot of number of clusters in terms of p */
|
||
|
{
|
||
|
int j;
|
||
|
char message[100];
|
||
|
static double xmin, xmax, ymin, ymax, xmid, ymid, dx, dy, plotxmin, plotxmax, plotymin, plotymax;
|
||
|
double pos[2], x1, y1, x2, y2, rgb[3], x, y;
|
||
|
static int first = 1;
|
||
|
|
||
|
if (first)
|
||
|
{
|
||
|
xmin = XMAX - 0.95;
|
||
|
xmax = XMAX - 0.05;
|
||
|
ymin = YMAX - 0.95;
|
||
|
ymax = YMAX - 0.05;
|
||
|
|
||
|
xmid = 0.5*(xmin + xmax);
|
||
|
ymid = 0.5*(ymin + ymax);
|
||
|
|
||
|
dx = 0.5*(xmax - xmin);
|
||
|
dy = 0.5*(ymax - ymin);
|
||
|
|
||
|
plotxmin = xmin + 0.05;
|
||
|
plotxmax = xmax - 0.1;
|
||
|
plotymin = ymin + 0.07;
|
||
|
plotymax = ymax - 0.15;
|
||
|
|
||
|
first = 0;
|
||
|
}
|
||
|
|
||
|
rgb[0] = 1.0; rgb[1] = 1.0; rgb[2] = 1.0;
|
||
|
// erase_area_rgb(xmid, ymid, dx, dy, rgb);
|
||
|
|
||
|
glColor3f(0.0, 0.0, 0.0);
|
||
|
glLineWidth(2);
|
||
|
|
||
|
/* axes and labels */
|
||
|
draw_line(plotxmin, plotymin, plotxmax + 0.05, plotymin);
|
||
|
draw_line(plotxmin, plotymin, plotxmin, plotymax + 0.1);
|
||
|
draw_line(plotxmin - 0.02, plotymax, plotxmin + 0.02, plotymax);
|
||
|
x = plot_coord(pcrit, plotxmin, plotxmax);
|
||
|
draw_line(x, plotymin, x, plotymax);
|
||
|
draw_line(plotxmax, plotymin - 0.02, plotxmax, plotymin + 0.02);
|
||
|
|
||
|
xy_to_pos(plotxmax + 0.06, plotymin - 0.03, pos);
|
||
|
sprintf(message, "p");
|
||
|
write_text_fixedwidth(pos[0], pos[1], message);
|
||
|
|
||
|
xy_to_pos(plotxmax - 0.015, plotymin - 0.06, pos);
|
||
|
sprintf(message, "1");
|
||
|
write_text_fixedwidth(pos[0], pos[1], message);
|
||
|
|
||
|
xy_to_pos(x - 0.02, plotymin - 0.04, pos);
|
||
|
sprintf(message, "pc");
|
||
|
write_text_fixedwidth(pos[0], pos[1], message);
|
||
|
|
||
|
xy_to_pos(plotxmin + 0.02, plotymax + 0.05, pos);
|
||
|
sprintf(message, "clusters/cells");
|
||
|
write_text_fixedwidth(pos[0], pos[1], message);
|
||
|
|
||
|
xy_to_pos(plotxmin + 0.05, plotymax - 0.01, pos);
|
||
|
sprintf(message, "%.2f", 1.0/(double)MAX_CLUSTER_NUMBER);
|
||
|
write_text_fixedwidth(pos[0], pos[1], message);
|
||
|
|
||
|
/* plot */
|
||
|
hsl_to_rgb_palette(HUE_GRAPH, 0.9, 0.5, rgb, COLOR_PALETTE);
|
||
|
glColor3f(rgb[0], rgb[1], rgb[2]);
|
||
|
x1 = plotxmin;
|
||
|
y1 = plotymin;
|
||
|
for (j=0; j<i; j++)
|
||
|
{
|
||
|
// x2 = plot_coord((double)j/(double)NSTEPS, plotxmin, plotxmax);
|
||
|
x2 = plot_coord(p_schedule(j), plotxmin, plotxmax);
|
||
|
y2 = plot_coord((double)plot_cluster_number[j]/(double)max_number, plotymin, plotymax);
|
||
|
|
||
|
draw_line(x1, y1, x2, y2);
|
||
|
x1 = x2;
|
||
|
y1 = y2;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void draw_cluster_histogram(int ncells, int *cluster_sizes, int maxclustersize, int maxclusterlabel)
|
||
|
/* draw histogram of cluster size distribution */
|
||
|
{
|
||
|
int i, bin, nbins, binwidth, *histo, maxheight = 0, csize, dh, n, max_x_axis, di;
|
||
|
static int maxbins = HISTO_BINS;
|
||
|
char message[100];
|
||
|
static double xmin, xmax, ymin, ymax, xmid, ymid, dx, dy, plotxmin, plotxmax, plotymin, plotymax, x, y;
|
||
|
double pos[2], x1, y1, x2, y2, hue, delta;
|
||
|
static int first = 1;
|
||
|
|
||
|
if (first)
|
||
|
{
|
||
|
xmin = XMAX - 0.95;
|
||
|
xmax = XMAX - 0.05;
|
||
|
ymin = YMAX - 0.95;
|
||
|
ymax = YMAX - 0.05;
|
||
|
|
||
|
xmid = 0.5*(xmin + xmax);
|
||
|
ymid = 0.5*(ymin + ymax);
|
||
|
|
||
|
dx = 0.5*(xmax - xmin);
|
||
|
dy = 0.5*(ymax - ymin);
|
||
|
|
||
|
plotxmin = xmin + 0.15;
|
||
|
plotxmax = xmax - 0.1;
|
||
|
plotymin = ymin + 0.07;
|
||
|
plotymax = ymax - 0.1;
|
||
|
|
||
|
first = 0;
|
||
|
}
|
||
|
|
||
|
if (maxclustersize > 0)
|
||
|
{
|
||
|
|
||
|
// if (maxclustersize < maxbins) nbins = maxclustersize;
|
||
|
// else
|
||
|
nbins = maxbins;
|
||
|
|
||
|
histo = (int *)malloc(nbins*sizeof(int));
|
||
|
|
||
|
for (bin = 0; bin < nbins; bin++) histo[bin] = 0;
|
||
|
|
||
|
// binwidth = maxclustersize/nbins;
|
||
|
// if (binwidth == 0) binwidth = 1;
|
||
|
binwidth = maxclustersize/nbins + 1;
|
||
|
|
||
|
/* compute histogram */
|
||
|
for (i=CLUSTER_SHIFT; i<maxclusterlabel; i++) if (cluster_sizes[i] > 0)
|
||
|
{
|
||
|
bin = (cluster_sizes[i]-1)/binwidth;
|
||
|
histo[bin]++;
|
||
|
}
|
||
|
for (bin=0; bin<maxbins; bin++) if (histo[bin] > maxheight) maxheight = histo[bin];
|
||
|
|
||
|
/* draw histogram */
|
||
|
glColor3f(0.0, 0.0, 0.0);
|
||
|
glLineWidth(2);
|
||
|
|
||
|
x1 = plotxmin;
|
||
|
y1 = plotymin;
|
||
|
max_x_axis = maxclustersize;
|
||
|
if (max_x_axis < HISTO_BINS) max_x_axis = HISTO_BINS;
|
||
|
|
||
|
for (bin=0; bin < nbins; bin++)
|
||
|
{
|
||
|
csize = bin*binwidth + binwidth/2;
|
||
|
hue = size_ratio_color(csize, ncells);
|
||
|
|
||
|
x2 = plot_coord((double)((bin+1)*binwidth)/(double)(max_x_axis+1), plotxmin, plotxmax);
|
||
|
// x2 = plot_coord((double)(bin+1)/(double)nbins, plotxmin, plotxmax);
|
||
|
|
||
|
y = log((double)(histo[bin]+1))/log((double)(maxheight+1));
|
||
|
y2 = plot_coord(y, plotymin, plotymax);
|
||
|
|
||
|
draw_colored_rectangle(x1, y1, x2, y2, hue);
|
||
|
x1 = x2;
|
||
|
}
|
||
|
|
||
|
draw_line(plotxmin, plotymin, plotxmax + 0.05, plotymin);
|
||
|
draw_line(plotxmin, plotymin, plotxmin, plotymax + 0.1);
|
||
|
|
||
|
/* graduation of y axis */
|
||
|
x = log((double)(maxheight+1))/log(10.0);
|
||
|
for (i=0; i<(int)x + 1; i++)
|
||
|
{
|
||
|
n = ipowi(10, i);
|
||
|
y = log((double)(n+1))/log((double)(maxheight+1));
|
||
|
y1 = plot_coord(y, plotymin, plotymax);
|
||
|
xy_to_pos(plotxmin - 0.1, y1, pos);
|
||
|
draw_line(plotxmin - 0.02, y1, plotxmin + 0.02, y1);
|
||
|
sprintf(message, "%i", n);
|
||
|
xy_to_pos(plotxmin - 0.07 - 0.025*(double)i, y1 - 0.01, pos);
|
||
|
write_text_fixedwidth(pos[0], pos[1], message);
|
||
|
}
|
||
|
|
||
|
/* graduation of x axis */
|
||
|
x = log((double)(max_x_axis+1))/log(10.0);
|
||
|
n = ipowi(10, (int)x);
|
||
|
y = (double)n/10.0;
|
||
|
|
||
|
delta = plot_coord((double)n/((double)(max_x_axis+1)), plotxmin, plotxmax) - plotxmin;
|
||
|
if (delta > 0.13 + 0.01*x) di = 1;
|
||
|
else if (delta > 0.08 + 0.01*x) di = 2;
|
||
|
else di = 5;
|
||
|
for (i=di; i<10; i+=di)
|
||
|
{
|
||
|
x1 = plot_coord(y*(double)i*10.0/(double)(max_x_axis+1), plotxmin, plotxmax);
|
||
|
if (i*n < max_x_axis*11/10)
|
||
|
{
|
||
|
sprintf(message, "%i", i*n);
|
||
|
xy_to_pos(x1 + 0.005 - 0.012*x, plotymin - 0.07, pos);
|
||
|
write_text_fixedwidth(pos[0], pos[1], message);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
delta = plot_coord((double)n/(10.0*(double)(max_x_axis+1)), plotxmin, plotxmax) - plotxmin;
|
||
|
for (i=0; i<100; i++) if (i*n < 11*max_x_axis)
|
||
|
{
|
||
|
y = (double)(i*n)/10.0;
|
||
|
x1 = plot_coord(y/(double)(max_x_axis+1), plotxmin, plotxmax);
|
||
|
xy_to_pos(x1, plotymin , pos);
|
||
|
if (i%10 == 0) draw_line(x1, plotymin - 0.02, x1, plotymin + 0.02);
|
||
|
else if (delta > 0.02) draw_line(x1, plotymin - 0.01, x1, plotymin + 0.01);
|
||
|
}
|
||
|
|
||
|
/* for debugging */
|
||
|
if (DEBUG) for (bin=0; bin < nbins; bin++) printf("Bin %i = %i\n", bin, histo[bin]);
|
||
|
|
||
|
|
||
|
free(histo);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void draw_cell(int c, int nx, int ny, int size)
|
||
|
/* draw a single cell, for debugging puposes */
|
||
|
{
|
||
|
int i, j, ishift, k, group;
|
||
|
double rgb[3], x, y, alpha, r, fade = 0, dsize;
|
||
|
static double h;
|
||
|
static int first = 1;
|
||
|
|
||
|
dsize = (double)size;
|
||
|
|
||
|
group = cell_to_ij(c, &i, &j, nx, ny);
|
||
|
switch (graphical_rep(LATTICE)) {
|
||
|
case (PLOT_SQUARES):
|
||
|
{
|
||
|
glBegin(GL_QUADS);
|
||
|
|
||
|
glVertex2i(i*size, j*size);
|
||
|
glVertex2i((i+1)*size, j*size);
|
||
|
glVertex2i((i+1)*size, (j+1)*size);
|
||
|
glVertex2i(i*size, (j+1)*size);
|
||
|
|
||
|
glEnd ();
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
case (PLOT_SQUARE_BONDS):
|
||
|
{
|
||
|
glLineWidth(5);
|
||
|
glBegin(GL_LINES);
|
||
|
|
||
|
/* horizontal segments */
|
||
|
if (group == 0)
|
||
|
{
|
||
|
glVertex2i(i*size, j*size);
|
||
|
glVertex2i((i+1)*size, j*size);
|
||
|
}
|
||
|
|
||
|
/* vertical segments */
|
||
|
else
|
||
|
{
|
||
|
glVertex2i(i*size, j*size);
|
||
|
glVertex2i(i*size, (j+1)*size);
|
||
|
}
|
||
|
|
||
|
glEnd ();
|
||
|
break;
|
||
|
}
|
||
|
case (PLOT_HEX):
|
||
|
{
|
||
|
if (first)
|
||
|
{
|
||
|
h = 0.5*sqrt(3.0);
|
||
|
first = 0;
|
||
|
}
|
||
|
r = (double)size*0.5/h;
|
||
|
|
||
|
x = ((double)i + 0.75)*dsize;
|
||
|
if (j%2 == 1) x += 0.5*dsize;
|
||
|
y = h*dsize*((double)j + 1.0);
|
||
|
|
||
|
glBegin(GL_TRIANGLE_FAN);
|
||
|
glVertex2d(x, y);
|
||
|
for (k=0; k<7; k++)
|
||
|
{
|
||
|
alpha = (1.0 + 2.0*(double)k)*PI/6.0;
|
||
|
glVertex2d(x + r*cos(alpha), y + r*sin(alpha));
|
||
|
}
|
||
|
glEnd();
|
||
|
break;
|
||
|
}
|
||
|
case (PLOT_HEX_BONDS):
|
||
|
{
|
||
|
if (first)
|
||
|
{
|
||
|
h = 0.5*sqrt(3.0);
|
||
|
first = 0;
|
||
|
}
|
||
|
r = (double)size*0.5/h;
|
||
|
|
||
|
x = ((double)i + 0.75)*dsize;
|
||
|
if (j%2 == 1) x -= 0.5*dsize;
|
||
|
y = h*dsize*((double)j + 1.0);
|
||
|
|
||
|
glBegin(GL_LINES);
|
||
|
switch (group){
|
||
|
case (0): /* vertical bonds */
|
||
|
{
|
||
|
glVertex2d(x-0.5*dsize, y+0.5*r);
|
||
|
glVertex2d(x-0.5*dsize, y-0.5*r);
|
||
|
break;
|
||
|
}
|
||
|
case (1): /* NE-SW bonds */
|
||
|
{
|
||
|
glVertex2d(x, y-r);
|
||
|
glVertex2d(x+0.5*dsize, y-0.5*r);
|
||
|
break;
|
||
|
}
|
||
|
case (2): /* NW-SE bonds */
|
||
|
{
|
||
|
glVertex2d(x-0.5*dsize, y-0.5*r);
|
||
|
glVertex2d(x, y-r);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
glEnd();
|
||
|
break;
|
||
|
}
|
||
|
case (PLOT_TRIANGLE):
|
||
|
{
|
||
|
if (first)
|
||
|
{
|
||
|
h = 0.5*sqrt(3.0);
|
||
|
first = 0;
|
||
|
}
|
||
|
r = (double)size*0.5/h;
|
||
|
|
||
|
x = 0.5*((double)i + 1.25)*dsize;
|
||
|
y = h*dsize*((double)j);
|
||
|
|
||
|
printf("Drawing cell %i = (%i, %i) at (%.0f, %.0f)\n", c, i, j, x, y);
|
||
|
|
||
|
glBegin(GL_TRIANGLES);
|
||
|
if ((i+j)%2 == 1)
|
||
|
{
|
||
|
glVertex2d(x-0.5*dsize, y);
|
||
|
glVertex2d(x+0.5*dsize, y);
|
||
|
glVertex2d(x, y+h*dsize);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
glVertex2d(x-0.5*dsize, y+h*dsize);
|
||
|
glVertex2d(x+0.5*dsize, y+h*dsize);
|
||
|
glVertex2d(x, y);
|
||
|
}
|
||
|
glEnd();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void test_neighbours(int start, t_perco *cell, int nx, int ny, int size, int ncells)
|
||
|
/* for debugging puposes */
|
||
|
{
|
||
|
int i, k;
|
||
|
|
||
|
for (i=start; i<ncells; i++)
|
||
|
{
|
||
|
printf("Testing cell %i of %i - %i neighbours\n", i, ncells, cell[i].nneighb);
|
||
|
blank();
|
||
|
glColor3f(1.0, 0.0, 0.0);
|
||
|
draw_cell(i, nx, ny, size);
|
||
|
glColor3f(0.0, 0.0, 1.0);
|
||
|
for (k=0; k<cell[i].nneighb; k++) draw_cell(cell[i].nghb[k], nx, ny, size);
|
||
|
glutSwapBuffers();
|
||
|
sleep(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void draw_configuration(t_perco *cell, int *cluster_sizes, int nx, int ny, int size, int max_cluster_size)
|
||
|
/* draw the configuration */
|
||
|
{
|
||
|
int i, j, ishift, k;
|
||
|
double rgb[3], x, y, alpha, r, fade = 0, dsize;
|
||
|
static double h, h1;
|
||
|
static int first = 1;
|
||
|
|
||
|
dsize = (double)size;
|
||
|
|
||
|
switch (graphical_rep(LATTICE)) {
|
||
|
case (PLOT_SQUARES):
|
||
|
{
|
||
|
blank();
|
||
|
|
||
|
glBegin(GL_QUADS);
|
||
|
|
||
|
for (i=0; i<nx; i++)
|
||
|
for (j=0; j<ny; j++)
|
||
|
{
|
||
|
if ((ADD_PLOT)&&(in_plot_box((double)(i+1)*dsize, (double)(j)*dsize))) fade = 1;
|
||
|
else fade = 0;
|
||
|
|
||
|
set_cell_color(cell[i*ny+j], cluster_sizes, fade, max_cluster_size);
|
||
|
|
||
|
glVertex2i(i*size, j*size);
|
||
|
glVertex2i((i+1)*size, j*size);
|
||
|
glVertex2i((i+1)*size, (j+1)*size);
|
||
|
glVertex2i(i*size, (j+1)*size);
|
||
|
}
|
||
|
|
||
|
glEnd ();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case (PLOT_SQUARE_BONDS):
|
||
|
{
|
||
|
ishift = nx*(ny+1);
|
||
|
|
||
|
blank();
|
||
|
|
||
|
if (ADD_PLOT)
|
||
|
{
|
||
|
rgb[0] = 1.0; rgb[1] = 1.0; rgb[2] = 1.0;
|
||
|
erase_area_rgb(XMAX - 0.5, YMAX - 0.5, 0.5, 0.5, rgb);
|
||
|
}
|
||
|
|
||
|
if (size < 8) glLineWidth(1 + size/4);
|
||
|
else glLineWidth(3);
|
||
|
|
||
|
glBegin(GL_LINES);
|
||
|
|
||
|
/* horizontal segments */
|
||
|
for (i=0; i<nx; i++)
|
||
|
for (j=0; j<ny+1; j++)
|
||
|
{
|
||
|
if ((ADD_PLOT)&&(in_plot_box((double)(i+1)*dsize, (double)(j)*dsize))) fade = 1;
|
||
|
else fade = 0;
|
||
|
|
||
|
set_cell_color(cell[i+nx*j], cluster_sizes, fade, max_cluster_size);
|
||
|
|
||
|
glVertex2i(i*size, j*size);
|
||
|
glVertex2i((i+1)*size, j*size);
|
||
|
}
|
||
|
|
||
|
/* vertical segments */
|
||
|
for (i=0; i<nx+1; i++)
|
||
|
for (j=0; j<ny; j++)
|
||
|
{
|
||
|
if ((ADD_PLOT)&&(in_plot_box((double)(i+1)*dsize, (double)(j+1)*dsize))) fade = 1;
|
||
|
else fade = 0;
|
||
|
|
||
|
set_cell_color(cell[ishift+ny*i+j], cluster_sizes, fade, max_cluster_size);
|
||
|
|
||
|
glVertex2i(i*size, j*size);
|
||
|
glVertex2i(i*size, (j+1)*size);
|
||
|
}
|
||
|
|
||
|
glEnd ();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case (PLOT_HEX):
|
||
|
{
|
||
|
blank();
|
||
|
|
||
|
if (first)
|
||
|
{
|
||
|
h = 0.5*sqrt(3.0);
|
||
|
first = 0;
|
||
|
}
|
||
|
r = (double)size*0.5/h;
|
||
|
|
||
|
for (j=0; j<ny; j++)
|
||
|
for (i=0; i<nx; i++)
|
||
|
{
|
||
|
|
||
|
x = ((double)i + 0.75)*dsize;
|
||
|
if (j%2 == 1) x += 0.5*dsize;
|
||
|
y = h*dsize*((double)j + 1.0);
|
||
|
|
||
|
if ((ADD_PLOT)&&(in_plot_box(x, y))) fade = 1;
|
||
|
else fade = 0;
|
||
|
|
||
|
set_cell_color(cell[j*nx+i], cluster_sizes, fade, max_cluster_size);
|
||
|
|
||
|
glBegin(GL_TRIANGLE_FAN);
|
||
|
|
||
|
glVertex2d(x, y);
|
||
|
for (k=0; k<7; k++)
|
||
|
{
|
||
|
alpha = (1.0 + 2.0*(double)k)*PI/6.0;
|
||
|
glVertex2d(x + r*cos(alpha), y + r*sin(alpha));
|
||
|
}
|
||
|
glEnd();
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case (PLOT_HEX_BONDS):
|
||
|
{
|
||
|
blank();
|
||
|
|
||
|
ishift = nx*(ny+1);
|
||
|
|
||
|
if (first)
|
||
|
{
|
||
|
h = 0.5*sqrt(3.0);
|
||
|
first = 0;
|
||
|
}
|
||
|
r = (double)size*0.5/h;
|
||
|
|
||
|
if (ADD_PLOT)
|
||
|
{
|
||
|
rgb[0] = 1.0; rgb[1] = 1.0; rgb[2] = 1.0;
|
||
|
erase_area_rgb(XMAX - 0.5, YMAX - 0.5, 0.5, 0.5, rgb);
|
||
|
}
|
||
|
|
||
|
if (size < 8) glLineWidth(1 + size/4);
|
||
|
else glLineWidth(3);
|
||
|
|
||
|
glBegin(GL_LINES);
|
||
|
for (i=0; i<nx; i++)
|
||
|
for (j=0; j<ny; j++)
|
||
|
{
|
||
|
x = ((double)i + 0.5)*dsize;
|
||
|
if (j%2 == 1) x -= 0.5*dsize;
|
||
|
y = h*dsize*((double)j + 0.75);
|
||
|
|
||
|
if ((ADD_PLOT)&&(in_plot_box(x, y))) fade = 1;
|
||
|
else fade = 0;
|
||
|
|
||
|
/* vertical bonds */
|
||
|
if (j<ny-1)
|
||
|
{
|
||
|
set_cell_color(cell[i+nx*j], cluster_sizes, fade, max_cluster_size);
|
||
|
|
||
|
glVertex2d(x-0.5*dsize, y+0.5*r);
|
||
|
glVertex2d(x-0.5*dsize, y-0.5*r);
|
||
|
}
|
||
|
|
||
|
if ((ADD_PLOT)&&(in_plot_box(x, y-0.5*h*dsize))) fade = 1;
|
||
|
else fade = 0;
|
||
|
|
||
|
/* NW-SE bonds */
|
||
|
set_cell_color(cell[2*ishift + i+nx*j], cluster_sizes, fade, max_cluster_size);
|
||
|
|
||
|
glVertex2d(x-0.5*dsize, y-0.5*r);
|
||
|
glVertex2d(x, y-r);
|
||
|
|
||
|
if ((ADD_PLOT)&&(in_plot_box(x+0.5*dsize, y-0.5*h*dsize))) fade = 1;
|
||
|
else fade = 0;
|
||
|
|
||
|
/* NE-SW bonds */
|
||
|
set_cell_color(cell[ishift + i+nx*j], cluster_sizes, fade, max_cluster_size);
|
||
|
|
||
|
glVertex2d(x, y-r);
|
||
|
glVertex2d(x+0.5*dsize, y-0.5*r);
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
glEnd();
|
||
|
break;
|
||
|
}
|
||
|
case (PLOT_TRIANGLE):
|
||
|
{
|
||
|
blank();
|
||
|
|
||
|
if (first)
|
||
|
{
|
||
|
h = 0.5*sqrt(3.0);
|
||
|
h1 = 0.5/sqrt(3.0);
|
||
|
first = 0;
|
||
|
}
|
||
|
r = (double)size*0.5/h;
|
||
|
|
||
|
for (j=0; j<ny; j++)
|
||
|
for (i=0; i<2*nx; i++)
|
||
|
{
|
||
|
|
||
|
x = 0.5*((double)i + 1.25)*dsize;
|
||
|
y = h*dsize*((double)j);
|
||
|
|
||
|
if ((ADD_PLOT)&&(in_plot_box(x, y))) fade = 1;
|
||
|
else fade = 0;
|
||
|
|
||
|
set_cell_color(cell[2*j*nx+i], cluster_sizes, fade, max_cluster_size);
|
||
|
|
||
|
glBegin(GL_TRIANGLES);
|
||
|
if ((i+j)%2 == 1)
|
||
|
{
|
||
|
glVertex2d(x-0.5*dsize, y);
|
||
|
glVertex2d(x+0.5*dsize, y);
|
||
|
glVertex2d(x, y+h*dsize);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
glVertex2d(x-0.5*dsize, y+h*dsize);
|
||
|
glVertex2d(x+0.5*dsize, y+h*dsize);
|
||
|
glVertex2d(x, y);
|
||
|
}
|
||
|
glEnd();
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void print_p(double p)
|
||
|
{
|
||
|
char message[100];
|
||
|
double y = YMAX - 0.13, pos[2], rgb[3] = {1.0, 1.0, 1.0};
|
||
|
static double xleftbox, xlefttext, xrightbox, xrighttext;
|
||
|
static int first = 1;
|
||
|
|
||
|
if (first)
|
||
|
{
|
||
|
xleftbox = XMIN + 0.2;
|
||
|
xlefttext = xleftbox - 0.45;
|
||
|
if (PLOT_CLUSTER_HISTOGRAM) xrightbox = XMAX - 0.41;
|
||
|
else xrightbox = XMAX - 0.27;
|
||
|
xrighttext = xrightbox - 0.45;
|
||
|
first = 0;
|
||
|
}
|
||
|
|
||
|
if (!PLOT_CLUSTER_SIZE)
|
||
|
{
|
||
|
if (NX > 1280) erase_area_rgb(xrightbox, y + 0.025, 0.15, 0.05, rgb);
|
||
|
else erase_area_rgb(xrightbox, y + 0.025, 0.22, 0.05, rgb);
|
||
|
}
|
||
|
glColor3f(0.0, 0.0, 0.0);
|
||
|
if (NX > 1280) xy_to_pos(xrighttext + 0.35, y, pos);
|
||
|
else xy_to_pos(xrighttext + 0.3, y, pos);
|
||
|
sprintf(message, "p = %.4f", p);
|
||
|
write_text(pos[0], pos[1], message);
|
||
|
}
|
||
|
|
||
|
void print_nclusters(int nclusters)
|
||
|
{
|
||
|
char message[100];
|
||
|
double y = YMAX - 0.25, pos[2], rgb[3] = {1.0, 1.0, 1.0};
|
||
|
static double xleftbox, xlefttext, xrightbox, xrighttext;
|
||
|
static int first = 1;
|
||
|
|
||
|
if (first)
|
||
|
{
|
||
|
xleftbox = XMIN + 0.2;
|
||
|
xlefttext = xleftbox - 0.45;
|
||
|
xrightbox = XMAX - 0.31;
|
||
|
xrighttext = xrightbox - 0.48;
|
||
|
first = 0;
|
||
|
}
|
||
|
|
||
|
if (!PLOT_CLUSTER_SIZE)
|
||
|
{
|
||
|
if (NX > 1280) erase_area_rgb(xrightbox, y + 0.025, 0.18, 0.05, rgb);
|
||
|
else erase_area_rgb(xrightbox, y + 0.025, 0.25, 0.05, rgb);
|
||
|
}
|
||
|
glColor3f(0.0, 0.0, 0.0);
|
||
|
if (NX > 1280) xy_to_pos(xrighttext + 0.35, y, pos);
|
||
|
else xy_to_pos(xrighttext + 0.3, y, pos);
|
||
|
if (nclusters == 1) sprintf(message, "%i cluster", nclusters);
|
||
|
else sprintf(message, "%i clusters", nclusters);
|
||
|
write_text_fixedwidth(pos[0], pos[1], message);
|
||
|
}
|
||
|
|
||
|
void print_largest_cluster_size(int max_cluster_size)
|
||
|
{
|
||
|
char message[100];
|
||
|
double y = YMAX - 0.25, pos[2], rgb[3] = {1.0, 1.0, 1.0};
|
||
|
static double xleftbox, xlefttext, xrightbox, xrighttext;
|
||
|
static int first = 1;
|
||
|
|
||
|
if (first)
|
||
|
{
|
||
|
xleftbox = XMIN + 0.2;
|
||
|
xlefttext = xleftbox - 0.45;
|
||
|
xrightbox = XMAX - 0.41;
|
||
|
xrighttext = xrightbox - 0.48;
|
||
|
first = 0;
|
||
|
}
|
||
|
|
||
|
if (!PLOT_CLUSTER_SIZE)
|
||
|
{
|
||
|
if (NX > 1280) erase_area_rgb(xrightbox, y + 0.025, 0.18, 0.05, rgb);
|
||
|
else erase_area_rgb(xrightbox, y + 0.025, 0.25, 0.05, rgb);
|
||
|
}
|
||
|
glColor3f(0.0, 0.0, 0.0);
|
||
|
if (NX > 1280) xy_to_pos(xrighttext + 0.35, y, pos);
|
||
|
else xy_to_pos(xrighttext + 0.3, y, pos);
|
||
|
sprintf(message, "max size %i", max_cluster_size);
|
||
|
write_text_fixedwidth(pos[0], pos[1], message);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*********************/
|
||
|
/* animation part */
|
||
|
/*********************/
|
||
|
|
||
|
int cell_number(int nx, int ny)
|
||
|
/* total number of cells in graph */
|
||
|
{
|
||
|
switch (LATTICE) {
|
||
|
case (BC_SQUARE_DIRICHLET): return(nx*ny);
|
||
|
case (BC_SQUARE_PERIODIC): return(nx*ny);
|
||
|
case (BC_SQUARE_BOND_DIRICHLET): return(2*nx*ny + nx + ny);
|
||
|
case (BC_HEX_SITE_DIRICHLET): return((int)((double)(nx*ny)*2.0/sqrt(3.0))); /* hex lattice requires more vertical space! */
|
||
|
case (BC_HEX_BOND_DIRICHLET): return(3*(int)((double)((nx+2)*(ny+2))*2.0/sqrt(3.0)));
|
||
|
/* hex lattice requires more vertical space! */
|
||
|
case (BC_TRIANGLE_SITE_DIRICHLET): return((int)((double)(2*nx*ny)*2.0/sqrt(3.0))); /* triangle lattice requires more vertical space! */
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void compute_nxny(int size, int *nx, int *ny)
|
||
|
/* compute the number of rows and columns depending on lattice */
|
||
|
{
|
||
|
switch (LATTICE) {
|
||
|
case (BC_HEX_SITE_DIRICHLET):
|
||
|
{
|
||
|
*nx = NX/size - 1;
|
||
|
*ny = (int)((double)NY*2.0/((double)size*sqrt(3.0)));
|
||
|
break;
|
||
|
}
|
||
|
case (BC_HEX_BOND_DIRICHLET):
|
||
|
{
|
||
|
*nx = NX/size + 1;
|
||
|
*ny = (int)((double)NY*2.0/((double)size*sqrt(3.0))) + 1;
|
||
|
break;
|
||
|
}
|
||
|
case (BC_TRIANGLE_SITE_DIRICHLET):
|
||
|
{
|
||
|
*nx = NX/size - 1;
|
||
|
*ny = (int)((double)NY*2.0/((double)size*sqrt(3.0))) + 1;
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
{
|
||
|
*nx = NX/size;
|
||
|
*ny = NY/size;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
int init_cell_lattice(t_perco *cell, int nx, int ny)
|
||
|
/* initialize the graph of connected cells - returns the number of cells */
|
||
|
{
|
||
|
int i, j, iplus, iminus, ishift, n;
|
||
|
|
||
|
printf("Initializing cell lattice ...");
|
||
|
|
||
|
switch (LATTICE) {
|
||
|
case (BC_SQUARE_DIRICHLET):
|
||
|
{
|
||
|
/* neighbours in the bulk */
|
||
|
#pragma omp parallel for private(i,j)
|
||
|
for (i=1; i<nx-1; i++){
|
||
|
for (j=1; j<ny-1; j++){
|
||
|
n = cellnb(i, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 4;
|
||
|
cell[n].nghb[0] = cellnb(i+1, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i-1, j, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i, j+1, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i, j-1, 0, nx, ny);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* left boundary */
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=1; j<ny-1; j++)
|
||
|
{
|
||
|
n = cellnb(0, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(1, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(0, j+1, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(0, j-1, 0, nx, ny);
|
||
|
}
|
||
|
/* right boundary */
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=1; j<ny-1; j++)
|
||
|
{
|
||
|
n = cellnb(nx-1, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(nx-2, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(nx-1, j+1, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(nx-1, j-1, 0, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* top boundary */
|
||
|
#pragma omp parallel for private(i)
|
||
|
for (i=1; i<nx-1; i++)
|
||
|
{
|
||
|
n = cellnb(i, ny-1, 0, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(i+1, ny-1, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i-1, ny-1, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i, ny-2, 0, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* bottom boundary */
|
||
|
#pragma omp parallel for private(i)
|
||
|
for (i=1; i<nx-1; i++)
|
||
|
{
|
||
|
n = cellnb(i, 0, 0, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(i+1, 0, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i-1, 0, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i, 1, 0, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* corners */
|
||
|
n = cellnb(0, 0, 0, nx, ny);
|
||
|
cell[n].nneighb = 2;
|
||
|
cell[n].nghb[0] = cellnb(1, 0, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(0, 1, 0, nx, ny);
|
||
|
|
||
|
n = cellnb(0, ny-1, 0, nx, ny);
|
||
|
cell[n].nneighb = 2;
|
||
|
cell[n].nghb[0] = cellnb(0, ny-2, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(1, ny-1, 0, nx, ny);
|
||
|
|
||
|
n = cellnb(nx-1, 0, 0, nx, ny);
|
||
|
cell[n].nneighb = 2;
|
||
|
cell[n].nghb[0] = cellnb(nx-1, 1, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(nx-2, 0, 0, nx, ny);
|
||
|
|
||
|
n = cellnb(nx-1, ny-1, 0, nx, ny);
|
||
|
cell[n].nneighb = 2;
|
||
|
cell[n].nghb[0] = cellnb(nx-1, ny-2, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(nx-2, ny-1, 0, nx, ny);
|
||
|
|
||
|
return(nx*ny);
|
||
|
break;
|
||
|
}
|
||
|
case (BC_SQUARE_PERIODIC):
|
||
|
{
|
||
|
/* neighbours in the bulk */
|
||
|
#pragma omp parallel for private(i,j)
|
||
|
for (i=1; i<nx-1; i++){
|
||
|
for (j=1; j<ny-1; j++){
|
||
|
n = cellnb(i, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 4;
|
||
|
cell[n].nghb[0] = cellnb(i+1, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i-1, j, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i, j+1, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i, j-1, 0, nx, ny);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* left boundary */
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=1; j<ny-1; j++)
|
||
|
{
|
||
|
n = cellnb(0, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 4;
|
||
|
cell[n].nghb[0] = cellnb(1, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(nx-1, j, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(0, j+1, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(0, j+1, 0, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* right boundary */
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=1; j<ny-1; j++)
|
||
|
{
|
||
|
n = cellnb(nx-1, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 4;
|
||
|
cell[n].nghb[0] = cellnb(nx-2, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(0, j, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(nx-1, j+1, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(nx-1, j-1, 0, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* top boundary */
|
||
|
#pragma omp parallel for private(i,iplus,iminus)
|
||
|
for (i=0; i<nx; i++)
|
||
|
{
|
||
|
n = cellnb(i, ny-1, 0, nx, ny);
|
||
|
iplus = (i+1) % nx;
|
||
|
iminus = (i-1) % nx;
|
||
|
if (iminus < 0) iminus += nx;
|
||
|
|
||
|
cell[n].nneighb = 4;
|
||
|
cell[n].nghb[0] = cellnb(iplus, ny-1, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(iminus, ny-1, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i, ny-2, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i, 0, 0, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* bottom boundary */
|
||
|
#pragma omp parallel for private(i,iplus,iminus)
|
||
|
for (i=0; i<nx; i++)
|
||
|
{
|
||
|
n = cellnb(i, 0, 0, nx, ny);
|
||
|
iplus = (i+1) % nx;
|
||
|
iminus = (i-1) % nx;
|
||
|
if (iminus < 0) iminus += nx;
|
||
|
|
||
|
cell[n].nneighb = 4;
|
||
|
cell[n].nghb[0] = cellnb(iplus, 0, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(iminus, 0, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i, 1, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i, ny-1, 0, nx, ny);
|
||
|
}
|
||
|
|
||
|
return(nx*ny);
|
||
|
break;
|
||
|
}
|
||
|
case (BC_SQUARE_BOND_DIRICHLET):
|
||
|
{
|
||
|
ishift = nx*(ny+1);
|
||
|
|
||
|
/* horizontal bonds */
|
||
|
/* neighbours in the bulk */
|
||
|
#pragma omp parallel for private(i,j)
|
||
|
for (i=1; i<nx-1; i++){
|
||
|
for (j=1; j<ny; j++){
|
||
|
n = cellnb(i, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 6;
|
||
|
cell[n].nghb[0] = cellnb(i+1, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i-1, j, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i, j-1, 1, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i, j, 1, nx, ny);
|
||
|
cell[n].nghb[4] = cellnb(i+1, j-1, 1, nx, ny);
|
||
|
cell[n].nghb[5] = cellnb(i+1, j, 1, nx, ny);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* bottom boundary */
|
||
|
#pragma omp parallel for private(i)
|
||
|
for (i=1; i<nx-1; i++)
|
||
|
{
|
||
|
n = cellnb(i, 0, 0, nx, ny);
|
||
|
cell[n].nneighb = 4;
|
||
|
cell[n].nghb[0] = cellnb(i+1, 0, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i-1, 0, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i, 0, 1, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i+1, 0, 1, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* top boundary */
|
||
|
#pragma omp parallel for private(i)
|
||
|
for (i=1; i<nx-1; i++)
|
||
|
{
|
||
|
n = cellnb(i, ny, 0, nx, ny);
|
||
|
cell[n].nneighb = 4;
|
||
|
cell[n].nghb[0] = cellnb(i+1, ny, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i-1, ny, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i, ny-1, 1, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i+1, ny-1, 1, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* left boundary */
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=1; j<ny; j++){
|
||
|
n = cellnb(0, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 5;
|
||
|
cell[n].nghb[0] = cellnb(1, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(0, j-1, 1, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(0, j, 1, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(1, j-1, 1, nx, ny);
|
||
|
cell[n].nghb[4] = cellnb(1, j, 1, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* right boundary */
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=1; j<ny; j++){
|
||
|
n = cellnb(nx-1, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 5;
|
||
|
cell[n].nghb[0] = cellnb(nx-2, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(nx-1, j-1, 1, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(nx-1, j, 1, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(nx, j-1, 1, nx, ny);
|
||
|
cell[n].nghb[4] = cellnb(nx, j, 1, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* corners */
|
||
|
n = cellnb(0, 0, 0, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(1, 0, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(0, 0, 1, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(1, 0, 1, nx, ny);
|
||
|
|
||
|
n = cellnb(nx-1, 0, 0, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(nx-2, 0, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(nx-1, 0, 1, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(nx, 0, 1, nx, ny);
|
||
|
|
||
|
n = cellnb(0, ny, 0, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(1, ny, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(0, ny-1, 1, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(1, ny-1, 1, nx, ny);
|
||
|
|
||
|
n = cellnb(nx-1, ny, 0, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(nx-2, ny, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(nx-1, ny-1, 1, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(nx, ny-1, 1, nx, ny);
|
||
|
|
||
|
/* vertical bonds */
|
||
|
/* neighbours in the bulk */
|
||
|
#pragma omp parallel for private(i,j)
|
||
|
for (i=1; i<nx; i++){
|
||
|
for (j=1; j<ny-1; j++){
|
||
|
n = cellnb(i, j, 1, nx, ny);
|
||
|
cell[n].nneighb = 6;
|
||
|
cell[n].nghb[0] = cellnb(i, j-1, 1, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i, j+1, 1, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i, j, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i-1, j, 0, nx, ny);
|
||
|
cell[n].nghb[4] = cellnb(i, j+1, 0, nx, ny);
|
||
|
cell[n].nghb[5] = cellnb(i-1, j+1, 0, nx, ny);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* left boundary */
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=1; j<ny-1; j++){
|
||
|
n = cellnb(0, j, 1, nx, ny);
|
||
|
cell[n].nneighb = 4;
|
||
|
cell[n].nghb[0] = cellnb(0, j-1, 1, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(0, j+1, 1, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(0, j, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(0, j+1, 0, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* right boundary */
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=1; j<ny-1; j++){
|
||
|
n = cellnb(nx, j, 1, nx, ny);
|
||
|
cell[n].nneighb = 4;
|
||
|
cell[n].nghb[0] = cellnb(nx, j-1, 1, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(nx, j+1, 1, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(nx-1, j, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(nx-1, j+1, 0, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* bottom boundary */
|
||
|
#pragma omp parallel for private(i)
|
||
|
for (i=1; i<nx; i++){
|
||
|
n = cellnb(i, 0, 1, nx, ny);
|
||
|
cell[n].nneighb = 5;
|
||
|
cell[n].nghb[0] = cellnb(i, 1, 1, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i-1, 0, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i, 0, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i-1, 1, 0, nx, ny);
|
||
|
cell[n].nghb[4] = cellnb(i, 1, 0, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* top boundary */
|
||
|
#pragma omp parallel for private(i)
|
||
|
for (i=1; i<nx; i++){
|
||
|
n = cellnb(i, ny-1, 1, nx, ny);
|
||
|
cell[n].nneighb = 5;
|
||
|
cell[n].nghb[0] = cellnb(i, ny-2, 1, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i-1, ny-1, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i, ny-1, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i-1, ny, 0, nx, ny);
|
||
|
cell[n].nghb[4] = cellnb(i, ny, 0, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* corners */
|
||
|
n = cellnb(0, 0, 1, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(0, 1, 1, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(0, 0, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(0, 1, 0, nx, ny);
|
||
|
|
||
|
n = cellnb(0, ny-1, 1, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(0, ny-2, 1, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(0, ny-1, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(0, ny, 0, nx, ny);
|
||
|
|
||
|
n = cellnb(nx, 0, 1, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(nx, 1, 1, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(nx-1, 0, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(nx-1, 1, 0, nx, ny);
|
||
|
|
||
|
n = cellnb(nx, ny-1, 1, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(nx, ny-2, 1, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(nx-1, ny, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(nx-1, ny-1, 0, nx, ny);
|
||
|
|
||
|
return(nx + ny + 2*nx*ny);
|
||
|
break;
|
||
|
}
|
||
|
case (BC_HEX_SITE_DIRICHLET):
|
||
|
{
|
||
|
/* neighbours in the bulk */
|
||
|
#pragma omp parallel for private(i,j)
|
||
|
for (i=1; i<nx-1; i++){
|
||
|
for (j=1; j<ny-1; j+=2){
|
||
|
n = cellnb(i, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 6;
|
||
|
cell[n].nghb[0] = cellnb(i+1, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i-1, j, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i+1, j+1, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i, j+1, 0, nx, ny);
|
||
|
cell[n].nghb[4] = cellnb(i+1, j-1,0, nx, ny);
|
||
|
cell[n].nghb[5] = cellnb(i, j-1, 0, nx, ny);
|
||
|
}
|
||
|
}
|
||
|
#pragma omp parallel for private(i,j)
|
||
|
for (i=1; i<nx-1; i++){
|
||
|
for (j=2; j<ny-1; j+=2){
|
||
|
n = cellnb(i, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 6;
|
||
|
cell[n].nghb[0] = cellnb(i+1, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i-1, j, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i-1, j+1, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i, j+1, 0, nx, ny);
|
||
|
cell[n].nghb[4] = cellnb(i-1, j-1,0, nx, ny);
|
||
|
cell[n].nghb[5] = cellnb(i, j-1, 0, nx, ny);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* left boundary */
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=1; j<ny-1; j+=2){
|
||
|
n = cellnb(0, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 5;
|
||
|
cell[n].nghb[0] = cellnb(1, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(0, j+1, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(1, j+1, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(0, j-1, 0, nx, ny);
|
||
|
cell[n].nghb[4] = cellnb(1, j-1, 0, nx, ny);
|
||
|
}
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=2; j<ny-1; j+=2){
|
||
|
n = cellnb(0, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(1, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(0, j+1, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(0, j-1, 0, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* right boundary */
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=1; j<ny-1; j+=2){
|
||
|
n = cellnb(nx-1, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(nx-2, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(nx-1, j+1, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(nx-1, j-1, 0, nx, ny);
|
||
|
}
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=2; j<ny-1; j+=2){
|
||
|
n = cellnb(nx-1, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 5;
|
||
|
cell[n].nghb[0] = cellnb(nx-2, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(nx-2, j+1, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(nx-1, j+1, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(nx-2, j-1, 0, nx, ny);
|
||
|
cell[n].nghb[4] = cellnb(nx-1, j-1, 0, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* bottom boundary */
|
||
|
#pragma omp parallel for private(i)
|
||
|
for (i=1; i<nx-1; i++){
|
||
|
n = cellnb(i, 0, 0, nx, ny);
|
||
|
cell[n].nneighb = 4;
|
||
|
cell[n].nghb[0] = cellnb(i+1, 0, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i-1, 0, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i-1, 1, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i, 1, 0, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* top boundary */
|
||
|
#pragma omp parallel for private(i)
|
||
|
for (i=1; i<nx-1; i++){
|
||
|
n = cellnb(i, ny-1, 0, nx, ny);
|
||
|
cell[n].nneighb = 4;
|
||
|
cell[n].nghb[0] = cellnb(i+1, ny-1, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i-1, ny-1, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i-1, ny-2, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i, ny-2, 0, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* corners */
|
||
|
n = cellnb(0, 0, 0, nx, ny);
|
||
|
cell[n].nneighb = 2;
|
||
|
cell[n].nghb[0] = cellnb(1, 0, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(0, 1, 0, nx, ny);
|
||
|
|
||
|
n = cellnb(nx-1, 0, 0, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(nx-2, 0, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(nx-1, 1, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(nx-2, 1, 0, nx, ny);
|
||
|
|
||
|
n = cellnb(0, ny-1, 0, nx, ny);
|
||
|
cell[n].nneighb = 2;
|
||
|
cell[n].nghb[0] = cellnb(1, ny-1, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(0, ny-2, 0, nx, ny);
|
||
|
|
||
|
n = cellnb(nx-1, ny-1, 0, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(nx-2, ny-1, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(nx-1, ny-2, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(nx-2, ny-2, 0, nx, ny);
|
||
|
|
||
|
return(nx*ny);
|
||
|
break;
|
||
|
}
|
||
|
case (BC_HEX_BOND_DIRICHLET):
|
||
|
{
|
||
|
/* neighbours in the bulk */
|
||
|
/* vertical bonds */
|
||
|
#pragma omp parallel for private(i,j)
|
||
|
for (i=1; i<nx; i++){
|
||
|
for (j=1; j<ny; j+=2){
|
||
|
n = cellnb(i, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 4;
|
||
|
cell[n].nghb[0] = cellnb(i-1, j, 1, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i, j, 2, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i-1, j+1, 1, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i-1, j+1, 2, nx, ny);
|
||
|
}
|
||
|
}
|
||
|
#pragma omp parallel for private(i,j)
|
||
|
for (i=1; i<nx; i++){
|
||
|
for (j=0; j<ny; j+=2){
|
||
|
n = cellnb(i, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 4;
|
||
|
cell[n].nghb[0] = cellnb(i-1, j, 1, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i, j, 2, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i, j+1, 1, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i, j+1, 2, nx, ny);
|
||
|
}
|
||
|
}
|
||
|
/* NE-SW bonds */
|
||
|
#pragma omp parallel for private(i,j)
|
||
|
for (i=0; i<nx-1; i++){
|
||
|
for (j=1; j<ny-1; j+=2){
|
||
|
n = cellnb(i, j, 1, nx, ny);
|
||
|
cell[n].nneighb = 4;
|
||
|
cell[n].nghb[0] = cellnb(i+1, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i+1, j, 2, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i, j-1, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i, j, 2, nx, ny);
|
||
|
}
|
||
|
}
|
||
|
#pragma omp parallel for private(i,j)
|
||
|
for (i=0; i<nx-1; i++){
|
||
|
for (j=2; j<ny-1; j+=2){
|
||
|
n = cellnb(i, j, 1, nx, ny);
|
||
|
cell[n].nneighb = 4;
|
||
|
cell[n].nghb[0] = cellnb(i+1, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i+1, j, 2, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i+1, j-1, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i, j, 2, nx, ny);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* NW-SE bonds */
|
||
|
#pragma omp parallel for private(i,j)
|
||
|
for (i=1; i<nx-1; i++){
|
||
|
for (j=1; j<ny-1; j+=2){
|
||
|
n = cellnb(i, j, 2, nx, ny);
|
||
|
cell[n].nneighb = 4;
|
||
|
cell[n].nghb[0] = cellnb(i, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i, j, 1, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i, j-1, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i-1, j, 1, nx, ny);
|
||
|
}
|
||
|
}
|
||
|
#pragma omp parallel for private(i,j)
|
||
|
for (i=0; i<nx; i++){
|
||
|
for (j=2; j<ny-1; j+=2){
|
||
|
n = cellnb(i, j, 2, nx, ny);
|
||
|
cell[n].nneighb = 4;
|
||
|
cell[n].nghb[0] = cellnb(i, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i, j, 1, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i+1, j-1, 0, nx, ny);
|
||
|
cell[n].nghb[3] = cellnb(i-1, j, 1, nx, ny);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* left boundary */
|
||
|
/* vertical bonds */
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=0; j<ny; j+=2)
|
||
|
{
|
||
|
n = cellnb(0, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 2;
|
||
|
cell[n].nghb[0] = cellnb(0, j, 2, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(0, j+1, 1, nx, ny);
|
||
|
}
|
||
|
/* NE-SW bonds */
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=1; j<ny-1; j+=2)
|
||
|
{
|
||
|
n = cellnb(0, j, 1, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(1, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(0, j-1, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(1, j, 2, nx, ny);
|
||
|
}
|
||
|
/* NW-SE bonds */
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=2; j<ny-1; j+=2)
|
||
|
{
|
||
|
n = cellnb(0, j, 2, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(0, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(1, j-1, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(0, j, 1, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* right boundary */
|
||
|
/* vertical bonds */
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=0; j<ny; j+=2)
|
||
|
{
|
||
|
n = cellnb(nx-1, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 2;
|
||
|
cell[n].nghb[0] = cellnb(nx-1, j+1, 2, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(nx-2, j, 1, nx, ny);
|
||
|
}
|
||
|
/* NE-SW bonds */
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=1; j<ny-1; j+=2)
|
||
|
{
|
||
|
n = cellnb(nx-1, j, 1, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(nx, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(nx-1, j-1, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(nx-1, j, 2, nx, ny);
|
||
|
}
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=2; j<ny-1; j+=2)
|
||
|
{
|
||
|
n = cellnb(nx-1, j, 1, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(nx, j, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(nx, j, 2, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(nx, j-1, 0, nx, ny);
|
||
|
}
|
||
|
/* NW-SE bonds */
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=1; j<ny-1; j+=2)
|
||
|
{
|
||
|
n = cellnb(nx-1, j, 2, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(nx-1, j-1, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(nx-1, j, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(nx-2, j, 1, nx, ny);
|
||
|
}
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=2; j<ny-1; j+=2)
|
||
|
{
|
||
|
n = cellnb(nx-1, j, 2, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(nx-1, j-1, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(nx-1, j, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(nx-2, j, 1, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* bottom boundary */
|
||
|
/* NE-SW bonds */
|
||
|
#pragma omp parallel for private(i)
|
||
|
for (i=1; i<nx-1; i++)
|
||
|
{
|
||
|
n = cellnb(i, 0, 1, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(i+1, 0, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i, 0, 2, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i+1, 0, 2, nx, ny);
|
||
|
}
|
||
|
/* NW-SE bonds */
|
||
|
#pragma omp parallel for private(i)
|
||
|
for (i=1; i<nx-1; i++)
|
||
|
{
|
||
|
n = cellnb(i, 0, 2, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(i, 0, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i-1, 0, 1, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i, 0, 1, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* top boundary */
|
||
|
/* vertical bonds */
|
||
|
#pragma omp parallel for private(i)
|
||
|
for (i=1; i<nx-1; i++)
|
||
|
{
|
||
|
n = cellnb(i, ny-1, 0, nx, ny);
|
||
|
cell[n].nneighb = 2;
|
||
|
cell[n].nghb[0] = cellnb(i-1, ny-1, 1, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i, ny-1, 2, nx, ny);
|
||
|
}
|
||
|
/* NE-SW bonds */
|
||
|
#pragma omp parallel for private(i)
|
||
|
for (i=1; i<nx-1; i++)
|
||
|
{
|
||
|
n = cellnb(i, ny-1, 1, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(i+1, ny-1, 2, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i, ny-1, 2, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i+1, ny-2, 0, nx, ny);
|
||
|
}
|
||
|
/* NW-SE bonds */
|
||
|
#pragma omp parallel for private(i)
|
||
|
for (i=1; i<nx-1; i++)
|
||
|
{
|
||
|
n = cellnb(i, ny-1, 2, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(i-1, ny-1, 1, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i, ny-1, 1, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i+1, ny-2, 0, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* corners */
|
||
|
n = cellnb(0, 0, 2, nx, ny);
|
||
|
cell[n].nneighb = 2;
|
||
|
cell[n].nghb[0] = cellnb(0, 0, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(0, 0, 1, nx, ny);
|
||
|
|
||
|
return(3*(nx+1)*(ny+1)); /* TO BE CHECKED */
|
||
|
break;
|
||
|
}
|
||
|
case (BC_TRIANGLE_SITE_DIRICHLET):
|
||
|
{
|
||
|
/* neighbours in the bulk */
|
||
|
#pragma omp parallel for private(i,j)
|
||
|
for (i=1; i<2*nx-1; i++){
|
||
|
for (j=1; j<ny-1; j++){
|
||
|
n = cellnb(i, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(i+1,j,0,nx,ny);
|
||
|
cell[n].nghb[1] = cellnb(i-1,j,0,nx,ny);
|
||
|
if ((i+j)%2 == 0) cell[n].nghb[2] = cellnb(i,j+1,0,nx,ny);
|
||
|
else cell[n].nghb[2] = cellnb(i,j-1,0,nx,ny);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* left boundary */
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=0; j<ny; j++){
|
||
|
n = cellnb(0, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 2;
|
||
|
cell[n].nghb[0] = cellnb(1, j, 0, nx, ny);
|
||
|
if (j%2 == 0) cell[n].nghb[1] = cellnb(0, j+1, 0, nx, ny);
|
||
|
else cell[n].nghb[1] = cellnb(0, j-1, 0, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* right boundary */
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=1; j<ny-1; j++){
|
||
|
n = cellnb(2*nx-1, j, 0, nx, ny);
|
||
|
cell[n].nneighb = 2;
|
||
|
cell[n].nghb[0] = cellnb(2*nx-2, j, 0, nx, ny);
|
||
|
if (j%2 == 1) cell[n].nghb[1] = cellnb(2*nx-1, j+1, 0, nx, ny);
|
||
|
else cell[n].nghb[1] = cellnb(2*nx-1, j-1, 0, nx, ny);
|
||
|
}
|
||
|
|
||
|
/* bottom boundary */
|
||
|
#pragma omp parallel for private(i,j)
|
||
|
for (i=1; i<2*nx-1; i++){
|
||
|
n = cellnb(i, 0, 0, nx, ny);
|
||
|
if (i%2 == 0)
|
||
|
{
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(i-1, 0, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i+1, 0, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i, 1, 0, nx, ny);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cell[n].nneighb = 2;
|
||
|
cell[n].nghb[0] = cellnb(i+1, 0, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i-1, 0, 0, nx, ny);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* top boundary */
|
||
|
#pragma omp parallel for private(i,j)
|
||
|
for (i=1; i<2*nx-1; i++){
|
||
|
n = cellnb(i, ny-1, 0, nx, ny);
|
||
|
if (i%2 == 1)
|
||
|
{
|
||
|
cell[n].nneighb = 3;
|
||
|
cell[n].nghb[0] = cellnb(i-1, ny-1, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i+1, ny-1, 0, nx, ny);
|
||
|
cell[n].nghb[2] = cellnb(i, ny-2, 0, nx, ny);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cell[n].nneighb = 2;
|
||
|
cell[n].nghb[0] = cellnb(i-1, ny-1, 0, nx, ny);
|
||
|
cell[n].nghb[1] = cellnb(i+1, ny-1, 0, nx, ny);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/* corners (at the right) */
|
||
|
n = cellnb(2*nx-1, 0, 0, nx, ny);
|
||
|
cell[n].nneighb = 1;
|
||
|
cell[n].nghb[0] = cellnb(2*nx-2, 0, 0, nx, ny);
|
||
|
|
||
|
n = cellnb(2*nx-1, ny-1, 0, nx, ny);
|
||
|
cell[n].nneighb = 1;
|
||
|
cell[n].nghb[0] = cellnb(2*nx-2, ny-1, 0, nx, ny);
|
||
|
|
||
|
|
||
|
return(2*nx*ny);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
printf("Done\n");
|
||
|
}
|
||
|
|
||
|
|
||
|
void init_cell_probabilities(t_perco *cell, int ncells)
|
||
|
/* initialize the probabilities of cells being open */
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
printf("Initializing cell probabilities ...");
|
||
|
#pragma omp parallel for private(i)
|
||
|
for (i=0; i<ncells; i++)
|
||
|
{
|
||
|
cell[i].proba = (double)rand()/RAND_MAX;
|
||
|
}
|
||
|
printf("Done\n");
|
||
|
}
|
||
|
|
||
|
void init_cell_state(t_perco *cell, double p, int ncells, int first)
|
||
|
/* initialize the probabilities of cells being open */
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
printf("Initializing cell state ...");
|
||
|
#pragma omp parallel for private(i)
|
||
|
for (i=0; i<ncells; i++)
|
||
|
{
|
||
|
if (cell[i].proba < p)
|
||
|
{
|
||
|
cell[i].open = 1;
|
||
|
cell[i].active = 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cell[i].open = 0;
|
||
|
cell[i].active = 0;
|
||
|
}
|
||
|
cell[i].flooded = 0;
|
||
|
if (first) cell[i].previous_cluster = 0;
|
||
|
else cell[i].previous_cluster = cell[i].cluster;
|
||
|
cell[i].cluster = 0;
|
||
|
cell[i].tested = 0;
|
||
|
}
|
||
|
printf("Done\n");
|
||
|
}
|
||
|
|
||
|
int init_flooded_cells(t_perco *cell, int nx, int ny, t_perco* *pstack)
|
||
|
/* make the left row of cells flooded, returns number of flooded cells */
|
||
|
{
|
||
|
int j, ishift;
|
||
|
|
||
|
// printf("Initializing flooded cells ...");
|
||
|
switch (graphical_rep(LATTICE)) {
|
||
|
case (PLOT_SQUARES):
|
||
|
{
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=0; j<ny; j++)
|
||
|
{
|
||
|
cell[j].open = 1;
|
||
|
cell[j].flooded = 1;
|
||
|
cell[j].cluster = 1;
|
||
|
cell[j].previous_cluster = 1;
|
||
|
cell[j].active = 1;
|
||
|
pstack[j] = &cell[j];
|
||
|
}
|
||
|
return(ny);
|
||
|
}
|
||
|
case (PLOT_SQUARE_BONDS):
|
||
|
{
|
||
|
ishift = nx*(ny+1);
|
||
|
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=0; j<ny; j++)
|
||
|
{
|
||
|
cell[ishift + j].open = 1;
|
||
|
cell[ishift + j].flooded = 1;
|
||
|
cell[ishift + j].cluster = 1;
|
||
|
cell[ishift + j].previous_cluster = 1;
|
||
|
cell[ishift + j].active = 1;
|
||
|
pstack[j] = &cell[ishift + j];
|
||
|
}
|
||
|
return(ny);
|
||
|
}
|
||
|
case (PLOT_HEX):
|
||
|
{
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=0; j<ny; j++)
|
||
|
{
|
||
|
cell[j*nx].open = 1;
|
||
|
cell[j*nx].flooded = 1;
|
||
|
cell[j*nx].cluster = 1;
|
||
|
cell[j*nx].previous_cluster = 1;
|
||
|
cell[j*nx].active = 1;
|
||
|
pstack[j] = &cell[j*nx];
|
||
|
}
|
||
|
return(ny);
|
||
|
}
|
||
|
case (PLOT_HEX_BONDS):
|
||
|
{
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=0; j<ny; j+=2)
|
||
|
{
|
||
|
cell[j*nx].open = 1;
|
||
|
cell[j*nx].flooded = 1;
|
||
|
cell[j*nx].cluster = 1;
|
||
|
cell[j*nx].previous_cluster = 1;
|
||
|
cell[j*nx].active = 1;
|
||
|
pstack[j] = &cell[j*nx];
|
||
|
}
|
||
|
return(ny);
|
||
|
}
|
||
|
case (PLOT_TRIANGLE):
|
||
|
{
|
||
|
#pragma omp parallel for private(j)
|
||
|
for (j=0; j<ny; j++)
|
||
|
{
|
||
|
cell[2*j*nx].open = 1;
|
||
|
cell[2*j*nx].flooded = 1;
|
||
|
cell[2*j*nx].cluster = 1;
|
||
|
cell[2*j*nx].previous_cluster = 1;
|
||
|
cell[2*j*nx].active = 1;
|
||
|
pstack[j] = &cell[2*j*nx];
|
||
|
}
|
||
|
return(ny);
|
||
|
}
|
||
|
}
|
||
|
// printf("Done\n");
|
||
|
}
|
||
|
|
||
|
|
||
|
int count_open_cells(t_perco *cell, int ncells)
|
||
|
/* count the number of active cells */
|
||
|
{
|
||
|
int n = 0, i;
|
||
|
|
||
|
for (i=0; i<ncells; i++) if (cell[i].open) n++;
|
||
|
return(n);
|
||
|
}
|
||
|
|
||
|
int count_flooded_cells(t_perco *cell, int ncells)
|
||
|
/* count the number of active cells */
|
||
|
{
|
||
|
int n = 0, i;
|
||
|
|
||
|
for (i=0; i<ncells; i++) if ((cell[i].open)&&(cell[i].flooded)) n++;
|
||
|
return(n);
|
||
|
}
|
||
|
|
||
|
int count_active_cells(t_perco *cell, int ncells)
|
||
|
/* count the number of active cells */
|
||
|
{
|
||
|
int n = 0, i;
|
||
|
|
||
|
for (i=0; i<ncells; i++)
|
||
|
if ((cell[i].active)&&(cell[i].flooded)) n++;
|
||
|
|
||
|
return(n);
|
||
|
}
|
||
|
|
||
|
|
||
|
int find_open_cells(t_perco *cell, int ncells, int position, t_perco* *pstack, int *stacksize, int cluster)
|
||
|
/* look for open neighbours of start_cell, returns difference in open cells */
|
||
|
{
|
||
|
int k, nopen = 0, n;
|
||
|
|
||
|
// printf("Position %i, open %i\n", position, pstack[position]->open);
|
||
|
|
||
|
if (!pstack[position]->open) return(-1);
|
||
|
|
||
|
pstack[position]->cluster = cluster;
|
||
|
|
||
|
for (k=0; k<pstack[position]->nneighb; k++)
|
||
|
{
|
||
|
n = pstack[position]->nghb[k];
|
||
|
if ((cell[n].open)&&(cell[n].cluster != cluster))
|
||
|
{
|
||
|
cell[n].flooded = 1;
|
||
|
cell[n].tested = 1;
|
||
|
cell[n].cluster = cluster;
|
||
|
cell[n].active = 1;
|
||
|
nopen++;
|
||
|
if (*stacksize < ncells)
|
||
|
{
|
||
|
(*stacksize)++;
|
||
|
pstack[*stacksize-1] = &cell[n];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (nopen == 0)
|
||
|
{
|
||
|
pstack[position]->active = 0;
|
||
|
return(-1);
|
||
|
}
|
||
|
else return(nopen);
|
||
|
}
|
||
|
|
||
|
|
||
|
int find_percolation_cluster(t_perco *cell, int ncells, t_perco* *pstack, int nstack)
|
||
|
/* new version of cluster search algorithm, using stacks; returns number of flooded cells */
|
||
|
{
|
||
|
int position = 0, i, stacksize = nstack, nactive = nstack;
|
||
|
|
||
|
while (nactive > 0)
|
||
|
{
|
||
|
/* find an active cell in stack */
|
||
|
while (!pstack[position]->active) position++;
|
||
|
if (position == stacksize) position = 0;
|
||
|
|
||
|
nactive += find_open_cells(cell, ncells, position, pstack, &stacksize, 1);
|
||
|
}
|
||
|
printf("Stack size %i\n", stacksize);
|
||
|
return(stacksize);
|
||
|
}
|
||
|
|
||
|
|
||
|
int find_all_clusters(t_perco *cell, int ncells, int reset, int *max_cluster_label)
|
||
|
/* find all clusters of open cells; returns number of clusters */
|
||
|
{
|
||
|
int nclusters = 0, i, j, nactive, stacksize, position, newcluster = 1, maxlabel = 0;
|
||
|
t_perco **cstack;
|
||
|
static int cluster;
|
||
|
|
||
|
cstack = (t_perco* *)malloc(ncells*sizeof(struct t_perco *));
|
||
|
|
||
|
if (reset) cluster = CLUSTER_SHIFT;
|
||
|
else cluster = (*max_cluster_label) + CLUSTER_SHIFT; /* give higher labels than before to new clusters */
|
||
|
|
||
|
for (i=0; i<ncells; i++) if ((cell[i].open)&&(cell[i].cluster != 1)&&(!cell[i].tested))
|
||
|
{
|
||
|
position = 0;
|
||
|
stacksize = 1;
|
||
|
nactive = 1;
|
||
|
cstack[0] = &cell[i];
|
||
|
|
||
|
/* choice of new color */
|
||
|
if (cell[i].previous_cluster >= CLUSTER_SHIFT) newcluster = cell[i].previous_cluster;
|
||
|
else
|
||
|
{
|
||
|
newcluster = cluster;
|
||
|
cluster++;
|
||
|
}
|
||
|
cell[i].cluster = newcluster;
|
||
|
cell[i].active = 1;
|
||
|
cell[i].tested = 1;
|
||
|
|
||
|
while (nactive > 0)
|
||
|
{
|
||
|
/* find an active cell in stack */
|
||
|
while (!cstack[position]->active) position++;
|
||
|
if (position == stacksize) position = 0;
|
||
|
|
||
|
nactive += find_open_cells(cell, ncells, position, cstack, &stacksize, newcluster);
|
||
|
}
|
||
|
// printf("Found cluster %i with %i active cells\n", cluster, stacksize);
|
||
|
|
||
|
nclusters++;
|
||
|
}
|
||
|
|
||
|
free(cstack);
|
||
|
|
||
|
/* determine maximal cluster label */
|
||
|
// #pragma omp parallel for private(i)
|
||
|
for (i=0; i<ncells; i++) if ((cell[i].open)&&(cell[i].cluster > maxlabel)) maxlabel = cell[i].cluster;
|
||
|
|
||
|
printf("Cluster = %i, maxlabel = %i\n", cluster, maxlabel);
|
||
|
|
||
|
*max_cluster_label = maxlabel;
|
||
|
return(nclusters);
|
||
|
}
|
||
|
|
||
|
void print_cluster_sizes(t_perco *cell, int ncells, int *cluster_sizes)
|
||
|
/* for debugging purposes */
|
||
|
{
|
||
|
int j;
|
||
|
|
||
|
for (j=0; j<ncells; j++) if (cell[j].open == 1)
|
||
|
printf("(cell %i: cluster %i: size %i)\n", j, cell[j].cluster, cluster_sizes[cell[j].cluster]);
|
||
|
sleep(1);
|
||
|
printf("\n\n");
|
||
|
}
|
||
|
|
||
|
int find_cluster_sizes(t_perco *cell, int ncells, int *cluster_sizes, int *maxclusterlabel)
|
||
|
/* determine the sizes of all clusters; returns the size of largest cluster */
|
||
|
{
|
||
|
int i, max = 0, maxlabel = 0;
|
||
|
|
||
|
// if (maxclusterlabel > ncells) maxclusterlabel = ncells;
|
||
|
|
||
|
/* determine label of larges cluster */
|
||
|
for (i=0; i<ncells; i++) if (cell[i].cluster > maxlabel) maxlabel = cell[i].cluster;
|
||
|
*maxclusterlabel = maxlabel + 1;
|
||
|
|
||
|
#pragma omp parallel for private(i)
|
||
|
for (i=0; i<*maxclusterlabel; i++) cluster_sizes[i] = 0;
|
||
|
|
||
|
for (i=0; i<ncells; i++) if (cell[i].open) cluster_sizes[cell[i].cluster]++;
|
||
|
|
||
|
if (DEBUG)
|
||
|
{
|
||
|
printf("Computed %i cluster sizes\n", *maxclusterlabel);
|
||
|
print_cluster_sizes(cell, ncells, cluster_sizes);
|
||
|
}
|
||
|
|
||
|
for (i=0; i<*maxclusterlabel; i++) if (cluster_sizes[i] > max) max = cluster_sizes[i];
|
||
|
|
||
|
// for (i=0; i<ncells; i++) if (cell[i].open) printf("%i ", cluster_sizes[cell[i].cluster]);
|
||
|
|
||
|
printf("Max cluster label %i\n", *maxclusterlabel);
|
||
|
printf("Largest cluster has %i cells\n", max);
|
||
|
return(max);
|
||
|
}
|