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

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
 
(не показано 8 промежуточных версий 1 участника)
Строка 1: Строка 1:
[[Виртуальная лаборатория]] > [[Статистические распределения в двумерном кристалле с треугольной решеткой]]
+
[[ТМ|Кафедра ТМ]] > [[Проект "Термокристалл"]] > [[Статистические распределения в двумерном кристалле с треугольной решеткой]] <HR>
 +
[[Виртуальная лаборатория]] > [[Статистические распределения в двумерном кристалле с треугольной решеткой]] <HR>
  
 
Рассматривается система частиц моделируемых материальными точками с линейным законом взаимодействия
 
Рассматривается система частиц моделируемых материальными точками с линейным законом взаимодействия
Строка 21: Строка 22:
  
 
Ось <math>x</math> направлена вдоль одного из направлений связей.
 
Ось <math>x</math> направлена вдоль одного из направлений связей.
 +
<math>m = 1,\quad c = 1</math>, шаг интегрирования <math>dt = 0.005</math>.
  
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Tsaplin/TriLatLin.html |width=1050 |height=1600 |border=0 }}
+
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Tsaplin/TriLatLin.html |width=1050 |height=2050 |border=0 }}
 
Скачать программу: [[Медиа:TriLatLin.zip | TriLatLin.zip]]
 
Скачать программу: [[Медиа:TriLatLin.zip | TriLatLin.zip]]
  
Разработчики [[Цаплин Вадим]], [[Кривцов Антон]]
+
<div class="mw-collapsible mw-collapsed">
 +
'''Текст программы на языке JavaScript (разработчики [[Цаплин Вадим]], [[Кривцов Антон]]):''' <div class="mw-collapsible-content">
 +
Файл '''"TriLatLin.js."'''
 +
<syntaxhighlight lang="javascript" line start="1" enclose="div">
 +
