• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Verlet

Programa em C

2 mensagens neste tópico

Boas,

Ando aqui a fazer um programa para resolver uma equação diferencial ordinaria de segundo grau pelo metodo de Euler-Cromer.

Os argumentos sao os coeficientes 'm','b' e 'K' da equacao m*(d2x/dt2)+b*(dx/dt)+Kx=0 , e também o tempo final 'tf', a velocidade e a posicao inicial 'x0' e 'v0', e o numero de intervalos 'N' em que se vai dividir o metodo.

Tenho o programa todo feito, mas acho que deve existir alguma forma mais eficiente e menos consumidora de linhas de código de verificar os argumentos inseridos pelo utilizador.

E sabem se é menos eficiente trabalhar directamente com a estrutura de dados do que com variáveis 'normais'?

Se puderem dar uma vista de olhos... ;)

Obrigado,

Verlet :)

/***********************************************
*					         *
*     Metodo de Euler-Cromer aplicado         *
*     à equacao diferencial:                  *
*                                             *
*         m*(d2x/dt2)+b*(dx/dt)+Kx=0          *
*                                             *
***********************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define dt 0.0001

//Estrutura que guarda as cond. iniciais e os parametros K,b,m
typedef struct
{
 double v;
 double x;
 double m;
 double K;
 double b;
 double tf;
}parametros;

//Funcao ajuda
void
ajuda (int status)
{
 printf ("\n\t\t\tMENU AJUDA\n\n");
 printf("A entrada na linha de comando deve ter a seguinte forma:\n\n");
 printf ("  <nome_programa> -x0=<x_inic> -v0=<v_inic> -K=<constante K>");
 printf(" -b=<constante b> -m=<massa> -tf=<t_final> \n\n");
 printf ("Exemplos:\n\n");
 printf ("    Prog7_3 -x0=0 -v0=5 -K=2 -b=1 -m=2 -tf=8\n");
 printf ("    Prog7_3 -x0=1 -v0=2 -b=1 -m=3 -K=1 -tf=12\n");
 printf ("    Prog7_3 -x0=2 -v0=4 -b=2 -K=1 -m=3 -tf=9\n\n");

 exit (status);
}

//Funcao- verifica os argumentos inseridos e coloca-os numa estrutura
parametros
tira_argumentos (int argc, char **argv)
{
 int n1=1;
 int test_tf=0, test_x0=0, test_v0=0;
 int test_K=0 , test_b=0 , test_m=0 ;
 parametros dados;

 //Verifica o numero de argumentos
 if (argc !=7)
   {
     printf("\n\t*** Erro:Numero de argumentos incorrecto ***\n\n");
     ajuda(-1);
   }

 //Verifica os argumentos inseridos
 while (n1 < argc)
   {
     if ( (strncmp(argv[n1], "-tf=", 4)==0) &&
   (sscanf(&argv[n1][4], "%lg", &dados.tf) == 1) )
test_tf = 1;
     else if ((strncmp (argv[n1], "-x0=", 4) == 0) &&
              (sscanf (&argv[n1][4], "%lg", &dados.x) == 1))
test_x0 = 1;
     else if ((strncmp (argv[n1], "-b=", 3) == 0) &&
              (sscanf (&argv[n1][3], "%lg", &(dados.b) ) == 1) )
test_b = 1;
     else if ((strncmp (argv[n1], "-K=", 3) == 0) &&
              (sscanf (&argv[n1][3], "%lg", &(dados.K) ) == 1) )
test_K = 1;
     else if ((strncmp (argv[n1], "-m=", 3) == 0) &&
              (sscanf (&argv[n1][3], "%lg", &(dados.m) ) == 1) )
test_m = 1;
     else if ((strncmp (argv[n1], "-v0=",4) == 0) &&
              (sscanf (&argv[n1][4], "%lg", &(dados.v)) == 1) )
test_v0 = 1;
     else
       {
         printf ("\n\t*** Erro num dos argumentos inseridos ***");
         printf("\n\t\tArgumento incorrecto: \"%s\" \n\n", argv[n1]);
         ajuda(-2);
       }
     ++n1;
   }

 //Verifica se existem argumentos nao inseridos
 if( (test_tf+test_x0+test_m+test_b+test_v0+test_K)!=6)
   {
     printf("\nNao inseriu todos os parametros:\n\n");

     if (test_x0 == 0)
printf ("  -Nao indicou o num. de nucleos inicial 'x0'\n");
     if (test_v0 == 0)
printf ("  -Nao inseriu a velocidade inicial 'v0'\n");
     if (test_tf == 0)
printf ("  -Nao indicou o intervalo de tempo 'tf' para a solucao\n");
     if (test_m==0)
printf ("  -Nao indicou a massa 'm'\n");
     if (test_b == 0)
	    printf ("  -Nao indicou a constante 'b'\n");
     if (test_K==0)
printf ("  -Nao indicou a constante 'K'\n\n");

     ajuda(-3);
   }

 return dados;
}

//Main
int
main(int argc, char **argv)
{
 double t=0;
 double t1,t2;
 parametros mov;

 //Guarda e verifica os argumentos inseridos
 mov=tira_argumentos(argc,argv);

 //Abertura do ficheiro de escrita e verifcacao
 FILE*out;
 if( (out=fopen("Prog7_3.txt","wt"))==NULL)
   {
     printf("\n\t*** Erro na abertura de ficheiro de escrita ***\n");
     printf("\t\tTente novamente, por favor\n\n");
     ajuda(-4);
   }

 t1=clock();
 //Ciclo de calculo e escrita em ficheiro
 fprintf(out,"%7.4lf %7.4lf\n",t,mov.x);
 while( t<(mov.tf) )
   {
     (mov.v)=(mov.v)-( (mov.b)*(mov.v)+(mov.K)*(mov.x) )*dt/mov.m;
     (mov.x)=(mov.x)+((mov.v)*dt);
     t=t+dt;

     fprintf(out,"%7.4lf %7.4lf\n",t,mov.x);
   }
 t2=clock();

 printf("Tempo:%lf\n\n",(t2-t1)/(double)CLOCKS_PER_SEC);

 fclose(out);
 return 0;
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O getopt devia tornar as coisas mais simples.

Quanto à eficiência, ao usares a estrutura talvez estejas a limitar as optimizações que o compilador é capaz de fazer, mas não ando muito por dentro desse assunto para te poder dar mais certezas.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora