Skip to content

Commit

Permalink
more angle progress
Browse files Browse the repository at this point in the history
  • Loading branch information
jrudz committed Jan 9, 2025
1 parent ff4588b commit 95352d3
Show file tree
Hide file tree
Showing 2 changed files with 260 additions and 39 deletions.
153 changes: 117 additions & 36 deletions src/nomad_simulations/schema_packages/force_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,6 @@ def normalize(self, archive, logger) -> None:
)

if self.forces is not None and self.energies is None:
print('in gen energies')
try:
# generated energies from forces numerically using spline
self.energies = self.compute_energies(
Expand Down Expand Up @@ -308,8 +307,38 @@ def normalize(self, archive, logger) -> None:
)


class PolynomialPotential(Potential):
class PolynomialForceConstant(ParameterEntry):
"""
Section defining a force constant for a potential of polynomial form.
"""

name = Quantity(
type=str,
shape=[],
description="""
Name of the force constant.
""",
)

exponent = Quantity(
type=np.int32,
shape=[],
description="""
Exponent for this term in the polynomial.
""",
)

value = Quantity(
type=np.float64,
shape=[],
description="""
Value of the force constant.
""",
)


class PolynomialPotential(Potential):
r"""
Abstract class for potentials with polynomial form:
$V(x) = [\left k_1 (x - x_0) + k_2 (x - x_0)^2 + x_3 (x - x_0)^3 + \dots + C$,
where $\{x_1, x_2, x_3 \dots}$ are the `force_constants` for each term in the polynomial
Expand All @@ -318,7 +347,7 @@ class PolynomialPotential(Potential):
"""

