Колебания энергий в одномерном кристалле — различия между версиями
Материал из Department of Theoretical and Applied Mechanics
Денис (обсуждение | вклад) |
Денис (обсуждение | вклад) |
||
(не показано 8 промежуточных версий этого же участника) | |||
Строка 1: | Строка 1: | ||
− | [[en: | + | [[en:Energy fluctuations in one-dimensional crystal]] |
+ | [[ТМ|Кафедра ТМ]] > [[Проект "Термокристалл"]] > [[Колебания энергий в одномерном кристалле]] <HR> | ||
[[Виртуальная лаборатория]] > [[Колебания энергий в одномерном кристалле]] <HR> | [[Виртуальная лаборатория]] > [[Колебания энергий в одномерном кристалле]] <HR> | ||
+ | [[Д.В. Цветков]] (программирование), [[А.М. Кривцов]] (аналитическое решение) <HR> | ||
Данная программа демонстрирует колебания кинетической, потенциальной и полной энергий в одномерном кристалле. | Данная программа демонстрирует колебания кинетической, потенциальной и полной энергий в одномерном кристалле. | ||
− | + | Колебания кинетической энергии описываются следующим уравнением: | |
− | Скачать программу: [[Медиа: | + | :<math> |
+ | K_J(t) = \frac{E}{2} \left(1 + J_0(4 \omega_0 )\right) | ||
+ | ,\qquad \omega_0 = \sqrt{C/m}, | ||
+ | </math> | ||
+ | где | ||
+ | <math>J_0</math> — Функция Бесселя первого рода в точке 0, | ||
+ | <math>C</math> — жесткость связи между частицами, | ||
+ | <math>m</math> — масса частицы. | ||
+ | |||
+ | {{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Tcvetkov/Bessel_fluctuations/Bessel_fluctuations_v3.0/Bessel_fluctuations.html |width=1055 |height=675 |border=0 }} | ||
+ | |||
+ | Скачать программу: [[Медиа:Bessel_fluctuations_v3.0.zip|Bessel_fluctuations_v3.0.zip]] | ||
<div class="mw-collapsible mw-collapsed" style="width:100%" > | <div class="mw-collapsible mw-collapsed" style="width:100%" > | ||
− | '''Текст программы на языке JavaScript ( | + | '''Текст программы на языке JavaScript (использована библиотека [https://github.com/SheetJS/bessel bessel.js]):''' <div class="mw-collapsible-content"> |
Файл '''"Bessel_fluctuations.js"''' | Файл '''"Bessel_fluctuations.js"''' | ||
<syntaxhighlight lang="javascript" line start="1" enclose="div"> | <syntaxhighlight lang="javascript" line start="1" enclose="div"> | ||
Строка 27: | Строка 40: | ||
var dt = 0.02 * t0; // шаг интегрирования по времени | var dt = 0.02 * t0; // шаг интегрирования по времени | ||
− | var N = | + | var R = 10; // количество реализаций |
− | var | + | var N = 10000; // количество частиц в каждой реализации |
+ | var periods = 10; // время расчета в периодах колебаний энергий | ||
var koeff = C / (dx * dx) / m * dt; // коэффициент для уравнения динамики частиц | var koeff = C / (dx * dx) / m * dt; // коэффициент для уравнения динамики частиц | ||
+ | |||
+ | var T; | ||
+ | // функция переводит время в периодах в расчетное время | ||
+ | function set_periods(n) { | ||
+ | // первый раз кинетическая и потенциальная энергии доходят до нуля за 0.4 периода колебаний | ||
+ | var T0 = Math.PI / (Math.sqrt(C / m)) / 2; // период колебаний | ||
+ | if (n >= 0.4 * T0) T = T0 * ( 0.4 + 0.75 + (n - 1) ); | ||
+ | else T = n; | ||
+ | } | ||
+ | set_periods(periods); | ||
// интерфейс программы | // интерфейс программы | ||
N_number.value = N; | N_number.value = N; | ||
N_number.oninput = function() {N = parseInt(N_number.value);}; | N_number.oninput = function() {N = parseInt(N_number.value);}; | ||
− | + | periods_number.value = periods; | |
− | + | periods_number.oninput = function() { | |
+ | set_periods(parseFloat(periods_number.value)); | ||
+ | }; | ||
+ | R_number.value = R; | ||
+ | R_number.oninput = function() {R = parseInt(R_number.value);}; | ||
button_start.onclick = calculate_new_system; | button_start.onclick = calculate_new_system; | ||
+ | button_stop.onclick = function() { | ||
+ | working = false; | ||
+ | }; | ||
+ | checkbox_Bessel.onchange = function() { | ||
+ | draw(); | ||
+ | if (checkbox_Bessel.checked) div_txt_J0.style.display = "block"; | ||
+ | else div_txt_J0.style.display = "none" | ||
+ | }; | ||
+ | checkbox_K.onchange = function() { | ||
+ | draw(); | ||
+ | if (checkbox_K.checked) div_txt_K.style.display = "block"; | ||
+ | else div_txt_K.style.display = "none" | ||
+ | }; | ||
+ | checkbox_P.onchange = function() { | ||
+ | draw(); | ||
+ | if (checkbox_P.checked) div_txt_P.style.display = "block"; | ||
+ | else div_txt_P.style.display = "none" | ||
+ | }; | ||
+ | checkbox_E.onchange = function() { | ||
+ | draw(); | ||
+ | if (checkbox_E.checked) div_txt_E.style.display = "block"; | ||
+ | else div_txt_E.style.display = "none" | ||
+ | }; | ||
− | + | var ctx = BF_canvas.getContext("2d"); // на context происходит рисование | |
− | + | var w = BF_canvas.width; // ширина окна в расчетных координатах | |
− | + | var h = BF_canvas.height; // высота окна в расчетных координатах | |
− | |||
− | var ctx = BF_canvas.getContext("2d"); | ||
− | var w = BF_canvas.width; | ||
− | var h = BF_canvas.height; | ||
// основная расчетная функция | // основная расчетная функция | ||
var data_K, data_P, data_E; // данные для графика | var data_K, data_P, data_E; // данные для графика | ||
− | |||
var t, n; | var t, n; | ||
var t_start; | var t_start; | ||
+ | var working; | ||
+ | var step; | ||
function calculate_new_system() { | function calculate_new_system() { | ||
− | |||
t = 0; | t = 0; | ||
n = N + 2; // количество узлов по оси x + 2 для ГУ | n = N + 2; // количество узлов по оси x + 2 для ГУ | ||
+ | working = true; | ||
+ | step = 0; | ||
+ | |||
span_time_calc.innerHTML = ""; | span_time_calc.innerHTML = ""; | ||
div_calc_speed.style.display = "none"; | div_calc_speed.style.display = "none"; | ||
+ | button_start.style.display = "none"; | ||
+ | button_stop.style.display = "inline"; | ||
// задание начальных условий | // задание начальных условий | ||
− | var P = []; | + | var all_P = []; |
− | + | for (var r = 0; r < R; r++) { | |
− | + | var P = []; | |
− | + | for (var i = 1; i < n - 1; i++) { | |
− | + | P[i] = {}; | |
+ | P[i].u = 0; | ||
+ | P[i].v = (2 * Math.random() - 1) * 0.25; | ||
+ | } | ||
+ | // периодические граничные условия | ||
+ | P[0] = P[n - 2]; | ||
+ | P[n - 1] = P[1]; | ||
+ | all_P.push(P); | ||
} | } | ||
− | |||
− | |||
− | |||
data_K = []; data_P = []; data_E = []; | data_K = []; data_P = []; data_E = []; | ||
Строка 74: | Строка 130: | ||
// основной расчет | // основной расчет | ||
t_start = performance.now(); | t_start = performance.now(); | ||
− | calculate( | + | calculate(all_P); |
} | } | ||
+ | calculate_new_system(); | ||
− | function calculate( | + | function calculate(all_P) { |
var t1 = performance.now(); | var t1 = performance.now(); | ||
− | |||
while (t < T) { | while (t < T) { | ||
// расчет энергий для графиков | // расчет энергий для графиков | ||
var Kin = 0; | var Kin = 0; | ||
var Pot = 0; | var Pot = 0; | ||
− | for (var j = 1; j < n - 1; j++) {Kin += P[j].v * P[j].v;} | + | for (var p = 0; p < all_P.length; p++) { |
− | + | var P = all_P[p]; | |
− | Kin = Kin * m; | + | for (var j = 1; j < n - 1; j++) {Kin += P[j].v * P[j].v;} |
− | Pot = Pot * C; | + | for (var j = 1; j < n - 1; j++) {Pot += Math.pow(P[j].u - P[j - 1].u, 2);} |
+ | } | ||
+ | Kin = Kin * m / all_P.length; | ||
+ | Pot = Pot * C / all_P.length; | ||
data_K.push(Kin); | data_K.push(Kin); | ||
data_P.push(Pot); | data_P.push(Pot); | ||
Строка 93: | Строка 152: | ||
// расчет состояния системы на следующем шаге | // расчет состояния системы на следующем шаге | ||
− | for (var i = 1; i < n - 1; i++) { | + | for (var p = 0; p < all_P.length; p++) { |
− | + | var P = all_P[p]; | |
− | + | for (var i = 1; i < n - 1; i++) { | |
− | + | P[i].v += (P[i + 1].u - 2 * P[i].u + P[i - 1].u) * koeff; | |
− | + | } | |
+ | for (var i = 1; i < n - 1; i++) { | ||
+ | P[i].u += P[i].v * dt; | ||
+ | } | ||
} | } | ||
+ | t += dt; | ||
+ | step++; | ||
− | + | // промежуточная прорисовка результатов, работа прогресс-бара | |
if ((performance.now() - t1) > 200) { | if ((performance.now() - t1) > 200) { | ||
− | draw(); | + | if (working) { |
− | + | draw(); | |
− | + | setTimeout( function(){calculate(all_P); }, 10); | |
− | + | div_container_progress.style.display = "block"; | |
− | + | progress_bar.style.width = Math.round(t / T * 100) + "%"; | |
− | + | span_progress.innerHTML = (t / T * 100).toFixed(0) + "%"; | |
+ | } else { | ||
+ | stop(); | ||
+ | } | ||
return; | return; | ||
} | } | ||
} | } | ||
+ | stop(); | ||
+ | } | ||
+ | function stop() { | ||
+ | // окончательная прорисовка результатов, удаление прогресс-бара, вывод скорости расчета | ||
draw(); | draw(); | ||
div_container_progress.style.display = "none"; | div_container_progress.style.display = "none"; | ||
button_start.style.display = "inline"; | button_start.style.display = "inline"; | ||
+ | button_stop.style.display = "none"; | ||
div_calc_speed.style.display = "block"; | div_calc_speed.style.display = "block"; | ||
− | span_time_calc.innerHTML = ((performance.now() - t_start) / N | + | span_time_calc.innerHTML = parseFloat(((performance.now() - t_start) * 1000 * 1000 / N / R / step).toPrecision(2)); |
return true; | return true; | ||
} | } | ||
Строка 122: | Строка 194: | ||
ctx.clearRect(0, 0, w, h); // очистка экрана | ctx.clearRect(0, 0, w, h); // очистка экрана | ||
− | // | + | if (checkbox_Bessel.checked) { |
− | + | // Функция Бесселя первого рода в точке 0 | |
− | + | ctx.strokeStyle = "#00dd00"; | |
− | + | ctx.lineWidth = 2; | |
− | + | ctx.beginPath(); | |
− | + | ctx.moveTo(0, h - data_E[data_E.length - 1] * besselj(4 * Math.sqrt(C / m) * 0, 0) / data_K[0] * h / 2 - h / 2); | |
− | + | for (var i = 0.001; i < t; i += 0.001) { | |
− | + | ctx.lineTo(i / t * w, h - data_E[data_E.length - 1] * besselj(4 * Math.sqrt(C / m) * i, 0) / data_K[0] * h / 2 - h / 2); | |
− | + | } | |
+ | ctx.stroke(); | ||
+ | } | ||
if (checkbox_K.checked) { | if (checkbox_K.checked) { | ||
Строка 142: | Строка 216: | ||
} | } | ||
ctx.stroke(); | ctx.stroke(); | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
Строка 161: | Строка 228: | ||
} | } | ||
ctx.stroke(); | ctx.stroke(); | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
Строка 179: | Строка 240: | ||
} | } | ||
ctx.stroke(); | ctx.stroke(); | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | |||
} | } | ||
} | } | ||
Строка 206: | Строка 260: | ||
en:"Full energy", | en:"Full energy", | ||
ru:"Полная энергия" | ru:"Полная энергия" | ||
+ | }, span_txt_Bessel:{ | ||
+ | field:"innerHTML", | ||
+ | en:"Analytical sol. for the kinetic energy", | ||
+ | ru:"Аналит. решение для кин. энергии" | ||
}, button_start:{ | }, button_start:{ | ||
field:"value", | field:"value", | ||
en:"Start", | en:"Start", | ||
ru:"Старт" | ru:"Старт" | ||
+ | }, button_stop:{ | ||
+ | field:"value", | ||
+ | en:"Stop", | ||
+ | ru:"Стоп" | ||
}, span_progress_txt:{ | }, span_progress_txt:{ | ||
field:"innerHTML", | field:"innerHTML", | ||
Строка 218: | Строка 280: | ||
en:"The calculation of this speed includes the time for processing interface and drawing the intermediate states of the system", | en:"The calculation of this speed includes the time for processing interface and drawing the intermediate states of the system", | ||
ru:"Расчет данной скорости включает в себя время на обработку интерфейса и прорисовку промежуточных состояний системы" | ru:"Расчет данной скорости включает в себя время на обработку интерфейса и прорисовку промежуточных состояний системы" | ||
− | }, | + | }, span_txt_molecular_dynamics:{ |
field:"innerHTML", | field:"innerHTML", | ||
− | en:" | + | en:"Molecular_dynamics:", |
− | ru:" | + | ru:"Молекулярная динамика:" |
+ | }, span_txt_particles:{ | ||
+ | field:"innerHTML", | ||
+ | en:"particles", | ||
+ | ru:"частиц" | ||
+ | }, span_txt_realizations:{ | ||
+ | field:"innerHTML", | ||
+ | en:"realizations", | ||
+ | ru:"реализаций" | ||
}, span_txt_calc_time:{ | }, span_txt_calc_time:{ | ||
field:"innerHTML", | field:"innerHTML", | ||
− | en:"Calculation time", | + | en:"Calculation time:", |
− | ru:"Время расчета" | + | ru:"Время расчета:" |
}, span_txt_calc_speed:{ | }, span_txt_calc_speed:{ | ||
field:"innerHTML", | field:"innerHTML", | ||
− | en:"Calculation speed", | + | en:"Calculation speed:", |
− | ru:"Скорость расчета" | + | ru:"Скорость расчета:" |
}, span_txt_ns_particle_step:{ | }, span_txt_ns_particle_step:{ | ||
field:"innerHTML", | field:"innerHTML", | ||
en:"ns/(particle⋅step)", | en:"ns/(particle⋅step)", | ||
ru:"нс/(частица⋅шаг)" | ru:"нс/(частица⋅шаг)" | ||
+ | }, span_txt_periods:{ | ||
+ | field:"innerHTML", | ||
+ | en:"periods", | ||
+ | ru:"периодов" | ||
+ | }, div_txt_P:{ | ||
+ | field:"innerHTML", | ||
+ | en:"P", | ||
+ | ru:"П" | ||
} | } | ||
}; | }; | ||
Строка 253: | Строка 331: | ||
<script src="Bessel_fluctuations.js"></script> | <script src="Bessel_fluctuations.js"></script> | ||
<script src="Lang/Lang.js"></script> | <script src="Lang/Lang.js"></script> | ||
+ | <script src="Libs/bessel.js"></script> | ||
<style> | <style> | ||
table.outer td, table.outer tr {border: 1px solid #ddd; padding-right: 10px; padding-left: 5px} | table.outer td, table.outer tr {border: 1px solid #ddd; padding-right: 10px; padding-left: 5px} | ||
Строка 259: | Строка 338: | ||
</head> | </head> | ||
<body> | <body> | ||
− | <canvas id="BF_canvas" width="1000" height="500" style="border:1px solid #000000;"></canvas><br> | + | <table style="border-collapse:collapse;"> |
+ | <tr><td style="text-align: center; vertical-align: top; width: 25px;"> | ||
+ | <div id="div_txt_J0" style="color: #00dd00; font-style:italic;">K<sub>J</sub></div> | ||
+ | <div id="div_txt_K" style="color: #ff0000; font-style:italic;">K</div> | ||
+ | <div id="div_txt_P" style="color: #0000ff; font-style:italic;"></div> | ||
+ | <div id="div_txt_E" style="color: #880088; font-style:italic;">E/2</div> | ||
+ | </td><td> | ||
+ | <canvas id="BF_canvas" width="1000" height="500" style="border:1px solid #000000; display: block "></canvas> | ||
+ | </td></tr><tr><td></td><td style="text-align: right;"> | ||
+ | <div style="color: #444444; font-style:italic; margin-top:-5px">x</div> | ||
+ | </td></tr><tr><td colspan="2"> | ||
+ | |||
+ | <table class="outer" style="border-collapse: collapse; width:100%"> | ||
+ | <tr> | ||
+ | <td style="width: 270px"> | ||
+ | <input type="checkbox" id="checkbox_Bessel" checked/><font color="#00dd00" size="5"><B>—</B></font> <span id="span_txt_Bessel"></span> <br> | ||
+ | <input type="checkbox" id="checkbox_K" checked/><font color="#ff0000" size="5"><B>—</B></font> <span id="span_kin_energy"></span> <br> | ||
+ | <input type="checkbox" id="checkbox_P"/><font color="#0000ff" size="5"><B>—</B></font> <span id="span_pot_energy"></span> <br> | ||
+ | <input type="checkbox" id="checkbox_E"/><font color="#880088" size="5"><B>—</B></font> <span id="span_full_energy"></span> <br> | ||
+ | </td><td> | ||
+ | <input type="button" id="button_start" style="background:#fb4;border-radius: 5px;color:#000; font-weight: bold;"/> | ||
+ | <input type="button" id="button_stop" style="background:#fb4;border-radius: 5px;color:#000; font-weight: bold; display:none"/><br> | ||
+ | <input type="image" src="Lang/RU.png" onclick="set_lang('ru')"/> | ||
+ | <input type="image" src="Lang/GB.png" onclick="set_lang('en')"/><br> | ||
+ | <div id="div_container_progress" style="display: none;"> | ||
+ | <span id="span_progress_txt"></span><span id="span_progress"></span> | ||
+ | <div id="container_bar" style="width:200px; height:20px; border:1px solid black;"> | ||
+ | <div id="progress_bar" style="width:10%;background-color: orange; height:20px;"></div> | ||
+ | </div> | ||
+ | </div> | ||
− | + | <div id="div_calc_speed" style="display: none"> | |
− | + | <abbr id="abbr_speed" style="border-bottom: 1px dotted black;"> | |
− | + | <span id="span_txt_calc_speed"></span> <span id="span_time_calc"></span> <span id="span_txt_ns_particle_step"></span> | |
− | + | </abbr> | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</div> | </div> | ||
− | |||
− | < | + | </td><td style="width: 320px"> |
− | + | <table class="inner"> | |
− | <span id=" | + | <tr> |
− | </ | + | <td> |
− | </ | + | <span id="span_txt_molecular_dynamics"></span> |
+ | </td> | ||
+ | </tr><tr> | ||
+ | <td> | ||
+ | <input type="number" id="N_number" step="1" min="2" style="width: 70px;"/> <span id="span_txt_particles"></span>, | ||
+ | <input type="number" id="R_number" step="1" min="1" style="width: 70px;"/> <span id="span_txt_realizations"></span><br><br> | ||
+ | </td> | ||
+ | </tr><tr> | ||
+ | <td> | ||
+ | <span id="span_txt_calc_time"></span> | ||
+ | </td> | ||
+ | </tr><tr> | ||
+ | <td> | ||
+ | <input type="number" id="periods_number" step="0.1" min="0" style="width: 70px;"/> <span id="span_txt_periods"></span> | ||
+ | </td> | ||
+ | </tr> | ||
+ | |||
+ | </table> | ||
+ | </td> | ||
+ | </tr> | ||
+ | </table> | ||
+ | |||
+ | </td></tr></table> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
<script>set_lang("ru")</script> | <script>set_lang("ru")</script> | ||
</body> | </body> | ||
Строка 304: | Строка 409: | ||
</div> | </div> | ||
</div> | </div> | ||
+ | |||
+ | == Старые версии программы == | ||
+ | * [[Колебания энергий в одномерном кристалле v2.5]] | ||
[[Category: Виртуальная лаборатория]] | [[Category: Виртуальная лаборатория]] | ||
[[Category: Программирование]] | [[Category: Программирование]] | ||
+ | [[Category: Проект "Термокристалл"]] |
Текущая версия на 13:45, 30 марта 2016
Кафедра ТМ > Проект "Термокристалл" > Колебания энергий в одномерном кристаллеВиртуальная лаборатория > Колебания энергий в одномерном кристалле
Д.В. Цветков (программирование), А.М. Кривцов (аналитическое решение)
Данная программа демонстрирует колебания кинетической, потенциальной и полной энергий в одномерном кристалле. Колебания кинетической энергии описываются следующим уравнением:
где
— Функция Бесселя первого рода в точке 0, — жесткость связи между частицами, — масса частицы.
Скачать программу: Bessel_fluctuations_v3.0.zip
Текст программы на языке JavaScript (использована библиотека bessel.js):
Файл "Bessel_fluctuations.js"
1 window.addEventListener("load", main_BF, false);
2 function main_BF() {
3
4 // Предварительные установки
5 var a0 = 1; // масштаб расстояния
6 var t0 = 1; // масштаб времени
7 var m0 = 1; // масштаб массы
8
9 var k0 = 2 * Math.PI / t0; // масштаб частоты
10 var C0 = m0 * k0 * k0; // масштаб жесткости
11
12 var m = 1 * m0; // масса
13 var C = 0.02 * C0; // жесткость
14
15 var dx = 1 * a0; // шаг сетки по оси x
16 var dt = 0.02 * t0; // шаг интегрирования по времени
17
18 var R = 10; // количество реализаций
19 var N = 10000; // количество частиц в каждой реализации
20 var periods = 10; // время расчета в периодах колебаний энергий
21
22 var koeff = C / (dx * dx) / m * dt; // коэффициент для уравнения динамики частиц
23
24 var T;
25 // функция переводит время в периодах в расчетное время
26 function set_periods(n) {
27 // первый раз кинетическая и потенциальная энергии доходят до нуля за 0.4 периода колебаний
28 var T0 = Math.PI / (Math.sqrt(C / m)) / 2; // период колебаний
29 if (n >= 0.4 * T0) T = T0 * ( 0.4 + 0.75 + (n - 1) );
30 else T = n;
31 }
32 set_periods(periods);
33
34 // интерфейс программы
35 N_number.value = N;
36 N_number.oninput = function() {N = parseInt(N_number.value);};
37 periods_number.value = periods;
38 periods_number.oninput = function() {
39 set_periods(parseFloat(periods_number.value));
40 };
41 R_number.value = R;
42 R_number.oninput = function() {R = parseInt(R_number.value);};
43 button_start.onclick = calculate_new_system;
44 button_stop.onclick = function() {
45 working = false;
46 };
47 checkbox_Bessel.onchange = function() {
48 draw();
49 if (checkbox_Bessel.checked) div_txt_J0.style.display = "block";
50 else div_txt_J0.style.display = "none"
51 };
52 checkbox_K.onchange = function() {
53 draw();
54 if (checkbox_K.checked) div_txt_K.style.display = "block";
55 else div_txt_K.style.display = "none"
56 };
57 checkbox_P.onchange = function() {
58 draw();
59 if (checkbox_P.checked) div_txt_P.style.display = "block";
60 else div_txt_P.style.display = "none"
61 };
62 checkbox_E.onchange = function() {
63 draw();
64 if (checkbox_E.checked) div_txt_E.style.display = "block";
65 else div_txt_E.style.display = "none"
66 };
67
68 var ctx = BF_canvas.getContext("2d"); // на context происходит рисование
69 var w = BF_canvas.width; // ширина окна в расчетных координатах
70 var h = BF_canvas.height; // высота окна в расчетных координатах
71
72 // основная расчетная функция
73 var data_K, data_P, data_E; // данные для графика
74 var t, n;
75 var t_start;
76 var working;
77 var step;
78 function calculate_new_system() {
79 t = 0;
80 n = N + 2; // количество узлов по оси x + 2 для ГУ
81 working = true;
82 step = 0;
83
84 span_time_calc.innerHTML = "";
85 div_calc_speed.style.display = "none";
86 button_start.style.display = "none";
87 button_stop.style.display = "inline";
88
89 // задание начальных условий
90 var all_P = [];
91 for (var r = 0; r < R; r++) {
92 var P = [];
93 for (var i = 1; i < n - 1; i++) {
94 P[i] = {};
95 P[i].u = 0;
96 P[i].v = (2 * Math.random() - 1) * 0.25;
97 }
98 // периодические граничные условия
99 P[0] = P[n - 2];
100 P[n - 1] = P[1];
101 all_P.push(P);
102 }
103
104 data_K = []; data_P = []; data_E = [];
105
106 // основной расчет
107 t_start = performance.now();
108 calculate(all_P);
109 }
110 calculate_new_system();
111
112 function calculate(all_P) {
113 var t1 = performance.now();
114 while (t < T) {
115 // расчет энергий для графиков
116 var Kin = 0;
117 var Pot = 0;
118 for (var p = 0; p < all_P.length; p++) {
119 var P = all_P[p];
120 for (var j = 1; j < n - 1; j++) {Kin += P[j].v * P[j].v;}
121 for (var j = 1; j < n - 1; j++) {Pot += Math.pow(P[j].u - P[j - 1].u, 2);}
122 }
123 Kin = Kin * m / all_P.length;
124 Pot = Pot * C / all_P.length;
125 data_K.push(Kin);
126 data_P.push(Pot);
127 data_E.push(Kin + Pot);
128
129 // расчет состояния системы на следующем шаге
130 for (var p = 0; p < all_P.length; p++) {
131 var P = all_P[p];
132 for (var i = 1; i < n - 1; i++) {
133 P[i].v += (P[i + 1].u - 2 * P[i].u + P[i - 1].u) * koeff;
134 }
135 for (var i = 1; i < n - 1; i++) {
136 P[i].u += P[i].v * dt;
137 }
138 }
139 t += dt;
140 step++;
141
142 // промежуточная прорисовка результатов, работа прогресс-бара
143 if ((performance.now() - t1) > 200) {
144 if (working) {
145 draw();
146 setTimeout( function(){calculate(all_P); }, 10);
147 div_container_progress.style.display = "block";
148 progress_bar.style.width = Math.round(t / T * 100) + "%";
149 span_progress.innerHTML = (t / T * 100).toFixed(0) + "%";
150 } else {
151 stop();
152 }
153 return;
154 }
155 }
156 stop();
157 }
158 function stop() {
159 // окончательная прорисовка результатов, удаление прогресс-бара, вывод скорости расчета
160 draw();
161 div_container_progress.style.display = "none";
162 button_start.style.display = "inline";
163 button_stop.style.display = "none";
164 div_calc_speed.style.display = "block";
165 span_time_calc.innerHTML = parseFloat(((performance.now() - t_start) * 1000 * 1000 / N / R / step).toPrecision(2));
166 return true;
167 }
168
169 function draw() {
170 ctx.clearRect(0, 0, w, h); // очистка экрана
171
172 if (checkbox_Bessel.checked) {
173 // Функция Бесселя первого рода в точке 0
174 ctx.strokeStyle = "#00dd00";
175 ctx.lineWidth = 2;
176 ctx.beginPath();
177 ctx.moveTo(0, h - data_E[data_E.length - 1] * besselj(4 * Math.sqrt(C / m) * 0, 0) / data_K[0] * h / 2 - h / 2);
178 for (var i = 0.001; i < t; i += 0.001) {
179 ctx.lineTo(i / t * w, h - data_E[data_E.length - 1] * besselj(4 * Math.sqrt(C / m) * i, 0) / data_K[0] * h / 2 - h / 2);
180 }
181 ctx.stroke();
182 }
183
184 if (checkbox_K.checked) {
185 // Кинетическая энергия
186 ctx.strokeStyle = "#ff0000";
187 ctx.lineWidth = 1;
188 ctx.beginPath();
189 ctx.moveTo(0, 0);
190 for (var i = 1; i < data_K.length; i++) {
191 ctx.lineTo(i / (data_K.length - 1) * w, h - data_K[i] / data_K[0] * h);
192 }
193 ctx.stroke();
194 }
195
196 if (checkbox_P.checked) {
197 // Потенциальная энергия
198 ctx.strokeStyle = "#0000ff";
199 ctx.lineWidth = 1;
200 ctx.beginPath();
201 ctx.moveTo(0, h - data_P[0] / data_K[0] * h);
202 for (var i = 1; i < data_P.length; i++) {
203 ctx.lineTo(i / (data_P.length - 1) * w, h - data_P[i] / data_K[0] * h);
204 }
205 ctx.stroke();
206 }
207
208 if (checkbox_E.checked) {
209 // Полная энергия
210 ctx.strokeStyle = "#880088";
211 ctx.lineWidth = 2;
212 ctx.beginPath();
213 ctx.moveTo(0, h - data_E[0] / 2 / data_K[0] * h);
214 for (var i = 1; i < data_E.length; i++) {
215 ctx.lineTo(i / (data_E.length - 1) * w, h - data_E[i] / 2 / data_K[0] * h);
216 }
217 ctx.stroke();
218 }
219 }
220 }
Файл "Lang.js"
1 strings = {
2 span_kin_energy:{
3 field:"innerHTML",
4 en:"Kinetic energy",
5 ru:"Кинетическая энергия"
6 }, span_pot_energy:{
7 field:"innerHTML",
8 en:"Potential energy",
9 ru:"Потенциальная энергия"
10 }, span_full_energy:{
11 field:"innerHTML",
12 en:"Full energy",
13 ru:"Полная энергия"
14 }, span_txt_Bessel:{
15 field:"innerHTML",
16 en:"Analytical sol. for the kinetic energy",
17 ru:"Аналит. решение для кин. энергии"
18 }, button_start:{
19 field:"value",
20 en:"Start",
21 ru:"Старт"
22 }, button_stop:{
23 field:"value",
24 en:"Stop",
25 ru:"Стоп"
26 }, span_progress_txt:{
27 field:"innerHTML",
28 en:"Progress: ",
29 ru:"Прогресс: "
30 }, abbr_speed:{
31 field:"title",
32 en:"The calculation of this speed includes the time for processing interface and drawing the intermediate states of the system",
33 ru:"Расчет данной скорости включает в себя время на обработку интерфейса и прорисовку промежуточных состояний системы"
34 }, span_txt_molecular_dynamics:{
35 field:"innerHTML",
36 en:"Molecular_dynamics:",
37 ru:"Молекулярная динамика:"
38 }, span_txt_particles:{
39 field:"innerHTML",
40 en:"particles",
41 ru:"частиц"
42 }, span_txt_realizations:{
43 field:"innerHTML",
44 en:"realizations",
45 ru:"реализаций"
46 }, span_txt_calc_time:{
47 field:"innerHTML",
48 en:"Calculation time:",
49 ru:"Время расчета:"
50 }, span_txt_calc_speed:{
51 field:"innerHTML",
52 en:"Calculation speed:",
53 ru:"Скорость расчета:"
54 }, span_txt_ns_particle_step:{
55 field:"innerHTML",
56 en:"ns/(particle⋅step)",
57 ru:"нс/(частица⋅шаг)"
58 }, span_txt_periods:{
59 field:"innerHTML",
60 en:"periods",
61 ru:"периодов"
62 }, div_txt_P:{
63 field:"innerHTML",
64 en:"P",
65 ru:"П"
66 }
67 };
68
69 function set_lang(lang){
70 for (var s in strings) {
71 document.getElementById(s)[strings[s].field] = strings[s][lang];
72 }
73 }
Файл "Bessel_fluctuations.html"
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Bessel fluctuations</title>
<script src="Bessel_fluctuations.js"></script>
<script src="Lang/Lang.js"></script>
<script src="Libs/bessel.js"></script>
<style>
table.outer td, table.outer tr {border: 1px solid #ddd; padding-right: 10px; padding-left: 5px}
table.inner td, table.inner tr {border: 0}
</style>
</head>
<body>
<table style="border-collapse:collapse;">
<tr><td style="text-align: center; vertical-align: top; width: 25px;">
<div id="div_txt_J0" style="color: #00dd00; font-style:italic;">K<sub>J</sub></div>
<div id="div_txt_K" style="color: #ff0000; font-style:italic;">K</div>
<div id="div_txt_P" style="color: #0000ff; font-style:italic;"></div>
<div id="div_txt_E" style="color: #880088; font-style:italic;">E/2</div>
</td><td>
<canvas id="BF_canvas" width="1000" height="500" style="border:1px solid #000000; display: block "></canvas>
</td></tr><tr><td></td><td style="text-align: right;">
<div style="color: #444444; font-style:italic; margin-top:-5px">x</div>
</td></tr><tr><td colspan="2">
<table class="outer" style="border-collapse: collapse; width:100%">
<tr>
<td style="width: 270px">
<input type="checkbox" id="checkbox_Bessel" checked/><font color="#00dd00" size="5"><B>—</B></font> <span id="span_txt_Bessel"></span> <br>
<input type="checkbox" id="checkbox_K" checked/><font color="#ff0000" size="5"><B>—</B></font> <span id="span_kin_energy"></span> <br>
<input type="checkbox" id="checkbox_P"/><font color="#0000ff" size="5"><B>—</B></font> <span id="span_pot_energy"></span> <br>
<input type="checkbox" id="checkbox_E"/><font color="#880088" size="5"><B>—</B></font> <span id="span_full_energy"></span> <br>
</td><td>
<input type="button" id="button_start" style="background:#fb4;border-radius: 5px;color:#000; font-weight: bold;"/>
<input type="button" id="button_stop" style="background:#fb4;border-radius: 5px;color:#000; font-weight: bold; display:none"/><br>
<input type="image" src="Lang/RU.png" onclick="set_lang('ru')"/>
<input type="image" src="Lang/GB.png" onclick="set_lang('en')"/><br>
<div id="div_container_progress" style="display: none;">
<span id="span_progress_txt"></span><span id="span_progress"></span>
<div id="container_bar" style="width:200px; height:20px; border:1px solid black;">
<div id="progress_bar" style="width:10%;background-color: orange; height:20px;"></div>
</div>
</div>
<div id="div_calc_speed" style="display: none">
<abbr id="abbr_speed" style="border-bottom: 1px dotted black;">
<span id="span_txt_calc_speed"></span> <span id="span_time_calc"></span> <span id="span_txt_ns_particle_step"></span>
</abbr>
</div>
</td><td style="width: 320px">
<table class="inner">
<tr>
<td>
<span id="span_txt_molecular_dynamics"></span>
</td>
</tr><tr>
<td>
<input type="number" id="N_number" step="1" min="2" style="width: 70px;"/> <span id="span_txt_particles"></span>,
<input type="number" id="R_number" step="1" min="1" style="width: 70px;"/> <span id="span_txt_realizations"></span><br><br>
</td>
</tr><tr>
<td>
<span id="span_txt_calc_time"></span>
</td>
</tr><tr>
<td>
<input type="number" id="periods_number" step="0.1" min="0" style="width: 70px;"/> <span id="span_txt_periods"></span>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td></tr></table>
<script>set_lang("ru")</script>
</body>
</html>