Exemple #1
0
def populate_restapi_database(clear_database_before_test):
    """Populates the database with a considerable set of nodes to test the restAPI"""
    # pylint: disable=unused-argument
    from aiida import orm

    struct_forcif = orm.StructureData().store()
    orm.StructureData().store()
    orm.StructureData().store()

    orm.Dict().store()
    orm.Dict().store()

    orm.CifData(ase=struct_forcif.get_ase()).store()

    orm.KpointsData().store()

    orm.FolderData().store()

    orm.CalcFunctionNode().store()
    orm.CalcJobNode().store()
    orm.CalcJobNode().store()

    orm.WorkFunctionNode().store()
    orm.WorkFunctionNode().store()
    orm.WorkChainNode().store()
    def run_wannier(self):
        """
        Run the Wannier90 calculation.
        """
        wannier_inputs = self.exposed_inputs(
            Wannier90Calculation, namespace='wannier'
        )
        wannier_parameters = wannier_inputs['parameters'].get_dict()
        wannier_parameters.setdefault('write_hr', True)
        wannier_parameters.setdefault('write_xyz', True)
        wannier_parameters.setdefault('use_ws_distance', True)
        self.report("Running Wannier90 calculation.")

        wannier_inputs['parameters'] = orm.Dict(dict=wannier_parameters)
        wannier_inputs['settings'] = orm.Dict(
            dict=ChainMap(
                wannier_inputs.get('settings', orm.Dict()).get_dict(),
                {"additional_retrieve_list": ['*.win']}
            )
        )

        return ToContext(
            wannier_calc=self.submit(
                Wannier90Calculation,
                structure=self.inputs.structure,
                **wannier_inputs
            )
        )
def test_cell_with_spin(gen_instance, sto_calc_inputs):
    """Test input geneation with spins"""
    import aiida.orm as orm
    from aiida.common.exceptions import InputValidationError

    sto_calc_inputs.settings = orm.Dict(dict={'SPINS': [1, 1, 1, 1, 1]})
    gen_instance.inputs = sto_calc_inputs
    gen_instance.prepare_inputs()

    positions = gen_instance.cell_file['POSITIONS_ABS']
    for i in range(5):
        assert positions[i].endswith(" SPIN=1.000 ")

    # Test non-collinear spins
    sto_calc_inputs.settings = orm.Dict(dict={'SPINS': [[1., 1., 1.]] * 5})
    gen_instance.prepare_inputs()
    positions = gen_instance.cell_file['POSITIONS_ABS']
    for i in range(5):
        assert positions[i].endswith(" SPIN=( 1.000000 1.000000 1.000000 ) ")

    # Test spin consistency checks
    param = sto_calc_inputs.parameters.get_dict()
    param['PARAM']['spin'] = 1.0  # This is wrong
    sto_calc_inputs.parameters = orm.Dict(dict=param)
    with pytest.raises(InputValidationError):
        gen_instance.prepare_inputs()

    # Summation of spins for non-collinear spins
    param['PARAM']['spin'] = 3**(1 / 2) * 5
    sto_calc_inputs.parameters = orm.Dict(dict=param)
    gen_instance.prepare_inputs()
Exemple #4
0
        def generate_sub_input(inputs, namespace, task):
            """
            Generate inputs for tasks, merge those in the namespace from those
            given in the inputs
            """
            if namespace in self.inputs:
                self.report(
                    'Taking input from the {} namespace'.format(namespace))
                bands_inputs = AttributeDict(
                    self.exposed_inputs(base_work, namespace=namespace))
            else:
                bands_inputs = AttributeDict(
                    {'calc': {
                        'parameters': orm.Dict(dict={'task': task})
                    }})

            # Special treatment - combine the paramaters
            parameters = inputs.calc.parameters.get_dict()
            bands_parameters = bands_inputs.calc.parameters.get_dict()

            nested_update(parameters, bands_parameters)
            # Make sure the task name is correct
            nested_update(parameters, {'task': self._task_name})

            # Update the SCF name space with those from the bands name space
            nested_update(inputs, bands_inputs)

            # Apply the new parameters
            inputs.calc.parameters = orm.Dict(dict=parameters)

            return inputs
