DMDA: add ownership ranges

Adds support for DMDAGetOwnershipRanges() and the lx, ly, lz arguments
to DMDACreateND().
Add support for DMComposite

DMComposite couples multiple DMs into a single DM that can be used with
solvers. The implementation will fail at run-time when routines are not
available (e.g., with petsc-3.3).

An example construction for a PDE-constrained optimization problem:

    da_pde = PETSc.DMDA().create(sizes=[m,n], proc_sizes=[1,PETSc.DECIDE], dof=2)
    da_pde.setOptionsPrefix('pde_')
    da_pde.setFromOptions()

    sizes = list(da_pde.getSizes())
    proc_sizes = da_pde.getProcSizes()
    sizes[0] = 1                # only one point in x (space) dimension
    da_control = PETSc.DMDA().create(sizes=sizes, proc_sizes=proc_sizes, dof=1)
    da_control.setOptionsPrefix('control_')
    da_control.setFromOptions()
    da_control.view()

    pack = PETSc.DMComposite().create()
    pack.setOptionsPrefix('pack_')
    pack.addDM(da_pde)
    pack.addDM(da_control)
    pack.view()

The composite array can be accessed using:

    da_pde, da_control = pack.getEntries()
    with pack.getAccess(X, (0,1)) as (U, C):
        with da_pde.getVecArray(U) as u:
            # set u[i,j,0] and u[i,j,1]
        with da_control.getVecArray(C) as c:
            # set c[i,j]