[1]:
# useful to autoreload the module without restarting the kernel
%load_ext autoreload
%autoreload 2
[2]:
from mppi import InputFiles as I, Calculators as C
[3]:
omp = 1
mpi = 4

Tutorial for the QeCalculator class

This tutorial describes the usage of the QeCalculator class, that manages the run of a calculation with the QuantumESPRESSO package.

[4]:
run_dir = 'QeCalculator_test'

Perform a scf computations for silicon

We init the PwInput object using an exsisting input file. Then we define an input with the associated name using the energy_cutoff as a parameter

[5]:
energy_cutoffs = 50
outdir_scf = 'outdir_scf'
name_scf = 'scf.in'
[6]:
inp = I.PwInput(file='IO_files/si_scf.in')
prefix = 'ecut_%s'%energy_cutoffs
inp.set_kpoints(points = [6,6,6])
inp.set_pseudo_dir(pseudo_dir='../pseudos')
inp.set_prefix(prefix)
inp.set_outdir(outdir_scf)
inp.set_energy_cutoff(energy_cutoffs)
name = name_scf
inp
[6]:
{'control': {'calculation': "'scf'",
  'verbosity': "'high'",
  'prefix': "'ecut_50'",
  'outdir': "'outdir_scf'",
  'pseudo_dir': "'../pseudos'"},
 'system': {'force_symmorphic': '.true.',
  'occupations': "'fixed'",
  'ibrav': '2',
  'celldm(1)': '10.3',
  'ntyp': '1',
  'nat': '2',
  'ecutwfc': 50},
 'electrons': {'diago_full_acc': '.false.', 'conv_thr': '1e-08'},
 'ions': {},
 'cell': {},
 'atomic_species': {'Si': ['28.086', 'Si.pbe-mt_fhi.UPF']},
 'atomic_positions': {'type': 'crystal',
  'values': [['Si', [0.125, 0.125, 0.125]], ['Si', [-0.125, -0.125, -0.125]]]},
 'kpoints': {'type': 'automatic', 'values': ([6, 6, 6], [0.0, 0.0, 0.0])},
 'cell_parameters': {},
 'file': 'IO_files/si_scf.in'}

Now we define an intance of the QeCalculator. For this example we use a direct scheduler

The first step is to create an istance of the RunRules class that contains the options of the calculator

[7]:
rr = C.RunRules(mpi=mpi,omp_num_threads=omp)
rr
[7]:
{'scheduler': 'direct', 'mpi': 4, 'omp_num_threads': 1}
[8]:
C.QeCalculator?
Init signature:
C.QeCalculator(
    runRules,
    executable='pw.x',
    skip=True,
    clean_restart=True,
    dry_run=False,
    wait_end_run=True,
    activate_BeeOND=False,
    verbose=True,
    **kwargs,
)
Docstring:
Perform a QuantumESPRESSO calculation. The parameters used to define the parellelization
strategy are provided in the `runRules` object.

Parameters:
   runRulues (:class:`RunRules`) : instance of the :class:`RunRules` class
   executable (:py:class:`string`) : set the executable (pw.x, ph.x, ..) of the QuantumESPRESSO package
   skip (:py:class:`bool`) : if True evaluate if the computation can be skipped. This is done by checking if the log
        file of the run contains the string `job_done`, defined as a data member of this class
   clean_restart (:py:class:`bool`) : if True delete the folder $prefix.save before running the computation
   dry_run (:py:class:`bool`) : with this option enabled the calculator setup the calculations and write the script
        for submitting the job, but the computations are not run
   wait_end_run (:py:class:`bool`) : with this option disabled the run method does not wait the end of the run.
        This option may be useful for interacting with the code in particular in _asincronous_ computation managed
        by the slurm scheduler
   activate_BeeOND (:py:class:`bool`) :  if True set I/O of the run in the BeeOND_dir created by the slurm scheduler.
        With this options enabled the ``out_dir`` of the run is set in the ``BeenOND_dir`` folder and the input wavefunction
        of the source folder (if needed) are copied in the ``BeeOND_dir``. At the end of the run the ``out_dir`` is moved
        in its original path. The value of the ``BeeOND_dir`` is written as a data member of the class and can be modified
        if needed
   verbose (:py:class:`bool`) : set the amount of information provided on terminal
   kwargs : other parameters that are stored in the _global_options dictionary

