Ejemplo n.º 1
0
    def check(self):
        """
        Check the bounds and equality conditions.
        """
        if not self.enable:
            return

        def _not_all_close(a, b):
            return np.logical_not(np.isclose(a, b))

        if self._v is None:
            self._v = np.zeros_like(self.u.v)

        checks = [(self.lower, np.less_equal, "violation of the lower limit",
                   "limit"),
                  (self.upper, np.greater_equal,
                   "violation of the upper limit", "limit"),
                  (self.equal, _not_all_close, 'should be equal', "expected"),
                  (self.not_equal, np.equal, 'should not be equal',
                   "not expected")]

        for check in checks:
            limit = check[0]
            func = check[1]
            text = check[2]
            text2 = check[3]
            if limit is None:
                continue

            self.v[:] = np.logical_or(self.v, func(self.u.v, limit.v))

            pos = np.argwhere(func(self.u.v, limit.v)).ravel()

            if len(pos) == 0:
                continue
            idx = [self.owner.idx.v[i] for i in pos]
            lim_v = limit.v * np.ones(self.n)

            title = f'{self.owner.class_name} {self.info} {text}.'

            err_dict = OrderedDict([
                ('idx', idx),
                ('values', self.u.v[pos]),
                (f'{text2}', lim_v[pos]),
            ])
            data = list(map(list, zip(*err_dict.values())))

            tab = Tab(title=title, data=data, header=list(err_dict.keys()))
            if self.error_out:
                logger.error(tab.draw())
            else:
                logger.warning(tab.draw())

        self.v[:] = np.logical_not(self.v)
Ejemplo n.º 2
0
    def warn_init_limit(self):
        """
        Warn if initialized at limits.
        """
        if self.no_warn:
            return

        for f, limit in self.warn_flags:
            if f not in self.export_flags:
                logger.error(f'warn_flags contain unknown flag {f}')
                continue

            pos = np.argwhere(np.not_equal(self.__dict__[f], 0)).ravel()
            if not len(pos):
                continue
            err_msg = f'{self.owner.class_name}.{self.name} {self.__dict__[limit].name} at limits'
            if isinstance(self.__dict__[limit].v, np.ndarray):
                lim_value = self.__dict__[limit].v[pos]
            else:
                lim_value = self.__dict__[limit].v

            err_data = {
                'idx': [self.owner.idx.v[i] for i in pos],
                'Flag': [f] * len(pos),
                'Input Value': self.u.v[pos],
                'Limit': lim_value * np.ones_like(pos),
            }

            tab = Tab(title=err_msg,
                      header=err_data.keys(),
                      data=list(map(list, zip(*err_data.values()))))

            logger.warning(tab.draw())
Ejemplo n.º 3
0
    def supported_models(self, export='plain'):
        """
        Return the support group names and model names in a table.

        Returns
        -------
        str
            A table-formatted string for the groups and models
        """

        pairs = list()
        for g in self.groups:
            models = list()
            for m in self.groups[g].models:
                models.append(m)
            if len(models) > 0:
                pairs.append((g, ', '.join(models)))

        tab = Tab(
            title='Supported Groups and Models',
            header=['Group', 'Models'],
            data=pairs,
            export=export,
        )

        return tab.draw()
Ejemplo n.º 4
0
    def check(self):
        """
        Check the bounds and equality conditions.
        """
        if not self.enable:
            return

        if self._v is None:
            self._v = np.zeros_like(self.u.v)

        for check in self.checks:
            limit = check[0]
            func = check[1]
            text = check[2]
            text2 = check[3]
            if limit is None:
                continue

            self.v[:] = np.logical_or(self.v, func(self.u.v, limit.v))

            pos = np.argwhere(func(self.u.v, limit.v)).ravel()

            if len(pos) == 0:
                continue
            idx = [self.owner.idx.v[i] for i in pos]
            lim_v = limit.v * np.ones(self.n)

            title = f'{self.owner.class_name} {self.info} {text}.'

            err_dict = OrderedDict([
                ('idx', idx),
                ('values', self.u.v[pos]),
                (f'{text2}', lim_v[pos]),
            ])
            data = list(map(list, zip(*err_dict.values())))

            tab = Tab(title=title, data=data, header=list(err_dict.keys()))
            if self.error_out:
                logger.error(tab.draw())
            else:
                logger.warning(tab.draw())

        self.v[:] = np.logical_not(self.v)
Ejemplo n.º 5
0
    def test_init(self):
        """
        Test if the TDS initialization is successful.

        This function update ``dae.f`` and ``dae.g`` and checks if the residuals
        are zeros.
        """

        system = self.system
        # fg_update is called in TDS.init()
        system.j_update(models=system.exist.pflow_tds)

        # reset diff. RHS where `check_init == False`
        system.dae.f[system.no_check_init] = 0.0

        # warn if variables are initialized at limits
        if system.config.warn_limits:
            for model in system.exist.pflow_tds.values():
                for item in model.discrete.values():
                    item.warn_init_limit()

        if np.max(np.abs(system.dae.fg)) < self.config.tol:
            logger.debug('Initialization tests passed.')
            return True

        # otherwise, show suspect initialization error
        fail_idx = np.ravel(np.where(abs(system.dae.fg) >= self.config.tol))
        nan_idx = np.ravel(np.where(np.isnan(system.dae.fg)))
        bad_idx = np.hstack([fail_idx, nan_idx])

        fail_names = [system.dae.xy_name[int(i)] for i in fail_idx]
        nan_names = [system.dae.xy_name[int(i)] for i in nan_idx]
        bad_names = fail_names + nan_names

        title = 'Suspect initialization issue! Simulation may crash!'
        err_data = {
            'Name': bad_names,
            'Var. Value': system.dae.xy[bad_idx],
            'Eqn. Mismatch': system.dae.fg[bad_idx],
        }
        tab = Tab(
            title=title,
            header=err_data.keys(),
            data=list(map(list, zip(*err_data.values()))),
        )

        logger.error(tab.draw())

        if system.options.get('verbose') == 1:
            breakpoint()
        system.exit_code += 1

        return False
Ejemplo n.º 6
0
    def test_init(self):
        """
        Update f and g to see if initialization is successful.
        """
        system = self.system
        self.fg_update(system.exist.pflow_tds)
        system.j_update(models=system.exist.pflow_tds)

        # reset diff. RHS where `check_init == False`
        system.dae.f[system.no_check_init] = 0.0

        # warn if variables are initialized at limits
        if system.config.warn_limits:
            for model in system.exist.pflow_tds.values():
                for item in model.discrete.values():
                    item.warn_init_limit()

        if np.max(np.abs(system.dae.fg)) < self.config.tol:
            logger.debug('Initialization tests passed.')
            return True

        # otherwise, show suspect initialization error
        fail_idx = np.where(abs(system.dae.fg) >= self.config.tol)
        fail_names = [system.dae.xy_name[int(i)] for i in np.ravel(fail_idx)]

        title = 'Suspect initialization issue! Simulation may crash!'
        err_data = {
            'Name': fail_names,
            'Var. Value': system.dae.xy[fail_idx],
            'Eqn. Mismatch': system.dae.fg[fail_idx],
        }
        tab = Tab(
            title=title,
            header=err_data.keys(),
            data=list(map(list, zip(*err_data.values()))),
        )

        logger.error(tab.draw())

        if system.options.get('verbose') == 1:
            breakpoint()
        system.exit_code += 1

        return False