2010-11-19 3 views
0

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

time = np.linspace(0, 5, 1000) 

def sm(x, t): 
    return np.array([x[1], eta*Ez0(x[0])]) 

traj = odeint(sm,[0,1.], time) 

Это работает отлично, но я хотел бы, чтобы остановить расчет, как только х [0] < 0. на данный момент я просто блокировать эволюцию: системном

def sm1(x, t): 
    if x[0] < 0: 
     return np.array([0, 0]) 
    else: 
     return np.array([x[1], eta*Ez0(x[0])]) 

traj = odeint(sm1,[0,1.],time) 

но я Гесс есть лучшие решения. Я нашел this, но мне кажется, что он исправляет количество шагов, что вызывает сожаление. Любое предложение оценено.

+0

Ваше решение кажется мне разумным. Как вы думаете, что с этим не так? –

+0

вы получите предупреждение: lsoda-- при текущих t (= r1), mxstep (= i1) шаги, предпринятые по этому вызову, до достижения tout В приведенном выше сообщении I1 = 500 В приведенном выше сообщении R1 = 0,4223349048304E + 00 Избыточная работа над этим вызовом (возможно, неправильный тип Dfun). Запуск с full_output = 1 для получения количественной информации. – Mermoz

ответ

1

Если вы пишете пользовательское расширение функции odeint, вы можете заставить свою функцию поднять конкретное исключение, когда оно будет закончено. Выполнение этого в Python может сделать его существенно медленнее, но я думаю, что вы пишете то же самое в C или Cython. Обратите внимание, что я не тестировал следующее.

class ThatsEnoughOfThat(Exception): 
    pass 

def custom_odeint(func, y0, t): # + whatever parameters you need 
    for timestep in t: 
     try: 
      # Do stuff. Call odeint/other scipy functions? 
     except ThatsEnoughOfThat: 
      break 
    return completedstuff 

def sm2(x, t): 
    if x[0] < 0: 
     raise ThatsEnoughOfThat 
    return np.array([x[1], eta*Ez0(x[0])]) 
Смежные вопросы