Beispiel #1
0
    def __setitem__(self, name, value):
        """
        Set an option in the local dictionary.

        Parameters
        ----------
        name : str
            name of the option.
        value : -
            value of the option to be value- and type-checked if declared.
        """
        try:
            meta = self._dict[name]
        except KeyError:
            # The key must have been declared.
            msg = "Option '{}' cannot be set because it has not been declared."
            self._raise(msg.format(name), exc_type=KeyError)

        if meta['deprecation'] is not None and name not in self._deprecation_warning_issued:
            warn_deprecation(meta['deprecation'])
            self._deprecation_warning_issued.append(name)

        if self._read_only:
            self._raise("Tried to set read-only option '{}'.".format(name),
                        exc_type=KeyError)

        self._assert_valid(name, value)

        meta['value'] = value
        meta['has_been_set'] = True
Beispiel #2
0
    def __getitem__(self, name):
        """
        Get an option from the dict or declared default.

        Parameters
        ----------
        name : str
            name of the option.

        Returns
        -------
        value : -
            value of the option.
        """
        # If the option has been set in this system, return the set value
        try:
            meta = self._dict[name]
            if meta['deprecation'] is not None and name not in self._deprecation_warning_issued:
                warn_deprecation(meta['deprecation'])
                self._deprecation_warning_issued.append(name)
            if meta['has_been_set']:
                return meta['value']
            else:
                self._raise(
                    "Option '{}' is required but has not been set.".format(
                        name))
        except KeyError:
            self._raise("Option '{}' cannot be found".format(name),
                        exc_type=KeyError)
Beispiel #3
0
def check_mpi_env():
    """
    Determine if the environment variable governing MPI usage is set.

    Returns
    -------
    bool
        True if MPI is required, False if it's to be skipped, None if not set.
    """
    if 'OPENMDAO_REQUIRE_MPI' in os.environ:
        warn_deprecation(
            "Set OPENMDAO_USE_MPI instead of OPENMDAO_REQUIRE_MPI.")

    mpi_selection = os.environ.get(
        'OPENMDAO_USE_MPI', os.environ.get('OPENMDAO_REQUIRE_MPI', None))

    # If OPENMDAO_USE_MPI is set to a postive value, the run will fail
    # immediately if the import fails
    if str(mpi_selection).lower() in ['always', '1', 'true', 'yes', 'y', 'on']:
        return True

    # If set to something else, no import is attempted.
    if mpi_selection is not None:
        return False

    # If unset, the import will be attempted but give no warning if it fails.
    return None
Beispiel #4
0
 def factorial(*args):
     """
     Raise a warning stating that the factorial function is deprecated.
     """
     warn_deprecation(
         "The 'factorial' function is deprecated. "
         "It is no longer supported for SciPy versions >= 1.5.")
     return scipy.special.factorial(*args)
def record_system_options(problem):
    """
    Record the system options for all systems in the model.

    Parameters
    ----------
    problem : Problem
        The problem for which all its systems' options are to be recorded.
    """
    warn_deprecation("The 'record_system_options' function is deprecated. "
                     "Use 'record_model_options' instead.")
    record_model_options(problem)
Beispiel #6
0
    def system_options(self):
        """
        Provide '_system_options' property for backwards compatibility.

        Returns
        -------
        dict
            reference to the _system_options attribute.
        """
        warn_deprecation("The system_options attribute is deprecated. "
                         "Use `list_model_options` instead.")
        return self._system_options
    def record_metadata(self, recording_requester):
        """
        Call record_metadata for all recorders.

        Parameters
        ----------
        recording_requester : object
            The object that needs its metadata recorded.

        """
        warn_deprecation(
            "The 'record_metadata' function is deprecated. "
            "All system and solver options are recorded automatically.")
Beispiel #8
0
    def system_metadata(self):
        """
        Provide 'system_metadata' property for backwards compatibility.

        Returns
        -------
        dict
            reference to the '_system_options' attribute.
        """
        warn_deprecation(
            "The BaseCaseReader.system_metadata attribute is deprecated. "
            "Use `list_model_options` instead.")
        return self._system_options
Beispiel #9
0
def get_conversion(old_units, new_units):
    """
    Return conversion factor and offset between old and new units (deprecated).

    Parameters
    ----------
    old_units : str
        original units as a string.
    new_units : str
        new units to return the value in.

    Returns
    -------
    (float, float)
        Conversion factor and offset
    """
    warn_deprecation("'get_conversion' has been deprecated. Use "
                     "'unit_conversion' instead.")

    return unit_conversion(old_units, new_units)
