def __init__(self, solver_object): self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Fem/Resources/ui/SolverCalculix.ui") from femtools.ccxtools import CcxTools as ccx # we do not need to pass the analysis, it will be found on fea init self.fea = ccx(solver_object) self.fea.setup_working_dir() self.fea.setup_ccx() self.Calculix = QtCore.QProcess() self.Timer = QtCore.QTimer() self.Timer.start(300) self.fem_console_message = '' # Connect Signals and Slots QtCore.QObject.connect(self.form.tb_choose_working_dir, QtCore.SIGNAL("clicked()"), self.choose_working_dir) 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.editCalculixInputFile) QtCore.QObject.connect(self.form.pb_run_ccx, QtCore.SIGNAL("clicked()"), self.runCalculix) QtCore.QObject.connect(self.form.rb_static_analysis, QtCore.SIGNAL("clicked()"), self.select_static_analysis) QtCore.QObject.connect(self.form.rb_frequency_analysis, QtCore.SIGNAL("clicked()"), self.select_frequency_analysis) QtCore.QObject.connect(self.form.rb_thermomech_analysis, QtCore.SIGNAL("clicked()"), self.select_thermomech_analysis) QtCore.QObject.connect(self.form.rb_check_mesh, QtCore.SIGNAL("clicked()"), self.select_check_mesh) QtCore.QObject.connect(self.Calculix, QtCore.SIGNAL("started()"), self.calculixStarted) QtCore.QObject.connect(self.Calculix, QtCore.SIGNAL("stateChanged(QProcess::ProcessState)"), self.calculixStateChanged) QtCore.QObject.connect(self.Calculix, QtCore.SIGNAL("error(QProcess::ProcessError)"), self.calculixError) QtCore.QObject.connect(self.Calculix, QtCore.SIGNAL("finished(int)"), self.calculixFinished) QtCore.QObject.connect(self.Timer, QtCore.SIGNAL("timeout()"), self.UpdateText) self.update()
def __init__(self, solver_object): self.form = FreeCADGui.PySideUic.loadUi( FreeCAD.getHomePath() + "Mod/Fem/Resources/ui/SolverCalculix.ui") from femtools.ccxtools import CcxTools as ccx # we do not need to pass the analysis, it will be found on fea init # TODO: if there is not analysis object in document init of fea # will fail with an exception and task panel will not open # handle more smart by a pop up error message and still open # task panel, may be deactivate write and run button. self.fea = ccx(solver_object) self.fea.setup_working_dir() self.fea.setup_ccx() self.Calculix = QtCore.QProcess() self.Timer = QtCore.QTimer() self.Timer.start(300) self.fem_console_message = "" # Connect Signals and Slots QtCore.QObject.connect(self.form.tb_choose_working_dir, QtCore.SIGNAL("clicked()"), self.choose_working_dir) 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.editCalculixInputFile) QtCore.QObject.connect(self.form.pb_run_ccx, QtCore.SIGNAL("clicked()"), self.runCalculix) QtCore.QObject.connect(self.form.rb_static_analysis, QtCore.SIGNAL("clicked()"), self.select_static_analysis) QtCore.QObject.connect(self.form.rb_frequency_analysis, QtCore.SIGNAL("clicked()"), self.select_frequency_analysis) QtCore.QObject.connect(self.form.rb_thermomech_analysis, QtCore.SIGNAL("clicked()"), self.select_thermomech_analysis) QtCore.QObject.connect(self.form.rb_check_mesh, QtCore.SIGNAL("clicked()"), self.select_check_mesh) QtCore.QObject.connect(self.Calculix, QtCore.SIGNAL("started()"), self.calculixStarted) QtCore.QObject.connect( self.Calculix, QtCore.SIGNAL("stateChanged(QProcess::ProcessState)"), self.calculixStateChanged) QtCore.QObject.connect(self.Calculix, QtCore.SIGNAL("error(QProcess::ProcessError)"), self.calculixError) QtCore.QObject.connect(self.Calculix, QtCore.SIGNAL("finished(int)"), self.calculixFinished) QtCore.QObject.connect(self.Timer, QtCore.SIGNAL("timeout()"), self.UpdateText) self.update()
def run_fem_solver(solver, working_dir=None): if solver.Proxy.Type == "Fem::FemSolverCalculixCcxTools": App.Console.PrintMessage("CalxuliX ccx tools solver!\n") from femtools.ccxtools import CcxTools as ccx fea = ccx(solver) fea.reset_mesh_purge_results_checked() if working_dir is None: fea.run() else: fea.update_objects() fea.setup_working_dir(working_dir) fea.setup_ccx() message = fea.check_prerequisites() if not message: fea.write_inp_file() fea.ccx_run() fea.load_results() else: App.Console.PrintError("Houston, we have a problem ...!\n{}\n".format(message)) else: # App.Console.PrintMessage("Frame work solver!\n") try: if working_dir is not None: machine = getMachine(solver, working_dir) else: machine = getMachine(solver) except MustSaveError: error_message = ( "Please save the file before executing the solver. " "This must be done because the location of the working " "directory is set to \"Beside *.FCStd File\"." ) App.Console.PrintError(error_message + "\n") if App.GuiUp: QtGui.QMessageBox.critical( FreeCADGui.getMainWindow(), "Can't start Solver", error_message ) return except DirectoryDoesNotExistError: error_message = "Selected working directory doesn't exist." App.Console.PrintError(error_message + "\n") if App.GuiUp: QtGui.QMessageBox.critical( FreeCADGui.getMainWindow(), "Can't start Solver", error_message ) return if not machine.running: machine.reset() machine.target = RESULTS machine.start() machine.join() # wait for the machine to finish.
def run_fem_solver(solver, working_dir=None): """ Execute *solver* of the solver framework. Uses :meth:`getMachine <femsolver.solverbase.Proxy.getMachine>` to obtain a :class:`Machine` instance of the solver. It than executes the Machine with using the ``RESULTS`` target (see :class:`Machine` for infos about different targets). This method is blocking, it waits for the solver to finished before returning. Be aware of :class:`Machine` caching when using the function. :param solver: A document object which must be a framework compliant solver. This means that it should be derived from the document object provided by :mod:`femsolver.solverbase` and implement all required methods correctly. Of particular importance is :meth:`getMachine <femsolver.solverbase.Proxy.getMachine>` as it is used by this method the get the :class:`Machine` used to execute the solver. :param working_dir: If specified it overwrites the automatic and user configurable working directory management of the Solver framework. Should always be a absolute path because the location of the binary is not consistent among platforms. If ``None`` the automatic working directory management is used. :note: There is some legacy code to execute the old Calculix solver (pre-framework) which behaives differently because it doesn't use a :class:`Machine`. """ if solver.Proxy.Type == "Fem::FemSolverCalculixCcxTools": App.Console.PrintMessage("CalxuliX ccx tools solver!\n") from femtools.ccxtools import CcxTools as ccx fea = ccx(solver) fea.reset_mesh_purge_results_checked() if working_dir is None: fea.run() else: fea.update_objects() fea.setup_working_dir(working_dir) fea.setup_ccx() message = fea.check_prerequisites() if not message: fea.write_inp_file() fea.ccx_run() fea.load_results() else: App.Console.PrintError( "Houston, we have a problem ...!\n{}\n".format(message)) else: # App.Console.PrintMessage("Frame work solver!\n") try: if working_dir is not None: machine = getMachine(solver, working_dir) else: machine = getMachine(solver) except femutils.MustSaveError: error_message = ( "Please save the file before executing the solver. " "This must be done because the location of the working " "directory is set to \"Beside *.FCStd File\".") App.Console.PrintError(error_message + "\n") if App.GuiUp: QtGui.QMessageBox.critical(FreeCADGui.getMainWindow(), "Can't start Solver", error_message) return except femutils.DirectoryDoesNotExistError: error_message = "Selected working directory doesn't exist." App.Console.PrintError(error_message + "\n") if App.GuiUp: QtGui.QMessageBox.critical(FreeCADGui.getMainWindow(), "Can't start Solver", error_message) return if not machine.running: machine.reset() machine.target = RESULTS machine.start() machine.join() # wait for the machine to finish.