예제 #1
0
 def set_leq_method(self, val, index):
     ui = self.ui.numerics
     cb = ui.tablewidget_linear_solver.cellWidget(index - 1, COL_SOLVER)
     cb.setToolTip(get_combobox_item(cb, val).toolTip())
     key = 'leq_method'
     self.update_keyword(key, LEQ_METHODS[val], args=[index])
     cb.setToolTip(get_combobox_item(cb, val).toolTip())
예제 #2
0
 def set_sweep(self, val, index):
     ui = self.ui.numerics
     cb = ui.tablewidget_preconditioner.cellWidget(index - 1, COL_SWEEP)
     cb.setToolTip(get_combobox_item(cb, val).toolTip())
     key = 'leq_sweep'
     self.update_keyword(key, SWEEP_TYPES[val], args=[index])
     cb.setToolTip(get_combobox_item(cb, val).toolTip())
     self.setup_numerics()
예제 #3
0
    def init_model_setup(self):
        ui = self.ui.model_setup
        ui.combobox_solver.activated.connect(self.set_solver)

        ui.checkbox_disable_fluid_solver.clicked.connect(self.disable_fluid_solver)

        ui.checkbox_keyword_energy_eq.clicked.connect(self.enable_energy_eq)

        key = 'turbulence_model'
        cb = ui.combobox_turbulence_model
        cb.activated.connect(self.set_turbulence_model)
        for (i, value) in enumerate(TURBULENCE_MODELS):
            item = get_combobox_item(cb, i)
            self.add_tooltip(item, key, value=value)

        key = 'drag_type'
        cb = ui.combobox_drag_type
        cb.activated.connect(self.set_drag_type)
        assert ui.combobox_drag_type.count() == len(DRAG_TYPES)
        for item in (ui.label_drag_type, cb):
            self.add_tooltip(item, key)
        for (i, val) in enumerate(DRAG_TYPES):
            item = get_combobox_item(cb, i)
            self.add_tooltip(item, key=key, description=self.keyword_doc[key]['valids'][val]['note'], value=val)

        cb = ui.combobox_momentum_formulation
        cb.activated.connect(self.set_momentum_formulation)
        self.add_tooltip(ui.label_momentum_formulation, key=None, description=self.keyword_doc['model_b']['description'])

        for i in range(4):
            item = get_combobox_item(cb, i)
            if i == 0:
                key = 'model_b'
                value = False
            elif i == 1:
                key = 'model_b'
                value = True
            elif i == 2:
                key = 'jackson'
                value = None
            else:
                key = 'ishii'
                value = None
            self.add_tooltip(item, key=key, value=value)

        key = 'subgrid_type'
        cb = ui.combobox_subgrid_type
        cb.activated.connect(self.set_subgrid_type)
        for (i, value) in enumerate(SUBGRID_TYPES):
            if value == 'NONE':
                self.add_tooltip(get_combobox_item(cb, i), key, value='None', description='No subgrid model')
            else:
                self.add_tooltip(get_combobox_item(cb, i), key, value=value.title())
        self.fluid_solver_disabled = False # squelch pylint access-member-before-definition
예제 #4
0
    def init_monitors(self):
        ui = self.ui.monitors

        self.monitors = {}  # key: index.  value: data dictionary for monitor
        self.monitors_current_index = None
        self.monitors_current_region = None  # And the names of the regions which define them
        self.monitors_region_dict = None
        self.monitors_saved_solids_names = []
        ui.dynamic_widgets = {}
        ui.toolbutton_add.clicked.connect(self.monitors_show_regions_popup)
        ui.toolbutton_delete.clicked.connect(self.monitors_delete_regions)
        for tb in (ui.toolbutton_delete, ):
            tb.setEnabled(False)  # Need a selection

        ui.tablewidget_regions.itemSelectionChanged.connect(
            self.handle_monitors_region_selection)

        self.monitors_current_tab = FLUID_TAB  # If fluid is disabled, we will switch
        self.monitors_current_solid = self.P = None
        ui.pushbutton_fluid.pressed.connect(
            lambda: self.monitors_change_tab(FLUID_TAB, None))
        ui.pushbutton_scalar.pressed.connect(
            lambda: self.monitors_change_tab(SCALAR_TAB, None))
        ui.pushbutton_reactions.pressed.connect(
            lambda: self.monitors_change_tab(REACTIONS_TAB, None))
        # Phase tab is not user-selectable

        # Trim width of "Fluid", "Scalar" "Reactions" and "Phase", like we do for
        # dynamically-created "Solid #" buttons
        for b in (ui.pushbutton_fluid, ui.pushbutton_scalar,
                  ui.pushbutton_reactions, ui.pushbutton_phase):
            w = b.fontMetrics().boundingRect(b.text()).width() + 20
            b.setMaximumWidth(w)

        # Show groupbox without title  (title is empty string)
        height = ui.checkbox_keyword_monitor_ep_g_args_MONITOR.sizeHint(
        ).height()
        tweak = 3
        ui.stackedwidget_detail.setStyleSheet(
            # Fix gap where title would be, with negative padding.
            # This is somewhat questionable (i.e. a total hack)
            'QGroupBox {margin-top: %spx; padding-top: %spx }' %
            (tweak - height, height))

        cb = ui.combobox_monitor_type
        key = 'monitor_type'
        for i in range(len(cb)):
            self.add_tooltip(get_combobox_item(cb, i), key, value=i)
        cb.setToolTip(get_combobox_item(cb, cb.currentIndex()).toolTip())
        cb.activated.connect(self.handle_combobox_monitor_type)
        # Make the table update when user changed MONITOR_NAME
        le = ui.lineedit_keyword_monitor_name_args_MONITOR
        le.post_update = self.setup_monitors
예제 #5
0
    def init_numerics_linear_solver_pane(self):
        ui = self.ui.numerics
        tw = ui.tablewidget_linear_solver
        # Add some tooltips
        key = 'leq_method'
        self.add_tooltip(tw.horizontalHeaderItem(COL_SOLVER), key)
        key = 'leq_it'
        self.add_tooltip(tw.horizontalHeaderItem(COL_RELAX), key)
        key = 'leq_tol'
        self.add_tooltip(tw.horizontalHeaderItem(COL_TOL), key)

        # Populate table with combobox and lineedit widgets
        for i in range(1, 1 + DIM_EQS):
            row = i - 1
            key = 'leq_method'
            cb = ComboBox()
            cb.args = [i]
            for (j, name) in enumerate(LEQ_METHOD_NAMES):
                cb.addItem(name)
            for (j, method) in enumerate(LEQ_METHODS):
                item = get_combobox_item(cb, j)
                item.args = [i]
                self.add_tooltip(item, key, value=method)

            cb.setToolTip(get_combobox_item(cb, 0).toolTip())
            cb.currentIndexChanged.connect(
                lambda val, i=i: self.set_leq_method(val, i))
            tw.setCellWidget(row, COL_SOLVER, cb)

            key = 'leq_it'
            le = LineEdit()
            le.dtype = int
            le.min = 0
            le.key = key
            le.args = [i]
            tw.setCellWidget(row, COL_ITER, le)
            le.value_updated.connect(self.project.submit_change)
            self.add_tooltip(le, key)

            key = 'leq_tol'
            le = LineEdit()
            le.dtype = float
            le.min = 0
            le.key = key
            le.args = [i]
            tw.setCellWidget(row, COL_TOL, le)
            le.value_updated.connect(self.project.submit_change)
            self.add_tooltip(le, key)
예제 #6
0
    def handle_combobox_monitor_type(self, index):
        ui = self.ui.monitors
        cb = ui.combobox_monitor_type
        cb.setToolTip(get_combobox_item(cb, index).toolTip())
        mon = self.monitors_current_index
        if mon is None:  # No selection
            return
        key = 'monitor_type'
        val = index
        prev_phase_required = self.monitor_requires_phase(mon)
        self.update_keyword(key, val, args=[mon])
        new_phase_required = self.monitor_requires_phase(mon)
        if prev_phase_required != new_phase_required:
            # Unset keys when 'phase_required' changes..
            kwlist = list(self.project.keywordItems())
            for kw in kwlist:
                key, args = kw.key, kw.args
                if key.startswith('monitor_') and args and args[0] == mon:
                    if key in ('monitor_x_w', 'monitor_y_s', 'monitor_z_b',
                               'monitor_x_e', 'monitor_y_n', 'monitor_z_t',
                               'monitor_name', 'monitor_type', 'monitor_dt'):
                        continue
                    self.unset_keyword(key, args=args)

        self.handle_monitors_region_selection(
        )  # Will update tabset & ensure valid tab
예제 #7
0
 def set_discretize(self, val, index):
     ui = self.ui.numerics
     key = 'discretize'
     self.update_keyword(key, val, args=[index])
     cb = ui.tablewidget_discretization.cellWidget(index - 1, COL_SCHEME)
     cb.setToolTip(get_combobox_item(cb, val).toolTip())
     self.setup_numerics()  # update checkboxes etc
예제 #8
0
    def init_numerics_discretization_pane(self):
        # Add some extra tooltips
        ui = self.ui.numerics
        cb = ui.combobox_cn_on
        key = 'cn_on'
        cb.currentIndexChanged.connect(self.set_cn_on)
        self.add_tooltip(get_combobox_item(cb, 0), key, value='.FALSE.')
        self.add_tooltip(get_combobox_item(cb, 1), key, value='.TRUE.')

        tw = ui.tablewidget_discretization
        key = 'discretize'
        self.add_tooltip(tw.horizontalHeaderItem(COL_SCHEME), key)
        key = 'ur_fac'
        self.add_tooltip(tw.horizontalHeaderItem(COL_RELAX), key)

        # Populate table with combobox and lineedit widgets

        for i in range(1, 1 + DIM_EQS):
            row = i - 1
            key = 'discretize'
            cb = ComboBox()
            cb.args = [i]
            for name in DISCRETIZATION_NAMES:
                cb.addItem(name)
            for j in range(len(DISCRETIZATION_NAMES)):
                item = get_combobox_item(cb, j)
                item.args = [i]
                self.add_tooltip(item, key, value=j)
            cb.setToolTip(get_combobox_item(cb, 0).toolTip())
            cb.currentIndexChanged.connect(
                lambda val, i=i: self.set_discretize(val, i))
            tw.setCellWidget(row, COL_SCHEME, cb)

            key = 'ur_fac'
            le = LineEdit()
            le.dtype = float
            le.key = key
            le.args = [i]
            tw.setCellWidget(row, COL_RELAX, le)
            le.value_updated.connect(self.project.submit_change)
            self.add_tooltip(le, key)
예제 #9
0
    def set_subgrid_type(self, idx):
        # Sets keyword SUBGRID_TYPE
        # Available selections
        #  NONE (DEFAULT)
        #  IGCI
        #  MILIOLI
        ui = self.ui.model_setup
        cb = ui.combobox_subgrid_type
        self.update_keyword('subgrid_type', SUBGRID_TYPES[idx])
        cb.setToolTip(get_combobox_item(cb, idx).toolTip())

        self.setup_model_setup()
