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