Ejemplo n.º 1
0
Foam::Vandermonde::Vandermonde
(
    const scalarSquareMatrix& A,
    const bool checkVandermonde
)
    :
    scalarDiagonalMatrix(A.m()),
    m_(A.m())
{
    if (checkVandermonde)
    {
        for (label i = 0; i < m_; i++)
        {
            for (label j = 0; i < m_; j++)
            {
                if (A[i][j] != pow(A[1][j], i))
                {
                    FatalErrorInFunction
                            << "Source matrix not of Vandermonde type." << nl
                            << abort(FatalError);
                }
            }
        }
    }

    for (label i = 0; i < m_; i++)
    {
        (*this)[i] = A[1][i];
    }
}
void Foam::LUsolve
(
    scalarSquareMatrix& matrix,
    Field<Type>& sourceSol
)
{
    labelList pivotIndices(matrix.n());
    LUDecompose(matrix, pivotIndices);
    LUBacksubstitute(matrix, pivotIndices, sourceSol);
}
Ejemplo n.º 3
0
Foam::eigenSolver::eigenSolver(const scalarSquareMatrix& A, bool symmetric)
:
    eigenvaluesRe_(A.n()),
    eigenvaluesIm_(A.n()),
    eigenvectors_(A.n(), A.n()),
    H_(),
    n_(A.n())
{
    if (symmetric)
    {
        eigenvectors_ = A;
        tridiagonaliseSymmMatrix();
        symmTridiagQL();
    }
    else
    {
        H_ = A;
        Hessenberg();
        realSchur();
    }
}
Ejemplo n.º 4
0
Foam::scalarSquareMatrix Foam::LUinvert( scalarSquareMatrix& luMatrix)
{
    //scalarSquareMatrix luMatrix = *this;

    scalarSquareMatrix luInvert(luMatrix.n());
    scalarField column(luMatrix.n());

    labelList pivotIndices(luMatrix.n());

    LUDecompose(luMatrix, pivotIndices);

    for (label j = 0; j < luMatrix.n(); j++)
    {
        for (label i = 0; i < luMatrix.n(); i++)
        {
            column[i] = 0.0;
        }

        column[j] = 1.0;

        LUBacksubstitute(luMatrix, pivotIndices, column);

        for (label i = 0; i < luMatrix.n(); i++)
        {
            luInvert[i][j] = column[i];
        }
    }

    return luInvert;
}
void Foam::LUBacksubstitute
(
    const scalarSquareMatrix& luMatrix,
    const labelList& pivotIndices,
    Field<Type>& sourceSol
)
{
    label n = luMatrix.n();

    label ii = 0;

    for (register label i=0; i<n; i++)
    {
        label ip = pivotIndices[i];
        Type sum = sourceSol[ip];
        sourceSol[ip] = sourceSol[i];
        const scalar* __restrict__ luMatrixi = luMatrix[i];

        if (ii != 0)
        {
            for (label j=ii-1; j<i; j++)
            {
                sum -= luMatrixi[j]*sourceSol[j];
            }
        }
        else if (sum != pTraits<Type>::zero)
        {
            ii = i+1;
        }

        sourceSol[i] = sum;
    }

    for (register label i=n-1; i>=0; i--)
    {
        Type sum = sourceSol[i];
        const scalar* __restrict__ luMatrixi = luMatrix[i];

        for (register label j=i+1; j<n; j++)
        {
            sum -= luMatrixi[j]*sourceSol[j];
        }

        sourceSol[i] = sum/luMatrixi[i];
    }
}
Ejemplo n.º 6
0
void multiply
(
    scalarSquareMatrix& ans,         // value changed in return
    const scalarDiagonalMatrix& A,
    const scalarSquareMatrix& B,
    const scalarDiagonalMatrix& C
)
{
    if (A.size() != B.n())
    {
        FatalErrorIn
        (
            "multiply("
            "scalarRectangularMatrix& answer),"
            "const DiagonalMatrix<scalar>& A, "
            "const scalarRectangularMatrix& B, "
            "const DiagonalMatrix<scalar>& C"
        )   << "A and B must have identical inner dimensions but A.m = "
            << A.size() << " and B.n = " << B.n()
            << abort(FatalError);
    }
    
    if (B.m() != C.size())
    {
        FatalErrorIn
        (
             "multiply("
            "scalarRectangularMatrix& answer),"
            "const DiagonalMatrix<scalar>& A, "
            "const scalarRectangularMatrix& B, "
            "const DiagonalMatrix<scalar>& C"
        )   << "B and C must have identical inner dimensions but B.m = "
            << B.m() << " and C.n = " << C.size()
            << abort(FatalError);
    }
    
    
    ans = scalarSquareMatrix(B.n(), B.n(), scalar(0));

    for (register label i = 0; i < A.size(); i++)
    {
        for (register label j = 0; j < C.size(); j++)
        {               
            ans[i][j] = A[i] * B[i][j] * C[j];
        }
    }

}
void Foam::solve
(
    scalarSquareMatrix& tmpMatrix,
    Field<Type>& sourceSol
)
{
    label n = tmpMatrix.n();

    // Elimination
    for (register label i=0; i<n; i++)
    {
        label iMax = i;
        scalar largestCoeff = mag(tmpMatrix[iMax][i]);

        // Swap entries around to find a good pivot
        for (register label j=i+1; j<n; j++)
        {
            if (mag(tmpMatrix[j][i]) > largestCoeff)
            {
                iMax = j;
                largestCoeff = mag(tmpMatrix[iMax][i]);
            }
        }

        if (i != iMax)
        {
            //Info<< "Pivoted on " << i << " " << iMax << endl;

            for (register label k=i; k<n; k++)
            {
                Swap(tmpMatrix[i][k], tmpMatrix[iMax][k]);
            }
            Swap(sourceSol[i], sourceSol[iMax]);
        }

        // Check that the system of equations isn't singular
        if (mag(tmpMatrix[i][i]) < 1e-20)
        {
            FatalErrorIn("solve(scalarSquareMatrix&, Field<Type>& sourceSol)")
                << "Singular Matrix"
                << exit(FatalError);
        }

        // Reduce to upper triangular form
        for (register label j=i+1; j<n; j++)
        {
            sourceSol[j] -= sourceSol[i]*(tmpMatrix[j][i]/tmpMatrix[i][i]);

            for (register label k=n-1; k>=i; k--)
            {
                tmpMatrix[j][k] -=
                    tmpMatrix[i][k]*tmpMatrix[j][i]/tmpMatrix[i][i];
            }
        }
    }

    // Back-substitution
    for (register label j=n-1; j>=0; j--)
    {
        Type ntempvec = pTraits<Type>::zero;

        for (register label k=j+1; k<n; k++)
        {
            ntempvec += tmpMatrix[j][k]*sourceSol[k];
        }

        sourceSol[j] = (sourceSol[j] - ntempvec)/tmpMatrix[j][j];
    }
}
void Foam::scalarSquareMatrix::LUDecompose
(
    scalarSquareMatrix& matrix,
    labelList& pivotIndices
)
{
    label n = matrix.n();
    scalar vv[n];

    for (register label i=0; i<n; i++)
    {
        scalar largestCoeff = 0.0;
        scalar temp;
        const scalar* __restrict__ matrixi = matrix[i];

        for (register label j=0; j<n; j++)
        {
            if ((temp = mag(matrixi[j])) > largestCoeff)
            {
                largestCoeff = temp;
            }
        }

        if (largestCoeff == 0.0)
        {
            FatalErrorIn
            (
                "scalarSquareMatrix::LUdecompose"
                "(scalarSquareMatrix& matrix, labelList& rowIndices)"
            )   << "Singular matrix" << exit(FatalError);
        }

        vv[i] = 1.0/largestCoeff;
    }

    for (register label j=0; j<n; j++)
    {
        scalar* __restrict__ matrixj = matrix[j];

        for (register label i=0; i<j; i++)
        {
            scalar* __restrict__ matrixi = matrix[i];

            scalar sum = matrixi[j];
            for (register label k=0; k<i; k++)
            {
                sum -= matrixi[k]*matrix[k][j];
            }
            matrixi[j] = sum;
        }

        label iMax = 0;

        scalar largestCoeff = 0.0;
        for (register label i=j; i<n; i++)
        {
            scalar* __restrict__ matrixi = matrix[i];
            scalar sum = matrixi[j];

            for (register label k=0; k<j; k++)
            {
                sum -= matrixi[k]*matrix[k][j];
            }

            matrixi[j] = sum;

            scalar temp;
            if ((temp = vv[i]*mag(sum)) >= largestCoeff)
            {
                largestCoeff = temp;
                iMax = i;
            }
        }

        pivotIndices[j] = iMax;

        if (j != iMax)
        {
            scalar* __restrict__ matrixiMax = matrix[iMax];

            for (register label k=0; k<n; k++)
            {
                Swap(matrixj[k], matrixiMax[k]);
            }

            vv[iMax] = vv[j];
        }

        if (matrixj[j] == 0.0)
        {
            matrixj[j] = SMALL;
        }

        if (j != n-1)
        {
            scalar rDiag = 1.0/matrixj[j];

            for (register label i=j+1; i<n; i++)
            {
                matrix[i][j] *= rDiag;
            }
        }
    }
}