关于并行问题的一点理解



  • 终于把之前的并行出错的问题解决了,还是要感谢@wwzhao 和@cfd-china 的帮助。
    简单一点,我之前的代码,在主函数中是这样的:

    int main()
    {
             .......
             if( // condition )           
             {
                    .......
                    U.correctBoundaryConditions();
                    T.correctBoundaryConditions();
                    p.correctBoundaryConditions();
                    .......
             }
    }
    

    这里加if的作用是因为我的代码,在并行的时候,并不是每个语句对proccessor都通用,比如说一些量的定义和操作等,因此加了个if判断一下。

    也就是说,这个地方对于有的proccessor执行了更新边界的操作,而有的processor并没有更新,这样会导致processor之间的数据交换发生问题(我个人的理解),因此就会报错。为了使得每个processor的差别仅仅是一些量定义和运算的差异,而在其他地方都同等对待,比如边界场的更新(因为proccessor之间也是通过processor边界进行数据交流的),因此我将上述代码改成如下形式:

    int main()
    {
             .......
             if( // condition )           
             {
                    .......
                    
                    .......
             }
            U.correctBoundaryConditions();
            T.correctBoundaryConditions();
            p.correctBoundaryConditions();
    }
    

    这样,对于每个processor来说,都同时更新了边界,数据交换就没问题了。

    我的case比较特殊,INLET入口边界条件是自定义的,有一些量的运算和赋值,不能破坏INLET边界,所以我用的是simple分块方法,也就是说只有processor0才会有INLET的faces,因此我的求解器代码,不能针对所有的processor,要加一些判断语句来区别processor0,另外,由于每个processor都调用了boundaryConditions(),因此自定义的INLET边界条件代码根据不同的processor也要加判断,执行不同的代码。所以在并行的时候,既要考虑到每个processor的运行代码,还要考虑到他们之间的数据交换是否存在问题。

    以上是我个人的理解,大家有什么不同的看法可以讨论哈。

    现在我的case还在算着,不知道结果怎么样,还是祈祷吧~~



  • @Aeronastro

    感谢反馈!恭喜解决问题!

    BTW,你这个算例如果要对处理器单处处理,是不是需要手动进行网格分块?



  • @cfd-china 没有必要手动进行分块,我只要保证有一个processor的INLET边界是完整的就好了,其他的怎么分块比较随意,实际手动分块的话也可以,我为了简单,就用了simple了。

    记得之前好像有关于手动分块的方法的帖子,我找找看:happy:


Log in to reply