WhenEvent

WhenEvent[event,action]

指定在 NDSolve 中,当方程中触发 event 产生的一个 action 和相关函数.

更多信息和选项

  • NDSolve[eqns,] 中,WhenEvent 表达式被包含在 eqns 中,被考虑为解的部分规范,尤其是分段或混合系统.
  • WhenEvent 表达式可以用于 NDSolveNDSolveValueParametricNDSolveParametricNDSolveValueDSolveDSolveValue.
  • 对应于在 NDSolveeqns 积分时,在特定时间 的事件.
  • 如果事件表达式以解的函数 f 显式给出,例如,在 f 的根处,事件变成 True,那么 WhenEvent 使用查找数值根的过程确定区间 ,其中, 是函数有根的时间. 显式给出事件的范例:
  • f0解的变量函数 f 跨过零
    f>0从下面 f 跨过零
    f<0从上面 f 跨过零
    Mod[t,Deltat]0以固定间隔 ,时间变量 采样
  • 如果显式表达式为 ev,事件可以使用形式 ev && pred 以谓词 pred 为条件. 在这种情况下,事件只有在如果 pred 在事件函数的根处为 True 才会被触发.
  • 当事件以无法直接转换为上面的显式格式的形式给出,那么事件表达式被考虑为应该是 TrueFalse 的谓词 pred. 在这种情况下,使用二等分找到区间 .
  • 带有条件和事件作为谓词的显式事件的诠释略有不同. 如果可能最好使用显式事件,因为它们更有可能被检测到,并能更高效地找到根. »
  • WhenEvent[{event1,},action] 被处理为 {WhenEvent[event1,action],}.
  • WhenEvent[event,{action1,action2,}] 时,按序计算 action.
  • 计算 action 得到的值被 WhenEvent 忽略,除非它有特殊的值被用于影响 NDSolve. 以下特殊值是被确认的:
  • "StopIntegration" 停止积分,返回解
    "RestartIntegration" 重新开始积分
    "CrossDiscontinuity"积分到 ,推算并在 重新开始
    "CrossSlidingDiscontinuity"积分到 ,推算并检查滑动模式条件,在 重新开始
    "RemoveEvent"去除事件
    y[t]->val把状态变量 y 改为 val
    d[t]->"DiscontinuitySignature"改变不连续签名变量 d
  • WhenEvent[f==0,d->"DiscontinuitySignature"] 时,不连续性是曲面 f==0d 必须是一个接受值 {-1, 0, 1}{-1, 1} 的离散变量,对于 事件后,有效的设为 Sign[f].
  • WhenEvent 具有属性 HoldAll,因此,默认情况下,eventaction 只有当变量被赋近似值时才被计算.
  • WhenEvent 接受以下选项:
  • "DetectionMethod" Automatic用于检测事件的方法
    "LocationMethod" Automatic用于在时间步骤中定位事件的方法
    "IntegrateEvent" Automatic是否积分事件函数
    "Priority" Automatic作用于同时发生事件的优先级
  • "DetectionMethod" 可能的设置为:
  • Automatic自动决定检测方法
    "Sign"使用一个符号变换
    "DerivativeSign"使用符号变换和时间导数
    "Interpolation"使用稠密解输出的插值
  • "Sign" 检测方法具有最少的开销,但在快速变换的函数中可能错过事件. "Interpolation" 检测方法更强大,在每个步骤中可以检测多个事件.
  • "LocationMethod" 可能的设置为:
  • Automatic自动确定定位方法
    "StepBegin"在每个步骤开始前定位事件
    "StepEnd"在每个步骤结束时定位事件
    "LinearInterpolation"在步骤中线性插值
    "Brent"在一个步骤中使用 Brent 的根定位
  • "IntegrateEvent" 可能的设置为:
  • Automatic自动决定
    False不积分事件函数
    True积分事件函数
  • "Priority" 的设置可以为任何整数或 Infinity. 在同时发生的事件中,将按排序的优先级顺序计算 action.

范例

打开所有单元关闭所有单元

基本范例  (1)

模拟一个在每次反弹时仍保留95%速度的反弹球:

范围  (16)

事件  (6)

x[t] 穿过 1/2 时,输出 t 的值:

x[t] 大于 1/2 时,输出 t 的值:

x[t] 小于 1/2时,输出 t 的值:

按固定时间间隔 ,采样解:

以列表指定多个事件,当发生任一事件便触发行动(action):

使用具有条件 的事件 检测正 轴的相交点:

一般而言,事件可以是任何可以被检验为 True 的表达式:

当点击按钮时,触发一个事件停止积分:

如果很快点击 Stop 按钮,积分会在 前终止:

行为  (9)

以列表指定多个行为,按连续顺序执行:

使用 "StopIntegration" 结束一个事件的解:

在事件第一次发生后,使用 "RemoveEvent" 删除事件:

在事件第三次发生后,删除事件:

在事件后,使用 "RestartIntegration" 强迫重新开始积分:

处理这种变化的更好的方法是使用离散状态变量 a[t]

规则可用于修改 DependentVariablesDiscreteVariables

使用 "CrossDiscontinuity" 管理不连续相交点:

使用 "CrossSlidingDiscontinuity" 表明可以使用菲利波夫(Filippov)延续:

使用 DiscreteVariables"DiscontinuitySignature" 有效穿越不连续点:

在 Filippov 滑动模式情况下,"DiscontinuitySignature" 为 0:

推广和延伸  (2)

有条件的停止积分:

有条件的去除一个事件:

选项  (11)

"DetectionMethod"  (3)

默认事件检测的方法是 "Sign",检验步骤间的符号变化:

上面等价于:

如果步骤直接的交叉点数目是偶数,"Sign" 可能错过事件:

如果符号相同,"DerivativeSign" 将步长缩短为一半,但是导数符号改变:

对于快速变化的事件函数,使用 "Interpolation" 方法定位事件:

"LocationMethod"  (3)

默认定位方法 "Brent" 精确定位一个事件:

"LinearInterpolation" 方法会合理定位事件:

如果高精度的事件定位不是必要的,则使用 "StepBegin""StepEnd"

"IntegrateEvent"  (2)

当事件函数比解变化更快时,可能错过相交点:

之间绘制具有时间步长和交叉点的事件函数:

"IntegrateEvent"->True 时,步长会取得更小一些:

定义一个函数,比较事件检测性能:

"DetectionMethod"->"Interpolation" 时,默认情况下,事件进行鲁棒性积分:

比较性能:

"Priority"  (3)

当事件同时发生时,设置优先级别,该例是为每个整数 t

在任何有限优先级之后, 但在优先级 Infinity 之前,将产生 Automatic 优先级:

Sort 是按标准顺序对优先级排序:

应用  (21)

反弹球  (3)

模拟一个球反弹下的步骤:

绘制球的动能、势能和总能量:

模拟20个反弹球同时从不同的高度下降:

模拟一个球的正方形内的侧墙的影响下改变方向的运动:

具有无理初始速度,不再有周期解:

最优化  (1)

通过事件检测求解微分方程可用于查找函数 在有限范围内的所有局部最小值和最大值. 考虑函数

设置搜索范围:

求解函数导数为 0 的微分方程并存储点:

绘制函数以及最小值和最大值:

交叉检测  (3)

标注参数曲线弧长度为1的点:

标注参数解进入或离开环形区域的解:

只标注参数解离开区域的点:

只标注参数解进入区域的点:

标注解进入或离开区域的点:

混合动力系统  (3)

每次线性振荡解穿过负 轴,反应它穿过 轴:

该复位振荡器的解展现出混沌的行为:

在具有反射点的直方图的负 轴上绘制解:

模拟具有正弦压迫的自由度为1的效应振荡器(impact oscillator):

模拟一个在固定时间间隔被敲打的阻尼振荡器:

