程序包 org.hipparchus.ode.events
事件
该包提供了处理常微分方程积分过程中发生的离散事件的类。
离散事件检测基于切换函数。用户在检测器对象中提供一个简单的依赖于当前时间和状态的g(state)
函数,以及在处理器对象中的handler函数
。积分器将在整个积分范围内监视函数的值,并在其符号发生变化时触发事件。该值的大小几乎无关紧要,但为了进行根查找,它应该是连续的(但不一定是平滑的)。
事件检测基于两个嵌套的搜索算法。一个顶层循环,由maxCheck间隔驱动,对积分步骤期间的g函数进行采样,以识别符号变化,从而确定根的区间。当在两个连续采样之间检测到符号变化时,将触发一个较低级别的根查找算法,以精确定位根,使用提供的阈值作为收敛标准。maxCheck间隔应该足够大,以避免对积分步骤进行过于细致的采样和过于频繁地评估g函数,但它应该足够小,以仍然分隔连续的根,否则可能会错过一些事件。有关maxCheck行为的正式定义,请参见下文。另一方面,阈值通常应该非常小,它实际上对应于必须定位事件的精度。
当触发事件时,有几种不同的选项可用:
- 积分可以停止(这称为G-stop功能),
- 状态向量或导数可以更改,
- 或者积分可以继续进行。
第一种情况,G-stop,是最常见的情况。一个典型的用例是当必须解决ODE直到达到某个目标状态时,其中状态的值已知但发生时间未知。例如,如果我们想要监视化学反应直到第一种物质达到某个预定义浓度,我们可以在检测器中使用以下切换函数设置:
public double g(final ODEStateAndDerivative state) { return state.getState()[0] - targetConcentration; }
以及在事件处理器中使用以下设置:
public Action eventOccurred(final ODEStateAndDerivative state, final ODEEventDetector detector, final boolean increasing) { return STOP; }
第二种情况,更改状态向量或导数,是在处理不连续动力学模型时遇到的情况。一个典型的情况是当太空船进行轨道机动时的运动。只要不进行机动,加速度就是平滑的,仅取决于重力、阻力、第三体引力、辐射压力。点火推进器引入了一个不连续性,必须由积分器适当处理。在这种情况下,我们将使用类似于以下设置的切换函数设置:
public double g(final ODEStateAndDerivative state) { return (state.getTime() - tManeuverStart) ∗ (state.getTime() - tManeuverStop); }
以及在事件处理器中使用以下设置:
public Action eventOccurred(final ODEStateAndDerivative state, final ODEEventDetector detector, final boolean increasing) { return RESET_DERIVATIVES; }
第三种情况主要用于监视目的,一个简单的例子是:
public double g(final ODEStateAndDerivative state) { final double[] y = state.getState(); return y[0] - y[1]; }
以及在事件处理器中使用以下设置:
public Action eventOccurred(final ODEStateAndDerivative state, final ODEEventDetector detector, final boolean increasing) { logger.log("y0(t) and y1(t) curves cross at t = " + t); return CONTINUE; }
事件处理规则
这些规则形式化了事件检测的概念,并用于确定何时必须向用户报告事件以及事件发生的顺序。这些规则假定事件处理器和g函数符合ODEEventHandler
和ODEIntegrator
上的文档。
- 如果g函数的符号已经改变了超过maxCheck(t, y(t))的时间,则必须检测到一个事件。形式上,给定时间t、t_e1、t_e2,使得t < t_e1 < t_e2,g(t_e1) = 0,g(t_e2) = 0,并且在区间{[t, t_e1>,
}上g(t_i) != 0(即t_e1、t_e2是t之后的下两个事件时间),那么如果maxCheck(t, y(t)) < t_e2,则将检测到t_e1。(即,最大检查间隔必须小于第二个事件发生之前的时间。) - MaxCheck(t, y(t))在步骤开始时进行评估,并在上一个maxCheck结束时再次调用;这意味着如果maxCheck在很大程度上取决于状态,则必须小心返回保守值,即最好返回小的maxCheck,因此进行大量检查比因为maxCheck太大而错过事件要好。
- MaxCheck应始终返回正值,即使积分是向后的。
- 对于给定的公差h和根r,事件可能发生在区间[r-h, r+h]上的任意点。公差是
收敛
参数和在添加
事件检测器时指定的根查找器的收敛设置中较大的那个。 - 每个根最多触发一个事件。
- 来自同一事件检测器的事件必须在增加和减少事件之间交替。也就是说,对于每一对增加事件,必须存在一个介于减少事件之间的事件,反之亦然。
- 当调用
eventOccured()
方法时,事件开始发生。当eventOccurred()返回或处理器的resetState()
方法返回时,事件停止发生,如果eventOccured()返回RESET_STATE
。 - 如果事件A发生在事件B之前,则A发生的效果对B可见。(包括重置状态或导数,或停止)
- 事件按时间顺序发生。如果积分是向前的,事件A发生在事件B之前,则事件B的时间大于或等于事件A的时间。
- 事件有一个总的顺序。也就是说,对于两个事件A和B,要么A发生在B之前,要么B发生在A之前。
-
类说明AbstractODEDetector<T extends AbstractODEDetector<T>>基类为
ODEEventDetector
。用于在ODE积分过程中事件发生时执行的操作的枚举。该接口表示一个依赖于状态的事件检查间隔。当事件时间接近时,检查事件是否被正确检测到。一些基本的方程式进行积分。该类在积分步骤中处理一个事件处理器
的状态。用于保存与事件发生相关的数据,这些数据需要决定如何修改积分。EventSlopeFilter<T extends ODEEventDetector>用于仅检测增加或减少事件的包装器。该单元测试的状态事件。EventSlopeFilterTest.FieldEvent<T extends CalculusFieldElement<T>>该单元测试的状态事件。检查事件处理程序和步骤处理程序在一致的时间被调用。FieldAdaptableInterval<T extends CalculusFieldElement<T>>该接口表示一个依赖于状态的事件检查间隔。当事件时间接近时,检查事件是否被正确检测到。一些基本的方程式进行积分。一些基本的方程式进行积分。FieldDetectorBasedEventState<T extends CalculusFieldElement<T>>该类在积分步骤中处理一个事件处理器
的状态。FieldEventOccurrence<T extends CalculusFieldElement<T>>用于保存与事件发生相关的数据,这些数据需要决定如何修改积分。用于仅检测增加或减少事件的包装器。FieldEventState<T extends CalculusFieldElement<T>>FieldODEEventDetector<T extends CalculusFieldElement<T>>这个接口表示在ODE积分过程中触发的离散事件的处理程序。FieldODEEventHandler<T extends CalculusFieldElement<T>>这个接口表示在ODE积分过程中触发的离散事件的处理程序。FieldODEStepEndHandler<T extends CalculusFieldElement<T>>这个接口表示在每个步结束时触发的ODE积分过程中的离散事件的处理程序。FieldStepEndEventState<T extends CalculusFieldElement<T>>这个类处理在步结束时触发的一个事件处理器
的状态。变量检查间隔的测试。用于过滤事件
的枚举。这个接口表示在ODE积分过程中触发的离散事件的检测器。这个接口表示在ODE积分过程中触发的离散事件的处理程序。这个接口表示在每个步结束时触发的ODE积分过程中的离散事件的处理程序。测试重叠状态事件。这个单元测试的状态事件。这个类处理在步结束时触发的一个事件处理器
的状态。变量检查间隔的测试。