Initial changes to build topological maps

structured_grid.py::

    - class, which is derived from numpy.ndarray, to hold the
structured grid.
    - Built over the top of a pymatgen.core.structure object, which
defines atom positions and periodicity vectors.
    - Data is stored in C format, i.e. row-dominant, as opposed to
FORTRAN’s column-dominant format.
    - Access is through a 3D numpy array, i.e. grid[i, j, k]

vasp_output.py::
    - minor changes to modify VolumetricData (and its derivatives) to
use StructuredGrid.
    - maintained compatibility with the API of VolumetricData, but did
add DeprecationWarnings where the functionality of StructuredGrid
overlaps, e.g. VolumetricData.data is now accessed directly as a numpy
array. Similarly, VolumetricData.shape should be used in preference to
VolumetricData.dim.
    - vaspio/tests passed using these modifications

dijkstra_path.py::

    - Implementation of the Dijkstra algorithm for finding the lowest
cost path through a graph structure.

    - To do: reimplement this to use a heap.
Dijkstra optimization -- not backward compatible

Implemented a heap algorithm to calculate the Dijkstra path. Also made
backward-incompatible changes to the interface. Rather than evaluating
a single path, the cost is stored and accessed through a property of
the same name for a given start point. That way, multiple paths can be
investigated without having to recalculate, as long as the start point
remains invariant.

Evaluation is tied to the start point:

    - changing the grid through DijkstraPath.grid = grid invalidates
the start point and resets cost_function to the default.
    - changing the cost function, if start is set, sparks an immediate
recalculation. Set start to None to avoid recalculation.
    - Changing the start point sparks an immediate recalculation.