Source code for calphy.queuekernel

"""
calphy: a Python library and command line interface for automated free
energy calculations.

Copyright 2021-2026 (c) Sarath Menon, Yury Lysogorskiy, Ralf Drautz
Interdisciplinary Centre for Advanced Materials Simulation (ICAMS),
Ruhr University Bochum, 44801 Bochum, Germany

calphy is published and distributed under the Academic Software Licence v1.0 (ASL).
calphy is distributed in the hope that it will be useful for non-commercial academic
research, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the LICENSE file for details.

The ASL permits academic non-commercial use only. Contact
sarath.menon@ruhr-uni-bochum.de to enquire about commercial use rights.

More information about the program can be found in:
Menon, Sarath, Yury Lysogorskiy, Jutta Rogal, and Ralf Drautz.
"Automated Free Energy Calculation from Atomistic Simulations." Physical Review Materials 5(10), 2021
DOI: 10.1103/PhysRevMaterials.5.103801

For more information contact:
sarath.menon@ruhr-uni-bochum.de
"""

import os
import numpy as np
import shutil
import argparse as ap
import subprocess
import yaml
import time
import datetime

from calphy.input import read_inputfile
from calphy.liquid import Liquid
from calphy.solid import Solid
from calphy.alchemy import Alchemy
from calphy.routines import (
    MeltingTemp,
    routine_fe,
    routine_ts,
    routine_pscale,
    routine_tscale,
    routine_alchemy,
    routine_composition_scaling,
)


[docs]def setup_calculation(calc): """ Set up a calculation Parameters ---------- options: dict options object kernel: int index of the calculation to be run Returns ------- job: Phase class job class """ # now we need to modify the routines if calc.mode == "melting_temperature": simfolder = None job = MeltingTemp(calculation=calc, simfolder=simfolder) elif calc.mode == "alchemy" or calc.mode == "composition_scaling": simfolder = calc.create_folders() job = Alchemy(calculation=calc, simfolder=simfolder) else: simfolder = calc.create_folders() if calc.reference_phase == "liquid": job = Liquid(calculation=calc, simfolder=simfolder) else: job = Solid(calculation=calc, simfolder=simfolder) return job
[docs]def run_calculation(job): """ Run calphy calculation Parameters ---------- job: Phase class Returns ------- job : Phase class """ if job.calc.mode == "fe": job = routine_fe(job) elif job.calc.mode == "ts": job = routine_ts(job) elif job.calc.mode == "alchemy": job = routine_alchemy(job) elif job.calc.mode == "melting_temperature": job.calculate_tm() elif job.calc.mode == "tscale": job = routine_tscale(job) elif job.calc.mode == "pscale": job = routine_pscale(job) elif job.calc.mode == "composition_scaling": job = routine_composition_scaling(job) else: raise ValueError( "Mode should be either fe/ts/alchemy/melting_temperature/tscale/pscale/composition_scaling" ) return job
[docs]def main(): arg = ap.ArgumentParser() # argument name of input file arg.add_argument( "-i", "--input", required=True, type=str, help="name of the input file" ) arg.add_argument( "-k", "--kernel", required=True, type=int, help="kernel number of the calculation to be run.", ) arg.add_argument( "-s", "--screen", required=False, type=bool, help="enable logging to screen", default=False, ) arg.add_argument( "--validate", action="store_true", default=False, help="perform full validation during input parsing (slower, validates all calculations)", ) # parse input # parse arguments args = vars(arg.parse_args()) kernel = args["kernel"] log_to_screen = args["screen"] validate = args["validate"] if validate: # Full validation mode: validate all calculations during parse calculations = read_inputfile(args["input"], validate=True) calc = calculations[kernel] else: # Fast mode: parse without validation, then validate only the one we need # Re-read the YAML to get clean data for just the kernel we need with open(args["input"], "r") as fin: data = yaml.safe_load(fin) calc_data = data["calculations"][kernel] calc_data["kernel"] = kernel calc_data["inputfile"] = args["input"] # Handle pressure conversion if "pressure" in calc_data.keys(): from calphy.input import _to_none calc_data["pressure"] = _to_none(calc_data["pressure"]) # Now validate this single calculation from calphy.input import Calculation calc = Calculation(**calc_data) # format and parse the arguments simfolder = calc.create_folders() if calc.mode == "melting_temperature": os.rmdir(simfolder) simfolder = None job = MeltingTemp( calculation=calc, simfolder=simfolder, log_to_screen=log_to_screen ) elif calc.mode == "alchemy" or calc.mode == "composition_scaling": job = Alchemy( calculation=calc, simfolder=simfolder, log_to_screen=log_to_screen ) os.chdir(simfolder) else: if calc.reference_phase == "liquid": job = Liquid( calculation=calc, simfolder=simfolder, log_to_screen=log_to_screen ) else: job = Solid( calculation=calc, simfolder=simfolder, log_to_screen=log_to_screen ) os.chdir(simfolder) if job.calc.mode == "fe": _ = routine_fe(job) elif job.calc.mode == "ts": _ = routine_ts(job) elif job.calc.mode == "alchemy": _ = routine_alchemy(job) elif job.calc.mode == "melting_temperature": job.calculate_tm() elif job.calc.mode == "tscale": _ = routine_tscale(job) elif job.calc.mode == "pscale": _ = routine_pscale(job) elif job.calc.mode == "composition_scaling": _ = routine_composition_scaling(job) else: raise ValueError( "Mode should be either fe/ts/alchemy/melting_temperature/tscale/pscale/composition_scaling" )