def doubleClicked(self, vobj): if FreeCADGui.activeWorkbench().name() != 'CfdWorkbench': FreeCADGui.activateWorkbench("CfdWorkbench") doc = FreeCADGui.getDocument(vobj.Object.Document) # it should be possible to find the AnalysisObject although it is not a documentObjectGroup if not FemGui.getActiveAnalysis(): analysis_obj = CfdTools.getParentAnalysisObject(self.Object) if analysis_obj: FemGui.setActiveAnalysis(analysis_obj) else: FreeCAD.Console.PrintError( 'No Active Analysis is detected from solver object in the active Document!\n' ) if not doc.getInEdit(): if FemGui.getActiveAnalysis().Document is FreeCAD.ActiveDocument: if self.Object in FemGui.getActiveAnalysis().Group: doc.setEdit(vobj.Object.Name) else: FreeCAD.Console.PrintError( 'Activate the analysis this solver belongs to!\n') else: FreeCAD.Console.PrintError( 'Active Analysis is not in active Document!\n') else: FreeCAD.Console.PrintError( 'Active Task Dialog found! Please close this one first!\n') return True
def doubleClicked(self, vobj): # bug: still not working, always bring up FemWorkbench if FreeCADGui.activeWorkbench().name() != 'CfdWorkbench': FreeCADGui.activateWorkbench("CfdWorkbench") if not FemGui.getActiveAnalysis() == self.Object: FemGui.setActiveAnalysis(self.Object) return True
def importFrd(filename, analysis=None, result_name_prefix=None): from . import importToolsFem import ObjectsFem if result_name_prefix is None: result_name_prefix = '' m = readResult(filename) result_mesh_object = None if len(m['Nodes']) > 0: if analysis: analysis_object = analysis mesh = importToolsFem.make_femmesh(m) result_mesh_object = ObjectsFem.makeMeshResult(FreeCAD.ActiveDocument, 'Result_mesh') result_mesh_object.FemMesh = mesh positions = [] for k, v in m['Nodes'].items(): positions.append(v) p_x_max, p_y_max, p_z_max = map(max, zip(*positions)) p_x_min, p_y_min, p_z_min = map(min, zip(*positions)) x_span = abs(p_x_max - p_x_min) y_span = abs(p_y_max - p_y_min) z_span = abs(p_z_max - p_z_min) span = max(x_span, y_span, z_span) number_of_increments = len(m['Results']) for result_set in m['Results']: if 'number' in result_set: eigenmode_number = result_set['number'] else: eigenmode_number = 0 step_time = result_set['time'] step_time = round(step_time, 2) if eigenmode_number > 0: results_name = result_name_prefix + 'mode_' + str( eigenmode_number) + '_results' elif number_of_increments > 1: results_name = result_name_prefix + 'time_' + str( step_time) + '_results' else: results_name = result_name_prefix + 'results' results = ObjectsFem.makeResultMechanical(FreeCAD.ActiveDocument, results_name) results.Mesh = result_mesh_object results = importToolsFem.fill_femresult_mechanical( results, result_set, span) if analysis: analysis_object.addObject(results) if FreeCAD.GuiUp: if analysis: import FemGui FemGui.setActiveAnalysis(analysis_object) FreeCAD.ActiveDocument.recompute() else: FreeCAD.Console.PrintError( 'Problem on frd file import. No nodes found in frd file.\n')
def doubleClicked(self, vobj): if not FemGui.getActiveAnalysis() == self.Object: if FreeCADGui.activeWorkbench().name() != 'CfdWorkbench': FreeCADGui.activateWorkbench("CfdWorkbench") FemGui.setActiveAnalysis(self.Object) return True return True
def import_z88_disp(filename, analysis=None, result_name_prefix=None): '''insert a FreeCAD FEM mechanical result object in the ActiveDocument ''' import importToolsFem import ObjectsFem if result_name_prefix is None: result_name_prefix = '' m = read_z88_disp(filename) if(len(m['Nodes']) > 0): if analysis is None: analysis_name = os.path.splitext(os.path.basename(filename))[0] analysis_object = ObjectsFem.makeAnalysis('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 = result_name_prefix + 'results' results = ObjectsFem.makeResultMechanical(results_name) for m in analysis_object.Member: # TODO analysis could have multiple mesh objects in the future if m.isDerivedFrom("Fem::FemMeshObject"): results.Mesh = m break results = importToolsFem.fill_femresult_mechanical(results, result_set, 0) analysis_object.Member = analysis_object.Member + [results] if(FreeCAD.GuiUp): import FemGui FemGui.setActiveAnalysis(analysis_object)
def import_z88_disp(filename, analysis=None, result_name_prefix=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 = result_name_prefix + '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 doubleClicked(self, vobj): if not FemGui.getActiveAnalysis() == self.Object: if FreeCADGui.activeWorkbench().name() != "FemWorkbench": FreeCADGui.activateWorkbench("FemWorkbench") FemGui.setActiveAnalysis(self.Object) return True return True
def import_z88_disp(filename, analysis=None, result_name_prefix=None): """insert a FreeCAD FEM mechanical result object in the ActiveDocument pure usage: import feminout.importZ88O2Results as importZ88O2Results disp_file = "/pathtofile/z88o2.txt" importZ88O2Results.import_z88_disp(disp_file) the z888i1.txt FEMMesh file needs to be in the same directory as z88o2.txt # ahh, make a new document first ;-) """ import ObjectsFem from . import importZ88Mesh from . import importToolsFem from femresult import resulttools if result_name_prefix is None: result_name_prefix = "" disp_read = read_z88_disp(filename) result_mesh_object = None if len(disp_read["Nodes"]) > 0: if analysis: analysis_object = analysis # read result mesh if filename.endswith("z88o2.txt"): mesh_file = filename.replace("o2", "i1") mesh_data = importZ88Mesh.read_z88_mesh(mesh_file) femmesh = importToolsFem.make_femmesh(mesh_data) result_mesh_object = ObjectsFem.makeMeshResult( FreeCAD.ActiveDocument, "Result_mesh") result_mesh_object.FemMesh = femmesh else: Console.PrintError("Z88 mesh file z88i1.txt not found.\n") # create result obj for result_set in disp_read["Results"]: results_name = result_name_prefix + "results" res_obj = ObjectsFem.makeResultMechanical(FreeCAD.ActiveDocument, results_name) res_obj.Mesh = result_mesh_object res_obj = importToolsFem.fill_femresult_mechanical( res_obj, result_set) res_obj = resulttools.add_disp_apps( res_obj) # fill DisplacementLengths res_obj = resulttools.fill_femresult_stats(res_obj) # fill Stats if analysis: analysis_object.addObject(res_obj) if FreeCAD.GuiUp: if analysis: import FemGui FemGui.setActiveAnalysis(analysis_object) FreeCAD.ActiveDocument.recompute() else: Console.PrintError( "Problem on Z88 result file import. No nodes found in Z88 result file.\n" ) return res_obj
def importCfdResult(filename, analysis=None, result_name_prefix=None): from CfdObjects import makeCfdResult import Fem result_obj = makeCfdResult(result_name_prefix) if result_name_prefix is None: result_name_prefix = "CfdResult" if analysis is None: analysis_name = os.path.splitext(os.path.basename(filename))[0] analysis_object = ObjectsFem.makeAnalysis('Analysis') analysis_object.Label = analysis_name else: analysis_object = analysis analysis_object.Member = analysis_object.Member + [result_obj] # FIXME move the ResultMesh in the analysis -> call the readReslt after setActiveAnalysis #Stats has been setup in C++ function Fem.readCfdResult if (FreeCAD.GuiUp) and analysis: import FemGui FemGui.setActiveAnalysis(analysis) Fem.readResult(filename, result_obj.Name) #always create a new femmesh
def doubleClicked(self, vobj): FreeCADGui.activateWorkbench('FemWorkbench') # Group meshing is only active on active analysis, we should make sure the analysis the mesh belongs too is active gui_doc = FreeCADGui.getDocument(vobj.Object.Document) if not gui_doc.getInEdit(): # may be go the other way around and just activate the analysis the user has doubleClicked on ?! # not a fast one, we need to iterate over all member of all analysis to know to which analyis the object belongs too!!! # first check if there is an analysis in the active document found_an_analysis = False for o in gui_doc.Document.Objects: if o.isDerivedFrom('Fem::FemAnalysisPython'): found_an_analysis = True break if found_an_analysis: if FemGui.getActiveAnalysis() is not None: if FemGui.getActiveAnalysis().Document is FreeCAD.ActiveDocument: if self.Object in FemGui.getActiveAnalysis().Member: if not gui_doc.getInEdit(): gui_doc.setEdit(vobj.Object.Name) else: FreeCAD.Console.PrintError('Activate the analysis this GMSH FEM mesh object belongs too!\n') else: print('GMSH FEM mesh object does not belong to the active analysis.') found_mesh_analysis = False for o in gui_doc.Document.Objects: if o.isDerivedFrom('Fem::FemAnalysisPython'): for m in o.Member: if m == self.Object: found_mesh_analysis = True FemGui.setActiveAnalysis(o) print('The analysis the GMSH FEM mesh object belongs too was found and activated: ' + o.Name) gui_doc.setEdit(vobj.Object.Name) break if not found_mesh_analysis: print('GMSH FEM mesh object does not belong to an analysis. Analysis group meshing will be deactivated.') gui_doc.setEdit(vobj.Object.Name) else: FreeCAD.Console.PrintError('Active analysis is not in active document.') else: print('No active analysis in active document, we are going to have a look if the GMSH FEM mesh object belongs to a non active analysis.') found_mesh_analysis = False for o in gui_doc.Document.Objects: if o.isDerivedFrom('Fem::FemAnalysisPython'): for m in o.Member: if m == self.Object: found_mesh_analysis = True FemGui.setActiveAnalysis(o) print('The analysis the GMSH FEM mesh object belongs to was found and activated: ' + o.Name) gui_doc.setEdit(vobj.Object.Name) break if not found_mesh_analysis: print('GMSH FEM mesh object does not belong to an analysis. Analysis group meshing will be deactivated.') gui_doc.setEdit(vobj.Object.Name) else: print('No analysis in the active document.') gui_doc.setEdit(vobj.Object.Name) else: FreeCAD.Console.PrintError('Active Task Dialog found! Please close this one first!\n') return True
def doubleClicked(self, vobj): FreeCADGui.activateWorkbench('FemWorkbench') # Group meshing is only active on active analysis, we should make sure the analysis the mesh belongs too is active gui_doc = FreeCADGui.getDocument(vobj.Object.Document) if not gui_doc.getInEdit(): # may be go the other way around and just activate the analysis the user has doubleClicked on ?! # not a fast one, we need to iterate over all member of all analysis to know to which analyis the object belongs too!!! # first check if there is an analysis in the active document found_an_analysis = False for o in gui_doc.Document.Objects: if o.isDerivedFrom('Fem::FemAnalysisPython'): found_an_analysis = True break if found_an_analysis: if FemGui.getActiveAnalysis() is not None: if FemGui.getActiveAnalysis().Document is FreeCAD.ActiveDocument: if self.Object in FemGui.getActiveAnalysis().Group: if not gui_doc.getInEdit(): gui_doc.setEdit(vobj.Object.Name) else: FreeCAD.Console.PrintError('Activate the analysis this Gmsh FEM mesh object belongs too!\n') else: print('Gmsh FEM mesh object does not belong to the active analysis.') found_mesh_analysis = False for o in gui_doc.Document.Objects: if o.isDerivedFrom('Fem::FemAnalysisPython'): for m in o.Group: if m == self.Object: found_mesh_analysis = True FemGui.setActiveAnalysis(o) print('The analysis the Gmsh FEM mesh object belongs too was found and activated: ' + o.Name) gui_doc.setEdit(vobj.Object.Name) break if not found_mesh_analysis: print('Gmsh FEM mesh object does not belong to an analysis. Analysis group meshing will be deactivated.') gui_doc.setEdit(vobj.Object.Name) else: FreeCAD.Console.PrintError('Active analysis is not in active document.') else: print('No active analysis in active document, we are going to have a look if the Gmsh FEM mesh object belongs to a non active analysis.') found_mesh_analysis = False for o in gui_doc.Document.Objects: if o.isDerivedFrom('Fem::FemAnalysisPython'): for m in o.Group: if m == self.Object: found_mesh_analysis = True FemGui.setActiveAnalysis(o) print('The analysis the Gmsh FEM mesh object belongs to was found and activated: ' + o.Name) gui_doc.setEdit(vobj.Object.Name) break if not found_mesh_analysis: print('Gmsh FEM mesh object does not belong to an analysis. Analysis group meshing will be deactivated.') gui_doc.setEdit(vobj.Object.Name) else: print('No analysis in the active document.') gui_doc.setEdit(vobj.Object.Name) else: FreeCAD.Console.PrintError('Active Task Dialog found! Please close this one first!\n') return True
def import_z88_disp( filename, analysis=None, result_name_prefix=None ): '''insert a FreeCAD FEM mechanical result object in the ActiveDocument pure usage: import feminout.importZ88O2Results as importZ88O2Results disp_file = '/pathtofile/z88o2.txt' importZ88O2Results.import_z88_disp(disp_file) the z888i1.txt FEMMesh file needs to be in the same directory as z88o2.txt # ahh, make a new document first ;-) ''' from . import importZ88Mesh from . import importToolsFem import ObjectsFem if result_name_prefix is None: result_name_prefix = '' disp_read = read_z88_disp(filename) result_mesh_object = None if len(disp_read['Nodes']) > 0: if analysis: analysis_object = analysis # read result mesh if filename.endswith('z88o2.txt'): mesh_file = filename.replace('o2', 'i1') mesh_data = importZ88Mesh.read_z88_mesh(mesh_file) femmesh = importToolsFem.make_femmesh(mesh_data) result_mesh_object = ObjectsFem.makeMeshResult( FreeCAD.ActiveDocument, 'Result_mesh' ) result_mesh_object.FemMesh = femmesh else: FreeCAD.Console.PrintError('Z88 mesh file z88i1.txt not found!') # create result obj for result_set in disp_read['Results']: results_name = result_name_prefix + 'results' res_obj = ObjectsFem.makeResultMechanical(FreeCAD.ActiveDocument, results_name) res_obj.Mesh = result_mesh_object res_obj = importToolsFem.fill_femresult_mechanical(res_obj, result_set) if analysis: analysis_object.addObject(res_obj) if FreeCAD.GuiUp: if analysis: import FemGui FemGui.setActiveAnalysis(analysis_object) FreeCAD.ActiveDocument.recompute() else: FreeCAD.Console.PrintError( 'Problem on Z88 result file import. No nodes found in Z88 result file.\n' ) return res_obj
def find_solver_analysis(self): # get the analysis the solver is in if self.solver.getParentGroup(): obj = self.solver.getParentGroup() if femutils.is_of_type(obj, "Fem::FemAnalysis"): self.analysis = obj if FreeCAD.GuiUp: FemGui.setActiveAnalysis(self.analysis)
def importFrd(filename, analysis=None, result_name_prefix=None): import importToolsFem import ObjectsFem if result_name_prefix is None: result_name_prefix = '' m = readResult(filename) mesh_object = None if(len(m['Nodes']) > 0): if analysis is None: analysis_name = os.path.splitext(os.path.basename(filename))[0] analysis_object = ObjectsFem.makeAnalysis('Analysis') analysis_object.Label = analysis_name else: analysis_object = analysis # see if statement few lines later, if not analysis -> no FemMesh object is created ! if 'Nodes' in m: positions = [] for k, v in m['Nodes'].items(): positions.append(v) p_x_max, p_y_max, p_z_max = map(max, zip(*positions)) p_x_min, p_y_min, p_z_min = map(min, zip(*positions)) x_span = abs(p_x_max - p_x_min) y_span = abs(p_y_max - p_y_min) z_span = abs(p_z_max - p_z_min) span = max(x_span, y_span, z_span) if (not analysis): mesh = importToolsFem.make_femmesh(m) if len(m['Nodes']) > 0: mesh_object = FreeCAD.ActiveDocument.addObject('Fem::FemMeshObject', 'ResultMesh') mesh_object.FemMesh = mesh analysis_object.Member = analysis_object.Member + [mesh_object] number_of_increments = len(m['Results']) for result_set in m['Results']: eigenmode_number = result_set['number'] step_time = result_set['time'] step_time = round(step_time, 2) if eigenmode_number > 0: results_name = result_name_prefix + 'mode_' + str(eigenmode_number) + '_results' elif number_of_increments > 1: results_name = result_name_prefix + 'time_' + str(step_time) + '_results' else: results_name = result_name_prefix + 'results' results = ObjectsFem.makeResultMechanical(results_name) for m in analysis_object.Member: # TODO analysis could have multiple mesh objects in the future if m.isDerivedFrom("Fem::FemMeshObject"): results.Mesh = m break results = importToolsFem.fill_femresult_mechanical(results, result_set, span) analysis_object.Member = analysis_object.Member + [results] if(FreeCAD.GuiUp): import FemGui FemGui.setActiveAnalysis(analysis_object)
def create_cube_test_results(): import os import shutil cube_file = test_file_dir + '/cube.fcstd' FreeCAD.open(cube_file) import FemGui FemGui.setActiveAnalysis(FreeCAD.ActiveDocument.MechanicalAnalysis) import FemToolsCcx fea = FemToolsCcx.FemToolsCcx() # static fea.reset_all() fea.run() fea.load_results() stat_types = ["U1", "U2", "U3", "Uabs", "Sabs"] stats_static = [] # we only have one result object so we are fine for s in stat_types: stats_static.append("{}: {}\n".format(s, fea.get_stats(s))) static_expected_values_file = temp_dir + '/cube_static_expected_values' f = open(static_expected_values_file, 'w') for s in stats_static: f.write(s) f.close() # could be added in FemToolsCcx to the self object as an Attribut frd_result_file = os.path.splitext(fea.inp_file_name)[0] + '.frd' dat_result_file = os.path.splitext(fea.inp_file_name)[0] + '.dat' frd_static_test_result_file = temp_dir + '/cube_static.frd' dat_static_test_result_file = temp_dir + '/cube_static.dat' shutil.copyfile(frd_result_file, frd_static_test_result_file) shutil.copyfile(dat_result_file, dat_static_test_result_file) # frequency fea.reset_all() fea.set_analysis_type('frequency') fea.solver.EigenmodesCount = 1 # we should only have one result object fea.run() fea.load_results() stats_frequency = [] # since we set eigenmodeno. we only have one result object so we are fine for s in stat_types: stats_frequency.append("{}: {}\n".format(s, fea.get_stats(s))) frequency_expected_values_file = temp_dir + '/cube_frequency_expected_values' f = open(frequency_expected_values_file, 'w') for s in stats_frequency: f.write(s) f.close() frd_frequency_test_result_file = temp_dir + '/cube_frequency.frd' dat_frequency_test_result_file = temp_dir + '/cube_frequency.dat' shutil.copyfile(frd_result_file, frd_frequency_test_result_file) shutil.copyfile(dat_result_file, dat_frequency_test_result_file) print('Results copied to: ' + temp_dir)
def importFrd(filename,Analysis=None): m = readResult(filename); MeshObject = None if(len(m) > 0): import Fem if Analysis == None: AnalysisName = os.path.splitext(os.path.basename(filename))[0] AnalysisObject = FreeCAD.ActiveDocument.addObject('Fem::FemAnalysis','Analysis') AnalysisObject.Label = AnalysisName else: AnalysisObject = Analysis if(m.has_key('Tet10Elem') and m.has_key('Nodes') and not Analysis ): mesh = Fem.FemMesh() nds = m['Nodes'] for i in nds: n = nds[i] mesh.addNode(n[0],n[1],n[2],i) elms = m['Tet10Elem'] for i in elms: e = elms[i] mesh.addVolume([e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9]],i) if len(nds) > 0: MeshObject = FreeCAD.ActiveDocument.addObject('Fem::FemMeshObject','ResultMesh') MeshObject.FemMesh = mesh AnalysisObject.Member = AnalysisObject.Member + [MeshObject] if(m.has_key('Displacement')): disp = m['Displacement'] if len(disp)>0: o = FreeCAD.ActiveDocument.addObject('Fem::FemResultVector','Displacement') o.Values = disp.values() o.DataType = 'Displacement' o.ElementNumbers = disp.keys() if(MeshObject): o.Mesh = MeshObject AnalysisObject.Member = AnalysisObject.Member + [o] if(m.has_key('Stress')): stress = m['Stress'] if len(stress)>0: o = FreeCAD.ActiveDocument.addObject('Fem::FemResultValue','MisesStress') mstress = [] for i in stress.values(): # van mises stress (http://en.wikipedia.org/wiki/Von_Mises_yield_criterion) mstress.append( sqrt( pow( i[0] - i[1] ,2) + pow( i[1] - i[2] ,2) + pow( i[2] - i[0] ,2) + 6 * (pow(i[3],2)+pow(i[4],2)+pow(i[5],2) ) ) ) o.Values = mstress o.DataType = 'VanMisesStress' o.ElementNumbers = stress.keys() if(MeshObject): o.Mesh = MeshObject AnalysisObject.Member = AnalysisObject.Member + [o] if(FreeCAD.GuiUp): import FemGui, FreeCADGui if FreeCADGui.activeWorkbench().name() != 'FemWorkbench': FreeCADGui.activateWorkbench("FemWorkbench") FemGui.setActiveAnalysis(AnalysisObject)
def doubleClicked(self, vobj): if not FemGui.getActiveAnalysis() == self.Object: if FreeCADGui.activeWorkbench().name() != 'FemWorkbench': FreeCADGui.activateWorkbench("FemWorkbench") FemGui.setActiveAnalysis(self.Object) return True else: taskd = _JobControlTaskPanel(self.Object) FreeCADGui.Control.showDialog(taskd) return True
def import_z88_disp(filename, analysis=None, result_name_prefix=None): '''insert a FreeCAD FEM mechanical result object in the ActiveDocument pure usage: import feminout.importZ88O2Results as importZ88O2Results disp_file = '/pathtofile/z88o2.txt' importZ88O2Results.import_z88_disp(disp_file) the z888i1.txt FEMMesh file needs to be in the same directory as z88o2.txt # ahh, make a new document first ;-) ''' from . import importZ88Mesh from . import importToolsFem import ObjectsFem if result_name_prefix is None: result_name_prefix = '' disp_read = read_z88_disp(filename) result_mesh_object = None if len(disp_read['Nodes']) > 0: if analysis: analysis_object = analysis # read result mesh if filename.endswith('z88o2.txt'): mesh_file = filename.replace('o2', 'i1') mesh_data = importZ88Mesh.read_z88_mesh(mesh_file) femmesh = importToolsFem.make_femmesh(mesh_data) result_mesh_object = ObjectsFem.makeMeshResult( FreeCAD.ActiveDocument, 'Result_mesh') result_mesh_object.FemMesh = femmesh else: FreeCAD.Console.PrintError('Z88 mesh file z88i1.txt not found!') # create result obj for result_set in disp_read['Results']: results_name = result_name_prefix + 'results' res_obj = ObjectsFem.makeResultMechanical(FreeCAD.ActiveDocument, results_name) res_obj.Mesh = result_mesh_object res_obj = importToolsFem.fill_femresult_mechanical( res_obj, result_set) if analysis: analysis_object.addObject(res_obj) if FreeCAD.GuiUp: if analysis: import FemGui FemGui.setActiveAnalysis(analysis_object) FreeCAD.ActiveDocument.recompute() else: FreeCAD.Console.PrintError( 'Problem on Z88 result file import. No nodes found in Z88 result file.\n' ) return res_obj
def importFrd(filename, analysis=None, result_name_prefix=None): from . import importToolsFem import ObjectsFem if result_name_prefix is None: result_name_prefix = '' m = readResult(filename) result_mesh_object = None if len(m['Nodes']) > 0: if analysis: analysis_object = analysis mesh = importToolsFem.make_femmesh(m) result_mesh_object = ObjectsFem.makeMeshResult(FreeCAD.ActiveDocument, 'Result_mesh') result_mesh_object.FemMesh = mesh positions = [] for k, v in m['Nodes'].items(): positions.append(v) p_x_max, p_y_max, p_z_max = map(max, zip(*positions)) p_x_min, p_y_min, p_z_min = map(min, zip(*positions)) x_span = abs(p_x_max - p_x_min) y_span = abs(p_y_max - p_y_min) z_span = abs(p_z_max - p_z_min) span = max(x_span, y_span, z_span) number_of_increments = len(m['Results']) for result_set in m['Results']: if 'number' in result_set: eigenmode_number = result_set['number'] else: eigenmode_number = 0 step_time = result_set['time'] step_time = round(step_time, 2) if eigenmode_number > 0: results_name = result_name_prefix + 'mode_' + str(eigenmode_number) + '_results' elif number_of_increments > 1: results_name = result_name_prefix + 'time_' + str(step_time) + '_results' else: results_name = result_name_prefix + 'results' results = ObjectsFem.makeResultMechanical(FreeCAD.ActiveDocument, results_name) results.Mesh = result_mesh_object results = importToolsFem.fill_femresult_mechanical(results, result_set, span) if analysis: analysis_object.addObject(results) if FreeCAD.GuiUp: if analysis: import FemGui FemGui.setActiveAnalysis(analysis_object) FreeCAD.ActiveDocument.recompute() else: FreeCAD.Console.PrintError('Problem on frd file import. No nodes found in frd file.\n')
def doubleClicked(self, vobj): if FreeCADGui.activeWorkbench().name() != 'CfdOFWorkbench': FreeCADGui.activateWorkbench("CfdOFWorkbench") # Group meshing is only active on active analysis, should confirm the analysis the mesh belongs too is active gui_doc = FreeCADGui.getDocument(vobj.Object.Document) if not gui_doc.getInEdit(): if FemGui.getActiveAnalysis() is not None: if FemGui.getActiveAnalysis( ).Document is FreeCAD.ActiveDocument: if self.Object in FemGui.getActiveAnalysis().Group: if not gui_doc.getInEdit(): gui_doc.setEdit(vobj.Object.Name) else: FreeCAD.Console.PrintError( 'Activate the analysis this mesh belongs to.\n' ) else: print('Mesh does not belong to the active analysis.') for o in gui_doc.Document.Objects: if o.isDerivedFrom('Fem::FemAnalysisPython'): for m in o.Group: if m == self.Object: FemGui.setActiveAnalysis(o) print( 'Analysis the Mesh belongs to was activated.' ) gui_doc.setEdit(vobj.Object.Name) break else: FreeCAD.Console.PrintError( 'Active Analysis is not in active Document!\n') else: # No active analysis for o in gui_doc.Document.Objects: if o.isDerivedFrom('Fem::FemAnalysisPython'): for m in o.Group: if m == self.Object: FemGui.setActiveAnalysis(o) print( 'Analysis the Mesh belongs to was activated.' ) gui_doc.setEdit(vobj.Object.Name) break else: print( 'Mesh GMSH object does not belong to an analysis. Group meshing will be deactivated.' ) gui_doc.setEdit(vobj.Object.Name) else: FreeCAD.Console.PrintError( 'Active Task Dialog found. Please close this one first.\n') return True
def doubleClicked(self, vobj): doc = FreeCADGui.getDocument(vobj.Object.Document) if not FemGui.getActiveAnalysis(): analysis_obj = CfdTools.getParentAnalysisObject(self.Object) if analysis_obj: FemGui.setActiveAnalysis(analysis_obj) else: CfdTools.cfdError('No parent analysis object detected') if not doc.getInEdit(): doc.setEdit(vobj.Object.Name) else: FreeCAD.Console.PrintError( 'Active Task Dialog found! Please close this one first!\n') return True
def find_analysis(self): import FemGui self.analysis = FemGui.getActiveAnalysis() if self.analysis: return found_analysis = False for m in FreeCAD.ActiveDocument.Objects: if femutils.is_of_type(m, "Fem::FemAnalysis"): if not found_analysis: self.analysis = m found_analysis = True else: self.analysis = None if self.analysis: FemGui.setActiveAnalysis(self.analysis)
def importCfdResult(filename, analysis=None, result_name_prefix=None): from CfdResult import makeCfdResult if not result_name_prefix: result_name_prefix = "CfdResult" result_obj = makeCfdResult(result_name_prefix) import Fem Fem.readCfdResult(filename, result_obj.Name) #always create a new femmesh ts = filename.split('_')[-1] try: time_step = float(ts[:-4]) except: time_step = 0.0 #Stats has been setup in C++ function Fem.readCfdResult if (FreeCAD.GuiUp) and analysis: import FemGui FemGui.setActiveAnalysis(analysis_object)
def doubleClicked(self, vobj): # Group meshing is only active on active analysis, we should make sure the analysis the mesh belongs too is active gui_doc = FreeCADGui.getDocument(vobj.Object.Document) if not gui_doc.getInEdit(): # may be go the other way around and just activate the analysis the user has doubleClicked on ?! # not a fast one, we need to iterate over all member of all analysis to know to which analyis the object belongs too!!! if FemGui.getActiveAnalysis() is not None: if FemGui.getActiveAnalysis().Document is FreeCAD.ActiveDocument: if self.Object in FemGui.getActiveAnalysis().Member: if not gui_doc.getInEdit(): gui_doc.setEdit(vobj.Object.Name) else: FreeCAD.Console.PrintError('Activate the analysis this mesh belongs to!\n') else: print('Mesh does not belong to the active analysis.') for o in gui_doc.Document.Objects: if o.isDerivedFrom('Fem::FemAnalysisPython'): for m in o.Member: if m == self.Object: FemGui.setActiveAnalysis(o) print('Analysis the Mesh belongs too was activated.') gui_doc.setEdit(vobj.Object.Name) break else: FreeCAD.Console.PrintError('Active Analysis is not in active Document!\n') else: # no active analysis, we gone have a look if the obj belongs to a non active analysis, for o in gui_doc.Document.Objects: if o.isDerivedFrom('Fem::FemAnalysisPython'): for m in o.Member: if m == self.Object: FemGui.setActiveAnalysis(o) print('Analysis the Mesh belongs too was activated.') gui_doc.setEdit(vobj.Object.Name) break else: print('Mesh GMSH object does not belong to an analysis. Group meshing will is deactivated.') gui_doc.setEdit(vobj.Object.Name) else: FreeCAD.Console.PrintError('Active Task Dialog found! Please close this one first!\n') return True
def process_dialog(self, gui_doc, vobj): if vobj.Object.Proxy.Type != "FemMeshGmsh": return if FemGui.getActiveAnalysis() is not None: if FemGui.getActiveAnalysis().Document is FreeCAD.ActiveDocument: if self.Object in FemGui.getActiveAnalysis().Group: if not gui_doc.getInEdit(): gui_doc.setEdit(vobj.Object.Name) else: FreeCAD.Console.PrintError('Activate the analysis this GMSH FEM mesh object belongs too!\n') else: print('GMSH FEM mesh object does not belong to the active analysis.') found_mesh_analysis = False for o in gui_doc.Document.Objects: if o.isDerivedFrom('Fem::FemAnalysisPython'): if _contains(o ,self.Object): found_mesh_analysis = True FemGui.setActiveAnalysis(o) print('The analysis the GMSH FEM mesh object belongs too was found and activated: ' + o.Name) gui_doc.setEdit(vobj.Object.Name) break if not found_mesh_analysis: print('GMSH FEM mesh object does not belong to an analysis. Analysis group meshing will be deactivated.') gui_doc.setEdit(vobj.Object.Name) else: FreeCAD.Console.PrintError('Active analysis is not in active document.') else: print('No active analysis in active document, we are going to have a look if the GMSH FEM mesh object belongs to a non active analysis.') found_mesh_analysis = False for o in gui_doc.Document.Objects: if o.isDerivedFrom('Fem::FemAnalysisPython'): if _contains(o, self.Object): found_mesh_analysis = True FemGui.setActiveAnalysis(o) print('The analysis the GMSH FEM mesh object belongs to was found and activated: ' + o.Name) gui_doc.setEdit(vobj.Object.Name) break if not found_mesh_analysis: print('GMSH FEM mesh object does not belong to an analysis. Analysis group meshing will be deactivated.') gui_doc.setEdit(vobj.Object.Name)
def importFrd(filename, analysis=None): m = readResult(filename) mesh_object = None if(len(m['Nodes']) > 0): import Fem 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 ! if 'Nodes' in m: positions = [] for k, v in m['Nodes'].iteritems(): positions.append(v) p_x_max, p_y_max, p_z_max = map(max, zip(*positions)) p_x_min, p_y_min, p_z_min = map(min, zip(*positions)) x_span = abs(p_x_max - p_x_min) y_span = abs(p_y_max - p_y_min) z_span = abs(p_z_max - p_z_min) span = max(x_span, y_span, z_span) if (not analysis) and ('Nodes' in m) and \ (('Hexa8Elem' in m) or ('Penta6Elem' in m) or ('Tetra4Elem' in m) or ('Tetra10Elem' in m) or ('Penta6Elem' in m) or ('Hexa20Elem' in m) or ('Tria3Elem' in m) or ('Tria6Elem' in m) or ('Quad4Elem' in m) or ('Quad8Elem' in m) or ('Seg2Elem' in m)): mesh = Fem.FemMesh() nds = m['Nodes'] for i in nds: n = nds[i] mesh.addNode(n[0], n[1], n[2], i) elms_hexa8 = m['Hexa8Elem'] for i in elms_hexa8: e = elms_hexa8[i] mesh.addVolume([e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7]], i) elms_penta6 = m['Penta6Elem'] for i in elms_penta6: e = elms_penta6[i] mesh.addVolume([e[0], e[1], e[2], e[3], e[4], e[5]], i) elms_tetra4 = m['Tetra4Elem'] for i in elms_tetra4: e = elms_tetra4[i] mesh.addVolume([e[0], e[1], e[2], e[3]], i) elms_tetra10 = m['Tetra10Elem'] for i in elms_tetra10: e = elms_tetra10[i] mesh.addVolume([e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9]], i) elms_penta15 = m['Penta15Elem'] for i in elms_penta15: e = elms_penta15[i] mesh.addVolume([e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9], e[10], e[11], e[12], e[13], e[14]], i) elms_hexa20 = m['Hexa20Elem'] for i in elms_hexa20: e = elms_hexa20[i] mesh.addVolume([e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9], e[10], e[11], e[12], e[13], e[14], e[15], e[16], e[17], e[18], e[19]], i) elms_tria3 = m['Tria3Elem'] for i in elms_tria3: e = elms_tria3[i] mesh.addFace([e[0], e[1], e[2]], i) elms_tria6 = m['Tria6Elem'] for i in elms_tria6: e = elms_tria6[i] mesh.addFace([e[0], e[1], e[2], e[3], e[4], e[5]], i) elms_quad4 = m['Quad4Elem'] for i in elms_quad4: e = elms_quad4[i] mesh.addFace([e[0], e[1], e[2], e[3]], i) elms_quad8 = m['Quad8Elem'] for i in elms_quad8: e = elms_quad8[i] mesh.addFace([e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7]], i) elms_seg2 = m['Seg2Elem'] for i in elms_seg2: e = elms_seg2[i] mesh.addEdge(e[0], e[1]) print ("imported mesh: {} nodes, {} HEXA8, {} PENTA6, {} TETRA4, {} TETRA10, {} PENTA15".format( len(nds), len(elms_hexa8), len(elms_penta6), len(elms_tetra4), len(elms_tetra10), len(elms_penta15))) print ("imported mesh: {} HEXA20, {} TRIA3, {} TRIA6, {} QUAD4, {} QUAD8, {} SEG2".format( len(elms_hexa20), len(elms_tria3), len(elms_tria6), len(elms_quad4), len(elms_quad8), len(elms_seg2))) if len(nds) > 0: mesh_object = FreeCAD.ActiveDocument.addObject('Fem::FemMeshObject', 'ResultMesh') mesh_object.FemMesh = mesh analysis_object.Member = analysis_object.Member + [mesh_object] for result_set in m['Results']: eigenmode_number = result_set['number'] if eigenmode_number > 0: results_name = 'Mode_' + str(eigenmode_number) + '_results' else: 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)) if eigenmode_number > 0: max_disp = max(x_max, y_max, z_max) # Allow for max displacement to be 0.1% of the span # FIXME - add to Preferences max_allowed_disp = 0.001 * span scale = max_allowed_disp / max_disp else: scale = 1.0 if len(disp) > 0: results.DisplacementVectors = map((lambda x: x * scale), disp.values()) results.NodeNumbers = disp.keys() if(mesh_object): results.Mesh = mesh_object stress = result_set['stress'] if len(stress) > 0: mstress = [] for i in stress.values(): mstress.append(calculate_von_mises(i)) if eigenmode_number > 0: results.StressValues = map((lambda x: x * scale), mstress) results.Eigenmode = eigenmode_number else: results.StressValues = mstress if (results.NodeNumbers != 0 and results.NodeNumbers != stress.keys()): print ("Inconsistent FEM results: element number for Stress doesn't equal element number for Displacement {} != {}" .format(results.NodeNumbers, len(results.StressValues))) results.NodeNumbers = stress.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 create_test_results(): import shutil import os import FemGui import femresult.resulttools as resulttools from femtools import ccxtools stat_types = ["U1", "U2", "U3", "Uabs", "Sabs", "MaxPrin", "MidPrin", "MinPrin", "MaxShear", "Peeq", "Temp", "MFlow", "NPress"] temp_dir = testtools.get_fem_test_tmp_dir() static_analysis_dir = temp_dir + 'FEM_ccx_static/' frequency_analysis_dir = temp_dir + 'FEM_ccx_frequency/' thermomech_analysis_dir = temp_dir + 'FEM_ccx_thermomech/' Flow1D_thermomech_analysis_dir = temp_dir + 'FEM_ccx_Flow1D_thermomech/' # run all unit tests from this module import Test import sys current_module = sys.modules[__name__] Test.runTestsFromModule(current_module) # static cube FreeCAD.open(static_analysis_dir + 'cube_static.fcstd') FemGui.setActiveAnalysis(FreeCAD.ActiveDocument.Analysis) fea = ccxtools.FemToolsCcx() print("create static result files") fea.reset_all() fea.run() fea.load_results() stats_static = [] for s in stat_types: statval = resulttools.get_stats(FreeCAD.ActiveDocument.getObject('CalculiX_static_results'), s) stats_static.append("{0}: ({1:.14g}, {2:.14g}, {3:.14g})\n".format(s, statval[0], statval[1], statval[2])) static_expected_values_file = static_analysis_dir + 'cube_static_expected_values' f = open(static_expected_values_file, 'w') for s in stats_static: f.write(s) f.close() frd_result_file = os.path.splitext(fea.inp_file_name)[0] + '.frd' dat_result_file = os.path.splitext(fea.inp_file_name)[0] + '.dat' frd_static_test_result_file = static_analysis_dir + 'cube_static.frd' dat_static_test_result_file = static_analysis_dir + 'cube_static.dat' shutil.copyfile(frd_result_file, frd_static_test_result_file) shutil.copyfile(dat_result_file, dat_static_test_result_file) # frequency cube FreeCAD.open(frequency_analysis_dir + 'cube_frequency.fcstd') FemGui.setActiveAnalysis(FreeCAD.ActiveDocument.Analysis) fea = ccxtools.FemToolsCcx() print("create frequency result files") fea.reset_all() fea.solver.EigenmodesCount = 1 # we should only have one result object fea.run() fea.load_results() stats_frequency = [] for s in stat_types: statval = resulttools.get_stats(FreeCAD.ActiveDocument.getObject('CalculiX_frequency_mode_1_results'), s) stats_frequency.append("{0}: ({1:.14g}, {2:.14g}, {3:.14g})\n".format(s, statval[0], statval[1], statval[2])) frequency_expected_values_file = frequency_analysis_dir + 'cube_frequency_expected_values' f = open(frequency_expected_values_file, 'w') for s in stats_frequency: f.write(s) f.close() frd_frequency_test_result_file = frequency_analysis_dir + 'cube_frequency.frd' dat_frequency_test_result_file = frequency_analysis_dir + 'cube_frequency.dat' shutil.copyfile(frd_result_file, frd_frequency_test_result_file) shutil.copyfile(dat_result_file, dat_frequency_test_result_file) # thermomech print("create thermomech result files") FreeCAD.open(thermomech_analysis_dir + 'spine_thermomech.fcstd') FemGui.setActiveAnalysis(FreeCAD.ActiveDocument.Analysis) fea = ccxtools.FemToolsCcx() fea.reset_all() fea.run() fea.load_results() stats_thermomech = [] for s in stat_types: statval = resulttools.get_stats(FreeCAD.ActiveDocument.getObject('CalculiX_thermomech_results'), s) stats_thermomech.append("{0}: ({1:.14g}, {2:.14g}, {3:.14g})\n".format(s, statval[0], statval[1], statval[2])) thermomech_expected_values_file = thermomech_analysis_dir + 'spine_thermomech_expected_values' f = open(thermomech_expected_values_file, 'w') for s in stats_thermomech: f.write(s) f.close() frd_result_file = os.path.splitext(fea.inp_file_name)[0] + '.frd' dat_result_file = os.path.splitext(fea.inp_file_name)[0] + '.dat' frd_thermomech_test_result_file = thermomech_analysis_dir + 'spine_thermomech.frd' dat_thermomech_test_result_file = thermomech_analysis_dir + 'spine_thermomech.dat' shutil.copyfile(frd_result_file, frd_thermomech_test_result_file) shutil.copyfile(dat_result_file, dat_thermomech_test_result_file) print('Results copied to the appropriate FEM test dirs in: ' + temp_dir) # Flow1D print("create Flow1D result files") FreeCAD.open(Flow1D_thermomech_analysis_dir + 'Flow1D_thermomech.fcstd') FemGui.setActiveAnalysis(FreeCAD.ActiveDocument.Analysis) fea = ccxtools.FemToolsCcx() fea.reset_all() fea.run() fea.load_results() stats_flow1D = [] for s in stat_types: statval = resulttools.get_stats(FreeCAD.ActiveDocument.getObject('CalculiX_thermomech_time_1_0_results'), s) stats_flow1D.append("{0}: ({1:.14g}, {2:.14g}, {3:.14g})\n".format(s, statval[0], statval[1], statval[2])) Flow1D_thermomech_expected_values_file = Flow1D_thermomech_analysis_dir + 'Flow1D_thermomech_expected_values' f = open(Flow1D_thermomech_expected_values_file, 'w') for s in stats_flow1D: f.write(s) f.close() frd_result_file = os.path.splitext(fea.inp_file_name)[0] + '.frd' dat_result_file = os.path.splitext(fea.inp_file_name)[0] + '.dat' frd_Flow1D_thermomech_test_result_file = Flow1D_thermomech_analysis_dir + 'Flow1D_thermomech.frd' dat_Flow1D_thermomech_test_result_file = Flow1D_thermomech_analysis_dir + 'Flow1D_thermomech.dat' shutil.copyfile(frd_result_file, frd_Flow1D_thermomech_test_result_file) shutil.copyfile(dat_result_file, dat_Flow1D_thermomech_test_result_file) print('Flow1D thermomech results copied to the appropriate FEM test dirs in: ' + temp_dir)
def create_test_results(): # run FEM unit tests run_fem_unittests() import os import shutil import FemGui import FemToolsCcx # static and frequency cube FreeCAD.open(static_save_fc_file) FemGui.setActiveAnalysis(FreeCAD.ActiveDocument.Analysis) fea = FemToolsCcx.FemToolsCcx() # static fea.reset_all() fea.run() fea.load_results() stat_types = ["U1", "U2", "U3", "Uabs", "Sabs"] stats_static = [] # we only have one result object so we are fine for s in stat_types: stats_static.append("{}: {}\n".format(s, fea.get_stats(s))) static_expected_values_file = static_analysis_dir + '/cube_static_expected_values' f = open(static_expected_values_file, 'w') for s in stats_static: f.write(s) f.close() # could be added in FemToolsCcx to the self object as an Attribut frd_result_file = os.path.splitext(fea.inp_file_name)[0] + '.frd' dat_result_file = os.path.splitext(fea.inp_file_name)[0] + '.dat' frd_static_test_result_file = static_analysis_dir + '/cube_static.frd' dat_static_test_result_file = static_analysis_dir + '/cube_static.dat' shutil.copyfile(frd_result_file, frd_static_test_result_file) shutil.copyfile(dat_result_file, dat_static_test_result_file) # frequency fea.reset_all() fea.set_analysis_type('frequency') fea.solver.EigenmodesCount = 1 # we should only have one result object fea.run() fea.load_results() stats_frequency = [] # since we set eigenmodeno. we only have one result object so we are fine for s in stat_types: stats_frequency.append("{}: {}\n".format(s, fea.get_stats(s))) frequency_expected_values_file = frequency_analysis_dir + '/cube_frequency_expected_values' f = open(frequency_expected_values_file, 'w') for s in stats_frequency: f.write(s) f.close() frd_frequency_test_result_file = frequency_analysis_dir + '/cube_frequency.frd' dat_frequency_test_result_file = frequency_analysis_dir + '/cube_frequency.dat' shutil.copyfile(frd_result_file, frd_frequency_test_result_file) shutil.copyfile(dat_result_file, dat_frequency_test_result_file) # thermomech FreeCAD.open(thermomech_save_fc_file) FemGui.setActiveAnalysis(FreeCAD.ActiveDocument.Analysis) fea = FemToolsCcx.FemToolsCcx() fea.reset_all() fea.run() fea.load_results() stat_types = ["U1", "U2", "U3", "Uabs", "Sabs"] stats_thermomech = [] # we only have one result object so we are fine for s in stat_types: stats_thermomech.append("{}: {}\n".format(s, fea.get_stats(s))) thermomech_expected_values_file = thermomech_analysis_dir + '/spine_thermomech_expected_values' f = open(thermomech_expected_values_file, 'w') for s in stats_thermomech: f.write(s) f.close() # could be added in FemToolsCcx to the self object as an Attribut frd_result_file = os.path.splitext(fea.inp_file_name)[0] + '.frd' dat_result_file = os.path.splitext(fea.inp_file_name)[0] + '.dat' frd_thermomech_test_result_file = thermomech_analysis_dir + '/spine_thermomech.frd' dat_thermomech_test_result_file = thermomech_analysis_dir + '/spine_thermomech.dat' shutil.copyfile(frd_result_file, frd_thermomech_test_result_file) shutil.copyfile(dat_result_file, dat_thermomech_test_result_file) print('Results copied to the appropriate FEM test dirs in: ' + temp_dir)
def importFrd(filename, analysis=None, result_name_prefix=None): from . import importToolsFem import ObjectsFem if result_name_prefix is None: result_name_prefix = '' m = readResult(filename) result_mesh_object = None if len(m['Nodes']) > 0: if analysis: analysis_object = analysis mesh = importToolsFem.make_femmesh(m) result_mesh_object = ObjectsFem.makeMeshResult(FreeCAD.ActiveDocument, 'Result_mesh') result_mesh_object.FemMesh = mesh positions = [] for k, v in m['Nodes'].items(): positions.append(v) p_x_max, p_y_max, p_z_max = map(max, zip(*positions)) p_x_min, p_y_min, p_z_min = map(min, zip(*positions)) x_span = abs(p_x_max - p_x_min) y_span = abs(p_y_max - p_y_min) z_span = abs(p_z_max - p_z_min) span = max(x_span, y_span, z_span) number_of_increments = len(m['Results']) if len(m['Results']) > 0: for result_set in m['Results']: if 'number' in result_set: eigenmode_number = result_set['number'] else: eigenmode_number = 0 step_time = result_set['time'] step_time = round(step_time, 2) if eigenmode_number > 0: results_name = result_name_prefix + 'mode_' + str(eigenmode_number) + '_results' elif number_of_increments > 1: results_name = result_name_prefix + 'time_' + str(step_time) + '_results' else: results_name = result_name_prefix + 'results' results = ObjectsFem.makeResultMechanical(FreeCAD.ActiveDocument, results_name) results.Mesh = result_mesh_object results = importToolsFem.fill_femresult_mechanical(results, result_set, span) if analysis: analysis_object.addObject(results) else: error_message = ( "We have nodes but no results in frd file, which means we only have a mesh in frd file. " "Usually this happens for analysis type 'NOANALYSIS' or if CalculiX returned no results because " "of nonpositive jacobian determinant in at least one element.\n" ) FreeCAD.Console.PrintMessage(error_message) if analysis: analysis_object.addObject(result_mesh_object) if FreeCAD.GuiUp: if analysis: import FemGui FemGui.setActiveAnalysis(analysis_object) FreeCAD.ActiveDocument.recompute() else: FreeCAD.Console.PrintError('Problem on frd file import. No nodes found in frd file.\n')
def importFrd(filename, Analysis=None): mstress = [] global displacement displacement = [] m = readResult(filename) MeshObject = None if(len(m) > 0): import Fem if Analysis is None: AnalysisName = os.path.splitext(os.path.basename(filename))[0] AnalysisObject = FreeCAD.ActiveDocument.addObject('Fem::FemAnalysis', 'Analysis') AnalysisObject.Label = AnalysisName else: AnalysisObject = Analysis results = FreeCAD.ActiveDocument.addObject('Fem::FemResultObject', 'Results') if ('Tet10Elem' in m) and ('Nodes' in m) and (not Analysis): mesh = Fem.FemMesh() nds = m['Nodes'] for i in nds: n = nds[i] mesh.addNode(n[0], n[1], n[2], i) elms = m['Tet10Elem'] for i in elms: e = elms[i] mesh.addVolume([e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9]], i) if len(nds) > 0: MeshObject = FreeCAD.ActiveDocument.addObject('Fem::FemMeshObject', 'ResultMesh') MeshObject.FemMesh = mesh AnalysisObject.Member = AnalysisObject.Member + [MeshObject] if 'Displacement' in m: disp = m['Displacement'] if len(disp) > 0: results.DisplacementVectors = disp.values() results.ElementNumbers = disp.keys() if(MeshObject): results.Mesh = MeshObject if 'Stress' in m: stress = m['Stress'] if len(stress) > 0: for i in stress.values(): # Von mises stress (http://en.wikipedia.org/wiki/Von_Mises_yield_criterion) s11 = i[0] s22 = i[1] s33 = i[2] s12 = i[3] s23 = i[4] s31 = i[5] s11s22 = pow(s11 - s22, 2) s22s33 = pow(s22 - s33, 2) s33s11 = pow(s33 - s11, 2) s12s23s31 = 6 * (pow(s12, 2) + pow(s23, 2) * pow(s31, 2)) mstress.append(sqrt(0.5 * (s11s22 + s22s33 + s33s11 + s12s23s31))) results.StressValues = mstress if (results.ElementNumbers != 0 and results.ElementNumbers != stress.keys()): print "Inconsistent FEM results: element number for Stress doesn't equal element number for Displacement" results.ElementNumbers = stress.keys() if(MeshObject): results.Mesh = MeshObject l = len(displacement) x_max, y_max, z_max = map(max, zip(*displacement)) 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(mstress) s_min = min(mstress) s_avg = sum(mstress) / 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] AnalysisObject.Member = AnalysisObject.Member + [results] if(FreeCAD.GuiUp): import FemGui import FreeCADGui if FreeCADGui.activeWorkbench().name() != 'FemWorkbench': FreeCADGui.activateWorkbench("FemWorkbench") FemGui.setActiveAnalysis(AnalysisObject)
def importFrd(filename, analysis=None): m = readResult(filename) mesh_object = None 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 ! if 'Nodes' in m: positions = [] for k, v in m['Nodes'].iteritems(): positions.append(v) p_x_max, p_y_max, p_z_max = map(max, zip(*positions)) p_x_min, p_y_min, p_z_min = map(min, zip(*positions)) x_span = abs(p_x_max - p_x_min) y_span = abs(p_y_max - p_y_min) z_span = abs(p_z_max - p_z_min) span = max(x_span, y_span, z_span) if (not analysis): import FemMeshTools mesh = FemMeshTools.make_femmesh(m) if len(m['Nodes']) > 0: mesh_object = FreeCAD.ActiveDocument.addObject('Fem::FemMeshObject', 'ResultMesh') mesh_object.FemMesh = mesh analysis_object.Member = analysis_object.Member + [mesh_object] for result_set in m['Results']: eigenmode_number = result_set['number'] if eigenmode_number > 0: results_name = 'Mode_' + str(eigenmode_number) + '_results' else: 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)) if eigenmode_number > 0: max_disp = max(x_max, y_max, z_max) # Allow for max displacement to be 0.1% of the span # FIXME - add to Preferences max_allowed_disp = 0.001 * span scale = max_allowed_disp / max_disp else: scale = 1.0 if len(disp) > 0: results.DisplacementVectors = map((lambda x: x * scale), disp.values()) results.NodeNumbers = disp.keys() if(mesh_object): results.Mesh = mesh_object stress = result_set['stress'] if len(stress) > 0: mstress = [] for i in stress.values(): mstress.append(calculate_von_mises(i)) if eigenmode_number > 0: results.StressValues = map((lambda x: x * scale), mstress) results.Eigenmode = eigenmode_number else: results.StressValues = mstress if (results.NodeNumbers != 0 and results.NodeNumbers != stress.keys()): print("Inconsistent FEM results: element number for Stress doesn't equal element number for Displacement {} != {}" .format(results.NodeNumbers, len(results.StressValues))) results.NodeNumbers = stress.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 importFrd( filename, analysis=None, result_name_prefix=None ): from . import importToolsFem import ObjectsFem if result_name_prefix is None: result_name_prefix = '' m = read_frd_result(filename) result_mesh_object = None if len(m['Nodes']) > 0: if analysis: analysis_object = analysis mesh = importToolsFem.make_femmesh(m) result_mesh_object = ObjectsFem.makeMeshResult( FreeCAD.ActiveDocument, 'Result_mesh' ) result_mesh_object.FemMesh = mesh number_of_increments = len(m['Results']) FreeCAD.Console.PrintLog( 'Increments: ' + str(number_of_increments) + '\n' ) if len(m['Results']) > 0: for result_set in m['Results']: if 'number' in result_set: eigenmode_number = result_set['number'] else: eigenmode_number = 0 step_time = result_set['time'] step_time = round(step_time, 2) if eigenmode_number > 0: results_name = ( '{}mode_{}_results' .format(result_name_prefix, eigenmode_number) ) elif number_of_increments > 1: results_name = ( '{}time_{}_results' .format(result_name_prefix, step_time) ) else: results_name = ( '{}results' .format(result_name_prefix) ) res_obj = ObjectsFem.makeResultMechanical(FreeCAD.ActiveDocument, results_name) res_obj.Mesh = result_mesh_object res_obj = importToolsFem.fill_femresult_mechanical(res_obj, result_set) 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 res_obj = restools.compact_result(res_obj) # fill DisplacementLengths res_obj = restools.add_disp_apps(res_obj) # fill StressValues res_obj = restools.add_von_mises(res_obj) # fill PrincipalMax, PrincipalMed, PrincipalMin, MaxShear res_obj = restools.add_principal_stress(res_obj) # fill Stats res_obj = restools.fill_femresult_stats(res_obj) else: error_message = ( "We have nodes but no results in frd file, " "which means we only have a mesh in frd file. " "Usually this happens for analysis type 'NOANALYSIS' " "or if CalculiX returned no results because " "of nonpositive jacobian determinant in at least one element.\n" ) FreeCAD.Console.PrintMessage(error_message) if analysis: analysis_object.addObject(result_mesh_object) if FreeCAD.GuiUp: if analysis: import FemGui FemGui.setActiveAnalysis(analysis_object) FreeCAD.ActiveDocument.recompute() else: FreeCAD.Console.PrintError( 'Problem on frd file import. No nodes found in frd file.\n' ) return res_obj
def importFrd(filename, analysis=None, result_name_prefix=None): if result_name_prefix is None: result_name_prefix = "" m = readResult(filename) mesh_object = None 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 ! if "Nodes" in m: positions = [] for k, v in m["Nodes"].iteritems(): positions.append(v) p_x_max, p_y_max, p_z_max = map(max, zip(*positions)) p_x_min, p_y_min, p_z_min = map(min, zip(*positions)) x_span = abs(p_x_max - p_x_min) y_span = abs(p_y_max - p_y_min) z_span = abs(p_z_max - p_z_min) span = max(x_span, y_span, z_span) if not analysis: import FemMeshTools mesh = FemMeshTools.make_femmesh(m) if len(m["Nodes"]) > 0: mesh_object = FreeCAD.ActiveDocument.addObject("Fem::FemMeshObject", "ResultMesh") mesh_object.FemMesh = mesh analysis_object.Member = analysis_object.Member + [mesh_object] number_of_increments = len(m["Results"]) for result_set in m["Results"]: eigenmode_number = result_set["number"] step_time = result_set["time"] step_time = round(step_time, 2) if eigenmode_number > 0: results_name = result_name_prefix + "mode_" + str(eigenmode_number) + "_results" elif number_of_increments > 1: results_name = result_name_prefix + "time_" + str(step_time) + "_results" else: results_name = result_name_prefix + "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"] no_of_values = len(disp) displacement = [] for k, v in disp.iteritems(): displacement.append(v) x_max, y_max, z_max = map(max, zip(*displacement)) if eigenmode_number > 0: max_disp = max(x_max, y_max, z_max) # Allow for max displacement to be 0.1% of the span # FIXME - add to Preferences max_allowed_disp = 0.001 * span scale = max_allowed_disp / max_disp else: scale = 1.0 if len(disp) > 0: results.DisplacementVectors = map((lambda x: x * scale), disp.values()) results.NodeNumbers = disp.keys() if mesh_object: results.Mesh = mesh_object # Read temperatures if they exist try: Temperature = result_set["temp"] if len(Temperature) > 0: if len(Temperature.values()) != len(disp.values()): Temp = [] Temp_extra_nodes = Temperature.values() nodes = len(disp.values()) for i in range(nodes): Temp_value = Temp_extra_nodes[i] Temp.append(Temp_value) results.Temperature = map((lambda x: x), Temp) else: results.Temperature = map((lambda x: x), Temperature.values()) results.Time = step_time except: pass stress = result_set["stress"] if len(stress) > 0: mstress = [] prinstress1 = [] prinstress2 = [] prinstress3 = [] shearstress = [] for i in stress.values(): mstress.append(calculate_von_mises(i)) prin1, prin2, prin3, shear = calculate_principal_stress(i) prinstress1.append(prin1) prinstress2.append(prin2) prinstress3.append(prin3) shearstress.append(shear) if eigenmode_number > 0: results.StressValues = map((lambda x: x * scale), mstress) results.PrincipalMax = map((lambda x: x * scale), prinstress1) results.PrincipalMed = map((lambda x: x * scale), prinstress2) results.PrincipalMin = map((lambda x: x * scale), prinstress3) results.MaxShear = map((lambda x: x * scale), shearstress) results.Eigenmode = eigenmode_number else: results.StressValues = mstress results.PrincipalMax = prinstress1 results.PrincipalMed = prinstress2 results.PrincipalMin = prinstress3 results.MaxShear = shearstress if results.NodeNumbers != 0 and results.NodeNumbers != stress.keys(): print( "Inconsistent FEM results: element number for Stress doesn't equal element number for Displacement {} != {}".format( results.NodeNumbers, len(results.StressValues) ) ) results.NodeNumbers = stress.keys() x_min, y_min, z_min = map(min, zip(*displacement)) sum_list = map(sum, zip(*displacement)) x_avg, y_avg, z_avg = [i / no_of_values for i in sum_list] s_max = max(results.StressValues) s_min = min(results.StressValues) s_avg = sum(results.StressValues) / no_of_values p1_min = min(results.PrincipalMax) p1_avg = sum(results.PrincipalMax) / no_of_values p1_max = max(results.PrincipalMax) p2_min = min(results.PrincipalMed) p2_avg = sum(results.PrincipalMed) / no_of_values p2_max = max(results.PrincipalMed) p3_min = min(results.PrincipalMin) p3_avg = sum(results.PrincipalMin) / no_of_values p3_max = max(results.PrincipalMin) ms_min = min(results.MaxShear) ms_avg = sum(results.MaxShear) / no_of_values ms_max = max(results.MaxShear) 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) / no_of_values 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, ] analysis_object.Member = analysis_object.Member + [results] if FreeCAD.GuiUp: import FemGui FemGui.setActiveAnalysis(analysis_object)
def proceed(self): temp_file = tempfile.mkstemp(suffix='.step')[1] selection = FreeCADGui.Selection.getSelection() if not selection: QtGui.QMessageBox.critical(None, "GMSHMesh macro", "An object has to be selected to run gmsh!") return # Export a part in step format ImportGui.export(selection, temp_file) selection_name = selection[0].Name # Mesh temporaly file file_format = self.cmb_format.currentText() temp_mesh_file = os.path.join(tempfile.tempdir, selection_name + '_Mesh.' + file_format) # OPTIONS GMSH: clmax = self.sb_max_element_size.text() clmin = self.sb_min_element_size.text() cmd_line_opt = self.le_cmd_line_opt.text() algo = self.cmb_algorithm.currentText() mesh_order = self.sb_mesh_order.text() if self.cb_optimized.isChecked(): cmd_optimize = ' -optimize' else: cmd_optimize = '' if self.rb_3D.isChecked(): dim = ' -3 ' if self.rb_2D.isChecked(): dim = ' -2 ' if self.rb_1D.isChecked(): dim = ' -1 ' if self.cb_max_elme_size.isChecked(): max_size = ' -clmax ' + clmax else: max_size = '' if self.cb_min_elme_size.isChecked(): min_size = ' -clmin ' + clmin else: min_size = '' if self.cb_mesh_order.isChecked(): order = ' -order ' + mesh_order else: order = '' options = ' -algo ' + algo + max_size + min_size + cmd_optimize + order + cmd_line_opt # RUN GMSH command = gmsh_bin + ' ' + temp_file + dim + '-format ' + file_format + ' -o ' + temp_mesh_file + '' + options FreeCAD.Console.PrintMessage("Running: \"{}\"\n".format(command)) try: output = subprocess.check_output([command, '-1'], shell=True, stderr=subprocess.STDOUT,) for line in output.split('\n'): if "Error" in line: FreeCAD.Console.PrintError("{}\n".format(line)) elif "Warning" in line: FreeCAD.Console.PrintWarning("{}\n".format(line)) #FreeCAD.Console.PrintMessage("Output: \"{}\"\n".format(output)) if file_format in ('unv', 'med'): Fem.insert(temp_mesh_file, FreeCAD.ActiveDocument.Name) if file_format == 'stl': Mesh.insert(temp_mesh_file, FreeCAD.ActiveDocument.Name) if file_format == 'msh': out_mesh_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), "geometry.msh") shutil.move(temp_mesh_file, out_mesh_file) FreeCAD.Console.PrintMessage("Output file written to: {}\n".format(out_mesh_file)) if self.cb_mec_anal.isChecked(): FMesh = App.activeDocument().ActiveObject MechanicalAnalysis.makeMechanicalAnalysis('MechanicalAnalysis') FemGui.setActiveAnalysis(App.activeDocument().ActiveObject) App.activeDocument().ActiveObject.Member = App.activeDocument().ActiveObject.Member + [FMesh] if self.rb_1D.isChecked(): FMeshG = Gui.ActiveDocument.ActiveObject FMeshG.DisplayMode = "Elements & Nodes" except: FreeCAD.Console.PrintError("Unexpected error in GMSHMesh macro: {} {}\n".format(sys.exc_info()[0], sys.exc_info()[1])) finally: try: del temp_file except: pass try: del temp_mesh_file except: pass
def importFrd(filename, Analysis=None): m = readResult(filename) result_set_number = len(m['Results']) MeshObject = None if(len(m) > 0): import Fem if Analysis is None: AnalysisName = os.path.splitext(os.path.basename(filename))[0] AnalysisObject = FreeCAD.ActiveDocument.addObject('Fem::FemAnalysis', 'Analysis') AnalysisObject.Label = AnalysisName else: AnalysisObject = Analysis if 'Nodes' in m: positions = [] for k, v in m['Nodes'].iteritems(): positions.append(v) p_x_max, p_y_max, p_z_max = map(max, zip(*positions)) p_x_min, p_y_min, p_z_min = map(min, zip(*positions)) x_span = abs(p_x_max - p_x_min) y_span = abs(p_y_max - p_y_min) z_span = abs(p_z_max - p_z_min) span = max(x_span, y_span, z_span) if ('Tet10Elem' in m) and ('Nodes' in m) and (not Analysis): mesh = Fem.FemMesh() nds = m['Nodes'] for i in nds: n = nds[i] mesh.addNode(n[0], n[1], n[2], i) elms = m['Tet10Elem'] for i in elms: e = elms[i] mesh.addVolume([e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9]], i) if len(nds) > 0: MeshObject = FreeCAD.ActiveDocument.addObject('Fem::FemMeshObject', 'ResultMesh') MeshObject.FemMesh = mesh AnalysisObject.Member = AnalysisObject.Member + [MeshObject] for result_set in m['Results']: eigenmode_number = result_set['number'] if result_set_number > 1: results_name = 'Mode_' + str(eigenmode_number) + '_results' else: results_name = 'Results' results = FreeCAD.ActiveDocument.addObject('Fem::FemResultObject', results_name) 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)) if result_set_number > 1: max_disp = max(x_max, y_max, z_max) # Allow for max displacement to be 0.1% of the span # FIXME - add to Preferences max_allowed_disp = 0.001 * span scale = max_allowed_disp / max_disp else: scale = 1.0 if len(disp) > 0: results.DisplacementVectors = map((lambda x: x * scale), disp.values()) results.ElementNumbers = disp.keys() if(MeshObject): results.Mesh = MeshObject stress = result_set['stress'] if len(stress) > 0: mstress = [] for i in stress.values(): mstress.append(calculate_von_mises(i)) if result_set_number > 1: results.StressValues = map((lambda x: x * scale), mstress) else: results.StressValues = mstress if (results.ElementNumbers != 0 and results.ElementNumbers != stress.keys()): print ("Inconsistent FEM results: element number for Stress doesn't equal element number for Displacement {} != {}" .format(results.ElementNumbers, len(results.StressValues))) results.ElementNumbers = stress.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] AnalysisObject.Member = AnalysisObject.Member + [results] if(FreeCAD.GuiUp): import FemGui import FreeCADGui if FreeCADGui.activeWorkbench().name() != 'FemWorkbench': FreeCADGui.activateWorkbench("FemWorkbench") FemGui.setActiveAnalysis(AnalysisObject)
def importFrd(filename, Analysis=None): m = readResult(filename) MeshObject = None if len(m["Nodes"]) > 0: import Fem if Analysis is None: AnalysisName = os.path.splitext(os.path.basename(filename))[0] AnalysisObject = FreeCAD.ActiveDocument.addObject("Fem::FemAnalysis", "Analysis") AnalysisObject.Label = AnalysisName else: AnalysisObject = Analysis if "Nodes" in m: positions = [] for k, v in m["Nodes"].iteritems(): positions.append(v) p_x_max, p_y_max, p_z_max = map(max, zip(*positions)) p_x_min, p_y_min, p_z_min = map(min, zip(*positions)) x_span = abs(p_x_max - p_x_min) y_span = abs(p_y_max - p_y_min) z_span = abs(p_z_max - p_z_min) span = max(x_span, y_span, z_span) if ("Tet10Elem" in m) and ("Nodes" in m) and (not Analysis): mesh = Fem.FemMesh() nds = m["Nodes"] for i in nds: n = nds[i] mesh.addNode(n[0], n[1], n[2], i) elms = m["Tet10Elem"] for i in elms: e = elms[i] mesh.addVolume([e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9]], i) if len(nds) > 0: MeshObject = FreeCAD.ActiveDocument.addObject("Fem::FemMeshObject", "ResultMesh") MeshObject.FemMesh = mesh AnalysisObject.Member = AnalysisObject.Member + [MeshObject] for result_set in m["Results"]: eigenmode_number = result_set["number"] if eigenmode_number > 0: results_name = "Mode_" + str(eigenmode_number) + "_results" else: results_name = "Results" results = FreeCAD.ActiveDocument.addObject("Fem::FemResultObject", results_name) 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)) if eigenmode_number > 0: max_disp = max(x_max, y_max, z_max) # Allow for max displacement to be 0.1% of the span # FIXME - add to Preferences max_allowed_disp = 0.001 * span scale = max_allowed_disp / max_disp else: scale = 1.0 if len(disp) > 0: results.DisplacementVectors = map((lambda x: x * scale), disp.values()) results.NodeNumbers = disp.keys() if MeshObject: results.Mesh = MeshObject stress = result_set["stress"] if len(stress) > 0: mstress = [] for i in stress.values(): mstress.append(calculate_von_mises(i)) if eigenmode_number > 0: results.StressValues = map((lambda x: x * scale), mstress) results.Eigenmode = eigenmode_number results.setEditorMode("Eigenmode", 1) else: results.StressValues = mstress if results.NodeNumbers != 0 and results.NodeNumbers != stress.keys(): print( "Inconsistent FEM results: element number for Stress doesn't equal element number for Displacement {} != {}".format( results.NodeNumbers, len(results.StressValues) ) ) results.NodeNumbers = stress.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, ] AnalysisObject.Member = AnalysisObject.Member + [results] if FreeCAD.GuiUp: import FemGui FemGui.setActiveAnalysis(AnalysisObject)