Cancel
Showing results for 
Search instead for 
Did you mean: 

Load eigenvectors and modes in femap API

Experimenter
Experimenter

Hi all,

 

I've done an 'Normal Modes/Eigenvalue' analysis in femap and for further calculation I need to load the eigenvectors and modes in femap API.

I'm new to femap API or rather new to femap in general. Can anyone help me to find the necessary command?

 

Thanks in advance!

6 REPLIES

Re: Load eigenvectors and modes in femap API

Siemens Phenom Siemens Phenom
Siemens Phenom

When you say eigenvectors, do you mean all vectors for all output sets or just certain ones?  Both can be done via API. 

Here's a small sample that uses the ".value" method on an OutputSet object to grab Eigenvalues.  It also filters the Results Set titles to grab the Mode.

 

 

The HTML Clipboard

Sub Main
    Dim App As femap.model
    Set App = feFemap()

    Dim oSet As OutputSet
    Set oSet = App.feOutputSet

    'Capture messages for bulk printing
    App.feAppMessageStartListing()

    While oSet.Next()
        title = oSet.title
        i = 0
        While rc<>FE_OK
            isMode = Right(title,i)
            getMode = Left(isMode,4)
            If getMode = "Mode" Then
                isMode = Left(isMode,InStr(isMode,","))
                isMode = Replace(isMode,"Mode","")
                isMode = Replace(isMode,",","")
                Exit While
            End If
            i += 1
            'End program if no modes exist in results sets
            If i = 10000 Then
                App.feAppMessage(FCM_NORMAL,"Results Titles Missing Keyword, Mode")
                App.feAppMessageEndListing()
                End
            End If
        Wend

        'Print To Message Pane
        App.feAppMessage(FCM_NORMAL,"Resulsts Set:"+Str(oSet.ID)+", Mode = "+isMode+", Eigenvalue = "+Str$(oSet.value))
    Wend

    'Send all messages to Message Pane
    App.feAppMessageEndListing()

End Sub

Re: Load eigenvectors and modes in femap API

Experimenter
Experimenter

Thank you for the quick response!

 

This code helped me a lot, bit if I understand it correctly it sweeps through all output sets of all existing analyses. If there is more than one analysis, how can I assure that I get the values from the right one? My idea is to get it via the active view (App.feView), but maybe there is a better way?

 

With eigenvectors I meant the translations in x, y and z direction for each node in each mode. I can get these values by oSet.vector(2), oSet.vector(3) and oSet.vector(4). I thought there would be a possiblity to get these values in a huge matrix, but this seems not possible? So I defined a matrix which I'm going to fill manually. This is my code so far:

 

Sub Main
    Dim App As femap.model
    Set App = feFemap()

    Dim oSet As OutputSet
    Set oSet = App.feOutputSet

    'matrix of eigenvectors, define dimensions
    Dim matrix_eigenvectors() As Variant
    Dim no_modes As Integer
    no_modes=oSet.CountSet
    ReDim matrix_eigenvectors(node_count*3, no_modes)

    'translations in x,y and z direction
    Dim x_trans As Object
    Dim y_trans As Object
    Dim z_trans As Object

    'Capture messages for bulk printing
    App.feAppMessageStartListing()

    While oSet.Next()
        title = oSet.title
        i = 0
        While rc<>FE_OK
            isMode = Right(title,i)
            getMode = Left(isMode,4)
            If getMode = "Mode" Then
                isMode = Left(isMode,InStr(isMode,","))
                isMode = Replace(isMode,"Mode","")
                isMode = Replace(isMode,",","")
                Exit While
            End If
            i += 1
            'End program if no modes exist in results sets
            If i = 10000 Then
                App.feAppMessage(FCM_NORMAL,"Results Titles Missing Keyword, Mode")
                App.feAppMessageEndListing()
                End
            End If
        Wend

        Set x_trans=oSet.Vector(2)
        Set y_trans=oSet.Vector(3)
        Set z_trans=oSet.Vector(4)


        'Print To Message Pane
        App.feAppMessage(FCM_NORMAL,"Resulsts Set:"+Str(oSet.ID)+", Mode = "+isMode+", Eigenvalue = "+Str$(oSet.value))
    Wend

    'Send all messages to Message Pane
    App.feAppMessageEndListing()

End Sub

 

Re: Load eigenvectors and modes in femap API

Siemens Phenom Siemens Phenom
Siemens Phenom

Could you send or poste a sample of your different Results Sets?  Also, you'll want to make use of the Results Browsing Object to grab the vector data the way you mentioned.  Try the API below - it uses the RBO to populate a virtual spreadsheet for x,y,z translation vectors from all modal output.  Then a matrix is populated with all values for easy indexing.

 

The HTML Clipboard

Sub Main
    Dim App As femap.model
    Set App = feFemap()

    Dim oSet As OutputSet
    Set oSet = App.feOutputSet

    'matrix of eigenvectors, define dimensions
    Dim matrix_eigenvectors() As Variant
    Dim no_modes As Integer
    no_modes=oSet.CountSet
    ReDim matrix_eigenvectors(node_count*3, no_modes)

    'translations in x,y and z direction
    Dim x_trans As Object
    Dim y_trans As Object
    Dim z_trans As Object

    '**********************************August 3, 2017***********************************
    Dim cRes As Results ' Results Browsing Object (RBO)
            'Dim cRes as Object
            '^ Equally valid syntax, although you loose intellisense
    Set cRes = App.feResults

    'For the Results Browsing Object
    Dim numbCols As Long
    Dim indCols As Variant, nIDvar As Variant, dVals As Variant

    Dim dTable As DataTable
    Set dTable = App.feDataTable
    '**********************************August 3, 2017***********************************

    'Capture messages for bulk printing
    App.feAppMessageStartListing()

    'Counter for matrix population later
    ResultsCount = 0
    While oSet.Next()
        title = oSet.title
        i = 0
        While rc<>FE_OK
            isMode = Right(title,i)
            getMode = Left(isMode,4)
            If getMode = "Mode" Then
                isMode = Left(isMode,InStr(isMode,","))
                isMode = Replace(isMode,"Mode","")
                isMode = Replace(isMode,",","")
                Exit While
            End If
            i += 1
            'End program if no modes exist in results sets
            If i = 10000 Then
                App.feAppMessage(FCM_NORMAL,"Results Titles Missing Keyword, Mode")
                App.feAppMessageEndListing()
                GoTo Out
            End If
        Wend

        Set x_trans=oSet.Vector(2)
        Set y_trans=oSet.Vector(3)
        Set z_trans=oSet.Vector(4)


        'Print To Message Pane
        App.feAppMessage(FCM_NORMAL,"Resulsts Set:"+Str(oSet.ID)+", Mode = "+isMode+", Eigenvalue = "+Str$(oSet.value))
        ResultsCount += 1

        cRes.AddColumn(oSet.ID,2,False,numbCols,indCols) 'X Translation
        cRes.AddColumn(oSet.ID,3,False,numbCols,indCols) 'Y Translation
        cRes.AddColumn(oSet.ID,4,False,numbCols,indCols) 'Z Translation
    Wend
Out:
        'Make the Data Table Appear
        App.feAppManagePanes("Data Table",1)

        'Make sure Data Table is Unlocked
        dTable.Lock(False)

        'Need to call ".Populate" method to fill RBO
        cRes.Populate()
        'Useful for debugging.  Visualize the virtual RBO by sending to Data Table
        cRes.SendToDataTable()

        'Copy everything in the Data Table to clipboard (easily paste into Excel!)
        dTable.Copy(True)

        Dim nSet As Set
        Set nSet = App.feSet
        nSet.AddAll(FT_NODE)

        ReDim matrix_eigenvectors(ResultsCount*3,nSet.Count)

        For j = 0 To 3*ResultsCount-1
            cRes.GetColumn(j,nIDvar,dVals)
            For k = 0 To UBound(dVals)
                matrix_eigenvectors(j,k) = dVals(k)
            Next
        Next

    'Send all messages to Message Pane
    App.feAppMessageEndListing()

End Sub

Re: Load eigenvectors and modes in femap API

Experimenter
Experimenter

This seems to be a very elegant way to produce a matrix, but it does not do exactly what I want to do.

I want to create a matrix in which each column stands for one mode (only one column for each mode). These columns should contain the values in the following order: x-translation of node 1, y-translation of node 1, z-translation of node 1, x-translation of node 2, y-translation of node 2, z-translation of node 2, ...

