Beispiel #1
0
    def __init__(self, **kwargs):
        self._kwargs = copy.deepcopy(kwargs)

        fw_policy = kwargs.pop('fw_policy', {})
        unknown_keys = set(fw_policy.keys()) - set(self.fw_policy_defaults.keys())
        if unknown_keys:
            msg = "Unknown key(s) present in fw_policy: {}".format(", ".join(unknown_keys))
            logger.error(msg)
            raise RuntimeError(msg)
        fw_policy = dict(self.fw_policy_defaults, **fw_policy)

        # make a namedtuple for easier access to the attributes
        self.fw_policy = self.FWPolicy(**fw_policy)

        #TODO consider if raising an exception if it's requested when not available
        # create the task manager only if possibile
        if 'qadapters' in kwargs:
            self.task_manager = TaskManager.from_dict(kwargs)
            msg = "Loading the abipy TaskManager from inside the fw_manager.yaml file is deprecated. " \
                  "Use a separate file"
            logger.warning(msg)
            warnings.warn(msg, DeprecationWarning, stacklevel=2)
        else:
            if self.fw_policy.abipy_manager:
                self.task_manager = TaskManager.from_file(self.fw_policy.abipy_manager)
            else:
                try:
                    self.task_manager = TaskManager.from_user_config()
                except:
                    logger.warning("Couldn't load the abipy task manager.")
                    self.task_manager = None
Beispiel #2
0
    def __init__(self, **kwargs):
        self._kwargs = copy.deepcopy(kwargs)

        fw_policy = kwargs.pop('fw_policy', {})
        unknown_keys = set(fw_policy.keys()) - set(
            self.fw_policy_defaults.keys())
        if unknown_keys:
            msg = "Unknown key(s) present in fw_policy: {}".format(
                ", ".join(unknown_keys))
            logger.error(msg)
            raise RuntimeError(msg)
        fw_policy = dict(self.fw_policy_defaults, **fw_policy)

        # make a namedtuple for easier access to the attributes
        self.fw_policy = self.FWPolicy(**fw_policy)

        #TODO consider if raising an exception if it's requested when not available
        # create the task manager only if possibile
        if 'qadapters' in kwargs:
            self.task_manager = TaskManager.from_dict(kwargs)
            msg = "Loading the abipy TaskManager from inside the fw_manager.yaml file is deprecated. " \
                  "Use a separate file"
            logger.warning(msg)
            warnings.warn(msg, DeprecationWarning, stacklevel=2)
        else:
            if self.fw_policy.abipy_manager:
                self.task_manager = TaskManager.from_file(
                    self.fw_policy.abipy_manager)
            else:
                try:
                    self.task_manager = TaskManager.from_user_config()
                except:
                    logger.warning("Couldn't load the abipy task manager.")
                    self.task_manager = None
Beispiel #3
0
    def run_anaddb(self, item, workdir):
        """
        Runs anaddb an reads the outputs
        """

        anaddb_inp, labels_list = self.get_anaddb_input(item)

        #TODO should this be an input?
        tm = TaskManager.from_user_config()

        ddb_path = item["ddb_path"]

        task = AnaddbTask.temp_shell_task(anaddb_inp, ddb_node=ddb_path, workdir=workdir, manager=tm)

        # Run the task here.
        task.start_and_wait(autoparal=False)

        report = task.get_event_report()
        if not report.run_completed:
            raise AnaddbError(task=task, report=report)

        phbst_file = task.open_phbst()
        phdos_file = task.open_phdos()
        ananc_file = AnaddbNcFile.from_file(os.path.join(workdir, "anaddb.nc"))

        return phbst_file, phdos_file, ananc_file, labels_list
Beispiel #4
0
    def itest_phonon_wfq_wf(self, lp, fworker, tmpdir, input_scf_phonon_si_low,
                            db_data):
        """
        Tests the PhononFullFWWorkflow and PhononFWWorkflow
        """
        qpt = [[0.1111, 0.2222, 0.3333]]

        # test at gamma. Pass a custom manager, to check proper serialization
        manager_path = os.path.join(abidata.dirpath, 'managers',
                                    "travis_manager.yml")
        ph_fac = PhononsFromGsFactory(
            qpoints=qpt,
            ph_tol={"tolvrs": 1.0e-7},
            wfq_tol={"tolwfr": 1.0e-16},
            with_ddk=False,
            with_dde=False,
            manager=TaskManager.from_file(manager_path))

        # first run the phonon workflow with generation task
        wf_gen = PhononFWWorkflow(input_scf_phonon_si_low,
                                  ph_fac,
                                  autoparal=False,
                                  initialization_info={
                                      "qpoints": qpt,
                                      "kppa": 100
                                  })

        wf_gen.add_mongoengine_db_insertion(db_data)

        scf_id = wf_gen.scf_fw.fw_id
        old_new = wf_gen.add_to_db(lpad=lp)
        scf_id = old_new[scf_id]

        # run all the workflow
        rapidfire(lp, fworker, m_dir=str(tmpdir))

        wf_gen = lp.get_wf_by_fw_id(scf_id)

        assert wf_gen.state == "COMPLETED"

        # then rerun a similar workflow, but completely generated at its creation
        wf_full = PhononFullFWWorkflow(input_scf_phonon_si_low,
                                       ph_fac,
                                       autoparal=False)

        scf_id = wf_full.scf_fw.fw_id
        old_new = wf_full.add_to_db(lpad=lp)
        scf_id = old_new[scf_id]

        # run all the workflow
        rapidfire(lp, fworker, m_dir=str(tmpdir))

        wf_full = lp.get_wf_by_fw_id(scf_id)

        assert wf_full.state == "COMPLETED"
Beispiel #5
0
    def itest_phonon_wfq_wf(self, lp, fworker, tmpdir, input_scf_phonon_si_low, db_data):
        """
        Tests the PhononFullFWWorkflow and PhononFWWorkflow
        """
        qpt = [[0.1111,0.2222,0.3333]]

        # test at gamma. Pass a custom manager, to check proper serialization
        manager_path = os.path.join(abidata.dirpath, 'managers', "travis_manager.yml")
        ph_fac = PhononsFromGsFactory(qpoints=qpt, ph_tol = {"tolvrs": 1.0e-7},
                                      wfq_tol = {"tolwfr": 1.0e-16}, with_ddk=False, with_dde=False,
                                      manager=TaskManager.from_file(manager_path))

        # first run the phonon workflow with generation task
        wf_gen = PhononFWWorkflow(input_scf_phonon_si_low, ph_fac, autoparal=False,
                                  initialization_info={"qpoints": qpt, "kppa": 100})

        wf_gen.add_mongoengine_db_insertion(db_data)

        scf_id = wf_gen.scf_fw.fw_id
        old_new = wf_gen.add_to_db(lpad=lp)
        scf_id = old_new[scf_id]

        # run all the workflow
        rapidfire(lp, fworker, m_dir=str(tmpdir))

        wf_gen = lp.get_wf_by_fw_id(scf_id)

        assert wf_gen.state == "COMPLETED"

        # then rerun a similar workflow, but completely generated at its creation
        wf_full = PhononFullFWWorkflow(input_scf_phonon_si_low, ph_fac, autoparal=False)

        scf_id = wf_full.scf_fw.fw_id
        old_new = wf_full.add_to_db(lpad=lp)
        scf_id = old_new[scf_id]

        # run all the workflow
        rapidfire(lp, fworker, m_dir=str(tmpdir))

        wf_full = lp.get_wf_by_fw_id(scf_id)

        assert wf_full.state == "COMPLETED"
