示例#1
0
    def test_get_number_electrons(self):
        from aiida_alloy.utils import get_numelectrons_structure_upffamily
        from aiida_alloy.utils import randomize_asestructure_elements
        from aiida.orm.nodes.data.upf import get_pseudos_from_structure
        test_seed = 42
        test_largerandom_ase = randomize_asestructure_elements(
            self.basic_ase_supercell, self.randomcell_elements,
            self.randomcell_concentrations, test_seed)

        expected_electron_dict = {
            'Al': 3,
            'Mg': 2,
            'Cu': 11,
        }
        expected_E = 0
        for i in range(len(test_largerandom_ase)):
            element = test_largerandom_ase[i].symbol
            expected_E += expected_electron_dict[element]

        test_largerandom_structure = StructureData(ase=test_largerandom_ase)
        pseudos = get_pseudos_from_structure(test_largerandom_structure,
                                             TEST_UPF_FAMILY)
        computed_E = get_numelectrons_structure_upffamily(
            test_largerandom_structure, pseudos)

        assert expected_E == computed_E
        def get_common_inputs():
            """Return the dictionary of inputs to be used as the basis for each `PwBaseWorkChain`."""
            protocol, protocol_modifiers = self._get_protocol()
            checked_pseudos = protocol.check_pseudos(
                modifier_name=protocol_modifiers.get('pseudo', None),
                pseudo_data=protocol_modifiers.get('pseudo_data', None))
            known_pseudos = checked_pseudos['found']

            inputs = AttributeDict({
                'pw': {
                    'code': self.inputs.code,
                    'parameters': self.ctx.parameters,
                    'metadata': {},
                }
            })

            if 'pseudo_family' in self.inputs:
                inputs.pw['pseudos'] = get_pseudos_from_structure(
                    self.inputs.structure, self.inputs.pseudo_family.value)
            else:
                inputs.pw['pseudos'] = get_pseudos_from_dict(
                    self.inputs.structure, known_pseudos)

            if 'set_2d_mesh' in self.inputs:
                inputs['set_2d_mesh'] = self.inputs.set_2d_mesh

            if 'options' in self.inputs:
                inputs.pw.metadata.options = self.inputs.options.get_dict()
            else:
                inputs.pw.metadata.options = get_default_options(with_mpi=True)

            return inputs
示例#3
0
def wf_setupparams(base_parameter, structure,
                   pseudo_familyname, nume2bnd_ratio,
                   cellpress_parameter):
        from aiida.orm.nodes.data.upf import get_pseudos_from_structure

        import collections
        def update(d, u):
            for k, v in u.items():
                if isinstance(v, collections.Mapping):
                    d[k] = update(d.get(k, {}), v)
                else:
                    d[k] = v
            return d

        pseudos = get_pseudos_from_structure(structure, pseudo_familyname.value)
        nelec = get_numelectrons_structure_upffamily(structure, pseudos)
        nbnd = nelec * nume2bnd_ratio.value
        nbnd = max(nbnd, 20) # minimum of 20 bands to avoid certain crashes
        parameter_dict = base_parameter.get_dict()
        parameter_dict['SYSTEM']['nbnd'] = nbnd

        cellpress_dict = cellpress_parameter.get_dict()
        parameter_dict.update(cellpress_dict)
        parameters = Dict(dict=parameter_dict)

        return parameters
示例#4
0
    def run_pw_nscf(self):
        """Run the NSCF step with pw.x"""

        self.out('scf_output', self.ctx.pw_scf.outputs.output_parameters)

        try:
            # Check if it's an explicit list of kpoints; this raises AttributeError if it's a mesh
            self.inputs.kpoints_nscf.get_kpoints()
            # If I am here, this an explicit grid, I stop
            raise ValueError(
                "You should pass an MP grid; we'll take care of converting to an explicit one"
            )
        except AttributeError:
            # Check that the one provided is an unshifted mesh
            assert self.inputs.kpoints_nscf.get_kpoints_mesh()[1] == [
                0, 0, 0
            ], "You should pass an unshifted mesh"
            self.ctx.kpoints_nscf_explicit = get_explicit_kpoints(
                self.inputs.kpoints_nscf
            )

        nscf_parameters = self.ctx.scf_parameters.copy()
        nscf_parameters['CONTROL']['calculation'] = 'nscf'

        inputs = {
            'code':
            self.inputs.pw_code,
            'structure':
            self.inputs.structure,
            'pseudos':
            get_pseudos_from_structure(
                self.inputs.structure, self.inputs.pseudo_family.value
            ),
            'parameters':
            orm.Dict(dict=nscf_parameters),
            'kpoints':
            self.ctx.kpoints_nscf_explicit,
            'parent_folder':
            self.ctx.pw_scf.outputs.remote_folder,
            'metadata': {
                'options': {
                    'resources': {
                        'num_machines': int(self.inputs.num_machines)
                    },
                    'max_wallclock_seconds':
                    int(self.inputs.max_wallclock_seconds),
                    'withmpi': True,
                }
            }
        }

        running = self.submit(
            CalculationFactory('quantumespresso.pw'), **inputs
        )
        self.report(
            'launching PwCalculation<{}> (NSCF step)'.format(running.pk)
        )

        return ToContext(pw_nscf=running)
示例#5
0
def get_nummachines_forcalc(structure, pseudo_familyname):
    # NOTE: used very adhoc guess for nodes, assuming quadratic scaling
    pseudos = get_pseudos_from_structure(structure, pseudo_familyname)
    num_electrons = get_numelectrons_structure_upffamily(structure, pseudos)
    a2 = 1.5 * 10**-6
    a1 = 5.7 * 10**-3
    a0 = 2
    numnodes = a2 * num_electrons**2 + a1 * num_electrons + a0
    numnodes = max(round(numnodes / 2) * 2, 2)  # force even # of nodes
    return numnodes
