Skip to content

Commit

Permalink
update ld1
Browse files Browse the repository at this point in the history
  • Loading branch information
superstar54 committed Sep 10, 2024
1 parent 317df26 commit 708aaed
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 40 deletions.
45 changes: 10 additions & 35 deletions src/ase_quantumespresso/ld1.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from .namelist import NamelistTemplate
import re


class Ld1Template(NamelistTemplate):
_label = "ld1"
outputname = "ld1.ld1o"

def __init__(self):
super().__init__(
Expand All @@ -13,6 +14,7 @@ def __init__(self):

def write_input(self, profile, directory, atoms, parameters, properties):
from ase.io.espresso_namelist.keys import ld1_keys

# I removed the "test" key from ld1_keys, because it was causing the following error:
# Error: reading number of pseudo wavefunctions (nwfs)
ld1_keys.pop("test")
Expand All @@ -22,38 +24,11 @@ def write_input(self, profile, directory, atoms, parameters, properties):
super().write_input(profile, directory, atoms, parameters, properties)

def read_results(self, directory):
path = directory / "ld1.ld1o"
with open(path, "r") as f:
energy_data = parse_energy_totals(f.read())

return {"ld1": energy_data}


from .parsers.ld1 import Ld1Parser

def parse_energy_totals(text):
# Pattern to find Etot and Etotps lines and capture relevant parts
etot_pattern = r"Etot\s+=\s+([-\d\.]+)\s+Ry,\s+([-\d\.]+)\s+Ha,\s+([-\d\.]+)\s+eV"
etotps_pattern = r"Etotps\s+=\s+([-\d\.]+)\s+Ry,\s+([-\d\.]+)\s+Ha,\s+([-\d\.]+)\s+eV"

# Search for patterns and extract values
etot_match = re.search(etot_pattern, text)
etotps_match = re.search(etotps_pattern, text)

# Structured data
energy_data = {}

if etot_match:
energy_data['Etot'] = {
'Ry': float(etot_match.group(1)),
'Ha': float(etot_match.group(2)),
'eV': float(etot_match.group(3))
}

if etotps_match:
energy_data['Etotps'] = {
'Ry': float(etotps_match.group(1)),
'Ha': float(etotps_match.group(2)),
'eV': float(etotps_match.group(3))
}

return energy_data
parser = Ld1Parser(directory, self.outputname)
exit_code = parser.parse()
results = parser.results
results["exit_code"] = exit_code
print("results", results)
return results
1 change: 0 additions & 1 deletion src/ase_quantumespresso/parsers/dos.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
Modified from aiida-quantumespresso.parsers.dos.DosParser.
"""

# from aiida_quantumespresso.calculations.pw import PwCalculation
from aiida_quantumespresso.utils.mapping import get_logging_container
from .exit_code import DosExitCodes
from .base import BaseParser
Expand Down
6 changes: 3 additions & 3 deletions src/ase_quantumespresso/parsers/exit_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class PwExitCodes:


@dataclass(frozen=True)
class NamelistsCalculation:
class NamelistsExitCodes:
ERROR_OUTPUT_STDOUT_MISSING: ExitCode = ExitCode(
302, "The folder did not contain the required stdout output file."
)
Expand All @@ -139,14 +139,14 @@ class NamelistsCalculation:


@dataclass(frozen=True)
class DosExitCodes(NamelistsCalculation):
class DosExitCodes(NamelistsExitCodes):
ERROR_OUTPUT_STDOUT_MISSING: ExitCode = ExitCode(
302, "The folder did not contain the required stdout output file."
)


@dataclass(frozen=True)
class ProjwfcExitCodes(NamelistsCalculation):
class ProjwfcExitCodes(NamelistsExitCodes):
ERROR_NO_RETRIEVED_TEMPORARY_FOLDER: ExitCode = ExitCode(
301, "The retrieved temporary folder could not be accessed."
)
Expand Down
80 changes: 80 additions & 0 deletions src/ase_quantumespresso/parsers/ld1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# -*- coding: utf-8 -*-
"""`Parser` implementation for the `ld1.x` code of Quantum ESPRESSO.
"""

from aiida_quantumespresso.utils.mapping import get_logging_container
from .exit_code import NamelistsExitCodes
from .base import BaseParser
import re


class Ld1Parser(BaseParser):
"""`Parser` implementation for the `dos.x` calculation, modified from aiida-quantumespresso."""

success_string = "End of pseudopotential test"

def __init__(self, directory, outputname):
"""Initialize the instance of `PwParser`."""
super().__init__(directory, output_filename=outputname)
self.outputname = outputname
self.exit_codes = NamelistsExitCodes()

def parse(self, **kwargs):
"""Parse the retrieved files of a ``DosCalculation`` into output nodes."""

logs = get_logging_container()

_, parsed_stdout, logs = self.parse_stdout_from_retrieved(logs)

base_exit_code = self.check_base_errors(logs)
if base_exit_code:
return self.exit(base_exit_code, logs)

self.out("output_parameters", parsed_stdout)

if "ERROR_OUTPUT_STDOUT_INCOMPLETE" in logs.error:
return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_INCOMPLETE, logs)

# Parse the Energy
filepath_dos = self.directory / self.outputname
try:
with open(filepath_dos, "r") as handle:
text = handle.read()
energy_data = parse_energy_totals(text)
self.out("ld1", energy_data)
except OSError:
return self.exit(self.exit_codes.ERROR_READING_DOS_FILE, logs)

return self.exit(logs=logs)


def parse_energy_totals(text):
# Pattern to find Etot and Etotps lines and capture relevant parts
etot_pattern = r"Etot\s+=\s+([-\d\.]+)\s+Ry,\s+([-\d\.]+)\s+Ha,\s+([-\d\.]+)\s+eV"
etotps_pattern = (
r"Etotps\s+=\s+([-\d\.]+)\s+Ry,\s+([-\d\.]+)\s+Ha,\s+([-\d\.]+)\s+eV"
)

# Search for patterns and extract values
etot_match = re.search(etot_pattern, text)
etotps_match = re.search(etotps_pattern, text)

# Structured data
energy_data = {}

if etot_match:
energy_data["Etot"] = {
"Ry": float(etot_match.group(1)),
"Ha": float(etot_match.group(2)),
"eV": float(etot_match.group(3)),
}

if etotps_match:
energy_data["Etotps"] = {
"Ry": float(etotps_match.group(1)),
"Ha": float(etotps_match.group(2)),
"eV": float(etotps_match.group(3)),
}

return energy_data
50 changes: 50 additions & 0 deletions tests/test_ld1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from ase_quantumespresso.espresso import Espresso, EspressoProfile
from ase_quantumespresso.ld1 import Ld1Template

input_data = {
"input": {
"title": "Pt",
"zed": 78.0,
"rel": 1,
"config": "[Xe] 4f13 6s1 6p0 5d9",
"iswitch": 3,
"dft": "PBE",
},
"inputp": {
"lpaw": True,
"use_xsd": False,
"pseudotype": 3,
"file_pseudopw": "Pt.star4f.pbe-n-kjpaw_psl.1.0.0.UPF",
"author": "Test",
"lloc": -1,
"rcloc": 2.4,
"which_augfun": "PSQ",
"rmatch_augfun_nc": True,
"nlcc": True,
"new_core_ps": True,
"rcore": 1.8,
"tm": True,
},
}
pseudo_potential_test_cards = """
6
6S 1 0 1.00 0.00 2.00 2.20 0.0
6S 1 0 0.00 4.40 2.00 2.20 0.0
6P 2 1 0.00 0.00 2.30 2.50 0.0
6P 2 1 0.00 6.40 2.30 2.50 0.0
5D 3 2 9.00 0.00 1.00 2.20 0.0
5D 3 2 0.00 0.80 1.00 2.20 0.0
"""


def test_base_ld1():
profile = EspressoProfile(command="ld1.x", pseudo_dir=".")
calc = Espresso(
directory="calculatioin",
profile=profile,
template=Ld1Template(),
input_data=input_data,
pseudo_potential_test_cards=pseudo_potential_test_cards,
)
calc.get_property("ld1")
assert calc.results["exit_code"].status == 0
2 changes: 1 addition & 1 deletion tests/test_pw.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
def test_pw(bulk_si, pseudopotentials, pseudo_dir, pw_input_data):
profile = EspressoProfile(command="pw.x", pseudo_dir=pseudo_dir)
calc = Espresso(
directory="test",
directory="calculatioin",
profile=profile,
pseudopotentials=pseudopotentials,
input_data=pw_input_data,
Expand Down

0 comments on commit 708aaed

Please sign in to comment.