Commit cbd073af authored by Daniel Speckhard's avatar Daniel Speckhard
Browse files

nomad-faird infrastructure.

parent 2a39c1f0
......@@ -9,6 +9,7 @@ syntax: glob
*.pyc
*.bk
*.swp
*.egg-info
.DS_Store
# logging files
......
from gpawparser.parser import GpawParserWrapper
# Copyright 2015-2018 Mikkel Strange, Fawzi Mohamed, Ankit Kariryaa, Ask Hjorth Larsen, Jens Jørgen Mortensen
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function
import re
#p = re.compile(r"(?P<x_name>.*_X.*)\+(?P<c_name>.*_C.*)")
p = re.compile(
'((?P<x_name>(GGA|LDA|MGGA|HF|HYB_MGGA)_X.*)|(?P<c_name>(GGA|LDA|MGGA)_C.*))')
short_names = {
'LDA': 'LDA_X+LDA_C_PW',
'PW91': 'GGA_X_PW91+GGA_C_PW91',
'PBE': 'GGA_X_PBE+GGA_C_PBE',
'PBEsol': 'GGA_X_PBE_SOL+GGA_C_PBE_SOL',
'revPBE': 'GGA_X_PBE_R+GGA_C_PBE',
'RPBE': 'GGA_X_RPBE+GGA_C_PBE',
'BLYP': 'GGA_X_B88+GGA_C_LYP',
'HCTH407': 'GGA_XC_HCTH_407',
'WC': 'GGA_X_WC+GGA_C_PBE',
'AM05': 'GGA_X_AM05+GGA_C_AM05',
# 'M06-L': 'MGGA_X_M06_L+MGGA_C_M06_L',
# 'TPSS': 'MGGA_X_TPSS+MGGA_C_TPSS',
# 'revTPSS': 'MGGA_X_REVTPSS+MGGA_C_REVTPSS',
'mBEEF': 'MGGA_X_MBEEF+GGA_C_PBE_SOL'}
def get_libxc_name(name):
if name in short_names:
libxc_name = short_names[name]
else:
libxc_name = name
return libxc_name
def get_libxc_xc_names(name):
name = get_libxc_name(name)
xc = {'xc_name': None,
'x_name' : None,
'c_name': None}
if '_XC_' in name:
xc['xc_name'] = name
return xc
if '+' in name:
s = name.split('+')
xc['x_name'] = s[0]
xc['c_name'] = s[1]
return xc
m = re.search(p, name)
if m is not None: # it is either a correlation or exchange functional
xc.update(m.groupdict())
return xc
xc['xc_name'] = name # for something like BEEF-vdW
return xc
if __name__ == '__main__':
# print(get_libxc_name('LDA'))
# print(get_libxc_name('GGA_X_PBE'))
names = ['GGA_X_B88+GGA_C_LYP',
'HF_X',
'HYB_GGA_XC_B1LYP',
'HYB_GGA_XC_HSE03',
'BEEF-vdW',
'LDA_K_TF']
for name in names:
print(get_libxc_xc_names(name))
# Copyright 2015-2018 Mikkel Strange, Fawzi Mohamed, Ankit Kariryaa, Ask Hjorth Larsen, Jens Jørgen Mortensen
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
used with parser2.py, the new file format (aff)
"""
import numpy as np
parameters = {
'mode': 'fd',
'xc': 'LDA',
'occupations': None,
'poissonsolver': None,
'h': None, # Angstrom
'gpts': None,
'kpts': [(0.0, 0.0, 0.0)],
'nbands': None,
'charge': 0,
'setups': {},
'basis': {},
'spinpol': None,
'fixdensity': False,
'filter': None,
'mixer': None,
'eigensolver': None,
'background_charge': None,
'external': None,
'random': False,
'hund': False,
'maxiter': 333,
'idiotproof': True,
'symmetry': {'point_group': True,
'time_reversal': True,
'symmorphic': True,
'tolerance': 1e-7},
'convergence': {'energy': 0.0005, # eV / electron
'density': 1.0e-4,
'eigenstates': 4.0e-8, # eV^2
'bands': 'occupied',
'forces': np.inf}, # eV / Ang
'dtype': None, # Deprecated
'width': None, # Deprecated
'verbose': 0}
# Copyright 2015-2018 Mikkel Strange, Fawzi Mohamed, Ankit Kariryaa, Ask Hjorth Larsen, Jens Jørgen Mortensen
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
......@@ -14,6 +14,7 @@
from __future__ import division
import os
import logging
from contextlib import contextmanager
import numpy as np
from ase.data import chemical_symbols
......@@ -40,17 +41,38 @@ def c(value, unit=None):
parser_info = {"name": "parser_gpaw", "version": "1.0"}
path = '../../../../nomad-meta-info/meta_info/nomad_meta_info/' +\
'gpaw.nomadmetainfo.json'
# metaInfoPath = os.path.normpath(
# os.path.join(os.path.dirname(os.path.abspath(__file__)), path))
# metaInfoEnv, warns = loadJsonFile(filePath=metaInfoPath,
# dependencyLoader=None,
# extraArgsHandling=InfoKindEl.ADD_EXTRA_ARGS,
# uri=None)
import nomad_meta_info
metaInfoPath = os.path.normpath(
os.path.join(os.path.dirname(os.path.abspath(__file__)), path))
os.path.join(os.path.dirname(os.path.abspath(nomad_meta_info.__file__)),
"gpaw.nomadmetainfo.json"))
metaInfoEnv, warnings = loadJsonFile(
filePath = metaInfoPath, dependencyLoader = None,
extraArgsHandling = InfoKindEl.ADD_EXTRA_ARGS, uri = None)
metaInfoEnv, warns = loadJsonFile(filePath=metaInfoPath,
dependencyLoader=None,
extraArgsHandling=InfoKindEl.ADD_EXTRA_ARGS,
uri=None)
class LibAtomsParserWrapper():
""" A proper class envolop for running this parser using Noamd-FAIRD infra. """
def __init__(self, backend, **kwargs):
self.backend_factory = backend
def parse(self, mainfile):
from unittest.mock import patch
logging.info('lib-atoms parser started')
logging.getLogger('nomadcore').setLevel(logging.WARNING)
backend = self.backend_factory(metaInfoEnv)
backend = parse_without_class(mainfile, backend)
return backend
def parse(filename):
p = JsonParseEventsWriterBackend(metaInfoEnv)
def parse_without_class(filename, backend):
# p = JsonParseEventsWriterBackend(metaInfoEnv)
p = backend
o = open_section
r = Reader(filename)
p.startedParsingSession(filename, parser_info)
......
# Copyright 2015-2018 Mikkel Strange, Fawzi Mohamed, Ankit Kariryaa, Ask Hjorth Larsen, Jens Jørgen Mortensen
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import division
import os
import logging
from contextlib import contextmanager
import numpy as np
from ase.data import chemical_symbols
# import setup_paths
from nomadcore.unit_conversion.unit_conversion import convert_unit as cu
from nomadcore.local_meta_info import loadJsonFile, InfoKindEl
from nomadcore.parser_backend import JsonParseEventsWriterBackend
from gpawparser.tar import Reader
from gpawparser.libxc_names import get_libxc_xc_names
from gpawparser.versions import get_prog_version
@contextmanager
def open_section(p, name):
gid = p.openSection(name)
yield gid
p.closeSection(name, gid)
def c(value, unit=None):
""" Dummy function for unit conversion"""
return cu(value, unit)
parser_info = {"name": "parser_gpaw", "version": "1.0"}
path = '../../../../nomad-meta-info/meta_info/nomad_meta_info/' +\
'gpaw.nomadmetainfo.json'
# metaInfoPath = os.path.normpath(
# os.path.join(os.path.dirname(os.path.abspath(__file__)), path))
# metaInfoEnv, warns = loadJsonFile(filePath=metaInfoPath,
# dependencyLoader=None,
# extraArgsHandling=InfoKindEl.ADD_EXTRA_ARGS,
# uri=None)
import nomad_meta_info
metaInfoPath = os.path.normpath(
os.path.join(os.path.dirname(os.path.abspath(nomad_meta_info.__file__)),
"gpaw.nomadmetainfo.json"))
metaInfoEnv, warnings = loadJsonFile(
filePath = metaInfoPath, dependencyLoader = None,
extraArgsHandling = InfoKindEl.ADD_EXTRA_ARGS, uri = None)
class GpawParserWrapper():
""" A proper class envolop for running this parser using Noamd-FAIRD infra. """
def __init__(self, backend, **kwargs):
self.backend_factory = backend
def parse(self, mainfile):
from unittest.mock import patch
logging.info('lib-atoms parser started')
logging.getLogger('nomadcore').setLevel(logging.WARNING)
backend = self.backend_factory(metaInfoEnv)
backend = parse_without_class(mainfile, backend)
return backend
def parse_without_class(filename, backend):
# p = JsonParseEventsWriterBackend(metaInfoEnv)
p = backend
o = open_section
r = Reader(filename)
p.startedParsingSession(filename, parser_info)
with o(p, 'section_run'):
p.addValue('program_name', 'GPAW')
p.addValue('program_version', get_prog_version(r.version))
if r.Mode == 'pw':
p.addValue('program_basis_set_type', 'plane waves')
with o(p, 'section_basis_set_cell_dependent'):
p.addValue('basis_set_cell_dependent_name',
'PW_%.1f_Ry' % (r.PlaneWaveCutoff * 2.0)) # in Ry
p.addRealValue('basis_set_planewave_cutoff',
c(r.PlaneWaveCutoff, 'hartree'))
elif r.Mode == 'fd':
with o(p, 'section_basis_set_cell_dependent'):
h1 = np.linalg.norm(r.UnitCell[0]) / r.dims['ngptsx']
h2 = np.linalg.norm(r.UnitCell[1]) / r.dims['ngptsy']
h3 = np.linalg.norm(r.UnitCell[2]) / r.dims['ngptsz']
h = (h1 + h2 + h3) / 3.0
p.addValue('basis_set_cell_dependent_name',
'GR_%.1f' % (c(h, 'bohr') * 1.0E15)) # in fm
elif r.Mode == 'lcao':
p.addValue('program_basis_set_type', 'numeric AOs')
with o(p, 'section_basis_set_atom_centered'):
p.addValue('basis_set_atom_centered_short_name', r.BasisSet)
with o(p, 'section_system') as system_gid:
p.addArrayValues('simulation_cell', c(r.UnitCell, 'bohr'))
symbols = np.array([chemical_symbols[z] for z in r.AtomicNumbers])
p.addArrayValues('atom_labels', symbols)
p.addArrayValues('atom_positions', c(r.CartesianPositions, 'bohr'))
if r.Mode == 'pw':
pbc = np.array((1, 1, 1), bool)
else:
pbc = np.array(r.BoundaryConditions, bool)
p.addArrayValues('configuration_periodic_dimensions', pbc)
with o(p, 'section_sampling_method'):
p.addValue('ensemble_type', 'NVE')
with o(p, 'section_frame_sequence'):
pass
with o(p, 'section_method') as method_gid:
p.addValue('relativity_method', 'pseudo_scalar_relativistic')
p.addValue('electronic_structure_method', 'DFT')
p.addValue('scf_threshold_energy_change', c(r.EnergyError,
'hartree'))
if 'FixMagneticMoment' in r:
p.addValue('x_gpaw_fix_magnetic_moment',
r.FixMagneticMoment)
if r.FixMagneticMoment:
p.addValue('x_gpaw_fixed_spin_Sz',
r.MagneticMoments.sum() / 2.)
if 'FermiWidth' in r:
p.addValue('smearing_kind', 'fermi')
p.addRealValue('smearing_width',
c(r.FermiWidth, 'hartree'))
if 'FixDensity' in r:
p.addValue('x_gpaw_fix_density', r.FixDensity)
if 'DensityConvergenceCriterion' in r:
p.addRealValue('x_gpaw_density_convergence_criterion',
r.DensityConvergenceCriterion)
if 'MixClass' in r:
p.addValue('x_gpaw_mix_class', r.MixClass)
if 'MixBeta' in r:
p.addValue('x_gpaw_mix_beta', r.MixBeta)
if 'MixWeight' in r:
p.addValue('x_gpaw_mix_weight', r.MixWeight)
if 'MixOld' in r:
p.addValue('x_gpaw_mix_old', r.MixOld)
if 'MaximumAngularMomentum' in r:
p.addValue('x_gpaw_maximum_angular_momentum',
r.MaximumAngularMomentum)
if 'SymmetryTimeReversalSwitch' in r:
p.addValue('x_gpaw_symmetry_time_reversal_switch',
r.SymmetryTimeReversalSwitch)
p.addValue('x_gpaw_xc_functional', r.XCFunctional)
xc_names = get_libxc_xc_names(r.XCFunctional)
for name in xc_names.values():
if name is not None:
with o(p, 'section_XC_functionals'):
p.addValue('XC_functional_name', name)
with o(p, 'section_single_configuration_calculation'):
p.addValue('single_configuration_calculation_to_system_ref',
system_gid)
p.addValue('single_configuration_to_calculation_method_ref',
method_gid)
p.addRealValue('energy_total', c(r.Epot, 'hartree'))
p.addRealValue('energy_XC', c(r.Exc, 'hartree'))
p.addRealValue('electronic_kinetic_energy', c(r.Ekin, 'hartree'))
p.addRealValue('energy_correction_entropy', c(r.S, 'hartree'))
if 'CartesianForces' in r:
p.addArrayValues('atom_forces_free',
c(r.CartesianForces, 'bohr/hartree'))
p.addArrayValues('x_gpaw_magnetic_moments', r.MagneticMoments)
p.addRealValue('x_gpaw_spin_Sz', r.MagneticMoments.sum() / 2.0)
#p.addArrayValues('x_gpaw_atomic_density_matrices',
# r.AtomicDensityMatrices)
#p.addArrayValues('x_gpaw_projections_real', r.Projections.real)
#p.addArrayValues('x_gpaw_projections_imag', r.Projections.imag)
with o(p, 'section_eigenvalues'):
p.addValue('eigenvalues_kind', 'normal')
p.addArrayValues('eigenvalues_values',
c(r.Eigenvalues, 'hartree'))
p.addArrayValues('eigenvalues_occupation', r.OccupationNumbers)
p.addArrayValues('eigenvalues_kpoints', r.IBZKPoints)
p.finishedParsingSession("ParseSuccess", None)
return p # Return the backend
if __name__ == '__main__':
import sys
filename = sys.argv[1]
parse(filename)
# Copyright 2015-2018 Mikkel Strange, Fawzi Mohamed, Ankit Kariryaa, Ask Hjorth Larsen, Jens Jørgen Mortensen
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import division
import os
from contextlib import contextmanager
import numpy as np
from ase import units
from ase.data import chemical_symbols
from ase.io.ulm import ulmopen
from ase.utils import basestring
#from ase.io.trajectory import read_atoms
from ase.data import atomic_masses
from ase.units import Rydberg
import setup_paths
from nomadcore.unit_conversion.unit_conversion import convert_unit as cu
from nomadcore.local_meta_info import loadJsonFile, InfoKindEl
from nomadcore.parser_backend import JsonParseEventsWriterBackend
from libxc_names import get_libxc_name
from default_parameters import parameters as parms
@contextmanager
def open_section(p, name):
gid = p.openSection(name)
yield gid
p.closeSection(name, gid)
def c(value, unit=None):
""" Dummy function for unit conversion"""
return cu(value, unit)
parser_info = {"name": "parser2_gpaw", "version": "1.0"}
path = '../../../../nomad-meta-info/meta_info/nomad_meta_info/' +\
'gpaw.nomadmetainfo.json'
# metaInfoPath = os.path.normpath(
# os.path.join(os.path.dirname(os.path.abspath(__file__)), path))
# metaInfoEnv, warns = loadJsonFile(filePath=metaInfoPath,
# dependencyLoader=None,
# extraArgsHandling=InfoKindEl.ADD_EXTRA_ARGS,
# uri=None)
import nomad_meta_info
metaInfoPath = os.path.normpath(
os.path.join(os.path.dirname(os.path.abspath(nomad_meta_info.__file__)),
"gpaw.nomadmetainfo.json"))
metaInfoEnv, warnings = loadJsonFile(
filePath = metaInfoPath, dependencyLoader = None,
extraArgsHandling = InfoKindEl.ADD_EXTRA_ARGS, uri = None)
def parse(filename):
p = JsonParseEventsWriterBackend(metaInfoEnv)
o = open_section
r = ulmopen(filename) # Reader(filename)
p.startedParsingSession(filename, parser_info)
parms.update(r.parameters.asdict())
with o(p, 'section_run'):
p.addValue('program_name', 'GPAW')
p.addValue('program_version', r.gpaw_version)
mode = parms['mode']
if isinstance(mode, basestring):
mode = {'name': mode}
if mode['name'] == 'pw':
p.addValue('program_basis_set_type', 'plane waves')
with o(p, 'section_basis_set_cell_dependent'):
p.addValue('basis_set_cell_dependent_name',
'PW_%.1f_Ry' % (mode['ecut'] / r.ha * 2)) # in Ry
p.addRealValue('basis_set_planewave_cutoff',
c(mode['ecut'], 'eV'))
elif mode['name'] == 'fd':
p.addValue('program_basis_set_type', 'real space grid')
with o(p, 'section_basis_set_cell_dependent'):
cell = r.atoms.cell
ngpts = r.density.density.shape
h1 = np.linalg.norm(cell[0]) / ngpts[0]
h2 = np.linalg.norm(cell[1]) / ngpts[1]
h3 = np.linalg.norm(cell[2]) / ngpts[2]
h = (h1 + h2 + h3) / 3.0
p.addValue('basis_set_cell_dependent_name',
'GR_%.1f' % (c(h, 'angstrom') * 1.0E15)) # in fm
elif mode['name'] == 'lcao':
p.addValue('program_basis_set_type', 'numeric AOs')
with o(p, 'section_basis_set_atom_centered'):
p.addValue('basis_set_atom_centered_short_name',
parms['basis'])
with o(p, 'section_system') as system_gid:
p.addArrayValues('simulation_cell',
c(r.atoms.cell, 'angstrom'))
symbols = np.array([chemical_symbols[z] for z in r.atoms.numbers])
p.addArrayValues('atom_labels', symbols)
p.addArrayValues('atom_positions', c(r.atoms.positions, 'angstrom'))
p.addArrayValues('configuration_periodic_dimensions',
np.array(r.atoms.pbc, bool))
if 'momenta' in r.atoms:
masses = atomic_masses[r.atoms.numbers]
velocities = r.atoms.momenta / masses.reshape(-1, 1)
p.addArrayValues('atom_velocities',
c(velocities * units.fs / units.Angstrom,
'angstrom/femtosecond'))
with o(p, 'section_sampling_method'):
p.addValue('ensemble_type', 'NVE')
with o(p, 'section_frame_sequence'):
pass
with o(p, 'section_method') as method_gid:
p.addValue('relativity_method', 'pseudo_scalar_relativistic')
p.addValue('electronic_structure_method', 'DFT')
p.addValue('scf_threshold_energy_change',
c(parms['convergence']['energy'], 'eV')) # eV / electron
#if r.FixMagneticMoment:
# p.addValue('x_gpaw_fixed_spin_Sz',
# r.MagneticMoments.sum() / 2.)
if parms['occupations'] is None: # use default values
if tuple(parms['kpts']) == (1, 1, 1):
width = 0.0
else:
width = 0.1
parms['occupations'] = {'width': width, 'name': 'fermi-dirac'}
p.addValue('smearing_kind', parms['occupations']['name'])
p.addRealValue('smearing_width',
c(parms['occupations']['width'], 'eV'))
p.addRealValue('total_charge', parms['charge'])
with o(p, 'section_XC_functionals'):
p.addValue('XC_functional_name',
get_libxc_name(parms['xc']))
with o(p, 'section_single_configuration_calculation'):
p.addValue('single_configuration_calculation_to_system_ref',
system_gid)
p.addValue('single_configuration_to_calculation_method_ref',
method_gid)
p.addValue('single_configuration_calculation_converged',
r.scf.converged)
p.addRealValue('energy_total',
c(r.hamiltonian.e_total_extrapolated, 'eV'))
p.addRealValue('energy_free',
c(r.hamiltonian.e_total_free, 'eV'))
p.addRealValue('energy_XC', c(r.hamiltonian.e_xc, 'eV'))
p.addRealValue('electronic_kinetic_energy',
c(r.hamiltonian.e_kinetic, 'eV'))
p.addRealValue('energy_correction_entropy',
c(r.hamiltonian.e_entropy, 'eV'))
nspin = r.density.density.shape[0]
ef = r.occupations.fermilevel
fermilevels = np.zeros(nspin)
if nspin == 1:
fermilevels[:] = ef
elif nspin == 2:
split = r.occupations.split
fermilevels[0] = ef + 0.5 * split
fermilevels[1] = ef - 0.5 * split
p.addArrayValues('energy_reference_fermi',
c(fermilevels, 'eV'))
# Load 3D arrays ("volumetric data")
origin = -0.5 * r.atoms.cell.sum(axis=0)
npoints = np.array(r.density.density.shape[1:])
npoints[~r.atoms.pbc] += 1
displacements = r.atoms.cell / npoints
def add_3d_array(values, kind, unit):
with o(p, 'section_volumetric_data'):
p.addArrayValues('volumetric_data_origin',
c(origin, 'angstrom'))
p.addArrayValues('volumetric_data_displacements',
c(displacements, 'angstrom'))
p.addArrayValues('volumetric_data_values',
c(values, unit))
p.addValue('volumetric_data_kind', kind)
# H.atom.ulm.gpw test can be used to verify that pseudodensity
# integrates to 0.98, corresponding closely to the norm of the
# H 1s pseudowavefunction (see output of "gpaw-setup H").
# It has mixed BCs so this should show that npoints is taken
# care of correctly, hopefully.
add_3d_array(r.density.density, kind='density',
unit='angstrom**(-3)')
add_3d_array(r.hamiltonian.potential, kind='potential_effective',
unit='eV*angstrom**(-3)')
if 'forces' in r.results: