Skip to content

Commit 95352d3

Browse files
author
jrudz
committed
more angle progress
1 parent ff4588b commit 95352d3

File tree

2 files changed

+260
-39
lines changed

2 files changed

+260
-39
lines changed

src/nomad_simulations/schema_packages/force_field.py

Lines changed: 117 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,6 @@ def normalize(self, archive, logger) -> None:
268268
)
269269

270270
if self.forces is not None and self.energies is None:
271-
print('in gen energies')
272271
try:
273272
# generated energies from forces numerically using spline
274273
self.energies = self.compute_energies(
@@ -308,8 +307,38 @@ def normalize(self, archive, logger) -> None:
308307
)
309308

310309

311-
class PolynomialPotential(Potential):
310+
class PolynomialForceConstant(ParameterEntry):
311+
"""
312+
Section defining a force constant for a potential of polynomial form.
312313
"""
314+
315+
name = Quantity(
316+
type=str,
317+
shape=[],
318+
description="""
319+
Name of the force constant.
320+
""",
321+
)
322+
323+
exponent = Quantity(
324+
type=np.int32,
325+
shape=[],
326+
description="""
327+
Exponent for this term in the polynomial.
328+
""",
329+
)
330+
331+
value = Quantity(
332+
type=np.float64,
333+
shape=[],
334+
description="""
335+
Value of the force constant.
336+
""",
337+
)
338+
339+
340+
class PolynomialPotential(Potential):
341+
r"""
313342
Abstract class for potentials with polynomial form:
314343
$V(x) = [\left k_1 (x - x_0) + k_2 (x - x_0)^2 + x_3 (x - x_0)^3 + \dots + C$,
315344
where $\{x_1, x_2, x_3 \dots}$ are the `force_constants` for each term in the polynomial
@@ -318,7 +347,7 @@ class PolynomialPotential(Potential):
318347
"""
319348

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

331360
self.name = 'PolynomialPotential'
361+
if not self.functional_form:
362+
self.functional_form = 'polynomial'
363+
elif self.functional_form != 'polynomial':
364+
logger.warning('Incorrect functional form set for PolynomialPotential.')
332365

333366

334367
class BondPotential(Potential):
335368
"""
336369
Section containing information about bond potentials.
337370
338-
Suggested types are: harmonic, cubic, Morse, fene, tabulated
371+
Suggested types are: harmonic, cubic, polynomial, Morse, fene, tabulated
339372
"""
340373

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

421454

422-
# TODO Add Fourth Power potential from gromacs, might want to make it a more general quartic polynomial, even though it's not as general
423-
# class QuarticBond(BondPotential):
424-
# r"""
425-
# Section containing information about a Cubic bond potential:
426-
# $V(r) = \frac{1}{2} k_r (r - r_0)^2 + \frac{1}{3} k_c (r - r_0)^3 + C$,
427-
# where $k_r$ is the (harmonic) `force_constant`, $k_c$ is the `force_constant_cubic`,
428-
# and $r_0$ is the `equilibrium_value` of $r$.
429-
# C is an arbitrary constant (not stored).
430-
# """
431-
432-
# force_constant_cubic = Quantity(
433-
# type=np.float64,
434-
# shape=[],
435-
# unit='J / m**3',
436-
# description="""
437-
# Specifies the cubic force constant of the bond potential.
438-
# """,
439-
# )
440-
441-
# def normalize(self, archive, logger) -> None:
442-
# super().normalize(archive, logger)
443-
444-
# self.name = 'CubicBond'
445-
# if not self.functional_form:
446-
# self.functional_form = 'cubic'
447-
# elif self.functional_form != 'cubic':
448-
# logger.warning('Incorrect functional form set for CubicBond.')
449-
450-
451455
class PolynomialBond(PolynomialPotential, BondPotential):
452456
"""
453457
Section containing information about a polynomial bond potential:
454458
"""
455459

456460
def __init__(self):
461+
super().__init__()
457462
docstring = PolynomialPotential.__doc__
458463
pattern = r'\$V\(x\)(.*?)(\(not stored\)\.)'
459464
match = re.search(pattern, docstring, re.DOTALL)
460465
extracted_text = '<functional form missing>'
461466
if match:
462-
extracted_text = match.group(1).strip()
467+
extracted_text = match.group().strip() # .group(1).strip()
463468
self.__doc__ = rf"""{self.__doc__} {extracted_text}.
464469
Here the dependent variable of the potential, $x$, corresponds to the bond distance."""
465470

@@ -572,7 +577,7 @@ class AnglePotential(Potential):
572577
"""
573578
Section containing information about angle potentials.
574579
575-
Suggested types are: harmonic, cosine, fourier_series, urey_bradley, tabulated
580+
Suggested types are: harmonic, cosine, restricted_cosinse, fourier_series, urey_bradley, polynomial, tabulated
576581
"""
577582

578583
equilibrium_value = Quantity(
@@ -745,12 +750,13 @@ class PolynomialAngle(PolynomialPotential, AnglePotential):
745750
"""
746751

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

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

792798

799+
class DihedralPotential(Potential):
800+
"""
801+
Section containing information about dihedral potentials.
802+
803+
Suggested types are: fourier_series, tabulated
804+
805+
# ? Something about angle convention?
806+
"""
807+
808+
equilibrium_value = Quantity(
809+
type=np.float64,
810+
unit='degree',
811+
shape=[],
812+
description="""
813+
Specifies the equilibrium dihedral angle.
814+
""",
815+
)
816+
817+
force_constant = Quantity(
818+
type=np.float64,
819+
shape=[],
820+
unit='J / degree**2',
821+
description="""
822+
Specifies the force constant of the dihedral angle potential.
823+
""",
824+
)
825+
826+
def normalize(self, archive, logger) -> None:
827+
super().normalize(archive, logger)
828+
829+
self.name = 'DihedralPotential'
830+
if not self.type:
831+
self.type = 'dihedral'
832+
elif self.type != 'dihedral':
833+
logger.warning('Incorrect type set for DihedralPotential.')
834+
835+
if self.n_particles:
836+
if self.n_particles != 4:
837+
logger.warning(
838+
'Incorrect number of particles set for DihedralPotential.'
839+
)
840+
else:
841+
self.n_particles = 4
842+
843+
844+
class TabulatedDihedral(DihedralPotential, TabulatedPotential):
845+
"""
846+
Section containing information about a tabulated bond potential. The value of the potential and/or force
847+
is stored for a set of corresponding bin distances.
848+
"""
849+
850+
bins = Quantity(
851+
type=np.float64,
852+
unit='degree',
853+
shape=[],
854+
description="""
855+
List of bin dihedral angles.
856+
""",
857+
)
858+
859+
forces = Quantity(
860+
type=np.float64,
861+
unit='J/degree',
862+
shape=[],
863+
description="""
864+
List of force values associated with each bin.
865+
""",
866+
)
867+
868+
def normalize(self, archive, logger) -> None:
869+
super().normalize(archive, logger)
870+
871+
self.name = 'TabulatedDihedral'
872+
873+
793874
class ForceField(ModelMethod):
794875
"""
795876
Section containing the parameters of a (classical, particle-based) force field model.

0 commit comments

Comments
 (0)