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. 3阶以上矩阵定义与求逆

3阶以上矩阵定义与求逆

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

    做2个算法植入,求解非线性方程组,需要构造Jacobian矩阵并求其逆矩阵。

    算法1中,矩阵为3阶方阵,类型为复数张量Tensor<complex>,可正常调用函数inv计算逆矩阵。
    算法2中,矩阵为8阶方阵,按常规的C++语法complex JacobianM定义矩阵,调用求逆函数时报错,求逆函数不适用C++语法定义的矩阵求逆。

    对上述矩阵求逆,请教道友如何定义一个3阶以上矩阵:
    (1)可求逆
    (2)逆矩阵可与向量点乘,&

    1c6878cb-7147-4236-a31f-25de38cd135b-截屏2024-03-06 22.21.48.png
    算法1的OpenFOAM脚本,成功运行。

    3d943742-b99f-4e99-bc10-0c92db9f84ad-图像2024-3-6 12.32.JPG 算法2的Python脚本,验证准确。

    ce003d10-765f-49d9-955b-97a6de0a13f4-图像2024-3-6 22.07.JPG 算法2的OpenFOAM脚本,报错。

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

    如何定义一个3阶以上矩阵:

    SquareMatrix<scalar> hmm(3);
    
        hmm(0, 0) = -3.0;
        hmm(0, 1) = 10.0;
        hmm(0, 2) = -4.0;
        hmm(1, 0) = 2.0;
        hmm(1, 1) = 3.0;
        hmm(1, 2) = 10.0;
        hmm(2, 0) = 2.0;
        hmm(2, 1) = 6.0;
        hmm(2, 2) = 1.0;
    
    Info<< inv(hmm);
    

    类似这样可以么

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

    L 1 条回复 最后回复
  • L 离线
    L 离线
    lizhisongsjtu
    在 中回复了 李东岳 最后由 李东岳 编辑
    #3

    openFoam中实现非线性方程组求解中的Jacobian矩阵、求逆、矩阵与列向量相乘

    谢谢东岳回复。今天试了一下,SquareMatrix类型的方阵,无法求逆。

    此外,还需要一个向量与方阵相乘的列向量,列向量的定义用List定义,不能点乘。

    (牛顿法求非线性方程组)

    #include "fvCFD.H"
    
    // #include "complex.H"
    
    #include "SquareMatrix.H"
    
    
    int main(int argc, char *argv[])
    {
        Info << "Operation of Tensor and Square Matrix in OpenFOAM:" << endl;
    
     
        Info << endl << endl << "Part I: tensor" << endl;
        tensor myTensor(.1, 1, 2, 3, 4, 5, 6, 7, 8);
        vector myVector(1, 1, 1.);
    
        Info << "myTensor = " << myTensor << endl;
        Info << "myTensorInverse = " << inv(myTensor) << endl;
        Info << "det(myTensor) = " << det(myTensor) << endl;
        Info << "tr(myTensor) = " << tr(myTensor) << endl;
        Info << "myTensor & myVector = " << (myTensor & myVector) << endl;
    
    
    
        Info << endl << endl << "Part II: SquareMatrix" << endl;
    
        // 目标矩阵是8x8,暂时用4x4替代。
        const label M(4);
        // 创建一个List
        List<scalar> myList(M);
        myList[0] = 1;
        myList[1] = 1;
        myList[2] = 1;
        myList[3] = 1;
    
        // 创建方阵并赋值。
        SquareMatrix<scalar> hmm(M);
    
        hmm(0, 0) = -3.0;
        hmm(0, 1) = 10.0;
        hmm(0, 2) = -4.0;
        hmm(0, 3) = -5.0;
    
        hmm(1, 0) = 2.0;
        hmm(1, 1) = 3.0;
        hmm(1, 2) = 10.0;
        hmm(1, 3) = 9.0;
        
        hmm(2, 0) = 2.0;
        hmm(2, 1) = 6.0;
        hmm(2, 2) = 1.0;
        hmm(2, 3) = 5.0;
    
        hmm(3, 0) = 5.0;
        hmm(3, 1) = 8.0;
        hmm(3, 2) = 10.0;
        hmm(3, 3) = -4.0;
    
    
    
        Info << "det(hmm) = " << det(hmm) << endl;
        Info << "hmm.size() = " << hmm.size() << endl;
    
        // Info << "tr(hmm) = " << tr(hmm) << endl;
        // Info << "inv(hmm) = " << inv(hmm) << endl;
    
        // Info << "hmm & myList = " << (hmm & myList) << endl;
    
    
    
        return 0;
    }
    
    1 条回复 最后回复
  • 李东岳李 在线
    李东岳李 在线
    李东岳 管理员
    写于 最后由 李东岳 编辑
    #4

    我试了一下,下面可以求逆,可以改成n阶

    scalarSquareMatrix M(3, Zero);
    M(0, 0) = 4;
    M(0, 1) = 12;
    M(0, 2) = -16;
    M(1, 0) = 12;
    M(1, 1) = 37;
    M(1, 2) = -43;
    M(2, 0) = -16;
    M(2, 1) = -43;
    M(2, 2) = 98;
    LUscalarMatrix L(M);
    
    scalarSquareMatrix invM(3);
    L.inv(invM);
    

    下面可以实现点乘:

    scalarSquareMatrix M(3, Zero);
    M(0, 0) = 4;
    M(0, 1) = 12;
    M(0, 2) = -16;
    M(1, 0) = 12;
    M(1, 1) = 37;
    M(1, 2) = -43;
    M(2, 0) = -16;
    M(2, 1) = -43;
    M(2, 2) = 98;
    
    scalarField x(3, Zero);
    scalarField Mx = M*x;
    

    汇总一下

    scalarSquareMatrix squareMatrix(3, Zero);
    squareMatrix(0, 0) = 4;
    squareMatrix(0, 1) = 12;
    squareMatrix(0, 2) = -16;
    squareMatrix(1, 0) = 12;
    squareMatrix(1, 1) = 37;
    squareMatrix(1, 2) = -43;
    squareMatrix(2, 0) = -16;
    squareMatrix(2, 1) = -43;
    squareMatrix(2, 2) = 98;
    const scalarField S(3, 1);
    
    LUscalarMatrix L(squareMatrix);
    
    scalarSquareMatrix inv(3); //矩阵求逆
    L.inv(inv);
    
    scalarField x(3, Zero);
    scalarField Mx = squareMatrix*x; //矩阵乘以向量
    
    scalarField x(L.solve(S)); //计算L \cdot x = S
    

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

    L 1 条回复 最后回复
  • L 离线
    L 离线
    lizhisongsjtu
    在 中回复了 李东岳 最后由 lizhisongsjtu 编辑
    #5

    @李东岳 在实数域内,这个方法完全可行。

    可惜,我构建的矩阵类型是复数,上述方法暂时不支持扩展到复数域。

    参考了CFD-online上帖子的回复,采用QR分解,把待分解的矩阵创建为RectangularMatrix<complex>类型。

    创建QRMatrix<complex> 类型的矩阵,需要提供至少两个参数。
    参考QRMatrix构造函数

    //- Construct with a matrix and perform QR decomposition
            explicit QRMatrix
            (
                const modes mode,
                const outputs output,
                const bool pivoting,
                MatrixType& A
            );
     
            //- Construct with a const matrix and perform QR decomposition
            explicit QRMatrix
            (
                const MatrixType& A,
                const modes mode,
                const outputs output = outputs::BOTH_QR,
                const bool pivoting = false
            );
    

    用如下语句创建QR矩阵,报错。

    RectangularMatrix<complex> JacobianM_QR({3,3}, Zero);
        JacobianM_QR(0, 0) = 4;
        JacobianM_QR(0, 1) = 12;
        JacobianM_QR(0, 2) = -16;
        JacobianM_QR(1, 0) = 12;
        JacobianM_QR(1, 1) = 37;
        JacobianM_QR(1, 2) = -43;
        JacobianM_QR(2, 0) = -16;
        JacobianM_QR(2, 1) = -43;
        JacobianM_QR(2, 2) = 98;
    
        Info << "JacobianM_QR = " << JacobianM_QR << endl;
        Info << "JacobianM_QR.size() = " << JacobianM_QR.size() << endl;
    
        // QRMatrix<complex>  QRM(JacobianM_A);
        // QRMatrix<complex>  QRM(JacobianM_A, uint8_t(1));
        QRMatrix<complex>  QRM(JacobianM_A, (uint8_t)1);
    
      // QRMatrix<complex>  QRM(JacobianM_QR, *);
      // *位置是uint8_t类型的1,
    
    L 1 条回复 最后回复
  • L 离线
    L 离线
    lizhisongsjtu
    在 中回复了 lizhisongsjtu 最后由 编辑
    #6

    下面的语句可以了:ok2:

        QRMatrix<RectangularMatrix<complex>> QRM
        (
            JacobianM_QR,
            QRMatrix<RectangularMatrix<complex>>::modes::ECONOMY,
            QRMatrix<RectangularMatrix<complex>>::outputs::ONLY_R
        );
    
    1 条回复 最后回复
  • 李东岳李 在线
    李东岳李 在线
    李东岳 管理员
    写于 最后由 编辑
    #7

    :146: :146: :146: :146: :146:

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

    1 条回复 最后回复
  • L 离线
    L 离线
    lizhisongsjtu
    写于 最后由 lizhisongsjtu 编辑
    #8

    总结一下:

    求任意矩阵的逆矩阵,OpenFOAM中有三种方法:

    (1) LU-scalarSquareMatrix,实数、方阵;

    (2) QR-RectangularMatrix<Type> or SquareMatrix<Type> ,实数/复数、方阵/非方阵;

    (3) SVD-scalarRectangularMatrix,实数、方阵/非方阵。

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

    绝对到位!嘎嘎一嘎子!

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

    1 条回复 最后回复

  • 登录

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