Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core hole calculations #455

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions doc/users/user_ref.rst
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,15 @@ User input reference
**Predicates**
- ``value.lower() in ['exponential']``

:OrbitalOccupancies: Modify the default orbital occupancies in order to perform a DeltaSCF calculation.

:red:`Keywords`
:occupancies: List of orbitals, i, for which the default occupancy, f, should be overwritten, written as a list in the format "i f_up f_down", where the orbitals are indexed from zero.

**Type** ``str``

**Default** ````

:Constants: Physical and mathematical constants used by MRChem

:red:`Keywords`
Expand Down
3 changes: 3 additions & 0 deletions python/mrchem/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
write_scf_properties,
write_scf_plot,
write_rsp_calc,
write_scf_occupancies,
parse_wf_method,
)
from .periodictable import PeriodicTable as PT, PeriodicTableByZ as PT_Z
Expand Down Expand Up @@ -165,6 +166,8 @@ def write_scf_calculation(user_dict, origin):
plot_dict = write_scf_plot(user_dict)
if len(plot_dict) > 0:
scf_dict["plots"] = plot_dict

scf_dict["occupancies"] = write_scf_occupancies(user_dict)

return scf_dict

Expand Down
96 changes: 96 additions & 0 deletions python/mrchem/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,3 +526,99 @@ def parse_wf_method(user_dict):
"dft_funcs": dft_funcs,
}
return wf_dict

# Error/warning messages
ERROR_MESSAGE_ORBITAL_OCCUPANCIES = (
lambda details: f"ABORT: INVALID ORBITAL OCCUPANCIES: {details}"
)

def write_scf_occupancies(user_dict):
"""Convert orbital occupancies from JSON syntax to program syntax."""
# First validate the input file
orbitals, occupancies = validate_orbital_occupancies(user_dict)

return [
{"orbital": orbital, "occupancy": occupancy}
for orbital, occupancy in zip(orbitals, occupancies)
]

def validate_orbital_occupancies(user_dict):
"""Parse the $occupancies block and ensure correct formatting."""
import re

# Regex components
line_start = r"^"
line_end = r"$"
decimal = r"[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)"
integer = r"[0-9]+"
one_or_more_whitespace = r"[\s]+"
zero_or_more_whitespace = r"[\s]*"

# Build regex
restricted_occupancies = (
line_start
+ zero_or_more_whitespace
+ integer
+ (one_or_more_whitespace + decimal)
+ zero_or_more_whitespace
+ line_end
)
unrestricted_occupancies = (
line_start
+ zero_or_more_whitespace
+ integer
+ (one_or_more_whitespace + decimal) * 2
+ zero_or_more_whitespace
+ line_end
)

occ_restricted = re.compile(restricted_occupancies)
occ_unrestricted = re.compile(unrestricted_occupancies)

occs_raw = user_dict["OrbitalOccupancies"]["occupancies"]

lines = [x.strip() for x in occs_raw.strip().splitlines() if x != ""]
# Parse coordinates
orbitals = []
occupancies = []
bad_occupancies = []
for occ in lines:
match_restricted = occ_restricted.match(occ)
match_unrestricted = occ_unrestricted.match(occ)
if match_restricted:
g = match_restricted.group()
orbitals.append(int(g.split()[0].strip()))
occupancies.append([float(c.strip()) for c in g.split()[1:]])
elif match_unrestricted:
g = match_unrestricted.group()
orbitals.append(int(g.split()[0].strip()))
occupancies.append([float(c.strip()) for c in g.split()[1:]])
else:
bad_occupancies.append(occ)

if bad_occupancies:
newline = "\n"
raise RuntimeError(
ERROR_MESSAGE_ORBITAL_OCCUPANCIES(
f"One or more orbital occupancies had an invalid input format:\n{newline.join(bad_occupancies)}"
)
)

# Check that the orbital is valid - we would need the total number of orbitals to do this properly
# so here we just check the index isn't negative
fltr = filter(lambda x: x < 0, orbitals)
if any(list(fltr)):
newline = "\n"
raise RuntimeError(
self.ERROR_MESSAGE_ORBITAL_OCCUPANCIES(
f"One or more invalid atomic symbols:\n{newline.join(set(fltr))}"
)
)

return orbitals, occupancies






2 changes: 1 addition & 1 deletion python/mrchem/input_parser/README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
This file was automatically generated by parselglossy on 2022-10-03
This file was automatically generated by parselglossy on 2023-09-01
Editing is *STRONGLY DISCOURAGED*
2 changes: 1 addition & 1 deletion python/mrchem/input_parser/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-

# This file was automatically generated by parselglossy on 2022-10-03
# This file was automatically generated by parselglossy on 2023-09-01
# Editing is *STRONGLY DISCOURAGED*
6 changes: 5 additions & 1 deletion python/mrchem/input_parser/api.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-

# This file was automatically generated by parselglossy on 2022-10-26
# This file was automatically generated by parselglossy on 2023-09-01
# Editing is *STRONGLY DISCOURAGED*

from copy import deepcopy
Expand Down Expand Up @@ -614,6 +614,10 @@ def stencil() -> JSONDict:
"['exponential']"],
'type': 'str'}],
'name': 'Permittivity'}]},
{ 'keywords': [ { 'default': '',
'name': 'occupancies',
'type': 'str'}],
'name': 'OrbitalOccupancies'},
{ 'keywords': [ { 'default': 78.9451185,
'name': 'hartree2simagnetizability',
'type': 'float'},
Expand Down
2 changes: 1 addition & 1 deletion python/mrchem/input_parser/cli.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-

# This file was automatically generated by parselglossy on 2022-10-03
# This file was automatically generated by parselglossy on 2023-09-01
# Editing is *STRONGLY DISCOURAGED*

import argparse
Expand Down
9 changes: 9 additions & 0 deletions python/mrchem/input_parser/docs/user_ref.rst
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,15 @@ User input reference
**Predicates**
- ``value.lower() in ['exponential']``

:OrbitalOccupancies: Modify the default orbital occupancies in order to perform a DeltaSCF calculation.

:red:`Keywords`
:occupancies: List of orbitals, i, for which the default occupancy, f, should be overwritten, written as a list in the format "i f_up f_down", where the orbitals are indexed from zero.

**Type** ``str``

**Default** ````

:Constants: Physical and mathematical constants used by MRChem

:red:`Keywords`
Expand Down
5 changes: 3 additions & 2 deletions python/mrchem/input_parser/plumbing/atoms.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@

try:
import pyparsing as pp

if pp.__version__.split(".")[0] < "3":
# Import local copy
from . import pyparsing as pp # type: ignore
# Import local copy
from . import pyparsing as pp # type: ignore
except ImportError:
# Import local copy
from . import pyparsing as pp # type: ignore
Expand Down
6 changes: 4 additions & 2 deletions python/mrchem/input_parser/plumbing/getkw.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@

try:
import pyparsing as pp

if pp.__version__.split(".")[0] < "3":
# Import local copy
from . import pyparsing as pp # type: ignore
# Import local copy
from . import pyparsing as pp # type: ignore
except ImportError:
# Import local copy
from . import pyparsing as pp # type: ignore
Expand Down Expand Up @@ -131,3 +132,4 @@ def parse_string_to_dict(lexer: "pp.ParserElement", s: str) -> JSONDict:
if flatten_list(tokens_list) != flatten_list(dict_to_list(tokens_dict)):
raise ParselglossyError("A keyword is repeated. Please check your input.")
return tokens_dict

2 changes: 1 addition & 1 deletion python/mrchem/input_parser/plumbing/lexer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-

# This file was automatically generated by parselglossy on 2022-10-03
# This file was automatically generated by parselglossy on 2023-09-01
# Editing is *STRONGLY DISCOURAGED*

import json
Expand Down
Loading