Skip to content
  • 最新
  • 版块
  • 东岳流体
  • 随机看[请狂点我]
皮肤
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • 默认(不使用皮肤)
  • 不使用皮肤
折叠
CFD中文网

CFD中文网

  1. CFD中文网
  2. OpenFOAM
  3. solve函数为啥不需要用对象去访问调用?

solve函数为啥不需要用对象去访问调用?

已定时 已固定 已锁定 已移动 OpenFOAM
11 帖子 4 发布者 7.6k 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
回复
  • 在新帖中回复
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • MicroM 离线
    MicroM 离线
    Micro
    写于 最后由 编辑
    #1

    微信图片_20210422152445.png

    图片的内容是icoFoam.C。想请教下,solve函数不是fvMatrix的成员函数吗,调用成员函数不是应该用对象去访问吗?为什么可以直接用函数名调用呢。就算是静态成员函数,不也应该用类的名字调用吗,请问这里是什么用法?谢谢!

    1 条回复 最后回复
  • W 离线
    W 离线
    wangfei9088 大神
    写于 最后由 wangfei9088 编辑
    #2

    可以这么理解,C++是采用面向对象的编程语言,但是也不是说就不能用面向过程编程。具体可以看东岳老师写的文章,非常详细。
    https://www.cfd-china.com/topic/1172/你要的openfoam编程杂七杂八

    http://dyfluid.com/docs/book/_book/chapter1/section2.html

    这段代码可以这么改:

            fvVectorMatrix UEqn
            (
                fvm::ddt(U)
              + fvm::div(phi, U)
              - fvm::laplacian(nu, U)
              == -fvc::grad(p)
            );
    
            if (piso.momentumPredictor())
            {
                UEqn.solve();
            }
    

    编译没问题,运行了几步就报错了。

    MicroM 1 条回复 最后回复
  • MicroM 离线
    MicroM 离线
    Micro
    在 中回复了 wangfei9088 最后由 编辑
    #3

    @wangfei9088 谢谢大佬回复啊,我明白在c++ 中也可以设置全局函数,用面向过程的方式来编写。可是在此处,solve函数作为fvMatrix类的成员函数,真的可以 直接以 “函数名加实参”的方式调用吗?谢谢!

    1 条回复 最后回复
  • W 离线
    W 离线
    wangfei9088 大神
    写于 最后由 wangfei9088 编辑
    #4

    看icoFoam.C的头文件fvCFD.H文件(~src/finiteVolume/cfdTools/general/include/),里边的fvMatrices.H头文件(~src/finiteVolume/fvMatrices/)就两行代码,留意到fvMatricesFwd.H头文件。

    39 #include "fvMatricesFwd.H"
    

    看到fvMatricesFwd.H文件(~src/finiteVolume/fvMatrices/)指出存在fvVectorMatrix是fvMatrix<vector>的别名。

    45 typedef fvMatrix<vector> fvVectorMatrix;
    

    找到fvMatrix.H头文件(~src/finiteVolume/fvMatrices/fvMatrix/),里边都是变量和函数,就顺便取看看fvMatrix.C文件的内容。

    在fvMatrix.C文件(~src/finiteVolume/fvMatrices/fvMatrix/)中意外找到了==的运算符重载,就是solve(UEqn == -fvc::grad(p));括号里边的运算符,A==B返回的是A-B。留意到最后一句告诉我有一个fvMatrixSolve.C文件。

    1356 template<class Type>
    1357 Foam::tmp<Foam::fvMatrix<Type>> Foam::operator==
    1358 (
    1359     const fvMatrix<Type>& A,
    1360     const fvMatrix<Type>& B
    1361 )
    1362 {
    1363     checkMethod(A, B, "==");
    1364    return (A - B);
    1365 }
    
    2336 // * * * * * * * * * * * * * * * * Solvers * * * * * * * * * * * * * * * * * //
    2337 
    2338 #include "fvMatrixSolve.C"
    

    于是,我在fvMatrixSolve.C文件(~src/finiteVolume/fvMatrices/fvMatrix/)中找到了下面这个函数:

    418 template<class Type>
    419 Foam::SolverPerformance<Type> Foam::solve(fvMatrix<Type>& fvm)
    420 {
    421     return fvm.solve();
    422 }
    

    这是什么啊?
    变量名作为实参的solve函数,返回的是变量名的成员函数。
    得证。

    1 条回复 最后回复
  • MicroM 离线
    MicroM 离线
    Micro
    写于 最后由 编辑
    #5

    @wangfei9088 十分感谢,您追踪代码的执行力太强了。我也按照您的搜索路径走了一遍,发现果然如此。您最后最终到的 Foam::solve函数看来应该是个全局函数,并且由这个全局函数来调用fvMatrix中的成员函数solve.请问这么理解对吗?谢谢!
    另外您提到如下图所示的
    ,97edc7182f685fb10bac7878984c607.png
    编译没有问题,但是运行报错。我重复了您的步骤,发现确实如此,原因应该是这种变动并不是等价变动,因为更改了UEqn的值(此后UEqn作为单独整体出现并参与计算了)。所以我做了如下的等价变动
    a1891e7ded7f2b2443cbc3f1cfb6027.png
    讲道理这样应该可以获得正确结果,可以居然连编译都编译不过了。。。好奇怪啊:138: :138:
    aee8537299d0308e530a09c019c8264.png

    1 条回复 最后回复
  • 李东岳李 离线
    李东岳李 离线
    李东岳 管理员
    写于 最后由 李东岳 编辑
    #6

    应该用(Ueqn==fvc::grad(p)).ref()->solve(),这是一个tmp类型

    @wangfei9088 大佬太厉害了 :140:

    http://dyfluid.com/index.html
    需要帮助debug算例的看这个 https://cfd-china.com/topic/8018

    MicroM W Y 3 条回复 最后回复
  • MicroM 离线
    MicroM 离线
    Micro
    在 中回复了 李东岳 最后由 编辑
    #7

    @李东岳 芜湖!谢谢岳哥!

    1 条回复 最后回复
  • W 离线
    W 离线
    wangfei9088 大神
    在 中回复了 李东岳 最后由 编辑
    #8

    @李东岳 老师,我就一菜鸟,班门弄斧啦。最后一笔还得靠您这样的大佬来点睛啊。学习了! :xiezuoye:

    1 条回复 最后回复
  • Y 离线
    Y 离线
    Yongbo
    在 中回复了 李东岳 最后由 Yongbo 编辑
    #9

    @李东岳 在 solve函数为啥不需要用对象去访问调用? 中说:

    应该用(Ueqn==fvc::grad(p)).ref()->solve(),这是一个tmp类型

    @wangfei9088 大佬太厉害了 :140:

    这里.ref() 是取引用吧,所以应该是

    (Ueqn==fvc::grad(p)).ref().solve() 或者

    (Ueqn==fvc::grad(p))->solve() ?

    @Micro 大佬试过李东岳老师修改后的代码了吗?

    MicroM 2 条回复 最后回复
  • MicroM 离线
    MicroM 离线
    Micro
    在 中回复了 Yongbo 最后由 编辑
    #10

    @Yongbo 还没有,我按照您说的试一下,你尝试后有结果了吗?

    1 条回复 最后回复
  • MicroM 离线
    MicroM 离线
    Micro
    在 中回复了 Yongbo 最后由 编辑
    #11

    @Yongbo 你说的两种方式是对的,我验证均通过编译了。东岳老师应该是笔误了

    1 条回复 最后回复

  • 登录

  • 登录或注册以进行搜索。
  • 第一个帖子
    最后一个帖子
0
  • 最新
  • 版块
  • 东岳流体
  • 随机看[请狂点我]