@contextmanager
    def vecscatter(self, readonly=True):

        assert self.dtype == PETSc.ScalarType, \
            "Can't create Vec with type %s, must be %s" % (self.dtype, PETSc.ScalarType)
        acc = (lambda d: d.vec_ro) if readonly else (lambda d: d.vec)
        # Allocate memory for the contiguous vector
        if not hasattr(self, '_vec'):
            # In this case we can just duplicate the layout vec
            # because we're not placing an array.
            self._vec = self.dataset.layout_vec.duplicate()

        scatters = self.dataset.vecscatters
        # Do the actual forward scatter to fill the full vector with values
        for d, vscat in zip(self, scatters):
            with acc(d) as v:
                vscat.scatterBegin(v, self._vec, addv=PETSc.InsertMode.INSERT_VALUES)
                vscat.scatterEnd(v, self._vec, addv=PETSc.InsertMode.INSERT_VALUES)
        yield self._vec
        if not readonly:
            # Reverse scatter to get the values back to their original locations
            for d, vscat in zip(self, scatters):
                with acc(d) as v:
                    vscat.scatterBegin(self._vec, v, addv=PETSc.InsertMode.INSERT_VALUES,
                                       mode=PETSc.ScatterMode.REVERSE)
                    vscat.scatterEnd(self._vec, v, addv=PETSc.InsertMode.INSERT_VALUES,
                                     mode=PETSc.ScatterMode.REVERSE)
            self.needs_halo_update = True
A context manager scattering the arrays of all components of this
dataset/ETHPy150Open OP2/PyOP2/pyop2/petsc_base.py/MixedDat.vecscatter