Редактирование: Статистические распределения в двумерном кристалле с треугольной решеткой
Внимание! Вы не авторизовались на сайте. Ваш IP-адрес будет публично видимым, если вы будете вносить любые правки. Если вы войдёте или создадите учётную запись, правки вместо этого будут связаны с вашим именем пользователя, а также у вас появятся другие преимущества.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия | Ваш текст | ||
Строка 1: | Строка 1: | ||
− | + | [[Виртуальная лаборатория]] > [[Статистические распределения в двумерном кристалле с треугольной решеткой]] | |
− | [[Виртуальная лаборатория]] > [[Статистические распределения в двумерном кристалле с треугольной решеткой]] | ||
Рассматривается система частиц моделируемых материальными точками с линейным законом взаимодействия | Рассматривается система частиц моделируемых материальными точками с линейным законом взаимодействия | ||
Строка 24: | Строка 23: | ||
<math>m = 1,\quad c = 1</math>, шаг интегрирования <math>dt = 0.005</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= | + | {{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Tsaplin/TriLatLin.html |width=1050 |height=1700 |border=0 }} |
Скачать программу: [[Медиа:TriLatLin.zip | TriLatLin.zip]] | Скачать программу: [[Медиа:TriLatLin.zip | TriLatLin.zip]] | ||
Строка 33: | Строка 32: | ||
function MainTriLatticeTemper() | 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 _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; | |
− | |||
− | |||
− | |||
− | var | + | if (j > 0) |
+ | { | ||
+ | var ai = j&1 ? i : i-1; // соседняя частица 1 | ||
− | if ( | + | 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; | ||
+ | } | ||
− | + | function Draw(ctx, width, height, V_dens, n_col) // рисование графиков распределения частиц по компонентам скорости Vx, Vy | |
− | + | { | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
ctx.lineWidth="0.6"; // ширина линии | ctx.lineWidth="0.6"; // ширина линии | ||
ctx.clearRect(0, 0, width, height); // очистить экран | ctx.clearRect(0, 0, width, height); // очистить экран | ||
Строка 456: | Строка 440: | ||
if (sV_axis) | 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 x_scal = width / (N_graph_Vx-1); // N_graph_Vx-1 == число промежутков между N_graph_Vx точек | ||
Строка 471: | Строка 455: | ||
if (checkbox_norm.checked) | if (checkbox_norm.checked) | ||
{ | { | ||
− | + | var width2 = width*width; | |
− | |||
− | |||
− | |||
if (sV_axis) // распределение по sqrt(V_(x,y)) | if (sV_axis) // распределение по sqrt(V_(x,y)) | ||
{ | { | ||
− | + | ctx.strokeStyle = "#006000"; | |
− | + | ctx.beginPath(); | |
+ | |||
+ | 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); | |
− | + | ctx.stroke(); | |
− | |||
} | } | ||
else // распределение по V_(x,y) | else // распределение по V_(x,y) | ||
{ | { | ||
− | + | ctx.strokeStyle = "#006000"; | |
− | + | ctx.beginPath(); | |
− | + | 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(); | |
+ | } | ||
} | } | ||
Строка 535: | Строка 523: | ||
for (var i = 1; i < n_points; i++) | 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(); | ctx.stroke(); | ||
/////////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////////// | ||
− | + | } | |
− | + | var En_area = 2; // 0 - весь график, 1 - начало, 2 - конец | |
− | + | function DrawE() // рисование графика энергии от времени | |
− | + | { | |
− | + | // кинетическая: | |
ctx_E.strokeStyle="#004000"; | ctx_E.strokeStyle="#004000"; | ||
Строка 582: | Строка 570: | ||
ctx_E.beginPath(); | 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 x = 0; | ||
Строка 596: | Строка 584: | ||
ctx_E.moveTo(x, y); | ctx_E.moveTo(x, y); | ||
− | + | var s_max = (En_area == 1) ? Math.min(s, 1500) : s; | |
for (var i = i0+1; i < s; i++) | 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(); | ctx_E.stroke(); | ||
− | + | // средняя линия <E> = K(0)/2 | |
y = Math.floor(height_E - K1[0]*y_scal/2); | y = Math.floor(height_E - K1[0]*y_scal/2); | ||
Строка 615: | Строка 603: | ||
ctx_E.beginPath(); | ctx_E.beginPath(); | ||
ctx_E.moveTo(0, y); | ctx_E.moveTo(0, y); | ||
− | + | ctx_E.lineTo(width_E, y); | |
ctx_E.stroke(); | ctx_E.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() | ||
+ | { | ||
+ | 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() | ||
+ | { | ||
+ | number_input_Y.value = slider_input_Y.value; | ||
+ | }; | ||
+ | slider_input_Y.onmouseup = function() { Restart(); }; | ||
+ | reset_calc.onclick = function() | ||
+ | { | ||
+ | if (suspended) suspend_calc.onclick(); | ||
+ | Restart(); | ||
+ | }; | ||
+ | suspend_calc.onclick = function() | ||
+ | { | ||
+ | suspended = !suspended; | ||
+ | var str = suspend_calc.value; | ||
+ | suspend_calc.value = suspend_calc.name; | ||
+ | suspend_calc.name = str; | ||
+ | }; | ||
+ | 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() | ||
+ | { | ||
+ | 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(); | |
− | + | setInterval(Step, 1000 / 30); // функция step будет запускаться 30 раз в секунду (в 1000 мс) | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Строка 769: | Строка 703: | ||
<!link rel="stylesheet" type="text/css" href="js_tm_styles.css" /> | <!link rel="stylesheet" type="text/css" href="js_tm_styles.css" /> | ||
</head> | </head> | ||
− | <body onload="MainTriLatticeTemper() | + | <body onload="MainTriLatticeTemper();"> |
− | |||
<p>Количество частиц: | <p>Количество частиц: | ||
<input type="range" id="slider_input_n1" | <input type="range" id="slider_input_n1" | ||
Строка 874: | Строка 807: | ||
(1/<I>k</I><SUB>2</SUB> = <span id="span_1k2"></span>) | (1/<I>k</I><SUB>2</SUB> = <span id="span_1k2"></span>) | ||
− | <! | + | <!span id="span_U"> <!/span> <!br> |
<p><B>Изменение кинетической энергии во времени.</B> Горизонтальная линия – половина полной энергии.</p> | <p><B>Изменение кинетической энергии во времени.</B> Горизонтальная линия – половина полной энергии.</p> | ||
<canvas id="canvas_energy" width="1000" height="300" style="border: 1px solid #000000"></canvas> | <canvas id="canvas_energy" width="1000" height="300" style="border: 1px solid #000000"></canvas> | ||
Строка 885: | Строка 818: | ||
<br> | <br> | ||
Время <I>t</I> = <span id="span_t"> </span> (<span id="span_steps"></span> шагов)</p> | Время <I>t</I> = <span id="span_t"> </span> (<span id="span_steps"></span> шагов)</p> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</body> | </body> | ||
</html> | </html> | ||
Строка 915: | Строка 826: | ||
[[Category: Виртуальная лаборатория]] | [[Category: Виртуальная лаборатория]] | ||
[[Category: Программирование]] | [[Category: Программирование]] | ||
− | |||
[[Category: JavaScript]] | [[Category: JavaScript]] |