diff --git a/mesaport/Access/gyre_access.py b/mesaport/Access/gyre_access.py index 8d93b23..152ac42 100644 --- a/mesaport/Access/gyre_access.py +++ b/mesaport/Access/gyre_access.py @@ -5,6 +5,9 @@ from . import access_helper from .support.utils import cwd +from threading import Lock +file_operation_lock = Lock() + """ This module defines the `GyreAccess` class, which handles GYRE input file operations. @@ -20,7 +23,7 @@ """ class GyreAccess: - def __init__(self, path, binary=False, target=''): + def __init__(self): """ Args: path (str): The path to the GYRE input file. @@ -28,11 +31,7 @@ def __init__(self, path, binary=False, target=''): target (str): The target to be used. """ self.check_env() - self.path = path - self.binary = binary - self.target = target - self.projectDir = os.path.abspath(path) - self.gyre_in = None + self.default_sections = self.gyreDefaults() def check_env(self): """ @@ -89,35 +88,36 @@ def writetoGyreFile(self, wdir, parameter, value, default_section=None, gyre_in= sections (list): A list with the sections of the inlist file. """ if default_section is None: - for section, values in self.gyreDefaults().items(): + for section, values in self.default_sections.items(): if parameter in values: default_section = section if default_section is None: raise(f"Parameter {parameter} not found in any GYRE input files.") this_section = False with cwd(wdir): - with open(gyre_in, "r") as file: - lines = file.readlines() - with open(gyre_in, "w+") as f: - indent = " " - for line in lines: - edited = False - if default_section in line: - this_section = True - if this_section: - if parameter in line: - if parameter == line.split("=")[0].strip(): - f.write(line.replace(line.split("=")[1], f" {value} ! Changed\n")) + with file_operation_lock: + with open(gyre_in, "r") as file: + lines = file.readlines() + with open(gyre_in, "w+") as f: + indent = " " + for line in lines: + edited = False + if default_section in line: + this_section = True + if this_section: + if parameter in line: + if parameter == line.split("=")[0].strip(): + f.write(line.replace(line.split("=")[1], f" {value} ! Changed\n")) + edited = True + this_section = False + elif line[0] == "/": + f.write(indent) + f.write(f"{parameter} = {value} ! Added\n") + f.write("/") edited = True this_section = False - elif line[0] == "/": - f.write(indent) - f.write(f"{parameter} = {value} ! Added\n") - f.write("/") - edited = True - this_section = False - if not edited: - f.write(line) + if not edited: + f.write(line) @@ -135,7 +135,7 @@ def modify_gyre_params(self, wdir, filename, data_format, gyre_in="gyre.in", dif self.writetoGyreFile(wdir, parameter="summary_file", value=f"'{filename.split('.')[0]}-freqs-nad.dat'", default_section="&nad_output", gyre_in=gyre_in) - def set(self, arg, gyre_in="gyre.in"): + def set(self, arg, wdir, gyre_in="gyre.in"): """Sets the value of a parameter in the inlist file. Args: @@ -143,11 +143,11 @@ def set(self, arg, gyre_in="gyre.in"): """ if isinstance(arg, dict): for key, value in arg.items(): - self.writetoGyreFile(self.projectDir, key, access_helper.toFortranType(value), gyre_in=gyre_in) + self.writetoGyreFile(wdir, key, access_helper.toFortranType(value), gyre_in=gyre_in) elif isinstance(arg, list): for item in arg: for key, value in item.items(): - self.writetoGyreFile(self.projectDir, key, access_helper.toFortranType(value), gyre_in=gyre_in) + self.writetoGyreFile(wdir, key, access_helper.toFortranType(value), gyre_in=gyre_in) elif arg is None: pass else: diff --git a/mesaport/ProjectOps/ops_helper.py b/mesaport/ProjectOps/ops_helper.py index 410868f..8d9779f 100644 --- a/mesaport/ProjectOps/ops_helper.py +++ b/mesaport/ProjectOps/ops_helper.py @@ -1,6 +1,7 @@ import subprocess import shlex -import sys, os, glob +import sys, os, glob, time +import numpy as np import shutil from rich import print @@ -38,16 +39,26 @@ def run_subprocess(commands, wdir, silent=True, runlog='', status=None, Pass os.environ.copy() to use the current environment. Or pass a dictionary with the environment variables to be used. """ if gyre_in is not None: - gyre_obj = GyreAccess(wdir) - if not os.path.exists(os.join(wdir, "gyre.in")): - gyre_obj.load(gyre_in=gyre_in, dest=wdir) + gyre_obj = GyreAccess() if parallel: num = filename.split(".")[0] - shutil.copy(gyre_in, os.path.join(wdir, f"gyre{num}.in")) - gyre_in = os.path.join(wdir, f"gyre{num}.in") + new_gyre_in = os.path.join(wdir, f"gyre{num}.in") + gyre_obj.modify_gyre_params(wdir, filename, data_format, gyre_in=new_gyre_in) + gyre_obj.set(arg=gyre_input_params, wdir=wdir, gyre_in=new_gyre_in) + time.sleep(1) + + # Update gyre_in to the new file + gyre_in = new_gyre_in commands = commands.replace("gyre.in", f"gyre{num}.in") - gyre_obj.modify_gyre_params(wdir, filename, data_format, gyre_in=gyre_in) - gyre_obj.set(gyre_input_params) + runlog = runlog.replace("gyre.log", f"gyre{num}.log") + else: + new_gyre_in = os.path.join(wdir, "gyre.in") + shutil.copyfile(gyre_in, new_gyre_in) + gyre_in = new_gyre_in + gyre_obj.modify_gyre_params(wdir, filename, data_format, gyre_in=gyre_in) + gyre_obj.set(arg=gyre_input_params, wdir=wdir, gyre_in=gyre_in) + + evo_terminated = False termination_code = None @@ -100,12 +111,6 @@ def run_subprocess(commands, wdir, silent=True, runlog='', status=None, sys.stdout.write(errline) logfile.write( "\n\n"+("*"*100)+"\n\n" ) _data, error = proc.communicate() - if gyre_in is not None: - working_dir = wdir.replace("LOGS", "") - with open(f'{working_dir}/gyre.log', 'a+') as f: - f.write(f"Done with {filename}.\n") - if parallel: - os.remove(gyre_in) if proc.returncode or error: print('The process raised an error:', proc.returncode, error) return False @@ -121,6 +126,11 @@ def run_subprocess(commands, wdir, silent=True, runlog='', status=None, age = age_ return termination_code, age else: + working_dir = wdir.replace("LOGS", "") + with open(f'{working_dir}/gyre.log', 'a+') as f: + f.write(f"Done with {filename}.\n") + if parallel: + os.remove(gyre_in) return True def process_outline(outline): diff --git a/mesaport/ProjectOps/project_ops.py b/mesaport/ProjectOps/project_ops.py index b4362f2..af63b30 100644 --- a/mesaport/ProjectOps/project_ops.py +++ b/mesaport/ProjectOps/project_ops.py @@ -372,6 +372,11 @@ def runGyre(self, gyre_in, files='all', wdir=None, data_format="GYRE", silent=Tr if parallel: gyre_input_params = gyre_input_params if gyre_input_params is not None else repeat(None) os.environ['HDF5_USE_FILE_LOCKING'] = 'FALSE' + ## copy gyre.in to gyre1.in, gyre2.in, etc. for parallel runs + for i, file in enumerate(files): + num = file.split(".")[0] + new_gyre_in = os.path.join(wdir, f"gyre{num}.in") + shutil.copyfile(gyre_in, new_gyre_in) # commands, wdir, # silent=True, runlog='', # status=None, filename="", @@ -381,7 +386,7 @@ def runGyre(self, gyre_in, files='all', wdir=None, data_format="GYRE", silent=Tr repeat(silent), repeat(runlog), repeat(None), files, repeat(data_format), repeat(True), repeat(gyre_in), - gyre_input_params, repeat(None), repeat(env)) + gyre_input_params, repeat(None), repeat(os.environ.copy())) if n_cores is None: n_cores = psutil.cpu_count(logical=True) Pool = mp.Pool @@ -401,7 +406,21 @@ def runGyre(self, gyre_in, files='all', wdir=None, data_format="GYRE", silent=Tr executor.map(ops_helper.run_subprocess, *args) except Exception as e: + filenames = glob.glob(os.path.join(LOGS_dir, f"gyre*.log")) + with open(runlog, 'a+') as outfile: + for fname in filenames: + with open(fname) as infile: + for line in infile: + outfile.write(line) + os.remove(fname) raise e + filenames = glob.glob(os.path.join(LOGS_dir, f"gyre*.log")) + with open(runlog, 'a+') as outfile: + for fname in filenames: + with open(fname) as infile: + for line in infile: + outfile.write(line) + os.remove(fname) res = True else: for i, file in enumerate(files):