Beispiel #10
0
def simple_warning(msg, category=UserWarning, stacklevel=2):
    """
    Display a simple warning message without the annoying extra line showing the warning call.

    Parameters
    ----------
    msg : str
        The warning message.
    category : class
        The warning class.
    stacklevel : int
        Number of levels up the stack to identify as the warning location.
    """
    warn_deprecation(
        'simple_warning is deprecated.  Use openmdao.warnings.issue_warning instead.'
    )
    old_format = warnings.formatwarning
    warnings.formatwarning = _warn_simple_format
    try:
        warnings.warn(msg, category, stacklevel)
    finally:
        warnings.formatwarning = old_format
Beispiel #11
0
def _n2_cmd(options, user_args):
    """
    Process command line args and call n2 on the specified file.

    Parameters
    ----------
    options : argparse Namespace
        Command line options.
    user_args : list of str
        Command line options after '--' (if any).  Passed to user script.
    """
    filename = _to_filename(options.file[0])

    if filename.endswith('.py'):
        # the file is a python script, run as a post_setup hook
        def _noraise(prob):
            prob.model._raise_connection_errors = False

        if options.use_declare_partial_info:
            warn_deprecation("'--use_declare_partial_info' is now the"
                             " default and the option is ignored.")

        def _viewmod(prob):
            n2(prob, outfile=options.outfile, show_browser=not options.no_browser,
                title=options.title, embeddable=options.embeddable)
            exit()  # could make this command line selectable later

        hooks._register_hook('setup', 'Problem', pre=_noraise)
        hooks._register_hook('final_setup', 'Problem', post=_viewmod)

        ignore_errors(True)
        _load_and_exec(options.file[0], user_args)
    else:
        # assume the file is a recording, run standalone
        n2(filename, outfile=options.outfile, title=options.title,
            show_browser=not options.no_browser, embeddable=options.embeddable)
Beispiel #12
0
    def add_output(self,
                   name,
                   val=1.0,
                   shape=None,
                   units=None,
                   res_units=None,
                   desc='',
                   lower=None,
                   upper=None,
                   ref=None,
                   ref0=None,
                   res_ref=None,
                   tags=None,
                   shape_by_conn=False,
                   copy_shape=None,
                   distributed=None):
        """
        Add an independent variable to this component.

        Parameters
        ----------
        name : str
            name of the variable in this component's namespace.
        val : float or list or tuple or ndarray
            The initial value of the variable being added in user-defined units. Default is 1.0.
        shape : int or tuple or list or None
            Shape of this variable, only required if val is not an array.
            Default is None.
        units : str or None
            Units in which the output variables will be provided to the component during execution.
            Default is None, which means it has no units.
        res_units : None
            This argument is deprecated because it was unused.
        desc : str
            description of the variable
        lower : None
            This argument is deprecated because it was unused.
        upper : None
            This argument is deprecated because it was unused.
        ref : None
            This argument is deprecated because it was unused.
        ref0 : None
            This argument is deprecated because it was unused.
        res_ref : None
            This argument is deprecated because it was unused.
        tags : str or list of strs
            User defined tags that can be used to filter what gets listed when calling
            list_outputs.
        shape_by_conn : bool
            If True, shape this output to match its connected input(s).
        copy_shape : str or None
            If a str, that str is the name of a variable. Shape this output to match that of
            the named variable.
        distributed : bool
            If True, this variable is a distributed variable, so it can have different sizes/values
            across MPI processes.
        """
        if res_units is not None:
            warn_deprecation(
                f"{self.msginfo}: The 'res_units' argument was used when adding "
                f"output '{name}'. This argument has been deprecated and will be "
                "removed in a future version.")
        if lower is not None:
            warn_deprecation(
                f"{self.msginfo}: The 'lower' argument was used when adding "
                f"output '{name}'. This argument has been deprecated and will be "
                "removed in a future version.")
        if upper is not None:
            warn_deprecation(
                f"{self.msginfo}: The 'upper' argument was used when adding "
                f"output '{name}'. This argument has been deprecated and will be "
                "removed in a future version.")
        if ref0 is not None:
            warn_deprecation(
                f"{self.msginfo}: The 'ref0' argument was used when adding "
                f"output '{name}'. This argument has been deprecated and will be "
                "removed in a future version.")
        if res_ref is not None:
            warn_deprecation(
                f"{self.msginfo}: The 'res_ref' argument was used when adding "
                f"output '{name}'. This argument has been deprecated and will be "
                "removed in a future version.")
        if ref is not None:
            warn_deprecation(
                f"{self.msginfo}: The 'ref' argument was used when adding "
                f"output '{name}'. This argument has been deprecated and will be "
                "removed in a future version.")

        ref = 1.0
        ref0 = 0.0

        if res_ref is None:
            res_ref = ref

        if tags is None:
            tags = {'indep_var'}
        else:
            tags = make_set(tags) | {'indep_var'}

        kwargs = {
            'shape': shape,
            'units': units,
            'res_units': res_units,
            'desc': desc,
            'lower': lower,
            'upper': upper,
            'ref': ref,
            'ref0': ref0,
            'res_ref': res_ref,
            'tags': tags,
            'shape_by_conn': shape_by_conn,
            'copy_shape': copy_shape,
            'distributed': distributed,
        }
        super().add_output(name, val, **kwargs)
