# How can I extract participation factors of a modal analysis?

Member, Moderator, Employee Posts: 867
✭✭✭✭
edited June 2023

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

Tagged:

• Member, Moderator, Employee Posts: 867
✭✭✭✭

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


• Member, Employee Posts: 330
✭✭✭✭

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?

• Member, Moderator, Employee Posts: 867
✭✭✭✭

@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.

• Member Posts: 21
**

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

• Member, Moderator, Employee Posts: 867
✭✭✭✭

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

• Member, Employee Posts: 290
✭✭✭✭
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

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?

• Member, Moderator, Employee Posts: 444
✭✭✭✭

@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()
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)