Julia. DifferentialEquations.jl. Callback functions
2021-01-02
·
2 мин. для прочтения
Использование обратного вызова функций в пакете DifferentialEquations.jl.
Содержание
1 Типы обратных вызовов
ContinuousCallback(непрерывный): срабатывает, когда непрерывная функция условия достигает нуля. В других средствах реализуется как событие (event).DiscreteCallback(дискретный): срабатывает, когда функция условия истинна.VectorContinuousCallback(векторный): эквивалентен вектору непрерывных обратных вызовов. Позволяет указать, когда вызывается какой обратный вызов.
1.1 Непрерывный обратный вызов
ContinuousCallback(condition,affect!,affect_neg!;
initialize = INITIALIZE_DEFAULT,
idxs = nothing,
rootfind=true,
save_positions=(true,true),
interp_points=10,
abstol=10eps(),reltol=0)
1.2 Дискретный обратный вызов
DiscreteCallback(condition,affect!;
initialize = INITIALIZE_DEFAULT,
save_positions=(true,true))
condition- функцияcondition(u,t,integrator), определяющая, когда следует использовать обратный вызов. Обратный вызов инициируется, если условие истинно (true).affect!- функцияaffect!(integrator), которая может изменять текущее состояние интегратора.save_positions- логический кортеж для сохранения до или послеaffect!. Это сохранение может происходить непосредственно до, после события, во время события. Оно не зависит от таких параметров, какsaveat,save_everystepи т.д. (например, еслиsaveat = [1.0,2.0,3.0], то можно добавить точку сохранения в2.1, если условие верно). Чтобы прерывистые изменения обрабатывались правильно (без ошибок), необходимо установитьsave_positions = (true, true).initialize- функцияfunction(c,u,t,integrator), которая может использоваться для инициализации состояния обратного вызоваc.
1.3 Векторный непрерывный обратный вызов
VectorContinuousCallback(condition,affect!,affect_neg!,len;
initialize = INITIALIZE_DEFAULT,
idxs = nothing,
rootfind=true,
save_positions=(true,true),
interp_points=10,
abstol=10eps(),reltol=0)
VectorContinuousCallback(condition,affect!,len;
initialize = INITIALIZE_DEFAULT,
idxs = nothing,
rootfind=true,
save_positions=(true,true),
affect_neg! = affect!,
interp_points=10,
abstol=10eps(),reltol=0)
1.4 Набор обратных вызовов
- Несколько обратных вызовов можно объединить в один набор:
CallbackSet(cb1,cb2,cb3)
- Можно передать столько угодно обратных вызовов. Когда решатели обнаруживают несколько обратных вызовов, применяются следующие правила:
ContinuousCallbacksиVectorContinuousCallbacksприменяются передDiscreteCallbacks(потому, что они часто реализуют обнаружение событий, которое возвращает временной шаг на величину, меньшему, чемdt).- Для
ContinuousCallbacksиVectorContinuousCallbacksприменяется только первый из них (шаг времени рассчитывается только по первому). - Затем по порядку применяются
DiscreteCallbacks. Порядок имеет значение только для условий: если предыдущий обратный вызов изменяет функция таким образом, что следующий обратный вызов больше не считает условие истинным, он не будет применяться.
2 Применение обратных вызовов
- Обратный вызов передаётся решателю:
sol = solve(prob,alg,callback=cb)
- Когда используется обратный вызов, режим сохранения по умолчанию отключён. Это потому, что в противном случае события дважды сохраняли бы одно из значений. Чтобы снова включить стандартное поведение при сохранении, необходимо, чтобы первое значение
save_positionsбыло истинным хотя бы для одного обратного вызова. - Общая проблема обратных вызовов заключается в том, что они вызывают большие изменения шага, поэтому после такого изменения может быть разумным уменьшить
dt. Например,set_proposed_dt!используется для установки следующего шага иterminate!используется для остановки моделирования.