Я создал простую одномерную модель частиц с двумя телами на C++. В модели частица 1 начинается с позиции (0,0), а частица 2 начинается с позиции (1,0). Частицы ускоряются навстречу друг другу со скоростью, пропорциональной расстоянию между ними.
Код мне кажется нормальным, но результаты выглядят очень просто и совершенно нефизически. Я подозреваю, что проблема может быть связана с предпринятыми шагами дискретного времени. Я попытался сделать скорость ускорения пропорциональной расстоянию ^ 2, и результаты не выглядят более реалистичными.
Вот код и результаты:
Вышеприведенный график представляет собой позицию по сравнению с. График времени.
Как я могу изменить код, чтобы получить более разумные результаты?
В подобных ситуациях рекомендуется настроить временной шаг на основе градиента силы, потому что вся концепция численного интегрирования заключается в том, что «вещи не меняются слишком сильно с этого момента до следующего временного шага», и это предположение нарушается, когда вы быстро перемещаетесь по области с быстро меняющейся силой.
У этого есть рискованный побочный эффект: если вы сделаете временной шаг «достаточно малым», чтобы справиться с быстрым изменением, а изменение станет «бесконечно быстрым», ваш алгоритм может «застрять» — вы можете столкнуться с парадоксом Ксено: Ахиллес и черепаха.
Чтобы избежать застревания, некоторые численные интегрирования (например, Рунге-Кутта) лучше учитывают кривизну более высокого порядка, позволяя делать больший шаг без потери точности.
Однако в вашем случае ускорение для всего следующего временного шага определяется текущим положением, поэтому, если ваши частицы оказываются близко друг к другу в начале шага, они отбрасываются далеко, и поскольку их сила притяжения будет затем значительно уменьшится, им будет трудно вернуться.
Несколько критических замечаний по вашему коду:
particle1[4]
, но используете только два компонентаdt
Что касается первого пункта, я бы использовал a struct
для своих частиц:
typedef struct{
double x;
double v;
} PARTICLE;
а затем вы можете получить доступ к их свойствам с помощью
PARTICLE p1, p2;
p1.v = 0.;
p1.x = 0.;
p2.v = 0.;
p2.x = 1.;
Что сразу более читабельно... Если вы хотите работать в двух измерениях, вы можете либо написать их явно как часть вашего struct
:( double x; double y; double vx; double vy;
), либо сделать их массивами.
Но на самом деле переменные шаги по времени и интерполяции более высокого порядка помогут обеспечить стабильность вашего решения.
Вы получаете частицы, которые находятся на расстоянии 0 друг от друга и, следовательно, имеют бесконечное ускорение. Компьютер не может решить эту проблему, поэтому он взрывается в зависимости от того, насколько шаг приближается к нулю.
Я не уверен, каким будет «физическое» поведение, учитывая, что точечные массы с нулевым расстоянием трудно изучать. Но если вы добавите координату Y и присвоите ей начальную скорость, вы можете получить лучшие результаты (в основном вытянутый эллипс вместо колеблющейся линии).
Вы можете сделать начальную скорость по оси y очень маленькой, чтобы приблизиться к движению по оси X. Или, может быть, просто добавить небольшое смещение к вашему дивизиону.
Джаред
Джаред
Джаред
Кеншин
Джаред
Кеншин
Джаред
Qмеханик
Джаред
Флорис
Дэвид Хаммен
ДжамалС
Кайл Канос
Кайл Канос
using namespace std
.