When extracting Frequency Response Results with PyMechanical the order of operations performed on the real and imaginary parts to calculate the amplitude is important. Analogous to vector operations, accumulating the real and imaginary components separately, before combining them to calculate the amplitude is mandatory.
This might sound obvious, but doing the amplitude calculation first and then the accumulation and averaging, is a trap that is easy to fall into.
def after_post(this, solution):# Do not edit this line
"""
Called after post processing.
Keyword Arguments :
this -- the datamodel object instance of the python code object you are currently editing in the tree
solution -- Solution
"""
import os
import wbjn
import Ans.DataProcessing as dpf
# RESULTS FILE NAME
myResName = 'Freq_amp'
dpn = wbjn.ExecuteCommand(ExtAPI,"returnValue(a+Parameters.GetActiveDesignPoint().Name)",a="DP")
projectDir = wbjn.ExecuteCommand(ExtAPI,"returnValue(GetUserFilesDirectory())")
filePath = os.path.join(projectDir,dpn + '_' + myResName + '.txt')
if os.path.isfile(filePath):
os.remove(filePath) #Remove old file if exists
# DEFINE DATASOURCE --> .RST/.RTH
dataSource = dpf.DataSources(solution.Parent.ResultFileName) # Use in Tree for solution
# GET TIMESTEPS OR FREQUENCIES
freqlist = dpf.operators.metadata.time_freq_provider(data_sources=dataSource).outputs.gettime_freq_support().TimeFreqs.Data
# GET RESULT FIELD CONTAINER (e.g. Acceleration in Z direction)
ACC_Z = dpf.operators.result.acceleration_Z(time_scoping=freqlist, data_sources=dataSource).outputs.getfields_container()
# OPERATE ON RESULT
# 1. Calculate Accumulated results component-wise (real, imaginary) over all nodes
accum = dpf.operators.math.accumulate_fc(fields_container=ACC_Z)
# 2. Calculate Average over all Nodes
avg = dpf.operators.math.scale_fc(fields_container=accum, ponderation=1.0/ACC_Z[0].ElementaryDataCount)
# 3. Calculate Amplitude of Real/Imaginary Data
amp = dpf.operators.math.amplitude_fc(fields_container=avg)
#WRITE TO FILE
with open(filePath,'w') as f:
# write column headers
f.write( 'Frequency, Amplitude')
f.write('\n')
for i, freq in enumerate(freqlist):
f.write( str(freq) + ', ' + str(amp.outputs.getfields_container()[i].Data[0]) )
f.write('\n')
pass