Статистические распределения в двумерном кристалле с треугольной решеткой

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск

Виртуальная лаборатория > Статистические распределения в двумерном кристалле с треугольной решеткой

Рассматривается система частиц моделируемых материальными точками с линейным законом взаимодействия в плоскости. Частицы располагаются в треугольной решетке, края свободны. Все частицы и связи одинаковые. Уравнение движения для каждой частицы имеет вид:

[math] m \ddot{\underline u} = c \sum_{\alpha}{\underline{e}_{\alpha} \underline{e}_{\alpha} \cdot (\underline{u}_{\alpha} - \underline u)}, [/math]

где [math]m[/math] – масса частицы, с – жесткость связи, [math]\underline{u}[/math] – вектор перемещения, [math]\underline{e}_{\alpha}[/math] – единичный вектор, направленный к одной из соседних частиц с индексом [math]\alpha[/math]:

[math] \underline{e}_{\alpha} = (\underline{r}_{\alpha} - \underline{r}) / |\underline{r}_{\alpha} - \underline{r}|, [/math]

где [math]\underline{r}[/math] – радиус-вектор частицы в начальной конфигурации.

Ось [math]x[/math] направлена вдоль одного из направлений связей. [math]m = 1,\quad c = 1[/math], шаг интегрирования [math]dt = 0.005[/math].

Скачать программу: TriLatLin.zip

Текст программы на языке JavaScript (разработчики Цаплин Вадим, Кривцов Антон):

