1. First introduction to FCC Si

We will now follow the FCC Si example in the VASP tutorial. We will obtain the same data, but using different strategies so that you as a user will be familiar with what is going on. The FCC Si tutorial is all about calculating the total energies at different volumes to find the volume that gives you the lowest energy.

In this tutorial we will complete the original FCC Si tutorial without using AiiDA-VASP and then continue to execute the first static (fixed volume) calculation with AiiDA-VASP in order to get to know how the submission, monitoring and inspection process works. The next tutorial will start to perform calculations at different volumes.

  1. First complete the FCC Si tutorial.

  2. Enable your AiiDA virtual environment where AiiDA-VASP is installed.

  3. Make sure your AiiDA daemon runs:

    %/$ verdi daemon start
    
  4. When the standard tutorial is completed we will now do the same in AiiDA-VASP using different strategies to you get a feel for how you can structurize a simple workflow like this. Let us now fetch the AiiDA-VASP run file for this example:

    %/$ wget https://github.com/aiida-vasp/aiida-vasp/raw/develop/tutorials/run_fcc_si_one_volume.py
    
  5. Inspect the file, which has the following content:

"""
Call script to calculate the total energies for one volume of standard silicon.

This particular call script set up a standard calculation that execute a calculation for
the fcc silicon structure.
"""
# pylint: disable=too-many-arguments
import numpy as np
from aiida.common.extendeddicts import AttributeDict
from aiida.orm import Code, Bool, Str
from aiida.plugins import DataFactory, WorkflowFactory
from aiida.engine import submit
from aiida import load_profile
load_profile()


def get_structure():
    """
    Set up Si primitive cell

    fcc Si:
       3.9
       0.5000000000000000    0.5000000000000000    0.0000000000000000
       0.0000000000000000    0.5000000000000000    0.5000000000000000
       0.5000000000000000    0.0000000000000000    0.5000000000000000
    Si
       1
    Cartesian
    0.0000000000000000  0.0000000000000000  0.0000000000000000

    """

    structure_data = DataFactory('structure')
    alat = 3.9
    lattice = np.array([[.5, .5, 0], [0, .5, .5], [.5, 0, .5]]) * alat
    structure = structure_data(cell=lattice)
    positions = [[0.0, 0.0, 0.0]]
    for pos_direct in positions:
        pos_cartesian = np.dot(pos_direct, lattice)
        structure.append_atom(position=pos_cartesian, symbols='Si')
    return structure


def main(code_string, incar, kmesh, structure, potential_family, potential_mapping, options):
    """Main method to setup the calculation."""

    # First, we need to fetch the AiiDA datatypes which will
    # house the inputs to our calculation
    dict_data = DataFactory('dict')
    kpoints_data = DataFactory('array.kpoints')

    # Then, we set the workchain you would like to call
    workchain = WorkflowFactory('vasp.verify')

    # And finally, we declare the options, settings and input containers
    settings = AttributeDict()
    inputs = AttributeDict()

    # organize settings
    settings.parser_settings = {'output_params': ['total_energies', 'maximum_force']}

    # set inputs for the following WorkChain execution
    # set code
    inputs.code = Code.get_from_string(code_string)
    # set structure
    inputs.structure = structure
    # set k-points grid density
    kpoints = kpoints_data()
    kpoints.set_kpoints_mesh(kmesh)
    inputs.kpoints = kpoints
    # set parameters
    inputs.parameters = dict_data(dict=incar)
    # set potentials and their mapping
    inputs.potential_family = Str(potential_family)
    inputs.potential_mapping = dict_data(dict=potential_mapping)
    # set options
    inputs.options = dict_data(dict=options)
    # set settings
    inputs.settings = dict_data(dict=settings)
    # set workchain related inputs, in this case, give more explicit output to report
    inputs.verbose = Bool(True)
    # submit the requested workchain with the supplied inputs
    submit(workchain, **inputs)


