How can I extract participation factors of a modal analysis?

Pernelle Marone-Hitz
Pernelle Marone-Hitz Member, Moderator, Employee Posts: 871
100 Answers 500 Comments 250 Likes First Anniversary
✭✭✭✭
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: 871
    100 Answers 500 Comments 250 Likes First Anniversary
    ✭✭✭✭
    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: 356
    25 Answers 100 Comments Second Anniversary 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: 871
    100 Answers 500 Comments 250 Likes First Anniversary
    ✭✭✭✭

    @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
    10 Comments First Anniversary 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: 871
    100 Answers 500 Comments 250 Likes First Anniversary
    ✭✭✭✭

    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, GitHub-issue-creator Posts: 315
    50 Answers 100 Comments Second Anniversary 25 Likes
    ✭✭✭✭
    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: 467
    100 Answers 250 Likes 100 Comments Second 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)