Search Icon

Accessing FEA data, resonant frequency analysis

For any ordinary type of standard analysis tasks, and even for the bulk of advanced tasks O-Calc Pro has reports and tools provided for you to use. On occasion however there will be some form of analysis or manipulation that requires deep and advanced access to elements or calculated values. In this post we will dive into an example of just such an analysis.

One task we might want to perform is a resonant frequency response analysis for the structure. Since we have a complete finite element analysis model of the structure being processed we have (by definition) a stiffness matrix (k), a mass matrix (m), and a damping matrix (d) for all of the elements in the model. This makes it relatively simple to determine our frequency response by doing a Eigen-extract on the matrix pairs.

Let’s dive into how this can be done..

private List < Accord. Math . Decompositions . GeneralizedEigenvalueDecomposition > EigenExrtact ()
{
List < Accord. Math . Decompositions . GeneralizedEigenvalueDecomposition > result =
new List < Accord. Math . Decompositions . GeneralizedEigenvalueDecomposition >() ;
if ( ! ( cPPLMain. CurrentPoleLoadInfo is PoleLoadInfoFEM )) return result;
PoleLoadInfoFEM pfem = ( cPPLMain. CurrentPoleLoadInfo as PoleLoadInfoFEM ) ;
PFEA. PPLFEM_GEN2 analysis = ( pfem. cCurrentEngine as PFEA. PPLFEM_GEN2 ) ;
analysis. SolveCycle ( PFEA. FiniteElementBase . Algorithm . CholeskyDecomposition ) ;
foreach ( PPF. BeamBase elem in analysis. Solver . Elements )
{
PPF. Matrix k = elem. GetGlobalStifnessMatrix () ;
PPF. Matrix m = elem. GetGlobalMassMatrix () ;
Accord. Math . Decompositions . GeneralizedEigenvalueDecomposition eigen =
new Accord. Math . Decompositions . GeneralizedEigenvalueDecomposition ( MatrixToArray ( k ) , MatrixToArray ( m )) ;
result. Add ( eigen ) ;
}
return result;
}
private double [ , ] MatrixToArray ( PPF. Matrix pMatrix )
{
double [ , ] result = new double [ pMatrix. ColumnCount , pMatrix. RowCount ] ;
for ( int x = 0 ; x < pMatrix. ColumnCount ; x++ )
{
for ( int y = 0 ; y < pMatrix. RowCount ; y++ )
{
result [ x, y ] = pMatrix [ x, y ] ;
}
}
return result;
}
private List<Accord.Math.Decompositions.GeneralizedEigenvalueDecomposition> EigenExrtact() { List<Accord.Math.Decompositions.GeneralizedEigenvalueDecomposition> result = new List<Accord.Math.Decompositions.GeneralizedEigenvalueDecomposition>(); if (!(cPPLMain.CurrentPoleLoadInfo is PoleLoadInfoFEM)) return result; PoleLoadInfoFEM pfem = (cPPLMain.CurrentPoleLoadInfo as PoleLoadInfoFEM); PFEA.PPLFEM_GEN2 analysis = (pfem.cCurrentEngine as PFEA.PPLFEM_GEN2); analysis.SolveCycle(PFEA.FiniteElementBase.Algorithm.CholeskyDecomposition); foreach (PPF.BeamBase elem in analysis.Solver.Elements) { PPF.Matrix k = elem.GetGlobalStifnessMatrix(); PPF.Matrix m = elem.GetGlobalMassMatrix(); Accord.Math.Decompositions.GeneralizedEigenvalueDecomposition eigen = new Accord.Math.Decompositions.GeneralizedEigenvalueDecomposition(MatrixToArray(k), MatrixToArray(m)); result.Add(eigen); } return result; } private double[,] MatrixToArray(PPF.Matrix pMatrix) { double[,] result = new double[pMatrix.ColumnCount, pMatrix.RowCount]; for (int x = 0; x < pMatrix.ColumnCount; x++) { for (int y = 0; y < pMatrix.RowCount; y++) { result[x, y] = pMatrix[x, y]; } } return result; }
private List<Accord.Math.Decompositions.GeneralizedEigenvalueDecomposition> EigenExrtact()
{
    List<Accord.Math.Decompositions.GeneralizedEigenvalueDecomposition> result = 
        new List<Accord.Math.Decompositions.GeneralizedEigenvalueDecomposition>();

    if (!(cPPLMain.CurrentPoleLoadInfo is PoleLoadInfoFEM)) return result;

    PoleLoadInfoFEM pfem = (cPPLMain.CurrentPoleLoadInfo as PoleLoadInfoFEM);

    PFEA.PPLFEM_GEN2 analysis = (pfem.cCurrentEngine as PFEA.PPLFEM_GEN2);

    analysis.SolveCycle(PFEA.FiniteElementBase.Algorithm.CholeskyDecomposition);
    foreach (PPF.BeamBase elem in analysis.Solver.Elements)
    {
        PPF.Matrix k = elem.GetGlobalStifnessMatrix();
        PPF.Matrix m = elem.GetGlobalMassMatrix();

        Accord.Math.Decompositions.GeneralizedEigenvalueDecomposition eigen = 
            new Accord.Math.Decompositions.GeneralizedEigenvalueDecomposition(MatrixToArray(k), MatrixToArray(m));

        result.Add(eigen);
    }

    return result;
}

private double[,] MatrixToArray(PPF.Matrix pMatrix)
{
    double[,] result = new double[pMatrix.ColumnCount, pMatrix.RowCount];
    for (int x = 0; x < pMatrix.ColumnCount; x++)
    {
        for (int y = 0; y < pMatrix.RowCount; y++)
        {
            result[x, y] = pMatrix[x, y];
        }
    }
    return result;
}

In this example we are using the Accord .NET Framework ( http://accord-framework.net/ ) to perform the Eigen extraction. For reference purposes the GeneralizedEigenvalueDecomposition class is exactly the same as the eig(k,m) function in Matlab. The result is an eigenvalue array and an eigenvector matrix.

From this example we can see that even the very deepest values from the FEA engine are accessible to report and plugin authors. As a result O-Calc Pro allows developers to develop a range of tools and reports that can perform many more types of operations than are allowed by other tools and platforms that are available.

Contact your local Osmose professional.