How do I calculate element volume weighted average of Nodal results in Mechanical?

Ayush Kumar
Ayush Kumar Member, Moderator, Employee Posts: 454
100 Answers 250 Likes 100 Comments Second Anniversary
✭✭✭✭
edited June 2023 in Structures

The average value given by Mechanical is just an average of all the Nodal results. Therefore, it is extremely dependent on the Mesh. If I have an equidistant mesh then it is correct but for the same if I have fine mesh some regions and coarse in others, the result will be wrong, because more number of sampling points are taken from the fine mesh region. Example - same model, same boundary conditions, different mesh - different results:

enter image description here

Tagged:

Best Answer

Answers

  • TerryR
    TerryR Member Posts: 1
    First Comment
    **
    edited January 15

    Ayush thanks much for posting that. For others, here is a more user friendly version for calculating the real average temperature. It works off of bodies, and having a named selection is optional.

    # -*- coding: utf-8 -*-
    
    # Analysis system index (eg zero if there is just 1 analysis system in the tree)
    analysis_system_index = 0
    
    # Optional: Create a Named Selection with only the selected BODIES of interest (eg multiple bodies of same material).
    named_sel_name = "Selection"
    
    # ACT reader
    reader = ExtAPI.DataModel.AnalysisList[analysis_system_index].GetResultsData()
    reader.CurrentResultSet = reader.ResultSetCount  #Get final result. Can show weird values otherwise.
    volume = reader.GetResult("VOLUME")
    temp = reader.GetResult("TEMP")
    
    # Bodies
    all_bodies = ExtAPI.DataModel.Project.Model.Geometry.GetChildren(DataModelObjectCategory.Body, True)
    
    # Mesh Data
    mesh_data = ExtAPI.DataModel.AnalysisList[analysis_system_index].MeshData
    
    # If the Named Selection is valid, get just those body ids.
    selected_body_ids = []
    named_sel = ExtAPI.DataModel.GetObjectsByName(named_sel_name)
    if len(named_sel) >= 1:
        selected_body_ids = named_sel[0].Ids
    
    print "Real average temperature for [", ExtAPI.DataModel.AnalysisList[analysis_system_index].Name, "]:"
    
    total_volume = 0.0
    total_w_element_temp = 0.0
    
    for body in all_bodies:
        geobody = body.GetGeoBody()
    
        # Ignore suppressed bodies
        if geobody.Suppressed:
            continue
    
        # Loop thru each selected body, or all bodies if none selected
        if (geobody.Id in selected_body_ids) or len(selected_body_ids)==0:
    
            body_volume = 0.0
            body_w_element_temp = 0.0
    
            #Get body elements
            Elements= mesh_data.MeshRegionById(geobody.Id).ElementIds
            for element_id in Elements:
    
                # volume of the element
                element_volume = volume.GetElementValues(element_id)[0]
    
                body_volume += element_volume
                total_volume += element_volume
    
                # nodes of that element
                nodes_element = mesh_data.NodeIdsFromElementIds([element_id])
    
                # Average element temperature
                average_element_temp = sum([temp.GetNodeValues(node_id)[0] for node_id in nodes_element]) / len(nodes_element)
    
                # Weighted Temperature
                body_w_element_temp += average_element_temp * element_volume
                total_w_element_temp += average_element_temp * element_volume
                #print average_element_temp
    
            # Don't divide by zero on invalid bodies
            if body_volume == 0.0:
                continue
    
            body_avg_temp = body_w_element_temp / body_volume
            print "Body [", geobody.Name, "]:",body_avg_temp, "°C   ", body_avg_temp *9/5+32, "°F"
    
    # Total Average temperature
    if total_volume == 0.0:
        total_volume = -1 # Error
    avg_temp = total_w_element_temp / total_volume
    
    # Print if more than one body selected
    if avg_temp <> body_avg_temp:
        print "Weighted average by volume for above bodies -", avg_temp, "°C", avg_temp *9/5+32, "°F"
    
    # Free rst file
    reader.Dispose()