def validate_and_prepare_pseudos_inputs(structure,
                                        pseudos=None,
                                        pseudo_family=None):  # pylint: disable=invalid-name
    """Validate the given pseudos mapping or pseudo potential family with respect to the given structure.

    Use the explicitly passed pseudos dictionary or use the pseudo_family in combination with the structure to obtain
    that dictionary.

    The pseudos dictionary should now be a dictionary of UPF nodes with the kind as linkname
    As such, if there are multiple kinds with the same element, there will be duplicate UPF nodes
    but multiple links for the same input node are not allowed. Moreover, to couple the UPF nodes
    to the Calculation instance, we have to go through the use_pseudo method, which takes the kind
    name as an additional parameter. When creating a Calculation through a Process instance, one
    cannot call the use methods directly but rather should pass them as keyword arguments. However,
    we can pass the additional parameters by using them as the keys of a dictionary

    :param structure: StructureData node
    :param pseudos: a dictionary where keys are the kind names and value are UpfData nodes
    :param pseudo_family: pseudopotential family name to use, should be Str node
    :raises: ValueError if neither pseudos or pseudo_family is specified or if no UpfData is found for
        every element in the structure
    :returns: a dictionary of UpfData nodes where the key is the kind name

    .. deprecated:: 4.0.0
        This functionality is now implemented in ``aiida-pseudo``.
    """
    from aiida.orm import Str

    warnings.warn(
        'this function is deprecated and will be removed in `v4.0.0`.',
        AiidaDeprecationWarning)

    if pseudos and pseudo_family:
        raise ValueError(
            'you cannot specify both "pseudos" and "pseudo_family"')
    elif pseudos is None and pseudo_family is None:
        raise ValueError(
            'neither an explicit pseudos dictionary nor a pseudo_family was specified'
        )
    elif pseudo_family:
        # This will already raise some exceptions, potentially, like the ones below
        pseudos = get_pseudos_from_structure(structure, pseudo_family.value)
    elif isinstance(pseudos, (str, Str)):
        raise TypeError(
            'you passed "pseudos" as a string - maybe you wanted to pass it as "pseudo_family" instead?'
        )

    for kind in structure.get_kind_names():
        if kind not in pseudos:
            raise ValueError(f'no pseudo available for element {kind}')
        elif not isinstance(pseudos[kind], (LegacyUpfData, UpfData)):
            raise ValueError(
                f'pseudo for element {kind} is not of type UpfData')

    return pseudos
示例#7
0
def wf_setupparams(base_parameter, structure, pseudo_familyname,
                   nume2bnd_ratio):
    pseudos = get_pseudos_from_structure(structure, pseudo_familyname.value)
    nelec = get_numelectrons_structure_upffamily(structure, pseudos)
    nbnd = nelec * nume2bnd_ratio.value
    nbnd = max(nbnd, 20)  # minimum of 20 bands to avoid certain crashes
    parameter_dict = base_parameter.get_dict()
    parameter_dict['SYSTEM']['nbnd'] = nbnd
    parameters = Dict(dict=parameter_dict)

    return parameters
示例#8
0
def launch_calculation(code, structure, pseudo_family, max_num_machines,
                       max_wallclock_seconds, with_mpi, daemon):
    """Run a CpCalculation."""
    from aiida.orm import Dict
    from aiida.orm.nodes.data.upf import get_pseudos_from_structure
    from aiida.plugins import CalculationFactory
    from aiida_quantumespresso.utils.resources import get_default_options

    parameters = {
        'CONTROL': {
            'calculation': 'cp',
            'restart_mode': 'from_scratch',
            'wf_collect': False,
            'iprint': 1,
            'isave': 100,
            'dt': 3.0,
            'max_seconds': 25 * 60,
            'nstep': 10,
        },
        'SYSTEM': {
            'ecutwfc': 30.0,
            'ecutrho': 240.0,
            'nr1b': 24,
            'nr2b': 24,
            'nr3b': 24,
        },
        'ELECTRONS': {
            'electron_damping': 1.0e-1,
            'electron_dynamics': 'damp',
            'emass': 400.0,
            'emass_cutoff': 3.0,
        },
        'IONS': {
            'ion_dynamics': 'none'
        },
    }

    inputs = {
        'code': code,
        'structure': structure,
        'pseudos': get_pseudos_from_structure(structure, pseudo_family),
        'parameters': Dict(dict=parameters),
        'metadata': {
            'options':
            get_default_options(max_num_machines, max_wallclock_seconds,
                                with_mpi),
        }
    }

    launch.launch_process(CalculationFactory('quantumespresso.cp'), daemon,
                          **inputs)
示例#9
0
    def run_pw_scf(self):
        """Run the SCF with pw.x."""

        # A fixed value, for testing
        ecutwfc = 30.

        self.ctx.scf_parameters = {
            'CONTROL': {
                'calculation': 'scf',
            },
            'SYSTEM': {
                'ecutwfc': ecutwfc,
                'ecutrho': ecutwfc * 8.,
            }
        }

        inputs = {
            'code':
            self.inputs.pw_code,
            'structure':
            self.inputs.structure,
            'pseudos':
            get_pseudos_from_structure(
                self.inputs.structure, self.inputs.pseudo_family.value
            ),
            'parameters':
            orm.Dict(dict=self.ctx.scf_parameters),
            'kpoints':
            self.inputs.kpoints_scf,
            'metadata': {
                'options': {
                    # int is used to convert from AiiDA nodes to python ints
                    'resources': {
                        'num_machines': int(self.inputs.num_machines)
                    },
                    'max_wallclock_seconds':
                    int(self.inputs.max_wallclock_seconds),
                    'withmpi': True,
                }
            }
        }

        running = self.submit(
            CalculationFactory('quantumespresso.pw'), **inputs
        )
        self.report(
            'launching PwCalculation<{}> (SCF step)'.format(running.pk)
        )

        return ToContext(pw_scf=running)
示例#10
0
####################
SiriusParameters = DataFactory('sirius.scf')
StructureData = DataFactory('structure')
KpointsData = DataFactory('array.kpoints')
Dict = DataFactory('dict')
SinglefileData = DataFactory('singlefile')

NLCGParameters = DataFactory('sirius.py.nlcg')
parameters = SiriusParameters(sirius_json)
nlcgconfig = yaml.load(open('nlcg.yaml', 'r'))
nlcgconfig = {'System': nlcgconfig['System'], 'CG': nlcgconfig['CG']}

nlcgparams = NLCGParameters(nlcgconfig)

structure, magnetization, kpoints = from_sirius_json(sirius_json)
pseudos = get_pseudos_from_structure(structure, args.pseudos)

print('tasks_per_core', args.ntasks_per_core)
# 'num_cores_per_machine': 1,
comp_resources = {
    'num_mpiprocs_per_machine': args.ntasks_per_node,
    'num_machines': args.nodes,
    'num_cores_per_mpiproc': args.ntasks_per_core
}

# set up calculation
inputs = {
    'code': code,
    'sirius_config': parameters,
    'structure': structure,
    'kpoints': kpoints,
示例#11
0
s = StructureData(cell=cell)
s.append_atom(position=(0., 0., 0.), symbols='Ba')
s.append_atom(position=(alat / 2., alat / 2., alat / 2.), symbols='Ti')
s.append_atom(position=(alat / 2., alat / 2., 0.), symbols='O')
s.append_atom(position=(alat / 2., 0., alat / 2.), symbols='O')
s.append_atom(position=(0., alat / 2., alat / 2.), symbols='O')

kpoints = KpointsData()
kpoints.set_kpoints_mesh([2, 2, 2])

# set up calculation
inputs = {
    'code': code,
    'sirius_config': parameters,
    'structure': s,
    'kpoints': kpoints,
    'metadata': {
        'description': "Test job submission with the aiida_sirius plugin",
    },
    'pseudos': get_pseudos_from_structure(s, 'sssp_efficiency')
}

# Note: in order to submit your calculation to the aiida daemon, do:
# from aiida.engine import submit
# future = submit(CalculationFactory('sirius'), **inputs)
calc = CalculationFactory('sirius.scf')
result = run(calc, **inputs)

res = result['sirius'].get_content()
print("Result: \n{}".format(res))
示例#12
0
structure = load_node(<STRUCTURE PK>)  # REPLACE <STRUCTURE PK>
builder.structure = structure

# Define calculation
parameters = {
  'CONTROL': {
    'calculation': 'scf',  # self-consistent field
  },
  'SYSTEM': {
    'ecutwfc': 30.,  # wave function cutoff in Ry
    'ecutrho': 240.,  # density cutoff in Ry
  },
}
builder.parameters = Dict(dict=parameters)

# Select pseudopotentials
builder.pseudos = get_pseudos_from_structure(structure, '<PP FAMILY>')  # REPLACE <PP FAMILY>

# Define K-point mesh in reciprocal space
KpointsData = DataFactory('array.kpoints')
kpoints = KpointsData()
kpoints.set_kpoints_mesh([4,4,4])
builder.kpoints = kpoints

# Set resources
builder.metadata.options.resources = {'num_machines': 1}

# Submit the job
calcjob = submit(builder)
print('Submitted CalcJob with PK=' + str(calcjob.pk))
        "precond": precond,
        "tol": 1e-09,
    },
    "System": {
        "T": 300.0,
        "smearing": "gaussian-spline"
    },
}
nlcgparams = NLCGParameters(nlcgconfig)

structure, magnetization, kpoints = from_sirius_json(sirius_json)

####################################################
# # Warning pseudopotentials are taken from aiida! #
####################################################
pseudos = get_pseudos_from_structure(structure, 'normcons')

# 'num_cores_per_machine': 1,
comp_resources = {
    'num_mpiprocs_per_machine': args.ntasks_per_node,
    'num_machines': args.nodes,
    'num_cores_per_mpiproc': args.ntasks_per_core
}

# set up calculation
inputs = {
    'code': code,
    'sirius_config': parameters,
    'structure': structure,
    'kpoints': kpoints,
    'nlcgparams': nlcgparams,
示例#14
0
# load SIRIUS parameters from json
sirius_json = json.load(open('sirius.json', 'r'))

# extract structure, magnetization, kppoints (for the sake of AiiDA provenance)
structure, magnetization, kpoints = helpers.from_sirius_json(sirius_json)

# set up calculation

inputs = {
    'code': code,
    'sirius_config': SiriusParameters(sirius_json),
    'sirius_md_params': md_parameters,
    'structure': structure,
    'kpoints': kpoints,
    'metadata': {
        'options': {
            'withmpi': True,
            'prepend_text': '#SBATCH --nodelist=ault02',
            'max_wallclock_seconds': 3600
        },
    },
    'pseudos': get_pseudos_from_structure(structure, 'sg15_pz')
}

calc = CalculationFactory('sirius.md')
# result = submit(calc, **inputs)
submit(calc, **inputs)

# res = result['sirius'].get_content()
# print("Result: \n{}".format(res))
示例#15
0
            'restart_mode': 'from_scratch',
            'wf_collect': True,
        },
        'SYSTEM': {
            'ecutwfc': 30.,
            'ecutrho': 240.,
        },
        'ELECTRONS': {
            'conv_thr': 1.e-6,
        }
    })

kpoints = KpointsData()
kpoints.set_kpoints_mesh([4, 4, 4])

builder.pseudos = get_pseudos_from_structure(s, pseudo_family)

builder.metadata.options.resources = {'num_machines': 1}
builder.metadata.options.max_wallclock_seconds = 1800

builder.metadata.label = 'My generic title'
builder.metadata.description = 'My generic description'

builder.structure = s
builder.parameters = parameters
builder.kpoints = kpoints

calc = submit(builder)

print(f'created calculation with PK={calc.pk}')
示例#16
0
def run_calculation(
    name, 
    struct, 
    group, 
    codename, 
    pseudo_family, 
    k_distance=0.20, 
    scale_element_init_moment={}, 
    input_namelists={}, 
    code_runtime_options=None
):
    """
    This function converts a given initial structure into an AiiDA readable format
    to perform a static SCF calculation.
     
    Parameters
    ----------
    name : str
        The name of the structure or calculations eg. name='Fe'
    struct : Structure object
        The defect structure
    group : str
        The name of the group to store AiiDA nodes on AiiDA database. Its advisable to keep track
        of this name to make sure you organize your data
    codename : str
        The name of the code configured on AiiDA database to perform this type of calculations
    pseudo_family : str
        A pseudopotential family configured on AiiDA database
    k_distance : float
        The density of k-point mesh use for k-point integration in DFT. For more see this
        material cloud page for its usage: https://www.materialscloud.org/work/tools/qeinputgenerator
        Default=0.2.
    scale_element_init_moment : dict
        A user define dictionary type of magnetic ions to scale its magnetic moment.
        Default={}.
    input_namelists : dict
        A user define Quantum ESPRESSO (QE) input namelists. Default={}
    mu_plus : bool
        If True, to specify a total charge of the system and initialise a
        starting charge of muon. Defualt=False
    code_runtime_options : None
        The HPC requirements of number of nodes and k-points. Depends on the code 
        configure in `codename`.
        
    Returns
    -------
    Submit calculation to AiiDA daemon 
    """

    from aiida_quantumespresso.utils.resources import get_default_options, get_automatic_parallelization_options
    from aiida.orm import Group

    g, just_created = Group.objects.get_or_create(group)

    code = Code.get_from_string(codename)
    builder = code.get_builder()

    builder.metadata.label = "{} - Unitcell".format(name)
    builder.metadata.description = "Magnetic test for - {}".format(name)

    StructureData     = DataFactory("structure")
    labeled_structure, nspin, magnetic_elements_kinds = analyze_pymatgen_structure(struct, mark_muon=False)
    builder.structure = StructureData(pymatgen=labeled_structure)

    structure_copy = StructureData(pymatgen=labeled_structure)

    if nspin == 2:
        # Set all polarizations to 0.4
        for k in magnetic_elements_kinds.keys():
            for idx in magnetic_elements_kinds[k].keys():
                magnetic_elements_kinds[k][idx] = magnetic_elements_kinds[k][idx] * scale_element_init_moment.get(k, 1.)
    elif nspin == 4:
        raise NotImplemented("Non collinear case not implemented.")


    Dict = DataFactory('dict')
    parameters_dict = {
        'CONTROL': {
            'calculation': 'scf',
            'restart_mode': 'from_scratch',
        },
        'SYSTEM': {
            'ecutwfc': 60.,
            'ecutrho': 600.,
            'occupations':'smearing',
            'smearing': 'm-v',
            'degauss' : 0.02,
            'nspin': nspin, #
        },
        'ELECTRONS': {
            'conv_thr'    : 1.e-7,
            'mixing_beta' : 0.30,
            'mixing_mode' : 'local-TF'
        }
    }

    #print('Old Dictionary\n', parameters_dict)

    #override
    parameters_dict=merge(input_namelists, parameters_dict)

    #print('New Dictionary\n', parameters_dict)

    parameters = Dict(dict=parameters_dict)
    builder.parameters = parameters

    if nspin == 2:
        parameters_dict['SYSTEM']['starting_magnetization'] = merge_dict_of_dicts(magnetic_elements_kinds)

    KpointsData = DataFactory('array.kpoints')
    #kpoints = KpointsData()
    #kpoints.set_kpoints_mesh([2,2,2],offset=(0,0,0))

    kpoints = KpointsData()
    kpoints.set_cell_from_structure(builder.structure)
    kpoints.set_kpoints_mesh_from_density(k_distance, force_parity=False)
    kpoints.store()

    settings_dict={}
    num_k_points = np.prod(kpoints.get_kpoints_mesh()[0])
    if num_k_points==1:
        settings_dict={'gamma_only': True}
    else:
        settings_dict={'gamma_only': False}


    builder.pseudos = get_pseudos_from_structure(structure_copy, pseudo_family)

    #builder.metadata.options.resources = resources

    #builder.metadata.options.max_wallclock_seconds = 259200  #86400

    builder.parameters = parameters
    builder.kpoints = kpoints

    # AAAA: automatic_parallelization does not work!!!
    automatic_parallelization = False
    if automatic_parallelization:
        automatic_parallelization = get_automatic_parallelization_options(1,  24*60*60-60*5)
        builder.automatic_parallelization = Dict(dict=automatic_parallelization)
    else:
        if code_runtime_options is None or code_runtime_options == '':
                                        # num machines, time, mpi
            default_options = get_default_options(1, 24*60*60-60*5, True)
            builder.metadata.options = default_options
        else:
            exec_options = code_runtime_options.split('|')[0].split()
            default_options = get_default_options(int(exec_options[0]), int(exec_options[1]), True)
            builder.metadata.options = default_options
        if code_runtime_options is None or code_runtime_options == '':
            npool = np.min([4, num_k_points])
            settings_dict['cmdline'] = ['-nk', str(npool), '-ndiag', '1']
        else:
            parallel_options = code_runtime_options.split('|')[1]
            settings_dict['cmdline'] = parallel_options.strip().split()

    clean_workdir = False
    final_scf = False
    if clean_workdir:
        builder.clean_workdir = Bool(True)

    if final_scf:
        builder.final_scf = Bool(True)

    calc = submit(builder)
    if not (g is None):
        g.add_nodes(calc)

    print(name +' magnetic test calculation created  with PK = {}'.format(calc.pk))
    return calc