Beispiel #13
0
def n2(data_source, outfile='n2.html', case_id=None, show_browser=True, embeddable=False,
       title=None, use_declare_partial_info=False):
    """
    Generate an HTML file containing a tree viewer.

    Optionally opens a web browser to view the file.

    Parameters
    ----------
    data_source : <Problem> or str
        The Problem or case recorder database containing the model or model data.

    case_id : int, str, or None
        Case name or index of case in SQL file if data_source is a database.

    outfile : str, optional
        The name of the final output file

    show_browser : bool, optional
        If True, pop up the system default web browser to view the generated html file.
        Defaults to True.

    embeddable : bool, optional
        If True, gives a single HTML file that doesn't have the <html>, <DOCTYPE>, <body>
        and <head> tags. If False, gives a single, standalone HTML file for viewing.

    title : str, optional
        The title for the diagram. Used in the HTML title.

    use_declare_partial_info : ignored
        This option is no longer used because it is now always true.
        Still present for backwards compatibility.

    """
    # grab the model viewer data
    model_data = _get_viewer_data(data_source, case_id=case_id)

    # if MPI is active only display one copy of the viewer
    if MPI and MPI.COMM_WORLD.rank != 0:
        return

    options = {}
    model_data['options'] = options

    if use_declare_partial_info:
        warn_deprecation("'use_declare_partial_info' is now the"
                         " default and the option is ignored.")

    raw_data = json.dumps(model_data, default=default_noraise).encode('utf8')
    b64_data = str(base64.b64encode(zlib.compress(raw_data)).decode("ascii"))
    model_data = 'var compressedModel = "%s";' % b64_data

    import openmdao
    openmdao_dir = os.path.dirname(inspect.getfile(openmdao))
    vis_dir = os.path.join(openmdao_dir, "visualization/n2_viewer")
    libs_dir = os.path.join(vis_dir, "libs")
    src_dir = os.path.join(vis_dir, "src")
    style_dir = os.path.join(vis_dir, "style")
    assets_dir = os.path.join(vis_dir, "assets")

    # grab the libraries, src and style
    lib_dct = {
        'd3': 'd3.v5.min',
        'awesomplete': 'awesomplete',
        'vk_beautify': 'vkBeautify',
        'pako_inflate': 'pako_inflate.min',
        'json5': 'json5_2.2.0.min'
    }
    libs = read_files(lib_dct.values(), libs_dir, 'js')
    src_names = \
        'utils', \
        'SymbolType', \
        'N2TreeNode', \
        'ModelData', \
        'N2Style', \
        'N2Window', \
        'N2Layout', \
        'N2MatrixCell', \
        'N2Legend', \
        'N2Matrix', \
        'N2Arrow', \
        'N2Search', \
        'N2Toolbar', \
        'N2Diagram', \
        'NodeInfo', \
        'N2UserInterface', \
        'defaults', \
        'ptN2'

    srcs = read_files(src_names, src_dir, 'js')

    style_names = \
        'window', \
        'partition_tree', \
        'n2toolbar-icons', \
        'toolbar', \
        'legend', \
        'awesomplete'

    styles = read_files((style_names), style_dir, 'css')

    with open(os.path.join(style_dir, "n2toolbar-icons-font.woff"), "rb") as f:
        encoded_font = str(base64.b64encode(f.read()).decode("ascii"))

    with open(os.path.join(style_dir, "logo_png.b64"), "r") as f:
        logo_png = str(f.read())

    with open(os.path.join(assets_dir, "spinner.png"), "rb") as f:
        waiting_icon = str(base64.b64encode(f.read()).decode("ascii"))

    with open(os.path.join(assets_dir, "n2toolbar_screenshot_png.b64"), "r") as f:
        n2toolbar_png = str(f.read())

    if title:
        title = "OpenMDAO Model Hierarchy and N2 diagram: %s" % title
    else:
        title = "OpenMDAO Model Hierarchy and N2 diagram"

    src_names = ('N2ErrorHandling',)
    head_srcs = read_files(src_names, src_dir, 'js')

    h = DiagramWriter(filename=os.path.join(vis_dir, "index.html"),
                      title=title,
                      styles=styles, embeddable=embeddable, head_srcs=head_srcs)

    if (embeddable):
        h.insert("non-embedded-n2", "embedded-n2")

    # put all style and JS into index
    h.insert('{{n2toolbar-icons}}', encoded_font)
    h.insert('{{logo_png}}', logo_png)
    h.insert('{{waiting_icon}}', waiting_icon)
    h.insert('{{n2toolbar_png}}', n2toolbar_png)
    h.insert('{{om_version}}', openmdao_version)

    for k, v in lib_dct.items():
        h.insert('{{{}_lib}}'.format(k), write_script(libs[v], indent=_IND))

    for name, code in srcs.items():
        h.insert('{{{}_lib}}'.format(name.lower()),
                 write_script(code, indent=_IND))

    h.insert('{{model_data}}', write_script(model_data, indent=_IND))

    # Write output file
    h.write(outfile)

    if notebook:
        # display in Jupyter Notebook
        outfile = os.path.relpath(outfile)
        if not colab:
            display(IFrame(src=outfile, width="100%", height=700))
        else:
            display(HTML(outfile))
    elif show_browser:
        # open it up in the browser
        from openmdao.utils.webview import webview
        webview(outfile)
