diff --git a/src/Mod/Fem/FemTools.py b/src/Mod/Fem/FemTools.py index 6c93cbf29..a178a0fd3 100644 --- a/src/Mod/Fem/FemTools.py +++ b/src/Mod/Fem/FemTools.py @@ -37,7 +37,7 @@ class FemTools(QtCore.QRunnable, QtCore.QObject): # "__init__" tries to use current active analysis in analysis is left empty. # Rises exception if analysis is not set and there is no active analysis # The constructur of FemTools is for use of analysis without solver object - def __init__(self, analysis=None): + def __init__(self, analysis=None, solver=None): if analysis: ## @var analysis @@ -47,6 +47,12 @@ class FemTools(QtCore.QRunnable, QtCore.QObject): 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 @@ -106,8 +112,9 @@ class FemTools(QtCore.QRunnable, QtCore.QObject): self.reset_mesh_color() return if self.result_object: - if self.result_object.Mesh.ViewObject.Visibility is False: - self.result_object.Mesh.ViewObject.Visibility = True + if FreeCAD.GuiUp: + if self.result_object.Mesh.ViewObject.Visibility is False: + self.result_object.Mesh.ViewObject.Visibility = True if result_type == "Sabs": values = self.result_object.StressValues elif result_type == "Uabs": @@ -147,9 +154,6 @@ class FemTools(QtCore.QRunnable, QtCore.QObject): # [{'Object':beam_sections, 'xxxxxxxx':value}, {}, ...] # [{'Object':shell_thicknesses, 'xxxxxxxx':value}, {}, ...] - ## @var solver - # solver of the analysis. Used to store solver and analysis parameters - self.solver = None ## @var mesh # mesh of the analysis. Used to generate .inp file and to show results self.mesh = None @@ -182,12 +186,22 @@ class FemTools(QtCore.QRunnable, QtCore.QObject): # Individual displacement_constraints are Proxy.Type "FemConstraintDisplacement" self.displacement_constraints = [] + found_solver_for_use = False for m in self.analysis.Member: if m.isDerivedFrom("Fem::FemSolverObjectPython"): - if not self.solver: + # for some methods no solver is needed (purge_results) --> solver could be none + # analysis has one solver and no solver was set --> use the one solver + # analysis has more than one solver and no solver was set --> use solver none + # analysis has no solver --> use solver none + if not found_solver_for_use and not self.solver: + # no solver was found before and no solver was set by constructor self.solver = m - else: - raise Exception('FEM: Multiple solver in analysis not yet supported!') + found_solver_for_use = True + elif found_solver_for_use: + self.solver = None + # another solver was found --> We have more than one solver + # we do not know which one to use, so we use none ! + # print('FEM: More than one solver in the analysis and no solver given to analys. No solver is set!') elif m.isDerivedFrom("Fem::FemMeshObject"): if not self.mesh: self.mesh = m diff --git a/src/Mod/Fem/FemToolsCcx.py b/src/Mod/Fem/FemToolsCcx.py index f2d7e4073..212b66c0d 100644 --- a/src/Mod/Fem/FemToolsCcx.py +++ b/src/Mod/Fem/FemToolsCcx.py @@ -42,7 +42,7 @@ class FemToolsCcx(FemTools.FemTools): # @param test_mode - True indicates that no real calculations will take place, so ccx bianry is not required. Used by test module. # "__init__" tries to use current active analysis in analysis is left empty. # Rises exception if analysis is not set and there is no active analysis - def __init__(self, analysis=None, test_mode=False): + def __init__(self, analysis=None, solver=None, test_mode=False): QtCore.QRunnable.__init__(self) QtCore.QObject.__init__(self) if analysis: @@ -53,6 +53,12 @@ class FemToolsCcx(FemTools.FemTools): 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 diff --git a/src/Mod/Fem/FemToolsZ88.py b/src/Mod/Fem/FemToolsZ88.py index 1225e6121..2e9dcdf47 100644 --- a/src/Mod/Fem/FemToolsZ88.py +++ b/src/Mod/Fem/FemToolsZ88.py @@ -40,7 +40,7 @@ class FemToolsZ88(FemTools.FemTools): # @param analysis - analysis object to be used as the core object. # "__init__" tries to use current active analysis in analysis is left empty. # Rises exception if analysis is not set and there is no active analysis - def __init__(self, analysis=None, test_mode=False): + def __init__(self, analysis=None, solver=None, test_mode=False): if analysis: ## @var analysis # FEM analysis - the core object. Has to be present. @@ -49,6 +49,12 @@ class FemToolsZ88(FemTools.FemTools): 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.base_name = "" diff --git a/src/Mod/Fem/TestFem.py b/src/Mod/Fem/TestFem.py index 103d34abd..a75a7e212 100644 --- a/src/Mod/Fem/TestFem.py +++ b/src/Mod/Fem/TestFem.py @@ -202,7 +202,7 @@ class FemTest(unittest.TestCase): self.assertTrue(self.pressure_constraint, "FemTest of new pressure constraint failed") self.analysis.Member = self.analysis.Member + [self.pressure_constraint] - fea = FemToolsCcx.FemToolsCcx(self.analysis, test_mode=True) + fea = FemToolsCcx.FemToolsCcx(self.analysis, self.solver_object, test_mode=True) fcc_print('Setting up working directory {}'.format(static_analysis_dir)) fea.setup_working_dir(static_analysis_dir) self.assertTrue(True if fea.working_dir == static_analysis_dir else False, diff --git a/src/Mod/Fem/_CommandRunSolver.py b/src/Mod/Fem/_CommandRunSolver.py index d9bcf4459..f98d45304 100644 --- a/src/Mod/Fem/_CommandRunSolver.py +++ b/src/Mod/Fem/_CommandRunSolver.py @@ -51,9 +51,12 @@ class _CommandRunSolver(FemCommands): else: print ("CalculiX failed ccx finished with error {}".format(ret_code)) - if FreeCADGui.Selection.getSelection()[0].SolverType == "FemSolverCalculix": + sel = FreeCADGui.Selection.getSelection() + if len(sel) == 1 and sel[0].isDerivedFrom("Fem::FemSolverObjectPython"): + self.solver = sel[0] + if self.solver.SolverType == "FemSolverCalculix": import FemToolsCcx - self.fea = FemToolsCcx.FemToolsCcx() + self.fea = FemToolsCcx.FemToolsCcx(None, self.solver) self.fea.reset_mesh_purge_results_checked() message = self.fea.check_prerequisites() if message: @@ -61,9 +64,9 @@ class _CommandRunSolver(FemCommands): return self.fea.finished.connect(load_results) QtCore.QThreadPool.globalInstance().start(self.fea) - elif FreeCADGui.Selection.getSelection()[0].SolverType == "FemSolverZ88": + elif self.solver.SolverType == "FemSolverZ88": import FemToolsZ88 - self.fea = FemToolsZ88.FemToolsZ88() + self.fea = FemToolsZ88.FemToolsZ88(None, self.solver) self.fea.reset_mesh_purge_results_checked() message = self.fea.check_prerequisites() if message: diff --git a/src/Mod/Fem/_CommandSolverCalculix.py b/src/Mod/Fem/_CommandSolverCalculix.py index df54b48f9..482bb6c80 100644 --- a/src/Mod/Fem/_CommandSolverCalculix.py +++ b/src/Mod/Fem/_CommandSolverCalculix.py @@ -41,7 +41,7 @@ class _CommandSolverCalculix(FemCommands): 'MenuText': QtCore.QT_TRANSLATE_NOOP("Fem_SolverCalculix", "Solver CalculiX"), 'Accel': "S, C", 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Fem_SolverCalculix", "Creates a FEM solver CalculiX")} - self.is_active = 'with_analysis_without_solver' + self.is_active = 'with_analysis' def Activated(self): FreeCAD.ActiveDocument.openTransaction("Create SolverCalculix") diff --git a/src/Mod/Fem/_CommandSolverZ88.py b/src/Mod/Fem/_CommandSolverZ88.py index 5755e32bb..545a2ef23 100644 --- a/src/Mod/Fem/_CommandSolverZ88.py +++ b/src/Mod/Fem/_CommandSolverZ88.py @@ -41,7 +41,7 @@ class _CommandSolverZ88(FemCommands): 'MenuText': QtCore.QT_TRANSLATE_NOOP("Fem_SolverZ88", "Solver Z88"), 'Accel': "S, Z", 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Fem_SolverZ88", "Creates a FEM solver Z88")} - self.is_active = 'with_analysis_without_solver' + self.is_active = 'with_analysis' def Activated(self): FreeCAD.ActiveDocument.openTransaction("Create SolverZ88") diff --git a/src/Mod/Fem/_TaskPanelFemSolverCalculix.py b/src/Mod/Fem/_TaskPanelFemSolverCalculix.py index 67a6c9a86..6d4c0b22c 100644 --- a/src/Mod/Fem/_TaskPanelFemSolverCalculix.py +++ b/src/Mod/Fem/_TaskPanelFemSolverCalculix.py @@ -141,7 +141,7 @@ class _TaskPanelFemSolverCalculix: self.form.pb_run_ccx.setText("Re-run CalculiX") self.femConsoleMessage("Loading result sets...") self.form.l_time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start)) - fea = FemToolsCcx.FemToolsCcx() + fea = FemToolsCcx.FemToolsCcx(None, self.solver_object) fea.reset_mesh_purge_results_checked() fea.inp_file_name = self.inp_file_name QApplication.setOverrideCursor(Qt.WaitCursor) @@ -182,7 +182,7 @@ class _TaskPanelFemSolverCalculix: if self.check_prerequisites_helper(): QApplication.setOverrideCursor(Qt.WaitCursor) self.inp_file_name = "" - fea = FemToolsCcx.FemToolsCcx() + fea = FemToolsCcx.FemToolsCcx(None, self.solver_object) fea.set_analysis_type(self.solver_object.AnalysisType) fea.update_objects() fea.write_inp_file() @@ -200,7 +200,7 @@ class _TaskPanelFemSolverCalculix: self.femConsoleMessage("Check dependencies...") self.form.l_time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start)) - fea = FemToolsCcx.FemToolsCcx() + fea = FemToolsCcx.FemToolsCcx(None, self.solver_object) fea.update_objects() message = fea.check_prerequisites() if message != "":