Файл "TriLatLin.js."

  1 function MainTriLatticeTemper()
  2 {
  3     var ctx_X = canvas_densitas_Vx.getContext("2d");
  4     var width_X = canvas_densitas_Vx.width;
  5     var height_X = canvas_densitas_Vx.height;
  6 
  7     var ctx_Y = canvas_densitas_Vy.getContext("2d");
  8     var width_Y = canvas_densitas_Vy.width;
  9     var height_Y = canvas_densitas_Vy.height;
 10 
 11     var ctx_E = canvas_energy.getContext("2d");
 12     var width_E = canvas_energy.width;
 13     var height_E = canvas_energy.height;
 14 
 15     // частица содержит перемещения и скорости
 16 
 17     var _Vx;
 18     var _Vy;
 19     var Vx2_sum; // сумма квадратов координат скорости Vx (с весом s)
 20     var Vxy_sum; // сумма произведений координат скорости VxVy (с весом s)
 21     var Vy2_sum; // сумма квадратов координат скорости Vy (с весом s)
 22     var Vx4_sum; // сумма (координат скорости Vx)^4 (с весом s)
 23     var Vy4_sum; // сумма (координат скорости Vy)^4 (с весом s)
 24     var U1x_sum, U1y_sum;
 25     var Vx2_av;  // средний Vx^2 c эксп. весом (для графиков)
 26     var Vy2_av;  // средний Vy^2 c эксп. весом
 27 
 28     var suspended = 0; // вычисление приостановлено == 1
 29 
 30     // массив частиц
 31 
 32     var Arr_prt = [];
 33 
 34     var n1 = 30;         // число рядов 1
 35     var n2 = 30;
 36     var n = n1 * n2;     // число частиц
 37     //var a = 1;         // равновесное расстояние между центрами частиц
 38     //var c = 1;         // линейная жесткость упругой связи
 39     //var m = 1;         // масса частицы
 40     //var с_m = c/m;
 41     var dt_sc_m = 0.005; // шаг интегрирования по времени dt_sc_m = dt*sqrt(c_m)
 42 
 43     // максимальные начальные скорости (в безразмерном времени)
 44 
 45     var Vx = 10;
 46     var Vy = 0.1;
 47     var Vc_x = 0;        // скорость
 48     var Vc_y = 0;        // центра масс
 49 
 50     var K1 = [];         // кин. энергия
 51     var P = [];          // пот. энергия
 52 
 53     slider_input_X.value = Vx;
 54     number_input_X.value = Vx;
 55     slider_input_Y.value = Vy;
 56     number_input_Y.value = Vy;
 57     sV_axis = 0;
 58 
 59     var s = 0;           // шаг по времени
 60     var V_max;           // максимальная координата скорости на графике
 61     var sV_max;          // максимальный корень из координаты скорости на графике
 62     var norm = 0;        // начальные координаты скорости имеют нормальное распределение == 1
 63     var Par = [];        // возвращаемое значение функции RandomNorm()
 64 
 65     // Случайные числа с нормальным распределением
 66     function RandomNorm() // <(Par[0])^2> == 1, <(Par[1])^2> == 1
 67     {
 68         var r_RandomNorm = Math.sqrt(-2*Math.log(Math.random()));
 69         var fi_RandomNorm = Math.random()*Math.PI*2;
 70 
 71         Par[0] = r_RandomNorm*Math.cos(fi_RandomNorm);
 72         Par[1] = r_RandomNorm*Math.sin(fi_RandomNorm);
 73     }
 74 
 75     function Restart()
 76     {
 77         Vx = number_input_X.value;
 78         Vy = number_input_Y.value;
 79 
 80         for (var j = 0; j < n2; j++)
 81         {
 82             Arr_prt[j] = [];
 83 
 84             for (var i = 0; i < n1; i++)
 85             {
 86                 if (norm)
 87                 {
 88                     RandomNorm();
 89                     _Vx = Par[0];
 90                     _Vy = Par[1];
 91                 }
 92                 else
 93                     do
 94                     {
 95                         _Vx = 2*Math.random()-1;
 96                         _Vy = 2*Math.random()-1;
 97                     }
 98                     while (_Vx*_Vx+_Vy*_Vy > 1);
 99 
100                 Vc_x += _Vx;
101                 Vc_y += _Vy;
102 
103                 var particle = {};
104                 particle.Ux = 0;
105                 particle.Uy = 0;
106                 particle.Vx = _Vx;
107                 particle.Vy = _Vy;
108 
109                 Arr_prt[j][i] = particle;
110             }
111 		}
112 
113         Vc_x /= n;
114         Vc_y /= n;
115 
116         // обнуление скорости центра масс
117 
118         Vx2_sum = 0;
119         Vy2_sum = 0;
120         Vxy_sum = 0;
121 
122         for (var j = 0; j < n2; j++)
123         {
124             for (var i = 0; i < n1; i++)
125             {
126                 Arr_prt[j][i].Vx -= Vc_x;
127                 Arr_prt[j][i].Vy -= Vc_y;
128 
129                 _Vx = Arr_prt[j][i].Vx;
130                 _Vy = Arr_prt[j][i].Vy;
131                 Vx2_sum += _Vx*_Vx;
132                 Vy2_sum += _Vy*_Vy;
133             }
134         }
135 
136         // нормировка компонент скорости
137 
138         Vx2_sum = Vx/Math.sqrt(Vx2_sum/n);
139         Vy2_sum = Vy/Math.sqrt(Vy2_sum/n);
140 
141         for (var j = 0; j < n2; j++)
142         {
143             for (var i = 0; i < n1; i++)
144             {
145                 Arr_prt[j][i].Vx *= Vx2_sum;
146                 Arr_prt[j][i].Vy *= Vy2_sum;
147             }
148         }
149 
150         s = 0;
151 
152         sV_max = Math.sqrt(Math.max(Vx, Vy)*2); // максимальное значение абсциссы на графиках
153         V_max = 2*Math.max(Vx, Vy);             // максимальное значение абсциссы на графиках
154 
155         ExCalculateReset();
156         Vx2_sum = 0; Vy2_sum = 0; Vxy_sum = 0;
157         Vx4_sum = 0; Vy4_sum = 0;
158         U1x_sum = 0; U1y_sum = 0;
159     }
160 
161     var k_sen = 0.1; // чувствительность усредненного по времени массива к текущим изменениям
162     span_sen.innerHTML = k_sen;
163 
164     function Step()
165     {
166         //if (!suspended)
167         //{
168         Calculate();         // шаг интегрирования по времени
169         ExCalculate(k_sen);  // подготовка для вывода графиков
170 
171         s++;
172         Paint();             // рисование графиков
173         //}
174     }
175 
176     // треугольная решетка
177     // x[j][i] = a*i + a/2*(j&1);
178     // y[j][i] = sqrt(3)/2*a*j;
179 
180     var sqrt3 = Math.sqrt(3);
181 
182     function Calculate() // шаг интегрирования
183     {
184         var i; var j;
185 
186         P[s] = 0;
187 
188         for (var k = 0; k < n; k++) // вычисление компонент скорости
189         {
190             i = k%n1;
191             j = Math.floor(k/n1);
192 
193             var Ux; var Uy; var U_4; var U_43; var U_1;
194 
195             if (j > 0)
196             {
197                 var ai = j&1 ? i : i-1; // соседняя частица 1
198 
199                 if (ai >= 0)
200                 {
201                     Ux = Arr_prt[j-1][ai].Ux - Arr_prt[j][i].Ux;
202                     Uy = Arr_prt[j-1][ai].Uy - Arr_prt[j][i].Uy;
203                     U_1 = Ux + Uy*sqrt3;
204                     U_4 = U_1 / 4 * dt_sc_m;
205                     U_43 = U_4*sqrt3;
206 
207                     Arr_prt[j][i].Vx += U_4;
208                     Arr_prt[j][i].Vy += U_43;
209 
210                     Arr_prt[j-1][ai].Vx -= U_4;
211                     Arr_prt[j-1][ai].Vy -= U_43;
212 
213                     P[s] += U_1*U_1/8;
214                 }
215 
216                 ai++; // соседняя частица 2
217 
218                 if (ai < n1)
219                 {
220                     Ux = Arr_prt[j-1][ai].Ux - Arr_prt[j][i].Ux;
221                     Uy = Arr_prt[j-1][ai].Uy - Arr_prt[j][i].Uy;
222                     U_1 = Uy*sqrt3 - Ux;
223                     U_4 = U_1 / 4 * dt_sc_m;
224                     U_43 = U_4*sqrt3;
225 
226                     Arr_prt[j][i].Vx -= U_4;
227                     Arr_prt[j][i].Vy += U_43;
228 
229                     Arr_prt[j-1][ai].Vx += U_4;
230                     Arr_prt[j-1][ai].Vy -= U_43;
231 
232                     P[s] += U_1*U_1/8;
233                 }
234             }
235 
236             if (i > 0) // соседняя частица 3
237             {
238                 U_1 = Arr_prt[j][i-1].Ux - Arr_prt[j][i].Ux;
239                 Ux = U_1 * dt_sc_m;
240 
241                 Arr_prt[j][i].Vx += Ux;
242                 Arr_prt[j][i-1].Vx -= Ux;
243 
244                 P[s] += U_1*U_1/2;
245             }
246         }
247 
248         K1[s] = 0;
249 
250 
251         for (var k = 0; k < n; k++) // вычисление перемещений
252         {
253             i = k%n1;
254             j = Math.floor(k/n1);
255 
256             var Vx_loc = Arr_prt[j][i].Vx;
257             var Vy_loc = Arr_prt[j][i].Vy;
258 
259             Arr_prt[j][i].Ux += Vx_loc * dt_sc_m;
260             Arr_prt[j][i].Uy += Vy_loc * dt_sc_m;
261 
262             K1[s] += (Vx_loc*Vx_loc+Vy_loc*Vy_loc)/2;
263 
264             Vxy_sum += Vx_loc*Vy_loc;
265             Vx_loc *= Vx_loc;
266             Vy_loc *= Vy_loc;
267             Vx2_sum += Vx_loc*s;
268             Vy2_sum += Vy_loc*s;
269 
270             Vx_loc *= Vx_loc;
271             Vy_loc *= Vy_loc;
272             Vx4_sum += Vx_loc*s;
273             Vy4_sum += Vy_loc*s;
274 
275             //U1x_sum += Arr_prt[j][i].Ux;
276             //U1y_sum += Arr_prt[j][i].Uy;
277         }
278 
279         U1x_sum += Arr_prt[0][0].Ux;
280         U1y_sum += Arr_prt[0][0].Uy;
281     }
282 
283     var N_graph_Vx = 20;
284     var Vx_dens = [];   // массив статистического распределения частиц по компонентам скорости Vx,
285     var Vy_dens = [];   // Vy.
286     var sVx_dens = [];  // массив статистического распределения частиц по компонентам скорости sqrt(Vx),
287     var sVy_dens = [];  // sqrt(Vy).
288 
289     function ExCalculateReset()
290     {
291         for (var i = 0; i < N_graph_Vx; i++)
292         {
293             Vx_dens[i] = 0;
294             Vy_dens[i] = 0;
295             sVx_dens[i] = 0;
296             sVy_dens[i] = 0;
297         }
298 
299         Vx2_av = 0; Vy2_av = 0;
300 
301         ExCalculate(1); // В начальный момент считаются статистические распределения без запаздывания (k_sen == 1)
302     }
303 
304     function ExCalculate(k_sen) // статистические вычисления на каждом шаге
305     {
306         var Vx_dens_loc = [];
307         var Vy_dens_loc = [];
308         var sVx_dens_loc = [];
309         var sVy_dens_loc = [];
310 
311         for (var i = 0; i < N_graph_Vx; i++)
312         {
313             Vx_dens_loc[i] = 0;
314             Vy_dens_loc[i] = 0;
315             sVx_dens_loc[i] = 0;
316             sVy_dens_loc[i] = 0;
317         }
318 
319         var Vx2_av_loc = 0;
320         var Vy2_av_loc = 0;
321 
322         ///////////////////////////////////////////////////////////////////////
323 
324         for (var k = 0; k < n; k++)
325         {
326             i = k%n1;
327             j = Math.floor(k/n1);
328 
329             var Vx_loc = Math.abs(Arr_prt[j][i].Vx);
330             var Vy_loc = Math.abs(Arr_prt[j][i].Vy);
331             var sVx_loc = Math.sqrt(Vx_loc);
332             var sVy_loc = Math.sqrt(Vy_loc);
333 
334             var n_d = Math.floor(Vx_loc/V_max*(N_graph_Vx-1)+0.5);
335             if (n_d < N_graph_Vx) { Vx_dens_loc[n_d]++; }
336 
337             n_d = Math.floor(Vy_loc/V_max*(N_graph_Vx-1)+0.5);
338             if (n_d < N_graph_Vx) { Vy_dens_loc[n_d]++; }
339 
340             n_d = Math.floor(sVx_loc/sV_max*(N_graph_Vx-1)+0.5);
341             if (n_d < N_graph_Vx) { sVx_dens_loc[n_d]++; }
342 
343             n_d = Math.floor(sVy_loc/sV_max*(N_graph_Vx-1)+0.5);
344             if (n_d < N_graph_Vx) { sVy_dens_loc[n_d]++; }
345 
346             Vx2_av_loc += Vx_loc*Vx_loc;
347             Vy2_av_loc += Vy_loc*Vy_loc;
348         }
349 
350         Vx_dens_loc[0] *= 2; Vy_dens_loc[0] *= 2;
351         sVx_dens_loc[0] = 0; sVy_dens_loc[0] = 0;
352 
353         Vx2_av_loc /= n; Vy2_av_loc /= n;
354 
355         ///////////////////////////////////////////////////////////////////////
356         // интегральный регулятор (фильтр низких частот)
357 
358         for (var i = 0; i < N_graph_Vx; i++)
359         {
360             Vx_dens[i] = k_sen*Vx_dens_loc[i] + (1-k_sen)*Vx_dens[i];
361             Vy_dens[i] = k_sen*Vy_dens_loc[i] + (1-k_sen)*Vy_dens[i];
362             sVx_dens[i] = k_sen*sVx_dens_loc[i] + (1-k_sen)*sVx_dens[i];
363             sVy_dens[i] = k_sen*sVy_dens_loc[i] + (1-k_sen)*sVy_dens[i];
364         }
365 
366         Vx2_av = k_sen*Vx2_av_loc + (1-k_sen)*Vx2_av;
367         Vy2_av = k_sen*Vy2_av_loc + (1-k_sen)*Vy2_av;
368     }
369 
370     function Paint()
371     {
372         Draw(ctx_X, width_X, height_X, sV_axis ? sVx_dens : Vx_dens, 0);
373         Draw(ctx_Y, width_Y, height_Y, sV_axis ? sVy_dens : Vy_dens, 1);
374 
375         var Vx2_aver = Vx2_sum / s / (s > 1 ? s-1 : 1) * 2 / n;
376         var Vy2_aver = Vy2_sum / s / (s > 1 ? s-1 : 1) * 2 / n;
377         var Vxy_aver = Vxy_sum / s / (s > 1 ? s-1 : 1) * 2 / n;
378 
379         span_Vx2.innerHTML = Vx2_aver.toFixed(3);
380         span_Vy2.innerHTML = Vy2_aver.toFixed(3);
381         span_V2.innerHTML = (Vx2_aver+Vy2_aver).toFixed(3);
382         span_Vxy.innerHTML = Vxy_aver.toExponential(2);//toPrecision(3);
383         //span_U.innerHTML = "< Ux > = " + (U1x_sum/s).toFixed(2) +
384         //"________ < Uy > = " + (U1y_sum/s).toFixed(2);
385 
386         var Vx4_aver = Vx4_sum / s / (s > 1 ? s-1 : 1) * 2 / n;
387         var Vy4_aver = Vy4_sum / s / (s > 1 ? s-1 : 1) * 2 / n;
388 
389         span_Mx.innerHTML = (Vx4_aver/Vx2_aver/Vx2_aver/3).toFixed(3);
390         span_My.innerHTML = (Vy4_aver/Vy2_aver/Vy2_aver/3).toFixed(3);
391 
392         span_k1.innerHTML = ((Vx2_aver+Vy2_aver) / (Vx*Vx+Vy*Vy)).toFixed(3);
393         span_k2.innerHTML = ((Vx2_aver-Vy2_aver) / (Vx*Vx-Vy*Vy)).toFixed(3);
394         span_1k2.innerHTML = ((Vx*Vx-Vy*Vy) / (Vx2_aver-Vy2_aver)).toFixed(3);
395 
396         DrawE();
397 
398         span_E.innerHTML = ((K1[s-1] + P[s-1])/n).toFixed(2);
399         span_t.innerHTML = (s*dt_sc_m).toFixed(2);
400         span_steps.innerHTML = s;
401     }
402 
403     ///////////////////////////////////////////////////////////////////////
404     // рисование графиков распределения частиц по компонентам скорости Vx, Vy
405 
406     function Draw(ctx, width, height, V_dens, n_col)
407     {
408         ctx.lineWidth="0.6";                    // ширина линии
409         ctx.clearRect(0, 0, width, height);     // очистить экран
410 
411         var dens_V_max;                         // максимальное значение плотности
412 
413         if (sV_axis)
414         {
415             dens_V_max = n*2*sV_max/(N_graph_Vx-1)*Math.sqrt(Math.sqrt(2/Math.E/(n_col ? Vy2_av : Vx2_av))/Math.PI);
416         }
417         else dens_V_max = n*2*V_max/(N_graph_Vx-1)/Math.sqrt(2*Math.PI*(n_col ? Vy2_av : Vx2_av));
418 
419         var x_scal = width / (N_graph_Vx-1);    // N_graph_Vx-1 == число промежутков между N_graph_Vx точек
420         var y_scal = height / dens_V_max / (sV_axis ? 1.2 : 1.1);  // 1.2,1.1 - коэффициент запаса
421 
422         var x = 0; var y;
423         var n_points = Math.floor(width / 3);
424 
425         ///////////////////////////////////////////////////////////////////////
426         // рисование нормального распределения
427 
428         if (checkbox_norm.checked)
429         {
430             var width2 = width*width;
431 
432             ctx.strokeStyle = "#006000";
433             ctx.beginPath();
434 
435             if (sV_axis) // распределение по sqrt(V_(x,y))
436             {
437                 var x1 = -V_max*V_max/width2/width2/(n_col ? Vy2_av : Vx2_av)/2;
438                 var y1 = y_scal*dens_V_max*Math.sqrt(Math.sqrt(2*Math.E/(n_col ? Vy2_av : Vx2_av)))*sV_max/width;
439 
440                 ctx.moveTo(x, height);
441 
442                 //for (var i = 1; i < n_points; i++)
443                 for (var i = 1; i <= width; i++)
444                 {
445                     //x = 3*i;
446                     x = i;
447                     var x2 = x*x;
448 
449                     y = Math.floor(height - y1*x*Math.exp(x2*x2*x1));
450 
451                     ctx.lineTo(x, y);
452                 }
453 
454                 //y = Math.floor(height - y1*width*Math.exp(width2*width2*x1));
455                 //ctx.lineTo(width, y);
456             }
457             else // распределение по V_(x,y)
458             {
459                 var y1 = y_scal*dens_V_max;// y_scal*n*2*V_max/(N_graph_Vx-1)/Math.sqrt(2*Math.PI*(n_col ? Vy2_av : Vx2_av));
460                 var x1 = -V_max*V_max/width/width/(n_col ? Vy2_av : Vx2_av)/2;
461 
462                 y = Math.floor(height - y1);
463 
464                 ctx.moveTo(x, y);
465 
466                 for (var i = 1; i < n_points; i++)
467                 {
468                     x = 3*i;
469                     y = Math.floor(height - y1*Math.exp(x*x*x1));
470 
471                     ctx.lineTo(x, y);
472                 }
473 
474                 y = Math.floor(height - y1*Math.exp(width*width*x1));
475                 ctx.lineTo(width, y);
476             }
477 
478             ctx.stroke();
479         }
480 
481         ///////////////////////////////////////////////////////////////////////
482         // рисование вычисленного распределения
483 
484         ctx.strokeStyle = n_col ? "#ff0000" : "#0000ff";
485         ctx.beginPath();
486 
487         x = 0;
488         y = Math.floor(height - y_scal*V_dens[0]);
489 
490         ctx.moveTo(x, y);
491 
492         for (var i = 1; i < n_points; i++)
493         {
494             y = 0;
495             x = 3*i;
496 
497             var j = Math.floor(x/x_scal);
498             var fi = x/x_scal - j;                       // 0 <= fi < 1
499 
500             if (j >= N_graph_Vx-1) alert("error!");
501 
502             // интерполяция кубическими сплайнами
503 
504             y += V_dens[j] * (fi-1) * (fi-1) * (2*fi+1); // значения
505             y += V_dens[j+1] * fi * fi * (3-2*fi);       // в узлах
506 
507             var y_d = (j == 0) ? V_dens[1]-V_dens[0] : (V_dens[j+1]-V_dens[j-1])/2;
508 
509             y += y_d * (fi-1) * (fi-1) * fi;             // производная в левом узле
510 
511             y_d = (j == N_graph_Vx-2) ? V_dens[N_graph_Vx-1]-V_dens[N_graph_Vx-2] : (V_dens[j+2]-V_dens[j])/2;
512 
513             y += y_d * fi * fi * (fi-1);                 // производная в правом узле
514 
515             y = Math.floor(height - y_scal*y);           // линейное отображение в область построения
516             y = Math.max(0, y);
517             y = Math.min(y, height);
518 
519             ctx.lineTo(x, y);
520         }
521 
522         y = Math.floor(height - y_scal*V_dens[N_graph_Vx-1]);
523         y = Math.min(y, height);
524         ctx.lineTo(width, y);
525         ctx.stroke();
526 
527         ///////////////////////////////////////////////////////////////////////
528     }
529 
530     var En_area = 2; // 0 - весь график, 1 - начало, 2 - конец
531 
532     function DrawE() // рисование графика энергии от времени
533     {
534         // кинетическая:
535 
536         ctx_E.strokeStyle="#004000";
537         ctx_E.lineWidth="0.7";                        // ширина линии
538         ctx_E.clearRect(0, 0, width_E, height_E);     // очистить экран
539         ctx_E.beginPath();
540 
541         var K_max = K1[0];
542         var x_scal;
543 
544         x_scal = (En_area == 0) ? x_scal = width_E / Math.max(s, 1500) : width_E / 1500;
545 
546         var y_scal = height_E / K_max;
547 
548         var i0 = (En_area == 2) ? Math.max(0, s-1500) : 0;
549 
550         var x = 0;
551         var y = Math.floor(height_E - K1[i0]*y_scal);
552 
553         ctx_E.moveTo(x, y);
554 
555         var s_max = (En_area == 1) ? Math.min(s, 1500) : s;
556 
557         for (var i = i0+1; i < s; i++)
558         {
559             y = Math.floor(height_E - K1[i]*y_scal);
560             x = Math.ceil((i-i0)*x_scal);
561 
562             ctx_E.lineTo(x, y);
563         }
564 
565         ctx_E.stroke();
566 
567         // средняя линия <E> = K(0)/2
568 
569         y = Math.floor(height_E - K1[0]*y_scal/2);
570 
571         ctx_E.strokeStyle="#000000";
572         ctx_E.beginPath();
573         ctx_E.moveTo(0, y);
574         ctx_E.lineTo(width_E, y);
575         ctx_E.stroke();
576     }
577 
578     //slider_sen.oninput = function()
579     slider_sen.onmousemove = function()
580     {
581         k_sen = span_sen.innerHTML = slider_sen.value;
582     };
583     number_input_X.oninput = function()
584     {
585         slider_input_X.value = number_input_X.value;
586         Restart();
587     };
588     //slider_input_X.oninput = function()
589     slider_input_X.onmousemove = function()
590     {
591         number_input_X.value = slider_input_X.value;
592     };
593     slider_input_X.onmouseup = function() { Restart(); };
594     number_input_Y.oninput = function()
595     {
596         slider_input_Y.value = number_input_Y.value;
597         Restart();
598     };
599     //slider_input_Y.oninput = function()
600     slider_input_Y.onmousemove = function()
601     {
602         number_input_Y.value = slider_input_Y.value;
603     };
604     slider_input_Y.onmouseup = function() { Restart(); };
605     reset_calc.onclick = function()
606     {
607         if (suspended) suspend_calc.onclick();
608         Restart();
609     };
610     
611     var StepIntID;
612     suspend_calc.onclick = function()
613     {
614         suspended = !suspended;
615         
616         if (suspended) clearInterval(StepIntID);
617         else           StepIntID=setInterval(Step, 1000 / 30);
618 
619         var str = suspend_calc.value;
620         suspend_calc.value = suspend_calc.name;
621         suspend_calc.name = str;
622     };
623     number_input_n1.oninput = function()
624     {
625         if (number_input_n1.value >= 10)
626         {
627             slider_input_n1.value = number_input_n1.value;
628             span_n1.innerHTML = " x " + number_input_n1.value;
629             n2 = n1 = number_input_n1.value;
630             n = n1*n2;
631 
632             span_n.innerHTML = n;
633             Restart();
634         }
635     };
636     //slider_input_n1.oninput = function()
637     slider_input_n1.onmousemove = function()
638     {
639         number_input_n1.value = slider_input_n1.value;
640 
641         if (slider_input_n1.value >= 10)
642         {
643             span_n1.innerHTML = " x " + number_input_n1.value;
644             span_n.innerHTML = number_input_n1.value*number_input_n1.value;
645         }
646     };
647     slider_input_n1.onmouseup = function()
648     {
649         number_input_n1.value = slider_input_n1.value;
650 
651         if (slider_input_n1.value >= 10)
652         {
653             span_n1.innerHTML = " x " + number_input_n1.value;
654             n2 = n1 = number_input_n1.value;
655             n = n1*n2;
656 
657             span_n.innerHTML = n;
658             Restart();
659         }
660     };
661     radio_V.onchange = function() { sV_axis = 0; span_sqrt1.innerHTML = span_sqrt2.innerHTML = ""; Paint(); };
662     radio_sV.onchange = function() { sV_axis = 1; span_sqrt1.innerHTML = span_sqrt2.innerHTML = "sqrt"; Paint(); };
663     radio_CV.onchange = function() { norm = 0; Restart(); };
664     radio_NV.onchange = function() { norm = 1; Restart(); };
665     checkbox_norm.onclick = function() { Paint(); };
666     radio_En_all.onchange = function() { En_area = 0; Paint(); };
667     radio_En_begin.onchange = function() { En_area = 1; Paint(); };
668     radio_En_end.onchange = function() { En_area = 2; Paint(); };
669 
670     Restart();
671     StepIntID=setInterval(Step, 1000 / 30);               // функция step будет запускаться 30 раз в секунду (в 1000 мс)
672 }

