Source code for aiida_lsmo.workchains.isotherm_calc_pe

"""IsothermCalcPE work chain."""

from aiida.plugins import DataFactory, WorkflowFactory
from aiida.orm import Dict, Str
from aiida.engine import WorkChain
from aiida_lsmo.utils import dict_merge
from aiida_lsmo.calcfunctions import PE_PARAMETERS_DEFAULT, calc_co2_parasitic_energy

# import sub-workchains
IsothermWorkChain = WorkflowFactory('lsmo.isotherm')  #pylint: disable=invalid-name

# import aiida data
CifData = DataFactory('cif')  #pylint: disable=invalid-name

ISOTHERM_PARAMETERS_DEFAULT = {  # Parameters used in 10.1021/acscentsci.9b00619
    "ff_framework": "UFF",  # valid_type=Str, help='Forcefield of the structure.'
    "ff_shifted": True,  # shift or truncate at cutoff
    "ff_tail_corrections": False,  # apply tail corrections
    "ff_mixing_rule": 'Lorentz-Berthelot',  # str, Mixing rule for the forcefield
    "ff_separate_interactions": False,  # bool, if true use only ff_framework for framework-molecule interactions
    "ff_cutoff": 12.0,  # valid_type=Float, help='CutOff truncation for the VdW interactions (Angstrom)'
    "temperature": 300,  # valid_type=Float, help='Temperature of the simulation'
    "zeopp_volpo_samples": 1e5,  # valid_type=Int,help='Number of samples for VOLPO calculation (per UC volume)'
    "zeopp_block_samples": 100,  # valid_type=Int, help='Number of samples for BLOCK calculation (per A^3)'
    "raspa_minKh": 1e-10,
    "raspa_verbosity": 10,  # valid_type=Int,help='Print stats every: number of cycles / raspa_verbosity'
    "raspa_widom_cycles": 1e5,  # valid_type=Int, help='Number of widom cycles'
    "raspa_gcmc_init_cycles": 1e3,  # valid_type=Int, help='Number of GCMC initialization cycles'
    "raspa_gcmc_prod_cycles": 1e4,  # valid_type=Int, help='Number of GCMC production cycles'
    "pressure_precision": 0.1,
    "pressure_maxstep": 5,  # valid_type=Float, help='Max distance between pressure points (bar)'
    "pressure_min": 0.001,  # valid_type=Float, help='Lower pressure to sample (bar)'
    "pressure_max": 30
}


[docs]class IsothermCalcPEWorkChain(WorkChain): """ Compute CO2 parassitic energy (PE) after running IsothermWorkChain for CO2 and N2 at 300K."""
[docs] @classmethod def define(cls, spec): super().define(spec) spec.expose_inputs(IsothermWorkChain, exclude=['molecule', 'parameters']) spec.input('parameters', valid_type=Dict, default=lambda: Dict(dict=ISOTHERM_PARAMETERS_DEFAULT), help='Parameters for Isotherm work chain') spec.input('pe_parameters', valid_type=Dict, default=lambda: Dict(dict=PE_PARAMETERS_DEFAULT), help='Parameters for PE process modelling') spec.outline( cls.run_isotherms, cls.run_calcpe, ) spec.expose_outputs(IsothermWorkChain, namespace='co2') spec.expose_outputs(IsothermWorkChain, namespace='n2') spec.output('output_parameters', valid_type=Dict, required=True, help='Output parmaters of a calc_PE calculations')
[docs] def run_isotherms(self): """Run Isotherm work chain for CO2 and N2.""" inputs = self.exposed_inputs(IsothermWorkChain) self.report("Run Isotherm work chain for CO2 and N2, in CifData<{}> (label: {} )".format( self.inputs.structure.pk, self.inputs.structure.label)) for mol in ['co2', 'n2']: dict_merge( inputs, { 'metadata': { 'call_link_label': 'run_isotherm_for_{}'.format(mol), }, 'molecule': Str(mol), 'parameters': self.inputs.parameters }) running = self.submit(IsothermWorkChain, **inputs) self.to_context(**{'isotherm_{}'.format(mol): running})
[docs] def run_calcpe(self): """Expose isotherm outputs, prepare calc_pe, run it and return the output.""" self.out_many(self.exposed_outputs(self.ctx.isotherm_co2, IsothermWorkChain, namespace='co2')) self.out_many(self.exposed_outputs(self.ctx.isotherm_n2, IsothermWorkChain, namespace='n2')) calcpe = calc_co2_parasitic_energy(isot_co2=self.ctx.isotherm_co2.outputs['output_parameters'], isot_n2=self.ctx.isotherm_n2.outputs['output_parameters'], pe_parameters=self.inputs['pe_parameters']) self.out("output_parameters", calcpe) self.report('calc_pe Dict<{}>'.format(calcpe.pk))