def _get_echem_corrections(self, correction_dict): """ Perform the thermodynamic corrections relevant to electrochemistry but are not specific to any particular mode. """ # pH corrections to proton and hydroxide species if any(ads in ['ele_g', 'H_g', 'OH_g'] for ads in self.species_definitions.keys()): G_H2 = self._electronic_energy_dict['H2_g'] + self._correction_dict['H2_g'] G_H = 0.5 * G_H2 - .0592 * self.pH G_H2O = self._electronic_energy_dict['H2O_g'] + self._correction_dict['H2O_g'] H2O_index = self.gas_names.index('H2O_g') G_OH = G_H2O - G_H # Do not need Kw, just need to make sure equilibria are satisfied correction_dict['H_g'] = G_H correction_dict['OH_g'] = G_OH # pressure corrections to species in the echem double layer based on kH if 'dl' in self.species_definitions.keys(): dl_species = [spec for spec in self.species_definitions.keys() if '_dl' in spec and '*' not in spec] for spec in dl_species: tempname = spec.split('_')[0] gas_spec = tempname + '_g' C_H2O = 55. KH_gas = self.species_definitions[spec].get('kH', 55.) # defaults to no correction P_gas = C_H2O / KH_gas P_corr = np.log(P_gas) * self._kB * self.temperature correction_dict[spec] = correction_dict[gas_spec] + P_corr # Generate energy for fake echem transition states after all other corrections if len(self.echem_transition_state_names) > 0: echem_thermo_dict = self.generate_echem_TS_energies() add_dict_in_place(correction_dict, echem_thermo_dict) return correction_dict
def _get_echem_corrections(self, correction_dict): """ Perform the thermodynamic corrections relevant to electrochemistry but are not specific to any particular mode. """ # pH corrections to proton and hydroxide species if any(ads in ['ele_g', 'H_g', 'OH_g'] for ads in self.species_definitions.keys()): G_H2 = self._electronic_energy_dict['H2_g'] + self._correction_dict['H2_g'] G_H = 0.5*G_H2 - .0592*self.pH G_H2O = self._electronic_energy_dict['H2O_g'] + self._correction_dict['H2O_g'] H2O_index = self.gas_names.index('H2O_g') G_OH = G_H2O - G_H + self._kB*self.temperature*np.log(self.gas_pressures[H2O_index]*1.e14) correction_dict['H_g'] = G_H correction_dict['OH_g'] = G_OH # pressure corrections to species in the echem double layer based on kH if 'dl' in self.species_definitions.keys(): dl_species = [spec for spec in self.species_definitions.keys() if '_dl' in spec and '*' not in spec] for spec in dl_species: tempname = spec.split('_')[0] gas_spec = tempname+'_g' C_H2O = 55. KH_gas = self.species_definitions[spec].get('kH', 55.) # defaults to no correction P_gas = C_H2O / KH_gas P_corr = np.log(P_gas) * self._kB * self.temperature correction_dict[spec] = correction_dict[gas_spec] + P_corr # Generate energy for fake echem transition states after all other corrections if len(self.echem_transition_state_names) > 0: echem_thermo_dict = self.generate_echem_TS_energies() add_dict_in_place(correction_dict, echem_thermo_dict) return correction_dict
def _get_echem_corrections(self, correction_dict): """ Perform the thermodynamic corrections relevant to electrochemistry but are not specific to any particular mode. """ # Generate energy for fake echem transition states after all other corrections if len(self.echem_transition_state_names) > 0: echem_thermo_dict = self.generate_echem_TS_energies() add_dict_in_place(correction_dict, echem_thermo_dict) # pH corrections to proton and hydroxide species if self.pH: proton_index = self.gas_names.index(self.proton_species or 'H_g') hydroxide_index = self.gas_names.index(self.hydroxide_species or 'OH_g') self.gas_pressures[proton_index] = 1. / 10**self.pH self.gas_pressures[hydroxide_index] = 1e-14 * 10**self.pH # pressure corrections to species in the echem double layer based on kH if 'dl' in self.species_definitions.keys(): dl_species = [ spec for spec in self.species_definitions.keys() if '_dl' in spec and '*' not in spec ] for spec in dl_species: tempname = spec.split('_')[0] gas_spec = tempname + '_g' C_H2O = 55. KH_gas = self.species_definitions[spec]['kH'] P_gas = C_H2O / KH_gas P_corr = np.log(P_gas) * self._kB * self.temperature correction_dict[spec] = correction_dict[gas_spec] + P_corr return correction_dict
def _get_echem_corrections(self, correction_dict): """ Perform the thermodynamic corrections relevant to electrochemistry but are not specific to any particular mode. """ # Generate energy for fake echem transition states after all other corrections if len(self.echem_transition_state_names) > 0: echem_thermo_dict = self.generate_echem_TS_energies() add_dict_in_place(correction_dict, echem_thermo_dict) # pH corrections to proton and hydroxide species if self.pH: proton_index = self.gas_names.index(self.proton_species or 'H_g') hydroxide_index = self.gas_names.index(self.hydroxide_species or 'OH_g') self.gas_pressures[proton_index] = 1. / 10**self.pH self.gas_pressures[hydroxide_index] = 1e-14 * 10**self.pH # pressure corrections to species in the echem double layer based on kH if 'dl' in self.species_definitions.keys(): dl_species = [spec for spec in self.species_definitions.keys() if '_dl' in spec and '*' not in spec] for spec in dl_species: tempname = spec.split('_')[0] gas_spec = tempname+'_g' C_H2O = 55. KH_gas = self.species_definitions[spec]['kH'] P_gas = C_H2O / KH_gas P_corr = np.log(P_gas) * self._kB * self.temperature correction_dict[spec] = correction_dict[gas_spec] + P_corr return correction_dict
def get_thermodynamic_corrections(self, **kwargs): """ Calculate all ``thermodynamic'' corrections beyond the energies in the input file. This master function will call sub-functions depending on the ``thermo mode'' of each class of species """ l = self.thermodynamic_corrections if 'electrochemical' in l and len( self.echem_transition_state_names) > 0: self.force_recalculation = True state_dict = {} for v in self.thermodynamic_variables: state_dict[v] = getattr(self, v) for key in kwargs: if key in state_dict: state_dict[key] = kwargs[key] current_state = [ repr(state_dict[v]) for v in self.thermodynamic_variables ] for sp in self.species_definitions: self.frequency_dict[sp] = \ self.species_definitions[sp].get('frequencies',[]) frequency_dict = self.frequency_dict.copy() if (getattr(self, '_current_state', None) == current_state and getattr(self, '_frequency_dict', None) == frequency_dict and not self.force_recalculation ): #if the thermodynamic state (and frequencies) #has not changed then don't bother re-calculating the corrections. return self._correction_dict correction_dict = {} self._correction_dict = correction_dict self._current_state = current_state self._frequency_dict = frequency_dict # apply corrections in self.thermodynamic_corrections on top of each other for correction in self.thermodynamic_corrections: mode = getattr(self, correction + '_thermo_mode') thermo_dict = getattr(self, mode)() add_dict_in_place(correction_dict, thermo_dict) if self.pressure_mode: getattr(self, self.pressure_mode + '_pressure')() if 'electrochemical' in l: correction_dict = self._get_echem_corrections(correction_dict) return correction_dict
def get_thermodynamic_corrections(self, **kwargs): # echem in generalized linear scaling needs recalculation l = self.thermodynamic_corrections if 'electrochemical' in l and len( self.echem_transition_state_names) > 0: self.force_recalculation = True state_dict = {} for v in self.thermodynamic_variables: state_dict[v] = getattr(self, v) for key in kwargs: if key in state_dict: state_dict[key] = kwargs[key] current_state = [ repr(state_dict[v]) for v in self.thermodynamic_variables ] for sp in self.species_definitions: self.frequency_dict[sp] = \ self.species_definitions[sp].get('frequencies',[]) frequency_dict = self.frequency_dict.copy() if (getattr(self, '_current_state', None) == current_state and getattr(self, '_frequency_dict', None) == frequency_dict and not self.force_recalculation ): #if the thermodynamic state (and frequencies) #has not changed then don't bother re-calculating the corrections. return self._correction_dict correction_dict = {} self._correction_dict = correction_dict self._current_state = current_state self._frequency_dict = frequency_dict # apply corrections in self.thermodynamic_corrections on top of each other for correction in self.thermodynamic_corrections: mode = getattr(self, correction + '_thermo_mode') thermo_dict = getattr(self, mode)() add_dict_in_place(correction_dict, thermo_dict) # apply electrochemical transition state "corrections" last if 'electrochemical' in l and len( self.echem_transition_state_names) > 0: echem_thermo_dict = self.generate_echem_TS_energies() add_dict_in_place(correction_dict, echem_thermo_dict) getattr(self, self.pressure_mode + '_pressure')() return correction_dict
def get_thermodynamic_corrections(self, **kwargs): """ Calculate all ``thermodynamic'' corrections beyond the energies in the input file. This master function will call sub-functions depending on the ``thermo mode'' of each class of species """ l = self.thermodynamic_corrections if 'electrochemical' in l: self.force_recalculation = True state_dict = {} for v in self.thermodynamic_variables: state_dict[v] = getattr(self, v) for key in kwargs: if key in state_dict: state_dict[key] = kwargs[key] current_state = [repr(state_dict[v]) for v in self.thermodynamic_variables] for sp in self.species_definitions: self.frequency_dict[sp] = \ self.species_definitions[sp].get('frequencies', []) frequency_dict = self.frequency_dict.copy() if ( getattr(self, '_current_state', None) == current_state and getattr(self, '_frequency_dict', None) == frequency_dict and not self.force_recalculation ): # if the thermodynamic state (and frequencies) # has not changed then don't bother re-calculating the corrections. return self._correction_dict correction_dict = {} self._correction_dict = correction_dict self._current_state = current_state self._frequency_dict = frequency_dict # apply corrections in self.thermodynamic_corrections on top of each other for correction in self.thermodynamic_corrections: mode = getattr(self, correction + '_thermo_mode') thermo_dict = getattr(self, mode)() add_dict_in_place(correction_dict, thermo_dict) if self.pressure_mode: getattr(self, self.pressure_mode + '_pressure')() if 'electrochemical' in l: correction_dict = self._get_echem_corrections(correction_dict) return correction_dict
def get_thermodynamic_corrections(self,**kwargs): # echem in generalized linear scaling needs recalculation l = self.thermodynamic_corrections if 'electrochemical' in l and len(self.echem_transition_state_names) > 0: self.force_recalculation = True state_dict = {} for v in self.thermodynamic_variables: state_dict[v] = getattr(self,v) for key in kwargs: if key in state_dict: state_dict[key] = kwargs[key] current_state = [repr(state_dict[v]) for v in self.thermodynamic_variables] for sp in self.species_definitions: self.frequency_dict[sp] = \ self.species_definitions[sp].get('frequencies',[]) frequency_dict = self.frequency_dict.copy() if ( getattr(self,'_current_state',None) == current_state and getattr(self,'_frequency_dict',None) == frequency_dict and not self.force_recalculation ): #if the thermodynamic state (and frequencies) #has not changed then don't bother re-calculating the corrections. return self._correction_dict correction_dict = {} self._correction_dict = correction_dict self._current_state = current_state self._frequency_dict = frequency_dict # apply corrections in self.thermodynamic_corrections on top of each other for correction in self.thermodynamic_corrections: mode = getattr(self,correction+'_thermo_mode') thermo_dict = getattr(self,mode)() add_dict_in_place(correction_dict, thermo_dict) # apply electrochemical transition state "corrections" last if 'electrochemical' in l and len(self.echem_transition_state_names) > 0: echem_thermo_dict = self.generate_echem_TS_energies() add_dict_in_place(correction_dict, echem_thermo_dict) getattr(self,self.pressure_mode+'_pressure')() return correction_dict