I tried to implement a routine, which should give a better idea of my intension. But the routine doesn't work.

 

The problem with the different results sets I solved by letting the user choose the relevant set(s).

 

Here's my modified code:

Sub Main

    Dim ModeShapes_Set As femap.Set
Set ModeShapes_Set = App.feSet Dim ModeShapes_oSet As OutputSet Set ModeShapes_oSet = App.feOutputSet 'node count for matrix dimension Dim nodes As Set Set nodes = App.feSet nodes.AddAll(FT_NODE) Dim node_count As Integer node_count=nodes.Count 'define matrix for eigenvectors Dim matrix_eigenvectors() As Variant
'define variables that act as indices for matrix Dim idx_row As Integer Dim idx_column As Integer idx_row = 0 idx_column = 0 'define array for eigenfrequencies (=eigenvalues) Dim eigenfreq As Variant 'translation vectors in x, y and z direction Dim x_trans As Object Dim y_trans As Object Dim z_trans As Object 'single translation value Dim translation As Double 'Capture messages for bulk printing App.feAppMessageStartListing() 'Select Output Set(s) to choose results from this (these) output set(s) App.feSelectOutputSets("Select Output Set Of Modal Analysis", ModeShapes_Set) Dim no_modes As Integer no_modes=0 While ModeShapes_Set.Next() ModeShapes_oSet.Get(ModeShapes_Set.CurrentID) 'update number of modes no_modes+=1 'update dimensions of matrix for eigenvectors ReDim matrix_eigenvectors(node_count*3, no_modes) 'update list for eigenfrequencies ReDim eigenfreq(no_modes) eigenfreq(no_modes-1) = ModeShapes_oSet.value 'get mode number from title title = ModeShapes_oSet.title Dim part_title As String part_title=Left(title, InStr(title,",")-1) part_title=Mid(part_title,6) 'Print To Message Pane App.feAppMessage(FCM_NORMAL, "Resulsts Set:"+Str(ModeShapes_oSet.ID)+", Mode = "+part_title+", Eigenvalue = "+Str$(ModeShapes_oSet.value)) 'translations of actual mode Set x_trans=ModeShapes_oSet.Vector(2) Set y_trans=ModeShapes_oSet.Vector(3) Set z_trans=ModeShapes_oSet.Vector(4) '########### this is what I want to realize ############# 'loop to fill in matrix components For trans_ID=0 To x_trans.Count 'I need the number of nodes, i.e. length of the above vectors matrix_eigenvectors(0+idx_row*3, idx_column) = x_trans(trans_ID) matrix_eigenvectors(1+idx_row*3, idx_column) = y_trans(trans_ID) matrix_eigenvectors(3+idx_row*3, idx_column) = z_trans(trans_ID) Next Wend 'Send all messages to Message Pane App.feAppMessageEndListing() End Sub

Re: Load eigenvectors and modes in femap API

Siemens Phenom Siemens Phenom
Siemens Phenom

I believe I have your solution.  I would still advise to use the Results Browsing Object as it is a more efficient means of quering large amounts of data.  I use the RBO in the API below, then simply grab a row at a time and fill a matrix the way you are looking for.  I print to the messages window, but you can also more easily visualize it in Excel if you uncomment Line 120.  You will need to add the Excel Type Library beforhand - simply right-click in the API pane and add the reference.

 

The HTML Clipboard

