Skip to article frontmatterSkip to article content

How to submit a PwBaseWorkChain

In the following we show how to run a calculation with the aiida-quantumespresso plugin using the new atomistic StructureData. The procedure is very similar to the old way, except to the fact that now properties like magnetization and charge are provided within the structure and not in the input parameters of the PwCalculation.

For now, only magnetization is supported.

PLEASE USE THE FOLLOWING VERSIONS OF THE RELATED CODES:

from aiida import load_profile, orm
from aiida_quantumespresso.workflows.pw.base import PwBaseWorkChain
from aiida_atomistic import StructureData, StructureDataMutable

load_profile()
Profile<uuid='1a5a8d0836814a04a238c67cc7481655' name='default'>

Once loaded the necessary modules, we start building up our StructureDataMutable, to be then converted into the AiiDA StructureData (via the to_immutable method):

mutable_structure = StructureDataMutable()
mutable_structure.set_cell([[0.0, 1.8, 1.8], [1.8, 0.0, 1.8], [1.8, 1.8, 0.0]])

mutable_structure.add_atom(**{
            'symbols':'Si',
            'positions':[1/2, 1/2, 1/2],
            'kinds': 'Si1'
        })
mutable_structure.add_atom(**{
            'symbols':'Si',
            'positions':[3/4, 3/4, 3/4],
            'kinds': 'Si1'
        })

structure = StructureData.from_mutable(mutable_structure)

We then generate the PwBaseWorkChain builder via the get_builder_from_protocol method, providing as input the pw.x code node and the structure:

from aiida.engine import submit, run_get_node


builder = PwBaseWorkChain.get_builder_from_protocol(
    code=orm.load_code("pw-qe-7.2@localhost"), 
    structure=structure,
    protocol="fast",
    )

run = run_get_node(builder)
11/19/2024 03:51:49 PM <586862> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [2659|PwBaseWorkChain|run_process]: launching PwCalculation<2664> iteration #1
11/19/2024 03:51:53 PM <586862> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [2659|PwBaseWorkChain|results]: work chain completed after 1 iterations
11/19/2024 03:51:54 PM <586862> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [2659|PwBaseWorkChain|on_terminated]: remote folders will not be cleaned

After the job is finished, you can inspect the outputs as usual:

run[0]
{'remote_folder': <RemoteData: uuid: 7d2847b9-aedf-44e0-a6a0-ef6601fd4fae (pk: 2665)>, 'retrieved': <FolderData: uuid: 99670a87-9a4f-49cf-a0b8-91bdb0a8e1df (pk: 2666)>, 'output_parameters': <Dict: uuid: f616f696-f0ca-463a-8824-3c77d7ecfe21 (pk: 2669)>, 'output_trajectory': <TrajectoryData: uuid: bd77412e-033b-46e7-bc8e-786e1b5bda52 (pk: 2668)>, 'output_band': <BandsData: uuid: 1a97beda-2273-434d-9074-36c652a60a51 (pk: 2667)>}

How to deal with magnetic configurations

The first way to prepare a magnetic calculation is to trigger the nspin or noncolin in the input parameters of the PwCalculation respectively for collinear (nspin=2) and non collinear (noncolin=.True.) calculations.

Of course, the magnetic moments have to be provided within the StructureData, so that they can be used to build the starting_magnetization variable in the &SYSTEM namelist.

Collinear case

We first load the structure using Pymatgen to parse the mcif file for BCC Iron:

from pymatgen.core import Structure

#suppose you are in the `aiida-atomistic` root folder
iron_bcc = Structure.from_file('../examples/structure/data/Fe_bcc.mcif', primitive=True)
magnetic_structure = StructureData.from_pymatgen(iron_bcc)

print(magnetic_structure.properties.magmoms)
[[0.0, 0.0, 2.5]]
magnetic_structure.properties.kinds
['Fe1']

We can check that our structure is collinear (trivial in this case):

magnetic_structure.is_collinear
True

For now, we consider only collinear magnetic moments along the z axis.

We can create again the builder as before, this time overriding nspin to be equal to 2 (collinear calculation):

builder = PwBaseWorkChain.get_builder_from_protocol(
    code=orm.load_code("pw-qe-7.2@localhost"), 
    structure=magnetic_structure,
    protocol="fast",
    overrides={
        "pw":{
            "parameters":{
                "SYSTEM":
                    {"nspin": 2}
            }
        }
    }
    )
run = run_get_node(builder)
11/19/2024 03:51:57 PM <586862> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [2676|PwBaseWorkChain|run_process]: launching PwCalculation<2681> iteration #1
11/19/2024 03:52:06 PM <586862> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [2676|PwBaseWorkChain|results]: work chain completed after 1 iterations
11/19/2024 03:52:06 PM <586862> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [2676|PwBaseWorkChain|on_terminated]: remote folders will not be cleaned

The output magnetic moments

For now, the new output magnetization of a structure will not be stored in the output StructureData (if any). The reason is that the output magnetization can present some discrepancies which are actually artifacts of the simulation. For example, (magnetic) symmetries maybe not correctly detected (due to different kinds) and so magnetization magnitudes (and orientations) are not the same as expected.

So, the if the user needs it, he can use a calcfuntion to generate a new StructureData with the new magnetic moments (both as list of floats or of len=3 lists):

trajectory = run[-1].called[-1].outputs.output_trajectory # run[1].called[-1].outputs.output_trajectory
magnetic_moments = [magmom[0] for magmom in trajectory.get_array('atomic_magnetic_moments')]
print(magnetic_moments)
[2.3254]
from aiida_quantumespresso.utils.magnetic import generate_structure_with_magmoms

new_structure = generate_structure_with_magmoms(magnetic_structure, magnetic_moments)
print(f"New StructureData: {new_structure}\nAttached magmoms: {new_structure.properties.magmoms}")
New StructureData: uuid: f56a783d-492d-42c0-9f85-dc751ed6a645 (pk: 2689)
Attached magmoms: [[0.0, 0.0, 2.3254]]

Using this utility function, kinds will be automatically detected.

If you don’t want the provenance and the new StructureData node to be stored, add metadata={"store_provenance": False} to the input of the calcfunction.

Non-collinear case

For the non-collinear case, we just need to put noncolin: True in the input parameters:

builder = PwBaseWorkChain.get_builder_from_protocol(
    code=orm.load_code("pw-qe-7.2@localhost"), 
    structure=magnetic_structure,
    protocol="fast",
    overrides={
        "pw":{
            "parameters":{
                "SYSTEM":
                    {"noncolin": True}
            }
        }
    }
    )
run = run_get_node(builder)
11/19/2024 03:52:08 PM <586862> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [2695|PwBaseWorkChain|run_process]: launching PwCalculation<2700> iteration #1
11/19/2024 03:52:28 PM <586862> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [2695|PwBaseWorkChain|results]: work chain completed after 1 iterations
11/19/2024 03:52:28 PM <586862> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [2695|PwBaseWorkChain|on_terminated]: remote folders will not be cleaned
run[0]
{'remote_folder': <RemoteData: uuid: efc276db-2c08-4341-a9f6-4d30ca7c3f1e (pk: 2701)>, 'retrieved': <FolderData: uuid: 14cee85a-d55c-4c23-84e3-ddf902f5b462 (pk: 2702)>, 'output_parameters': <Dict: uuid: 876ca6eb-7e8c-4bc5-abe9-5b06f560a0e0 (pk: 2705)>, 'output_trajectory': <TrajectoryData: uuid: 0d2c035b-7719-4dcc-8a0f-f36b14a63a19 (pk: 2704)>, 'output_band': <BandsData: uuid: 9e19ca8b-2086-41ed-ae19-15980023bda2 (pk: 2703)>}

Currently, no parser for non-collinear magnetization is implemented in the aiida-quantumespresso plugin.