Beispiel #6
0
    def create(self):
        """
        create single abinit G0W0 flow
        """
        # manager = 'slurm' if 'ceci' in self.spec['mode'] else 'shell'
        # an AbiStructure object has an overwritten version of get_sorted_structure that sorts according to Z
        # this could also be pulled into the constructor of Abistructure
        # abi_structure = self.structure.get_sorted_structure()
        from abipy import abilab
        item = copy.copy(self.structure.item)
        self.structure.__class__ = abilab.Structure
        self.structure = self.structure.get_sorted_structure_z()
        self.structure.item = item
        abi_structure = self.structure
        manager = TaskManager.from_user_config()
        # Initialize the flow.
        flow = Flow(self.work_dir, manager, pickle_protocol=0)
        # kpoint grid defined over density 40 > ~ 3 3 3
        if self.spec['converge'] and not self.all_converged:
            # (2x2x2) gamma centered mesh for the convergence test on nbands and ecuteps
            # if kp_in is present in the specs a kp_in X kp_in x kp_in mesh is used for the convergence study
            print('== here ===')
            print(self.spec.__class__)
            json.dumps(self.spec.data, indent=2)
            if 'kp_in' in self.spec.data.keys():
                if self.spec['kp_in'] > 9:
                    print(
                        'WARNING:\nkp_in should be < 13 to generate an n x n x n mesh\nfor larger values a grid with '
                        'density kp_in will be generated')
                kppa = self.spec['kp_in']
            else:
                kppa = 2
        else:
            # use the specified density for the final calculation with the converged nbands and ecuteps of other
            # stand alone calculations
            kppa = self.spec['kp_grid_dens']
        gamma = True

        # 'standard' parameters for stand alone calculation
        scf_nband = self.get_bands(self.structure) + 20
        # additional bands to accommodate for nbdbuf and a bit extra
        nscf_nband = [10 * self.get_bands(self.structure)]

        nksmall = None
        ecuteps = [8]

        extra_abivars = dict()

        # read user defined extra abivars from file  'extra_abivars' should be dictionary
        extra_abivars.update(read_extra_abivars())
        # self.bands_fac = 0.5 if 'gwcomp' in extra_abivars.keys() else 1
        # self.convs['nscf_nbands']['test_range'] =
        # tuple([self.bands_fac*x for x in self.convs['nscf_nbands']['test_range']])

        ecut = extra_abivars.pop('ecut', 44)
        ecutsigx = extra_abivars.pop('ecutsigx', 44)

        # if npfft is too large or if npfft changes between the nscf calcualtion and the screening / sigma calulations
        # strange things can happen
        if 'npfft' not in extra_abivars:
            extra_abivars['npfft'] = 3

        if ecutsigx > ecut:
            raise RuntimeError('ecutsigx can not be larger than ecut')
        if ecutsigx < max(ecuteps):
            raise RuntimeError('ecutsigx < ecuteps this is not realistic')

        response_models = ['godby']
        if 'ppmodel' in extra_abivars.keys():
            response_models = [extra_abivars.pop('ppmodel')]

        if self.option is not None:
            for k in self.option.keys():
                if k == 'ecut':
                    ecut = self.option[k]
                if k in ['ecuteps', 'nscf_nbands']:
                    pass
                else:
                    extra_abivars.update({k: self.option[k]})

        try:
            grid = read_grid_from_file(s_name(self.structure) +
                                       ".full_res")['grid']
            all_done = read_grid_from_file(
                s_name(self.structure) + ".full_res")['all_done']
            workdir = os.path.join(s_name(self.structure), 'w' + str(grid))
        except (IOError, OSError):
            grid = 0
            all_done = False
            workdir = None

        if not all_done:
            if (self.spec['test']
                    or self.spec['converge']) and not self.all_converged:
                if self.spec['test']:
                    print('| setting test calculation')
                    tests = SingleAbinitGWWork(self.structure, self.spec).tests
                    response_models = []
                else:
                    if grid == 0:
                        print('| setting convergence calculations for grid 0')
                        # tests = SingleAbinitGWWorkFlow(self.structure, self.spec).convs
                        tests = self.convs
                    else:
                        print('| extending grid')
                        # tests = expand(SingleAbinitGWWorkFlow(self.structure, self.spec).convs, grid)
                        tests = expand(self.convs, grid)
                ecuteps = []
                nscf_nband = []
                for test in tests:
                    if tests[test]['level'] == 'scf':
                        if self.option is None:
                            extra_abivars.update(
                                {test + '_s': tests[test]['test_range']})
                        elif test in self.option:
                            extra_abivars.update({test: self.option[test]})
                        else:
                            extra_abivars.update(
                                {test + '_s': tests[test]['test_range']})
                    else:
                        for value in tests[test]['test_range']:
                            if test == 'nscf_nbands':
                                nscf_nband.append(
                                    value * self.get_bands(self.structure))
                                # scr_nband takes nscf_nbands if not specified
                                # sigma_nband takes scr_nbands if not specified
                            if test == 'ecuteps':
                                ecuteps.append(value)
                            if test == 'response_model':
                                response_models.append(value)
            elif self.all_converged:
                print(
                    '| setting up for testing the converged values at the high kp grid '
                )
                # add a bandstructure and dos calculation
                if os.path.isfile('bands'):
                    nksmall = -30
                    # negative value > only bandstructure
                else:
                    nksmall = 30
                # in this case a convergence study has already been performed.
                # The resulting parameters are passed as option
                ecuteps = [
                    self.option['ecuteps'], self.option['ecuteps'] +
                    self.convs['ecuteps']['test_range'][1] -
                    self.convs['ecuteps']['test_range'][0]
                ]
                nscf_nband = [
                    self.option['nscf_nbands'], self.option['nscf_nbands'] +
                    self.convs['nscf_nbands']['test_range'][1] -
                    self.convs['nscf_nbands']['test_range'][0]
                ]
                # for option in self.option:
                #    if option not in ['ecuteps', 'nscf_nband']:
                #        extra_abivars.update({option + '_s': self.option[option]})
        else:
            print('| all is done for this material')
            return

        logger.info('ecuteps : %s ' % str(ecuteps))
        logger.info('extra   : %s ' % str(extra_abivars))
        logger.info('nscf_nb : %s ' % str(nscf_nband))
        inputs = g0w0_convergence_inputs(abi_structure,
                                         self.pseudo_table,
                                         kppa,
                                         nscf_nband,
                                         ecuteps,
                                         ecutsigx,
                                         scf_nband,
                                         ecut,
                                         accuracy="normal",
                                         spin_mode="unpolarized",
                                         smearing=None,
                                         response_models=response_models,
                                         charge=0.0,
                                         gw_qprange=2,
                                         gamma=gamma,
                                         nksmall=nksmall,
                                         extra_abivars=extra_abivars)

        work = G0W0Work(scf_inputs=inputs[0],
                        nscf_inputs=inputs[1],
                        scr_inputs=inputs[2],
                        sigma_inputs=inputs[3])

        # work = g0w0_extended_work(abi_structure, self.pseudo_table, kppa, nscf_nband, ecuteps, ecutsigx, scf_nband,
        # accuracy="normal", spin_mode="unpolarized", smearing=None, response_models=response_models,
        # charge=0.0, sigma_nband=None, scr_nband=None, gamma=gamma, nksmall=nksmall, **extra_abivars)

        print(workdir)
        flow.register_work(work, workdir=workdir)
        return flow.allocate()
