Çok aşamalı (örneğin Runge-Kutta) yöntemlerin 2. veya daha yüksek dereceden ODE'lere veya ODE sistemlerine nasıl uygulanacağı konusunda biraz karışıklık var gibi görünüyor. İşlem, anladıktan sonra çok basittir, ancak iyi bir açıklama olmadan belki de açık değildir. Aşağıdaki yöntem en basit bulduğum yöntemdir.
Sizin durumunuzda, çözmek istediğiniz diferansiyel denklem . İlk adım, bu ikinci dereceden ODE'yi birinci dereceden ODE'lerin bir sistemi olarak yazmaktır. Bu şu şekilde yapılır:F=mx¨
[x˙v˙]=[vF/m]
Bu sistemde tüm denklemler sen gerektiğini söylemek olan eşzamanlı çözülmesi gerektiğini değil avans ve sonra avans , her ikisi de aynı anda ileri olmalıdır. Döngüsüz vektör işlemlerini destekleyen dillerde, bu, uzunluk 2 kod vektörlerinizde gerekli tüm terimleri yaparak kolayca yapılabilir. , için 2 uzunluğunda vektörler gerekir ve durum değişkeni zaman atlama için gerekli olan kod olarak yazılabilir MATLAB uzunluğu, 2'nin bir vektör olması gerekir:x ( x , v )vxk1
k4
(x,v)
while (t<TMAX)
k1 = RHS( t, X );
k2 = RHS( t + dt / 2, X + dt / 2 * k1 );
k3 = RHS( t + dt / 2, X + dt / 2 * k2 );
k4 = RHS( t + dt, X + dt * k3 );
X = X + dt / 6 * ( k1 + 2 * k2 + 2 * k3 + k4 );
t = t + dt;
end
burada ve içeren bir vektör döndürür . Gördüğünüz gibi, şeyleri vektörleştirerek, ODE sisteminizde kaç denklem olursa olsun RK4 kodunun sözdizimini değiştirmeniz bile gerekmez.X
( ˙ x ( t ) , ˙ v ( t ) )=(x,v)RHS( t, X )
(x˙(t),v˙(t))
Ne yazık ki C ++ böyle vektör işlemlerini yerel olarak desteklemediğinden, bir vektör kütüphanesi kullanmanız, döngüler kullanmanız veya ayrı parçaları manuel olarak yazmanız gerekir. C ++ ' std::valarray
da aynı efekti elde etmek için kullanabilirsiniz . İşte sabit ivmeli basit bir çalışma örneği.
#include <valarray>
#include <iostream>
const size_t NDIM = 2;
typedef std::valarray<double> Vector;
Vector RHS( const double t, const Vector X )
{
// Right hand side of the ODE to solve, in this case:
// d/dt(x) = v;
// d/dt(v) = 1;
Vector output(NDIM);
output[0] = X[1];
output[1] = 1;
return output;
}
int main()
{
//initialize values
// State variable X is [position, velocity]
double init[] = { 0., 0. };
Vector X( init, NDIM );
double t = 0.;
double tMax=5.;
double dt = 0.1;
//time loop
int nSteps = round( ( tMax - t ) / dt );
for (int stepNumber = 1; stepNumber<=nSteps; ++stepNumber)
{
Vector k1 = RHS( t, X );
Vector k2 = RHS( t + dt / 2.0, X + dt / 2.0 * k1 );
Vector k3 = RHS( t + dt / 2.0, X + dt / 2.0 * k2 );
Vector k4 = RHS( t + dt, X + dt * k3 );
X += dt / 6.0 * ( k1 + 2.0 * k2 + 2.0 * k3 + k4 );
t += dt;
}
std::cout<<"Final time: "<<t<<std::endl;
std::cout<<"Final position: "<<X[0]<<std::endl;
std::cout<<"Final velocity: "<<X[1]<<std::endl;
}