Beispiel #14
0
def assert_rel_error(test_case, actual, desired, tolerance=1e-15):
    """
    Check relative error.

    Determine that the relative error between `actual` and `desired`
    is within `tolerance`. If `desired` is zero, then use absolute error.

    Parameters
    ----------
    test_case : class:`unittest.TestCase`
        TestCase instance used for assertions.
    actual : float, array-like, dict
        The value from the test.
    desired : float, array-like, dict
        The value expected.
    tolerance : float
        Maximum relative error ``(actual - desired) / desired``.

    Returns
    -------
    float
        The error.
    """
    warn_deprecation("'assert_rel_error' has been deprecated. Use "
                     "'assert_near_equal' instead.")

    if isinstance(actual, dict) and isinstance(desired, dict):

        actual_keys = set(actual.keys())
        desired_keys = set(desired.keys())

        if actual_keys.symmetric_difference(desired_keys):
            msg = 'Actual and desired keys differ. Actual extra keys: {}, Desired extra keys: {}'
            actual_extra = actual_keys.difference(desired_keys)
            desired_extra = desired_keys.difference(actual_keys)
            test_case.fail(msg.format(actual_extra, desired_extra))

        error = 0.

        for key in actual_keys:
            try:
                new_error = assert_rel_error(test_case, actual[key],
                                             desired[key], tolerance)
                error = max(error, new_error)
            except test_case.failureException as exception:
                msg = '{}: '.format(key) + str(exception)
                raise test_case.failureException(msg) from None

    elif isinstance(actual, float) and isinstance(desired, float):
        if isnan(actual) and not isnan(desired):
            test_case.fail('actual nan, desired %s' % desired)
        if desired != 0:
            error = (actual - desired) / desired
        else:
            error = actual
        if abs(error) > tolerance:
            test_case.fail(
                'actual %s, desired %s, rel error %s, tolerance %s' %
                (actual, desired, error, tolerance))

    # array values
    else:
        actual = np.atleast_1d(actual)
        desired = np.atleast_1d(desired)
        if actual.shape != desired.shape:
            test_case.fail('actual and desired have differing shapes.'
                           ' actual {}, desired {}'.format(
                               actual.shape, desired.shape))
        if not np.all(np.isnan(actual) == np.isnan(desired)):
            if actual.size == 1 and desired.size == 1:
                test_case.fail('actual %s, desired %s' % (actual, desired))
            else:
                test_case.fail(
                    'actual and desired values have non-matching nan'
                    ' values')

        if np.linalg.norm(desired) == 0:
            error = np.linalg.norm(actual)
        else:
            error = np.linalg.norm(actual - desired) / np.linalg.norm(desired)

        if abs(error) > tolerance:
            if actual.size < 10 and desired.size < 10:
                test_case.fail(
                    'actual %s, desired %s, rel error %s, tolerance %s' %
                    (actual, desired, error, tolerance))
            else:
                test_case.fail(
                    'arrays do not match, rel error %.3e > tol (%.3e)' %
                    (error, tolerance))

    return error