aiidateam / aiida-common-workflows

A repository for the implementation of common workflow interfaces across materials-science codes and plugins
https://aiida-common-workflows.readthedocs.io
MIT License
52 stars 32 forks source link

`Workflows`: harmonic phonons via finite differences #306

Open bastonero opened 1 year ago

bastonero commented 1 year ago

Phonons in the harmonic approximations can be obtained with any code able to compute forces using the so-called frozen phonons technique (or small displacements). A workchain is added for common frozen phonons using this methodology.

IMPORTANT NOTE: In this workchain we don't account for non-analytical corrections, relevant for insulators. This can be added in a modular way via an other workchain dedicated for that purpose (e.g. CommonDielectricWorkChain or similar). Eventually, one can devise a master workchain which can compute at glance the needed NAC parameters, to be added to the PhonopyData/ForceConstantsData which gathers together all the information. In principle, one could also add separately such parameters, as they are needed only to interpolate the band structure (at the gamma point phonons are ill-defined).

bastonero commented 1 year ago

A minimal working example is provided here:

from aiida import orm, load_profile
from aiida.plugins import WorkflowFactory, DbImporterFactory
from aiida.engine import submit

load_profile()
# ========================================================= #
WC = WorkflowFactory("common_workflows.phonons.frozen_phonons")
CodDbImporter = DbImporterFactory('cod')
# ========================================================= #
code = orm.load_code("pw@localhost")
phonopy_code = orm.load_code("phonopy@localhost")

cod = CodDbImporter()
results = cod.query(id='1526655') # Si   1526655
structure = results[0].get_aiida_structure() # it has 8 atoms

inputs = {
    'structure': structure,
    'supercell_matrix': orm.List([1,1,1]),
    'displacement_generator': orm.Dict({'distance':0.01}),
    'symmetry': {
        'symprec': orm.Float(1e-5),
        'distinguish_kinds': orm.Bool(True),
        'is_symmetry': orm.Bool(True),
    },
    'phonopy': {
        'code': phonopy_code,
        'parameters': orm.Dict({'band':'auto'}),  
    },
    'sub_process_class': 'common_workflows.relax.quantum_espresso',
    'generator_inputs': {
        'protocol': 'fast',
        'engines': {
            'relax': {
                'code': code,
                'options': {
                    'resources': {
                        'num_machines': 1
                    }
                }
            }
        },
        'electronic_type': 'metal',
    }
}

calc = submit(WC, **inputs)

Then you can plot the phonon dispersion with the following:

calc.outputs.output_phonopy.phonon_band_structure.show_mpl()
bastonero commented 1 year ago

I have some problems with the testing - the sssp fixture doesn't seem to be willing to work. Nevertheless, I was able to run the workflow smoothly with the above reported example (it runs in 30 s / 1 min).

Moreover, the dependencies seem rather tricky.

It would be great if someone else can give it a try. Of course the input name choices, as well as the entire implementation can (should) be discussed.

bastonero commented 1 year ago

Some comments from meeting with @giovannipizzi and @mbercx :

  1. Write a PhonopyWorkChain able to submit multiple PhonopyCalculation, each for a different property.
  2. We will have at the beginning two separate workflows, one dealing frozen phonons, one dealing linear response
  3. To understand the design for the overrides. This will define the input structure.

A possible solution that we came up with is:

inputs = {
    'structure': structure,
    'generator_inputs': {
        'protocol': 'fast', # ==> qpoints_mesh/supercell_matrix [2,2,2,]
        'force_calculator':{
            'sub_process_class': 'common_workflows.relax.quantum_espresso', #?
            'engines': {
                'relax': {
                    'code': code,
                    'options': {
                        'resources': {
                            'num_machines': 1
                        }
                    }
                },
            },
            'electronic_type': 'metal'
        },
        'phonon_properties': {
            'properties': ['bands', 'force_constants', 'dos', 'thermodynamics', ...],
            'engine': {
                'code': phonopy_code,
                'options': {...},
            },
        },
    }
}

builder = FrozenPhononWorkChain.get_builder_from_protocol(**inputs)
builder.supercell_matrix = orm.List([2,2,2,])
...