From 1f20da40b7fdbfd31ea3d161e477017432bf3f52 Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Tue, 29 Jan 2019 23:51:24 +0100 Subject: [PATCH] FEM: import tools, move stats calculation into result tools --- src/Mod/Fem/feminout/importCcxFrdResults.py | 5 +- src/Mod/Fem/feminout/importToolsFem.py | 89 ------------------- .../Fem/femobjects/_FemResultMechanical.py | 2 +- src/Mod/Fem/femresult/resulttools.py | 87 ++++++++++++++++++ 4 files changed, 91 insertions(+), 92 deletions(-) diff --git a/src/Mod/Fem/feminout/importCcxFrdResults.py b/src/Mod/Fem/feminout/importCcxFrdResults.py index 68c8f05208..67d5ed6a1a 100644 --- a/src/Mod/Fem/feminout/importCcxFrdResults.py +++ b/src/Mod/Fem/feminout/importCcxFrdResults.py @@ -98,11 +98,12 @@ def importFrd(filename, analysis=None, result_name_prefix=None): if analysis: analysis_object.addObject(res_obj) # complementary result object calculations + import femresult.resulttools as restools if not res_obj.MassFlowRate: # only compact result if not Flow 1D results # compact result object, workaround for bug 2873, https://www.freecadweb.org/tracker/view.php?id=2873 - from femresult.resulttools import compact_result as rs - res_obj = rs(res_obj) + res_obj = restools.compact_result(res_obj) + res_obj = restools.fill_femresult_stats(res_obj) # fill Stats else: error_message = ( "We have nodes but no results in frd file, which means we only have a mesh in frd file. " diff --git a/src/Mod/Fem/feminout/importToolsFem.py b/src/Mod/Fem/feminout/importToolsFem.py index fbe81e43f5..dca9414986 100644 --- a/src/Mod/Fem/feminout/importToolsFem.py +++ b/src/Mod/Fem/feminout/importToolsFem.py @@ -329,95 +329,6 @@ def fill_femresult_mechanical(results, result_set): results.NetworkPressure = list(map((lambda x: x), NetworkPressure.values())) results.Time = step_time - # fill the stats list - fill_femresult_stats(results) - return results - - -def fill_femresult_stats(results): - ''' - fills a FreeCAD FEM mechanical result object with stats data - results: FreeCAD FEM result object - ''' - FreeCAD.Console.PrintLog('Calculate stats list for result obj: ' + results.Name + '\n') - no_of_values = 1 # to avoid division by zero - # set stats values to 0, they may not exist in result obj results - x_min = y_min = z_min = x_max = y_max = z_max = x_avg = y_avg = z_avg = 0 - a_max = a_min = a_avg = s_max = s_min = s_avg = 0 - p1_min = p1_avg = p1_max = p2_min = p2_avg = p2_max = p3_min = p3_avg = p3_max = 0 - ms_min = ms_avg = ms_max = peeq_min = peeq_avg = peeq_max = 0 - temp_min = temp_avg = temp_max = mflow_min = mflow_avg = mflow_max = npress_min = npress_avg = npress_max = 0 - - if results.DisplacementVectors: - no_of_values = len(results.DisplacementVectors) - x_max, y_max, z_max = map(max, zip(*results.DisplacementVectors)) - x_min, y_min, z_min = map(min, zip(*results.DisplacementVectors)) - sum_list = map(sum, zip(*results.DisplacementVectors)) - x_avg, y_avg, z_avg = [i / no_of_values for i in sum_list] - a_min = min(results.DisplacementLengths) - a_avg = sum(results.DisplacementLengths) / no_of_values - a_max = max(results.DisplacementLengths) - if results.StressValues: - s_min = min(results.StressValues) - s_avg = sum(results.StressValues) / no_of_values - s_max = max(results.StressValues) - if results.PrincipalMax: - p1_min = min(results.PrincipalMax) - p1_avg = sum(results.PrincipalMax) / no_of_values - p1_max = max(results.PrincipalMax) - if results.PrincipalMed: - p2_min = min(results.PrincipalMed) - p2_avg = sum(results.PrincipalMed) / no_of_values - p2_max = max(results.PrincipalMed) - if results.PrincipalMin: - p3_min = min(results.PrincipalMin) - p3_avg = sum(results.PrincipalMin) / no_of_values - p3_max = max(results.PrincipalMin) - if results.MaxShear: - ms_min = min(results.MaxShear) - ms_avg = sum(results.MaxShear) / no_of_values - ms_max = max(results.MaxShear) - if results.Peeq: - peeq_min = min(results.Peeq) - peeq_avg = sum(results.Peeq) / no_of_values - peeq_max = max(results.Peeq) - if results.Temperature: - temp_min = min(results.Temperature) - temp_avg = sum(results.Temperature) / no_of_values - temp_max = max(results.Temperature) - if results.MassFlowRate: - no_of_values = len(results.MassFlowRate) # DisplacementVectors is empty, no_of_values needs to be set - mflow_min = min(results.MassFlowRate) - mflow_avg = sum(results.MassFlowRate) / no_of_values - mflow_max = max(results.MassFlowRate) - if results.NetworkPressure: - npress_min = min(results.NetworkPressure) - npress_avg = sum(results.NetworkPressure) / no_of_values - npress_max = max(results.NetworkPressure) - - results.Stats = [x_min, x_avg, x_max, - y_min, y_avg, y_max, - z_min, z_avg, z_max, - a_min, a_avg, a_max, - s_min, s_avg, s_max, - p1_min, p1_avg, p1_max, - p2_min, p2_avg, p2_max, - p3_min, p3_avg, p3_max, - ms_min, ms_avg, ms_max, - peeq_min, peeq_avg, peeq_max, - temp_min, temp_avg, temp_max, - mflow_min, mflow_avg, mflow_max, - npress_min, npress_avg, npress_max] - # stat_types = ["U1", "U2", "U3", "Uabs", "Sabs", "MaxPrin", "MidPrin", "MinPrin", "MaxShear", "Peeq", "Temp", "MFlow", "NPress"] - # len(stat_types) == 13*3 == 39 - # do not forget to adapt initialization of all Stats items in modules: - # - module femobjects/_FemResultMechanical.py - # do not forget to adapt the def get_stats in: - # - module femresult/resulttools.py - # - module femtest/testccxtools.py - # TODO: all stats stuff should be reimplemented, ma be a dictionary would be far more robust than a list - - FreeCAD.Console.PrintLog('Stats list for result obj: ' + results.Name + ' calculated\n') return results diff --git a/src/Mod/Fem/femobjects/_FemResultMechanical.py b/src/Mod/Fem/femobjects/_FemResultMechanical.py index 0d014303cd..f3707a63c1 100644 --- a/src/Mod/Fem/femobjects/_FemResultMechanical.py +++ b/src/Mod/Fem/femobjects/_FemResultMechanical.py @@ -62,7 +62,7 @@ class _FemResultMechanical(): obj.addProperty("App::PropertyFloatList", "UserDefined", "NodeData", "User Defined Results", True) obj.addProperty("App::PropertyFloatList", "Temperature", "NodeData", "Temperature field", True) - # initialize the Stats with the appropriate count of items (see fill_femresult_stats in feminout/importToolsFem.py) + # initialize the Stats with the appropriate count of items (see fill_femresult_stats in femresult/resulttools.py) zero_list = 39 * [0] obj.Stats = zero_list diff --git a/src/Mod/Fem/femresult/resulttools.py b/src/Mod/Fem/femresult/resulttools.py index 7974ebf9b7..502c43c62a 100644 --- a/src/Mod/Fem/femresult/resulttools.py +++ b/src/Mod/Fem/femresult/resulttools.py @@ -153,6 +153,93 @@ def get_stats(resultobj, result_type): return stats +def fill_femresult_stats(results): + ''' + fills a FreeCAD FEM mechanical result object with stats data + results: FreeCAD FEM result object + ''' + FreeCAD.Console.PrintLog('Calculate stats list for result obj: ' + results.Name + '\n') + no_of_values = 1 # to avoid division by zero + # set stats values to 0, they may not exist in result obj results + x_min = y_min = z_min = x_max = y_max = z_max = x_avg = y_avg = z_avg = 0 + a_max = a_min = a_avg = s_max = s_min = s_avg = 0 + p1_min = p1_avg = p1_max = p2_min = p2_avg = p2_max = p3_min = p3_avg = p3_max = 0 + ms_min = ms_avg = ms_max = peeq_min = peeq_avg = peeq_max = 0 + temp_min = temp_avg = temp_max = mflow_min = mflow_avg = mflow_max = npress_min = npress_avg = npress_max = 0 + + if results.DisplacementVectors: + no_of_values = len(results.DisplacementVectors) + x_max, y_max, z_max = map(max, zip(*results.DisplacementVectors)) + x_min, y_min, z_min = map(min, zip(*results.DisplacementVectors)) + sum_list = map(sum, zip(*results.DisplacementVectors)) + x_avg, y_avg, z_avg = [i / no_of_values for i in sum_list] + a_min = min(results.DisplacementLengths) + a_avg = sum(results.DisplacementLengths) / no_of_values + a_max = max(results.DisplacementLengths) + if results.StressValues: + s_min = min(results.StressValues) + s_avg = sum(results.StressValues) / no_of_values + s_max = max(results.StressValues) + if results.PrincipalMax: + p1_min = min(results.PrincipalMax) + p1_avg = sum(results.PrincipalMax) / no_of_values + p1_max = max(results.PrincipalMax) + if results.PrincipalMed: + p2_min = min(results.PrincipalMed) + p2_avg = sum(results.PrincipalMed) / no_of_values + p2_max = max(results.PrincipalMed) + if results.PrincipalMin: + p3_min = min(results.PrincipalMin) + p3_avg = sum(results.PrincipalMin) / no_of_values + p3_max = max(results.PrincipalMin) + if results.MaxShear: + ms_min = min(results.MaxShear) + ms_avg = sum(results.MaxShear) / no_of_values + ms_max = max(results.MaxShear) + if results.Peeq: + peeq_min = min(results.Peeq) + peeq_avg = sum(results.Peeq) / no_of_values + peeq_max = max(results.Peeq) + if results.Temperature: + temp_min = min(results.Temperature) + temp_avg = sum(results.Temperature) / no_of_values + temp_max = max(results.Temperature) + if results.MassFlowRate: + no_of_values = len(results.MassFlowRate) # DisplacementVectors is empty, no_of_values needs to be set + mflow_min = min(results.MassFlowRate) + mflow_avg = sum(results.MassFlowRate) / no_of_values + mflow_max = max(results.MassFlowRate) + if results.NetworkPressure: + npress_min = min(results.NetworkPressure) + npress_avg = sum(results.NetworkPressure) / no_of_values + npress_max = max(results.NetworkPressure) + + results.Stats = [x_min, x_avg, x_max, + y_min, y_avg, y_max, + z_min, z_avg, z_max, + a_min, a_avg, a_max, + s_min, s_avg, s_max, + p1_min, p1_avg, p1_max, + p2_min, p2_avg, p2_max, + p3_min, p3_avg, p3_max, + ms_min, ms_avg, ms_max, + peeq_min, peeq_avg, peeq_max, + temp_min, temp_avg, temp_max, + mflow_min, mflow_avg, mflow_max, + npress_min, npress_avg, npress_max] + # stat_types = ["U1", "U2", "U3", "Uabs", "Sabs", "MaxPrin", "MidPrin", "MinPrin", "MaxShear", "Peeq", "Temp", "MFlow", "NPress"] + # len(stat_types) == 13*3 == 39 + # do not forget to adapt initialization of all Stats items in modules: + # - module femobjects/_FemResultMechanical.py + # do not forget to adapt the def get_stats in: + # - get_stats in module femresult/resulttools.py + # - module femtest/testccxtools.py + # TODO: all stats stuff should be reimplemented, ma be a dictionary would be far more robust than a list + + FreeCAD.Console.PrintLog('Stats list for result obj: ' + results.Name + ' calculated\n') + return results + + def compact_result(res_obj): ''' compacts result.Mesh and appropriate result.NodeNumbers