예제 #1
0
 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
예제 #2
0
    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()
예제 #3
0
    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()
예제 #4
0
 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()
예제 #5
0
    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()
예제 #6
0
    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()
예제 #7
0
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
예제 #8
0
    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()
예제 #9
0
    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])