Часть трудностей в решении некоторых систем ОДУ заключается в определении подходящего времени для остановки решения. Окончательное время в интервале интегрирования может быть определено определенным событием, а не числом. Примером может служить яблоко, падающее с дерева. Решатель ОДУ должен остановиться, когда яблоко ударится о землю, но вы можете не знать, когда это событие произойдет заранее. Точно так же некоторые проблемы связаны с событиями, которые не прекращают решение. Примером является луна, вращающаяся вокруг планеты. В этом случае вы можете не захотеть остановить интегрирование раньше, но вы все еще хотите обнаруживать каждый раз, когда луна завершает один период вокруг большого тела.
Используйте функции событий, чтобы обнаружить, когда определенные события происходят во время решения ОДУ. Функции события берут выражение, которое вы задаете, и обнаруживают событие, когда это выражение равно нулю. Они также могут сигнализировать решателю ОДУ остановить интегрирование, когда они обнаруживают событие.
Используйте 'Events'
опция odeset
функция для задания функции события. Функция события должна иметь общую форму
[value,isterminal,direction] = myEventsFcn(t,y)
В случае ode15i
функция события должна также принять третий входной параметр для yp
.
Выходные аргументы value
, isterminal
, и direction
являются векторами, чьи i
th-й элемент соответствует i
е-е событие:
value(i)
является математическим выражением, описывающим i
то событие. Событие происходит, когда value(i)
равно нулю.
isterminal(i) = 1
если интегрирование должна завершиться, когда i
Происходит событие th. В противном случае это 0
.
direction(i) = 0
если все нули должны быть расположены (значение по умолчанию). Значение +1
находит только нули, где функция события увеличивается, и -1
находит только нули, где функция события уменьшается. Задайте direction = []
использовать значение по умолчанию 0
для всех событий.
Снова рассмотрим случай падения яблока с дерева. ОДУ, которая представляет падающее тело,
с начальными условиями и . Можно использовать функцию события, чтобы определить, когда , что когда яблоко ударяется о землю. Для этой задачи функция события, которая обнаруживает, когда яблоко ударяется о землю,
function [position,isterminal,direction] = appleEventsFcn(t,y) position = y(1); % The value that we want to be zero isterminal = 1; % Halt integration direction = 0; % The zero can be approached from either direction
Если вы задаете функцию событий, то вызывайте решатель ОДУ с тремя дополнительными выходными аргументами, как
[t,y,te,ye,ie] = odeXY(odefun,tspan,y0,options)
Три дополнительных выхода, возвращенных решателем, соответствуют обнаруженным событиям:
te
- это вектор-столбец времени, в которое произошли события.
ye
содержит значение решения в каждом из моментов времени в te
.
ie
содержит индексы в вектор, возвращенный функцией события. Значения указывают, какое событие обнаружил решатель.
Также можно вызвать решатель с одним выходом, как
sol = odeXY(odefun,tspan,y0,options)
В этом случае информация о событии хранится в структуре следующим образом sol.te
, sol.ye
, и sol.ie
.
Механизм корневого нахождения, используемый решателем ОДУ в сочетании с функцией события, имеет следующие ограничения:
Если терминальное событие происходит во время первого шага интегрирования, то решатель регистрирует событие как нетерминальное и продолжает интегрирование.
Если во время первого шага происходит более одного терминального события, то регистрируется только первое событие, и решатель продолжает интеграцию.
Нули определяются пересечениями знаков между шагами. Поэтому можно пропустить нули функций с четным количеством переходов между шагами.
Если решатель шагает мимо событий, попробуйте уменьшить RelTol
и AbsTol
для повышения точности. Кроме того, установите MaxStep
для размещения верхней границы размера шага. Настройка tspan
не изменяет шаги, предпринятые решателем.
В этом примере показано, как написать функцию простого события для использования с решателем ОДУ. Файл примера ballode
моделирует движение прыгающего мяча. Функция events останавливает интегрирование каждый раз, когда мяч прыгает, и интеграция затем перезапускается с новыми начальными условиями. Когда мяч прыгает, интегрирование останавливается и перезапускается несколько раз.
Уравнения для прыгающего мяча
Прыгание мяча происходит, когда высота мяча равна нулю после уменьшения. Функция событий, которая кодирует это поведение,
function [value,isterminal,direction] = bounceEvents(t,y) value = y(1); % Detect height = 0 isterminal = 1; % Stop the integration direction = -1; % Negative direction only
Тип ballode
чтобы запустить пример и проиллюстрировать использование функции событий для симуляции прыгания мяча.
ballode
В этом примере показано, как использовать направленные компоненты функции события. Файл примера orbitode
моделирует ограниченную задачу трех тел, где одно тело вращается вокруг двух намного больших тел. Функция событий определяет точки на орбите, где орбитальное тело находится ближе всего и дальше всего. Поскольку значение функции событий одинаково в ближайших и самых дальних точках орбиты, направление пересечения нуля является тем, что их отличает.
Уравнения для ограниченных задач трех тел
где
Первые два компонента решения являются координатами тела бесконечно малой массы, поэтому построение графика одного относительно другого дает орбиту тела.
Функция событий, вложенная в orbitode.m
ищет два события. Одно событие определяет точку максимального расстояния от начальной точки, а другое - точку, где космический корабль возвращается к начальной точке. События расположены точно, хотя размеры шагов, используемых интегратором, не определяются местоположениями событий. В этом примере возможность задать направление пересечения нуля является критической. И точка возврата к начальной точке, и точка максимального расстояния от начальной точки имеют одинаковые значения события, и направление пересечения используется, чтобы различить их. Функция событий, которая кодирует это поведение,
function [value,isterminal,direction] = orbitEvents(t,y) % dDSQdt is the derivative of the equation for current distance. Local % minimum/maximum occurs when this value is zero. dDSQdt = 2 * ((y(1:2)-y0(1:2))' * y(3:4)); value = [dDSQdt; dDSQdt]; isterminal = [1; 0]; % stop at local minimum direction = [1; -1]; % [local minimum, local maximum] end
Тип orbitode
чтобы запустить пример.
orbitode
This is an example of event location where the ability to specify the direction of the zero crossing is critical. Both the point of return to the initial point and the point of maximum distance have the same event function value, and the direction of the crossing is used to distinguish them. Calling ODE45 with event functions active... Note that the step sizes used by the integrator are NOT determined by the location of the events, and the events are still located accurately.