Commit 63874e7c authored by Lauri Himanen's avatar Lauri Himanen
Browse files

Added a few phonon properties, disabled phonon method detection for now.

parent beb68ec0
Pipeline #73784 passed with stages
in 34 minutes and 52 seconds
......@@ -23,7 +23,7 @@ import numpy as np
from scipy.spatial import Voronoi # pylint: disable=no-name-in-module
from matid.symmetry import WyckoffSet
from nomad.normalizing.data.aflow_prototypes import aflow_prototypes
from nomad.aflow_prototypes import aflow_prototypes
from nomad.constants import atomic_masses
......
......@@ -409,7 +409,7 @@ def write_prototype_data_file(aflow_prototypes: dict, filepath) -> None:
def prototypes_update(ctx, filepath, matches_only):
if matches_only:
from nomad.normalizing.data.aflow_prototypes import aflow_prototypes
from nomad.aflow_prototypes import aflow_prototypes
else:
# The basic AFLOW prototype data is available in a Javascript file. Here we
# retrieve it and read only the prototype list from it.
......
......@@ -2,9 +2,10 @@ import numpy as np # pylint: disable=unused-import
import typing # pylint: disable=unused-import
from nomad.metainfo import ( # pylint: disable=unused-import
MSection, MCategory, Category, Package, Quantity, Section, SubSection, SectionProxy,
Reference, MEnum
Reference, MEnum, derived
)
from nomad.metainfo.legacy import LegacyDefinition
import nomad.atomutils
m_package = Package(
......@@ -5157,6 +5158,30 @@ class section_thermodynamical_properties(MSection):
''',
a_legacy=LegacyDefinition(name='thermodynamical_property_heat_capacity_C_v'))
@derived(
type=np.dtype(np.float64),
shape=['number_of_thermodynamical_property_values'],
unit='joule / kelvin * kilogram',
description='''
Stores the specific heat capacity at constant volume.
''',
a_legacy=LegacyDefinition(name='specific_heat_capacity'),
cached=True
)
def specific_heat_capacity(self) -> np.array:
"""Returns the specific heat capacity by dividing the heat capacity per
cell with the mass of the atoms in the cell.
"""
s_frame_sequence = self.m_parent
first_frame = s_frame_sequence.frame_sequence_local_frames_ref[0]
system = first_frame.single_configuration_calculation_to_system_ref
atomic_numbers = system.atom_species
mass_per_unit_cell = nomad.atomutils.get_summed_atomic_mass(atomic_numbers)
heat_capacity = self.thermodynamical_property_heat_capacity_C_v
specific_heat_capacity = heat_capacity / mass_per_unit_cell
return specific_heat_capacity
thermodynamical_property_temperature = Quantity(
type=np.dtype(np.float64),
shape=['number_of_thermodynamical_property_values'],
......
import numpy as np
from elasticsearch_dsl import InnerDoc
from nomad.metainfo import MSection, Section, SubSection, Quantity, MEnum, Reference
from nomad.datamodel.metainfo.public import section_k_band, section_dos
from nomad.datamodel.metainfo.public import section_k_band, section_dos, section_thermodynamical_properties
class WyckoffVariables(MSection):
......@@ -452,6 +452,27 @@ class Properties(MSection):
Reference to an electronic density of states.
"""
)
phonon_band_structure = Quantity(
type=Reference(section_k_band.m_def),
shape=[],
description="""
Reference to a phonon band structure.
"""
)
phonon_dos = Quantity(
type=Reference(section_dos.m_def),
shape=[],
description="""
Reference to a phonon density of states.
"""
)
thermodynamical_properties = Quantity(
type=Reference(section_thermodynamical_properties.m_def),
shape=[],
description="""
Reference to a specific heat capacity.
"""
)
class section_encyclopedia(MSection):
......
# Copyright 2018 Markus Scheidgen
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an"AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
......@@ -279,14 +279,9 @@ class EncyclopediaNormalizer(Normalizer):
)
return
# Get the method type, stop if unknown
# Get the method type. For now, we allow unknown method type.
# Mostly to allow phonon calculations through.
representative_method, method_type = self.method_type(method, calc_type)
if method_type == config.services.unavailable_value:
self.logger.info(
"Unsupported method type for encyclopedia, encyclopedia metainfo not created.",
enc_status="unsupported_method_type",
)
return
# Get representative scc
try:
......
......@@ -102,20 +102,51 @@ class PropertiesNormalizer():
def has_fermi_surface(self) -> None:
pass
def has_thermal_properties(self) -> None:
pass
def phonon_dispersion(self) -> None:
pass
def phonon_dos(self) -> None:
pass
def specific_heat_cv(self) -> None:
pass
def thermodynamical_properties(self, properties: Properties) -> None:
"""Tries to resolve a reference to a representative set of
thermodynamical properties. Will not store any data if it cannot be
resolved unambiguously.
"""
try:
resolved_section = None
frame_sequences = self.backend.entry_archive.section_run[0].section_frame_sequence
for frame_sequence in frame_sequences:
thermodynamical_props = frame_sequence.section_thermodynamical_properties
for thermodynamical_prop in thermodynamical_props:
if resolved_section is None:
resolved_section = thermodynamical_prop
else:
self.logger("Could not unambiguously select data to display for specific heat.")
return
except Exception:
return
if resolved_section is not None:
properties.thermodynamical_properties = resolved_section
def helmholtz_free_energy(self) -> None:
pass
def phonon_band_structure(self, properties: Properties, context: Context) -> None:
"""Tries to resolve a reference to a representative phonon band
structure. Will not store any data if it cannot be resolved
unambiguously.
"""
try:
representative_scc = context.representative_scc
bands = representative_scc.section_k_band
if bands is None:
return
representative_phonon_band = None
for band in bands:
if band.band_structure_kind == "vibrational":
if representative_phonon_band is None:
representative_phonon_band = band
else:
self.logger("Could not unambiguously select data to display for a phonon band structure.")
return
except Exception:
return
if representative_phonon_band is not None:
properties.phonon_band_structure = representative_phonon_band
def energies(self, properties: Properties, gcd: int, representative_scc: Section) -> None:
energy_dict = {}
......@@ -152,3 +183,8 @@ class PropertiesNormalizer():
# Save metainfo
self.electronic_band_structure(properties, calc_type, material_type, context, sec_system)
self.energies(properties, gcd, representative_scc)
# Phonon calculations have a specific set of properties to extract
if context.calc_type == Calculation.calculation_type.type.phonon_calculation:
self.thermodynamical_properties(properties)
self.phonon_band_structure(properties, context)
......@@ -54,15 +54,6 @@ def test_molecular_dynamics(molecular_dynamics: EntryArchive):
assert calc_type == "molecular dynamics"
# Disabled until the method information can be retrieved
# def test_phonon(phonon: EntryArchive):
# """Tests that geometry optimizations are correctly processed."
# """
# enc = phonon.get_mi2_section(Encyclopedia.m_def)
# calc_type = enc.calc_type.calc_type
# assert calc_type == "phonon calculation"
def test_1d_metainfo(one_d: EntryArchive):
"""Tests that metainfo for 1D systems is correctly processed.
"""
......@@ -476,3 +467,29 @@ def test_hashes_undefined(hash_vasp):
# not really need the method to be accurately defined.
assert method_hash is None
assert group_eos_hash is None
def test_phonon(phonon: EntryArchive):
"""Tests that phonon calculations are correctly processed.
"""
enc = phonon.entry_archive.section_encyclopedia
calc_type = enc.calculation.calculation_type
prop = enc.properties
band = prop.phonon_band_structure
thermo_props = prop.thermodynamical_properties
assert calc_type == "phonon calculation"
# Check band structure
assert band is not None
assert band.band_structure_kind == "vibrational"
for segment in band.section_k_band_segment:
assert segment.band_energies is not None
assert segment.band_k_points is not None
assert segment.band_segm_labels is not None
# Check thermodynamical properties
assert thermo_props is not None
assert thermo_props.thermodynamical_property_heat_capacity_C_v is not None
assert thermo_props.specific_heat_capacity is not None
assert thermo_props.thermodynamical_property_temperature is not None
assert thermo_props.vibrational_free_energy_at_constant_volume is not None
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment