Chain v1
Материал из Department of Theoretical and Applied Mechanics
Версия от 22:18, 5 ноября 2014; Денис (обсуждение | вклад)
Виртуальная лаборатория > Динамика одномерного кристалла > Цепь - версии > Chain v1
Скачать программу: Chain_v1_release.zip Текст программы на языке JavaScript (разработчик Цветков Денис): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default"> Файл "Chain_v1_release.js"
function MainChain(canvas) {
// Предварительные установки
var context = canvas.getContext("2d"); // на context происходит рисование
document.oncontextmenu=function(e){return false}; // блокировка контекстного меню
var Pi = 3.1415926; // число "пи"
var m0 = 1; // масштаб массы
var T0 = 1; // масштаб времени (период колебаний исходной системы)
var a0 = 1; // масштаб расстояния (диаметр шара)
var k0 = 2 * Pi / T0; // масштаб частоты
var C0 = m0 * k0 * k0; // масштаб жесткости
// *** Задание физических параметров ***
var Ny = 5; // Число шаров, помещающихся по вертикали в окно (задает размер шара относительно размера окна)
var scale = canvas.height / Ny / a0; // масштабный коэффициент для перехода от расчетных к экранным координатам
var m = 1 * m0; // масса
var C = 1 * C0; // жесткость
var r = a0; // радиус частицы в расчетных координатах
var rScale = r * scale; // радиус частицы в экранных координатах
var num = 10; // количество частиц
var v0 = 1*a0/T0; // начальный разброс скоростей
// *** Задание вычислительных параметров ***
var fps = 50; // frames per second - число кадров в секунду (качечтво отображения)
var spf = 100; // steps per frame - число шагов интегрирования между кадрами (скорость расчета)
var dt = 0.045 * T0 / fps; // шаг интегрирования (качество расчета)
// Выполнение программы
var w = canvas.width / scale; // ширина окна в расчетных координатах
var h = canvas.height / scale; // высота окна в расчетных координатах
var pDist = w/num; // расстояние между шарами (в начальном положении)
var hC = h/2 * scale; // высота цепи
// Работа с массивом
var balls = []; // массив шаров
for (var i = 1; i < num + 1; i++) {
var b = [];
b.x0 = pDist*(0.5 + i-1); // расчетные координаты начального положения шара
b.uu = 0; // расчетное смещение шара относительно начального положения
b.xx = b.x0 + b.uu; // расчетные координаты положения шара
b.x = b.xx*scale; // экранные координаты шара
b.fx = 0; // сила, действующая на шар
b.vx = v0*(2*Math.random()-1); // скорость
balls[i] = b; // добавить элемент в конец массива
}
// здесь задается периодическая система
balls[0] = balls[num];
balls[num+1] = balls[1];
// уравновешивание суммарной скорости по оси х (чтобы частицы не улетали в сторону)
var sumVx = 0;
for (var i0 = 1; i0 < num+1; i0++) sumVx += balls[i0].vx;
var vxAverage = sumVx/num;
for (var i1 = 1; i1 < num+1; i1++) balls[i1].vx -= vxAverage;
// высота оси у на графике u(n)
var sumVx2 = 0;
for (var i2 = 1; i2 < num+1; i2++) sumVx2 += balls[i2].vx*balls[i2].vx;
var sigma2 = sumVx2 / num;
var omega2 = C/m;
var xLabel = 2*Math.sqrt(sigma2/omega2);
// график
var steps = 0; // количество шагов интегрирования
var uGraph = new TM_graph( // определить график
"#uGraph", // на html-элементе #uGraph
"n", "u", // подписи на осях
null // в данном типе графика не используется
,-xLabel, +xLabel, xLabel/4 // мин. значение оси Y, макс. значение оси Y, шаг по оси Y
);
var vGraph = new TM_graph( // определить график
"#vGraph", // на html-элементе #vGraph
"n", "v", // подписи на осях
null // в данном типе графика не используется
,-1.2*v0, 1.2*v0, 1.2*v0/4 // мин. значение оси Y, макс. значение оси Y, шаг по оси Y
);
// Основной цикл программы
function control() {
physics();
draw();
}
// Расчетная часть программы
function physics(){
for (var s=1; s<=spf; s++) {// то, что происходит каждый шаг времени
for (var i=1; i<balls.length-1; i++){
balls[i].fx = C*(balls[i+1].uu - 2*balls[i].uu + balls[i-1].uu);
balls[i].vx += balls[i].fx / m * dt;
balls[i].xx += balls[i].vx * dt;
balls[i].x = balls[i].xx * scale;
}
// присваиваем новые перемещения
for (var i2=1; i2 < balls.length-1; i2++) balls[i2].uu = balls[i2].xx - balls[i2].x0;
}
steps++;
// для графика создаем массив пар значений [x, y]
var uData = []; var vData = [];
for (var i0=1; i0<balls.length-1; i0++) uData[i0] = [i0, balls[i0].uu];
for (var i1=1; i1<balls.length-1; i1++) vData[i1] = [i1, balls[i1].vx];
if (steps % 10 == 0) uGraph.graph(uData); // подаем данные на график
if (steps % 10 == 0) vGraph.graph(vData); // подаем данные на график
}
// Рисование
var rScale13 = rScale*1.3; // ___в целях оптимизации___
var rScaleShift = rScale/5.0; // ___в целях оптимизации___
function draw(){
context.clearRect(0, 0, w*scale, h*scale); // очистить экран
for (var i = 0; i < balls.length; i++){
var b = balls[i];
// расчет градиента нужно проводить для каждого шара
var gradient=context.createRadialGradient(b.x, hC, rScale13, b.x-rScaleShift, hC+rScaleShift,0);
gradient.addColorStop(0,"#0000bb");
gradient.addColorStop(1,"#44ddff");
context.fillStyle=gradient;
context.beginPath();
context.arc(b.x, hC, r*scale,0,2*Math.PI);
context.closePath();
context.fill();
}
}
// Запуск системы
setInterval(control, 1000/fps);
}
Файл "Chain_v1_release.html"
<!DOCTYPE html>
<html>
<head>
<title>Chain</title>
<script src="Chain_v1_release.js"></script>
<script src="jquery.min.js"></script>
<script src="TM_v2.js"></script>
<script language="javascript" type="text/javascript" src="jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="jquery.flot.axislabels.js"></script>
</head>
<body>
<canvas id="canvasChain" width="800" height="100" style="border:1px solid #000000;"></canvas>
<script type="text/javascript">MainChain(document.getElementById('canvasChain'));</script>
<!--графики-->
<div style="float:left;">
<div id="uGraph" style="width:600px; height:300px; clear:both; float:left;"></div>
<div id="vGraph" style="width:600px; height:300px; clear:both; float:left;"></div>
</div>
<div style="clear:both;"></div>
</body>
</html>
</toggledisplay>