Set dataset having displacements and optionally forces

        Note
        ----
        Elements of the list accessed by 'first_atoms' corresponds to each
        displaced supercell. Each displaced supercell contains only one
        displacement. dict['first_atoms']['forces'] gives atomic forces in
        each displaced supercell.

        Parameters
        ----------
        displacement_dataset : dict
            There are two dict structures.
            Type 1. One atomic displacement in each supercell:
                {'natom': number of atoms in supercell,
                 'first_atoms': [
                   {'number': atom index of displaced atom,
                    'displacement': displacement in Cartesian coordinates,
                    'forces': forces on atoms in supercell},
                   {...}, ...]}
            Type 2. All atomic displacements in each supercell:
                {'natom': number of atoms in supercell,
                 'displacements': ndarray, dtype='double', order='C',
                                  shape=(supercells, natom, 3)
                 'forces': ndarray, dtype='double',, order='C',
                                  shape=(supercells, natom, 3)}
            In type 2, displacements and forces can be given by numpy array
            with different shape but that can be reshaped to
            (supercells, natom, 3).

def dataset(self, dataset):
        """Set dataset having displacements and optionally forces

        Note
        ----
        Elements of the list accessed by 'first_atoms' corresponds to each
        displaced supercell. Each displaced supercell contains only one
        displacement. dict['first_atoms']['forces'] gives atomic forces in
        each displaced supercell.

        Parameters
        ----------
        displacement_dataset : dict
            There are two dict structures.
            Type 1. One atomic displacement in each supercell:
                {'natom': number of atoms in supercell,
                 'first_atoms': [
                   {'number': atom index of displaced atom,
                    'displacement': displacement in Cartesian coordinates,
                    'forces': forces on atoms in supercell},
                   {...}, ...]}
            Type 2. All atomic displacements in each supercell:
                {'natom': number of atoms in supercell,
                 'displacements': ndarray, dtype='double', order='C',
                                  shape=(supercells, natom, 3)
                 'forces': ndarray, dtype='double',, order='C',
                                  shape=(supercells, natom, 3)}
            In type 2, displacements and forces can be given by numpy array
            with different shape but that can be reshaped to
            (supercells, natom, 3).

        """

        if 'displacements' in dataset:
            natom = self._supercell.get_number_of_atoms()
            if type(dataset['displacements']) is np.ndarray:
                if dataset['displacements'].ndim in (1, 2):
                    d = dataset['displacements'].reshape((-1, natom, 3))
                    dataset['displacements'] = d
            if type(dataset['forces']) is np.ndarray:
                if dataset['forces'].ndim in (1, 2):
                    f = dataset['forces'].reshape((-1, natom, 3))
                    dataset['forces'] = f
        self._displacement_dataset = dataset
        self._supercells_with_displacements = None