Файл "TriLatLin.html" <syntaxhighlight lang="html5" line start="1" enclose="div"> <!DOCTYPE html> <html> <head>

   <title>Треугольная Решетка</title>
   <script src="TriLatLin.js"></script>
   <!link rel="stylesheet" type="text/css" href="js_tm_styles.css" />

</head> <body onload="MainTriLatticeTemper();" style="font-family: Arial; font-size: 13.5px;

border-top:solid 1.5pt; border-bottom:solid 1.5pt;">

Количество частиц: <input type="range" id="slider_input_n1" min=10 max=300 value=30 step=1 style="width: 160px;"> 900 (<input type="number" id="number_input_n1" min=10 max=300 value=30 step=1 style="width: 50px;"> x 30 рядов).

Начальные перемещения частиц – нулевые.

Начальное распределение вектора скорости частиц – случайное, с плотностью:

<input type="radio" id="radio_CV" name="dens" checked /> Равномерная плотность внутри эллипса Vx2 / Vx,max2 + Vy2 / Vy,max2 = 1; 0 вне эллипса,
<input type="radio" id="radio_NV" name="dens" /> Нормальное распределение плотности.

Задаваемые начальные среднеквадратические значения σ (Vx(0)) и σ (Vy(0)) указаны под графиками.

Распределение частиц по компонентам скорости Vx (слева) и Vy (справа).