Computations are performed in the folder specified by the ``run_dir`` parameter. The input and
the log files are written in the run_dir. Instead, the $prefix.xml file and the $prefix.save
folders are written in the ``out_dir`` path. The values of the prefix and out_dir variables
are read from the input file. If the ``out_dir`` path is a relative path its root is located
in the ``run_dir`` folder.

Example:
 >>> rr = RunRules(scheduler='slurm',ntasks_per_node=4,memory='124GB')
 >>> code = calculator(rr,skip=True,clean_restart=True,verbose=True)
 >>> code.run(input = ..., run_dir = ...,name = ..., source_dir = ..., **kwargs)

 When the run method is called the class runs the command:
     cd run_dir ; `mpirun command` executable_name -inp name.in > name.log

 where the arguments of the run method are:

Args:
    run_dir (:py:class:`string`) : the folder in which the simulation is performed
    input (:py:class:`string`) : instance of the :class:`PwInput` class
        that define the input object
    name (:py:class:`string`) : string with the name associated to the input file.
        Usually it is convenient to set the name equal to the prefix of the input object so
        the name of the input file and the prefix folder built by QuantumESPRESSO are the same
    source_dir (:py:class:`string`) : useful for the nscf computations. The source folder contains
        the wave-functions created by a scf calculation. If present the class copies this folder in the
        ``out_dir`` with the name $prefix.save
    kwargs : other parameters that are stored in the run_options dictionary
File:           ~/Applications/MPPI/mppi/Calculators/QeCalculator.py
Type:           type
Subclasses:

[9]:
code = C.QeCalculator(rr)
code.global_options()
Initialize a QuantumESPRESSO calculator with scheduler direct
[9]:
{'scheduler': 'direct',
 'mpi': 4,
 'omp_num_threads': 1,
 'executable': 'pw.x',
 'skip': True,
 'clean_restart': True,
 'dry_run': False,
 'wait_end_run': True,
 'activate_BeeOND': False,
 'verbose': True}

We run the computation passing the the input object and the associated name to the run method of the calculator.

First of all we perform a simple call to the run method

[10]:
result = code.run(run_dir=run_dir,input=inp,name=name,other_variable = 1)
result
create the run_dir folder : 'QeCalculator_test'
run command: mpirun -np 4 pw.x -inp scf.in.in > scf.in.log
computation scf.in is running...
Note: The following floating-point exceptions are signalling: IEEE_DENORMAL
Note: The following floating-point exceptions are signalling: IEEE_DENORMAL
Note: The following floating-point exceptions are signalling: IEEE_DENORMAL
Note: The following floating-point exceptions are signalling: IEEE_DENORMAL
computation scf.in ended
[10]:
'/home/marco/Applications/MPPI/sphinx_source/tutorials/QeCalculator_test/outdir_scf/ecut_50.save/data-file-schema.xml'

The structure of the folder built by the calculator can be analyzed by browsing the run_dir. In general the name.log file is written in the run_dir while the the prefix.xml file and the prefix.save folder are written in the out_dir folder defined by the outdir key of the input file. It this parameter is expressed as a relative path the folder is located in the path run_dir/out_dir, however an absolute path (also outer from the run_dir) can be used.

We observe that the output of the run method is a string with the the data-file-schema.xml

After the run all the parameters passed to the calculator are written in the run_options attribute

[11]:
code.run_options
[11]:
{'scheduler': 'direct',
 'mpi': 4,
 'omp_num_threads': 1,
 'executable': 'pw.x',
 'skip': True,
 'clean_restart': True,
 'dry_run': False,
 'wait_end_run': True,
 'activate_BeeOND': False,
 'verbose': True,
 'run_dir': 'QeCalculator_test',
 'input': {'control': {'calculation': "'scf'",
   'verbosity': "'high'",
   'prefix': "'ecut_50'",
   'outdir': "'outdir_scf'",
   'pseudo_dir': "'../pseudos'"},
  'system': {'force_symmorphic': '.true.',
   'occupations': "'fixed'",
   'ibrav': '2',
   'celldm(1)': '10.3',
   'ntyp': '1',
   'nat': '2',
   'ecutwfc': 50},
  'electrons': {'diago_full_acc': '.false.', 'conv_thr': '1e-08'},
  'ions': {},
  'cell': {},
  'atomic_species': {'Si': ['28.086', 'Si.pbe-mt_fhi.UPF']},
  'atomic_positions': {'type': 'crystal',
   'values': [['Si', [0.125, 0.125, 0.125]],
    ['Si', [-0.125, -0.125, -0.125]]]},
  'kpoints': {'type': 'automatic', 'values': ([6, 6, 6], [0.0, 0.0, 0.0])},
  'cell_parameters': {},
  'file': 'IO_files/si_scf.in'},
 'name': 'scf.in',
 'other_variable': 1,
 'is_to_run': True}

