Chain v2
Материал из Department of Theoretical and Applied Mechanics
Виртуальная лаборатория > Динамика одномерного кристалла > Цепь - версии > Chain v2
Скачать программу: Chain_v2_release.zip
Текст программы на языке JavaScript (разработчик Цветков Денис):
Файл "Chain_v2_release.js"
1 function MainChain(canvas) {
2
3 // Предварительные установки
4
5 var context = canvas.getContext("2d"); // на context происходит рисование
6 document.oncontextmenu=function(e){return false}; // блокировка контекстного меню
7
8 var Pi = 3.1415926; // число "пи"
9
10 var m0 = 1; // масштаб массы
11 var T0 = 1; // масштаб времени (период колебаний исходной системы)
12 var a0 = 1; // масштаб расстояния (диаметр шара)
13
14 var k0 = 2 * Pi / T0; // масштаб частоты
15 var C0 = m0 * k0 * k0; // масштаб жесткости
16
17 // *** Задание физических параметров ***
18
19 var Ny = 5; // Число шаров, помещающихся по вертикали в окно (задает размер шара относительно размера окна)
20 var scale = canvas.height / Ny / a0; // масштабный коэффициент для перехода от расчетных к экранным координатам
21 var m = 1 * m0; // масса
22 var C = 1 * C0; // жесткость
23 var num = 24; // начальное количество частиц
24
25 // *** Задание вычислительных параметров ***
26
27 var fps = 50; // frames per second - число кадров в секунду (качечтво отображения)
28 var spf = 100; // steps per frame - число шагов интегрирования между кадрами (скорость расчета)
29 var dt = 0.045 * T0 / fps; // шаг интегрирования (качество расчета)
30
31 // Выполнение программы
32
33 var w = canvas.width / scale; // ширина окна в расчетных координатах
34 var h = canvas.height / scale; // высота окна в расчетных координатах
35
36 // Генерорование начальных условий
37
38 var balls; // массив шаров
39 var uGraph; var vGraph; // переменные графиков
40 var r, rScale, pDist, hC, steps; // описание дано далее
41 var rScale13, rScaleShift; // ___в целях оптимизации___
42 MainChain.prototype.setNum = function(n){num = n}; // задать новое количество частиц
43 MainChain.prototype.newSystem = function(conf){
44 MainChain.prototype.actualConf = conf;
45 r = a0*10/num; // радиус частицы в расчетных координатах
46 rScale = r * scale; // радиус частицы в экранных координатах
47 pDist = w/num; // расстояние между шарами (в начальном положении)
48 hC = h/2 * scale; // высота цепи
49 rScale13 = rScale*1.3; // ___в целях оптимизации___
50 rScaleShift = rScale/5.0; // ___в целях оптимизации___
51 steps = 0; // количество шагов интегрирования
52
53 balls = [];
54 for (var i = 1; i < num + 1; i++) {
55 var b = [];
56
57 b.x0 = pDist*(0.5 + i-1); // расчетные координаты начального положения шара
58 b.fx = 0; // сила, действующая на шар
59 b.vx = 0; // скорость
60 b.uu = 0; // расчетное смещение шара относительно начального положения
61
62 conf(b, i); // конфигурации начальных условий заданы ниже
63
64 b.xx = b.x0 + b.uu; // расчетные координаты положения шара
65 b.x = b.xx*scale; // экранные координаты шара
66
67 balls[i] = b; // добавить элемент в конец массива
68 }
69
70 // здесь задается периодическая система
71 balls[0] = balls[num];
72 balls[num+1] = balls[1];
73
74 // уравновешивание суммарной скорости по оси х (чтобы частицы не улетали в сторону)
75 var sumVx = 0;
76 for (var i0 = 1; i0 < num+1; i0++) sumVx += balls[i0].vx;
77 var vxAverage = sumVx/num;
78 for (var i1 = 1; i1 < num+1; i1++) balls[i1].vx -= vxAverage;
79
80 // высота оси у на графике u(n)
81 var sumVx2 = 0;
82 for (var i2 = 1; i2 < num+1; i2++) sumVx2 += balls[i2].vx*balls[i2].vx;
83 var sigma2 = sumVx2 / num;
84 var omega2 = C/m;
85 var yLabel = 2*Math.sqrt(sigma2/omega2) *(num/8); // в конце - коэффициент
86
87 uGraph = new TM_graph( // определить график
88 "#uGraph", // на html-элементе #uGraph
89 "n", "u", // подписи на осях
90 null // в данном типе графика не используется
91 ,-yLabel, +yLabel, yLabel/4 // мин. значение оси Y, макс. значение оси Y, шаг по оси Y
92 );
93
94 vGraph = new TM_graph( // определить график
95 "#vGraph", // на html-элементе #vGraph
96 "n", "v", // подписи на осях
97 null // в данном типе графика не используется
98 ,-1.2, 1.2, 1.2/4 // мин. значение оси Y, макс. значение оси Y, шаг по оси Y
99 );
100 };
101
102 // настройки для конфигураций
103 var v0 = 1*a0/T0; // conf_random - начальный разброс скоростей
104 var sinNum = 2; // conf_sin - количество периодов синуса в цепи
105 var hillDiv = 1/4; // conf_hill - часть (доля) цепи, которую занимает "холм"
106
107 // конфигурации
108 MainChain.prototype.conf_random = function(b){b.vx = v0*(2*Math.random()-1);};
109 MainChain.prototype.conf_sin = function(b, i){b.vx = Math.sin(2*Pi * i/num*sinNum);};
110 MainChain.prototype.conf_one = function(b, i){if (i == Math.ceil(num/2)) b.vx = 0.5; else b.vx = 0;};
111 MainChain.prototype.conf_stair2 = function(b, i){if (i%4 == 0 || (i-1)%4 == 0) b.vx = 1; else b.vx = 0;};
112 MainChain.prototype.conf_stair3 = function(b, i){if (i%6 == 0 || (i-1)%6 == 0 || (i-2)%6 == 0) b.vx = 1; else b.vx = 0;};
113 MainChain.prototype.conf_hill = function(b, i){
114 var nd2 = num*hillDiv/2;
115 if (i <= nd2*2) b.vx = (nd2*nd2 - (i-nd2)*(i-nd2))/(nd2*nd2);
116 else b.vx = 0;
117 };
118
119 // Основной цикл программы
120
121 function control() {
122 physics();
123 draw();
124 }
125
126 // Расчетная часть программы
127
128 function physics(){
129 for (var s=1; s<=spf; s++) {// то, что происходит каждый шаг времени
130 for (var i=1; i<balls.length-1; i++){
131 balls[i].fx = C*(balls[i+1].uu - 2*balls[i].uu + balls[i-1].uu);
132 balls[i].vx += balls[i].fx / m * dt;
133 balls[i].xx += balls[i].vx * dt;
134
135 balls[i].x = balls[i].xx * scale;
136 }
137 // присваиваем новые перемещения
138 for (var i2=1; i2 < balls.length-1; i2++) balls[i2].uu = balls[i2].xx - balls[i2].x0;
139 }
140 steps++;
141
142 // для графика создаем массив пар значений [x, y]
143 var uData = []; var vData = [];
144 for (var i0=1; i0<balls.length-1; i0++) uData[i0] = [i0, balls[i0].uu];
145 for (var i1=1; i1<balls.length-1; i1++) vData[i1] = [i1, balls[i1].vx];
146
147 if (steps % 4 == 0) uGraph.graph(uData); // подаем данные на график
148 if (steps % 4 == 0) vGraph.graph(vData); // подаем данные на график
149 }
150
151 // Рисование
152
153 function draw(){
154 context.clearRect(0, 0, w*scale, h*scale); // очистить экран
155 for (var i = 0; i < balls.length; i++){
156 var b = balls[i];
157
158 // расчет градиента нужно проводить для каждого шара
159 var gradient=context.createRadialGradient(b.x, hC, rScale13, b.x-rScaleShift, hC+rScaleShift,0);
160 gradient.addColorStop(0,"#0000bb");
161 gradient.addColorStop(1,"#44ddff");
162 context.fillStyle=gradient;
163
164 context.beginPath();
165 context.arc(b.x, hC, r*scale,0,2*Math.PI);
166 context.closePath();
167 context.fill();
168 }
169 }
170
171 // Запуск системы
172
173 MainChain.prototype.newSystem(MainChain.prototype.conf_hill);
174 setInterval(control, 1000/fps);
175 }
Файл "Chain_v2_release.html"
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>Chain</title>
5 <script src="Chain_v2_release.js"></script>
6
7 <script src="jquery.min.js"></script>
8 <script src="TM_v2.js"></script>
9 <script language="javascript" type="text/javascript" src="jquery.flot.js"></script>
10 <script language="javascript" type="text/javascript" src="jquery.flot.axislabels.js"></script>
11 </head>
12 <body>
13 <canvas id="canvasChain" width="800" height="100" style="border:1px solid #000000;"></canvas>
14 <script type="text/javascript">var app = new MainChain(document.getElementById('canvasChain'));</script>
15
16 <!--графики-->
17 <div style="float:left;">
18 <div id="uGraph" style="width:600px; height:300px; clear:both; float:left;"></div>
19 <div id="vGraph" style="width:600px; height:300px; clear:both; float:left;"></div>
20 </div>
21 <div>
22 Конфигурации (наведите на кнопку,<br>чтобы увидеть описание):<br>
23 <input type="button" title="Случайная скорость у каждой частички" style="width: 130px" name="" onclick="app.newSystem(app.conf_random);return false;" value="Random"/><br>
24 <input type="button" title="Начальная скорость частиц задается с помощью функции синуса" style="width: 130px" name="" onclick="app.newSystem(app.conf_sin);return false;" value="Sin"/><br>
25 <input type="button" title="Скорость равна 0 у всех частичек, кроме одной" style="width: 130px" name="" onclick="app.newSystem(app.conf_one);return false;" value="One particle shift"/><br>
26 <input type="button" title="Начальная скорость частиц задается ступеньками - две частички движутся, две не движутся" style="width: 130px" name="" onclick="app.newSystem(app.conf_stair2);return false;" value="Stairs (2 particles)"/><br>
27 <input type="button" title="Начальная скорость частиц задается ступеньками - три частички движутся, три не движутся" style="width: 130px" name="" onclick="app.newSystem(app.conf_stair3);return false;" value="Stairs (3 particles)"/><br>
28 <input type="button" title="Начальная скорость частиц задается холмом, холм занимает 1/4 часть цепи" style="width: 130px" name="" onclick="app.newSystem(app.conf_hill);return false;" value="Hill"/><br>
29 <br><br>
30 Количество частиц:<br>
31 <input type="button" style="width: 30px" name="" onclick="app.setNum(12); app.newSystem(app.actualConf);return false;" value="12"/>
32 <input type="button" style="width: 30px" name="" onclick="app.setNum(24); app.newSystem(app.actualConf);return false;" value="24"/>
33 <input type="button" style="width: 30px" name="" onclick="app.setNum(48); app.newSystem(app.actualConf);return false;" value="48"/>
34 <input type="button" style="width: 30px" name="" onclick="app.setNum(96); app.newSystem(app.actualConf);return false;" value="96"/>
35 </div>
36 <div style="clear:both;"></div>
37 </body>
38 </html>