我认为您无法避免对浮点比较使用容差。由于使用浮点数的舍入、离散化等导致的错误是不可避免的。
我通常用来测试我编写的 FEM 代码的方法是:
- 测试单个元素上的刚度和质量矩阵,以确保我得到正确的局部元素组装,与已知结果进行比较
- 在一个简单的网格上再次测试,以确保我得到正确的全局装配,与已知结果进行比较
- 测试在具有已知结果的函数上组装负载向量
- 在应该“精确”的制造解决方案上测试整个求解器(工作精度,有足够的细化;一个例子是泊松问题,在P1离散化)
- 在不精确的制造解上测试求解器,反复细化解,计算误差,并根据网格尺寸回归误差以确定求解器的收敛顺序
对于泊松问题,这些测试会锻炼大部分求解器。对于更复杂的问题,您的里程可能会有所不同;为某些问题编写测试用例比为其他问题编写测试用例更容易,并且为某些程序(例如,您自己编写的串行代码)编写测试比为其他程序(例如,并行代码,其中处理器排序可以影响减少的结果)。
在选择公差时,所有这些测试都需要一些判断,但是通过制造的解决方案,您将清楚地知道什么时候是严重错误的,什么时候是正确的。通常,我从类似的东西开始10−7作为特征值约为 1 的解的绝对容差,并相应地向上或向下调整。
测试收敛顺序需要最多的判断,因为您不仅需要选择容差,还需要选择用于回归的网格间距。最好先进行试验,然后绘制误差与网格大小的关系图(实际上,因为它是幂律,误差范数的对数与网格大小的对数;您还将回归误差范数的对数与网格大小的对数)。一旦你有了有意义的数据,然后将绘制收敛行为的代码转换为一个测试,该测试将从回归获得的收敛顺序与理论的收敛顺序进行比较。例如,如果我期望收敛阶数为 3,并且我得到介于 2.7 和 3.3 之间的任何值,或者类似的结果,那么我会说测试“通过”。