Está en la página 1de 10

Ecuaciones diferenciales de primer orden

Los fenómenos más interesantes en la naturaleza que queramos modelar o representar


cuantitativamente, son aquellos en los que las variables cambian en el tiempo (por ejemplo,
biológicas, sistemas eléctricos o mecánicos).
Si los cambios son continuos, el sistema a menudo puede ser representado con ecuaciones que
involucran las derivadas de variables dependientes. Tal las ecuaciones se llaman ecuaciones
diferenciales.
El objetivo principal de muchos modelos es poder escribir un conjunto de ecuaciones
diferenciales que describen el sistema que se está estudiando, como con la mayor precisión
posible. Muy pocas ecuaciones diferenciales pueden resolverse analíticamente, por lo que una
vez nuevamente, se requieren métodos numéricos. Consideraremos el método más simple de
solución numeración: el método de Euler.

Movimiento vertical bajo resistencia al aire: método de Euler


Emplearemos el método de Euler en un ejemplo de la dinámica newtoniana, en el movimiento
bajo la aceleración de la gravedad con resistencia del aire. Suponga que un paracaidista sale de
un helicóptero quieto en el aire, pero no abre su paracaídas durante 24 segundos. Nos gustaría
encontrar su velocidad en función del tiempo durante este periodo. Suponiendo que la
resistencia del aire no es despreciable, el cae sujeto a dos fuerzas verticales opuestas: la
gravedad que actúa hacia abajo y resistencia del aire que actúa hacia arriba. La fuerza de
resistencia del aire se supone proporcional al cuadrado de su velocidad. Aplicando la segunda
ley de Newton al paracaidista:

Es la ecuación diferencial que describe el movimiento del paracaidista bajo la gravedad. La


constante k varía con la forma y la masa, y se puede encontrar experimentalmente a partir de la
velocidad terminal del objeto que cae. La velocidad terminal (v T) se alcanza cuando el objeto
deja de acelerar

Antes de ver la solución numérica de la ecuación diferencial, debemos notar que este diferencial
particular se puede resolver analíticamente:

, donde: y
El método de Euler para resolver la ecuación diferencial numéricamente consiste en reemplazar
la derivada en el lado izquierdo lado con su cociente de Newton, e igual esto con el lado
derecho tal como está. Después de un reordenamiento de los términos, obtenemos

Si dividimos el período de tiempo t en n intervalos de h, entonces t = n h. Si definimos vn como


v (t), entonces vn + 1= v (t + h). Por lo tanto, podemos reemplazar la ecuación con el esquema
iterativo.

Dado que se nos da la condición inicial v0 = 0, la ecuación de arriba proporciona un esquema


numérico para encontrar la aproximación de Euler vn a v(t) en general.

También podemos probar su precisión probando diferentes valores de h y comparar los


resultados con la solución exacta.
El siguiente programa usa el método de Euler como implementado en la ecuación de arriba para
estimar v durante los primeros 24 segundos del movimiento del paracaidista. También calcula la
solución exacta para comparar.

program para
implicit none
real, parameter :: g = 9.8
real k, h, t, t0, tend, v, v0, x
integer i, n
print*, "enter k, h, t0, v(t0), tend:"
read*, k, h, t0, v0, tend
x = (tend - t0) / h
n = int( x + spacing(x)) + 1 ! trip count
t = t0
v = v0
print "(3a10)", "time", "euler", "exact"
do i = 1, n
print "(3f10.2)", t, v, vexact(t, v0, g, k)
v = v + h * (g - k * v * v)
t=t+h
end do
contains
function vexact(t, v0, g, k)
real vexact
real, intent(in) :: g, k, t, v0
real a, c
a = sqrt( g / k )
c = (a + v0) / (a - v0)
vexact = a * (c - exp(-2*a*k*t))/(c + exp(-2*a*k*t))
end function vexact
end program para

Métodos de Runge-Kutta

Hay una variedad de algoritmos, bajo el nombre general de Runge-Kutta, que pueden ser
utilizado para integrar sistemas de ecuaciones diferenciales ordinarias. La fórmula de cuarto
orden es dada a continuación, como referencia. Una derivación de esta y otras fórmulas de
Runge-Kutta puede ser se encuentra en la mayoría de los libros sobre análisis numérico.

Fórmulas de cuarto orden de Runge-Kutta


La ecuación diferencial general de primer orden es dy / dx = f (x, y), y (0)

La estimación de Runge-Kutta de cuarto orden y * en x + h viene dada por

Donde
Sistemas de ecuaciones diferenciales: un modelo depredador-presa

Las fórmulas de Runge-Kutta pueden adaptarse para sistemas integrado de ecuaciones


diferenciales de primer orden. Aquí adaptamos las fórmulas de cuarto orden para integrar el
conocido Modelo depredador-presa de Lotka- Volterra:

donde x (t) y y (t) son el tamaño de la población de las presas y los depredadores
respectivamente, en el momento t, y p, q, r y s son parámetros determinados biológicamente.
Definimos f (x, y) y g (x, y) como los lados derechos de las ecuaciones arriba y abajo,
respectivamente. En este caso, Runge-Kutta estima x * y y * en el tiempo (t + h) se puede
encontrar a partir de x e y en el tiempo t con las fórmulas

Cabe señalar que en este ejemplo x e y son las variables dependientes, y t (que no aparece
explícitamente en las ecuaciones) es la variable independiente.

Se implementa un programa de modelado interactivo esqueleto, Driver. Su base es un


Procedimiento de Runge-Kutta de cuarto orden para integrar un sistema basado en el tiempo (de
cualquier tamaño) de diferencial de primer orden ecuaciones. Consta de cuatro unidades de
programa (que se pueden compilar por separado), de las cuales solo una necesita ser recopilado
por los usuarios:
• un módulo DrGlobal con declaraciones globales de tipos y variables derivados; • una subrutina
externa DEqs que define las ecuaciones diferenciales del modelo; en principio, esto es la única
unidad de programa que debe recompilarse cuando el usuario configura o cambia un
modelo; • un módulo DrUtils con algunas subrutinas de servicios básicos, incluida una subrutina
Runge-Kutta; • un controlador de programa principal para ejecutar el paquete. Cada una de estas
unidades de programa se describirá a su vez. Para ilustrar el paquete, está configurado aquí para
ejecutar el modelo depredador-presa, con x (0) = 105, y (0) = 8, p = 0.4, q = 0.04, r = 0.02, y s =
2.
***************************************************************************

module drglobal
! global declarations for driver
type vartype ! type for model variables
character(4) name ! name
real inval ! initial value
real val ! current value
end type vartype

type partype ! type for model parameters


character(4) name ! name
real val ! value
end type partype

type (partype), allocatable, target :: params(:) ! parameters


type (vartype), allocatable :: vars (:) ! variables
real, allocatable, target :: x(:) ! current values of variables
real t, dt ! model time and step-length
! for runge-kutta
integer itime, runtime ! counter, number of integrations
integer numvars, numparams ! number of model variables, parameters
character(1) opt ! response to main menu
end module drglobal

subroutine deqs( f )
! evaluates rhs of des
use drglobal
implicit none
real, intent(out) :: f(:)
real, pointer :: prey, pred, p, q, r, s
! model equations are:
! dx/dt = f1 = px - qxy
! dy/dt = f2 = rxy - sy
prey => x(1) ! symbolic aliases ...
pred => x(2) ! ... reduce likelihood of errors
p => params(1) % val
q => params(2) % val
r => params(3) % val
s => params(4) % val
f(1) = p * prey - q * prey * pred
f(2) = r * prey * pred - s * pred
end subroutine deqs

module drutils
! driver utility subroutines
use drglobal
implicit none

interface
subroutine deqs( f ) ! defines model des
real f(:)
end subroutine deqs
end interface

contains

subroutine headings ! generates output headings


integer i
print "(3a11)", "time", (vars(i) % name, i = 1, numvars)
print*
print "(3f11.2)", t, x
end subroutine headings

subroutine initialize
! all this info could be read from a disk file
numvars = 2
numparams = 4
allocate( vars(numvars), params(numparams), x(numvars) )
vars(1) % name = "prey"
vars(1) % inval = 105
vars(2) % name = "pred"
vars(2) % inval = 8
params(1) % val = 0.4
params(2) % val = 0.04
params(3) % val = 0.02
params(4) % val = 2.0
vars % val = 0 ! set current values to zero for safety
dt = 1
t=0
runtime = 10
end subroutine initialize

subroutine run ! run the model


call headings
do itime = 1, runtime
t = t + dt
call runge
print "(3f11.2)", t, x
end do
vars % val = x ! current values
end subroutine run

subroutine runge
! 4th order runge-kutta
real :: f(numvars)
real, dimension( numvars ) :: a, b, c, d, v ! working space
!real h
a = 0; b = 0; c = 0; d = 0 ! initialize
v = x ! initialize for runge-kutta
call deqs( f )
a = dt * f
x = v + a / 2 ! v has original x, update x
call deqs( f )
b = dt * f
x=v+b/2
call deqs( f )
c = dt * f
x=v+c
call deqs( f )
d = dt * f
x = v + (a + 2 * b + 2 * c + d) / 6 ! finally update x for return
end subroutine runge

subroutine tidyup
! close files, throw away dynamic storage, etc.
deallocate( vars, params, x )
end subroutine
end module drutils

program driver
! runs differential equations models
! model de must be defined in external subroutine deqs
use drglobal ! global declarations
use drutils ! driver subroutines
implicit none
call initialize
opt = ""
print*, "driver sample model"
print*
do while (opt /= "q" .and. opt /= "q")
print*, "c: tomando los valores finales"
print*, "i: con las condiciones iniciales"
print*, "q: salir"
print*
read*, opt
print*
select case (opt)
case ("c", "c")
x = vars % val
call run
case ("i", "i")
x = vars % inval
t=0
call run
end select
end do
call tidyup
end program driver

También podría gustarte