<input type="radio" id="radio_V" name="axis" checked /> Оси абсцисс – |Vx| и |Vy| (масштаб одинаковый).
<input type="radio" id="radio_sV" name="axis" /> Оси абсцисс – sqrt|Vx| и sqrt|Vy| (масштаб одинаковый).

Оси ординат – плотности распределения частиц.

<input type=checkbox id=checkbox_norm checked />Изобразить нормальное распределение с дисперсией, равной дисперсии вычисляемой плотности.

P <canvas id="canvas_densitas_Vx" width="300" height="200" style="border: 1px solid #000000"></canvas> <canvas id="canvas_densitas_Vy" width="300" height="200" style="border: 1px solid #000000"></canvas> <input type="range" orient="vertical" id="slider_sen" min=0.1 max=1 value=0.1 step=0.1 style="height: 160px; width: 30px; -webkit-appearance: slider-vertical;" /> Чувствительность
к мгновенным изменениям
|Vx| |Vy|
<input type="range" id="slider_input_X" min=0 max=10 value=2 step=0.1
                style="width: 160px;" />σ (Vx(0)) =<input type="number"
id="number_input_X" min=0 max=10 value=2 step=0.1 style="width: 50px;" />
<input type="range" id="slider_input_Y" min=0 max=10 value=2 step=0.1
                style="width: 160px;" />σ (Vy(0)) =<input type="number"
