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

Woods-Saxon confinement #90

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 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
6 changes: 6 additions & 0 deletions examples/mio/skdef.hsd
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ AtomParameters {
DftbAtom {
ShellResolved = No
DensityCompression = PowerCompression { Power = 2; Radius = 2.5 }
# Alternatively: Woods-Saxon compression potential
# (see J. Chem. Theory Comput. 12, 1, 53-64 (2016) eqn. 4.)
# With default W = 100.0:
# DensityCompression = WoodsSaxonCompression { a = 2.0; r0 = 6.0 }
# or with manual W:
# DensityCompression = WoodsSaxonCompression { W = 300.0; a = 2.0; r0 = 6.0 }
WaveCompressions = SingleAtomCompressions {
S = PowerCompression { Power = 2; Radius = 3.0 }
}
Expand Down
75 changes: 57 additions & 18 deletions sktools/src/sktools/calculators/slateratom.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
import sktools.hsd.converter as conv
import sktools.common as sc
from sktools.taggedfile import TaggedFile
import sktools.compressions
import sktools.compressions as skcomp
import sktools.radial_grid as oc
import sktools.xcfunctionals as xc


LOGGER = logging.getLogger('slateratom')
Expand Down Expand Up @@ -134,7 +135,7 @@ class SlateratomInput:
functional : str
DFT functional type ('lda', 'pbe', 'blyp', 'lcpbe', 'lcbnl')
compressions : list
List of PowerCompression objects. Either empty (no compression applied)
List of Compression objects. Either empty (no compression applied)
or has a compression object for every angular momentum of the atom.
settings : SlaterAtom
Further detailed settings of the program.
Expand Down Expand Up @@ -193,16 +194,26 @@ def __init__(self, settings, atomconfig, functional, compressions):
if compressions is None:
compressions = []
for comp in compressions:
if not isinstance(comp, sktools.compressions.PowerCompression):
msg = "Invalid compressiont type {} for slateratom".format(
if not isinstance(comp, (skcomp.PowerCompression,
skcomp.WoodsSaxonCompression)):
msg = "Invalid compression type {} for slateratom".format(
comp.__class__.__name__)
raise sc.SkgenException(msg)
maxang = atomconfig.maxang
ncompr = len(compressions)
if ncompr and ncompr != maxang + 1:
if ncompr > 0 and ncompr != maxang + 1:
msg = "Invalid number of compressions" \
"(expected {:d}, got {:d})".format(maxang + 1, ncompr)
raise sc.SkgenException(msg)

# block different compression types of different shells for now
if ncompr > 0:
compids = [comp.compid for comp in compressions]
if not len(set(compids)) == 1:
msg = "At the moment, shells may only be compressed by the " \
+ "same type of potential."
raise sc.SkgenException(msg)

self._compressions = compressions
myrelativistics = sc.RELATIVISTICS_NONE, sc.RELATIVISTICS_ZORA
if atomconfig.relativistics not in myrelativistics:
Expand All @@ -213,7 +224,7 @@ def __init__(self, settings, atomconfig, functional, compressions):
def isXCFunctionalSupported(self, functional):
'''Checks if the given xc-functional is supported by the calculator,
in particular: checks if AVAILABLE_FUNCTIONALS intersect with
sktools.xcfunctionals.XCFUNCTIONALS
xc.XCFUNCTIONALS

Args:
functional: xc-functional, defined in xcfunctionals.py
Expand All @@ -224,8 +235,8 @@ def isXCFunctionalSupported(self, functional):

tmp = []
for xx in SUPPORTED_FUNCTIONALS:
if xx in sktools.xcfunctionals.XCFUNCTIONALS:
tmp.append(sktools.xcfunctionals.XCFUNCTIONALS[xx])
if xx in xc.XCFUNCTIONALS:
tmp.append(xc.XCFUNCTIONALS[xx])

return bool(functional.__class__ in tmp)

Expand Down Expand Up @@ -297,14 +308,42 @@ def write(self, workdir):

# Compressions
if len(self._compressions) == 0:
out += ["{:g} {:d} \t\t{:s} Compr. radius and power ({:s})".format(
1e30, 0, self._COMMENT, sc.ANGMOM_TO_SHELL[ll])
# no compression for all shells
out += ["{:d} \t\t\t{:s} Compression ID".format(
skcomp.SUPPORTED_COMPRESSIONS['nocompression'],
self._COMMENT) + " ({:s})".format(sc.ANGMOM_TO_SHELL[ll])
for ll in range(maxang + 1)]
else:
out += ["{:g} {:g} \t\t{:s} Compr. radius and power ({:s})".format(
compr.radius, compr.power, self._COMMENT,
sc.ANGMOM_TO_SHELL[ll])
for ll, compr in enumerate(self._compressions)]
# define the type of compression for each shell
for ll, compr in enumerate(self._compressions):
if compr.compid == \
skcomp.SUPPORTED_COMPRESSIONS['powercompression']:
out += ["{:d} \t\t{:s} Compression ID".format(
skcomp.SUPPORTED_COMPRESSIONS['powercompression'],
self._COMMENT) \
+ " ({:s})".format(sc.ANGMOM_TO_SHELL[ll])]
elif compr.compid == \
skcomp.SUPPORTED_COMPRESSIONS['woodssaxoncompression']:
out += ["{:d} \t\t{:s} Compression ID".format(
skcomp.SUPPORTED_COMPRESSIONS['woodssaxoncompression'],
self._COMMENT) \
+ " ({:s})".format(sc.ANGMOM_TO_SHELL[ll])]
else:
msg = 'Invalid compression type.'
raise sc.SkgenException(msg)
# provide the compression parametrization for each shell
for ll, compr in enumerate(self._compressions):
if compr.compid == \
skcomp.SUPPORTED_COMPRESSIONS['powercompression']:
out += ["{:g} {:g} \t\t{:s} Compr. radius and power ({:s})"
.format(compr.radius, compr.power, self._COMMENT,
sc.ANGMOM_TO_SHELL[ll])]
elif compr.compid == \
skcomp.SUPPORTED_COMPRESSIONS['woodssaxoncompression']:
out += ["{:g} {:g} {:g} \t\t{:s}".format(
compr.ww, compr.aa, compr.r0, self._COMMENT) \
+ " Compr. height, slope, half-height radius ({:s})"
.format(sc.ANGMOM_TO_SHELL[ll])]

out += ["{:d} \t\t\t{:s} nr. of occupied shells ({:s})".format(
len(occ), self._COMMENT, sc.ANGMOM_TO_SHELL[ll])
Expand All @@ -313,9 +352,9 @@ def write(self, workdir):
# STO powers and exponents
exponents = self._settings.exponents
maxpowers = self._settings.maxpowers
out += ["{:d} {:d} \t\t\t{:s} nr. of exponents, max. power ({:s})".format(
len(exponents[ll]), maxpowers[ll], self._COMMENT,
sc.ANGMOM_TO_SHELL[ll])
out += ["{:d} {:d} \t\t\t{:s} nr. of exponents, max. power ({:s})"
.format(len(exponents[ll]), maxpowers[ll], self._COMMENT,
sc.ANGMOM_TO_SHELL[ll])
for ll in range(maxang + 1)]
out.append("{:s} \t\t{:s} automatic exponent generation".format(
self._LOGICALSTRS[False], self._COMMENT))
Expand All @@ -326,7 +365,7 @@ def write(self, workdir):

out.append("{:s} \t\t{:s} write eigenvectors".format(
self._LOGICALSTRS[False], self._COMMENT))
out.append("{} {:g} \t\t{:s} broyden mixer, mixing factor".format(
out.append("{} {:g} \t\t\t{:s} broyden mixer, mixing factor".format(
2, 0.1, self._COMMENT))

# Occupations
Expand Down
5 changes: 4 additions & 1 deletion sktools/src/sktools/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,10 @@ def is_shelf_file_matching(shelf_file, mydict):
return False
match = True
for key in mydict:
match = key in db and db[key] == mydict[key]
try:
match = key in db and db[key] == mydict[key]
except KeyError:
match = False
if not match:
return False
return True
Expand Down
71 changes: 71 additions & 0 deletions sktools/src/sktools/compressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ def fromhsd(cls, root, query):
node=child)

myself = cls()
myself.compid = SUPPORTED_COMPRESSIONS[
myself.__class__.__name__.lower()]
myself.power = power
myself.radius = radius

Expand All @@ -62,9 +64,78 @@ def __eq__(self, other):
return power_ok and radius_ok


class WoodsSaxonCompression(sc.ClassDict):
'''Compression by the Woods Saxon potential.

Attributes
----------
ww : float
Height (W) of the compression
aa : float
Slope (a) of the compression
r0 : float
Half-height radius of the compression
'''

@classmethod
def fromhsd(cls, root, query):
'''Creates instance from a HSD-node and with given query object.'''

ww, child = query.getvalue(
root, 'w', conv.float0, defvalue=100.0, returnchild=True)
if ww < 0.0:
msg = 'Invalid potential height (W) {:f}'.format(ww)
raise hsd.HSDInvalidTagValueException(msg=msg, node=child)

aa, child = query.getvalue(root, 'a', conv.float0, returnchild=True)
if aa <= 0.0:
msg = 'Invalid potential slope (a) {:f}'.format(aa)
raise hsd.HSDInvalidTagValueException(msg=msg, node=child)

r0, child = query.getvalue(root, 'r0', conv.float0, returnchild=True)
if r0 < 0.0:
msg = 'Invalid potential half-height radius {:f}'.format(r0)
raise hsd.HSDInvalidTagValueException(msg=msg, node=child)

myself = cls()
myself.compid = SUPPORTED_COMPRESSIONS[
myself.__class__.__name__.lower()]
myself.ww = ww
myself.aa = aa
myself.r0 = r0

return myself


def tohsd(self, root, query, parentname=None):
''''''

if parentname is None:
mynode = root
else:
mynode = query.setchild(root, 'WoodsSaxonCompression')

query.setchildvalue(mynode, 'w', conv.float0, self.ww)
query.setchildvalue(mynode, 'a', conv.float0, self.aa)
query.setchildvalue(mynode, 'r0', conv.float0, self.r0)


def __eq__(self, other):
ww_ok = abs(self.ww - other.ww) < 1e-8
aa_ok = abs(self.aa - other.aa) < 1e-8
r0_ok = abs(self.r0 - other.r0) < 1e-8
return ww_ok and aa_ok and r0_ok


# Registered compressions with corresponding hsd name as key
COMPRESSIONS = {
'powercompression': PowerCompression,
'woodssaxoncompression': WoodsSaxonCompression,
}
SUPPORTED_COMPRESSIONS = {
'nocompression': 0,
'powercompression': 1,
'woodssaxoncompression': 2,
}


Expand Down
3 changes: 2 additions & 1 deletion slateratom/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ set(sources-f90
diagonalizations.f90
globals.f90
hamiltonian.f90
input.f90
integration.f90
lapack.f90
mixer.f90
Expand All @@ -32,6 +31,8 @@ set(sources-f90
set(sources-fpp
blasroutines.F90
broydenmixer.F90
confinement.F90
input.F90
lapackroutines.F90
simplemixer.F90)

Expand Down
Loading
Loading