def on_execute_gencase(self): """ Saves data into disk and uses GenCase to generate the case files.""" self.on_save_case() if not Case.the().executable_paths.gencase: warning_dialog(__("GenCase executable is not set.")) return gencase_full_path = path.abspath(Case.the().executable_paths.gencase) arguments = [ "{path}/{name}_Def".format(path=Case.the().path, name=Case.the().name), "{path}/{name}_out/{name}".format(path=Case.the().path, name=Case.the().name), "-save:+all" ] cmd_string = "{} {}".format(gencase_full_path, " ".join(arguments)) refocus_cwd() process = QtCore.QProcess(get_fc_main_window()) process.setWorkingDirectory(Case.the().path) ensure_process_is_executable_or_fail(gencase_full_path) process.start(gencase_full_path, arguments) debug("Executing -> {}".format(cmd_string)) process.waitForFinished() try: output = str(process.readAllStandardOutput().data(), encoding='utf-8') except UnicodeDecodeError: output = str(process.readAllStandardOutput().data(), encoding='latin1') if process.exitCode(): Case.the().info.is_gencase_done = False error_dialog( __("Error executing GenCase. Did you add objects to the case?. Another reason could be memory issues. View details for more info." ), output) else: try: total_particles_text = output[ output.index("Total particles: "):output.index(" (bound=")] total_particles = int( total_particles_text[total_particles_text.index(": ") + 2:]) Case.the().info.particle_number = total_particles GencaseCompletedDialog(particle_count=total_particles, detail_text=output, cmd_string=cmd_string, parent=get_fc_main_window()).show() Case.the().info.is_gencase_done = True self.on_save_case() Case.the().info.needs_to_run_gencase = False except ValueError: print_exc() Case.the().info.is_gencase_done = False Case.the().info.needs_to_run_gencase = True # Refresh widget enable/disable status as GenCase finishes self.gencase_completed.emit(Case.the().info.is_gencase_done)
def on_ex_simulate(self): """ Defines what happens on simulation button press. It shows the run window and starts a background process with dualsphysics running. Updates the window with useful info.""" refocus_cwd() if Case.the().info.needs_to_run_gencase: # Warning window about save_case warning_dialog( "You should run GenCase again. Otherwise, the obtained results may not be as expected" ) static_params_exe = [ Case.the().get_out_xml_file_path(), Case.the().get_out_folder_path(), "-{device}".format( device=self.device_selector.currentText().lower()), "-svres" ] additional_parameters = list() if Case.the().info.run_additional_parameters: additional_parameters = Case.the( ).info.run_additional_parameters.split(" ") final_params_ex = static_params_exe + additional_parameters cmd_string = "{} {}".format(Case.the().executable_paths.dsphysics, " ".join(final_params_ex)) run_dialog = RunDialog( case_name=Case.the().name, processor=self.device_selector.currentText(), number_of_particles=Case.the().info.particle_number, cmd_string=cmd_string, parent=get_fc_main_window()) run_dialog.set_value(0) run_dialog.run_update(0, 0, None) Case.the().info.is_simulation_done = False run_fs_watcher = QtCore.QFileSystemWatcher() self.simulation_started.emit() # Cancel button handler def on_cancel(): log(__("Stopping simulation")) if process: process.kill() run_dialog.hide_all() Case.the().info.is_simulation_done = True self.simulation_cancelled.emit() run_dialog.cancelled.connect(on_cancel) # Launch simulation and watch filesystem to monitor simulation filelist = [ f for f in os.listdir(Case.the().path + "/" + Case.the().name + "_out/") if f.startswith("Part") ] for f in filelist: os.remove(Case.the().path + "/" + Case.the().name + "_out/" + f) def on_dsph_sim_finished(exit_code): """ Simulation finish handler. Defines what happens when the process finishes.""" # Reads output and completes the progress bar try: output = str(process.readAllStandardOutput().data(), encoding='utf-8') except UnicodeDecodeError: output = str(process.readAllStandardOutput().data(), encoding='latin1') run_dialog.set_detail_text(str(output)) run_dialog.run_complete() run_fs_watcher.removePath(Case.the().path + "/" + Case.the().name + "_out/") if exit_code == 0: # Simulation went correctly Case.the().info.is_simulation_done = True Case.the().info.needs_to_run_gencase = False self.simulation_complete.emit(True) else: # In case of an error Case.the().info.needs_to_run_gencase = True if "exception" in str(output).lower(): log("There was an error on the execution. Opening an error dialog for that." ) run_dialog.hide() self.simulation_complete.emit(False) error_dialog( __("An error occurred during execution. Make sure that parameters exist and are properly defined. " "You can also check your execution device (update the driver of your GPU). Read the details for more information." ), str(output)) save_case(Case.the().path, Case.the()) # Launches a QProcess in background process = QtCore.QProcess(get_fc_main_window()) process.finished.connect(on_dsph_sim_finished) ensure_process_is_executable_or_fail( Case.the().executable_paths.dsphysics) if platform in ("linux", "linux2"): os.environ["LD_LIBRARY_PATH"] = os.path.dirname( Case.the().executable_paths.dsphysics) process.start(Case.the().executable_paths.dsphysics, final_params_ex) def on_fs_change(): """ Executed each time the filesystem changes. This updates the percentage of the simulation and its details.""" run_file_data = "" with open(Case.the().path + "/" + Case.the().name + "_out/Run.out", "r", encoding="utf-8") as run_file: run_file_data = run_file.readlines() # Fill details window run_dialog.set_detail_text("".join(run_file_data)) # Set percentage scale based on timemax for l in run_file_data: if Case.the().execution_parameters.timemax == -1: if "TimeMax=" in l: Case.the().execution_parameters.timemax = float( l.split("=")[1]) current_value: float = 0.0 totalpartsout: int = 0 last_estimated_time = None # Update execution metrics last_part_lines = list( filter( lambda x: "Part_" in x and "stored" not in x and " " in x, run_file_data)) if last_part_lines: current_value = (float(last_part_lines[-1].split(None)[1]) * float(100)) / float( Case.the().execution_parameters.timemax) else: current_value = None # Update particles out last_particles_out_lines = list( filter(lambda x: "(total: " in x and "Particles out:" in x, run_file_data)) if last_particles_out_lines: totalpartsout = int(last_particles_out_lines[-1].split( "(total: ")[1].split(")")[0]) try: last_estimated_time = str(" ".join( last_part_lines[-1].split(None)[-2:])) except IndexError: last_estimated_time = None # Update run dialog run_dialog.run_update(current_value, totalpartsout, last_estimated_time) # Set filesystem watcher to the out directory. run_fs_watcher.addPath(Case.the().path + "/" + Case.the().name + "_out/") run_fs_watcher.directoryChanged.connect(on_fs_change) # Handle error on simulation start if process.state() == QtCore.QProcess.NotRunning: # Probably error happened. run_fs_watcher.removePath(Case.the().path + "/" + Case.the().name + "_out/") process = None error_dialog( "Error on simulation start. Check that the DualSPHysics executable is correctly set." ) else: run_dialog.show()
def execute_bathymetry_tool(self): """ Executes bathymetry tool and returns the output path of the generated file. """ export_process = QtCore.QProcess(get_fc_main_window()) temp_dir = gettempdir() working_dialog = WorkingDialog(self) def on_export_finished(): temp_bathymetry_file_path = "{}/output.stl".format(temp_dir) import_geo(filename=str(temp_bathymetry_file_path), scale_x=1.0, scale_y=1.0, scale_z=1.0, name=str(self.geo_objname_text.text()), autofill=self.geo_autofill_chck.isChecked(), case=Case.the()) working_dialog.accept() executable_parameters = [ "-loadpos", str(self.geo_file_path.text()), "-move:{}:{}:{}".format(self.bath_move_x_e.text(), self.bath_move_y_e.text(), self.bath_move_z_e.text()), "-rotate:{}:{}:{}".format(self.bath_rotate_x_e.text(), self.bath_rotate_y_e.text(), self.bath_rotate_z_e.text()), "-scale:{}:{}:{}".format(self.bath_scale_x_e.text(), self.bath_scale_y_e.text(), self.bath_scale_z_e.text()) ] if self.bath_selection_enabled_chk.isChecked(): executable_parameters.append("-selposmin:{}:{}".format( self.bath_selection_point_x_e.text(), self.bath_selection_point_y_e.text())) executable_parameters.append("-selsize:{}:{}".format( self.bath_selection_size_x_e.text(), self.bath_selection_size_y_e.text())) executable_parameters.append("-gdp:{}".format( self.bath_grid_dp_x_e.text())) if self.bath_initdomain_enabled_chk.isChecked(): executable_parameters.append("-gposmin:{}:{}".format( self.bath_initdomain_point_x_e.text(), self.bath_initdomain_point_y_e.text())) executable_parameters.append("-gsize:{}:{}".format( self.bath_initdomain_size_x_e.text(), self.bath_initdomain_size_y_e.text())) if self.bath_xmin_check.isChecked(): executable_parameters.append("-gexpandxmin:{}:{}:{}:{}".format( self.bath_xmin_size_e.text(), self.bath_xmin_z_e.text(), self.bath_xmin_size2_e.text(), self.bath_xmin_z2_e.text())) if self.bath_xmax_check.isChecked(): executable_parameters.append("-gexpandxmax:{}:{}:{}:{}".format( self.bath_xmax_size_e.text(), self.bath_xmax_z_e.text(), self.bath_xmax_size2_e.text(), self.bath_xmax_z2_e.text())) if self.bath_ymin_check.isChecked(): executable_parameters.append("-gexpandymin:{}:{}:{}:{}".format( self.bath_ymin_size_e.text(), self.bath_ymin_z_e.text(), self.bath_ymin_size2_e.text(), self.bath_ymin_z2_e.text())) if self.bath_ymax_check.isChecked(): executable_parameters.append("-gexpandymax:{}:{}:{}:{}".format( self.bath_ymax_size_e.text(), self.bath_ymax_z_e.text(), self.bath_ymax_size2_e.text(), self.bath_ymax_z2_e.text())) if self.bath_periodicx_enabled_chk.isChecked(): executable_parameters.append("-gperix:{}:{}".format( self.bath_periodicx_rampwidth_x_e.text(), self.bath_periodicx_flatwidth_x_e.text())) if self.bath_periodicy_enabled_chk.isChecked(): executable_parameters.append("-gperiy:{}:{}".format( self.bath_periodicy_rampwidth_x_e.text(), self.bath_periodicy_flatwidth_x_e.text())) if self.bath_finalmove_enabled_chk.isChecked(): executable_parameters.append("-gmove:{}:{}:{}".format( self.bath_finalmove_x_e.text(), self.bath_finalmove_y_e.text(), self.bath_finalmove_z_e.text())) executable_parameters.append("-savegrid:stl:mm") executable_parameters.append("{}/output.stl".format(temp_dir)) self.save_default_data() export_process.finished.connect(on_export_finished) ensure_process_is_executable_or_fail( Case.the().executable_paths.bathymetrytool) debug("Executing: {} {}".format( Case.the().executable_paths.bathymetrytool, " ".join(executable_parameters))) export_process.start(Case.the().executable_paths.bathymetrytool, executable_parameters) working_dialog.exec()