Exemple #5
0
def generate_inputs_default():
    """Return only those inputs that the parser will expect to be there."""
    a = 5.43
    structure = orm.StructureData(
        cell=[[a / 2., a / 2., 0], [a / 2., 0, a / 2.], [0, a / 2., a / 2.]])
    structure.append_atom(position=(0., 0., 0.), symbols='Si', name='Si1')
    structure.append_atom(position=(a / 4., a / 4., a / 4.),
                          symbols='Si',
                          name='Si2')
    structure.store()
    parameters = {
        'CONTROL': {
            'calculation': 'scf'
        },
        'SYSTEM': {
            'ecutrho': 240.0,
            'ecutwfc': 30.0
        }
    }
    kpoints = orm.KpointsData()
    kpoints.set_cell_from_structure(structure)
    kpoints.set_kpoints_mesh_from_density(0.15)

    return AttributeDict({
        'structure': structure,
        'kpoints': kpoints,
        'parameters': orm.Dict(dict=parameters),
        'settings': orm.Dict()
    })
def generate_inputs():
    """Minimal input for pw2wannier90 calculations."""
    basepath = os.path.dirname(os.path.abspath(__file__))
    nnkp_filepath = os.path.join(basepath, 'fixtures', 'pw2wannier90', 'inputs', 'aiida.nnkp')

    parameters = {
        'inputpp': {
            'write_amn': False,
            'write_mmn': False,
            'write_unk': False,
            'scdm_proj': True,
            'scdm_entanglement': 'isolated',
        }
    }

    settings = {'ADDITIONAL_RETRIEVE_LIST': ['*.amn', '*.mmn', '*.eig']}

    # Since we don't actually run pw2wannier.x, we only pretend to have the output folder
    # of a parent pw.x calculation. The nnkp file, instead, is real.
    inputs = {
        'parent_folder': orm.FolderData().store(),
        'nnkp_file': orm.SinglefileData(file=nnkp_filepath).store(),
        'parameters': orm.Dict(dict=parameters),
        'settings': orm.Dict(dict=settings),
    }

    return AttributeDict(inputs)
def test_plot_fleur_multiple_wc_matplotlib(aiida_profile, read_dict_from_file):
    """test if plot fleur can visualize a multiple workchain output node, Fleur calcjob output nodes """

    from matplotlib.axes import Axes

    aiida_path = os.path.dirname(aiida_fleur.__file__)
    out_node_path = os.path.join(aiida_path,
                                 '../tests/files/jsons/fleur_outputpara.json')
    out_node_scf_path = os.path.join(
        aiida_path, '../tests/files/jsons/fleur_output_scf_wc_para.json')
    out_node_eos_path = os.path.join(
        aiida_path, '../tests/files/jsons/fleur_output_eos_wc_para.json')

    fleur_outputnode = orm.Dict(dict=read_dict_from_file(out_node_path),
                                label='output_para')
    p_calc = plot_fleur([fleur_outputnode, fleur_outputnode], show=False)

    assert isinstance(p_calc, list)
    assert p_calc[0] == []  # isinstance(p_scf[0], plt.figure)

    scf_output = orm.Dict(dict=read_dict_from_file(out_node_scf_path),
                          label='output_scf_wc_para')
    p_scf = plot_fleur([scf_output, scf_output], show=False)

    assert isinstance(p_scf, list)
    # assert isinstance(p_scf[0][0], type(Axes))  # return 2 plots

    eos_output = orm.Dict(dict=read_dict_from_file(out_node_eos_path),
                          label='output_eos_wc_para')
    p_eos = plot_fleur([eos_output, eos_output], show=False)

    assert isinstance(p_eos, list)
def test_plot_fleur_single_wc_bokeh(aiida_profile, read_dict_from_file):
    """test if plot fleur can visualize a single workchain with bokeh backend"""
    try:  #bokeh is not a prerequisite of Aiida-Fleur, might become of masci-tools
        from bokeh.layouts import column  # gridplot
    except ImportError:
        return

    aiida_path = os.path.dirname(aiida_fleur.__file__)
    out_node_path = os.path.join(aiida_path,
                                 '../tests/files/jsons/fleur_outputpara.json')
    out_node_scf_path = os.path.join(
        aiida_path, '../tests/files/jsons/fleur_output_scf_wc_para.json')
    out_node_eos_path = os.path.join(
        aiida_path, '../tests/files/jsons/fleur_output_eos_wc_para.json')

    fleur_outputnode = orm.Dict(dict=read_dict_from_file(out_node_path),
                                label='output_para')
    p_calc = plot_fleur(fleur_outputnode, show=False, backend='bokeh')

    assert isinstance(p_calc, list)
    assert p_calc[0] is None  # currently does not have a visualization

    scf_out = orm.Dict(dict=read_dict_from_file(out_node_scf_path),
                       label='output_scf_wc_para')
    p_scf = plot_fleur(scf_out, show=False, backend='bokeh')

    assert isinstance(p_scf, list)
    assert isinstance(p_scf[0], type(column()))
