Principal | Gráficos 3D | Gráficos 2D | Fractales | Math | Códigos | Tutoriales | Links
La convergencia lenta del método de Euler y lo restringido de su región de estabilidad absoluta nos lleva a considerar métodos de orden de convergencia mayor, un ejemplo es el llamado método Runge-Kutta de orden cuatro definido por las fórmulas:
La exactitud del metodo de Runge-Kutta es mucho mayor que el de Euler.
En este ejemplo vamos a resolver la ecuacion diferencial :
mediante el metodo de Runge-Kutta con n=20, en el intervalo [0, 1].
/*
dy/dt = 1.0 - t + 4.0*y
y(0.0) = 1.0
*/
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define MAXPUNTOS 20
double y[MAXPUNTOS+1];
double t[MAXPUNTOS+1];
double f(double t, double y)
{
return (1.0 - t+ 4.0*y);
}
//solucion exacta de la ecuacion diferencial
double exacta(double t)
{
return (t/4.0 - 3.0/16.0 + (19.0/16.0)*exp(4.0*t));
}
void RK4(double tinicial, double tfinal, double yinicial, int n)
{
double k1, k2, k3, k4;
double h;
int i;
h=(tfinal-tinicial)/n;
t[0]=tinicial;
y[0]=yinicial;
for (i=0; i<n; i++)
{
k1=h*f(t[i], y[i]);
k2=h*f(t[i]+h/2.0, y[i]+k1/2.0);
k3=h*f(t[i]+h/2.0, y[i]+k2/2.0);
k4=h*f(t[i]+h, y[i]+k3);
y[i+1]=y[i]+(1.0/6.0)*(k1 + 2.0*k2 + 2.0*k3+ k4);
t[i+1]=t[i] + h;
}
}
void init(void)
{
RK4(0.0, 1.0, 1.0, MAXPUNTOS);
}
void display(void)
{
int i;
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode( GL_MODELVIEW_MATRIX );
glLoadIdentity();
//grafica de la solucion exacta en color Verde
glColor3f(0.0,1.0,0.0);
glBegin(GL_LINE_STRIP);
for (i=0; i<MAXPUNTOS; i++)
glVertex2f(t[i], exacta(t[i]));
glEnd();
//grafica de la solucion numerica en color Blanco
glColor3f(1.0,1.0,1.0);
glBegin(GL_LINE_STRIP);
for (i=0; i<MAXPUNTOS; i++)
glVertex2f(t[i], y[i]);
glEnd();
glFlush ();
}
void reshape (int w, int h)
{
if (!h)
return;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 1.0, 0.0, 40.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 27: exit(0);
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (350, 350);
glutInitWindowPosition (0, 0);
glutCreateWindow ("Metodo de Runge-Kutta");
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
|
valcoey@hotmail.com
Ramiro Alcocer, 2001
Principal | Gráficos 3D | Gráficos 2D | Fractales | Math | Códigos | Tutoriales | Links