轨迹最终安定为一个连贯的轨道:

使用同样的振荡器,但是在固定的时间间隔进行随机的敲打:

摩擦模型  (1)

对使用弹簧固定在墙壁上的方块,使用摩擦力 的不同模型,包括粘性、库伦力、Stribeck 和静态. 比较不同模型的位置和速度:

方块的牛顿方程:

粘性摩擦力 与相对速度 成正比:

方块在弹簧的自然长度为 1 之上稳定:

库伦摩擦力 与相对速度 的符号成正比:

方块随着传送带移动,直至弹簧力足够大:

Stribeck 摩擦力 是一种修正后的库伦摩擦力 F_(str)=gamma sgn(v) e^(-2 TemplateBox[{v}, Abs]):

低速上的变化略有减少:

静摩擦力 将方块保持在原地直至取决于表面粗糙度,弹簧力超过一定值 μ. 当方块被卡住时,使用设为 1 的离散变量 stuck,否则使用 0:

检查弹簧力是否小于 μ,并且该方块是否相对于滑动带没有移动:

方块持续黏在传送带上,然后由于弹簧力滑走:

比较不同模型:

电力电子学  (4)

对由四个二极管和一个电容构成的 AC-to-DC 全波整流器建模,用于平滑输出:

输入电压 vi 和整流后的电压 vr

