diff --git a/aiida_quantumespresso_hp/workflows/hubbard.py b/aiida_quantumespresso_hp/workflows/hubbard.py index 22fec03..1886c85 100644 --- a/aiida_quantumespresso_hp/workflows/hubbard.py +++ b/aiida_quantumespresso_hp/workflows/hubbard.py @@ -374,7 +374,7 @@ def run_scf_fixed_magnetic(self): run with smeared occupations. """ previous_workchain = self.ctx.workchains_scf[-1] - previous_parameters = previous_workchain.out.output_parameters + previous_parameters = previous_workchain.outputs.output_parameters inputs = self.get_inputs(PwBaseWorkChain, 'scf') inputs.pw.parameters['CONTROL']['calculation'] = 'scf' diff --git a/tests/conftest.py b/tests/conftest.py index 8437f42..21330f5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -275,12 +275,13 @@ def _generate_parser(entry_point_name): @pytest.fixture -def generate_inputs_pw(fixture_code, generate_structure, generate_kpoints_mesh): +def generate_inputs_pw(fixture_code, generate_structure, generate_kpoints_mesh, generate_upf_family): """Generate default inputs for a `PwCalculation.""" - def _generate_inputs_pw(parameters=None): + def _generate_inputs_pw(parameters=None, structure=None): """Generate default inputs for a `PwCalculation.""" from aiida.orm import Dict + from aiida.orm.nodes.data.upf import get_pseudos_from_structure from aiida_quantumespresso.utils.resources import get_default_options parameters_base = {'CONTROL': {'calculation': 'scf'}, 'SYSTEM': {'ecutrho': 240.0, 'ecutwfc': 30.0}} @@ -290,7 +291,7 @@ def _generate_inputs_pw(parameters=None): inputs = { 'code': fixture_code('quantumespresso.pw'), - 'structure': generate_structure(), + 'structure': structure or generate_structure(), 'kpoints': generate_kpoints_mesh(2), 'parameters': Dict(dict=parameters_base), 'metadata': { @@ -298,6 +299,9 @@ def _generate_inputs_pw(parameters=None): } } + family = generate_upf_family(inputs['structure']) + inputs['pseudos'] = get_pseudos_from_structure(inputs['structure'], family.label) + return inputs return _generate_inputs_pw @@ -341,7 +345,7 @@ def _generate_inputs_hubbard(structure=None, hubbard_u=None): structure = structure or generate_structure() hubbard_u = hubbard_u or Dict(dict={kind.name: 1.0 for kind in structure.kinds}) - inputs_pw = generate_inputs_pw() + inputs_pw = generate_inputs_pw(structure=structure) inputs_hp = generate_inputs_hp() kpoints = inputs_pw.pop('kpoints') @@ -389,3 +393,50 @@ def generate_hp_retrieved(): retrieved.store() return retrieved + + +@pytest.fixture(scope='session') +def generate_upf_data(tmp_path_factory): + """Return a `UpfData` instance for the given element a file for which should exist in `tests/fixtures/pseudos`.""" + + def _generate_upf_data(element): + """Return `UpfData` node.""" + from aiida.orm import UpfData + + with open(tmp_path_factory.mktemp('pseudos') / f'{element}.upf', 'w+b') as handle: + handle.write(f''.encode('utf-8')) + handle.flush() + return UpfData(file=handle.name) + + return _generate_upf_data + + +@pytest.fixture(scope='session') +def generate_upf_family(generate_upf_data): + """Return a `UpfFamily` that serves as a pseudo family.""" + + def _generate_upf_family(structure, label='SSSP-testing2'): + from aiida.common import exceptions + from aiida.orm import UpfFamily + + try: + existing = UpfFamily.objects.get(label=label) + except exceptions.NotExistent: + pass + else: + UpfFamily.objects.delete(existing.pk) + + family = UpfFamily(label=label) + + pseudos = {} + + for kind in structure.kinds: + pseudo = generate_upf_data(kind.symbol).store() + pseudos[pseudo.element] = pseudo + + family.store() + family.add_nodes(list(pseudos.values())) + + return family + + return _generate_upf_family diff --git a/tests/workflows/test_hubbard.py b/tests/workflows/test_hubbard.py index 0f85cd0..297d413 100644 --- a/tests/workflows/test_hubbard.py +++ b/tests/workflows/test_hubbard.py @@ -23,6 +23,22 @@ def _generate_workchain_hubbard(inputs=None): return _generate_workchain_hubbard +@pytest.fixture +def generate_scf_workchain_node(): + """Generate an instance of `WorkflowNode`.""" + from aiida.common import LinkType + from aiida.orm import WorkflowNode + + node = WorkflowNode().store() + parameters = Dict(dict={ + 'number_of_bands': 1, + 'total_magnetization': 1, + }).store() + parameters.add_incoming(node, link_type=LinkType.RETURN, link_label='output_parameters') + + return node + + @pytest.mark.usefixtures('aiida_profile') def test_setup(generate_workchain_hubbard, generate_inputs_hubbard): """Test `SelfConsistentHubbardWorkChain.setup`.""" @@ -65,3 +81,20 @@ def test_validate_inputs_valid_structure(generate_workchain_hubbard, generate_in process.validate_inputs() assert process.ctx.current_structure == inputs['structure'] + + +@pytest.mark.usefixtures('aiida_profile') +def test_run_scf_fixed_magnetic( + generate_workchain_hubbard, generate_inputs_hubbard, generate_structure, generate_scf_workchain_node +): + """Test `SelfConsistentHubbardWorkChain.run_scf_fixed_magnetic`.""" + structure = generate_structure((('Co', 'Co'), ('Li', 'Li'))) + inputs = generate_inputs_hubbard(structure) + inputs['hubbard_u'] = Dict(dict={'Co': 1}) + + process = generate_workchain_hubbard(inputs=inputs) + process.setup() + + # Mock the `workchains_scf` context variable as if a `PwBaseWorkChain` has been run in + process.ctx.workchains_scf = [generate_scf_workchain_node] + process.run_scf_fixed_magnetic()