Extract Tabular Data Min, Max, Avg of Field Results to csv file

mgoldgruber
mgoldgruber Member, Employee Posts: 2 ✭✭✭
edited March 4 in Announcements

The following code extracts the Tabular Data Min, Max, Avg Field Results seen in Mechanical (e.g. von mises stress, deformation, etc.) 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.

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_vonmises'

    # 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 

    # DEFINE FOR WHICH NAMED SELECTION THE TABLE OF MIN/MAX/AVG RESULTS SHOULD BE EXTRACTED (ATTENTION! NAMED SELCTION NAME MUST BE ALL CAPS!)
    # UNCOMMENT THIS LINE AND CHANGE THE NAMED SELECTION NAME TO EXTRACT DATA FOR A SPECIFC NAMED SELECTION
    # ns_scoping = dpf.operators.scoping.on_named_selection(requested_location='Nodal', named_selection_name='INNER_LID_BODY', data_sources=dataSource)

    # GET RESULT FIELD CONTAINER (e.g. Stresses, Temperature, etc.)
    # ADD mesh_scoping IF EXTRACTION SHOULD BE DONE ON NAMED SELECTION FROM LINE 31 (mesh_scoping = None -> Use full mesh)
    fc = dpf.operators.result.stress_von_mises(mesh_scoping=None, time_scoping=time, data_sources=dataSource).outputs.getfields_container()

    # GET MIN MAX FROM FIELD (FIELD CONTAINER)
    minmax_op = dpf.operators.min_max.min_max_fc(fields_container=fc)

    # GET AVERAGE FROM FIELD (Sum up and divide by number of elements/nodes)
    sum_op = dpf.operators.math.accumulate_fc(fields_container=fc)
    avg_op = dpf.operators.math.scale_fc(fields_container=sum_op, ponderation=1.0/fc[0].ElementaryDataCount)

    # GET MIN MAX TABLE as List []
    min_res_table = minmax_op.outputs.field_min.GetData().Data
    max_res_table = minmax_op.outputs.field_max.GetData().Data

    # GET AVG TABLE as List []
    avg_res_table = []
    for i in range(avg_op.outputs.fields_container.GetData().FieldCount):
        avg_res_table.append(avg_op.outputs.fields_container.GetData()[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+'], Minimum ['+fc.Get(0).Unit+'], Maximum ['+fc.Get(0).Unit+'], Average ['+fc.Get(0).Unit+']')
        f.write('\n')   
        #Data
        for t, min_, max_, avg_ in zip(time, min_res_table, max_res_table, avg_res_table):
            f.write(str(t))
            f.write(', ' + str(min_)+', ' + str(max_)+', ' + str(avg_))
            f.write('\n')