def write_size(self, template): """Write SIZE file from SIZE.j2 template.""" if mpi.rank == 0: size_file = self.sim.path_run / "SIZE" logger.info(f"Writing SIZE file... {size_file}") with open(size_file, "w") as fp: self.oper.write_size( template, fp, comments=self.sim.params.short_name_type_run)
def write_box(self, template): """Write <case name>.box file from box.j2 template.""" if mpi.rank == 0: box_file = self.sim.path_run / f"{self.name_pkg}.box" logger.info(f"Writing box file... {box_file}") with open(box_file, "w") as fp: self.sim.oper.write_box( template, fp, comments=self.sim.params.short_name_type_run)
def _save_info_solver_params_xml(self, replace=False): """Saves the par file, along with FluidSim's params_simul.xml and info.xml""" params = self.sim.params if mpi.rank == 0 and self._has_to_save and params.NEW_DIR_RESULTS: par_file = Path(self.path_run) / f"{self.name_solver}.par" logger.info( f"Writing params files... {par_file}, params_simul.xml, " "info_solver.xml") with open(par_file, "w") as fp: params.nek._write_par(fp) super()._save_info_solver_params_xml(replace, comment=f"snek5000 {__version__}")
def get_configfile(cls, host=None): """Get path of the Snakemake configuration file for the current machine. All configuration files are stored under ``etc`` sub-package. """ if not host: host = os.getenv("SNIC_RESOURCE", os.getenv("GITHUB_WORKFLOW", gethostname())) root = cls.get_root() configfile = root / "etc" / f"{host}.yml" if not configfile.exists(): logger.warning( "Expected a configuration file describing compilers and flags: " f"{configfile}") configfile = Path(get_asset("default_configfile.yml")) logger.info(f"Using default configuration instead: {configfile}") return configfile
def post_init(self): if mpi.rank == 0: _banner_length = 42 logger.info("*" * _banner_length) logger.info(f"solver: {self.__class__}") logger.info(f"path_run: {self.path_run}") logger.info("*" * _banner_length) # This also calls _save_info_solver_params_xml super().post_init() # Write source files to compile the simulation if mpi.rank == 0 and self._has_to_save and self.sim.params.NEW_DIR_RESULTS: self.copy(self.path_run)
def copy(self, new_dir, force=False): """Copy case files to a new directory. The directory does not have to be present. :param new_dir: A str or Path-like instance pointing to the new directory. :param force: Force copy would overwrite if files already exist. """ # Avoid race conditions! Should be only executed by rank 0. if mpi.rank != 0: return abs_paths = self.get_paths() subpackages = self._get_subpackages() root = self.root def conditional_ignore(src, names): """Ignore if not found in ``abs_paths``.""" src = Path(src) include = abs_paths + [root / subpkg for subpkg in subpackages] exclude = tuple(name for name in names if not any( (src / name) == path for path in include)) logger.debug("".join(( f"- src: {src}", "\n- include:\n", "\n ".join(str(name) for name in include), "\n- exclude:\n", "\n ".join(exclude), "\n----", ))) return exclude new_root = Path(new_dir) try: logger.info("Copying with shutil.copytree ...") copytree_kwargs = dict(src=root, dst=new_root, symlinks=False, ignore=conditional_ignore) # Python 3.8+ shutil.copytree(**copytree_kwargs, dirs_exist_ok=True) except (TypeError, shutil.Error): try: logger.warning( "Python < 3.8: shutil.copytree may not proceed if directories exist." ) # Hoping that new_root has not been created shutil.copytree(**copytree_kwargs) except FileExistsError as e: logger.warning(e) logger.info("Copying with shutil.copy2 ...") # Copy one by one from the scratch if not new_root.exists(): logger.debug(f"Creating {new_root} ...") os.makedirs(new_root, exist_ok=True) for abs_path in abs_paths: rel_path = abs_path.relative_to(root) new_path = new_root / rel_path if not new_path.parent.exists(): os.makedirs(new_path.parent) logger.debug(f"Copying {new_path}") if new_path.exists(): if force: logger.warning( f"{new_path} would be overwritten ...") else: logger.warning( f"{new_path} exists, skipping. Use force=True to overwrite." ) continue shutil.copy2(abs_path, new_path) finally: logger.info(f"Copied: {root} -> {new_root}")