示例#17
0
def launch_calculation(
    code, structures, num_images, num_steps, pseudo_family, kpoints_mesh, ecutwfc, ecutrho, smearing, max_num_machines,
    max_wallclock_seconds, with_mpi, daemon, parent_folder, dry_run
):
    """
    Run a NebCalculation.
    Note that some parameters are hardcoded.
    """
    from aiida.orm import Dict
    from aiida.orm.nodes.data.upf import get_pseudos_from_structure
    from aiida.plugins import CalculationFactory
    from aiida_quantumespresso.utils.resources import get_default_options

    pw_parameters = {
        'CONTROL': {
            'calculation': 'relax',
        },
        'SYSTEM': {
            'ecutwfc': ecutwfc,
            'ecutrho': ecutrho,
        }
    }

    neb_parameters = {
        'PATH': {
            'restart_mode': ('restart' if parent_folder else 'from_scratch'),
            'opt_scheme': 'broyden',
            'num_of_images': num_images,
            'nstep_path': num_steps,
        },
    }

    try:
        validate.validate_smearing(pw_parameters, smearing)
    except ValueError as exception:
        raise click.BadParameter(str(exception))

    inputs = {
        'code': code,
        'first_structure': structures[0],
        'last_structure': structures[1],
        'pw': {
            'pseudos': get_pseudos_from_structure(structures[0], pseudo_family),
            'kpoints': kpoints_mesh,
            'parameters': Dict(dict=pw_parameters),
        },
        'parameters': Dict(dict=neb_parameters),
        'metadata': {
            'options': get_default_options(max_num_machines, max_wallclock_seconds, with_mpi),
        }
    }

    if parent_folder:
        inputs['parent_folder'] = parent_folder

    if dry_run:
        if daemon:
            # .submit() would forward to .run(), but it's better to stop here,
            # since it's a bit unexpected and the log messages output to screen
            # would be confusing ("Submitted NebCalculation<None> to the daemon")
            raise click.BadParameter('cannot send to the daemon if in dry_run mode', param_hint='--daemon')
        inputs['metadata']['store_provenance'] = False
        inputs['metadata']['dry_run'] = True

    launch.launch_process(CalculationFactory('quantumespresso.neb'), daemon, **inputs)
示例#18
0
kpoints.set_kpoints_mesh([2, 2, 2])

# 'num_cores_per_machine': 1,
comp_resources = {'num_mpiprocs_per_machine': 2,
                  'num_machines': 1,
                  'num_cores_per_mpiproc': 6}

# set up calculation
inputs = {
    'code': code,
    'sirius_config': parameters,
    'structure': s,
    'kpoints': kpoints,
    'nlcgparams': nlcgparams,
    'metadata': {
        'description': "Test job submission with the aiida_sirius plugin",
        'options': {
            'resources': comp_resources,
            'withmpi': True,
            'max_wallclock_seconds': 200
        }
    },
    'pseudos': get_pseudos_from_structure(s, 'normcons')
}

# Note: in order to submit your calculation to the aiida daemon, do:
# from aiida.engine import submit
# future = submit(CalculationFactory('sirius'), **inputs)
calc = CalculationFactory('sirius.py.nlcg')
result = submit(calc, **inputs)
示例#19
0
def launch_calculation(code, structure, pseudo_family, kpoints_mesh, ecutwfc,
                       ecutrho, hubbard_u, hubbard_v, hubbard_file_pk,
                       starting_magnetization, smearing, max_num_machines,
                       max_wallclock_seconds, with_mpi, daemon, parent_folder,
                       dry_run, mode, unfolded_kpoints):
    """Run a PwCalculation."""
    from aiida.orm import Dict
    from aiida.orm.nodes.data.upf import get_pseudos_from_structure
    from aiida.plugins import CalculationFactory
    from aiida_quantumespresso.utils.resources import get_default_options

    parameters = {
        'CONTROL': {
            'calculation': mode,
        },
        'SYSTEM': {
            'ecutwfc': ecutwfc,
            'ecutrho': ecutrho,
        }
    }

    if mode in CALCS_REQUIRING_PARENT and not parent_folder:
        raise click.BadParameter(
            "calculation '{}' requires a parent folder".format(mode),
            param_hint='--parent-folder')

    try:
        hubbard_file = validate.validate_hubbard_parameters(
            structure, parameters, hubbard_u, hubbard_v, hubbard_file_pk)
    except ValueError as exception:
        raise click.BadParameter(str(exception))

    try:
        validate.validate_starting_magnetization(structure, parameters,
                                                 starting_magnetization)
    except ValueError as exception:
        raise click.BadParameter(str(exception))

    try:
        validate.validate_smearing(parameters, smearing)
    except ValueError as exception:
        raise click.BadParameter(str(exception))

    if unfolded_kpoints:
        from aiida.orm import KpointsData
        unfolded_list = kpoints_mesh.get_kpoints_mesh(print_list=True)
        kpoints_mesh = KpointsData()
        kpoints_mesh.set_kpoints(unfolded_list)

    inputs = {
        'code': code,
        'structure': structure,
        'pseudos': get_pseudos_from_structure(structure, pseudo_family),
        'kpoints': kpoints_mesh,
        'parameters': Dict(dict=parameters),
        'metadata': {
            'options':
            get_default_options(max_num_machines, max_wallclock_seconds,
                                with_mpi),
        }
    }

    if parent_folder:
        inputs['parent_folder'] = parent_folder

    if hubbard_file:
        inputs['hubbard_file'] = hubbard_file

    if dry_run:
        if daemon:
            # .submit() would forward to .run(), but it's better to stop here,
            # since it's a bit unexpected and the log messages output to screen
            # would be confusing ("Submitted PwCalculation<None> to the daemon")
            raise click.BadParameter(
                'cannot send to the daemon if in dry_run mode',
                param_hint='--daemon')
        inputs['metadata']['store_provenance'] = False
        inputs['metadata']['dry_run'] = True

    launch.launch_process(CalculationFactory('quantumespresso.pw'), daemon,
                          **inputs)