예제 #10
0
    def init_numerics_preconditioner_pane(self):
        ui = self.ui.numerics
        tw = ui.tablewidget_preconditioner
        # Add some tooltips to column headers
        key = 'leq_pc'
        self.add_tooltip(tw.horizontalHeaderItem(COL_PRECON), key)
        key = 'leq_sweep'
        self.add_tooltip(tw.horizontalHeaderItem(COL_SWEEP), key)
        # Populate table
        for i in range(1, 1 + DIM_EQS):
            row = i - 1
            key = 'leq_pc'
            cb = ComboBox()
            cb.args = [i]
            for j, name in enumerate(PRECON_NAMES):
                cb.addItem(name)
                item = get_combobox_item(cb, j)
                item.args = [i]
                self.add_tooltip(item, key, value=PRECON_TYPES[j])

            cb.currentIndexChanged.connect(
                lambda val, i=i: self.set_preconditioner(val, i))
            tw.setCellWidget(row, COL_PRECON, cb)
            self.add_tooltip(cb, key)

            key = 'leq_sweep'
            cb = ComboBox()
            cb.args = [i]
            for j, name in enumerate(SWEEP_NAMES):
                cb.addItem(name)
                item = get_combobox_item(cb, j)
                item.args = [i]
                self.add_tooltip(item, key, value=SWEEP_TYPES[j])
            cb.currentIndexChanged.connect(
                lambda val, i=i: self.set_sweep(val, i))
            tw.setCellWidget(row, COL_SWEEP, cb)
            self.add_tooltip(cb, key)
예제 #11
0
    def init_solids_tfm(self):
        ui = self.ui.solids
        key = 'kt_type'
        cb = ui.combobox_kt_type
        cb.activated.connect(self.set_kt_type)
        self.add_tooltip(cb, key)
        for (i, v) in enumerate(KT_TYPES):
            self.add_tooltip(get_combobox_item(cb, i), key, value=v)

        key = 'friction_model'
        cb = ui.combobox_friction_model
        self.add_tooltip(cb, key)
        for (i, v) in enumerate(FRICTION_MODELS):
            self.add_tooltip(get_combobox_item(cb, i), key, value=v)
        cb.activated.connect(self.set_friction_model)

        key = 'rdf_type'
        cb = ui.combobox_rdf_type
        self.add_tooltip(cb, key)
        for (i, v) in enumerate(RDF_TYPES):
            self.add_tooltip(get_combobox_item(cb, i),
                             key,
                             value=v or 'CARNAHAN_STARLING')
        cb.activated.connect(self.set_rdf_type)

        key = 'blending_function'
        cb = ui.combobox_blending_function
        self.add_tooltip(cb, key)
        for (i, v) in enumerate(BLENDING_FUNCTIONS):
            self.add_tooltip(get_combobox_item(cb, i), key, value=v)
        cb.activated.connect(self.set_blending_function)

        # This does not correspond to a single keyword
        label = ui.label_max_packing_correlation
        cb = ui.combobox_max_packing_correlation
        description = 'Correlation to compute maximum packing for polydisperse systems'
        self.add_tooltip(label, key=None, description=description)
        self.add_tooltip(cb, key=None, description=description)
        self.add_tooltip(get_combobox_item(cb, 0),
                         key=None,
                         description="Constant packing correlation")
        self.add_tooltip(get_combobox_item(cb, 1), key='yu_standish')
        self.add_tooltip(get_combobox_item(cb, 2), key='fedors_landel')
        cb.activated.connect(self.set_max_packing_correlation)
예제 #12
0
    def set_turbulence_model(self, val):
        # Available selections:
        #  None; [DEFAULT]
        #  Mixing Length:
        #    Selection always available
        #    Sets keyword TURBULENCE_MODEL to MIXING_LENGTH
        #    Requires IC_L_SCALE for all IC regions
        #  K-Epsilon
        #    Selection always available
        #    Sets keyword TURBULENCE_MODEL to K_EPSILON
        #    Requires IC_K_TURB_G for all IC regions TODO
        #    Requires IC_E_TURB_G for all IC regions TODO
        #    Requires BC_K_TURB_G for inflow (MI and PI) BC regions TODO
        #    Requires BC_E_TURB_G for inflow (MI and PI) BC regions TODO
        ui = self.ui.model_setup
        cb = ui.combobox_turbulence_model
        if cb.currentIndex() != val:
            cb.setCurrentIndex(val)
        turbulence_model = TURBULENCE_MODELS[val]
        # Avoid resetting turbulence_model from None to 'NONE' at startup
        if turbulence_model != self.project.get_value('turbulence_model',
                                                      default=DEFAULT_TURBULENCE_MODEL):
            self.update_keyword('turbulence_model', turbulence_model)
        # Set combobox tooltip to match item value
        cb.setToolTip(get_combobox_item(cb, val).toolTip())

        enabled = (turbulence_model != 'NONE')
        #Specify maximum fluid viscosity (not shown in mockup)
        # Selection available if TURBULENCE_MODEL =/ 'NONE'
        # Sets keyword MU_GMAX
        # DEFAULT 1.0e3 (Pa.s)
        for item in (ui.label_mu_gmax, ui.lineedit_keyword_mu_gmax, ui.label_mu_gmax_units):
            item.setEnabled(enabled)
        if enabled:
            val = ui.lineedit_keyword_mu_gmax.value
            if val=='' or val is None:
                val = default_values.mu_g0
            self.update_keyword('mu_gmax', val)
        else:
            self.unset_keyword('mu_gmax')
예제 #13
0
    def setup_model_setup(self):
        ui = self.ui.model_setup
        solver = self.project.solver
        ui.checkbox_disable_fluid_solver.setChecked(self.fluid_solver_disabled)
        self.add_tooltip(ui.checkbox_disable_fluid_solver, key=None, description="""Granular flow in vacuum:
Sets ro_g0 (fluid density) to 0 and disables fluid momentum equations for faster convergence""")
        self.disable_fluid_solver(self.fluid_solver_disabled)

        # Don't allow setting single-phase once solids are defined
        cb = ui.combobox_solver
        get_combobox_item(cb, 0).setEnabled(not self.solids)

        key = 'turbulence_model'
        turbulence_model = self.project.get_value(key, default=DEFAULT_TURBULENCE_MODEL)
        if turbulence_model not in TURBULENCE_MODELS:
            self.error("Invalid turbulence model %s" % turbulence_model)
            turbulence_model = DEFAULT_TURBULENCE_MODEL
            self.update_keyword(key, turbulence_model)
        else:
            self.set_turbulence_model(TURBULENCE_MODELS.index(turbulence_model))

        #Specify Gravitational acceleration
        #    Specification always available
        #    Sets keywords GRAVITY_X, GRAVITY_Y, GRAVITY_Z
        #    DEFAULT values
        # handled by keyword widgets

        #  Leave blank when converting dat files to mfx
        #  New cases take the values from the mfix.dat.template
        # Implementation Note:  Not doing this.  There's not a
        # strong reason for it, and we don't distinguish converting dat files from opening existing projects.


        #    If keyword GRAVITY is specified
        #  GRAVITY_Y = -GRAVITY
        #  GRAVITY_X = GRAVITY_Z = 0.0


        #Specify drag model
        # Selection requires TFM, DEM, or PIC solver
        enabled = self.project.solver in (TFM, DEM, PIC)

        for item in (ui.label_drag_type, ui.combobox_drag_type):
            item.setEnabled(enabled)

        val = self.project.get_value('drag_type')
        if val is None:
            idx = DRAG_TYPES.index(DEFAULT_DRAG_TYPE)
        else:
            if not val in DRAG_TYPES:
                self.error('Invalid drag_type %s' % val)
                idx = DRAG_TYPES.index(DEFAULT_DRAG_TYPE)
            else:
                idx = DRAG_TYPES.index(val)
        ui.combobox_drag_type.setCurrentIndex(idx)
        drag_type = DRAG_TYPES[idx]

        # SYAM_OBRIEN
        #    Specify model parameter: DRAG_C1
        #      DEFAULT 0.8
        #    Specify model parameter: DRAG_D1
        #      DEFAULT 2.65
        enabled = self.project.solver in (TFM, DEM, PIC) and drag_type == 'SYAM_OBRIEN'
        for item in (ui.label_syam_obrien,
                     ui.label_drag_c1, ui.lineedit_keyword_drag_c1,
                     ui.label_drag_d1, ui.lineedit_keyword_drag_d1):
            item.setEnabled(enabled)
        if enabled:
            for (key, default) in (('drag_c1', 0.8), ('drag_d1', 2.65)):
                val = self.project.get_value(key)
                if val is None:
                    val = default
                    self.update_keyword(key, val)

        # HYS
        #    Specify model parameter LAM_HYS
        #      DEFAULT 1.0e-6 (meters)
        key = 'lam_hys'
        default = 1.0e-6
        enabled =  self.project.solver in (TFM, DEM, PIC) and drag_type == 'HYS'
        for item in (ui.label_lam_hys, ui.lineedit_keyword_lam_hys,
                     ui.label_lam_hys_units):
            item.setEnabled(enabled)

        if enabled:
            val = self.project.get_value(key)
            if val is None:
                val = default
                self.update_keyword(key, val)


        #Specify momentum equation formulation; Select Model A, Model B; Jackson, Ishii
        #MODEL_B
        #[ .FALSE. ] -------------------------- Use Model A
        #.TRUE. ----------------------------- Use Model B.
        model_b = self.project.get_value('model_b', default=False)

        #ISHII
        #Flag to enable Ishii form of momentum equations.         two-phase flow.
        #.TRUE. ----------------------------- Solve Ishii form of momentum equations.
        # [ .FALSE. ]
        ishii = self.project.get_value('ishii', default=False)

        #JACKSON
        #LOGICAL
        #Flag to enable Jackson form of momentum equations.

        #.TRUE. ----------------------------- Solve Jackson form of momentum equations.
        #[ .FALSE. ] -------------------------- Default
        jackson = self.project.get_value('jackson', default=False)

        if model_b + ishii + jackson > 1:
            self.error("Invalid momentum equations: more than 1 of model_b, ishii and jackson specified")
        cb = ui.combobox_momentum_formulation
        idx = 0 # model A
        if model_b:
            idx = 1
        elif jackson:
            idx = 2
        elif ishii:
            idx = 3
        cb.setCurrentIndex(idx)
        # set combobox
        cb.setToolTip(get_combobox_item(cb, idx).toolTip())


        #Select sub-grid model:
        # Selection requirements:
        #  Only available with MFIX-TFM solver
        #  DRAG_TYPE="WEN_YU"
        #  KT_TYPE="ALGEBRAIC"
        #  TURBULENCE_MODEL /= K_EPSILON
        #  BLENDING_STRESS = NONE
        #  FRICTION_MODEL /= SRIVASTAVA
        #  (There are more restrictions…)
        key = 'subgrid_type'
        cb = ui.combobox_subgrid_type
        drag_type = self.project.get_value('drag_type', default=DEFAULT_DRAG_TYPE)
        kt_type = self.project.get_value('kt_type', default=DEFAULT_KT_TYPE)
        turbulence_model = self.project.get_value('turbulence_model', default=DEFAULT_TURBULENCE_MODEL)
        blending_stress = self.project.get_value('blending_stress') # Note, not set anywhere in GUI
        friction_model = self.project.get_value('friction_model', default=DEFAULT_FRICTION_MODEL)

        enabled = (solver == TFM
                   and drag_type == 'WEN_YU'
                   and kt_type == 'ALGEBRAIC'
                   and turbulence_model != 'K_EPSILON'
                   and bool(blending_stress) == False
                   and friction_model != 'SRIVASTAVA')
        cb = ui.combobox_subgrid_type
        for item in (ui.label_subgrid_type, cb,
                     ui.label_filter_size_ratio, ui.lineedit_keyword_filter_size_ratio,
                     ui.checkbox_keyword_subgrid_wall):
            item.setEnabled(enabled)
        if not enabled:
            self.unset_keyword(key)

        value = self.project.get_value(key, default=DEFAULT_SUBGRID_TYPE)
        if value not in SUBGRID_TYPES:
            self.error("Invalid subgrid_type %s" % value)
            value = DEFAULT_SUBGRID_TYPE
        idx = SUBGRID_TYPES.index(value)
        cb.setCurrentIndex(idx)
        cb.setToolTip(get_combobox_item(cb, idx).toolTip())


        #Specify sub-grid model filter size ratio:
        # Specification requires SUBGRID_TYPE =/ NONE
        # Sets keyword FILTER_SIZE_RATIO
        # DEFAULT 2.0 # handled by widget.default
        #Enable sub-grid wall correction model:
        # Specification requires SUBGRID_TYPE =/ NONE
        # Sets keyword SUBGRID_WALL
        # DEFAULT FALSE # handled by widget.default
        enabled = self.project.get_value('subgrid_type') not in (None, 'NONE')
        for item in (ui.label_filter_size_ratio, ui.lineedit_keyword_filter_size_ratio,
                     ui.checkbox_keyword_subgrid_wall):
            item.setEnabled(enabled)
