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>