Beispiel #7
0
    def itest_phonon_wf(self, lp, fworker, tmpdir, input_scf_phonon_si_low, use_autoparal, db_data):
        """
        Tests the complete running of PhononFullFWWorkflow and PhononFWWorkflow
        """

        # test at gamma. Pass a custom manager, to check proper serialization
        manager_path = os.path.join(abidata.dirpath, 'managers', "travis_manager.yml")
        ph_fac = PhononsFromGsFactory(qpoints=[[0,0,0]], ph_tol = {"tolvrs": 1.0e-7}, ddk_tol = {"tolwfr": 1.0e-16},
                                      dde_tol = {"tolvrs": 1.0e-7}, wfq_tol = {"tolwfr": 1.0e-16},
                                      manager=TaskManager.from_file(manager_path))

        # first run the phonon workflow with generation task
        wf_gen = PhononFWWorkflow(input_scf_phonon_si_low, ph_fac, autoparal=use_autoparal,
                                  initialization_info={"ngqpt": [1,1,1], "kppa": 100})

        wf_gen.add_anaddb_ph_bs_fw(input_scf_phonon_si_low.structure, ph_ngqpt=[1,1,1], ndivsm=2, nqsmall=2)
        wf_gen.add_mongoengine_db_insertion(db_data)
        wf_gen.add_final_cleanup(["WFK"])

        scf_id = wf_gen.scf_fw.fw_id
        ph_generation_fw_id = wf_gen.ph_generation_fw.fw_id
        old_new = wf_gen.add_to_db(lpad=lp)
        scf_id = old_new[scf_id]
        ph_generation_fw_id = old_new[ph_generation_fw_id]

        # run all the workflow
        rapidfire(lp, fworker, m_dir=str(tmpdir))

        wf_gen = lp.get_wf_by_fw_id(scf_id)

        assert wf_gen.state == "COMPLETED"

        ph_task = load_abitask(get_fw_by_task_index(wf_gen, "phonon_0", index=-1))

        # check the effect of the final cleanup
        assert len(glob.glob(os.path.join(ph_task.outdir.path, "*_WFK"))) == 0
        assert len(glob.glob(os.path.join(ph_task.outdir.path, "*_DEN1"))) > 0
        assert len(glob.glob(os.path.join(ph_task.tmpdir.path, "*"))) == 0
        assert len(glob.glob(os.path.join(ph_task.indir.path, "*"))) == 0

        # check the save in the DB
        from abiflows.database.mongoengine.abinit_results import PhononResult
        with db_data.switch_collection(PhononResult) as PhononResult:
            results = PhononResult.objects()
            assert len(results) == 1
            r = results[0]

            assert r.abinit_input.structure.to_mgobj() == input_scf_phonon_si_low.structure
            assert r.abinit_output.structure.to_mgobj() == input_scf_phonon_si_low.structure
            assert r.abinit_input.ecut == input_scf_phonon_si_low['ecut']
            assert r.abinit_input.kppa == 100
            nptu.assert_array_equal(r.abinit_input.gs_input.to_mgobj()['ngkpt'], input_scf_phonon_si_low['ngkpt'])
            nptu.assert_array_equal(r.abinit_input.ngqpt, [1,1,1])

            ana_task = load_abitask(get_fw_by_task_index(wf_gen, "anaddb", index=None))

            with tempfile.NamedTemporaryFile(mode="wb") as db_file:
                db_file.write(r.abinit_output.phonon_bs.read())
                db_file.seek(0)
                assert filecmp.cmp(ana_task.phbst_path, db_file.name)

            mrgddb_task = load_abitask(get_fw_by_task_index(wf_gen, "mrgddb", index=None))

            # read/write in binary for py3k compatibility with mongoengine
            with tempfile.NamedTemporaryFile(mode="wb") as db_file:
                db_file.write(r.abinit_output.ddb.read())
                db_file.seek(0)
                assert filecmp.cmp(mrgddb_task.merged_ddb_path, db_file.name)

        # then rerun a similar workflow, but completely generated at its creation
        wf_full = PhononFullFWWorkflow(input_scf_phonon_si_low, ph_fac, autoparal=use_autoparal)
        wf_full.add_anaddb_ph_bs_fw(input_scf_phonon_si_low.structure, ph_ngqpt=[1,1,1], ndivsm=2, nqsmall=2)
        wf_full.add_mongoengine_db_insertion(db_data)

        scf_id = wf_full.scf_fw.fw_id
        old_new = wf_full.add_to_db(lpad=lp)
        scf_id = old_new[scf_id]

        # run all the workflow
        rapidfire(lp, fworker, m_dir=str(tmpdir))

        wf_full = lp.get_wf_by_fw_id(scf_id)

        assert wf_full.state == "COMPLETED"

        # the full workflow doesn't contain the generation FW and the cleanup tasks, but should have the same
        # amount of perturbations.
        if use_autoparal:
            diff = 1
        else:
            diff = 2
        assert len(wf_full.id_fw) + diff == len(wf_gen.id_fw)

        if self.check_numerical_values:
            gen_scf_task = load_abitask(get_fw_by_task_index(wf_gen, "scf", index=-1))
            with gen_scf_task.open_gsr() as gen_gsr:
                gen_energy = gen_gsr.energy
                assert gen_energy == pytest.approx(-240.264972012, rel=0.01)

            gen_ana_task = load_abitask(get_fw_by_task_index(wf_gen, "anaddb", index=None))
            with gen_ana_task.open_phbst() as gen_phbst:
                gen_phfreq = gen_phbst.phbands.phfreqs[0, 3]
                assert gen_phfreq == pytest.approx(0.06029885, rel=0.1)

            full_scf_task = load_abitask(get_fw_by_task_index(wf_gen, "scf", index=-1))
            with full_scf_task.open_gsr() as full_gsr:
                full_energy = full_gsr.energy
                assert full_energy == pytest.approx(-240.264972012, rel=0.01)

            full_ana_task = load_abitask(get_fw_by_task_index(wf_gen, "anaddb", index=None))
            with full_ana_task.open_phbst() as full_phbst:
                full_phfreqs = full_phbst.phbands.phfreqs[0, 3]
                assert full_phfreqs == pytest.approx(0.06029885, rel=0.1)

            assert gen_energy == pytest.approx(full_energy, rel=1e-6)
            assert gen_phfreq == pytest.approx(full_phfreqs, rel=1e-6)
