Você está na página 1de 3

program oscilador

implicit none
call oscillator
end program oscilador
!--------------------------------------------------------------------
subroutine oscillator
!--------------------------------------------------------------------
!Movimiento oscilatorio en el eje x
!Descrito por un sistema de EDO's de segundo orden
!--------------------------------------------------------------------
implicit none
integer, parameter::n=2 !numero de las ecuaciones de primer orden
double precision ti,tf,dt,tmax
double precision xi(n),xf(n)
double precision energy0,energy
double precision,parameter::k=1.0
double precision,parameter::m=1.0
double precision,parameter::b=0.5
!double precision,parameter::F0=1.0
!double precision,parameter::w=1.0
integer i
external d2x

!abrir archivos para escribir resultados


open (unit=10,file='oscillator.dat')

!*** Datos iniciales

ti=0.00 !valores iniciales para la variable t


xi(1)=0.50 !posici�n inicial en x(m)
xi(2)=0.00 !velocidad inicial en direcci�n x (m/s)

!***Limites y pasos de integraci�n


dt=0.2 !tama�o de pasos para la integraci�n (s)
tmax=60.0 !integrar hasta tmax (s)
!***fin de los datos iniciales

energy0=m*xi(2)**2/2+k*xi(1)**2/2

!Imprimir las condiciones iniciales y la cabezera

write(10,*)' Movimiento de un proyectil'


write(10,*)' M�todo: Runge-Kutta de 4� orden'
write(10,100)
write(10,102) ti, xi(1), xi(2), energy0

!Integraci�n de las EDO's

do while (ti <= tmax)


tf = ti + dt

call rk4n(d2x,ti,tf,xi,xf,n) !Llamar a la subrutina rk4n

energy=m*xf(2)**2/2 + k*xf(1)**2/2

write(10,102) tf, xf(1), xf(2), energy

!Preparar para el siguiente paso


ti = tf
do i=1,n
xi(i)=xf(i)
end do
end do

100 format(5x,'t',11x,'x',11x,'dx/dt',11x,'energia')
102 format(4(1pe12.3))
end subroutine oscillator

!--------------------------------------------------------------------

subroutine d2x(t,x,dx,n)
implicit none
integer n
double precision t
double precision x(n),dx(n)

!Movimiento oscilatorio simple en el eje x

double precision,parameter::k=1.0
double precision,parameter::m=1.0
double precision,parameter::b=0.5
double precision,parameter::F0=1.0
double precision,parameter::w=1.0

!Primer orden

dx(1)=x(2)

!Segundo orden

dx(2)=-(k/m)*x(1)-(b/m)*x(2)+(F0/m)*cos(w*t)

end subroutine d2x

!--------------------------------------------------------------------

subroutine rk4n(fcn,ti,tf,xi,xf,n)
implicit none
integer n
double precision ti,tf
double precision xi(n),xf(n)

integer j
double precision h,t
double precision x(n),dx(n)
double precision k1(n),k2(n),k3(n),k4(n)

external fcn
h=tf-ti
t=ti

call fcn(t,xi,dx,n)
do j=1,n
k1(j)=h*dx(j)
x(j)=xi(j)+k1(j)/2.0
end do
call fcn(t+h/2.0,x,dx,n)
do j=1,n
k2(j)=h*dx(j)
x(j)=xi(j)+k2(j)/2.0
end do

call fcn(t+h/2.0,x,dx,n)
do j=1,n
k3(j)=h*dx(j)
x(j)=xi(j)+k3(j)
end do

call fcn(t+h,x,dx,n)
do j=1,n
k4(j)=h*dx(j)
xf(j)=xi(j)+k1(j)/6.0+k2(j)/3.0+k3(j)/3.0+k4(j)/6.0
end do

end subroutine rk4n

Você também pode gostar