pyiron / pyiron_atomistics

pyiron_atomistics - an integrated development environment (IDE) for atomistic simulation in computational materials science.
https://pyiron-atomistics.readthedocs.io
BSD 3-Clause "New" or "Revised" License
43 stars 15 forks source link

Lammps submit to executor #1451

Closed jan-janssen closed 3 months ago

jan-janssen commented 3 months ago

This pull request is the continuation of https://github.com/pyiron/pyiron_atomistics/pull/1130 to define a calculate() function which can be submitted using an pympipool.Executor. Example:

from pympipool import Executor
import os
import posixpath
import shutil
import subprocess
from pyiron_atomistics import Project
from pyiron_atomistics.lammps.output import parse_lammps_output

def calculate_lammps(working_directory, input_file_dict, executable_dict, collect_output_kwargs):
    os.makedirs(working_directory, exist_ok=True)
    for file_name, content in input_file_dict["files_to_create"].items():
        with open(os.path.join(working_directory, file_name), "w") as f:
            f.writelines(content)
    for file_name, source in input_file_dict["files_to_copy"].items():
        shutil.copy(source, os.path.join(working_directory, file_name))
    _ = subprocess.run(
        executable_dict["command"],
        cwd=working_directory,
        shell=executable_dict["shell"],
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        universal_newlines=True,
        check=True,
    )
    return parse_lammps_output(
        dump_h5_full_file_name=posixpath.join(working_directory, "dump.h5"),
        dump_out_full_file_name=posixpath.join(working_directory, "dump.out"),
        log_lammps_full_file_name=posixpath.join(working_directory, "log.lammps"),
        **collect_output_kwargs,
    )

pr = Project("test")
pr.remove_jobs(recursive=True, silently=True)
job = pr.create.job.Lammps("lmp")
job.structure = pr.create.structure.ase.bulk("Al", cubic=True)
job.validate_ready_to_run()

executable, shell = job.executable.get_input_for_subprocess_call(
    cores=job.server.cores, threads=job.server.threads, gpus=job.server.gpus
)
with Executor() as exe:
    future = exe.submit(
        calculate_lammps, 
        working_directory="tmp", 
        input_file_dict=job.get_input_file_dict(), 
        executable_dict={
            "command": executable,
            "shell": shell,
        }, 
        collect_output_kwargs={
            "units": job.units,
            "potential_elements": job.input.potential.get_element_lst(),
            "structure": job.structure,
        },
    )
    output_dict = future.result()

job._python_only_job = True
job.save()
job._store_output(output_dict=output_dict)

job_reload = pr.load(job.job_name)
print(job_reload.output.energy_pot)
jan-janssen commented 3 months ago

This pull request requires https://github.com/pyiron/pyiron_base/pull/1472 to be merged first