Редактирование: Сравнение методов Рунге-Кутта и Липфрога
Внимание! Вы не авторизовались на сайте. Ваш IP-адрес будет публично видимым, если вы будете вносить любые правки. Если вы войдёте или создадите учётную запись, правки вместо этого будут связаны с вашим именем пользователя, а также у вас появятся другие преимущества.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия | Ваш текст | ||
Строка 1: | Строка 1: | ||
[[Виртуальная лаборатория]]>[[Сравнение методов Рунге-Кутта и Липфрога]] <HR> | [[Виртуальная лаборатория]]>[[Сравнение методов Рунге-Кутта и Липфрога]] <HR> | ||
+ | Сравнение методов численного интегрирования: Рунге-Кутта и Липфрога | ||
− | + | В данном примере интегрируется уравнение грузика на пружинке: <math>\ddot{x} = -cx</math> методом Рунге-Кутта и Липфрога. Строится фазовая плоскость для каждого из методов. | |
− | = | + | {{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Pogodina/Integrate/Chain_v3_release.html |width=1000 |height=2000 |border=0 }} |
− | |||
− | |||
− | + | Скачать [[Медиа:New1.rar|New1.rar]]. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
<div class="mw-collapsible mw-collapsed" style="width:100%" > | <div class="mw-collapsible mw-collapsed" style="width:100%" > | ||
− | '''Текст программы на языке JavaScript (разработчик [[Погодина Валерия]]):''' <div class="mw-collapsible-content"> | + | '''Текст программы на языке JavaScript (разработчик [[Погодина Валерия]], код основан на программе [[Цветков Денис]]):''' <div class="mw-collapsible-content"> |
− | Файл '''" | + | Файл '''"Integral3"''' |
<syntaxhighlight lang="javascript" line start="1" enclose="div"> | <syntaxhighlight lang="javascript" line start="1" enclose="div"> | ||
− | + | window.addEventListener("load", Main_Integrate, true); | |
− | + | function Main_Integrate() { | |
− | + | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | function | ||
// Предварительные установки | // Предварительные установки | ||
− | + | ||
− | var | + | var context = Integrate_canvas.getContext("2d"); // на context происходит рисование |
− | + | var context1 = Integrate_canvas1.getContext("2d"); // на context происходит рисование | |
− | + | var T0 = 1; // масштаб времени (период колебаний исходной системы) | |
− | + | var time = 0; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | var | ||
− | |||
− | |||
+ | // *** Задание вычислительных параметров *** | ||
+ | |||
+ | //const fps = 5500; // frames per second - число кадров в секунду (качеcтво отображения) | ||
+ | //const spf = 260; // steps per frame - число шагов интегрирования между кадрами (скорость расчета) | ||
+ | //const dt = 0.1 * T0 / fps; // шаг интегрирования | ||
+ | const fps = 550; // frames per second - число кадров в секунду (качеcтво отображения) | ||
+ | const spf = 5; // steps per frame - число шагов интегрирования между кадрами (скорость расчета) | ||
+ | const dt = 1 * T0; // шаг интегрирования | ||
+ | var n = 10; | ||
− | + | Text_n.value = n; | |
− | + | Slider_n.min = 1; | |
− | + | Slider_n.max = 100; | |
− | + | Slider_n.step = 1; | |
− | + | Slider_n.value = Text_n.value; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | // Добавление шара | |
− | + | var particles = []; | |
− | for (var | + | var particles1 = []; |
− | + | for (var i=0; i<n; i++) { | |
− | + | particles[i] = []; | |
+ | particles1[i] = []; | ||
} | } | ||
− | + | for (var i = 0; i < n; i++) { | |
− | + | for (var j = 0; j < n; j++) { | |
− | + | var b = []; | |
− | + | var a = []; | |
− | + | b.x = 0.3 / n * i; | |
− | + | b.vx =j * 0.3 / n; | |
− | + | a.x = 0.3 / n * i; | |
− | + | a.vx =j * 0.3 / n; | |
− | + | particles[i][j] = b; | |
− | + | particles1[i][j] = a; | |
− | + | } | |
− | |||
− | |||
− | |||
} | } | ||
− | + | this.set_n = function(input) | |
− | + | { | |
− | + | n = Number(input); | |
− | + | Text_n.value = n; | |
− | + | Slider_n.value = Text_n.value; //записываем значение начального смещения | |
− | + | for (var i=0; i<n; i++) { | |
− | + | particles[i] = []; | |
− | + | particles1[i] = []; | |
− | + | } | |
− | + | for (var i = 0; i < n; i++) { | |
− | + | for (var j = 0; j < n; j++) { | |
− | + | var b = []; | |
− | + | var a = []; | |
− | + | b.x = 0.3 / n * i; | |
− | + | b.vx = j * 0.3 / n; | |
− | + | a.x = 0.3 / n * i; | |
+ | a.vx = j * 0.3 / n; | ||
+ | particles[i][j] = b; | ||
+ | particles1[i][j] = a; | ||
+ | } | ||
+ | } ; | ||
+ | context.clearRect(0, 0, 300, 300); | ||
+ | context1.clearRect(0, 0, 300, 300); | ||
} | } | ||
− | + | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | setInterval(control1, 1500 / fps); | ||
− | + | function control1() { | |
− | + | physics1(); | |
− | + | draw(); | |
− | + | } | |
− | |||
− | |||
− | |||
− | + | function physics1() { // то, что происходит каждый шаг времени | |
− | // | + | for (var s = 1; s <= spf; s++) { |
− | + | for (i = 0; i < n; i++) { | |
− | + | for (j = 0; j < n; j++) { | |
− | + | runge(); | |
− | + | leapfrog(); | |
− | + | } | |
− | + | } | |
− | + | } | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | function leapfrog(){ | |
− | + | particles1[i][j].vx = particles1[i][j].vx - particles1[i][j].x * dt; | |
− | + | particles1[i][j].x = particles1[i][j].x + particles1[i][j].vx * dt; | |
− | + | console.log(particles1[0][0].x); | |
− | + | } | |
− | |||
− | + | function runge() { | |
− | + | var k1, k2, k3, k4; | |
− | + | k1 = - (particles[i][j].x); | |
− | + | k2 = - (particles[i][j].x + k1 * dt / 2); | |
− | + | k3 = - (particles[i][j].x + k2 * dt / 2); | |
− | + | k4 = - (particles[i][j].x + k3 * dt); | |
+ | particles[i][j].vx = particles[i][j].vx + dt / 6 * (k1 + 2 * k2 + 2 * k3 + k4); | ||
+ | k1 = (particles[i][j].vx); | ||
+ | k2 = (particles[i][j].vx + k1 * dt / 2); | ||
+ | k3 = (particles[i][j].vx + k2 * dt / 2); | ||
+ | k4 = (particles[i][j].vx + k3 * dt); | ||
+ | particles[i][j].x = particles[i][j].x + dt / 6 * (k1 + 2 * k2 + 2 * k3 + k4); | ||
+ | console.log(particles[0][0].x); | ||
+ | } | ||
− | + | function draw() { | |
− | + | context.clearRect(0, 0, 600, 600); | |
− | + | context.fillStyle="#000000"; | |
− | + | context.beginPath(); | |
− | + | context.moveTo(0, 300); | |
− | + | context.lineTo(600, 300); | |
− | + | context.stroke(); | |
− | + | context.beginPath(); | |
− | + | context.moveTo(300, 0); | |
− | + | context.lineTo(300, 600); | |
− | + | context.stroke(); | |
− | + | context1.clearRect(0, 0, 600, 600); | |
− | + | context1.fillStyle="#000000"; | |
− | + | context1.beginPath(); | |
− | + | context1.moveTo(0, 300); | |
− | + | context1.lineTo(600, 300); | |
− | + | context1.stroke(); | |
− | + | context1.beginPath(); | |
− | + | context1.moveTo(300, 0); | |
− | + | context1.lineTo(300, 600); | |
+ | context1.stroke(); | ||
+ | for (var i = 0; i < n; i++) { | ||
+ | for (var j = 0; j < n; j++) { | ||
+ | context.beginPath(); | ||
+ | context.arc(particles[i][j].x * 300 + 300, 300 - particles[i][j].vx * 300, 1, 0, 2 * Math.PI, false); //рисуем шар | ||
+ | context.fill(); | ||
+ | context.closePath(); | ||
− | + | context1.beginPath(); | |
− | + | context1.arc(particles1[i][j].x * 300 + 300, 300 - particles1[i][j].vx * 300, 1, 0, 2 * Math.PI, false); //рисуем шар | |
− | + | context1.fill(); | |
+ | context1.closePath(); | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | } | + | } |
− | + | } | |
− | + | </syntaxhighlight> | |
− | + | Файл '''"Chain_v3_release.html"''' | |
+ | <syntaxhighlight lang="html5" line start="1" enclose="div"> | ||
+ | <!DOCTYPE html> | ||
+ | <html> | ||
+ | <head> | ||
+ | <meta charset="UTF-8"/> | ||
+ | <title> Integrate </title> | ||
+ | <script src="Integral3.js"></script> | ||
+ | </head> | ||
+ | <body> | ||
+ | <canvas id="Integrate_canvas" width="600" height="600" style="border:1px solid #000000;"></canvas> | ||
+ | <canvas id="Integrate_canvas1" width="600" height="600" style="border:1px solid #000000;"></canvas> | ||
+ | <div> | ||
+ | <!-- n--> | ||
+ | <div> | ||
+ | n = | ||
+ | <input id="Text_n" style="width: 4.2ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput=" | ||
+ | if (!this.checkValidity()) return; | ||
+ | app.set_n(this.value); | ||
+ | document.getElementById('Slider_n').value = this.value; | ||
+ | "> | ||
+ | <input type = "range" id="Slider_n" style="width: 100px;" oninput="app.set_n(this.value); document.getElementById('Text_n').value = this.value;"> | ||
+ | </I></font> | ||
+ | </div> | ||
+ | </div> | ||
+ | <script type="text/javascript"> app = new Main_Integrate(document.getElementById('Integrate_canvas'),document.getElementById('Integrate_canvas1'));</script> | ||
+ | </body> | ||
+ | </html> | ||
</syntaxhighlight> | </syntaxhighlight> | ||
</div> | </div> | ||
</div> | </div> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
[[Category: Виртуальная лаборатория]] | [[Category: Виртуальная лаборатория]] | ||
[[Category: Программирование]] | [[Category: Программирование]] | ||
[[Category: JavaScript]] | [[Category: JavaScript]] |