vr 增加时,vo[t]=vr[t];电容器充电,并将电流供给到负载. 当 vr 开始降低 (vr'[t]<0),电容器通过负载放电,输出电压服从 vo'[t]=vo[t]/c r

对系统进行仿真:

绘制电容平滑处理后的输出电压:

对使用脉冲宽度调制反馈控制 q[t] 的 DC-to-DC 降压转换器建模,该转换器将输入电压 vi 转换到所需的输出电压 vd

使用基尔霍夫定理获得上述电路的模型:

控制信号 q[t] 将在占每个周期 τvd/vi 时间段内接通晶体管:

从一个较高的电压 vi=24 降到较低的电压 vd=16:

对使用脉冲宽度调制反馈控制 q[t] 的 DC-to-DC 升压转换器建模,该转换器将输入电压 vi 转换到所需的输出电压 vd

使用基尔霍夫定理获得上述电路的模型:

控制信号 q[t] 将在占每个周期 τvi/vd 时间段内接通晶体管:

从较低的电压 vi=24 升到较高的电压 vd=36:

对从输入电压电平 vi 到所需输出电压电平 vo 的 DC-to-DC 升压转换器 使用脉冲宽度调制反馈控制 q[t] 建模:

使用基尔霍夫定理获得上述电路的模型:

控制信号 q[t] 将晶体管开启每个周期的 vd/(vi+vd) 时间:

从较低的电压 vi=24 升到较高的电压 vd=36:

从较高的电压 vi=24 降到较低的电压 vd=16:

数字控制  (5)

仿真用离散时间控制器 稳定的系统

仿真和可视化:

使用无振 (dead-beat) 离散时间控制器控制双重积分器:

使用无振(dead-beat)数字反馈控制器

仿真和可视化:

用 1 公斤质体模拟移动物体的位置:

用采样比例-微分(PD)控制器保持位置常量:

仿真和可视化:

设计具有状态方程 和输出 的机械设备(plant)的离散时间控制器,仿真闭环系统:

通过使用状态估计器和状态反馈设计连续时间的控制器:

用采样时间 采样获取一个离散时间控制器:

使用离散时间控制器:

仿真具有控制器和 plant 的闭环系统:

绘制结果:

模拟一个固定在移动车上位置为 x,角度为 θ,承受水平力为 f 的钟摆:

设计一个稳定关于不稳定垂直固定点钟摆的控制器:

利用 WhenEvent 在固定采样时间应用反馈:

仿真该系统:

在倒置位置()钟摆的角度快速稳定:

PDE 模型  (1)

模拟温控器控制下一个房间中的热生成,该房间有三面绝热墙和一面受外界温度影响的玻璃墙:

事件中加热器的负载被增加或减少:

PDE 模拟空气中的热扩散,在圆 内生成热,通过玻璃窗散热:

如果位于 处的温控器测量到的温度高于/低于触发温度,且离散变量 发生变化,则关闭/打开加热器:

初始状态等于外部温度,查看 PDE 的时间积分:

可视化温控器测量的温度、外部温度和加热器的触发. 加热器处于开启状态时显示蓝色背景:

查看积分过程中的时间步长,注意 NDSolveValue 如何在事件期间根据需要调整时间步长:

属性和关系  (2)

NDSolve 会尝试自动设置 WhenEvent 事件来处理 中的不连续点:

在自动不连续处理后,下面等价问题将被解决:

如果 是一个黑盒(black-box)函数,NDSolve 不能自动处理不连续性:

这种情况,可以通过添加 WhenEvent 正确处理不连续性:

或者,使用 "CrossSlidingDiscontinuity" 穿越不连续性:

可能存在的问题  (6)

事件诠释  (1)

显式给出条件的事件与单个谓词略有不同的诠释:

WhenEvent 不能找到显式根函数,因此当 pred 变成 True 时事件发生:

当给定显式函数 (),事件被认为根 ,但条件是谓词 () 在 时为 False,因此从不会被触发:

显示解的踪迹和事件位置,背景为绿,当条件为 True,当条件为 False 时,背景为红色:

当给定显式函数 (),事件被作为根

显示解的踪迹和事件位置,背景为绿,当条件为 True,当条件为 False 时,背景为红色:

事件检测  (2)

使用默认的 "DetectionMethod",可能会错过一些事件:

尝试 "DerivativeSign""Interpolation" 获取更好的事件检测:

对应于事件顺序的根的事件可能会错过:

相反,改写奇数根:

任意接近事件  (1)

有些系统允许在有限的时间跨度中有无限数量的事件:

最终,一个事件没有被检测到:

为定位事件收紧公差,改善检测:

如果比这更快的事件将不会被检测到:

通过插值检测,事件检测会进一步改善:

最后两个事件的间隔很接近这个极限:

在事件错过前自动停止积分:

事件在积分停止点被检测到:

增加工作精度允许在更精细的时间尺度中检测事件:

事件行为  (2)

在 ODE 中不能重置最高阶导数:

但作为 DAE 求解,可以重置最高阶导数:

通过重新初始化,求解对应的 值,因此 的残差为0:

对于有序事件行为,变量是按序被修改的:

若要交换变量值,使用同步事件:

互动范例  (2)

用有理和无理初始值比较一个在盒中的球:

用有理和无理初始值比较一个在盒中的球:

Wolfram Research (2012),WhenEvent,Wolfram 语言函数,https://reference.wolfram.com/language/ref/WhenEvent.html (更新于 2014 年).

文本

Wolfram Research (2012),WhenEvent,Wolfram 语言函数,https://reference.wolfram.com/language/ref/WhenEvent.html (更新于 2014 年).

CMS

Wolfram 语言. 2012. "WhenEvent." Wolfram 语言与系统参考资料中心. Wolfram Research. 最新版本 2014. https://reference.wolfram.com/language/ref/WhenEvent.html.

APA

Wolfram 语言. (2012). WhenEvent. Wolfram 语言与系统参考资料中心. 追溯自 https://reference.wolfram.com/language/ref/WhenEvent.html 年

BibTeX

@misc{reference.wolfram_2024_whenevent, author="Wolfram Research", title="{WhenEvent}", year="2014", howpublished="\url{https://reference.wolfram.com/language/ref/WhenEvent.html}", note=[Accessed: 24-November-2024 ]}

BibLaTeX

@online{reference.wolfram_2024_whenevent, organization={Wolfram Research}, title={WhenEvent}, year={2014}, url={https://reference.wolfram.com/language/ref/WhenEvent.html}, note=[Accessed: 24-November-2024 ]}