def setup(self, check=True, out_stream=sys.stdout):
        """Performs all setup of vector storage, data transfer, etc.,
        necessary to perform calculations.

        Args
        ----
        check : bool, optional
            Check for potential issues after setup is complete (the default
            is True)

        out_stream : a file-like object, optional
            Stream where report will be written if check is performed.
        """
        self._setup_errors = []

        # if we modify the system tree, we'll need to call _init_sys_data,
        # _setup_variables and _setup_connections again
        tree_changed = False

        # call _setup_variables again if we change metadata
        meta_changed = False

        self._probdata = _ProbData()
        if isinstance(self.root.ln_solver, LinearGaussSeidel):
            self._probdata.top_lin_gs = True

        self.driver.root = self.root

        # Give every system an absolute pathname
        self.root._init_sys_data(self.pathname, self._probdata)

        # divide MPI communicators among subsystems
        self._setup_communicators()

        # Returns the parameters and unknowns metadata dictionaries
        # for the root, which has an entry for each variable contained
        # in any child of root. Metadata for each variable will contain
        # the name of the variable relative to that system, the absolute
        # name of the variable, any user defined metadata, and the value,
        # size and/or shape if known. For example:
        #  unknowns_dict['G1.G2.foo.v1'] = {
        #     'pathname' : 'G1.G2.foo.v1', # absolute path from the top
        #     'size' : 1,
        #     'shape' : 1,
        #     'val': 2.5,   # the initial value of that variable (if known)
        #  }
        params_dict, unknowns_dict = self.root._setup_variables()

        self._probdata.params_dict = params_dict
        self._probdata.unknowns_dict = unknowns_dict
        self._probdata.to_prom_name = self.root._sysdata.to_prom_name

        # collect all connections, both implicit and explicit from
        # anywhere in the tree, and put them in a dict where each key
        # is an absolute param name that maps to the absolute name of
        # a single source.
        connections = self._setup_connections(params_dict, unknowns_dict)
        self._probdata.connections = connections

        for tgt, (src, idxs) in iteritems(connections):
            tmeta = params_dict[tgt]
            if 'pass_by_obj' not in tmeta or not tmeta['pass_by_obj']:

                # Allow the user to omit the size of a parameter and pull
                # the size and shape from the connection source.
                if tmeta['shape'] == ():

                    smeta = unknowns_dict[src]

                    # Connected with src_indices specified
                    if idxs is not None:
                        size = len(idxs)
                        tmeta['shape'] = (size, )
                        tmeta['size'] = size
                        tmeta['val'] = smeta['val'][np.array(idxs)]

                    # Regular connection
                    else:
                        tmeta['shape'] = smeta['shape']
                        tmeta['size'] = smeta['size']
                        tmeta['val'] = smeta['val']

                # set src_indices into variable metadata
                if idxs is not None:
                    if isinstance(idxs, np.ndarray):
                        tmeta['src_indices'] = idxs
                    else:
                        tmeta['src_indices'] = np.array(idxs,
                                                  dtype=self._impl.idx_arr_type)

        # TODO: handle any automatic grouping of systems here...
        #       If we modify the system tree here, we'll have to call
        #       the full setup over again...

        if MPI:
            for s in self.root.components(recurse=True):
                # TODO: get rid of check for setup_distrib_idxs when we move to beta
                if hasattr(s, 'setup_distrib_idxs') or (
                         hasattr(s, 'setup_distrib') and (s.setup_distrib
                                                is not Component.setup_distrib)):
                    # component defines its own setup_distrib, so
                    # the metadata will change
                    meta_changed = True

        # All changes to the system tree or variable metadata
        # must be complete at this point.

        # if the system tree has changed, we have to redo the entire setup
        if tree_changed:
            return self.setup(check=check, out_stream=out_stream)
        elif meta_changed:
            params_dict, unknowns_dict = \
                self.root._setup_variables(compute_indices=True)

        # perform additional checks on connections
        # (e.g. for compatible types and shapes)
        self._setup_errors.extend(check_connections(connections, params_dict,
                                               unknowns_dict,
                                               self.root._sysdata.to_prom_name))

        # calculate unit conversions and store in param metadata
        self._setup_units(connections, params_dict, unknowns_dict)

        # propagate top level promoted names, unit conversions,
        # and connections down to all subsystems
        to_prom_name = self.root._sysdata.to_prom_name
        self._probdata.to_prom_name = to_prom_name

        for path, meta in iteritems(params_dict):
            # set top promoted name into var metadata
            meta['top_promoted_name'] = to_prom_name[path]

            # Check for dangling params that have no size or shape
            if path not in connections:
                if 'pass_by_obj' not in meta or not meta['pass_by_obj']:
                    if meta['shape'] == ():
                        self._setup_errors.append("Unconnected param '{}' is missing "
                                           "a shape or default value.".format(path))

        for path, meta in iteritems(unknowns_dict):
            meta['top_promoted_name'] = to_prom_name[path]

        # Given connection information, create mapping from system pathname
        # to the parameters that system must transfer data to
        param_owners = _assign_parameters(connections)

        pois = self.driver.desvars_of_interest()
        oois = self.driver.outputs_of_interest()

        self._driver_vois = set()
        for tup in chain(pois, oois):
            self._driver_vois.update(tup)

        # make sure pois and oois all refer to existing vars.
        # NOTE: all variables of interest (includeing POIs) must exist in
        #      the unknowns dict
        promoted_unknowns = self.root._sysdata.to_abs_uname

        parallel_p = False
        for vnames in pois:
            if len(vnames) > 1:
                parallel_p = True
            for v in vnames:
                if v not in promoted_unknowns:
                    raise NameError("Can't find param of interest '%s'." % v)

        parallel_u = False
        for vnames in oois:
            if len(vnames) > 1:
                parallel_u = True
            for v in vnames:
                if v not in promoted_unknowns:
                    raise NameError("Can't find quantity of interest '%s'." % v)

        mode = self._check_for_parallel_derivs(pois, oois, parallel_u, parallel_p)

        self._probdata.relevance = Relevance(self.root, params_dict,
                                             unknowns_dict, connections,
                                             pois, oois, mode)

        # perform auto ordering
        for s in self.root.subgroups(recurse=True, include_self=True):
            # set auto order if order not already set
            if not s._order_set:
                order = None
                broken_edges = None
                if self.comm.rank == 0:
                    order, broken_edges = s.list_auto_order()
                if MPI:
                    if trace:
                        debug("problem setup order bcast")
                    order, broken_edges = self.comm.bcast((order, broken_edges), root=0)
                    if trace:
                        debug("problem setup order bcast DONE")
                s.set_order(order)

                # Mark "head" of each broken edge
                for edge in broken_edges:
                    cname = edge[1]
                    head_sys = self.root
                    for name in cname.split('.'):
                        head_sys = getattr(head_sys, name)
                    head_sys._run_apply = True

        # report any differences in units or initial values for
        # sourceless connected inputs
        self._check_input_diffs(connections, params_dict, unknowns_dict)

        # If we force_fd root and don't need derivatives in solvers, then we
        # don't have to allocate any deriv vectors.
        alloc_derivs = not self.root.fd_options['force_fd']
        for sub in self.root.subgroups(recurse=True, include_self=True):
            alloc_derivs = alloc_derivs or sub.nl_solver.supports['uses_derivatives']

        # create VecWrappers for all systems in the tree.
        self.root._setup_vectors(param_owners, impl=self._impl, alloc_derivs=alloc_derivs)

        # Prepare Driver
        self.driver._setup()

        # get map of vars to VOI indices
        self._poi_indices, self._qoi_indices = self.driver._map_voi_indices()

        # Prepare Solvers
        for sub in self.root.subgroups(recurse=True, include_self=True):
            sub.nl_solver.setup(sub)
            sub.ln_solver.setup(sub)

        self._check_solvers()

        # Prep for case recording and record metadata
        self._start_recorders()

        if self._setup_errors:
            stream = cStringIO()
            stream.write("\nThe following errors occurred during setup:\n")
            for err in self._setup_errors:
                stream.write("%s\n" % err)
            raise RuntimeError(stream.getvalue())

        # Lock any restricted options in the options dictionaries.
        OptionsDictionary.locked = True

        # check for any potential issues
        if check or force_check:
            return self.check_setup(out_stream)

        return {}
dataset/ETHPy150Open OpenMDAO/OpenMDAO/openmdao/core/problem.py/Problem.setup/original