if __name__ == '__main__':
    # Code_string is chosen among the list given by 'verdi code list'
    CODE_STRING = 'vasp@mycluster'

    # INCAR equivalent
    # Set input parameters
    INCAR = {'istart': 0, 'icharg': 2, 'encut': 240, 'ismear': 0, 'sigma': 0.1}

    # KPOINTS equivalent
    # Set kpoint mesh
    KMESH = [11, 11, 11]

    # POTCAR equivalent
    # Potential_family is chosen among the list given by
    # 'verdi data vasp-potcar listfamilies'
    POTENTIAL_FAMILY = 'pbe'
    # The potential mapping selects which potential to use, here we use the standard
    # for silicon, this could for instance be {'Si': 'Si_GW'} to use the GW ready
    # potential instead
    POTENTIAL_MAPPING = {'Si': 'Si'}

    # jobfile equivalent
    # In options, we typically set scheduler options.
    # See https://aiida.readthedocs.io/projects/aiida-core/en/latest/scheduler/index.html
    # AttributeDict is just a special dictionary with the extra benefit that
    # you can set and get the key contents with mydict.mykey, instead of mydict['mykey']
    OPTIONS = AttributeDict()
    OPTIONS.account = ''
    OPTIONS.qos = ''
    OPTIONS.resources = {'num_machines': 1, 'num_mpiprocs_per_machine': 16}
    OPTIONS.queue_name = ''
    OPTIONS.max_wallclock_seconds = 3600
    OPTIONS.max_memory_kb = 1024000

    # POSCAR equivalent
    # Set the silicon structure
    STRUCTURE = get_structure()

    main(CODE_STRING, INCAR, KMESH, STRUCTURE, POTENTIAL_FAMILY, POTENTIAL_MAPPING, OPTIONS)
  1. Change the following based on what is required by your previous setup steps:

    code_string
    

    which is the entry you would like to use when executing verdi code list.

  2. Change the following to comply with requirements of your cluster or your project:

    options.account = ''
    options.qos = ''
    options.resources = {'num_machines': 1, 'num_mpiprocs_per_machine': 16}
    options.queue_name = ''
    
    For example, if you use a SGE scheduler, you need to modify resources as follows::

    resources = {‘num_machines’: 1, ‘tot_num_mpiprocs’: 16, ‘parallel_env’: ‘mpi*’} # for SGE

  3. Save and execute the resulting run script by issuing:

    %/$ python run_fcc_si_one_volume.py
    
  4. Check its progress with:

    %/$ verdi process list
    PK  Created    Process label                 Process State      Process status
    ------  ---------  ----------------------------  -----------------  -----------------------------------------------------------
    
    101366  25s ago    VerifyWorkChain               ⏵ Waiting          Waiting for child processes: 101367
    101367  24s ago    VaspWorkChain                 ⏵ Waiting          Waiting for child processes: 101368
    101368  24s ago    VaspCalculation               ⏵ Waiting          Monitoring scheduler: job state RUNNING
    

    Different messages appear, depending on when you run verdi process list. Notice that only active processes are shown by this command. In order to also list the processes that has completed we use verdi process list -a.

  5. After a while, we execut verdi process list -a and get:

    %/$ verdi process list -a
    PK  Created    Process label                 Process State      Process status
    ------  ---------  ----------------------------  -----------------  -----------------------------------------------------------
    
    101366  3m ago     VerifyWorkChain               ⏹ Finished [0]
    101367  3m ago     VaspWorkChain                 ⏹ Finished [0]
    101368  3m ago     VaspCalculation               ⏹ Finished [0]
    

    The processes composing the workflow are now finished. Basically, your calculation, or workflow is done. As you can see, the run were composed of three Workchains.

  6. Let us have a look at what happened (we typically inspect the topmost, i.e. the workchain with the lowest PK):

    %/$ verdi process report 101366
    2019-10-02 11:02:37 [5034 | REPORT]: [101366|VerifyWorkChain|run_next_workchain]: launching VaspWorkChain<101367> iteration #1
    2019-10-02 11:02:37 [5035 | REPORT]:   [101367|VaspWorkChain|run_calculation]: launching VaspCalculation<101368> iteration #1
    2019-10-02 11:03:25 [5036 | REPORT]:   [101367|VaspWorkChain|_handle_succesfull]: VaspCalculation<101368> completed successfully
    2019-10-02 11:03:26 [5037 | REPORT]:   [101367|VaspWorkChain|results]: VaspWorkChain<101367> completed after 1 iterations
    2019-10-02 11:03:26 [5038 | REPORT]:   [101367|VaspWorkChain|results]: attaching the node Dict<101371> as 'misc'
    2019-10-02 11:03:26 [5039 | REPORT]:   [101367|VaspWorkChain|results]: attaching the node RemoteData<101369> as 'remote_folder'
    2019-10-02 11:03:26 [5040 | REPORT]:   [101367|VaspWorkChain|results]: attaching the node FolderData<101370> as 'retrieved'
    2019-10-02 11:03:28 [5041 | REPORT]:   [101367|VaspWorkChain|on_terminated]: cleaned remote folders of calculations: 101368
    
  7. Let us have a look at what is stored on the topmost workchain. The topmost workchain typically contain the output of the workflow calculation:

    %/$ verdi process show 101366
    Property       Value
    -------------  ------------------------------------
    type           WorkChainNode
    pk             101366
    uuid           c914f898-cf59-4fad-8ea8-a189db9af379
    label
    description
    ctime          2019-10-02 11:02:36.177448+00:00
    mtime          2019-10-02 11:03:27.471046+00:00
    process state  Finished
    exit status    0
    computer       [6] mycluster
    
    Inputs                     PK  Type
    ---------------------  ------  -------------
    clean_workdir          101364  Bool
    code                   101271  Code
    kpoints                101356  KpointsData
    max_iterations         101363  Int
    options                101360  Dict
    parameters             101357  Dict
    potential_family       101358  Str
    potential_mapping      101359  Dict
    settings               101361  Dict
    structure              101355  StructureData
    verbose                101362  Bool
    verify_max_iterations  101365  Int
    
    Outputs            PK  Type
    -------------  ------  ----------
    misc           101371  Dict
    remote_folder  101369  RemoteData
    retrieved      101370  FolderData
    
    Called        PK  Type
    --------  ------  -------------
    CALL      101367  WorkChainNode
    
    Log messages
    ---------------------------------------------
    There are 1 log messages for this calculation
    Run 'verdi process report 101366' to see them
    

    Here you can see the inputs and outputs of your workflow (attached on a workchain).

  8. Let us inspect the misc output:

    %/$ verdi data dict show 101371
    {
        "maximum_force": 0.0,
        "maximum_stress": 20.21457093,
        "symmetries": {
            "num_space_group_operations": {
                 "dynamic": [
                     48
                 ],
                 "static": [
                     48
                 ]
            },
            "point_group": {
                "dynamic": [
                    null
                ],
                "static": [
                    null
                ]
            },
            "primitive_translations": [
                1
            ]
        },
        "total_energies": {
            "energy_extrapolated": -4.87588342
        }
    }
    

    As you can see, this contains the maximum_force, maximum_stress and total_energies in standard VASP units. The container misc is used to house quantities that are not system size dependent (with size, we also mean grid sizes etc., like the k-point grid).