Skip to content

Commit

Permalink
- Add tests for plane-wave cutoffs
Browse files Browse the repository at this point in the history
- Correct formula `cutoff_radius`
- Correct failure handling of `cutoff_fractional`
  • Loading branch information
ndaelman committed Aug 8, 2024
1 parent db23f37 commit c26c547
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 11 deletions.
23 changes: 12 additions & 11 deletions src/nomad_simulations/schema_packages/basis_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,11 @@ def cutoff_radius(self) -> pint.Quantity:
"""
Compute the cutoff radius for the plane-wave basis set, expressed in reciprocal coordinates.
"""
if self.cutoff_energy is None:
return None
m_e = const.m_e * ureg(const.unit('electron mass'))
return np.sqrt(2 * m_e * self.cutoff_energy)
h = const.h * ureg(const.unit('Planck constant'))
return np.sqrt(2 * m_e * self.cutoff_energy) / h

def normalize(self, archive: EntryArchive, logger: BoundLogger) -> None:
super(BasisSet, self).normalize(archive, logger)
Expand Down Expand Up @@ -113,16 +116,14 @@ def set_cutoff_fractional(self, mt_r_min: pint.Quantity, logger: BoundLogger) ->
Compute the fractional cutoff parameter for the interstitial plane waves in the LAPW family.
This parameter is defined wrt the smallest muffin-tin region.
"""
try:
self.cutoff_fractional = self.cutoff_radius / mt_r_min # unitless
except AttributeError:
logger.warning('`MuffinTin.cutoff_energy` must be defined.')
except ZeroDivisionError:
logger.warning('`MuffinTin.radius` cannot be zero.')
except TypeError:
logger.warning(
'`MuffinTin.radius` and `MuffinTin.cutoff_energy` must be defined.'
)
reference_unit = 'angstrom'
if self.cutoff_fractional is not None:
logger.info('`APWPlaneWaveBasisSet.cutoff_fractional` already defined. Will not overwrite.') #! extend implementation
return
elif self.cutoff_energy is None or mt_r_min is None:
logger.warning('`APWPlaneWaveBasisSet.cutoff_energy` and `APWPlaneWaveBasisSet.radius` must both be defined. Aborting normalization step.')
return
self.cutoff_fractional = self.cutoff_radius.to(f'1 / {reference_unit}') * mt_r_min.to(reference_unit)


class AtomCenteredFunction(ArchiveSection):
Expand Down
33 changes: 33 additions & 0 deletions tests/test_basis_set.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from nomad.units import ureg
import numpy as np
from . import logger

from nomad_simulations.schema_packages.basis_set import APWPlaneWaveBasisSet


def test_cutoff():
"""Test the quantitative results when computing certain plane-wave cutoffs."""
p_unit = '1 / angstrom'
ref_cutoff_radius = 1.823 * ureg(p_unit)
pw = APWPlaneWaveBasisSet(cutoff_energy=500 * ureg('eV'))
assert np.isclose(pw.cutoff_radius.to(p_unit).magnitude, ref_cutoff_radius.magnitude, atol=1e-3) # reference computed by ChatGPT 4o

pw.set_cutoff_fractional(1 / ref_cutoff_radius, logger)
assert np.isclose(pw.cutoff_fractional, 1, rtol=1e-2)

def test_cutoff_failure():
"""Test modes where `cutoff_fractional` is not computed."""
# missing cutoff_energy
pw = APWPlaneWaveBasisSet()
pw.set_cutoff_fractional(ureg.angstrom, logger)
assert pw.cutoff_fractional is None

# missing mt_radius
pw = APWPlaneWaveBasisSet(cutoff_energy=500 * ureg('eV'))
pw.set_cutoff_fractional(None, logger)
assert pw.cutoff_fractional is None

# cutoff_fractional already set
pw = APWPlaneWaveBasisSet(cutoff_energy=500 * ureg('eV'), cutoff_fractional=1)
pw.set_cutoff_fractional(ureg.angstrom, logger)
assert pw.cutoff_fractional == 1

1 comment on commit c26c547

@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__.py14286%53–55
   atoms_state.py1902189%31–33, 219–222, 246, 301–302, 370–371, 373, 555, 567–568, 629–633, 648–652, 659
   basis_set.py1526855%14, 88, 94–95, 149, 216–218, 272–276, 306–324, 327–329, 366–369, 372, 403–418, 424–429, 432–445
   general.py75791%29–30, 98, 162, 272–273, 283
   model_method.py2657771%28–30, 189–192, 195–202, 294–295, 315, 336–355, 371–397, 400–417, 771, 782, 824–831, 869, 888, 968, 1025, 1100, 1214
   model_system.py2612292%43–45, 520–523, 570–577, 751–752, 973–977, 983–984, 992–993, 998, 1021
   numerical_settings.py2596276%30–32, 165, 235, 237–238, 241–244, 248–249, 256–259, 268–271, 275–278, 280–283, 288–291, 297–300, 484–511, 586, 621–624, 648, 651, 696, 698–701, 705, 709, 756, 760–781, 836–837, 904
   outputs.py1151091%27–28, 247–250, 290–293, 318, 320, 357, 376
   physical_property.py102793%38–40, 220, 349–351
   variables.py651183%26–28, 116, 139, 159–160, 163, 185, 208, 228
src/nomad_simulations/schema_packages/properties
   band_gap.py51590%26–28, 153–154
   band_structure.py1112280%27–29, 249–282, 295, 302, 338–339, 342
   energies.py36975%25–27, 54, 75, 100, 121, 131, 140
   fermi_surface.py17476%25–27, 58
   forces.py22673%26–28, 55, 75, 98
   hopping_matrix.py29583%25–27, 75, 110
   permittivity.py48883%25–27, 115–123
   spectral_profile.py25612452%27–29, 75–78, 113–116, 217–318, 374–386, 411–414, 434, 439–442, 484–520, 544, 591–594, 610–611, 616–622
   thermodynamics.py751876%25–27, 53, 74, 90, 99, 108, 119, 128, 155, 165, 175, 195, 211, 236, 252, 277
src/nomad_simulations/schema_packages/utils
   utils.py681479%26–29, 79–88, 97–98, 103, 106
TOTAL223650677% 

Tests Skipped Failures Errors Time
323 0 💤 28 ❌ 0 🔥 6.022s ⏱️

Please sign in to comment.