diff --git a/nomad/cli/dev.py b/nomad/cli/dev.py index 2494ae42b64d93f2e220dc687c08b1a064bf2940..82a73709e7f63eca511bd44b9fcc47cbd9fe2457 100644 --- a/nomad/cli/dev.py +++ b/nomad/cli/dev.py @@ -42,3 +42,12 @@ def qa(skip_tests: bool, exitfirst: bool): ret_code += os.system('python -m mypy --ignore-missing-imports --follow-imports=silent --no-strict-optional nomad tests') sys.exit(ret_code) + + +@dev.command(help='Generates source-code for the new metainfo from .json files of the old.') +@click.argument('package', nargs=1) +def legacy_metainfo(package): + from nomad.metainfo.legacy import convert, generate_metainfo_code + + env = convert(package) + generate_metainfo_code(env) diff --git a/nomad/cli/parse.py b/nomad/cli/parse.py index e1b7e2206fab9e240ab3ce8f07de25f0736e3cc6..a1433f11950e4ff434dc4e05d59ce6058b29b2fa 100644 --- a/nomad/cli/parse.py +++ b/nomad/cli/parse.py @@ -119,6 +119,11 @@ def _parse( if metainfo: def backend_factory(env, logger): + # from vaspparser.metainfo import m_env + # from nomad.metainfo import Section + # m_env.resolve_definition('section_basis_set_atom_centered', Section) + # return MetainfoBackend(m_env, logger=logger) + return MetainfoBackend(convert(env), logger=logger) kwargs.update(backend_factory=backend_factory) diff --git a/nomad/datamodel/metainfo/__init__.py b/nomad/datamodel/metainfo/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ca3964e9949df137a0beafd4034c74e304c4c2bf --- /dev/null +++ b/nomad/datamodel/metainfo/__init__.py @@ -0,0 +1,11 @@ +import sys +from nomad.metainfo import Environment +from nomad.metainfo.legacy import LegacyMetainfoEnvironment +import nomad.datamodel.metainfo.common +import nomad.datamodel.metainfo.public +import nomad.datamodel.metainfo.general + +m_env = LegacyMetainfoEnvironment() +m_env.m_add_sub_section(Environment.packages, sys.modules['nomad.datamodel.metainfo.common'].m_package) # type: ignore +m_env.m_add_sub_section(Environment.packages, sys.modules['nomad.datamodel.metainfo.public'].m_package) # type: ignore +m_env.m_add_sub_section(Environment.packages, sys.modules['nomad.datamodel.metainfo.general'].m_package) # type: ignore diff --git a/nomad/datamodel/metainfo/common.py b/nomad/datamodel/metainfo/common.py new file mode 100644 index 0000000000000000000000000000000000000000..c01bbe1758f6eee2d12fedc9685780de1df59fca --- /dev/null +++ b/nomad/datamodel/metainfo/common.py @@ -0,0 +1,1190 @@ +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 +) + +from nomad.datamodel.metainfo import public + +m_package = Package(name='common', description='None') + + +class settings_atom_in_molecule(MCategory): + ''' + Parameters of an atom within a molecule. + ''' + + +class settings_constraint(MCategory): + ''' + Some parameters that describe a constraint + ''' + + +class settings_interaction(MCategory): + ''' + Some parameters that describe a bonded interaction. + ''' + + +class soap_parameter(MCategory): + ''' + A soap parameter + ''' + + +class response_context(MSection): + ''' + The top level context containing the reponse to an api query, when using jsonAPI they + are tipically in the meta part + ''' + + m_def = Section(validate=False) + + shortened_meta_info = Quantity( + type=str, + shape=[], + description=''' + A meta info whose corresponding data has been shortened + ''') + + section_response_message = SubSection( + sub_section=SectionProxy('section_response_message'), + repeats=True) + + +class section_atom_type(MSection): + ''' + Section describing a type of atom in the system. + ''' + + m_def = Section(validate=False) + + atom_type_charge = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='coulomb', + description=''' + Charge of the atom type. + ''') + + atom_type_mass = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='kilogram', + description=''' + Mass of the atom type. + ''') + + atom_type_name = Quantity( + type=str, + shape=[], + description=''' + Name (label) of the atom type. + ''') + + +class section_constraint(MSection): + ''' + Section describing a constraint between arbitrary atoms. + ''' + + m_def = Section(validate=False) + + constraint_atoms = Quantity( + type=np.dtype(np.int32), + shape=['number_of_constraints', 'number_of_atoms_per_constraint'], + description=''' + List of the indexes involved in this constraint. The fist atom has index 1, the + last number_of_topology_atoms. + ''') + + constraint_kind = Quantity( + type=str, + shape=[], + description=''' + Short and unique name for this constraint type. Valid names are described in the + [constraint\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/constraint-kind). + ''') + + constraint_parameters = Quantity( + type=typing.Any, + shape=[], + description=''' + Explicit constraint parameters for this kind of constraint (depending on the + constraint type, some might be given implicitly through other means). + ''') + + number_of_atoms_per_constraint = Quantity( + type=int, + shape=[], + description=''' + Number of atoms involved in this constraint. + ''') + + number_of_constraints = Quantity( + type=int, + shape=[], + description=''' + Number of constraints of this type. + ''') + + +class section_dft_plus_u_orbital(MSection): + ''' + Section for DFT+U-settings of a single orbital + ''' + + m_def = Section(validate=False) + + dft_plus_u_orbital_atom = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + DFT+U-orbital setting: atom index (references index of atom_labels/atom_positions) + ''') + + dft_plus_u_orbital_J = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + DFT+U-orbital setting: value J (exchange interaction) + ''', + categories=[public.energy_value]) + + dft_plus_u_orbital_label = Quantity( + type=str, + shape=[], + description=''' + DFT+U-orbital setting: orbital label (normally (n,l)), notation: '3d', '4f', ... + ''') + + dft_plus_u_orbital_U_effective = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + DFT+U-orbital setting: value U_{effective} (U-J), if implementation uses it + ''', + categories=[public.energy_value]) + + dft_plus_u_orbital_U = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + DFT+U-orbital setting: value U (on-site Coulomb interaction) + ''', + categories=[public.energy_value]) + + +class section_excited_states(MSection): + ''' + Excited states properties. + ''' + + m_def = Section(validate=False) + + excitation_energies = Quantity( + type=np.dtype(np.float64), + shape=['number_of_excited_states'], + description=''' + Excitation energies. + ''', + categories=[public.energy_value]) + + number_of_excited_states = Quantity( + type=int, + shape=[], + description=''' + Number of excited states. + ''') + + oscillator_strengths = Quantity( + type=np.dtype(np.float64), + shape=['number_of_excited_states'], + description=''' + Excited states oscillator strengths. + ''') + + transition_dipole_moments = Quantity( + type=np.dtype(np.float64), + shape=['number_of_excited_states', 3], + description=''' + Transition dipole moments. + ''') + + +class section_interaction(MSection): + ''' + Section containing the description of a bonded interaction between arbitrary atoms. + ''' + + m_def = Section(validate=False) + + interaction_atoms = Quantity( + type=np.dtype(np.int32), + shape=['number_of_interactions', 'number_of_atoms_per_interaction'], + description=''' + List of the indexes involved in this interaction. The fist atom has index 1, the + last atom index number_of_topology_atoms. + ''') + + interaction_kind = Quantity( + type=str, + shape=[], + description=''' + Short and unique name for this interaction type. Valid names are described in the + [interaction\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/interaction-kind). + ''') + + interaction_parameters = Quantity( + type=typing.Any, + shape=[], + description=''' + Explicit interaction parameters for this kind of interaction (depending on the + interaction_kind some might be given implicitly through other means). + ''') + + number_of_atoms_per_interaction = Quantity( + type=int, + shape=[], + description=''' + Number of atoms involved in this interaction. + ''') + + number_of_interactions = Quantity( + type=int, + shape=[], + description=''' + Number of interactions of this type. + ''') + + +class section_method_basis_set(MSection): + ''' + This section contains the definition of the basis sets that are defined independently + of the atomic configuration. + ''' + + m_def = Section(validate=False) + + mapping_section_method_basis_set_atom_centered = Quantity( + type=np.dtype(np.int64), + shape=['number_of_basis_sets_atom_centered', 2], + description=''' + Reference to an atom-centered basis set defined in section_basis_set_atom_centered + and to the atom kind as defined in section_method_atom_kind. + ''') + + mapping_section_method_basis_set_cell_associated = Quantity( + type=public.section_basis_set_cell_dependent, + shape=[], + description=''' + Reference to a cell-associated basis set. + ''') + + method_basis_set_kind = Quantity( + type=str, + shape=[], + description=''' + String describing the use of the basis set, i.e, if it used for expanding a + wavefunction or an electron density. Allowed values are listed in the + [basis\\_set\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/basis-set-kind). + ''') + + number_of_basis_sets_atom_centered = Quantity( + type=int, + shape=[], + description=''' + String describing the use of the basis set, i.e, if it used for expanding a + wavefunction or an electron density. Allowed values are listed in the + [basis\\_set\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/basis-set-kind). + ''') + + +class section_molecule_constraint(MSection): + ''' + Section describing a constraint between atoms within a molecule. + ''' + + m_def = Section(validate=False) + + molecule_constraint_atoms = Quantity( + type=np.dtype(np.int32), + shape=['number_of_molecule_constraints', 'number_of_atoms_per_molecule_constraint'], + description=''' + List of the indexes involved in this constraint. The fist atom has index 1, the + last index is number_of_atoms_in_molecule. + ''') + + molecule_constraint_kind = Quantity( + type=str, + shape=[], + description=''' + Short and unique name for this constraint type. Valid names are described in the + [constraint\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/constraint-kind). + ''') + + molecule_constraint_parameters = Quantity( + type=typing.Any, + shape=[], + description=''' + Explicit constraint parameters for this kind of constraint (depending on the + constraint type some might be given implicitly through other means). + ''') + + number_of_atoms_per_molecule_constraint = Quantity( + type=int, + shape=[], + description=''' + Number of atoms, in this molecule, involved in this constraint. + ''') + + number_of_molecule_constraints = Quantity( + type=int, + shape=[], + description=''' + Number of constraints of this type. + ''') + + +class section_molecule_interaction(MSection): + ''' + Section describing a bonded interaction between atoms within a molecule. + ''' + + m_def = Section(validate=False) + + molecule_interaction_atoms = Quantity( + type=np.dtype(np.int32), + shape=['number_of_molecule_interactions', 'number_of_atoms_per_molecule_interaction'], + description=''' + List of the indexes involved in this bonded interaction within a molecule. The + first atom has index 1, the last index is number_of_atoms_in_. + ''') + + molecule_interaction_kind = Quantity( + type=str, + shape=[], + description=''' + Short and unique name for this interaction type, used for bonded interactions for + atoms in a molecule. Valid names are described in the [interaction\\_kind wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/interaction-kind). + ''') + + molecule_interaction_parameters = Quantity( + type=typing.Any, + shape=[], + description=''' + Explicit interaction parameters for this kind of interaction (depending on the + interaction type some might be given implicitly through other means), used for + bonded interactions for atoms in a molecule. + ''') + + number_of_atoms_per_molecule_interaction = Quantity( + type=int, + shape=[], + description=''' + Number of atoms, in this molecule, involved in this interaction. + ''') + + number_of_molecule_interactions = Quantity( + type=int, + shape=[], + description=''' + Number of bonded interactions of this type. + ''') + + +class section_molecule_type(MSection): + ''' + Section describing a type of molecule in the system. + ''' + + m_def = Section(validate=False) + + atom_in_molecule_charge = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms_in_molecule'], + unit='coulomb', + description=''' + Charge of each atom in the molecule. + ''', + categories=[settings_atom_in_molecule]) + + atom_in_molecule_name = Quantity( + type=str, + shape=['number_of_atoms_in_molecule'], + description=''' + Name (label) of each atom in the molecule. + ''', + categories=[settings_atom_in_molecule]) + + atom_in_molecule_to_atom_type_ref = Quantity( + type=Reference(SectionProxy('section_atom_type')), + shape=['number_of_atoms_in_molecule'], + description=''' + Reference to the atom type of each atom in the molecule. + ''', + categories=[settings_atom_in_molecule]) + + molecule_type_name = Quantity( + type=str, + shape=[], + description=''' + Name of the molecule. + ''') + + number_of_atoms_in_molecule = Quantity( + type=int, + shape=[], + description=''' + Number of atoms in this molecule. + ''') + + section_molecule_constraint = SubSection( + sub_section=SectionProxy('section_molecule_constraint'), + repeats=True) + + section_molecule_interaction = SubSection( + sub_section=SectionProxy('section_molecule_interaction'), + repeats=True) + + +class section_response_message(MSection): + ''' + Messages outputted by the program formatting the data in the current response + ''' + + m_def = Section(validate=False) + + response_message_count = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + How many times this message was repeated + ''') + + response_message_level = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + level of the message: 0 fatal, 1 error, 2 warning, 3 debug + ''') + + response_message = Quantity( + type=str, + shape=[], + description=''' + Message outputted by the program formatting the data in the current format + ''') + + +class section_soap_coefficients(MSection): + ''' + Stores the soap coefficients for the pair of atoms given in + soap_coefficients_atom_pair. + ''' + + m_def = Section(validate=False) + + number_of_soap_coefficients = Quantity( + type=int, + shape=[], + description=''' + number of soap coefficients + ''') + + soap_coefficients_atom_pair = Quantity( + type=str, + shape=[], + description=''' + Pair of atoms described in the current section + ''') + + soap_coefficients = Quantity( + type=np.dtype(np.float64), + shape=['number_of_soap_coefficients'], + description=''' + Compressed coefficient of the soap descriptor for the atom pair + soap_coefficients_atom_pair + ''') + + +class section_soap(MSection): + ''' + Stores a soap descriptor for this configuration. + ''' + + m_def = Section(validate=False) + + soap_angular_basis_L = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + angular basis L + ''', + categories=[soap_parameter]) + + soap_angular_basis_type = Quantity( + type=str, + shape=[], + description=''' + angular basis type + ''', + categories=[soap_parameter]) + + soap_kernel_adaptor = Quantity( + type=str, + shape=[], + description=''' + kernel adaptor + ''', + categories=[soap_parameter]) + + soap_parameters_gid = Quantity( + type=str, + shape=[], + description=''' + Unique checksum of all the soap parameters (all those with abstract type + soap_parameter) with prefix psoap + ''') + + soap_radial_basis_integration_steps = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + radial basis integration steps + ''', + categories=[soap_parameter]) + + soap_radial_basis_mode = Quantity( + type=str, + shape=[], + description=''' + radial basis mode + ''', + categories=[soap_parameter]) + + soap_radial_basis_n = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + radial basis N + ''', + categories=[soap_parameter]) + + soap_radial_basis_sigma = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + radial basis sigma + ''', + categories=[soap_parameter]) + + soap_radial_basis_type = Quantity( + type=str, + shape=[], + description=''' + radial basis type + ''', + categories=[soap_parameter]) + + soap_radial_cutoff_center_weight = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + radial cutoff center weight + ''', + categories=[soap_parameter]) + + soap_radial_cutoff_rc_width = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + radial cutoff width + ''', + categories=[soap_parameter]) + + soap_radial_cutoff_rc = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + radial cutoff + ''', + categories=[soap_parameter]) + + soap_radial_cutoff_type = Quantity( + type=str, + shape=[], + description=''' + radial cutoff type + ''', + categories=[soap_parameter]) + + soap_spectrum_2l1_norm = Quantity( + type=bool, + shape=[], + description=''' + 2l1 norm spectrum + ''', + categories=[soap_parameter]) + + soap_spectrum_global = Quantity( + type=bool, + shape=[], + description=''' + global spectrum + ''', + categories=[soap_parameter]) + + soap_spectrum_gradients = Quantity( + type=bool, + shape=[], + description=''' + gradients in specturm + ''', + categories=[soap_parameter]) + + soap_type_list = Quantity( + type=str, + shape=[], + description=''' + Type list + ''', + categories=[soap_parameter]) + + section_soap_coefficients = SubSection( + sub_section=SectionProxy('section_soap_coefficients'), + repeats=True) + + +class section_topology(MSection): + ''' + Section containing the definition of topology (connectivity among atoms in force + fileds), force field, and constraints of a system. + ''' + + m_def = Section(validate=False) + + atom_to_molecule = Quantity( + type=np.dtype(np.int32), + shape=['number_of_topology_atoms', 2], + description=''' + Table mapping atom to molecules: the first column is the index of the molecule and + the second column the index of the atom, signifying that the atom in the second + column belongs to the molecule in the first column in the same row. + ''') + + molecule_to_molecule_type_map = Quantity( + type=Reference(SectionProxy('section_molecule_type')), + shape=['number_of_topology_molecules'], + description=''' + Mapping from molecules to molecule types. + ''') + + number_of_topology_atoms = Quantity( + type=int, + shape=[], + description=''' + Number of atoms in the system described by this topology. + ''') + + number_of_topology_molecules = Quantity( + type=int, + shape=[], + description=''' + Number of molecules in the system, as described by this topology. + ''') + + topology_force_field_name = Quantity( + type=str, + shape=[], + description=''' + A unique string idenfiying the force field defined in this section. Strategies to + define it are discussed in the + [topology\\_force\\_field\\_name](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/topology-force-field-name). + ''') + + section_atom_type = SubSection( + sub_section=SectionProxy('section_atom_type'), + repeats=True) + + section_constraint = SubSection( + sub_section=SectionProxy('section_constraint'), + repeats=True) + + section_interaction = SubSection( + sub_section=SectionProxy('section_interaction'), + repeats=True) + + section_molecule_type = SubSection( + sub_section=SectionProxy('section_molecule_type'), + repeats=True) + + +class section_method(public.section_method): + + m_def = Section(validate=False, extends_base_section=True) + + dft_plus_u_functional = Quantity( + type=str, + shape=[], + description=''' + Type of DFT+U functional (such as DFT/DFT+U double-counting compensation). Valid + names are described in the [dft\\_plus\\_u\\_functional wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/dft- + plus-u-functional). + ''') + + dft_plus_u_projection_type = Quantity( + type=str, + shape=[], + description=''' + DFT+U: Type of orbitals used for projection in order to calculate occupation + numbers. Valid names are described in the [dft\\_plus\\_u\\_projection\\_type wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/dft- + plus-u-projection-type). + ''') + + gw_bare_coulomb_cutofftype = Quantity( + type=str, + shape=[], + description=''' + Cutoff type for the calculation of the bare Coulomb potential: none, 0d, 1d, 2d. + See Rozzi et al., PRB 73, 205119 (2006) + ''') + + gw_bare_coulomb_gmax = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='1 / meter', + description=''' + Maximum G for the pw basis for the Coulomb potential. + ''') + + gw_basis_set = Quantity( + type=str, + shape=[], + description=''' + Auxillary basis set used for non-local operators: mixed - mixed basis set, Kotani + and Schilfgaarde, Solid State Comm. 121, 461 (2002). + ''') + + gw_core_treatment = Quantity( + type=str, + shape=[], + description=''' + It specifies whether the core states are treated in the GW calculation: all - All + electron calculation; val - Valence electron only calculation; vab - Core + electrons are excluded from the mixed product basis; xal - All electron treatment + of the exchange self-energy only + ''') + + gw_frequency_grid_type = Quantity( + type=str, + shape=[], + description=''' + Frequency integration grid type for the correlational self energy: 'eqdis' - + equidistant frequencies from 0 to freqmax; 'gaulag' - Gauss-Laguerre quadrature + from 0 to infinity; 'gauleg' - Gauss-Legendre quadrature from 0 to freqmax; + 'gaule2' (default) - double Gauss-Legendre quadrature from 0 to freqmax and from + freqmax to infinity. + ''') + + gw_max_frequency = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Maximum frequency for the calculation of the self energy. + ''') + + gw_mixed_basis_gmax = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='1 / meter', + description=''' + Cut-off parameter for the truncation of the expansion of the plane waves in the + interstitial region. + ''') + + gw_mixed_basis_lmax = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Maximum l value used for the radial functions within the muffin-tin. + ''') + + gw_mixed_basis_tolerance = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Eigenvalue threshold below which the egenvectors are discarded in the construction + of the radial basis set. + ''') + + gw_ngridq = Quantity( + type=np.dtype(np.int32), + shape=[3], + description=''' + k/q-point grid size used in the GW calculation. + ''') + + gw_frequency_number = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Number referring to the frequency used in the calculation of the self energy. + ''') + + gw_frequency_values = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Values of the frequency used in the calculation of the self energy. + ''') + + gw_frequency_weights = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Weights of the frequency used in the calculation of the self energy. + ''') + + gw_number_of_frequencies = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Number of frequency points used in the calculation of the self energy. + ''') + + gw_polarizability_number_of_empty_states = Quantity( + type=int, + shape=[], + description=''' + Number of empty states used to compute the polarizability P + ''') + + gw_qp_equation_treatment = Quantity( + type=str, + shape=[], + description=''' + Methods to solve the quasi-particle equation: 'linearization', 'self-consistent' + ''') + + gw_screened_coulomb_volume_average = Quantity( + type=str, + shape=[], + description=''' + Type of volume averaging for the dynamically screened Coulomb potential: isotropic + - Simple averaging along a specified direction using only diagonal components of + the dielectric tensor; anisotropic - Anisotropic screening by C. Freysoldt et al., + CPC 176, 1-13 (2007) + ''') + + gw_screened_Coulomb = Quantity( + type=str, + shape=[], + description=''' + Model used to calculate the dinamically-screened Coulomb potential: 'rpa' - Full- + frequency random-phase approximation; 'ppm' - Godby-Needs plasmon-pole model Godby + and Needs, Phys. Rev. Lett. 62, 1169 (1989); 'ppm_hl' - Hybertsen and Louie, Phys. + Rev. B 34, 5390 (1986); 'ppm_lh' - von der Linden and P. Horsh, Phys. Rev. B 37, + 8351 (1988); 'ppm_fe' - Farid and Engel, Phys. Rev. B 47,15931 (1993); 'cdm' - + Contour deformation method, Phys. Rev. B 67, 155208 (2003).) + ''') + + gw_self_energy_c_analytical_continuation = Quantity( + type=str, + shape=[], + description=''' + Models for the correlation self-energy analytical continuation: 'pade' - Pade's + approximant (by H. J. Vidberg and J. W. Serence, J. Low Temp. Phys. 29, 179 + (1977)); 'mpf' - Multi-Pole Fitting (by H. N Rojas, R. W. Godby and R. J. Needs, + Phys. Rev. Lett. 74, 1827 (1995)); 'cd' - contour deformation; 'ra' - real axis + ''') + + gw_self_energy_c_number_of_empty_states = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Number of empty states to be used to calculate the correlation self energy. + ''') + + gw_self_energy_c_number_of_poles = Quantity( + type=int, + shape=[], + description=''' + Number of poles used in the analytical continuation. + ''') + + gw_self_energy_singularity_treatment = Quantity( + type=str, + shape=[], + description=''' + Treatment of the integrable singular terms in the calculation of the self energy. + Values: 'mpb' - Auxiliary function method by S. Massidda, M. Posternak, and A. + Baldereschi, PRB 48, 5058 (1993); 'crg' - Auxiliary function method by P. Carrier, + S. Rohra, and A. Goerling, PRB 75, 205126 (2007). + ''') + + gw_starting_point = Quantity( + type=str, + shape=[], + description=''' + Exchange-correlation functional of the ground-state calculation. See XC_functional + list at https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/XC- + functional + ''') + + gw_type_test = Quantity( + type=str, + shape=[], + description=''' + GW methodology: exciting test variable + ''') + + gw_type = Quantity( + type=str, + shape=[], + description=''' + GW methodology: G0W0; ev-scGW: (eigenvalues self-consistent GW) – Phys.Rev.B 34, + 5390 (1986); qp-scGW: (quasi-particle self-consistent GW) – Phys. Rev. Lett. 96, + 226402 (2006) scGW0: (self-consistent G with fixed W0) – Phys.Rev.B 54, 8411 + (1996); scG0W: (self-consistent W with fixed G0); scGW: (self-consistent GW) – + Phys. Rev. B 88, 075105 (2013) + ''') + + method_to_topology_ref = Quantity( + type=Reference(SectionProxy('section_topology')), + shape=[], + description=''' + Reference to the topology and force fields to be used. + ''') + + section_dft_plus_u_orbital = SubSection( + sub_section=SectionProxy('section_dft_plus_u_orbital'), + repeats=True) + + section_method_basis_set = SubSection( + sub_section=SectionProxy('section_method_basis_set'), + repeats=True) + + +class section_single_configuration_calculation(public.section_single_configuration_calculation): + + m_def = Section(validate=False, extends_base_section=True) + + energy_C_mGGA = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Component of the correlation (C) energy at the GGA (or MetaGGA) level using the + self-consistent density of the target XC functional (full unscaled value, i.e., + not scaled due to exact-exchange mixing). + ''', + categories=[public.energy_value, public.energy_type_C, public.energy_component]) + + energy_reference_fermi = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + unit='joule', + description=''' + Fermi energy (separates occupied from unoccupied single-particle states in metals) + ''', + categories=[public.energy_type_reference, public.energy_value]) + + energy_reference_highest_occupied = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + unit='joule', + description=''' + Highest occupied single-particle state energy (in insulators or HOMO energy in + finite systems) + ''', + categories=[public.energy_type_reference, public.energy_value]) + + energy_reference_lowest_unoccupied = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + unit='joule', + description=''' + Lowest unoccupied single-particle state energy (in insulators or LUMO energy in + finite systems) + ''', + categories=[public.energy_type_reference, public.energy_value]) + + energy_X_mGGA_scaled = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Component of the exchange (X) energy at the GGA (or MetaGGA) level, using the self + consistent density of the target functional, scaled accordingly to the mixing + parameter. + ''', + categories=[public.energy_value, public.energy_component]) + + energy_X_mGGA = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Component of the exchange (X) energy at the GGA (or MetaGGA) level using the self + consistent density of the target functional (full unscaled value, i.e., not scaled + due to exact-exchange mixing). + ''', + categories=[public.energy_type_X, public.energy_value, public.energy_component]) + + gw_fermi_energy = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + GW Fermi energy + ''') + + gw_fundamental_gap = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + GW fundamental band gap + ''') + + gw_optical_gap = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + GW optical band gap + ''') + + gw_self_energy_c = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], + unit='joule', + description=''' + Diagonal matrix elements of the correlation self-energy + ''') + + gw_self_energy_x = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], + unit='joule', + description=''' + Diagonal matrix elements of the exchange self-energy + ''') + + gw_xc_potential = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], + unit='joule', + description=''' + Diagonal matrix elements of the exchange-correlation potential + ''') + + section_excited_states = SubSection( + sub_section=SectionProxy('section_excited_states'), + repeats=True) + + +class section_scf_iteration(public.section_scf_iteration): + + m_def = Section(validate=False, extends_base_section=True) + + energy_reference_fermi_iteration = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + unit='joule', + description=''' + Fermi energy (separates occupied from unoccupied single-particle states in metals) + during the self-consistent field (SCF) iterations. + ''', + categories=[public.energy_type_reference, public.energy_value]) + + energy_reference_highest_occupied_iteration = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + unit='joule', + description=''' + Highest occupied single-particle state energy (in insulators or HOMO energy in + finite systems) during the self-consistent field (SCF) iterations. + ''', + categories=[public.energy_type_reference, public.energy_value]) + + energy_reference_lowest_unoccupied_iteration = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + unit='joule', + description=''' + Lowest unoccupied single-particle state energy (in insulators or LUMO energy in + finite systems) during the self-consistent field (SCF) iterations. + ''', + categories=[public.energy_type_reference, public.energy_value]) + + +class section_eigenvalues(public.section_eigenvalues): + + m_def = Section(validate=False, extends_base_section=True) + + gw_qp_linearization_prefactor = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], + description=''' + Linearization prefactor + ''') + + +class section_system(public.section_system): + + m_def = Section(validate=False, extends_base_section=True) + + number_of_electrons = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + description=''' + Number of electrons in system + ''', + categories=[public.configuration_core]) + + topology_ref = Quantity( + type=Reference(SectionProxy('section_topology')), + shape=[], + description=''' + Reference to the topology used for this system; if not given, the trivial topology + should be assumed. + ''') + + is_representative = Quantity( + type=bool, + shape=[], + description=''' + Most systems in a run are only minor variations of each other. Systems marked + representative where chosen to be representative for all systems in the run. + ''') + + section_soap = SubSection( + sub_section=SectionProxy('section_soap'), + repeats=True) + + +class section_run(public.section_run): + + m_def = Section(validate=False, extends_base_section=True) + + section_topology = SubSection( + sub_section=SectionProxy('section_topology'), + repeats=True) + + +m_package.__init_metainfo__() diff --git a/nomad/datamodel/metainfo/general.py b/nomad/datamodel/metainfo/general.py new file mode 100644 index 0000000000000000000000000000000000000000..bbb8dda361553f4485dace53b8c67d1e60fce48d --- /dev/null +++ b/nomad/datamodel/metainfo/general.py @@ -0,0 +1,141 @@ +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 +) + + +m_package = Package(name='general', description='None') + + +class section_entry_info(MSection): + ''' + General information about this entry that is independent from its domain, field, or + used parser + ''' + + m_def = Section(validate=False) + + entry_upload_time = Quantity( + type=np.dtype(np.int64), + shape=[], + description=''' + Upload datetime, given as total number of seconds is the elapsed since the unix + epoch (1 January 1970) + ''') + + entry_uploader_name = Quantity( + type=str, + shape=[], + description=''' + Name of the uploader, given as lastname, firstname. + ''') + + entry_uploader_id = Quantity( + type=str, + shape=[], + description=''' + The id of the uploader. + ''') + + upload_id = Quantity( + type=str, + shape=[], + description=''' + Nomad upload id + ''') + + calc_id = Quantity( + type=str, + shape=[], + description=''' + Nomad calc id. + ''') + + calc_hash = Quantity( + type=str, + shape=[], + description=''' + Calculation hash based on raw file contents. + ''') + + mainfile = Quantity( + type=str, + shape=[], + description=''' + Path to the main file within the upload. + ''') + + parser_name = Quantity( + type=str, + shape=[], + description=''' + Name of the parser used to extract this information. + ''') + + filepaths = Quantity( + type=str, + shape=['number_of_files'], + description=''' + Filepaths of files that belong to this entry, i.e. files in the same directory. + Filepaths are relative to the upload. + ''') + + number_of_files = Quantity( + type=int, + shape=[], + description=''' + Number of files that belong to this entry. + ''') + + section_archive_processing_info = SubSection( + sub_section=SectionProxy('section_archive_processing_info'), + repeats=True) + + +class section_archive_processing_info(MSection): + ''' + Information about the used archive processing steps and their execution. + ''' + + m_def = Section(validate=False) + + archive_processor_name = Quantity( + type=str, + shape=[], + description=''' + Name of the applied archive processing program. + ''') + + archive_processor_error = Quantity( + type=str, + shape=[], + description=''' + The main error during execution of the archive processing program that failed the + program. + ''') + + number_of_archive_processor_warnings = Quantity( + type=int, + shape=[], + description=''' + Number of warnings during execution of the archive processing program. + ''') + + archive_processor_warnings = Quantity( + type=str, + shape=['number_of_archive_processor_warnings'], + description=''' + Warnings during execution of the archive processing program. + ''') + + archive_processor_status = Quantity( + type=str, + shape=[], + description=''' + Status returned by archive processing program. + ''') + + +m_package.__init_metainfo__() diff --git a/nomad/datamodel/metainfo/public.py b/nomad/datamodel/metainfo/public.py new file mode 100644 index 0000000000000000000000000000000000000000..f58404cf1c9eceb0fc437594df2741e861454fc6 --- /dev/null +++ b/nomad/datamodel/metainfo/public.py @@ -0,0 +1,4747 @@ +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 +) + + +m_package = Package(name='public', description='None') + + +class accessory_info(MCategory): + ''' + Information that *in theory* should not affect the results of the calculations (e.g., + timing). + ''' + + +class atom_forces_type(MCategory): + ''' + The types of forces acting on the atoms (i.e., minus derivatives of the specific type + of energy with respect to the atom position). + ''' + + +class basis_set_description(MCategory): + ''' + One of the parts building the basis set of the system (e.g., some atom-centered basis + set, plane-waves or both). + ''' + + +class configuration_core(MCategory): + ''' + Properties defining the current configuration. + ''' + + +class conserved_quantity(MCategory): + ''' + A quantity that is preserved during the time propagation (for example, + kinetic+potential energy during NVE). + ''' + + +class energy_component_per_atom(MCategory): + ''' + A value of an energy component per atom, concurring in defining the total energy per + atom. + ''' + + +class energy_component(MCategory): + ''' + A value of an energy component, expected to be an extensive property. + ''' + + +class energy_total_potential_per_atom(MCategory): + ''' + A value of the total potential energy per atom. Note that a direct comparison may not + be possible because of a difference in the methods for computing total energies and + numerical implementations of various codes might leads to different energy zeros (see + section_energy_code_independent for a code-independent definition of the energy). + ''' + + +class energy_total_potential(MCategory): + ''' + A value of the total potential energy. Note that a direct comparison may not be + possible because of a difference in the methods for computing total energies and + numerical implementations of various codes might leads to different energy zeros (see + section_energy_code_independent for a code-independent definition of the energy). + ''' + + +class energy_type_C(MCategory): + ''' + This metadata stores the correlation (C) energy. + ''' + + +class energy_type_reference(MCategory): + ''' + This metadata stores an energy used as reference point. + ''' + + +class energy_type_van_der_Waals(MCategory): + ''' + This metadata stores the converged van der Waals energy. + ''' + + +class energy_type_XC(MCategory): + ''' + This metadata stores the exchange-correlation (XC) energy. + ''' + + +class energy_type_X(MCategory): + ''' + This metadata stores the exchange (X) energy. + ''' + + +class energy_value(MCategory): + ''' + This metadata stores an energy value. + ''' + + +class error_estimate_contribution(MCategory): + ''' + An estimate of a partial quantity contributing to the error for a given quantity. + ''' + + +class error_estimate(MCategory): + ''' + An estimate of the error on the converged (final) value. + ''' + + +class message_debug(MCategory): + ''' + A debugging message of the computational program. + ''' + + +class message_error(MCategory): + ''' + An error message of the computational program. + ''' + + +class message_info(MCategory): + ''' + An information message of the computational program. + ''' + + +class message_warning(MCategory): + ''' + A warning message of the computational program. + ''' + + +class parallelization_info(MCategory): + ''' + Contains information on the parallelization of the program, i.e. which parallel + programming language was used and its version, how many cores had been working on the + calculation and the flags and parameters needed to run the parallelization of the + code. + ''' + + +class parsing_message_debug(MCategory): + ''' + This field is used for debugging messages of the parsing program. + ''' + + +class parsing_message_error(MCategory): + ''' + This field is used for error messages of the parsing program. + ''' + + +class parsing_message_info(MCategory): + ''' + This field is used for info messages of the parsing program. + ''' + + +class parsing_message_warning(MCategory): + ''' + This field is used for warning messages of the parsing program. + ''' + + +class program_info(MCategory): + ''' + Contains information on the program that generated the data, i.e. the program_name, + program_version, program_compilation_host and program_compilation_datetime as direct + children of this field. + ''' + + +class scf_info(MCategory): + ''' + Contains information on the self-consistent field (SCF) procedure, i.e. the number of + SCF iterations (number_of_scf_iterations) or a section_scf_iteration section with + detailed information on the SCF procedure of specified quantities. + ''' + + +class settings_barostat(MCategory): + ''' + Contains parameters controlling the barostat in a molecular dynamics calculation. + ''' + + +class settings_coupled_cluster(MCategory): + ''' + Contains parameters for the coupled-cluster method (CC) in the post Hartree-Fock step. + ''' + + +class settings_geometry_optimization(MCategory): + ''' + Contains parameters controlling the geometry optimization. + ''' + + +class settings_GW(MCategory): + ''' + Contains parameters for the GW-method in the post Hartree-Fock step, that expands the + self-energy in terms of the single particle Green's function $G$ and the screened + Coulomb interaction $W$. + ''' + + +class settings_integrator(MCategory): + ''' + Contains parameters that control the molecular dynamics (MD) integrator. + ''' + + +class settings_k_points(MCategory): + ''' + Contains parameters that control the $k$-point mesh. + ''' + + +class settings_MCSCF(MCategory): + ''' + Contains parameters for the multi-configurational self-consistent-field (MCSCF) + method. + ''' + + +class settings_metadynamics(MCategory): + ''' + Contains parameters that control the metadynamics sampling. + ''' + + +class settings_molecular_dynamics(MCategory): + ''' + Contains parameters that control the molecular dynamics sampling. + ''' + + +class settings_moller_plesset_perturbation_theory(MCategory): + ''' + Contains parameters for Møller–Plesset perturbation theory. + ''' + + +class settings_Monte_Carlo(MCategory): + ''' + Contains parameters that control the Monte-Carlo sampling. + ''' + + +class settings_multi_reference(MCategory): + ''' + Contains parameters for the multi-reference single and double configuration + interaction method. + ''' + + +class settings_numerical_parameter(MCategory): + ''' + A parameter that can influence the convergence, but not the physics (unlike + settings_physical_parameter) + ''' + + +class settings_physical_parameter(MCategory): + ''' + A parameter that defines the physical model used. Use settings_numerical_parameter for + parameters that that influence only the convergence/accuracy. + ''' + + +class settings_post_hartree_fock(MCategory): + ''' + Contains parameters for the post Hartree-Fock method. + ''' + + +class settings_potential_energy_surface(MCategory): + ''' + Contains parameters that control the potential energy surface. + ''' + + +class settings_relativity(MCategory): + ''' + Contains parameters and information connected with the relativistic treatment used in + the calculation. + ''' + + +class settings_run(MCategory): + ''' + Contains parameters that control the whole run (but not the *single configuration + calculation*, see section_single_configuration_calculation). + ''' + + +class settings_sampling(MCategory): + ''' + Contains parameters controlling the sampling. + ''' + + +class settings_scf(MCategory): + ''' + Contains parameters connected with the convergence of the self-consistent field (SCF) + iterations. + ''' + + +class settings_self_interaction_correction(MCategory): + ''' + Contains parameters and information connected with the self-interaction correction + (SIC) method being used in self_interaction_correction_method. + ''' + + +class settings_smearing(MCategory): + ''' + Contain parameters that control the smearing of the orbital occupation at finite + electronic temperatures. + ''' + + +class settings_stress_tensor(MCategory): + ''' + Settings to calculate the stress tensor (stress_tensor) consistent with the total + energy of the system given in energy_total. + ''' + + +class settings_thermostat(MCategory): + ''' + Contains parameters that control the thermostat in the molecular dynamics (MD) + calculations. + ''' + + +class settings_van_der_Waals(MCategory): + ''' + Contain parameters and information connected with the Van der Waals treatment used in + the calculation to compute the Van der Waals energy (energy_van_der_Waals). + ''' + + +class settings_XC_functional(MCategory): + ''' + Contain parameters connected with the definition of the exchange-correlation (XC) + functional (see section_XC_functionals and XC_functional). + ''' + + +class settings_XC(MCategory): + ''' + Contains parameters connected with the definition of the exchange-correlation (XC) + *method*. Here, the term *method* is a more general concept than just *functionals* + and include, e.g., post Hartree-Fock methods, too. + ''' + + +class stress_tensor_type(MCategory): + ''' + Contains the final value of the default stress tensor (stress_tensor) and/or the value + of the stress tensor (stress_tensor_value) of the kind defined in stress_tensor_kind. + ''' + + +class time_info(MCategory): + ''' + Stores information on the date and timings of the calculation. They are useful for, + e.g., debugging or visualization purposes. + ''' + + +class archive_context(MSection): + ''' + Contains information relating to an archive. + ''' + + m_def = Section(validate=False) + + archive_gid = Quantity( + type=str, + shape=[], + description=''' + unique identifier of an archive. + ''') + + +class calculation_context(MSection): + ''' + Contains information relating to a calculation. + ''' + + m_def = Section(validate=False) + + calculation_gid = Quantity( + type=str, + shape=[], + description=''' + unique identifier of a calculation. + ''') + + +class section_atom_projected_dos(MSection): + ''' + Section collecting the information on an atom projected density of states (DOS) + evaluation. + ''' + + m_def = Section(validate=False) + + atom_projected_dos_energies = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atom_projected_dos_values'], + unit='joule', + description=''' + Array containing the set of discrete energy values for the atom-projected density + (electronic-energy) of states (DOS). + ''') + + atom_projected_dos_lm = Quantity( + type=np.dtype(np.int32), + shape=['number_of_lm_atom_projected_dos', 2], + description=''' + Tuples of $l$ and $m$ values for which atom_projected_dos_values_lm are given. For + the quantum number $l$ the conventional meaning of azimuthal quantum number is + always adopted. For the integer number $m$, besides the conventional use as + magnetic quantum number ($l+1$ integer values from $-l$ to $l$), a set of + different conventions is accepted (see the [m_kind wiki + page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/m-kind). + The adopted convention is specified by atom_projected_dos_m_kind. + ''') + + atom_projected_dos_m_kind = Quantity( + type=str, + shape=[], + description=''' + String describing what the integer numbers of $m$ in atom_projected_dos_lm mean. + The allowed values are listed in the [m_kind wiki + page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/m-kind). + ''') + + atom_projected_dos_values_lm = Quantity( + type=np.dtype(np.float64), + shape=['number_of_lm_atom_projected_dos', 'number_of_spin_channels', 'number_of_atoms', 'number_of_atom_projected_dos_values'], + description=''' + Values correspond to the number of states for a given energy (the set of discrete + energy values is given in atom_projected_dos_energies) divided into contributions + from each $l,m$ channel for the atom-projected density (electronic-energy) of + states. Here, there are as many atom-projected DOS as the number_of_atoms, the + list of labels of the atoms and their meanings are in atom_labels. + ''') + + atom_projected_dos_values_total = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_atoms', 'number_of_atom_projected_dos_values'], + description=''' + Values correspond to the number of states for a given energy (the set of discrete + energy values is given in atom_projected_dos_energies) divided into contributions + summed up over all $l$ channels for the atom-projected density (electronic-energy) + of states (DOS). Here, there are as many atom-projected DOS as the + number_of_atoms, the list of labels of the atoms and their meanings are in + atom_labels. + ''') + + number_of_atom_projected_dos_values = Quantity( + type=int, + shape=[], + description=''' + Gives the number of energy values for the atom-projected density of states (DOS) + based on atom_projected_dos_values_lm and atom_projected_dos_values_total. + ''') + + number_of_lm_atom_projected_dos = Quantity( + type=int, + shape=[], + description=''' + Gives the number of $l$, $m$ combinations for the atom projected density of states + (DOS) defined in section_atom_projected_dos. + ''') + + +class section_atomic_multipoles(MSection): + ''' + Section describing multipoles (charges/monopoles, dipoles, quadrupoles, ...) for each + atom. + ''' + + m_def = Section(validate=False) + + atomic_multipole_kind = Quantity( + type=str, + shape=[], + description=''' + String describing the method used to obtain the electrostatic multipoles + (including the electric charge, dipole, etc.) for each atom. Such multipoles + require a charge-density partitioning scheme, specified by the value of this + metadata. Allowed values are listed in the [atomic_multipole_kind wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/atomic- + multipole-kind). + ''') + + atomic_multipole_lm = Quantity( + type=np.dtype(np.int32), + shape=['number_of_lm_atomic_multipoles', 2], + description=''' + Tuples of $l$ and $m$ values for which the atomic multipoles (including the + electric charge, dipole, etc.) are given. The method used to obtain the multipoles + is specified by atomic_multipole_kind. The meaning of the integer number $l$ is + monopole/charge for $l=0$, dipole for $l=1$, quadrupole for $l=2$, etc. The + meaning of the integer numbers $m$ is specified by atomic_multipole_m_kind. + ''') + + atomic_multipole_m_kind = Quantity( + type=str, + shape=[], + description=''' + String describing the definition for each integer number $m$ in + atomic_multipole_lm. Allowed values are listed in the [m_kind wiki + page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/m-kind). + ''') + + atomic_multipole_values = Quantity( + type=np.dtype(np.float64), + shape=['number_of_lm_atomic_multipoles', 'number_of_atoms'], + description=''' + Value of the multipoles (including the monopole/charge for $l$ = 0, the dipole for + $l$ = 1, etc.) for each atom, calculated as described in atomic_multipole_kind. + ''') + + number_of_lm_atomic_multipoles = Quantity( + type=int, + shape=[], + description=''' + Gives the number of $l$, $m$ combinations for atomic multipoles + atomic_multipole_lm. + ''') + + +class section_basis_functions_atom_centered(MSection): + ''' + This section contains the description of the basis functions (at least one function) + of the (atom-centered) basis set defined in section_basis_set_atom_centered. + ''' + + m_def = Section(validate=False) + + +class section_basis_set_atom_centered(MSection): + ''' + This section describes the atom-centered basis set. The main contained information is + a short, non unique but human-interpretable, name for identifying the basis set + (basis_set_atom_centered_short_name), a longer, unique name + (basis_set_atom_centered_unique_name), the atomic number of the atomic species the + basis set is meant for (basis_set_atom_number), and a list of actual basis functions + in the section_basis_functions_atom_centered section. + ''' + + m_def = Section(validate=False) + + basis_set_atom_centered_ls = Quantity( + type=np.dtype(np.int32), + shape=['number_of_kinds_in_basis_set_atom_centered'], + description=''' + Azimuthal quantum number ($l$) values (of the angular part given by the spherical + harmonic $Y_{lm}$) of the atom-centered basis function defined in the current + section_basis_set_atom_centered. + ''') + + basis_set_atom_centered_radial_functions = Quantity( + type=np.dtype(np.float64), + shape=['number_of_kinds_in_basis_set_atom_centered', 401, 5], + description=''' + Values of the radial function of the different basis function kinds. The values + are numerically tabulated on a default 0.01-nm equally spaced grid from 0 to 4 nm. + The 5 tabulated values are $r$, $f(r)$, $f'(r)$, $f(r) \\cdot r$, + $\\frac{d}{dr}(f(r) \\cdot r)$. + ''') + + basis_set_atom_centered_short_name = Quantity( + type=str, + shape=[], + description=''' + Code-specific, but explicative, base name for the basis set (not unique). Details + are explained in the [basis_set_atom_centered_short_name wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/basis- + set-atom-centered-short-name), this name should not contain the *atom kind* (to + simplify the use of a single name for multiple elements). + ''') + + basis_set_atom_centered_unique_name = Quantity( + type=str, + shape=[], + description=''' + Code-specific, but explicative, base name for the basis set (not unique). This + string starts with basis_set_atom_centered_short_name. If the basis set defined in + this section_basis_set_atom_centered is not identical to the default definition + (stored in a database) of the basis set with the same name stored in a database, + then the string is extended by 10 identifiable characters as explained in the + [basis_set_atom_centered_name wiki page](https://gitlab.mpcdf.mpg.de/nomad- + lab/nomad-meta-info/wikis/metainfo/basis-set-atom-centered-unique-name). The + reason for this procedure is that often atom-centered basis sets are obtained by + fine tuning basis sets provided by the code developers or other sources. Each + basis sets, which has normally a standard name, often reported in publications, + has also several parameters that can be tuned. This metadata tries to keep track + of the original basis set and its modifications. This string here defined should + not contain the *atom kind* for which this basis set is intended for, in order to + simplify the use of a single name for multiple *atom kinds* (see atom_labels for + the actual meaning of *atom kind*). + ''') + + basis_set_atom_number = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Atomic number (i.e., number of protons) of the atom for which this basis set is + constructed (0 means unspecified or a pseudo atom). + ''') + + number_of_basis_functions_in_basis_set_atom_centered = Quantity( + type=int, + shape=[], + description=''' + Gives the number of different basis functions in a section_basis_set_atom_centered + section. This equals the number of actual coefficients that are specified when + using this basis set. + ''') + + number_of_kinds_in_basis_set_atom_centered = Quantity( + type=int, + shape=[], + description=''' + Gives the number of different *kinds* of radial basis functions in the + section_basis_set_atom_centered section. Specifically, basis functions with the + same $n$ and $l$ quantum numbers are grouped in sets. Each set counts as one + *kind*. + ''') + + section_basis_functions_atom_centered = SubSection( + sub_section=SectionProxy('section_basis_functions_atom_centered'), + repeats=True) + + section_gaussian_basis_group = SubSection( + sub_section=SectionProxy('section_gaussian_basis_group'), + repeats=True) + + +class section_basis_set_cell_dependent(MSection): + ''' + Section describing a cell-dependent (atom-independent) basis set, e.g. plane waves. + The contained information is the type of basis set (in basis_set_cell_dependent_kind), + its parameters (e.g., for plane waves in basis_set_planewave_cutoff), and a name that + identifies the actually used basis set (a string combining the type and the + parameter(s), stored in basis_set_cell_dependent_name). + ''' + + m_def = Section(validate=False) + + basis_set_cell_dependent_kind = Quantity( + type=str, + shape=[], + description=''' + A string defining the type of the cell-dependent basis set (i.e., non atom + centered such as plane-waves). Allowed values are listed in the + [basis_set_cell_dependent_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad- + lab/nomad-meta-info/wikis/metainfo/basis-set-cell-dependent-kind). + ''') + + basis_set_cell_dependent_name = Quantity( + type=str, + shape=[], + description=''' + A label identifying the cell-dependent basis set (i.e., non atom centered such as + plane-waves). Allowed values are listed in the [basis_set_cell_dependent_name wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/basis- + set-cell-dependent-name). + ''') + + basis_set_planewave_cutoff = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Spherical cutoff in reciprocal space for a plane-wave basis set. It is the energy + of the highest plan-ewave ($\\frac{\\hbar^2|k+G|^2}{2m_e}$) included in the basis + set. Note that normally this basis set is used for the wavefunctions, and the + density would have 4 times the cutoff, but this actually depends on the use of the + basis set by the method. + ''') + + +class section_basis_set(MSection): + ''' + This section contains references to *all* basis sets used in this + section_single_configuration_calculation. More than one basis set instance per *single + configuration calculation* (see section_single_configuration_calculation) may be + needed. This is true for example, for codes that implement adaptive basis sets along + the self-consistent field (SCF) convergence (e.g., exciting). In such cases, there is + a section_basis_set instance per SCF iteration, if necessary. Another example is + having a basis set for wavefunctions, a different one for the density, an auxiliary + basis set for resolution of identity (RI), etc. + + Supported are the two broad classes of basis sets: *atom-centered* (e.g., Gaussian- + type, numerical atomic orbitals) and *cell-dependent* (like plane waves or real-space + grids, so named because they are typically used for periodic-system calculations and + dependent to the simulated cell as a whole). + + Basis sets used in this section_single_configuration_calculation, belonging to either + class, are defined in the dedicated section: [section_basis_set_cell_dependent + ](section_basis_set_cell_dependent) or section_basis_set_atom_centered. The + correspondence between the basis sets listed in this section and the definition given + in the dedicated sessions is given by the two concrete metadata: + mapping_section_basis_set_cell_dependent and mapping_section_basis_set_atom_centered. + The latter metadata is a list that connects each atom in the system with its basis + set, where the same basis set can be assigned to more than one atom. + ''' + + m_def = Section(validate=False) + + basis_set_kind = Quantity( + type=str, + shape=[], + description=''' + String describing the use of the basis set, i.e, if it used for expanding a wave- + function or an electron density. Allowed values are listed in the [basis_set_kind + wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/basis-set-kind). + ''') + + basis_set_name = Quantity( + type=str, + shape=[], + description=''' + String identifying the basis set in an unique way. The rules for building this + string are specified in the [basis_set_name wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/basis- + set-name). + ''') + + mapping_section_basis_set_atom_centered = Quantity( + type=Reference(SectionProxy('section_basis_set_atom_centered')), + shape=['number_of_atoms'], + description=''' + An array of the dimension of number_of_atoms where each atom (identified by the + index in the array) is assigned to an atom-centered basis set, for this + section_single_configuration_calculation. The actual definition of the atom- + centered basis set is in the section_basis_set_atom_centered that is referred to + by this metadata. + ''') + + mapping_section_basis_set_cell_dependent = Quantity( + type=Reference(SectionProxy('section_basis_set_cell_dependent')), + shape=[], + description=''' + Assignment of the cell-dependent (i.e., non atom centered, e.g., plane-waves) + parts of the basis set, which is defined (type, parameters) in + section_basis_set_cell_dependent that is referred to by this metadata. + ''') + + number_of_basis_functions = Quantity( + type=int, + shape=[], + description=''' + Stores the total number of basis functions in a section_basis_set section. + ''') + + +class section_restricted_uri(MSection): + ''' + Restricted URIs on this calculation (Coverage: any info or files that are related with + this calculation can be subject to restriction) + ''' + + m_def = Section(validate=False) + + number_of_restricted_uri = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + The number of restricted uris in restricted_uri list. + ''') + + restricted_uri = Quantity( + type=str, + shape=['number_of_restricted_uri'], + description=''' + The list of nomad uri(s) identifying the restricted info/file corresponding to + this calculation + ''') + + restricted_uri_reason = Quantity( + type=str, + shape=[], + description=''' + The reason of restriction for the uri or file. The reason can be 'propriety + license', 'open-source redistribution restricted license', 'other license', or + 'author restricted'. + ''') + + restricted_uri_issue_authority = Quantity( + type=str, + shape=[], + description=''' + The issue authority is the restriction owner for the uri or file. This can be + license owner such as 'VASP' or 'AMBER', 'NOMAD', or the author of the uri. For + example the repository user name of the author. + ''') + + restricted_uri_end_date = Quantity( + type=str, + shape=[], + description=''' + The deadline date of the restriction for the uri or file. The end date can be in + date format string for those restrictions set by authors or NOMAD otherwise it is + set to 'unlimited' for the restriction related to license. + ''') + + restricted_uri_restriction = Quantity( + type=str, + shape=[], + description=''' + The type of restriction for the uri or file. The type can be 'any access' or + 'license permitted'. + ''') + + restricted_uri_license = Quantity( + type=str, + shape=[], + description=''' + The info of the license that is the reason of restriction. + ''') + + number_of_restricted_uri_files = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + The number of restricted files in restricted_uri_files list. + ''') + + +class section_calculation_to_calculation_refs(MSection): + ''' + Section that describes the relationship between different + section_single_configuration_calculation sections. + + For instance, one calculation is a perturbation performed using a self-consistent + field (SCF) calculation as starting point, or a simulated system is partitioned in + regions with different but connected Hamiltonians (e.g., QM/MM, or a region treated + via Kohn-Sham DFT embedded into a region treated via orbital-free DFT). + + The kind of relationship between the calculation defined in this section and the + referenced one is described by calculation_to_calculation_kind. The referenced + section_single_configuration_calculation is identified via + calculation_to_calculation_ref (typically used for a + section_single_configuration_calculation in the same section_run) or + calculation_to_calculation_external_url. + ''' + + m_def = Section(validate=False) + + calculation_to_calculation_external_url = Quantity( + type=str, + shape=[], + description=''' + URL used to reference an externally stored calculation. The kind of relationship + between the present and the referenced section_single_configuration_calculation is + specified by calculation_to_calculation_kind. + ''') + + calculation_to_calculation_kind = Quantity( + type=str, + shape=[], + description=''' + String defining the relationship between the referenced + section_single_configuration_calculation and the present + section_single_configuration_calculation. Valid values are described in the + [calculation_to_calculation_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad- + lab/nomad-meta-info/wikis/metainfo/calculation-to-calculation-kind). Often + calculations are connected, for instance, one calculation is a perturbation + performed using a self-consistent field (SCF) calculation as starting point, or a + simulated system is partitioned in regions with different but connected + Hamiltonians (e.g., QM/MM, or a region treated via Kohn-Sham DFT embedded into a + region treated via orbital-free DFT). Hence, the need of keeping track of these + connected calculations. The referenced calculation is identified via + calculation_to_calculation_ref (typically used for a calculation in the same + section_run) or calculation_to_calculation_external_url. + ''') + + calculation_to_calculation_ref = Quantity( + type=Reference(SectionProxy('section_single_configuration_calculation')), + shape=[], + description=''' + Reference to another calculation. If both this and + calculation_to_calculation_external_url are given, then + calculation_to_calculation_ref is a local copy of the URL given in + calculation_to_calculation_external_url. The kind of relationship between the + present and the referenced section_single_configuration_calculation is specified + by calculation_to_calculation_kind. + ''') + + +class section_calculation_to_folder_refs(MSection): + ''' + Section that describes the relationship between + section_single_configuration_calculationa and the folder containing the original + calulations + ''' + + m_def = Section(validate=False) + + calculation_to_folder_external_url = Quantity( + type=str, + shape=[], + description=''' + URL used to reference a folder containing external calculations. The kind of + relationship between the present and the referenced + section_single_configuration_calculation is specified by + calculation_to_folder_kind. + ''') + + calculation_to_folder_kind = Quantity( + type=str, + shape=[], + description=''' + String defining the relationship between the referenced + section_single_configuration_calculation and a folder containing calculations. + ''') + + +class section_dos(MSection): + ''' + Section collecting information of a (electronic-energy or vibrational-energy) density + of states (DOS) evaluation. + ''' + + m_def = Section(validate=False) + + dos_energies_normalized = Quantity( + type=np.dtype(np.float64), + shape=['number_of_dos_values'], + unit='joule', + description=''' + Array containing the set of discrete energy values with respect to the top of the + valence band for the density (electronic-energy) of states (DOS). This is the + total DOS, see atom_projected_dos_energies and species_projected_dos_energies for + partial density of states. + ''') + + dos_energies = Quantity( + type=np.dtype(np.float64), + shape=['number_of_dos_values'], + unit='joule', + description=''' + Array containing the set of discrete energy values for the density (electronic- + energy or vibrational energy) of states (DOS). This is the total DOS, see + atom_projected_dos_energies and species_projected_dos_energies for partial density + of states. + ''') + + dos_fermi_energy = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Stores the Fermi energy of the density of states. + ''') + + dos_integrated_values = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_dos_values'], + description=''' + Integrated density of states (starting at $-\\infty$), pseudo potential + calculations should start with the number of core electrons if they cover only the + active electrons + ''') + + dos_kind = Quantity( + type=str, + shape=[], + description=''' + String to specify the kind of density of states (either electronic or + vibrational). + ''') + + dos_lm = Quantity( + type=np.dtype(np.int32), + shape=['number_of_dos_lms', 2], + description=''' + Tuples of $l$ and $m$ values for which dos_values_lm are given. For the quantum + number $l$ the conventional meaning of azimuthal quantum number is always adopted. + For the integer number $m$, besides the conventional use as magnetic quantum + number ($l+1$ integer values from $-l$ to $l$), a set of different conventions is + accepted (see the [m_kind wiki page](https://gitlab.rzg.mpg.de/nomad-lab/nomad- + meta-info/wikis/metainfo/m-kind). The actual adopted convention is specified by + dos_m_kind. + ''') + + dos_m_kind = Quantity( + type=str, + shape=[], + description=''' + String describing what the integer numbers of $m$ in dos_lm mean. The allowed + values are listed in the [m_kind wiki page](https://gitlab.rzg.mpg.de/nomad- + lab/nomad-meta-info/wikis/metainfo/m-kind). + ''') + + dos_values_lm = Quantity( + type=np.dtype(np.float64), + shape=['number_of_dos_lms', 'number_of_spin_channels', 'number_of_atoms', 'number_of_dos_values'], + unit='joule', + description=''' + Array containing the density (electronic-energy) of states values projected on the + various spherical harmonics (integrated on all atoms), see + atom_projected_dos_values_lm for atom values. + ''') + + dos_values_normalized = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_dos_values'], + description=''' + Density of states (DOS) values divided by the unit cell volume and by the number + of atoms. + ''') + + dos_values = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_dos_values'], + description=''' + Values (number of states for a given energy, the set of discrete energy values is + given in dos_energies) of density (electronic-energy or vibrational-energy) of + states. This refers to the simulation cell, i.e. integrating over all energies + will give the number of electrons in the simulation cell. + ''') + + number_of_dos_lms = Quantity( + type=int, + shape=[], + description=''' + Gives the number of $l$, $m$ combinations for the given projected density of + states (DOS) in dos_values and dos_values_lm. + ''') + + number_of_dos_values = Quantity( + type=int, + shape=[], + description=''' + Gives the number of energy values for the density of states (DOS), see + dos_energies. + ''') + + +class section_eigenvalues(MSection): + ''' + Section containing (electronic-energy) eigenvalues for one spin channel. If, for + example, the eigenvalues of the Kohn-Sham operator are to be stored, a string + identifying this kind of eigenvalues is put in eigenvalues_kind, the coordinates of + the $k$-points at which the eigenvalues are evaluated is stored in + eigenvalues_kpoints, and the energy values of the eigenstates and their occupation is + stored in eigenvalues_values and eigenvalues_occupation, respectively. + ''' + + m_def = Section(validate=False) + + eigenvalues_kind = Quantity( + type=str, + shape=[], + description=''' + A short string describing the kind of eigenvalues, as defined in the + [eigenvalues_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/eigenvalues-kind). + ''') + + eigenvalues_kpoints_multiplicity = Quantity( + type=np.dtype(np.float64), + shape=['number_of_eigenvalues_kpoints'], + description=''' + Multiplicity of the $k$ point (i.e., how many distinct points per cell this + expands to after applying all symmetries). This defaults to 1. If expansion is + preformed then each point will have weight + eigenvalues_kpoints_weights/eigenvalues_kpoints_multiplicity. + ''') + + eigenvalues_kpoints_weights = Quantity( + type=np.dtype(np.float64), + shape=['number_of_eigenvalues_kpoints'], + description=''' + Weights of the $k$ points (in the basis of the reciprocal lattice vectors) used + for the evaluation of the eigenvalues tabulated in eigenvalues_values, should + account for symmetry too. + ''') + + eigenvalues_kpoints = Quantity( + type=np.dtype(np.float64), + shape=['number_of_eigenvalues_kpoints', 3], + description=''' + Coordinates of the $k$ points (in the basis of the reciprocal lattice vectors) + used for the evaluation of the eigenvalues tabulated in eigenvalues_values. + ''') + + eigenvalues_occupation = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], + description=''' + Occupation of the eigenstates. The corresponding eigenvalues (energy) are given in + eigenvalues_values. The coordinates in the reciprocal space are defined in + eigenvalues_kpoints. + ''') + + eigenvalues_values = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], + unit='joule', + description=''' + Values of the (electronic-energy) eigenvalues. The coordinates of the + corresponding eigenstates in the reciprocal space are defined in + eigenvalues_kpoints and their occupations are given in eigenvalues_occupation. + ''') + + number_of_band_segment_eigenvalues = Quantity( + type=int, + shape=[], + description=''' + Gives the number of eigenvalues in a band segment, see band_energies. + ''') + + number_of_eigenvalues_kpoints = Quantity( + type=int, + shape=[], + description=''' + Gives the number of $k$ points, see eigenvalues_kpoints. $k$ points are calculated + within a run and are irreducible if a symmetry is used. + ''') + + number_of_eigenvalues = Quantity( + type=int, + shape=[], + description=''' + Gives the number of eigenvalues, see eigenvalues_values. + ''') + + number_of_normalized_band_segment_eigenvalues = Quantity( + type=int, + shape=[], + description=''' + Gives the number of normalized eigenvalues in a band segment, see + + band_energies_normalized. + ''') + + +class section_energy_code_independent(MSection): + ''' + Section describing a code-independent total energy obtained by subtracting some + reference energy calculated with the same code. It contains the type in + energy_code_independent_kind and the computed code-independent total energy in + energy_code_independent_value. The computed energy allows for comparisons among + different codes and numerical settings. + ''' + + m_def = Section(validate=False) + + energy_code_independent_kind = Quantity( + type=str, + shape=[], + description=''' + Type of the code-independent total energy (obtained by subtracting a reference + energy calculated with the same code), created to be comparable among different + codes and numerical settings. Details can be found on the [energy_code_independent + wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/energy-code-independent). + ''') + + energy_code_independent_value = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the code-independent total energy (obtained by subtracting a reference + energy calculated with the same code). This value is created to be comparable + among different codes and numerical settings. Details can be found on the + [energy_code_independent wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad- + meta-info/wikis/metainfo/energy-code-independent). + ''', + categories=[energy_component, energy_value, energy_total_potential]) + + +class section_energy_van_der_Waals(MSection): + ''' + Section containing the Van der Waals energy value (energy_van_der_Waals_value) of type + van_der_Waals_kind. This is used when more than one Van der Waals methods are applied + in the same *single configuration calculation*, see + section_single_configuration_calculation. The main Van der Waals method (the one + concurring to energy_current, and used, e.g., for evaluating the forces for a + relaxation or dynamics) is given in energy_van_der_Waals and is defined in + settings_van_der_Waals. + ''' + + m_def = Section(validate=False) + + energy_van_der_Waals_kind = Quantity( + type=str, + shape=[], + description=''' + Method used to compute van der Waals energy stored in energy_van_der_Waals_value. + This metadata is used when more than one van der Waals method is applied in the + same *single configuration calculation* (see + section_single_configuration_calculation). The method used for van der Waals (the + one consistent with energy_current and, e.g., for evaluating the forces for a + relaxation or dynamics) is defined in settings_van_der_Waals. + ''') + + energy_van_der_Waals_value = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of van der Waals energy, calculated with the method defined in + energy_van_der_Waals_kind. This metadata is used when more than one van der Waals + method is applied in the same *single configuration calculation* (see + section_single_configuration_calculation). The value of the van der Waals energy + consistent with energy_current and used, e.g., for evaluating the forces for a + relaxation or dynamics, is given in energy_van_der_Waals and defined in + settings_van_der_Waals. + ''', + categories=[energy_value, energy_type_van_der_Waals, energy_component]) + + energy_van_der_Waals = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value for the converged van der Waals energy calculated using the method described + in van_der_Waals_method, and used in energy_current. This is the van der Waals + method consistent with, e.g., forces used for relaxation or dynamics. Alternative + methods are listed in section_energy_van_der_Waals. + ''', + categories=[energy_value, energy_type_van_der_Waals, energy_component]) + + +class section_frame_sequence_user_quantity(MSection): + ''' + Section collecting some user-defined quantities evaluated along a sequence of frame. + ''' + + m_def = Section(validate=False) + + frame_sequence_user_quantity_frames = Quantity( + type=np.dtype(np.int32), + shape=['number_of_user_quantity_evaluations_in_sequence'], + description=''' + Array containing the strictly increasing indices referring to the frames of + frame_sequence_user_quantity. If not given it defaults to the trivial mapping + 0,1,... + ''') + + frame_sequence_user_quantity_name = Quantity( + type=str, + shape=[], + description=''' + Descriptive name of a user-defined quantity, sampled along this sequence of frames + (i.e., a trajectory, a frame is one section_single_configuration_calculation). + Dedicated metadata are created for the conserved energy-like quantity + (frame_sequence_conserved_quantity), the kinetic and potential energies + (frame_sequence_kinetic_energy and frame_sequence_potential_energy), the + instantaneous temperature (frame_sequence_temperature) and pressure + (frame_sequence_pressure). This metadata should be used for other quantities that + are monitored along a sequence of frames. + ''') + + frame_sequence_user_quantity_stats = Quantity( + type=np.dtype(np.float64), + shape=[2, 'number_of_frame_sequence_user_quantity_components'], + description=''' + Average of frame_sequence_user_quantity and its standard deviation in this + sequence of frames (i.e., a trajectory, a frame is one + section_single_configuration_calculation). + ''') + + frame_sequence_user_quantity = Quantity( + type=np.dtype(np.float64), + shape=['number_of_user_quantity_evaluations_in_sequence', 'number_of_frame_sequence_user_quantity_components'], + description=''' + Array containing the values of the user-defined quantity defined in + frame_sequence_user_quantity_name, evaluated along this sequence of frames (i.e., + trajectory, a frame is one section_single_configuration_calculation). If not all + frames have a value the indices of the frames that have a value are stored in + frame_sequence_kinetic_energy_frames. If not all frames have a value the indices + of the frames that have a value are stored in + frame_sequence_kinetic_energy_frames. + ''') + + number_of_frame_sequence_user_quantity_components = Quantity( + type=int, + shape=[], + description=''' + Gives the number of user-defined quantity defined by + frame_sequence_user_quantity_name and monitored in a sequence of frames. A + sequence is a trajectory, which can have number_of_frames_in_sequence each + representing one section_single_configuration_calculation section. + + Dedicated metadata monitored along a sequence of frames are created for the + conserved energy-like quantity (frame_sequence_conserved_quantity), the kinetic + and potential energies ([frame_sequence_kinetic_energy and + frame_sequence_potential_energy](frame_sequence_kinetic_energy and + frame_sequence_potential_energy)), the instantaneous temperature + (frame_sequence_temperature) and the pressure (frame_sequence_pressure). + ''') + + number_of_user_quantity_evaluations_in_sequence = Quantity( + type=int, + shape=[], + description=''' + Gives the number of user defined quantity evaluations along a sequence of + frame_sequence_user_quantity frames. A sequence is a trajectory, which can have + number_of_frames_in_sequence each representing one + section_single_configuration_calculation section. + ''') + + +class section_frame_sequence(MSection): + ''' + Section containing a sequence of frames, i.e. a trajectory which can have + number_of_frames_in_sequence each representing one + section_single_configuration_calculation section evaluated with a sampling method + (e.g, molecular dynamics, Monte Carlo, geometry optimization). The sampling method + might be a subset of the whole trajectory. + + Information on the method used for the sampling can be found in the + section_sampling_method section and information of each frame of the sequence are + found in the section_single_configuration_calculation section. + ''' + + m_def = Section(validate=False) + + frame_sequence_conserved_quantity_frames = Quantity( + type=np.dtype(np.int32), + shape=['number_of_conserved_quantity_evaluations_in_sequence'], + description=''' + Array containing the strictly increasing indices of the frames the + frame_sequence_conserved_quantity values refers to. If not given it defaults to + the trivial mapping 0,1,... + ''') + + frame_sequence_conserved_quantity_stats = Quantity( + type=np.dtype(np.float64), + shape=[2], + unit='joule', + description=''' + Average value of energy-like frame_sequence_conserved_quantity, and its standard + deviation, over this sequence of frames (i.e., a trajectory, a frame is one + section_single_configuration_calculation). + ''') + + frame_sequence_conserved_quantity = Quantity( + type=np.dtype(np.float64), + shape=['number_of_conserved_quantity_evaluations_in_sequence'], + unit='joule', + description=''' + Array containing the values of a quantity that should be conserved, along a + sequence of frames (i.e., a trajectory). A frame is one + section_single_configuration_calculation), for example the total energy in the NVE + ensemble. If not all frames have a value the indices of the frames that have a + value are stored in frame_sequence_conserved_quantity_frames. + ''') + + frame_sequence_continuation_kind = Quantity( + type=Reference(SectionProxy('section_frame_sequence')), + shape=[], + description=''' + Type of continuation that has been performed from the previous sequence of frames + (i.e., a trajectory, a frame is one section_single_configuration_calculation), + upon restart. + ''') + + frame_sequence_external_url = Quantity( + type=str, + shape=[], + description=''' + If the energy, forces, and other quantities for the frames (a frame is one + section_single_configuration_calculation) in section_frame_sequence are obtained + by calling a different code than the code that drives the sequence (e.g., a + wrapper that drives a molecular dynamics, Monte Carlo, geometry optimization and + calls an electronic-structure code for energy and forces for each configuration), + this metadata holds the reference to where the + section_single_configuration_calculation for each frame are located. The format + for this reference is described in the [frame_sequence_external_url wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/frame- + sequence-external-url). + ''') + + frame_sequence_kinetic_energy_frames = Quantity( + type=np.dtype(np.int32), + shape=['number_of_kinetic_energies_in_sequence'], + description=''' + Array containing the strictly increasing indices referring to the frames of + frame_sequence_kinetic_energy. If not given it defaults to the trivial mapping + 0,1,... + ''') + + frame_sequence_kinetic_energy_stats = Quantity( + type=np.dtype(np.float64), + shape=[2], + unit='joule', + description=''' + Average kinetic energy and its standard deviation over this sequence of frames + (i.e., a trajectory, a frame is one section_single_configuration_calculation). + ''') + + frame_sequence_kinetic_energy = Quantity( + type=np.dtype(np.float64), + shape=['number_of_kinetic_energies_in_sequence'], + unit='joule', + description=''' + Array containing the values of the kinetic energy along this sequence of frames + (i.e., a trajectory, a frame is one section_single_configuration_calculation). If + not all frames have a value the indices of the frames that have a value are stored + in frame_sequence_kinetic_energy_frames. + ''') + + frame_sequence_local_frames_ref = Quantity( + type=Reference(SectionProxy('section_single_configuration_calculation')), + shape=['number_of_frames_in_sequence'], + description=''' + Reference from each frame (a frame is one + section_single_configuration_calculation) in this section_frame_sequence to the + corresponding section_single_configuration_calculation. Each + section_frame_sequence binds a collection of + section_single_configuration_calculation, because they all belong to, e.g., a + molecular dynamics trajectory, or geometry optimization. The full information for + each frame is stored in section_single_configuration_calculation and this metadata + establishes the link for each frame. + ''') + + frame_sequence_potential_energy_frames = Quantity( + type=np.dtype(np.int32), + shape=['number_of_potential_energies_in_sequence'], + description=''' + Array containing the strictly increasing indices referring to the frames of + frame_sequence_potential_energy. If not given it defaults to the trivial mapping + 0,1,... + ''') + + frame_sequence_potential_energy_stats = Quantity( + type=np.dtype(np.float64), + shape=[2], + unit='joule', + description=''' + Average potential energy and its standard deviation over this sequence of frames + (i.e., a trajectory, a frame is one section_single_configuration_calculation). + ''') + + frame_sequence_potential_energy = Quantity( + type=np.dtype(np.float64), + shape=['number_of_potential_energies_in_sequence'], + unit='joule', + description=''' + Array containing the value of the potential energy along this sequence of frames + (i.e., a trajectory, a frame is one section_single_configuration_calculation). + This is equal to energy_total of the corresponding + section_single_configuration_calculation and repeated here in a summary array for + easier access. If not all frames have a value the indices of the frames that have + a value are stored in frame_sequence_potential_energy_frames. + ''') + + frame_sequence_pressure_frames = Quantity( + type=np.dtype(np.int32), + shape=['number_of_pressure_evaluations_in_sequence'], + description=''' + Array containing the strictly increasing indices referring to the frames of + frame_sequence_pressure. If not given it defaults to the trivial mapping 0,1,... + ''') + + frame_sequence_pressure_stats = Quantity( + type=np.dtype(np.float64), + shape=[2], + unit='pascal', + description=''' + Average pressure (one third of the trace of the stress tensor) and standard + deviation over this sequence of frames (i.e., a trajectory, a frame is one + section_single_configuration_calculation). + ''') + + frame_sequence_pressure = Quantity( + type=np.dtype(np.float64), + shape=['number_of_pressure_evaluations_in_sequence'], + unit='pascal', + description=''' + Array containing the values of the pressure (one third of the trace of the stress + tensor) along this sequence of frames (a frame is one + section_single_configuration_calculation). If not all frames have a value the + indices of the frames that have a value are stored in + frame_sequence_pressure_frames. + ''') + + frame_sequence_temperature_frames = Quantity( + type=np.dtype(np.int32), + shape=['number_of_temperatures_in_sequence'], + description=''' + Array containing the strictly increasing indices referring to the frames of + frame_sequence_temperature. If not given it defaults to the trivial mapping + 0,1,... + ''') + + frame_sequence_temperature_stats = Quantity( + type=np.dtype(np.float64), + shape=[2], + unit='kelvin', + description=''' + Average temperature and its standard deviation over this sequence of frames (i.e., + a trajectory, a frame is one section_single_configuration_calculation). + ''') + + frame_sequence_temperature = Quantity( + type=np.dtype(np.float64), + shape=['number_of_temperatures_in_sequence'], + unit='kelvin', + description=''' + Array containing the values of the instantaneous temperature (a quantity, + proportional to frame_sequence_kinetic_energy, whose ensemble average equals the + thermodynamic temperature) along this sequence of frames (i.e., a trajectory, a + frame is one section_single_configuration_calculation). If not all frames have a + value the indices of the frames that have a value are stored in + frame_sequence_temperature_frames. + ''') + + frame_sequence_time = Quantity( + type=np.dtype(np.float64), + shape=['number_of_frames_in_sequence'], + unit='second', + description=''' + Time along this sequence of frames (i.e., a trajectory, a frame is one + section_single_configuration_calculation). Time start is arbitrary, but when a + sequence is a continuation of another time should be continued too. + ''') + + frame_sequence_to_sampling_ref = Quantity( + type=Reference(SectionProxy('section_sampling_method')), + shape=[], + description=''' + Reference from the present section_frame_sequence to the section_sampling_method, + that defines the parameters used in this sequence of frames (i.e., a trajectory, a + frame is one section_single_configuration_calculation). + ''') + + geometry_optimization_converged = Quantity( + type=bool, + shape=[], + description=''' + Arrays specify whether a geometry optimization is converged. + ''') + + number_of_conserved_quantity_evaluations_in_sequence = Quantity( + type=int, + shape=[], + description=''' + Gives the number of conserved quantity evaluations in this sequence. A sequence is + a trajectory, which can have number_of_frames_in_sequence each representing one + section_single_configuration_calculation section. + ''') + + number_of_frames_in_sequence = Quantity( + type=int, + shape=[], + description=''' + Gives the number of frames in a sequence. A sequence is a trajectory, which can + have number_of_frames_in_sequence each representing one + section_single_configuration_calculation section. + ''') + + number_of_kinetic_energies_in_sequence = Quantity( + type=int, + shape=[], + description=''' + Gives the number of kinetic energy evaluations in this sequence of frames, see + frame_sequence_kinetic_energy. + ''') + + number_of_potential_energies_in_sequence = Quantity( + type=int, + shape=[], + description=''' + Gives the number of potential energies evaluation in this sequence. A sequence is + a trajectory, which can have number_of_frames_in_sequence each representing one + section_single_configuration_calculation section. + ''') + + number_of_pressure_evaluations_in_sequence = Quantity( + type=int, + shape=[], + description=''' + Gives the number of pressure evaluations in this sequence. A sequence is a + trajectory, which can have number_of_frames_in_sequence each representing one + section_single_configuration_calculation section. + ''') + + number_of_temperatures_in_sequence = Quantity( + type=int, + shape=[], + description=''' + Gives the number of temperature frames (frame_sequence_temperature) used in the + section_frame_sequence. A sequence is a trajectory, which can have + number_of_frames_in_sequence each representing one + section_single_configuration_calculation section. + ''') + + previous_sequence_ref = Quantity( + type=Reference(SectionProxy('section_frame_sequence')), + shape=[], + description=''' + Contains a reference to the previous sequence. A sequence is a trajectory, which + can have number_of_frames_in_sequence each representing one + section_single_configuration_calculation section. If not given, a start from an + initial configuration is assumed. + ''') + + section_frame_sequence_user_quantity = SubSection( + sub_section=SectionProxy('section_frame_sequence_user_quantity'), + repeats=True) + + section_thermodynamical_properties = SubSection( + sub_section=SectionProxy('section_thermodynamical_properties'), + repeats=True) + + +class section_gaussian_basis_group(MSection): + ''' + Section that describes a group of Gaussian contractions. Groups allow one to calculate + the primitive Gaussian integrals once for several different linear combinations of + them. This defines basis functions with radial part $f_i(r) = r^{l_i} \\\\sum_{j} c_{i + j} A(l_i, \\\\alpha_j) exp(-\\\\alpha_j r^2)$ where $A(l_i, \\\\alpha_j)$ is a the + normalization coefficient for primitive Gaussian basis functions. Here, $\\\\alpha_j$ is + defined in gaussian_basis_group_exponents, $l_i$ is given in gaussian_basis_group_ls, + and $c_{i j}$ is given in gaussian_basis_group_contractions, whereas the radial part + is given by the spherical harmonics $Y_{l m}$. + + This section is defined only if the original basis function uses Gaussian basis + functions, and the sequence of radial functions $f_i$ across all + section_gaussian_basis_group in section_basis_set_atom_centered should match the one + of basis_set_atom_centered_radial_functions. + ''' + + m_def = Section(validate=False) + + gaussian_basis_group_contractions = Quantity( + type=np.dtype(np.float64), + shape=['number_of_gaussian_basis_group_contractions', 'number_of_gaussian_basis_group_exponents'], + description=''' + contraction coefficients $c_{i j}$ defining the contracted basis functions with + respect to *normalized* primitive Gaussian functions. They define the Gaussian + basis functions as described in section_gaussian_basis_group. + ''') + + gaussian_basis_group_exponents = Quantity( + type=np.dtype(np.float64), + shape=['number_of_gaussian_basis_group_exponents'], + unit='1 / meter ** 2', + description=''' + Exponents $\\alpha_j$ of the Gaussian functions defining this basis set + $exp(-\\alpha_j r^2)$. One should be careful about the units of the coefficients. + ''') + + gaussian_basis_group_ls = Quantity( + type=np.dtype(np.float64), + shape=['number_of_gaussian_basis_group_contractions'], + description=''' + Azimuthal quantum number ($l$) values (of the angular part given by the spherical + harmonic $Y_{l m}$ of the various contracted basis functions). + ''') + + number_of_gaussian_basis_group_contractions = Quantity( + type=int, + shape=[], + description=''' + Gives the number of different contractions, i.e. resulting basis functions in a + section_gaussian_basis_group section. + ''') + + number_of_gaussian_basis_group_exponents = Quantity( + type=int, + shape=[], + description=''' + Gives the number of different Gaussian exponents in a section_gaussian_basis_group + section. + ''') + + +class section_k_band_normalized(MSection): + ''' + This section stores information on a normalized $k$-band (electronic band structure) + evaluation along one-dimensional pathways in the $k$ (reciprocal) space given in + section_k_band_segment. Eigenvalues calculated at the actual $k$-mesh used for + energy_total evaluations, can be found in the section_eigenvalues section. + ''' + + m_def = Section(validate=False) + + k_band_path_normalized_is_standard = Quantity( + type=bool, + shape=[], + description=''' + If the normalized path is along the default path defined in W. Setyawan and S. + Curtarolo, [Comput. Mater. Sci. **49**, 299-312 + (2010)](http://dx.doi.org/10.1016/j.commatsci.2010.05.010). + ''') + + section_k_band_segment_normalized = SubSection( + sub_section=SectionProxy('section_k_band_segment_normalized'), + repeats=True) + + +class section_k_band_segment_normalized(MSection): + ''' + Section collecting the information on a normalized $k$-band segment. This section + stores band structures along a one-dimensional pathway in the $k$ (reciprocal) space. + + Eigenvalues calculated at the actual $k$-mesh used for energy_total evaluations are + defined in section_eigenvalues and the band structures are represented as third-order + tensors: one dimension for the spin channels, one for the sequence of $k$ points for + the segment (given in number_of_k_points_per_segment), and one for the sequence of + eigenvalues at a given $k$ point. The values of the $k$ points in each segment are + stored in band_k_points. The energies and occupation for each eigenstate, at each $k$ + point, segment, and spin channel are stored in band_energies and band_occupations, + respectively. The labels for the segment are specified in band_segm_labels. + ''' + + m_def = Section(validate=False) + + band_energies_normalized = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_normalized_k_points_per_segment', 'number_of_normalized_band_segment_eigenvalues'], + unit='joule', + description=''' + $k$-dependent energies of the electronic band segment (electronic band structure) + with respect to the top of the valence band. This is a third-order tensor, with + one dimension used for the spin channels, one for the $k$ points for each segment, + and one for the eigenvalue sequence. + ''') + + band_k_points_normalized = Quantity( + type=np.dtype(np.float64), + shape=['number_of_normalized_k_points_per_segment', 3], + description=''' + Fractional coordinates of the $k$ points (in the basis of the reciprocal-lattice + vectors) for which the normalized electronic energies are given. + ''') + + band_occupations_normalized = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_normalized_k_points_per_segment', 'number_of_normalized_band_segment_eigenvalues'], + description=''' + Occupation of the $k$-points along the normalized electronic band. The size of the + dimensions of this third-order tensor are the same as for the tensor in + band_energies. + ''') + + band_segm_labels_normalized = Quantity( + type=str, + shape=[2], + description=''' + Start and end labels of the points in the segment (one-dimensional pathways) + sampled in the $k$-space, using the conventional symbols, e.g., Gamma, K, L. The + coordinates (fractional, in the reciprocal space) of the start and end points for + each segment are given in band_segm_start_end_normalized + ''') + + band_segm_start_end_normalized = Quantity( + type=np.dtype(np.float64), + shape=[2, 3], + description=''' + Fractional coordinates of the start and end point (in the basis of the reciprocal + lattice vectors) of the segment sampled in the $k$ space. The conventional symbols + (e.g., Gamma, K, L) of the same points are given in band_segm_labels + ''') + + number_of_normalized_k_points_per_segment = Quantity( + type=int, + shape=[], + description=''' + Gives the number of $k$ points in the segment of the normalized band structure + (see section_k_band_segment_normalized). + ''') + + +class section_k_band_segment(MSection): + ''' + Section collecting the information on a $k$-band or $q$-band segment. This section + stores band structures along a one-dimensional pathway in the $k$ or $q$ (reciprocal) + space. + + Eigenvalues calculated at the actual $k$-mesh used for energy_total evaluations are + defined in section_eigenvalues and the band structures are represented as third-order + tensors: one dimension for the spin channels, one for the sequence of $k$ or $q$ + points for the segment (given in number_of_k_points_per_segment), and one for the + sequence of eigenvalues at a given $k$ or $q$ point. The values of the $k$ or $q$ + points in each segment are stored in band_k_points. The energies and occupation for + each eigenstate, at each $k$ or $q$ point, segment, and spin channel are stored in + band_energies and band_occupations, respectively. The labels for the segment are + specified in band_segm_labels. + ''' + + m_def = Section(validate=False) + + band_energies = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_k_points_per_segment', 'number_of_band_segment_eigenvalues'], + unit='joule', + description=''' + $k$-dependent or $q$-dependent energies of the electronic or vibrational band + segment (electronic/vibrational band structure). This is a third-order tensor, + with one dimension used for the spin channels (1 in case of a vibrational band + structure), one for the $k$ or $q$ points for each segment, and one for the + eigenvalue sequence. + ''') + + band_k_points = Quantity( + type=np.dtype(np.float64), + shape=['number_of_k_points_per_segment', 3], + description=''' + Fractional coordinates of the $k$ or $q$ points (in the basis of the reciprocal- + lattice vectors) for which the electronic energy are given. + ''') + + band_occupations = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_k_points_per_segment', 'number_of_band_segment_eigenvalues'], + description=''' + Occupation of the $k$-points along the electronic band. The size of the dimensions + of this third-order tensor are the same as for the tensor in band_energies. + ''') + + band_segm_labels = Quantity( + type=str, + shape=[2], + description=''' + Start and end labels of the points in the segment (one-dimensional pathways) + sampled in the $k$-space or $q$-space, using the conventional symbols, e.g., + Gamma, K, L. The coordinates (fractional, in the reciprocal space) of the start + and end points for each segment are given in band_segm_start_end + ''') + + band_segm_start_end = Quantity( + type=np.dtype(np.float64), + shape=[2, 3], + description=''' + Fractional coordinates of the start and end point (in the basis of the reciprocal + lattice vectors) of the segment sampled in the $k$ space. The conventional symbols + (e.g., Gamma, K, L) of the same points are given in band_segm_labels + ''') + + number_of_k_points_per_segment = Quantity( + type=int, + shape=[], + description=''' + Gives the number of $k$ points in the segment of the band structure, see + section_k_band_segment. + ''') + + +class section_k_band(MSection): + ''' + This section stores information on a $k$-band (electronic or vibrational band + structure) evaluation along one-dimensional pathways in the $k$ or $q$ (reciprocal) + space given in section_k_band_segment. Eigenvalues calculated at the actual $k$-mesh + used for energy_total evaluations, can be found in the section_eigenvalues section. + ''' + + m_def = Section(validate=False) + + band_structure_kind = Quantity( + type=str, + shape=[], + description=''' + String to specify the kind of band structure (either electronic or vibrational). + ''') + + section_k_band_segment = SubSection( + sub_section=SectionProxy('section_k_band_segment'), + repeats=True) + + +class section_method_atom_kind(MSection): + ''' + Every section_method_atom_kind section contains method-related information about a + kind of atom, and is identified by one or more strings stored in + method_atom_kind_label. + + This categorization into atom kinds is more flexible than just atomic species, because + to different atoms of the same species different atom-centered basis sets or pseudo- + potentials may be assigned. For instance, if two different oxygen atoms are assigned + to different basis sets or pseudo-potentials, they have to distinguished into two + different *kinds* of O atoms, by creating two distinct section_method_atom_kind + sections. + ''' + + m_def = Section(validate=False) + + method_atom_kind_atom_number = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Atomic number (number of protons) of this atom kind, use 0 if not an atom. + ''') + + method_atom_kind_explicit_electrons = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Number of explicit electrons (often called valence). + ''') + + method_atom_kind_label = Quantity( + type=str, + shape=[], + description=''' + String used to identify the atoms of this kind. This should correspond to the + atom_labels of the configuration. It is possible for one atom kind to have + multiple labels (in order to allow two atoms of the same kind to have two + differently defined sets of atom-centered basis functions or two different pseudo- + potentials). Atom kind is typically the symbol of the atomic species but it can be + also a ghost or pseudo-atom. + ''') + + method_atom_kind_mass = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='atomic_mass_unit', + description=''' + Mass of the kind of this kind of atoms. + ''') + + method_atom_kind_pseudopotential_name = Quantity( + type=str, + shape=[], + description=''' + Name identifying the pseudopotential used. + ''') + + +class section_method_to_method_refs(MSection): + ''' + Section that describes the relationship between different section_method sections. + + For instance, one calculation is a perturbation performed using a self-consistent + field (SCF) calculation as starting point, or a simulated system is partitioned in + regions with different but connected Hamiltonians (e.g., QM/MM, or a region treated + via Kohn-Sham DFT embedded into a region treated via orbital-free DFT). + + The kind of relationship between the method defined in this section and the referenced + one is described by method_to_method_kind. The referenced section section_method is + identified via method_to_method_ref (typically used for a section_method section in + the same section_run) or method_to_method_external_url. + ''' + + m_def = Section(validate=False) + + method_to_method_external_url = Quantity( + type=str, + shape=[], + description=''' + URL used to reference an externally stored section_method. The kind of + relationship between the present and the referenced section_method is specified by + method_to_method_kind. + ''') + + method_to_method_kind = Quantity( + type=str, + shape=[], + description=''' + String defining the kind of relationship that the referenced section_method has + with the present section_method. Valid values are described in the + [method_to_method_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad- + meta-info/wikis/metainfo/method-to-method-kind). Often calculations are connected, + for instance, one calculation is a perturbation performed using a self-consistent + field (SCF) calculation as starting point, or a simulated system is partitioned in + regions with different but connected Hamiltonians (e.g., QM/MM, or a region + treated via Kohn-Sham DFT embedded into a region treated via orbital-free DFT). + Hence, the need of keeping track of these connected calculations. The referenced + section_method is identified via method_to_method_ref (typically used for a + section_method in the same section_run) or method_to_method_external_url. + ''') + + method_to_method_ref = Quantity( + type=Reference(SectionProxy('section_method')), + shape=[], + description=''' + Reference to a local section_method. If both method_to_method_ref and + method_to_method_external_url are given, then method_to_method_ref is a local copy + of the value contained in method_to_method_external_url. The kind of relationship + between the method defined in the present section_method and the referenced one is + described by method_to_method_kind. + ''') + + +class section_method(MSection): + ''' + Section containing the various parameters that define the theory and the + approximations (convergence, thresholds,...) to perform a *single configuration + calculation*, see section_single_configuration_calculation. + + *NOTE*: This section does not contain settings for molecular dynamics, geometry + optimization etc. See section frame_sequence for these other settings instead. + ''' + + m_def = Section(validate=False) + + basis_set = Quantity( + type=str, + shape=[], + description=''' + Unique string identifying the basis set used for the final wavefunctions + calculated with XC_method. It might identify a class of basis sets, often matches + one of the strings given in any of basis_set_name. + ''', + categories=[settings_potential_energy_surface, settings_numerical_parameter]) + + calculation_method_current = Quantity( + type=str, + shape=[], + description=''' + String that represents the method used to calculate the energy_current. If the + method is perturbative, this string does not describe the starting point method, + the latter being referenced to by section_method_to_method_refs. For self- + consistent field (SCF) ab initio calculations, for example, this is composed by + concatenating XC_method_current and basis_set. See [calculation_method_current + wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/calculation-method-current) for the details. + ''') + + calculation_method_kind = Quantity( + type=str, + shape=[], + description=''' + Kind of method in calculation_method_current. + + Accepted values are: + + - absolute + + - perturbative. + ''') + + calculation_method = Quantity( + type=str, + shape=[], + description=''' + String that uniquely represents the method used to calculate energy_total, If the + present calculation_method_current is a perturbative method Y that uses method X + as starting point, this string is automatically created as X@Y, where X is taken + from calculation_method_current and Y from method_to_method_ref. In order to + activate this, method_to_method_kind must have the value starting_point (see the + [method_to_method_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad- + meta-info/wikis/metainfo/method-to-method-kind)). + ''') + + electronic_structure_method = Quantity( + type=str, + shape=[], + description=''' + Non-unique string identifying the used electronic structure method. It is not + unique in the sense that two calculations with the same + electronic_structure_method string may have not been performed with exactly the + same method. The allowed strings are given in the [electronic structure method + wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/electronic-structure-method). + ''', + categories=[settings_potential_energy_surface, settings_XC]) + + k_mesh_points = Quantity( + type=np.dtype(np.float64), + shape=['number_of_k_mesh_points', 3], + description=''' + List of all the k points in the $k$-point mesh. These are the k point used to + evaluate energy_total, and are in fractional coordinates (in the basis of the + reciprocal-lattice vectors). + ''', + categories=[settings_k_points, settings_potential_energy_surface]) + + k_mesh_weights = Quantity( + type=np.dtype(np.float64), + shape=['number_of_k_mesh_points'], + description=''' + Weights of all the k points in the $k$-point mesh. These are the weights for + k_mesh_points (i.e. the k point used to evaluate energy_total). + ''', + categories=[settings_k_points, settings_potential_energy_surface]) + + number_of_k_mesh_points = Quantity( + type=int, + shape=[], + description=''' + number of k points in the mesh (i.e. the k points used to evaluate energy_total). + ''', + categories=[settings_k_points, settings_potential_energy_surface]) + + number_of_spin_channels = Quantity( + type=int, + shape=[], + description=''' + Gives the number of spin channels, see section_method. + ''') + + relativity_method = Quantity( + type=str, + shape=[], + description=''' + Describes the relativistic treatment used for the calculation of the final energy + and related quantities. If skipped or empty, no relativistic treatment is applied. + ''', + categories=[settings_potential_energy_surface, settings_XC, settings_relativity]) + + scf_max_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Specifies the maximum number of allowed self-consistent field (SCF) iterations in + a calculation run, see section_run. + ''', + categories=[settings_scf]) + + scf_threshold_energy_change = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Specifies the threshold for the energy_total_scf_iteration change between two + subsequent self-consistent field (SCF) iterations. The SCF is considered converged + when the total-energy change between two SCF cycles is below the threshold + (possibly in combination with other criteria). + ''', + categories=[settings_scf]) + + self_interaction_correction_method = Quantity( + type=str, + shape=[], + description=''' + Contains the name for the self-interaction correction (SIC) treatment used to + calculate the final energy and related quantities. If skipped or empty, no special + correction is applied. + + The following SIC methods are available: + + | SIC method | Description | + + | ------------------------- | -------------------------------- | + + | `""` | No correction | + + | `"SIC_AD"` | The average density correction | + + | `"SIC_SOSEX"` | Second order screened exchange | + + | `"SIC_EXPLICIT_ORBITALS"` | (scaled) Perdew-Zunger correction explicitly on a + set of orbitals | + + | `"SIC_MAURI_SPZ"` | (scaled) Perdew-Zunger expression on the spin + density / doublet unpaired orbital | + + | `"SIC_MAURI_US"` | A (scaled) correction proposed by Mauri and co- + workers on the spin density / doublet unpaired orbital | + ''', + categories=[settings_potential_energy_surface, settings_XC, settings_self_interaction_correction]) + + smearing_kind = Quantity( + type=str, + shape=[], + description=''' + Specifies the kind of smearing on the electron occupation used to calculate the + free energy (see energy_free) + + Valid values are: + + | Smearing kind | Description | + + | ------------------------- | --------------------------------- | + + | `"empty"` | No smearing is applied | + + | `"gaussian"` | Gaussian smearing | + + | `"fermi"` | Fermi smearing | + + | `"marzari-vanderbilt"` | Marzari-Vanderbilt smearing | + + | `"methfessel-paxton"` | Methfessel-Paxton smearing | + + | `"tetrahedra"` | Interpolation of state energies and occupations + (ignores smearing_width) | + ''', + categories=[settings_smearing]) + + smearing_width = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Specifies the width of the smearing in energy for the electron occupation used to + calculate the free energy (see energy_free). + + *NOTE:* Not all methods specified in smearing_kind uses this value. + ''', + categories=[settings_smearing]) + + spin_target_multiplicity = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Stores the target (user-imposed) value of the spin multiplicity $M=2S+1$, where + $S$ is the total spin. It is an integer number. This value is not necessarily the + value obtained at the end of the calculation. See spin_S2 for the converged value + of the spin moment. + ''') + + stress_tensor_method = Quantity( + type=str, + shape=[], + description=''' + Specifies the method used to calculate stress_tensor for, e.g., molecular dynamics + and geometry optimization. + + The allowed values are: + + * numeric + + * analytic + ''', + categories=[settings_stress_tensor]) + + total_charge = Quantity( + type=np.dtype(np.int32), + shape=[], + unit='coulomb', + description=''' + Provides the total amount of charge of the system in a run. + ''') + + van_der_Waals_method = Quantity( + type=str, + shape=[], + description=''' + Describes the Van der Waals method. If skipped or an empty string is used, it + means no Van der Waals correction is applied. + + Allowed values are: + + | Van der Waals method | Description | + + | --------------------- | ----------------------------------------- | + + | `""` | No Van der Waals correction | + + | `"TS"` | A. Tkatchenko and M. Scheffler, [Phys. Rev. Lett. + **102**, 073005 (2009)](http://dx.doi.org/10.1103/PhysRevLett.102.073005) | + + | `"OBS"` | F. Ortmann, F. Bechstedt, and W. G. Schmidt, [Phys. Rev. + B **73**, 205101 (2006)](http://dx.doi.org/10.1103/PhysRevB.73.205101) | + + | `"G06"` | S. Grimme, [J. Comput. Chem. **27**, 1787 + (2006)](http://dx.doi.org/10.1002/jcc.20495) | + + | `"JCHS"` | P. Jurečka, J. Černý, P. Hobza, and D. R. Salahub, + [Journal of Computational Chemistry **28**, 555 + (2007)](http://dx.doi.org/10.1002/jcc.20570) | + + | `"MDB"` | Many-body dispersion. A. Tkatchenko, R. A. Di Stasio Jr, + R. Car, and M. Scheffler, [Physical Review Letters **108**, 236402 + (2012)](http://dx.doi.org/10.1103/PhysRevLett.108.236402) and A. Ambrosetti, A. M. + Reilly, R. A. Di Stasio Jr, and A. Tkatchenko, [The Journal of Chemical Physics + **140**, 18A508 (2014)](http://dx.doi.org/10.1063/1.4865104) | + + | `"XC"` | The method to calculate the Van der Waals energy uses a + non-local functional which is described in section_XC_functionals. | + ''', + categories=[settings_van_der_Waals, settings_potential_energy_surface, settings_XC]) + + XC_functional = Quantity( + type=str, + shape=[], + description=''' + This value describes a DFT exchange-correlation (XC) functional used for + evaluating the energy value stored in energy_XC_functional and related quantities + (e.g., forces). + + It is a unique short name obtained by combining the data stored in + section_XC_functionals, more specifically by combining different + XC_functional_name as described in the [XC_functional wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/XC- + functional). + ''', + categories=[settings_physical_parameter, settings_XC_functional, settings_potential_energy_surface, settings_XC]) + + XC_method = Quantity( + type=str, + shape=[], + description=''' + Describes the exchange correlation (XC) method used for evaluating the XC energy + (energy_XC). Differently from XC_functional, perturbative treatments are also + accounted for, where the string contains the reference to both the perturbative + (e.g., MP2) and the starting point (e.g, Hartree-Fock) XC method defined in the + section section_method. + + The value consists of XC_method_current concatenated with the `@` character and + the XC method (XC_method) defined in section_method that is referred to by + method_to_method_ref where method_to_method_kind = "starting_point_method". + ''', + categories=[settings_potential_energy_surface, settings_XC]) + + XC_method_current = Quantity( + type=str, + shape=[], + description=''' + Identifies the exchange correlation (XC) method used for energy_XC and related + quantities in a standardized short form as a string. + + It is built by joining the values in the following order using the underscore `_` + character: electronic_structure_method, XC_functional, + self_interaction_correction_method, van_der_Waals_method and relativity_method. + + If any of the methods listed in the string contain non-standard settings, then the + first 10 characters of the Base64 URL encoding of SHA 512 checksum of a normalized + JSON with all non-redundant non-derived settings_XC are appended to the the string + preceded by an underscore. + + With empty strings, the underscore `_` character is skipped. + + If the method defined in the section_method section is perturbative, the + XC_method_current contains only the perturbative method, not the starting point + (e.g. the DFT XC functional used as a starting point for a RPA perturbative + calculation). In this case, the string that contains both the perturbative and + starting point method is stored in XC_method. + ''', + categories=[settings_potential_energy_surface, settings_XC]) + + section_method_atom_kind = SubSection( + sub_section=SectionProxy('section_method_atom_kind'), + repeats=True) + + section_method_to_method_refs = SubSection( + sub_section=SectionProxy('section_method_to_method_refs'), + repeats=True) + + section_XC_functionals = SubSection( + sub_section=SectionProxy('section_XC_functionals'), + repeats=True) + + +class section_original_system(MSection): + ''' + Section containing symmetry information that is specific to the original system. + ''' + + m_def = Section(validate=False) + + equivalent_atoms_original = Quantity( + type=np.dtype(np.int32), + shape=['number_of_atoms'], + description=''' + Gives a mapping table of atoms to symmetrically independent atoms in the original + cell. This is used to find symmetrically equivalent atoms. + ''') + + wyckoff_letters_original = Quantity( + type=str, + shape=['number_of_atoms'], + description=''' + Wyckoff letters for atoms in the original cell. + ''') + + +class section_primitive_system(MSection): + ''' + Section containing symmetry information that is specific to the primitive system. The + primitive system is derived from the standardized system with a transformation that is + specific to the centring. The transformation matrices can be found e.g. from here: + https://atztogo.github.io/spglib/definition.html#transformation-to-the-primitive-cell + ''' + + m_def = Section(validate=False) + + atom_positions_primitive = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms_primitive', 3], + description=''' + Atom positions in the primitive cell in reduced units. + ''') + + atomic_numbers_primitive = Quantity( + type=np.dtype(np.int32), + shape=['number_of_atoms_primitive'], + description=''' + Atomic numbers in the primitive cell. + ''') + + equivalent_atoms_primitive = Quantity( + type=np.dtype(np.int32), + shape=['number_of_atoms_primitive'], + description=''' + Gives a mapping table of atoms to symmetrically independent atoms in the primitive + cell. This is used to find symmetrically equivalent atoms. + ''') + + lattice_vectors_primitive = Quantity( + type=np.dtype(np.float64), + shape=[3, 3], + unit='meter', + description=''' + Primitive lattice vectors. The vectors are the rows of this matrix. + ''') + + number_of_atoms_primitive = Quantity( + type=int, + shape=[], + description=''' + Number of atoms in primitive system. + ''') + + wyckoff_letters_primitive = Quantity( + type=str, + shape=['number_of_atoms_primitive'], + description=''' + Wyckoff letters for atoms in the primitive cell. + ''') + + +class section_processor_info(MSection): + ''' + Section with information about a processor that generated or added information to the + current calculation. + ''' + + m_def = Section(validate=False) + + processor_id = Quantity( + type=str, + shape=[], + description=''' + Id (name+version) of the processor that generated or added information to the + current calculation. + ''') + + processor_number_of_evaluated_contexts = Quantity( + type=np.dtype(np.int64), + shape=[], + description=''' + number of contexts evaluated with this processor in the current current + calculation. + ''') + + processor_number_of_failed_contexts = Quantity( + type=np.dtype(np.int64), + shape=[], + description=''' + number of contexts in the current current calculation that had failure for this + processor. + ''') + + processor_number_of_skipped_contexts = Quantity( + type=np.dtype(np.int64), + shape=[], + description=''' + number of contexts skipped by this processor in the current current calculation. + ''') + + processor_number_of_successful_contexts = Quantity( + type=np.dtype(np.int64), + shape=[], + description=''' + number of contexts in the current calculation that where successfully handled by + this processor. + ''') + + processor_version_details = Quantity( + type=typing.Any, + shape=[], + description=''' + detailed version information on the processor that generated or added information + to the current calculation. + ''') + + +class section_processor_log_event(MSection): + ''' + A log event + ''' + + m_def = Section(validate=False) + + processor_log_event_level = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Level of the logging, a lower number has more priority. The levels are the same as + log4j: FATAL -> 100, ERROR -> 200, WARN -> 300, INFO -> 400, DEBUG -> 500, TRACE + -> 600 + ''') + + processor_log_event_message = Quantity( + type=str, + shape=[], + description=''' + The log message + ''') + + +class section_processor_log(MSection): + ''' + log of a processor + ''' + + m_def = Section(validate=False) + + processor_log_processor_id = Quantity( + type=str, + shape=[], + description=''' + The processor id of the processor creating this log + ''') + + processor_log_start = Quantity( + type=str, + shape=[], + description=''' + Start of the log (in ansi notation YYYY-MM-TT...) + ''') + + section_processor_log_event = SubSection( + sub_section=SectionProxy('section_processor_log_event'), + repeats=True) + + +class section_prototype(MSection): + ''' + Information on the prototype corresponding to the current section. + ''' + + m_def = Section(validate=False) + + prototype_aflow_id = Quantity( + type=str, + shape=[], + description=''' + AFLOW id of the prototype (see + http://aflowlib.org/CrystalDatabase/prototype_index.html) identified on the basis + of the space_group and normalized_wyckoff. + ''') + + prototype_aflow_url = Quantity( + type=str, + shape=[], + description=''' + Url to the AFLOW definition of the prototype (see + http://aflowlib.org/CrystalDatabase/prototype_index.html) identified on the basis + of the space_group and normalized_wyckoff. + ''') + + prototype_assignment_method = Quantity( + type=str, + shape=[], + description=''' + Method used to identify the prototype. + ''') + + prototype_label = Quantity( + type=str, + shape=[], + description=''' + Label of the prototype identified on the basis of the space_group and + normalized_wyckoff. The label is in the same format as in the read_prototypes + function: <space_group_number>-<prototype_name>-<Pearson's symbol>). + ''') + + +class section_run(MSection): + ''' + Every section_run represents a single call of a program. What exactly is contained in + a run depends on the run type (see for example section_method and + section_single_configuration_calculation) and the program (see [program_info + ](program_info)). + ''' + + m_def = Section(validate=False) + + calculation_file_uri = Quantity( + type=str, + shape=[], + description=''' + Contains the nomad uri of a raw the data file connected to the current run. There + should be an value for the main_file_uri and all ancillary files. + ''') + + message_debug_run = Quantity( + type=str, + shape=[], + description=''' + A debugging message of the computational program, associated with a run. + ''', + categories=[message_debug]) + + message_error_run = Quantity( + type=str, + shape=[], + description=''' + An error message of the computational program, associated with a run. + ''', + categories=[message_info, message_debug, message_warning, message_error]) + + message_info_run = Quantity( + type=str, + shape=[], + description=''' + An information message of the computational program, associated with a run. + ''', + categories=[message_info, message_debug]) + + message_warning_run = Quantity( + type=str, + shape=[], + description=''' + A warning message of the computational program, associated with a run. + ''', + categories=[message_info, message_debug, message_warning]) + + parsing_message_debug_run = Quantity( + type=str, + shape=[], + description=''' + This field is used for debugging messages of the parsing program associated with a + single configuration calculation, see section_single_configuration_calculation. + ''', + categories=[parsing_message_debug]) + + parsing_message_error_run = Quantity( + type=str, + shape=[], + description=''' + This field is used for error messages of the parsing program associated with a + run, see section_run. + ''', + categories=[parsing_message_info, parsing_message_error, parsing_message_warning, parsing_message_debug]) + + parsing_message_info_run = Quantity( + type=str, + shape=[], + description=''' + This field is used for info messages of the parsing program associated with a run, + see section_run. + ''', + categories=[parsing_message_info, parsing_message_debug]) + + parsing_message_warning_run = Quantity( + type=str, + shape=[], + description=''' + This field is used for warning messages of the parsing program associated with a + run, see section_run. + ''', + categories=[parsing_message_info, parsing_message_warning, parsing_message_debug]) + + program_basis_set_type = Quantity( + type=str, + shape=[], + description=''' + The type of basis set used by the program to represent wave functions. + + Valid values are: + + * Numeric AOs + + * Gaussians + + * (L)APW+lo + + * FLAPW (full-potential linearized augmented planewave) + + * Plane waves + + * Real-space grid + + * Local-orbital minimum-basis + ''') + + program_compilation_datetime = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Contains the program compilation date and time from *Unix epoch* (00:00:00 UTC on + 1 January 1970) in seconds. For date and times without a timezone, the default + timezone GMT is used. + ''', + categories=[accessory_info, program_info]) + + program_compilation_host = Quantity( + type=str, + shape=[], + description=''' + Specifies the host on which the program was compiled. + ''', + categories=[accessory_info, program_info]) + + program_name = Quantity( + type=str, + shape=[], + description=''' + Specifies the name of the program that generated the data. + ''', + categories=[accessory_info, program_info]) + + program_version = Quantity( + type=str, + shape=[], + description=''' + Specifies the version of the program that was used. This should be the version + number of an official release, the version tag or a commit id as well as the + location of the repository. + ''', + categories=[accessory_info, program_info]) + + run_clean_end = Quantity( + type=bool, + shape=[], + description=''' + Indicates whether this run terminated properly (true), or if it was killed or + exited with an error code unequal to zero (false). + ''') + + run_hosts = Quantity( + type=typing.Any, + shape=[], + description=''' + An associative list of host(s) that performed this simulation. This is an + associative list that contains program-dependent information (*key*) on how the + host was used (*value*). Useful for debugging purposes. + ''', + categories=[accessory_info, parallelization_info]) + + raw_id = Quantity( + type=str, + shape=[], + description=''' + An optional calculation id, if one is found in the code input/output files. + ''') + + time_run_cpu1_end = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the end time of the run on CPU 1. + ''', + categories=[accessory_info, time_info]) + + time_run_cpu1_start = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the start time of the run on CPU 1. + ''', + categories=[accessory_info, time_info]) + + time_run_date_end = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the end date of the run as time since the *Unix epoch* (00:00:00 UTC on 1 + January 1970) in seconds. For date and times without a timezone, the default + timezone GMT is used. + ''', + categories=[accessory_info, time_info]) + + time_run_date_start = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the start date of the run as time since the *Unix epoch* (00:00:00 UTC on 1 + January 1970) in seconds. For date and times without a timezone, the default + timezone GMT is used. + ''', + categories=[accessory_info, time_info]) + + time_run_wall_end = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the internal wall-clock time at the end of the run. + ''', + categories=[accessory_info, time_info]) + + time_run_wall_start = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the internal wall-clock time from the start of the run. + ''', + categories=[accessory_info, time_info]) + + section_basis_set_atom_centered = SubSection( + sub_section=SectionProxy('section_basis_set_atom_centered'), + repeats=True) + + section_basis_set_cell_dependent = SubSection( + sub_section=SectionProxy('section_basis_set_cell_dependent'), + repeats=True) + + section_frame_sequence = SubSection( + sub_section=SectionProxy('section_frame_sequence'), + repeats=True) + + section_method = SubSection( + sub_section=SectionProxy('section_method'), + repeats=True) + + section_sampling_method = SubSection( + sub_section=SectionProxy('section_sampling_method'), + repeats=True) + + section_single_configuration_calculation = SubSection( + sub_section=SectionProxy('section_single_configuration_calculation'), + repeats=True) + + section_system = SubSection( + sub_section=SectionProxy('section_system'), + repeats=True) + + +class section_sampling_method(MSection): + ''' + Section containing the settings describing a (potential-energy surface) sampling + method. + + Results and monitored quantities of such sampling are collected in a sequence of + frames, section_frame_sequence. + ''' + + m_def = Section(validate=False) + + ensemble_type = Quantity( + type=str, + shape=[], + description=''' + Kind of sampled ensemble stored in section_frame_sequence; valid values are + defined in [ensemble_type wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad- + meta-info/wikis/metainfo/ensemble-type). + ''') + + geometry_optimization_energy_change = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of threshold for the energy_total change between two geometry optimization + steps, as convergence criterion of the geometry_optimization_method. A geometry + optimization is considered converged when the energy_total change between two + geometry optimization steps is below the threshold (possibly in combination with + other criteria) + ''', + categories=[settings_sampling, settings_geometry_optimization]) + + geometry_optimization_geometry_change = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='meter', + description=''' + Value of threshold for the displacement of the nuclei between two geometry + optimization steps as convergence criterion of the geometry_optimization_method. A + geometry optimization is considered converged when the maximum among the + displacements of the nuclei between two geometry optimization steps is below the + threshold (possibly in combination with other criteria) + ''', + categories=[settings_sampling, settings_geometry_optimization]) + + geometry_optimization_method = Quantity( + type=str, + shape=[], + description=''' + Algorithm for the geometry optimization. Allowed values are listed in the + [geometry_optimization_method wiki page](https://gitlab.mpcdf.mpg.de/nomad- + lab/nomad-meta-info/wikis/metainfo/geometry-optimization-method). + ''', + categories=[settings_sampling, settings_geometry_optimization]) + + geometry_optimization_threshold_force = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='newton', + description=''' + Value of threshold for the force modulus as convergence criterion of the + geometry_optimization_method. A geometry optimization is considered converged when + the maximum of the moduli of the force on each of the atoms is below this + threshold (possibly in combination with other criteria) + ''', + categories=[settings_sampling, settings_geometry_optimization]) + + sampling_method_expansion_order = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Order up to which the potential energy surface was expanded in a Taylor series + (see sampling_method). + ''') + + sampling_method = Quantity( + type=str, + shape=[], + description=''' + Type of method used to do the sampling. + + Allowed values are: + + | Sampling method | Description | + + | ------------------------------ | -------------------------------- | + + | `"geometry_optimization"` | Geometry optimization | + + | `"molecular_dynamics"` | Molecular dynamics | + + | `"montecarlo"` | (Metropolis) Monte Carlo | + + | `"steered_molecular_dynamics"` | Steered molecular dynamics (with time dependent + external forces) | + + | `"meta_dynamics"` | Biased molecular dynamics with history- + dependent Hamiltonian | + + | `"wang_landau_montecarlo"` | Monte Carlo according to the Wang-Landau + formulation. | + + | `"blue_moon"` | Blue Moon sampling | + + | `"langevin_dynamics"` | Langevin dynamics | + + | `"taylor_expansion"` | Taylor expansion of the potential energy + surface | + ''') + + +class section_scf_iteration(MSection): + ''' + Every section_scf_iteration represents a self-consistent field (SCF) iteration, see + scf_info, and gives detailed information on the SCF procedure of the specified + quantities. + ''' + + m_def = Section(validate=False) + + electronic_kinetic_energy_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Electronic kinetic energy as defined in XC_method during the self-consistent field + (SCF) iterations. + ''', + categories=[energy_value, energy_component]) + + energy_change_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Stores the change of total energy with respect to the previous self-consistent + field (SCF) iteration. + ''', + categories=[energy_value, error_estimate_contribution]) + + energy_correction_entropy_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Entropy correction to the potential energy to compensate for the change in + occupation so that forces at finite T do not need to keep the change of occupation + in account. The array lists the values of the entropy correction for each self- + consistent field (SCF) iteration. Defined consistently with XC_method. + ''', + categories=[energy_value, energy_component]) + + energy_correction_hartree_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Correction to the density-density electrostatic energy in the sum of eigenvalues + (that uses the mixed density on one side), and the fully consistent density- + density electrostatic energy during the self-consistent field (SCF) iterations. + Defined consistently with XC_method. + ''', + categories=[energy_value, energy_component]) + + energy_electrostatic_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Total electrostatic energy (nuclei + electrons) during each self-consistent field + (SCF) iteration. + ''', + categories=[energy_value, energy_component]) + + energy_free_per_atom_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Free energy per atom (whose minimum gives the smeared occupation density + calculated with smearing_kind) calculated with XC_method during the self- + consistent field (SCF) iterations. + ''', + categories=[energy_value, energy_component_per_atom]) + + energy_free_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Free energy (whose minimum gives the smeared occupation density calculated with + smearing_kind) calculated with the method described in XC_method during the self- + consistent field (SCF) iterations. + ''', + categories=[energy_component, energy_value, energy_total_potential]) + + energy_hartree_error_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Error in the Hartree (electrostatic) potential energy during each self-consistent + field (SCF) iteration. Defined consistently with XC_method. + ''', + categories=[energy_value, error_estimate_contribution]) + + energy_sum_eigenvalues_per_atom_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the energy per atom, where the energy is defined as the sum of the + eigenvalues of the Hamiltonian matrix given by XC_method, during each self- + consistent field (SCF) iteration. + ''', + categories=[energy_value, energy_component_per_atom]) + + energy_sum_eigenvalues_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Sum of the eigenvalues of the Hamiltonian matrix defined by XC_method, during each + self-consistent field (SCF) iteration. + ''', + categories=[energy_value, energy_component]) + + energy_total_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the total electronic energy calculated with the method described in + XC_method during each self-consistent field (SCF) iteration. + ''', + categories=[energy_component, energy_value, energy_total_potential]) + + energy_total_T0_per_atom_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the total energy, calculated with the method described in XC_method per + atom extrapolated to $T=0$, based on a free-electron gas argument, during each + self-consistent field (SCF) iteration. + ''', + categories=[energy_total_potential_per_atom, energy_value, energy_component]) + + energy_total_T0_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the total energy (or equivalently free energy), calculated with the + method described in XC_method and extrapolated to $T=0$, based on a free-electron + gas argument, during each self-consistent field (SCF) iteration. + ''', + categories=[energy_component, energy_value, energy_total_potential]) + + energy_XC_potential_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value for exchange-correlation (XC) potential energy: the integral of the first + order derivative of the functional stored in XC_functional (integral of + v_xc*electron_density), i.e., the component of XC that is in the sum of the + eigenvalues. Values are given for each self-consistent field (SCF) iteration + (i.e., not the converged value, the latter being stored in energy_XC_potential). + ''', + categories=[energy_value, energy_component]) + + energy_XC_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value for exchange-correlation (XC) energy obtained during each self-consistent + field (SCF) iteration, using the method described in XC_method. + ''', + categories=[energy_value, energy_component]) + + spin_S2_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Stores the value of the total spin moment operator $S^2$ during the self- + consistent field (SCF) iterations of the XC_method. It can be used to calculate + the spin contamination in spin-unrestricted calculations. + ''') + + time_scf_iteration_cpu1_end = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the end time of a self-consistent field (SCF) iteration on CPU 1. + ''', + categories=[accessory_info, time_info]) + + time_scf_iteration_cpu1_start = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the start time of a self-consistent field (SCF) iteration on CPU 1. + ''', + categories=[accessory_info, time_info]) + + time_scf_iteration_date_end = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the end date of a self-consistent field (SCF) iteration as time since the + *Unix epoch* (00:00:00 UTC on 1 January 1970) in seconds. For date and times + without a timezone, the default timezone GMT is used. + ''', + categories=[accessory_info, time_info]) + + time_scf_iteration_date_start = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the start date of a self-consistent field (SCF) iteration as time since the + *Unix epoch* (00:00:00 UTC on 1 January 1970) in seconds. For date and times + without a timezone, the default timezone GMT is used. + ''', + categories=[accessory_info, time_info]) + + time_scf_iteration_wall_end = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the internal wall-clock time at the end of a self-consistent field (SCF) + iteration. + ''', + categories=[accessory_info, time_info]) + + time_scf_iteration_wall_start = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the internal wall-clock time from the start of a self-consistent field + (SCF) iteration. + ''', + categories=[accessory_info, time_info]) + + +class section_single_configuration_calculation(MSection): + ''' + Every section_single_configuration_calculation section contains the values computed + during a *single configuration calculation*, i.e. a calculation performed on a given + configuration of the system (as defined in section_system) and a given computational + method (e.g., exchange-correlation method, basis sets, as defined in section_method). + + The link between the current section_single_configuration_calculation and the related + section_system and section_method sections is established by the values stored in + single_configuration_calculation_to_system_ref and + single_configuration_to_calculation_method_ref, respectively. + + The reason why information on the system configuration and computational method is + stored separately is that several *single configuration calculations* can be performed + on the same system configuration, viz. several system configurations can be evaluated + with the same computational method. This storage strategy avoids redundancies. + ''' + + m_def = Section(validate=False) + + atom_forces_free_raw = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 3], + unit='newton', + description=''' + Forces acting on the atoms, calculated as minus gradient of energy_free, + **without** constraints. The derivatives with respect to displacements of nuclei + are evaluated in Cartesian coordinates. The (electronic) energy_free contains the + change in (fractional) occupation of the electronic eigenstates, which are + accounted for in the derivatives, yielding a truly energy-conserved quantity. + These forces may contain unitary transformations (center-of-mass translations and + rigid rotations for non-periodic systems) that are normally filtered separately + (see atom_forces_free for the filtered counterpart). Forces due to constraints + such as fixed atoms, distances, angles, dihedrals, etc. are also considered + separately (see atom_forces_free for the filtered counterpart). + ''', + categories=[atom_forces_type]) + + atom_forces_free = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 3], + unit='newton', + description=''' + Forces acting on the atoms, calculated as minus gradient of energy_free, + **including** constraints, if present. The derivatives with respect to + displacements of the nuclei are evaluated in Cartesian coordinates. 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. In addition, these forces + are obtained by filtering out the unitary transformations (center-of-mass + translations and rigid rotations for non-periodic systems, see + atom_forces_free_raw for the unfiltered counterpart). Forces due to constraints + such as fixed atoms, distances, angles, dihedrals, etc. are included (see + atom_forces_free_raw for the unfiltered counterpart). + ''', + categories=[atom_forces_type]) + + atom_forces_raw = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 3], + unit='newton', + description=''' + Forces acting on the atoms, calculated as minus gradient of energy_total, + **without** constraints. The derivatives with respect to displacements of the + nuclei are evaluated in Cartesian coordinates. These forces may contain unitary + transformations (center-of-mass translations and rigid rotations for non-periodic + systems) that are normally filtered separately (see atom_forces for the filtered + counterpart). Forces due to constraints such as fixed atoms, distances, angles, + dihedrals, etc. are also considered separately (see atom_forces for the filtered + counterpart). + ''', + categories=[atom_forces_type]) + + atom_forces_T0_raw = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 3], + unit='newton', + description=''' + Forces acting on the atoms, calculated as minus gradient of energy_total_T0, + **without** constraints. The derivatives with respect to displacements of the + nuclei are evaluated in Cartesian coordinates. These forces may contain unitary + transformations (center-of-mass translations and rigid rotations for non-periodic + systems) that are normally filtered separately (see atom_forces_T0 for the + filtered counterpart). Forces due to constraints such as fixed atoms, distances, + angles, dihedrals, etc. are also considered separately (see atom_forces_T0 for the + filtered counterpart). + ''', + categories=[atom_forces_type]) + + atom_forces_T0 = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 3], + unit='newton', + description=''' + Forces acting on the atoms, calculated as minus gradient of energy_total_T0, + **including** constraints, if present. The derivatives with respect to + displacements of the nuclei are evaluated in Cartesian coordinates. In addition, + these forces are obtained by filtering out the unitary transformations (center-of- + mass translations and rigid rotations for non-periodic systems, see + atom_forces_free_T0_raw for the unfiltered counterpart). Forces due to constraints + such as fixed atoms, distances, angles, dihedrals, etc. are also included (see + atom_forces_free_T0_raw for the unfiltered counterpart). + ''', + categories=[atom_forces_type]) + + atom_forces = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 3], + unit='newton', + description=''' + Forces acting on the atoms, calculated as minus gradient of energy_total, + **including** constraints, if present. The derivatives with respect to + displacements of nuclei are evaluated in Cartesian coordinates. In addition, these + forces are obtained by filtering out the unitary transformations (center-of-mass + translations and rigid rotations for non-periodic systems, see + atom_forces_free_raw for the unfiltered counterpart). Forces due to constraints + such as fixed atoms, distances, angles, dihedrals, etc. are included (see + atom_forces_raw for the unfiltered counterpart). + ''', + categories=[atom_forces_type]) + + electronic_kinetic_energy = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Self-consistent electronic kinetic energy as defined in XC_method. + ''', + categories=[energy_value, energy_component]) + + energy_C = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Correlation (C) energy calculated with the method described in XC_functional. + ''', + categories=[energy_value, energy_type_C, energy_component]) + + energy_correction_entropy = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Entropy correction to the potential energy to compensate for the change in + occupation so that forces at finite T do not need to keep the change of occupation + in account. Defined consistently with XC_method. + ''', + categories=[energy_value, energy_component]) + + energy_correction_hartree = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Correction to the density-density electrostatic energy in the sum of eigenvalues + (that uses the mixed density on one side), and the fully consistent density- + density electrostatic energy. Defined consistently with XC_method. + ''', + categories=[energy_value, energy_component]) + + energy_current = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the energy calculated with calculation_method_current. energy_current is + equal to energy_total for non-perturbative methods. For perturbative methods, + energy_current is equal to the correction: energy_total minus energy_total of the + calculation_to_calculation_ref with calculation_to_calculation_kind = + starting_point (see the [method_to_method_kind wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/method- + to-method-kind)). See also [energy_current wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/energy- + current). + ''', + categories=[energy_component, energy_value, energy_total_potential]) + + energy_electrostatic = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Total electrostatic energy (nuclei + electrons), defined consistently with + calculation_method. + ''', + categories=[energy_value, energy_component]) + + energy_free_per_atom = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Free energy per atom (whose minimum gives the smeared occupation density + calculated with smearing_kind) calculated with XC_method. + ''', + categories=[energy_value, energy_component_per_atom]) + + energy_free = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Free energy (nuclei + electrons) (whose minimum gives the smeared occupation + density calculated with smearing_kind) calculated with the method described in + XC_method. + ''', + categories=[energy_component, energy_value, energy_total_potential]) + + energy_hartree_error = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Error in the Hartree (electrostatic) potential energy. Defined consistently with + XC_method. + ''', + categories=[energy_value, error_estimate_contribution]) + + energy_hartree_fock_X_scaled = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Scaled exact-exchange energy that depends on the mixing parameter of the + functional. For example in hybrid functionals, the exchange energy is given as a + linear combination of exact-energy and exchange energy of an approximate DFT + functional; the exact exchange energy multiplied by the mixing coefficient of the + hybrid functional would be stored in this metadata. Defined consistently with + XC_method. + ''', + categories=[energy_value, energy_component]) + + energy_hartree_fock_X = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Converged exact-exchange (Hartree-Fock) energy. Defined consistently with + XC_method. + ''', + categories=[energy_type_X, energy_value, energy_component]) + + energy_method_current = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the energy calculated with the method calculation_method_current. + Depending on calculation_method_kind it might be a total energy or only a + correction. + ''', + categories=[energy_value, energy_component]) + + energy_sum_eigenvalues_per_atom = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the energy per atom, where the energy is defined as the sum of the + eigenvalues of the Hamiltonian matrix given by XC_method. + ''', + categories=[energy_value, energy_component_per_atom]) + + energy_sum_eigenvalues = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Sum of the eigenvalues of the Hamiltonian matrix defined by XC_method. + ''', + categories=[energy_value, energy_component]) + + energy_T0_per_atom = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the total energy per atom, calculated with the method described in + XC_method and extrapolated to $T=0$, based on a free-electron gas argument. + ''', + categories=[energy_total_potential_per_atom, energy_value, energy_component]) + + energy_total_T0_per_atom = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the total energy, calculated with the method described in XC_method per + atom extrapolated to $T=0$, based on a free-electron gas argument. + ''', + categories=[energy_total_potential_per_atom, energy_value, energy_component]) + + energy_total_T0 = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the total energy (or equivalently free energy), calculated with the + method described in XC_method and extrapolated to $T=0$, based on a free-electron + gas argument. + ''', + categories=[energy_component, energy_value, energy_total_potential]) + + energy_total = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the total energy, calculated with the method described in XC_method and + extrapolated to $T=0$, based on a free-electron gas argument. + ''', + categories=[energy_component, energy_value, energy_total_potential]) + + energy_XC_functional = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the exchange-correlation (XC) energy calculated with the functional + stored in XC_functional. + ''', + categories=[energy_type_XC, energy_value, energy_component]) + + energy_XC_potential = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the exchange-correlation (XC) potential energy: the integral of the first + order derivative of the functional stored in XC_functional (integral of + v_xc*electron_density), i.e., the component of XC that is in the sum of the + eigenvalues. Value associated with the configuration, should be the most converged + value. + ''', + categories=[energy_value, energy_component]) + + energy_XC = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the exchange-correlation (XC) energy calculated with the method described + in XC_method. + ''', + categories=[energy_type_XC, energy_value, energy_component]) + + energy_X = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value fo the exchange (X) energy calculated with the method described in + XC_method. + ''', + categories=[energy_type_X, energy_value, energy_component]) + + energy_zero_point = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Value for the converged zero-point vibrations energy calculated using the method + described in zero_point_method , and used in energy_current . + ''') + + hessian_matrix = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 'number_of_atoms', 3, 3], + description=''' + The matrix with the second derivative with respect to atom displacements. + ''') + + message_debug_evaluation = Quantity( + type=str, + shape=[], + description=''' + A debugging message of the computational program, associated with a *single + configuration calculation* (see section_single_configuration_calculation). + ''', + categories=[message_debug]) + + message_error_evaluation = Quantity( + type=str, + shape=[], + description=''' + An error message of the computational program, associated with a *single + configuration calculation* (see section_single_configuration_calculation). + ''', + categories=[message_info, message_debug, message_warning, message_error]) + + message_info_evaluation = Quantity( + type=str, + shape=[], + description=''' + An information message of the computational program, associated with a *single + configuration calculation* (see section_single_configuration_calculation). + ''', + categories=[message_info, message_debug]) + + message_warning_evaluation = Quantity( + type=str, + shape=[], + description=''' + A warning message of the computational program. + ''', + categories=[message_info, message_debug, message_warning]) + + number_of_scf_iterations = Quantity( + type=int, + shape=[], + description=''' + Gives the number of performed self-consistent field (SCF) iterations at a specfied + level of theory. + ''', + categories=[scf_info]) + + parsing_message_debug_evaluation = Quantity( + type=str, + shape=[], + description=''' + This field is used for debugging messages of the parsing program associated with a + run, see section_run. + ''', + categories=[parsing_message_debug]) + + parsing_message_error_single_configuration = Quantity( + type=str, + shape=[], + description=''' + This field is used for error messages of the parsing program associated with a + single configuration calculation, see section_single_configuration_calculation. + ''', + categories=[parsing_message_info, parsing_message_error, parsing_message_warning, parsing_message_debug]) + + parsing_message_info_single_configuration = Quantity( + type=str, + shape=[], + description=''' + This field is used for info messages of the parsing program associated with a + single configuration calculation, see section_single_configuration_calculation. + ''', + categories=[parsing_message_info, parsing_message_debug]) + + parsing_message_warning_evaluation = Quantity( + type=str, + shape=[], + description=''' + This field is used for warning messages of the parsing program associated with a + run, see section_run. + ''', + categories=[parsing_message_info, parsing_message_warning, parsing_message_debug]) + + single_configuration_calculation_converged = Quantity( + type=bool, + shape=[], + description=''' + Determines whether a *single configuration calculation* in + section_single_configuration_calculation is converged. + ''') + + single_configuration_calculation_to_system_ref = Quantity( + type=Reference(SectionProxy('section_system')), + shape=[], + description=''' + Reference to the system (atomic configuration, cell, ...) that is calculated in + section_single_configuration_calculation. + ''') + + single_configuration_to_calculation_method_ref = Quantity( + type=Reference(SectionProxy('section_method')), + shape=[], + description=''' + Reference to the method used for the calculation in + section_single_configuration_calculation. + ''') + + spin_S2 = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Stores the value of the total spin moment operator $S^2$ for the converged + wavefunctions calculated with the XC_method. It can be used to calculate the spin + contamination in spin-unrestricted calculations. + ''') + + stress_tensor = Quantity( + type=np.dtype(np.float64), + shape=[3, 3], + unit='pascal', + description=''' + Stores the final value of the default stress tensor consistent with energy_total + and calculated with the method specified in stress_tensor_method. + + This value is used (if needed) for, e.g., molecular dynamics and geometry + optimization. Alternative definitions of the stress tensor can be assigned with + stress_tensor_kind + ''', + categories=[stress_tensor_type]) + + time_calculation = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the wall-clock time needed for a calculation using + calculation_method_current. Basically, it tracks the real time that has been + elapsed from start to end. + ''', + categories=[accessory_info, time_info]) + + time_single_configuration_calculation_cpu1_end = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the end time of the *single configuration calculation* (see + section_single_configuration_calculation) on CPU 1. + ''', + categories=[accessory_info, time_info]) + + time_single_configuration_calculation_cpu1_start = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the start time of the *single configuration calculation* (see + section_single_configuration_calculation) on CPU 1. + ''', + categories=[accessory_info, time_info]) + + time_single_configuration_calculation_date_end = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the end date of the *single configuration calculation* (see + section_single_configuration_calculation) as time since the *Unix epoch* (00:00:00 + UTC on 1 January 1970) in seconds. For date and times without a timezone, the + default timezone GMT is used. + ''', + categories=[accessory_info, time_info]) + + time_single_configuration_calculation_date_start = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the start date of the *single configuration calculation* (see + section_single_configuration_calculation) as time since the *Unix epoch* (00:00:00 + UTC on 1 January 1970) in seconds. For date and times without a timezone, the + default timezone GMT is used. + ''', + categories=[accessory_info, time_info]) + + time_single_configuration_calculation_wall_end = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the internal wall-clock time at the end of the *single configuration + calculation* (see section_single_configuration_calculation). + ''', + categories=[accessory_info, time_info]) + + time_single_configuration_calculation_wall_start = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the internal wall-clock time from the start of the *single configuration + calculation* (see section_single_configuration_calculation). + ''', + categories=[accessory_info, time_info]) + + zero_point_method = Quantity( + type=str, + shape=[], + description=''' + Describes the zero-point vibrations method. If skipped or an empty string is used, + it means no zero-point vibrations correction is applied. + ''') + + section_atom_projected_dos = SubSection( + sub_section=SectionProxy('section_atom_projected_dos'), + repeats=True) + + section_atomic_multipoles = SubSection( + sub_section=SectionProxy('section_atomic_multipoles'), + repeats=True) + + section_basis_set = SubSection( + sub_section=SectionProxy('section_basis_set'), + repeats=True) + + section_calculation_to_calculation_refs = SubSection( + sub_section=SectionProxy('section_calculation_to_calculation_refs'), + repeats=True) + + section_calculation_to_folder_refs = SubSection( + sub_section=SectionProxy('section_calculation_to_folder_refs'), + repeats=True) + + section_dos = SubSection( + sub_section=SectionProxy('section_dos'), + repeats=True) + + section_eigenvalues = SubSection( + sub_section=SectionProxy('section_eigenvalues'), + repeats=True) + + section_energy_code_independent = SubSection( + sub_section=SectionProxy('section_energy_code_independent'), + repeats=True) + + section_energy_van_der_Waals = SubSection( + sub_section=SectionProxy('section_energy_van_der_Waals'), + repeats=True) + + section_k_band_normalized = SubSection( + sub_section=SectionProxy('section_k_band_normalized'), + repeats=True) + + section_k_band = SubSection( + sub_section=SectionProxy('section_k_band'), + repeats=True) + + section_scf_iteration = SubSection( + sub_section=SectionProxy('section_scf_iteration'), + repeats=True) + + section_species_projected_dos = SubSection( + sub_section=SectionProxy('section_species_projected_dos'), + repeats=True) + + section_stress_tensor = SubSection( + sub_section=SectionProxy('section_stress_tensor'), + repeats=True) + + section_volumetric_data = SubSection( + sub_section=SectionProxy('section_volumetric_data'), + repeats=True) + + +class section_species_projected_dos(MSection): + ''' + Section collecting the information on a species-projected density of states (DOS) + evaluation. + ''' + + m_def = Section(validate=False) + + number_of_lm_species_projected_dos = Quantity( + type=int, + shape=[], + description=''' + Gives the number of $l$, $m$ combinations for the species-projected density of + states (DOS) defined in section_species_projected_dos. + ''') + + number_of_species_projected_dos_values = Quantity( + type=int, + shape=[], + description=''' + Gives the number of energy values for the species-projected density of states + (DOS) defined in section_species_projected_dos. + ''') + + number_of_species = Quantity( + type=int, + shape=[], + description=''' + Gives the number of species for the species-projected density of states (DOS) + defined in section_species_projected_dos. + ''') + + species_projected_dos_energies_normalized = Quantity( + type=np.dtype(np.float64), + shape=['number_of_species_projected_dos_values'], + unit='joule', + description=''' + Contains the set of discrete energy values with respect to the top of the valence + band for the species-projected density of states (DOS). It is derived from the + species_projected_dos_energies species field. + ''') + + species_projected_dos_energies = Quantity( + type=np.dtype(np.float64), + shape=['number_of_species_projected_dos_values'], + unit='joule', + description=''' + Contains the set of discrete energy values for the species-projected density of + states (DOS). + ''') + + species_projected_dos_lm = Quantity( + type=np.dtype(np.int32), + shape=['number_of_lm_species_projected_dos', 2], + description=''' + Consists of tuples of $l$ and $m$ values for all given values in the + species_projected_dos_values_lm species field. + + The quantum number $l$ represents the azimuthal quantum number, whereas for the + quantum number $m$, besides the conventional use as magnetic quantum number ($l+1$ + integer values from $-l$ to $l$), a set of different conventions is accepted. The + adopted convention is specified by atom_projected_dos_m_kind. + ''') + + species_projected_dos_m_kind = Quantity( + type=str, + shape=[], + description=''' + Specifies the kind of the integer numbers $m$ used in species_projected_dos_lm. + + Allowed values are listed in the [m_kind wiki + page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/m-kind) + and can be (quantum) numbers of + + * spherical + + * polynomial + + * real_orbital + + * integrated + + functions or values. + ''') + + species_projected_dos_species_label = Quantity( + type=str, + shape=['number_of_species'], + description=''' + Contains labels of the atomic species for the species-projected density of states + (DOS). + + Differently from atom_labels, which allow more than one label for the same atomic + species (by adding a number or a string to the label), this list is expected to + refer to actual atomic species, i.e. belonging to the periodic table of elements. + Thus, the species-projected DOS are expected to be as many as the different atomic + species in the system. + ''') + + species_projected_dos_values_lm = Quantity( + type=np.dtype(np.float64), + shape=['number_of_lm_species_projected_dos', 'number_of_spin_channels', 'number_of_species', 'number_of_species_projected_dos_values'], + description=''' + Holds species-projected density of states (DOS) values, divided into contributions + from each $l,m$ channel. + + Here, there are as many species-projected DOS as the number of species, + number_of_species. The list of labels of the species is given in + species_projected_dos_species_label. + ''') + + species_projected_dos_values_total = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_species', 'number_of_species_projected_dos_values'], + description=''' + Holds species-projected density of states (DOS) values, summed up over all + azimuthal quantum numbers $l$. + + Here, there are as many species-projected DOS as the number of species, + number_of_species. The list of labels of the species is given in + species_projected_dos_species_label. + ''') + + +class section_springer_material(MSection): + ''' + Every section_springer_material contains results of classification of materials with + the same formula according to Springer Materials - it contains + section_springer_classsification, section_springer_compound, section_springer_id, + section_springer_references + ''' + + m_def = Section(validate=False) + + springer_id = Quantity( + type=str, + shape=[], + description=''' + Id of the classified material according to Springer Materials + ''') + + springer_alphabetical_formula = Quantity( + type=str, + shape=[], + description=''' + The alphabetical formula of the material according to Springer Materials Database + ''') + + springer_url = Quantity( + type=str, + shape=[], + description=''' + Url to the source page in Springer Materials describing the current entry + ''') + + springer_compound_class = Quantity( + type=str, + shape=['N'], + description=''' + Name of a class of the current compound, as defined in by Springer Materials. This + is a property of the chemical formula of the compound + ''') + + springer_classification = Quantity( + type=str, + shape=['N'], + description=''' + Contains the classification name of the current material according to Springer + Materials + ''') + + section_springer_id = SubSection( + sub_section=SectionProxy('section_springer_id'), + repeats=True) + + +class section_springer_id(MSection): + ''' + Identifiers used by Springer Materials + ''' + + m_def = Section(validate=False) + + +class section_std_system(MSection): + ''' + Section containing symmetry information that is specific to the standardized system. + The standardized system is defined as given by spglib and the details can be found + from https://arxiv.org/abs/1506.01455 + ''' + + m_def = Section(validate=False) + + atom_positions_std = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms_std', 3], + description=''' + Standardized atom positions in reduced units. + ''') + + atomic_numbers_std = Quantity( + type=np.dtype(np.int32), + shape=['number_of_atoms_std'], + description=''' + Atomic numbers of the atoms in the standardized cell. + ''') + + equivalent_atoms_std = Quantity( + type=np.dtype(np.int32), + shape=['number_of_atoms_std'], + description=''' + Gives a mapping table of atoms to symmetrically independent atoms in the + standardized cell. This is used to find symmetrically equivalent atoms. + ''') + + lattice_vectors_std = Quantity( + type=np.dtype(np.float64), + shape=[3, 3], + unit='meter', + description=''' + Standardized lattice vectors of the conventional cell. The vectors are the rows of + this matrix. + ''') + + number_of_atoms_std = Quantity( + type=int, + shape=[], + description=''' + Number of atoms in standardized system. + ''') + + wyckoff_letters_std = Quantity( + type=str, + shape=['number_of_atoms_std'], + description=''' + Wyckoff letters for atoms in the standardized cell. + ''') + + +class section_stress_tensor(MSection): + ''' + Section collecting alternative values to stress_tensor that have been calculated. + + This section allows the storage of multiple definitions and evaluated values of the + stress tensor, while only one definition is used for, e.g., molecular dynamics or + geometry optimization (if needed). + ''' + + m_def = Section(validate=False) + + stress_tensor_kind = Quantity( + type=str, + shape=[], + description=''' + Specifies the method used to compute the stress tensor stored in + stress_tensor_value. This is an *alternative* to the stress tensor defined in + stress_tensor_method, which is stored in stress_tensor. + + This field allows for multiple definitions and evaluated values of the stress + tensor, while only one definition is used for, e.g., molecular dynamics and + geometry optimization. + ''') + + stress_tensor_value = Quantity( + type=np.dtype(np.float64), + shape=[3, 3], + unit='pascal', + description=''' + Contains the value of the stress tensor of the kind defined in stress_tensor_kind. + This is an *alternative* to the stress tensor defined in stress_tensor_method. + + This field allows for multiple definitions and evaluated values of the stress + tensor, while only one definition is used for, e.g., molecular dynamics and + geometry optimization. + ''', + categories=[stress_tensor_type]) + + +class section_symmetry(MSection): + ''' + Section containing information about the symmetry properties of the system. + ''' + + m_def = Section(validate=False) + + bravais_lattice = Quantity( + type=str, + shape=[], + description=''' + Identifier for the Bravais lattice in Pearson notation. The first lowercase letter + identifies the crystal family and can be one of the following: a (triclinic), b + (monoclinic), o (orthorhombic), t (tetragonal), h (hexagonal) or c (cubic). The + second uppercase letter identifies the centring and can be one of the following: P + (primitive), S (face centred), I (body centred), R (rhombohedral centring) or F + (all faces centred). + ''') + + choice = Quantity( + type=str, + shape=[], + description=''' + String that specifies the centering, origin and basis vector settings of the 3D + space group that defines the symmetry group of the simulated physical system (see + section_system). Values are as defined by spglib. + ''') + + crystal_system = Quantity( + type=str, + shape=[], + description=''' + Name of the crystal system. Can be one of the following: triclinic, monoclinic, + orthorhombic, tetragonal, trigonal, hexagonal or cubic. + ''') + + hall_number = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + The Hall number for this system. + ''') + + hall_symbol = Quantity( + type=str, + shape=[], + description=''' + The Hall symbol for this system. + ''') + + international_short_symbol = Quantity( + type=str, + shape=[], + description=''' + Specifies the International Union of Crystallography (IUC) short symbol of the 3D + space group of this system + ''') + + origin_shift = Quantity( + type=np.dtype(np.float64), + shape=[3], + description=''' + Vector $\\mathbf{p}$ from the origin of the standardized system to the origin of + the original system. Together with the matrix $\\mathbf{P}$, found in + space_group_3D_transformation_matrix, the transformation between the standardized + coordinates $\\mathbf{x}_s$ and original coordinates $\\mathbf{x}$ is then given by + $\\mathbf{x}_s = \\mathbf{P} \\mathbf{x} + \\mathbf{p}$. + ''') + + point_group = Quantity( + type=str, + shape=[], + description=''' + Symbol of the crystallographic point group in the Hermann-Mauguin notation. + ''') + + space_group_number = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Specifies the International Union of Crystallography (IUC) number of the 3D space + group of this system. + ''') + + symmetry_method = Quantity( + type=str, + shape=[], + description=''' + Identifies the source of the symmetry information contained within this section. + If equal to 'spg_normalized' the information comes from a normalization step. + ''') + + transformation_matrix = Quantity( + type=np.dtype(np.float64), + shape=[3, 3], + description=''' + Matrix $\\mathbf{P}$ that is used to transform the standardized coordinates to the + original coordinates. Together with the vector $\\mathbf{p}$, found in + space_group_3D_origin_shift, the transformation between the standardized + coordinates $\\mathbf{x}_s$ and original coordinates $\\mathbf{x}$ is then given by + $\\mathbf{x}_s = \\mathbf{P} \\mathbf{x} + \\mathbf{p}$. + ''') + + section_original_system = SubSection( + sub_section=SectionProxy('section_original_system'), + repeats=True) + + section_primitive_system = SubSection( + sub_section=SectionProxy('section_primitive_system'), + repeats=True) + + section_std_system = SubSection( + sub_section=SectionProxy('section_std_system'), + repeats=True) + + +class section_system_to_system_refs(MSection): + ''' + Section that describes the relationship between different section_system sections. + + For instance, if a phonon calculation using a finite difference approach is performed + the force evaluation is typically done in a larger supercell but the properties such + as the phonon band structure are still calculated for the primitive cell. + + The kind of relationship between the system defined in this section and the referenced + one is described by system_to_system_kind. The referenced section_system is identified + via system_to_system_ref. + ''' + + m_def = Section(validate=False) + + system_to_system_kind = Quantity( + type=str, + shape=[], + description=''' + String defining the relationship between the referenced section_system and the + present section_system. Often systems are connected for example if a phonon + calculation using finite differences is performed the force ealuation is done in a + larger supercell but properties such as the phonon band structure are still + calculated for the primitive cell. Hence, the need of keeping track of these + connected systems. The referenced system is identified via system_to_system_ref. + ''') + + system_to_system_ref = Quantity( + type=Reference(SectionProxy('section_system')), + shape=[], + description=''' + Reference to another system. The kind of relationship between the present and the + referenced section_system is specified by system_to_system_kind. + ''') + + +class section_system(MSection): + ''' + Every section_system contains all needed properties required to describe the simulated + physical system, e.g. the given atomic configuration, the definition of periodic cell + (if present), the external potentials and other parameters. + ''' + + m_def = Section(validate=False) + + atom_atom_number = Quantity( + type=np.dtype(np.int32), + shape=['number_of_sites'], + description=''' + Atomic number Z of the atom. + ''') + + atom_concentrations = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms'], + description=''' + concentration of the atom species in a variable composition, by default it should + be considered an array of ones. Summing these should give the number_of_sites + ''') + + atom_labels = Quantity( + type=str, + shape=['number_of_atoms'], + description=''' + Labels of the atoms. These strings identify the atom kind and conventionally start + with the symbol of the atomic species, possibly followed by the atomic number. The + same atomic species can be labeled with more than one atom_labels in order to + distinguish, e.g., atoms of the same species assigned to different atom-centered + basis sets or pseudo-potentials, or simply atoms in different locations in the + structure (e.g., bulk and surface). These labels can also be used for *particles* + that do not correspond to physical atoms (e.g., ghost atoms in some codes using + atom-centered basis sets). This metadata defines a configuration and is therefore + required. + ''', + categories=[configuration_core]) + + atom_positions = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 3], + unit='meter', + description=''' + Positions of all the atoms, in Cartesian coordinates. This metadata defines a + configuration and is therefore required. For alloys where concentrations of + species are given for each site in the unit cell, it stores the position of the + sites. + ''', + categories=[configuration_core]) + + atom_species = Quantity( + type=np.dtype(np.int32), + shape=['number_of_atoms'], + description=''' + Species of the atom (normally the atomic number Z, 0 or negative for unidentifed + species or particles that are not atoms. + ''') + + atom_velocities = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 3], + unit='meter / second', + description=''' + Velocities of the nuclei, defined as the change in Cartesian coordinates of the + nuclei with respect to time. + ''') + + configuration_periodic_dimensions = Quantity( + type=bool, + shape=[3], + description=''' + Array labeling which of the lattice vectors use periodic boundary conditions. Note + for the parser developers: This value is not expected to be given for each + section_single_configuration_calculation. It is assumed to be valid from the + section_single_configuration_calculation where it is defined for all subsequent + section_single_configuration_calculation in section_run, until redefined. + ''', + categories=[configuration_core]) + + configuration_raw_gid = Quantity( + type=str, + shape=[], + description=''' + checksum of the configuration_core, i.e. the geometry of the system. The values + are not normalized in any way so equivalent configurations might have different + values + ''') + + embedded_system = Quantity( + type=bool, + shape=[], + description=''' + Is the system embedded into a host geometry?. + ''', + categories=[configuration_core]) + + lattice_vectors = Quantity( + type=np.dtype(np.float64), + shape=[3, 3], + unit='meter', + description=''' + Holds the lattice vectors (in Cartesian coordinates) of the simulation cell. The + last (fastest) index runs over the $x,y,z$ Cartesian coordinates, and the first + index runs over the 3 lattice vectors. + ''', + categories=[configuration_core]) + + local_rotations = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 3, 3], + description=''' + A rotation matrix defining the orientation of each atom. If the rotation matrix + only needs to be specified for some atoms, the remaining atoms should set it to + the zero matrix (not the identity!) + ''') + + number_of_atoms = Quantity( + type=int, + shape=[], + description=''' + Stores the total number of atoms used in the calculation. For alloys where + concentrations of species are given for each site in the unit cell, it stores the + number of sites. + ''') + + number_of_sites = Quantity( + type=int, + shape=[], + description=''' + number of sites in a variable composition representation. By default (no variable + composition) it is the same as number_of_atoms. + ''') + + SC_matrix = Quantity( + type=np.dtype(np.int32), + shape=[3, 3], + description=''' + Specifies the matrix that transforms the unit-cell into the super-cell in which + the actual calculation is performed. + ''') + + simulation_cell = Quantity( + type=np.dtype(np.float64), + shape=[3, 3], + unit='meter', + description=''' + DEPRECATED, use lattice_vectors instead. Holds the lattice vectors (in Cartesian + coordinates) of the simulation cell. The last (fastest) index runs over the + $x,y,z$ Cartesian coordinates, and the first index runs over the 3 lattice + vectors. + ''', + categories=[configuration_core]) + + symmorphic = Quantity( + type=bool, + shape=[], + description=''' + Is the space group symmorphic? Set to True if all translations are zero. + ''') + + system_composition = Quantity( + type=str, + shape=[], + description=''' + Composition, i.e. cumulative chemical formula with atoms ordered by decreasing + atomic number Z. + ''') + + system_configuration_consistent = Quantity( + type=bool, + shape=[], + description=''' + Flag set is the configuration is consistent + ''') + + system_name = Quantity( + type=str, + shape=[], + description=''' + Specifies the name of the system. This information is provided by the user in some + codes and is stored here for debugging or visualization purposes. + ''') + + system_reweighted_composition = Quantity( + type=str, + shape=[], + description=''' + Composition, i.e. cumulative chemical with atoms ordered by decreasing atomic + number Z reweighted so that the sum is close to 100, and values are rounded up, + and are stable (i.e. it is a fixed point). + ''') + + system_type = Quantity( + type=str, + shape=[], + description=''' + Type of the system + ''') + + time_reversal_symmetry = Quantity( + type=bool, + shape=[], + description=''' + Is time-reversal symmetry present? + ''') + + chemical_composition = Quantity( + type=str, + shape=[], + description=''' + The chemical composition as full formula of the system, based on atom species. + ''') + + chemical_composition_reduced = Quantity( + type=str, + shape=[], + description=''' + The chemical composition as reduced formula of the system, based on atom species. + ''') + + chemical_composition_bulk_reduced = Quantity( + type=str, + shape=[], + description=''' + The chemical composition as reduced bulk formula of the system, based on atom + species. + ''') + + section_prototype = SubSection( + sub_section=SectionProxy('section_prototype'), + repeats=True) + + section_springer_material = SubSection( + sub_section=SectionProxy('section_springer_material'), + repeats=True) + + section_symmetry = SubSection( + sub_section=SectionProxy('section_symmetry'), + repeats=True) + + section_system_to_system_refs = SubSection( + sub_section=SectionProxy('section_system_to_system_refs'), + repeats=True) + + +class section_thermodynamical_properties(MSection): + ''' + Section that defines thermodynamical properties about the system in a + section_frame_sequence. + ''' + + m_def = Section(validate=False) + + helmholz_free_energy = Quantity( + type=np.dtype(np.float64), + shape=['number_of_thermodynamical_property_values'], + unit='joule', + description=''' + Stores the Helmholtz free energy per unit cell at constant volume of a + thermodynamic calculation. + ''') + + number_of_thermodynamical_property_values = Quantity( + type=int, + shape=[], + description=''' + Gives the number of thermal properties values available in + section_thermodynamical_properties. + ''') + + thermodynamical_properties_calculation_method = Quantity( + type=str, + shape=[], + description=''' + Method used to calculate the thermodynamic quantities. + + Valid values: + + * harmonic + ''') + + thermodynamical_property_heat_capacity_C_v = Quantity( + type=np.dtype(np.float64), + shape=['number_of_thermodynamical_property_values'], + unit='joule / kelvin', + description=''' + Stores the heat capacity per cell unit at constant volume. + ''') + + thermodynamical_property_temperature = Quantity( + type=np.dtype(np.float64), + shape=['number_of_thermodynamical_property_values'], + unit='kelvin', + description=''' + Specifies the temperatures at which properties such as the Helmholtz free energy + are calculated. + ''') + + vibrational_free_energy_at_constant_volume = Quantity( + type=np.dtype(np.float64), + shape=['number_of_thermodynamical_property_values'], + unit='joule', + description=''' + Holds the vibrational free energy per atom at constant volume. + ''') + + +class section_volumetric_data(MSection): + ''' + Section defining a set of volumetric data on a uniform real-space + + grid. + + To store an array (e.g. a density or a potential), define: + + * three grid point displacement vectors ("displacements") + + * number of grid points along each axis ("nx", "ny" and "nz") + + * the origin of the coordinate system, i.e. coordinates of the first grid + + point ("origin") + + * how many spatial functions are represented, e.g., two for a + + normal spin-polarized density ("multiplicity") + + * the values for each grid point ("values") + + * the unit that applies to each value ("units") + + * the kind of array represented by the volumetric data ("kind"). + + Allowed kinds are (please add new kinds as necessary): "density", + + "potential_hartree" and "potential_effective". Densities and + + potentials that are spin-polarized should have multiplicity two. + + Rules for more complex spins are to be decided when necessary. + ''' + + m_def = Section(validate=False) + + volumetric_data_displacements = Quantity( + type=np.dtype(np.float64), + shape=[3, 3], + unit='meter', + description=''' + displacement vectors between grid points along each axis; same indexing rules as + lattice_vectors. In many cases, displacements and number of points are related to + lattice_vectors through: [displacement] * [number of points + N] = + [lattice_vector],where N is 1 for periodic directions and 0 for non-periodic ones + ''') + + volumetric_data_kind = Quantity( + type=str, + shape=[], + description=''' + The kind of function, e.g. density, potential_hartree, potential_effective. The + unit of measurement for "volumetric_data_values" depends on the kind: Densities + are 1/m^3 and potentials are J/m^3. See [full specification on the + wiki](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/volumetric-data). + ''') + + volumetric_data_multiplicity = Quantity( + type=int, + shape=[], + description=''' + number of functions stored + ''') + + volumetric_data_nx = Quantity( + type=int, + shape=[], + description=''' + number of points along x axis + ''') + + volumetric_data_ny = Quantity( + type=int, + shape=[], + description=''' + number of points along y axis + ''') + + volumetric_data_nz = Quantity( + type=int, + shape=[], + description=''' + number of points along z axis + ''') + + volumetric_data_origin = Quantity( + type=np.dtype(np.float64), + shape=[3], + description=''' + location of the first grid point; same coordinate system as atom_positions when + applicable. + ''') + + volumetric_data_values = Quantity( + type=np.dtype(np.float64), + shape=['volumetric_data_multiplicity', 'volumetric_data_nx', 'volumetric_data_ny', 'volumetric_data_nz'], + description=''' + Array of shape (multiplicity, nx, ny, nz) containing the values. The units of + these values depend on which kind of data the values represent; see + "volumetric_data_kind". + ''') + + +class section_XC_functionals(MSection): + ''' + Section containing one of the exchange-correlation (XC) functionals for the present + section_method that are combined to form the XC_functional. + ''' + + m_def = Section(validate=False) + + XC_functional_name = Quantity( + type=str, + shape=[], + description=''' + Provides the name of one of the exchange and/or correlation (XC) functionals + combined in XC_functional. + + The valid unique names that can be used are listed in the [XC_functional wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/XC- + functional). + + *NOTE*: This value should refer to a correlation, an exchange or an exchange- + correlation functional only. + ''', + categories=[settings_physical_parameter]) + + XC_functional_parameters = Quantity( + type=typing.Any, + shape=[], + description=''' + Contains an associative list of non-default values of the parameters for the + functional declared in XC_functional_name of the section_XC_functionals section. + + For example, if a calculations using a hybrid XC functional (e.g., HSE06) + specifies a user-given value of the mixing parameter between exact and GGA + exchange, then this non-default value is stored in this metadata. + + The labels and units of these values are defined in the paragraph dedicated to the + specified functional declared in XC_functional_name of the [XC_functional wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/XC- + functional). + + If this metadata is not given, the default parameter values for the + XC_functional_name are assumed. + ''', + categories=[settings_physical_parameter]) + + XC_functional_weight = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Provides the value of the weight for the exchange, correlation, or exchange- + correlation functional declared in XC_functional_name (see + section_XC_functionals). + + This weight is used in the linear combination of the different XC functional names + (XC_functional_name) in different section_XC_functionals sections to form the + XC_functional used for evaluating energy_XC_functional and related quantities. + + If not specified then the default is set to 1. + ''', + categories=[settings_physical_parameter]) + + +m_package.__init_metainfo__() diff --git a/nomad/metainfo/elastic_extension.py b/nomad/metainfo/elastic_extension.py index c68b29e8f7ea9e187e263661913842536a86ef57..99f33675ca06d56f893f6429c80e673b2353de68 100644 --- a/nomad/metainfo/elastic_extension.py +++ b/nomad/metainfo/elastic_extension.py @@ -167,7 +167,7 @@ class ElasticDocument(SectionAnnotation): annotation.mapping = Date(**kwargs) elif isinstance(quantity.type, Reference): inner_document = ElasticDocument.create_document( - quantity.type.target_section_def, inner_doc=True, + cast(Section, quantity.type.target_section_def), inner_doc=True, prefix=annotation.field) annotation.mapping = Object(inner_document) elif isinstance(quantity.type, MEnum): diff --git a/nomad/metainfo/legacy.py b/nomad/metainfo/legacy.py index f394ba80c3c0312a6b6ab1716b877791088be9a9..5bfaa9591eadf0e068793c3cd256f52aad9fc589 100644 --- a/nomad/metainfo/legacy.py +++ b/nomad/metainfo/legacy.py @@ -1,5 +1,5 @@ -from typing import cast, Dict, List, Union, Any, Set, Iterable +from typing import cast, Dict, List, Union, Any, Set, Iterable, Tuple import numpy as np from pint.errors import UndefinedUnitError import os.path @@ -12,7 +12,7 @@ import nomad_meta_info from nomad import utils from nomad.metainfo import ( Definition, SubSection, Package, Quantity, Category, Section, Reference, units, - Environment, MEnum) + Environment, MEnum, MProxy) logger = utils.get_logger(__name__) @@ -23,11 +23,37 @@ _ignored_packages = [ 'repository.nomadmetainfo.json'] +def python_package_mapping(metainfo_package_name: str) -> Tuple[str, str]: + ''' + Compute the python package for the given metainfo package name. It returns + a tuple containing a file path and a package name. The filepath denotes the file + for this package within the nomad git project. + ''' + + split_mi_package_name = metainfo_package_name.split('_') + prefix = split_mi_package_name[0] + + if prefix in ['common', 'general', 'public']: + directory = 'nomad/datamodel/metainfo' + python_package_name = 'nomad.datamodel.metainfo.%s' % metainfo_package_name + + else: + directory = 'dependencies/parsers/%s/%sparser/metainfo' % (prefix, prefix) + python_package_name = '%sparser.metainfo.%s' % (prefix, metainfo_package_name) + + path = '%s/%s.py' % (directory, metainfo_package_name) + + return python_package_name, path + + class LegacyMetainfoEnvironment(Environment): ''' A metainfo environment with functions to create a legacy metainfo version of the environment. ''' + + legacy_package_name = Quantity(type=str) + def legacy_info(self, definition: Definition, *args, **kwargs) -> InfoKindEl: ''' Creates a legacy metainfo objects for the given definition. ''' super_names: List[str] = list() @@ -62,6 +88,11 @@ class LegacyMetainfoEnvironment(Environment): dtype_str = 'C' elif isinstance(definition.type, Reference): dtype_str = 'r' + if isinstance(definition.type.target_section_def, MProxy): + proxy = definition.type.target_section_def + proxy.m_proxy_section = definition + proxy.m_proxy_quantity = Quantity.type + definition.type.target_section_def = proxy.m_proxy_resolve() result['referencedSections'] = [definition.type.target_section_def.name] elif isinstance(definition.type, MEnum): dtype_str = 'C' @@ -136,6 +167,7 @@ class EnvironmentConversion: def create_env(self) -> LegacyMetainfoEnvironment: env = LegacyMetainfoEnvironment() + env.legacy_package_name = self.legacy_env.name.replace('.nomadmetainfo.json', '').replace('.', '_') for package_conv in self.package_conversions.values(): package = package_conv.package errors, warnings = package.m_all_validate() @@ -149,7 +181,6 @@ class EnvironmentConversion: (warnings[0], len(warnings) - 1, package)) env.m_add_sub_section(Environment.packages, package) package.init_metainfo() - return env def __fix_legacy_super_names(self): @@ -206,7 +237,9 @@ class PackageConversion: self.env_conversion = env_conversion self.legacy_defs: List[InfoKindEl] = [] - self.package = Package(name=name) + python_package, python_path = python_package_mapping(name) + + self.package = Package(name=name, a_python=(python_package, python_path)) self.quantities: Dict[str, Quantity] = {} self.logger = logger.bind(package=name) @@ -356,20 +389,18 @@ def convert(metainfo_path: str) -> LegacyMetainfoEnvironment: return EnvironmentConversion(metainfo_path).create_env() -def generate_metainfo_code(metainfo_env: Environment, directory: str = None): +def generate_metainfo_code(metainfo_env: LegacyMetainfoEnvironment): ''' Generates python code with metainfo definitions for all packages in the given environement Arguments: env: The metainfo environment. - directory: An optional directory path. The directory must exist. Default - is the working directory. + python_package_path: An optional directory path. The directory must exist. Default + is the working directory. The path will be used to form the module prefix + for generated Python modules. ''' - if directory is None: - directory = '.' - def format_description(description, indent=0, width=90): paragraphs = [paragraph.strip() for paragraph in description.split('\n')] @@ -383,13 +414,19 @@ def generate_metainfo_code(metainfo_env: Environment, directory: str = None): format_paragraph(p, i == 0) for i, p in enumerate(paragraphs) if p != '']) - def format_type(mi_type): + def format_type(pkg, mi_type): if type(mi_type) == np.dtype: return 'np.dtype(np.%s)' % mi_type if mi_type in [int, float, str, bool]: return mi_type.__name__ if isinstance(mi_type, Reference): - return "SectionProxy('%s')" % mi_type.target_section_def.name + if pkg == mi_type.target_section_def.m_parent: + return "Reference(SectionProxy('%s'))" % mi_type.target_section_def.name + + else: + python_pkg, _ = mi_type.target_section_def.m_parent.a_python + return '%s.%s' % (python_pkg.split('.')[-1], mi_type.target_section_def.name) + else: return str(mi_type) @@ -401,10 +438,16 @@ def generate_metainfo_code(metainfo_env: Environment, directory: str = None): if pkg == definition.m_parent: return definition.name else: - return definition.qualified_name() + python_pkg, _ = definition.m_parent.a_python + return '%s.%s' % (python_pkg.split('.')[-1], definition.name) return ', '.join([format_definition_ref(definition) for definition in definitions]) + def fromat_package_import(pkg): + python_package, _ = pkg.a_python + packages = python_package.split('.') + return 'from %s import %s' % ('.'.join(packages[:-1]), packages[-1]) + env = JinjaEnvironment( loader=PackageLoader('nomad.metainfo', 'templates'), autoescape=select_autoescape(['python'])) @@ -412,31 +455,26 @@ def generate_metainfo_code(metainfo_env: Environment, directory: str = None): format_description=format_description, format_type=format_type, format_unit=format_unit, - format_definition_refs=format_definition_refs) + format_definition_refs=format_definition_refs, + fromat_package_import=fromat_package_import) for package in metainfo_env.packages: - file_name = package.name - with open(os.path.join(directory, '%s.py' % file_name), 'wt') as f: + _, path = package.a_python + if not os.path.exists(os.path.dirname(path)): + os.makedirs(os.path.dirname(path)) + + with open(path, 'wt') as f: code = env.get_template('package.j2').render(pkg=package) code = '\n'.join([ line.rstrip() if line.strip() != '' else '' for line in code.split('\n')]) f.write(code) + _, path = python_package_mapping(metainfo_env.legacy_package_name) + with open(os.path.join(os.path.dirname(path), '__init__.py'), 'wt') as f: -# if __name__ == '__main__': -# output = 'output' - -# env = convert('vasp.nomadmetainfo.json') -# assert env.resolve_definition('x_vasp_incar_EFIELD_PEAD', Quantity) is not None -# assert 'x_vasp_incar_EFIELD_PEAD' in env.legacy_info_env() -# generate_metainfo_code(env, output) - -# from output import public -# import json - -# run = public.section_run() -# system = run.m_create(public.section_system) -# system.atom_labels = ['H', 'H', 'O'] - -# print(json.dumps(run.m_to_dict(with_meta=True), indent=2)) + code = env.get_template('environment.j2').render(env=metainfo_env) + code = '\n'.join([ + line.rstrip() if line.strip() != '' else '' + for line in code.split('\n')]) + f.write(code) diff --git a/nomad/metainfo/metainfo.py b/nomad/metainfo/metainfo.py index 02834a706894ded692df26157ef00e9f4d529321..4647ade4e3f4e7df798f6d703236b07378305bae 100644 --- a/nomad/metainfo/metainfo.py +++ b/nomad/metainfo/metainfo.py @@ -95,15 +95,17 @@ class MProxy(): url: The reference represented as an URL string. ''' - def __init__(self, m_proxy_url: str, m_proxy_section: 'MSection', m_proxy_quantity: 'Quantity'): + def __init__( + self, m_proxy_url: str, m_proxy_section: 'MSection' = None, + m_proxy_quantity: 'Quantity' = None): self.m_proxy_url = m_proxy_url self.m_proxy_section = m_proxy_section self.m_proxy_resolved = None - self.m_reference_type = m_proxy_quantity.type + self.m_proxy_quantity = m_proxy_quantity def m_proxy_resolve(self): - if self.m_proxy_section and not self.m_proxy_resolved: - self.m_proxy_resolved = self.m_reference_type.resolve(self) + if self.m_proxy_section and self.m_proxy_quantity and not self.m_proxy_resolved: + self.m_proxy_resolved = self.m_proxy_quantity.type.resolve(self) if self.m_proxy_resolved is not None and isinstance(self, MProxy): setattr(self, '__class__', self.m_proxy_resolved.__class__) @@ -112,12 +114,28 @@ class MProxy(): return self.m_proxy_resolved def __getattr__(self, key): - if self.m_proxy_resolve(): + if self.m_proxy_resolve() is not None: return getattr(self.m_proxy_resolved, key) raise ReferenceError('could not resolve %s' % self.m_proxy_url) +class SectionProxy(MProxy): + def m_proxy_resolve(self): + if self.m_proxy_section and not self.m_proxy_resolved: + root = self.m_proxy_section + while root is not None and not isinstance(root, Package): + root = root.m_parent + + if isinstance(root, Package): + self.m_proxy_resolved = root.all_definitions.get(self.m_proxy_url) + + if self.m_proxy_resolved is None: + raise ReferenceError('could not resolve %s' % self.m_proxy_url) + + return self.m_proxy_resolved + + class DataType: ''' Allows to define custom data types that can be used in the meta-info. @@ -298,9 +316,7 @@ class _QuantityType(DataType): class Reference(DataType): ''' Datatype used for reference quantities. ''' - def __init__(self, section_def: 'Section'): - if not isinstance(section_def, Section): - raise MetainfoError('%s is not a section definition.' % section_def) + def __init__(self, section_def: Union['Section', 'SectionProxy']): self.target_section_def = section_def def resolve(self, proxy) -> 'MSection': @@ -311,6 +327,12 @@ class Reference(DataType): return proxy.m_proxy_section.m_resolve(proxy.m_proxy_url) def set_normalize(self, section: 'MSection', quantity_def: 'Quantity', value: Any) -> Any: + if isinstance(self.target_section_def, MProxy): + proxy = self.target_section_def + proxy.m_proxy_section = section + proxy.m_proxy_quantity = quantity_def + self.target_section_def = proxy.m_proxy_resolve() + if self.target_section_def.m_follows(Definition.m_def): # special case used in metainfo definitions, where we reference metainfo definitions # using their Python class. E.g. referencing a section definition using its @@ -325,13 +347,14 @@ class Reference(DataType): if isinstance(value, MProxy): value.m_proxy_section = section + value.m_proxy_quantity = quantity_def return value if not isinstance(value, MSection): raise TypeError( 'The value %s is not a section and can not be used as a reference.' % value) - if not value.m_follows(self.target_section_def): + if not value.m_follows(self.target_section_def): # type: ignore raise TypeError( '%s is not a %s and therefore an invalid value of %s.' % (value, self.target_section_def, quantity_def)) @@ -2398,13 +2421,3 @@ class Environment(MSection): raise KeyError('Could not uniquely identify %s' % name) else: raise KeyError('Could not resolve %s' % name) - - -class SectionProxy(MProxy): - def m_proxy_resolve(self): - if self.m_proxy_section and not self.m_proxy_resolved: - root = self.m_proxy_section.m_root() - if isinstance(root, Package): - self.m_proxy_resolved = root.all_definitions.get(self.m_proxy_url) - - super().m_proxy_resolve() diff --git a/nomad/metainfo/templates/environment.j2 b/nomad/metainfo/templates/environment.j2 new file mode 100644 index 0000000000000000000000000000000000000000..36c874093c11e58379d6695d84822ca3d6e28177 --- /dev/null +++ b/nomad/metainfo/templates/environment.j2 @@ -0,0 +1,14 @@ +import sys +from nomad.metainfo import Environment +from nomad.metainfo.legacy import LegacyMetainfoEnvironment + +{%- for package in env.packages %} +import {{ package.a_python[0] }} +{%- endfor %} + +m_env = LegacyMetainfoEnvironment() + +{%- for package in env.packages %} +m_env.m_add_sub_section(Environment.packages, sys.modules['{{ package.a_python[0] }}'].m_package) # type: ignore +{%- endfor %} + diff --git a/nomad/metainfo/templates/package.j2 b/nomad/metainfo/templates/package.j2 index dff2fe2cb4f7191db08c91d8da026e2e149a35eb..731cb210f66bd56cead7f30ac65c465b10215910 100644 --- a/nomad/metainfo/templates/package.j2 +++ b/nomad/metainfo/templates/package.j2 @@ -1,10 +1,11 @@ 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 + MSection, MCategory, Category, Package, Quantity, Section, SubSection, SectionProxy, + Reference ) {% for dependency in pkg.dependencies %} -from . import {{dependency.name}} +{{ fromat_package_import(dependency) }} {%- endfor %} m_package = Package(name='{{ pkg.name }}', description='{{ pkg.description }}') @@ -33,7 +34,7 @@ class {{ section.name }}({%- if section.extends_base_section -%}{{ format_defini m_def = Section(validate=False{%- if section.extends_base_section -%}, extends_base_section=True{%- endif -%}) {% for quantity in section.quantities %} {{ quantity.name }} = Quantity( - type={{ format_type(quantity.type) }}, + type={{ format_type(pkg, quantity.type) }}, shape={{ quantity.shape }} {%- if quantity.unit is not none -%}, unit={{ format_unit(quantity.unit) }} diff --git a/nomad/parsing/metainfo.py b/nomad/parsing/metainfo.py index 55c3f3e823b60625a9cc77f2cbe108b15e9dbdef..588434595573fbae87d5710d2755a01962a8502d 100644 --- a/nomad/parsing/metainfo.py +++ b/nomad/parsing/metainfo.py @@ -318,4 +318,4 @@ class MetainfoBackend(LegacyParserBackend): pass def pwarn(self, msg): - pass + self.logger.warning(msg) diff --git a/nomad/utils.py b/nomad/utils.py index c2a71853c3cbedad352c04f9dcd39a5ef198264e..2fc434d7457874c970601c8ca8b7ebb9dade382a 100644 --- a/nomad/utils.py +++ b/nomad/utils.py @@ -407,6 +407,10 @@ def timer(logger, event, method='info', **kwargs): finally: stop = time.time() + if logger is None: + print(event, stop - start) + return + logger_method = getattr(logger, 'info', None) if logger_method is not None: logger_method(event, exec_time=stop - start, **kwargs) diff --git a/tests/metainfo/test_legacy.py b/tests/metainfo/test_legacy.py index 71d54e9f6fe7a5b7e6a91fd65077dbe9dce78338..b0e7de7c1b64bb012f57a99dbee578a3bfb6ee97 100644 --- a/tests/metainfo/test_legacy.py +++ b/tests/metainfo/test_legacy.py @@ -21,7 +21,7 @@ from nomad.metainfo.metainfo import ( MSection, MCategory, Section, Quantity, SubSection, Definition, Package, DeriveError, MetainfoError, Environment, MResource, Datetime, units, Annotation, SectionAnnotation, DefinitionAnnotation, Reference, MProxy, derived) -from nomad.metainfo.legacy import LegacyMetainfoEnvironment, convert +from nomad.metainfo.legacy import LegacyMetainfoEnvironment, convert, python_package_mapping from nomad.parsing.metainfo import MetainfoBackend @@ -60,6 +60,7 @@ def legacy_example(): @pytest.fixture(scope='session') def legacy_env(legacy_example): env = InfoKindEnv() + env.name = 'test.nomadmetainfo.json' for definition in legacy_example.get('metaInfos'): env.addInfoKindEl(InfoKindEl( description='test_description', package='test_package', **definition)) @@ -71,6 +72,24 @@ def env(legacy_env): return convert(legacy_env) +@pytest.mark.parametrize('package,path,name', [ + ( + 'vasp', + 'dependencies/parsers/vasp/vaspparser/metainfo/vasp.py', + 'vaspparser.metainfo.vasp'), + ( + 'common', + 'nomad/datamodel/metainfo/common.py', + 'nomad.datamodel.metainfo.common'), + ( + 'vasp_incars', + 'dependencies/parsers/vasp/vaspparser/metainfo/vasp_incars.py', + 'vaspparser.metainfo.vasp_incars') +]) +def test_package_mapping(package, path, name): + assert python_package_mapping(package) == (name, path) + + def test_environment(env: LegacyMetainfoEnvironment, no_warn): assert env.packages[0].name == 'test_package' assert 'section_system' in env.packages[0].all_definitions diff --git a/tests/test_datamodel.py b/tests/test_datamodel.py index 41275bc37ed9fd6f4f20a158f659ddc1a814fbf1..2c7b581945e5683498c8e0895e41995943957886 100644 --- a/tests/test_datamodel.py +++ b/tests/test_datamodel.py @@ -111,6 +111,25 @@ def generate_calc(pid: int = 0, calc_id: str = None, upload_id: str = None) -> d return entry +def test_common_metainfo(): + from nomad.datamodel.metainfo import public + + run = public.section_run() + system = run.m_create(public.section_system) + system.atom_labels = ['H', 'H', 'O'] + + assert run.section_system[0].atom_labels == ['H', 'H', 'O'] + + +def test_vasp_metainfo(): + from nomad.datamodel.metainfo import public + + run = public.section_run() + + assert 'vasp_src_date' not in run.m_def.all_quantities + from vaspparser.metainfo import m_env # pylint: disable=unused-import + + if __name__ == '__main__': import sys import json