def load_table(self, lineEdit, direct_load=False): title = "Error reached while loading 'specific impedance' table" try: if direct_load: self.path_imported_table = lineEdit.text() else: window_label = 'Choose a table to import the specific impedance' self.path_imported_table, _ = QFileDialog.getOpenFileName(None, window_label, self.userPath, 'Files (*.csv; *.dat; *.txt)') if self.path_imported_table == "": return None, None imported_filename = os.path.basename(self.path_imported_table) lineEdit.setText(self.path_imported_table) imported_file = np.loadtxt(self.path_imported_table, delimiter=",") if imported_file.shape[1]<2: message = "The imported table has insufficient number of columns. The spectrum" message += " data must have only two columns to the frequencies and values." PrintMessageInput([title, message, window_title_1]) return None, None imported_values = imported_file[:,1] if imported_file.shape[1]>=2: self.frequencies = imported_file[:,0] self.f_min = self.frequencies[0] self.f_max = self.frequencies[-1] self.f_step = self.frequencies[1] - self.frequencies[0] if self.project.change_project_frequency_setup(imported_filename, list(self.frequencies)): self.lineEdit_reset(self.lineEdit_load_table_path) return None, None else: self.project.set_frequencies(self.frequencies, self.f_min, self.f_max, self.f_step) return imported_values, imported_filename except Exception as log_error: message = str(log_error) PrintMessageInput([title, message, window_title_1]) lineEdit.setFocus() return None, None
def set_flange_cross_section_to_list_elements(self, list_elements): section_parameters = {} for element_id in list_elements: element = self.structural_elements[element_id] if self.flag_checkBox: cross_section = element.cross_section if cross_section is None: section_parameters = {} return True else: outer_diameter = self.outer_diameter inner_diameter = cross_section.inner_diameter thickness = (self.outer_diameter - inner_diameter) / 2 offset_y = cross_section.offset_y offset_z = cross_section.offset_z insulation_thickness = cross_section.insulation_thickness insulation_density = cross_section.insulation_density else: outer_diameter = self.outer_diameter inner_diameter = self.inner_diameter thickness = (outer_diameter - inner_diameter) / 2 offset_y = self.offset_y offset_z = self.offset_z insulation_thickness = self.insulation_thickness insulation_density = self.insulation_density if outer_diameter <= inner_diameter: section_parameters = {} title = "Invalid input to the outer/inner diameters" message = "The outer diameter input should be greater than the inner diameter. \n" message += "This condition must be satified to proceed." PrintMessageInput([title, message, window_title_1]) return True section_parameters[element_id] = { "outer_diameter": outer_diameter, "thickness": thickness, "offset_y": offset_y, "offset_z": offset_z, "insulation_thickness": insulation_thickness, "insulation_density": insulation_density } for element_id in list_elements: pipe_section_info = { "section_type_label": "Pipe section", "section_parameters": section_parameters[element_id] } self.cross_section = CrossSection( pipe_section_info=pipe_section_info) self.project.set_cross_section_by_elements([element_id], self.cross_section) return False
def ImportResults(self): try: skiprows = int(self.lineEdit_skiprows.text()) self.imported_data = np.loadtxt(self.import_path, delimiter=",", skiprows=skiprows) self.legend_imported = "imported data: " + basename( self.import_path).split(".")[0] self.tabWidget_plot_results.setCurrentWidget(self.tab_plot) title = "Information" message = "The results has been imported." PrintMessageInput([title, message, window_title_2]) except Exception as log_error: title = "Error while loading table" message = str( log_error) + " It is recommended to skip the header rows." PrintMessageInput([title, message, window_title_1]) return
def ImportResults(self): try: skiprows = int(self.lineEdit_skiprows.text()) self.imported_data = np.loadtxt(self.import_path, delimiter=",", skiprows=skiprows) self.legend_imported = "imported data: " + basename( self.import_path).split(".")[0] self.tabWidget_plot_results.setCurrentWidget(self.tab_plot) title = "Loading table" message = "The reactions data have been imported." PrintMessageInput([title, message, window_title_3]) except Exception as _error: title = "Error reached while loading table" message = f"{str(_error)}\n It is recommended to skip the header rows." PrintMessageInput([title, message, window_title_1])
def process_errors(self): if len(self.errors) != 0: title = "REFPROP: Error while processing fluid properties" message = "The following errors were found while processing the fluid properties.\n\n" for key, _error in self.errors.items(): message += f"{str(key)}: {str(_error)}\n\n" message += "It is recommended to check the fluid composition and state properties to proceed." PrintMessageInput([title, message, "ERROR"], fontsizes=[13, 12]) return True
def get_information(self): try: if self.lineEdit_decoupled_DOFs.text() != "": decoupled_DOFs_bool = self.dict_decoupled_DOFs_label_to_bool[self.lineEdit_decoupled_DOFs.text()] decoupled_DOFs_labels = self.dict_decoupled_DOFs_bool_to_label[decoupled_DOFs_bool] read = GetInformationOfGroup(self.project, decoupled_DOFs_bool, decoupled_DOFs_labels) if read.lines_removed: self.load_decoupling_info() self.clear_texts() else: title = "UNSELECTED GROUP" message = "Please, select a group in the list to get the information." PrintMessageInput([title, message, window_title2]) except Exception as e: title = "ERROR WHILE GETTING INFORMATION OF SELECTED GROUP" message = str(e) PrintMessageInput([title, message, window_title1])
def pick_color_edit(self): read = PickColorInput() self.adding = False self.editing = True if read.complete: str_color = str(read.color).replace(" ", "") #[1:-1] self.lineEdit_color_edit.setText(str_color) if self.check_color_input(self.lineEdit_color_edit): self.lineEdit_color_edit.setText("") PrintMessageInput([self.title, self.message, window_title])
def checkBoxEvent(self): self.flag_rotation_x = self.checkBox_rotation_x.isChecked() self.flag_rotation_y = self.checkBox_rotation_y.isChecked() self.flag_rotation_z = self.checkBox_rotation_z.isChecked() self.rotations_mask = [self.flag_rotation_x, self.flag_rotation_y, self.flag_rotation_z] if self.rotations_mask.count(False) == 3: title = "INVALID DECOUPLING SETUP" message = "There are no rotation DOFs decoupling in the current setup. \nYou should tick at least one rotation DOF before continue." PrintMessageInput([title, message, window_title1]) return
def createProjectFolder(self): if self.lineEdit_project_name.text() == "": title = 'Empty project name' message = "Please, inform a valid project name to continue." PrintMessageInput([title, message, window_title1]) self.stop = True return if self.lineEdit_project_folder.text() == "": title = 'None project folder selected' message = "Please, select a folder where the project data are going to be stored." PrintMessageInput([title, message, window_title1]) self.stop = True return if not os.path.exists(self.project_directory): os.mkdir(self.project_directory) self.stop = False
def add_selected_gas(self): if self.label_selected_fluid.text() != "": if self.check_composition_input(): return self.load_new_gas_composition_info() self.update_remainig_composition() else: title = "None 'Fluid' selected" message = "Dear user, it is necessary to select a fluid in the list to proceed" PrintMessageInput([title, message, window_title_1])
def processInput(self, workingClass, *args, **kwargs): try: self.beforeInput() read = workingClass(*args, **kwargs) self.opv.setInputObject(None) return read except Exception as log_error: title = "Error detected in processInput method" message = str(log_error) PrintMessageInput([title, message, window_title_1])
def remove_all_element_length_correction(self): temp_dict_groups = self.dict_group_elements.copy() keys = temp_dict_groups.keys() for key in keys: self.log_removal = False self.remove_function(key) window_title = "WARNING" title = "INFO MESSAGE" message = "The element length correction has been \nremoved from all elements." PrintMessageInput([title, message, window_title])
def check_pressure_value(self, lineEdit_pressure): pressure = None str_value = lineEdit_pressure.text() if str_value != "": try: pressure = float(str_value) except Exception as log_error: title = "Invalid entry to the pressure" message = "Dear user, you have typed an invalid value at the pressure input field." message += "You should to inform a valid float number to proceed." window_title = "ERROR" PrintMessageInput([title, message, window_title]) else: title = "Empty pressure input field" message = "Dear user, the pressure input field is empty. Please, inform a valid float number to proceed." window_title = "ERROR" PrintMessageInput([title, message, window_title]) lineEdit_pressure.setFocus() return pressure
def remove_bc_from_file(typed_values, path, keys_to_remove, message, equals_keys=False): try: if isinstance(typed_values, int): typed_values = [typed_values] bc_removed = False config = configparser.ConfigParser() config.read(path) sections = config.sections() for typed_value in typed_values: _typed_value = str(typed_value) if _typed_value in sections: keys = config[_typed_value].keys() for key_to_remove in keys_to_remove: for key in keys: if key_to_remove in key: if equals_keys: if key_to_remove != key: continue bc_removed = True config.remove_option(section=_typed_value, option=key) if list(config[_typed_value].keys()) == []: config.remove_section(section=_typed_value) if bc_removed: with open(path, 'w') as config_file: config.write(config_file) if message is not None and bc_removed: PrintMessageInput( ["Removal of selected boundary condition", message, "WARNING"]) except Exception as log_error: PrintMessageInput( ["Error while removing BC from file", str(log_error), "ERROR"])
def run(self): if self.target is not None: try: self.target() except Exception as log_error: print(log_error) title = "An error has been reached in LoadingScreen" PrintMessageInput([title, str(log_error), "ERROR"]) self.finished.emit() self.thread().quit()
def export_animation_to_file(self): if self.lineEdit_FileName.text() != "": file_format = self.get_file_format() filename = self.lineEdit_FileName.text() + file_format if os.path.exists(self.save_path): self.export_file_path = get_new_path(self.save_path, filename) self.opv.opvAnalysisRenderer.start_export_animation_to_file( self.export_file_path, self.frames) self.process_animation() else: title = "Invalid folder path" message = "Inform a valid folder path before trying export the animation.\n\n" message += f"{self.label_export_path.text()}" PrintMessageInput([title, message, "ERROR"]) self.label_export_path.setText("<Folder path>") else: title = "Empty file name" message = "Inform a file name before trying export the animation." PrintMessageInput([title, message, "ERROR"]) self.lineEdit_FileName.setFocus()
def check_reset_all(self): temp_dict_group_elements = self.dict_group_elements.copy() for key, elements in temp_dict_group_elements.items(): self.project.set_capped_end_by_elements(elements, False, key) lines = self.project.preprocessor.all_lines self.project.set_capped_end_by_lines(lines, False) self.load_elements_info() self.load_lines_info() self.lineEdit_selected_ID.setText("") title = "CAPPED END RESET" message = "The capped end effect has been removed \nfrom all elements of the structural model." PrintMessageInput([title, message, window_title2])
def check_input_values_with_units(self, lineEdit_temperature, lineEdit_pressure): _temperature_value = self.check_temperature_value(lineEdit_temperature) if _temperature_value is None: return None if self.unit_temperature == "°C": _temperature_value += 273.15 elif self.unit_temperature == "°F": _temperature_value = (_temperature_value - 32) * (5 / 9) + 273.15 if _temperature_value < 0: title = "Invalid entry to the temperature" message = "The typed value at temperature input field reaches a negative value in Kelvin scale." message += "It is necessary to enter a value that maintains the physicall coherence and consistence " message += "to proceed with the fluid setup." PrintMessageInput([title, message, window_title_1]) return None _pressure_value = self.check_pressure_value(lineEdit_pressure) if _pressure_value is None: return None if self.unit_pressure == "kPa": _pressure_value *= 1e3 elif self.unit_pressure == "bar": _pressure_value *= 101325 elif self.unit_pressure == "psi": _pressure_value *= 6894.75729 if _pressure_value < 0: title = "Invalid entry to the pressure" message = "The typed value at pressure input field reaches a negative value in Pascal scale." message += "It is necessary to enter a value that maintains the physicall coherence and consistence " message += "to proceed with the fluid setup." PrintMessageInput([title, message, window_title_1]) return None return [round(_temperature_value, 5), round(_pressure_value, 5)]
def actions_to_finalize(self): if self.compressor_info: if self.compressor_info["connection type"] == 1: title = "Fluid properties convergence" message = "The following fluid properties were obtained after completing the iterative updating process:" message += f"\n\nTemperature (discharge) = {round(self.fluid_properties['temperature'],4)} [K]" message += f"\nIsentropic exponent = {round(self.fluid_properties['isentropic exponent'],6)} [-]" message += "\n\nReference fluid properties:" message += f"\n\nTemperature (suction) = {self.compressor_info['temperature (suction)']} [K]" message += f"\nPressure (suction) = {self.compressor_info['pressure (suction)']} [Pa]" message += f"\nPressure (discharge) = {round(self.compressor_info['pressure (discharge)'],4)} [Pa]" message += f"\nMolar mass = {round(self.fluid_properties['molar mass'],6)} [kg/mol]" PrintMessageInput([title, message, "WARNING"])
def check(self): window_title = "WARNING" if self.lineEdit_selected_frequency.text() == "": title = "Aditional action required" message = "Select a frequency from the available list \n" message += "of frequencies to continue." PrintMessageInput([title, message, window_title]) return else: frequency_selected = float(self.lineEdit_selected_frequency.text()) if frequency_selected in self.frequencies: self.selected_index = self.dict_frequency_to_index[frequency_selected] self.get_stress_data()
def remove_selected_beam_xaxis_rotation(self): if self.selected_key == "": return lines = self.project.preprocessor.dict_beam_xaxis_rotating_angle_to_lines[self.selected_key] self.project.preprocessor.dict_beam_xaxis_rotating_angle_to_lines.pop(self.selected_key) for line in lines: delta_angle = - self.project.preprocessor.dict_lines_to_rotation_angles[line] self.project.set_beam_xaxis_rotation_by_line(line, delta_angle) self.update_plots() title = "X-axis rotation angle removal" message = f"The x-axis rotation angle attributed to the lines {lines} has been removed from the current model setup.\n\n\n " message += "Press Close button to continue." PrintMessageInput([title, message, window_title2])
def check_constant_values(self): lineEdit_nodeID = self.lineEdit_nodeID.text() self.stop, self.nodes_typed = self.before_run.check_input_NodeID( lineEdit_nodeID) if self.stop: self.lineEdit_nodeID.setFocus() return Fx = self.check_complex_entries(self.lineEdit_real_Fx, self.lineEdit_imag_Fx, "Fx") if self.stop: return Fy = self.check_complex_entries(self.lineEdit_real_Fy, self.lineEdit_imag_Fy, "Fy") if self.stop: return Fz = self.check_complex_entries(self.lineEdit_real_Fz, self.lineEdit_imag_Fz, "Fz") if self.stop: return Mx = self.check_complex_entries(self.lineEdit_real_Mx, self.lineEdit_imag_Mx, "Mx") if self.stop: return My = self.check_complex_entries(self.lineEdit_real_My, self.lineEdit_imag_My, "My") if self.stop: return Mz = self.check_complex_entries(self.lineEdit_real_Mz, self.lineEdit_imag_Mz, "Mz") if self.stop: return loads = [Fx, Fy, Fz, Mx, My, Mz] if loads.count(None) != 6: self.loads = loads table_names = self.list_Nones data = [self.loads, table_names] self.remove_all_table_files_from_nodes(self.nodes_typed) self.project.set_nodal_loads_by_node(self.nodes_typed, data, False) print(f"[Set Nodal loads] - defined at node(s) {self.nodes_typed}") self.opv.updateRendererMesh() self.close() else: window_title = "ERROR" title = "Additional inputs required" message = "You must to inform at least one nodal load\n" message += "before confirming the input!" PrintMessageInput([title, message, window_title])
def check_constant_values(self): lineEdit_nodeID = self.lineEdit_nodeID.text() self.stop, self.nodes_typed = self.before_run.check_input_NodeID(lineEdit_nodeID) if self.stop: self.lineEdit_nodeID.setFocus() return if self.lineEdit_real_alldofs.text() != "" or self.lineEdit_imag_alldofs.text() != "": prescribed_dofs = self.check_complex_entries(self.lineEdit_real_alldofs, self.lineEdit_imag_alldofs, "all dofs") if self.stop: return else: ux = self.check_complex_entries(self.lineEdit_real_ux, self.lineEdit_imag_ux, "ux") if self.stop: return uy = self.check_complex_entries(self.lineEdit_real_uy, self.lineEdit_imag_uy, "uy") if self.stop: return uz = self.check_complex_entries(self.lineEdit_real_uz, self.lineEdit_imag_uz, "uz") if self.stop: return rx = self.check_complex_entries(self.lineEdit_real_rx, self.lineEdit_imag_rx, "rx") if self.stop: return ry = self.check_complex_entries(self.lineEdit_real_ry, self.lineEdit_imag_ry, "ry") if self.stop: return rz = self.check_complex_entries(self.lineEdit_real_rz, self.lineEdit_imag_rz, "rz") if self.stop: return prescribed_dofs = [ux, uy, uz, rx, ry, rz] if prescribed_dofs != self.list_Nones: self.prescribed_dofs = prescribed_dofs table_names = self.list_Nones data = [self.prescribed_dofs, table_names] self.remove_all_table_files_from_nodes(self.nodes_typed) self.project.set_prescribed_dofs_bc_by_node(self.nodes_typed, data, False) print(f"[Set Prescribed DOF] - defined at node(s) {self.nodes_typed}") self.opv.updateRendererMesh() self.close() else: window_title ="ERROR" title = "Additional inputs required" message = "You must inform at least one prescribed dof\n" message += "before confirming the input!" PrintMessageInput([title, message, window_title])
def remove_table(self): self.dict_node_to_compressor_excitation = self.project.file.get_dict_of_compressor_excitation_from_file( ) self.selected_node = self.lineEdit_node_ID_info.text() self.selected_table = self.lineEdit_table_name_info.text() if self.selected_node == "": title = "EMPTY TABLE SELECTION" message = "You should to select a table from list before continue." PrintMessageInput([title, message, window_title_2]) return else: node_id = int(self.selected_node) node = self.preprocessor.nodes[node_id] prefix = self.selected_table.split("_node")[0] str_table_index = prefix.split("table")[1] table_index = int(str_table_index) if table_index in node.compressor_excitation_table_indexes: node.compressor_excitation_table_indexes.remove(table_index) if table_index in node.dict_index_to_compressor_connection_info.keys( ): node.dict_index_to_compressor_connection_info.pop(table_index) for list_data in self.dict_node_to_compressor_excitation[node_id]: [str_key, table_name_file] = list_data if self.selected_table in table_name_file: remove_bc_from_file([node_id], self.node_acoustic_path, [str_key], None) title = "Compressor excitation table removal finished" message = f"The following compressor excitation table attributed to \n" message += f"the {node_id} node has been removed from the model:\n\n" message += f"{self.selected_table}" PrintMessageInput([title, message, window_title_2]) self.load_compressor_excitation_tables_info() self.reset_node_and_reload(node_id)
def check_node(self, node_string): try: tokens = node_string.text().strip().split(',') try: tokens.remove('') except: pass node_typed = list(map(int, tokens)) except Exception: title = "INVALID NODE ID" message = "Wrong input for Node ID." PrintMessageInput([title, message, window_title1]) return None, False if len(node_typed) == 1: try: self.preprocessor.nodes[node_typed[0]].external_index except: title = "INVALID NODE ID" message = " The Node ID input values must be\n greater than 1 and less than {}.".format( len(self.nodes)) PrintMessageInput([title, message, window_title1]) return None, False elif len(node_typed) == 0: title = "INVALID NODE ID" message = "Please, enter a valid Node ID." PrintMessageInput([title, message, window_title1]) return None, False else: title = "MULTIPLE NODE IDs" message = "Please, type or select only one Node ID." PrintMessageInput([title, message, window_title1]) return None, False return node_typed[0], True
def check_warnings(self): # WARNINGS REACHED DURING SOLUTION title = self.analysis_type_label message = "" if self.analysis_type_label == "Harmonic Analysis - Structural": if self.solve.flag_ModeSup_prescribed_NonNull_DOFs: message = self.solve.warning_ModeSup_prescribedDOFs if self.solve.flag_Clump and self.analysis_ID==1: message = self.solve.warning_Clump[0] if self.analysis_type_label == "Modal Analysis - Structural": if self.solve.flag_Modal_prescribed_NonNull_DOFs: message = self.solve.warning_Modal_prescribedDOFs[0] if message != "": PrintMessageInput([title, message, window_title_2])
def check_selected_frequency(self): if self.lineEdit.text() == "": window_title = "WARNING" title = "Additional action required to plot the results" message = "You should select a frequency from the available list \n\n" message += "before trying to plot the displacement/rotation field." PrintMessageInput([title, message, window_title]) return else: frequency_selected = float(self.lineEdit.text()) if frequency_selected in self.frequencies: self.frequency = self.frequency_to_index[frequency_selected] self.close()
def check(self): if self.lineEdit.text() == "": window_title = "WARNING" title = "Additional action required to plot the results" message = "You should select a frequency from the available list \n\n" message += "before trying to plot the acoustic pressure field." PrintMessageInput([title, message, window_title]) return else: frequency_selected = float(self.lineEdit.text()) self.frequency = self.frequency_to_index[frequency_selected] self.opv.changeAndPlotAnalysis(self.frequency, pressure_field_plot=True) self.close()
def check_nodeID(self, lineEdit, export=False): lineEdit_nodeID = lineEdit.text() self.stop, self.node_ID = self.before_run.check_input_NodeID( lineEdit_nodeID, single_ID=True) if self.stop: return True if len(self.preprocessor.neighboor_elements_of_node(self.node_ID)) > 1: title = "INVALID SELECTION - NODE {}".format(self.node_ID) message = "The selected NODE ID must be in the beginning \nor termination of the pipelines." PrintMessageInput([title, message, window_title_1]) return True
def check_dofs_coupling(self): if self.check_get_nodes(): return if self.flag_first_node: self.selected_node_id = self.first_node elif self.flag_last_node: self.selected_node_id = self.last_node neighboor_elements = self.preprocessor.neighboor_elements_of_node(self.selected_node_id) if len(neighboor_elements)<3: message = "The decoupling of rotation dofs can only \nbe applied to the T connections." title = "Incorrect Node ID selection" window_title = "Error message" PrintMessageInput([title, message, window_title]) return if self.rotations_mask.count(False) == 3: title = "INVALID DECOUPLING SETUP" message = "There are no rotation DOFs decoupling in the current setup. \nYou should tick at least one rotation DOF before continue." PrintMessageInput([title, message, window_title1]) return if self.structural_elements[self.element_id].element_type in ['beam_1']: self.project.set_B2PX_rotation_decoupling(self.element_id, self.selected_node_id, self.rotations_mask) print("[Set Rotation Decoupling] - defined at element {} and at node {}".format(self.element_id, self.selected_node_id)) self.complete = True self.close() else: title = "INVALID DECOUPLING SETUP" element_type = self.structural_elements[self.element_id] message = f"The selected element have a '{element_type.upper()}' formulation, you should have a \n'BEAM_1' element type in selection" message += " to decouple the rotation dofs. \nTry to choose another element or change the element type formulation." PrintMessageInput([title, message, window_title1]) return