Add grid_shape pre/postcondition checks.

This PR is not ready. It simply adds the checks we want on `grid_shape`. But the code does not conform to these. In particular: `all(gs <= s for (s, gs) in zip(shape, grid_shape) if s > 0)`. 

Once this condition is satisfied and this is merged this will close issue #406
I think the order of operations should be changed here.  We should first get a fully validated and normalized `self.grid_shape`, then get `self.targets`, then get `self.comm`.

Would this work?

```python
if grid_shape is None:
    grid_shape = make_grid_shape(...)
self.grid_shape = normalize_grid_shape(grid_shape, self.shape, self.dist, len(all_targets))
self.targets = [...] # as before
self.comm = self.context._make_subcomm(self.targets)
```