예제 #14
0
    def setup_tfm_tab(self):
        # Note - we are doing this setup on first show of this tab, rather
        # than at init or project load time
        ui = self.ui.solids

        # Select Viscous Stress Model (KTGS):
        # Selection is unavailable for constant solids viscosity (MU_S0 defined)
        # FIXME This is not right, solids viscosity model is phase-dependent
        #enabled = (self.solids_viscosity_model != CONSTANT) # SRS p18
        #for item in (ui.label_kt_type, ui.combobox_kt_type,
        #             ui.label_friction_model, ui.combobox_friction_model):
        #    item.setEnabled(enabled)

        # SRS p18 - enable/disable menu items in viscous stress model
        key = 'kt_type'
        kt_type = self.project.get_value(key, default=DEFAULT_KT_TYPE)
        cb = ui.combobox_kt_type
        if kt_type:
            if kt_type not in KT_TYPES:
                self.warn("Invalid kt_type %s" % kt_type)
                self.unset_keyword(key)
                self.add_tooltip(cb, key=key)
            else:
                cb.setCurrentIndex(KT_TYPES.index(kt_type))
                self.add_tooltip(cb, key=key, value=kt_type)
        else:
            self.add_tooltip(cb, key=key)

        mmax = self.project.get_value('mmax', default=1)
        k_e = (self.project.get_value(
            'turbulence_model',
            default=DEFAULT_TURBULENCE_MODEL) == 'K_EPSILON')
        added_mass = self.project.get_value('m_am') or self.project.get_value(
            'added_mass')
        drag_type = self.project.get_value('drag_type')
        friction_model = self.project.get_value('friction_model',
                                                default=DEFAULT_FRICTION_MODEL)
        enabled = [
            True,  #ALGEBRAIC
            True,  #LUN_1984
            True,  #IA_NONEP
            k_e,  #SIMONIN
            k_e,  #AHMADI
            mmax == 1,  #GD99
            mmax == 1,  #GTSH
            mmax <= 2 and (not added_mass) and drag_type in ('WEN_YU', 'HYS')
        ]  # GHD
        #assert len(enabled) == len(KT_TYPES)
        for (i, e) in enumerate(enabled):
            set_item_enabled(get_combobox_item(cb, i), e)

        # Select Frictional Stress Model
        cb = ui.combobox_friction_model
        key = 'friction_model'
        # Srivastava and Sundaresan, 2003
        # Unavailable for Algebraic Formulation viscous stress model
        set_item_enabled(get_combobox_item(cb, 1), (kt_type != 'ALGEBRAIC'))
        if kt_type == 'ALGEBRAIC':
            if friction_model == 'SRIVASTAVA':  # Forbidden
                cb.setCurrentIndex(2)  # None
                friction_model = FRICTION_MODELS[2]
                self.update_keyword(key, friction_model)

        if friction_model not in FRICTION_MODELS:
            self.warn("Unrecogized friction_model %s" % friction_model)
            cb.setCurrentIndex(2)  # None
            friction_model = FRICTION_MODELS[2]
            self.update_keyword(key, friction_model)
        else:
            cb.setCurrentIndex(FRICTION_MODELS.index(friction_model))
        self.add_tooltip(cb, key=key, value=friction_model)

        # Specify solids volume fraction at onset of friction
        enabled = (friction_model == 'SRIVASTAVA')
        for item in (ui.label_eps_f_min, ui.lineedit_keyword_eps_f_min):
            item.setEnabled(enabled)

        #Specify particle-particle restitution coefficient
        # Specification available only when required
        # Required for MMAX >=2
        # Required for viscous stress models except GHD and algebraic formulation
        # Sets keyword C_E
        enabled = (mmax >= 2) or (kt_type not in ('GHD', 'ALGEBRAIC'))
        for item in (ui.label_c_e, ui.lineedit_keyword_c_e):
            item.setEnabled(enabled)

        #  Garzo, Hrenya and Dufty, 2007
        #    Selection not available for MMAX > 2
        #    Selection not available with added mass force
        #    Sets keyword KT_TYPE to GHD
        #    Requires WEN_YU or HYS drag model
        #    Specify coefficient of restitution; R_p (optional)
        # note R_P *replaces* C_E for kt_type==GHD

        ghd = (kt_type == 'GHD')
        if ghd:
            names = list(self.solids.keys())
            if names:
                ui.label_r_p_1_1.setText("%s restitution coeff." % names[0])
            if len(names) > 1:
                ui.label_r_p_1_2.setText("%s-%s restitution coeff." %
                                         (names[0], names[1]))
                ui.label_r_p_2_2.setText("%s restitution coeff." % names[1])

        for item in (ui.label_c_e, ui.lineedit_keyword_c_e):
            item.hide() if ghd else item.show()

        for item in (ui.label_r_p_1_1, ui.lineedit_keyword_r_p_args_1_1):
            item.show() if ghd else item.hide()

        for item in (ui.label_r_p_1_2, ui.label_r_p_2_2,
                     ui.lineedit_keyword_r_p_args_1_2,
                     ui.lineedit_keyword_r_p_args_2_2):
            item.show() if (ghd and len(names) > 1) else item.hide()

        #Specify interphase friction coefficient
        # Specification available only when required
        # Required for MMAX >= 2
        # Sets keyword C_F
        enabled = (mmax >= 2)
        for item in (ui.label_c_f, ui.lineedit_keyword_c_f):
            item.setEnabled(enabled)

        #Specify angle of particle-particle friction
        # Specification available only when required
        # Required for FRICTION_MODEL=SCHAEFFER
        # Required for FRICTION_MODEL=SRIVASTAVA
        # Sets keyword PHI
        enabled = friction_model in ('SCHAEFFER', 'SRIVASTAVA')
        for item in (ui.label_phi, ui.lineedit_keyword_phi):
            item.setEnabled(enabled)

        ### Advanced
        # Select radial distribution function
        key = 'rdf_type'
        rdf_type = self.project.get_value(key)
        if mmax > 1:
            if rdf_type not in RDF_TYPES:
                self.warn('Invalid rdf_type %s' % rdf_type)
                rdf_type = 'LEBOWITZ'
                self.update_keyword('rdf_type', rdf_type)
        if mmax < 2:
            if rdf_type:
                self.warn('Invalid rdf_type %s' % rdf_type)
                rdf_type = None
                self.update_keyword(key, rdf_type)

        cb = ui.combobox_rdf_type
        index = RDF_TYPES.index(rdf_type)
        if index == 0 and mmax > 1:
            index = 1  # Lebowitz
            rdf_type = 'LEBOWITZ'  # So that tooltip will be set correctly
        cb.setCurrentIndex(index)
        self.add_tooltip(cb, key=key, value=rdf_type or 'CARNAHAN_STARLING')

        enabled = [mmax == 1] + 4 * [mmax > 1]
        for (i, e) in enumerate(enabled):
            set_item_enabled(get_combobox_item(cb, i), e)

        # Select stress blending model
        # Selection only available with FRICTION_MODEL=SCHAEFFER
        key = 'blending_function'
        cb = ui.combobox_blending_function
        blending_function = self.project.get_value(
            'blending_function', default=DEFAULT_BLENDING_FUNCTION)
        if blending_function not in BLENDING_FUNCTIONS:
            self.warn('Invalid blending_function %s' % blending_function)
            blending_function = DEFAULT_BLENDING_FUNCTION
            self.update_keyword(key, blending_function)
        cb.setCurrentIndex(BLENDING_FUNCTIONS.index(blending_function))
        self.add_tooltip(cb, key, value=blending_function)
        enabled = (friction_model == 'SCHAEFFER')
        for item in (ui.label_blending_function, cb):
            item.setEnabled(enabled)
        if not enabled:
            self.unset_keyword(key)
        else:  # Restore value (should we do this?)
            v = cb.currentIndex()
            if self.project.get_value(key, default=DEFAULT_BLENDING_FUNCTION
                                      ) != BLENDING_FUNCTIONS[v]:
                self.update_keyword(key, BLENDING_FUNCTIONS[v])

        # Specify the segregation slope coefficient
        #  Only available for MMAX > 1 in conjunction with the following viscous stress
        # algebraic formulation; Lun. 1984; Simonin, 1996; Ahmadi, 1995
        enabled = (mmax > 1) and kt_type in [
            'ALGEBRAIC', 'LUN_1984', 'SIMONIN', 'AHMADI'
        ]
        for item in (ui.label_segregation_slope_coefficient,
                     ui.lineedit_keyword_segregation_slope_coefficient):
            item.setEnabled(enabled)

        # Select maximum packing correlation
        # Selection only available with FRICTION_MODEL=SCHAEFFER and MMAX >1
        enabled = (friction_model == 'SCHAEFFER') and (mmax > 1)
        for item in (ui.label_max_packing_correlation,
                     ui.combobox_max_packing_correlation):
            item.setEnabled(enabled)
        # Constant [DEFAULT]
        # Selection always available
        # Yu & Standish
        # Selection always available
        cb = ui.combobox_max_packing_correlation
        yu_standish = self.project.get_value('yu_standish')
        fedors_landel = self.project.get_value('fedors_landel')
        set_item_enabled(get_combobox_item(cb, 2),
                         mmax == 2)  # Only enable F_L for binary mixture

        if yu_standish and fedors_landel:
            self.warn("YU_STANDISH and FEDORS_LANDEL both set")
            self.unset_keyword('yu_standish')
            self.unset_keyword('fedors_landel')
            yu_standish = fedors_landel = False
        if fedors_landel and (mmax != 2):
            self.warn("FEDORS_LANDEL only valid for binary mixtures")
            self.unset_keyword('fedors_landel')
            fedors_landel = False
        if yu_standish:
            cb.setCurrentIndex(1)
            self.add_tooltip(cb, key='YU_STANDISH')
        elif fedors_landel:
            cb.setCurrentIndex(2)
            self.add_tooltip(cb, key='FEDORS_LANDEL')
        else:
            cb.setCurrentIndex(0)
            self.add_tooltip(cb,
                             key=None,
                             description="Constant packing correlation")

        # Specify excluded volume in Boyle-Massoudi stress (optional)
        # Only available with algebraic formulation of viscous stress model
        enabled = (kt_type == 'ALGEBRAIC')
        for item in (ui.label_v_ex, ui.lineedit_keyword_v_ex):
            item.setEnabled(enabled)
예제 #15
0
    def handle_regions_selection(self):
        tw = self.ui.table
        cb = self.ui.combobox
        selections = get_selected_rows(tw)

        buttonbox = self.ui.buttonbox
        buttonbox.button(buttonbox.Ok).setEnabled(bool(selections))

        region_types = [tw.item(x, 1).text() for x in selections]
        types_match = len(set(region_types)) < 2

        if self.boundary:
            #  Pressure Inflow
            #     Not available for STL regions
            #     Not available for volume regions
            #  (also, chained regions must match type)
            disable = any(x in ('STL', 'box')
                          for x in region_types) or not types_match
            item = get_combobox_item(cb, PRESSURE_INFLOW)
            set_item_enabled(item, not disable)

            # Volume BCs are only allowed for walls
            disable = any(x == 'box' for x in region_types) or not types_match
            for idx in (MASS_INFLOW, PRESSURE_OUTFLOW, MASS_OUTFLOW):
                item = get_combobox_item(cb, idx)
                set_item_enabled(item, not disable)

            # Don't stay on disabled item
            if not item_enabled(get_combobox_item(cb, cb.currentIndex())):
                cb.setCurrentIndex(BC_TYPES.index(DEFAULT_BC_TYPE))

            bc_type = BC_TYPES[cb.currentIndex()]
            # Wall type boundary
            if bc_type.endswith('W'):
                self.handle_type(cb.currentIndex())
            # For inflows/outflows, only allow compatible orientation
            else:
                if len(selections) == 1:
                    region_type = tw.item(selections[0], 1).text()
                    for i in range(0, tw.rowCount()):
                        if i == selections[0]:
                            continue
                        enable = (tw.item(i, 1).text() == region_type)
                        self.enable_row(i, enable)
                elif len(selections) == 0:
                    self.handle_type(cb.currentIndex())
                else:
                    pass

        elif self.surface:
            #  (would be nicer if this were in iss.py)
            # IS regions can be planes or volumes (not points or STLs)
            # *-Axis permeable/semipermeable not available for planes
            disable = selections and any('plane' in tw.item(x, 1).text()
                                         for x in selections)
            for index in (X_SEMIPERMEABLE, Y_SEMIPERMEABLE, Z_SEMIPERMEABLE,
                          X_IMPERMEABLE, Y_IMPERMEABLE, Z_IMPERMEABLE):
                item = get_combobox_item(cb, index)
                set_item_enabled(item, (not selections) or (not disable))
            for index in (SEMIPERMEABLE, IMPERMEABLE):
                item = get_combobox_item(cb, index)
                set_item_enabled(item, (not selections) or disable)

            # Available selections:
            #  Impermeable
            #    Selection only available for plane regions
            #  X-Axis Impermeable
            #    Selection only available for volume regions
            #  Y-Axis Impermeable
            #    Selection only available for volume regions
            #  z-Axis Impermeable
            #    Selection only available for volume regions

            #  Semi-permeable
            #    Selection only available for plane regions
            #  X-Axis semi-permeable
            #    Selection only available for volume regions
            #  Y-Axis semi-permeable
            #    Selection only available for volume regions
            #  Z-Axis semi-permeable
            #    Selection only available for volume regions
            # DEFAULT - Impermeable

            if len(selections) == 1:
                region_type = tw.item(selections[0], 1).text()
                plane = 'plane' in region_type
                for i in range(0, tw.rowCount()):
                    if i == selections[0]:
                        continue
                    text = tw.item(i, 1).text()
                    enable = (('plane' in text or text == 'box')
                              or (plane == ('plane' in tw.item(i, 1).text())))
                    self.enable_row(i, enable)
            elif len(selections) == 0:
                self.handle_type(self.ui.combobox.currentIndex())

        elif self.monitor:
            if len(selections) == 1:
                region_type = tw.item(selections[0], 1).text()
                for monitor_type in MONITOR_TYPES:
                    point = monitor_type in MONITOR_TYPES_POINT
                    plane = monitor_type in MONITOR_TYPES_PLANE
                    volume = monitor_type in MONITOR_TYPES_VOLUME
                    enable = (point and region_type == 'point'
                              or plane and 'plane' in region_type
                              or volume and region_type == 'box')

                    item = get_combobox_item(cb, monitor_type)
                    set_item_enabled(item, enable)

            elif len(selections) == 0:
                for monitor_type in MONITOR_TYPES:
                    item = get_combobox_item(cb, monitor_type)
                    set_item_enabled(item, True)
                self.handle_type(self.ui.combobox.currentIndex())
예제 #16
0
    def popup(self, label_text):
        # Widget is shared by ICs/BCs/PSs/ISs/VTK output
        # NB, we distinguish the caller based on the label text
        ui = self.ui
        ui.label_top.setText(label_text)

        buttonbox = self.ui.buttonbox
        buttonbox.button(buttonbox.Ok).setEnabled(False)

        self.boundary = boundary = ('boundary condition' in label_text)
        self.surface = surface = ('internal surface' in label_text)
        self.vtk = vtk = ('VTK output' in label_text)
        self.monitor = monitor = ('monitor' in label_text)

        tw = ui.table
        if (monitor or vtk
            ):  # Output filenames will collide if we allow multiple regions
            tw.setSelectionMode(QAbstractItemView.SingleSelection)
            self.setWindowTitle("Select region")
        else:
            tw.setSelectionMode(QAbstractItemView.MultiSelection)
            self.setWindowTitle("Select regions")

        # setup the combobox appropriately
        cb = ui.combobox
        label = ui.label_type
        gui = self.parent
        show_type = False
        if boundary or surface:
            label.setText('Boundary type' if boundary else 'Surface type')
            cb.clear()
            cb.addItems(BC_NAMES if boundary else IS_NAMES)
            if boundary:
                for i in range(len(cb)):
                    gui.add_tooltip(get_combobox_item(cb, i),
                                    key='bc_type',
                                    value=BC_TYPES[i])
                gui.add_tooltip(
                    get_combobox_item(cb, BC_TYPES.index('CYCLIC')),
                    key=None,
                    description=
                    'Cyclic boundary condition in specified direction')
            if surface:
                for i in range(len(cb)):
                    gui.add_tooltip(get_combobox_item(cb, i),
                                    key='is_type',
                                    value=IS_TYPES[i])

            index = BC_TYPES.index(
                DEFAULT_BC_TYPE) if boundary else IS_TYPES.index(
                    DEFAULT_IS_TYPE)
            cb.setCurrentIndex(index)
            self.handle_type(index)
            show_type = True
        elif vtk:
            label.setText('Output type')
            cb.clear()
            cb.addItems(['Cell data', 'Particle data'])
            # slight hack to set tooltips
            get_combobox_item(cb, 0).setToolTip('Cell data (VTU file)')
            get_combobox_item(cb, 1).setToolTip('Particle data (VTP file)')
            show_type = True
        elif monitor:
            label.setText('Monitor type')
            cb.clear()
            cb.addItems(MONITOR_TYPE_NAMES)
            for i in range(len(cb)):
                gui.add_tooltip(get_combobox_item(cb, i),
                                key='monitor_type',
                                value=i)
            ui.frame_object_type.show()
            show_type = True

        if show_type:
            ui.frame_object_type.show()
            set_combobox_tooltip(cb)
            nrows = 2
        else:
            ui.frame_object_type.hide()
            nrows = 1

        self.show()
        self.raise_()
        self.activateWindow()
        # Table fixup

        resize = tw.horizontalHeader().setSectionResizeMode
        ncols = tw.columnCount()
        stretch_column = 0
        for col_index in range(0, ncols):
            if col_index == stretch_column:
                resize(col_index, QHeaderView.Stretch)
            else:
                resize(col_index, QHeaderView.ResizeToContents)

        table_height = 4 + tw.horizontalHeader().height() + (tw.rowHeight(0) *
                                                             tw.rowCount())

        min_table_height = 150
        tw.setMinimumHeight(min(min_table_height, table_height))
        tw.setMaximumHeight(table_height)

        width = (tw.horizontalHeader().width() +
                 tw.verticalScrollBar().isVisible() *
                 (4 + tw.verticalScrollBar().width()))
        self.setMaximumWidth(max(width, ui.label_top.size().width()))
        #self.setMinimumWidth(width)

        # Height of all stuff other than the main table - try to prevent scrollbars
        margins = 10
        line_spacing = 6
        stuff_height = (nrows + 1) * self.combobox.size().height(
        ) + margins + (nrows + 2) * line_spacing

        height = (table_height + stuff_height)

        self.setMinimumHeight(min(min_table_height + stuff_height, height))
        self.setMaximumHeight(height)
예제 #17
0
    def numerics_setup_discretization_tab(self):
        """Discretization (tab)"""
        ui = self.ui.numerics
        #Select temporal discretization scheme
        #    Selection always available
        #    Available selections:
        #  Implicit Euler [DEFAULT]
        #    Sets keyword CN_ON to .FALSE.
        #  Crank-Nicolson
        #    Sets keyword CN_ON to .TRUE.
        cb = ui.combobox_cn_on
        idx = 1 if self.project.get_value('cn_on') else 0
        cb.setCurrentIndex(idx)
        cb.setToolTip(get_combobox_item(cb, idx).toolTip())

        tw = ui.tablewidget_discretization
        self.fixup_numerics_table(tw)

        #  Available selections
        #    First-order upwind [DEFAULT for all equations]
        # Sets keyword DISCRETIZE(#) to 0
        #    First-order upwind (dwf)
        # Sets keyword DISCRETIZE(#) to 1
        #    Superbee
        # Sets keyword DISCRETIZE(#) to 2
        #    SMART
        # Sets keyword DISCRETIZE(#) to 3
        #    ULTRA-QUICK
        # Sets keyword DISCRETIZE(#) to 4
        #    QUICKEST
        # Sets keyword DISCRETIZE(#) to 5
        #    MUSCL
        # Sets keyword DISCRETIZE(#) to 6
        #    van Leer
        # Sets keyword DISCRETIZE(#) to 7
        #    minmod
        # Sets keyword DISCRETIZE(#) to 8
        #    Central
        # Sets keyword DISCRETIZE(#) to 9
        # see "make_combobox"

        #    Column 3: Specify under relaxation factors
        #  Specification always available
        #  Sets keyword UR_FAC for each equation #
        #  DEFAULTS are equation type specific
        defaults = [
            None,  #    0 - unused
            0.8,  #    1 - gas pressure: 0.8
            0.5,  #    2 - volume fraction: 0.5
            0.5,  #    3 - u-momentum: 0.5
            0.5,  #    4 - v-momentum: 0.5
            0.5,  #    5 - w-momentum: 0.5
            1.0,  #    6 - energy: 1.0
            1.0,  #    7 - species: 1.0
            0.5,  #    8 - granular energy: 0.5
            0.8,  #    9 - user-scalar/k-epsilon: 0.8
            1.0
        ]  #    10 - DES diffusion: 1.0

        for i in range(1, 1 + DIM_EQS):
            row = i - 1
            key = 'discretize'
            default = 0
            cb = tw.cellWidget(row, COL_SCHEME)
            val = self.project.get_value(key, args=[i])
            if val is None:
                val = default
                #self.update_keyword(key, val, args=[i]) #?
            cb.setCurrentIndex(val)

            key = 'ur_fac'
            le = tw.cellWidget(row, COL_RELAX)
            val = self.project.get_value(key, args=[i])
            if val is None:
                val = defaults[i]
                #self.update_keyword(key, val, args=[i]) #?
            le.updateValue(
                key, val)  # initialize lineedit, since it's not registered

        #Enable deferred correction
        #    Selection only available if minval(discretize) > 0
        #    Sets keyword DEF_COR
        #    DEFAULT value .FALSE.
        key = 'discretize'
        enabled = min(
            self.project.get_value(key, args=[i], default=0)
            for i in range(1, 1 + DIM_EQS)) > 0
        key = 'def_cor'
        cb = ui.checkbox_keyword_def_cor
        cb.setEnabled(enabled)
        self.add_tooltip(cb, key)
        if not enabled:
            cb.setToolTip(cb.toolTip() +
                          " Disabled for first-order upwinding.")
            cb.setChecked(False)
            self.unset_keyword(key)

        #Enable chi-scheme correction
        #    Selection only available if the species equation spatial discretization is SMART or
        #MUSCL (DISCRETIZE(7) = 3 or 6)
        #    Sets keyword CHI_SCHEME
        #    DEFAULT value .FALSE.
        enabled = self.project.get_value('discretize', args=[7]) in (3, 6)
        key = 'chi_scheme'
        cb = ui.checkbox_keyword_chi_scheme
        cb.setEnabled(enabled)
        if not enabled:
            cb.setChecked(False)
            self.unset_keyword(key)
예제 #18
0
    def __init__(self, app, parent=None, phases='GLCS'):
        super(SpeciesPopup, self).__init__(parent)
        self.app = app
        self.phases = phases
        self.include_comments = False
        self.default_phase = phases[0] if phases else ''
        self.density_enabled = True
        datadir = os.path.abspath(os.path.dirname(__file__))
        self.load_burcat(os.path.join(datadir, 'burcat.pickle'))
        ui = self.ui = get_ui('species_popup.ui', self)

        # key=species, val=data tuple.  can add phase to key if needed
        self.defined_species = OrderedDict()
        self.extra_aliases = set()  # To support enforcing uniqueness
        self.mfix_keywords = set(k.lower()
                                 for k in self.parent().keyword_doc.keys())
        self.mfix_fortran_globals = set()  # TODO: implement this
        # uniqueness of aliases across all phases

        self.search_results = []
        self.user_species_names = set()

        # Set up UI
        ui.lineedit_search.textChanged.connect(self.do_search)
        ui.pushbutton_import.clicked.connect(self.do_import)
        ui.pushbutton_import.setEnabled(False)
        ui.tablewidget_search.itemSelectionChanged.connect(
            self.handle_search_selection)
        ui.tablewidget_defined_species.itemSelectionChanged.connect(
            self.handle_defined_species_selection)

        ui.pushbutton_new.clicked.connect(self.handle_new)
        ui.pushbutton_copy.clicked.connect(self.handle_copy)
        ui.checkbox_include_comments.clicked.connect(
            self.handle_include_comments)

        for phase in 'GLSC':
            button = getattr(self.ui, 'pushbutton_%s' % phase)
            button.clicked.connect(self.handle_phase)

        cb = ui.combobox_phase
        cb.currentIndexChanged.connect(self.handle_combobox_phase)
        for i, t in enumerate(phase_names):
            get_combobox_item(cb, i).setToolTip(t)

        #http://stackoverflow.com/questions/15845487/how-do-i-prevent-the-enter-key-from-closing-my-qdialog-qt-4-8-1
        # Do not use buttonbox.  https://mfix.netl.doe.gov/gitlab/develop/mfix/issues/101
        buttons = (ui.pushbutton_ok, ui.pushbutton_cancel)
        buttons[0].clicked.connect(lambda: (self.save.emit(), self.close()))
        buttons[1].clicked.connect(lambda: (self.cancel.emit(), self.close()))

        class AliasValidator(QValidator):

            # Make sure aliases are unique
            def __init__(self, parent=None):
                super(AliasValidator, self).__init__()
                self.parent = parent

            def validate(self, text, pos):
                if text == "":
                    self.parent.set_ok_button(False)
                    return (QValidator.Intermediate, text, pos)
                dig_start = text[0].isdigit()
                und_start = text[0] == '_'
                not_alphanum_und = not all(c.isalnum() or c == '_'
                                           for c in text)
                if dig_start or und_start or not_alphanum_und:
                    return (QValidator.Invalid, text, pos)
                current_species = self.parent.current_species
                if current_species not in self.parent.defined_species:  # Why would this happen?
                    self.parent.set_ok_button(False)
                    return (QValidator.Invalid, text, pos)
                current_alias = self.parent.defined_species[
                    current_species].get('alias')
                if current_alias is None:
                    self.parent.set_ok_button(False)
                    return (QValidator.Invalid, text, pos)
                for v in self.parent.defined_species.values():
                    v_alias = v.get('alias', '')
                    if v_alias.lower() == current_alias.lower(
                    ):  # Skip selected item
                        continue
                    if v_alias.lower() == text.lower():
                        self.parent.set_ok_button(False,
                                                  'Alias must be unique')
                        return (QValidator.Intermediate, text, pos)
                tlower = text.lower()
                if tlower in self.parent.extra_aliases:
                    self.parent.set_ok_button(False, 'Alias must be unique')
                    return (QValidator.Intermediate, text, pos)
                if tlower in self.parent.mfix_keywords:
                    self.parent.set_ok_button(False,
                                              '%s is an MFiX keyword' % text)
                    return (QValidator.Intermediate, text, pos)
                self.parent.set_ok_button(True)
                return (QValidator.Acceptable, text, pos)

        lineedit = ui.lineedit_alias
        lineedit.setValidator(AliasValidator(parent=self))
        lineedit.editingFinished.connect(self.handle_alias)

        for line_edit in (ui.lineedit_mol_weight, ui.lineedit_h_f,
                          ui.lineedit_density):
            line_edit.setValidator(QDoubleValidator())

        self.species_panel_items = [
            ui.label_species, ui.lineedit_alias, ui.lineedit_mol_weight,
            ui.lineedit_h_f, ui.lineedit_density, ui.tablewidget_params
        ]

        hv = QHeaderView
        for tw in (self.tablewidget_search, self.tablewidget_defined_species):
            resize_column(tw, 0, hv.Stretch)
            resize_column(tw, 1, hv.ResizeToContents)
        tw = self.tablewidget_params
        for i in (0, 1):
            resize_column(tw, i, hv.Stretch)

        self.set_ok_button(False)  # nothing to accept
        self.clear_species_panel()
예제 #19
0
    def setup_pic_tab(self):
        # Note - we are doing this setup on first show of this tab, rather
        # than at init or project load time
        ui = self.ui.solids

        #Specify void fraction at close pack (required)
        # Sets keyword EP_STAR [0.42]
        #Define parcel CFL number
        # Sets keyword CFL_PIC
        # DEFAULT 0.1
        for (key, default) in [('ep_star', 0.42), ('cfl_pic', 0.1)]:
            val = self.project.get_value(key)
            if val is None:
                self.update_keyword(key, default)

        #Select solid stress model
        # Selection always available
        # Available selection
        # Snider, 2001 [DEFAULT]
        # Selection always available
        # Sets keyword MPPIC_SOLID_STRESS_SNIDER=.T.
        self.update_keyword('mppic_solid_stress_snider', True)
        # TODO FIXME does this ever get cleared?

        #Option to enable implicit treatment of drag force
        # Sets keyword: MPPIC_PDRAG_IMPLICIT
        # Disabled [DEFAULT]
        pass

        #Define particle-particle momentum retention
        # Sets keyword MPPIC_COEFF_EN1
        # DEFAULT 0.4
        #Define wall normal momentum retention
        # Sets keyword MPPIC_COEFF_EN_WALL
        # DEFAULT 0.3
        #Define wall tangential momentum retention
        # Sets keyword MPPIC_COEFF_ET_WALL
        # DEFAULT 0.99
        for (key, default) in [('mppic_coeff_en1', 0.4),
                               ('mppic_coeff_en_wall', 0.3),
                               ('mppic_coeff_et_wall', 0.99)]:
            val = self.project.get_value(key)
            if val is None:
                self.update_keyword(key, default)

        #Select gas-solids coupling scheme:
        # Selection unavailable if fluid model is disabled
        # Available selections:
        # One-way Coupled
        # Selection always available
        # Sets keyword DES_ONEWAY_COUPLED true
        # Fully Coupled
        # Selection always available
        # Sets keyword DES_ONEWAY_COUPLED false
        enabled = not self.fluid_solver_disabled
        for item in (ui.label_coupling_method_2,
                     ui.combobox_coupling_method_2):
            item.setEnabled(enabled)
        des_oneway_coupled = self.project.get_value('des_oneway_coupled',
                                                    default=False)
        if des_oneway_coupled not in (True, False):
            self.warn("Invalid des_oneway_coupled %s" % des_oneway_coupled)
            des_oneway_coupled = False
            self.update_keyword('des_oneway_coupled', des_oneway_coupled)
        ui.combobox_coupling_method_2.setCurrentIndex(
            0 if des_oneway_coupled else 1)

        #Select interpolation framework:
        # Selection always available
        # Available selections:
        # field-to-particle and particle-to-field [DEFAULT]
        # Sets keyword DES_INTERP_ON to true
        # Sets keyword DES_INTERP_MEAN_FIELDS to true
        # field-to-particle only
        # Sets keyword DES_INTERP_ON to true
        # Sets keyword DES_INTERP_MEAN_FIELDS to false
        # particle-to-field only
        # Sets keyword DES_INTERP_ON to false
        # Sets keyword DES_INTERP_MEAN_FIELDS to true
        # no-interpolation
        # Sets keyword DES_INTERP_ON to false
        # Sets keyword DES_INTERP_MEAN_FIELDS to false
        des_interp_on = self.project.get_value('des_interp_on', default=True)
        if des_interp_on not in (True, False):
            self.warn("Invalid des_interp_on %s" % des_interp_on)
            des_interp_on = True
            self.update_keyword('des_interp_on', des_interp_on)

        des_interp_mean_fields = self.project.get_value(
            'des_interp_mean_fields', default=True)
        if des_interp_mean_fields not in (True, False):
            self.warn("Invalid des_interp_mean_fields %s" %
                      des_interp_mean_fields)
            des_interp_mean_fields = True
            self.update_keyword('des_interp_mean_fields',
                                des_interp_mean_fields)

        index = 2 * (1 - des_interp_on) + (1 - des_interp_mean_fields)
        ui.combobox_des_interp_2.setCurrentIndex(index)

        #Select interpolation scheme:
        # Selection available except when no-interpolation framework is selected
        # Available selections:
        # None [locked default for no-interpolation framework]
        # Selection not available
        # Sets keyword DES_INTERP_SCHEME='NONE' # Todo, update SRS
        # Garg 2012
        # Selection not available with explicit coupling enabled
        # Sets keyword DES_INTERP_SCHEME='GARG_2012'
        # Square DPVM
        # Selection always available
        # Requires an interpolation width, DES_INTERP_WIDTH
        # Sets keyword DES_INTERP_SCHEME='SQUARE_DPVM'
        #
        cb = ui.combobox_des_interp_scheme_2
        label = ui.label_des_interp_scheme_2
        des_interp_scheme = self.project.get_value('des_interp_scheme')
        des_explicitly_coupled = self.project.get_value(
            'des_explicitly_coupled')
        interp_enabled = des_interp_on or des_interp_mean_fields  # not no-interp
        for item in (cb, label):
            item.setEnabled(interp_enabled)
        if not interp_enabled:
            cb.setCurrentIndex(NONE)
            des_interp_scheme = 'NONE'
        else:
            if des_interp_scheme not in des_interp_schemes:
                self.warning("invalid des_interp_scheme %s" %
                             des_interp_scheme)
                des_interp_scheme = 'SQUARE_DPVM'
            idx = des_interp_schemes.index(des_interp_scheme)
            cb.setCurrentIndex(idx)

        # per-item enable flags
        enabled = (not interp_enabled, not des_explicitly_coupled, True)
        for (i, e) in enumerate(enabled):
            set_item_enabled(get_combobox_item(cb, i), e)
        # Make sure we don't leave the combobox on an invalid item!
        if not enabled[cb.currentIndex()]:
            idx = enabled.index(True)  # 2 is always True so this is safe
            cb.setCurrentIndex(idx)
            des_interp_scheme = des_interp_schemes[idx]
        # Value of des_interp_scheme may have changed
        self.update_keyword('des_interp_scheme', des_interp_scheme)

        #Define interpolation width (DPVM only) (required)
        # Specification only available with SQUARE_DPVM interpolation scheme
        # Sets keyword DES_INTERP_WIDTH
        # TODO default?
        key = 'des_interp_width'
        enabled = interp_enabled and (des_interp_scheme == 'SQUARE_DPVM')  #?
        for item in (ui.label_des_interp_width_2,
                     ui.lineedit_keyword_des_interp_width_2,
                     ui.label_des_interp_width_2_units):
            item.setEnabled(enabled)
        if des_interp_scheme != 'SQUARE_DPVM':
            self.unset_keyword(key)
        else:
            self.update_keyword('des_interp_width',
                                ui.lineedit_keyword_des_interp_width_2.value)

        #Define solids stress model parameter: pressure constant
        # Sets keyword PSFAC_FRIC_PIC
        # DEFAULT 10.0
        #Define solids stress model parameter: volume fraction exponent
        # Sets keyword FRIC_EXP_PIC
        # DEFAULT 3.0
        #Define solids stress model parameter: non-singularity factor
        # Sets keyword FRIC_NON_SING_FAC
        # DEFAULT 1.0E-8
        for (key, default) in [('psfac_fric_pic', 10.0), ('fric_exp_pic', 3.0),
                               ('fric_non_sing_fac', 1.0e-8)]:
            val = self.project.get_value(key)
            if val is None:
                self.update_keyword(key, default)
