Chain
Материал из Department of Theoretical and Applied Mechanics
Department of TM > "Thermo Crystal" Project > The dynamics of one-dimensional crystal
Virtual laboratory > The dynamics of one-dimensional crystal
Virtual laboratory > The dynamics of one-dimensional crystal
Here is the latest version of the program, which simulates the dynamics of one-dimensional crystal.
Download program: Chain_v3_release.zip
The text of the program is written in JavaScript (the developer is Цветков Денис):
Файл "Chain_v3_release.js"
1 function MainChain(canvas, vCanvas) {
2
3 // Предварительные установки
4
5 var context = canvas.getContext("2d"); // на context происходит рисование
6 var vContext = vCanvas.getContext("2d");// на context происходит рисование
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 m = 1 * m0; // масса
20 var C = 1 * C0; // жесткость
21 var numStart = 24; // начальное количество частиц
22
23 // *** Задание вычислительных параметров ***
24
25 var fps = 50; // frames per second - число кадров в секунду (качечтво отображения)
26 var spf = 10; // steps per frame - число шагов интегрирования между кадрами (скорость расчета)
27 var dt = 0.4 * T0 / fps; // шаг интегрирования (качество расчета)
28
29 // Выполнение программы
30
31 var scale = canvas.height / a0; // масштабный коэффициент для перехода от расчетных к экранным координатам
32 var wScale = canvas.width; // ширина окна в экранных координатах
33 var hScale = canvas.height; // высота окна в экранных координатах
34 var w = wScale / scale; // ширина окна в расчетных координатах
35 var h = hScale / scale; // высота окна в расчетных координатах
36 var chainHeightScale = hScale/2; // высота положения цепи в экранных координатах
37
38 // константы для графика скорости
39 var vWScale = vCanvas.width; // ширина окна в экранных координатах
40 var vHScale = vCanvas.height; // высота окна в экранных координатах
41 var vHeightScale = vHScale/2; // высота графика скорости в экранных координатах
42 var vAxisScale = vHScale * 0.4; // масштаб оси "y" графика скорости
43 var uvWResize = vWScale/wScale; // пересчет ширины относительно основного окна
44
45 // Генерорование начальных условий
46
47 var particles; // массив частиц
48 var num, pDist; // количество частиц и расстояние между шарами (в начальном положении)
49 MainChain.prototype.setNum = function(n){num = n; pDist = w/(num-1);}; // задать новое количество частиц
50 MainChain.prototype.setNum(numStart);
51 var uAxisScale; // масштаб оси "y" цепи
52 MainChain.prototype.newSystem = function(conf){
53 MainChain.prototype.actualConf = conf;
54 particles = [];
55 for (var i = 1; i < num + 1; i++) {
56 var b = [];
57
58 b.x0 = pDist*(i-1); // расчетные координаты начального положения частицы
59 b.x0Scale = b.x0*scale; // экранные координаты начального положения частицы
60 b.fu = 0; b.vu = 0; b.uu = 0; // сила; скорость; смещение отн. нач. положения
61
62 conf(b, i); // конфигурации начальных условий заданы ниже
63 particles[i] = b; // добавить элемент в массив
64 }
65
66 // здесь задается периодическая система
67 particles[0] = particles[num];
68 particles[num+1] = particles[1];
69
70 // уравновешивание суммарной скорости по оси х (чтобы частицы не улетали в сторону)
71 var sumvu = 0;
72 for (var i0 = 1; i0 < num+1; i0++) sumvu += particles[i0].vu;
73 var vuAverage = sumvu/num;
74 for (var i1 = 1; i1 < num+1; i1++) particles[i1].vu -= vuAverage;
75
76 // настройка оси "y"
77 var confCoeff = 1;
78 if (conf == MainChain.prototype.conf_random) confCoeff = Math.sqrt(num)/6;
79 if (conf == MainChain.prototype.conf_one || conf == MainChain.prototype.conf_stair2) confCoeff = num/5;
80 if (conf == MainChain.prototype.conf_stair3) confCoeff = num/10;
81 uAxisScale = hScale/(num/35) * confCoeff;
82 };
83
84 // настройки для конфигураций
85 var v0 = 1*a0/T0; // conf_random - начальный разброс скоростей
86 var sinNum = 2; // conf_sin - количество периодов синуса в цепи
87 var hillDiv = 1/4; // conf_hill - часть (доля) цепи, которую занимает "холм"
88
89 // конфигурации
90 MainChain.prototype.conf_random = function(b){b.vu = v0*(2*Math.random()-1);};
91 MainChain.prototype.conf_sin = function(b, i){b.vu = Math.sin(2*Pi * i/num*sinNum);};
92 MainChain.prototype.conf_one = function(b, i){if (i == Math.ceil(num/2)) b.vu = 0.5; else b.vu = 0;};
93 MainChain.prototype.conf_stair2 = function(b, i){if (i%4 == 0 || (i-1)%4 == 0) b.vu = 1; else b.vu = 0;};
94 MainChain.prototype.conf_stair3 = function(b, i){if (i%6 == 0 || (i-1)%6 == 0 || (i-2)%6 == 0) b.vu = 1; else b.vu = 0;};
95 MainChain.prototype.conf_hill = function(b, i){
96 var nd2 = hillDiv *num/2; // количество частиц, у которых изменится начальная скорость / 2 (половина параболы)
97 if (i > num/2-nd2 && i < num/2+nd2) b.vu = (1 - (i-num/2)*(i-num/2)/(nd2*nd2)); // парабола
98 else b.vu = 0;
99 };
100
101 // Основной цикл программы
102
103 function control() {
104 physics();
105 draw();
106 }
107
108 // Расчетная часть программы
109
110 function physics(){
111 for (var s=1; s<=spf; s++) {// то, что происходит каждый шаг времени
112 for (var i=1; i<particles.length-1; i++) {
113 particles[i].fu = C*(particles[i+1].uu - 2*particles[i].uu + particles[i-1].uu);
114 particles[i].vu += particles[i].fu / m * dt;
115 }
116 // присваиваем новые перемещения
117 for (var i2=1; i2 < particles.length-1; i2++ ) particles[i2].uu += particles[i2].vu * dt;
118 }
119 }
120
121 // Рисование
122
123 function draw(){
124 function clearAndPrepairCtx(ctx, wS, hS, lineHeight){ // очистить экран и нарисовать линию посередине
125 ctx.clearRect(0, 0, wS, hS); // очистить экран
126 ctx.strokeStyle = 'gray';
127 ctx.beginPath();
128 ctx.moveTo(0, lineHeight);
129 ctx.lineTo(wS, lineHeight);
130 ctx.stroke();
131 ctx.strokeStyle = 'black';
132 }
133
134 // цепь
135 clearAndPrepairCtx(context, wScale, hScale, chainHeightScale);
136 context.beginPath();
137 context.moveTo(particles[1].x0Scale, chainHeightScale + particles[1].uu*uAxisScale);
138 for (var i = 2; i < particles.length-1; i++)
139 context.lineTo(particles[i].x0Scale, chainHeightScale + particles[i].uu*uAxisScale);
140 context.stroke();
141
142 // график скорости
143 clearAndPrepairCtx(vContext, vWScale, vHScale, vHeightScale);
144 vContext.beginPath();
145 vContext.moveTo(particles[1].x0Scale * uvWResize, vHeightScale + particles[1].vu*vAxisScale);
146 for (var i0 = 2; i0 < particles.length-1; i0++)
147 vContext.lineTo(particles[i0].x0Scale * uvWResize, vHeightScale + particles[i0].vu*vAxisScale);
148 vContext.stroke();
149 }
150
151 // Запуск системы
152
153 MainChain.prototype.newSystem(MainChain.prototype.conf_hill);
154 setInterval(control, 1000/fps);
155 }
Файл "Chain_v2_release.html"
<!DOCTYPE html>
<html>
<head>
<title>Chain</title>
<script src="Chain_v3_release.js"></script>
</head>
<body>
<table>
<tr>
<td>u</td>
<td><canvas id="canvasChain" width="800" height="200" style="border:1px solid #000000;"></canvas></td>
<td rowspan="4" style="width:200px" valign="top">
Configurations<br>(guide the cursor at the button,<br>for seeing description):<br>
<input type="button" title="Случайная скорость у каждой частички" style="width: 150px" name="" onclick="app.newSystem(app.conf_random);return false;" value="Random"/><br>
<input type="button" title="Начальная скорость частиц задается с помощью функции синуса" style="width: 150px" name="" onclick="app.newSystem(app.conf_sin);return false;" value="Sin"/><br>
<input type="button" title="Скорость равна 0 у всех частичек, кроме одной" style="width: 150px" name="" onclick="app.newSystem(app.conf_one);return false;" value="Impulse"/><br>
<input type="button" title="Начальная скорость частиц задается ступеньками - две частички движутся, две не движутся" style="width: 150px" name="" onclick="app.newSystem(app.conf_stair2);return false;" value="Stairs (2 particles)"/><br>
<input type="button" title="Начальная скорость частиц задается ступеньками - три частички движутся, три не движутся" style="width: 150px" name="" onclick="app.newSystem(app.conf_stair3);return false;" value="Stairs (3 particles)"/><br>
<input type="button" title="Начальная скорость частиц задается холмом, холм занимает 1/4 часть цепи" style="width: 150px" name="" onclick="app.newSystem(app.conf_hill);return false;" value="Hill"/><br>
<br><br>
<div style="width:150px">
Количество частиц:<br>
<input type="button" style="width: 40px" name="" onclick="app.setNum(12); app.newSystem(app.actualConf);return false;" value="12"/>
<input type="button" style="width: 40px" name="" onclick="app.setNum(24); app.newSystem(app.actualConf);return false;" value="24"/>
<input type="button" style="width: 40px" name="" onclick="app.setNum(48); app.newSystem(app.actualConf);return false;" value="48"/>
<input type="button" style="width: 40px" name="" onclick="app.setNum(96); app.newSystem(app.actualConf);return false;" value="96"/>
<input type="button" style="width: 40px" name="" onclick="app.setNum(300); app.newSystem(app.actualConf);return false;" value="300"/>
<input type="button" style="width: 40px" name="" onclick="app.setNum(600); app.newSystem(app.actualConf);return false;" value="600"/>
<input type="button" style="width: 40px" name="" onclick="app.setNum(1200); app.newSystem(app.actualConf);return false;" value="1200"/>
<input type="button" style="width: 40px" name="" onclick="app.setNum(2400); app.newSystem(app.actualConf);return false;" value="2400"/>
<input type="button" style="width: 40px" name="" onclick="app.setNum(4800); app.newSystem(app.actualConf);return false;" value="4800"/>
</div>
</td>
</tr><tr>
<td></td>
<td align="center">x</td>
</tr ><tr>
<td style="padding:30px 0 0 0;">v</td>
<td style="padding:30px 0 0 0;"><canvas id="canvasChainV" width="800" height="100" style="border:1px solid #000000;"></canvas></td>
</tr><tr>
<td></td>
<td align="center">x</td>
</tr>
</table>
<script type="text/javascript">var app = new MainChain(document.getElementById('canvasChain'), document.getElementById('canvasChainV'));</script>
</body>
</html>
Here you can find the previous versions of the program.
The proposed directions of the stand development
- Implement the ability to set a directed impulse.
- Add control of speed simulation management (for example, the slider).
- Research a variety of forces of interaction (linear, square, cubic, their variations and potential).