Skip to content

Commit

Permalink
Merge pull request #563 from timcallow/lammps_tempfile
Browse files Browse the repository at this point in the history
Use tempfile module for lammps file generation
  • Loading branch information
RandomDefaultUser authored Oct 7, 2024
2 parents 0fed9cc + 6ff7d58 commit 873c795
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 61 deletions.
9 changes: 2 additions & 7 deletions mala/descriptors/atomic_density.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,8 @@ def __calculate_lammps(self, outdir, **kwargs):
keep_logs = kwargs.get("keep_logs", False)

lammps_format = "lammps-data"
self.lammps_temporary_input = os.path.join(
outdir, "lammps_input_" + self.calculation_timestamp + ".tmp"
)
self.setup_lammps_tmp_files("ggrid", outdir)

ase.io.write(
self.lammps_temporary_input, self.atoms, format=lammps_format
)
Expand All @@ -160,10 +159,6 @@ def __calculate_lammps(self, outdir, **kwargs):
"sigma": self.parameters.atomic_density_sigma,
"rcutfac": self.parameters.atomic_density_cutoff,
}
self.lammps_temporary_log = os.path.join(
outdir,
"lammps_ggrid_log_" + self.calculation_timestamp + ".tmp",
)
lmp = self._setup_lammps(nx, ny, nz, lammps_dict)

