From ab06fdc2a5fbe746c85e518e4dd7d98944364c6b Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Sat, 14 May 2016 19:47:09 +0100 Subject: [PATCH] FEM: Z88: add module z88DispReader.py --- src/Mod/Fem/App/CMakeLists.txt | 1 + src/Mod/Fem/CMakeLists.txt | 1 + src/Mod/Fem/Init.py | 1 + src/Mod/Fem/z88DispReader.py | 165 +++++++++++++++++++++++++++++++++ 4 files changed, 168 insertions(+) create mode 100644 src/Mod/Fem/z88DispReader.py diff --git a/src/Mod/Fem/App/CMakeLists.txt b/src/Mod/Fem/App/CMakeLists.txt index 5b90a508a..2845d6bca 100755 --- a/src/Mod/Fem/App/CMakeLists.txt +++ b/src/Mod/Fem/App/CMakeLists.txt @@ -120,6 +120,7 @@ SET(FemScripts_SRCS MechanicalMaterial.py FemSelectionObserver.py TestFem.py + z88DispReader.py TaskPanelFemBeamSection.ui TaskPanelFemShellThickness.ui diff --git a/src/Mod/Fem/CMakeLists.txt b/src/Mod/Fem/CMakeLists.txt index 4fda50380..7b8bdc0d1 100755 --- a/src/Mod/Fem/CMakeLists.txt +++ b/src/Mod/Fem/CMakeLists.txt @@ -69,6 +69,7 @@ INSTALL( # solver Z88 importZ88Mesh.py + z88DispReader.py FemInputWriterZ88.py FemToolsZ88.py FemSolverZ88.py diff --git a/src/Mod/Fem/Init.py b/src/Mod/Fem/Init.py index f3d684bbe..7048db356 100644 --- a/src/Mod/Fem/Init.py +++ b/src/Mod/Fem/Init.py @@ -36,3 +36,4 @@ FreeCAD.addImportType("CalculiX result (*.frd)", "ccxFrdReader") FreeCAD.addImportType("Abaqus file (*.inp)", "FemGui") FreeCAD.addImportType("Z88 mesh file (*.txt)", "importZ88Mesh") FreeCAD.addExportType("Z88 mesh file (*.txt)", "importZ88Mesh") +FreeCAD.addImportType("Z88 displacement result file (*.txt)", "z88DispReader") diff --git a/src/Mod/Fem/z88DispReader.py b/src/Mod/Fem/z88DispReader.py new file mode 100644 index 000000000..acc23e272 --- /dev/null +++ b/src/Mod/Fem/z88DispReader.py @@ -0,0 +1,165 @@ +# *************************************************************************** +# * * +# * Copyright (c) 2016 - Bernd Hahnebach * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + + +import FreeCAD +import os +from math import pow, sqrt + + +__title__ = "FreeCAD Z88 Disp Reader" +__author__ = "Bernd Hahnebach " +__url__ = "http://www.freecadweb.org" + + +Debug = False + +if open.__module__ == '__builtin__': + pyopen = open # because we'll redefine open below + + +def open(filename): + "called when freecad opens a file" + docname = os.path.splitext(os.path.basename(filename))[0] + insert(filename, docname) + + +def insert(filename, docname): + "called when freecad wants to import a file" + try: + doc = FreeCAD.getDocument(docname) + except NameError: + doc = FreeCAD.newDocument(docname) + FreeCAD.ActiveDocument = doc + import_z88_disp(filename) + + +def import_z88_disp(filename, analysis=None): + '''insert a FreeCAD FEM Result object in the ActiveDocument + ''' + m = read_z88_disp(filename) + if(len(m['Nodes']) > 0): + if analysis is None: + analysis_name = os.path.splitext(os.path.basename(filename))[0] + import FemAnalysis + analysis_object = FemAnalysis.makeFemAnalysis('Analysis') + analysis_object.Label = analysis_name + else: + analysis_object = analysis # see if statement few lines later, if not analysis -> no FemMesh object is created ! + + for result_set in m['Results']: + results_name = 'Results' + results = FreeCAD.ActiveDocument.addObject('Fem::FemResultObject', results_name) + for m in analysis_object.Member: + if m.isDerivedFrom("Fem::FemMeshObject"): + results.Mesh = m + break + + disp = result_set['disp'] + l = len(disp) + displacement = [] + for k, v in disp.iteritems(): + displacement.append(v) + + x_max, y_max, z_max = map(max, zip(*displacement)) + scale = 1.0 + if len(disp) > 0: + results.DisplacementVectors = map((lambda x: x * scale), disp.values()) + results.NodeNumbers = disp.keys() + + x_min, y_min, z_min = map(min, zip(*displacement)) + sum_list = map(sum, zip(*displacement)) + x_avg, y_avg, z_avg = [i / l for i in sum_list] + + s_max = max(results.StressValues) + s_min = min(results.StressValues) + s_avg = sum(results.StressValues) / l + + disp_abs = [] + for d in displacement: + disp_abs.append(sqrt(pow(d[0], 2) + pow(d[1], 2) + pow(d[2], 2))) + results.DisplacementLengths = disp_abs + + a_max = max(disp_abs) + a_min = min(disp_abs) + a_avg = sum(disp_abs) / l + + 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] + analysis_object.Member = analysis_object.Member + [results] + + if(FreeCAD.GuiUp): + import FemGui + FemGui.setActiveAnalysis(analysis_object) + + +def read_z88_disp(z88_disp_input): + ''' + read a z88 disp file and extract the nodes and elements + z88 Displacment output file is z88o2.txt + works with Z88OS14 + + pure usage: + import FemToolsZ88 + fea = FemToolsZ88.FemToolsZ88() + import z88dispReader + disp_file = '/pathtofile/z88o2.txt' + z88DispReader.import_z88_disp(disp_file , fea.analysis) + + The FreeCAD file needs to have an Analysis and an appropiate FEM Mesh + ''' + nodes = {} + mode_disp = {} + mode_results = {} + results = [] + + z88_disp_file = pyopen(z88_disp_input, "r") + + for no, line in enumerate(z88_disp_file): + lno = no + 1 + linelist = line.split() + + if lno >= 6: + # disp line + # print(linelist) + node_no = int(linelist[0]) + mode_disp_x = float(linelist[1]) + mode_disp_y = float(linelist[2]) + if len(linelist) > 3: + mode_disp_z = float(linelist[3]) + else: + mode_disp_z = 0.0 + mode_disp[node_no] = FreeCAD.Vector(mode_disp_x, mode_disp_y, mode_disp_z) + nodes[node_no] = node_no + + mode_results['disp'] = mode_disp + results.append(mode_results) + + if Debug: + for r in results[0]['disp']: + print(r, ' --> ', results[0]['disp'][r]) + + z88_disp_file.close() + return {'Nodes': nodes, 'Results': results}