КП: Молекула углекислого газа — различия между версиями

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
(Аннотация проекта)
 
(не показано 12 промежуточных версий 4 участников)
Строка 1: Строка 1:
[[А.М. Кривцов]] > [[Теоретическая механика: физико-механический факультет|Теоретическая механика]] > [[Курсовые проекты ТМ 2015]] > '''Молекула метана''' <HR>
+
[[А.М. Кривцов]] > [[Теоретическая механика: физико-механический факультет|Теоретическая механика]] > [[Курсовые проекты ТМ 2015]] > '''Молекула углекислого газа''' <HR>
  
  
Строка 11: Строка 11:
  
 
== Аннотация проекта ==
 
== Аннотация проекта ==
Моделирование молекул, даже самых простых - сложная задача. Для их моделирования необходимо использовать многочастичные потенциалы, но их программирование  - тоже очень сложная задача. Встает вопрос о том, можло ли найти более простой путь моделирования простейших молекул.
+
Моделирование молекул, даже самых простых - сложная задача. Для их моделирования необходимо использовать многочастичные потенциалы, но их программирование  - тоже очень сложная задача. Встает вопрос о том, можно ли найти более простой путь моделирования простейших молекул.
  
Для моделирования хорошо подходят парные потенциалы, ибо они имеют простой вид и легко программируются. Но как их применить к моделированию молекул ? Моя работа и посвещена решению данной проблемы.
+
Для моделирования хорошо подходят парные потенциалы, ибо они имеют простой вид и легко программируются. Но как их применить к моделированию молекул ? Моя работа и посвящена решению данной проблемы.
  
 
== Формулировка задачи ==
 
== Формулировка задачи ==
Смоделировать с помощью многочастичного потенциала молекулу углекислого газа ( 2D модель ) и рассмотреть ее простейшую динамику частицы.
+
Смоделировать с помощью многочастичного потенциала молекулу углекислого газа ( 2D модель ) и рассмотреть ее простейшую динамику молекулы.
  
 
== Общие сведения по теме ==
 
== Общие сведения по теме ==
Строка 85: Строка 85:
  
  
{{#widget:Iframe|url=http://cl49743.tmweb.ru/sites/Balls_v4_release.html |width=810|height:600|border=0}}
+
{{#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 Вторая версия (потенциал Морзе) ]
Строка 682: Строка 682:
  
 
== Обсуждение результатов и выводы ==
 
== Обсуждение результатов и выводы ==
Можно смоделировать  молекулу с помощью парных потенциалов. За конечное время при небольшой вязкости среды частицы собираются в молекулы. При моделировании частиц только с помощью парных потенциалов молекула получается очень неустойчивой. Но ее поведение в системе при небольших скоростях получается достаточно правдаподобной. Это означает что можно изучать динамику системы при малых скоростях частиц. При больших скоростях частицы разрушаются. После разрушения они собираются заного, образуя те же самые частицы.
+
Разработан алгоритм,  с помощью которого можно смоделировать  молекулу углекислого газа при помощи парных потенциалов. Данная модель имеет свои особенности:
 +
*За конечное время при небольшой вязкости среды частицы собираются в молекулы углекислого газа.  
 +
* Поведение молекулы углекислого газа в системе при небольших скоростях получается реалистичным. Это означает, что можно изучать динамику системы при малых скоростях молекул.  
 +
*При больших скоростях молекулы углекислого газа разрушаются. После разрушения они собираются заново, образуя те же самые молекулы.
 +
 
 +
В будущем планируется  ввести степени насыщенности связи и начать моделировать более сложные молекулы.
 
<br>
 
<br>
 
Скачать презентацию: Молекула углекислого газа в среде инертного газа [[File:CO2engine.pdf]]
 
Скачать презентацию: Молекула углекислого газа в среде инертного газа [[File:CO2engine.pdf]]
 +
<br>
 +
Скачать отчет:[[ File: SmirnovKurs.docx]]
  
 
== Ссылки по теме ==
 
== Ссылки по теме ==

Текущая версия на 23:05, 10 января 2017

А.М. Кривцов > Теоретическая механика > Курсовые проекты ТМ 2015 > Молекула углекислого газа


Курсовой проект по Теоретической механике

Исполнитель: Смирнов Александр

Группа: 09 (23604)

Семестр: весна 2015

Аннотация проекта[править]

Моделирование молекул, даже самых простых - сложная задача. Для их моделирования необходимо использовать многочастичные потенциалы, но их программирование - тоже очень сложная задача. Встает вопрос о том, можно ли найти более простой путь моделирования простейших молекул.

Для моделирования хорошо подходят парные потенциалы, ибо они имеют простой вид и легко программируются. Но как их применить к моделированию молекул ? Моя работа и посвящена решению данной проблемы.

Формулировка задачи[править]

Смоделировать с помощью многочастичного потенциала молекулу углекислого газа ( 2D модель ) и рассмотреть ее простейшую динамику молекулы.

Общие сведения по теме[править]

Для решения задачи будем использовать два потенциала: потенциал Морзе и потенциал Леннард-Джонса.

Потенциал Морзе [править]

Парный силовой потенциал взаимодействия. Определяется формулой:

[math] \varPi(r) = D\left[e^{-2\alpha(r-a)}-2e^{-\alpha(r-a)}\right], [/math]

где

  • [math]D[/math] — энергия связи,
  • [math]a[/math] — длина связи,
  • [math]\alpha[/math] — параметр, характеризующий ширину потенциальной ямы.

Потенциал имеет один безразмерный параметр [math]\alpha a [/math]. При [math]\alpha a = 6[/math] взаимодействия Морзе и Леннард-Джонса близки. При увеличении [math]\alpha a [/math] ширина потенциальной ямы для взаимодействия Морзе уменьшается, взаимодействие становится более жестким и хрупким. Уменьшение [math]\alpha a [/math] приводит к противоположным изменениям — потенциальная яма расширяется, жесткость падает. Сила, соответствующая потенциалу Морзе, вычисляется по формуле:

[math] F(r) = -\varPi'(r) = 2\alpha D\left[e^{-2\alpha(r-a)}-e^{-\alpha(r-a)}\right]. [/math]

Или в векторной форме:

[math] {\bf F}({\bf r})= -\nabla\varPi(r) = 2\alpha D\left[e^{-2\alpha(r-a)}-e^{-\alpha(r-a)}\right]\frac{{\bf r}}{r} [/math]
Потенциал Леннард-Джонса[править]

Также парный силовой потенциал взаимодействия. Определяется формулой:

[math] \varPi(r) = D\left[\left(\frac{a}{r}\right)^{12}-2\left(\frac{a}{r}\right)^{6}\right], [/math]

где

  • [math]r[/math] — расстояние между частицами,
  • [math]D[/math] — энергия связи,
  • [math]a[/math] — длина связи.

Сила взаимодействия, соответствующая потенциалу Леннард-Джонса, вычисляется по формуле

[math] F(r) = \frac{12D}{a}\left[\left(\frac{a}{r}\right)^{13} - \left(\frac{a}{r}\right)^{7}\right]. [/math]

Векторная сила взаимодействия определяется формулой

[math] {\bf F}({\bf r})= -\nabla\varPi(r) = \frac{12D}{a^2}\left[\left(\frac{a}{r}\right)^{14}-\left(\frac{a}{r}\right)^{8}\right]{\bf r} [/math]
Углекислый газ [править]

Углекислый газ ( диоксид углерода ) - газ без запаха и цвета. Молекула углекислого газа имеет линейное строение и ковалентные полярные связи, хотя сама молекула не является полярной. Дипольный момент = 0.

Решение[править]

Взяв за основу программу Balls v4, было получено:

  • программа, в которой можно рассмотреть динамику одной молекулы углекислого газа в другом газе ( например в азоте ).
  • 2 версии программы с различными потенциалами.
  • создание молекулы за конечное время.

Первая версия (потенциал Морзе)

  • Синий шар - кислород .
  • Коралловый шар - углерод .
  • Желтый шар - азот.


Вторая версия (потенциал Морзе)

  • Цвет шаров аналогичный.
  • Левая кнопка мыши - добавление желтой частицы.
  • Правая кнопка мыши - удаление любого шара.
  • В системе теперь присутствует несколько молекул.


Текст программы на языке JavaScript:

Файл 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 }

Обсуждение результатов и выводы[править]

Разработан алгоритм, с помощью которого можно смоделировать молекулу углекислого газа при помощи парных потенциалов. Данная модель имеет свои особенности:

  • За конечное время при небольшой вязкости среды частицы собираются в молекулы углекислого газа.
  • Поведение молекулы углекислого газа в системе при небольших скоростях получается реалистичным. Это означает, что можно изучать динамику системы при малых скоростях молекул.
  • При больших скоростях молекулы углекислого газа разрушаются. После разрушения они собираются заново, образуя те же самые молекулы.

В будущем планируется ввести степени насыщенности связи и начать моделировать более сложные молекулы.
Скачать презентацию: Молекула углекислого газа в среде инертного газа CO2engine.pdf
Скачать отчет:Файл:SmirnovKurs.docx

Ссылки по теме[править]

См. также[править]