Статистические распределения в двумерном кристалле с треугольной решеткой — различия между версиями
Материал из Department of Theoretical and Applied Mechanics
Денис (обсуждение | вклад) |
|||
(не показано 10 промежуточных версий 1 участника) | |||
Строка 1: | Строка 1: | ||
− | [[Виртуальная лаборатория]] > [[Статистические распределения в двумерном кристалле с треугольной решеткой]] | + | [[ТМ|Кафедра ТМ]] > [[Проект "Термокристалл"]] > [[Статистические распределения в двумерном кристалле с треугольной решеткой]] <HR> |
+ | [[Виртуальная лаборатория]] > [[Статистические распределения в двумерном кристалле с треугольной решеткой]] <HR> | ||
− | + | Рассматривается система частиц моделируемых материальными точками с линейным законом взаимодействия | |
+ | в плоскости. Частицы располагаются в треугольной решетке, края свободны. Все частицы и связи одинаковые. | ||
+ | Уравнение движения для каждой частицы имеет вид: | ||
− | + | ::<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>. | ||
+ | |||
+ | {{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Tsaplin/TriLatLin.html |width=1050 |height=2050 |border=0 }} | ||
+ | Скачать программу: [[Медиа: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]] |
Текущая версия на 13:47, 30 марта 2016
Кафедра ТМ > Проект "Термокристалл" > Статистические распределения в двумерном кристалле с треугольной решеткойВиртуальная лаборатория > Статистические распределения в двумерном кристалле с треугольной решеткой
Рассматривается система частиц моделируемых материальными точками с линейным законом взаимодействия в плоскости. Частицы располагаются в треугольной решетке, края свободны. Все частицы и связи одинаковые. Уравнение движения для каждой частицы имеет вид:
где
– масса частицы, с – жесткость связи, – вектор перемещения, – единичный вектор, направленный к одной из соседних частиц с индексом :где
– радиус-вектор частицы в начальной конфигурации.Ось
направлена вдоль одного из направлений связей. , шаг интегрирования .Скачать программу: 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>Задаваемые начальные среднеквадратические значения σ (<I><B>V<SUB>x</SUB></B></I>(0)) и
29 σ (<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;" />σ (<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;" />σ (<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>