Колебания энергий в одномерном кристалле v2.5
Материал из Department of Theoretical and Applied Mechanics
Версия от 23:39, 20 октября 2015; Денис (обсуждение | вклад) (Новая страница: «Виртуальная лаборатория > Колебания энергий в одномерном кристалле > Колебания эн…»)
Виртуальная лаборатория > Колебания энергий в одномерном кристалле > v2.5
Данная программа демонстрирует колебания кинетической, потенциальной и полной энергий в одномерном кристалле.
Скачать программу: Bessel_fluctuations_v2.5_no_realiz.zip
Текст программы на языке JavaScript (разработчик Цветков Денис):
Файл "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 N = 100000; // количество частиц в каждой реализации
19 var periods = 10; // время расчета в периодах колебаний энергий
20
21 var koeff = C / (dx * dx) / m * dt; // коэффициент для уравнения динамики частиц
22
23 var T;
24 // функция переводит время в периодах в расчетное время
25 function set_periods(n) {
26 // первый раз кинетическая и потенциальная энергии доходят до нуля за 0.4 периода колебаний
27 var T0 = Math.PI / (Math.sqrt(C / m)) / 2; // период колебаний
28 if (n >= 0.4 * T0) T = T0 * ( 0.4 + 0.75 + (n - 1) );
29 else T = n;
30 }
31 set_periods(periods);
32
33 // интерфейс программы
34 N_number.value = N;
35 N_number.oninput = function() {N = parseInt(N_number.value);};
36 periods_number.value = periods;
37 periods_number.oninput = function() {
38 set_periods(parseFloat(periods_number.value));
39 };
40 button_start.onclick = calculate_new_system;
41 checkbox_K.onchange = function() {
42 draw();
43 if (checkbox_K.checked) div_txt_K.style.display = "block";
44 else div_txt_K.style.display = "none"
45 };
46 checkbox_P.onchange = function() {
47 draw();
48 if (checkbox_P.checked) div_txt_P.style.display = "block";
49 else div_txt_P.style.display = "none"
50 };
51 checkbox_E.onchange = function() {
52 draw();
53 if (checkbox_E.checked) div_txt_E.style.display = "block";
54 else div_txt_E.style.display = "none"
55 };
56
57 var ctx = BF_canvas.getContext("2d"); // на context происходит рисование
58 var w = BF_canvas.width; // ширина окна в расчетных координатах
59 var h = BF_canvas.height; // высота окна в расчетных координатах
60
61 // основная расчетная функция
62 var data_K, data_P, data_E; // данные для графика
63 var t, n;
64 var t_start;
65 function calculate_new_system() {
66 t = 0;
67 n = N + 2; // количество узлов по оси x + 2 для ГУ
68 span_time_calc.innerHTML = "";
69 div_calc_speed.style.display = "none";
70
71 // задание начальных условий
72 var P = [];
73 for (var i = 1; i < n - 1; i++) {
74 P[i] = {};
75 P[i].u = 0;
76 P[i].v = (2 * Math.random() - 1) * 0.25;
77 }
78 // периодические граничные условия
79 P[0] = P[n - 2];
80 P[n - 1] = P[1];
81
82 data_K = []; data_P = []; data_E = [];
83
84 // основной расчет
85 t_start = performance.now();
86 calculate(P);
87 }
88 calculate_new_system();
89
90 function calculate(P) {
91 var t1 = performance.now();
92 while (t < T) {
93 // расчет энергий для графиков
94 var Kin = 0;
95 var Pot = 0;
96 for (var j = 1; j < n - 1; j++) {Kin += P[j].v * P[j].v;}
97 for (var j = 1; j < n - 1; j++) {Pot += Math.pow(P[j].u - P[j - 1].u, 2);}
98 Kin = Kin * m;
99 Pot = Pot * C;
100 data_K.push(Kin);
101 data_P.push(Pot);
102 data_E.push(Kin + Pot);
103
104 // расчет состояния системы на следующем шаге
105 for (var i = 1; i < n - 1; i++) {
106 P[i].v += (P[i + 1].u - 2 * P[i].u + P[i - 1].u) * koeff;
107 }
108 for (var i = 1; i < n - 1; i++) {
109 P[i].u += P[i].v * dt;
110 }
111 t += dt;
112
113 // промежуточная прорисовка результатов, работа прогресс-бара
114 if ((performance.now() - t1) > 200) {
115 draw();
116 setTimeout( function(){calculate(P); }, 10);
117 div_container_progress.style.display = "block";
118 button_start.style.display = "none";
119 progress_bar.style.width = Math.round(t / T * 100) + "%";
120 span_progress.innerHTML = (t / T * 100).toFixed(0) + "%";
121 return;
122 }
123 }
124 // окончательная прорисовка результатов, удаление прогресс-бара, вывод скорости расчета
125 draw();
126 div_container_progress.style.display = "none";
127 button_start.style.display = "inline";
128 div_calc_speed.style.display = "block";
129 span_time_calc.innerHTML = parseFloat(((performance.now() - t_start) * 1000 * 1000 / N / Math.ceil(T/dt)).toPrecision(2));
130 return true;
131 }
132
133 function draw() {
134 ctx.clearRect(0, 0, w, h); // очистка экрана
135
136 if (checkbox_K.checked) {
137 // Кинетическая энергия
138 ctx.strokeStyle = "#ff0000";
139 ctx.lineWidth = 1;
140 ctx.beginPath();
141 ctx.moveTo(0, 0);
142 for (var i = 1; i < data_K.length; i++) {
143 ctx.lineTo(i / (data_K.length - 1) * w, h - data_K[i] / data_K[0] * h);
144 }
145 ctx.stroke();
146 }
147
148 if (checkbox_P.checked) {
149 // Потенциальная энергия
150 ctx.strokeStyle = "#0000ff";
151 ctx.lineWidth = 1;
152 ctx.beginPath();
153 ctx.moveTo(0, h - data_P[0] / data_K[0] * h);
154 for (var i = 1; i < data_P.length; i++) {
155 ctx.lineTo(i / (data_P.length - 1) * w, h - data_P[i] / data_K[0] * h);
156 }
157 ctx.stroke();
158 }
159
160 if (checkbox_E.checked) {
161 // Полная энергия
162 ctx.strokeStyle = "#880088";
163 ctx.lineWidth = 2;
164 ctx.beginPath();
165 ctx.moveTo(0, h - data_E[0] / 2 / data_K[0] * h);
166 for (var i = 1; i < data_E.length; i++) {
167 ctx.lineTo(i / (data_E.length - 1) * w, h - data_E[i] / 2 / data_K[0] * h);
168 }
169 ctx.stroke();
170 }
171 }
172 }
Файл "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 }, button_start:{
15 field:"value",
16 en:"Start",
17 ru:"Старт"
18 }, span_progress_txt:{
19 field:"innerHTML",
20 en:"Progress: ",
21 ru:"Прогресс: "
22 }, abbr_speed:{
23 field:"title",
24 en:"The calculation of this speed includes the time for processing interface and drawing the intermediate states of the system",
25 ru:"Расчет данной скорости включает в себя время на обработку интерфейса и прорисовку промежуточных состояний системы"
26 }, span_txt_nubmer_of_particles:{
27 field:"innerHTML",
28 en:"Number of particles:",
29 ru:"Количество частиц:"
30 }, span_txt_calc_time:{
31 field:"innerHTML",
32 en:"Calculation time:",
33 ru:"Время расчета:"
34 }, span_txt_calc_speed:{
35 field:"innerHTML",
36 en:"Calculation speed:",
37 ru:"Скорость расчета:"
38 }, span_txt_ns_particle_step:{
39 field:"innerHTML",
40 en:"ns/(particle⋅step)",
41 ru:"нс/(частица⋅шаг)"
42 }, span_txt_periods:{
43 field:"innerHTML",
44 en:"periods",
45 ru:"периодов"
46 }, div_txt_P:{
47 field:"innerHTML",
48 en:"P",
49 ru:"П"
50 }
51 };
52
53 function set_lang(lang){
54 for (var s in strings) {
55 document.getElementById(s)[strings[s].field] = strings[s][lang];
56 }
57 }
Файл "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>
<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_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_K" checked/><font color="#ff0000" size="5"><B>—</B></font> <span id="span_kin_energy"></span> <br>
<input type="checkbox" id="checkbox_P" checked/><font color="#0000ff" size="5"><B>—</B></font> <span id="span_pot_energy"></span> <br>
<input type="checkbox" id="checkbox_E" checked/><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;"/><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_nubmer_of_particles"></span></td>
<td><input type="number" id="N_number" step="1" min="2" style="width: 70px;"/></td>
</tr>
<tr>
<td><span id="span_txt_calc_time"></span></td>
<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>