Jump to content
Verlet

Programa em C

Recommended Posts

Verlet

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;
}

Share this post


Link to post
Share on other sites
Rui Carlos

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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.