def update_pss_solids_mass_fraction_total(self): if not self.pss_current_indices: return PS0 = self.pss_current_indices[0] P = self.pss_current_solid if P is None: return species = self.solids_species.get(P) if not P: return ui = self.ui.point_sources key = 'ps_x_s' table = ui.tablewidget_solids_mass_fraction if table.rowCount() == 0: return total = sum( safe_float( self.project.get_value(key, default=0.0, args=[PS0, P, i])) for i in range(1, len(species) + 1)) total = round(total, 6) item = table.item(table.rowCount() - 1, 1) font = item.font() font.setBold(True) item.setFont(font) item.setText(str(total)) if total != 1.0: item.setForeground(Qt.red) #We should warn, but this creates too many popups while PS is being set up #self.warning("Mass fractions sum to %s, must be 1.0" % total, popup=True) elif ui.isEnabled(): item.setForeground(Qt.black) # FIXME looks wrong when greyed-out
def mesh_add(self, index): """add a control point to the end""" table = self.mesh_tables[index] data = table.value d = ['x', 'y', 'z'][index] k = data.keys() i = 0 if k: i = max(k) + 1 loc = safe_float(list(data.values())[-1]['position']) + 1 c = 1 else: loc = self.project.get_value(d + '_max', 1) c = self.project.get_value(CELL_MFIX_KEYS[index], 1) ctrl = data[i] = { 'position': loc, 'cells': c, 'stretch': 1.0, 'first': 0.0, 'last': 0.0 } self.mesh_update_mfixkeys(ctrl, i, d) table.set_value(data) table.fit_to_contents() self.update_background_mesh()
def handle_pss_solids_mass_fraction(self, widget, value_dict, args): ui = self.ui.point_sources key = 'ps_x_s' val = value_dict[key] widget.updateValue(key, val) if val == '': self.unset_keyword(key, args=args) else: self.update_keyword(key, val, args=args) # DEFAULT - last defined species has mass fraction of 1.0 # See also pss_set_default_keys PS = args[0] P = args[1] species = self.solids_species[P] if species: N = len(species) for PS in self.pss_current_indices: total = sum( safe_float( self.project.get_value(key, default=0, args=[PS, P, i ])) for i in range(1, 1 + N)) for i in range(1, 1 + N): default = float(i == N) if total == 0 else 0.0 self.set_keyword_default(key, default, args=[PS, P, i]) self.update_pss_solids_mass_fraction_table()
def update_background_mesh_extents(self, key, val, args): """collect extents changes, check if value is different""" if not self.mesh_extents: return val = safe_float(val, 0) ind = MESH_EXTENT_KEYS.index(key) old_val = self.mesh_extents[ind] if old_val != val: self.mesh_extents[ind] = val self.update_background_mesh()
def init_background_mesh(self): """init the background mesh""" project = self.project self.mesh_extents = [ safe_float(project.get_value(key, default=0.0)) for key in MESH_EXTENT_KEYS ] self.mesh_cells = [ safe_int(project.get_value(key, default=1)) for key in MESH_CELL_KEYS ] self.mesh_spacing = [[], [], []] # disable delete btns for btn in self.mesh_delete_btns: btn.setEnabled(False) # collect dx, dy, dz for (i, (s, c)) in enumerate(zip(['dx', 'dy', 'dz'], MESH_CELL_KEYS)): d = [ project.get_value(s, args=args) for args in sorted(project.get_key_indices(s)) ] l = len(d) # if there are spacing, update the keywords. if l > 0: self.mesh_cells[i] = l self.update_mesh_keyword(c, l) self.mesh_spacing[i] = d self.extract_mesh_spacing(i, d) # collect variable grid spacing keywords for (i, k) in enumerate(['x', 'y', 'z']): indices = project.get_key_indices('cp' + k) if indices: table_dic = OrderedDict() for j, ind in enumerate(sorted(indices)): ind = ind[0] table_dic[j] = { 'position': project.get_value('cp' + k, 0, args=ind), 'cells': project.get_value('nc' + k, 1, args=ind + 1), 'stretch': project.get_value('er' + k, 1, args=ind + 1), 'first': project.get_value('first_d' + k, 0, args=ind + 1), 'last': project.get_value('last_d' + k, 0, args=ind + 1) } self.mesh_tables[i].set_value(table_dic) self.mesh_tables[i].fit_to_contents() self.update_background_mesh()
def mesh_split(self, table, d): """split the selected control point""" row, col = table.get_clicked_cell() data = table.value split_data = data[row] prev_data_loc = self.project.get_value(d + '_min', 0) if row >= 2: prev_data_loc = safe_float(data[row - 1]['position']) # find the midpoint, and slit the cells evenly midpoint = (safe_float(split_data['position']) - prev_data_loc) / 2.0 + prev_data_loc cells = max(int(safe_int(split_data['cells'], 1) / 2), 1) split_data['cells'] = cells # insert the cell # TODO: better way? new = OrderedDict() for i, ctrl in data.items(): if i < row: new[i] = ctrl elif i == row: new[i] = { 'position': midpoint, 'cells': cells, 'stretch': 1.0, 'first': 0.0, 'last': 0.0 } self.mesh_update_mfixkeys(new[i], i, d) new[i + 1] = ctrl self.mesh_update_mfixkeys(ctrl, i + 1, d) else: new[i + 1] = ctrl self.mesh_update_mfixkeys(ctrl, i + 1, d) table.set_value(new) table.fit_to_contents() self.update_background_mesh()
def ctrl_pts_to_loc(ctrl, min_loc): """given control points, convert to location""" loc = [min_loc] last = min_loc for pt in ctrl.values(): er = safe_float(pt['stretch'], 1.0) cp = safe_float(pt['position'], 0.0) nc = safe_int(pt['cells'], 1) # uniform dx dx = (cp - last) / nc # first dx? fdx = safe_float(pt['first'], 0.0) if fdx < 0 and len(loc) > 2: fdx = loc[-1] - loc[-2] # expansion ratio ratio = 1 prev_cell_w = dx if nc > 1 and er != 1: ratio = er**(1 / (nc - 1)) prev_cell_w = (cp - loc[-1]) * (1 - ratio) / ( 1 - ratio**nc) # current cell width prev_cell_w /= ratio # backup one cell for the loop below # add cell positions to list for i in range(nc): cell_w = dx if er != 1: cell_w = prev_cell_w * ratio loc.append(loc[-1] + cell_w) prev_cell_w = cell_w last = loc[-1] return loc
def handle_pss_fluid_mass_fraction(self, widget, value_dict, args): ui = self.ui.point_sources key = 'ps_x_g' val = value_dict[key] widget.updateValue(key, val) if val == '': self.unset_keyword(key, args=args) else: self.update_keyword(key, val, args=args) # DEFAULT - last defined species has mass fraction of 1.0 # (only enforce this if no mass fractions are set) # See also pss_set_default_keys if self.fluid_species: N = len(self.fluid_species) for PS in args[0]: total = sum( safe_float( self.project.get_value(key, default=0, args=[PS, i])) for i in range(1, 1 + N)) for i in range(1, 1 + N): default = float(i == N) if total == 0.0 else 0.0 self.set_keyword_default(key, default, args=[PS, i]) self.update_pss_fluid_mass_fraction_table()
def pss_set_default_keys(self, PS): #Fluid #- Define mass flowrate: #- Sets keyword PS_MASSFLOW_G(#) #- DEFAULT 0.0 key = 'ps_massflow_g' default = 0.0 self.set_keyword_default(key, default, args=[PS]) mmax = self.project.get_value('mmax', default=0) nmax_g = self.project.get_value('nmax_g', default=0) nmax_s = [None] + [ self.project.get_value('nmax_s', default=0, args=[i]) for i in range(1, 1 + mmax) ] energy_eq = self.project.get_value('energy_eq', default=True) species_eq = [ self.project.get_value('species_eq', default=True, args=[i]) for i in range(1 + mmax) ] # including index 0 = fluid solids_model = [None] + [ self.project.get_value('solids_model', args=[i]) for i in range(1, 1 + mmax) ] #- Define temperature #- Specification only available when solving energy equations #- DEFAULT value 293.15 #- Sets keyword PS_T_G(#) if energy_eq: key = 'ps_t_g' default = 293.15 self.set_keyword_default(key, default, args=[PS]) #- Select species and set mass fractions (table format) #- Specification only available when solving species equations #- DEFAULT value 1.0 of last defined species #- Sets keyword PS_X_G(#,#) #- Error check: if specified, mass fractions must sum to 1.0 if species_eq[0]: key = 'ps_x_g' for i in range(1, 1 + nmax_g): default = 0.0 self.set_keyword_default(key, default, args=[PS, i]) total = sum( safe_float(self.project.get_value(key, default=0, args=[PS, i])) for i in range(1, nmax_g)) # All but last if total == 0 and nmax_g > 0: # Set last species to 1, only if all other are 0 self.update_keyword(key, 1.0, args=[PS, nmax_g]) #- Define X/Y/Z-axial velocity: #- Specification always available #- DEFAULT value 0.0 #- Sets keyword PS_U/V/W_G(#) default = 0.0 for c in 'uvw': key = 'ps_%s_g' % c self.set_keyword_default(key, default, args=[PS]) #Solids-# #*At this time, only TFM solids can be defined with point sources. At some point in the future, this could be extended to PIC solids, but never DEM.* for P in range(1, 1 + mmax): if solids_model[P] != 'TFM': continue #- Define mass flowrate: #- Select mass inflow specification type: #- Sets keyword PS_MASSFLOW_S(#,#) #- DEFAULT 0.0 key = 'ps_massflow_s' default = 0.0 self.set_keyword_default(key, default, args=[PS, P]) #- Define temperature #- Specification only available when solving energy equations #- DEFAULT value 293.15 #- Sets keyword PS_T_S(#,#) if energy_eq: key = 'ps_t_s' default = 293.15 self.set_keyword_default(key, default, args=[PS, P]) #- Select species and set mass fractions (table format) #- Specification only available when solving species equations #- DEFAULT value 1.0 of last defined species #- Sets keyword PS_X_S(#,#,#) #- Error check: if specified, mass fractions must sum to 1.0 if species_eq[P]: key = 'ps_x_s' N = nmax_s[P] for i in range(1, 1 + N): default = 0.0 self.set_keyword_default(key, default, args=[PS, P, i]) total = sum( safe_float( self.project.get_value(key, default=0, args=[PS, i])) for i in range(1, N)) # All but last if total == 0 and N > 0: # Set last species to 1, only if all other are 0 self.update_keyword(key, 1.0, args=[PS, P, N]) #- Define X/Y/Z-axial velocity: #- Specification always available #- DEFAULT value 0.0 #- Sets keyword PS_{UVW}_S(#,#) default = 0.0 for c in 'uvw': key = 'ps_%s_s' % c self.set_keyword_default(key, default, args=[PS, P])