Exemple #9
0
def test_pw_ibrav_tol(fixture_sandbox, generate_calc_job, fixture_code, generate_kpoints_mesh, generate_upf_data):
    """Test that `IBRAV_TOLERANCE` controls the tolerance when checking cell consistency."""
    entry_point_name = 'quantumespresso.pw'

    parameters = {'CONTROL': {'calculation': 'scf'}, 'SYSTEM': {'ecutrho': 240.0, 'ecutwfc': 30.0, 'ibrav': 2}}

    # The structure needs to be rotated in the same way QE does it for ibrav=2.
    param = 5.43
    eps = 0.1
    cell = [[-param / 2., eps, param / 2.], [-eps, param / 2. + eps, param / 2.], [-param / 2., param / 2., 0]]
    structure = orm.StructureData(cell=cell)
    structure.append_atom(position=(0., 0., 0.), symbols='Si', name='Si')
    structure.append_atom(position=(param / 4., param / 4., param / 4.), symbols='Si', name='Si')

    upf = generate_upf_data('Si')
    inputs = {
        'code': fixture_code(entry_point_name),
        'structure': structure,
        'kpoints': generate_kpoints_mesh(2),
        'parameters': orm.Dict(dict=parameters),
        'pseudos': {
            'Si': upf
        },
        'metadata': {
            'options': get_default_options()
        },
    }
    # Without adjusting the tolerance, the check fails.
    with pytest.raises(QEInputValidationError):
        generate_calc_job(fixture_sandbox, entry_point_name, inputs)

    # After adjusting the tolerance, the input validation no longer fails.
    inputs['settings'] = orm.Dict(dict={'ibrav_cell_tolerance': eps})
    generate_calc_job(fixture_sandbox, entry_point_name, inputs)
def test_plot_fleur_single_wc_matplotlib(aiida_profile, read_dict_from_file):
    """test if plot fleur can visualize a workchain"""

    aiida_path = os.path.dirname(aiida_fleur.__file__)
    out_node_path = os.path.join(aiida_path,
                                 '../tests/files/jsons/fleur_outputpara.json')
    out_node_scf_path = os.path.join(
        aiida_path, '../tests/files/jsons/fleur_output_scf_wc_para.json')
    out_node_eos_path = os.path.join(
        aiida_path, '../tests/files/jsons/fleur_output_eos_wc_para.json')

    fleur_outputnode = orm.Dict(dict=read_dict_from_file(out_node_path),
                                label='output_para')
    p_calc = plot_fleur(fleur_outputnode, show=False)

    assert isinstance(p_calc, list)
    assert p_calc[0] is None  # isinstance(p_scf[0], plt.figure)

    scf_output = orm.Dict(dict=read_dict_from_file(out_node_scf_path),
                          label='output_scf_wc_para')
    p_scf = plot_fleur(scf_output, show=False)

    assert isinstance(p_scf, list)
    # assert isinstance(p_scf[0], type(plt.axes))  # isinstance(p_scf[0], plt.figure)

    eos_output = orm.Dict(dict=read_dict_from_file(out_node_eos_path),
                          label='output_eos_wc_para')
    p_eos = plot_fleur(eos_output, show=False)

    assert isinstance(p_eos, list)
Exemple #11
0
def generate_inputs():
    """Return a dictionary of inputs for a `CalcJobNode` fixture to be created."""
    from aiida import orm

    inputs = {'parameters': orm.Dict(dict={}), 'settings': orm.Dict(dict={})}

    return inputs
Exemple #12
0
def test_validate_instructions():
    """Test the `TransferCalculation` validators."""
    from aiida.calculations.transfer import validate_instructions

    instructions = orm.Dict(dict={}).store()
    result = validate_instructions(instructions, None)
    expected = (
        '\n\nno indication of what to do in the instruction node:\n'
        f' > {instructions.uuid}\n'
        '(to store the files in the repository set retrieve_files=True,\n'
        'to copy them to the specified folder on the remote computer,\n'
        'set it to False)\n'
    )
    assert result == expected

    instructions = orm.Dict(dict={'retrieve_files': 12}).store()
    result = validate_instructions(instructions, None)
    expected = (
        'entry for retrieve files inside of instruction node:\n'
        f' > {instructions.uuid}\n'
        'must be either True or False; instead, it is:\n > 12\n'
    )
    assert result == expected

    instructions = orm.Dict(dict={'retrieve_files': True}).store()
    result = validate_instructions(instructions, None)
    expected = (
        'no indication of which files to copy were found in the instruction node:\n'
        f' > {instructions.uuid}\n'
        'Please include at least one of `local_files`, `remote_files`, or `symlink_files`.\n'
        'These should be lists containing 3-tuples with the following format:\n'
        '    (source_node_key, source_relpath, target_relpath)\n'
    )
    assert result == expected
Exemple #13
0
    def get_builder(self,
                    structure,
                    calc_engines,
                    protocol,
                    relaxation_type,
                    threshold_forces=None,
                    threshold_stress=None,
                    **kwargs):
        """Return a process builder for the corresponding workchain class with inputs set according to the protocol.

        :param structure: the structure to be relaxed
        :param calc_engines: ...
        :param protocol: the protocol to use when determining the workchain inputs
        :param relaxation_type: the type of relaxation to perform, instance of `RelaxType`
        :param threshold_forces: target threshold for the forces in eV/Å.
        :param threshold_stress: target threshold for the stress in eV/Å^3.
        :param kwargs: any inputs that are specific to the plugin.
        :return: a `aiida.engine.processes.ProcessBuilder` instance ready to be submitted.
        """
        # pylint: disable=too-many-locals
        from aiida_quantumespresso_epfl.common.protocol.pw import generate_inputs  # pylint: disable=import-error

        code = calc_engines['relax']['code']
        process_class = QuantumEspressoRelaxWorkChain._process_class  # pylint: disable=protected-access
        pseudo_family = kwargs.pop('pseudo_family')

        builder = QuantumEspressoRelaxWorkChain.get_builder()
        inputs = generate_inputs(process_class,
                                 protocol,
                                 code,
                                 structure,
                                 pseudo_family,
                                 override={'relax': {}})
        builder._update(inputs)  # pylint: disable=protected-access

        if relaxation_type == RelaxType.ATOMS:
            relaxation_schema = 'relax'
        elif relaxation_type == RelaxType.ATOMS_CELL:
            relaxation_schema = 'vc-relax'
        else:
            raise ValueError('relaxation type `{}` is not supported'.format(
                relaxation_type.value))

        builder.relaxation_scheme = orm.Str(relaxation_schema)

        if threshold_forces is not None:
            parameters = builder.base.parameters.get_dict()
            parameters.setdefault('CONTROL',
                                  {})['forc_conv_thr'] = threshold_forces
            builder.base.parameters = orm.Dict(dict=parameters)

        if threshold_stress is not None:
            parameters = builder.base.parameters.get_dict()
            parameters.setdefault('CELL',
                                  {})['press_conv_thr'] = threshold_stress
            builder.base.parameters = orm.Dict(dict=parameters)

        return builder
