diff --git a/src/nomad_simulations/properties/__init__.py b/src/nomad_simulations/properties/__init__.py index 0146ca18..f0266d16 100644 --- a/src/nomad_simulations/properties/__init__.py +++ b/src/nomad_simulations/properties/__init__.py @@ -20,10 +20,11 @@ FermiLevel, ChemicalPotential, TotalEnergy, - ClassicalEnergyContributions, - QuantumEnergyContributions, + Energy, + ClassicalEnergy, + QuantumEnergy, ) -from .forces import TotalForce, ForceContributions +from .forces import TotalForce, Force from .band_gap import ElectronicBandGap from .spectral_profile import ( SpectralProfile, diff --git a/src/nomad_simulations/properties/energies.py b/src/nomad_simulations/properties/energies.py index 3b441f54..ca568994 100644 --- a/src/nomad_simulations/properties/energies.py +++ b/src/nomad_simulations/properties/energies.py @@ -131,7 +131,7 @@ def normalize(self, archive, logger) -> None: f"Misidentified type for classical energy." ) -class QuamtumEnergy(Energy): +class QuantumEnergy(Energy): """ Abstract physical property section describing some quantum energy of a (sub)system. """ @@ -300,7 +300,7 @@ def normalize(self, archive, logger) -> None: # List of quantum energy contributions ###################################### -class ElectronicEnergy(QuamtumEnergy): +class ElectronicEnergy(QuantumEnergy): """ Physical property section describing the electronic energy of a (sub)system. """ @@ -310,7 +310,7 @@ def normalize(self, archive, logger) -> None: #! allowed_contributions = ['PotKin'] Not sure how to deal with sub-contributions... - I lean towards keeping a flat list but I am not sure of all the usages -class ElectronicKineticEnergy(QuamtumEnergy): +class ElectronicKineticEnergy(QuantumEnergy): """ Physical property section describing the electronic kinetic energy of a (sub)system. """ @@ -319,7 +319,7 @@ def normalize(self, archive, logger) -> None: super().normalize(archive, logger) -class XCEnergy(QuamtumEnergy): +class XCEnergy(QuantumEnergy): """ Physical property section describing the exchange-correlation (XC) energy of a (sub)system, calculated using the functional stored in XC_functional. @@ -331,7 +331,7 @@ def normalize(self, archive, logger) -> None: super().normalize(archive, logger) -class XCPotentialEnergy(QuamtumEnergy): +class XCPotentialEnergy(QuantumEnergy): """ Physical property section describing the potential energy contribution to the exchange-correlation (XC) energy, i.e., the integral of the first order derivative of the functional @@ -347,7 +347,7 @@ def normalize(self, archive, logger) -> None: # ? XCCorrelationEnergy? -class CorrelationEnergy(QuamtumEnergy): +class CorrelationEnergy(QuantumEnergy): """ Physical property section describing the correlation energy of a (sub)system, calculated using the method described in XC_functional. @@ -369,7 +369,7 @@ def normalize(self, archive, logger) -> None: # ? XCExchangeEnergy? -class ExchangeEnergy(QuamtumEnergy): +class ExchangeEnergy(QuantumEnergy): """ Physical property section describing the exchange energy of a (sub)system, calculated using the method described in XC_functional. @@ -381,7 +381,7 @@ def normalize(self, archive, logger) -> None: super().normalize(archive, logger) -class ZeroTemperatureEnergy(QuamtumEnergy): +class ZeroTemperatureEnergy(QuantumEnergy): """ Physical property section describing the total energy of a (sub)system extrapolated to $T=0$, based on a free-electron gas argument. """ @@ -392,7 +392,7 @@ def normalize(self, archive, logger) -> None: super().normalize(archive, logger) -class ZeroPointEnergy(QuamtumEnergy): +class ZeroPointEnergy(QuantumEnergy): """ Physical property section describing the zero-point vibrational energy of a (sub)system, calculated using the method described in zero_point_method. @@ -404,7 +404,7 @@ def normalize(self, archive, logger) -> None: super().normalize(archive, logger) -class ElectrostaticEnergy(QuamtumEnergy): +class ElectrostaticEnergy(QuantumEnergy): """ Physical property section describing the electrostatic energy (nuclei + electrons) of a (sub)system. """ @@ -413,7 +413,7 @@ def normalize(self, archive, logger) -> None: super().normalize(archive, logger) -class NuclearRepulsionEnergy(QuamtumEnergy): +class NuclearRepulsionEnergy(QuantumEnergy): """ Physical property section describing the nuclear-nuclear repulsion energy of a (sub)system. """ diff --git a/src/nomad_simulations/properties/forces.py b/src/nomad_simulations/properties/forces.py index 11676584..8e56bbb5 100644 --- a/src/nomad_simulations/properties/forces.py +++ b/src/nomad_simulations/properties/forces.py @@ -41,105 +41,116 @@ from nomad_simulations.physical_property import PhysicalProperty +#################################################### +# Abstract force classes +#################################################### -################################ -# List of Forces Contributions # -################################ - - -class FreeForce(PhysicalProperty): +class Force(PhysicalProperty): """ - 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. + Abstract physical property section describing some energy of a (sub)system. """ + type = Quantity( + type=MEnum('classical', 'quantum'), + description=""" + """, + ) + value = Quantity( type=np.dtype(np.float64), - shape=['n_atoms', 3], unit='newton', description=""" - The value of the free force. + The value of the force. """, ) def normalize(self, archive, logger) -> None: super().normalize(archive, logger) +###################################################### +# List of general force properties/contributions that +# can have both classical and quantum interpretations +###################################################### -class ZeroTemperatureForce(PhysicalProperty): +class TotalForce(Force): """ - Contains the value and information regarding the forces on the atoms - corresponding to the minus gradient of energy_T0. + 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.dtype(np.float64), - shape=['n_atoms', 3], - unit='newton', - description=""" - The value of the free force. - """, + contributions = SubSection( + sub_section=Force.m_def, repeats=True ) def normalize(self, archive, logger) -> None: super().normalize(archive, logger) -class RawForce(PhysicalProperty): - """ """ +################################ +# List of Forces Contributions # +################################ - 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. - """, - # ? This is VERY imprecise, is this used regularly? - ) + +class FreeForce(Force): + """ + Physical property section describing... + + 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. + """ 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): + +class ZeroTemperatureForce(Force): """ - Section containing contributions to the potential energy from a classical force field. + Physical property section describing... + + Contains the value and information regarding the forces on the atoms + corresponding to the minus gradient of energy_T0. """ - free = SubSection(sub_section=FreeForce.m_def, repeats=False) + def normalize(self, archive, logger) -> None: + super().normalize(archive, logger) - zero_temperature_force = SubSection( - sub_section=ZeroTemperatureForce.m_def, repeats=False - ) - raw = SubSection(sub_section=RawForce.m_def, repeats=False) +class RawForce(Force): + """ + Physical property section describing... + + Value of the forces acting on the atoms **not including** such as fixed atoms, + distances, angles, dihedrals, etc. + """ + # ? This is VERY imprecise, is this used regularly? def normalize(self, archive, logger) -> None: super().normalize(archive, logger) - self.name = self.m_def.name + + +# ? 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, +# ) # Old version of the Forces description @@ -149,28 +160,4 @@ def normalize(self, archive, logger) -> None: # 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=""" - The value of the total force. - """, - ) - - contributions = SubSection( - sub_section=ForceContributions.m_def, repeats=False - ) - # ? Do we need to separate classical and quantum contributions here? - - def normalize(self, archive, logger) -> None: - super().normalize(archive, logger)