How do I calculate element volume weighted average of Nodal results in Mechanical?
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:
Best Answer
-
The solution to this is element volume weighted average. This code expects a named selection with all the elements of interest
elements_ns
and please adjust line 2 and 7 as per the analysis system index in Mechanical.Note: This works only for 3D bodies, for surfaces area weighted average can be done using element faces named selection.
# ACT reader reader = ExtAPI.DataModel.AnalysisList[0].GetResultsData() volume = reader.GetResult("VOLUME") temp = reader.GetResult("TEMP") # Mesh Data mesh = ExtAPI.DataModel.AnalysisList[0].MeshData total_volume = 0.0 w_element_temp = [] elements = ExtAPI.DataModel.GetObjectsByName("elements_ns")[0] for element_id in elements.Ids: # nodes of that element nodes_element = mesh.NodeIdsFromElementIds([element_id]) # volume of the element element_volume = volume.GetElementValues(element_id)[0] total_volume += element_volume # Average element temperature average_element_temp = sum([temp.GetNodeValues(node_id)[0] for node_id in nodes_element]) / len(nodes_element) # Weighted Temperature w_element_temp.append(average_element_temp * element_volume) # Average temperature avg_temp = sum(w_element_temp) / total_volume # Free rst file reader.Dispose() print avg_temp
5
Answers
-
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()
0