def submit_workchain(structure,
                     daemon,
                     protocol,
                     parameters,
                     pseudo_family,
                     num_machines,
                     num_mpiprocs_per_machine=4,
                     set_2d_mesh=False):
    print("running dft band structure calculation for {}".format(
        structure.get_formula()))

    # Set custom pseudo
    modifiers = {'parameters': parameters}
    """ if pseudo_family is not None:
        from aiida_quantumespresso.utils.protocols.pw import _load_pseudo_metadata
        pseudo_data = _load_pseudo_metadata(pseudo_family)
        modifiers.update({'pseudo': 'custom', 'pseudo_data': pseudo_data}) """
    # if pseudo_family is not None:
    #     from aiida_quantumespresso.utils.pseudopotential import get_pseudos_from_structure
    #     pseudo_data = get_pseudos_from_structure(structure, pseudo_family)
    #     modifiers.update({'pseudo': 'custom', 'pseudo_data': pseudo_data})

    # Submit the DFT bands workchain
    pwbands_workchain_parameters = {
        'code':
        code,
        'structure':
        structure,
        'protocol':
        orm.Dict(dict={
            'name': protocol,
            'modifiers': modifiers
        }),
        'options':
        orm.Dict(
            dict={
                'resources': {
                    'num_machines': num_machines,
                    'num_mpiprocs_per_machine': num_mpiprocs_per_machine
                },
                'max_wallclock_seconds': 3600 * 5,
                'withmpi': True,
            }),
        'set_2d_mesh':
        orm.Bool(set_2d_mesh)
    }
    if pseudo_family is not None:
        pwbands_workchain_parameters['pseudo_family'] = orm.Str(pseudo_family)
    if daemon:
        dft_workchain = submit(PwBandStructureWorkChain,
                               **pwbands_workchain_parameters)
    else:
        from aiida.engine import run_get_pk
        dft_workchain = run_get_pk(PwBandStructureWorkChain,
                                   **pwbands_workchain_parameters)
    return dft_workchain
    def _generate_workchain_stm():

        entry_point_code_siesta = 'siesta.siesta'
        entry_point_code = 'siesta.stm'
        entry_point_wc = 'siesta.stm'

        psml = generate_psml_data('Si')

        structure = generate_structure()

        params = generate_param().get_dict()
        params[
            "%block local-density-of-states"] = "\n -9.6  -1.6 eV \n %endblock local-density-of-states"

        inputs = {
            'code':
            fixture_code(entry_point_code_siesta),
            'stm_code':
            fixture_code(entry_point_code),
            'stm_mode':
            orm.Str("constant-height"),
            'stm_spin':
            orm.Str("none"),
            'stm_value':
            orm.Float(1),
            'emin':
            orm.Float(-1),
            'emax':
            orm.Float(1),
            'structure':
            structure,
            'kpoints':
            generate_kpoints_mesh(2),
            'parameters':
            orm.Dict(dict=params),
            'basis':
            generate_basis(),
            'pseudos': {
                'Si': psml,
                'SiDiff': psml
            },
            'options':
            orm.Dict(
                dict={
                    'resources': {
                        'num_machines': 1
                    },
                    'max_wallclock_seconds': 1800,
                    'withmpi': False,
                })
        }

        process = generate_workchain(entry_point_wc, inputs)

        return process
Exemple #16
0
 def _generate_inputs(parser_options=None):
     """Return only those inputs that the parser will expect to be there."""
     inputs = {
         'parameters': orm.Dict(dict={'PATH': {
             'num_of_images': 3
         }}),
         'pw': {
             'parameters': orm.Dict(dict={}),
         },
         'settings': orm.Dict(dict={'parser_options': parser_options})
     }
     return AttributeDict(inputs)
def test_base_template(fixture_sandbox, aiida_localhost, generate_calc_job):
    """Test a base template that emulates the arithmetic add."""

    entry_point_name = 'templatereplacer'
    inputs = {
        'code':
        orm.Code(remote_computer_exec=(aiida_localhost, '/bin/bash')),
        'metadata': {
            'options': {
                'resources': {
                    'num_machines': 1,
                    'tot_num_mpiprocs': 1
                }
            }
        },
        'template':
        orm.Dict(
            dict={
                'input_file_template': 'echo $(({x} + {y}))',
                'input_file_name': 'input.txt',
                'cmdline_params': ['input.txt'],
                'output_file_name': 'output.txt',
            }),
        'parameters':
        orm.Dict(dict={
            'x': 1,
            'y': 2
        }),
    }

    # Check the attributes of the resulting `CalcInfo`
    calc_info = generate_calc_job(fixture_sandbox, entry_point_name, inputs)
    assert isinstance(calc_info, datastructures.CalcInfo)
    assert sorted(calc_info.retrieve_list) == sorted(
        [inputs['template']['output_file_name']])

    # Check the integrity of the `codes_info`
    codes_info = calc_info.codes_info
    assert isinstance(codes_info, list)
    assert len(codes_info) == 1

    # Check the attributes of the resulting `CodeInfo`
    code_info = codes_info[0]
    assert isinstance(code_info, datastructures.CodeInfo)
    assert code_info.code_uuid == inputs['code'].uuid
    assert code_info.stdout_name == inputs['template']['output_file_name']
    assert sorted(code_info.cmdline_params) == sorted(
        inputs['template']['cmdline_params'])

    # Check the content of the generated script
    with fixture_sandbox.open(inputs['template']['input_file_name']) as handle:
        input_written = handle.read()
        assert input_written == f"echo $(({inputs['parameters']['x']} + {inputs['parameters']['y']}))"