예제 #20
0
 def set_cn_on(self, val):
     ui = self.ui.numerics
     cb = ui.combobox_cn_on
     key = 'cn_on'
     self.update_keyword(key, bool(val))
     cb.setToolTip(get_combobox_item(cb, int(val)).toolTip())
예제 #21
0
    def setup_dem_tab(self):
        # Ensures all constraints (items enabled/disabled) are set
        # called by each 'set_' function, so don't call those here

        ui = self.ui.solids
        # Inline comments from MFIX-UI_SRS as of 2016-07-01
        #  Please update as needed!

        #MFIX-UI_SRS
        #Enable automatic particle generation
        # Enabled sets keyword GENER_PART_CONFIG to true
        # Disabled enables the user to specify number of entries in particle input file
        # Default value is 0
        default = 0
        # Sets keyword PARTICLES
        gener_part_config = self.project.get_value('gener_part_config')
        particles = self.project.get_value('particles')

        if gener_part_config:
            if particles:  # Should not both be set
                self.warning("gener_part_config set, particles=%s" % particles)
                particles = default
        else:
            if particles is None:  # set to 0 if not set
                particles = default
            elif particles < 0:
                self.warning("Invalid particles %s" % particles)
                particles = default
        self.update_keyword('particles', particles)

        enabled = not gener_part_config
        for item in (ui.label_particles, ui.lineedit_keyword_particles):
            item.setEnabled(enabled)

        #Select numerical integration method
        # Selection always available
        # Available selections
        #Euler [DEFAULT]
        # Selection always available
        # Sets keyword DES_INTG_METHOD to 'EULER'
        #Adams-Bashforth
        # Selection always available
        # Sets keyword DES_INTG_METHOD to 'ADAMS_BASHFORTH'1
        des_intg_method = self.project.get_value('des_intg_method',
                                                 default='EULER')
        if des_intg_method not in des_intg_methods:
            self.warn("Invalid des_intg_method %s" % des_intg_method)
            des_intg_method = 'EULER'
        ui.combobox_des_intg_method.setCurrentIndex(
            des_intg_methods.index(des_intg_method))

        #Selection collision model
        # Selection always available
        # Available selections
        #Linear Spring-Dashpot [DEFAULT]
        # Selection always available
        # Sets keyword DES_COLL_MODEL to 'LSD'
        #Hertzian
        # Selection always available
        # Sets keyword DES_COLL_MODEL to 'HERTZIAN'
        des_coll_model = self.project.get_value('des_coll_model',
                                                default='LSD')
        if des_coll_model not in des_coll_models:
            self.warn("Invalid des_coll_model %s" % des_coll_model)
            des_coll_model = 'LSD'
        ui.combobox_des_coll_model.setCurrentIndex(
            des_coll_models.index(des_coll_model))

        #Select gas-solids coupling scheme:
        # Selection unavailable if fluid model is disabled
        # Available selections:
        # One-way Coupled
        # Selection always available
        # Sets keyword DES_ONEWAY_COUPLED true
        # Fully Coupled
        # Selection always available
        # Sets keyword DES_ONEWAY_COUPLED false
        enabled = not self.fluid_solver_disabled
        for item in (ui.label_coupling_method, ui.combobox_coupling_method):
            item.setEnabled(enabled)
        des_oneway_coupled = self.project.get_value('des_oneway_coupled',
                                                    default=False)
        if des_oneway_coupled not in (True, False):
            self.warn("Invalid des_oneway_coupled %s" % des_oneway_coupled)
            des_oneway_coupled = False
            self.update_keyword('des_oneway_coupled', des_oneway_coupled)
        ui.combobox_coupling_method.setCurrentIndex(
            0 if des_oneway_coupled else 1)

        #Optional to enable explicitly coupled simulation
        # Unavailable for GARG_2012 interpolation
        des_interp_scheme = self.project.get_value('des_interp_scheme')
        enabled = (des_interp_scheme != 'GARG_2012')
        ui.checkbox_keyword_des_explicitly_coupled.setEnabled(enabled)

        #Select interpolation framework:
        # Selection always available
        # Available selections:
        # Field-to-Particle and Particle-to-Field [DEFAULT]
        #  Sets keyword DES_INTERP_ON to true
        #  Sets keyword DES_INTERP_MEAN_FIELDS to true
        # Field-to-Particle only
        #  Sets keyword DES_INTERP_ON to true
        #  Sets keyword DES_INTERP_MEAN_FIELDS to false
        # Particle-to-Field only
        #  Sets keyword DES_INTERP_ON to false
        #  Sets keyword DES_INTERP_MEAN_FIELDS to true
        # No Interpolation
        #  Sets keyword DES_INTERP_ON to false
        #  Sets keyword DES_INTERP_MEAN_FIELDS to false
        #
        # issues/116 must also set DES_INTERP_SCHEME to None when no-interpolation
        des_interp_on = self.project.get_value('des_interp_on', default=True)
        if des_interp_on not in (True, False):
            self.warn("Invalid des_interp_on %s" % des_interp_on)
            des_interp_on = True
            self.update_keyword('des_interp_on', des_interp_on)

        des_interp_mean_fields = self.project.get_value(
            'des_interp_mean_fields', default=True)
        if des_interp_mean_fields not in (True, False):
            self.warn("Invalid des_interp_mean_fields %s" %
                      des_interp_mean_fields)
            des_interp_mean_fields = True
            self.update_keyword('des_interp_mean_fields',
                                des_interp_mean_fields)

        index = 2 * (1 - des_interp_on) + (1 - des_interp_mean_fields)
        ui.combobox_des_interp.setCurrentIndex(index)

        #Select interpolation scheme:
        # Selection available except when no-interpolation framework is selected
        # Available selections:
        #  None [locked default for no-interpolation framework]
        #  Selection always available
        #  Sets keyword DES_INTERP_SCHEME='NONE'
        # Garg 2012
        #  Selection not available with explicit coupling enabled
        #  Sets keyword DES_INTERP_SCHEME='GARG_2012'
        # Square DPVM
        #  Selection always available
        #  Requires an interpolation width, DES_INTERP_WIDTH
        #  Sets keyword DES_INTERP_SCHEME='SQUARE_DPVM'
        #
        cb = ui.combobox_des_interp_scheme
        label = ui.label_des_interp_scheme
        des_interp_scheme = self.project.get_value('des_interp_scheme')
        des_explicitly_coupled = self.project.get_value(
            'des_explicitly_coupled')
        interp_enabled = des_interp_on or des_interp_mean_fields  # not no-interp
        for item in (cb, label):
            item.setEnabled(interp_enabled)
        if not interp_enabled:
            cb.setCurrentIndex(NONE)
            des_interp_scheme = 'NONE'
        else:
            if des_interp_scheme not in des_interp_schemes:
                des_interp_scheme = 'NONE'
            cb.setCurrentIndex(des_interp_schemes.index(des_interp_scheme))

        #
        # per-item enable flags
        enabled = (True, True, not des_explicitly_coupled)
        for (i, e) in enumerate(enabled):
            set_item_enabled(get_combobox_item(cb, i), e)
        # Make sure we don't leave the combobox on an invalid item!
        if not enabled[cb.currentIndex()]:
            idx = enabled.index(True)  # 2 is always True so this is safe
            cb.setCurrentIndex(idx)
            des_interp_scheme = des_interp_schemes[idx]
        # Value of des_interp_scheme may have changed
        self.update_keyword('des_interp_scheme', des_interp_scheme)

        #Define interpolation width (DPVM only) (required)
        # Specification only available with SQUARE_DPVM interpolation scheme
        # Sets keyword DES_INTERP_WIDTH
        # TODO default?
        key = 'des_interp_width'
        enabled = interp_enabled and (des_interp_scheme == 'SQUARE_DPVM')  #?
        for item in (ui.label_des_interp_width,
                     ui.lineedit_keyword_des_interp_width,
                     ui.label_des_interp_width_units):
            item.setEnabled(enabled)
        if des_interp_scheme != 'SQUARE_DPVM':
            self.unset_keyword(key)
        else:
            self.update_keyword(key,
                                ui.lineedit_keyword_des_interp_width.value)

        #Option to enable diffusion of particle data
        # Selection unavailable with GARG_2012 interpolation scheme
        # No keyword is set by this option
        # Enables the user to specify a diffusion width
        # Sets keyword DES_DIFFUSE_WIDTH
        key = 'des_diffuse_width'
        enabled = (des_interp_scheme != 'GARG_2012')
        ui.checkbox_enable_des_diffuse_width.setEnabled(enabled)
        if not enabled:
            ui.checkbox_enable_des_diffuse_width.setChecked(False)
            self.unset_keyword(key)
            ui.lineedit_keyword_des_diffuse_width.clear()  # ??? FIXME
        enabled = ui.checkbox_enable_des_diffuse_width.isChecked()
        for item in (ui.label_des_diffuse_width,
                     ui.lineedit_keyword_des_diffuse_width,
                     ui.label_des_diffuse_width_units):
            item.setEnabled(enabled)
            if enabled:
                self.update_keyword(
                    key, ui.lineedit_keyword_des_diffuse_width.value)

        #Specify friction coefficient
        # Specification always required
        # Sets keyword MEW (MEW_W)
        pass

        #Specify normal spring constant
        # Only available for LSD collision model
        # Sets keyword KN (KN_W)
        #Specify tangential spring constant factor
        # Only available for LSD collision model
        # Sets keyword KT_FAC (KT_W_FAC)
        # Default values of 2.0/7.0
        #Specify tangential damping coefficient factor
        # Only available for LSD collision model
        # Sets keyword DES_ETAT_FAC (DES_ETAT_W_FAC)
        # Default values of 0.5
        enabled = (des_coll_model == 'LSD')
        for item in (ui.label_kn, ui.lineedit_keyword_kn,
                     ui.lineedit_keyword_kn_w, ui.label_kn_units,
                     ui.label_kt_fac, ui.lineedit_keyword_kt_fac,
                     ui.lineedit_keyword_kt_w_fac, ui.label_des_etat_fac,
                     ui.lineedit_keyword_des_etat_fac,
                     ui.lineedit_keyword_des_etat_w_fac):
            item.setEnabled(enabled)

        if enabled:  # TODO set these defaults at load-time, not when this tab is shown
            for (key, default) in [('kt_fac', Equation('2/7')),
                                   ('kt_w_fac', Equation('2/7')),
                                   ('des_etat_fac', 0.5),
                                   ('des_etat_w_fac', 0.5)]:
                if self.project.get_value(key) is None:
                    self.update_keyword(key, default)

        # Unset keywords if not enabled?
        #Specify Young's modulus
        # Only available for Hertzian collision model
        # Sets keyword E_YOUNG (EW_YOUNG)

        layout = ui.gridlayout_dem_parameters
        enabled = (des_coll_model == 'HERTZIAN')
        for item in (ui.label_e_young, ui.lineedit_keyword_ew_young,
                     ui.label_e_young_units, ui.label_v_poisson,
                     ui.lineedit_keyword_vw_poisson):
            item.setEnabled(enabled)

        key = 'e_young'
        solids_names = list(self.solids.keys())
        if self.solids_dem_saved_solids_names != solids_names:

            # We put these back after inserting rows
            for item in (ui.label_v_poisson, ui.lineedit_keyword_vw_poisson):
                item.hide()
                layout.removeWidget(item)

            # Delete all the old ones...
            for idx in range(layout.count() - 1, -1, -1):
                item = layout.itemAt(idx)
                w = item.widget()
                if not w:
                    continue
                name = w.objectName()
                if '_args_' in name:
                    w.hide()
                    if isinstance(w, LineEdit):
                        self.project.unregister_widget(w)
                    layout.removeWidget(w)
                    w.setParent(None)
                    w.deleteLater()

            # ...and make new ones
            idx = layout.indexOf(ui.lineedit_keyword_ew_young)
            columns = 4
            row = 1 + int(idx / columns)
            for (p, name) in enumerate(self.solids.keys(), 1):
                row += 1
                label = QLabel('    ' + name)
                label.setObjectName('label_%s_args_%s' % (key, p))
                # FIXME use dynamic_widgets instead of setattr
                setattr(ui, label.objectName(), label)
                label.args = [p]
                self.add_tooltip(label, key)
                layout.addWidget(label, row, 0, 1, 1)
                label.setEnabled(enabled)

                le = LineEdit()
                le.setMaximumWidth(150)  # matches ui file
                le.key = key
                le.args = [p]
                le.dtype = float
                le.setValInfo(min=0.0)
                le.setObjectName('lineedit_keyword_%s_args_%s' % (key, p))
                setattr(ui, le.objectName(), le)
                self.add_tooltip(le, key)
                layout.addWidget(le, row, 1, 1, 1)
                le.setEnabled(enabled)
                val = self.project.get_value(key, args=[p])
                if val is not None:
                    le.updateValue(key, val)
                self.project.register_widget(le, keys=[key], args=[p])

                label = QLabel('Pa')
                label.setObjectName('label_%s_units_args_%s' % (key, p))
                layout.addWidget(label, row, 3, 1, 1)
                label.setEnabled(enabled)

            #Specify Poisson ratio:
            # Only available for Hertzian collision model
            # Sets keyword V_POISSON (VW_POISSON)
            row += 1
            layout.addWidget(ui.label_v_poisson, row, 0, 1, 1)
            layout.addWidget(ui.lineedit_keyword_vw_poisson, row, 2, 1, 1)
            for item in (ui.label_v_poisson, ui.lineedit_keyword_vw_poisson):
                item.show()
                item.setEnabled(enabled)

            row += 1
            key = 'v_poisson'

            for (p, name) in enumerate(self.solids.keys(), 1):
                row += 1
                label = QLabel('    ' + name)
                label.setObjectName('label_%s_args_%s' % (key, p))
                setattr(ui, label.objectName(), label)
                label.args = [p]
                self.add_tooltip(label, key)
                layout.addWidget(label, row, 0, 1, 1)
                label.setEnabled(enabled)
                le = LineEdit()
                le.setMaximumWidth(150)  #?
                le.key = key
                le.args = [p]
                le.dtype = float
                le.setValInfo(min=0.0)
                le.setObjectName('lineedit_keyword_%s_args_%s' % (key, p))
                setattr(ui, le.objectName(), le)
                self.add_tooltip(le, key)
                layout.addWidget(le, row, 1, 1, 1)
                le.setEnabled(enabled)
                val = self.project.get_value(key, args=[p])
                if val is not None:
                    le.updateValue(key, val)
                self.project.register_widget(le, keys=[key], args=[p])

        # Use dynamic_widgets here instead of setattr/getattr
        for key in 'e_young', 'v_poisson':
            for p in range(1, 1 + len(self.solids.keys())):
                for pat in 'label_%s_args_%s', 'lineedit_keyword_%s_args_%s':
                    w = getattr(ui, pat % (key, p), None)
                    if w:
                        w.setEnabled(enabled)

        #Specify normal restitution coefficient
        # Specification always required
        # Sets keyword DES_EN_INPUT (DES_EN_WALL_INPUT)
        # Input given as an upper triangular matrix
        mmax = self.project.get_value('mmax', default=len(self.solids))
        tw = ui.tablewidget_des_en_input

        def make_item(str):
            item = QTableWidgetItem(str)
            set_item_noedit(item)
            set_item_enabled(item, False)
            return item

        if (self.solids_dem_saved_solids_names != solids_names
                or tw.rowCount() != mmax + 1 or tw.columnCount() != mmax):

            # Clear out old lineedit widgets
            for row in range(tw.rowCount()):
                for col in range(tw.columnCount()):
                    w = tw.cellWidget(row, col)
                    if w:
                        self.project.unregister_widget(w)
                        w.deleteLater()
            tw.clearContents()

            # Make a new batch
            tw.setRowCount(mmax + 1)  # extra row for "Wall"
            tw.setColumnCount(mmax)
            tw.setHorizontalHeaderLabels(solids_names)
            tw.setVerticalHeaderLabels(solids_names + ['Wall'])

            arg = 1  # One-based
            key = 'des_en_input'
            for row in range(mmax):
                for col in range(mmax):
                    if col < row:
                        tw.setItem(row, col, make_item('--'))
                    else:
                        le = LineEdit()
                        le.setMaximumWidth(150)
                        le.key = key
                        le.args = [arg]
                        le.setdtype('dp')
                        self.add_tooltip(le, key)
                        tw.setCellWidget(row, col, le)
                        val = self.project.get_value(key, args=[arg])
                        if val is not None:
                            le.updateValue(key, val)
                        self.project.register_widget(le,
                                                     keys=[key],
                                                     args=[arg])
                        arg += 1
            arg = 1
            key = 'des_en_wall_input'
            row = mmax
            for col in range(mmax):
                le = LineEdit()
                le.setMaximumWidth(150)
                le.key = key
                le.args = [arg]
                le.setdtype('dp')
                self.add_tooltip(le, key)
                tw.setCellWidget(row, col, le)
                val = self.project.get_value(key, args=[arg])
                if val is not None:
                    le.updateValue(key, val)
                self.project.register_widget(le, keys=[key], args=[arg])
                arg += 1

        self.fixup_solids_table(tw, stretch_column=mmax - 1)
        # This makes the table look a little nicer
        tw.setShowGrid(False)
        # Move column headers to left so they line up with lineedits
        for i in range(tw.columnCount()):
            item = tw.horizontalHeaderItem(i)
            if item:
                item.setTextAlignment(Qt.AlignLeft)

        #Specify tangential restitution coefficient
        # Specification available for Hertzian collision model
        # Sets keyword DES_ET_INPUT (DES_ET_WALL_INPUT)
        # Input given as an upper triangular matrix
        enabled = (des_coll_model == 'HERTZIAN')
        ui.label_des_et_input.setEnabled(enabled)
        tw = ui.tablewidget_des_et_input
        # note - this is too much of a duplicate of des_en_input above
        if not enabled:
            # Clear out old lineedit widgets
            for row in range(tw.rowCount()):
                for col in range(tw.columnCount()):
                    w = tw.cellWidget(row, col)
                    if w:
                        self.project.unregister_widget(w)
                        w.deleteLater()
            tw.clearContents()
            tw.setRowCount(0)
            tw.setColumnCount(0)

        if enabled:
            if (self.solids_dem_saved_solids_names != solids_names
                    or tw.rowCount() != mmax + 1 or tw.columnCount() != mmax):

                # Clear out old lineedit widgets
                for row in range(tw.rowCount()):
                    for col in range(tw.columnCount()):
                        w = tw.cellWidget(row, col)
                        if w:
                            self.project.unregister_widget(w)
                            w.deleteLater()
                tw.clearContents()
                # Make a new batch
                tw.setRowCount(mmax + 1)  # extra row for "Wall"
                tw.setColumnCount(mmax)
                tw.setHorizontalHeaderLabels(solids_names)
                tw.setVerticalHeaderLabels(solids_names + ['Wall'])

                arg = 1
                key = 'des_et_input'
                for row in range(mmax):
                    for col in range(mmax):
                        if col < row:
                            tw.setItem(row, col, make_item('--'))
                        else:
                            le = LineEdit()
                            le.setMaximumWidth(150)
                            le.key = key
                            le.args = [arg]
                            le.setdtype('dp')
                            self.add_tooltip(le, key)
                            tw.setCellWidget(row, col, le)
                            val = self.project.get_value(key, args=[arg])
                            if val is not None:
                                le.updateValue(key, val)
                            self.project.register_widget(le,
                                                         keys=[key],
                                                         args=[arg])
                            arg += 1
                key = 'des_et_wall_input'
                row = mmax
                arg = 1
                for col in range(mmax):
                    le = LineEdit()
                    le.setMaximumWidth(150)
                    le.key = key
                    le.args = [arg]
                    le.setdtype('dp')
                    tw.setCellWidget(row, col, le)
                    val = self.project.get_value(key, args=[arg])
                    if val is not None:
                        le.updateValue(key, val)
                    self.project.register_widget(le, keys=[key], args=[arg])
                    arg += 1
        self.fixup_solids_table(tw, stretch_column=mmax - 1)
        # This makes the table look a little nicer
        tw.setShowGrid(False)
        # Move column headers to left so they line up with lineedits
        for i in range(tw.columnCount()):
            item = tw.horizontalHeaderItem(i)
            if item:
                item.setTextAlignment(Qt.AlignLeft)

        #Select cohesion model
        # Selection always available
        # Available selections
        #None [DEFAULT]
        #Selection always available
        #Sets keyword USE_COHESION to false
        #Sets keyword VAN_DER_WAALS to false
        #Van der Waals
        #Selection always available
        #Sets keyword USE_COHESION to true
        #Sets keyword VAN_DER_WAALS to true
        use_cohesion = self.project.get_value('use_cohesion')
        van_der_waals = self.project.get_value('van_der_waals')
        cb = ui.combobox_cohesion_model
        if use_cohesion:
            if not van_der_waals:
                self.warn('inconsistent value for keyword van_der_waals')
                self.unset_keyword('van_der_waals')
            cb.setCurrentIndex(1)
        else:
            if van_der_waals:
                self.warn('inconsistent value for keyword van_der_waals')
                self.update_keyword('van_der_waals', True)
            cb.setCurrentIndex(0)

        #Specify Hamaker constant
        # Specification only available for Van der Waals cohesion model
        # Sets keyword HAMAKER_CONSTANT (WALL_HAMAKER_CONSTANT)
        #Specify outer cutoff
        # Specification only available for Van der Waals cohesion model
        # Sets keyword VDW_OUTER_CUTOFF (WALL_OUTER_CUTOFF)
        #Specify inner cutoff
        # Specification only available for Van der Waals cohesion model
        # Sets keyword VDW_INNER_CUTOFF (WALL_INNER_CUTOFF)
        #Specify asperities
        # Specification only available for Van der Waals cohesion model
        # Sets keyword ASPERITIES
        enabled = bool(van_der_waals)
        ui.groupbox_cohesion_parameters.setEnabled(enabled)
        # (settings handled by keyword widgets.  TODO:
        #  decide if we want to unset keywords if not enabled

        #List the following options under an 'Advanced' section header.
        #Select Neighbor Search Method
        # Selection always available
        # Available selection
        #Grid-based [DEFAULT]
        #Selection always available
        #Sets keyword DES_NEIGHBOR_SEARCH 4
        #N-Square
        #Selection always available
        #Sets keyword DES_NEIGHBOR_SEARCH 1
        des_neighbor_search = self.project.get_value('des_neighbor_search',
                                                     default=4)
        if des_neighbor_search not in (1, 4):
            self.warn("Invalid des_neighbor_search %s" % des_neighbor_search)
            des_neighbor_search = 4
            self.update_keyword('des_neighbor_search', des_neighbor_search)
        cb = ui.combobox_des_neighbor_search
        cb.setCurrentIndex(0 if des_neighbor_search == 4 else 1)

        #Specify maximum steps between neighbor search
        #Specification always available
        # Sets keyword NEIGHBOR_SEARCH_N
        #Specify factor defining particle neighborhood
        #Specification always available
        # Sets keyword FACTOR_RLM
        #Specify neighborhood search radius ratio
        #Specification always available
        #Sets keyword NEIGHBOR_SEARCH_RAD_RATIO
        #Specify search grid partitions (optional)
        #Specification always available
        #Sets keyword DESGRIDSEARCH_IMAX
        #Sets keyword DESGRIDSEARCH_JMAX
        #Sets keyword DESGRIDSEARCH_KMAX
        pass  # handled by keyword widgets

        #Enable user scalar tracking
        #Selection always available
        #Does not directly set any keywords
        #Enables specification of number of user scalars
        # Sets keyword DES_USR_VAR_SIZE
        des_usr_var_size = self.project.get_value('des_usr_var_size',
                                                  default=None)
        enabled = (des_usr_var_size is not None)
        cb = ui.checkbox_enable_des_usr_var_size
        cb.setChecked(enabled)
        ui.lineedit_keyword_des_usr_var_size.setEnabled(enabled)

        #Define minimum distance for contact conduction (optional)
        #Unavailable if not solving energy equations
        #Define fluid lens proportion constant (optional)
        # Unavailable if not solving energy equations
        enabled = self.project.get_value('energy_eq', default=True)
        for item in (ui.label_des_min_cond_dist,
                     ui.lineedit_keyword_des_min_cond_dist,
                     ui.label_des_min_cond_dist_units, ui.label_flpc,
                     ui.lineedit_keyword_flpc):
            item.setEnabled(enabled)

        # Remember the names of solids phases, to track changes
        self.solids_dem_saved_solids_names = solids_names