# For now the file is chosen automatically, because this is used
Expand Down
39 changes: 17 additions & 22 deletions mala/descriptors/bispectrum.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Bispectrum descriptor class."""

import os
import tempfile

import ase
import ase.io
Expand Down Expand Up @@ -141,9 +142,8 @@ def __calculate_lammps(self, outdir, **kwargs):
keep_logs = kwargs.get("keep_logs", False)

lammps_format = "lammps-data"
self.lammps_temporary_input = os.path.join(
outdir, "lammps_input_" + self.calculation_timestamp + ".tmp"
)
self.setup_lammps_tmp_files("bgrid", outdir)

ase.io.write(
self.lammps_temporary_input, self.atoms, format=lammps_format
)
Expand All @@ -157,11 +157,6 @@ def __calculate_lammps(self, outdir, **kwargs):
"twojmax": self.parameters.bispectrum_twojmax,
"rcutfac": self.parameters.bispectrum_cutoff,
}

self.lammps_temporary_log = os.path.join(
outdir,
"lammps_bgrid_log_" + self.calculation_timestamp + ".tmp",
)
lmp = self._setup_lammps(nx, ny, nz, lammps_dict)

# An empty string means that the user wants to use the standard input.
Expand Down Expand Up @@ -227,6 +222,7 @@ def __calculate_lammps(self, outdir, **kwargs):
array_shape=(nrows_local, ncols_local),
use_fp64=use_fp64,
)

self._clean_calculation(lmp, keep_logs)

# Copy the grid dimensions only at the end.
Expand All @@ -243,6 +239,7 @@ def __calculate_lammps(self, outdir, **kwargs):
(nz, ny, nx, self.fingerprint_length),
use_fp64=use_fp64,
)

self._clean_calculation(lmp, keep_logs)

# switch from x-fastest to z-fastest order (swaps 0th and 2nd
Expand Down Expand Up @@ -511,7 +508,6 @@ def __calculate_python(self, **kwargs):
########

class _ZIndices:

def __init__(self):
self.j1 = 0
self.j2 = 0
Expand All @@ -525,7 +521,6 @@ def __init__(self):
self.jju = 0

class _BIndices:

def __init__(self):
self.j1 = 0
self.j2 = 0
Expand Down Expand Up @@ -968,21 +963,21 @@ def __compute_ui(self, nr_atoms, atoms_cutoff, distances_cutoff, grid):
)
jju1 += 1
if jju_outer in self.__index_u1_symmetry_pos:
ulist_r_ij[:, self.__index_u1_symmetry_pos[jju2]] = (
ulist_r_ij[:, self.__index_u_symmetry_pos[jju2]]
)
ulist_i_ij[:, self.__index_u1_symmetry_pos[jju2]] = (
-ulist_i_ij[:, self.__index_u_symmetry_pos[jju2]]
)
ulist_r_ij[
:, self.__index_u1_symmetry_pos[jju2]
] = ulist_r_ij[:, self.__index_u_symmetry_pos[jju2]]
ulist_i_ij[
:, self.__index_u1_symmetry_pos[jju2]
] = -ulist_i_ij[:, self.__index_u_symmetry_pos[jju2]]
jju2 += 1

if jju_outer in self.__index_u1_symmetry_neg:
ulist_r_ij[:, self.__index_u1_symmetry_neg[jju3]] = (
-ulist_r_ij[:, self.__index_u_symmetry_neg[jju3]]
)
ulist_i_ij[:, self.__index_u1_symmetry_neg[jju3]] = (
ulist_i_ij[:, self.__index_u_symmetry_neg[jju3]]
)
ulist_r_ij[
:, self.__index_u1_symmetry_neg[jju3]
] = -ulist_r_ij[:, self.__index_u_symmetry_neg[jju3]]
ulist_i_ij[
:, self.__index_u1_symmetry_neg[jju3]
] = ulist_i_ij[:, self.__index_u_symmetry_neg[jju3]]
jju3 += 1

# This emulates add_uarraytot.
Expand Down
64 changes: 39 additions & 25 deletions mala/descriptors/descriptor.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
"""Base class for all descriptor calculators."""

from abc import abstractmethod
from datetime import datetime
from functools import cached_property
import os
import tempfile

import ase
from ase.units import m
Expand Down Expand Up @@ -163,26 +163,6 @@ def descriptors_contain_xyz(self):
def descriptors_contain_xyz(self, value):
self.parameters.descriptors_contain_xyz = value

@cached_property
def calculation_timestamp(self):
"""
Timestamp of calculation start.
Used to distinguish multiple LAMMPS runs performed in the same
directory. Since the interface is file based, this timestamp prevents
problems with slightly
"""
if get_rank() == 0:
timestamp = datetime.timestamp(datetime.utcnow())
else:
timestamp = None

if self.parameters._configuration["mpi"]:
timestamp = get_comm().bcast(timestamp, root=0)
return datetime.fromtimestamp(timestamp).strftime("%F-%H-%M-%S-%f")[
:-3
]

##############################
# Methods
##############################
Expand Down Expand Up @@ -238,6 +218,44 @@ def backconvert_units(array, out_units):
"this descriptor type."
)

def setup_lammps_tmp_files(self, lammps_type, outdir):
"""
Create the temporary lammps input and log files.
Parameters
----------
lammps_type: str
Type of descriptor calculation (e.g. bgrid for bispectrum)
outdir: str
Directory where lammps files are kept
Returns
-------
None
"""
if get_rank() == 0:
prefix_inp_str = "lammps_" + lammps_type + "_input"
prefix_log_str = "lammps_" + lammps_type + "_log"
lammps_tmp_input_file=tempfile.NamedTemporaryFile(
delete=False, prefix=prefix_inp_str, suffix="_.tmp", dir=outdir
)
self.lammps_temporary_input = lammps_tmp_input_file.name
lammps_tmp_input_file.close()

lammps_tmp_log_file=tempfile.NamedTemporaryFile(
delete=False, prefix=prefix_log_str, suffix="_.tmp", dir=outdir
)
self.lammps_temporary_log = lammps_tmp_log_file.name
lammps_tmp_log_file.close()
else:
self.lammps_temporary_input=None
self.lammps_temporary_log=None

if self.parameters._configuration["mpi"]:
self.lammps_temporary_input = get_comm().bcast(self.lammps_temporary_input, root=0)
self.lammps_temporary_log = get_comm().bcast(self.lammps_temporary_log, root=0)


# Calculations
##############

Expand Down Expand Up @@ -827,10 +845,6 @@ def _clean_calculation(self, lmp, keep_logs):
os.remove(self.lammps_temporary_log)
os.remove(self.lammps_temporary_input)

# Reset timestamp for potential next calculation using same LAMMPS
# object.
del self.calculation_timestamp

def _setup_atom_list(self):
"""
Set up a list of atoms potentially relevant for descriptor calculation.
Expand Down
9 changes: 2 additions & 7 deletions mala/descriptors/minterpy_descriptors.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,8 @@ def _calculate(self, atoms, outdir, grid_dimensions, **kwargs):

# The rest is the stanfard LAMMPS atomic density stuff.
lammps_format = "lammps-data"
self.lammps_temporary_input = os.path.join(
outdir, "lammps_input_" + self.calculation_timestamp + ".tmp"
)
self.setup_lammps_tmp_files("minterpy", outdir)

ase.io.write(
self.lammps_temporary_input, self.atoms, format=lammps_format
)
Expand All @@ -175,10 +174,6 @@ def _calculate(self, atoms, outdir, grid_dimensions, **kwargs):
"sigma": self.parameters.atomic_density_sigma,
"rcutfac": self.parameters.atomic_density_cutoff,
}
self.lammps_temporary_log = os.path.join(
outdir,
"lammps_bgrid_log_" + self.calculation_timestamp + ".tmp",
)
lmp = self._setup_lammps(nx, ny, nz, lammps_dict)

# For now the file is chosen automatically, because this is used
Expand Down

0 comments on commit 873c795

Please sign in to comment.