def _check_solvers(self):
        """ Search over all solvers and raise errors for unsupported
        configurations. These include:

        Raise an exception if we detect a LinearGaussSeidel
        solver and that group has either cycles or uniterated states.

        Raise an exception if a Newton solver is found under any system that
        is set to complex step.
        """

        # all states that have some maxiter>1 linear solver above them in the tree
        iterated_states = set()
        group_states = []

        has_iter_solver = {}
        for group in self.root.subgroups(recurse=True, include_self=True):
            try:
                has_iter_solver[group.pathname] = (group.ln_solver.options['maxiter'] > 1)
            except KeyError:

                # DirectSolver handles coupled derivatives without iteration
                if isinstance(group.ln_solver, DirectSolver):
                    has_iter_solver[group.pathname] = (True)

            # Look for nl solvers that require derivs under Complex Step.
            opt = group.fd_options
            if opt['force_fd'] == True and opt['form'] == 'complex_step':

                # TODO: Support using complex step on a subsystem
                if group.name != '':
                    msg = "Complex step is currently not supported for groups"
                    msg += " other than root."
                    self._setup_errors.append(msg)

                # Complex Step, so check for deriv requirement in subsolvers
                for sub in self.root.subgroups(recurse=True, include_self=True):
                    if hasattr(sub.nl_solver, 'ln_solver'):
                        msg = "The solver in '{}' requires derivatives. We "
                        msg += "currently do not support complex step around it."
                        self._setup_errors.append(msg.format(sub.name))

            parts = group.pathname.split('.')
            for i in range(len(parts)):
                # if an ancestor solver iterates, we're ok
                if has_iter_solver['.'.join(parts[:i])]:
                    is_iterated_somewhere = True
                    break
            else:
                is_iterated_somewhere = False

            # if we're iterated at this level or somewhere above, then it's
            # ok if we have cycles or states.
            if is_iterated_somewhere:
                continue

            if isinstance(group.ln_solver, LinearGaussSeidel) and \
                                     group.ln_solver.options['maxiter'] == 1:
                # If group has a cycle and lings can't iterate, that's
                # an error if current lin solver or ancestor lin solver doesn't
                # iterate.
                graph = group._get_sys_graph()
                strong = [sorted(s) for s in nx.strongly_connected_components(graph)
                          if len(s) > 1]
                if strong:
                    self._setup_errors.append("Group '%s' has a LinearGaussSeidel "
                                   "solver with maxiter==1 but it contains "
                                   "cycles %s. To fix this error, change to "
                                   "a different linear solver, e.g. ScipyGMRES "
                                   "or PetscKSP, or increase maxiter (not "
                                   "recommended)."
                                   % (group.pathname, strong))

            states = [n for n,m in iteritems(group._unknowns_dict) if m.get('state')]
            if states:
                group_states.append((group, states))

                # this group has an iterative lin solver, so all states in it are ok
                if isinstance(group.ln_solver, DirectSolver) or \
                   group.ln_solver.options['maxiter'] > 1:
                    iterated_states.update(states)
                else:
                    # see if any states are in comps that have their own
                    # solve_linear method
                    for s in states:
                        if s not in iterated_states:
                            cname = s.rsplit('.', 1)[0]
                            comp = self.root
                            for name in cname.split('.'):
                                comp = getattr(comp, name)
                            if not _needs_iteration(comp):
                                iterated_states.add(s)

        for group, states in group_states:
            uniterated_states = [s for s in states if s not in iterated_states]

            # It's an error if we find states that don't have some
            # iterative linear solver as a parent somewhere in the tree, or they
            # don't live in a Component that defines its own solve_linear method.

            if uniterated_states:
                self._setup_errors.append("Group '%s' has a LinearGaussSeidel "
                               "solver with maxiter==1 but it contains "
                               "implicit states %s. To fix this error, "
                               "change to a different linear solver, e.g. "
                               "ScipyGMRES or PetscKSP, or increase maxiter "
                               "(not recommended)." %
                               (group.pathname, uniterated_states))
dataset/ETHPy150Open OpenMDAO/OpenMDAO/openmdao/core/problem.py/Problem._check_solvers/original