Velocidade média em função da densidade e fluxo em função da densidade

De Física Computacional
Ir para: navegação, pesquisa
#include<stdio.h>
#include<stdlib.h>
#include<math.h> 

/* declaracao de funcoes */
void passo(void);
void inicializacao(void);
void atualizar_posicao(void);
int mudar_velocidade(int(v));
int calculo_distancia(void);

/*  declaracao var global   */
#define tempo_max 100
#define comprimento_rua 100
#define veloc_max 6

/*  velocidade: numero de posições   */
/*  que o carro andará num passo     */

//definimos vel[comprimento_rua], pois o numero maximo de carros = comprimento_rua
int rua[comprimento_rua], vel[comprimento_rua];
int prim_carro, dist, num_carros;
int i, j, t;

//z_max = numero de amostragens
int z, z_max = 1000;

//print: precisamos primeiro coletar todos os resultados, fazermos a media, para so entao printarmos
//print[0][i] guarda a velocidade media
//print[1][i] guarda o fluxo
double probab_vel = 0.3, print[2][comprimento_rua], v_media, fluxo;

void main(void)
{
	//srand48(time(NULL));
	
	FILE *vm;
	vm = fopen("1_lane_dens.dat", "w+");

	for(num_carros = 1; num_carros < comprimento_rua; num_carros++)
	{
		print[0][num_carros] = 0;
		print[1][num_carros] = 0;
	}

	for(z = 0; z < z_max; z++)
	{

		for(num_carros = 1; num_carros < comprimento_rua; num_carros++)
		{
			v_media = 0;
			fluxo = 0;
			inicializacao();
		
			for(t = 0; t < tempo_max; t++)
			{			
				passo();
					
			}

			//fluxo medio
			fluxo /= tempo_max;
			
			//calculo da velocidade media
			for(j = 0; j < num_carros; j++)
			{
				v_media += vel[j];
			}
			v_media /= num_carros;
			
			print[0][num_carros] += v_media;
			print[1][num_carros] += fluxo;
		
		}
	}
	
	for(num_carros = 1; num_carros < comprimento_rua; num_carros++)
	{
		fprintf(vm, "%lf %lf %lf\n", ((double)num_carros)/comprimento_rua, print[0][num_carros]/z_max, print[1][num_carros]/z_max);
	}
	
	fclose(vm);
}

void inicializacao(void){

   	// zerando vetores
   	//-1 significa que a posicao esta vazia

	for(i = 0; i < comprimento_rua; i++){

			rua[i] = -1;
	}
	
	//iniciando os carros - rua[i] representa o indice do carro, atraves do qual acessaremos sua velocidade em vel[rua[i]]
	for(i = 0; i < num_carros; i++)
	{
		vel[i] = 0;
		rua[i*comprimento_rua/num_carros] = i;

	}
	
		
}

void passo(void)
{
    i = 0;//posicoes na rua
	prim_carro = -1; //para que caso ainda nao haja um primeiro carro, prim_carro assuma um valor que nao se confunda com nenhum indice de carro (que vao de 0 a num_carros)
		
	while(i < comprimento_rua){

  		/*  Para descobrir a posicao do primeiro carro */
    	/*  tem carro na posição 'i'?          		   */
		
		if (rua[i] == -1){	
	
			/*	não, não tem carro em 'i'	*/
			/*	vai pra prox posicao 'i'   	*/

			i++;
				
		}
	
		else{
	
			/*	caso for o primeiro carro,	*/
			/*	salvar sua posicao para    	*/
			/*	calcularmos a distancia do 	*/
			/*	ultimo carro ao primeiro   	*/

			if(prim_carro == -1){

				prim_carro = i;
			}
				

			//calculando distancia ate o proximo carro

			dist = calculo_distancia();

			//mudando velocidades

			vel[rua[i]] = mudar_velocidade(vel[rua[i]]);
								
			//atualizando posicoes

			atualizar_posicao();

			//pulando para o proximo carro
			i+=dist;	
		}	
	}
		
}


void atualizar_posicao(void){

	/*	atualiza apenas se a velocidade	*/
	/*	for diferente de zero        	*/

	if( vel[rua[i]] != 0 ){

		//para o ultimo carro, condicoes de contorno periodicas
		if( i + vel[rua[i]] >= comprimento_rua ){
			//como somente os carros que atravessam a secao transversal entre a ultima e a primeira celula da rua entram nesse if, podemos contar o fluxo aqui
			fluxo++;

			rua[(i+ vel[rua[i]]) % comprimento_rua] = rua[i];
		}
		else{

			rua[i + vel[rua[i]]] = rua[i];
		}
			
		rua[i] = -1;
	}
				
}




int calculo_distancia(void){

		/*	RETORNA A DISTANCIA ENTRE O	*/
		/*	CARRO 'i' E O QUE ESTA NA   */
		/*	SUA FRENTE NA FAIXA 'x'    	*/ 

		/*	caso não for o ultimo carro	*/
		/*	procura posição do prox. e	*/
		/*	calcula a distancia até ele	*/

		/* temos que isolar o caso i = comprimento_rua - 1,*/
		/*	já que j = i + 1 = comprimento_rua, e usamos   */
		/*	rua[j], sendo que j < comprimento_rua;	   */
		
		
		if( i + 1 < comprimento_rua ){

			j = i + 1;

			while ( (rua[j] == -1) && (j < comprimento_rua) ){

				j++;	
			}
		
			if ( j != comprimento_rua ){

				dist = j - i;
			}
			
		}
		

		/*	para o ultimo carro a distan-	*/
		/*	cia é calculada em relacao ao	*/
		/*	primeiro, pois são C.C. perio-	*/
		/*	dicas.                       	*/

		//ultimo carro, e existe um primeiro carro
		if( ((i == comprimento_rua - 1) || (j == comprimento_rua)) && (prim_carro != -1)){

			dist = comprimento_rua - (i - prim_carro);
		}	

		//caso so haja um carro ou a pista esteja vazia
		else if(((i == comprimento_rua - 1) || (j == comprimento_rua)) && (prim_carro == -1))
		{
			dist = comprimento_rua;
		}
		return dist;


}

int mudar_velocidade(int(v)){

	int x;
	/*   	RETORNA NOVA VELOCIDADE  	*/	

	/*	            Regra 1         	*/
	/*	caso dê pra acelerar, acelere	*/
	if( ( v < veloc_max ) && ( dist > v + 1 ) ){

		x = v + 1;
	}

	/*	           Regra 2           	*/
	/*	caso pouco espaço, desacelere	*/
	else if( dist < v + 1 ){

		x = dist - 1;
	}
	else
	{
		x = v;
	}
	
	/*	           Regra 3              */
	/*	redução de velocidade randomica	*/
	if( ( x > 0 ) && ( drand48() < probab_vel )){

		x--;
	}
	
	return x;
}