Skip to content

Commit

Permalink
Making convergence and functional = all work; changing appearance of …
Browse files Browse the repository at this point in the history
…printout
  • Loading branch information
elinscott committed Jul 31, 2024
1 parent 65f9a1e commit 9373f05
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 217 deletions.
17 changes: 14 additions & 3 deletions src/koopmans/calculators/_koopmans_cp.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ def read_ham_xml_files(self, bare=False) -> List[np.ndarray]:
return ham_matrix

def _ham_pkl_file(self, bare: bool = False) -> Path:
assert self.directory is not None
if bare:
suffix = '.bare_ham.pkl'
else:
Expand Down Expand Up @@ -549,7 +550,7 @@ def files_to_convert_with_spin2_to_spin1(self):
prefix, suffix = f.split('.')
nspin_2_files.append(f'{prefix}1.{suffix}')

parent = self.parameters.outdir / f'{self.parameters.prefix}_{self.parameters.ndr}.save/K00001'
parent = self.read_directory / 'K00001'
return {'spin_2_files': [(self, parent / f1) for f1 in nspin_2_files], 'spin_1_files': nspin_1_files}

@property
Expand All @@ -570,14 +571,14 @@ def files_to_convert_with_spin1_to_spin2(self):
nspin_2up_files.append(f'{prefix}1.{suffix}')
nspin_2dw_files.append(f'{prefix}2.{suffix}')

parent = self.parameters.outdir / f'{self.parameters.prefix}_{self.parameters.ndr}.save/K00001'
parent = self.read_directory / 'K00001'

return {'spin_1_files': [(self, parent / f) for f in nspin_1_files],
'spin_2_up_files': nspin_2up_files,
'spin_2_down_files': nspin_2dw_files}

def convert_wavefunction_2to1(self):
nspin2_tmpdir = self.parameters.outdir / f'{self.parameters.prefix}_{self.parameters.ndr}.save/K00001'
nspin2_tmpdir = self.read_directory / 'K00001'
nspin1_tmpdir = self.parameters.outdir / f'{self.parameters.prefix}_98.save/K00001'

for directory in [nspin2_tmpdir, nspin1_tmpdir]:
Expand Down Expand Up @@ -643,6 +644,16 @@ def convert_wavefunction_1to2(self):
with open(file_out, 'wb') as fd:
fd.write(contents)

@property
def read_directory(self) -> Path:
assert isinstance(self.parameters.outdir, Path)
return self.parameters.outdir / f'{self.parameters.prefix}_{self.parameters.ndr}.save'

@property
def write_directory(self):
assert isinstance(self.parameters.outdir, Path)
return self.parameters.outdir / f'{self.parameters.prefix}_{self.parameters.ndw}.save'


def convert_flat_alphas_for_kcp(flat_alphas: List[float],
parameters: settings.KoopmansCPSettingsDict) -> List[List[float]]:
Expand Down
3 changes: 2 additions & 1 deletion src/koopmans/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,9 @@ @misc{Dabo2009
author = {Dabo, I. and Cococcioni, M. and Marzari, N.},
year = {2009},
month = jan,
eprint = {0901.2637},
abstract = {In effective single-electron theories, self-interaction manifests itself through the unphysical dependence of the energy of an electronic state as a function of its occupation, which results in important deviations from the ideal Koopmans trend and strongly affects the accuracy of electronic-structure predictions. Here, we study the non-Koopmans behavior of local and semilocal density-functional theory (DFT) total energy methods as a means to quantify and to correct self-interaction errors. We introduce a non-Koopmans self-interaction correction that generalizes the Perdew-Zunger scheme, and demonstrate its considerably improved performance in correcting the deficiencies of DFT approximations for self-interaction problems of fundamental and practical relevance.},
archiveprefix = {arxiv}
archiveprefix = {arXiv}
}

@article{Dabo2010,
Expand Down
24 changes: 16 additions & 8 deletions src/koopmans/workflows/_convergence.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import numpy as np

from koopmans import cell, utils
from koopmans.outputs import OutputModel

from ._workflow import Workflow

Expand Down Expand Up @@ -215,8 +216,16 @@ def ConvergenceVariableFactory(conv_var, **kwargs) -> ConvergenceVariable:
'construct your ConvergenceWorkflow using the ConvergenceWorkflowFactory')


class ConvergenceOutputs(OutputModel):

converged_values: Dict[str, Any]


class ConvergenceWorkflow(Workflow):

output_model = ConvergenceOutputs # type: ignore
outputs: ConvergenceOutputs

'''
A Workflow class that wraps another workflow in a convergence procedure in order to converge the observable within the specified tolerance with respect to the variables
'''
Expand Down Expand Up @@ -297,22 +306,19 @@ def _run(self) -> None:
subwf = self._subworkflow_class.fromparent(self)

# For each parameter we're converging wrt...
header = ''
subdir = Path()
label = ''
for index, variable in zip(indices, self.variables):
value = variable.values[index]
if isinstance(value, float):
value_str = f'{value:.1f}'
else:
value_str = str(value)
header += f'{variable.name} = {value_str}, '

if isinstance(value, list):
value_str = ''.join([str(x) for x in value])

# Create new working directory
subdir /= f'{variable.name}_{value_str}'.replace(
' ', '_').replace('.', 'd')
label += f' {variable.name} {value_str}'.replace('.', '_')

# Set the value
variable.set_value(subwf, value)
Expand All @@ -329,9 +335,8 @@ def _run(self) -> None:
# for _ in range(extra_orbitals)]
# utils.write_alpha_file(directory=Path(), alphas=alphas, filling=filling)

self.print(header.rstrip(', '), style='subheading')

# Perform calculation
subwf.name += label
subwf.run()

# Store the result
Expand Down Expand Up @@ -371,6 +376,8 @@ def _run(self) -> None:
self.print('\n Converged variables are '
+ ', '.join([f'{p.name} = {p.converged_value}' for p in self.variables]))

self.outputs = self.output_model(converged_values={v.name: v.converged_value for v in self.variables})

return
else:
# Work out which variables are yet to converge, and line up more calculations
Expand All @@ -379,7 +386,7 @@ def _run(self) -> None:
new_array_shape = list(np.shape(results))
new_array_slice: List[Union[int, slice]] = [
slice(None) for _ in indices]
self.print('Progress update', style='heading')
self.print('\nProgress update', style='heading')
for index, var in enumerate(self.variables):
subarray_slice = [slice(None) for _ in self.variables]
subarray_slice[index] = slice(0, -1)
Expand All @@ -403,6 +410,7 @@ def _run(self) -> None:
var.extend()
new_array_shape[index] += 1
new_array_slice[index] = slice(None, -1)
self.print()

new_results = np.empty(new_array_shape)
new_results[:] = np.nan
Expand Down
17 changes: 13 additions & 4 deletions src/koopmans/workflows/_dft.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,18 @@ def __init__(self, *args, **kwargs):
self.parameters.functional = 'dft'


class DFTCPOutput(OutputModel):
pass


class DFTCPWorkflow(DFTWorkflow):
output_model = DFTCPOutput # type: ignore
outputs: DFTCPOutput

def _run(self):

calc = self.new_calculator('kcp')

# Removing old directories
if self.parameters.from_scratch:
utils.system_call(f'rm -r {calc.parameters.outdir} 2>/dev/null', False)

calc.prefix = 'dft'
calc.directory = '.'
calc.parameters.ndr = 50
Expand All @@ -59,8 +61,15 @@ def _run(self):
return calc


class DFTPWOutput(OutputModel):
pass


class DFTPWWorkflow(DFTWorkflow):

output_model = DFTPWOutput # type: ignore
outputs: DFTPWOutput

def _run(self):

# Create the calculator
Expand Down
Loading

0 comments on commit 9373f05

Please sign in to comment.