Julia中带反射边界的SDEProblem模拟实现问题咨询
问题根源
你使用ContinuousCallback没有生效的核心原因是对该回调的使用逻辑错误:ContinuousCallback的工作原理是通过根查找算法定位condition函数的零点,当condition返回值穿过0时触发回调,要求condition必须返回数值,而不是布尔值。你之前写的`condition(u,t,integrator) = u<0返回的是布尔值,会被隐式转换为1/0两个固定值,永远不会出现过零点,因此回调全程不会触发,自然没有反射效果。
正确实现方案
1. 修正ContinuousCallback写法
只需要把condition改为直接返回状态值u即可,当u从正穿过0变为负时就会自动触发回调:
# 返回值u穿过0时触发回调,对应u=0的边界点 condition(u,t,integrator) = u function affect!(integrator) integrator.u = -integrator.u end cb = ContinuousCallback(condition,affect!;save_positions=(false,false))
修正后不管是固定步长的EM求解器,还是自适应步长的SOSRI求解器,都可以得到正确的反射效果,不需要依赖极小的时间步长。
不同场景的推荐选择
- 固定步长求解器场景:
- 若计算量要求低、步长已经设置得足够小,可以继续用
DiscreteCallback,实现简单运行速度快 - 若步长较大,推荐用修正后的
ContinuousCallback,哪怕步长偏大也不会漏过边界穿越,精度更高
- 若计算量要求低、步长已经设置得足够小,可以继续用
- 自适应步长求解器场景:
必须使用修正后的ContinuousCallback,DiscreteCallback会因为自适应步长的节点间隔不稳定,很容易漏过边界穿越,导致反射效果差。
关于求解器支持的说明
反射边界模拟不限制仅用显式时间步进求解器,DifferentialEquations.jl的回调系统对显式、隐式SDE求解器都提供完整支持,只要回调定义符合要求即可正常工作。
内容的提问来源于stack exchange,提问作者Shffl
相关产品推荐
相关产品推荐