force_constants = SubSection(
sub_section=ParameterEntry.m_def,
sub_section=PolynomialForceConstant.m_def,
repeats=True,
description="""
List of force constants value and corresponding unit for polynomial potentials.
Expand All @@ -329,13 +358,17 @@ def normalize(self, archive, logger) -> None:
super().normalize(archive, logger)

self.name = 'PolynomialPotential'
if not self.functional_form:
self.functional_form = 'polynomial'
elif self.functional_form != 'polynomial':
logger.warning('Incorrect functional form set for PolynomialPotential.')


class BondPotential(Potential):
"""
Section containing information about bond potentials.
Suggested types are: harmonic, cubic, Morse, fene, tabulated
Suggested types are: harmonic, cubic, polynomial, Morse, fene, tabulated
"""

equilibrium_value = Quantity(
Expand Down Expand Up @@ -419,47 +452,19 @@ def normalize(self, archive, logger) -> None:
logger.warning('Incorrect functional form set for CubicBond.')


# TODO Add Fourth Power potential from gromacs, might want to make it a more general quartic polynomial, even though it's not as general
# class QuarticBond(BondPotential):
# r"""
# Section containing information about a Cubic bond potential:
# $V(r) = \frac{1}{2} k_r (r - r_0)^2 + \frac{1}{3} k_c (r - r_0)^3 + C$,
# where $k_r$ is the (harmonic) `force_constant`, $k_c$ is the `force_constant_cubic`,
# and $r_0$ is the `equilibrium_value` of $r$.
# C is an arbitrary constant (not stored).
# """

# force_constant_cubic = Quantity(
# type=np.float64,
# shape=[],
# unit='J / m**3',
# description="""
# Specifies the cubic force constant of the bond potential.
# """,
# )

# def normalize(self, archive, logger) -> None:
# super().normalize(archive, logger)

# self.name = 'CubicBond'
# if not self.functional_form:
# self.functional_form = 'cubic'
# elif self.functional_form != 'cubic':
# logger.warning('Incorrect functional form set for CubicBond.')


class PolynomialBond(PolynomialPotential, BondPotential):
"""
Section containing information about a polynomial bond potential:
"""

def __init__(self):
super().__init__()
docstring = PolynomialPotential.__doc__
pattern = r'\$V\(x\)(.*?)(\(not stored\)\.)'
match = re.search(pattern, docstring, re.DOTALL)
extracted_text = '<functional form missing>'
if match:
extracted_text = match.group(1).strip()
extracted_text = match.group().strip() # .group(1).strip()
self.__doc__ = rf"""{self.__doc__} {extracted_text}.
Here the dependent variable of the potential, $x$, corresponds to the bond distance."""

Expand Down Expand Up @@ -572,7 +577,7 @@ class AnglePotential(Potential):
"""
Section containing information about angle potentials.
Suggested types are: harmonic, cosine, fourier_series, urey_bradley, tabulated
Suggested types are: harmonic, cosine, restricted_cosinse, fourier_series, urey_bradley, polynomial, tabulated
"""

equilibrium_value = Quantity(
Expand Down Expand Up @@ -745,12 +750,13 @@ class PolynomialAngle(PolynomialPotential, AnglePotential):
"""

def __init__(self):
super().__init__()
docstring = PolynomialPotential.__doc__
pattern = r'\$V\(x\)(.*?)(\(not stored\)\.)'
match = re.search(pattern, docstring, re.DOTALL)
extracted_text = '<functional form missing>'
if match:
extracted_text = match.group(1).strip()
extracted_text = match.group().strip() # .group(1).strip()
self.__doc__ = rf"""{self.__doc__} {extracted_text}.
Here the dependent variable of the potential, $x$, corresponds to the angle between three particles."""

Expand Down Expand Up @@ -790,6 +796,81 @@ def normalize(self, archive, logger) -> None:
self.name = 'TabulatedAngle'


class DihedralPotential(Potential):
"""
Section containing information about dihedral potentials.
Suggested types are: fourier_series, tabulated
# ? Something about angle convention?
"""

equilibrium_value = Quantity(
type=np.float64,
unit='degree',
shape=[],
description="""
Specifies the equilibrium dihedral angle.
""",
)

force_constant = Quantity(
type=np.float64,
shape=[],
unit='J / degree**2',
description="""
Specifies the force constant of the dihedral angle potential.
""",
)

def normalize(self, archive, logger) -> None:
super().normalize(archive, logger)

self.name = 'DihedralPotential'
if not self.type:
self.type = 'dihedral'
elif self.type != 'dihedral':
logger.warning('Incorrect type set for DihedralPotential.')

if self.n_particles:
if self.n_particles != 4:
logger.warning(
'Incorrect number of particles set for DihedralPotential.'
)
else:
self.n_particles = 4


class TabulatedDihedral(DihedralPotential, TabulatedPotential):
"""
Section containing information about a tabulated bond potential. The value of the potential and/or force
is stored for a set of corresponding bin distances.
"""

bins = Quantity(
type=np.float64,
unit='degree',
shape=[],
description="""
List of bin dihedral angles.
""",
)

forces = Quantity(
type=np.float64,
unit='J/degree',
shape=[],
description="""
List of force values associated with each bin.
""",
)

def normalize(self, archive, logger) -> None:
super().normalize(archive, logger)

self.name = 'TabulatedDihedral'


class ForceField(ModelMethod):
"""
Section containing the parameters of a (classical, particle-based) force field model.
Expand Down
Loading

1 comment on commit 95352d3

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage

Coverage Report
FileStmtsMissCoverMissing
src/nomad_simulations
   __init__.py4250%3–4
   _version.py11282%5–6
src/nomad_simulations/schema_packages
   __init__.py15287%39–41
   atoms_state.py1902189%13–15, 201–204, 228, 283–284, 352–353, 355, 537, 549–550, 611–615, 630–634, 641
   basis_set.py2402888%8–9, 122–133, 172–185, 208, 391–395, 417–418, 462–465, 584, 615, 617
   force_field.py2859766%135, 141, 190–196, 199–206, 209–304, 363–364, 399–400, 404, 423–424, 451–452, 510–511, 515–516, 542–543, 571–573, 607–608, 612, 631–632, 650–651, 669–670, 702–703, 743–744, 794–796, 827–841, 869–871, 917–920
   general.py89891%4–7, 121, 185, 295–296, 306
   model_method.py2707871%10–12, 180–183, 186–193, 285–286, 306, 327–348, 364–390, 393–410, 596, 789, 800, 842–849, 887, 906, 986, 1043, 1118, 1232
   model_system.py3483789%45–51, 235, 254, 258, 261, 264, 290, 376–377, 454–455, 472–473, 686–689, 736–743, 917–918, 1140–1144, 1150–1151, 1159–1160, 1165, 1188
   numerical_settings.py2676277%12–14, 217, 219–220, 223–226, 230–231, 238–241, 250–253, 257–260, 262–265, 270–273, 279–282, 469–496, 571, 606–609, 633, 636, 681, 683–686, 690, 694, 741, 745–766, 821–822, 889, 972
   outputs.py1201092%9–10, 250–253, 293–296, 321, 323, 360, 379
   physical_property.py102793%20–22, 202, 331–333
   variables.py861286%8–10, 98, 121, 145, 167, 189, 211, 233, 256, 276
src/nomad_simulations/schema_packages/properties
   band_gap.py51590%8–10, 135–136
   band_structure.py1232580%9–11, 232–265, 278, 285, 321–322, 325, 372–373, 378
   energies.py42979%7–9, 36, 57, 82, 103, 119, 134
   fermi_surface.py17476%7–9, 40
   forces.py25676%7–9, 43, 63, 86
   greens_function.py991387%7–9, 210–211, 214, 235–236, 239, 260–261, 264, 400
   hopping_matrix.py29583%7–9, 58, 94
   permittivity.py48883%7–9, 97–105
   spectral_profile.py26012851%9–11, 57–60, 95–98, 199–300, 356–368, 393–396, 416, 421–424, 466–502, 526, 573–576, 592–593, 598–604
   thermodynamics.py752764%7–9, 35, 56, 72, 81, 90, 101, 110, 137, 147, 157, 172–174, 177, 193, 213–215, 218, 234, 254–256, 259
src/nomad_simulations/schema_packages/utils
   utils.py791680%8–11, 65–74, 83–84, 89, 92, 169–170
TOTAL288661279% 

Tests Skipped Failures Errors Time
416 0 💤 3 ❌ 0 🔥 7.702s ⏱️

Please sign in to comment.