Почему моя модель с двумя телами не работает? [закрыто]

Я создал простую одномерную модель частиц с двумя телами на C++. В модели частица 1 начинается с позиции (0,0), а частица 2 начинается с позиции (1,0). Частицы ускоряются навстречу друг другу со скоростью, пропорциональной расстоянию между ними.

Код мне кажется нормальным, но результаты выглядят очень просто и совершенно нефизически. Я подозреваю, что проблема может быть связана с предпринятыми шагами дискретного времени. Я попытался сделать скорость ускорения пропорциональной расстоянию ^ 2, и результаты не выглядят более реалистичными.

Вот код и результаты:

введите описание изображения здесь

введите описание изображения здесь

Вышеприведенный график представляет собой позицию по сравнению с. График времени.

Как я могу изменить код, чтобы получить более разумные результаты?

Я думаю, вы должны добавить в свой вопрос, что вы ожидаете . Для меня это звучит как «ускоренные навстречу друг другу со скоростью, пропорциональной расстоянию между ними» означает, что это должен быть гармонический осциллятор. Это верно??
Я бы также предложил прокомментировать ваш код...
Но в коде у вас ускорение пропорционально 1 г (особенно посмотрите на ваше определение dv1dt).
@ Джаред, гравитация пропорциональна 1/d^2, но гравитация ведет себя как гармонический осциллятор. Я думаю, что 1/d тоже должен. Тем не менее, 1/d^2 также дает такие же странные результаты.
Гравитация (в частности, ньютоновская гравитация, как кажется, вы делаете) не является гармоническим осциллятором.
@ Джаред, да, технически нет, но движение колебательное с максимальной амплитудой. Мой график ясно показывает, что амплитуда увеличивается (и уменьшается) повсюду. Гармонические колебания или нет, результаты не соответствуют коду.
Стоит отметить, что гравитация, определяемая уравнением Пуассона , приводит к нестабильным орбитам в 1D или 2D (она приводит к устойчивым решениям в 3D... и я думаю, что другие... но я слишком далеко захожу в свою классическую механику). класс, чтобы действительно дать хороший комментарий здесь).
Будет ли вычислительная наука лучшим местом для ответа на этот вопрос?
@Qmechanic Я не знаю. Я не знаком с этим форумом, но я определенно не думаю, что он подходит для StackOverflow или форума по компьютерным наукам. Я по-прежнему придерживаюсь мнения, что для полученных результатов есть веская причина (это не связано с хаосом или вычислениями).
@Qmechanic - я согласен с Джаредом: речь идет о численных методах физики. Хотя численное интегрирование — это то, что изучают нефизики, методы, необходимые для решения этой проблемы, должны представлять интерес для этого сообщества. Принятый в настоящее время ответ не отвечает на вопрос...
Я собирался быть неприятным и написать неприятный вики-ответ сообщества. Вместо этого я просто буду злым в комментарии и скажу, что этот код ужасен.
Вы не должны вручную открывать и закрывать файл; используйте RAII.
Я голосую за то, чтобы закрыть этот вопрос как не по теме, потому что он касается отладки программы, а не физики. Возможно, вычислительная наука лучше подходит для этой программы.

Ответы (2)

В подобных ситуациях рекомендуется настроить временной шаг на основе градиента силы, потому что вся концепция численного интегрирования заключается в том, что «вещи не меняются слишком сильно с этого момента до следующего временного шага», и это предположение нарушается, когда вы быстро перемещаетесь по области с быстро меняющейся силой.

У этого есть рискованный побочный эффект: если вы сделаете временной шаг «достаточно малым», чтобы справиться с быстрым изменением, а изменение станет «бесконечно быстрым», ваш алгоритм может «застрять» — вы можете столкнуться с парадоксом Ксено: Ахиллес и черепаха.

Чтобы избежать застревания, некоторые численные интегрирования (например, Рунге-Кутта) лучше учитывают кривизну более высокого порядка, позволяя делать больший шаг без потери точности.

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

Несколько критических замечаний по вашему коду:

  1. Вы определяете particle1[4], но используете только два компонента
  2. Вы жестко кодируете временной шаг вместо использования такой переменной, какdt
  3. Вы используете самый простой метод интеграции... узнайте о других
  4. Вы неявно определяете массу = 1 и постоянную силы = 1; рассмотрите возможность создания этих переменных (даже если вы установите для них значение 1)

Что касается первого пункта, я бы использовал 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;), либо сделать их массивами.

Но на самом деле переменные шаги по времени и интерполяции более высокого порядка помогут обеспечить стабильность вашего решения.

Спасибо, вы попали в точку, что не так с программой. Спасибо за ваши советы, я только начинаю заниматься численными методами.
Написать хорошо работающий симулятор сложно. Но награды потрясающие, когда вы узнаете все, что нужно знать. Вы находитесь на первом шаге, и этот ответ проведет вас через шаги 2, 3 и 4. Чем больше вы будете над этим работать, тем больше нюансов вы устраните, пройдя шаги 5...12. На данный момент вы получили докторскую степень.

Вы получаете частицы, которые находятся на расстоянии 0 друг от друга и, следовательно, имеют бесконечное ускорение. Компьютер не может решить эту проблему, поэтому он взрывается в зависимости от того, насколько шаг приближается к нулю.

Я не уверен, каким будет «физическое» поведение, учитывая, что точечные массы с нулевым расстоянием трудно изучать. Но если вы добавите координату Y и присвоите ей начальную скорость, вы можете получить лучшие результаты (в основном вытянутый эллипс вместо колеблющейся линии).

Вы можете сделать начальную скорость по оси y очень маленькой, чтобы приблизиться к движению по оси X. Или, может быть, просто добавить небольшое смещение к вашему дивизиону.

Это не теория хаоса, если это компьютерная аномалия.
Если вам нужна «теория хаоса», то вы можете посмотреть мою следующую анимацию , где это образует «луну». Каждая составная сфера состоит из случайным образом распределенных шаров, и иногда получается луна, а иногда нет (я случайно записал один из моментов, когда формировалась луна, что, с моей точной настройкой, составляет примерно 1 из 10). бежит).
Пот-а-к, пот-а-к. В любом случае термин теория хаоса не имеет четкого определения. Но я имею в виду, что крошечные изменения в начальных условиях вызывают большие изменения в выходе.
Нет, термин хаос определен очень четко. Это означает, что при одних и тех же начальных условиях небольшие вариации приводят к совершенно разным результатам.
Например, если ОП меняет свой временной шаг, колебания резко меняются? ;-)
Я просто шучу. Вы правы, конечно. Но дело в том, что расчет плохо определен из-за ошибки деления на ноль, которая должна произойти, если временной шаг был правильным.
Что ж, кое с чем мы согласны... Вы никогда не должны позволять точечным частицам, под действием какой-либо силы, сталкиваться на "близком к нулю" расстоянии.
Это не "теория хаоса". Задача двух тел не хаотична. Это просто плохая математика.
Задача двух тел не хаотична, но вы должны поддерживать положительное расстояние между ними.
Проблема не хаотическая, но подход к решению ... другими словами, используя фиксированный временной шаг, ОП превратил нехаотическую проблему в хаотическую (а именно, чувствительную к небольшим отклонениям на входе). «Давайте отменим все это».