El método de Runge-Kutta (RK) es un conjunto de métodos iterativos (implícitos y explícitos) para la aproximación de soluciones de ecuaciones diferenciales ordinarias, en esta documentación se muestra el de cuarto y sexto orden. Otro método agregado es la Regla Trapezoidal que puede ser explícita, para diferenciar los métodos de solución explícito e implícito se agregan los dos puntos siguientes:
Autor : Marco Polo Jácome Toss Fecha de creación : 12 de Septiembre del 2017Licencia : GNU General Public License (GPL) 3.0Plataforma : ScilabCódigo fuente creado para dar solución numérica a múltiples ecuaciones diferenciales.Actualizado : 04 de Abril del 2022Método de integración explícito. En este método es posible calcular la aproximación en cada paso directamente evaluando la función f(x,y), como ejemplo de un método de integración explicito se muestra la regla del punto medio.
Donde
Método de integración implícito. Las aproximaciones en este método vienen definidas por un sistema de ecuaciones implícito. En la siguiente ecuación se muestra la forma implícita del método de integración del punto medio.
La ventaja del "scripting" es poder dar solución en forma ordenada a n número de ecuaciones diferenciales.
Se considera el problema de valor inicial (PVI) de ecuaciones diferenciales ordinarias (EDO) :
Lo anterior es bastante importante debido a que debemos indicar las condiciones iniciales para poder dar solución a una EDO.
Debido a su simplicidad de resolver varias ecuaciones de estado es flexible para dar solución a modelos de máquinas eléctricas como para otros tipos de modelos que dependan principalmente del tiempo o en caso contrario que no involucre esta variable.
Las líneas de código siguientes pertenecen al archivo start.sce el cual contiene tres métodos de solución Rk4,Rk3 y Trapezoidal ya antes mencionados.
xxxxxxxxxxgetd .;op=input('Seleccione la forma de solucion : RK4(1) / RK6(2) / RTRAPEZOIDAL(3) : ')mnecudif(op)
La siguiente lista de archivos (dependientes) muestra como se encuentra estructurado en forma general el programa y siempre debe ejecutar el archivo start.sce para poder llamar la lista restante de archivos con extensión *.sci .
Start
De manera sencilla iniciamos el Start.sce e inmediatamente se indica el tipo de método a ocupar.
xxxxxxxxxx**Seleccione la forma de solución : RK4(1) / RK6(2) / RTRAPEZOIDAL(3) : **En el archivo ecuDif es necesario especificar las ecuaciones de estado, por lo que Xdot contiene dos ecuaciones de estado por este motivo se tiene dos variables Xdot(1,1) y Xdot(2,1). Estas variables se pasan a los archivos rk4.sci y rk6.sci junto con la variable de tiempo para poder dar solución a la EDO.
En este archivo se introducen las constantes y valores necesarios de las ecuaciones de estado con sus respectivas variables de estado representados con Xdot, todo es un arreglo matricial.
xxxxxxxxxxfunction [Xdot]=ecuDif(t,x) m=0.5; b=0.1; L=0.5; g=9.81; k=b/(m*L); Xdot=zeros(2,1); //#Xdot Xdot(1,1)=x(2); Xdot(2,1)=-(g/L)*sin(x(1))-(k/m)*x(2);endfunctionEs necesario cambiar la línea del archivo rk4 o rk6 que contiene disp([t(i),r(1,i)',r(2,i)']) al incrementar las variables y ecuaciones o únicamente mostrar una al igual que las variables iniciales mostradas en el archivo attributes.sci.
xxxxxxxxxxfunction [t,r]=rk6(t0, tf, N, conIni) matrixSize= size(conIni,1) if (matrixSize==1) then conIni=conIni'; endh=(tf-t0)/N; //Pasot(1) = t0;r(:,1) = conIni; //Condiciones Inicialesfor i = 1:N //Seccion Modificable para matriz disp([t(i),r(1,i)',r(2,i)']) // Cambiar #Xdot k1 = h*ecuDif(t(i), r(:,i)); k2 = h*ecuDif(t(i)+h, r(:,i)+k1); k3 = h*ecuDif(t(i)+h/2, r(:,i)+(3*k1+k2)/8); k4 = h*ecuDif(t(i)+(2*h)/3, r(:,i)+(8*k1+2*k2+8*k3)/27); k5 = h*ecuDif(t(i)+((7-sqrt(21))*h)/14,r(:,i)+((3*k1*(3*sqrt(21)-7))-(8*k2*(7-sqrt(21)))+(48*k3*(7-sqrt(21)))-(3*k4*(21-sqrt(21))))/392); k6 = h*ecuDif(t(i)+(7+sqrt(21))*h/14, r(:,i)+(-5*k1*(231+51*sqrt(21))-40*k2*(7+sqrt(21))-320*k3*sqrt(21)+3*k4*(21+121*sqrt(21))+392*k5*(6+sqrt(21)))/1960); r(:,i+1) = r(:,i)+(15*k1*(22+7*sqrt(21))+120*k2+40*k3*(7*sqrt(21)-5)-63*k4*(3*sqrt(21)-2)-14*k5*(49+9*sqrt(21))+70*k6*(7-sqrt(21)))/180; t(i +1) = t0 + i*h;end[t,r']; endfunctionxxxxxxxxxxfunction [t,r]=rk4(t0, tf, N, conIni) matrixSize= size(conIni,1) if (matrixSize==1) then conIni=conIni'; endh=(tf-t0)/N; //Pasot(1) = t0;r(:,1) = conIni; //Condiciones Inicialesfor i = 1:N //Seccion Modificable para matriz disp([t(i),r(1,i)',r(2,i)']) //Cambiar #Xdot k1 = h*ecuDif(t(i), r(:,i)); k2 = h*ecuDif(t(i)+h/2, r(:,i)+0.5*k1); k3 = h*ecuDif(t(i)+h/2, r(:,i)+0.5*k2); k4 = h*ecuDif(t(i)+h, r(:,i)+k3); r(:,i+1) = r(:,i) + (k1 + 2*k2 + 2*k3 + k4)/6; t(i +1) = t0 + i*h;end[t,r']; endfunctionxxxxxxxxxxfunction [t,r]=rtrapezoidal(t0, tf, N, conIni) matrixSize= size(conIni,1) if (matrixSize==1) then conIni=conIni'; endh=(tf-t0)/N; //Pasot(1) = t0;r(:,1) = conIni; //Condiciones Inicialesfor i = 1:N //Seccion Modificable para matriz disp([t(i),r(1,i)',r(2,i)']) //Cambiar #Xdot y1 = r(:,i)+h*ecuDif(t(i), r(:,i)); y2 = r(:,i)+(h/2)*((ecuDif(t(i), r(:,i)))+(ecuDif(t(i)+h, y1))); r(:,i+1) = y2; t(i +1) = t0 + i*h;end[t,r']; endfunctionEl archivo contiene los atributos de la simulación y debe establecer el número de condiciones iniciales, las cuales dependen de las variables de estado a resolver siendo necesario modificar la impresión disp([t(i),r(1,i)',r(2,i)']) de los archivos rk4 y rk6.
ti: tiempo inicial de simulación.tf: tiempo final de simulación.varIni: variables iniciales.muestras: muestras.Los valores iniciales mostrados en el bloque siguiente son el tiempo inicial, tiempo final, valores iniciales en este caso para dos variables y el número de muestras.
xxxxxxxxxxglobal ti tf varIni muestras ti=0;tf=10;varIni=[0.01, 0.02]; //Cambiar #Xdotmuestras=10000;Las opciones mencionadas en la parte 1.1 pertenecen al código siguiente :
xxxxxxxxxxfunction mnecudif(alg) if(alg == 1) then [t,r]=rk4(ti,tf,muestras,varIni); plot(t,[r(1,:)',r(2,:)']) legend('Xdot(1)','Xdot(2)') xlabel('tiempo, seg') ylabel('Y') title('Solución Runge Kutta orden 4') xgrid elseif ( alg == 2) then [t,r]=rk6(ti,tf,muestras,varIni); plot(t,[r(1,:)',r(2,:)']) legend('Xdot(1)','Xdot(2)') xlabel('tiempo, seg') ylabel('Ysol') title('Solución Runge Kutta orden 6') xgrid elseif (alg == 3) then [t,r]=rtrapezoidal(ti,tf,muestras,varIni); plot(t,[r(1,:)',r(2,:)']) legend('Xdot(1)','Xdot(2)') xlabel('tiempo, seg') ylabel('Y') title('Solución Regla Trapezoidal Explicita') xgrid else disp('Error: Seleccione un método de solución '); endendfunction Un péndulo simple se define como una partícula de masa "m" suspendida "O" por un hilo inextensible de longitud "L" y de masa despreciable.
Aplicando la segunda Ley de Newton, siendo la aceleración de la partícula hacia adentro de la trayectoria circular se obtiene:
Siendo la aceleración de la partícula hacia adentro dada por:
La aceleración tangencial de la partícula es:
De la segunda Ley de Newton incluyendo la fricción se obtiene:
El valor de k (fricción) esta dado por :
Las variables de estado son :
Por lo tanto, las ecuaciones de estado son las siguientes:
Estableciendo la ecuaciones en el archivo ecuDif.sci y valores correspondientes.
xxxxxxxxxxfunction [Xdot]=ecuDif(t,x) m=0.5; b=0.1; L=1.5; g=9.81; k=b/(m*L); Xdot=zeros(2,1); //#Xdot Xdot(1,1)=x(2); Xdot(2,1)=-(g/L)*sin(x(1))-(k/m)*x(2);endfunctionLa solución paraXdot(1) y Xdot(2) de las ecuaciones de estado es:

Utilizando el método de la transformada de Laplace se resolverá la ecuación diferencial siguiente:
Aplicando la transformada de Laplace a la Ecuación diferencial anterior se obtiene la solución para Y(S).
La solución en el dominio del tiempo se obtiene con la transformada inversa.
El resultado anterior se grafica con Scilab mediante el bloque siguiente:
xxxxxxxxxxt=0:0.01:1;y=8*exp(-3*t)-2*cos(2*t)+3*sin(2*t)plot(t,y)xlabel("Tiempo, seg.")ylabel('y(t)')title('Solución de la Ecuación Diferencial')xgrid()La solución de la ecuación diferencial y gráfica se muestra a continuación:

Para dar solución es necesario configurar el archivo ecuDif de la forma siguiente:
xxxxxxxxxxfunction [Xdot]=ecuDif(t,x) Xdot=zeros(1,1); //#Xdot Xdot(1,1)=13*sin(2*t)-3*x(1)endfunctionModificamos las condiciones iniciales del archivo attributes como se muestra:
xxxxxxxxxxglobal ti tf varIni muestras ti=0;tf=1;varIni=[6,0]; //Cambiar #Xdotmuestras=1000;Se debe ajustar el archivo mnecudif para mostrar únicamente una solución, esta ecuación diferencial tiene una única variable.
xxxxxxxxxxfunction mnecudif(alg)if(alg == 1) then[t,r]=rk4(ti,tf,muestras,varIni);plot(t,[r(1,:)])legend('Xdot(1)')xlabel('tiempo, seg')ylabel('Y')title('Solución Runge Kutta orden 4')xgridelseif ( alg == 2) then[t,r]=rk6(ti,tf,muestras,varIni);plot(t,[r(1,:)'])legend('Xdot(1)')xlabel('tiempo, seg')ylabel('Ysol')title('Solución Runge Kutta orden 6')xgridelseif (alg == 3) then[t,r]=rtrapezoidal(ti,tf,muestras,varIni);plot(t,[r(1,:)'])legend('Xdot(1)')xlabel('tiempo, seg')ylabel('Y')title('Solución Regla Trapezoidal Explicita')xgridelsedisp('Error: Seleccione un método de solución ');endendfunction Finalmente al realizar estas modificaciones podrás observar la solución siguiente:

Copyright © 2017 en adelante, Marco Polo Jácome Toss (rk4,rk6,trapezoidal). Este programa es software libre: usted puede redistribuirlo y /o modificarlo bajo los términos de la Licencia General GNU (GNU General Public License) publicado por la Fundación para el Software Libre para la versión 3 de dicha Licencia o anterior, o cualquier versión posterior.
Este programa se distribuye con la esperanza de que sea útil pero sin ninguna garantía; incluso sin la garantía implícita de comercialización o idoneidad para un propósito en particular.
Vea la información de Licencia de RK4 para más detalle.