Exemple #1
0
    def test_get_conversion(self):
        self.assertEqual(get_conversion('km', 'm'), (1000., 0.))

        try:
            get_conversion('km', 1.0)
        except RuntimeError as err:
            self.assertEqual(str(err), "Cannot convert to new units: 1.0")
        else:
            self.fail("Expecting RuntimeError")
Exemple #2
0
    def test_get_conversion(self):
        msg = "'get_conversion' has been deprecated. Use 'unit_conversion' instead."
        with assert_warning(OMDeprecationWarning, msg):
            get_conversion('km', 'm'), (1000., 0.)

        self.assertEqual(get_conversion('km', 'm'), (1000., 0.))

        try:
            get_conversion('km', 1.0)
        except ValueError as err:
            self.assertEqual(str(err), "The units '1.0' are invalid.")
        else:
            self.fail("Expecting ValueError")
Exemple #3
0
    def test_get_conversion(self):
        msg = "'get_conversion' has been deprecated. Use 'unit_conversion' instead."
        with assert_warning(DeprecationWarning, msg):
            get_conversion('km', 'm'), (1000., 0.)

        self.assertEqual(get_conversion('km', 'm'), (1000., 0.))

        try:
            get_conversion('km', 1.0)
        except RuntimeError as err:
            self.assertEqual(str(err), "Cannot convert to new units: '1.0'.")
        else:
            self.fail("Expecting RuntimeError")
Exemple #4
0
    def get_val(self, name, units=None, indices=None):
        """
        Get an output/input variable.

        Function is used if you want to specify display units.

        Parameters
        ----------
        name : str
            Promoted or relative variable name in the root system's namespace.
        units : str, optional
            Units to convert to before upon return.
        indices : int or list of ints or tuple of ints or int ndarray or Iterable or None, optional
            Indices or slice to return.

        Returns
        -------
        float or ndarray
            The requested output/input variable.
        """
        val = self[name]

        if indices is not None:
            val = val[indices]

        if units is not None:
            base_units = self._get_units(name)

            if base_units is None:
                msg = "Can't express variable '{}' with units of 'None' in units of '{}'."
                raise TypeError(msg.format(name, units))

            try:
                scale, offset = get_conversion(base_units, units)
            except TypeError:
                msg = "Can't express variable '{}' with units of '{}' in units of '{}'."
                raise TypeError(msg.format(name, base_units, units))

            val = (val + offset) * scale

        return val
Exemple #5
0
    def _initialize(self):
        """
        Allocate the global matrices.
        """
        # var_indices are the *global* indices for variables on this proc
        system = self._system
        is_top = system.pathname == ''

        abs2meta = system._var_abs2meta

        self._int_mtx = int_mtx = self._matrix_class(system.comm)
        ext_mtx = self._matrix_class(system.comm)

        iproc = system.comm.rank
        abs2idx = system._var_allprocs_abs2idx['nonlinear']
        sizes = system._var_sizes['nonlinear']['output']
        out_ranges = self._out_ranges = {}
        for name in system._var_allprocs_abs_names['output']:
            start = np.sum(sizes[iproc, :abs2idx[name]])
            out_ranges[name] = (start, start + sizes[iproc, abs2idx[name]])

        sizes = system._var_sizes['nonlinear']['input']
        in_ranges = self._in_ranges = {}
        for name in system._var_allprocs_abs_names['input']:
            start = np.sum(sizes[iproc, :abs2idx[name]])
            in_ranges[name] = (start, start + sizes[iproc, abs2idx[name]])

        abs2prom_out = system._var_abs2prom['output']
        conns = {} if isinstance(system,
                                 Component) else system._conn_global_abs_in2out
        keymap = self._keymap
        abs_key2shape = self._abs_key2shape

        # create the matrix subjacs
        for abs_key, (info, shape) in iteritems(self._subjacs_info):
            res_abs_name, wrt_abs_name = abs_key
            # because self._subjacs_info is shared among all 'related' assembled jacs,
            # we use out_ranges (and later in_ranges) to weed out keys outside of this jac
            if res_abs_name not in out_ranges:
                continue
            res_offset, _ = out_ranges[res_abs_name]

            if wrt_abs_name in abs2prom_out:
                out_offset, _ = out_ranges[wrt_abs_name]
                int_mtx._add_submat(abs_key, info, res_offset, out_offset,
                                    None, shape)
                keymap[abs_key] = abs_key
            elif wrt_abs_name in in_ranges:
                if wrt_abs_name in conns:  # connected input
                    out_abs_name = conns[wrt_abs_name]
                    # calculate unit conversion
                    in_units = abs2meta[wrt_abs_name]['units']
                    out_units = abs2meta[out_abs_name]['units']
                    if in_units and out_units and in_units != out_units:
                        factor, _ = get_conversion(out_units, in_units)
                        if factor == 1.0:
                            factor = None
                    else:
                        factor = None

                    out_offset, _ = out_ranges[out_abs_name]
                    src_indices = abs2meta[wrt_abs_name]['src_indices']

                    # need to add an entry for d(output)/d(source)
                    # instead of d(output)/d(input)
                    abs_key2 = (res_abs_name, out_abs_name)
                    keymap[abs_key] = abs_key2

                    shape = abs_key2shape(abs_key2)

                    int_mtx._add_submat(abs_key, info, res_offset, out_offset,
                                        src_indices, shape, factor)

                elif not is_top:  # input is connected to something outside current system
                    ext_mtx._add_submat(abs_key, info, res_offset,
                                        in_ranges[wrt_abs_name][0], None,
                                        shape)

        sizes = system._var_sizes
        iproc = system.comm.rank
        out_size = np.sum(sizes['nonlinear']['output'][iproc, :])

        int_mtx._build(out_size, out_size)
        if ext_mtx._submats:
            in_size = np.sum(sizes['nonlinear']['input'][iproc, :])
            ext_mtx._build(out_size, in_size)
        else:
            ext_mtx = None

        self._ext_mtx[system.pathname] = ext_mtx
Exemple #6
0
 def test_light_year(self):
     factor, offset = get_conversion('ly', 'au')
     self.assertAlmostEqual(factor, 63241, places=0)
Exemple #7
0
    def _initialize(self, system):
        """
        Allocate the global matrices.

        Parameters
        ----------
        system : System
            Parent system to this jacobian.
        """
        # var_indices are the *global* indices for variables on this proc
        is_top = system.pathname == ''

        abs2meta = system._var_abs2meta
        all_meta = system._var_allprocs_abs2meta

        self._int_mtx = int_mtx = self._matrix_class(system.comm)
        ext_mtx = self._matrix_class(system.comm)

        iproc = system.comm.rank
        abs2idx = system._var_allprocs_abs2idx['nonlinear']
        out_sizes = system._var_sizes['nonlinear']['output']
        in_sizes = system._var_sizes['nonlinear']['input']
        out_ranges = self._out_ranges
        in_ranges = self._in_ranges

        abs2prom_out = system._var_abs2prom['output']
        conns = {} if isinstance(system,
                                 Component) else system._conn_global_abs_in2out
        abs_key2shape = self._abs_key2shape

        # create the matrix subjacs
        for abs_key, info in iteritems(self._subjacs_info):
            res_abs_name, wrt_abs_name = abs_key
            # because self._subjacs_info is shared among all 'related' assembled jacs,
            # we use out_ranges (and later in_ranges) to weed out keys outside of this jac
            if res_abs_name not in out_ranges:
                continue
            res_offset, res_end = out_ranges[res_abs_name]
            res_size = res_end - res_offset

            if wrt_abs_name in abs2prom_out:
                out_offset, out_end = out_ranges[wrt_abs_name]
                out_size = out_end - out_offset
                shape = (res_size, out_size)
                int_mtx._add_submat(abs_key, info, res_offset, out_offset,
                                    None, shape)
            elif wrt_abs_name in in_ranges:
                if wrt_abs_name in conns:  # connected input
                    out_abs_name = conns[wrt_abs_name]
                    meta_in = abs2meta[wrt_abs_name]
                    all_out_meta = all_meta[out_abs_name]
                    # calculate unit conversion
                    in_units = meta_in['units']
                    out_units = all_out_meta['units']
                    if in_units and out_units and in_units != out_units:
                        factor, _ = get_conversion(out_units, in_units)
                        if factor == 1.0:
                            factor = None
                    else:
                        factor = None

                    out_offset, out_end = out_ranges[out_abs_name]
                    out_size = out_end - out_offset
                    shape = (res_size, out_size)
                    src_indices = abs2meta[wrt_abs_name]['src_indices']

                    # need to add an entry for d(output)/d(source)
                    # instead of d(output)/d(input)
                    abs_key2 = (res_abs_name, out_abs_name)

                    if src_indices is not None:
                        shape = abs_key2shape(abs_key2)
                        if len(src_indices.shape) > 1:
                            src_indices = _flatten_src_indices(
                                src_indices, meta_in['shape'],
                                all_out_meta['global_shape'],
                                all_out_meta['global_size'])
                    int_mtx._add_submat(abs_key, info, res_offset, out_offset,
                                        src_indices, shape, factor)

                elif not is_top:  # input is connected to something outside current system
                    in_offset, in_end = in_ranges[wrt_abs_name]
                    shape = (res_size, in_end - in_offset)
                    ext_mtx._add_submat(abs_key, info, res_offset, in_offset,
                                        None, shape)

        iproc = system.comm.rank
        out_size = np.sum(out_sizes[iproc, :])

        int_mtx._build(out_size, out_size, in_ranges, out_ranges)
        if ext_mtx._submats:
            in_size = np.sum(in_sizes[iproc, :])
            ext_mtx._build(out_size, in_size, in_ranges, out_ranges)
        else:
            ext_mtx = None

        self._ext_mtx[system.pathname] = ext_mtx
    def _initialize(self):
        """
        Allocate the global matrices.
        """
        # var_indices are the *global* indices for variables on this proc
        system = self._system

        abs2meta_in = system._var_abs2meta['input']
        abs2meta_out = system._var_abs2meta['output']

        self._int_mtx = int_mtx = self.options['matrix_class'](system.comm)
        ext_mtx = self.options['matrix_class'](system.comm)

        out_ranges = {}
        for abs_name in system._var_allprocs_abs_names['output']:
            out_ranges[abs_name] = self._get_var_range(abs_name, 'output')

        in_ranges = {}
        src_indices_dict = {}
        for abs_name in system._var_allprocs_abs_names['input']:
            in_ranges[abs_name] = self._get_var_range(abs_name, 'input')
            src_indices_dict[abs_name] = \
                system._var_abs2meta['input'][abs_name]['src_indices']

        for s in self._system.system_iter(local=True, recurse=True, include_self=True):

            min_res_offset = sys.maxsize
            max_res_offset = 0
            min_in_offset = sys.maxsize
            max_in_offset = 0

            for in_abs_name in s._var_abs_names['input']:
                in_offset, in_end = in_ranges[in_abs_name]
                if in_end > max_in_offset:
                    max_in_offset = in_end
                if in_offset < min_in_offset:
                    min_in_offset = in_offset

            for res_abs_name in s._var_abs_names['output']:
                res_offset, res_end = out_ranges[res_abs_name]
                if res_end > max_res_offset:
                    max_res_offset = res_end
                if res_offset < min_res_offset:
                    min_res_offset = res_offset

                # only need to collect subjac info for components, not subgroups
                if not isinstance(s, Component):
                    continue

                res_size = abs2meta_out[res_abs_name]['size']

                for out_abs_name in s._var_abs_names['output']:
                    out_offset, _ = out_ranges[out_abs_name]

                    abs_key = (res_abs_name, out_abs_name)
                    if abs_key in self._subjacs_info:
                        info, shape = self._subjacs_info[abs_key]
                    else:
                        info = SUBJAC_META_DEFAULTS
                        shape = (res_size, abs2meta_out[out_abs_name]['size'])

                    int_mtx._add_submat(
                        abs_key, info, res_offset, out_offset, None, shape)

                for in_abs_name in s._var_abs_names['input']:
                    abs_key = (res_abs_name, in_abs_name)
                    self._keymap[abs_key] = abs_key

                    if abs_key in self._subjacs_info:
                        info, shape = self._subjacs_info[abs_key]
                    else:
                        info = SUBJAC_META_DEFAULTS
                        shape = (res_size, abs2meta_in[in_abs_name]['size'])

                    self._keymap[abs_key] = abs_key

                    if in_abs_name in system._conn_global_abs_in2out:
                        out_abs_name = system._conn_global_abs_in2out[in_abs_name]
                        out_offset, _ = out_ranges[out_abs_name]
                        src_indices = src_indices_dict[in_abs_name]

                        # calculate unit conversion
                        in_units = abs2meta_in[in_abs_name]['units']
                        out_units = abs2meta_out[out_abs_name]['units']
                        if in_units and out_units:
                            factor, _ = get_conversion(out_units, in_units)
                        else:
                            factor = None

                        if src_indices is None:
                            int_mtx._add_submat(
                                abs_key, info, res_offset, out_offset, None, shape,
                                factor)
                        else:
                            # need to add an entry for d(output)/d(source)
                            # instead of d(output)/d(input) when we have
                            # src_indices
                            abs_key2 = (res_abs_name, out_abs_name)
                            self._keymap[abs_key] = abs_key2
                            int_mtx._add_submat(
                                abs_key2, info, res_offset, out_offset,
                                src_indices, shape, factor)
                    else:
                        ext_mtx._add_submat(
                            abs_key, info, res_offset, in_ranges[in_abs_name][0],
                            None, shape)

            self._view_ranges[s.pathname] = (
                min_res_offset, max_res_offset, min_in_offset, max_in_offset)

        sizes = system._var_sizes
        iproc = system.comm.rank
        out_size = np.sum(sizes['nonlinear']['output'][iproc, :])

        int_mtx._build(out_size, out_size)
        if ext_mtx._submats:
            in_size = np.sum(sizes['nonlinear']['input'][iproc, :])
            ext_mtx._build(out_size, in_size)
        else:
            ext_mtx = None

        self._ext_mtx[system.pathname] = ext_mtx
Exemple #9
0
    def _initialize(self, system):
        """
        Allocate the global matrices.

        Parameters
        ----------
        system : System
            Parent system to this jacobian.
        """
        # var_indices are the *global* indices for variables on this proc
        is_top = system.pathname == ''

        abs2meta = system._var_abs2meta
        all_meta = system._var_allprocs_abs2meta

        self._int_mtx = int_mtx = self._matrix_class(system.comm, True)
        ext_mtx = self._matrix_class(system.comm, False)

        iproc = system.comm.rank
        abs2idx = system._var_allprocs_abs2idx['nonlinear']
        in_sizes = system._var_sizes['nonlinear']['input']
        out_ranges = self._out_ranges
        # for non-MPI case, global_out_ranges is out_ranges
        global_out_ranges = self._nodup_out_ranges
        in_ranges = self._in_ranges

        abs2prom_out = system._var_abs2prom['output']
        owns = system._owning_rank
        conns = {} if isinstance(system, Component) else system._conn_global_abs_in2out
        abs_key2shape = self._abs_key2shape
        check_owns = system._use_owned_sizes()

        # create the matrix subjacs
        for abs_key, info in iteritems(self._subjacs_info):
            res_abs_name, wrt_abs_name = abs_key
            # because self._subjacs_info is shared among all 'related' assembled jacs,
            # we use global_out_ranges (and later in_ranges) to weed out keys outside of this jac
            if res_abs_name not in global_out_ranges:
                continue
            res_offset, res_end = global_out_ranges[res_abs_name]
            res_size = res_end - res_offset

            if wrt_abs_name in abs2prom_out:
                if check_owns and (owns[wrt_abs_name] != iproc and
                                   not all_meta[wrt_abs_name]['distributed']):
                    continue
                out_offset, out_end = global_out_ranges[wrt_abs_name]
                out_size = out_end - out_offset
                shape = (res_size, out_size)
                int_mtx._add_submat(abs_key, info, res_offset, out_offset, None, shape)
            elif wrt_abs_name in in_ranges:
                if wrt_abs_name in conns:  # connected input
                    out_abs_name = conns[wrt_abs_name]
                    if out_abs_name not in global_out_ranges:
                        continue

                    if check_owns and (owns[wrt_abs_name] != iproc and
                                       not (all_meta[wrt_abs_name]['distributed'] or
                                            all_meta[out_abs_name]['distributed'])):
                        continue

                    meta_in = abs2meta[wrt_abs_name]
                    all_out_meta = all_meta[out_abs_name]
                    # calculate unit conversion
                    in_units = meta_in['units']
                    out_units = all_out_meta['units']
                    if in_units and out_units and in_units != out_units:
                        factor, _ = get_conversion(out_units, in_units)
                        if factor == 1.0:
                            factor = None
                    else:
                        factor = None

                    out_offset, out_end = global_out_ranges[out_abs_name]
                    out_size = out_end - out_offset
                    shape = (res_size, out_size)
                    src_indices = abs2meta[wrt_abs_name]['src_indices']

                    if src_indices is not None:
                        # need to add an entry for d(output)/d(source)
                        # instead of d(output)/d(input).  int_mtx is a square matrix whose
                        # rows and columns map to output/resid vars only.
                        abs_key2 = (res_abs_name, out_abs_name)

                        shape = abs_key2shape(abs_key2)
                        if len(src_indices.shape) > 1:
                            src_indices = _flatten_src_indices(src_indices, meta_in['shape'],
                                                               all_out_meta['global_shape'],
                                                               all_out_meta['global_size'])

                    int_mtx._add_submat(abs_key, info, res_offset, out_offset,
                                        src_indices, shape, factor)

                elif not is_top:  # input is connected to something outside current system
                    in_offset, in_end = in_ranges[wrt_abs_name]
                    # don't use global offsets for ext_mtx
                    res_offset, res_end = out_ranges[res_abs_name]
                    res_size = res_end - res_offset
                    shape = (res_size, in_end - in_offset)
                    ext_mtx._add_submat(abs_key, info, res_offset, in_offset, None, shape)

        out_size = system._outputs._data.size
        if check_owns:
            total_non_dup_size = np.sum(system._owned_sizes)
            self._int_mtx._build(total_non_dup_size, total_non_dup_size, system)
        else:
            int_mtx._build(out_size, out_size, system)

        if ext_mtx._submats:
            in_size = np.sum(in_sizes[iproc, :])
            ext_mtx._build(out_size, in_size)
        else:
            ext_mtx = None

        self._ext_mtx[system.pathname] = ext_mtx