Sub Main
    Dim App As femap.model
    Set App = feFemap()

    Dim ModeShapes_Set As femap.Set
    Set ModeShapes_Set = App.feSet

    Dim ModeShapes_oSet As OutputSet
    Set ModeShapes_oSet = App.feOutputSet

    Dim cRes As Results ' Results Browsing Object (RBO)
    Dim numbCols As Long, indCols As Variant, nIDs As Long, dVals As Variant
    Dim dTable As femap.DataTable
        Set cRes = App.feResults
        Set dTable = App.feDataTable

    'node count for matrix dimension
    Dim nodes As Set
    Set nodes = App.feSet
    nodes.AddAll(FT_NODE)
    Dim node_count As Integer
    node_count=nodes.Count

    'define matrix for eigenvectors
    Dim matrix_eigenvectors() As Variant
    'define variables that act as indices for matrix
    Dim idx_row As Integer
    Dim idx_column As Integer
    idx_row = 0
    idx_column = 0
    'define array for eigenfrequencies (=eigenvalues)
    Dim eigenfreq As Variant

    'translation vectors in x, y and z direction
    'Dim x_trans As Object
    Dim y_trans As Object
    Dim z_trans As Object
    'single translation value
    Dim translation As Double

    'Capture messages for bulk printing
    'App.feAppMessageStartListing()

    'Select Output Set(s) to choose results from this (these) output set(s)
    App.feSelectOutputSets("Select Output Set Of Modal Analysis", ModeShapes_Set)

    Dim no_modes As Integer
    no_modes=0

    While ModeShapes_Set.Next()

        ModeShapes_oSet.Get(ModeShapes_Set.CurrentID)

        'update number of modes
        no_modes+=1
        'update dimensions of matrix for eigenvectors
        ReDim matrix_eigenvectors(node_count*3, 3*no_modes*node_count)
        'update list for eigenfrequencies
        ReDim eigenfreq(no_modes)
        eigenfreq(no_modes-1) = ModeShapes_oSet.value

        'get mode number from title
        title = ModeShapes_oSet.title
        Dim part_title As String
        part_title=Left(title, InStr(title,",")-1)
        part_title=Mid(part_title,6)

        'Print To Message Pane
        App.feAppMessage(FCM_NORMAL, "Resulsts Set:"+Str(ModeShapes_oSet.ID)+", Mode = "+part_title+", Eigenvalue = "+Str$(ModeShapes_oSet.value))

        'translations of actual mode
'        Set x_trans =ModeShapes_oSet.Vector(2)
'        Set y_trans=ModeShapes_oSet.Vector(3)
'        Set z_trans=ModeShapes_oSet.Vector(4)

        cRes.AddColumn(ModeShapes_oSet.ID,2,False,numbCols,indCols) 'X Translation
        cRes.AddColumn(ModeShapes_oSet.ID,3,False,numbCols,indCols) 'Y Translation
        cRes.AddColumn(ModeShapes_oSet.ID,4,False,numbCols,indCols) 'Z Translation

        '########### this is what I want to realize #############
        'loop to fill in matrix components
'        For trans_ID=0 To x_trans.Count                                                                  'I need the number of nodes, i.e. length of the above vectors
'           matrix_eigenvectors(0+idx_row*3, idx_column) = x_trans(trans_ID)
'           matrix_eigenvectors(1+idx_row*3, idx_column) = y_trans(trans_ID)
'           matrix_eigenvectors(3+idx_row*3, idx_column) = z_trans(trans_ID)
'        Next

    Wend
    cRes.Populate()
    cRes.SendToDataTable()

    'Send all messages to Message Pane
    App.feAppMessageEndListing()

    App.feAppMessageStartListing()

    j = 0
    k = 0
        While nodes.Next()
            cRes.GetRow(q,nIDs,dVals)
            For a = 0 To UBound(dVals)-1
                For i = k To k+2
                    matrix_eigenvectors(i,j) = dVals(a)
                    App.feAppMessage(FCM_NORMAL,"m("+Str(i)+","+Str(j)+")"+Str(matrix_eigenvectors(i,j)))
                    a += 1
                Next
                a-=1
                j+=1
            Next
            j = 0
            q += 1
            k += 3
        Wend

    'Send all messages to Message Pane
    App.feAppMessageEndListing()

    'Uncomment below to call Excel sub.  Add Excel Type Library first (Right-click and choose 'References')
    'Useful for debugging
    'ExcelPaste(matrix_eigenvectors)


End Sub
Sub ExcelPaste(matrix_eigenvectors)

    Dim appExcel As Excel.Application
    Set appExcel =  New Excel.Application

    Dim wb As Excel.Workbook
    Set wb = appExcel.Workbooks.Add

    Dim ws As Excel.Worksheet
    Set ws = wb.ActiveSheet

    appExcel.Visible = True

    ws.Range("A1:ZZ9999").Value2 = matrix_eigenvectors
End Sub

Re: Load eigenvectors and modes in femap API

Experimenter
Experimenter

Yes, that's what I was looking for. Thank you so much for your help! Also for your advice to use the RBO and check it by data table/excel.