def test_process(deepmd_code):
    """Test running a calculation
    note this does not test that the expected outputs are created of output parsing"""
    from aiida.plugins import DataFactory, CalculationFactory
    from aiida.engine import run

    # Prepare input parameters
    DiffParameters = DataFactory('deepmd')
    parameters = DiffParameters({'ignore-case': True})

    from aiida.orm import SinglefileData
    file1 = SinglefileData(
        file=os.path.join(tests.TEST_DIR, "input_files", 'file1.txt'))
    file2 = SinglefileData(
        file=os.path.join(tests.TEST_DIR, "input_files", 'file2.txt'))

    # data_folder = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'input_folder')
    data_folder = orm.FolderData(
        tree=os.path.join(tests.TEST_DIR, "input_files"))
    # data_folder = './input_folder'
    # set up calculation
    inputs = {
        'code': deepmd_code,
        'model': orm.Dict(dict={}),
        'learning_rate': orm.Dict(dict={}),
        'loss': orm.Dict(dict={}),
        'training': orm.Dict(dict={}),
        'file': {
            'box_raw':
            SinglefileData(
                file=os.path.join(tests.TEST_DIR, "input_files", 'file1.txt')),
            'coord_raw':
            SinglefileData(
                file=os.path.join(tests.TEST_DIR, "input_files", 'file2.txt'))
        },
        'metadata': {
            'dry_run': True,
            'options': {
                'max_wallclock_seconds': 30,
                'resources': {
                    'num_machines': 1,
                    'num_mpiprocs_per_machine': 1
                }
            },
        },
    }

    result = run(CalculationFactory('dptrain'), **inputs)
    computed_diff = result['deepmd'].get_content()

    assert 'content1' in computed_diff
    assert 'content2' in computed_diff
def generate_inputs_calculation(
    protocol: Dict,
    code: orm.Code,
    structure: orm.StructureData,
    otfg_family: OTFGGroup,
    override: Dict[str, Any] = None
) -> Dict[str, Any]:
    """Generate the inputs for the `CastepCalculation` for a given code, structure and pseudo potential family.

    :param protocol: the dictionary with protocol inputs.
    :param code: the code to use.
    :param structure: the input structure.
    :param otfg_family: the pseudo potential family.
    :param override: a dictionary to override specific inputs.
    :return: the fully defined input dictionary.
    """
    from aiida_castep.calculations.helper import CastepHelper
    override = {} if not override else override.get('calc', {})
    # This merge perserves the merged `parameters` in the override
    merged_calc = recursive_merge(protocol['calc'], override)

    # Create KpointData for CastepCalculation, the kpoints_spacing passed is
    # already in the AiiDA convention, e.g. with 2pi factor built into it.
    kpoints = orm.KpointsData()
    kpoints.set_cell_from_structure(structure)
    kpoints.set_kpoints_mesh_from_density(protocol['kpoints_spacing'])

    # For bare calculation level, we need to make sure the dictionary is not "flat"
    param = merged_calc['parameters']

    # Remove incompatible options: cut_off_energy and basis_precisions can not be
    # both specified
    if 'cut_off_energy' in param:
        param.pop('basis_precision', None)

    helper = CastepHelper()
    param = helper.check_dict(param, auto_fix=True, allow_flat=True)

    dictionary = {
        'structure': structure,
        'kpoints': kpoints,
        'code': code,
        'parameters': orm.Dict(dict=param),
        'pseudos': get_pseudos_from_structure(structure, otfg_family.label),
        'metadata': merged_calc.get('metadata', {})
    }
    # Add the settings input if present
    if 'settings' in merged_calc:
        dictionary['settings'] = orm.Dict(dict=merged_calc['settings'])

    return dictionary
    def _generate_inputs(calculation_type='scf', settings=None, metadata=None):
        structure = generate_structure()
        parameters = {'CONTROL': {'calculation': calculation_type}}
        kpoints = orm.KpointsData()
        kpoints.set_cell_from_structure(structure)
        kpoints.set_kpoints_mesh_from_density(0.15)

        return AttributeDict({
            'structure': generate_structure(),
            'kpoints': kpoints,
            'parameters': orm.Dict(dict=parameters),
            'settings': orm.Dict(dict=settings),
            'metadata': metadata or {}
        })
def inputs(fixture_code, remote, parameters, settings):
    """Fixture: inputs for Z2packBaseWorkChain."""
    from aiida_quantumespresso.utils.resources import get_default_options

    inputs = {
        'code': fixture_code('quantumespresso.pw2gw'),
        'parent_folder': remote,
        'parameters': orm.Dict(dict=parameters),
        'settings': orm.Dict(dict=settings),
        'metadata': {
            'options': get_default_options()
        }
    }
    return inputs
