def Activated(self): MatObj = None for i in FemGui.getActiveAnalysis().Member: if i.isDerivedFrom("App::MaterialObject"): MatObj = i if not MatObj: femDoc = FemGui.getActiveAnalysis().Document if FreeCAD.ActiveDocument is not femDoc: FreeCADGui.setActiveDocument(femDoc) FreeCAD.ActiveDocument.openTransaction("Create Material") FreeCADGui.addModule("MechanicalMaterial") FreeCADGui.doCommand("MechanicalMaterial.makeMechanicalMaterial('MechanicalMaterial')") FreeCADGui.doCommand( "App.activeDocument()." + FemGui.getActiveAnalysis().Name + ".Member = App.activeDocument()." + FemGui.getActiveAnalysis().Name + ".Member + [App.ActiveDocument.ActiveObject]" ) FreeCADGui.doCommand("Gui.activeDocument().setEdit(App.ActiveDocument.ActiveObject.Name,0)") # FreeCADGui.doCommand("Fem.makeMaterial()") else: if FreeCAD.ActiveDocument is not MatObj.Document: FreeCADGui.setActiveDocument(MatObj.Document) FreeCADGui.doCommand("Gui.activeDocument().setEdit('" + MatObj.Name + "',0)")
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 IsActive(self): if not self.is_active: active = False elif self.is_active == "with_document": active = FreeCADGui.ActiveDocument is not None elif self.is_active == "with_analysis": active = FemGui.getActiveAnalysis() is not None and self.active_analysis_in_active_doc() elif self.is_active == "with_results": active = ( FemGui.getActiveAnalysis() is not None and self.active_analysis_in_active_doc() and self.results_present() ) elif self.is_active == "with_part_feature": active = FreeCADGui.ActiveDocument is not None and self.part_feature_selected() elif self.is_active == "with_solver": active = ( FemGui.getActiveAnalysis() is not None and self.active_analysis_in_active_doc() and self.solver_selected() ) elif self.is_active == "with_analysis_without_solver": active = ( FemGui.getActiveAnalysis() is not None and self.active_analysis_in_active_doc() and not self.analysis_has_solver() ) return active
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 setEdit(self, vobj, mode=0): if FemGui.getActiveAnalysis() is not None: if hasattr(self.Object, "Mesh") and self.Object.Mesh: mem = FemGui.getActiveAnalysis().Member if self.Object in mem: if self.Object.Mesh in mem: import PyGui._TaskPanelFemResultShow taskd = PyGui._TaskPanelFemResultShow._TaskPanelFemResultShow(self.Object) taskd.obj = vobj.Object FreeCADGui.Control.showDialog(taskd) return True else: error_message = 'FEM: Result mesh object is not in active analysis.\n' FreeCAD.Console.PrintError(error_message) QtGui.QMessageBox.critical(None, 'Not in activate analysis', error_message) return False else: error_message = 'FEM: Result object is not in active analysis.\n' FreeCAD.Console.PrintError(error_message) QtGui.QMessageBox.critical(None, 'Not in activate analysis', error_message) return False else: error_message = 'FEM: Result object has no appropriate FEM mesh.\n' FreeCAD.Console.PrintError(error_message) QtGui.QMessageBox.critical(None, 'No result object', error_message) return False else: error_message = 'FEM: No active analysis found! Please activate the analysis you would like to view results for.\n' FreeCAD.Console.PrintError(error_message) QtGui.QMessageBox.critical(None, 'No activate analysis', error_message) return False
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 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 Activated(self): femDoc = FemGui.getActiveAnalysis().Document if FreeCAD.ActiveDocument is not femDoc: FreeCADGui.setActiveDocument(femDoc) FreeCAD.ActiveDocument.openTransaction("Create Solid Material") FreeCADGui.addModule("ObjectsFem") FreeCADGui.doCommand("ObjectsFem.makeMaterialSolid(FreeCAD.ActiveDocument, 'SolidMaterial')") FreeCADGui.doCommand("FreeCAD.ActiveDocument." + FemGui.getActiveAnalysis().Name + ".Member = FreeCAD.ActiveDocument." + FemGui.getActiveAnalysis().Name + ".Member + [FreeCAD.ActiveDocument.ActiveObject]") FreeCADGui.doCommand("FreeCADGui.ActiveDocument.setEdit(FreeCAD.ActiveDocument.ActiveObject.Name)")
def Activated(self): femDoc = FemGui.getActiveAnalysis().Document if FreeCAD.ActiveDocument is not femDoc: FreeCADGui.setActiveDocument(femDoc) FreeCAD.ActiveDocument.openTransaction("Create Fluid Material") FreeCADGui.addModule("ObjectsFem") FreeCADGui.doCommand("ObjectsFem.makeMaterialFluid('FluidMaterial')") FreeCADGui.doCommand("App.activeDocument()." + FemGui.getActiveAnalysis().Name + ".Member = App.activeDocument()." + FemGui.getActiveAnalysis().Name + ".Member + [App.ActiveDocument.ActiveObject]") FreeCADGui.doCommand("Gui.activeDocument().setEdit(App.ActiveDocument.ActiveObject.Name)")
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 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 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 editCalculixInputFile(self): print 'editCalculixInputFile {}'.format(self.inp_file_name) if self.fem_prefs.GetBool("UseInternalEditor", True): FemGui.open(self.inp_file_name) else: ext_editor_path = self.fem_prefs.GetString("ExternalEditorPath", "") if ext_editor_path: self.start_ext_editor(ext_editor_path, self.inp_file_name) else: print "External editor is not defined in FEM preferences. Falling back to internal editor" FemGui.open(self.inp_file_name)
def IsActive(self): if not self.is_active: active = False elif self.is_active == 'with_document': active = FreeCADGui.ActiveDocument is not None elif self.is_active == 'with_analysis': active = FreeCADGui.ActiveDocument is not None and FemGui.getActiveAnalysis() is not None elif self.is_active == 'with_results': active = FreeCADGui.ActiveDocument is not None and FemGui.getActiveAnalysis() is not None and self.results_present() elif self.is_active == 'with_part_feature': active = FreeCADGui.ActiveDocument is not None and FemGui.getActiveAnalysis() is not None and self.part_feature_selected() return active
def Activated(self): self.result_object = None for i in FemGui.getActiveAnalysis().Member: if i.isDerivedFrom("Fem::FemResultObject"): self.result_object = i if not self.result_object: QtGui.QMessageBox.critical(None, "Missing prerequisite", "No result found in active Analysis") return taskd = _ResultControlTaskPanel(FemGui.getActiveAnalysis()) FreeCADGui.Control.showDialog(taskd)
def editCalculixInputFile(self): print('editCalculixInputFile {}'.format(self.fea.inp_file_name)) ccx_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Ccx") if ccx_prefs.GetBool("UseInternalEditor", True): FemGui.open(self.fea.inp_file_name) else: ext_editor_path = ccx_prefs.GetString("ExternalEditorPath", "") if ext_editor_path: self.start_ext_editor(ext_editor_path, self.fea.inp_file_name) else: print("External editor is not defined in FEM preferences. Falling back to internal editor") FemGui.open(self.fea.inp_file_name)
def check_prerequisites(self): self.Start = time.time() self.femConsoleMessage("Check dependencies...") self.form.label_Time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start)) self.MeshObject = None # [{'Object':MaterialObject}, {}, ...] self.MaterialObjects = [] # [{'Object':FixedObject, 'NodeSupports':bool}, {}, ...] self.FixedObjects = [] # [{'Object':ForceObject, 'NodeLoad':value}, {}, ... self.ForceObjects = [] # [{'Object':PressureObject, 'xxxxxxxx':value}, {}, ...] self.PressureObjects = [] if not FemGui.getActiveAnalysis(): QtGui.QMessageBox.critical(None, "Missing prerequisite", "No active Analysis") return False for i in FemGui.getActiveAnalysis().Member: if i.isDerivedFrom("Fem::FemMeshObject"): self.MeshObject = i elif i.isDerivedFrom("App::MaterialObjectPython"): MaterialObjectDict = {} MaterialObjectDict['Object'] = i self.MaterialObjects.append(MaterialObjectDict) elif i.isDerivedFrom("Fem::ConstraintFixed"): FixedObjectDict = {} FixedObjectDict['Object'] = i self.FixedObjects.append(FixedObjectDict) elif i.isDerivedFrom("Fem::ConstraintForce"): ForceObjectDict = {} ForceObjectDict['Object'] = i self.ForceObjects.append(ForceObjectDict) elif i.isDerivedFrom("Fem::ConstraintPressure"): PressureObjectDict = {} PressureObjectDict['Object'] = i self.PressureObjects.append(PressureObjectDict) if not self.MeshObject: QtGui.QMessageBox.critical(None, "Missing prerequisite", "No mesh object in the Analysis") return False if not self.MaterialObjects: QtGui.QMessageBox.critical(None, "Missing prerequisite", "No material object in the Analysis") return False if not self.FixedObjects: QtGui.QMessageBox.critical(None, "Missing prerequisite", "No fixed-constraint nodes defined in the Analysis") return False if not (self.ForceObjects or self.PressureObjects): QtGui.QMessageBox.critical(None, "Missing prerequisite", "No force-constraint or pressure-constraint defined in the Analysis") return False return True
def IsActive(self): if not self.is_active: active = False elif self.is_active == 'with_document': active = FreeCADGui.ActiveDocument is not None elif self.is_active == 'with_analysis': active = FemGui.getActiveAnalysis() is not None and self.active_analysis_in_active_doc() elif self.is_active == 'with_results': active = FemGui.getActiveAnalysis() is not None and self.active_analysis_in_active_doc() and self.results_present() elif self.is_active == 'with_selresult': active = FemGui.getActiveAnalysis() is not None and self.active_analysis_in_active_doc() and self.result_selected() elif self.is_active == 'with_part_feature': active = FreeCADGui.ActiveDocument is not None and self.part_feature_selected() elif self.is_active == 'with_femmesh': active = FreeCADGui.ActiveDocument is not None and self.femmesh_selected() elif self.is_active == 'with_gmsh_femmesh': active = FreeCADGui.ActiveDocument is not None and self.gmsh_femmesh_selected() elif self.is_active == 'with_femmesh_andor_res': active = FreeCADGui.ActiveDocument is not None and self.with_femmesh_andor_res_selected() elif self.is_active == 'with_material': active = FemGui.getActiveAnalysis() is not None and self.active_analysis_in_active_doc() and self.material_selected() elif self.is_active == 'with_material_solid_which_has_no_nonlinear_material': active = FemGui.getActiveAnalysis() is not None and self.active_analysis_in_active_doc() and self.material_solid_selected() and self.has_no_nonlinear_material() elif self.is_active == 'with_solver': active = FemGui.getActiveAnalysis() is not None and self.active_analysis_in_active_doc() and self.solver_selected() elif self.is_active == 'with_solver_elmer': active = FemGui.getActiveAnalysis() is not None and self.active_analysis_in_active_doc() and self.solver_elmer_selected() elif self.is_active == 'with_analysis_without_solver': active = FemGui.getActiveAnalysis() is not None and self.active_analysis_in_active_doc() and not self.analysis_has_solver() return active
def get_active_analysis(self): import FemGui self.analysis = FemGui.getActiveAnalysis() if self.analysis: for m in FemGui.getActiveAnalysis().Member: if m.Name == self.mesh_obj.Name: print(self.analysis.Name) return else: # print('Mesh is not member of active analysis, means no group meshing') self.analysis = None # no group meshing else: # print('No active analyis, means no group meshing') self.analysis = None # no group meshing
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 Activated(self): sel = FreeCADGui.Selection.getSelection() if len(sel) == 1 and sel[0].isDerivedFrom("App::MaterialObjectPython"): lin_mat_obj = sel[0] # check if an nonlinear material exists which is based on the selected material already allow_nonlinear_material = True for o in FreeCAD.ActiveDocument.Objects: if hasattr(o, "Proxy") and o.Proxy is not None and o.Proxy.Type == "FemMaterialMechanicalNonlinear" and o.LinearBaseMaterial == lin_mat_obj: FreeCAD.Console.PrintError(o.Name + ' is based on the selected material: ' + lin_mat_obj.Name + '. Only one nonlinear object for each material allowed.\n') allow_nonlinear_material = False break if allow_nonlinear_material: string_lin_mat_obj = "App.ActiveDocument.getObject('" + lin_mat_obj.Name + "')" command_to_run = "FemGui.getActiveAnalysis().Member = FemGui.getActiveAnalysis().Member + [FemMaterialMechanicalNonlinear.makeFemMaterialMechanicalNonlinear(" + string_lin_mat_obj + ")]" FreeCAD.ActiveDocument.openTransaction("Create FemMaterialMechanicalNonlinear") FreeCADGui.addModule("FemMaterialMechanicalNonlinear") FreeCADGui.doCommand(command_to_run) # set the material nonlinear property of the solver to nonlinear if only one solver is available and if this solver is a CalculiX solver solver_object = None for m in FemGui.getActiveAnalysis().Member: if m.isDerivedFrom('Fem::FemSolverObjectPython'): if not solver_object: solver_object = m else: # we do not change the material nonlinear attribut if we have more than one solver solver_object = None break if solver_object and solver_object.SolverType == 'FemSolverCalculix': solver_object.MaterialNonlinearity = "nonlinear"
def Activated(self): import FemGui taskd = _JobControlTaskPanel(FemGui.getActiveAnalysis()) #taskd.obj = vobj.Object taskd.update() FreeCADGui.Control.showDialog(taskd)
def calculixFinished(self,exitCode): print "calculixFinished()",exitCode print self.Calculix.state() out = self.Calculix.readAllStandardOutput() print out if out: self.OutStr = self.OutStr + unicode(out).replace('\n','<br>') self.formUi.textEdit_Output.setText(self.OutStr) self.Timer.stop() self.OutStr = self.OutStr + '<font color="#0000FF">{0:4.1f}:</font> '.format(time.time() - self.Start) + '<font color="#00FF00">Calculix done!</font><br>' self.formUi.textEdit_Output.setText(self.OutStr) self.formUi.pushButton_generate.setText("Re-run Calculix") print "Loading results...." self.OutStr = self.OutStr + '<font color="#0000FF">{0:4.1f}:</font> '.format(time.time() - self.Start) + 'Loading result sets...<br>' self.formUi.textEdit_Output.setText(self.OutStr) self.formUi.label_Time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start) ) QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) CalculixLib.importFrd(self.Basename + '.frd',FemGui.getActiveAnalysis() ) QApplication.restoreOverrideCursor() self.OutStr = self.OutStr + '<font color="#0000FF">{0:4.1f}:</font> '.format(time.time() - self.Start) + '<font color="#00FF00">Loading results done!</font><br>' self.formUi.textEdit_Output.setText(self.OutStr) self.formUi.label_Time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start) )
def __init__(self, analysis=None, test_mode=False): if analysis: ## @var analysis # FEM analysis - the core object. Has to be present. # It's set to analysis passed in "__init__" or set to current active analysis by default if nothing has been passed to "__init__". self.analysis = analysis else: import FemGui self.analysis = FemGui.getActiveAnalysis() if self.analysis: self.update_objects() self.base_name = "" if self.solver: self.set_analysis_type() self.setup_working_dir() self.setup_z88() else: raise Exception('FEM: No solver found!') else: raise Exception('FEM: No active analysis found!') self.z88_is_running = False self.z88_testrun = QtCore.QProcess() self.z88_solverun = QtCore.QProcess() QtCore.QObject.connect(self.z88_testrun, QtCore.SIGNAL("started()"), self.z88_testrun_started) QtCore.QObject.connect(self.z88_testrun, QtCore.SIGNAL("finished(int)"), self.z88_testrun_finished) QtCore.QObject.connect(self.z88_solverun, QtCore.SIGNAL("started()"), self.z88_solverun_started) QtCore.QObject.connect(self.z88_solverun, QtCore.SIGNAL("finished(int)"), self.z88_solverun_finished)
def results_present(): results = False analysis_members = FemGui.getActiveAnalysis().Member for o in analysis_members: if o.isDerivedFrom('Fem::FemResultObject'): results = True return results
def calculixFinished(self, exitCode): print "calculixFinished()", exitCode print self.Calculix.state() # Restore previous cwd QtCore.QDir.setCurrent(self.cwd) self.printCalculiXstdout() self.Timer.stop() self.femConsoleMessage("Calculix done!", "#00AA00") self.form.pushButton_generate.setText("Re-run Calculix") print "Loading results...." self.femConsoleMessage("Loading result sets...") self.form.label_Time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start)) fea = FemTools() fea.reset_all() frd_result_file = os.path.splitext(self.inp_file_name)[0] + '.frd' if os.path.isfile(frd_result_file): QApplication.setOverrideCursor(Qt.WaitCursor) ccxFrdReader.importFrd(frd_result_file, FemGui.getActiveAnalysis()) QApplication.restoreOverrideCursor() self.femConsoleMessage("Loading results done!", "#00AA00") else: self.femConsoleMessage("Loading results failed! Results file doesn\'t exist", "#FF0000") self.form.label_Time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start))
def __init__(self, analysis=None, test_mode=False): QtCore.QRunnable.__init__(self) QtCore.QObject.__init__(self) if analysis: ## @var analysis # FEM analysis - the core object. Has to be present. # It's set to analysis passed in "__init__" or set to current active analysis by default if nothing has been passed to "__init__". self.analysis = analysis else: import FemGui self.analysis = FemGui.getActiveAnalysis() if self.analysis: self.update_objects() self.set_analysis_type() self.set_eigenmode_parameters() ## @var base_name # base name of .inp/.frd file (without extension). It is used to construct .inp file path that is passed to CalculiX ccx self.base_name = "" ## @var results_present # boolean variable indicating if there are calculation results ready for use self.results_present = False self.setup_working_dir() if test_mode: self.ccx_binary_present = True else: self.ccx_binary_present = False self.setup_ccx() self.result_object = None else: raise Exception('FEM: No active analysis found!')
def __init__(self, analysis=None, solver=None): if analysis: ## @var analysis # FEM analysis - the core object. Has to be present. # It's set to analysis passed in "__init__" or set to current active analysis by default if nothing has been passed to "__init__". self.analysis = analysis else: import FemGui self.analysis = FemGui.getActiveAnalysis() if solver: ## @var solver # solver of the analysis. Used to store the active solver and analysis parameters self.solver = solver else: self.solver = None if self.analysis: self.update_objects() self.results_present = False self.result_object = None else: raise Exception('FEM: No active analysis found!')
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 __init__(self, analysis=None, solver=None, test_mode=False): QtCore.QRunnable.__init__(self) QtCore.QObject.__init__(self) if analysis: ## @var analysis # FEM analysis - the core object. Has to be present. # It's set to analysis passed in "__init__" or set to current active analysis by default if nothing has been passed to "__init__". self.analysis = analysis else: import FemGui self.analysis = FemGui.getActiveAnalysis() if solver: ## @var solver # solver of the analysis. Used to store the active solver and analysis parameters self.solver = solver else: self.solver = None if self.analysis: self.update_objects() ## @var base_name # base name of .inp/.frd file (without extension). It is used to construct .inp file path that is passed to CalculiX ccx self.base_name = "" ## @var results_present # boolean variable indicating if there are calculation results ready for use self.results_present = False if self.solver: self.set_analysis_type() self.setup_working_dir() else: raise Exception('FEM: No solver found!') if test_mode: self.ccx_binary_present = True else: self.ccx_binary_present = False self.setup_ccx() self.result_object = None else: raise Exception('FEM: No active analysis found!')
def Activated(self): FreeCAD.ActiveDocument.openTransaction("Create CFD mesh by GMSH") FreeCADGui.addModule("FemGui") sel = FreeCADGui.Selection.getSelection() if (len(sel) == 1): if (sel[0].isDerivedFrom("Part::Feature")): mesh_obj_name = sel[0].Name + "_Mesh" FreeCADGui.addModule("CfdMeshGmsh") FreeCADGui.doCommand("CfdMeshGmsh.makeCfdMeshGmsh('" + mesh_obj_name + "')") FreeCADGui.doCommand( "App.ActiveDocument.ActiveObject.Part = App.ActiveDocument." + sel[0].Name) if FemGui.getActiveAnalysis(): FreeCADGui.addModule("FemGui") FreeCADGui.doCommand( "FemGui.getActiveAnalysis().Member = FemGui.getActiveAnalysis().Member + [App.ActiveDocument.ActiveObject]" ) FreeCADGui.doCommand( "Gui.ActiveDocument.setEdit(App.ActiveDocument.ActiveObject.Name)" ) FreeCADGui.Selection.clearSelection()
def write_footer(self, f): FcVersionInfo = FreeCAD.Version() f.write( '\n***********************************************************\n') f.write('** CalculiX Input file\n') f.write('** written by {} function\n'.format( sys._getframe().f_code.co_name)) f.write('**\n') f.write('** written by --> FreeCAD ' + FcVersionInfo[0] + '.' + FcVersionInfo[1] + '.' + FcVersionInfo[2] + '\n') f.write('** written on --> ' + time.ctime() + '\n') f.write('** file name --> ' + os.path.basename(FreeCAD.ActiveDocument.FileName) + '\n') f.write('** analysis name --> ' + FemGui.getActiveAnalysis().Name + '\n') f.write('**\n') f.write('**\n') f.write('** Units\n') f.write('**\n') f.write('** Geometry (mesh data) --> mm\n') f.write("** Materials (Young's modulus) --> N/mm2 = MPa\n") f.write('** Loads (nodal loads) --> N\n') f.write('**\n')
def update(self): self.MeshObject = None self.result_object = get_results_object( FreeCADGui.Selection.getSelection()) for i in FemGui.getActiveAnalysis().Member: if i.isDerivedFrom("Fem::FemMeshObject"): self.MeshObject = i break if self.MeshObject.FemMesh.NodeCount == len( self.result_object.ElementNumbers): self.suitable_results = True else: self.suitable_results = False if not self.MeshObject.FemMesh.VolumeCount: FreeCAD.Console.PrintError( 'Graphical bending stress output for beam or shell FEM Meshes not yet supported!\n' ) else: FreeCAD.Console.PrintError( 'Result node numbers are not equal to FEM Mesh NodeCount!\n' )
def Activated(self): # a mesh could be made with and without an analysis, # we're going to check not for an analysis in command manager module FreeCAD.ActiveDocument.openTransaction("Create FEM mesh by Gmsh") mesh_obj_name = 'FEMMeshGmsh' # mesh_obj_name = self.selobj.Name + "_Mesh" # if requested by some people add Preference for this FreeCADGui.addModule("ObjectsFem") FreeCADGui.doCommand( "ObjectsFem.makeMeshGmsh(FreeCAD.ActiveDocument, '" + mesh_obj_name + "')") FreeCADGui.doCommand( "FreeCAD.ActiveDocument.ActiveObject.Part = FreeCAD.ActiveDocument." + self.selobj.Name) import FemGui if FemGui.getActiveAnalysis(): FreeCADGui.addModule("FemGui") FreeCADGui.doCommand( "FemGui.getActiveAnalysis().addObject(FreeCAD.ActiveDocument.ActiveObject)" ) FreeCADGui.doCommand( "Gui.ActiveDocument.setEdit(FreeCAD.ActiveDocument.ActiveObject.Name)" ) FreeCADGui.Selection.clearSelection()
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 Activated(self): # a mesh could be made with and without an analysis, # we're going to check not for an analysis in command manager module FreeCAD.ActiveDocument.openTransaction("Create FEM mesh Netgen") mesh_obj_name = 'FEMMeshNetgen' # mesh_obj_name = sel[0].Name + "_Mesh" # if requested by some people add Preference for this FreeCADGui.addModule("ObjectsFem") FreeCADGui.doCommand( "ObjectsFem.makeMeshNetgen(FreeCAD.ActiveDocument, '" + mesh_obj_name + "')") FreeCADGui.doCommand( "FreeCAD.ActiveDocument.ActiveObject.Shape = FreeCAD.ActiveDocument." + self.selobj.Name) # Netgen mesh object could be added without an active analysis, but if there is an active analysis move it in there import FemGui import FemGui if FemGui.getActiveAnalysis(): FreeCADGui.addModule("FemGui") FreeCADGui.doCommand( "FemGui.getActiveAnalysis().addObject(FreeCAD.ActiveDocument.ActiveObject)" ) FreeCADGui.doCommand( "FreeCADGui.ActiveDocument.setEdit(FreeCAD.ActiveDocument.ActiveObject.Name)" ) FreeCADGui.Selection.clearSelection()
def Activated(self): FreeCAD.ActiveDocument.openTransaction("Create FEM mesh Netgen") FreeCADGui.addModule("FemGui") sel = FreeCADGui.Selection.getSelection() if (len(sel) == 1): if (sel[0].isDerivedFrom("Part::Feature")): mesh_obj_name = 'FEMMeshNetgen' # mesh_obj_name = sel[0].Name + "_Mesh" # if requested by some people add Preference for this FreeCADGui.doCommand( "App.ActiveDocument.addObject('Fem::FemMeshShapeNetgenObject', '" + mesh_obj_name + "')") FreeCADGui.doCommand( "App.ActiveDocument.ActiveObject.Shape = App.activeDocument()." + sel[0].Name) if FemGui.getActiveAnalysis(): FreeCADGui.addModule("FemGui") FreeCADGui.doCommand( "FemGui.getActiveAnalysis().Member = FemGui.getActiveAnalysis().Member + [App.ActiveDocument.ActiveObject]" ) FreeCADGui.doCommand( "Gui.ActiveDocument.setEdit(App.ActiveDocument.ActiveObject.Name)" ) FreeCADGui.Selection.clearSelection()
def Activated(self): sel = FreeCADGui.Selection.getSelection() if len(sel) == 1 and sel[0].isDerivedFrom("App::MaterialObjectPython"): lin_mat_obj = sel[0] # check if an nonlinear material exists which is based on the selected material already allow_nonlinear_material = True for o in FreeCAD.ActiveDocument.Objects: if hasattr( o, "Proxy" ) and o.Proxy is not None and o.Proxy.Type == "FemMaterialMechanicalNonlinear" and o.LinearBaseMaterial == lin_mat_obj: FreeCAD.Console.PrintError( o.Name + ' is based on the selected material: ' + lin_mat_obj.Name + '. Only one nonlinear object for each material allowed.\n' ) allow_nonlinear_material = False break if allow_nonlinear_material: string_lin_mat_obj = "App.ActiveDocument.getObject('" + lin_mat_obj.Name + "')" command_to_run = "FemGui.getActiveAnalysis().Member = FemGui.getActiveAnalysis().Member + [FemMaterialMechanicalNonlinear.makeFemMaterialMechanicalNonlinear(" + string_lin_mat_obj + ")]" FreeCAD.ActiveDocument.openTransaction( "Create FemMaterialMechanicalNonlinear") FreeCADGui.addModule("FemMaterialMechanicalNonlinear") FreeCADGui.doCommand(command_to_run) # set the material nonlinear property of the solver to nonlinear if only one solver is available and if this solver is a CalculiX solver solver_object = None for m in FemGui.getActiveAnalysis().Member: if m.isDerivedFrom('Fem::FemSolverObjectPython'): if not solver_object: solver_object = m else: # we do not change the material nonlinear attribut if we have more than one solver solver_object = None break if solver_object and solver_object.SolverType == 'FemSolverCalculix': solver_object.MaterialNonlinearity = "nonlinear"
def __init__(self, solver_runner_obj): ui_path = os.path.join(os.path.dirname(__file__), "TaskPanelCfdSolverControl.ui") self.form = FreeCADGui.PySideUic.loadUi(ui_path) self.analysis_object = FemGui.getActiveAnalysis() self.solver_runner = solver_runner_obj self.solver_object = solver_runner_obj.solver # update UI self.console_message = '' self.solver_run_process = CfdConsoleProcess(finishedHook=self.solverFinished, stdoutHook=self.gotOutputLines, stderrHook=self.gotErrorLines) self.Timer = QtCore.QTimer() self.form.terminateSolver.clicked.connect(self.killSolverProcess) self.form.terminateSolver.setEnabled(False) self.open_paraview = QtCore.QProcess() self.working_dir = CfdTools.getOutputPath(self.analysis_object) self.updateUI() # Connect Signals and Slots QtCore.QObject.connect(self.form.pb_write_inp, QtCore.SIGNAL("clicked()"), self.write_input_file_handler) QtCore.QObject.connect(self.form.pb_edit_inp, QtCore.SIGNAL("clicked()"), self.editSolverInputFile) QtCore.QObject.connect(self.form.pb_run_solver, QtCore.SIGNAL("clicked()"), self.runSolverProcess) # QtCore.QObject.connect(self.form.pb_show_result, QtCore.SIGNAL("clicked()"), self.showResult) QtCore.QObject.connect(self.form.pb_paraview, QtCore.SIGNAL("clicked()"), self.openParaview) # self.form.pb_show_result.setEnabled(False) QtCore.QObject.connect(self.Timer, QtCore.SIGNAL("timeout()"), self.updateText) self.Start = time.time()
def IsActive(self): if not self.is_active: active = False elif self.is_active == 'with_document': active = FreeCADGui.ActiveDocument is not None elif self.is_active == 'with_analysis': active = FemGui.getActiveAnalysis( ) is not None and self.active_analysis_in_active_doc() elif self.is_active == 'with_results': active = FemGui.getActiveAnalysis( ) is not None and self.active_analysis_in_active_doc( ) and self.results_present() elif self.is_active == 'with_selresult': active = FemGui.getActiveAnalysis( ) is not None and self.active_analysis_in_active_doc( ) and self.result_selected() elif self.is_active == 'with_part_feature': active = FreeCADGui.ActiveDocument is not None and self.part_feature_selected( ) elif self.is_active == 'with_femmesh': active = FreeCADGui.ActiveDocument is not None and self.femmesh_selected( ) elif self.is_active == 'with_gmsh_femmesh': active = FreeCADGui.ActiveDocument is not None and self.gmsh_femmesh_selected( ) elif self.is_active == 'with_femmesh_andor_res': active = FreeCADGui.ActiveDocument is not None and self.with_femmesh_andor_res_selected( ) elif self.is_active == 'with_material': active = FemGui.getActiveAnalysis( ) is not None and self.active_analysis_in_active_doc( ) and self.material_selected() elif self.is_active == 'with_solver': active = FemGui.getActiveAnalysis( ) is not None and self.active_analysis_in_active_doc( ) and self.solver_selected() elif self.is_active == 'with_analysis_without_solver': active = FemGui.getActiveAnalysis( ) is not None and self.active_analysis_in_active_doc( ) and not self.analysis_has_solver() return active
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 edit(self, directory): pattern = os.path.join(directory, "*.inp") FreeCAD.Console.PrintMessage("{}\n".format(pattern)) f = glob.glob(pattern)[0] FemGui.open(f)
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): 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 = result_name_prefix + 'mode_' + str( eigenmode_number) + '_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'] 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): 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'].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): 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' import FemMechanicalResult results = FemMechanicalResult.makeFemMechanicalResult(results_name) for m in analysis_object.Member: if m.isDerivedFrom("Fem::FemMeshObject"): results.Mesh = m break disp = result_set['disp'] stressv = result_set['stressv'] strainv = result_set['strainv'] no_of_values = len(disp) displacement = [] for k, v in disp.items(): 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 = list( map((lambda x: x * scale), disp.values())) results.StressVectors = list( map((lambda x: x * scale), stressv.values())) results.StrainVectors = list( map((lambda x: x * scale), strainv.values())) results.NodeNumbers = list(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 = list(map((lambda x: x), Temp)) else: results.Temperature = list( 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 = list( map((lambda x: x * scale), mstress)) results.PrincipalMax = list( map((lambda x: x * scale), prinstress1)) results.PrincipalMed = list( map((lambda x: x * scale), prinstress2)) results.PrincipalMin = list( map((lambda x: x * scale), prinstress3)) results.MaxShear = list( 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 != list(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 = list(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 writeCalculixInputFile(self): print 'writeCalculixInputFile' self.Start = time.time() #dirName = self.form.lineEdit_outputDir.text() dirName = self.TempDir print 'CalculiX run directory: ', dirName self.femConsoleMessage("Check dependencies...") self.form.label_Time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start)) MeshObject = None if FemGui.getActiveAnalysis(): for i in FemGui.getActiveAnalysis().Member: if i.isDerivedFrom("Fem::FemMeshObject"): MeshObject = i else: QtGui.QMessageBox.critical(None, "Missing prerequisit", "No active Analysis") return if not MeshObject: QtGui.QMessageBox.critical(None, "Missing prerequisit", "No mesh object in the Analysis") return MathObject = None for i in FemGui.getActiveAnalysis().Member: if i.isDerivedFrom("App::MaterialObjectPython"): MathObject = i if not MathObject: QtGui.QMessageBox.critical(None, "Missing prerequisit", "No material object in the Analysis") return matmap = MathObject.Material FixedObject = None for i in FemGui.getActiveAnalysis().Member: if i.isDerivedFrom("Fem::ConstraintFixed"): FixedObject = i if not FixedObject: QtGui.QMessageBox.critical( None, "Missing prerequisit", "No fixed-constraint nodes defined in the Analysis") return ForceObject = None for i in FemGui.getActiveAnalysis().Member: if i.isDerivedFrom("Fem::ConstraintForce"): ForceObject = i if not ForceObject: QtGui.QMessageBox.critical( None, "Missing prerequisit", "No force-constraint nodes defined in the Analysis") return QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.Basename = self.TempDir + '/' + MeshObject.Name filename = self.Basename + '.inp' self.femConsoleMessage(self.Basename) self.femConsoleMessage("Write mesh...") # write mesh MeshObject.FemMesh.writeABAQUS(filename) # reopen file with "append" and add the analysis definition inpfile = open(filename, 'a') self.femConsoleMessage("Write loads & Co...") # write fixed node set NodeSetName = FixedObject.Name inpfile.write( '\n\n\n\n***********************************************************\n' ) inpfile.write('** node set for fixed constraint\n') inpfile.write('*NSET,NSET=' + NodeSetName + '\n') for o, f in FixedObject.References: fo = o.Shape.getElement(f) if fo.ShapeType == 'Face': FixedObjectType = 'AreaSupport' n = MeshObject.FemMesh.getNodesByFace(fo) for i in n: inpfile.write(str(i) + ',\n') elif fo.ShapeType == 'Edge': FixedObjectType = 'LineSupport' print 'Line Supports are not yet implemented to export to CalculiX' # getNodesByEdge(fo) # not implemented yet elif fo.ShapeType == 'Vertex': FixedObjectType = 'PointSupport' print 'Point Supports are not yet implemented to export to CalculiX' # write load node set NodeSetNameForce = ForceObject.Name inpfile.write( '\n\n\n\n***********************************************************\n' ) inpfile.write('** node set for load\n') inpfile.write('*NSET,NSET=' + NodeSetNameForce + '\n') NbrForceNods = 0 for o, f in ForceObject.References: fo = o.Shape.getElement(f) if fo.ShapeType == 'Face': ForceObjectType = 'AreaLoad' n = MeshObject.FemMesh.getNodesByFace(fo) for i in n: inpfile.write(str(i) + ',\n') NbrForceNods = NbrForceNods + 1 elif fo.ShapeType == 'Edge': ForceObjectType = 'LineLoad' print 'Line Loads are not yet implemented to export to CalculiX' # getNodesByEdge(fo) # not implemented yet elif fo.ShapeType == 'Vertex': ForceObjectType = 'PointLoad' print 'Point Loads are not yet implemented to export to CalculiX' # get material properties YM = FreeCAD.Units.Quantity( MathObject.Material['Mechanical_youngsmodulus']) if YM.Unit.Type == '': print 'Material "Mechanical_youngsmodulus" has no Unit, asuming kPa!' YM = FreeCAD.Units.Quantity(YM.Value, FreeCAD.Units.Unit('Pa')) else: print 'YM unit: ', YM.Unit.Type print 'YM = ', YM PR = float(MathObject.Material['FEM_poissonratio']) print 'PR = ', PR # write material properties inpfile.write( '\n\n\n\n***********************************************************\n' ) inpfile.write('** material\n') inpfile.write('** unit is MPa = N/mm2\n') inpfile.write('*MATERIAL, Name=' + matmap['General_name'] + '\n') inpfile.write('*ELASTIC \n') inpfile.write('{0:.3f}, '.format(YM.Value * 1E-3)) inpfile.write('{0:.3f}\n'.format(PR)) inpfile.write('*SOLID SECTION, Elset=Eall, Material=' + matmap['General_name'] + '\n') # write step beginn inpfile.write( '\n\n\n\n***********************************************************\n' ) inpfile.write( '** one step is needed to calculate the mechanical analysis of FreeCAD\n' ) inpfile.write( '** loads are applied quasi-static, means without involving the time dimension\n' ) inpfile.write('*STEP\n') inpfile.write('*STATIC\n') # write constaints inpfile.write('\n\n** constaints\n') if FixedObjectType == 'AreaSupport': inpfile.write('*BOUNDARY\n') inpfile.write(NodeSetName + ',1,3,0.0\n') elif FixedObjectType == 'LineSupport': pass # ToDo elif FixedObjectType == 'PointSupport': pass # ToDo # write loads #inpfile.write('*DLOAD\n') #inpfile.write('Eall,NEWTON\n') inpfile.write('\n\n** loads\n') if ForceObjectType == 'AreaLoad': Force = ForceObject.Force / NbrForceNods vec = ForceObject.DirectionVector inpfile.write('** direction: ' + str(vec) + '\n') inpfile.write( '** concentrated load [N] distributed on the area of the given faces.\n' ) inpfile.write('** ' + str(ForceObject.Force) + ' N / ' + str(NbrForceNods) + ' Nodes = ' + str(Force) + ' N on each node\n') inpfile.write('*CLOAD\n') inpfile.write(NodeSetNameForce + ',1,' + ` vec.x * Force ` + '\n') inpfile.write(NodeSetNameForce + ',2,' + ` vec.y * Force ` + '\n') inpfile.write(NodeSetNameForce + ',3,' + ` vec.z * Force ` + '\n') elif ForceObjectType == 'LineLoad': pass # ToDo elif ForceObjectType == 'PointLoad': pass # ToDo # write outputs, both are needed by FreeCAD inpfile.write('\n\n** outputs --> frd file\n') inpfile.write('*NODE FILE\n') inpfile.write('U\n') inpfile.write('*EL FILE\n') inpfile.write('S, E\n') inpfile.write('** outputs --> dat file\n') inpfile.write('*NODE PRINT , NSET=Nall \n') inpfile.write('U \n') inpfile.write('*EL PRINT , ELSET=Eall \n') inpfile.write('S \n') inpfile.write('\n\n') # write step end inpfile.write('*END STEP \n') # write some informations FcVersionInfo = FreeCAD.Version() inpfile.write( '\n\n\n\n***********************************************************\n' ) inpfile.write('**\n') inpfile.write('** CalculiX Inputfile\n') inpfile.write('**\n') inpfile.write('** written by --> FreeCAD ' + FcVersionInfo[0] + '.' + FcVersionInfo[1] + '.' + FcVersionInfo[2] + '\n') inpfile.write('** written on --> ' + time.ctime() + '\n') inpfile.write('** file name --> ' + os.path.basename(FreeCAD.ActiveDocument.FileName) + '\n') inpfile.write('** analysis name --> ' + FemGui.getActiveAnalysis().Name + '\n') inpfile.write('**\n') inpfile.write('**\n') inpfile.write('** Units\n') inpfile.write('**\n') inpfile.write('** Geometry (mesh data) --> mm\n') inpfile.write("** Materials (young's modulus) --> N/mm2 = MPa\n") inpfile.write('** Loads (nodal loads) --> N\n') inpfile.write('**\n') inpfile.write('**\n') inpfile.close() QApplication.restoreOverrideCursor()
def writeFile(self): print('started FemConstraintDisplacementInpFile') import FemGui f_analysis = FemGui.getActiveAnalysis() displacement_constraints = [] beam_sections = [] shell_thicknesses = [] f_mesh = None dir_name = None file_name = None for m in f_analysis.Member: if m.isDerivedFrom("Fem::ConstraintDisplacement"): displacement_constraint_dict = {} displacement_constraint_dict['Object'] = m displacement_constraints.append(displacement_constraint_dict) elif m.isDerivedFrom("Fem::FemMeshObject"): f_mesh = m elif hasattr(m, "Proxy") and m.Proxy.Type == 'FemBeamSection': beam_section_dict = {} beam_section_dict['Object'] = m beam_sections.append(beam_section_dict) elif hasattr(m, "Proxy") and m.Proxy.Type == "FemShellThickness": shell_thickness_dict = {} shell_thickness_dict['Object'] = m shell_thicknesses.append(shell_thickness_dict) dir_name = FreeCAD.ActiveDocument.TransientDir.replace( '\\', '/') + '/FemConstraints' if not os.path.isdir(dir_name): os.mkdir(dir_name) file_name = dir_name + '/' + 'FemConstraintDisplacement.txt' print(file_name) inpfile = open(file_name, 'w') inpfile.write( '\n***********************************************************\n') inpfile.write('** Node sets for prescribed displacement constraint\n') #inpfile.write('** written by {} function\n'.format(sys._getframe().f_code.co_name)) for fobj in displacement_constraints: disp_obj = fobj['Object'] inpfile.write('*NSET,NSET=' + disp_obj.Name + '\n') for o, elem in disp_obj.References: fo = o.Shape.getElement(elem) n = [] if fo.ShapeType == 'Face': n = f_mesh.FemMesh.getNodesByFace(fo) elif fo.ShapeType == 'Edge': n = f_mesh.FemMesh.getNodesByEdge(fo) elif fo.ShapeType == 'Vertex': n = f_mesh.FemMesh.getNodesByVertex(fo) for i in n: inpfile.write(str(i) + ',\n') inpfile.write( '\n***********************************************************\n') inpfile.write('** Displacement constraint applied\n') #f.write('** written by {} function\n'.format(sys._getframe().f_code.co_name)) for disp_obj in displacement_constraints: disp_obj_name = disp_obj['Object'].Name inpfile.write('*BOUNDARY\n') if disp_obj['Object'].xFix == True: inpfile.write(disp_obj_name + ',1\n') elif disp_obj['Object'].xFree == False: inpfile.write(disp_obj_name + ',1,1,' + str(disp_obj['Object'].xDisplacement) + '\n') if disp_obj['Object'].yFix == True: inpfile.write(disp_obj_name + ',2\n') elif disp_obj['Object'].yFree == False: inpfile.write(disp_obj_name + ',2,2,' + str(disp_obj['Object'].yDisplacement) + '\n') if disp_obj['Object'].zFix == True: inpfile.write(disp_obj_name + ',3\n') elif disp_obj['Object'].zFree == False: inpfile.write(disp_obj_name + ',3,3,' + str(disp_obj['Object'].zDisplacement) + '\n') if beam_sections or shell_thicknesses: if disp_obj['Object'].rotxFix == True: inpfile.write(disp_obj_name + ',4\n') elif disp_obj['Object'].rotxFree == False: inpfile.write(disp_obj_name + ',4,4,' + str(disp_obj['Object'].xRotation) + '\n') if disp_obj['Object'].rotyFix == True: inpfile.write(disp_obj_name + ',5\n') elif disp_obj['Object'].rotyFree == False: inpfile.write(disp_obj_name + ',5,5,' + str(disp_obj['Object'].yRotation) + '\n') if disp_obj['Object'].rotzFix == True: inpfile.write(disp_obj_name + ',6\n') elif disp_obj['Object'].rotzFree == False: inpfile.write(disp_obj_name + ',6,6,' + str(disp_obj['Object'].zRotation) + '\n') inpfile.close() print('completed FemConstraintDisplacementInpFile')
def create_test_results(): import os import shutil import sys import FemGui import Test 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 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() fea.update_objects() 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 = join(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() fea.update_objects() 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 = join(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 = join(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 = join( 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 = join( Flow1D_thermomech_analysis_dir, "Flow1D_thermomech.frd") dat_Flow1D_thermomech_test_result_file = join( 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 edit(self, directory): pattern = os.path.join(directory, "z88i1.txt") FreeCAD.Console.PrintMessage("{}\n".format(pattern)) f = glob.glob(pattern)[0] FemGui.open(f) pattern = os.path.join(directory, "z88i2.txt") FreeCAD.Console.PrintMessage("{}\n".format(pattern)) f = glob.glob(pattern)[0] FemGui.open(f) pattern = os.path.join(directory, "z88i5.txt") FreeCAD.Console.PrintMessage("{}\n".format(pattern)) f = glob.glob(pattern)[0] FemGui.open(f) pattern = os.path.join(directory, "z88man.txt") FreeCAD.Console.PrintMessage("{}\n".format(pattern)) f = glob.glob(pattern)[0] FemGui.open(f) pattern = os.path.join(directory, "z88mat.txt") FreeCAD.Console.PrintMessage("{}\n".format(pattern)) f = glob.glob(pattern)[0] FemGui.open(f) pattern = os.path.join(directory, "z88elp.txt") FreeCAD.Console.PrintMessage("{}\n".format(pattern)) f = glob.glob(pattern)[0] FemGui.open(f)
def Activated(self): taskd = _JobControlTaskPanel(FemGui.getActiveAnalysis()) #taskd.obj = vobj.Object taskd.update() FreeCADGui.Control.showDialog(taskd)
def active_analysis_in_active_doc(self): return FemGui.getActiveAnalysis().Document is FreeCAD.ActiveDocument
App.setActiveDocument("Unnamed") App.ActiveDocument = App.getDocument("Unnamed") Gui.ActiveDocument = Gui.getDocument("Unnamed") Gui.activateWorkbench("PartWorkbench") App.ActiveDocument.addObject("Part::Cylinder", "Cylinder") App.ActiveDocument.ActiveObject.Label = "Cylinder" App.ActiveDocument.recompute() Gui.SendMsgToActiveView("ViewFit") Gui.activateWorkbench("CfdWorkbench") Gui.ActiveDocument.setEdit('Cylinder', 0) import FemGui import CfdObjects CfdObjects.makeCfdAnalysis('CfdAnalysis') FemGui.setActiveAnalysis(App.activeDocument().ActiveObject) FemGui.getActiveAnalysis().addObject(CfdObjects.makeCfdSolver('OpenFOAM')) FemGui.getActiveAnalysis().addObject(CfdObjects.makeCfdSolver('Fenics')) FemGui.getActiveAnalysis().addObject( CfdObjects.makeCfdFluidMaterial('FluidMaterial')) mesh_obj = CfdObjects.makeCfdMeshGmsh('Cylinder_Mesh') mesh_obj.Part = App.ActiveDocument.Cylinder FemGui.getActiveAnalysis().addObject(mesh_obj) try: from cfdobjects.CaeMesherGmsh import CaeMesherGmsh except: from CaeMesherGmsh import CaeMesherGmsh # before move obj into cfdobjects folder # is there a API like `CfdObjects.makeCfdF` gmsh_mesh = CaeMesherGmsh(mesh_obj, FemGui.getActiveAnalysis())
def IsActive(self): if FemGui.getActiveAnalysis(): return True else: return False
import MechanicalMaterial import cadquery as cq def PrintError(message): FreeCAD.Console.PrintError("FEM Error: {}".format(message)) doc = FreeCAD.ActiveDocument box = cq.Workplane("XY").box(10, 10, 10).val().wrapped newFeature = doc.addObject('Part::Feature', 'Box') newFeature.Shape = box FemAnalysis.makeFemAnalysis('Analysis') FemGui.setActiveAnalysis(FreeCAD.ActiveDocument.Analysis) # solver solver_object = FemSolverCalculix.makeFemSolverCalculix('CalculiX') solver_object.GeometricalNonlinearity = 'linear' solver_object.SteadyState = True solver_object.MatrixSolverType = 'default' solver_object.IterationsControlParameterTimeUse = False doc.Analysis.Member = doc.Analysis.Member + [solver_object] # material material_object = MechanicalMaterial.\ makeMechanicalMaterial('MechanicalMaterial') mat = material_object.Material mat['Name'] = "Steel-Generic" mat['YoungsModulus'] = "210000 MPa"
def IsActive(self): return FreeCADGui.ActiveDocument is not None and FemGui.getActiveAnalysis( ) is not None
def importFrd(filename, analysis=None, result_name_prefix=""): from . import importToolsFem import ObjectsFem if analysis: doc = analysis.Document else: doc = FreeCAD.ActiveDocument m = read_frd_result(filename) result_mesh_object = None res_obj = None if len(m["Nodes"]) > 0: mesh = importToolsFem.make_femmesh(m) result_mesh_object = ObjectsFem.makeMeshResult(doc, "ResultMesh") result_mesh_object.FemMesh = mesh res_mesh_is_compacted = False nodenumbers_for_compacted_mesh = [] number_of_increments = len(m["Results"]) 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(doc, results_name) res_obj.Mesh = result_mesh_object res_obj = importToolsFem.fill_femresult_mechanical( res_obj, result_set) if analysis: analysis.addObject(res_obj) # complementary result object calculations import femresult.resulttools as restools import femtools.femutils as femutils if not res_obj.MassFlowRate: # information 1: # only compact result if not Flow 1D results # compact result object, workaround for bug 2873 # https://www.freecadweb.org/tracker/view.php?id=2873 # information 2: # if the result data has multiple result sets there will be multiple result objs # they all will use one mesh obj # on the first res obj fill the mesh obj will be compacted, thus # it does not need to be compacted on further result sets # but NodeNumbers need to be compacted for every result set (res object fill) # example frd file: https://forum.freecadweb.org/viewtopic.php?t=32649#p274291 if res_mesh_is_compacted is False: # first result set, compact FemMesh and NodeNumbers res_obj = restools.compact_result(res_obj) res_mesh_is_compacted = True nodenumbers_for_compacted_mesh = res_obj.NodeNumbers else: # all other result sets, do not compact FemMesh, only set NodeNumbers res_obj.NodeNumbers = nodenumbers_for_compacted_mesh # fill DisplacementLengths res_obj = restools.add_disp_apps(res_obj) # fill vonMises res_obj = restools.add_von_mises(res_obj) if res_obj.getParentGroup(): has_reinforced_mat = False for obj in res_obj.getParentGroup().Group: if obj.isDerivedFrom("App::MaterialObjectPython") \ and femutils.is_of_type(obj, "Fem::MaterialReinforced"): has_reinforced_mat = True restools.add_principal_stress_reinforced(res_obj) break if has_reinforced_mat is False: # fill PrincipalMax, PrincipalMed, PrincipalMin, MaxShear res_obj = restools.add_principal_stress_std(res_obj) else: # if a pure frd file was opened no analysis and thus no parent group # fill PrincipalMax, PrincipalMed, PrincipalMin, MaxShear res_obj = restools.add_principal_stress_std(res_obj) # fill Stats res_obj = restools.fill_femresult_stats(res_obj) else: error_message = ( "Nodes, but no results found in frd file. " "It means there only is a mesh but no results in frd file. " "Usually this happens for: \n" "- analysis type 'NOANALYSIS'\n" "- if CalculiX returned no results " "(happens on nonpositive jacobian determinant in at least one element)\n" "- just no frd results where requestet in input file " "(neither 'node file' nor 'el file' in output section')\n") Console.PrintMessage(error_message) # create a result obj, even if we have no results but a result mesh in frd file # see error message above for more information if not res_obj: if result_name_prefix: results_name = ("{}_Results".format(result_name_prefix)) else: results_name = ("Results".format(result_name_prefix)) res_obj = ObjectsFem.makeResultMechanical(doc, results_name) res_obj.Mesh = result_mesh_object # TODO, node numbers in result obj could be set if analysis: analysis.addObject(res_obj) if FreeCAD.GuiUp: if analysis: import FemGui FemGui.setActiveAnalysis(analysis) doc.recompute() else: Console.PrintError( "Problem on frd file import. No nodes found in frd file.\n") # None will be returned # or would it be better to raise an exception if there are not even nodes in frd file return res_obj
def import_z88_disp(filename, analysis=None, result_name_prefix=None): '''insert a FreeCAD FEM Result object in the ActiveDocument ''' 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] 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'] 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)) 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 / 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)