Skip to content

Commit

Permalink
[FEM] connect CCX solver to results pipeline
Browse files Browse the repository at this point in the history
- it was often criticized that our default solver CCX is not connected to the results pipeline system. One had to connect it manually, the create the different filter etc. but as soon as one changed a constraint and re-run the solver the whole work was gone and one had to recreate the pipeline.
This PR solves this by creating a pipeline and by reloading new results to it on a solver re-run.
The CCX results dialog feature is not touched, since the pipeline is hidden when the dialog is active.
  • Loading branch information
donovaly committed Feb 18, 2023
1 parent 124a03f commit de95a22
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/Mod/Fem/femtaskpanels/task_result_mechanical.py
Expand Up @@ -65,6 +65,11 @@ def __init__(self, obj):
# if Mesh and result are in active analysis
# activate the result mesh object
self.mesh_obj.ViewObject.show()
# hide pipeline if any
CCX_pipeline = FreeCADGui.ActiveDocument.getObject("SolverCCXResult")
if CCX_pipeline is not None:
self.pipeline_visibility = CCX_pipeline.Visibility
CCX_pipeline.hide()

ui_path = FreeCAD.getHomePath() + "Mod/Fem/Resources/ui/"
self.result_widget = FreeCADGui.PySideUic.loadUi(ui_path + "ResultShow.ui")
Expand Down Expand Up @@ -190,6 +195,12 @@ def __init__(self, obj):
self.result_widget.sb_displacement_factor_max.setValue(10. * scale_factor)
self.result_widget.sb_displacement_factor.setValue(scale_factor)

def __del__(self):
# restore visibility
CCX_pipeline = FreeCADGui.ActiveDocument.getObject("SolverCCXResult")
if self.pipeline_visibility and CCX_pipeline is not None:
CCX_pipeline.Visibility = self.pipeline_visibility

def restore_result_dialog(self):
try:
rt = FreeCAD.FEM_dialog["results_type"]
Expand Down
48 changes: 48 additions & 0 deletions src/Mod/Fem/femtaskpanels/task_solver_ccxtools.py
Expand Up @@ -74,6 +74,14 @@ def __init__(self, solver_object):

self.fem_console_message = ""

self.CCX_pipeline = None
self.CCX_mesh_visibility = False

# store visibility of possibly existing mesh object
CCX_mesh = self.fea.analysis.Document.getObject("ResultMesh")
if CCX_mesh is not None:
self.CCX_mesh_visibility = CCX_mesh.ViewObject.Visibility

# Connect Signals and Slots
QtCore.QObject.connect(
self.form.tb_choose_working_dir,
Expand Down Expand Up @@ -241,6 +249,8 @@ def calculixFinished(self, exitCode):
# print("calculixFinished(), exit code: {}".format(exitCode))
FreeCAD.Console.PrintLog("calculix state: {}\n".format(self.Calculix.state()))

had_errors = False

# Restore previous cwd
QtCore.QDir.setCurrent(self.cwd)

Expand All @@ -250,6 +260,7 @@ def calculixFinished(self, exitCode):
self.calculixNoError()
else:
self.calculixError()
had_errors = True

self.form.pb_run_ccx.setText("Re-run CalculiX")
self.femConsoleMessage("Loading result sets...")
Expand Down Expand Up @@ -279,10 +290,47 @@ def calculixFinished(self, exitCode):
self.fea.load_results()
except Exception:
FreeCAD.Console.PrintError("loading results failed\n")
had_errors = True

QApplication.restoreOverrideCursor()
self.form.l_time.setText("Time: {0:4.1f}: ".format(time.time() - self.Start))

# create a results pipeline from the just created results object
if not had_errors:
CCX_results = self.fea.analysis.Document.getObject("CCX_Results")
# safe guard
if CCX_results is None:
return
# check if there is already a pipeline
self.CCX_pipeline = self.fea.analysis.Document.getObject("SolverCCXResult")
if self.CCX_pipeline is None:
try:
self._createResults()
except Exception:
FreeCAD.Console.PrintError("Results pipeline could not be created\n")
had_errors = True
self.CCX_pipeline.load(CCX_results)
self.CCX_pipeline.recomputeChildren()
self.fea.analysis.Document.recompute()
# recompute() updated the result mesh data
# but not the shape and bar coloring
self.CCX_pipeline.ViewObject.updateColorBars()
# restore mesh object visibility
CCX_mesh = self.fea.analysis.Document.getObject("ResultMesh")
if CCX_mesh is not None:
CCX_mesh.ViewObject.Visibility = self.CCX_mesh_visibility
else:
FreeCAD.Console.PrintError("\nNo result pipeline was created.\n")

def _createResults(self):
self.CCX_pipeline = self.fea.analysis.Document.addObject(
"Fem::FemPostPipeline", "SolverCCXResult")
self.CCX_pipeline.Label = "SolverCCXResult"
self.CCX_pipeline.ViewObject.SelectionStyle = "BoundBox"
self.fea.analysis.addObject(self.CCX_pipeline)
# to assure the user sees something, set the default to Surface
self.CCX_pipeline.ViewObject.DisplayMode = "Surface"

def choose_working_dir(self):
wd = QtGui.QFileDialog.getExistingDirectory(None, "Choose CalculiX working directory",
self.fea.working_dir)
Expand Down

0 comments on commit de95a22

Please sign in to comment.