Exemple #22
0
    def run_scf(self):
        """
        Run the SCF calculation step.
        """
        self.report('Launching SCF calculation.')

        inputs = self.exposed_inputs(PwCalculation, namespace='scf')
        inputs['parameters'] = merge_nested_dict(
            orm.Dict(dict={'CONTROL': {
                'calculation': 'scf'
            }}), inputs.get('parameters', orm.Dict()))
        return ToContext(scf=self.submit(PwCalculation,
                                         structure=self.inputs.structure,
                                         kpoints=self.inputs.kpoints_mesh,
                                         **inputs))
Exemple #23
0
    def run_calc(self):
        """
        Run the QE calculation.
        """

        self.report("Submitting pw.x bands calculation.")

        pw_inputs = self.exposed_inputs(PwCalculation, namespace='pw')
        pw_inputs['parameters'] = merge_nested_dict(
            orm.Dict(dict={'CONTROL': {
                'calculation': 'bands'
            }}), pw_inputs.get('parameters', orm.Dict())
        )

        return ToContext(pw_calc=self.submit(PwCalculation, **pw_inputs))
def generate_inputs_relax(protocol: Dict,
                          code: orm.Code,
                          structure: orm.StructureData,
                          otfg_family: OTFGGroup,
                          override: Dict[str, Any] = None) -> Dict[str, Any]:
    """Generate the inputs for the `CastepRelaxWorkChain` for a given code, structure and pseudo potential family.

    :param protocol: the dictionary with protocol inputs.
    :param code: the code to use.
    :param structure: the input structure.
    :param otfg_family: the pseudo potential family.
    :param override: a dictionary to override specific inputs.
    :return: the fully defined input dictionary.
    """
    protocol['base'] = generate_inputs_base(protocol['base'], code, structure,
                                            otfg_family,
                                            override.get('base', {}))
    merged = recursive_merge(protocol, override)

    # Remove inputs that should not be passed top-level
    merged['base'].pop('structure', None)

    calc = merged['base'].pop('calc')

    # Here we move the 'calc' up from the 'base' this is how the relax workchain accepts inputs
    dictionary = {
        'base': merged['base'],
        'calc': calc,
        'structure': structure,
        'relax_options': orm.Dict(dict=merged['relax_options'])
    }

    return dictionary
Exemple #25
0
    def _wrap_bare_dict_inputs(self, port_namespace, inputs):
        """Wrap bare dictionaries in `inputs` in a `Dict` node if dictated by the corresponding inputs portnamespace.

        :param port_namespace: a `PortNamespace`
        :param inputs: a dictionary of inputs intended for submission of the process
        :return: an attribute dictionary with all bare dictionaries wrapped in `Dict` if dictated by the port namespace
        """
        from aiida.engine.processes import PortNamespace

        wrapped = {}

        for key, value in inputs.items():

            if key not in port_namespace:
                wrapped[key] = value
                continue

            port = port_namespace[key]

            if isinstance(port, PortNamespace):
                wrapped[key] = self._wrap_bare_dict_inputs(port, value)
            elif port.valid_type == orm.Dict and isinstance(value, dict):
                wrapped[key] = orm.Dict(dict=value)
            else:
                wrapped[key] = value

        return AttributeDict(wrapped)
def generate_inputs_spinorbit(generate_calc_job_node, fixture_localhost,
                              generate_structure, generate_kpoints_mesh):
    """Create the required inputs for the ``ProjwfcCalculation`` with lspinorb=.true."""
    entry_point_name = 'quantumespresso.pw'
    inputs = {
        'structure': generate_structure(),
        'kpoints': generate_kpoints_mesh(4)
    }

    parent_calcjob = generate_calc_job_node(entry_point_name,
                                            fixture_localhost,
                                            'default',
                                            inputs=inputs)
    params = orm.Dict(
        dict={
            'number_of_spin_components': 4,
            'non_colinear_calculation': True,
            'spin_orbit_calculation': True
        })
    params.add_incoming(parent_calcjob,
                        link_type=LinkType.CREATE,
                        link_label='output_parameters')
    params.store()
    inputs = {
        'parent_folder': parent_calcjob.outputs.remote_folder,
    }

    return AttributeDict(inputs)
