FEM: multiple solver are possible in one analysis, use the selected for calculation run

This commit is contained in:
Bernd Hahnebach 2016-06-03 06:29:06 +01:00
parent 7287b479db
commit f1858cfdbf
8 changed files with 50 additions and 21 deletions

View File

@ -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,6 +112,7 @@ class FemTools(QtCore.QRunnable, QtCore.QObject):
self.reset_mesh_color()
return
if self.result_object:
if FreeCAD.GuiUp:
if self.result_object.Mesh.ViewObject.Visibility is False:
self.result_object.Mesh.ViewObject.Visibility = True
if result_type == "Sabs":
@ -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

View File

@ -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

View File

@ -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 = ""

View File

@ -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,

View File

@ -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:

View File

@ -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")

View File

@ -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")

View File

@ -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 != "":