Beispiel #8
0
    def itest_phonon_wf(self, lp, fworker, tmpdir, input_scf_phonon_si_low,
                        use_autoparal, db_data):
        """
        Tests the complete running of PhononFullFWWorkflow and PhononFWWorkflow
        """

        # test at gamma. Pass a custom manager, to check proper serialization
        manager_path = os.path.join(abidata.dirpath, 'managers',
                                    "travis_manager.yml")
        ph_fac = PhononsFromGsFactory(
            qpoints=[[0, 0, 0]],
            ph_tol={"tolvrs": 1.0e-7},
            ddk_tol={"tolwfr": 1.0e-16},
            dde_tol={"tolvrs": 1.0e-7},
            wfq_tol={"tolwfr": 1.0e-16},
            manager=TaskManager.from_file(manager_path))

        # first run the phonon workflow with generation task
        wf_gen = PhononFWWorkflow(input_scf_phonon_si_low,
                                  ph_fac,
                                  autoparal=use_autoparal,
                                  initialization_info={
                                      "ngqpt": [1, 1, 1],
                                      "kppa": 100
                                  })

        wf_gen.add_anaddb_ph_bs_fw(input_scf_phonon_si_low.structure,
                                   ph_ngqpt=[1, 1, 1],
                                   ndivsm=2,
                                   nqsmall=2)
        wf_gen.add_mongoengine_db_insertion(db_data)
        wf_gen.add_final_cleanup(["WFK"])

        scf_id = wf_gen.scf_fw.fw_id
        ph_generation_fw_id = wf_gen.ph_generation_fw.fw_id
        old_new = wf_gen.add_to_db(lpad=lp)
        scf_id = old_new[scf_id]
        ph_generation_fw_id = old_new[ph_generation_fw_id]

        # run all the workflow
        rapidfire(lp, fworker, m_dir=str(tmpdir))

        wf_gen = lp.get_wf_by_fw_id(scf_id)

        assert wf_gen.state == "COMPLETED"

        ph_task = load_abitask(
            get_fw_by_task_index(wf_gen, "phonon_0", index=-1))

        # check the effect of the final cleanup
        assert len(glob.glob(os.path.join(ph_task.outdir.path, "*_WFK"))) == 0
        assert len(glob.glob(os.path.join(ph_task.outdir.path, "*_DEN1"))) > 0
        assert len(glob.glob(os.path.join(ph_task.tmpdir.path, "*"))) == 0
        assert len(glob.glob(os.path.join(ph_task.indir.path, "*"))) == 0

        # check the save in the DB
        from abiflows.database.mongoengine.abinit_results import PhononResult
        with db_data.switch_collection(PhononResult) as PhononResult:
            results = PhononResult.objects()
            assert len(results) == 1
            r = results[0]

            assert r.abinit_input.structure.to_mgobj(
            ) == input_scf_phonon_si_low.structure
            assert r.abinit_output.structure.to_mgobj(
            ) == input_scf_phonon_si_low.structure
            assert r.abinit_input.ecut == input_scf_phonon_si_low['ecut']
            assert r.abinit_input.kppa == 100
            nptu.assert_array_equal(
                r.abinit_input.gs_input.to_mgobj()['ngkpt'],
                input_scf_phonon_si_low['ngkpt'])
            nptu.assert_array_equal(r.abinit_input.ngqpt, [1, 1, 1])

            ana_task = load_abitask(
                get_fw_by_task_index(wf_gen, "anaddb", index=None))

            with tempfile.NamedTemporaryFile(mode="wb") as db_file:
                db_file.write(r.abinit_output.phonon_bs.read())
                db_file.seek(0)
                assert filecmp.cmp(ana_task.phbst_path, db_file.name)

            mrgddb_task = load_abitask(
                get_fw_by_task_index(wf_gen, "mrgddb", index=None))

            # read/write in binary for py3k compatibility with mongoengine
            with tempfile.NamedTemporaryFile(mode="wb") as db_file:
                db_file.write(r.abinit_output.ddb.read())
                db_file.seek(0)
                assert filecmp.cmp(mrgddb_task.merged_ddb_path, db_file.name)

        # then rerun a similar workflow, but completely generated at its creation
        wf_full = PhononFullFWWorkflow(input_scf_phonon_si_low,
                                       ph_fac,
                                       autoparal=use_autoparal)
        wf_full.add_anaddb_ph_bs_fw(input_scf_phonon_si_low.structure,
                                    ph_ngqpt=[1, 1, 1],
                                    ndivsm=2,
                                    nqsmall=2)
        wf_full.add_mongoengine_db_insertion(db_data)

        scf_id = wf_full.scf_fw.fw_id
        old_new = wf_full.add_to_db(lpad=lp)
        scf_id = old_new[scf_id]

        # run all the workflow
        rapidfire(lp, fworker, m_dir=str(tmpdir))

        wf_full = lp.get_wf_by_fw_id(scf_id)

        assert wf_full.state == "COMPLETED"

        # the full workflow doesn't contain the generation FW and the cleanup tasks, but should have the same
        # amount of perturbations.
        if use_autoparal:
            diff = 1
        else:
            diff = 2
        assert len(wf_full.id_fw) + diff == len(wf_gen.id_fw)

        if self.check_numerical_values:
            gen_scf_task = load_abitask(
                get_fw_by_task_index(wf_gen, "scf", index=-1))
            with gen_scf_task.open_gsr() as gen_gsr:
                gen_energy = gen_gsr.energy
                assert gen_energy == pytest.approx(-240.264972012, rel=0.01)

            gen_ana_task = load_abitask(
                get_fw_by_task_index(wf_gen, "anaddb", index=None))
            with gen_ana_task.open_phbst() as gen_phbst:
                gen_phfreq = gen_phbst.phbands.phfreqs[0, 3]
                assert gen_phfreq == pytest.approx(0.06029885, rel=0.1)

            full_scf_task = load_abitask(
                get_fw_by_task_index(wf_gen, "scf", index=-1))
            with full_scf_task.open_gsr() as full_gsr:
                full_energy = full_gsr.energy
                assert full_energy == pytest.approx(-240.264972012, rel=0.01)

            full_ana_task = load_abitask(
                get_fw_by_task_index(wf_gen, "anaddb", index=None))
            with full_ana_task.open_phbst() as full_phbst:
                full_phfreqs = full_phbst.phbands.phfreqs[0, 3]
                assert full_phfreqs == pytest.approx(0.06029885, rel=0.1)

            assert gen_energy == pytest.approx(full_energy, rel=1e-6)
            assert gen_phfreq == pytest.approx(full_phfreqs, rel=1e-6)