Construct a `PhononWfkqWork` from a DDB and DVDB file.
        For each q found, a WFQ task and an EPH task computing the matrix elements are created.

def from_den_ddb_dvdb(cls, inp, den_path, ddb_path, dvdb_path, mpiprocs=1, remove_wfkq=True,
                          qpath=None, with_ddk=True, expand=True, manager=None):
        """
        Construct a `PhononWfkqWork` from a DDB and DVDB file.
        For each q found, a WFQ task and an EPH task computing the matrix elements are created.
        """
        import abipy.abilab as abilab

        # Create file nodes
        den_file = FileNode(den_path)
        ddb_file = FileNode(ddb_path)
        dvdb_file = FileNode(dvdb_path)

        # Create new work
        new = cls(manager=manager)
        new.remove_wfkq = remove_wfkq
        new.wfkq_tasks = []
        new.wfkq_task_children = collections.defaultdict(list)
        if manager is None: manager = TaskManager.from_user_config()
        tm = manager.new_with_fixed_mpi_omp(mpiprocs, 1)

        # Create a WFK task
        kptopt = 1 if expand else 3
        nscf_inp = inp.new_with_vars(iscf=-2, kptopt=kptopt)
        wfk_task = new.register_nscf_task(nscf_inp, deps={den_file: "DEN"},manager=tm)
        new.wfkq_tasks.append(wfk_task)
        new.wfk_task = wfk_task

        # Read path and regular grid from DDB file
        with abilab.abiopen(ddb_path) as ddb:
            q_frac_coords = np.array([k.frac_coords for k in ddb.qpoints])
            ddb_ngqpt = ddb.guessed_ngqpt

        # If qpath is set, we read the list of q-points to be used to interpolate the DVDB file.
        # The DVDB and DDB file have to correspond to a regular grid.
        dvdb = dvdb_file
        if qpath is None:
            qpath = q_frac_coords
        else:
            interp_inp = inp.new_with_vars(optdriver=7, eph_task=-5, ddb_ngqpt=ddb_ngqpt,
                                           ph_nqpath=len(qpath), ph_qpath=qpath, prtphdos=0)
            dvdb = new.register_eph_task(interp_inp, deps={wfk_task: "WFK", ddb_file: "DDB", dvdb_file: "DVDB"},
                                          manager=tm)

        # Create a WFK expansion task
        if expand:
            fbz_nscf_inp = inp.new_with_vars(optdriver=8)
            fbz_nscf_inp.set_spell_check(False)
            fbz_nscf_inp.set_vars(wfk_task="wfk_fullbz")
            tm_serial = manager.new_with_fixed_mpi_omp(1,1)
            wfk_task = new.register_nscf_task(fbz_nscf_inp, deps={wfk_task: "WFK", den_file: "DEN"},
                                              manager=tm_serial)
            new.wfkq_tasks.append(wfk_task)
            new.wfk_task = wfk_task

        if with_ddk:
            kptopt = 3 if expand else 1
            ddk_inp = inp.new_with_vars(optdriver=8,kptopt=kptopt)
            ddk_inp.set_spell_check(False)
            ddk_inp.set_vars(wfk_task="wfk_ddk")
            ddk_task = new.register_nscf_task(ddk_inp, deps={wfk_task: "WFK", den_file: "DEN"}, manager=tm)
            new.wfkq_tasks.append(ddk_task)

        # For each qpoint
        for qpt in qpath:
            is_gamma = np.sum(qpt ** 2) < 1e-12
            if is_gamma:
                # Create a link from WFK to WFQ on_ok
                wfkq_task = wfk_task
                deps = {wfk_task: ["WFK","WFQ"], ddb_file: "DDB", dvdb: "DVDB" }
            else:
                # Create a WFQ task
                nscf_inp = nscf_inp.new_with_vars(kptopt=3, qpt=qpt, nqpt=1)
                wfkq_task = new.register_nscf_task(nscf_inp, deps={den_file: "DEN"}, manager=tm)
                new.wfkq_tasks.append(wfkq_task)
                deps = {wfk_task: "WFK", wfkq_task: "WFQ", ddb_file: "DDB", dvdb: "DVDB" }

            # Create a EPH task
            eph_inp = inp.new_with_vars(optdriver=7, prtphdos=0, eph_task=-2, kptopt=3,
                                        ddb_ngqpt=[1,1,1], nqpt=1, qpt=qpt)
            t = new.register_eph_task(eph_inp, deps=deps, manager=tm)
            new.wfkq_task_children[wfkq_task].append(t)

        return new