Как сохранить импульс при численном интегрировании пути заряженной частицы через магнитное поле

У меня есть скрипт Python, прикрепленный ниже, который предназначен для отслеживания траектории заряженной частицы в статическом однородном магнитном поле. Очень просто вычислить мгновенную силу, действующую на частицу (это просто произведение ее скорости на магнитное поле B), но, к сожалению, моя сверхпростая попытка численного интегрирования эффектов этой силы не сохраняет импульс. .

Я понимаю, почему это не так. Если я представлю, что при t=0 вектор скорости равен [1,0,0] (при B=[0,0,1]), то приложенная мгновенная сила будет примерно такой: F_mag = [0,a,0 ], но численное интегрирование применяет эту силу в течение более чем бесконечно малого периода, и поэтому на следующем временном шаге скорость будет [1,a,0], где a — некоторое ненулевое значение, которое явно имеет большую величину, чем [ 1,0,0]. С каждым шагом импульс будет увеличиваться на коэффициент, пропорциональный скорости. Импульс не сохраняется --- экспоненциальный взрыв (см. изображение ниже)!

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

Есть ли прямой способ рассчитать силу, приложенную магнитным полем, таким образом, чтобы сохранить импульс? Я могу уменьшить размер шага, но импульс все равно будет расти экспоненциально — не идеально! Я также мог бы просто переключиться на Рунге-Кутту, а не на простое интегрирование по Эйлеру, но я подумал, что здесь может быть возможность сделать что-то более умное! Заранее спасибо за любые ваши предложения!

from pylab import * 

DT = 0.1 
N_ITS = int(100.0/DT)

pos    = array([0.0,0.0,0.0],'f')
vel    = array([1.0,0.0,0.0],'f') 
mass   = 1.0 
charge = 1.0

# uniform magnetic field
B = array([0.0,0.0,1.0])

# track momentum for plotting
mom_h = []
# track position for plotting
pos_h = []

for _ in xrange(N_ITS) :
    ## total momentum
    mom = linalg.norm(vel)
    mom_h.append(mom)
    pos_h.append(array(pos))

    ### fixed magnetic field
    F_mag = array(-cross(vel,B))

    ### apply force
    vel += DT*F_mag/mass

    ### update position
    pos += vel*DT

figure(figsize=(6,10))
subplot2grid((2,1),(0,0)) 
title('position') 
pos_h = array(pos_h)    
plot(pos_h[:,0],pos_h[:,1])

subplot2grid((2,1),(1,0))
title('momentum') 
plot(mom_h)

show()

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

Будет ли вычислительная наука лучшим местом для ответа на этот вопрос?
@Qmechanic Учитывая роль сохранения импульса в этом вопросе, он может быть здесь по теме. Я смотрю на этот мета-вопрос и думаю, что он очень близок к границе между темой и не по теме, но он не совсем соответствует ни одному из критериев, которые мы определили как не по теме. (Я ходил туда-сюда по этому решению на протяжении многих лет.)
Я удалил некоторые комментарии, которые отвечали на вопрос.
@DavidZ Эм... почему? Это очень раздражает. Я видел некоторую полезную информацию, размещенную здесь в ответ на мой вопрос, но теперь я больше не могу получить доступ к этой информации? Кому выгодно удалять эти комментарии?
@weemattisnot Это помогает сайту оставаться чистым. Эти люди должны были публиковать ответы, а не комментарии, и они по-прежнему могут это делать.
Я думаю, что удаление комментариев, которые отвечают на вопросы, приносит больше вреда, чем пользы. Конечно, было бы лучше поощрять авторов вместо этого давать ответы и удалять свои собственные комментарии после того, как они это сделали?
Между прочим, когда вы делаете график положение-положение, обычно лучше всего использовать «равное» соотношение сторон, чтобы расстояния в разных направлениях были одинаковыми.

Ответы (1)

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