Exemple #10
0
    def _initialize(self):
        """
        Allocate the global matrices.
        """
        # var_indices are the *global* indices for variables on this proc
        system = self._system

        abs2meta = system._var_abs2meta

        self._int_mtx = int_mtx = self.options['matrix_class'](system.comm)
        ext_mtx = self.options['matrix_class'](system.comm)

        out_ranges = {
            abs_name: self._get_var_range(abs_name, 'output') for abs_name in
                system._var_allprocs_abs_names['output']
        }

        in_ranges = {}
        for abs_name in system._var_allprocs_abs_names['input']:
            in_ranges[abs_name] = self._get_var_range(abs_name, 'input')

        # set up view ranges for all subsystems
        for s in system.system_iter(recurse=True, include_self=True):
            min_res_offset = sys.maxsize
            max_res_offset = 0
            min_in_offset = sys.maxsize
            max_in_offset = 0

            for in_abs_name in s._var_abs_names['input']:
                in_offset, in_end = in_ranges[in_abs_name]
                if in_end > max_in_offset:
                    max_in_offset = in_end
                if in_offset < min_in_offset:
                    min_in_offset = in_offset

            for res_abs_name in s._var_abs_names['output']:
                res_offset, res_end = out_ranges[res_abs_name]
                if res_end > max_res_offset:
                    max_res_offset = res_end
                if res_offset < min_res_offset:
                    min_res_offset = res_offset

            self._view_ranges[s.pathname] = (
                min_res_offset, max_res_offset, min_in_offset, max_in_offset)

        abs2prom_out = system._var_abs2prom['output']
        conns = system._conn_global_abs_in2out

        # create the matrix subjacs
        for abs_key, (info, shape) in iteritems(self._subjacs_info):
            if not info['dependent']:
                continue
            res_abs_name, wrt_abs_name = abs_key
            res_offset, _ = out_ranges[res_abs_name]
            if wrt_abs_name in abs2prom_out:
                out_offset, _ = out_ranges[wrt_abs_name]
                int_mtx._add_submat(
                    abs_key, info, res_offset, out_offset, None, shape)
            else:
                if wrt_abs_name in conns:  # connected input
                    out_abs_name = conns[wrt_abs_name]
                    # calculate unit conversion
                    in_units = abs2meta[wrt_abs_name]['units']
                    out_units = abs2meta[out_abs_name]['units']
                    if in_units and out_units and in_units != out_units:
                        factor, _ = get_conversion(out_units, in_units)
                        if factor == 1.0:
                            factor = None
                    else:
                        factor = None

                    out_offset, _ = out_ranges[out_abs_name]
                    src_indices = abs2meta[wrt_abs_name]['src_indices']
                    if src_indices is None:
                        int_mtx._add_submat(
                            abs_key, info, res_offset, out_offset, None, shape,
                            factor)
                    else:
                        # need to add an entry for d(output)/d(source)
                        # instead of d(output)/d(input) when we have
                        # src_indices
                        abs_key2 = (res_abs_name, out_abs_name)
                        self._keymap[abs_key] = abs_key2
                        int_mtx._add_submat(
                            abs_key2, info, res_offset, out_offset,
                            src_indices, shape, factor)

                else:  # input connected to src outside current system
                    ext_mtx._add_submat(
                        abs_key, info, res_offset, in_ranges[wrt_abs_name][0],
                        None, shape)

                if abs_key not in self._keymap:
                    self._keymap[abs_key] = abs_key

        sizes = system._var_sizes
        iproc = system.comm.rank
        out_size = np.sum(sizes['nonlinear']['output'][iproc, :])

        int_mtx._build(out_size, out_size)
        if ext_mtx._submats:
            in_size = np.sum(sizes['nonlinear']['input'][iproc, :])
            ext_mtx._build(out_size, in_size)
        else:
            ext_mtx = None

        self._ext_mtx[system.pathname] = ext_mtx
    def _initialize(self, system):
        """
        Allocate the global matrices.

        Parameters
        ----------
        system : System
            Parent system to this jacobian.
        """
        # var_indices are the *global* indices for variables on this proc
        is_top = system.pathname == ''

        abs2meta = system._var_abs2meta
        all_meta = system._var_allprocs_abs2meta

        self._int_mtx = int_mtx = self._matrix_class(system.comm)
        ext_mtx = self._matrix_class(system.comm)

        iproc = system.comm.rank
        abs2idx = system._var_allprocs_abs2idx['nonlinear']
        out_sizes = system._var_sizes['nonlinear']['output']
        in_sizes = system._var_sizes['nonlinear']['input']
        out_ranges = self._out_ranges
        in_ranges = self._in_ranges

        abs2prom_out = system._var_abs2prom['output']
        conns = {} if isinstance(system, Component) else system._conn_global_abs_in2out
        keymap = self._keymap
        abs_key2shape = self._abs_key2shape

        # create the matrix subjacs
        for abs_key, info in iteritems(self._subjacs_info):
            res_abs_name, wrt_abs_name = abs_key
            # because self._subjacs_info is shared among all 'related' assembled jacs,
            # we use out_ranges (and later in_ranges) to weed out keys outside of this jac
            if res_abs_name not in out_ranges:
                continue
            res_offset, _ = out_ranges[res_abs_name]

            if wrt_abs_name in abs2prom_out:
                out_offset, _ = out_ranges[wrt_abs_name]
                int_mtx._add_submat(abs_key, info, res_offset, out_offset, None, info['shape'])
                keymap[abs_key] = abs_key
            elif wrt_abs_name in in_ranges:
                if wrt_abs_name in conns:  # connected input
                    out_abs_name = conns[wrt_abs_name]
                    meta_in = abs2meta[wrt_abs_name]
                    all_out_meta = all_meta[out_abs_name]
                    # calculate unit conversion
                    in_units = meta_in['units']
                    out_units = all_out_meta['units']
                    if in_units and out_units and in_units != out_units:
                        factor, _ = get_conversion(out_units, in_units)
                        if factor == 1.0:
                            factor = None
                    else:
                        factor = None

                    out_offset, _ = out_ranges[out_abs_name]
                    src_indices = abs2meta[wrt_abs_name]['src_indices']

                    # need to add an entry for d(output)/d(source)
                    # instead of d(output)/d(input)
                    abs_key2 = (res_abs_name, out_abs_name)
                    keymap[abs_key] = abs_key2

                    if src_indices is None:
                        shape = info['shape']
                    else:
                        shape = abs_key2shape(abs_key2)
                        if len(src_indices.shape) > 1:
                            src_indices = _flatten_src_indices(src_indices, meta_in['shape'],
                                                               all_out_meta['global_shape'],
                                                               all_out_meta['global_size'])
                    int_mtx._add_submat(abs_key, info, res_offset, out_offset,
                                        src_indices, shape, factor)

                elif not is_top:  # input is connected to something outside current system
                    ext_mtx._add_submat(abs_key, info, res_offset,
                                        in_ranges[wrt_abs_name][0], None, info['shape'])

        iproc = system.comm.rank
        out_size = np.sum(out_sizes[iproc, :])

        int_mtx._build(out_size, out_size, in_ranges, out_ranges)
        if ext_mtx._submats:
            in_size = np.sum(in_sizes[iproc, :])
            ext_mtx._build(out_size, in_size, in_ranges, out_ranges)
        else:
            ext_mtx = None

        self._ext_mtx[system.pathname] = ext_mtx
    def _initialize(self):
        """
        Allocate the global matrices.
        """
        # var_indices are the *global* indices for variables on this proc
        system = self._system

        abs2meta = system._var_abs2meta

        self._int_mtx = int_mtx = self.options['matrix_class'](system.comm)
        ext_mtx = self.options['matrix_class'](system.comm)

        out_ranges = {
            abs_name: self._get_var_range(abs_name, 'output')
            for abs_name in system._var_allprocs_abs_names['output']
        }

        in_ranges = {}
        for abs_name in system._var_allprocs_abs_names['input']:
            in_ranges[abs_name] = self._get_var_range(abs_name, 'input')

        # set up view ranges for all subsystems
        for s in system.system_iter(recurse=True, include_self=True):
            min_res_offset = sys.maxsize
            max_res_offset = 0
            min_in_offset = sys.maxsize
            max_in_offset = 0

            for in_abs_name in s._var_abs_names['input']:
                in_offset, in_end = in_ranges[in_abs_name]
                if in_end > max_in_offset:
                    max_in_offset = in_end
                if in_offset < min_in_offset:
                    min_in_offset = in_offset

            for res_abs_name in s._var_abs_names['output']:
                res_offset, res_end = out_ranges[res_abs_name]
                if res_end > max_res_offset:
                    max_res_offset = res_end
                if res_offset < min_res_offset:
                    min_res_offset = res_offset

            self._view_ranges[s.pathname] = (min_res_offset, max_res_offset,
                                             min_in_offset, max_in_offset)

        abs2prom_out = system._var_abs2prom['output']
        conns = system._conn_global_abs_in2out

        # create the matrix subjacs
        for abs_key, (info, shape) in iteritems(self._subjacs_info):
            if not info['dependent']:
                continue
            res_abs_name, wrt_abs_name = abs_key
            res_offset, _ = out_ranges[res_abs_name]
            if wrt_abs_name in abs2prom_out:
                out_offset, _ = out_ranges[wrt_abs_name]
                int_mtx._add_submat(abs_key, info, res_offset, out_offset,
                                    None, shape)
            else:
                if wrt_abs_name in conns:  # connected input
                    out_abs_name = conns[wrt_abs_name]
                    # calculate unit conversion
                    in_units = abs2meta[wrt_abs_name]['units']
                    out_units = abs2meta[out_abs_name]['units']
                    if in_units and out_units and in_units != out_units:
                        factor, _ = get_conversion(out_units, in_units)
                        if factor == 1.0:
                            factor = None
                    else:
                        factor = None

                    out_offset, _ = out_ranges[out_abs_name]
                    src_indices = abs2meta[wrt_abs_name]['src_indices']
                    if src_indices is None:
                        int_mtx._add_submat(abs_key, info, res_offset,
                                            out_offset, None, shape, factor)
                    else:
                        # need to add an entry for d(output)/d(source)
                        # instead of d(output)/d(input) when we have
                        # src_indices
                        abs_key2 = (res_abs_name, out_abs_name)
                        self._keymap[abs_key] = abs_key2
                        int_mtx._add_submat(abs_key2, info, res_offset,
                                            out_offset, src_indices, shape,
                                            factor)

                else:  # input connected to src outside current system
                    ext_mtx._add_submat(abs_key, info, res_offset,
                                        in_ranges[wrt_abs_name][0], None,
                                        shape)

                if abs_key not in self._keymap:
                    self._keymap[abs_key] = abs_key

        sizes = system._var_sizes
        iproc = system.comm.rank
        out_size = np.sum(sizes['nonlinear']['output'][iproc, :])

        int_mtx._build(out_size, out_size)
        if ext_mtx._submats:
            in_size = np.sum(sizes['nonlinear']['input'][iproc, :])
            ext_mtx._build(out_size, in_size)
        else:
            ext_mtx = None

        self._ext_mtx[system.pathname] = ext_mtx
    def _initialize(self):
        """
        Allocate the global matrices.
        """
        # var_indices are the *global* indices for variables on this proc
        system = self._system
        is_top = system.pathname == ''

        abs2meta = system._var_abs2meta

        self._int_mtx = int_mtx = self.options['matrix_class'](system.comm)
        ext_mtx = self.options['matrix_class'](system.comm)

        out_ranges = {
            abs_name: self._get_var_range(abs_name, 'output')
            for abs_name in system._var_allprocs_abs_names['output']
        }

        in_ranges = {
            abs_name: self._get_var_range(abs_name, 'input')
            for abs_name in system._var_allprocs_abs_names['input']
        }

        # set up view ranges for all subsystems
        for s in system.system_iter(recurse=True, include_self=True):
            input_names = s._var_abs_names['input']
            if input_names:
                min_in_offset = in_ranges[input_names[0]][0]
                max_in_offset = in_ranges[input_names[-1]][1]
            else:
                min_in_offset = sys.maxsize
                max_in_offset = 0

            output_names = s._var_abs_names['output']
            if output_names:
                min_res_offset = out_ranges[output_names[0]][0]
                max_res_offset = out_ranges[output_names[-1]][1]
            else:
                min_res_offset = sys.maxsize
                max_res_offset = 0

            self._view_ranges[s.pathname] = (min_res_offset, max_res_offset,
                                             min_in_offset, max_in_offset)

        # # keep track of mapped keys to check for corner case where one source connects to
        # # multiple inputs using src_indices on the same component.
        # mapped_keys = {}

        abs2prom_out = system._var_abs2prom['output']
        conns = system._conn_global_abs_in2out
        keymap = self._keymap
        abs_key2shape = self._abs_key2shape

        # create the matrix subjacs
        for abs_key, (info, shape) in iteritems(self._subjacs_info):
            if not info['dependent']:
                continue
            res_abs_name, wrt_abs_name = abs_key
            # because self._subjacs_info is shared among all 'related' assembled jacs,
            # we use out_ranges (and later in_ranges) to weed out keys outside of this jac
            if res_abs_name not in out_ranges:
                continue
            res_offset, _ = out_ranges[res_abs_name]

            if wrt_abs_name in abs2prom_out:
                out_offset, _ = out_ranges[wrt_abs_name]
                int_mtx._add_submat(abs_key, info, res_offset, out_offset,
                                    None, shape)
                keymap[abs_key] = abs_key
            elif wrt_abs_name in in_ranges:
                if wrt_abs_name in conns:  # connected input
                    out_abs_name = conns[wrt_abs_name]
                    # calculate unit conversion
                    in_units = abs2meta[wrt_abs_name]['units']
                    out_units = abs2meta[out_abs_name]['units']
                    if in_units and out_units and in_units != out_units:
                        factor, _ = get_conversion(out_units, in_units)
                        if factor == 1.0:
                            factor = None
                    else:
                        factor = None

                    out_offset, _ = out_ranges[out_abs_name]
                    src_indices = abs2meta[wrt_abs_name]['src_indices']

                    # need to add an entry for d(output)/d(source)
                    # instead of d(output)/d(input)
                    abs_key2 = (res_abs_name, out_abs_name)
                    keymap[abs_key] = abs_key2

                    shape = abs_key2shape(abs_key2)

                    int_mtx._add_submat(abs_key, info, res_offset, out_offset,
                                        src_indices, shape, factor)

                elif not is_top:  # input is connected to something outside current system
                    ext_mtx._add_submat(abs_key, info, res_offset,
                                        in_ranges[wrt_abs_name][0], None,
                                        shape)

        sizes = system._var_sizes
        iproc = system.comm.rank
        out_size = np.sum(sizes['nonlinear']['output'][iproc, :])

        int_mtx._build(out_size, out_size)
        if ext_mtx._submats:
            in_size = np.sum(sizes['nonlinear']['input'][iproc, :])
            ext_mtx._build(out_size, in_size)
        else:
            ext_mtx = None

        self._ext_mtx[system.pathname] = ext_mtx