예제 #22
0
    def handle_iss_region_selection(self):
        ui = self.ui.internal_surfaces
        table = ui.tablewidget_regions
        row = get_selected_row(table)
        if row is None:
            indices = []
            regions = []
        else:
            (indices, regions) = table.item(row, 0).data(UserRole)
        self.iss_current_indices, self.iss_current_regions = indices, regions
        enabled = (row is not None)
        for item in (ui.toolbutton_delete, ui.bottom_frame):
            item.setEnabled(enabled)
        ui.bottom_frame.setEnabled(enabled)
        if not enabled:
            # Clear
            for widget in widget_iter(ui.bottom_frame):
                if isinstance(widget, LineEdit):
                    widget.setText('')
            return
        IS0 = self.iss_current_indices[0]
        cb = ui.combobox_is_type
        key = 'is_type'
        is_type = self.project.get_value(key, args=[IS0])
        if is_type not in IS_TYPES:
            self.error("Unknown IS_TYPE %s" % is_type)
            is_type = 'IMPERMEABLE'
            for IS in self.iss_current_indices:
                self.update_keyword(key, is_type, args=[IS])
        cb.setCurrentIndex(IS_TYPES.index(is_type))

        # Available selections:
        #  Impermeable
        #    Selection only available for plane regions
        #    set keyword IS_TYPE(#) to 'IMPERMEABLE'
        #  X-Axis Impermeable
        #    Selection only available for volume regions
        #    set keyword IS_TYPE(#) to 'X_IMPERMEABLE'
        #  Y-Axis Impermeable
        #    Selection only available for volume regions
        #    set keyword IS_TYPE(#) to 'Y_IMPERMEABLE'
        #  z-Axis Impermeable
        #    Selection only available for volume regions
        #    set keyword IS_TYPE(#) to 'Z_IMPERMEABLE'
        #  Semi-permeable
        #    Selection only available for plane regions
        #    set keyword IS_TYPE(#) to 'SEMIPERMEABLE'
        #  X-Axis semi-permeable
        #    Selection only available for volume regions
        #    set keyword IS_TYPE(#) to 'X_SEMIPERMEABLE'
        #  Y-Axis semi-permeable
        #    Selection only available for volume regions
        #    set keyword IS_TYPE(#) to 'Y_SEMIPERMEABLE'
        #  Z-Axis semi-permeable
        #    Selection only available for volume regions
        #    set keyword IS_TYPE(#) to 'Z_SEMIPERMEABLE'
        # DEFAULT - Impermeable

        plane = is_type in ('IMPERMEABLE', 'SEMIPERMEABLE')
        vol = not plane
        for (i, enable) in enumerate(
            (plane, vol, vol, vol, plane, vol, vol, vol)):
            get_combobox_item(cb, i).setEnabled(enable)

        self.setup_iss()  # reinitialize all widgets in current tab
        ui.scrollarea_detail.ensureVisible(0, 0)  # scroll to top
예제 #23
0
    def handle_monitors_region_selection(self):
        ui = self.ui.monitors
        table = ui.tablewidget_regions
        row = get_selected_row(table)
        nrows = table.rowCount()
        if row is None:
            index = None
            region = None
        else:
            (index, region) = table.item(row, COLUMN_REGION).data(UserRole)
        self.monitors_current_index, self.monitors_current_region = index, region
        enabled = (row is not None)
        for item in (ui.toolbutton_delete, ui.bottom_frame):
            item.setEnabled(enabled)
        if not enabled:
            return
        # Set combobox to only allow appropriate monitor_type
        cb = ui.combobox_monitor_type
        mon = index
        monitor_type = self.project.get_value('monitor_type', args=[mon])
        region_type = self.monitors_region_dict.get(region)
        if region_type is None:
            self.error("Invalid region %s" % region)
            return
        region_type = region_type.get('type')
        if region_type == 'point':
            valids = MONITOR_TYPES_POINT
        elif 'plane' in region_type:
            valids = MONITOR_TYPES_PLANE
        elif 'box' in region_type:
            valids = MONITOR_TYPES_VOLUME
        else:
            valids = []
        for i in range(len(cb)):
            get_combobox_item(cb, i).setEnabled(i in valids)
        if monitor_type is None or monitor_type not in valids:
            # Default not specified in SRS, but 1 (sum) is valid for planes and volumes
            monitor_type = 0 if region_type == 'point' else 1
            self.update_keyword('monitor_type', monitor_type, args=[mon])
        cb.setCurrentIndex(monitor_type)
        cb.setToolTip(get_combobox_item(cb, monitor_type).toolTip())
        enable_phase = self.monitor_requires_phase(mon)
        if enable_phase:  # Disable all tabs except 'Phase'
            for i in range(ui.tab_layout.columnCount() - 1):  # Skip 'Phase'
                item = ui.tab_layout.itemAtPosition(0, i)
                if not item:
                    continue
                widget = item.widget()
                if not widget:
                    continue
                widget.setEnabled(False)
                widget.setToolTip('')
                ui.pushbutton_phase.setEnabled(True)
        else:
            ui.pushbutton_fluid.setEnabled(True)
            for i in range(1,
                           1 + len(self.solids)):  # Enable tabs for TFM solids
                item = ui.tab_layout.itemAtPosition(0, i)
                if not item:
                    continue
                widget = item.widget()
                if not widget:
                    continue
                enabled = self.project.get_value('solids_model',
                                                 args=[i]) == 'TFM'
                widget.setEnabled(enabled)
                widget.setToolTip('TFM solids required' if not enabled else '')
            ui.pushbutton_scalar.setEnabled(
                self.project.get_value('nscalar', default=0) > 0)
            ui.pushbutton_phase.setEnabled(False)

        self.setup_monitors()  # reinitialize all widgets
        ui.scrollarea_detail.ensureVisible(0, 0)  # scroll to top