Add a function that allows us to query a colored set of cells.

Here is a more complete description of what is happening:

1/ This function is called on a separate task upon calling distribute_dofs() to run
in the background for when we need the result at a later time.

2/ This also introduces new member functions that require us to adjust
the memory statistics.

The new objects increase memory use by DoFHandler by about 1/7th for Q(1)
elements and likely much less for more interesting elements (because the
memory consumption of the set of colored cells only depends on the number
of cells, not on the number of DoFs per cell. On the other hand, memory
consumption of the DoFHandler is not a large fraction of overall memory
use in programs. For example, for a program derived from step-6 (namely,
tests/deal.II/memory_consumption_01.cc), we have these statistics after
the change:

DEAL::Cycle 3:
DEAL::   Number of active cells:       3248
DEAL::   Number of degrees of freedom: 32433
DEAL::Memory consumption -- Triangulation: 1375395
DEAL::Memory consumption -- DoFHandler:    620480
DEAL::Memory consumption -- FE:            12280
DEAL::Memory consumption -- Constraints:   1307806
DEAL::Memory consumption -- Sparsity:      8321760
DEAL::Memory consumption -- Matrix:        16383928
DEAL::Memory consumption -- Solution:      259552
DEAL::Memory consumption -- Rhs:           259552
DEAL::Memory consumption -- DataOut:       1159725

In other words, the DoFHandler is a very small fraction of the matrix,
for example, and this fraction only becomes smaller for more complex
problems with more entries per row in the matrix.

3/ Of course, there is a cost to all of this. Here is some timing
information, with and without the new functionality, for a modified
version of step-6 (using 10 instead of 8 refinement cycles; 3 runs
each, I'm only showing the fastest one):

  debug mode (previously):
    real    0m46.703s
    user    3m29.468s
    sys     0m40.032s
  debug mode with new functionality:
    real    0m46.014s
    user    3m39.464s
    sys     0m39.524s

  release (previously):
    real    0m12.660s
    user    1m56.408s
    sys     0m26.108s
  release mode with new functionality:
    real    0m12.728s
    user    1m56.608s
    sys     0m24.312s

In other words, this increases debug overall CPU time slightly (~5%)
but does not noticeably increase wallclock time -- exactly what we
wanted. Of course, the goal is to eventually use this information
elsewhere and reduce the wallclock time.

4/ To be usable in realistic situations, this function also needs to
take into account hanging node constraints and so internally calls
DoFTools::make_hanging_node_constraints().
Add a number of adapted testcases that use the prebuilt graph from DoFHandler.