Skip to content
Snippets Groups Projects
Commit 66cb4e4b authored by Jazil Saadana's avatar Jazil Saadana
Browse files

Depot Boltzman

parent 89e61df0
No related branches found
No related tags found
No related merge requests found
grid.c 0 → 100644
#include "grid.h"
grid_t grid_create( int x, int y, double rho, vect_t vel ) {
grid_t grid;
grid.x = x;
grid.y = y;
grid.mask = mask_create( x, y );
grid.nodes = malloc( x*sizeof(node_t*) );
grid.norm = malloc( x*sizeof(int*) );
for( int i = 0; i < x; i++ ) {
grid.nodes[i] = malloc( y*sizeof(node_t) );
grid.norm[i] = calloc( y, sizeof(int) );
for( int j = 0; j < y; j++ ) {
node_init( &grid.nodes[i][j], rho, vel );
}
}
return grid;
}
void grid_collide( grid_t *g ) {
for( int i = 0; i < g->x; i++ ) {
for( int j = 0; j < g->y; j++) {
node_compute( &g->nodes[i][j] );
if( g->mask[i][j] ) { node_solid( &g->nodes[i][j] ); }
else { node_fluid( &g->nodes[i][j] ); }
}
}
grid_propage(g);
grid_mod(g);
printf("fini le calul\n");
}
// propagation périodicité
void grid_propage( grid_t *g ) {
int x = g->x;
int y = g->y;
for( int i = 0; i < g->x; i++ ) {
for( int j = 0; j < g->y; j++) {
for( int k = 0; k < 9; k++ ) {
int x_next = (i - (int)(g->nodes[i][j].c[k].x) + x) % x;
int y_next = (j - (int)(g->nodes[i][j].c[k].y) + y) % y;
g->nodes[i][j].f[k] = g->nodes[x_next][y_next].fout[k];
}
}
}
}
void grid_destroy( grid_t grid ) {
mask_destroy( grid.mask, grid.x );
for( int i = 0; i < grid.x; i++) {
free( grid.nodes[i] );
}
free( grid.nodes );
}
// normalisation par rapport à une val max fixée
void grid_mod( grid_t *g ) {
double max = MAX_NORM;
double min = 0;
for( int i=0; i<g->x; i++ ) {
for( int j=0; j<g->y; j++ ) {
double mod = vect_mod( g->nodes[i][j].vel );
if( mod > MAX_NORM) mod = MAX_NORM;
g->norm[i][j] = mod*255/MAX_NORM;
}
}
}
grid.h 0 → 100644
#ifndef _GRID_
#define _GRID_
#include <stdlib.h>
#include <stdbool.h>
#include "node.h"
#include "mask.h"
#define MAX 255
#define MAX_NORM 0.05
typedef struct {
node_t **nodes;
bool **mask;
int **norm;
int x;
int y;
} grid_t;
grid_t grid_create( int x, int y, double rho, vect_t vel );
void grid_collide( grid_t *g );
void grid_propage( grid_t *g );
void grid_destroy( grid_t grid );
void grid_mod( grid_t *g );
#endif
\ No newline at end of file
lib_gfx.c 0 → 100644
/// @file gfx.c
/// @author Florent Gluck
/// @date November 6, 2016
/// Helper routines to render pixels in fullscreen graphic mode.
/// Uses the SDL2 library.
#include "lib_gfx.h"
/// Create a fullscreen graphic window.
/// @param title Title of the window.
/// @param width Width of the window in pixels.
/// @param height Height of the window in pixels.
/// @return a pointer to the graphic context or NULL if it failed.
struct gfx_context_t* gfx_create(char *title, uint width, uint height) {
if (SDL_Init(SDL_INIT_VIDEO) != 0) goto error;
SDL_Window *window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_FULLSCREEN_DESKTOP);
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING, width, height);
uint32_t *pixels = malloc(width*height*sizeof(uint32_t));
struct gfx_context_t *ctxt = malloc(sizeof(struct gfx_context_t));
if (!window || !renderer || !texture || !pixels || !ctxt) goto error;
ctxt->renderer = renderer;
ctxt->texture = texture;
ctxt->window = window;
ctxt->width = width;
ctxt->height = height;
ctxt->pixels = pixels;
SDL_ShowCursor(SDL_DISABLE);
gfx_clear(ctxt, COLOR_BLACK);
return ctxt;
error:
return NULL;
}
/// Draw a pixel in the specified graphic context.
/// @param ctxt Graphic context where the pixel is to be drawn.
/// @param x X coordinate of the pixel.
/// @param y Y coordinate of the pixel.
/// @param color Color of the pixel.
void gfx_putpixel(struct gfx_context_t *ctxt, int x, int y, uint32_t color) {
if (x < ctxt->width && y < ctxt->height)
ctxt->pixels[ctxt->width*y+x] = color;
}
/// Clear the specified graphic context.
/// @param ctxt Graphic context to clear.
/// @param color Color to use.
void gfx_clear(struct gfx_context_t *ctxt, uint32_t color) {
int n = ctxt->width*ctxt->height;
while (n)
ctxt->pixels[--n] = color;
}
/// Display the graphic context.
/// @param ctxt Graphic context to clear.
void gfx_present(struct gfx_context_t *ctxt) {
SDL_UpdateTexture(ctxt->texture, NULL, ctxt->pixels, ctxt->width*sizeof(uint32_t));
SDL_RenderCopy(ctxt->renderer, ctxt->texture, NULL, NULL);
SDL_RenderPresent(ctxt->renderer);
}
/// Destroy a graphic window.
/// @param ctxt Graphic context of the window to close.
void gfx_destroy(struct gfx_context_t *ctxt) {
SDL_ShowCursor(SDL_ENABLE);
SDL_DestroyTexture(ctxt->texture);
SDL_DestroyRenderer(ctxt->renderer);
SDL_DestroyWindow(ctxt->window);
free(ctxt->pixels);
ctxt->texture = NULL;
ctxt->renderer = NULL;
ctxt->window = NULL;
ctxt->pixels = NULL;
SDL_Quit();
free(ctxt);
}
/// If a key was pressed, returns its key code (non blocking call).
/// List of key codes: https://wiki.libsdl.org/SDL_Keycode
/// SDL_PumpEvents() must be called before.
/// @return 0 if escape was not pressed.
SDL_Keycode gfx_keypressed() {
const Uint8 *state = SDL_GetKeyboardState(NULL);
if (state && state[SDL_SCANCODE_ESCAPE]) {
return SDLK_ESCAPE;
}
return 0;
}
/// If a mouse left button was pressed, returns its position
/// relative to window (non blocking call).
/// SDL_PumpEvents() must be called before.
/// @return 0 if no button was pressed and modifies the location
// otherwise.
int gfx_left_right_mouse_pressed( grid_t *g ) {
Point p ={ 0, 0 };
Uint32 ret = SDL_GetMouseState(&p.x, &p.y) & ( SDL_BUTTON(SDL_BUTTON_LEFT) | SDL_BUTTON(SDL_BUTTON_RIGHT) );
if (ret == 1) {
int x = (int)( (double)p.x / 1680.0 * (double)g->x);
int y = (int)( (double)p.y/ 1050.0 * (double)g->y);
if( g->mask[x, y] ) {
mask_settrue( g->mask, x, y );
}
} else if (ret == 4) {
int x = (int)( (double)p.x / 1680.0 * (double)g->x);
int y = (int)( (double)p.y/ 1050.0 * (double)g->y);
mask_setfalse( g->mask, x, y );
}
return 0;
}
void render(struct gfx_context_t *context, grid_t *g) {
gfx_clear(context, COLOR_BLACK);
int offset_x = (int)(SCREEN_WIDTH/2 - g->x/2);
int offset_y = (int)(SCREEN_HEIGHT/2 - g->y/2);
for(int i=0; i<g->x; i++) {
for(int j=0; j<g->y; j++) {
int intensity = g->norm[i][j];
uint32_t color = MAKE_COLOR(intensity, intensity, intensity );
gfx_putpixel(context, i+offset_x, j+offset_y, color);
}
}
}
#ifndef _LIB_GFX_H_
#define _LIB_GFX_H_
#include <stdint.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#include "grid.h"
#define SCREEN_WIDTH 200
#define SCREEN_HEIGHT 200
#define MAKE_COLOR(r,g,b) ((uint32_t)b|((uint32_t)g<<8)|((uint32_t)r<<16))
#define COLOR_GET_B(color) (color & 0xff)
#define COLOR_GET_G(color) ((color >> 8) & 0xff)
#define COLOR_GET_R(color) ((color >> 16) & 0xff)
#define COLOR_BLACK 0x00000000
#define COLOR_RED 0x00FF0000
#define COLOR_GREEN 0x0000FF00
#define COLOR_BLUE 0x000000FF
#define COLOR_WHITE 0x00FFFFFF
#define COLOR_YELLOW 0x00FFFF00
typedef unsigned int uint;
typedef unsigned long ulong;
typedef unsigned char uchar;
struct gfx_context_t {
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Texture *texture;
uint32_t *pixels;
int width;
int height;
};
typedef struct Point Point;
struct Point
{
int x;
int y;
};
extern void gfx_putpixel(struct gfx_context_t *ctxt, int x, int y, uint32_t color);
extern void gfx_clear(struct gfx_context_t *ctxt, uint32_t color);
extern struct gfx_context_t* gfx_create(char *text, uint width, uint height);
extern void gfx_destroy(struct gfx_context_t *ctxt);
extern void gfx_present(struct gfx_context_t *ctxt);
extern SDL_Keycode gfx_keypressed( );
extern SDL_Texture* SDL_CreateTexture(SDL_Renderer* renderer, Uint32 format, int access, int w, int h);
int gfx_left_right_mouse_pressed( grid_t *g );
void render(struct gfx_context_t *context, grid_t *g);
#endif
main.c 0 → 100644
#include <stdlib.h>
#include "grid.h"
#include "mask.h"
#include "node.h"
#include "lib_gfx.h"
#include <pthread.h>
#include <semaphore.h>
grid_t g;
SDL_Keycode escape = 0;
//pathread_barrier_t b;
sem_t lock;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutexcalc = PTHREAD_MUTEX_INITIALIZER;
struct gfx_context_t *ctxt;
void *keyboad_control()
{
pthread_mutex_lock(&mutex);
escape = gfx_keypressed();
if (escape == SDLK_ESCAPE)
{
exit(0);
}
pthread_mutex_unlock(&mutex);
sem_post(&lock);
}
void *Calculate()
{
pthread_mutex_lock(&mutex);
grid_collide(&g);
sem_post(&lock);
pthread_mutex_unlock(&mutex);
}
void *Display(){
pthread_mutex_lock(&mutex);
gfx_present(ctxt);
sem_post(&lock);
pthread_mutex_unlock(&mutex);
}
int main(int argc, char *argv[])
{
/*je trouve la barriere!!!! */
// pthread_barrier_init(&b);
int x = atoi(argv[1]), y = atoi(argv[2]);
TAU = atof(argv[3]);
G = atof(argv[4]);
double Gy = atof(argv[5]);
const double rho = 1.0;
int n_thread = atoi(argv[6]);
int nthread_calcul = n_thread - 2;
int rest, portion;
pthread_t t_keyboard, t_display, t_calulator;
sem_init(&lock, 0, n_thread);
vect_t u = vect_new(0.02, 0.0);
g = grid_create(x, y, rho, u);
ctxt = gfx_create("Bolzmann", x, y);
if (!ctxt)
{
fprintf(stderr, "Graphics initialization failed!\n");
return EXIT_FAILURE;
}
portion = atoi(argv[1])/nthread_calcul;
rest = atoi(argv[1])%nthread_calcul;
while (1)
{
SDL_PumpEvents();
SDL_ShowCursor(SDL_ENABLE);
g.x = portion;
g.y = portion;
for (int i = 0; i < nthread_calcul; i++)
{
if (i == nthread_calcul -1)
{
g.x += rest;
g.y += rest;
}
pthread_mutex_lock(&mutex);
pthread_create(&t_calulator, NULL, Calculate, NULL);
sem_wait(&lock);
pthread_mutex_unlock(&mutex);
g.x += portion;
g.y += portion;
}
if (pthread_create(&t_keyboard, NULL, keyboad_control, NULL))
{
perror("pthread_create");
return EXIT_FAILURE;
}
sem_wait(&lock);
g.x = x;
g.y = y;
render(ctxt, &g);
if (pthread_create(&t_display, NULL, Display, NULL))
{
perror("pthread_create");
return EXIT_FAILURE;
}
sem_wait(&lock);
gfx_left_right_mouse_pressed(&g);
for (int i = 0; i < nthread_calcul; i++)
{
pthread_join(t_calulator, NULL);
}
sem_destroy(&lock);
}
pthread_join(t_display, NULL);
pthread_join(t_keyboard, NULL);
sem_destroy(&lock);
gfx_destroy(ctxt);
grid_destroy(g);
return EXIT_SUCCESS;
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.main.o</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
File added
makefile 0 → 100644
CC = gcc -std=c11
FLAGS = -g -Wall -Wextra -std=gnu11
LIBS = -lm -lSDL2 -lpthread
all : main.o test.o
main.o : main.c grid.o mask.o node.o vector.o lib_gfx.o
$(CC) $(FLAGS) $^ -o $@ $(LIBS)
test.o : test.c grid.o mask.o node.o vector.o
$(CC) $(FLAGS) $^ -o $@ $(LIBS)
grid.o : grid.h grid.c
$(CC) -c $^
node.o : node.h node.c
$(CC) -c $^
mask.o : mask.h mask.c
$(CC) -c $^
vector.o : vector.h vector.c
$(CC) -c $^
lib_gfx.o : lib_gfx.h lib_gfx.c
$(CC) -c $^
run :
./main.o
test :
./test.o
trun : test run
clean :
rm -f *.o *.gch
# $@ Le nom de la cible
# $< Le nom de la première dépendance
# $^ La liste des dépendances
# $? La liste des dépendances plus récentes que la cible
# $* Le nom du fichier sans suffixe
\ No newline at end of file
mask.c 0 → 100644
#include "mask.h"
bool **mask_create( int x, int y ) {
bool **mask = malloc( x*sizeof(bool*) );
for( int i = 0; i < x; i++ ) {
mask[i] = calloc( sizeof(bool), y );
}
return mask;
}
void mask_destroy( bool **mask, int x ) {
for( int i=0; i<x; i++ ) {
free( mask[i] );
}
free( mask );
}
void mask_settrue( bool **mask, int x, int y ) {
mask[x][y] = true;
}
void mask_setfalse( bool **mask, int x, int y ) {
mask[x][y] = false;
}
mask.h 0 → 100644
#ifndef _MASK_
#define _MASK_
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "grid.h"
bool **mask_create( int x, int y );
void mask_destroy( bool **mask, int x );
void mask_settrue( bool **mask, int x, int y );
void mask_setfalse( bool **mask, int x, int y );
#endif
\ No newline at end of file
node.c 0 → 100644
#include "node.h"
const double W[9] = { 1.0/36.0, 1.0/9.0, 1.0/36.0, 1.0/9.0, 4.0/9.0, 1.0/9.0, 1.0/36.0, 1.0/9.0, 1.0/36.0 };
void node_copy_mat( double *src, double *dst ) {
for( int i=0; i<9;i++ ) {
dst[i] = src[i];
}
}
// initialisation de Vect c
void node_init_c( node_t *n ) {
n->c[0] = vect_new( -1, -1 );
n->c[1] = vect_new( -1, 0 );
n->c[2] = vect_new( -1, 1 );
n->c[3] = vect_new( 0, -1 );
n->c[4] = vect_new( 0, 0 );
n->c[5] = vect_new( 0, 1 );
n->c[6] = vect_new( 1, -1);
n->c[7] = vect_new( 1, 0 );
n->c[8] = vect_new( 1, 1 );
}
// inisialisation
void node_init( node_t *n, double rho, vect_t vel ) {
node_init_c( n );
n->rho = rho;
n->vel = vel;
node_feq( n );
node_copy_mat( n->feq, n->f );
}
void node_compute( node_t *n ) {
node_rho( n );
node_vel( n );
node_feq( n );
}
// Etape de collision eq 5
void node_fluid( node_t *n ) {
for( int i=0; i<9;i++ ) {
n->fout[i] = n->f[i] - 1.0/TAU * ( n->f[i] - n->feq[i] );
}
}
// parois solide
void node_solid( node_t *n ) {
for( int i=0; i<9;i++ ) {
n->fout[i] = n->f[9-i-1] ;
n->vel = vect_new(0, 0);
n->rho = 1;
}
}
// calcule rho(x,t) eq 1
void node_rho( node_t *n ) {
n->rho = 0;
for( int i=0; i<9;i++ ) {
n->rho += n->f[i];
}
}
// Calcul u(x,t) eq 1
void node_vel( node_t *n ) {
double vel_x = 0.0, vel_y = 0.0;
n->vel = vect_new( 0, 0 );
for( int i=0; i<9;i++ ) {
n->vel.x += n->f[i] * n->c[i].x;
n->vel.y += n->f[i] * n->c[i].y;
}
n->vel = vect_divc( n->vel, n->rho );
}
// calcul feq(x,t) eq 6
void node_feq( node_t *n ) {
vect_t j = vect_addc( n->vel, TAU * G );
for( int i=0; i<9;i++ ) {
n->feq[i] = 1.0 + 3.0 * vect_scal( n->c[i], j );
n->feq[i] += 9.0/2.0 * vect_scal( n->c[i], j ) * vect_scal( n->c[i], j );
n->feq[i] -= 3.0/2.0 * vect_scal( j, j );
n->feq[i] *= W[i] * n->rho;
}
}
node.h 0 → 100644
#ifndef _NODE_
#define _NODE_
#include <stdio.h>
#include "vector.h"
double TAU ;
double G ;
typedef struct {
double f[9] ;
double feq[9];
double fout[9];
vect_t c[9] ;
double rho;
vect_t vel;
int x;
int y;
} node_t;
void node_copy_mat( double *src, double *dst );
void node_init_c( node_t *n );
void node_init( node_t *n, double rho, vect_t vel );
void node_compute( node_t *n );
void node_fluid( node_t *n );
void node_solid( node_t *n );
void node_rho( node_t *n );
void node_vel( node_t *n );
void node_feq( node_t *n );
#endif
test.c 0 → 100644
#include <stdlib.h>
#include <assert.h>
#include "node.h"
#define PRECISION 0.00000001
int main() {
double rho = 5.0;
vect_t u = vect_new( 0.1, -0.1 );
node_t t;
node_init( &t, rho, u );
node_rho( &t );
node_vel( &t );
double sum_rho = 0;
double sum_rho_ux = 0;
double sum_rho_uy = 0;
double sum_rho_ux2 = 0;
double sum_rho_uy2 = 0;
double sum_rho_ux_uy = 0;
for( int i=0; i<9; i++) {
sum_rho += t.feq[i];
sum_rho_ux += t.feq[i] * t.c[i].x;
sum_rho_uy += t.feq[i] * t.c[i].y;
sum_rho_ux2 += ( t.c[i].x * t.c[i].x - 1.0/3.0 ) * t.feq[i];
sum_rho_uy2 += ( t.c[i].y * t.c[i].y - 1.0/3.0 ) * t.feq[i];
sum_rho_ux_uy += t.c[i].x * t.c[i].y * t.feq[i];
}
assert( fabs(t.rho-sum_rho) < PRECISION );
printf( " test 1 : rho=sum(feq) sucess\n");
assert( fabs(t.rho*t.vel.x-sum_rho_ux) < PRECISION );
printf( " test 2 : rho.ux=sum(feq.cx) sucess\n");
assert( fabs(t.rho*t.vel.y-sum_rho_uy) < PRECISION );
printf( " test 3 : rho.uy=sum(feq.cy) sucess\n");
assert( fabs(t.rho*t.vel.x*t.vel.x-sum_rho_ux2) < PRECISION );
printf( " test 4 : rho.ux²=sum[feq.(cx²-1/3)] sucess\n");
assert( fabs(t.rho*t.vel.y*t.vel.y-sum_rho_uy2) < PRECISION );
printf( " test 5 : rho.uy²=sum[feq.(cy²-1/3)] sucess\n");
assert( fabs(t.rho*t.vel.x*t.vel.y-sum_rho_ux_uy) < PRECISION );
printf( " test 6 : rho.ux.uy=sum[feq.cx.cy] sucess\n");
return 0;
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.test.o</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
File added
vector.c 0 → 100644
#include "vector.h"
vect_t vect_new( double x, double y ) {
vect_t v = { x, y };
return v;
}
vect_t vect_add( vect_t a, vect_t b ) {
return vect_new( a.x + b.x, a.y + b.y );
}
double vect_scal( vect_t a, vect_t b ) {
return a.x * b.x + a.y * b.y;
}
double vect_mod( vect_t a ) {
return sqrt( a.x * a.x + a.y * a.y );
}
vect_t vect_mulc( vect_t v, double cst ) {
return vect_new( v.x * cst, v.y * cst );
}
vect_t vect_addc( vect_t v, double cst ) {
return vect_new( v.x + cst, v.y + cst );
}
vect_t vect_divc( vect_t v, double cst ) {
assert( cst != 0.0 );
return vect_new( v.x / cst, v.y / cst );
}
void vect_print( vect_t v ) {
printf( "[%f, %f]\n", v.x, v.y );
}
vector.h 0 → 100644
#ifndef _VECTOR_
#define _VECTOR_
#include <stdio.h>
#include <math.h>
#include <assert.h>
typedef struct {
double x;
double y;
} vect_t;
vect_t vect_new( double x, double y );
vect_t vect_add( vect_t a, vect_t b );
double vect_scal( vect_t a, vect_t b );
double vect_mod( vect_t a );
vect_t vect_mulc( vect_t v, double cst );
vect_t vect_addc( vect_t v, double cst );
vect_t vect_divc( vect_t v, double cst );
void vect_print( vect_t v );
#endif
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment