1 / 1 / 0
Регистрация: 18.09.2015
Сообщений: 85
1

Модель потенциала Ленарда Джонса, метод молекулярной динамики

20.09.2018, 21:58. Показов 3860. Ответов 6

Author24 — интернет-сервис помощи студентам
Прошу помочь по данному вопросу. Сам думал, но не смог ничего путного придумать(( . Есть программа, летают шарики (ну то есть атомы газа). Отталкиваются от стенок и друг от друга. Но друг от друга они отталкиваются просто как бы по закону импульса, рассчитываются векторы и т. д. Нужно заменить простое взаимодействие шариков на взаимодействие по потенциалу Ленарда-Джонса. То есть при определенном близком расстоянии они отталкиватся, при среднем притягиваются, а при очень далеком вообще не взаимодействуют. Архив полного проекта прикладываю - https://my-files.ru/3xri5i. Заранее спасибо!

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace Molecules // Имя проекта (решения) - Molecules
{
 
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        List<Atom> atoms_list = new List<Atom>(); // список (коллекция) экземпляров (атомов)
        int razmer, kolvo; // размер и кол-во атомов
        Random rand = new Random(DateTime.Now.Millisecond); //экземпляр класса Random        
 
        public class Atom  //класс описывающий отдельный атом
        {  
            public double velosity { get { return Math.Sqrt(dX * dX + dY * dY); } }
            public double X, Y; // Координаты центра атомов
            public double dX, dY; // Путь за 1 tick таймера
            private double rad, mass;
            public static double koeffColiss = 1; //Коэффициент коллизии (столкновения), 1 или -1, направление вперед или в противоположную сторону
            static Random rnd = new Random(DateTime.Now.Millisecond);
            static PictureBox Field; //поле PictireBox 
 
            public double radius
            {
                get { return rad; }
                set 
                {
                    rad = value;
                    mass = rad * rad;
                }
            }
 
            public double Mass
            {
                get { return mass; }
                set { rad = Math.Sqrt(mass = value); }
            }
 
            public double Velosity { get { return Math.Sqrt(dX * dX + dY * dY); } }
 
            public Atom(int Size, PictureBox field) //метод описывающий атом
            {
                Field = field; //задание поля, в котором рисовать
                radius = Size * 0.5; //расчет радиуса, в зависимости от размера, заданного пользователем
                dX = (rnd.NextDouble() - 0.5) * 5; // Путь за один tick таймера 
                dY = (rnd.NextDouble() - 0.5) * 5;
            }
 
 
            // Функция рисования
            public void drawBall(PaintEventArgs e)
            {
                e.Graphics.DrawEllipse(new Pen(Color.Blue), (float)(X - radius), (float)(Y - radius), 2 * (float)radius, 2 * (float)radius); //рисование круга
            }
 
            //рассчет траектории (отскакивание от стенок)
            public void beginAtom()
            { 
                if (X <= radius && dX < 0) dX *= -koeffColiss; // Если координата Х <= 10 то меняем направление движения по оси Х на противоположное
                else if (X >= Field.Width - radius && dX > 0) dX *= -koeffColiss;
                if (Y <= radius && dY < 0) dY *= -koeffColiss; // Если координата У <= 10 то меняем направление движения по оси У на противоположное
                else if (Y >= Field.Height - radius && dY > 0) dY *= -koeffColiss;
 
                X += dX;
                Y += dY;
            }
 
            public bool BallOwerlap(Atom ball1)
            {
                return (X - ball1.X) * (X - ball1.X) + (Y - ball1.Y) * (Y - ball1.Y) <=
                     (radius + ball1.radius) * (radius + ball1.radius); // условие столкновения
            }
 
            public void collisAtoms(Atom ball1) // Здесь рассчитывается взаимодействие шариков друг с другом
            {
                if (BallOwerlap(ball1))
                {
                    if ((dX - ball1.dX) * (X - ball1.X) + (dY - ball1.dY) * (Y - ball1.Y) < 0) //условие столкновения, учитывая dX
                    {
                        double dx = ball1.X - X, dy = ball1.Y - Y;
                        double alfa = Math.Atan2(dy, dx);
                        double angle = Math.Atan2(dY, dX) - alfa, angleBall = Math.Atan2(ball1.dY, ball1.dX) - alfa,
                        mod = Velosity, modBall = ball1.Velosity;
                        double DX = mod * Math.Cos(angle),
                        newDY = mod * Math.Sin(angle),
                        DX1 = modBall * Math.Cos(angleBall),
                        newDY1 = modBall * Math.Sin(angleBall);
                        double newDX = (DX * (Mass - ball1.Mass) + 2 * ball1.Mass * DX1) / (Mass + ball1.Mass),
                        newDX1 = (DX1 * (ball1.Mass - Mass) + 2 * ball1.Mass * DX) / (Mass + ball1.Mass);
                        angle = Math.Atan2(newDY, newDX) + alfa;
                        angleBall = Math.Atan2(newDY1, newDX1) + alfa;
                        mod = koeffColiss * Math.Sqrt(newDX * newDX + newDY * newDY);
                        modBall = koeffColiss * Math.Sqrt(newDX1 * newDX1 + newDY1 * newDY1);
                        dX = mod * Math.Cos(angle);
                        dY = mod * Math.Sin(angle);
                        ball1.dX = modBall * Math.Cos(angleBall);
                        ball1.dY = modBall * Math.Sin(angleBall);
                    }
 
                }
 
            }
        }
 
        private void button1_Click(object sender, EventArgs e) //функция-событие по нажатию кнопки
        {
            timer1.Enabled = true; //запуск таймера
 
            razmer = Convert.ToInt32(textBox2.Text); //преобразование строки из TextBox2 ("Размер атомов") в целое число
            kolvo = Convert.ToInt32(textBox1.Text); //преобразование строки из TextBox1 ("Кол-во атомов") в целое число
 
            atoms_list.Clear(); //очищение списка атомов во избежании добавления новых атомов при повторном нажатии кнопки
            int r = razmer / 2; 
            for (int i = 0; i < kolvo; i++) //цикл, пока не пройдет все атомы (kolvo)  
            {
                Atom a = new Atom(razmer, pictureBox1); //создание экземпляра конкретного атома класа Atom
                a.X = rand.Next(10, pictureBox1.Width - r); //Присваивание радномных координат созданным атомам
                a.Y = rand.Next(r, pictureBox1.Height - r); //Чтобы атом не создавался за пределами PictureBox, отнять r
                foreach (Atom a1 in atoms_list); 
                atoms_list.Add(a); //добавление созданных атомов в список
            }
 
        }
 
         public void timer1_Tick(object sender, EventArgs e) //функция, когда запускается таймер
        {
            foreach (Atom a in atoms_list) a.beginAtom();//для каждого атома из спиcка применяется функция beginAtom
            for (int i = 0; i < atoms_list.Count - 1; i++) 
                    for (int j = i + 1; j < atoms_list.Count; j++) if (atoms_list[i].BallOwerlap(atoms_list[j]))  
                    {
                    atoms_list[i].collisAtoms(atoms_list[j]); 
                    }
            pictureBox1.Invalidate(); //перерисовка PictureBox
        }
 
        private void paint(object sender, PaintEventArgs e)
        {
            foreach (Atom a in atoms_list) a.drawBall(e); // Само рисование //для каждого атома из спиcка применяется функция drawBall(e)
        }
 
    }
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.09.2018, 21:58
Ответы с готовыми решениями:

Потенциал Ленарда Джонса, метод молекулярной динамики
Здравствуйте! Прошу помочь по данному вопросу. Сама думала, но не смогла ничего путного придумать((...

Задача на метод молекулярной динамики
Нужна найти траекторию движения электронов в атоме лития, протон принять неподвижным. Задачу...

Метод молекулярной динамики и схема Верле
Здравствуйте, уважаемые формучане. Суть проблемы: необходимо смоделировать поведение кучки атомов...

Хаотическое поведение системы частиц молекулярной динамики (перевод с TrueBasic в C++)
Есть программа на языке True basic, она описывает хаотическое поведение системы частиц молекулярной...

6
Эксперт .NETАвтор FAQ
10409 / 5139 / 1824
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
21.09.2018, 01:55 2
Лучший ответ Сообщение было отмечено xXxBadBoyxXx как решение

Решение

Цитата Сообщение от xXxBadBoyxXx Посмотреть сообщение
взаимодействие по потенциалу Ленарда-Джонса
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
    public class LennardJonesAtom : Atom
    {
        float epsylon;
 
        public LennardJonesAtom(float radius, float epsylon) : base(radius)
        {
            this.epsylon = epsylon;
        }
 
        public override void CalcCollision(Atom other)
        {
            //calc distance between atoms
            var dist = Distance(other);
 
            if (dist > Radius * 5) //no interaction
                return;
 
            //calc force
            var k = Radius / dist;
            var f = 4 * epsylon * (float)(Math.Pow(k, 12) - Math.Pow(k, 6));//module of force (LennardJones)
 
            //to avoid infinite forces -> imitate elastic impact
            if (f > 30 || float.IsNaN(f))
            {
                base.CalcCollision(other);
                return;
            }
 
            //force vector
            var force = new PointF(X - other.X, Y - other.Y).Normalized().Mul(f);
 
            //apply force
            ApplyForce(force);
            other.ApplyForce(force.Mul(-1));
        }
    }
Модель потенциала Ленарда Джонса, метод молекулярной динамики
Вложения
Тип файла: zip Molecules.zip (736.7 Кб, 77 просмотров)
2
1 / 1 / 0
Регистрация: 18.09.2015
Сообщений: 85
21.09.2018, 09:31  [ТС] 3
Спасибо огромное! Очень благодарен! Только возникли некоторые вопросы:
1) При взаимодействии по потенциалу Л-Д, шарики входят друг в друга при столкновениях, а также вылетают за границы PictireBox с правой стороны
2) Не совсем понял назначение маленьких шариков внутри синих
0
Эксперт .NETАвтор FAQ
10409 / 5139 / 1824
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
21.09.2018, 10:18 4
Цитата Сообщение от xXxBadBoyxXx Посмотреть сообщение
При взаимодействии по потенциалу Л-Д, шарики входят друг в друга при столкновениях
В методе LennardJonesAtom.CalcCollision исправьте.
Вместо
C#
1
2
            //calc force
            var k = Radius / dist;
Нужно
C#
1
2
            //calc force
            var k = (Radius + other.Radius) / dist;
Цитата Сообщение от xXxBadBoyxXx Посмотреть сообщение
а также вылетают за границы PictireBox с правой стороны
Нет, у меня ничего не вылетает. Скорее всего у вас просто пикчербокс слишком широкий и не помещается на экране по ширине. Сделайте меньше ширину пикчербокса.
Цитата Сообщение от xXxBadBoyxXx Посмотреть сообщение
Не совсем понял назначение маленьких шариков внутри синих
Это просто блик. Что бы шарик был похож на шарик а не на блинчик.
0
1 / 1 / 0
Регистрация: 18.09.2015
Сообщений: 85
21.09.2018, 10:31  [ТС] 5
Все, разобрался, работает) Еще раз большое спасибо! Вот такой вопрос, можно ли по данной программе находить какие-либо данные макроскопической системы газа? Нам в университете сказали смоделировать потенциал Л-Д, а потом раздадут индивидуальные задания на исследование этого газа.
0
Эксперт .NETАвтор FAQ
10409 / 5139 / 1824
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
21.09.2018, 11:35 6
Цитата Сообщение от xXxBadBoyxXx Посмотреть сообщение
Вот такой вопрос, можно ли по данной программе находить какие-либо данные макроскопической системы газа? Нам в университете сказали смоделировать потенциал Л-Д, а потом раздадут индивидуальные задания на исследование этого газа.
Конечно можно, температуру например (как сумма кинетических энергий атомов).
0
0 / 0 / 0
Регистрация: 25.12.2017
Сообщений: 1
18.03.2019, 14:24 7
xXxBadBoyxXx, Приветствую, нет ли программы с нахождением макроскопических данных. Буду благодарен если отправите, тоже нужна.
0
18.03.2019, 14:24
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.03.2019, 14:24
Помогаю со студенческими работами здесь

Математическая модель кадрового потенциала региона
Здравствуйте. Нужна помощь в поиске мат модели. Тема диплома &quot;ИС управления кадровым потенциалом...

Модель динамики разгона автомобиля
Доброго времени суток. Необходима модель динамики разгона авто, т.е. некий калькулятор. Нап-р...

Метод Галёркина для модели динамики популяции
Нужна помощь в написании программы. Смысл в том, чтобы посчитать некоторую функцию u(t), исходя из...

Звук воспроизводится через наушники, а пишет, что через динамики. Динамики не работают
Добрый день. Столкнулась с такой проблемой - отсутствует звук в динамиках. Устанавливала драйвера,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru