The following code extracts the Tabular Data of Joint Force Probes seen in Mechanical to a CSV file. The file is saved in the user_files folder in the Workbench Project folder.
In contrary to other solutions in this Forum (https://discuss.ansys.com/discussion/255/how-to-access-tabular-data-using-act)
this one works without the Mechanical Window to be open and therefore allows for batch-mode execution for automation with, Ansys optiSLang, for instance.
A similar solution for exporting Tabular Data of Min, Max, Avg Field Results seen in Mechanical (e.g. von mises stress, deformation, etc.) can be found here: https://discuss.ansys.com/discussion/4747/extract-tabular-data-min-max-avg-of-field-results-to-csv-file

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 mech_dpf
import Ans.DataProcessing as dpf
import os
import wbjn
mech_dpf.setExtAPI(ExtAPI)
dpn = wbjn.ExecuteCommand(ExtAPI,"returnValue(a+Parameters.GetActiveDesignPoint().Name)",a="dp")
projectDir = wbjn.ExecuteCommand(ExtAPI,"returnValue(GetUserFilesDirectory())")
myResName = 'Sim_jointprobe_force'
# GET SOLUTION SOURCE (uncomment to use outside of this method or in scripting editor)
solution = Model.Analyses[0].Solution
#GET DATA SOURCE (i.e. result file)
dataSource = dpf.DataSources(solution.Parent.ResultFileName)
# GET TIMESTEPS OR FREQUENCIES
time_op = dpf.operators.metadata.time_freq_provider(data_sources=dataSource).outputs.gettime_freq_support().TimeFreqs
time = time_op.Data
time_unit = time_op.Unit
# GET JOINT ELEMENT ID (CHANGE NAME OF JOINT OBJ ACCORDINGLY)
jointObj = DataModel.GetObjectsByName("Translational - Ground To joint_close")[0]
jointElemId = solution.SolverData.GetObjectData(jointObj).ElementId
joint_scoping = dpf.MeshScopingFactory.ElementalScoping([jointElemId])
# GET FORCE COMPONENTS RESULTS (ITEM INDEX = 1,2,3 --> Forces X, Y, Z)
funit = DataModel.CurrentUnitFromQuantityName("Force")
fx = dpf.operators.result.smisc(item_index = 1, data_sources=dataSource, time_scoping = time, mesh_scoping=joint_scoping).outputs.getfields_container()
fy = dpf.operators.result.smisc(item_index = 2, data_sources=dataSource, time_scoping = time, mesh_scoping=joint_scoping).outputs.getfields_container()
fz = dpf.operators.result.smisc(item_index = 3, data_sources=dataSource, time_scoping = time, mesh_scoping=joint_scoping).outputs.getfields_container()
# CALCULATE TOTAL FORCE
fxsqr = dpf.operators.math.sqr_fc(fx).outputs.getfields_container()
fysqr = dpf.operators.math.sqr_fc(fy).outputs.getfields_container()
fzsqr = dpf.operators.math.sqr_fc(fz).outputs.getfields_container()
fxysqr = dpf.operators.math.add_fc(fxsqr, fysqr).outputs.getfields_container()
fxyzsqr = dpf.operators.math.add_fc(fxysqr, fzsqr).outputs.getfields_container()
ftot = dpf.operators.math.sqrt_fc(fxyzsqr).outputs.getfields_container()
# GET TABLE as List []
fx_table, fy_table, fz_table, ftot_table = [], [], [], []
for i in range(time_op.Data.Count):
fx_table.append(fx[i].Data[0])
fy_table.append(fy[i].Data[0])
fz_table.append(fz[i].Data[0])
ftot_table.append(ftot[i].Data[0])
# WRITE TO CSV FILE
filePath = os.path.join(projectDir,dpn + '_' + myResName + '.csv')
if os.path.isfile(filePath):
os.remove(filePath)
with open(filePath,'w') as f:
#Header
f.write('Time ['+time_unit+'], Joint Probe (Total Force X) ['+funit+'], Joint Probe (Total Force Y) ['+funit+'], Joint Probe (Total Force Z) ['+funit+'], Joint Probe (Total Force Total) ['+funit+'] ')
f.write('\n')
#Data
for t, fx_, fy_, fz_, ftot_ in zip(time, fx_table, fy_table, fz_table, ftot_table):
f.write(str(t))
f.write(', ' + str(fx_)+', ' + str(fy_)+', ' + str(fz_)+', ' + str(ftot_))
f.write('\n')