How can I extract participation factors of a modal analysis?

Pernelle Marone-Hitz
Pernelle Marone-Hitz Member, Moderator, Employee Posts: 867
500 Comments Photogenic Name Dropper Solution Developer Community of Practice Member
✭✭✭✭
edited June 2023 in Structures

How can I extract participation factors or ratio of effective mass of a modal analysis through scripting?

Tagged:

Best Answer

  • Pernelle Marone-Hitz
    Pernelle Marone-Hitz Member, Moderator, Employee Posts: 867
    500 Comments Photogenic Name Dropper Solution Developer Community of Practice Member
    ✭✭✭✭
    Answer ✓

    Participation factors and similar results are not exposed in GetResultsData.A workaround is to open and read the solver output file to access the information. The following code will extract the ratio of effective mass to total mass:

        # Read solve.out file and store it line by line
            import os
            FileDir=ExtAPI.DataModel.AnalysisList[0].WorkingDir
            TextFile='solve.out'
            SolveOutLines = [] #Declare an empty list named "lines"
                
            with open(os.path.join(FileDir, TextFile), "r") as in_file:  
                for line in in_file: #For each line of text store in a string variable named "SolveOutLines", and
                    SolveOutLines.append(line)  #add that line to list of lines.
                    
            # Create dictionnaries to store frequencies and participation factors (in fact will store ratio of effective mass to total mass)
            RatioX={}
            RatioY={}
            RatioZ={}
    
            # In SolveOutLines search for participation factors
            for line in range(len(SolveOutLines)):
                if SolveOutLines[line]=='          ***** PARTICIPATION FACTOR CALCULATION *****  X  DIRECTION\n' :
                    LineStart=line+3
                    LineEnd=LineStart+NumberOfModes
                    for i in range(LineStart,LineEnd):
                        temp_list=SolveOutLines[i].split(' ') # split text at ' '
                        temp_list2=[]
                        for j in range(len(temp_list)):
                            if temp_list[j] != '' :
                                temp_list2.append(temp_list[j])
                        RatioX[temp_list2[1]]=temp_list2[7]
                elif SolveOutLines[line]=='          ***** PARTICIPATION FACTOR CALCULATION *****  Y  DIRECTION\n' :
                    LineStart=line+3
                    LineEnd=LineStart+NumberOfModes
                    for i in range(LineStart,LineEnd):
                        temp_list=SolveOutLines[i].split(' ') # split text at ' '
                        temp_list2=[]
                        for j in range(len(temp_list)):
                            if temp_list[j] != '' :
                                temp_list2.append(temp_list[j])
                        RatioY[temp_list2[1]]=temp_list2[7]
                elif SolveOutLines[line]=='          ***** PARTICIPATION FACTOR CALCULATION *****  Z  DIRECTION\n' :
                    LineStart=line+3
                    LineEnd=LineStart+NumberOfModes
                    for i in range(LineStart,LineEnd):
                        temp_list=SolveOutLines[i].split(' ') # split text at ' '
                        temp_list2=[]
                        for j in range(len(temp_list)):
                            if temp_list[j] != '' :
                                temp_list2.append(temp_list[j])
                        RatioZ[temp_list2[1]]=temp_list2[7]
                        
            # Deal with numbers that have ('\n') due to exponent coding
            CorrectX=RatioX.values()
            for i in range(len(CorrectX)):
                temp_str=CorrectX[i].split('\n')
                CorrectX[i]=temp_str[0]
            j=0
            for i in RatioX:
                RatioX[i]=CorrectX[j]
                j=j+1   
            CorrectY=RatioY.values()
            for i in range(len(CorrectY)):
                temp_str=CorrectY[i].split('\n')
                CorrectY[i]=temp_str[0]
            j=0
            for i in RatioY:
                RatioY[i]=CorrectY[j]
                j=j+1
            CorrectZ=RatioZ.values()
            for i in range(len(CorrectZ)):
                temp_str=CorrectZ[i].split('\n')
                CorrectZ[i]=temp_str[0]
            j=0
            for i in RatioZ:
                RatioZ[i]=CorrectZ[j]
                j=j+1
    

Answers

  • Mike.Thompson
    Mike.Thompson Member, Employee Posts: 330
    25 Answers First Anniversary 100 Comments 25 Likes
    ✭✭✭✭

    @Pernelle Marone-Hitz ,

    Is there any way to get the participation factors more directly other than parsing the text of the solve.out file? They are reported in the Solution Information object in the worksheet, so Mechanical must have the data stored somewhere internally, correct?

  • Pernelle Marone-Hitz
    Pernelle Marone-Hitz Member, Moderator, Employee Posts: 867
    500 Comments Photogenic Name Dropper Solution Developer Community of Practice Member
    ✭✭✭✭

    @Mike.Thompson That's a very old post, initially from 2018 (?). At the time there was no better solution, I haven't checked more recent versions, but it would be great to have a better solution.

  • dafedin
    dafedin Member Posts: 21
    First Anniversary 10 Comments Name Dropper
    **

    Hello @Pernelle Marone-Hitz

    Is there a solution for getting data from the Solution Worksheet like Component Names, component items Ids etc.?

  • Pernelle Marone-Hitz
    Pernelle Marone-Hitz Member, Moderator, Employee Posts: 867
    500 Comments Photogenic Name Dropper Solution Developer Community of Practice Member
    ✭✭✭✭

    A new DPF operator was recently added to read modal participation factors from the mode file:
    ansys.dpf.core.operators.result.spectrum_data.spectrum_data
    See:
    https://dpf.docs.pyansys.com/version/dev/api/ansys.dpf.core.operators.result.spectrum_data.html#ansys.dpf.core.operators.result.spectrum_data.OutputsSpectrumData.participation_factors

  • Landon Mitchell Kanner
    Landon Mitchell Kanner Member, Employee Posts: 290
    100 Comments 25 Answers 25 Likes Photogenic
    ✭✭✭✭
    edited August 14

    The DPF operator is giving the follow error:
    OSError: exception: access violation reading 0x0000000000000000

    Here is the code:

    from ansys.dpf import core as dpf
    from ansys.dpf.core import animation
    from ansys.dpf.core import examples
    
    my_data_sources = dpf.DataSources(examples.download_modal_frame())
    op = dpf.operators.result.spectrum_data(data_sources=my_data_sources)
    result_participation_factors = op.outputs.participation_factors()
    

    And here is the Traceback:

    Traceback (most recent call last):
    File "", line 1, in
    File "C:\Users\lmkanner\AppData\Local\Programs\Python\Python310\lib\site-packages\ansys\dpf\core\outputs.py", line 75, in call
    return self.get_data()
    File "C:\Users\lmkanner\AppData\Local\Programs\Python\Python310\lib\site-packages\ansys\dpf\core\outputs.py", line 72, in get_data
    return self._operator.get_output(self._pin, type_output)
    File "C:\Users\lmkanner\AppData\Local\Programs\Python\Python310\lib\site-packages\ansys\dpf\core\dpf_operator.py", line 543, in get_output
    internal_obj = type_tuple[1](self, pin)
    File "C:\Users\lmkanner\AppData\Local\Programs\Python\Python310\lib\site-packages\ansys\dpf\gate\generated\operator_capi.py", line 420, in operator_getoutput_fields_container
    res = capi.dll.Operator_getoutput_FieldsContainer(op._internal_obj if op is not None else None, utils.to_int32(iOutput), ctypes.byref(utils.to_int32(errorSize)), ctypes.byref(sError))
    OSError: exception: access violation reading 0x0000000000000000

    Any idea what is the cause?

  • Ayush Kumar
    Ayush Kumar Member, Moderator, Employee Posts: 444
    250 Likes Solution Developer Community of Practice Member Ansys Employee First Anniversary
    ✭✭✭✭

    @Landon Mitchell Kanner can you try the following code? The participation factors are in the mode file, that must be added to the Data Sources.

    from ansys.dpf import core as dpf
    ds = dpf.DataSources()
    ds.add_file_path(r"\Path\to\file.mode")
    sd = dpf.Operator(r"spectrum_data")
    sd.inputs.data_sources.connect(ds)
    pf_fc = sd.outputs.participation_factors.get_data()
    print(pf_fc)
    print(pf_fc[1].data)