id="number_input_Y" min=0 max=10 value=2 step=0.1 style="width: 50px;" />
   
<input type="button" id="reset_calc" value="Старт"> <input type="button" id="suspend_calc" value="Приостановить" name = "Возобновить">

Средние значения Vx2 и Vy2 по всем частицам.
(Усреднение производится также по времени с весом, пропорциональным времени):

   TxxS = 
   < Vx2 > = 
   
TyyS = < Vy2 > =
< Vx2 > + < Vy2 > =
< VxVy > =

Отношение моментов распределения компонент скорости:
Для нормального распределения < V4 > / < V2 >2 / 3 = 1

   < Vx4 >  / < Vx2 >2 / 3 = 
   
< Vy4 > / < Vy2 >2 / 3 =

Отношение стационарных и начальных квадратов компонент скорости:

   TxxS + TyyS =
   k1
   (Txx0 + Tyy0)
   
TxxSTyyS = k2 (Txx0Tyy0)
   k1 = 
k2 =
(1/k2 = )

Изменение кинетической энергии во времени. Горизонтальная линия – половина полной энергии.

   <canvas id="canvas_energy" width="1000" height="300" style="border: 1px solid #000000"></canvas>
   
<input type="radio" id="radio_En_all" name="radio_En" />График целиком. <input type="radio" id="radio_En_begin" name="radio_En" />Начало графика. <input type="radio" id="radio_En_end" name="radio_En" checked />Окончание графика.

Полная энергия, приходящаяся на одну частицу: E = .
Время t = ( шагов)

</body> </html>