function MainTriLatticeTemper()
 +
{
 +
    var ctx_X = canvas_densitas_Vx.getContext("2d"); // для рисования плотности
 +
    var width_X = canvas_densitas_Vx.width;
 +
    var height_X = canvas_densitas_Vx.height;
 +
 
 +
    var ctx_Y = canvas_densitas_Vy.getContext("2d"); // для рисования плотности
 +
    var width_Y = canvas_densitas_Vy.width;
 +
    var height_Y = canvas_densitas_Vy.height;
 +
 
 +
    var ctx_E = canvas_energy.getContext("2d");      // для рисования графика энергии
 +
    var width_E = canvas_energy.width;
 +
    var height_E = canvas_energy.height;
 +
 
 +
    var ctx_V = canvas_nubes_V.getContext("2d");    // для рисования облака
 +
    var width_V = canvas_nubes_V.width;
 +
    var height_V = canvas_nubes_V.height;
 +
 
 +
    var ctx_U = canvas_nubes_U.getContext("2d");    // для рисования облака
 +
    var width_U = canvas_nubes_U.width;
 +
    var height_U = canvas_nubes_U.height;
 +
 
 +
    // частица содержит перемещения и скорости
 +
 
 +
    var _Vx;
 +
    var _Vy;
 +
    var Vx2_sum;        // сумма квадратов координат скорости Vx (с весом s)
 +
    var Vxy_sum;        // сумма произведений координат скорости VxVy (с весом s)
 +
    var Vy2_sum;        // сумма квадратов координат скорости Vy (с весом s)
 +
    var Vx4_sum;        // сумма (координат скорости Vx)^4 (с весом s)
 +
    var Vy4_sum;        // сумма (координат скорости Vy)^4 (с весом s)
 +
    var U1x_sum, U1y_sum;
 +
    var Vx2_av;          // средний Vx^2 c эксп. весом (для графиков)
 +
    var Vy2_av;          // средний Vy^2 c эксп. весом
 +
 
 +
    var suspended = 0;  // вычисление приостановлено == 1
 +
 
 +
    // массив частиц
 +
 
 +
    var Arr_prt = [];
 +
 
 +
    var n1 = 30;        // число рядов 1
 +
    var n2 = 30;
 +
    var n = n1 * n2;    // число частиц
 +
    //var a = 1;        // равновесное расстояние между центрами частиц
 +
    //var c = 1;        // линейная жесткость упругой связи
 +
    //var m = 1;        // масса частицы
 +
    //var с_m = c/m;
 +
    var dt_sc_m = 0.005; // шаг интегрирования по времени dt_sc_m = dt*sqrt(c_m)
 +
 
 +
    // максимальные начальные скорости (в безразмерном времени)
 +
 
 +
    var Vx = 10;
 +
    var Vy = 0.1;
 +
    var Vc_x = 0;        // скорость
 +
    var Vc_y = 0;        // центра масс
 +
 
 +
    var K1 = [];        // кин. энергия
 +
    var P = [];          // пот. энергия
 +
 
 +
    slider_input_X.value = Vx;
 +
    number_input_X.value = Vx;
 +
    slider_input_Y.value = Vy;
 +
    number_input_Y.value = Vy;
 +
    sV_axis = 0;
 +
 
 +
    var s = 0;          // шаг по времени
 +
    var V_max;          // максимальная координата скорости на графике
 +
    var sV_max;          // максимальный корень из координаты скорости на графике
 +
    var norm = 0;        // начальные координаты скорости имеют нормальное распределение == 1
 +
    var Par = [];        // возвращаемое значение функции RandomNorm()
 +
 
 +
    // Случайные числа с нормальным распределением
 +
    function RandomNorm() // <(Par[0])^2> == 1, <(Par[1])^2> == 1
 +
    {
 +
        var r_RandomNorm = Math.sqrt(-2*Math.log(Math.random()));
 +
        var fi_RandomNorm = Math.random()*Math.PI*2;
 +
 
 +
        Par[0] = r_RandomNorm*Math.cos(fi_RandomNorm);
 +
        Par[1] = r_RandomNorm*Math.sin(fi_RandomNorm);
 +
    }
 +
 
 +
    function Restart()
 +
    {
 +
        Vx = number_input_X.value;
 +
        Vy = number_input_Y.value;
 +
 
 +
        for (var j = 0; j < n2; j++)
 +
        {
 +
            Arr_prt[j] = [];
 +
 
 +
            for (var i = 0; i < n1; i++)
 +
            {
 +
                if (norm)
 +
                {
 +
                    RandomNorm();
 +
                    _Vx = Par[0];
 +
                    _Vy = Par[1];
 +
                }
 +
                else
 +
                    do
 +
                    {
 +
                        _Vx = 2*Math.random()-1;
 +
                        _Vy = 2*Math.random()-1;
 +
                    }
 +
                    while (_Vx*_Vx+_Vy*_Vy > 1);
 +
 
 +
                Vc_x += _Vx;
 +
                Vc_y += _Vy;
 +
 
 +
                var particle = {};
 +
                particle.Ux = 0;
 +
                particle.Uy = 0;
 +
                particle.Vx = _Vx;
 +
                particle.Vy = _Vy;
 +
 
 +
                Arr_prt[j][i] = particle;
 +
            }
 +
}
 +
 
 +
        Vc_x /= n;
 +
        Vc_y /= n;
 +
 
 +
        // обнуление скорости центра масс
 +
 
 +
        Vx2_sum = 0;
 +
        Vy2_sum = 0;
 +
        Vxy_sum = 0;
 +
 
 +
        for (var j = 0; j < n2; j++)
 +
        {
 +
            for (var i = 0; i < n1; i++)
 +
            {
 +
                Arr_prt[j][i].Vx -= Vc_x;
 +
                Arr_prt[j][i].Vy -= Vc_y;
 +
 
 +
                _Vx = Arr_prt[j][i].Vx;
 +
                _Vy = Arr_prt[j][i].Vy;
 +
                Vx2_sum += _Vx*_Vx;
 +
                Vy2_sum += _Vy*_Vy;
 +
            }
 +
        }
 +
 
 +
        // нормировка компонент скорости
 +
 
 +
        Vx2_sum = Vx/Math.sqrt(Vx2_sum/n);
 +
        Vy2_sum = Vy/Math.sqrt(Vy2_sum/n);
 +
 
 +
        for (var j = 0; j < n2; j++)
 +
        {
 +
            for (var i = 0; i < n1; i++)
 +
            {
 +
                Arr_prt[j][i].Vx *= Vx2_sum;
 +
                Arr_prt[j][i].Vy *= Vy2_sum;
 +
            }
 +
        }
 +
 
 +
        s = 0;
 +
 
 +
        sV_max = Math.sqrt(Math.max(Vx, Vy)*2); // максимальное значение абсциссы на графиках
 +
        V_max = 2*Math.max(Vx, Vy);            // максимальное значение абсциссы на графиках
 +
 
 +
        ExCalculateReset();
 +
        Vx2_sum = 0; Vy2_sum = 0; Vxy_sum = 0;
 +
        Vx4_sum = 0; Vy4_sum = 0;
 +
        U1x_sum = 0; U1y_sum = 0;
 +
    }
 +
 
 +
    var k_sen = 0.1; // чувствительность усредненного по времени массива к текущим изменениям
 +
    span_sen.innerHTML = k_sen;
 +
 
 +
    function Step()
 +
    {
 +
        //if (!suspended)
 +
        //{
 +
        Calculate();        // шаг интегрирования по времени
 +
        ExCalculate(k_sen);  // подготовка для вывода графиков
 +
 
 +
        s++;
 +
        Paint();            // рисование графиков
 +
        //}
 +
    }
 +
 
 +
    // треугольная решетка
 +
    // x[j][i] = a*i + a/2*(j&1);
 +
    // y[j][i] = sqrt(3)/2*a*j;
 +
 
 +
    var sqrt3 = Math.sqrt(3);
 +
 
 +
    function Calculate() // шаг интегрирования
 +
    {
 +
        var i; var j;
 +
 
 +
        P[s] = 0;
 +
 
 +
        for (var k = 0; k < n; k++) // вычисление компонент скорости
 +
        {
 +
            i = k%n1;
 +
            j = Math.floor(k/n1);
 +
 
 +
            var Ux; var Uy; var U_4; var U_43; var U_1;
 +
 
 +
            if (j > 0)
 +
            {
 +
                var ai = j&1 ? i : i-1; // соседняя частица 1
 +
 
 +
                if (ai >= 0)
 +
                {
 +
                    Ux = Arr_prt[j-1][ai].Ux - Arr_prt[j][i].Ux;
 +
                    Uy = Arr_prt[j-1][ai].Uy - Arr_prt[j][i].Uy;
 +
                    U_1 = Ux + Uy*sqrt3;
 +
                    U_4 = U_1 / 4 * dt_sc_m;
 +
                    U_43 = U_4*sqrt3;
 +
 
 +
                    Arr_prt[j][i].Vx += U_4;
 +
                    Arr_prt[j][i].Vy += U_43;
 +
 
 +
                    Arr_prt[j-1][ai].Vx -= U_4;
 +
                    Arr_prt[j-1][ai].Vy -= U_43;
 +
 
 +
                    P[s] += U_1*U_1/8;
 +
                }
 +
 
 +
                ai++; // соседняя частица 2
 +
 
 +
                if (ai < n1)
 +
                {
 +
                    Ux = Arr_prt[j-1][ai].Ux - Arr_prt[j][i].Ux;
 +
                    Uy = Arr_prt[j-1][ai].Uy - Arr_prt[j][i].Uy;
 +
                    U_1 = Uy*sqrt3 - Ux;
 +
                    U_4 = U_1 / 4 * dt_sc_m;
 +
                    U_43 = U_4*sqrt3;
 +
 
 +
                    Arr_prt[j][i].Vx -= U_4;
 +
                    Arr_prt[j][i].Vy += U_43;
 +
 
 +
                    Arr_prt[j-1][ai].Vx += U_4;
 +
                    Arr_prt[j-1][ai].Vy -= U_43;
 +
 
 +
                    P[s] += U_1*U_1/8;
 +
                }
 +
            }
 +
 
 +
            if (i > 0) // соседняя частица 3
 +
            {
 +
                U_1 = Arr_prt[j][i-1].Ux - Arr_prt[j][i].Ux;
 +
                Ux = U_1 * dt_sc_m;
 +
 
 +
                Arr_prt[j][i].Vx += Ux;
 +
                Arr_prt[j][i-1].Vx -= Ux;
 +
 
 +
                P[s] += U_1*U_1/2;
 +
            }
 +
        }
 +
 
 +
        K1[s] = 0;
 +
 
 +
 
 +
        for (var k = 0; k < n; k++) // вычисление перемещений
 +
        {
 +
            i = k%n1;
 +
            j = Math.floor(k/n1);
 +
 
 +
            var Vx_loc = Arr_prt[j][i].Vx;
 +
            var Vy_loc = Arr_prt[j][i].Vy;
 +
 
 +
            Arr_prt[j][i].Ux += Vx_loc * dt_sc_m;
 +
            Arr_prt[j][i].Uy += Vy_loc * dt_sc_m;
 +
 
 +
            K1[s] += (Vx_loc*Vx_loc+Vy_loc*Vy_loc)/2;
 +
 
 +
            Vxy_sum += Vx_loc*Vy_loc;
 +
            Vx_loc *= Vx_loc;
 +
            Vy_loc *= Vy_loc;
 +
            Vx2_sum += Vx_loc*s;
 +
            Vy2_sum += Vy_loc*s;
 +
 
 +
            Vx_loc *= Vx_loc;
 +
            Vy_loc *= Vy_loc;
 +
            Vx4_sum += Vx_loc*s;
 +
            Vy4_sum += Vy_loc*s;
 +
 
 +
            //U1x_sum += Arr_prt[j][i].Ux;
 +
            //U1y_sum += Arr_prt[j][i].Uy;
 +
        }
 +
 
 +
        U1x_sum += Arr_prt[0][0].Ux;
 +
        U1y_sum += Arr_prt[0][0].Uy;
 +
    }
 +
 
 +
    var N_graph_Vx = 20;
 +
    var Vx_dens = [];  // массив статистического распределения частиц по компонентам скорости Vx,
 +
    var Vy_dens = [];  // Vy.
 +
    var sVx_dens = [];  // массив статистического распределения частиц по компонентам скорости sqrt(Vx),
 +
    var sVy_dens = [];  // sqrt(Vy).
 +
 
 +
    function ExCalculateReset()
 +
    {
 +
        for (var i = 0; i < N_graph_Vx; i++)
 +
        {
 +
            Vx_dens[i] = 0;
 +
            Vy_dens[i] = 0;
 +
            sVx_dens[i] = 0;
 +
            sVy_dens[i] = 0;
 +
        }
 +
 
 +
        Vx2_av = 0; Vy2_av = 0;
 +
 
 +
        ExCalculate(1); // В начальный момент считаются статистические распределения без запаздывания (k_sen == 1)
 +
    }
 +
 
 +
    function ExCalculate(k_sen) // статистические вычисления на каждом шаге
 +
    {
 +
        var Vx_dens_loc = [];
 +
        var Vy_dens_loc = [];
 +
        var sVx_dens_loc = [];
 +
        var sVy_dens_loc = [];
 +
 
 +
        for (var i = 0; i < N_graph_Vx; i++)
 +
        {
 +
            Vx_dens_loc[i] = 0;
 +
            Vy_dens_loc[i] = 0;
 +
            sVx_dens_loc[i] = 0;
 +
            sVy_dens_loc[i] = 0;
 +
        }
 +
 
 +
        var Vx2_av_loc = 0;
 +
        var Vy2_av_loc = 0;
 +
 
 +
        ///////////////////////////////////////////////////////////////////////
 +
 
 +
        for (var k = 0; k < n; k++)
 +
        {
 +
            i = k%n1;
 +
            j = Math.floor(k/n1);
 +
 
 +
            var Vx_loc = Math.abs(Arr_prt[j][i].Vx);
 +
            var Vy_loc = Math.abs(Arr_prt[j][i].Vy);
 +
            var sVx_loc = Math.sqrt(Vx_loc);
 +
            var sVy_loc = Math.sqrt(Vy_loc);
 +
 
 +
            var n_d = Math.floor(Vx_loc/V_max*(N_graph_Vx-1)+0.5);
 +
            if (n_d < N_graph_Vx) { Vx_dens_loc[n_d]++; }
 +
 
 +
            n_d = Math.floor(Vy_loc/V_max*(N_graph_Vx-1)+0.5);
 +
            if (n_d < N_graph_Vx) { Vy_dens_loc[n_d]++; }
 +
 
 +
            n_d = Math.floor(sVx_loc/sV_max*(N_graph_Vx-1)+0.5);
 +
            if (n_d < N_graph_Vx) { sVx_dens_loc[n_d]++; }
 +
 
 +
            n_d = Math.floor(sVy_loc/sV_max*(N_graph_Vx-1)+0.5);
 +
            if (n_d < N_graph_Vx) { sVy_dens_loc[n_d]++; }
 +
 
 +
            Vx2_av_loc += Vx_loc*Vx_loc;
 +
            Vy2_av_loc += Vy_loc*Vy_loc;
 +
        }
 +
 
 +
        Vx_dens_loc[0] *= 2; Vy_dens_loc[0] *= 2;
 +
        sVx_dens_loc[0] = 0; sVy_dens_loc[0] = 0;
 +
 
 +
        Vx2_av_loc /= n; Vy2_av_loc /= n;
 +
 
 +
        ///////////////////////////////////////////////////////////////////////
 +
        // интегральный регулятор (фильтр низких частот)
 +
 
 +
        for (var i = 0; i < N_graph_Vx; i++)
 +
        {
 +
            Vx_dens[i] = k_sen*Vx_dens_loc[i] + (1-k_sen)*Vx_dens[i];
 +
            Vy_dens[i] = k_sen*Vy_dens_loc[i] + (1-k_sen)*Vy_dens[i];
 +
            sVx_dens[i] = k_sen*sVx_dens_loc[i] + (1-k_sen)*sVx_dens[i];
 +
            sVy_dens[i] = k_sen*sVy_dens_loc[i] + (1-k_sen)*sVy_dens[i];
 +
        }
 +
 
 +
        Vx2_av = k_sen*Vx2_av_loc + (1-k_sen)*Vx2_av;
 +
        Vy2_av = k_sen*Vy2_av_loc + (1-k_sen)*Vy2_av;
 +
    }
 +
 
 +
    function Paint()
 +
    {
 +
        Draw(ctx_X, width_X, height_X, sV_axis ? sVx_dens : Vx_dens, 0);
 +
        Draw(ctx_Y, width_Y, height_Y, sV_axis ? sVy_dens : Vy_dens, 1);
 +
 
 +
        var Vx2_aver = Vx2_sum / s / (s > 1 ? s-1 : 1) * 2 / n;
 +
        var Vy2_aver = Vy2_sum / s / (s > 1 ? s-1 : 1) * 2 / n;
 +
        var Vxy_aver = Vxy_sum / s / (s > 1 ? s-1 : 1) * 2 / n;
 +
 
 +
        span_Vx2.innerHTML = Vx2_aver.toFixed(3);
 +
        span_Vy2.innerHTML = Vy2_aver.toFixed(3);
 +
        span_V2.innerHTML = (Vx2_aver+Vy2_aver).toFixed(3);
 +
        span_Vxy.innerHTML = Vxy_aver.toExponential(2);//toPrecision(3);
 +
        //span_U.innerHTML = "< Ux > = " + (U1x_sum/s).toFixed(2) +
 +
        //"________ < Uy > = " + (U1y_sum/s).toFixed(2);
 +
 
 +
        var Vx4_aver = Vx4_sum / s / (s > 1 ? s-1 : 1) * 2 / n;
 +
        var Vy4_aver = Vy4_sum / s / (s > 1 ? s-1 : 1) * 2 / n;
 +
 
 +
        span_Mx.innerHTML = (Vx4_aver/Vx2_aver/Vx2_aver/3).toFixed(3);
 +
        span_My.innerHTML = (Vy4_aver/Vy2_aver/Vy2_aver/3).toFixed(3);
 +
 
 +
        span_k1.innerHTML = ((Vx2_aver+Vy2_aver) / (Vx*Vx+Vy*Vy)).toFixed(3);
 +
        span_k2.innerHTML = ((Vx2_aver-Vy2_aver) / (Vx*Vx-Vy*Vy)).toFixed(3);
 +
        span_1k2.innerHTML = ((Vx*Vx-Vy*Vy) / (Vx2_aver-Vy2_aver)).toFixed(3);
 +
 
 +
        DrawE();
 +
 
 +
        span_E.innerHTML = ((K1[s-1] + P[s-1])/n).toFixed(2);
 +
        span_t.innerHTML = (s*dt_sc_m).toFixed(2);
 +
        span_steps.innerHTML = s;
 +
       
 +
        DrawNubes(ctx_V, width_V, height_V, 0/*n_can*/);
 +
        DrawNubes(ctx_U, width_U, height_U, 1/*n_can*/);
 +
    }
 +
 
 +
    ///////////////////////////////////////////////////////////////////////
 +
    // рисование графиков распределения частиц по компонентам скорости Vx, Vy
 +
 
 +
    function Draw(ctx, width, height, V_dens, n_col)
 +
    {
 +
        ctx.lineWidth="0.6";                    // ширина линии
 +
        ctx.clearRect(0, 0, width, height);    // очистить экран
 +
 
 +
        var dens_V_max;                        // максимальное значение плотности
 +
 
 +
        if (sV_axis)
 +
        {
 +
            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);
 +
        }
 +
        else dens_V_max = n*2*V_max/(N_graph_Vx-1)/Math.sqrt(2*Math.PI*(n_col ? Vy2_av : Vx2_av));
 +
 
 +
        var x_scal = width / (N_graph_Vx-1);    // N_graph_Vx-1 == число промежутков между N_graph_Vx точек
 +
        var y_scal = height / dens_V_max / (sV_axis ? 1.2 : 1.1);  // 1.2,1.1 - коэффициент запаса
 +
 
 +
        var x = 0; var y;
 +
        var n_points = Math.floor(width / 3);
 +
 
 +
        ///////////////////////////////////////////////////////////////////////
 +
        // рисование нормального распределения
 +
 
 +
        if (checkbox_norm.checked)
 +
        {
 +
            var width2 = width*width;
 +
 
 +
            ctx.strokeStyle = "#006000";
 +
            ctx.beginPath();
 +
 
 +
            if (sV_axis) // распределение по sqrt(V_(x,y))
 +
            {
 +
                var x1 = -V_max*V_max/width2/width2/(n_col ? Vy2_av : Vx2_av)/2;
 +
                var y1 = y_scal*dens_V_max*Math.sqrt(Math.sqrt(2*Math.E/(n_col ? Vy2_av : Vx2_av)))*sV_max/width;
 +
 
 +
                ctx.moveTo(x, height);
 +
 
 +
                //for (var i = 1; i < n_points; i++)
 +
                for (var i = 1; i <= width; i++)
 +
                {
 +
                    //x = 3*i;
 +
                    x = i;
 +
                    var x2 = x*x;
 +
 
 +
                    y = Math.floor(height - y1*x*Math.exp(x2*x2*x1));
 +
 
 +
                    ctx.lineTo(x, y);
 +
                }
 +
 
 +
                //y = Math.floor(height - y1*width*Math.exp(width2*width2*x1));
 +
                //ctx.lineTo(width, y);
 +
            }
 +
            else // распределение по V_(x,y)
 +
            {
 +
                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));
 +
                var x1 = -V_max*V_max/width/width/(n_col ? Vy2_av : Vx2_av)/2;
 +
 
 +
                y = Math.floor(height - y1);
 +
 
 +
                ctx.moveTo(x, y);
 +
 
 +
                for (var i = 1; i < n_points; i++)
 +
                {
 +
                    x = 3*i;
 +
                    y = Math.floor(height - y1*Math.exp(x*x*x1));
 +
 
 +
                    ctx.lineTo(x, y);
 +
                }
 +
 
 +
                y = Math.floor(height - y1*Math.exp(width*width*x1));
 +
                ctx.lineTo(width, y);
 +
            }
 +
 
 +
            ctx.stroke();
 +
        }
 +
 
 +
        ///////////////////////////////////////////////////////////////////////
 +
        // рисование вычисленного распределения
 +
 
 +
        ctx.strokeStyle = n_col ? "#ff0000" : "#0000ff";
 +
        ctx.beginPath();
 +
 
 +
        x = 0;
 +
        y = Math.floor(height - y_scal*V_dens[0]);
 +
 
 +
        ctx.moveTo(x, y);
 +
 
 +
        for (var i = 1; i < n_points; i++)
 +
        {
 +
            y = 0;
 +
            x = 3*i;
 +
 
 +
            var j = Math.floor(x/x_scal);
 +
            var fi = x/x_scal - j;                      // 0 <= fi < 1
 +
 
 +
            if (j >= N_graph_Vx-1) alert("error!");
 +
 
 +
            // интерполяция кубическими сплайнами
 +
 
 +
            y += V_dens[j] * (fi-1) * (fi-1) * (2*fi+1); // значения
 +
            y += V_dens[j+1] * fi * fi * (3-2*fi);      // в узлах
 +
 
 +
            var y_d = (j == 0) ? V_dens[1]-V_dens[0] : (V_dens[j+1]-V_dens[j-1])/2;
 +
 
 +
            y += y_d * (fi-1) * (fi-1) * fi;            // производная в левом узле
 +
 
 +
            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;
 +
 
 +
            y += y_d * fi * fi * (fi-1);                // производная в правом узле
 +
 
 +
            y = Math.floor(height - y_scal*y);          // линейное отображение в область построения
 +
            y = Math.max(0, y);
 +
            y = Math.min(y, height);
 +
 
 +
            ctx.lineTo(x, y);
 +
        }
 +
 
 +
        y = Math.floor(height - y_scal*V_dens[N_graph_Vx-1]);
 +
        y = Math.min(y, height);
 +
        ctx.lineTo(width, y);
 +
        ctx.stroke();
 +
 
 +
        ///////////////////////////////////////////////////////////////////////
 +
    }
 +
 
 +
    var En_area = 2; // 0 - весь график, 1 - начало, 2 - конец
 +
 
 +
    function DrawE() // рисование графика энергии от времени
 +
    {
 +
        // кинетическая:
 +
 
 +
        ctx_E.strokeStyle="#004000";
 +
        ctx_E.lineWidth="0.7";                        // ширина линии
 +
        ctx_E.clearRect(0, 0, width_E, height_E);    // очистить экран
 +
        ctx_E.beginPath();
 +
 
 +
        var K_max = K1[0];
 +
        var x_scal;
 +
 
 +
        x_scal = (En_area == 0) ? x_scal = width_E / Math.max(s, 1500) : width_E / 1500;
 +
 
 +
        var y_scal = height_E / K_max;
 +
 
 +
        var i0 = (En_area == 2) ? Math.max(0, s-1500) : 0;
 +
 
 +
        var x = 0;
 +
        var y = Math.floor(height_E - K1[i0]*y_scal);
 +
 
 +
        ctx_E.moveTo(x, y);
 +
 
 +
        var s_max = (En_area == 1) ? Math.min(s, 1500) : s;
 +
 
 +
        for (var i = i0+1; i < s; i++)
 +
        {
 +
            y = Math.floor(height_E - K1[i]*y_scal);
 +
            x = Math.ceil((i-i0)*x_scal);
 +
 
 +
            ctx_E.lineTo(x, y);
 +
        }
 +
 
 +
        ctx_E.stroke();
 +
 
 +
        // средняя линия <E> = K(0)/2
 +
 
 +
        y = Math.floor(height_E - K1[0]*y_scal/2);
 +
 
 +
        ctx_E.strokeStyle="#000000";
 +
        ctx_E.beginPath();
 +
        ctx_E.moveTo(0, y);
 +
        ctx_E.lineTo(width_E, y);
 +
        ctx_E.stroke();
 +
    }
 +
 
 +
    function DrawNubes(ctx, width, height, n_can)  // рисования облака
 +
    {
 +
        ctx.strokeStyle="#000000";
 +
        ctx.lineWidth=1;                        // ширина линии
 +
        ctx.clearRect(0, 0, width, height);    // очистить экран
 +
        ctx.beginPath();
 +
 
 +
        if (n_can == 0)
 +
        {
 +
            for (var k = 0; k < n; k++)
 +
            {
 +
                i = k%n1;
 +
                j = Math.floor(k/n1);
 +
 
 +
                var x = Math.floor((Arr_prt[j][i].Vx/V_max+1)*width/2);
 +
                var y = Math.floor((Arr_prt[j][i].Vy/V_max+1)*height/2);
 +
                ctx.moveTo(x-1, y);
 +
                ctx.lineTo(x+1, y);
 +
            }
 +
 
 +
            ctx.stroke();
 +
        }
 +
        else
 +
        {
 +
            for (var k = 0; k < n; k++)
 +
            {
 +
                i = k%n1;
 +
                j = Math.floor(k/n1);
 +
 
 +
                var x = Math.floor((Arr_prt[j][i].Ux/V_max+1)*width/2);
 +
                var y = Math.floor((Arr_prt[j][i].Uy/V_max+1)*height/2);
 +
                ctx.moveTo(x-1, y);
 +
                ctx.lineTo(x+1, y);
 +
            }
 +
 
 +
            ctx.stroke();
 +
        }
 +
    }
 +
 
 +
    //slider_sen.oninput = function()
 +
    slider_sen.onmousemove = function()
 +
    {
 +
        k_sen = span_sen.innerHTML = slider_sen.value;
 +
    };
 +
    number_input_X.oninput = function()
 +
    {
 +
        slider_input_X.value = number_input_X.value;
 +
        Restart();
 +
    };
 +
    //slider_input_X.oninput = function()
 +
    slider_input_X.onmousemove = function()
 +
    {
 +
        number_input_X.value = slider_input_X.value;
 +
    };
 +
    slider_input_X.onmouseup = function() { Restart(); };
 +
    number_input_Y.oninput = function()
 +
    {
 +
        slider_input_Y.value = number_input_Y.value;
 +
        Restart();
 +
    };
 +
    //slider_input_Y.oninput = function()
 +
    slider_input_Y.onmousemove = function()
 +
    {
 +
        number_input_Y.value = slider_input_Y.value;
 +
    };
 +
    slider_input_Y.onmouseup = function() { Restart(); };
 +
    reset_calc.onclick = function()
 +
    {
 +
        if (suspended) suspend_calc.onclick();
 +
        Restart();
 +
    };
 +
   
 +
    var StepIntID;
 +
    suspend_calc.onclick = function()
 +
    {
 +
        suspended = !suspended;
 +
       
 +
        if (suspended) clearInterval(StepIntID);
 +
        else          StepIntID=setInterval(Step, 1000 / 30);
 +
 
 +
        var str = suspend_calc.value;
 +
        suspend_calc.value = suspend_calc.name;
 +
        suspend_calc.name = str;
 +
 
 +
        str = suspend_calc1.value;
 +
        suspend_calc1.value = suspend_calc1.name;
 +
        suspend_calc1.name = str;
 +
    };
 +
    reset_calc1.onclick = reset_calc.onclick;
 +
    suspend_calc1.onclick = suspend_calc.onclick;
 +
    number_input_n1.oninput = function()
 +
    {
 +
        if (number_input_n1.value >= 10)
 +
        {
 +
            slider_input_n1.value = number_input_n1.value;
 +
            span_n1.innerHTML = " x " + number_input_n1.value;
 +
            n2 = n1 = number_input_n1.value;
 +
            n = n1*n2;
 +
 
 +
            span_n.innerHTML = n;
 +
            Restart();
 +
        }
 +
    };
 +
    //slider_input_n1.oninput = function()
 +
    slider_input_n1.onmousemove = function()
 +
    {
 +
        number_input_n1.value = slider_input_n1.value;
 +
 
 +
        if (slider_input_n1.value >= 10)
 +
        {
 +
            span_n1.innerHTML = " x " + number_input_n1.value;
 +
            span_n.innerHTML = number_input_n1.value*number_input_n1.value;
 +
        }
 +
    };
 +
    slider_input_n1.onmouseup = function()
 +
    {
 +
        number_input_n1.value = slider_input_n1.value;
 +
 
 +
        if (slider_input_n1.value >= 10)
 +
        {
 +
            span_n1.innerHTML = " x " + number_input_n1.value;
 +
            n2 = n1 = number_input_n1.value;
 +
            n = n1*n2;
 +
 
 +
            span_n.innerHTML = n;
 +
            Restart();
 +
        }
 +
    };
 +
    radio_V.onchange = function() { sV_axis = 0; span_sqrt1.innerHTML = span_sqrt2.innerHTML = ""; Paint(); };
 +
    radio_sV.onchange = function() { sV_axis = 1; span_sqrt1.innerHTML = span_sqrt2.innerHTML = "sqrt"; Paint(); };
 +
    radio_CV.onchange = function() { norm = 0; Restart(); };
 +
    radio_NV.onchange = function() { norm = 1; Restart(); };
 +
    checkbox_norm.onclick = function() { Paint(); };
 +
    radio_En_all.onchange = function() { En_area = 0; Paint(); };
 +
    radio_En_begin.onchange = function() { En_area = 1; Paint(); };
 +
    radio_En_end.onchange = function() { En_area = 2; Paint(); };
 +
 
 +
    Restart();
 +
    StepIntID=setInterval(Step, 1000 / 30);              // функция step будет запускаться 30 раз в секунду (в 1000 мс)
 +
}
 +
</syntaxhighlight>
 +
Файл '''"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;">
 +
    <p>Количество частиц:
 +
        <input type="range" id="slider_input_n1"
 +
        min=10 max=300 value=30 step=1 style="width: 160px;">
 +
        <span id="span_n">900</span> (<input type="number"
 +
        id="number_input_n1" min=10 max=300 value=30 step=1 style="width: 50px;">
 +
        <span id="span_n1"> x 30</span> рядов).
 +
    </p>
 +
 
 +
    <p>Начальные перемещения частиц – нулевые.</p>
 +
    <p>Начальное распределение вектора скорости частиц – случайное, с плотностью:</p>
 +
 
 +
    <p><input type="radio" id="radio_CV" name="dens" checked />
 +
    Равномерная плотность внутри эллипса <I><B>V<SUB>x</SUB></B></I><SUP>2</SUP> /
 +
    <I><B>V<SUB>x,max</SUB></B></I><SUP>2</SUP> + <I><B>V<SUB>y</SUB></B></I><SUP>2</SUP> /
 +
    <I><B>V<SUB>y,max</SUB></B></I><SUP>2</SUP> = 1; 0 вне эллипса,<br>
 +
    <input type="radio" id="radio_NV" name="dens" />
 +
    Нормальное распределение плотности.</p>
 +
 
 +
    <p>Задаваемые начальные среднеквадратические значения &sigma; (<I><B>V<SUB>x</SUB></B></I>(0)) и
 +
    &sigma; (<I><B>V<SUB>y</SUB></B></I>(0)) указаны под графиками.</p>
 +
 
 +
    <p><B>Распределение частиц по компонентам скорости <I>V<SUB>x</SUB></I> (слева)
 +
    и <I>V<SUB>y</SUB></I> (справа).</B></p>
 +
 
 +
    <p><input type="radio" id="radio_V" name="axis" checked />
 +
    Оси абсцисс – |<I><B>V<SUB>x</SUB></B></I>| и |<I><B>V<SUB>y</SUB></B></I>|
 +
    (масштаб одинаковый).<br>
 +
    <input type="radio" id="radio_sV" name="axis" />
 +
    Оси абсцисс – sqrt|<I><B>V<SUB>x</SUB></B></I>| и sqrt|<I><B>V<SUB>y</SUB></B></I>|
 +
    (масштаб одинаковый).</p>
 +
 
 +
    <p>Оси ординат – плотности распределения частиц.</p>
 +
    <p><input type=checkbox id=checkbox_norm checked />Изобразить нормальное распределение с дисперсией,
 +
    равной дисперсии вычисляемой плотности.</p>
 +
 
 +
    <table>
 +
        <tr><td><I>P</I></td>
 +
            <td><canvas id="canvas_densitas_Vx" width="300" height="200" style="border:
 +
                1px solid #000000"></canvas></td>
 +
            <td><canvas id="canvas_densitas_Vy" width="300" height="200" style="border:
 +
                1px solid #000000"></canvas></td>
 +
            <td><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;" /></td>
 +
            <td>Чувствительность<br> к мгновенным изменениям<br><span id="span_sen"></span></td>
 +
        </tr>
 +
        <tr><td></td><td style="text-align: center"><span id = "span_sqrt1"></span>|<I><B>V<SUB>x</SUB></B></I>|</td>
 +
        <td style="text-align: center"><span id = "span_sqrt2"></span>|<I><B>V<SUB>y</SUB></B></I>|</td>
 +
        </tr>
 +
        <tr><td></td><td></td><td></td></tr>
 +
        <tr><td></td><td></td><td></td></tr>
 +
        <tr><td></td><td></td><td></td></tr>
 +
        <tr><td></td>
 +
            <td><input type="range" id="slider_input_X" min=0 max=10 value=2 step=0.1
 +
                style="width: 160px;" />&sigma; (<I><B>V<SUB>x</SUB></B></I>(0)) =<input type="number"
 +
                id="number_input_X" min=0 max=10 value=2 step=0.1 style="width: 50px;" /></td>
 +
            <td><input type="range" id="slider_input_Y" min=0 max=10 value=2 step=0.1
 +
                style="width: 160px;" />&sigma; (<I><B>V<SUB>y</SUB></B></I>(0)) =<input type="number"
 +
                id="number_input_Y" min=0 max=10 value=2 step=0.1 style="width: 50px;" /></td>
 +
        </tr>
 +
    </table>
 +
 
 +
    <br>
 +
    <input type="button" id="reset_calc" value="Старт">
 +
    <input type="button" id="suspend_calc" value="Приостановить" name = "Возобновить">
 +
    <br>
 +
 
 +
    <p>Средние значения <I><B>V<SUB>x</SUB></B></I><SUP>2</SUP> и
 +
    <I><B>V<SUB>y</SUB></B></I><SUP>2</SUP> по всем частицам.<br>
 +
    (Усреднение производится также по времени с весом, пропорциональным времени):</p>
 +
 
 +
    <I><B>T<SUB>xx</SUB></B><SUP>S</SUP></I> =
 +
    < <I><B>V<SUB>x</SUB></B></I><SUP>2</SUP> > = <span id="span_Vx2"></span>
 +
    <br>
 +
    <I><B>T<SUB>yy</SUB></B><SUP>S</SUP></I> =
 +
    < <I><B>V<SUB>y</SUB></B></I><SUP>2</SUP> > = <span id="span_Vy2"></span>
 +
    <br>
 +
    < <I><B>V<SUB>x</SUB></B></I><SUP>2</SUP> > + < <I><B>V<SUB>y</SUB></B></I><SUP>2</SUP> > = <span id="span_V2"></span>
 +
    <br>
 +
    < <I><B>V<SUB>x</SUB>V<SUB>y</SUB></B></I> > = <span id="span_Vxy"></span>
 +
    <br>
 +
 
 +
    <p>Отношение моментов распределения компонент скорости:<br>
 +
    Для нормального распределения
 +
    < <I><B>V</B></I><SUP>4</SUP> >  / < <I><B>V</B></I><SUP>2</SUP> ><SUP>2</SUP> / 3 = 1</p>
 +
    < <I><B>V<SUB>x</SUB></B></I><SUP>4</SUP> >  / < <I><B>V<SUB>x</SUB></B></I><SUP>2</SUP> ><SUP>2</SUP> / 3 =
 +
    <span id="span_Mx"></span><br>
 +
    < <I><B>V<SUB>y</SUB></B></I><SUP>4</SUP> >  / < <I><B>V<SUB>y</SUB></B></I><SUP>2</SUP> ><SUP>2</SUP> / 3 =
 +
    <span id="span_My"></span><br>
 +
 
 +
    <p>Отношение стационарных и начальных квадратов компонент скорости:</p>
 +
    <I><B>T<SUB>xx</SUB></B><SUP>S</SUP></I> + <I><B>T<SUB>yy</SUB></B><SUP>S</SUP></I> =
 +
    <I>k</I><SUB>1</SUB>
 +
    (<B><I>T<SUB>xx</SUB></I></B><SUP>0</SUP> + <B><I>T<SUB>yy</SUB></I></B><SUP>0</SUP>)
 +
    <br>
 +
    <I><B>T<SUB>xx</SUB></B><SUP>S</SUP></I> – <I><B>T<SUB>yy</SUB></B><SUP>S</SUP></I> =
 +
    <I>k</I><SUB>2</SUB>
 +
    (<B><I>T<SUB>xx</SUB></I></B><SUP>0</SUP> – <B><I>T<SUB>yy</SUB></I></B><SUP>0</SUP>)
 +
    <br>
 +
 
 +
    <I>k</I><SUB>1</SUB> = <span id="span_k1"></span><br>
 +
    <I>k</I><SUB>2</SUB> = <span id="span_k2"></span><br>
 +
    (1/<I>k</I><SUB>2</SUB> = <span id="span_1k2"></span>)
 +
 
 +
    <!--span id="span_U">  </span>    <br-->
 +
    <p><B>Изменение кинетической энергии во времени.</B> Горизонтальная линия – половина полной энергии.</p>
 +
    <canvas id="canvas_energy" width="1000" height="300" style="border: 1px solid #000000"></canvas>
 +
    <br>
 +
    <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 />Окончание графика.
 +
 
 +
    <p>Полная энергия, приходящаяся на одну частицу: <I>E</I> = <span id="span_E">  </span>.
 +
    <br>
 +
    Время <I>t</I> = <span id="span_t">  </span> (<span id="span_steps"></span> шагов)</p>
 +
 
 +
    <table>
 +
        <tr>
 +
            <td></td><td style="text-align: center"><B>Скорости частиц</B></td>
 +
            <td></td><td style="text-align: center"><B>Перемещения частиц</B></td>
 +
        </tr>
 +
        <tr><td><I><B>V<SUB>y</SUB></B></I></td>
 +
            <td><canvas id="canvas_nubes_V" width="400" height="400" style="border:
 +
                1px solid #000000"></canvas></td>
 +
            <td  width=100 style="text-align: right"><I><B>U<SUB>y</SUB></B></I></td>
 +
            <td><canvas id="canvas_nubes_U" width="400" height="400" style="border:
 +
                1px solid #000000"></canvas></td>
 +
        </tr>
 +
        <tr><td></td><td style="text-align: center"><I><B>V<SUB>x</SUB></B></I></td>
 +
            <td></td><td style="text-align: center"><I><B>U<SUB>x</SUB></B></I></td>
 +
        </tr>
 +
    </table>
 +
    <br>
 +
    <input type="button" id="reset_calc1" value="Старт">
 +
    <input type="button" id="suspend_calc1" value="Приостановить" name = "Возобновить">
 +
    <br>
 +
    <br>
 +
</body>
 +
</html>
 +
</syntaxhighlight>
 +
</div>
 +
</div>
  
 
[[Category: Виртуальная лаборатория]]
 
[[Category: Виртуальная лаборатория]]
 
[[Category: Программирование]]
 
[[Category: Программирование]]
 +
[[Category: Проект "Термокристалл"]]
 
[[Category: JavaScript]]
 
[[Category: JavaScript]]

Текущая версия на 13:47, 30 марта 2016

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

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

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

Файл "TriLatLin.html"

  1 <!DOCTYPE html>
  2 <html>
  3 <head>
  4     <title>Треугольная Решетка</title>
  5     <script src="TriLatLin.js"></script>
  6     <!link rel="stylesheet" type="text/css" href="js_tm_styles.css" />
  7 </head>
  8 <body onload="MainTriLatticeTemper();" style="font-family: Arial; font-size: 13.5px;
  9  border-top:solid 1.5pt; border-bottom:solid 1.5pt;">
 10     <p>Количество частиц:
 11         <input type="range" id="slider_input_n1"
 12          min=10 max=300 value=30 step=1 style="width: 160px;">
 13         <span id="span_n">900</span> (<input type="number"
 14         id="number_input_n1" min=10 max=300 value=30 step=1 style="width: 50px;">
 15         <span id="span_n1"> x 30</span> рядов). 
 16     </p>
 17 
 18     <p>Начальные перемещения частиц – нулевые.</p>
 19     <p>Начальное распределение вектора скорости частиц – случайное, с плотностью:</p>
 20 
 21     <p><input type="radio" id="radio_CV" name="dens" checked />
 22     Равномерная плотность внутри эллипса <I><B>V<SUB>x</SUB></B></I><SUP>2</SUP> /
 23     <I><B>V<SUB>x,max</SUB></B></I><SUP>2</SUP> + <I><B>V<SUB>y</SUB></B></I><SUP>2</SUP> /
 24     <I><B>V<SUB>y,max</SUB></B></I><SUP>2</SUP> = 1; 0 вне эллипса,<br>
 25     <input type="radio" id="radio_NV" name="dens" />
 26     Нормальное распределение плотности.</p>
 27 
 28     <p>Задаваемые начальные среднеквадратические значения &sigma; (<I><B>V<SUB>x</SUB></B></I>(0)) и
 29     &sigma; (<I><B>V<SUB>y</SUB></B></I>(0)) указаны под графиками.</p>
 30 
 31     <p><B>Распределение частиц по компонентам скорости <I>V<SUB>x</SUB></I> (слева)
 32     и <I>V<SUB>y</SUB></I> (справа).</B></p>
 33 
 34     <p><input type="radio" id="radio_V" name="axis" checked />
 35     Оси абсцисс – |<I><B>V<SUB>x</SUB></B></I>| и |<I><B>V<SUB>y</SUB></B></I>|
 36     (масштаб одинаковый).<br>
 37     <input type="radio" id="radio_sV" name="axis" />
 38     Оси абсцисс – sqrt|<I><B>V<SUB>x</SUB></B></I>| и sqrt|<I><B>V<SUB>y</SUB></B></I>|
 39     (масштаб одинаковый).</p>
 40 
 41     <p>Оси ординат – плотности распределения частиц.</p>
 42     <p><input type=checkbox id=checkbox_norm checked />Изобразить нормальное распределение с дисперсией,
 43     равной дисперсии вычисляемой плотности.</p>
 44 
 45     <table>
 46         <tr><td><I>P</I></td>
 47             <td><canvas id="canvas_densitas_Vx" width="300" height="200" style="border:
 48                 1px solid #000000"></canvas></td>
 49             <td><canvas id="canvas_densitas_Vy" width="300" height="200" style="border:
 50                 1px solid #000000"></canvas></td>
 51             <td><input type="range" orient="vertical" id="slider_sen" min=0.1 max=1 value=0.1 step=0.1
 52                  style="height: 160px; width: 30px; -webkit-appearance: slider-vertical;" /></td>
 53             <td>Чувствительность<br> к мгновенным изменениям<br><span id="span_sen"></span></td>
 54         </tr>
 55         <tr><td></td><td style="text-align: center"><span id = "span_sqrt1"></span>|<I><B>V<SUB>x</SUB></B></I>|</td>
 56         <td style="text-align: center"><span id = "span_sqrt2"></span>|<I><B>V<SUB>y</SUB></B></I>|</td>
 57         </tr>
 58         <tr><td></td><td></td><td></td></tr>
 59         <tr><td></td><td></td><td></td></tr>
 60         <tr><td></td><td></td><td></td></tr>
 61         <tr><td></td>
 62             <td><input type="range" id="slider_input_X" min=0 max=10 value=2 step=0.1
 63                  style="width: 160px;" />&sigma; (<I><B>V<SUB>x</SUB></B></I>(0)) =<input type="number"
 64                  id="number_input_X" min=0 max=10 value=2 step=0.1 style="width: 50px;" /></td>
 65             <td><input type="range" id="slider_input_Y" min=0 max=10 value=2 step=0.1
 66                  style="width: 160px;" />&sigma; (<I><B>V<SUB>y</SUB></B></I>(0)) =<input type="number"
 67                  id="number_input_Y" min=0 max=10 value=2 step=0.1 style="width: 50px;" /></td>
 68         </tr>
 69     </table>
 70 
 71     <br>
 72     <input type="button" id="reset_calc" value="Старт">
 73     <input type="button" id="suspend_calc" value="Приостановить" name = "Возобновить">
 74     <br>
 75 
 76     <p>Средние значения <I><B>V<SUB>x</SUB></B></I><SUP>2</SUP> и
 77     <I><B>V<SUB>y</SUB></B></I><SUP>2</SUP> по всем частицам.<br>
 78     (Усреднение производится также по времени с весом, пропорциональным времени):</p>
 79 
 80     <I><B>T<SUB>xx</SUB></B><SUP>S</SUP></I> = 
 81     < <I><B>V<SUB>x</SUB></B></I><SUP>2</SUP> > = <span id="span_Vx2"></span>
 82     <br>
 83     <I><B>T<SUB>yy</SUB></B><SUP>S</SUP></I> =
 84     < <I><B>V<SUB>y</SUB></B></I><SUP>2</SUP> > = <span id="span_Vy2"></span>
 85     <br>
 86     < <I><B>V<SUB>x</SUB></B></I><SUP>2</SUP> > + < <I><B>V<SUB>y</SUB></B></I><SUP>2</SUP> > = <span id="span_V2"></span>
 87     <br>
 88     < <I><B>V<SUB>x</SUB>V<SUB>y</SUB></B></I> > = <span id="span_Vxy"></span>
 89     <br>
 90 
 91     <p>Отношение моментов распределения компонент скорости:<br>
 92     Для нормального распределения
 93     < <I><B>V</B></I><SUP>4</SUP> >  / < <I><B>V</B></I><SUP>2</SUP> ><SUP>2</SUP> / 3 = 1</p>
 94     < <I><B>V<SUB>x</SUB></B></I><SUP>4</SUP> >  / < <I><B>V<SUB>x</SUB></B></I><SUP>2</SUP> ><SUP>2</SUP> / 3 = 
 95     <span id="span_Mx"></span><br>
 96     < <I><B>V<SUB>y</SUB></B></I><SUP>4</SUP> >  / < <I><B>V<SUB>y</SUB></B></I><SUP>2</SUP> ><SUP>2</SUP> / 3 = 
 97     <span id="span_My"></span><br>
 98 
 99     <p>Отношение стационарных и начальных квадратов компонент скорости:</p>
100     <I><B>T<SUB>xx</SUB></B><SUP>S</SUP></I> + <I><B>T<SUB>yy</SUB></B><SUP>S</SUP></I> =
101     <I>k</I><SUB>1</SUB>
102     (<B><I>T<SUB>xx</SUB></I></B><SUP>0</SUP> + <B><I>T<SUB>yy</SUB></I></B><SUP>0</SUP>)
103     <br>
104     <I><B>T<SUB>xx</SUB></B><SUP>S</SUP></I><I><B>T<SUB>yy</SUB></B><SUP>S</SUP></I> =
105     <I>k</I><SUB>2</SUB>
106     (<B><I>T<SUB>xx</SUB></I></B><SUP>0</SUP><B><I>T<SUB>yy</SUB></I></B><SUP>0</SUP>)
107     <br>
108 
109     <I>k</I><SUB>1</SUB> = <span id="span_k1"></span><br>
110     <I>k</I><SUB>2</SUB> = <span id="span_k2"></span><br>
111     (1/<I>k</I><SUB>2</SUB> = <span id="span_1k2"></span>)
112 
113     <!--span id="span_U">  </span>    <br-->
114     <p><B>Изменение кинетической энергии во времени.</B> Горизонтальная линия – половина полной энергии.</p>
115     <canvas id="canvas_energy" width="1000" height="300" style="border: 1px solid #000000"></canvas>
116     <br>
117     <input type="radio" id="radio_En_all" name="radio_En" />График целиком.
118     <input type="radio" id="radio_En_begin" name="radio_En" />Начало графика.
119     <input type="radio" id="radio_En_end" name="radio_En" checked />Окончание графика.
120 
121     <p>Полная энергия, приходящаяся на одну частицу: <I>E</I> = <span id="span_E">  </span>.
122     <br>
123     Время <I>t</I> = <span id="span_t">  </span> (<span id="span_steps"></span> шагов)</p>
124 
125     <table>
126         <tr>
127             <td></td><td style="text-align: center"><B>Скорости частиц</B></td>
128             <td></td><td style="text-align: center"><B>Перемещения частиц</B></td>
129         </tr>
130         <tr><td><I><B>V<SUB>y</SUB></B></I></td>
131             <td><canvas id="canvas_nubes_V" width="400" height="400" style="border:
132                 1px solid #000000"></canvas></td>
133             <td  width=100 style="text-align: right"><I><B>U<SUB>y</SUB></B></I></td>
134             <td><canvas id="canvas_nubes_U" width="400" height="400" style="border:
135                 1px solid #000000"></canvas></td>
136         </tr>
137         <tr><td></td><td style="text-align: center"><I><B>V<SUB>x</SUB></B></I></td>
138             <td></td><td style="text-align: center"><I><B>U<SUB>x</SUB></B></I></td>
139         </tr>
140     </table>
141     <br>
142     <input type="button" id="reset_calc1" value="Старт">
143     <input type="button" id="suspend_calc1" value="Приостановить" name = "Возобновить">
144     <br>
145     <br>
146 </body>
147 </html>