How to run DFT+U (+V)

In the following we show how to run a DFT+U calculation. We consider the Hubbard parameters to be known (we don’t compute them here). As implemented in the HubbardStructureData, also for our atomistic StructureData we need to define the Hubbard class, now part of the properties attribute. We load the structure using pymatgen:

from pymatgen.core import Structure

MnO = Structure.from_file('../examples/structure/data/MnO.mcif', primitive=True)
mutable_structure = StructureDataMutable.from_pymatgen(MnO)
mutable_structure.get_magmoms()
array([[ 2.31, 2.31, -4.62], [-2.31, -2.31, 4.62], [ 0. , 0. , 0. ], [ 0. , 0. , 0. ]])

we make the structure to be collinear:

mutable_structure.set_magmoms([
    [0, 0, 4.62],
    [0, 0, 4.62],
    [0, 0, 0],
    [0, 0, 0]
])
mutable_structure.is_collinear
True

Then, we attach the hubbard parameters using the initialize_onsites_hubbard method of the StructureDataMutable:

#mutable_structure.clear_property('magmoms')
for kind in set(mutable_structure.properties.kinds):
    if "Mn" in kind:
        mutable_structure.initialize_onsites_hubbard(kind, '3d', 4, 'U', use_kinds=True)
mutable_structure.properties.hubbard.parameters
[HubbardParameters(atom_index=0, atom_manifold='3d', neighbour_index=0, neighbour_manifold='3d', translation=(0, 0, 0), value=4.0, hubbard_type='U'), HubbardParameters(atom_index=1, atom_manifold='3d', neighbour_index=1, neighbour_manifold='3d', translation=(0, 0, 0), value=4.0, hubbard_type='U')]

Please note that we have two Mn kinds, detected during the initialization of the structure (being magnetic, the two kinds are detected using the initial magmoms). Try to change this and put the same kind.

We are now ready to run the calculation:

from aiida.engine import submit, run_get_node

structure = StructureData.from_mutable(mutable_structure)

builder = PwBaseWorkChain.get_builder_from_protocol(
    code=orm.load_code("pw-qe-7.2@localhost"), 
    structure=structure,
    protocol="fast",
    overrides={
        "pw":{
            "parameters":{
                "SYSTEM":
                    {"nspin": 2}
            }
        }
    }
    )
run = run_get_node(builder)
11/19/2024 03:52:30 PM <586862> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [2712|PwBaseWorkChain|run_process]: launching PwCalculation<2717> iteration #1
11/19/2024 03:53:26 PM <586862> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [2712|PwBaseWorkChain|sanity_check_insufficient_bands]: PwCalculation<2717> run with smearing and highest band is occupied
11/19/2024 03:53:26 PM <586862> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [2712|PwBaseWorkChain|sanity_check_insufficient_bands]: BandsData<2720> has invalid occupations: Occupation of 1.0 at last band lkn<0,0,25>
11/19/2024 03:53:26 PM <586862> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [2712|PwBaseWorkChain|sanity_check_insufficient_bands]: PwCalculation<2717> had insufficient bands
11/19/2024 03:53:26 PM <586862> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [2712|PwBaseWorkChain|sanity_check_insufficient_bands]: Action taken: increased number of bands to 29 and restarting from the previous charge density.
11/19/2024 03:53:26 PM <586862> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [2712|PwBaseWorkChain|inspect_process]: PwCalculation<2717> finished successfully but a handler was triggered, restarting
11/19/2024 03:53:26 PM <586862> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [2712|PwBaseWorkChain|run_process]: launching PwCalculation<2725> iteration #2
11/19/2024 03:53:47 PM <586862> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [2712|PwBaseWorkChain|results]: work chain completed after 2 iterations
11/19/2024 03:53:47 PM <586862> aiida.orm.nodes.process.workflow.workchain.WorkChainNode: [REPORT] [2712|PwBaseWorkChain|on_terminated]: remote folders will not be cleaned