Instead, let see what happens if the simulation fails. For instance if we provide an empty input to code

[12]:
inp2 = I.PwInput()
[13]:
pref2 = 'si_scf_test2'
inp2.set_prefix(pref2)
inp2
[13]:
{'control': {'calculation': "'scf'",
  'verbosity': "'high'",
  'prefix': "'si_scf_test2'",
  'outdir': "'./'"},
 'system': {'force_symmorphic': '.false.'},
 'electrons': {'diago_full_acc': '.false.'},
 'ions': {},
 'cell': {},
 'atomic_species': {},
 'atomic_positions': {},
 'kpoints': {},
 'cell_parameters': {}}
[14]:
result2 = code.run(input = inp2, run_dir = run_dir,name=pref2)
result2
run command: mpirun -np 4 pw.x -inp si_scf_test2.in > si_scf_test2.log
computation si_scf_test2 is running...
computation si_scf_test2 ended
Expected file /home/marco/Applications/MPPI/sphinx_source/tutorials/QeCalculator_test/si_scf_test2.save/data-file-schema.xml not found

                Check if wait_end_run is False or the dry_run option is active.
                Otherwise a possible error has occured during the computation
--------------------------------------------------------------------------
MPI_ABORT was invoked on rank 3 in communicator MPI_COMM_WORLD
with errorcode 1.

NOTE: invoking MPI_ABORT causes Open MPI to kill all MPI processes.
You may or may not see output from other processes, depending on
exactly when Open MPI kills them.
--------------------------------------------------------------------------
[dal-xps:515106] 3 more processes have sent help message help-mpi-api.txt / mpi-abort
[dal-xps:515106] Set MCA parameter "orte_base_help_aggregate" to 0 to see all help / error messages
[14]:
'/home/marco/Applications/MPPI/sphinx_source/tutorials/QeCalculator_test/si_scf_test2.save/data-file-schema.xml'

In this case the calculator provide a warning since the data-file-schema has not been found after the computation

Usage of the skip parameter

If we repeat a calculation that has been already performed and skip = True the class skip its computation, for instance

[15]:
result = code.run(run_dir=run_dir,input=inp,name=name, skip = True)
Skip the run of scf.in

Instead if we set skip=False the computation is executed in any case

[16]:
result = code.run(run_dir=run_dir,input=inp,name=name,skip=False)
delete log file: QeCalculator_test/scf.in.log
delete xml file: /home/marco/Applications/MPPI/sphinx_source/tutorials/QeCalculator_test/outdir_scf/ecut_50.xml
delete folder: /home/marco/Applications/MPPI/sphinx_source/tutorials/QeCalculator_test/outdir_scf/ecut_50.save
delete the out_dir: /home/marco/Applications/MPPI/sphinx_source/tutorials/QeCalculator_test/outdir_scf
run command: mpirun -np 4 pw.x -inp scf.in.in > scf.in.log
computation scf.in is running...
Note: The following floating-point exceptions are signalling: IEEE_DENORMAL
Note: The following floating-point exceptions are signalling: IEEE_DENORMAL
Note: The following floating-point exceptions are signalling: IEEE_DENORMAL
Note: The following floating-point exceptions are signalling: IEEE_DENORMAL
computation scf.in ended

The option of the calculator clean_restart allows to use to decide if the pre existing results have to be erased or not before running the computation.

Test of the slurm scheduler

If the slurm scheduler is chosen the calculator prepare the slurm script and submit it.

[17]:
rr = C.RunRules(scheduler='slurm',ntasks_per_node=4,omp_num_threads=2)
rr
[17]:
{'scheduler': 'slurm',
 'nodes': 1,
 'ntasks_per_node': 4,
 'cpus_per_task': 1,
 'omp_num_threads': 2,
 'gpus_per_node': None,
 'memory': None,
 'time': None,
 'partition': None,
 'account': None,
 'qos': None,
 'map_by': None,
 'pe': 1,
 'rank_by': None}
