ดูเหมือนจะมีความสับสนเล็กน้อยเกี่ยวกับวิธีการใช้วิธีการหลายขั้นตอน (เช่น Runge-Kutta) กับลำดับที่ 2 หรือสูงกว่าเพื่อ ODEs หรือระบบของ ODE กระบวนการนี้ง่ายมากเมื่อคุณเข้าใจ แต่อาจไม่ชัดเจนหากไม่มีคำอธิบายที่ดี วิธีการต่อไปนี้เป็นวิธีที่ฉันพบง่ายที่สุด
ในกรณีของคุณสมการเชิงอนุพันธ์ที่คุณต้องการที่จะแก้ปัญหาคือ{x} ขั้นตอนแรกคือการเขียน ODE ลำดับที่สองนี้เป็นระบบของ ODE ลำดับที่หนึ่ง สิ่งนี้จะทำตามF= m x¨
[ x˙โวลต์˙] = [ vF/ม]
สมการทั้งหมดในระบบนี้จะต้องแก้ไขพร้อมกันซึ่งก็คือบอกว่าคุณไม่ควรเลื่อนแล้วเลื่อนพวกเขาทั้งคู่ควรจะก้าวหน้าในเวลาเดียวกัน ในภาษาที่รองรับการทำงานของเวกเตอร์โดยไม่มีการวนซ้ำทำได้ง่าย ๆ โดยทำข้อกำหนดที่จำเป็นทั้งหมดในเวกเตอร์โค้ดที่มีความยาว 2 ฟังก์ชันที่คำนวณด้านขวามือ (อัตราการเปลี่ยนแปลง) ของ ODE ของคุณควรคืนค่าเวกเตอร์ที่มีความยาว 2 , การควรจะเป็นพาหะของความยาว 2 และตัวแปรของรัฐควรจะเป็นเวกเตอร์ของความยาว 2. ใน MATLAB รหัสที่จำเป็นสำหรับเวลาก้าวสามารถเขียนเป็น:โวลต์xk1
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
ที่และผลตอบแทนที่มีเวกเตอร์(t)) อย่างที่คุณเห็นโดยการทำให้เวกเตอร์เป็นสิ่งที่คุณไม่จำเป็นต้องเปลี่ยนไวยากรณ์ของรหัส RK4 ไม่ว่าจะมีสมการกี่อันในระบบ ODE ของคุณX
= ( x , v )RHS( t, X )
( x˙( t ) , v˙( T ) )
น่าเสียดายที่ C ++ ไม่สนับสนุนการทำงานของเวกเตอร์ในลักษณะนี้ดังนั้นคุณต้องใช้ไลบรารีเวกเตอร์ใช้ลูปหรือเขียนส่วนต่าง ๆ ด้วยตนเอง ใน C ++ คุณสามารถใช้std::valarray
เพื่อให้ได้ผลเหมือนกัน นี่คือตัวอย่างการทำงานที่เรียบง่ายพร้อมการเร่งความเร็วคงที่
#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;
}