Exemple #27
0
def test_pw_wrong_ibrav(fixture_sandbox, generate_calc_job, fixture_code, generate_kpoints_mesh, generate_upf_data):
    """Test that a `PwCalculation` with an incorrect `ibrav` raises."""
    entry_point_name = 'quantumespresso.pw'

    parameters = {'CONTROL': {'calculation': 'scf'}, 'SYSTEM': {'ecutrho': 240.0, 'ecutwfc': 30.0, 'ibrav': 2}}

    # Here we use the wrong order of unit cell vectors on purpose.
    param = 5.43
    cell = [[0, param / 2., param / 2.], [-param / 2., 0, param / 2.], [-param / 2., param / 2., 0]]
    structure = orm.StructureData(cell=cell)
    structure.append_atom(position=(0., 0., 0.), symbols='Si', name='Si')
    structure.append_atom(position=(param / 4., param / 4., param / 4.), symbols='Si', name='Si')

    upf = generate_upf_data('Si')
    inputs = {
        'code': fixture_code(entry_point_name),
        'structure': structure,
        'kpoints': generate_kpoints_mesh(2),
        'parameters': orm.Dict(dict=parameters),
        'pseudos': {
            'Si': upf
        },
        'metadata': {
            'options': get_default_options()
        }
    }

    with pytest.raises(QEInputValidationError):
        generate_calc_job(fixture_sandbox, entry_point_name, inputs)
Exemple #28
0
def calculate_invariant_with_parities(dimensionality: orm.Int,
                                      scf_out_params: orm.Dict,
                                      par_data: orm.ArrayData) -> orm.Dict:
    """Calculate the z2 invariant from the parities using the output of a BandsxCalculation."""
    dim = dimensionality.value

    parities = par_data.get_array('par')

    n_el = int(scf_out_params.get_dict()['number_of_electrons'])
    if dim == 2:
        x = 1
        for p in parities:
            delta = 1
            for i in range(0, n_el, 2):
                delta *= p[i]

            x *= delta

        if x == 1:
            res = {'nu': 0}
        elif x == -1:
            res = {'nu': 1}
        else:
            res = {'nu': -1}
            # raise exceptions.OutputParsingError(
            #     'Invalid result for z2 using parities')

    elif dim == 3:
        raise NotImplemented('dimensionality = 3  not implemented.')
    else:
        raise exceptions.InputValidationError(
            'dimensionality must be either 2 or 3')

    return orm.Dict(dict=res)
def tags_and_magnetization(structure, magnetization_per_site):
    """Gather the same atoms with the same magnetization into one atomic kind."""
    if magnetization_per_site:
        ase_structure = structure.get_ase()
        if len(magnetization_per_site) != len(ase_structure.numbers):
            raise ValueError(
                'The size of `magnetization_per_site` is different from the number of atoms.'
            )

        # Combine atom type with magnetizations.
        complex_symbols = [
            f'{symbol}_{magn}' for symbol, magn in zip(
                ase_structure.get_chemical_symbols(), magnetization_per_site)
        ]
        # Assign a unique tag for every atom kind.
        combined = {
            symbol: tag + 1
            for tag, symbol in enumerate(set(complex_symbols))
        }
        # Assigning correct tags to every atom.
        tags = [combined[key] for key in complex_symbols]
        ase_structure.set_tags(tags)
        # Tag-magnetization correspondance.
        tags_correspondance = {
            str(value): float(key.split('_')[1])
            for key, value in combined.items()
        }
        return StructureData(ase=ase_structure), orm.Dict(
            dict=tags_correspondance)
    return structure, None
    def setup_parameters(self):
        """Set up the default input parameters required for the `PwBandsWorkChain`."""
        ecutwfc = []
        ecutrho = []

        for kind in self.inputs.structure.get_kind_names():
            try:
                dual = self.ctx.protocol['pseudo_data'][kind]['dual']
                cutoff = self.ctx.protocol['pseudo_data'][kind]['cutoff']
                cutrho = dual * cutoff
                ecutwfc.append(cutoff)
                ecutrho.append(cutrho)
            except KeyError:
                self.report('failed to retrieve the cutoff or dual factor for {}'.format(kind))
                return self.exit_codes.ERROR_INVALID_INPUT_UNRECOGNIZED_KIND

        self.ctx.parameters = orm.Dict(dict={
            'CONTROL': {
                'restart_mode': 'from_scratch',
                'tstress': self.ctx.protocol['tstress'],
                'tprnfor': self.ctx.protocol['tprnfor'],
            },
            'SYSTEM': {
                'ecutwfc': max(ecutwfc),
                'ecutrho': max(ecutrho),
                'smearing': self.ctx.protocol['smearing'],
                'degauss': self.ctx.protocol['degauss'],
                'occupations': self.ctx.protocol['occupations'],
            },
            'ELECTRONS': {
                'conv_thr': self.ctx.protocol['convergence_threshold_per_atom'] * len(self.inputs.structure.sites),
            }
        })