示例#20
0
def qePwOriginalSubmit(codename,
                       structure,
                       kpoints,
                       pseudo_family,
                       metadata,
                       pseudo_dict={},
                       add_parameters={},
                       del_parameters={},
                       cluster_options={},
                       settings_dict={}):
    """

    :code:`qePwOriginalSubmit` will submit an original computational task to the desired computer by using certain code.

    :param codename: (mandatory) A string represents the code for pw.x that you want to use.
    :type codename: python string object

    :param structure: (mandatory) The structure of your system.
    :type structure: aiida.orm.StructureData object

    :param add_parameters: (optional, default = {}) The desired parameters that you want to state, it can be
                           incomplete, because inside the function there is a default setting for parameters which can
                           be used in most cases, but if you have specific need, you can put that in parameters,
                           the format is similar as pw.x input file.

                           If you want to assign DFT+U and spin-polarization, you need to specify it on your own.

                           In Aiida, there is a very efficient way to specify the :code:`hubbard_u`,
                           :code:`starting_magnetization` and :code:`starting_ns_eigenvalue`. I give some examples
                           in below:

                           .. code-block:: python

                                # hubbard_u
                                'SYSTEM': {
                                    'hubbard_u': {
                                        'Fe': 5.0,
                                        'Fe3': 5.0 # if you have different spins of same atom, then you should use
                                        newStructure function to create the structure
                                    },
                                    'starting_magnetization': {
                                        'Fe': 0.1,
                                        'Fe3': 0.1,
                                    },
                                    'starting_ns_eigenvalue': [
                                        [1, 1, 'Fe', 1.0] # represent: starting_ns_eigenvalue(1, 1, 1)=1.0
                                        # others are the same, if you want to assign to Fe3, just replace Fe with Fe3.
                                    ]
                                }

    :type add_parameters: python dictionary

    :param del_parameters: (optional, default = {}) The tags that we would like to delete, for example if we do not
                           want to use spin-polarized simulation, then 'nspin' needs to be deleted. Same structure
                           as add_parameters.

                           e.g. :code:`{'CONTROL': [key1, key2, key3], 'SYSTEM': [key1, key2, key3]}`
    :type del_parameters: python dictionary object

    :param kpoints: (mandatory) The kpoints that you want to use, if the kpoints has only 1 list, then it is the kpoint
                    mesh, but if two lists are detected, then the first will be k-point mesh, the second one will be the
                    origin of k-point mesh.e.g. [[3, 3, 1]] or [[3, 3, 1],[0.5, 0.5, 0.5]]
    :type kpoints: python list object

    :param pseudo_family: (mandatory) The pseudopotential family that you want to use. Make sure that you already have
                          that configured, otherwise an error will occur.
    :type pseudo_family: python string object.

    :param pseudo_dict: (optional, default = {}) which contains the pseudopotential files that we want to use in the
                        simulation. In here it is very important to note that the path of the pseudopotential file
                        has to be in the absolute path.

                        e.g.

                        .. code-block:: python

                            pseudo_dict = {
                                'Fe': UpfData(absolute_path),
                                'Fe3': UpfData(absolute_path)
                            }
    :type pseudo_dict: python dictionary object.

    :param cluster_options: (optional, default = {}) The detailed option for the cluster. Different cluster may have
                            different settings. Only the following 3 keys can have effects: (1) resources (2) account
                            (3) queue_name
    :type cluster_options: python dictionary object

    :param metadata: (mandatory) The dictionary that contains information about metadata. For example: label and
                     description. label and description are mendatory.

                     e.g. :code:`{'label':{}, 'description':{}}`
    :type metadata: python dictionary object

    :param settings_dict: (optional, default = {}) which contains the additional information for the pw.x
                          calculation. e.g. Fixed atom, retrieving more files, parser options, etc. And the
                          command-line options.
    :type settings_dict: python dictionary object

    :returns: uuid of the new CalcJobNode

    """

    code = Code.get_from_string(codename)
    computer = codename.split('@')[1]  # get the name of the cluster
    pw_builder = code.get_builder()

    # pseudopotential
    # check whether pseudo_family and pseudo_dict are set at the same time, if true, then break
    if len(pseudo_family) > 0 and len(pseudo_dict) > 0:
        return ValueError(
            "You cannot set pseudo_family and pseudo_dict at the same time")
    if len(pseudo_family) == 0 and len(pseudo_dict) == 0:
        return ValueError(
            "You need to specify at least one in pseudo_family or pseudo_dict."
        )

    if len(pseudo_family) != 0:
        pw_builder.pseudos = get_pseudos_from_structure(
            structure, family_name=pseudo_family)
    if len(pseudo_dict) != 0:
        pw_builder.pseudos = pseudo_dict

    # set kpoints
    kpts = KpointsData()
    if len(kpoints) == 1:
        kpts.set_kpoints_mesh(mesh=kpoints[0])
    else:
        kpts.set_kpoints_mesh(mesh=kpoints[0], offset=kpoints[1])

    # parameters
    parameters_default = Dict(dict=pwParameter)

    # add parameters in add_parameters
    parameters_tmp = deepcopy(parameters_default)

    for key, value in add_parameters.items():
        for key2, value2 in value.items():
            parameters_tmp[key][key2] = value2

    # delete parameters in del_parameters
    for key, value in del_parameters.items():
        tmp = parameters_tmp[key]
        for key2 in value:
            if key2 in tmp.keys():
                tmp.pop(key2)
            else:
                pass

    parameters_default = parameters_tmp

    # set labels and description
    pw_builder.metadata.label = metadata['label']
    pw_builder.metadata.description = metadata['description']

    # set default options for slurm
    pw_builder.metadata.options['resources'] = slurm_options[computer]['qe'][
        'resources']  # in here machine = node
    pw_builder.metadata.options['max_wallclock_seconds'] = slurm_options[
        computer]['qe']['max_wallclock_seconds']  #in here machine = node
    pw_builder.metadata.options['account'] = slurm_options[computer]['qe'][
        'account']  # in here machine = node
    pw_builder.metadata.options['scheduler_stderr'] = slurm_options[computer][
        'qe']['scheduler_stderr']
    pw_builder.metadata.options['scheduler_stderr'] = slurm_options[computer][
        'qe']['scheduler_stderr']
    pw_builder.metadata.options['queue_name'] = slurm_options[computer]['qe'][
        'queue_name']

    # revised by cluster_options
    if len(cluster_options) > 0:
        if 'resources' in cluster_options.keys():
            pw_builder.metadata.options['resources'] = cluster_options[
                'resources']
        if 'account' in cluster_options.keys():
            pw_builder.metadata.options['account'] = cluster_options['account']
        if 'queue_name' in cluster_options.keys():
            pw_builder.metadata.options['queue_name'] = cluster_options[
                'queue_name']

    # initialize the settings_dict
    if len(settings_dict) == 0:
        settings_dict['cmdline'] = ['-nk', '4']
    else:
        pass  # do nothing

    # get atomic occupations
    if 'lda_plus_u' in parameters_default['SYSTEM']:
        if parameters_default['SYSTEM']['lda_plus_u']:
            settings_dict['parser_options'] = {
                'parse_atomic_occupations': True
            }

    # launch the simulation
    pw_builder.structure = structure
    pw_builder.kpoints = kpts
    pw_builder.parameters = parameters_default
    pw_builder.settings = Dict(dict=settings_dict)
    calc = submit(pw_builder)

    return calc.uuid