[18]:
code = C.QeCalculator(rr)
code.global_options()
Initialize a QuantumESPRESSO calculator with scheduler slurm
[18]:
{'scheduler': 'slurm',
 'nodes': 1,
 'ntasks_per_node': 4,
 'cpus_per_task': 1,
 'omp_num_threads': 2,
 'gpus_per_node': None,
 'memory': None,
 'time': None,
 'partition': None,
 'account': None,
 'qos': None,
 'map_by': None,
 'pe': 1,
 'rank_by': None,
 'executable': 'pw.x',
 'skip': True,
 'clean_restart': True,
 'dry_run': False,
 'wait_end_run': True,
 'activate_BeeOND': False,
 'verbose': True}
[19]:
result = code.run(run_dir=run_dir,input=inp,name=name,skip=False,dry_run=True,clean_restart=False)
run performed starting from existing results
run command: mpirun -np 4 pw.x -inp scf.in.in > scf.in.log
Dry_run option active. Script not submitted
The wait_end_run is False or the dry_run option is active. The calculator proceedes to the postprocessing

The slurm script is written in the run_dir. The execution of the run requires that the slurm scheduler is installed. However with the dry_run option we can write the script on disk.

Note that we have disabled the option clean_restart, in this way the .log, .xml files and the .save floders are not removed before running the computation

Perform a nscf computation for silicon. Usage of the source_dir option

We show how to perform a pw nscf calculation using the results of the first scf run as an input.

Before running this computation ensure that the scf one has been computed and that the save folder is written in the run_dir.

[20]:
rr = C.RunRules(mpi=mpi,omp_num_threads=omp)
code = C.QeCalculator(rr)
Initialize a QuantumESPRESSO calculator with scheduler direct
[21]:
num_bands = 8
[22]:
inp.set_nscf(num_bands,force_symmorphic=True)
prefix = 'bands_%s'%num_bands
outdir_nscf = 'outdir_nscf'
inp.set_prefix(prefix)
inp.set_outdir(outdir_nscf)
inp.set_energy_cutoff(50)
name_nscf = 'nscf.in'
inp
[22]:
{'control': {'calculation': "'nscf'",
  'verbosity': "'high'",
  'prefix': "'bands_8'",
  'outdir': "'outdir_nscf'",
  'pseudo_dir': "'../pseudos'"},
 'system': {'force_symmorphic': '.true.',
  'occupations': "'fixed'",
  'ibrav': '2',
  'celldm(1)': '10.3',
  'ntyp': '1',
  'nat': '2',
  'ecutwfc': 50,
  'nbnd': 8},
 'electrons': {'diago_full_acc': '.false.', 'conv_thr': 1e-08},
 'ions': {},
 'cell': {},
 'atomic_species': {'Si': ['28.086', 'Si.pbe-mt_fhi.UPF']},
 'atomic_positions': {'type': 'crystal',
  'values': [['Si', [0.125, 0.125, 0.125]], ['Si', [-0.125, -0.125, -0.125]]]},
 'kpoints': {'type': 'automatic', 'values': ([6, 6, 6], [0.0, 0.0, 0.0])},
 'cell_parameters': {},
 'file': 'IO_files/si_scf.in'}
[23]:
result = code.run(input=inp,run_dir=run_dir,name=name_nscf,source_dir='QeCalculator_test/outdir_scf/ecut_50.save')
result
copy source_dir QeCalculator_test/outdir_scf/ecut_50.save in the /home/marco/Applications/MPPI/sphinx_source/tutorials/QeCalculator_test/outdir_nscf/bands_8.save
run command: mpirun -np 4 pw.x -inp nscf.in.in > nscf.in.log
computation nscf.in is running...
computation nscf.in ended
Note: The following floating-point exceptions are signalling: IEEE_DENORMAL
Note: The following floating-point exceptions are signalling: IEEE_DENORMAL
Note: The following floating-point exceptions are signalling: IEEE_DENORMAL
Note: The following floating-point exceptions are signalling: IEEE_DENORMAL
[23]:
'/home/marco/Applications/MPPI/sphinx_source/tutorials/QeCalculator_test/outdir_nscf/bands_8.save/data-file-schema.xml'
[ ]: