Create entries for multi-element Pourbaix construction.

        This works by finding all possible linear combinations
        of entries that can result in the specified composition
        from the initialized comp_dict.

        Args:
            entries ([PourbaixEntries]): list of pourbaix entries
                to process into MultiEntries
            forced_include ([PourbaixEntries]) list of pourbaix entries
                that must be included in multielement entries
            nproc (int): number of processes to be used in parallel
                treatment of entry combos

def _generate_multielement_entries(self, entries, forced_include=None,
                                       nproc=None):
        """
        Create entries for multi-element Pourbaix construction.

        This works by finding all possible linear combinations
        of entries that can result in the specified composition
        from the initialized comp_dict.

        Args:
            entries ([PourbaixEntries]): list of pourbaix entries
                to process into MultiEntries
            forced_include ([PourbaixEntries]) list of pourbaix entries
                that must be included in multielement entries
            nproc (int): number of processes to be used in parallel
                treatment of entry combos
        """
        N = len(self._elt_comp)  # No. of elements
        total_comp = Composition(self._elt_comp)
        forced_include = forced_include or []

        # generate all combinations of compounds that have all elements
        entry_combos = [itertools.combinations(
            entries, j + 1 - len(forced_include)) for j in range(N)]
        entry_combos = itertools.chain.from_iterable(entry_combos)
        if forced_include:
            entry_combos = [forced_include + list(ec) for ec in entry_combos]
        entry_combos = filter(lambda x: total_comp < MultiEntry(x).composition,
                              entry_combos)

        # Generate and filter entries
        processed_entries = []
        total = sum([comb(len(entries), j + 1 - len(forced_include))
                     for j in range(N)])
        if total > 1e6:
            warnings.warn("Your pourbaix diagram includes {} entries and may "
                          "take a long time to generate.".format(total))

        # Parallel processing of multi-entry generation
        if nproc is not None:
            f = partial(self.process_multientry, prod_comp=total_comp)
            with Pool(nproc) as p:
                processed_entries = list(tqdm(p.imap(f, entry_combos),
                                              total=total))
            processed_entries = list(filter(bool, processed_entries))
        # Serial processing of multi-entry generation
        else:
            for entry_combo in entry_combos:
                processed_entry = self.process_multientry(entry_combo, total_comp)
                if processed_entry is not None:
                    processed_entries.append(processed_entry)

        return processed_entries