示例#21
0
def qePwContinueSubmit(uuid,
                       pseudo_family,
                       pseudo_dict={},
                       codename='',
                       parent_folder=True,
                       add_parameters={},
                       del_parameters={},
                       kpoints=[],
                       cluster_options={},
                       metadata={},
                       settings_dict={}):
    """

    `qePwContinueSubmit` will continue a simulation with similar or modified input parameters. All the parameters are
    listed in the kwargs.

    :param uuid: (mandatory) The uuid of previous calculation. We will start our calculation from there. Because uuid
                 is the unique identification number for each CalcJobNode

                    **Notice**: The uuid must be in the results dictionary, if not the program will shout KeyError.
                    And if you are testing, you could use assignValue to quickly create a dictionary that contains
                    the uuid that you want to continue.
    :type uuid: python string object

    :param pseudo_family: (mandatory) The pseudopotential family that you want to use. Make sure that you already have
                          that configured, otherwise an error will occur. This is mendatory.
    :type pseudo_family: python string object

    :param pseudo_dict: (optional, default = {}) Which contains the pseudopotential files that we want to use in the
                        simulation.
    :type pseudo_dict: python dictionary object

    :param codename: (optional, default = '') Represent the code for pw.x that you want to use. If you want to use the
                     same as previous calculation, then you need to use Str('')
    :type codename: python string object

    :param parent_folder: (optional, default = True) If parent_folder is True, then the calculation will start with the
                          output files from previous calculations.
    :type parent_folder: python boolean object

    :param add_parameters: (optional, default = {}) The desired parameters that you want to state, it can be incomplete,
                           because inside the function there is a default setting for parameters which can be used in
                           most cases, but if you have specific need, you can put that in parameters, the format is
                           similar as pw.x input file.

                           If you want to assign DFT+U and spin-polarization, you need to specify it on your own.

                           e.g. :code:`{'CONTROL':{}, 'SYSTEM':{}}`

                           **Notice**: more options in qePwOriginalSubmit function. In qePwContinueSubmit,
                           we assume that the user wants to restart from previous converged wave functions and
                           charge density, so we set ['CONTROL']['restart_mode']='restart', ['ELECTRON'][
                           'startingwfc']='file and ['ELECTRON']['startingpot']='file'.
    :type add_parameters: python dictionary object

    :param del_parameters: (optional, default = {})The tags that we would like to delete, for example if we do not
                           want to use spin-polarized simulation, then 'nspin' needs to be deleted. Same structure as
                           add_parameters.

                           e.g. :code:`{'CONTROL': [key1, key2, key3], 'SYSTEM': [key1, key2, key3]}`
    :type del_parameters: python dictionary object

    :param kpoints: (optional, default = []), if you want to keep the k-points for previous calculation, just use an
                    empty list :code:`[]`. The kpoints that you want to use, if the kpoints has only 1 list,
                    then it is the kpoint mesh, but if two lists are detected, then the first will be k-point mesh,
                    the second one will be the origin of k-point mesh.e.g. [[3, 3, 1]] or [[3, 3, 1],[0.5, 0.5, 0.5]]
    :type kpoints: python list object

    :param cluster_options: (optional, default = {}) The detailed option for the cluster. Different cluster may have
                            different settings. Only the following 3 keys can have effects: (1) resources (2)
                            account (3) queue_name. If value is :code:`{}`, then it means we will use previous settings
    :type cluster_options: python dictionary object

    :param metadata: (optional, default = {}) The dictionary that contains information about metadata. For example:
                     label and description.label and description are mendatory. If value is :code:`{}`,
                     then it means we will use previous settings.
    :type metadata: python dictionary object

    :param settings_dict: (optional, default = {}) which contains the additional information for the pw.x calculation.
                          e.g. Fixed atom, retrieving more files, parser options, etc. And the command-line options.
                          If value is :code:`{}`, then it means we will use previous settings.
    :type settings_dict: python dictionary object

    :returns: uuid of the CalcJobNode of the newest calculation.

    """

    node = load_node(uuid=uuid)

    if len(codename) == 0:  # not going to change cluster
        computer = node.computer.label
        restart_builder = node.get_builder_restart()  # get the restart_builder
    else:
        computer = codename.split('@')[1]
        code = Code.get_from_string(codename)
        restart_builder = code.get_builder()

    parameters_tmp = deepcopy(node.inputs.parameters)

    parameters_dict = parameters_tmp.get_dict()
    calc_type = parameters_dict['CONTROL']['calculation']

    # change the parameters (since this is the continuation of the previous calculation)
    parameters_tmp['CONTROL']['restart_mode'] = 'restart'
    parameters_tmp['ELECTRONS'][
        'startingwfc'] = 'file'  # from wave function in aiida.save
    parameters_tmp['ELECTRONS'][
        'startingpot'] = 'file'  # from charge density in aiida.save

    if calc_type == 'relax' or calc_type == 'vc-relax':
        structure = node.outputs.output_structure
    elif calc_type == 'scf' or calc_type == 'nscf':
        structure = node.inputs.structure

    # assign parameters in add_parameters
    for key, value in add_parameters.items():
        for key2, value2 in value.items():
            parameters_tmp[key][key2] = value2

    # delete parameters in del_parameters
    for key, value in del_parameters.items():
        tmp = parameters_tmp[key]
        for key2 in value:
            if key2 in tmp.keys():
                tmp.pop(key2)

    parameters_default = parameters_tmp

    # reset the kpoints
    if len(kpoints) > 0:
        kpts = KpointsData()
        if len(kpoints) == 1:
            kpts.set_kpoints_mesh(mesh=kpoints[0])
        else:
            kpts.set_kpoints_mesh(mesh=kpoints[0], offset=kpoints[1])
    else:
        kpts = node.inputs.kpoints

    # pseudopotential
    # check whether pseudo_family and pseudo_dict are set at the same time, if true, then break
    if len(pseudo_family) > 0 and len(pseudo_dict) > 0:
        return ValueError(
            "You cannot set pseudo_family and pseudo_dict at the same time")
    if len(pseudo_family) == 0 and len(pseudo_dict) == 0:
        return ValueError(
            "You need to specify at least one in pseudo_family or pseudo_dict."
        )

    if len(pseudo_family) != 0:
        restart_builder.pseudos = get_pseudos_from_structure(
            structure, family_name=pseudo_family)
    if len(pseudo_dict) != 0:
        restart_builder.pseudos = pseudo_dict

    # set default options for slurm
    restart_builder.metadata.options['resources'] = slurm_options[computer][
        'qe']['resources']  # in here machine = node
    restart_builder.metadata.options['max_wallclock_seconds'] = slurm_options[
        computer]['qe']['max_wallclock_seconds']  # in here machine = node
    restart_builder.metadata.options['account'] = slurm_options[computer][
        'qe']['account']  # in here machine = node
    restart_builder.metadata.options['scheduler_stderr'] = slurm_options[
        computer]['qe']['scheduler_stderr']
    restart_builder.metadata.options['scheduler_stderr'] = slurm_options[
        computer]['qe']['scheduler_stderr']
    restart_builder.metadata.options['queue_name'] = slurm_options[computer][
        'qe']['queue_name']

    # reset cluster_options:
    if len(cluster_options) > 0:
        if 'resources' in cluster_options.keys():
            restart_builder.metadata.options['resources'] = cluster_options[
                'resources']
        if 'account' in cluster_options.keys():
            restart_builder.metadata.options['account'] = cluster_options[
                'account']
        if 'queue_name' in cluster_options.keys():
            restart_builder.metadata.options['queue_name'] = cluster_options[
                'queue_name']

    # reset metadata
    if len(metadata) > 0:
        if 'label' in metadata.keys():
            restart_builder.metadata.label = metadata['label']
        else:
            restart_builder.metadata.label = node.label

        if 'description' in metadata.keys():
            restart_builder.metadata.description = metadata['description']
        else:
            restart_builder.metadata.description = node.description
    else:
        restart_builder.metadata.label = node.label
        restart_builder.metadata.description = node.description

    # assign the parent_folder
    if parent_folder:
        restart_builder.parent_folder = node.outputs.remote_folder

    # set settings_dict
    if len(settings_dict) > 0:
        pass
    else:
        settings_dict = node.inputs.settings.get_dict()

    # submit the calculation
    restart_builder.structure = structure
    restart_builder.kpoints = kpts
    restart_builder.parameters = parameters_default
    restart_builder.settings = Dict(dict=settings_dict)
    calc = submit(restart_builder)

    return calc.uuid