КП: Молекула углекислого газа — различия между версиями
(→Обсуждение результатов и выводы) |
(→Решение) |
||
Строка 85: | Строка 85: | ||
− | {{#widget:Iframe|url=http://cl49743.tmweb.ru/sites/Balls_v4_release.html |width=810|height: | + | {{#widget:Iframe|url=http://cl49743.tmweb.ru/sites/Balls_v4_release.html |width=810|height:800|border=0}} |
[http://cl49743.tmweb.ru/sites/Balls_v4_release.html Вторая версия (потенциал Морзе) ] | [http://cl49743.tmweb.ru/sites/Balls_v4_release.html Вторая версия (потенциал Морзе) ] |
Версия 14:04, 3 июня 2015
А.М. Кривцов > Теоретическая механика > Курсовые проекты ТМ 2015 > Молекула метана
Курсовой проект по Теоретической механике
Исполнитель: Смирнов Александр
Группа: 09 (23604)
Семестр: весна 2015
Содержание
Аннотация проекта
Моделирование молекул, даже самых простых - сложная задача. Для их моделирования необходимо использовать многочастичные потенциалы, но их программирование - тоже очень сложная задача. Встает вопрос о том, можло ли найти более простой путь моделирования простейших молекул.
Для моделирования хорошо подходят парные потенциалы, ибо они имеют простой вид и легко программируются. Но как их применить к моделированию молекул ? Моя работа и посвещена решению данной проблемы.
Формулировка задачи
Смоделировать с помощью многочастичного потенциала молекулу углекислого газа ( 2D модель ) и рассмотреть ее простейшую динамику частицы.
Общие сведения по теме
Для решения задачи будем использовать два потенциала: потенциал Морзе и потенциал Леннард-Джонса.
Потенциал Морзе
Парный силовой потенциал взаимодействия. Определяется формулой:
где
- — энергия связи,
- — длина связи,
- — параметр, характеризующий ширину потенциальной ямы.
Потенциал имеет один безразмерный параметр
. При взаимодействия Морзе и Леннард-Джонса близки. При увеличении ширина потенциальной ямы для взаимодействия Морзе уменьшается, взаимодействие становится более жестким и хрупким. Уменьшение приводит к противоположным изменениям — потенциальная яма расширяется, жесткость падает. Сила, соответствующая потенциалу Морзе, вычисляется по формуле:Или в векторной форме:
Потенциал Леннард-Джонса
Также парный силовой потенциал взаимодействия. Определяется формулой:
где
- — расстояние между частицами,
- — энергия связи,
- — длина связи.
Сила взаимодействия, соответствующая потенциалу Леннард-Джонса, вычисляется по формуле
Векторная сила взаимодействия определяется формулой
Углекислый газ
Углекислый газ ( диоксид углерода ) - газ без запаха и цвета. Молекула углекислого газа имеет линейное строение и ковалентные полярные связи, хотя сама молекула не является полярной. Дипольный момент = 0.
Решение
Взяв за основу программу Balls v4, было получено:
- программа, в которой можно рассмотреть динамику одной молекулы углекислого газа в другом газе ( например в азоте ).
- 2 версии программы с различными потенциалами.
- создание молекулы за конечное время.
Первая версия (потенциал Морзе)
- Синий шар - кислород .
- Коралловый шар - углерод .
- Желтый шар - азот.
Вторая версия (потенциал Морзе)
- Цвет шаров аналогичный.
- Левая кнопка мыши - добавление желтой частицы.
- Правая кнопка мыши - удаление любого шара.
- В системе теперь присутствует несколько молекул.
Файл CO2.js
1 // m: Молекула углекислого газа
2 // Версия 2.0 от 01.06.15
3
4 window.addEventListener("load", MainBalls, true);
5 function MainBalls() {
6
7 // Предварительные установки
8
9 var canvas = canvasBalls;
10 var context = canvas.getContext("2d"); // на context происходит рисование
11 canvas.oncontextmenu = function (e) {return false;}; // блокировка контекстного меню
12
13 var Pi = 3.1415926; // число "пи"
14
15 var m0 = 1; // масштаб массы
16 var T0 = 1; // масштаб времени (период колебаний исходной системы)
17 var a0 = 1; // масштаб расстояния (диаметр шара)
18
19 var g0 = a0 / T0 / T0; // масштаб ускорения (ускорение, при котором за T0 будет пройдено расстояние a0)
20 var k0 = 2 * Pi / T0; // масштаб частоты
21 var C0 = m0 * k0 * k0; // масштаб жесткости
22 var B0 = 2 * m0 * k0; // масштаб вязкости
23
24 // *** Задание физических параметров ***
25
26 var Ny = 5; // число шаров, помещающихся по вертикали в окно (задает размер шара относительно размера окна)
27 var m = 1 * m0; // масса
28 var Cwall = 10 * C0; // жесткость стен
29 var B = 0.003 * B0; // вязкость среды
30 var Bwall = 0.03 * B0; // вязкость на стенках
31 var Cball = 0.1 * Cwall; // жесткость между частицами
32 var mg = 0//0.25 * m * g0; // сила тяжести
33 var r = 0.1 * a0; // радиус частицы в расчетных координатах
34 var K = 0.85; // сила взаимодействия ограничивается значением, реализующимся при r/a = K
35 var a = 5 * r; // равновесное расстояние между частицами
36 var a_1 = 2.1 * r;
37 var a_2 = 2.1 * a ;
38 var aCut = 2 * r ; // радиус обрезания
39 var alfa = 5 ;
40
41
42 // *** Задание вычислительных параметров ***
43
44 var fps = 50; // frames per second - число кадров в секунду (качечтво отображения)
45 var spf = 100; // steps per frame - число шагов интегрирования между кадрами (скорость расчета)
46 var dt = 0.045 * T0 / fps; // шаг интегрирования (качество расчета)
47
48 // Выполнение программы
49
50 var scale = canvas.height / Ny / a0 ; // масштабный коэффициент для перехода от расчетных к экранным координатам
51 var r2 = r * r ; // ___в целях оптимизации___
52 var aCut2 = aCut * aCut ; // ___в целях оптимизации___
53 var a2 = a * a ; // ___в целях оптимизации___
54 var a22 = a_2 * a_2 ;
55 var a11 = a_1 * a_1 ;
56 var D = a2 * Cball / 72 ; // энергия связи между частицами
57 var LJCoeff = 12 * D / a2 ; // коэффициент для расчета потенциала Л-Дж
58 var a1 = alfa / a ;
59 var MorzCoeff = 2 * a1 * D ;
60
61 var Ka = K * r ; // ___в целях оптимизации___
62 var K2a2 = Ka*Ka ; // ___в целях оптимизации___
63
64 var w = canvas.width / scale ; // ширина окна в расчетных координатах
65 var h = canvas.height / scale ; // высота окна в расчетных координатах
66
67
68
69
70
71 var dNd = null ; // ссылка на захваченный курсором шар (drag & drop)
72
73 // Работа с мышью
74
75 var mx_, my_; // буфер позиции мыши (для расчета скорости при отпускании шара)
76
77 canvas.onmousedown = function(e) { // функция при нажатии клавиши мыши
78 var m = mouseCoords(e); // получаем расчетные координаты курсора мыши
79 // цикл в обратную сторону, чтобы захватывать шар, нарисованный "сверху"
80 // (т.к. цикл рисования идет в обычном порядке)
81 for (var i = balls.length - 1; i >= 0; i--) {
82 var b = balls[i];
83 var rx = b.x - m.x;
84 var ry = b.y - m.y;
85 var rLen2 = rx * rx + ry * ry; // квадрат расстояния между курсором и центром шара
86 if (rLen2 <= r2) { // курсор нажал на шар
87 if (e.which == 1) { // нажата левая клавиша мыши
88 dNd = b;
89 dNd.xPlus = dNd.x - m.x; // сдвиг курсора относительно центра шара по x
90 dNd.yPlus = dNd.y - m.y; // сдвиг курсора относительно центра шара по y
91 mx_ = m.x; my_ = m.y;
92 canvas.onmousemove = mouseMove; // пока клавиша нажата - работает функция перемещения
93 } else if (e.which == 3) { // нажата правая клавиша мыши
94 balls.splice(i, 1); // удалить шар
95 }
96 return;
97 }
98 }
99 for (var i = C.length - 1; i >= 0; i--) {
100 var b = C[i];
101 var rx = b.x - m.x;
102 var ry = b.y - m.y;
103 var rLen2 = rx * rx + ry * ry; // квадрат расстояния между курсором и центром шара
104 if (rLen2 <= r2) { // курсор нажал на шар
105 if (e.which == 1) { // нажата левая клавиша мыши
106 dNd = b;
107 dNd.xPlus = dNd.x - m.x; // сдвиг курсора относительно центра шара по x
108 dNd.yPlus = dNd.y - m.y; // сдвиг курсора относительно центра шара по y
109 mx_ = m.x; my_ = m.y;
110 canvas.onmousemove = mouseMove; // пока клавиша нажата - работает функция перемещения
111 } else if (e.which == 3) { // нажата правая клавиша мыши
112 C.splice(i, 1); // удалить шар
113 }
114 return;
115 }
116 }
117 for (var i = O1.length - 1; i >= 0; i--) {
118 var b = O1[i];
119 var rx = b.x - m.x;
120 var ry = b.y - m.y;
121 var rLen2 = rx * rx + ry * ry; // квадрат расстояния между курсором и центром шара
122 if (rLen2 <= r2) { // курсор нажал на шар
123 if (e.which == 1) { // нажата левая клавиша мыши
124 dNd = b;
125 dNd.xPlus = dNd.x - m.x; // сдвиг курсора относительно центра шара по x
126 dNd.yPlus = dNd.y - m.y; // сдвиг курсора относительно центра шара по y
127 mx_ = m.x; my_ = m.y;
128 canvas.onmousemove = mouseMove; // пока клавиша нажата - работает функция перемещения
129 } else if (e.which == 3) { // нажата правая клавиша мыши
130 O1.splice(i, 1); // удалить шар
131 }
132 return;
133 }
134 }
135 for (var i = O2.length - 1; i >= 0; i--) {
136 var b = O2[i];
137 var rx = b.x - m.x;
138 var ry = b.y - m.y;
139 var rLen2 = rx * rx + ry * ry; // квадрат расстояния между курсором и центром шара
140 if (rLen2 <= r2) { // курсор нажал на шар
141 if (e.which == 1) { // нажата левая клавиша мыши
142 dNd = b;
143 dNd.xPlus = dNd.x - m.x; // сдвиг курсора относительно центра шара по x
144 dNd.yPlus = dNd.y - m.y; // сдвиг курсора относительно центра шара по y
145 mx_ = m.x; my_ = m.y;
146 canvas.onmousemove = mouseMove; // пока клавиша нажата - работает функция перемещения
147 } else if (e.which == 3) { // нажата правая клавиша мыши
148 O2.splice(i, 1); // удалить шар
149 }
150 return;
151 }
152 }
153
154 // если не вышли по return из цикла - нажатие было вне шара, добавляем новый
155 if (e.which == 1) {
156 dNd = addNewBall(m.x, m.y); // добавляем шар и сразу захватываем его курсором
157 if (dNd == null) return; // если шар не добавился (из за стен или других шаров) - возвращаемся
158 dNd.xPlus = 0; dNd.yPlus = 0; // держим шар по центру
159 mx_ = m.x; my_ = m.y;
160 canvas.onmousemove = mouseMove; // пока клавиша нажата - работает функция перемещения
161 }
162
163
164 };
165
166 document.onmouseup = function(e) { // функция при отпускании клавиши мыши
167 canvas.onmousemove = null; // когда клавиша отпущена - функции перемещения нету
168 dNd = null; // когда клавиша отпущена - захваченного курсором шара нету
169 };
170
171 function mouseMove(e) { // функция при перемещении мыши, работает только с зажатой ЛКМ
172 var m = mouseCoords(e); // получаем расчетные координаты курсора мыши
173 dNd.x = m.x + dNd.xPlus;
174 dNd.y = m.y + dNd.yPlus;
175 dNd.vx = 0.6 * (m.x - mx_) / dt / fps; dNd.vy = 0.6 * (m.y - my_) / dt / fps;
176 mx_ = m.x; my_ = m.y;
177 }
178
179 function mouseCoords(e) { // функция возвращает расчетные координаты курсора мыши
180 var m = [];
181 var rect = canvas.getBoundingClientRect();
182 m.x = (e.clientX - rect.left) / scale;
183 m.y = (e.clientY - rect.top) / scale;
184 return m;
185 }
186
187 // Работа с массивом
188
189 var balls = []; // массив шаров
190 var C =[] ;
191 var O1 = [] ;
192 var O2 = [] ;
193
194 var addNewBall = function(x, y) {
195 // проверка - не пересекается ли новый шар со стенами или уже существующими шарами
196 if (x - r < 0 || x + r > w || y - r < 0 || y + r > h) return null;
197 for (var i = 0; i < balls.length; i++) {
198 var rx = balls[i].x - x;
199 var ry = balls[i].y - y;
200 var rLen2 = rx * rx + ry * ry;
201 if (rLen2 < 4 * r2) return null;
202 }
203 var b = [];
204
205 b.x = x; b.y = y; // расчетные координаты шара
206 b.fx = 0; b.fy = mg; // сила, действующая на шар
207 b.vx = 0; b.vy = 0; // скорость
208
209 balls[balls.length] = b; // добавить элемент в конец массива
210
211 return b;
212 };
213
214 var addNewC = function(x, y) {
215 // проверка - не пересекается ли новый шар со стенами или уже существующими шарами
216 if (x - r < 0 || x + r > w || y - r < 0 || y + r > h) return null;
217 for (var i = 0; i < balls.length; i++) {
218 var rx = balls[i].x - x;
219 var ry = balls[i].y - y;
220 var rLen2 = rx * rx + ry * ry;
221 if (rLen2 < 4 * r2) return null;
222 }
223 var b = [];
224
225 b.x = x; b.y = y; // расчетные координаты шара
226 b.fx = 0; b.fy = mg; // сила, действующая на шар
227 b.vx = 0; b.vy = 0; // скорость
228
229 C[C.length] = b; // добавить элемент в конец массива
230
231 return b;
232 };
233
234 var addNewO1 = function(x, y) {
235 // проверка - не пересекается ли новый шар со стенами или уже существующими шарами
236 if (x - r < 0 || x + r > w || y - r < 0 || y + r > h) return null;
237 for (var i = 0; i < balls.length; i++) {
238 var rx = balls[i].x - x;
239 var ry = balls[i].y - y;
240 var rLen2 = rx * rx + ry * ry;
241 if (rLen2 < 4 * r2) return null;
242 }
243 var b = [];
244
245 b.x = x; b.y = y; // расчетные координаты шара
246 b.fx = 0; b.fy = mg; // сила, действующая на шар
247 b.vx = 0; b.vy = 0; // скорость
248
249 O1[O1.length] = b; // добавить элемент в конец массива
250
251 return b;
252 };
253
254 var addNewO2 = function(x, y) {
255 // проверка - не пересекается ли новый шар со стенами или уже существующими шарами
256 if (x - r < 0 || x + r > w || y - r < 0 || y + r > h) return null;
257 for (var i = 0; i < balls.length; i++) {
258 var rx = balls[i].x - x;
259 var ry = balls[i].y - y;
260 var rLen2 = rx * rx + ry * ry;
261 if (rLen2 < 4 * r2) return null;
262 }
263 var b = [];
264
265 b.x = x; b.y = y; // расчетные координаты шара
266 b.fx = 0; b.fy = mg; // сила, действующая на шар
267 b.vx = 0; b.vy = 0; // скорость
268
269 O2[O2.length] = b; // добавить элемент в конец массива
270
271 return b;
272 };
273
274 // Основной цикл программы
275
276 function control() {
277 physics();
278 draw();
279 }
280
281 // Расчетная часть программы
282
283 function powers(b ,b2 , hkk , jk ) {
284 var rx = b.x - b2.x; var ry = b.y - b2.y; // вектор смотрит на первый шар (b)
285 var r2 = rx * rx + ry * ry; // квадрат расстояния между шарами
286
287 var rLen = (Math.sqrt(r2));
288
289 if (r2 < K2a2) {
290 if (rLen > 0.00001) { // проверка, чтобы избежать деления на 0
291 rx = rx / rLen * Ka;
292 ry = ry / rLen * Ka;
293 }
294 r2 = K2a2;
295 rLen = Ka; // корень K2a2
296 }
297
298 // сила взаимодействия
299
300 var u = Math.exp( -a1 * ( rLen - hkk )) ;
301 var F = jk * MorzCoeff * u* ( u - 1 ) /rLen ;
302
303 var Fx = F * rx; var Fy = F * ry;
304 b.fx += Fx; b.fy += Fy;
305 b2.fx -= Fx; b2.fy -= Fy;
306 }
307
308
309 function physics() { // то, что происходит каждый шаг времени
310 for (var s = 1; s <= spf; s++) {
311
312 // пересчет сил идет отдельным массивом, т.к. далее будут добавляться силы взаимодействия между шарами
313
314 for (var i0 = 0; i0 < balls.length; i0++) {
315 balls[i0].fx = - B * balls[i0].vx;
316 balls[i0].fy = mg - B * balls[i0].vy;
317 }
318 for (var i0 = 0; i0 < C.length; i0++) {
319 C[i0].fx = - B * C[i0].vx;
320 C[i0].fy = mg - B * C[i0].vy;
321 }
322 for (var i0 = 0; i0 < O1.length; i0++) {
323 O1[i0].fx = - B * O1[i0].vx;
324 O1[i0].fy = mg - B * O1[i0].vy;
325 }
326 for (var i0 = 0; i0 < O2.length; i0++) {
327 O2[i0].fx = - B * O2[i0].vx;
328 O2[i0].fy = mg - B * O2[i0].vy;
329 }
330
331
332 for (var i = 0; i < balls.length; i++) { // dlya Balls
333 // расчет взаимодействия производится со всеми следующими шарами в массиве,
334 // чтобы не считать каждое взаимодействие дважды
335
336 var b = balls[i];
337
338 for (var j = i + 1; j < balls.length; j++) {
339 var b2 = balls[j];
340 var rx = b.x - b2.x; var ry = b.y - b2.y; // вектор смотрит на первый шар (b)
341 var r2 = rx * rx + ry * ry; // квадрат расстояния между шарами
342
343 if ( r2 > aCut2 ) continue ;
344
345 powers(b,b2,a_1,0.3) ;
346
347 }
348 for (var j = 0; j < C.length; j++) {
349 var b2 = C[j];
350 var rx = b.x - b2.x; var ry = b.y - b2.y; // вектор смотрит на первый шар (b)
351 var r2 = rx * rx + ry * ry; // квадрат расстояния между шарами
352
353 if ( r2 > aCut2 ) continue ;
354
355 powers(b,b2,a_1,0.3) ;
356
357 }
358 for (var j = 0; j < O1.length; j++) {
359 var b2 = O1[j];
360 var rx = b.x - b2.x; var ry = b.y - b2.y; // вектор смотрит на первый шар (b)
361 var r2 = rx * rx + ry * ry; // квадрат расстояния между шарами
362
363 if ( r2 > aCut2 ) continue ;
364
365 powers(b,b2,a_1,0.3) ;
366
367 }
368
369 for (var j = 0; j < O2.length; j++) {
370 var b2 = O2[j];
371 var rx = b.x - b2.x; var ry = b.y - b2.y; // вектор смотрит на первый шар (b)
372 var r2 = rx * rx + ry * ry; // квадрат расстояния между шарами
373
374 if ( r2 > aCut2 ) continue ;
375
376 powers( b, b2, a_1 ,0.3) ;
377
378 }
379
380 if (b == dNd) continue; // если шар схвачен курсором - его вз. со стенами и перемещение не считаем
381
382 if (b.y + r > h) { b.fy += -Cwall * (b.y + r - h) - Bwall * b.vy; }
383 if (b.y - r < 0) { b.fy += -Cwall * (b.y - r) - Bwall * b.vy;}
384 if (b.x + r > w) { b.fx += -Cwall * (b.x + r - w) - Bwall * b.vx; }
385 if (b.x - r < 0) { b.fx += -Cwall * (b.x - r) - Bwall * b.vx; }
386
387 b.vx += b.fx / m * dt; b.vy += b.fy / m * dt;
388 b.x += b.vx * dt; b.y += b.vy * dt;
389
390 }
391
392 for (var i = 0; i < C.length; i++) { // dlya C
393 // расчет взаимодействия производится со всеми следующими шарами в массиве,
394 // чтобы не считать каждое взаимодействие дважды
395
396 var b = C[i];
397
398 for (var j = i + 1; j < C.length; j++) {
399 var b2 = C[j];
400 var rx = b.x - b2.x; var ry = b.y - b2.y; // вектор смотрит на первый шар (b)
401 var r2 = rx * rx + ry * ry; // квадрат расстояния между шарами
402
403 if ( r2 > aCut2 ) continue ;
404
405 powers(b,b2,a_1, 0.3) ;
406
407 }
408 for (var j = 0; j < O1.length; j++) {
409 var b2 = O1[j];
410 var rx = b.x - b2.x; var ry = b.y - b2.y; // вектор смотрит на первый шар (b)
411 var r2 = rx * rx + ry * ry; // квадрат расстояния между шарами
412
413 if ( j == i ) { powers(b,b2,a, 6) ;}
414 else {
415 if ( r2 > aCut2 ) continue ;
416 powers(b,b2,a_1, 0.3) ;
417 }
418
419 }
420
421 for (var j = 0; j < O2.length; j++) {
422 var b2 = O2[j];
423 var rx = b.x - b2.x; var ry = b.y - b2.y; // вектор смотрит на первый шар (b)
424 var r2 = rx * rx + ry * ry; // квадрат расстояния между шарами
425
426 if ( j == i ) { powers(b,b2,a,6) ;}
427 else {
428 if ( r2 > aCut2 ) continue ;
429 powers(b,b2,a_1, 0.3) ;
430 }
431
432 }
433
434 if (b == dNd) continue; // если шар схвачен курсором - его вз. со стенами и перемещение не считаем
435
436 if (b.y + r > h) { b.fy += -Cwall * (b.y + r - h) - Bwall * b.vy; }
437 if (b.y - r < 0) { b.fy += -Cwall * (b.y - r) - Bwall * b.vy;}
438 if (b.x + r > w) { b.fx += -Cwall * (b.x + r - w) - Bwall * b.vx; }
439 if (b.x - r < 0) { b.fx += -Cwall * (b.x - r) - Bwall * b.vx; }
440
441 b.vx += b.fx / m * dt; b.vy += b.fy / m * dt;
442 b.x += b.vx * dt; b.y += b.vy * dt;
443
444 }
445
446 for (var i = 0; i < C.length; i++) { // dlya O1
447 // расчет взаимодействия производится со всеми следующими шарами в массиве,
448 // чтобы не считать каждое взаимодействие дважды
449
450 var b = O1[i];
451
452 for (var j = i + 1; j < O1.length; j++) {
453
454 var b2 = O1[j];
455 var rx = b.x - b2.x; var ry = b.y - b2.y; // вектор смотрит на первый шар (b)
456 var r2 = rx * rx + ry * ry; // квадрат расстояния между шарами
457
458 if ( r2 > aCut2 ) continue ;
459
460 powers(b,b2,a_1,0.3) ;
461
462 }
463
464 for (var j = 0; j < O2.length; j++) {
465 var b2 = O2[j];
466 var rx = b.x - b2.x; var ry = b.y - b2.y; // вектор смотрит на первый шар (b)
467 var r2 = rx * rx + ry * ry; // квадрат расстояния между шарами
468
469 if ( i == j ) { powers(b,b2,a_2, 3) ;}
470 else {
471 if ( r2 > aCut2 ) continue ;
472 else powers(b,b2,a_1 , 0.3) ;
473 }
474
475 }
476
477 if (b == dNd) continue; // если шар схвачен курсором - его вз. со стенами и перемещение не считаем
478
479 if (b.y + r > h) { b.fy += -Cwall * (b.y + r - h) - Bwall * b.vy; }
480 if (b.y - r < 0) { b.fy += -Cwall * (b.y - r) - Bwall * b.vy;}
481 if (b.x + r > w) { b.fx += -Cwall * (b.x + r - w) - Bwall * b.vx; }
482 if (b.x - r < 0) { b.fx += -Cwall * (b.x - r) - Bwall * b.vx; }
483
484 b.vx += b.fx / m * dt; b.vy += b.fy / m * dt;
485 b.x += b.vx * dt; b.y += b.vy * dt;
486
487 }
488
489 for (var i = 0; i < C.length; i++) { // dlya O2
490 // расчет взаимодействия производится со всеми следующими шарами в массиве,
491 // чтобы не считать каждое взаимодействие дважды
492
493 var b = O2[i];
494
495 for (var j = i + 1; j < O2.length; j++) {
496 var b2 = O2[j];
497 var rx = b.x - b2.x; var ry = b.y - b2.y; // вектор смотрит на первый шар (b)
498 var r2 = rx * rx + ry * ry; // квадрат расстояния между шарами
499
500 if ( r2 > aCut2) continue ;
501
502 powers(b,b2,a_1, 0.3) ;
503
504 }
505
506 if (b == dNd) continue; // если шар схвачен курсором - его вз. со стенами и перемещение не считаем
507
508 if (b.y + r > h) { b.fy += -Cwall * (b.y + r - h) - Bwall * b.vy; }
509 if (b.y - r < 0) { b.fy += -Cwall * (b.y - r) - Bwall * b.vy;}
510 if (b.x + r > w) { b.fx += -Cwall * (b.x + r - w) - Bwall * b.vx; }
511 if (b.x - r < 0) { b.fx += -Cwall * (b.x - r) - Bwall * b.vx; }
512
513 b.vx += b.fx / m * dt; b.vy += b.fy / m * dt;
514 b.x += b.vx * dt; b.y += b.vy * dt;
515
516 }
517 }
518 }
519
520 // Рисование
521
522 var rScale13 = r * scale * 1.3; // ___в целях оптимизации___
523 var rScaleShift = r * scale / 5; // ___в целях оптимизации___
524 function draw() {
525 context.clearRect(0, 0, w * scale, h * scale); // очистить экран
526 for (var i = 0; i < balls.length; i++){
527 var xS = balls[i].x * scale; var yS = balls[i].y * scale;
528
529 context.fillStyle = "#FFD700";
530
531 context.beginPath();
532 context.arc(xS, yS, r * scale, 0, 2 * Math.PI, false);
533 context.closePath();
534 context.fill();
535 }
536
537 for (var i = 0; i < C.length; i++){
538 var xS = C[i].x * scale; var yS = C[i].y * scale;
539
540 context.fillStyle = "#f08080";
541
542 context.beginPath();
543 context.arc(xS, yS, r * scale, 0, 2 * Math.PI, false);
544 context.closePath();
545 context.fill();
546 }
547 for (var i = 0; i < O1.length; i++){
548 var xS = O1[i].x * scale; var yS = O1[i].y * scale;
549
550 context.fillStyle = "#3070d0";
551
552 context.beginPath();
553 context.arc(xS, yS, r * scale, 0, 2 * Math.PI, false);
554 context.closePath();
555 context.fill();
556 }
557 for (var i = 0; i < O2.length; i++){
558 var xS = O2[i].x * scale; var yS = O2[i].y * scale;
559
560 context.fillStyle = "#3070d0";
561
562 context.beginPath();
563 context.arc(xS, yS, r * scale, 0, 2 * Math.PI, false);
564 context.closePath();
565 context.fill();
566 }
567 }
568
569 // Запуск системы
570 for (var i = 0; i < 8; i++){ // добавляем 20 частиц, сдвинув их от стен
571 //addNewBall(Math.random() * (w - 2 * r) + r, Math.random() * (h - 2 * r) + r , 10 );
572 addNewC(Math.random() * (w - 2 * r) + r, Math.random() * (h - 2 * r) + r , 10 );
573 addNewO1(Math.random() * (w - 2 * r) + r, Math.random() * (h - 2 * r) + r , 10 );
574 addNewO2(Math.random() * (w - 2 * r) + r, Math.random() * (h - 2 * r) + r , 10 );
575
576 }
577 setInterval(control, 1000 / fps);
578 }
Обсуждение результатов и выводы
Была написана программа, моделирующая молекулы углекислого газа. Можно смоделировать молекулу с помощью парных потенциалов. Данная модель имеет свои оссобенности:
- За конечное время при небольшой вязкости среды частицы собираются в молекулы углекислого газа.
- При моделировании молекул СО2 только с помощью парных потенциалов молекула получается неустойчивой.
- Ее поведение в системе при небольших скоростях получается достаточно правдоподобной. Это означает что можно изучать динамику системы при малых скоростях частиц.
- При больших скоростях молекулы углекислого газа разрушаются. После разрушения они собираются заного, образуя те же самые молекулы.
В будущем планируется ввести степени насыщенности связи и начать смоделировать более сложные молекулы.
Скачать презентацию: Молекула углекислого газа в среде инертного газа