Skip to content

Commit

Permalink
updated force and energy contributions
Browse files Browse the repository at this point in the history
  • Loading branch information
jrudz committed Jun 14, 2024
1 parent 0d329a9 commit 454cd9f
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 78 deletions.
15 changes: 8 additions & 7 deletions src/nomad_simulations/outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# limitations under the License.
#

import numpy as np
from structlog.stdlib import BoundLogger
from typing import Optional, List

Expand Down Expand Up @@ -308,13 +309,13 @@ class WorkflowOutputs(Outputs):
""",
)

workflow_ref = Quantity(
type=SimulationWorkflow,
description="""
Reference to the `SelfConsistency` section that defines the numerical settings to converge the
output property.
""",
)
# workflow_ref = Quantity(
# type=SimulationWorkflow,
# description="""
# Reference to the `SelfConsistency` section that defines the numerical settings to converge the
# output property.
# """,
# )

def normalize(self, archive, logger) -> None:
super().normalize(archive, logger)
Expand Down
8 changes: 7 additions & 1 deletion src/nomad_simulations/properties/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from .energies import FermiLevel, ChemicalPotential, TotalEnergy
from .energies import (
FermiLevel,
ChemicalPotential,
TotalEnergy,
ClassicalEnergyContributions,
QuantumEnergyContributions,
)
from .band_gap import ElectronicBandGap
from .spectral_profile import (
SpectralProfile,
Expand Down
8 changes: 4 additions & 4 deletions src/nomad_simulations/properties/energies.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ class ExternalEnergy(PhysicalProperty):
def normalize(self, archive, logger) -> None:
super().normalize(archive, logger)

class ClassicalEnergyContributions(PhysicalProperty):
class ClassicalEnergyContributions(ArchiveSection):
"""
Section containing contributions to the potential energy from a classical force field.
"""
Expand Down Expand Up @@ -451,7 +451,7 @@ def normalize(self, archive, logger) -> None:
super().normalize(archive, logger)


class T0Energy(PhysicalProperty):
class ZeroTemperatureEnergy(PhysicalProperty):
"""
Section containing the total energy of a (sub)system extrapolated to $T=0$.
"""
Expand Down Expand Up @@ -520,7 +520,7 @@ def normalize(self, archive, logger) -> None:
super().normalize(archive, logger)


class QuantumEnergyContributions(EnergyContributions):
class QuantumEnergyContributions(ArchiveSection):
"""
Section containing contributions to the potential energy from a DFT calculation.
"""
Expand All @@ -538,7 +538,7 @@ class QuantumEnergyContributions(EnergyContributions):

exchange = SubSection(sub_section=ExchangeEnergy.m_def, repeats=False)

t0 = SubSection(sub_section=T0Energy.m_def, repeats=False)
zero_temperature = SubSection(sub_section=ZeroTemperatureEnergy.m_def, repeats=False)

zero_point = SubSection(sub_section=ZeroPointEnergy.m_def, repeats=False)

Expand Down
147 changes: 81 additions & 66 deletions src/nomad_simulations/properties/forces.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,113 +69,128 @@

from .model_system import ModelSystem

################################
# List of Forces Contributions #
################################


class ForceTotal(PhysicalProperty):
class FreeForce(PhysicalProperty):
"""
Section containing the total force of a (sub)system.
Contains the value and information regarding the forces on the atoms
corresponding to the minus gradient of energy_free. The (electronic) energy_free
contains the information on the change in (fractional) occupation of the
electronic eigenstates, which are accounted for in the derivatives, yielding a
truly energy-conserved quantity.
"""

value = Quantity(
type=np.float64,
type=np.dtype(np.float64),
shape=['n_atoms', 3],
unit='newton',
description="""
The value of the total force.
The value of the free force.
""",
)

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



class ForcesEntry(Atomic):
class ZeroTemperatureForce(PhysicalProperty):
"""
Section describing a contribution to or type of atomic forces.
Contains the value and information regarding the forces on the atoms
corresponding to the minus gradient of energy_T0.
"""

m_def = Section(validate=False)

value = Quantity(
type=np.dtype(np.float64),
shape=['n_atoms', 3],
unit='newton',
description="""
Value of the forces acting on the atoms. This is calculated as minus gradient of
the corresponding energy type or contribution **including** constraints, if
present. The derivatives with respect to displacements of nuclei are evaluated in
Cartesian coordinates. In addition, these are obtained by filtering out the
unitary transformations (center-of-mass translations and rigid rotations for
non-periodic systems, see value_raw for the unfiltered counterpart).
The value of the free force.
""",
)

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

class RawForce(PhysicalProperty):
"""
"""

value = Quantity(
type=np.dtype(np.float64),
shape=['n_atoms', 3],
unit='newton',
description="""
Value of the forces acting on the atoms **not including** such as fixed atoms,
distances, angles, dihedrals, etc.""",
distances, angles, dihedrals, etc.
""",
# ? This is VERY imprecise, is this used regularly?
)
# ? This is VERY imprecise, is this used regularly?

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


#? Do we want to support custom contributions?
# contributions = SubSection(
# sub_section=ForcesEntry.m_def,
# description="""
# Contains other forces contributions to the total atomic forces not already
# defined.
# """,
# repeats=True,
# )

# types = SubSection(
# sub_section=ForcesEntry.m_def,
# description="""
# Contains other types of forces not already defined.
# """,
# repeats=True,
# )

class ForceContributions(ArchiveSection):
"""
Section containing all forces types and contributions.
Section containing contributions to the potential energy from a classical force field.
"""

m_def = Section(validate=False)
free = SubSection(sub_section=FreeForce.m_def, repeats=False)

total = SubSection(
sub_section=ForcesEntry.m_def,
description="""
Contains the value and information regarding the total forces on the atoms
calculated as minus gradient of energy_total.
""",
)
# ! We need to avoid giving the precise method of calculation without also providing context, this is not necessarily true in general!
zero_temperature_force = SubSection(sub_section=ZeroTemperatureForce.m_def, repeats=False)

free = SubSection(
sub_section=ForcesEntry.m_def,
description="""
Contains the value and information regarding the forces on the atoms
corresponding to the minus gradient of energy_free. The (electronic) energy_free
contains the information on the change in (fractional) occupation of the
electronic eigenstates, which are accounted for in the derivatives, yielding a
truly energy-conserved quantity.
""",
)
raw = SubSection(sub_section=RawForce.m_def, repeats=False)

t0 = SubSection(
sub_section=ForcesEntry.m_def,
description="""
Contains the value and information regarding the forces on the atoms
corresponding to the minus gradient of energy_T0.
""",
)
def normalize(self, archive, logger) -> None:
super().normalize(archive, logger)
self.name = self.m_def.name

contributions = SubSection(
sub_section=ForcesEntry.m_def,
description="""
Contains other forces contributions to the total atomic forces not already
defined.
""",
repeats=True,
)

types = SubSection(
sub_section=ForcesEntry.m_def,
# Old version of the Forces description
# Value of the forces acting on the atoms. This is calculated as minus gradient of
# the corresponding energy type or contribution **including** constraints, if
# present. The derivatives with respect to displacements of nuclei are evaluated in
# Cartesian coordinates. In addition, these are obtained by filtering out the
# unitary transformations (center-of-mass translations and rigid rotations for
# non-periodic systems, see value_raw for the unfiltered counterpart).
class TotalForce(PhysicalProperty):
"""
Section containing the total force of a (sub)system.
Contains the value and information regarding the total forces on the atoms
calculated as minus gradient of energy_total.
"""
# ! We need to avoid giving the precise method of calculation without also providing context, this is not necessarily true in general!

value = Quantity(
type=np.float64,
unit='newton',
description="""
Contains other types of forces not already defined.
The value of the total force.
""",
repeats=True,
)

force_contributions = SubSection(sub_section=ForceContributions.m_def, repeats=False)
#? Do we need to separate classical and quantum contributions here?




forces = SubSection(sub_section=Forces.m_def)


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

0 comments on commit 454cd9f

Please sign in to comment.