energy_check - Methodology and code
Python imports
[1]:
# Standard library imports
from pathlib import Path
import datetime
from typing import Optional, Union
# http://www.numpy.org/
import numpy as np
# https://ipython.org/
from IPython.display import display, Markdown
# https://github.com/usnistgov/atomman
import atomman as am
import atomman.lammps as lmp
import atomman.unitconvert as uc
from atomman.tools import filltemplate
# https://github.com/usnistgov/iprPy
import iprPy
from iprPy.tools import read_calc_file
print('Notebook last executed on', datetime.date.today(), 'using iprPy version', iprPy.__version__)
Notebook last executed on 2023-07-31 using iprPy version 0.11.6
1. Load calculation and view description
1.1. Load the calculation
[2]:
# Load the calculation being demoed
calculation = iprPy.load_calculation('energy_check')
1.2. Display calculation description and theory
[3]:
# Display main docs and theory
display(Markdown(calculation.maindoc))
display(Markdown(calculation.theorydoc))
energy_check calculation style
Lucas M. Hale, lucas.hale@nist.gov, Materials Science and Engineering Division, NIST.
Idea suggested by Udo v. Toussaint (Max-Planck-Institute f. Plasmaphysics)
Introduction
The energy_check calculation style provides a quick check if the energy of an atomic configuration matches with an expected one.
Version notes
Additional dependencies
Disclaimers
Small variations in the energy are to be expected due to numerical precisions.
2. Define calculation functions and generate files
This section defines the calculation functions and associated resource files exactly as they exist inside the iprPy package. This allows for the code used to be directly visible and modifiable by anyone looking to see how it works.
2.1. energy_check()
This is the primary function for the calculation. The version of this function built in iprPy can be accessed by calling the calc() method of an object of the associated calculation class.
[4]:
def energy_check(lammps_command: str,
system: am.System,
potential: lmp.Potential,
mpi_command: Optional[str] = None) -> dict:
"""
Performs a quick run 0 calculation to evaluate the potential energy of a
configuration.
Parameters
----------
lammps_command :str
Command for running LAMMPS.
system : atomman.System
The atomic configuration to evaluate.
potential : atomman.lammps.Potential
The LAMMPS implemented potential to use.
mpi_command : str, optional
The MPI command for running LAMMPS in parallel. If not given, LAMMPS
will run serially.
Returns
-------
dict
Dictionary of results consisting of keys:
- **'E_pot'** (*float*) - The per-atom potential energy of the system.
"""
# Get lammps units
lammps_units = lmp.style.unit(potential.units)
# Define lammps variables
lammps_variables = {}
system_info = system.dump('atom_data', f='init.dat',
potential=potential)
lammps_variables['atomman_system_pair_info'] = system_info
# Fill in lammps input script
template = read_calc_file('iprPy.calculation.energy_check', 'run0.template')
script = filltemplate(template, lammps_variables, '<', '>')
# Run LAMMPS
output = lmp.run(lammps_command, script=script,
mpi_command=mpi_command, logfile=None)
# Extract output values
thermo = output.simulations[-1]['thermo']
results = {}
results['E_pot'] = uc.set_in_units(thermo.v_peatom.values[-1],
lammps_units['energy'])
return results
2.2. run0.template file
[5]:
with open('run0.template', 'w') as f:
f.write("""#LAMMPS input script that evaluates a system's energy and pressure without relaxing
box tilt large
<atomman_system_pair_info>
variable peatom equal pe/atoms
thermo_style custom step lx ly lz pxx pyy pzz pe v_peatom
thermo_modify format float %.13e
run 0""")
3. Specify input parameters
3.1. System-specific paths
lammps_command is the LAMMPS command to use (required).
mpi_command MPI command for running LAMMPS in parallel. A value of None will run simulations serially.
[6]:
lammps_command = 'lmp'
mpi_command = None
# Optional: check that LAMMPS works and show its version
print(f'LAMMPS version = {am.lammps.checkversion(lammps_command)["version"]}')
LAMMPS version = 15 Sep 2022
3.2. Interatomic potential
potential_name gives the name of the potential_LAMMPS reference record in the iprPy library to use for the calculation.
potential is an atomman.lammps.Potential object (required).
[7]:
potential_name = '1999--Mishin-Y--Ni--LAMMPS--ipr1'
# Retrieve potential and parameter file(s) using atomman
potential = am.load_lammps_potential(id=potential_name, getfiles=True)
3.3. System
system is an atomman.System representing a fundamental unit cell of the system (required). Here, this is loaded as the ucell from a relaxed_crystal record.
expected_potential_energy is the expected per-atom potential energy for the system. Not needed for the calculation itself, but used here to compare with the computed value. This is taken from the relaxed_crystal record.
[8]:
# Fetch a relaxed crystal record from the database
potdb = am.library.Database(local=False)
crystal = potdb.get_relaxed_crystal(potential_LAMMPS_id=potential.id, family='A1--Cu--fcc', standing='good')
# Set ucell from the crystal record
system = crystal.ucell
# Set the expected potential energy from the crystal record
expected_potential_energy = crystal.potential_energy
Multiple matching record retrieved from remote
# family symbols alat Ecoh method standing
1 A1--Cu--fcc Ni 3.5200 -4.4500 dynamic good
2 A1--Cu--fcc Ni 7.3760 0.0119 dynamic good
Please select one:1
4. Run calculation and view results
4.1. Run calculation
All primary calculation method functions take a series of inputs and return a dictionary of outputs.
[9]:
results_dict = energy_check(lammps_command, system, potential, mpi_command=mpi_command)
print(results_dict.keys())
dict_keys(['E_pot'])
4.2. Report results
Values returned in the results_dict:
‘E_pot’ is the computed average potential energy across all atoms.
[10]:
energy_unit = 'eV'
print('Measured potential energy:', uc.get_in_units(results_dict['E_pot'], energy_unit), energy_unit)
if expected_potential_energy is not None:
print('Expected potential energy:', uc.get_in_units(expected_potential_energy, energy_unit), energy_unit)
Measured potential energy: -4.4499999983489 eV
Expected potential energy: -4.44999999835575 eV