Commit 2ac8db01 authored by Markus Scheidgen's avatar Markus Scheidgen
Browse files

Merge branch 'md-workflow' into 'v1.0.0'

Implemented new lammps parser

See merge request !173
parents 65eed34b f16b3d09
Pipeline #82273 passed with stages
in 23 minutes and 2 seconds
Subproject commit 1c1dacfde7328e8ec9ca49419fae7d56157d9479
Subproject commit 2b9ee49d74cf89bb07e2b798e6e391fd5ac724c6
Subproject commit 3e4eb8aac2cf46882569e3823669f894c6890885
Subproject commit 84602c2c62462b93274dab91fce38a72b249cb49
......@@ -1607,6 +1607,32 @@ class section_energy_van_der_Waals(MSection):
a_legacy=LegacyDefinition(name='energy_van_der_Waals'))
class section_energy_contribution(MSection):
'''
Section describing the contributions to the total energy.
'''
m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_energy_contribution'))
energy_contibution_kind = Quantity(
type=str,
shape=[],
description='''
The kind of the energy contribution. Can be one of bond, pair, coulomb, etc.
''',
a_legacy=LegacyDefinition(name='energy_contibution_kind'))
energy_contribution_value = Quantity(
type=np.dtype(np.float64),
shape=[],
unit='joule',
description='''
Value of the energy contribution.
''',
categories=[energy_component, energy_value],
a_legacy=LegacyDefinition(name='energy_contribution_value'))
class section_frame_sequence_user_quantity(MSection):
'''
Section collecting some user-defined quantities evaluated along a sequence of frame.
......@@ -4460,6 +4486,42 @@ class section_single_configuration_calculation(MSection):
''',
a_legacy=LegacyDefinition(name='zero_point_method'))
enthalpy = Quantity(
type=np.dtype(np.float64),
shape=[],
unit='joule',
description='''
Value of the calculated enthalpy i.e. energy_total + pressure * volume.
''',
categories=[energy_component, energy_value],
a_legacy=LegacyDefinition(name='energy_enthalpy'))
pressure = Quantity(
type=np.dtype(np.float64),
shape=[],
unit='pascal',
description='''
Value of the pressure of the system.
''',
a_legacy=LegacyDefinition(name='pressure'))
temperature = Quantity(
type=np.dtype(np.float64),
shape=[],
unit='kelvin',
description='''
Value of the temperature of the system.
''',
a_legacy=LegacyDefinition(name='temperature'))
time_step = Quantity(
type=int,
shape=[],
description='''
The number of time steps with respect to the start of the calculation.
''',
a_legacy=LegacyDefinition(name='time_step'))
section_atom_projected_dos = SubSection(
sub_section=SectionProxy('section_atom_projected_dos'),
repeats=True,
......@@ -4505,6 +4567,11 @@ class section_single_configuration_calculation(MSection):
repeats=True,
a_legacy=LegacyDefinition(name='section_energy_van_der_Waals'))
section_energy_contribution = SubSection(
sub_section=SectionProxy('section_energy_contribution'),
repeats=True,
a_legacy=LegacyDefinition(name='section_energy_contribution'))
section_k_band_normalized = SubSection(
sub_section=SectionProxy('section_k_band_normalized'),
repeats=True,
......@@ -5771,6 +5838,41 @@ class Elastic(MSection):
a_legacy=LegacyDefinition(name='strain_maximum'))
class MolecularDynamics(MSection):
'''
Section containing results of molecular dynamics workflow.
'''
m_def = Section(
validate=False, a_legacy=LegacyDefinition(name='section_molecular_dynamics'))
finished_normally = Quantity(
type=bool,
shape=[],
description='''
Indicates if calculation terminated normally.
''',
a_legacy=LegacyDefinition(name='finished_normally'))
with_trajectory = Quantity(
type=bool,
shape=[],
description='''
Indicates if calculation includes trajectory data.
''',
a_legacy=LegacyDefinition(name='with_trajectory'),
a_search=Search())
with_thermodynamics = Quantity(
type=bool,
shape=[],
description='''
Indicates if calculation contains thermodynamic data.
''',
a_legacy=LegacyDefinition(name='with_thermodynamics'),
a_search=Search())
class Workflow(MSection):
'''
Section containing the results of a workflow.
......@@ -5802,5 +5904,9 @@ class Workflow(MSection):
sub_section=SectionProxy('Elastic'),
a_legacy=LegacyDefinition(name='section_elastic'))
section_molecular_dynamics = SubSection(
sub_section=SectionProxy('MolecularDynamics'),
a_legacy=LegacyDefinition(name='section_molecular_dynamics'))
m_package.__init_metainfo__()
......@@ -27,6 +27,7 @@ from aptfimparser import APTFIMParser
from vaspparser import VASPParser
from phonopyparser import PhonopyParser
from elasticparser import ElasticParser
from lammpsparser import LammpsParser
try:
# these packages are not available without parsing extra, which is ok, if the
......@@ -378,11 +379,7 @@ parsers = [
parser_class_name='tinkerparser.TinkerParser',
mainfile_contents_re=r'TINKER --- Software Tools for Molecular Design'
),
LegacyParser(
name='parsers/lammps', code_name='lammps', domain='dft',
parser_class_name='lammpsparser.LammpsParser',
mainfile_contents_re=r'^LAMMPS'
),
LammpsParser(),
LegacyParser(
name='parsers/amber', code_name='Amber', domain='dft',
parser_class_name='amberparser.AMBERParser',
......
......@@ -20,7 +20,7 @@ import logging
class Quantity:
def __init__(self, name, re_pattern, str_operation=None, unit=None, dtype=None):
def __init__(self, name, re_pattern, str_operation=None, unit=None, dtype=None, comment=None):
self.name = name
self.re_pattern = re.compile(re_pattern.encode())
self.unit = unit
......@@ -28,6 +28,7 @@ class Quantity:
self.dtype = dtype
self._value = None
self._str_operation = str_operation
self._comment = comment
@property
def value(self):
......@@ -37,6 +38,10 @@ class Quantity:
def value(self, val_in):
def convert_value(val):
if self._comment is not None:
if val.strip()[0] == self._comment:
return
if self._str_operation is not None:
val = self._str_operation(val)
......@@ -44,36 +49,44 @@ class Quantity:
val = val.strip().split() if isinstance(val, str) else val
val = val[0] if len(val) == 1 else val
def _get_dtype(val):
dtype = type(val)
def _convert(val):
if isinstance(val, str):
if self.dtype is None:
if val.isdecimal():
self.dtype = int
val = int(val)
else:
try:
float(val)
self.dtype = float
val = float(val)
except Exception:
self.dtype = str
pass
self.shape = []
return self.dtype
return val
elif type(val) in [np.ndarray, list]:
try:
dtype = float if self.dtype is None else self.dtype
val = np.array(val, dtype=dtype)
self.dtype = dtype
if np.all(np.mod(val, 1) == 0):
val = np.array(val, dtype=int)
self.dtype = int
self.shape = list(np.shape(val))
except Exception:
val = [_convert(v) for v in val]
self.dtype = None
elif dtype in (np.ndarray, list, tuple):
if len(val) > 0:
_get_dtype(val[-1])
self.shape = list(np.shape(val))
return lambda x: np.array(x, dtype=self.dtype)
return val
else:
self.dtype = type(val)
self.shape = []
return self.dtype
return val
val = _convert(val)
dtype = _get_dtype(val)
return dtype(val)
return val
self._value = None if val_in is None else [convert_value(val) for val in val_in]
......@@ -149,7 +162,7 @@ class UnstructuredTextFileParser:
if key is None or quantity.name in key:
value = []
for res in quantity.re_pattern.finditer(self.file_mmap):
value.append(''.join([group.decode() for group in res.groups()]))
value.append(''.join([group.decode() for group in res.groups() if group]))
if not value:
continue
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment