Текущая версия |
Ваш текст |
Строка 1: |
Строка 1: |
− | [[ТМ|Кафедра ТМ]] > [[Проект "Термокристалл"]] > [[Статистические распределения в двумерном кристалле с треугольной решеткой]] <HR>
| + | [[Виртуальная лаборатория]] > [[Статистические распределения в двумерном кристалле с треугольной решеткой]] |
− | [[Виртуальная лаборатория]] > [[Статистические распределения в двумерном кристалле с треугольной решеткой]] <HR> | |
| | | |
| Рассматривается система частиц моделируемых материальными точками с линейным законом взаимодействия | | Рассматривается система частиц моделируемых материальными точками с линейным законом взаимодействия |
Строка 22: |
Строка 21: |
| | | |
| Ось <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=2050 |border=0 }} | + | {{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Tsaplin/TriLatLin.html |width=1050 |height=1600 |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>Задаваемые начальные среднеквадратические значения σ (<I><B>V<SUB>x</SUB></B></I>(0)) и
| |
− | σ (<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;" />σ (<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;" />σ (<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]] |