Source code for calphy.queuekernel

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

Copyright 2021  (c) Sarath Menon^1, Yury Lysogorskiy^2, Ralf Drautz^2
^1: Max Planck Institut für Eisenforschung, Dusseldorf, Germany
^2: Ruhr-University Bochum, Bochum, Germany

calphy is published and distributed under the Academic Software License 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.
calphy API is published and distributed under the BSD 3-Clause "New" or "Revised" License
See the LICENSE FILE for more details.

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/yury.lysogorskiy@icams.rub.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" )